Epic: #37. Depends on: none (but merge after Epic D's Quill task to share the service-role diff)
Goal
Boss is a persona and service role. Asked to "spin up a crow", it returns a structured instruction via Flock.ask ({"name":"Ash","persona":"Soot","trust":"stranger"}) and the harness creates the crow in a dynamic crow registry (new JSON store in .crows/crows.json, pattern: nests.go), enforcing MaxSpunCrows in guardrails. Registry crows have name + backing persona + starting trust and are assignable to nests.
Acceptance criteria — falsifiable tests
TestBossSpinUpCreatesCrow (boss_test.go) — Given scripted brain returning {"name":"Ash","persona":"Soot","trust":"stranger"}, when owner posts @Boss spin up a crow named Ash, then registry contains Ash (GET /api/crows returns it: name Ash, persona Soot, level stranger), and a Boss say/deliver announces it in the nest. Red now: no registry, no Boss role.
TestSpinUpCapRefused — With MaxSpunCrows already reached, the next spin-up adds nothing to the registry and Boss posts a say naming the cap; no 500, no silent drop.
TestSpinUpDuplicateNameRefused — Spinning up a name that exists in personas.go roster or the registry is refused the same way (cap message shape).
TestSpinUpTrustGated — Registry crow with starting trust trusted is clamped to regular (guardrail: earned trust can't be minted; assert ledger level ≤ Regular).
TestSpinUpGoesThroughFlock — saturated flock + short ctx: no registry write, no Boss message (pattern: TestQuillRelayGoesThroughFlock / #28).
./crows personas regenerated: PERSONAS.md gets the Boss section committed; EVENTS.md documents GET /api/crows row first.
Test command
go test -race -count=1 -run 'TestBoss|TestSpinUp' .
Blockers / unknowns
Persona template for a spun crow = existing persona's policy (Soot's "grumpy retriever"), never new lore; guardrails apply identically to the persona crow.
Epic: #37. Depends on: none (but merge after Epic D's Quill task to share the service-role diff)
## Goal
Boss is a persona and service role. Asked to "spin up a crow", it returns a structured instruction via `Flock.ask` (`{"name":"Ash","persona":"Soot","trust":"stranger"}`) and the harness creates the crow in a **dynamic crow registry** (new JSON store in `.crows/crows.json`, pattern: `nests.go`), enforcing `MaxSpunCrows` in guardrails. Registry crows have name + backing persona + starting trust and are assignable to nests.
## Acceptance criteria — falsifiable tests
1. `TestBossSpinUpCreatesCrow` (`boss_test.go`) — Given scripted brain returning `{"name":"Ash","persona":"Soot","trust":"stranger"}`, when owner posts `@Boss spin up a crow named Ash`, then registry contains Ash (GET `/api/crows` returns it: name Ash, persona Soot, level stranger), and a Boss `say`/`deliver` announces it in the nest. Red now: no registry, no Boss role.
2. `TestSpinUpCapRefused` — With `MaxSpunCrows` already reached, the next spin-up adds nothing to the registry and Boss posts a `say` naming the cap; no 500, no silent drop.
3. `TestSpinUpDuplicateNameRefused` — Spinning up a name that exists in `personas.go` roster or the registry is refused the same way (cap message shape).
4. `TestSpinUpTrustGated` — Registry crow with starting trust `trusted` is clamped to `regular` (guardrail: earned trust can't be minted; assert ledger level ≤ Regular).
5. `TestSpinUpGoesThroughFlock` — saturated flock + short ctx: no registry write, no Boss message (pattern: `TestQuillRelayGoesThroughFlock` / #28).
6. `./crows personas` regenerated: PERSONAS.md gets the Boss section committed; EVENTS.md documents `GET /api/crows` row first.
## Test command
`go test -race -count=1 -run 'TestBoss|TestSpinUp' .`
## Blockers / unknowns
Persona template for a spun crow = existing persona's policy (Soot's "grumpy retriever"), never new lore; guardrails apply identically to the persona crow.
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: #37. Depends on: none (but merge after Epic D's Quill task to share the service-role diff)
Goal
Boss is a persona and service role. Asked to "spin up a crow", it returns a structured instruction via
Flock.ask({"name":"Ash","persona":"Soot","trust":"stranger"}) and the harness creates the crow in a dynamic crow registry (new JSON store in.crows/crows.json, pattern:nests.go), enforcingMaxSpunCrowsin guardrails. Registry crows have name + backing persona + starting trust and are assignable to nests.Acceptance criteria — falsifiable tests
TestBossSpinUpCreatesCrow(boss_test.go) — Given scripted brain returning{"name":"Ash","persona":"Soot","trust":"stranger"}, when owner posts@Boss spin up a crow named Ash, then registry contains Ash (GET/api/crowsreturns it: name Ash, persona Soot, level stranger), and a Bosssay/deliverannounces it in the nest. Red now: no registry, no Boss role.TestSpinUpCapRefused— WithMaxSpunCrowsalready reached, the next spin-up adds nothing to the registry and Boss posts asaynaming the cap; no 500, no silent drop.TestSpinUpDuplicateNameRefused— Spinning up a name that exists inpersonas.goroster or the registry is refused the same way (cap message shape).TestSpinUpTrustGated— Registry crow with starting trusttrustedis clamped toregular(guardrail: earned trust can't be minted; assert ledger level ≤ Regular).TestSpinUpGoesThroughFlock— saturated flock + short ctx: no registry write, no Boss message (pattern:TestQuillRelayGoesThroughFlock/ #28)../crows personasregenerated: PERSONAS.md gets the Boss section committed; EVENTS.md documentsGET /api/crowsrow first.Test command
go test -race -count=1 -run 'TestBoss|TestSpinUp' .Blockers / unknowns
Persona template for a spun crow = existing persona's policy (Soot's "grumpy retriever"), never new lore; guardrails apply identically to the persona crow.