B3: POST nest messages + event-driven response #10

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

Epic: #2. Depends on: #9

Goal

A POST /api/nests/{id}/messages endpoint that appends a message and, if a crow is addressed or a request opens, schedules exactly one crow response. No idle loops — responses happen only because a message landed.

Context a stranger needs

Routes register in Server.Handler() (server.go:43) with the new Go 1.22 method+path pattern style already used (mux.HandleFunc("POST /api/lists", ...)). Bodies via decode() (64 KiB cap, server.go:116). Response scheduling must go through Flock.ask/classify, never a brain directly (CLAUDE.md section 9). Guardrail: reject posts to an unknown nest (404) and to a nest the poster isn't part of the same way /api/lists rejects an unknown nest (server.go:143).

Acceptance criteria — falsifiable tests

  1. TestPostMessageToNest (server_test.go pattern) — Given a nest exists, when POSTing a valid say, then 201 + the message appears in GET of that nest's log. Red now, green after.
  2. TestPostMessageUnknownNest — when POSTing to nope, then 404 with {"message"}. Red now, green after.
  3. TestPostMessageTriggersOneResponse — Given a mock-brain nest with crow Hugin addressed, when a crow posts a request @-mentioning Hugin, then exactly one Hugin message is appended within the response step (assert count, not sleep). Red now, green after.
  4. TestNoIdleResponse — Given nobody is addressed, when a plain say is posted, then no crow message is appended (no timer fires). Red now, green after.

Test command

go test -race -run 'TestPostMessage|TestNoIdleResponse' ./...

Blockers / unknowns

@-parse lives in B4; this task can stub "addressed crow" as an explicit to field until B4.

Epic: #2. Depends on: #9 ## Goal A `POST /api/nests/{id}/messages` endpoint that appends a message and, if a crow is addressed or a request opens, schedules exactly one crow response. No idle loops — responses happen only because a message landed. ## Context a stranger needs Routes register in `Server.Handler()` (`server.go:43`) with the new Go 1.22 method+path pattern style already used (`mux.HandleFunc("POST /api/lists", ...)`). Bodies via `decode()` (64 KiB cap, `server.go:116`). Response scheduling must go through `Flock.ask`/`classify`, never a brain directly (CLAUDE.md section 9). Guardrail: reject posts to an unknown nest (404) and to a nest the poster isn't part of the same way `/api/lists` rejects an unknown nest (`server.go:143`). ## Acceptance criteria — falsifiable tests 1. `TestPostMessageToNest` (server_test.go pattern) — Given a nest exists, when POSTing a valid `say`, then 201 + the message appears in `GET` of that nest's log. Red now, green after. 2. `TestPostMessageUnknownNest` — when POSTing to `nope`, then 404 with `{"message"}`. Red now, green after. 3. `TestPostMessageTriggersOneResponse` — Given a mock-brain nest with crow Hugin addressed, when a crow posts a `request` @-mentioning Hugin, then exactly one Hugin message is appended within the response step (assert count, not sleep). Red now, green after. 4. `TestNoIdleResponse` — Given nobody is addressed, when a plain `say` is posted, then no crow message is appended (no timer fires). Red now, green after. ## Test command `go test -race -run 'TestPostMessage|TestNoIdleResponse' ./...` ## Blockers / unknowns @-parse lives in B4; this task can stub "addressed crow" as an explicit `to` field until B4.
Sign in to join this conversation.