feat(roles): M18 seat-role progressive capability restriction (#45)
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.
This commit is contained in:
@@ -467,3 +467,35 @@ Release self-determination live: the system aligns itself to RELEASE without man
|
||||
|
||||
The conductor loop is proven end to end on a live seat; TOOLS.md covers the
|
||||
tools/ tree; suites green at every gate.
|
||||
|
||||
## Phase 23: M18 — seat-role progressive capability restriction
|
||||
|
||||
- Role contracts: `roles/<role>.json` — roleVersion, name (must match
|
||||
filename), tools ceiling (subset of pi built-ins), network declared
|
||||
(none | api-only | open; enforcement is a later milestone). Strict
|
||||
schema, fail closed; a non-role document (e.g. conductor-policy.json)
|
||||
refuses.
|
||||
- `mosaic-task.mjs resolve-role <file>`: config-free validation, emits
|
||||
MOSAIC_ROLE_TOOLS / MOSAIC_ROLE_NETWORK for agent.sh to consume.
|
||||
- `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 are loud on stderr.
|
||||
Adapters unchanged (MOSAIC_TOOLS carries the effective set); headless
|
||||
M9 chain (mission ∩ task) untouched.
|
||||
- Ships roles/researcher.json — the existing researcher seat declares the
|
||||
role; without the contract the fail-closed gate would refuse its launch.
|
||||
- Suite additions (14 cases, task suite 74 → 88): contract resolution,
|
||||
wrong-kind/name/network/duplicate/unsupported/missing refusals, seat
|
||||
narrowing E2E via mock adapter, tool-free E2E, missing-contract refusal.
|
||||
- Test-authoring correction: the first version of the missing-contract
|
||||
case registered its check only on the failure path (a `|| RC=$?` chain
|
||||
swallowed it on success); caught by count arithmetic (74 + 15 ≠ 88),
|
||||
restructured so the case always registers.
|
||||
|
||||
## Result (M18)
|
||||
|
||||
Seat roles are ceilings, not labels: the M15 role field now resolves to a
|
||||
versioned contract that seats cannot escalate past. Suites 24/88/14/17 +
|
||||
verify green.
|
||||
|
||||
Reference in New Issue
Block a user