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
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.
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).
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).
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.
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.
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.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Epic: #36. Depends on: #38
Goal
Relay:
@Quill get Hugin to draft the taglinemakes Quill post arequestinto the nest authored by Quill, addressed to the named member crow,refers_tothe owner's original message — so the existing must-respond loop (respondToRequest) answers it. Quill does not do the work itself. Structured parsing goes throughFlock.ask(one narrow call returning JSON:{"crow": "...", "task": "..."}or{"crow": ""}), never a direct brain call.Acceptance criteria — falsifiable tests
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 withauthor: "Quill",kind: "request",to: "Hugin",refers_to: <owner msg_id>; then Hugin'sdeliverfollows (full loop). Red now: no relay path exists.TestQuillRelayUnknownCrowStalls— Given brain answers{"crow":"Soot",...}and Soot is not a nest member, then norequestfrom Quill exists in the nest; Quill posts asaynaming the crow it could not find (assert one Quill message with kindsay, zero kindrequest).TestQuillRelayNotAnsweredTwice— In criterion 1's run, Quill posts exactly two messages total (the parsed relay is its only speech; no separate Quilldeliveranswering the task itself).TestQuillRelayGoesThroughFlock— With the flock saturated (MaxCrowsInFlight0 slots free) and a 50ms context, the relay call returns without posting any Quill message (guardrail honored; usesFlock.reservebehavior from #28).Test command
go test -race -count=1 -run 'TestQuillRelay' .Blockers / unknowns
EVENTS.md first: document the relay shape (Quill-authored
requestwithrefers_toset to the owner message) in the kind table note. Decide nothing new aboutrelayedflags —refers_to+ author is enough.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'sexactly one model callassertion true. Criterion 3 now asserts Quill posts exactly ONE message on a successful relay (kind request) and zero delivers.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: