Epic B: Nest conversation loop #2

Closed
opened 2026-10-28 05:26:54 +00:00 by jacisjake · 2 comments
jacisjake commented 2026-10-28 05:26:54 +00:00 (Migrated from github.com)

Part of: docs/SCOPE.md (S2) Depends on: #1 (Epic A)

Objective

A human posts a message into a nest and a crow answers it — the room works as conversation, not pipeline: say, request, claim, deliver, refer with @-addressing, event-driven (no idle loops), replayable over SSE. Mock brain first; live models only after the loop passes tests.

Context a stranger needs

  • Nest (nests.go:17) is {ID, Name, Crows} with no message log — the store persists to .crows/nests.json. A nest message log is new: append-only per nest, persisted alongside, mirroring NestStore.save()'s atomic write pattern (nests.go:133).
  • Hub (hub.go) already does per-list_id fan-out with numbered history and Last-Event-ID replay (hub.go:121). Reuse the shape, keyed by nest_id. The existing GET /api/events?list_id= (server.go:191) stays; nests need their own stream route (add ?nest_id= on the same handler or a parallel one — smallest change that keeps contracts-first).
  • Message kinds and payload fields must be written into EVENTS.md before any Go code (repo hard rule).
  • Server routes live in Server.Handler() (server.go:43). Bodies decode via decode() with the 64 KiB cap.
  • The spec's rules (CHATROOM_SPEC section 4): deliver addresses back to the requester; corrections acknowledged once; membership is a boundary. Event-driven + who-may-speak gating (CHATROOM_SPEC.md:50-56) — the trust-gated half is Epic C/D's dispatch; B only needs "addressed crows must respond" with the mock brain.
  • Personas and Flock.ask (flock.go:132): every model call goes through ask or classify (CLAUDE.md section 9). For B's mock tests, MockBrain (brain.go:223) already exists.

Out of scope for this epic

Complexity routing, expectations, nudges, assistant or COS roles, debate mode, UI changes.

Plan of record

  • #8 — EVENTS.md: nest message-kind contract
  • #9 — MessageLog store with persistence and replay
  • #10 — POST messages endpoint + event-driven responder trigger
  • #11 — @-addressing parse and addressed-crow-must-respond
  • #12 — Mock-brain end-to-end conversation test
  • #13 — Live models answer as crows in the nest

Definition of done

curl posts owner → request → claim → deliver into a test nest; SSE reconnect with Last-Event-ID replays all four in order; with the mock brain all tests in the plan pass under -race; with a live key, a named crow posts an in-character deliver in a nest within 60 seconds of a request.

Part of: docs/SCOPE.md (S2) Depends on: #1 (Epic A) ## Objective A human posts a message into a nest and a crow answers it — the room works as conversation, not pipeline: `say`, `request`, `claim`, `deliver`, `refer` with @-addressing, event-driven (no idle loops), replayable over SSE. Mock brain first; live models only after the loop passes tests. ## Context a stranger needs - `Nest` (`nests.go:17`) is `{ID, Name, Crows}` with no message log — the store persists to `.crows/nests.json`. A nest message log is new: append-only per nest, persisted alongside, mirroring `NestStore.save()`'s atomic write pattern (`nests.go:133`). - `Hub` (`hub.go`) already does per-`list_id` fan-out with numbered history and `Last-Event-ID` replay (`hub.go:121`). Reuse the shape, keyed by `nest_id`. The existing `GET /api/events?list_id=` (`server.go:191`) stays; nests need their own stream route (add `?nest_id=` on the same handler or a parallel one — smallest change that keeps contracts-first). - Message kinds and payload fields must be written into `EVENTS.md` before any Go code (repo hard rule). - Server routes live in `Server.Handler()` (`server.go:43`). Bodies decode via `decode()` with the 64 KiB cap. - The spec's rules (CHATROOM_SPEC section 4): deliver addresses back to the requester; corrections acknowledged once; membership is a boundary. Event-driven + who-may-speak gating (`CHATROOM_SPEC.md:50-56`) — the trust-gated half is Epic C/D's dispatch; B only needs "addressed crows must respond" with the mock brain. - Personas and `Flock.ask` (`flock.go:132`): every model call goes through `ask` or `classify` (`CLAUDE.md` section 9). For B's mock tests, `MockBrain` (`brain.go:223`) already exists. ## Out of scope for this epic Complexity routing, expectations, nudges, assistant or COS roles, debate mode, UI changes. ## Plan of record - [x] #8 — EVENTS.md: nest message-kind contract - [x] #9 — MessageLog store with persistence and replay - [x] #10 — POST messages endpoint + event-driven responder trigger - [x] #11 — @-addressing parse and addressed-crow-must-respond - [x] #12 — Mock-brain end-to-end conversation test - [x] #13 — Live models answer as crows in the nest ## Definition of done `curl` posts owner → request → claim → deliver into a test nest; SSE reconnect with `Last-Event-ID` replays all four in order; with the mock brain all tests in the plan pass under `-race`; with a live key, a named crow posts an in-character `deliver` in a nest within 60 seconds of a `request`.
jacisjake commented 2026-10-28 05:36:51 +00:00 (Migrated from github.com)

Sentry decision landed (#6): it becomes the nest watchdog, quarantining crows outside their contract (flag message kind). Epic F gains: a Sentry-watchdog task beside COS spin-up.

Sentry decision landed (#6): it becomes the nest watchdog, quarantining crows outside their contract (`flag` message kind). Epic F gains: a Sentry-watchdog task beside COS spin-up.
jacisjake commented 2026-10-28 11:04:38 +00:00 (Migrated from github.com)

Definition of done walked 2026-10-28:

  • curl owner -> request -> (crow claim/deliver) chain exercised against the running server (mock): 201s, records in log.
  • SSE reconnect with Last-Event-ID replays in order (TestNestConversationEndToEndMock + manual curl).
  • Mock brain: all 50 tests pass under -race.
  • Live key: TestLiveCrowDeliversInNest PASS on nvidia/nemotron-3.5-lightning:free (11.5s, responsive deliver, logged non-mock flight). The pinned gemma:free model is currently 429'd upstream, so the test skips there by design rather than lying.
Definition of done walked 2026-10-28: - curl owner -> request -> (crow claim/deliver) chain exercised against the running server (mock): 201s, records in log. - SSE reconnect with Last-Event-ID replays in order (TestNestConversationEndToEndMock + manual curl). - Mock brain: all 50 tests pass under -race. - Live key: TestLiveCrowDeliversInNest PASS on nvidia/nemotron-3.5-lightning:free (11.5s, responsive deliver, logged non-mock flight). The pinned gemma:free model is currently 429'd upstream, so the test skips there by design rather than lying.
Sign in to join this conversation.