Darkwing's round 2 candidate, approved by Filbert (#1518 comment 26730).
build-r2.patch a27890d5, manifest 869168c7, 34 files, applied on HEAD and
checked 34/34. Integration gate on an export of HEAD plus the patch:
business 60/60 on Node 24 and 26, every package test and every
scripts/test-*.sh green, test-task 98/98 with the live-provider cases.
Conductor, queue, conversation and discord confirmed in git worktrees of
HEAD with and without the patch, identical results. Lead decision 63
accepts the vocabulary location, the example path and the business
branch.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
Role contracts (roles/<role>.json): roleVersion, name bound to filename,
tools ceiling (subset of pi built-ins), network declared (none|api-only|
open; enforced when network policy lands). Strict schema, fail closed -
a non-role document refuses resolution.
mosaic-task.mjs resolve-role: config-free contract validation, emits
MOSAIC_ROLE_TOOLS / MOSAIC_ROLE_NETWORK.
agent.sh: a declared role binds to its contract. Missing/invalid contract
refuses the launch (exit 2, names the role - the under-equipped-seat
failure mode, mirroring M17 skills). Effective tools = ceiling ∩ requested
(CLI --tools or agent.json caps); no request -> ceiling stands; narrowing
and tool-free outcomes loud on stderr. Adapters unchanged; headless M9
chain (mission ∩ task) untouched.
Ships roles/researcher.json (existing seat declares the role; without the
contract the fail-closed gate would refuse its launch).
Task suite 74 -> 88: contract resolution, wrong-kind/name/network/
duplicate/unsupported/missing refusals, ceiling narrowing E2E (mock
adapter), tool-free E2E, missing-contract refusal. Test-authoring
correction recorded in BUILD-LOG (a check that registered on one path
only, caught by count arithmetic).
Suites 24/88/14/17 + verify green.
Owner direction: the repository root holds first-class, bootstrap-required
configuration only. conductor-policy.json is a ROLE contract (the
conductor's authority), one of scores of future role contracts
(agent-policy, coder-policy, ...) - such files get a dedicated home.
- roles/conductor-policy.json (git mv)
- conductor-apply.sh + test-conductor.sh read the new path
- CONDUCTOR.md records the roles/ convention
Closes UX follow-up from owner layout review; no issue (convention change).