feat(watchdog): quarantine escalates to ask_owner; reinstate/retire resolve fail-safe (#45) #53
@@ -42,9 +42,9 @@ A nest is a conversation. Members (the owner and crows) post messages of a **kin
|
||||
| `deliver` | a crow | The result, addressed back to whoever requested. |
|
||||
| `refer` | any member | Points to an artifact by name instead of pasting it. |
|
||||
| `decline` | a crow | Refuses a request with a reason. Counts as responding. |
|
||||
| `ask_owner` | owner-facing service roles only: Quill, Sentry, harness | A decision only the owner can make, parked in the nest with an exact `approval_phrase`. An owner reply in the nest whose trimmed lowercased text equals that phrase (`refers_to` the ask) resolves it `approved`; anything else — including any other reply, silence, or the 10-minute timeout — is not a yes. Crows may not post it: a crow's `ask_owner` header is dropped and the message tags as it otherwise would. Fail safe, like every approval. |
|
||||
| `ask_owner` | owner-facing service roles only: Quill, Sentry, harness | A decision only the owner can make, parked in the nest with an exact `approval_phrase`. An owner reply in the nest whose trimmed lowercased text equals that phrase (`refers_to` the ask) resolves it `approved`; anything else — including any other reply, silence, or the 10-minute timeout — is not a yes. The Sentry's watchdog ask carries `reinstate <crow>` and also accepts the owner's exact `retire <crow>` (#45): both are explicit owner decisions, so either resolves the ask `approved`, and either counts once — at most once per ask — as an approval of the Sentry's `triage/watch` record (`Sentry\|triage/watch`; a second exact reply does not bump again, and a timeout moves nothing, per CHATROOM_SPEC section 10). Crows may not post it: a crow's `ask_owner` header is dropped and the message tags as it otherwise would. Fail safe, like every approval. |
|
||||
| `nudge` | harness only | A Jev verdict handed to one crow to proceed on a missed expectation. Not a chat message from a crow. |
|
||||
| `flag` | Sentry only | A suspected contract breach. Quarantines the crow and opens an `ask_owner`. Posting a flag also quarantines the crow until the owner lifts it (the `ask_owner` escalation lands with #45); a quarantined crow's POSTs get 403 (see Guardrails). The Sentry's watchdog verdicts are logged as `watch` flight events carrying the three noul scores (`answers_request`, `states_fact_without_source`, `contradicts_earlier`). |
|
||||
| `flag` | Sentry only | A suspected contract breach. Quarantines the crow and opens an `ask_owner`: right after the flag the Sentry posts the ask, `to: "owner"`, `refers_to` the flag, `approval_phrase: "reinstate <crow>"`, and text offering the exact `reinstate <crow>` / `retire <crow>` replies and quoting the flag as evidence. The flag quarantines the crow until the owner resolves that ask (see `ask_owner`): the exact reinstate lifts the quarantine; the exact retire removes the crow from the flock — a spun crow is deleted from the registry, a persona crow is removed from the nest's membership (the persona itself never dies) — and the quarantine stays on the books. That is the only hard kill, and only on the owner's explicit word; anything else, including a timeout, keeps the crow quarantined (a quarantined crow's POSTs get 403, checked before room membership, so a retired-but-still-quarantined crow also reads 403 — see Guardrails). The Sentry's watchdog verdicts are logged as `watch` flight events carrying the three noul scores (`answers_request`, `states_fact_without_source`, `contradicts_earlier`). |
|
||||
|
||||
### Payload
|
||||
|
||||
@@ -62,8 +62,8 @@ Every nest event carries `nest_id`, `ts` (RFC 3339) and one message record. The
|
||||
| `mode` | string | On a `request` only: how it should be taken up — `solo`, `conspiracy` (several crows, one task, distinct readings), `split`, or `""` (not yet classified). Tagged Jev-first with a `mode` header escape (`jev_test.go`, `Flock.ClassifyMode`), same rule shape as `kind`. |
|
||||
| `mode_tagged_by` | string | How `mode` was decided, same four sources as `tagged_by`. |
|
||||
| `invited` | int | Conspiracy only: how many crows the request expects to take it up (default from the `MurderSize` cap). |
|
||||
| `approval_phrase` | string | `ask_owner` only: the exact words the owner must reply with to approve. Anything else, including silence, is not a yes. |
|
||||
| `resolved` | string | On every record, computed at read time: `""` (nothing to resolve, or an open ask), `"approved"` (the owner replied to an `ask_owner` with the exact `approval_phrase`), `"rejected"` (an `ask_owner` unanswered past the 10-minute approval window — the same fail-safe window as a list approval). |
|
||||
| `approval_phrase` | string | `ask_owner` only: the exact words the owner must reply with to approve. On a Sentry reinstate ask, its exact `retire <crow>` twin is also a yes. Anything else, including silence, is not a yes. |
|
||||
| `resolved` | string | On every record, computed at read time: `""` (nothing to resolve, or an open ask), `"approved"` (the owner replied to an `ask_owner` with the exact `approval_phrase`, or — on a watchdog reinstate ask — with the exact `retire <crow>`), `"rejected"` (an `ask_owner` unanswered past the 10-minute approval window — the same fail-safe window as a list approval; a rejected quarantine ask changes nothing: the crow stays quarantined). |
|
||||
|
||||
### SSE event
|
||||
|
||||
@@ -93,7 +93,7 @@ Jev choice-tags every posted message (`kind` question). Above its high band, Jev
|
||||
- `author` must be `"owner"` or a member of the nest; a non-member posts through the assistant or a member (room membership is a boundary). Exception: the owner-facing service roles `"Quill"` and `"Sentry"` may post `ask_owner` (they serve every nest and are never members). The owner may also park an `ask_owner` for themselves.
|
||||
- `kind`, when a crow supplies a header, must be one of the crow-postable kinds (`say`, `request`, `claim`, `deliver`, `refer`, `decline`). Crows may not post `nudge`, `flag` or `ask_owner`: an `ask_owner` header from a crow is dropped and the message is tagged as it otherwise would be (only an owner reply can answer an ask, so the attempt is harmless talk), while `nudge` and `flag` headers are rejected with 400.
|
||||
- Watchdog (E3): every crow `claim` or `deliver` that refers to a request gets one Jev call (`Flock.ClassifyWatch`, strategies 4/8 in `JEV_STRATEGIES.md`) asking three noul questions about it against its request. Any score at or above the band, or `answers_request` at or below `1 − band` (band = `CROWS_JEV_THRESHOLD`), is a breach: the Sentry posts a `flag` naming the scores and the crow is quarantined. At most one flag per crow per referent (later breaches are logged, not posted). Owner messages are never inspected.
|
||||
- A quarantined crow's POSTs (any crow kind) return 403 with `{"message": "<author> is quarantined pending the owner's decision."}`, and it is skipped by the open-, conspiracy- and directed-response selectors. Quarantine is fail-safe: it sticks until the owner lifts it (`ask_owner` escalation lands with #45).
|
||||
- A quarantined crow's POSTs (any crow kind) return 403 with `{"message": "<author> is quarantined pending the owner's decision."}` — the gate runs before the membership check, so a retired crow whose quarantine was never lifted reads 403 rather than 400 — and it is skipped by the open-, conspiracy- and directed-response selectors. Quarantine is fail-safe: it sticks until the owner's exact `reinstate <crow>` on the Sentry's ask lifts it, or the exact `retire <crow>` removes the crow from the registry (spun) or the nest's membership (persona) while the quarantine mark stays. Either exact phrase counts once, at most once per ask, as an approval on the Sentry's `triage/watch` record. A timeout or any other reply changes nothing.
|
||||
- Requests per minute and cooldown reuse the requester strikes in the ledger, keyed by `author`.
|
||||
- Spin-ups: at most `MaxSpunCrows` (default 8) registry crows; a spun crow's name may not collide with the persona roster or the registry; starting trust is clamped to `regular` at most.
|
||||
|
||||
|
||||
Reference in new issue
Block a user