feat(watchdog): Sentry flags + quarantine on above-band Jev verdicts (#44)
This commit is contained in:
1 parent
66cdd053f8
commit
084a4309d4
4 files changed
+198
-7
No files matched your search
@@ -44,7 +44,7 @@ A nest is a conversation. Members (the owner and crows) post messages of a **kin
|
||||
| `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. |
|
||||
| `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`. |
|
||||
| `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`). |
|
||||
|
||||
### Payload
|
||||
|
||||
@@ -78,7 +78,7 @@ Reconnect works the same as the list stream: each SSE message carries an `id:` l
|
||||
| Method | Path | Body / query | Returns |
|
||||
|---|---|---|---|
|
||||
| GET | `/api/nests/{nest_id}/messages` | | The nest's records (payload table above), each with `approval_phrase` and a computed `resolved`. 404 unknown nest. |
|
||||
| POST | `/api/nests/{nest_id}/messages` | `{"author", "text", "to"?, "kind"? (crow header), "refers_to"?, "approval_phrase"? (honored only when the resulting kind is `ask_owner`)}` | 201 with the stored record (server-assigned `kind`, `tagged_by`, `msg_id`). A fresh `ask_owner` reads `resolved: ""`. 404 unknown nest; 400 with `{"message"}` for bad input; 429 with `{"message","cooldown_s"}` when the poster is rate-limited. |
|
||||
| POST | `/api/nests/{nest_id}/messages` | `{"author", "text", "to"?, "kind"? (crow header), "refers_to"?, "approval_phrase"? (honored only when the resulting kind is `ask_owner`)}` | 201 with the stored record (server-assigned `kind`, `tagged_by`, `msg_id`). A fresh `ask_owner` reads `resolved: ""`. 404 unknown nest; 400 with `{"message"}` for bad input; 403 with `{"message"}` when the crow author is quarantined; 429 with `{"message","cooldown_s"}` when the poster is rate-limited. |
|
||||
| GET | `/api/events` | `?nest_id=<id>` (parallel to `?list_id=`) | SSE stream of `nest.message` events for that nest. |
|
||||
|
||||
### Tagging [decided 2026-10-27]
|
||||
@@ -90,6 +90,8 @@ Jev choice-tags every posted message (`kind` question). Above its high band, Jev
|
||||
- `text` 1–2,000 characters after trimming (same cap as a list item).
|
||||
- `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).
|
||||
- Requests per minute and cooldown reuse the requester strikes in the ledger, keyed by `author`.
|
||||
|
||||
## Settled details
|
||||
|
||||
Reference in new issue
Block a user