ci/woodpecker/pr/ci Pipeline failed
Ratifies the Mosaic Stack PRD rev1 (Jason Woltje, 2026-09-01) as project source of truth and installs the GOV.1 lifecycle model: - docs/PRD.md becomes a permanent shim (kind: shim, current_rev -> docs/PRDs/2026-08-31_PRD_rev1/). Its path never changes again. - docs/PRDs/2026-08-26_PRD_rev0/PRD.md archives the 2026-08-26 North Star verbatim (sha256 60cc2f98...36afdf unchanged). Archive, never delete. - docs/PRDs/2026-08-31_PRD_rev1/ is the frozen rev1 bundle: 18 sectioned documents (VIS, DATA, AUTHN, AUTHZ, SEAT, ROLE, HARN, PROV, SESS, UI, CLI, GOV.1-5) consolidating rev0 D1-D15, the fleet north star, the agent-runtime L1/L2 contracts and the control-plane-surfaces lane findings, with a single decision map (GOV.3) and a closed open-questions frontier (GOV.5, grill rounds 1-8). Drafting inputs (_source-* snapshots) are not shipped. Consequences of the ratified rulings carried in the same change: - Q-T1 (ruling B, "shipped but frozen"): D3 amended in GOV.3/VIS.1; federation M1-M3 acknowledged as shipped behind tier === 'federated', excluded from the v1 bar and frozen, with a security re-audit gate before any resumption. docs/MISSION-MANIFEST.md, docs/federation/MISSION-MANIFEST.md and docs/scratchpads/mvp-20260312.md get status: superseded + banners (content preserved verbatim); docs/guides/deployment.md gains a "Relationship to the PRD (D15)" section. NORTH_STAR.yaml adds dormant workstream M (projects no goals by design); NORTH_STAR.md regenerated. - Q-G2 (distinct registry prefixes): every citation of the operator DECISION-REGISTER in the bundle reads OD-nn; the stack registry stays D1-D15; L1-Dnn/L2-Dnn untouched. Prefix rule recorded in GOV.1. Follow-ups (not in this PR): CI parity drift-gate witness (Q-C1); brain-side DECISION-REGISTER rename to OD- with redirect table on its next touch.
146 lines
7.3 KiB
Markdown
146 lines
7.3 KiB
Markdown
---
|
||
id: AUTHZ.1
|
||
status: ratified
|
||
ratified: 2026-09-01 (Jason Woltje; PRD rev1 ratification PR)
|
||
---
|
||
|
||
# AUTHZ.1 — Capability authority, enforcement, and accepted risk
|
||
|
||
The agent-side authority model: what binds a seat, where it is enforced, what
|
||
is closed by construction, and what is accepted as residual risk. Sources: the
|
||
L2 authorization contracts, `mosaic-core` (measured 2026-08-31), and the lane's
|
||
`AUTHORIZATION-GAPS.md`.
|
||
|
||
## Glossary
|
||
|
||
**Privilege escapation** *(Jason, 2026-08-31)* — the outcome class in which an
|
||
agent exercises authority it was never granted, regardless of mechanism.
|
||
Deliberately collapses escalation and misdirection: the outcome is identical;
|
||
the distinction matters only when choosing a control.
|
||
|
||
## Authority composition is pure intersection
|
||
|
||
```
|
||
role capability ceiling
|
||
∩ assignment scope ∩ lease scope ∩ workflow state
|
||
∩ target policy ∩ trusted backend availability
|
||
= effective capability grant
|
||
```
|
||
|
||
No operation adds capability. Only an authenticated principal with
|
||
role-management authority may create, edit, activate, bind, or roll back roles
|
||
(L2-D13); agents cannot, ever. Orchestrators cannot deploy seats at all —
|
||
coordination goes through `mosaic coord` requests to the coordinator service
|
||
(register OD-08/OD-09). Cycle detection is unnecessary because no grant edge
|
||
exists.
|
||
|
||
## Enforcement point: `mosaic-core`
|
||
|
||
A tracked, non-npm Pi extension loaded via role-scoped settings. Per seat, per
|
||
launch: trusted-path manifest load
|
||
(`<brainHome>/fleet/roles/<role>/mosaic-core.manifest.json` — committed,
|
||
non-symlink, role cross-checked), fail-closed state machine
|
||
(`not-applied | applied | fail-closed`), exact active-tool reconciliation,
|
||
per-call interception with read containment (canonicalization + realpath +
|
||
credential-path deny), per-incarnation append-only journal. Capabilities C1–C8
|
||
are the authority; tools are their bound projections; `tools[]` must equal the
|
||
bound bindings exactly. The capability map is closed and hardcoded in the
|
||
canary phase (gap G7 — by design for now; L2-D21 is the end state).
|
||
|
||
## The firewall rules
|
||
|
||
1. **Agents never reach role-management surfaces** (L2-D13). A seat that can
|
||
invoke role management can self-grant, voiding the model.
|
||
2. **The coordinator is a service, never a seat** (gap G4; register OD-08). A
|
||
coordinator-as-seat turns the intersection chain into a cycle.
|
||
|
||
## Closed vs accepted
|
||
|
||
**Closed by construction: escalation.** The intersection chain admits no
|
||
capability-adding edge.
|
||
|
||
**Accepted within reason: misdirection.** A rogue or colluding orchestrator can
|
||
still *route work* to a seat that already legitimately holds a capability. The
|
||
authority is genuine, so no structural control can refuse it. Jason's ruling:
|
||
escalation and misdirection are tiered **by outcome — identically**; locking
|
||
down far enough to mechanically prevent misdirection cripples the system to
|
||
inoperability. Mitigation posture: **audit and visibility, not prevention** —
|
||
see the audit surface in [[UI.1-webui-surfaces]] and gap G3 below.
|
||
|
||
## Role separation as the working mitigation
|
||
|
||
Design intent (not yet enforced by any manifest — gap C3 in the lane ledger):
|
||
|
||
| Role | Must NOT |
|
||
|---|---|
|
||
| coding agent | create remote git repositories |
|
||
| gate agent | code |
|
||
| review agent | code |
|
||
| interact agent | code, create remote repositories |
|
||
|
||
Breaking the monopoly means no single seat holds an exit path; escape requires
|
||
inter-seat coordination, which is exactly what the audit exists to catch.
|
||
Register OD-25–OD-34 (review/gate/arena families, independence rules) carry the
|
||
role taxonomy this matrix projects onto.
|
||
|
||
## Gap register (measured 2026-08-31)
|
||
|
||
| ID | Gap | Status |
|
||
|---|---|---|
|
||
| G1 | No least-privilege language anywhere in L1/L2/NORTH-STAR (grep-verified) | **L2-D52 amendment drafted** |
|
||
| G2 | Assignment issuance criteria unspecified (renewal names criteria; issuance does not) — full-ceiling requests validate cleanly | **L2-D52 amendment drafted** |
|
||
| G3 | No misdirection audit exists — no tooling, agent, or surface | open → [[UI.1-webui-surfaces]] §Audit |
|
||
| G4 | Coordinator-as-seat would collapse the model | firewall — never violate |
|
||
| G5 | Seat config mixes authority classes (role binding beside a model dropdown) | open → [[SEAT.1-seat-profile]] |
|
||
| G6 | `role-harness-config/DESIGN.md` scope defect (unstated surface) | fix drafted (amendment in `proposed/docs/`) |
|
||
| G7 | Capability map closed/hardcoded | by design (canary phase) |
|
||
|
||
Amendments staged in `proposed/docs/` per the lane convention; ledger items
|
||
A3/A4 track ratification. The auditor-identity question (an auditor agent is
|
||
itself a seat, itself subject to misdirection) is on the grill:
|
||
[[GOV.5-open-questions]] Q-A1.
|
||
## E2 inputs (triage 2026-08-31; see [[GOV.2-docs-inventory]])
|
||
|
||
**Canonical ground truth**: `DEVELOPER-GUIDE/architecture/mutator-class-gate.md`
|
||
(the default-deny whole-class gate this section's language must match),
|
||
`lease-broker-protocol.md` + `lease-broker-security.md` (incl. the named
|
||
promote-lease-lost-ACK residual), `ADMIN-GUIDE/security/discord-ingress.md`
|
||
(the one implemented admission/role model).
|
||
**Pending pulls**: DRAFT S2 `rbac-grant-model.md` (granular RBAC per rev0 §4).
|
||
|
||
## S2 contract feed (extraction 2026-08-31)
|
||
|
||
Full extraction record: lane `S2-EXTRACTION-2026-08-31.md` (per-contract cores, dependency edges, ruling cross-checks). Pulls binding on this section:
|
||
|
||
- **Three-layer authority (contract 2)**: platform role (member/admin,
|
||
instance administration only, **no implicit tenant access** — two live admin
|
||
bypass paths named non-conformant and scheduled for retirement:
|
||
`command-authorization.service.ts` admin short-circuit, `mcp.service.ts`
|
||
scope derivation); hierarchy grants (viewer/member/owner, deny-by-default,
|
||
down-chain, effective = max, live fail-closed); workspace membership
|
||
(its own mechanism, REQ-ID-001). The layers are non-substitutable.
|
||
- **Agents are not a valid grant subject** — grant subject is exactly-one-of
|
||
user_id/team_id. Structural enforcement of the agents-never-reach-role-
|
||
surfaces ruling, stronger than policy.
|
||
- **Consent ≠ authorization (contract 7 §5.7)**: consent records govern
|
||
agentic/feature data access, are distinct from hierarchy grants, and confer
|
||
no platform authorization; default-deny with **no platform-admin bypass**;
|
||
consent mutation is subject-only (admins refused at write time).
|
||
- **Bounded revocation propagation**: next authz decision denies; open
|
||
Socket.IO connections re-evaluated within 30s or next inbound message.
|
||
- **company-CRUD capability**: platform-scoped, admin-assigned, audited
|
||
delegation of exactly one visibility-mutation command (`platform_capabilities`
|
||
table) — the model's template for narrow capability delegation.
|
||
- **Membership locality + no-existence-oracle (contract 8 §3)**:
|
||
member-readable workspaces contribute only at their own node, never promoted
|
||
upward; unreadable vs nonexistent are byte-equivalent.
|
||
|
||
## Audit implementation ruling (Q-A1/Q-A2, Jason 2026-09-01)
|
||
|
||
The authorization audit is **mechanical tooling**: deterministic checks over
|
||
the grant/assignment record, witness-style (the S2 writer-coverage pattern),
|
||
feeding the audit page read-only. Agents may consume audit output but never
|
||
produce the verdict — prompt adherence is not an enforcement mechanism. Q-A2
|
||
(who audits the auditor) dissolves: the auditor is code, audited by ordinary
|
||
review and CI.
|