docs(plan): resolve harness IDs + lifecycle review gate (#50)

Owner adjudication:
- canonical harness IDs match executables: pi, claude, codex, opencode
- agent.json uses one scalar harness ID; registry/manifest resolution, no
  hard-coded schema enum
- target mosaic harness list/detect/install/rm/status lifecycle
- detection recognizes reviewed executables and records compatibility
  without reading/copying harness homes
- installs are exact-version/verified, Mosaic-managed, never global
- detected external harness is available but not container-ready until
  imported/installed, absent a separately reviewed host adapter

Gate 1 resolved. Remaining P0/review gates stay open; no implementation
authorized. Suites 24/15/90/14/17 + verify green; unslop clean.
This commit is contained in:
2026-09-04 12:26:57 -05:00
parent 9ea7dea711
commit 69d1bb3aa4
3 changed files with 96 additions and 12 deletions
+16
View File
@@ -635,3 +635,19 @@ review. Implementation remains blocked until all ten gates are resolved.
Implementation remains blocked pending owner/conductor adjudication and a
revised spec.
## Phase 25 review revision: harness lifecycle (gate 1 resolved)
- Owner confirmed canonical harness IDs match executable names: `pi`,
`claude`, `codex`, `opencode`. agent.json stores one scalar ID; dynamic
manifest/registry resolution replaces a hard-coded schema enum.
- Spec adds `mosaic harness list|detect|install|rm|status`.
- Detection recognizes reviewed canonical executables, records compatible
findings as available, and never imports harness homes/config/auth.
- Installation is exact-version/verified, Mosaic-managed, never global;
immutable runtime packages survive dataRoot reset.
- Container seam remains explicit for review: a detected host executable is
available but not launch-ready until imported/installed into a managed
runtime, unless host execution gets a separate reviewed adapter.
- Gate 1 marked RESOLVED in the spec and #50; all other P0/review gates remain
open. No implementation authorized.
+1
View File
@@ -17,3 +17,4 @@ are never rewritten or removed; corrections are new entries.
| 2026-09-03 | owner (direction) + assistant (conductor) | M19 correction (#48): mosaic-managed auth moved from ~/.pi to the data root (auth/<account>.json, 0600 enforced); ~/.pi read-only to the stack as a ROADMAP standing decision; auth.sh config-driven; test-auth 15 cases | scripts/auth.sh, scripts/agent.sh, scripts/test-auth.sh, docs/TOOLS.md, docs/plans/ROADMAP.md, README.md; suites 24/15/90/14/17 + verify green |
| 2026-09-03 | owner (requirements) + assistant (conductor/spec author) | Harness/provider/auth registry specification (#49): agent.json harness declaration, centralized providers/accounts/settings profiles, audited runtime selection, per-seat auth/models materialization, centralized OAuth lifecycle, local/remote Ollama, target mosaic CLI | docs/plans/2026-09-03_auth-provider-harness-registry.md; implementation blocked pending ten-gate review; unslop clean |
| 2026-09-03 | ms-test (independent reviewer, zai/glm-5.3) + assistant (conductor) | Independent read-only review of auth/provider/harness registry spec (#50): answered ten gates; verdict ACCEPT WITH CHANGES; P0 launch provider/model resolution, rotating-OAuth persistence, role ceiling ∩ profile/data-map/reset alignment | Findings persisted in #50 + BUILD-LOG Phase 25; no repo edits by reviewer; implementation remains blocked pending adjudication |
| 2026-09-03 | owner (decision) + assistant (conductor/spec revision) | #50 gate-1 adjudication: executable-name harness IDs (`pi`, `claude`, `codex`, `opencode`), registry/manifest resolution (no hard-coded enum), `mosaic harness detect/install/list/rm/status`, detected-vs-container-ready distinction | auth/provider/harness spec revised; gate 1 resolved; remaining gates/P0 blockers open |
@@ -10,8 +10,10 @@ and authentication accounts without modifying a user's default harness
configuration or requiring provider registration on every agent seat.
Pi is the first implementation checkpoint. The registry and seat contracts
must remain harness-neutral so future adapters (Claude Code, Codex, OpenCode)
materialize their own native files from the same desired state.
must remain harness-neutral so future adapters (`claude`, `codex`, `opencode`)
materialize their own native files from the same desired state. Canonical
harness IDs are the executable names so CLI, manifests, diagnostics, and user
expectation stay 1:1.
## Non-negotiable decisions already made
@@ -62,10 +64,11 @@ Rules:
- `harness` is a scalar identifier, not an array. One process launch runs one
harness.
- It is not permanently hard-coded to an enum in the agent schema. The value
must match a versioned harness manifest/adapter identifier.
- Canonical identifiers proposed for review: `pi`, `claude-code`, `codex`,
`opencode`. Provider `openai-codex` and harness `codex` remain distinct.
- It is not hard-coded to an enum in the agent schema. The value must resolve
dynamically through the installed/available harness registry.
- Canonical identifiers (owner-confirmed during #50 review) are executable
names: `pi`, `claude`, `codex`, `opencode`. Provider `openai-codex` and
harness `codex` remain distinct.
- No CLI harness override in phase 1. Harness is part of reviewed seat identity;
an override would bypass that declaration.
- Migration: existing `agentVersion: 1` seats without `harness` resolve to `pi`
@@ -83,9 +86,59 @@ adapters/pi/harness.json
adapters/claude-code/harness.json
```
A manifest declares its identifier, adapter, materializers, native config paths,
and supported credential types. Adding a harness requires a reviewed adapter +
manifest + suites; it is not a mutable auth-registry operation.
A manifest declares its identifier, executable name, adapter, compatible
version range, installer/detector metadata, execution mode, materializers,
native config paths, and supported credential types. Adding harness support
requires a reviewed adapter + manifest + suites. Detecting/installing a known
harness is mutable machine state; changing the manifest/adapter contract is a
reviewed repository change.
### Harness detection, installation, and availability
Target CLI:
```text
mosaic harness list [--available|--installed] [--json]
mosaic harness detect [<id>|--all]
mosaic harness install <id> [--version <exact-compatible-version>]
mosaic harness rm <id>
mosaic harness status [<id>] [--json]
```
Lifecycle and rules:
1. `detect` checks canonical executable names (`pi`, `claude`, `codex`,
`opencode`) on PATH and approved known locations, resolves real paths,
obtains versions using manifest-declared noninteractive commands, validates
compatibility, and records compatible findings as available. Unknown
executables are never auto-registered.
2. Detection records metadata only: executable path, version, source
(`external-detected`), compatibility result, detection timestamp, and
manifest identity. It never reads/copies the harness's home, settings, auth,
sessions, extensions, or plugins.
3. `install <id>` resolves the reviewed catalog/manifest, pins an exact
compatible version, verifies package identity/checksum where supported, and
installs/packages into a Mosaic-managed immutable runtime. It never performs
an unversioned global install and never writes the default harness home.
4. Built-in pi is an image-baked managed harness. Future installs should package
a harness-specific container image/bundle beside the active release so
`reset.sh` does not destroy installed runtimes; dataRoot stores registry
state and receipts, not the package payload.
5. Availability and launch-readiness are separate fields. A compatible detected
host executable is `available`; under the current container boundary it is
not automatically `ready` until imported/installed into a managed runtime,
unless a separately reviewed adapter explicitly supports host execution.
6. `agent.json.harness` launch requires a compatible, ready harness + adapter +
materializer. Detected-but-not-ready, missing, incompatible, or ambiguous
installations refuse loudly; no fallback to pi.
7. Install/detect/remove operations write append-only receipts. Removal refuses
while defined seats reference the harness unless those bindings are migrated
first.
Registry state is derived under `<dataRoot>/harnesses/`; the reviewed catalog
and adapter manifests remain in the installation/repository. This avoids a
hard-coded enum while preventing arbitrary PATH executables from becoming
trusted harnesses.
## Central registry layout
@@ -309,6 +362,8 @@ mosaic auth provider create
mosaic auth provider create --id ollama-local --kind custom-endpoint ...
mosaic auth provider rm <id>
mosaic harness list|detect|install|rm|status ...
mosaic agent settings use <seat> <profile>
mosaic agent auth use <seat> <provider/account>
mosaic agent auth status <seat>
@@ -385,6 +440,10 @@ No named accounts currently exist, so migration is state-free:
previous files and records refusal.
- OAuth central refresh rematerializes affected seats; agents never authenticate.
- `harness: pi` resolves; unregistered/unsupported harness refuses.
- Harness detection records recognized compatible executables without reading
harness homes; incompatible/ambiguous detections refuse availability.
- Harness install is exact-version/verified, Mosaic-managed, and never global;
detected-but-not-ready harnesses cannot launch seats.
- Pi materialization generates valid auth.json/models.json with scoped providers
and models; custom local/remote Ollama entries remain distinct.
- Launch refuses missing/stale/invalid materialization; no account fallback.
@@ -393,7 +452,13 @@ No named accounts currently exist, so migration is state-free:
## Review gates (must resolve before implementation)
1. Confirm canonical harness IDs: `pi`, `claude-code`, `codex`, `opencode`.
1. **RESOLVED (owner, #50):** canonical harness IDs are executable names:
`pi`, `claude`, `codex`, `opencode`; validation is registry/manifest-driven,
not a schema enum. `mosaic harness detect/install/list/rm/status` owns the
lifecycle. Remaining seam to approve: detected host executables are
available but not launch-ready under the container boundary until
imported/installed into a managed runtime (unless host execution receives a
separate reviewed adapter).
2. Confirm `agentVersion: 2` migration and whether `settingsProfile` becomes
mandatory for defined seats.
3. Confirm registry path/schema split (`account.json` metadata +
@@ -409,8 +474,10 @@ No named accounts currently exist, so migration is state-free:
implementation must prove refresh without exposing or duplicating tokens.
8. Confirm local Ollama container routing (`host-gateway`) and remote Ollama
transport/auth requirements.
9. Decide whether M20 `packages/mosaic` begins with this auth/provider domain or
whether scripts prototype it first.
9. Decide whether M20 `packages/mosaic` begins with this auth/provider/harness
domain or whether scripts prototype it first. Confirm managed harness
packaging: harness-specific container image/bundle survives dataRoot reset;
registry state and receipts remain under dataRoot.
10. Define backup/reset semantics for the central registry. Current reset wipes
the data root; OAuth re-login cost may justify a separately protected
registry root, but that would require an explicit canon change.