D3: Relay — Quill posts requests on the owner's behalf #40

Closed
opened 2026-10-28 13:42:50 +00:00 by jacisjake · 2 comments
jacisjake commented 2026-10-28 13:42:50 +00:00 (Migrated from github.com)

Epic: #36. Depends on: #38

Goal

Relay: @Quill get Hugin to draft the tagline makes Quill post a request into the nest authored by Quill, addressed to the named member crow, refers_to the owner's original message — so the existing must-respond loop (respondToRequest) answers it. Quill does not do the work itself. Structured parsing goes through Flock.ask (one narrow call returning JSON: {"crow": "...", "task": "..."} or {"crow": ""}), never a direct brain call.

Acceptance criteria — falsifiable tests

  1. TestQuillRelayPostsRequest (quill_test.go) — Given nest members Hugin and Munin and a scripted brain answering {"crow":"Hugin","task":"draft the tagline"}, when the owner posts @Quill get Hugin to draft the tagline, then a new message exists with author: "Quill", kind: "request", to: "Hugin", refers_to: <owner msg_id>; then Hugin's deliver follows (full loop). Red now: no relay path exists.
  2. TestQuillRelayUnknownCrowStalls — Given brain answers {"crow":"Soot",...} and Soot is not a nest member, then no request from Quill exists in the nest; Quill posts a say naming the crow it could not find (assert one Quill message with kind say, zero kind request).
  3. TestQuillRelayNotAnsweredTwice — In criterion 1's run, Quill posts exactly two messages total (the parsed relay is its only speech; no separate Quill deliver answering the task itself).
  4. TestQuillRelayGoesThroughFlock — With the flock saturated (MaxCrowsInFlight 0 slots free) and a 50ms context, the relay call returns without posting any Quill message (guardrail honored; uses Flock.reserve behavior from #28).

Test command

go test -race -count=1 -run 'TestQuillRelay' .

Blockers / unknowns

EVENTS.md first: document the relay shape (Quill-authored request with refers_to set to the owner message) in the kind table note. Decide nothing new about relayed flags — refers_to + author is enough.

Epic: #36. Depends on: #38 ## Goal Relay: `@Quill get Hugin to draft the tagline` makes Quill post a `request` into the nest authored by Quill, addressed to the named member crow, `refers_to` the owner's original message — so the existing must-respond loop (`respondToRequest`) answers it. Quill does not do the work itself. Structured parsing goes through `Flock.ask` (one narrow call returning JSON: `{"crow": "...", "task": "..."}` or `{"crow": ""}`), never a direct brain call. ## Acceptance criteria — falsifiable tests 1. `TestQuillRelayPostsRequest` (`quill_test.go`) — Given nest members Hugin and Munin and a scripted brain answering `{"crow":"Hugin","task":"draft the tagline"}`, when the owner posts `@Quill get Hugin to draft the tagline`, then a new message exists with `author: "Quill"`, `kind: "request"`, `to: "Hugin"`, `refers_to: <owner msg_id>`; then Hugin's `deliver` follows (full loop). Red now: no relay path exists. 2. `TestQuillRelayUnknownCrowStalls` — Given brain answers `{"crow":"Soot",...}` and Soot is not a nest member, then no `request` from Quill exists in the nest; Quill posts a `say` naming the crow it could not find (assert one Quill message with kind `say`, zero kind `request`). 3. `TestQuillRelayNotAnsweredTwice` — In criterion 1's run, Quill posts exactly two messages total (the parsed relay is its only speech; no separate Quill `deliver` answering the task itself). 4. `TestQuillRelayGoesThroughFlock` — With the flock saturated (`MaxCrowsInFlight` 0 slots free) and a 50ms context, the relay call returns without posting any Quill message (guardrail honored; uses `Flock.reserve` behavior from #28). ## Test command `go test -race -count=1 -run 'TestQuillRelay' .` ## Blockers / unknowns EVENTS.md first: document the relay shape (Quill-authored `request` with `refers_to` set to the owner message) in the kind table note. Decide nothing new about `relayed` flags — `refers_to` + author is enough.
jacisjake commented 2026-10-28 13:54:28 +00:00 (Migrated from github.com)

Criterion amended during pickup: relay is decided in ONE structured Quill call (reply prefixed RELAY {"crow":...,"task":...}), not an extra parse call — this keeps #38's exactly one model call assertion true. Criterion 3 now asserts Quill posts exactly ONE message on a successful relay (kind request) and zero delivers.

Criterion amended during pickup: relay is decided in ONE structured Quill call (reply prefixed `RELAY {"crow":...,"task":...}`), not an extra parse call — this keeps #38's `exactly one model call` assertion true. Criterion 3 now asserts Quill posts exactly ONE message on a successful relay (kind request) and zero delivers.
jacisjake commented 2026-10-28 14:49:19 +00:00 (Migrated from github.com)

PR: https://github.com/jacisjake/so-many-crows/pull/48 — amended design implemented (one structured Quill call, RELAY prefix; triggerResponse extraction). Two small notes, no criteria changed:

  • Broken-JSON stall reads "I could not find that crow in this nest." — "omit the name" rendered grammatically instead of "I could not find in this nest."
  • TestQuillRelayGoesThroughFlock passed even at RED (a saturated flock means today's respondQuill also posts nothing); it stays as the guard that the relay path keeps ask as the only model door. The other three relay tests were RED as expected.
PR: https://github.com/jacisjake/so-many-crows/pull/48 — amended design implemented (one structured Quill call, RELAY prefix; triggerResponse extraction). Two small notes, no criteria changed: - Broken-JSON stall reads "I could not find that crow in this nest." — "omit the name" rendered grammatically instead of "I could not find in this nest." - TestQuillRelayGoesThroughFlock passed even at RED (a saturated flock means today's respondQuill also posts nothing); it stays as the guard that the relay path keeps ask as the only model door. The other three relay tests were RED as expected.
Sign in to join this conversation.