docs: ratify PRD rev1 — consolidated bundle, permanent shim, rev0 archived
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.
This commit is contained in:
2026-09-01 18:32:14 -05:00
parent 9aa4983cf2
commit ad21ad7ac5
26 changed files with 3644 additions and 927 deletions
@@ -0,0 +1,157 @@
---
id: CLI.1
status: ratified
ratified: 2026-09-01 (Jason Woltje; PRD rev1 ratification PR)
---
# CLI.1 — CLI surface and parity obligation
## The rule
The CLI is the **primary execution method** (D8); the WebUI operates the same
tooling over the Gateway API and never bypasses it (D12). Register OD-49 fixes
`mosaic config` as the stable installation-configuration command family backed
by one desired-state engine; register OD-53 makes every interface (CLI, TUI,
WebUI, API, automation) a client of that same engine.
Parity is therefore **structural, not aspirational**: a capability that exists
in the CLI without a WebUI surface is an incomplete projection; a WebUI wish
with no backing tool is **"blocked on tooling"** and the tool is built first
(D8 consequence). Neither side ever grows private logic.
## Parity matrix obligation
The ratified bundle must carry (or cite, per D8's baseline inputs) three
artifacts, kept current:
1. **Tool inventory** — what official tooling exists and what is missing.
2. **WebUI→tool mapping** — every page control mapped to the tool it calls
([[UI.1-webui-surfaces]] page inventory is the row source).
3. **Measured `next`-branch state** — what actually works today.
All three artifacts were measured 2026-08-31 against `origin/next` commit
`9aa4983c` and appear below. Grill: [[GOV.5-open-questions]] Q-C1 (matrix
freshness ownership after ratification).
## Artifact 1 — tool inventory (measured, `origin/next` @ `9aa4983c`)
Registration root: `packages/mosaic/src/cli.ts` (commander); command modules
under `packages/mosaic/src/commands/`; `coord`/`prdy`/`doctor`/runtime
launchers dispatch to bash tools under `packages/mosaic/framework/tools/`
(subcommand tables at `commands/launch.ts:11511255`); sibling packages
(`brain`, `forge`, `macp`, `quality-rails`, `log`, `memory`, `queue`,
`storage`) register their own families.
Control-plane-relevant families, by rev1 domain:
| Domain | Families (measured) |
|---|---|
| SEAT | `fleet` (init/install/systemd/lifecycle/roster/add/remove/verify/ps), `fleet` roster-v2 CRUD (`get/plan/create/update/delete`), `fleet apply`/`reconcile`/`doctor`/`regen`, `fleet provision`, `fleet migrate-v1 preview`, `agent` (configs + enroll + nested fleet-agent commands), `promote`, `comms send` |
| ROLE | `fleet persona` (`list/show/customize` — baseline ⊕ `roles.local/` overrides), `fleet profile` (`list/show` topology templates) |
| HARN | `config` (framework config + hooks), `compose-contract <harness>`, `skill`, `seq`, `init`/`sync`/`bootstrap`, `doctor`, runtime launchers (`claude`/`codex`/`opencode`/`pi`, experimental `claudex`, `yolo`) |
| PROV | `gateway config` (raw provider API-key env vars only), `wizard` (setup-time provider config) |
| AUTHN | `login`, `auth users {list,create,delete}`, `auth sso {list,test}` (stubbed — see gaps), `auth sessions list` (stubbed), `gateway` token lifecycle (`config rotate-token/recover-token`) |
| SESS | `tui`, `sessions {list,resume,destroy}`, `interaction` (durable-session surface: enroll/attach/send/chat/stop/recover), `coord`, `watch`, `mission` |
| Governance/other | `prdy {init,update,validate,status}`, `federation {grant,peer}`, `macp tasks gate`, `telemetry`, `upgrade`/`update`/`restore`/`uninstall`, `q`, sibling-package families |
Notable structural facts: there is **no top-level `mosaic role` verb** — role
management lives at `fleet persona`, three levels deep; and `doctor`/`status`
exist twice (top-level framework-scoped vs `fleet`-scoped), shadowing by name.
## Artifact 2 + 3 — WebUI→tool mapping with measured state
Rows are the [[UI.1-webui-surfaces]] page domains; measured against
`apps/web/src/spa/pages/` and the gateway controllers on the same commit.
| Surface function | WebUI today | CLI today | Parity state |
|---|---|---|---|
| Seat lifecycle & roster (SEAT) | **no Seats page** (routes are only /admin, /settings, /projects, /tasks, /chat) | complete (`fleet`/`agent` families) | CLI-ahead — page is D2's work, tooling exists |
| Role/persona config (ROLE) | no page | `fleet persona` | CLI-ahead; naming mismatch: no `mosaic role` verb for the ROLE page to mirror |
| User role/ban (AUTHN) | admin UsersTab toggles role/ban via admin endpoints directly | `auth users` lacks `set-role`/`ban`/`unban` | **WebUI-only mutation — violates the D12 rule as implemented** |
| SSO admin (AUTHN) | SsoProviderSection reads *public* `/api/sso/providers` discovery | `auth sso list/test` stubbed: "admin endpoint missing" | **blocked on gateway tooling**; CLI and WebUI don't even hit the same surface |
| Auth-session admin (AUTHN) | — | `auth sessions list` stubbed (no server endpoint) | blocked on gateway tooling |
| Provider list/test (PROV) | settings ProvidersTab: `GET /api/providers`, `POST /api/providers/test` | none — only `gateway config` raw env-var writes | **WebUI-only read/test — no `mosaic provider` family exists** |
| Default harness/provider/model selection (HARN/SESS) | `GET/PUT /api/chat/preferences/selection` per user | none persists the stored preference (`tui --model` is per-session only) | WebUI-only mutation |
| Authorization hierarchy & grants (UI-audit) | **no page** | **no command** | **the largest D12 gap**: `hierarchy.controller.ts` exposes full CRUD (companies, estates, platform-projects, grants incl. `grants/:id/change`) with audit repository and grant evaluation behind it — reachable only by raw API |
| Federation grants/peers | no page | `federation grant/peer` | CLI-ahead (posture pending Q-T1) |
**Consequences for the build order** (D8: tool first, then surface):
`mosaic provider {list,test}`, `auth users {set-role,ban,unban}`, a stored
harness-selection command, the missing gateway admin endpoints for SSO/session
listing, and a CLI face for the hierarchy/grant surface all precede their
pages. The two **WebUI-only mutations** (role/ban toggle, harness selection)
are standing D12 violations to remediate, not precedents to extend. The
hierarchy CRUD surface is the natural backing for [[UI.1-webui-surfaces]]'s
authorization audit page — but it must get a CLI face and an audit read-path
before the page ships.
## Command families in scope for the control plane
`mosaic config` (OD-49 desired-state engine), `mosaic coord` (agent coordination
boundary — register OD-09), `mosaic prdy` (PRD creation/acceptance — register
OD-22), role management (one canonical API, L2-D14), seat lifecycle
(launch/relaunch per register OD-59), `mosaic doctor` (drift detection classes,
e.g. the #1194 framework-tool drift addendum in [[GOV.4-workstream-contracts]]).
## `mosaic config` v1 subset (pulled 2026-08-31 from the minimal-subset spec)
The Q14 ruling (2026-08-29) fixes the current scope: shipped surface
`edit/get/set/show/hooks/path` **plus exactly two new read-only verbs**
`mosaic config validate` and `mosaic config plan` (`--file` | `--preset`,
mutually exclusive; `--format table|json`). `apply`, `add`, `restructure`,
`migrate`, `remove`, `export` are **out of v1 pending a full-engine ruling**
([[GOV.5-open-questions]] Q-D5) — the configuration-lifecycle draft's "stable
namespace" table describing the full family is aspirational, not current state.
Contract highlights: **valid** vs **conformant** are distinct verdicts with
distinct exit codes (nonconformance is a diagnostic, not a parser failure);
`plan` emits `create|update|blocked` operations with risk classes
(`none|review-required|full-engine-required`), a SHA-256 `planId`, and
`applySupported: false` always in v1; destructive/unsupported drift is
`blocked`, never silently normalized; absolute no-mutation during
validate/plan (no writes, no network, no credential calls); results ride the
T78 `CapabilityResultV1` envelope (capability IDs
`config.installation.validate`/`.plan`); inputs capped, YAML
aliases/anchors/tags rejected, no secret-shaped fields accepted or echoed.
## E2 inputs (triage 2026-08-31; see [[GOV.2-docs-inventory]])
**Canonical ground truth**: `requirements/cli-capability-migration.md` (T78,
`source_of_truth: true`), `fleet/reference/cli.md` (local fleet CLI vs
gateway-backed catalog), `USER-GUIDE/getting-started/quickstart.md`.
**Pending pulls**: DRAFT S2 `tool-gateway-mapping.md`; brain
`docs/specs/2026-08-29_mosaic-config-minimal-subset.md` (`mosaic config
validate/plan`, cites OD-49OD-55) and
`docs/guides/proposed/workflows/configuration-lifecycle.md` (the OD-49 engine
family definition).
## 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:
- **Contract 5 §4.5 is the parity clause this section's matrix enforces**:
CLI remains the primary execution method for every Gateway command; no
WebUI-only command exists; a Gateway command without CLI exposure is a
conformance gap tracked at the family's implementing issue. The
hierarchy/grants CRUD gap measured in this section is exactly such a
tracked conformance gap once contract 5 ratifies.
- **Command envelope**: typed request/result DTOs (no `any`), closed
per-family error taxonomy, audit correlation id, fail-closed — aligns with
the T78 `CapabilityResultV1` direction already in this section.
- **Contract 9 (api-artifacts)**: `ApiAuthClass` closed six-value enum
(`none`/`session`/`api-key`/`admin`/`federation`/`bootstrap`); OPENAPI.yaml
generated, CI byte-drift-gated, never hand-edited; hard ordering — nothing
under contract 9 lands before contract 5 (PR #1438) is on the trunk.
- **Roll-up (contract 8)** ships as a query-only tool with no command
counterpart (A5 rank 5) — the taxonomy precedent for read-only surfaces in
the parity matrix.
- **Mandated removals** the CLI inventory must track: `mosaic auth users
delete` (with the hard-delete endpoint) is required to be disabled/removed
by contract 4.
## Parity freshness ruling (Q-C1, Jason 2026-09-01)
The parity matrix becomes a generated artifact with a CI drift-gate witness in
the stack repo (the contract-9 pattern): CI regenerates the tool inventory and
WebUI→tool mapping from code and fails on divergence from the committed
matrix. No human cadence to forget. Building the witness is E6-return
follow-up work.