diff --git a/docs/PRD.md b/docs/PRD.md index 1d05add0..36965619 100644 --- a/docs/PRD.md +++ b/docs/PRD.md @@ -886,7 +886,7 @@ The canonical dispatcher/control-plane vertical slice (work graph, execution att ## Official CLI Capability and Tool Migration Workstream (T78) Normative contract on integration trunk `next`: -[docs/requirements/cli-capability-migration.md](./requirements/cli-capability-migration.md) — +[docs/requirements/cli-capability-migration.md](./requirements/cli-capability-migration.md): migrates agent-facing operations from directly invoked scripts into documented, first-class `mosaic` CLI command groups, together with the central-registry resolver, capability catalog, adapter boundary, and phased legacy-tool-tree decommission the migration requires. The contract diff --git a/docs/SITEMAP.md b/docs/SITEMAP.md index 925f52b1..13b1345a 100644 --- a/docs/SITEMAP.md +++ b/docs/SITEMAP.md @@ -18,7 +18,7 @@ - [Active task rollup](TASKS.md) — orchestrator-owned work state; workers do not modify it. - [MVP mission manifest](MISSION-MANIFEST.md) — control-plane mission rollup; activity and status remain under its authorized owner. - [Documentation catalog and truth audit](reports/documentation/2026-08-10-docs-catalog-audit.md) — complete baseline inventory, evidence labels, broken-link clusters, and migration recommendations. -- [CLI capability migration requirements](requirements/cli-capability-migration.md) — T78 official CLI capability and tool migration contract; normative contract with implementation hold (M0). +- [CLI capability migration requirements](requirements/cli-capability-migration.md): T78 official CLI capability and tool migration contract, normative contract with implementation hold (M0). ## Protected current authority and executable books diff --git a/docs/requirements/cli-capability-migration.md b/docs/requirements/cli-capability-migration.md index 2af2956c..a12c0134 100644 --- a/docs/requirements/cli-capability-migration.md +++ b/docs/requirements/cli-capability-migration.md @@ -7,12 +7,12 @@ source_of_truth: true # Official Mosaic CLI Capability and Tool Migration - **Workstream:** T78 -- **Status:** active requirements contract; implementation held by the M0 gates +- **Status:** active requirements contract, implementation held by the M0 gates - **Decision authority:** Jason Woltje - **Design owner:** Vision - **Integration trunk:** `next` -This contract is authoritative only on the integration trunk `next`; branch copies are proposals. +This contract is authoritative only on the integration trunk `next`. Branch copies are proposals. Publication does not authorize implementation until the M0 milestone, task-graph, interface, and partition gates pass. @@ -149,10 +149,10 @@ downgrade the execution boundary. `git.issue.comment` reads its body from `--input ` or stdin with `--input -`. The CLI MUST: -1. reject a missing or empty body; -2. apply a documented byte limit before provider access; -3. never place the body in process arguments, diagnostics, or audit metadata; -4. compute a body digest for read-back verification without exposing the body; +1. reject a missing or empty body. +2. apply a documented byte limit before provider access. +3. never place the body in process arguments, diagnostics, or audit metadata. +4. compute a body digest for read-back verification without exposing the body. 5. avoid automatic retry after an uncertain provider mutation. ### CLI-REQ-005: Structured result envelope @@ -206,12 +206,12 @@ mutation retry. The capability catalog generates or validates: -- `mosaic --help` command-group listing; -- group and command help; -- stable capability identifiers; -- machine-readable capability discovery; -- documentation tables; -- policy-generation inputs; +- `mosaic --help` command-group listing. +- group and command help. +- stable capability identifiers. +- machine-readable capability discovery. +- documentation tables. +- policy-generation inputs. - tests that reject undocumented public commands and orphaned capabilities. ## 7. Central registry resolver @@ -228,13 +228,13 @@ content and remains a separate concern. The resolver consumes schema v1 from issue `#1382` without creating parallel keys. Every key is optional. The exact v1 surface is: -- `$schema`, with the known marker `mosaic-config-v1`; -- `mosaicHome`, reserved, null, and without a v1 consumer; -- `brainHome`, default `~/.mosaic`; -- `instances.gitea..url`; -- `fleet.socket`; -- `harnessConfig.pi.agentDir`; -- `harnessConfig.claude.configDir`; +- `$schema`, with the known marker `mosaic-config-v1`. +- `mosaicHome`, reserved, null, and without a v1 consumer. +- `brainHome`, default `~/.mosaic`. +- `instances.gitea..url`. +- `fleet.socket`. +- `harnessConfig.pi.agentDir`. +- `harnessConfig.claude.configDir`. - `harnessConfig.claude.secureStorageDir`. Credential values, model and effort defaults, and `fleet.rosterPath` are forbidden. A non-null @@ -257,8 +257,8 @@ commands backed by `ConfigService`. For each supported value, resolution follows exactly: -1. the schema-defined `MOSAIC__OVERRIDE` environment override; -2. validated `config.json` value; +1. the schema-defined `MOSAIC__OVERRIDE` environment override. +2. validated `config.json` value. 3. one centralized framework default, when the key defines a default. A present override always wins. An empty or invalid override fails and does not fall through to the @@ -317,11 +317,11 @@ names outside the resolver and its reviewed defaults. A new key requires: -1. a named consumer; -2. a `#1382` schema amendment; +1. a named consumer. +2. a `#1382` schema amendment. 3. joint ACK from the frozen-schema and resolver-contract custodians until handoff, recorded by - custodian-authored commits rather than relayed tokens alone; -4. parser, invalid-input, default, and two-root tests; + custodian-authored commits rather than relayed tokens alone. +4. parser, invalid-input, default, and two-root tests. 5. documentation in the same reviewed change. Speculative keys are forbidden. @@ -385,7 +385,7 @@ digest with every decision. Before `mosaicd`, local compatibility mode may evaluate a package-owned policy for behavior and test parity, but it reports locally asserted identity and makes no broker-grade authorization claim. Mode selection is declared by topology and policy, never inferred from broker availability. A missing or -unhealthy required broker returns `unavailable`; it never falls back to local mode. +unhealthy required broker returns `unavailable`. It never falls back to local mode. A capability using a shared, service, operator, or admin credential is broker-only. Local mode may use only the acting seat's own credential against a registry endpoint. Privileged infrastructure, @@ -403,10 +403,10 @@ authorization. `mosaicd` derives or verifies actor identity from the authenticat Every capability test includes: -1. an allowed request with expected result; -2. a denied request differing only in the relevant lane or scope; -3. a malformed target or configuration denial; -4. a credential-redaction assertion; +1. an allowed request with expected result. +2. a denied request differing only in the relevant lane or scope. +3. a malformed target or configuration denial. +4. a credential-redaction assertion. 5. a verdict-discrimination control that proves the test can fail. ## 9. Adapter and broker contract @@ -438,7 +438,7 @@ validation, and mutation uncertainty. It reports `executionMode: local-adapter` Private child adapters receive bodies and credentials only through stdin, owner-only temporary files, or inherited file descriptors, never child-process arguments. Captured child stderr, shell trace, and diagnostics are inside the redaction boundary. Local results always use -`audit: { authority: 'none', recorded: false }`; a local event identifier is not authoritative +`audit: { authority: 'none', recorded: false }`. A local event identifier is not authoritative audit evidence. The local adapter is compatibility, not a sandbox or authorization claim. @@ -449,12 +449,12 @@ The broker adapter sends the same logical request to `mosaicd` outside the seat `mosaicd` owns: - authoritative seat identity, recorded in audit from the derived runtime identity rather than - `actorHint`; -- capability and scope authorization; -- credential resolution; -- operation execution; -- output sanitization; -- audit persistence; + `actorHint`. +- capability and scope authorization. +- credential resolution. +- operation execution. +- output sanitization. +- audit persistence. - bounded timeout and cancellation behavior. A contradictory `actorHint` produces a diagnostic and never replaces the derived actor. Broker @@ -469,10 +469,10 @@ registry contract. No command hard-codes a daemon socket. The initial TypeScript layout is: -- `packages/mosaic/src/central-registry/` for `MosaicRegistryResolver`, schema, and provenance; -- `packages/mosaic/src/capabilities/` for catalog, request, result, policy interfaces, and tests; -- `packages/mosaic/src/capabilities/adapters/local/` for temporary local adapter modules; -- `packages/mosaic/src/capabilities/adapters/mosaicd/` for the broker client seam; +- `packages/mosaic/src/central-registry/` for `MosaicRegistryResolver`, schema, and provenance. +- `packages/mosaic/src/capabilities/` for catalog, request, result, policy interfaces, and tests. +- `packages/mosaic/src/capabilities/adapters/local/` for temporary local adapter modules. +- `packages/mosaic/src/capabilities/adapters/mosaicd/` for the broker client seam. - `packages/mosaic/src/commands/git.ts`, with later first-class domain files following the same command pattern. @@ -485,16 +485,16 @@ tree as the final path. The representative seat container has: -- one seat identity; -- rootless execution; -- read-only root filesystem, with explicit bounded writable mounts; -- a read-only internal `~/.config/mosaic/config.json` supplied by topology; -- no host credential tree; -- no shared host or fleet tmux socket; +- one seat identity. +- rootless execution. +- read-only root filesystem, with explicit bounded writable mounts. +- a read-only internal `~/.config/mosaic/config.json` supplied by topology. +- no host credential tree. +- no shared host or fleet tmux socket. - a dedicated per-seat tmux socket only for one named, reviewed temporary adapter with a stated - removal stage; -- no Docker, Podman, or other container-runtime socket; -- no installed legacy tool tree mount; + removal stage. +- no Docker, Podman, or other container-runtime socket. +- no installed legacy tool tree mount. - network access limited to declared capability paths. Container implementation is outside this mission. Contract and compatibility tests are inside it. @@ -529,11 +529,11 @@ security review `e270098` are the M0 evidence. Both reviews found no blocker. Before expanding direct execution from the working tree: -1. fix the `check-helper-drift.sh` environment assignment that suppresses version diagnostics; -2. strip 20 dangling Excalidraw `node_modules` symlinks; -3. add `tools/**/node_modules/` to the brain `.gitignore`; -4. keep the reviewed `package-lock.json` as the reproducible dependency contract; -5. correct the baseline report's misleading path-count headline; +1. fix the `check-helper-drift.sh` environment assignment that suppresses version diagnostics. +2. strip 20 dangling Excalidraw `node_modules` symlinks. +3. add `tools/**/node_modules/` to the brain `.gitignore`. +4. keep the reviewed `package-lock.json` as the reproducible dependency contract. +5. correct the baseline report's misleading path-count headline. 6. move `ci-publish-watch.sh` credential headers from process arguments to curl stdin configuration when that suite is changed. @@ -542,10 +542,10 @@ Before expanding direct execution from the working tree: Runtime code is loaded from reviewed package or installed artifacts, not directly from a mutable multi-writer checkout as the final design. Any transitional direct execution requires: -- a protected-path review rule; -- an accepted digest anchored outside the synced tree in reviewed package metadata or Stack source; -- verification before execution, including every credential-helper invocation; -- a periodic verifier whose mismatch alert reaches a human; +- a protected-path review rule. +- an accepted digest anchored outside the synced tree in reviewed package metadata or Stack source. +- verification before execution, including every credential-helper invocation. +- a periodic verifier whose mismatch alert reaches a human. - a stated removal point. ### SRC-REQ-004: Credential helper integrity @@ -560,13 +560,13 @@ helper into the reviewed runtime installation or another explicitly protected lo Inventory every direct caller of `~/.config/mosaic/tools`, grouped as: -- skills and guides; -- hooks and generated harness configuration; -- systemd units and timers; -- launchers and provisioning; -- tests and CI; -- direct agent commands; -- private tool-to-tool calls; +- skills and guides. +- hooks and generated harness configuration. +- systemd units and timers. +- launchers and provisioning. +- tests and CI. +- direct agent commands. +- private tool-to-tool calls. - production consumers. Each census run creates a fresh randomized planted legacy reference at a unique path and is valid @@ -578,10 +578,10 @@ zero from only one host, is not evidence. Migrate in this order: -1. read-only status, health, list, and view; -2. bounded CI and communications; -3. issue, pull-request, and milestone mutation; -4. credentialed infrastructure; +1. read-only status, health, list, and view. +2. bounded CI and communications. +3. issue, pull-request, and milestone mutation. +4. credentialed infrastructure. 5. merge, deployment, identity, authorization, and secret management. Each wave proves contract parity before consumer cutover. Waves 1 through 3 may use local mode with @@ -605,76 +605,76 @@ Wave 5 cutover is always broker-only and begins only after the M6 `mosaicd` boun Compatibility shims are private and time-bounded. Each shim: -- names its public replacement; -- preserves existing safety behavior; -- emits a machine-detectable deprecation diagnostic without corrupting JSON output; -- has a measured consumer and removal issue; +- names its public replacement. +- preserves existing safety behavior. +- emits a machine-detectable deprecation diagnostic without corrupting JSON output. +- has a measured consumer and removal issue. - cannot be used to add new direct callers. ### MIG-REQ-005: Final removal The installed `~/.config/mosaic/tools` script surface is removed only after: -1. all active consumers use official capabilities; -2. the census reports zero with a firing planted control; -3. Constitution and wrapper-first gates are mechanically enforced by the CLI path; -4. systemd units are regenerated, daemon-reloaded, re-enabled, and behavior-tested; -5. fleet-doctor state is preserved; -6. clean install, upgrade, rollback, and stale-install tests pass; +1. all active consumers use official capabilities. +2. the census reports zero with a firing planted control. +3. Constitution and wrapper-first gates are mechanically enforced by the CLI path. +4. systemd units are regenerated, daemon-reloaded, re-enabled, and behavior-tested. +5. fleet-doctor state is preserved. +6. clean install, upgrade, rollback, and stale-install tests pass. 7. user, admin, developer, API, and migration documentation is current. ## 13. Testing requirements ### TST-REQ-001: Resolver -- exact schema-v1 valid fixture; -- absent, null, exact-v1, and unknown-non-null `$schema` cases; -- unknown top-level and nested key warnings with full-path diagnostics; -- `mosaic registry validate` lint rejection of the same unknown-key fixture; -- invalid URL, path, socket, and type failures; +- exact schema-v1 valid fixture. +- absent, null, exact-v1, and unknown-non-null `$schema` cases. +- unknown top-level and nested key warnings with full-path diagnostics. +- `mosaic registry validate` lint rejection of the same unknown-key fixture. +- invalid URL, path, socket, and type failures. - every precedence branch, including present-empty and present-invalid override denial without - fallback; -- two valid roots; -- container topology with a read-only internal registry and no host registry path; -- no credential value accepted or emitted; + fallback. +- two valid roots. +- container topology with a read-only internal registry and no host registry path. +- no credential value accepted or emitted. - control proving the invalid fixture fails. ### TST-REQ-002: Capability catalog -- command and capability ID uniqueness; -- every public command documented; -- no orphan catalog record; -- parser, policy, help, and docs consume the same definition; -- unauthorized lane and scope denial; -- unknown capability denial; -- topology-selected mode never falls back when the required broker is unavailable; +- command and capability ID uniqueness. +- every public command documented. +- no orphan catalog record. +- parser, policy, help, and docs consume the same definition. +- unauthorized lane and scope denial. +- unknown capability denial. +- topology-selected mode never falls back when the required broker is unavailable. - shared, service, operator, and admin credential classes reject local mode. ### TST-REQ-003: Pilot -- issue list and view against a valid configured instance; -- invalid instance and repository denial; -- comment success with provider response-shape and body-digest confirmation; -- comment denial before provider access; +- issue list and view against a valid configured instance. +- invalid instance and repository denial. +- comment success with provider response-shape and body-digest confirmation. +- comment denial before provider access. - post-request uncertainty without retry, plus provider-native same-key and - `uncertain-no-retry` read-back reconciliation cases; -- credential, cookie, token, comment-body, child-argv, captured-stderr, and shell-trace redaction; -- local results prove `identityTrust: local-asserted` and `audit.recorded: false`; + `uncertain-no-retry` read-back reconciliation cases. +- credential, cookie, token, comment-body, child-argv, captured-stderr, and shell-trace redaction. +- local results prove `identityTrust: local-asserted` and `audit.recorded: false`. - broker-stub results prove derived-identity precedence and reject unconfirmed - `audit.recorded: true`; -- user-editable endpoint changes cannot redirect a shared or service credential; -- local-adapter and broker-stub request/result seam parity at M3; + `audit.recorded: true`. +- user-editable endpoint changes cannot redirect a shared or service credential. +- local-adapter and broker-stub request/result seam parity at M3. - live local-adapter and `mosaicd` contract parity at M6. ### TST-REQ-004: Migration -- fresh randomized consumer-census plant detected independently on every affected host and site; -- compatibility diagnostics in table and JSON modes; -- systemd timer and restart behavior; -- production M365/AD consumer probes; -- fleet-doctor digest-state preservation; -- clean install, upgrade, rollback, stale install, and greenfield operation; -- representative container without legacy tools mounted; +- fresh randomized consumer-census plant detected independently on every affected host and site. +- compatibility diagnostics in table and JSON modes. +- systemd timer and restart behavior. +- production M365/AD consumer probes. +- fleet-doctor digest-state preservation. +- clean install, upgrade, rollback, stale install, and greenfield operation. +- representative container without legacy tools mounted. - representative container mounts no shared or fleet tmux socket, and any temporary tmux exception uses only the named adapter's dedicated per-seat socket. @@ -688,15 +688,15 @@ PR to `next`, terminal-green CI, and linked-issue closure. The workstream updates in the same delivery sequence: -- official CLI help; -- `docs/PRD.md` workstream pointer; -- `docs/ROADMAP.md` parallel-track entry; -- `docs/SITEMAP.md` requirements link; -- user guide commands and deprecation behavior; -- administrator configuration, migration, and recovery; -- developer architecture, capability authoring, schemas, and adapter contracts; -- API and machine-readable result schemas; -- release notes; +- official CLI help. +- `docs/PRD.md` workstream pointer. +- `docs/ROADMAP.md` parallel-track entry. +- `docs/SITEMAP.md` requirements link. +- user guide commands and deprecation behavior. +- administrator configuration, migration, and recovery. +- developer architecture, capability authoring, schemas, and adapter contracts. +- API and machine-readable result schemas. +- release notes. - T78 program-map and unified-roadmap records. No command is public until its help, structured output, authorization behavior, and documentation @@ -710,7 +710,7 @@ are present. | M1 | Inventory consumers, normalize baseline, freeze registry resolver, capability catalog, policy, and runtime-integrity contracts | Typed interfaces and migration census reviewed | | M2 | Implement resolver, catalog, common result envelope, and adapter interface | Contract and two-root tests green | | M3 | Deliver pilot issue list, view, and comment | Allowed and denied controls, uncertainty behavior, docs, review, CI | -| M4 | Migrate waves 1 through 3; prepare wave 4 private adapters without shared-credential cutover | Per-suite owner handoff and parity evidence | +| M4 | Migrate waves 1 through 3, prepare wave 4 private adapters without shared-credential cutover | Per-suite owner handoff and parity evidence | | M5 | Cut eligible consumers and generate harness policy | No new direct references, compatibility callers measured | | M6 | Prove representative container and `mosaicd` seam, then cut over shared-credential wave 4 and all wave 5 capabilities | Boundary, authorization, audit, and parity tests green | | M7 | Remove installed legacy script tree | Zero callers, migration and rollback evidence, docs and release gates complete | @@ -719,18 +719,18 @@ are present. T78 completes only when: -1. the official TypeScript CLI exposes documented first-class capability groups; -2. the central registry resolver and capability catalog are single typed authorities; -3. two-root and container-topology tests prove no command-path hard-coding; -4. authorization has allowed and denied situational evidence; -5. agent-visible output, logs, and process arguments contain no credential values; -6. local and `mosaicd` modes share one request and result contract and report their mode honestly; +1. the official TypeScript CLI exposes documented first-class capability groups. +2. the central registry resolver and capability catalog are single typed authorities. +3. two-root and container-topology tests prove no command-path hard-coding. +4. authorization has allowed and denied situational evidence. +5. agent-visible output, logs, and process arguments contain no credential values. +6. local and `mosaicd` modes share one request and result contract and report their mode honestly. 7. a representative rootless seat container performs granted operations without legacy tools, - host credentials, or a container-runtime socket; -8. tmux and fleet-comms can be replaced without changing public communications callers; -9. the legacy consumer census reaches zero with a discriminating control; -10. the installed `~/.config/mosaic/tools` script surface is removed; -11. independent review passes for every source partition; + host credentials, or a container-runtime socket. +8. tmux and fleet-comms can be replaced without changing public communications callers. +9. the legacy consumer census reaches zero with a discriminating control. +10. the installed `~/.config/mosaic/tools` script surface is removed. +11. independent review passes for every source partition. 12. all PRs are squash-merged to `next`, terminal CI is green, and linked issues are closed. ## 17. Contract-freeze status @@ -739,7 +739,7 @@ The architecture inputs are frozen for independent review: 1. The central-registry resolver has joint C1, amended C2, and C3 approval. 2. User-editable `config.json` is not authorization policy. Target grant authority belongs to - `mosaicd`; local mode is explicitly non-authoritative. + `mosaicd`. Local mode is explicitly non-authoritative. 3. Registry, capability, and adapter source boundaries are packaged TypeScript modules. Brain tools remain working source and temporary private adapters, not the final runtime contract. 4. Issue `#758` remains an independent dependency and is not re-scoped into T78.