Files
stack/docs/PRDs/2026-08-31_PRD_rev1/CLI.1-parity.md
T
jason.woltje ad21ad7ac5
ci/woodpecker/pr/ci Pipeline failed
docs: ratify PRD rev1 — consolidated bundle, permanent shim, rev0 archived
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.
2026-09-01 18:32:14 -05:00

158 lines
10 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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.