feat(watchdog): quarantine escalates to ask_owner; reinstate/retire resolve fail-safe (#45) #53

Merged
jacisjake merged 3 commits from task/45-quarantine-escalation into main 2026-10-28 15:21:01 +00:00
jacisjake commented 2026-10-28 15:19:58 +00:00 (Migrated from github.com)

What was addressed

  • A watchdog flag now escalates: right after flag + quarantine the Sentry posts an ask_owner to the owner, refers_to the flag, approval_phrase: reinstate <crow>, offering the exact reinstate/retire phrases with the flag as evidence.
  • Owner's exact reinstate <crow> lifts the quarantine; exact retire <crow> deletes a spun crow from the registry or removes a persona crow from the nest's membership (quarantine mark stays). Wrong phrase, crow replies and timeouts do nothing — fail safe. All effects are idempotent (lift re-checks quarantine, removals no-op, bump once per ask).
  • Either exact phrase counts as one approval on Sentry|triage/watch (at most once per ask; a timeout moves nothing, spec §10).
  • Read-time resolved now accepts the retire <crow> twin of a reinstate ask as approved (#41 logic extended).
  • The quarantine 403 gate runs before the nest-membership check, so a retired-but-still-quarantined crow reads 403, not 400.
  • Server.askTimeout is now atomic.Int64: handlers and the watchdog emit path read it concurrently, and tests narrow the window while the server runs (race-detector flagged the plain write). One #41 test write site updated to the Store API.
  • EVENTS.md updated first: ask_owner, flag, approval_phrase/resolved, and the guardrails bullet.

How to test / validate

  • go test -race -count=1 -run 'TestQuarantine|TestReinstate|TestRetire|TestWatch' . → all PASS. Pre-implementation RED excerpt: --- FAIL: TestQuarantineOpensAskOwner ... a quarantine must escalate: an ask_owner referring the flag must exist, log: [...Kind:flag...] (flag posted, no ask).
  • gofmt -l . and go vet ./... → no output.
  • go test -race -count=1 -timeout 180s . → ok somanycrows (full suite; new tests also pass -count=5 race-clean).
  • git show e60155c --stat → contract commit lands before the red test and the code.

Configurations or dependencies

  • None: no new env vars, keys or capabilities; the escalation rides the existing watchdog path.

Closes #45
Epic: #37

## What was addressed - A watchdog flag now escalates: right after flag + quarantine the Sentry posts an `ask_owner` to the owner, `refers_to` the flag, `approval_phrase: reinstate <crow>`, offering the exact reinstate/retire phrases with the flag as evidence. - Owner's exact `reinstate <crow>` lifts the quarantine; exact `retire <crow>` deletes a spun crow from the registry or removes a persona crow from the nest's membership (quarantine mark stays). Wrong phrase, crow replies and timeouts do nothing — fail safe. All effects are idempotent (lift re-checks quarantine, removals no-op, bump once per ask). - Either exact phrase counts as one approval on `Sentry|triage/watch` (at most once per ask; a timeout moves nothing, spec §10). - Read-time `resolved` now accepts the `retire <crow>` twin of a reinstate ask as approved (#41 logic extended). - The quarantine 403 gate runs before the nest-membership check, so a retired-but-still-quarantined crow reads 403, not 400. - `Server.askTimeout` is now `atomic.Int64`: handlers and the watchdog emit path read it concurrently, and tests narrow the window while the server runs (race-detector flagged the plain write). One #41 test write site updated to the Store API. - EVENTS.md updated first: `ask_owner`, `flag`, `approval_phrase`/`resolved`, and the guardrails bullet. ## How to test / validate - [ ] `go test -race -count=1 -run 'TestQuarantine|TestReinstate|TestRetire|TestWatch' .` → all PASS. Pre-implementation RED excerpt: `--- FAIL: TestQuarantineOpensAskOwner ... a quarantine must escalate: an ask_owner referring the flag must exist, log: [...Kind:flag...]` (flag posted, no ask). - [ ] `gofmt -l .` and `go vet ./...` → no output. - [ ] `go test -race -count=1 -timeout 180s .` → `ok somanycrows` (full suite; new tests also pass `-count=5` race-clean). - [ ] `git show e60155c --stat` → contract commit lands before the red test and the code. ## Configurations or dependencies - [ ] None: no new env vars, keys or capabilities; the escalation rides the existing watchdog path. Closes #45 Epic: #37
Sign in to join this conversation.