Compare commits
2 Commits
docs/issue
...
fix/mos-op
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d1f7c75773 | ||
| 5e832049bb |
136
docs/PRD.md
136
docs/PRD.md
@@ -1100,139 +1100,3 @@ All work is **alpha** (< 0.1.0) until Jason approves 0.1.0 beta release.
|
||||
10. ASSUMPTION: **Conversations and messages get their own PG tables** (not stored in brain's entity model). They follow a chat-specific schema with proper foreign keys to users and projects. Rationale: Chat has different access patterns (streaming, pagination, search) than brain entities.
|
||||
|
||||
11. RESOLVED: **Pi handles all target LLM providers natively.** Anthropic, OpenAI/Codex, Z.ai, Ollama, LM Studio, and llama.cpp are all supported via Pi's built-in providers or `models.json` configuration with `openai-completions` API type. No custom provider adapters needed in @mosaicstack/agent — only configuration management.
|
||||
|
||||
---
|
||||
|
||||
## Fleet Declarative Configuration Management (#758)
|
||||
|
||||
### Status and objective
|
||||
|
||||
- **Requirement ID:** `FCM-PRD-001`
|
||||
- **Status:** approved architecture; M0 documentation gate in progress
|
||||
- **Authority:** issue #758 and the independently approved baseline plan
|
||||
|
||||
Provide one understandable, schema-validated lifecycle for the local Mosaic fleet. The operator-owned YAML/JSON roster is the canonical desired-state input. Generated agent environment files, systemd enablement, tmux sessions, heartbeat state, and installed framework assets are derived or observed state. Mutations must pass through one shared compiler/reconciler and must be previewable, atomic where possible, recoverable, automation-safe, and non-destructive toward unmanaged resources.
|
||||
|
||||
### Normative scope
|
||||
|
||||
#### In scope for M0–M5
|
||||
|
||||
1. A narrow v2 YAML/JSON roster for local tmux/systemd fleets.
|
||||
2. One executable structural contract with schema/parser parity and canonical snake_case output.
|
||||
3. Semantic validation through the existing baseline plus `roles.local` profile/persona/provision resolver; a parallel role resolver is forbidden.
|
||||
4. Canonical classes `code`, `review`, `security-review`, `validator`, `merge-gate`, `orchestrator`, `team-leader`, `enhancer`, and `interaction`, including documented legacy aliases.
|
||||
5. Read/validate/plan/apply/migrate, full local fleet-agent CRUD, lifecycle, status, verify, stable JSON output, and documented exit codes.
|
||||
6. Deterministic `.env.generated` projections, a strict non-shell `.env.local` allowlist, generation/digest stamping, and fail-closed quarantine of forbidden legacy keys.
|
||||
7. v1 inventory, preview, field-complete migration, canary cutover, rollback, compatibility aliases, and explicit disposition of every shipped example/profile.
|
||||
8. Documentation, packaging/update checks, clean-install/cold-start dogfood, and independent correctness, security, validator, and merge gates.
|
||||
|
||||
#### Out of scope for M0–M5
|
||||
|
||||
- Kubernetes-style resource envelopes.
|
||||
- Remote/SSH reconciliation or distributed placement mutation.
|
||||
- Connector/Matrix/Discord lifecycle mutation.
|
||||
- Secret-reference or credential-provider schema.
|
||||
- Arbitrary command or channel overrides.
|
||||
- Gateway `/api/agents` mapping, control-plane convergence, UI configuration storage, or rename of that separate DB-backed catalog.
|
||||
- Live-fleet mutation during M0.
|
||||
|
||||
Each excluded capability requires a separate post-M5 PRD and threat model. Existing v1 remote/connector fields are inventory-only: local apply must reject them without invoking systemd or tmux.
|
||||
|
||||
### Authority and identity decisions
|
||||
|
||||
- The roster owns fleet membership, launch policy, and persisted lifecycle intent.
|
||||
- Role/persona contracts are product reference data; `roles.local` is the update-surviving local extension layer.
|
||||
- Tess and Ultron are configurable instance/display names, not schema identities.
|
||||
- `validator` issues the independent final validation certificate but cannot approve-to-land or merge.
|
||||
- `merge-gate` remains the sole approve-to-land and merge authority after required review, security, validation, CI, and queue gates.
|
||||
- `orchestrator` may apply validated owner-policy-compliant topology changes and grant/revoke bounded capacity leases.
|
||||
- `team-leader` may accept/release and use a named lease but cannot change global topology, re-lease capacity, or gain merge authority.
|
||||
- `review` and `security-review` provide independent correctness and security records respectively; neither authors the reviewed change.
|
||||
- `interaction` is request/status only. `enhancer` proposes fleet improvements. `code` authors implementation but cannot self-review.
|
||||
- Operator policy remains the exception, pause, and lease-revocation boundary.
|
||||
|
||||
A capacity lease names existing agents, purpose, and expiry. It never changes class, runtime, tools, credentials, roster ownership, or merge authority.
|
||||
|
||||
### Lifecycle and generated-state decisions
|
||||
|
||||
The normative dimensions are `enabled`, persisted `desired_state: running|stopped`, and observed `running|stopped|error|unknown|unmanaged`.
|
||||
|
||||
1. Fresh create defaults to enabled and stopped; `create --start` persists running.
|
||||
2. v1 migration preserves known observed running/stopped state. Unknown state blocks apply for that entry.
|
||||
3. Start/stop without `--persist` is transient and reports drift; the next apply/reboot restores persisted intent.
|
||||
4. Start/stop with `--persist` atomically updates generation and converges the local unit/session.
|
||||
5. Restart does not change desired state and rejects stopped entries unless explicitly started.
|
||||
6. Apply acts only on local, enabled, roster-owned entries. Ownership must be proven before stale projections are quarantined or removed; fuzzy names never authorize stopping an unmanaged session.
|
||||
7. Rollback restores roster/projection generation and captured unit enablement, stops processes introduced by the failed generation, and never starts an agent that was stopped before cutover.
|
||||
8. The systemd unit reads only `%i.env.generated` after migration. `.env.local` is parsed as data, cannot shadow authoritative keys, and never uses shell `source`, `eval`, expansion, or command substitution.
|
||||
9. `MOSAIC_AGENT_COMMAND`, channel flags, credential variables, and unknown agent keys are forbidden. Migration reports key names and content hashes only—never values—and blocks launch/apply until disposition.
|
||||
|
||||
### Functional requirements
|
||||
|
||||
| ID | Requirement |
|
||||
| --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| FCM-FR-01 | Show and validate YAML/JSON using one structural contract and shared semantic role/topology validation. |
|
||||
| FCM-FR-02 | Produce a deterministic, non-mutating desired-versus-observed plan covering roster, projections, units, sessions, installed assets, and orphans. |
|
||||
| FCM-FR-03 | Apply under a lock with expected-generation checks, atomic writes/backups, ordered convergence, post-verification, and machine-readable recovery data. |
|
||||
| FCM-FR-04 | Provide create, inspect, update, remove, list, start, stop, restart, status, validate, reconcile, doctor, dry-run, and automation-safe operations. |
|
||||
| FCM-FR-05 | Validate duplicate names, unsupported classes/runtimes/models/options, topology cycles, missing role contracts, stale generated state, unmanaged sessions, unit drift, and socket ambiguity. |
|
||||
| FCM-FR-06 | Generate deterministic, mode-0600, digest-stamped launch projections; safely parse only allowlisted local operational overrides. |
|
||||
| FCM-FR-07 | Read v1 for one deprecation window, write v2 after migration, preserve known lifecycle intent, and provide preview/canary/rollback. |
|
||||
| FCM-FR-08 | Classify every shipped example/profile as migrated, versioned compatibility fixture, or retired with replacement. |
|
||||
| FCM-FR-09 | Report desired, observed, generation, drift, readiness, ownership, and failing plane without exposing privileged values. |
|
||||
| FCM-FR-10 | Keep gateway-backed `mosaic agent` records explicitly separate from local `mosaic fleet` desired state. |
|
||||
|
||||
### Non-functional requirements
|
||||
|
||||
- **Security:** fail closed on command/credential/unknown overrides; reject traversal, injection, shadowing, and unauthorized topology/lifecycle actions; never expose secret or command values.
|
||||
- **Reliability:** lock plus expected generation; temporary write, fsync, atomic rename, recoverable backup; deterministic idempotent replay; ordered rollback on partial failure.
|
||||
- **Safety:** no destructive inference from stale names; no local actions for remote/schema-only entries; stopped agents remain stopped through migration and reboot.
|
||||
- **Compatibility:** canonical snake_case serialization with bounded v1 camelCase/alias input support and explicit warnings.
|
||||
- **Observability:** stable text/JSON status, drift, plan, migration, and recovery output with documented exit codes `0` success, `2` invalid, `3` drift, `4` conflict, `5` partial failure, and `6` policy denial.
|
||||
- **Maintainability:** schema, roster load, profiles, provision, migration, and apply share the existing role-resolution implementation.
|
||||
- **Documentation:** every field, command, transition, migration rule, recovery workflow, class power, and example is linked from the fleet docs IA and validated in CI.
|
||||
|
||||
### Acceptance criteria
|
||||
|
||||
| ID | Acceptance criterion |
|
||||
| --------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| FCM-AC-01 | `docs/PRD.md`, `docs/TASKS.md`, docs-IA checklist, and example/profile inventory are approved before implementation. |
|
||||
| FCM-AC-02 | YAML and JSON positive/negative, round-trip, unknown-field, enum, duplicate, topology, and property/fuzz tests prove schema/parser parity and canonical serialization. |
|
||||
| FCM-AC-03 | Every class resolves through the existing profile/persona resolver; authority and lease tests enforce the normative matrix. |
|
||||
| FCM-AC-04 | Every shipped example/profile has a CI-valid migrate/compatibility/retire disposition with no unresolved class at M1 exit. |
|
||||
| FCM-AC-05 | Validate/show/plan are deterministic and non-mutating; JSON shapes and exit codes are contract-tested. |
|
||||
| FCM-AC-06 | Generated/local env precedence, mode, digest, forbidden shadowing, command injection, quarantine, and no-value diagnostics pass independent security tests. |
|
||||
| FCM-AC-07 | CRUD is generation-guarded, atomic/recoverable, idempotent, concurrency-tested, and creates stopped agents unless start is explicitly persisted. |
|
||||
| FCM-AC-08 | Apply/lifecycle exactly implements the transition contract, including transient/persisted operations, reboot, partial failure, and rollback. |
|
||||
| FCM-AC-09 | Remote/schema-only and unmanaged entries receive zero local lifecycle calls; local targeting covers named and default tmux sockets exactly. |
|
||||
| FCM-AC-10 | Status/verify/doctor expose all state planes and actionable drift without secret, credential, or privileged command values. |
|
||||
| FCM-AC-11 | v1 migration handles every mapped field, known/unknown observed state, aliases, env quarantine, current 9-managed/3-unmanaged synthetic fixture, canary, and rollback. |
|
||||
| FCM-AC-12 | `fleet add/remove` compatibility aliases and v1 reads remain for the approved deprecation window while v2 writers emit only v2. |
|
||||
| FCM-AC-13 | Package/install/update tests prove schema, tools, units, roles, docs, and examples ship together while site-owned state survives. |
|
||||
| FCM-AC-14 | Fleet documentation checklist is complete, links/format/examples validate, and operator recovery procedures match tested behavior. |
|
||||
| FCM-AC-15 | Independent correctness review, security review, validator certificate, terminal-green CI, and merge-gate approval complete before issue closure. |
|
||||
|
||||
### Risks and mitigations
|
||||
|
||||
| Risk | Mitigation / verification |
|
||||
| ------------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
|
||||
| Schema and parser drift create false validation | One executable contract or bidirectional parity tests; shared semantic resolver. |
|
||||
| Apply starts intentionally stopped agents | Persist separate desired state; migration preserves known observed state; reboot/rollback tests. |
|
||||
| Preserved env files become a hidden control plane | Generated-only unit input; strict local allowlist; shadow rejection and quarantine before start. |
|
||||
| Command, secret, or credential values leak | Values never enter v2 output; key-name/hash-only diagnostics; adversarial security tests and review. |
|
||||
| Stale artifacts cause destructive cleanup | Proof-of-ownership requirement; unmanaged/remote zero-call tests; deterministic plan before apply. |
|
||||
| Concurrent writers or crashes corrupt roster | Lock, expected generation, fsync/rename, backup, failure injection, and recovery plan. |
|
||||
| New compiler duplicates role logic | Hard prohibition on parallel resolver; parity tests across profile, provision, roster, migration, apply. |
|
||||
| Control-plane naming confuses automation | Explicit local `mosaic fleet` versus gateway DB catalog documentation; no implicit mapping in M1–M5. |
|
||||
| Legacy examples silently teach invalid classes | Complete disposition inventory and M1 CI exit gate. |
|
||||
|
||||
### Verification and milestone intent
|
||||
|
||||
- **M0:** requirements, authority, lifecycle, migration mapping, TASKS DAG, docs IA, and legacy inventory approved; no implementation or live mutation.
|
||||
- **M1:** narrow v2 compiler, shared resolver, roles/aliases, validate/show/plan, and all shipped example/profile dispositions.
|
||||
- **M2:** safe launch projection and generation-guarded atomic CRUD; command/credential quarantine proven before lifecycle.
|
||||
- **M3:** local-only apply/lifecycle/status/verify/doctor implementing the full transition table.
|
||||
- **M4:** field-complete v1 migration, compatibility window, orphan inventory, canary, and rollback.
|
||||
- **M5:** accepted documentation IA, package/update checks, clean-install dogfood, independent correctness/security/validator evidence, and merge-gate release approval.
|
||||
|
||||
Detailed delivery dependencies and acceptance mappings are canonical in `docs/TASKS.md`. Documentation acceptance is tracked in [`docs/scratchpads/758-fleet-config-docs-ia-checklist.md`](scratchpads/758-fleet-config-docs-ia-checklist.md), and shipped artifact disposition is inventoried in [`docs/tasks/758-legacy-example-profile-disposition.md`](tasks/758-legacy-example-profile-disposition.md).
|
||||
|
||||
@@ -1,12 +1,5 @@
|
||||
# Documentation Sitemap
|
||||
|
||||
## Fleet declarative configuration management
|
||||
|
||||
- [Normative requirements](PRD.md#fleet-declarative-configuration-management-758) — issue #758 scope, authority, lifecycle, migration, acceptance, risks, and milestones.
|
||||
- [M0–M5 delivery DAG](TASKS.md#w4--fleet-declarative-configuration-management-758) — one-card/one-PR implementation order and independent gates.
|
||||
- [Documentation IA acceptance checklist](scratchpads/758-fleet-config-docs-ia-checklist.md) — required paths, owners, evidence, and exit checks.
|
||||
- [Legacy example/profile disposition inventory](tasks/758-legacy-example-profile-disposition.md) — shipped artifacts and M1 migration decisions.
|
||||
|
||||
## Native Kanban and canonical task SOT
|
||||
|
||||
- [Canonical requirements](requirements/native-kanban-sot.md) — ratified P0–P3 requirements and acceptance criteria.
|
||||
@@ -48,3 +41,10 @@
|
||||
- [Retention and deprecation evidence](tess/M5-MIGRATION-RETENTION-DEPRECATION.md)
|
||||
- [Verification matrix](tess/VERIFICATION-MATRIX.md)
|
||||
- [Documentation checklist](tess/M5-003-DOCUMENTATION-CHECKLIST.md)
|
||||
- [Independent Option 2 runtime-portability qualification (2026-07-14)](tess/qualification/2026-07-14-option2-runtime-portability.md)
|
||||
|
||||
## Runtime-neutral Mos portability
|
||||
|
||||
- [Optional AI egress gateway ADR](architecture/ADR-MOS-EGRESS-GATEWAYS.md) — placement and gates for LiteLLM, Bifrost, and purpose-built translation proxies.
|
||||
- [Runtime-neutral Mos identity and failover mission](https://git.mosaicstack.dev/mosaicstack/stack/issues/754)
|
||||
- [Logical identity and connector lease/fencing implementation](https://git.mosaicstack.dev/mosaicstack/stack/issues/755)
|
||||
|
||||
@@ -15,11 +15,10 @@
|
||||
## Workstream Rollup
|
||||
|
||||
| id | status | workstream | progress | tasks file | notes |
|
||||
| --- | ----------------- | ------------------------ | ----------------- | ------------------------------------------------------------------- | -------------------------------------------------------------------------------- |
|
||||
| --- | ----------------- | ---------------------- | ---------------- | --------------------------------------------------------------- | -------------------------------------------------------------------------------- |
|
||||
| W1 | planning-complete | Federation v1 (FED) | 0 / 7 milestones | [docs/federation/TASKS.md](./federation/TASKS.md) | M1 task breakdown populated; M2–M7 deferred to mission planning |
|
||||
| W2 | planning-complete | Tess interaction agent | 0 / 5 milestones | [docs/tess/TASKS.md](./tess/TASKS.md) | Issue #706; independent planning gate PASS; M1 issue #707 ready |
|
||||
| W3 | planning-complete | Native Kanban/SOT | 0 / 4 phases | [docs/native-kanban-sot/TASKS.md](./native-kanban-sot/TASKS.md) | Issue #751; canon independently approved; implementation held until canon merges |
|
||||
| W4 | in-progress | Fleet declarative config | M0 / 6 milestones | [W4 DAG below](#w4--fleet-declarative-configuration-management-758) | Issue #758; M0 requirements/docs only; implementation blocked on M0 gates |
|
||||
|
||||
## Cross-Cutting Tracking
|
||||
|
||||
@@ -93,64 +92,3 @@ Active workstream is **W1 — Federation v1**. Workers should:
|
||||
## #633 — comms-block emitter + FLEET-LAUNCH runbook — feat/633-comms-block-runbook
|
||||
|
||||
- Status: implemented + tested (TDD). `mosaic fleet comms-block <role> [--host]` wraps resolveCommsBlock → readFleetCommsBlock; fails loud (stderr + exit 1) on unknown role / missing roster instead of silent empty. docs/fleet/FLEET-LAUNCH.md runbook: worker path + orchestrator .env fold (MOSAIC_AGENT_COMMAND; line-41 [-z] short-circuits line-44 yolo hardcode) + 3 launch gotchas + #632 preserve note + North-Star 4-field arc (harness ✅/model ✅ roster-native today; yolo + command/channels = PATH B #636). 177 fleet+comms tests green (6 new resolveCommsBlock cases). PATH A of the A→B→webUI arc. Detail: scratchpads/633-comms-block-runbook.md.
|
||||
|
||||
---
|
||||
|
||||
## W4 — Fleet declarative configuration management (#758)
|
||||
|
||||
**Rules:** The table below is the canonical M0–M5 dependency DAG. Each delivery card owns one short-lived branch and one PR. Gate cards (`*-ROR`, `*-SEC`, `*-VAL`, `*-MERGE`) independently attest to the referenced delivery PR and do not author that PR. No implementation starts until `FCM-M0-MERGE` is complete. `done` requires merged PR, terminal-green CI, and linked tracking closure/evidence.
|
||||
|
||||
| id | status | description | issue | agent | repo | branch | depends_on | estimate | notes |
|
||||
| ------------ | ----------- | -------------------------------------------------------------------------------------------------------------------- | ----- | ------ | ----- | ---------------------------------- | ----------------------------------------------------------------- | -------- | ------------------------------------------------------------------------------------------------------------------ |
|
||||
| FCM-M0-01 | in-progress | Ratify requirements, authority/lifecycle/migration decisions, DAG, docs IA checklist, and shipped artifact inventory | #758 | haiku | stack | docs/issue-758-m0 | — | 18K | One docs-only PR; maps FCM-AC-01; no source/schema/roles/examples/systemd/live changes |
|
||||
| FCM-M0-ROR | not-started | Independent requirements/content review of M0 PR | #758 | sonnet | stack | — | FCM-M0-01 | 8K | Verify approved plan fidelity, DAG completeness, links, and every card→AC mapping; non-author attestation |
|
||||
| FCM-M0-SEC | not-started | Independent security review of authority, quarantine, lifecycle, and migration requirements | #758 | sonnet | stack | — | FCM-M0-01 | 8K | Threat-model requirements only; verify no secret-value handling and no surprise-start path; non-author attestation |
|
||||
| FCM-M0-VAL | not-started | Validator certificate for M0 acceptance baseline | #758 | sonnet | stack | — | FCM-M0-ROR, FCM-M0-SEC | 6K | Confirm FCM-AC-01 and no unresolved architecture blocker; validator cannot merge |
|
||||
| FCM-M0-MERGE | not-started | Merge-gate approval and squash merge of M0 PR | #758 | haiku | stack | — | FCM-M0-VAL | 3K | Terminal-green CI required; unlocks implementation |
|
||||
| FCM-M1-01 | not-started | Implement narrow v2 executable schema, canonical serialization, and schema/parser parity suite | #758 | codex | stack | feat/fcm-v2-contract | FCM-M0-MERGE | 30K | One PR; FCM-AC-02; structural validation only, no lifecycle mutation |
|
||||
| FCM-M1-02 | not-started | Share existing profile/persona/provision resolver for roster semantic validation and topology policy | #758 | codex | stack | feat/fcm-shared-role-validation | FCM-M1-01 | 28K | One PR; FCM-AC-03; parallel resolver forbidden |
|
||||
| FCM-M1-03 | not-started | Add/ratify validator, team-leader, interaction role contracts, aliases, authority, and lease tests | #758 | codex | stack | feat/fcm-role-authority | FCM-M1-02 | 24K | One PR; FCM-AC-03; merge-gate remains sole merger |
|
||||
| FCM-M1-04 | not-started | Resolve every shipped example/profile disposition and add CI validation through shared contract/resolver | #758 | codex | stack | feat/fcm-example-profile-migration | FCM-M1-03 | 28K | One PR; FCM-AC-04; inventory rows cannot remain decision-required |
|
||||
| FCM-M1-05 | not-started | Implement non-mutating config show, validate, and deterministic plan with stable JSON/exit codes | #758 | codex | stack | feat/fcm-config-read-plan | FCM-M1-02 | 32K | One PR; FCM-AC-05, FCM-AC-09, FCM-AC-10 |
|
||||
| FCM-M1-DOC | not-started | Publish v2 fields, roles/leases, desired-vs-observed, and example/profile disposition docs | #758 | haiku | stack | docs/fcm-m1-contract | FCM-M1-03, FCM-M1-04, FCM-M1-05 | 16K | One PR; FCM-AC-14; update sitemap and docs checklist evidence |
|
||||
| FCM-M1-ROR | not-started | Independent correctness review of all M1 delivery PRs | #758 | sonnet | stack | — | FCM-M1-01, FCM-M1-02, FCM-M1-03, FCM-M1-04, FCM-M1-05, FCM-M1-DOC | 14K | Exact-head reviews; schema/parser/resolver parity and docs checked |
|
||||
| FCM-M1-SEC | not-started | Independent security review of validation, authority, aliases, and input hardening | #758 | sonnet | stack | — | FCM-M1-01, FCM-M1-02, FCM-M1-03, FCM-M1-04, FCM-M1-05 | 12K | Fuzz/injection/topology/policy findings must be resolved |
|
||||
| FCM-M1-VAL | not-started | Validator certificate for M1 contract/compiler exit | #758 | sonnet | stack | — | FCM-M1-ROR, FCM-M1-SEC | 8K | Certify FCM-AC-02–05 and no mutation/lifecycle path |
|
||||
| FCM-M1-MERGE | not-started | Merge-gate approval for M1 completion | #758 | haiku | stack | — | FCM-M1-VAL | 4K | All M1 PRs merged, terminal-green, inventory resolved |
|
||||
| FCM-M2-01 | not-started | Implement deterministic mode-0600 `.env.generated` projection with generation/digest stamps | #758 | codex | stack | feat/fcm-generated-env | FCM-M1-MERGE | 30K | One PR; FCM-AC-06; no unit launch migration yet |
|
||||
| FCM-M2-02 | not-started | Implement strict data-only `.env.local` parser, shadow rejection, and forbidden legacy-key quarantine | #758 | codex | stack | feat/fcm-local-env-quarantine | FCM-M2-01 | 34K | One PR; FCM-AC-06; never output values or privileged commands |
|
||||
| FCM-M2-03 | not-started | Migrate generic unit/launcher to generated input with fail-closed digest validation | #758 | codex | stack | feat/fcm-launch-chain | FCM-M2-02 | 32K | One PR; FCM-AC-06; old `%i.env` cannot launch v2 |
|
||||
| FCM-M2-04 | not-started | Implement generation-guarded atomic fleet-agent create/get/list/update/delete and compatibility aliases | #758 | codex | stack | feat/fcm-atomic-crud | FCM-M2-03 | 38K | One PR; FCM-AC-07, FCM-AC-12; create defaults stopped; no apply engine |
|
||||
| FCM-M2-DOC | not-started | Publish generated-env chain, quarantine, and CRUD operator/developer guides | #758 | haiku | stack | docs/fcm-m2-projection-crud | FCM-M2-02, FCM-M2-03, FCM-M2-04 | 16K | One PR; FCM-AC-14; synthetic values only |
|
||||
| FCM-M2-ROR | not-started | Independent correctness review of M2 projection and CRUD PRs | #758 | sonnet | stack | — | FCM-M2-01, FCM-M2-02, FCM-M2-03, FCM-M2-04, FCM-M2-DOC | 14K | Crash/concurrency/idempotency/permissions review |
|
||||
| FCM-M2-SEC | not-started | Independent security review of launch chain, overrides, quarantine, paths, and diagnostics | #758 | sonnet | stack | — | FCM-M2-01, FCM-M2-02, FCM-M2-03, FCM-M2-04 | 16K | Adversarial shell/systemd/tmux/path/secret tests; FCM-AC-06–07 |
|
||||
| FCM-M2-VAL | not-started | Validator certificate for M2 safe-projection/CRUD exit | #758 | sonnet | stack | — | FCM-M2-ROR, FCM-M2-SEC | 8K | Prove no hidden launch authority or surprise starts |
|
||||
| FCM-M2-MERGE | not-started | Merge-gate approval for M2 completion | #758 | haiku | stack | — | FCM-M2-VAL | 4K | All M2 PRs merged and terminal-green |
|
||||
| FCM-M3-01 | not-started | Implement locked local-only config apply with ordered convergence and machine-readable recovery | #758 | codex | stack | feat/fcm-local-apply | FCM-M2-MERGE | 40K | One PR; FCM-AC-08–10; zero calls for remote/unmanaged entries |
|
||||
| FCM-M3-02 | not-started | Implement transient/persisted start, stop, restart, and fleet-wide lifecycle transitions | #758 | codex | stack | feat/fcm-lifecycle | FCM-M3-01 | 36K | One PR; FCM-AC-08–09; exact socket targeting |
|
||||
| FCM-M3-03 | not-started | Implement status, verify, and doctor desired/observed/generation/drift/readiness contracts | #758 | codex | stack | feat/fcm-status-doctor | FCM-M3-01 | 30K | One PR; FCM-AC-09–10; safe effective output only |
|
||||
| FCM-M3-04 | not-started | Add failure-injection, reboot/linger, unmanaged ownership, socket, and rollback integration suite | #758 | codex | stack | test/fcm-lifecycle-recovery | FCM-M3-02, FCM-M3-03 | 32K | One PR; FCM-AC-08–10 |
|
||||
| FCM-M3-DOC | not-started | Publish CLI, lifecycle, status/drift, reconcile/recover, and systemd/tmux troubleshooting docs | #758 | haiku | stack | docs/fcm-m3-operations | FCM-M3-02, FCM-M3-03, FCM-M3-04 | 18K | One PR; FCM-AC-14 |
|
||||
| FCM-M3-ROR | not-started | Independent correctness review of M3 lifecycle/recovery PRs | #758 | sonnet | stack | — | FCM-M3-01, FCM-M3-02, FCM-M3-03, FCM-M3-04, FCM-M3-DOC | 16K | Exact targeting, state transitions, recovery ordering |
|
||||
| FCM-M3-SEC | not-started | Independent security review of apply/lifecycle authority and unmanaged-resource protection | #758 | sonnet | stack | — | FCM-M3-01, FCM-M3-02, FCM-M3-03, FCM-M3-04 | 16K | Policy denial, injection, TOCTOU, no-value output |
|
||||
| FCM-M3-VAL | not-started | Validator certificate for M3 local lifecycle exit | #758 | sonnet | stack | — | FCM-M3-ROR, FCM-M3-SEC | 10K | Certify full transition table and FCM-AC-08–10 |
|
||||
| FCM-M3-MERGE | not-started | Merge-gate approval for M3 completion | #758 | haiku | stack | — | FCM-M3-VAL | 4K | All M3 PRs merged and terminal-green |
|
||||
| FCM-M4-01 | not-started | Implement field-complete v1 inventory, preview, aliases, unsupported-field reporting, and v2 writer | #758 | codex | stack | feat/fcm-v1-migrator | FCM-M3-MERGE | 38K | One PR; FCM-AC-11–12; no mutation without `--write` |
|
||||
| FCM-M4-02 | not-started | Implement observed-state preservation, canary cutover, orphan classification, and reversible rollback | #758 | codex | stack | feat/fcm-migration-cutover | FCM-M4-01 | 40K | One PR; FCM-AC-11; unknown state blocks; stopped stays stopped |
|
||||
| FCM-M4-03 | not-started | Add synthetic 9-managed/3-unmanaged migration, env quarantine, upgrade, and rollback E2E fixtures | #758 | codex | stack | test/fcm-migration-e2e | FCM-M4-02 | 34K | One PR; FCM-AC-11–12; no real credential/live-host data |
|
||||
| FCM-M4-DOC | not-started | Publish v1→v2 field map, aliases, example disposition, backup/restore, and migration runbook | #758 | haiku | stack | docs/fcm-m4-migration | FCM-M4-01, FCM-M4-02, FCM-M4-03 | 18K | One PR; FCM-AC-14 |
|
||||
| FCM-M4-ROR | not-started | Independent correctness review of M4 migration/cutover PRs | #758 | sonnet | stack | — | FCM-M4-01, FCM-M4-02, FCM-M4-03, FCM-M4-DOC | 16K | Field completeness, state preservation, rollback fidelity |
|
||||
| FCM-M4-SEC | not-started | Independent security review of migration inventory, quarantine, and cutover | #758 | sonnet | stack | — | FCM-M4-01, FCM-M4-02, FCM-M4-03 | 16K | Secret-safe reporting and non-destructive ownership proof |
|
||||
| FCM-M4-VAL | not-started | Validator certificate for M4 compatibility/migration exit | #758 | sonnet | stack | — | FCM-M4-ROR, FCM-M4-SEC | 10K | Certify FCM-AC-11–12 and rollback evidence |
|
||||
| FCM-M4-MERGE | not-started | Merge-gate approval for M4 completion | #758 | haiku | stack | — | FCM-M4-VAL | 4K | All M4 PRs merged and terminal-green |
|
||||
| FCM-M5-01 | not-started | Complete fleet documentation IA, sitemap, validated examples, and checklist evidence | #758 | haiku | stack | docs/fcm-complete-ia | FCM-M4-MERGE | 28K | One PR; FCM-AC-14; no required checklist item incomplete |
|
||||
| FCM-M5-02 | not-started | Add package/install/update asset-drift and site-owned-state preservation qualification | #758 | codex | stack | test/fcm-package-upgrade | FCM-M4-MERGE | 32K | One PR; FCM-AC-13 |
|
||||
| FCM-M5-03 | not-started | Run clean-home install, cold-start, local canary, rolling restart, failure, and rollback qualification | #758 | codex | stack | test/fcm-dogfood-qualification | FCM-M5-01, FCM-M5-02 | 30K | One PR; FCM-AC-08, FCM-AC-11, FCM-AC-13; synthetic harness/evidence only; never mutate production fleet |
|
||||
| FCM-M5-ROR | not-started | Independent final correctness and documentation review | #758 | sonnet | stack | — | FCM-M5-01, FCM-M5-02, FCM-M5-03 | 16K | Verify FCM-AC-01–14 evidence and docs links/examples |
|
||||
| FCM-M5-SEC | not-started | Independent final security review and threat-gate closure | #758 | sonnet | stack | — | FCM-M5-01, FCM-M5-02, FCM-M5-03 | 18K | Review launch/migration/lifecycle authority, secret handling, recovery |
|
||||
| FCM-M5-VAL | not-started | Ultron/validator final acceptance certificate | #758 | sonnet | stack | — | FCM-M5-ROR, FCM-M5-SEC | 12K | Independent certificate for FCM-AC-01–15; no merge authority |
|
||||
| FCM-M5-MERGE | not-started | Merge-gate final approve-to-land, terminal CI verification, issue closure, and release handoff | #758 | haiku | stack | — | FCM-M5-VAL | 6K | Sole merge path; FCM-AC-15; squash merge and close #758 after green CI |
|
||||
|
||||
### W4 acceptance mapping check
|
||||
|
||||
Every delivery card maps to at least one `FCM-AC-*` criterion in its notes. Gate cards verify those mappings rather than introducing implementation. The detailed documentation checklist is [`docs/scratchpads/758-fleet-config-docs-ia-checklist.md`](scratchpads/758-fleet-config-docs-ia-checklist.md); the shipped artifact inventory is [`docs/tasks/758-legacy-example-profile-disposition.md`](tasks/758-legacy-example-profile-disposition.md).
|
||||
|
||||
151
docs/architecture/ADR-MOS-EGRESS-GATEWAYS.md
Normal file
151
docs/architecture/ADR-MOS-EGRESS-GATEWAYS.md
Normal file
@@ -0,0 +1,151 @@
|
||||
# ADR: Optional AI egress gateways for runtime-neutral Mos
|
||||
|
||||
**Status:** Proposed for controlled prototypes; not approved as Mosaic core
|
||||
|
||||
**Date:** 2026-07-14
|
||||
|
||||
**Issues:** #754, #755
|
||||
|
||||
**Decision owner:** Mosaic Gateway / provider-adapter architecture
|
||||
|
||||
## Context
|
||||
|
||||
The emergency Mos continuity path kept Claude Code as the harness and translated Anthropic Messages traffic to Codex OAuth through a small localhost proxy. That preserved the existing Claude Discord plugin and transcript, but exposed two architectural facts:
|
||||
|
||||
1. Harness identity, channel entitlement, provider credentials, and inference transport are separate concerns.
|
||||
2. A generic AI gateway can improve provider routing, budgets, and observability, but must not become Mosaic's identity, authorization, tenant, or orchestration boundary.
|
||||
|
||||
The Tess qualification report also found that current provider rebinding is not identity-continuous failover. Mosaic still needs a logical agent identity, durable connector lease/fencing, canonical handoff/checkpoint, exactly-once receipts, concrete harness adapters, and cross-harness rollback E2E.
|
||||
|
||||
## Decision
|
||||
|
||||
Mosaic MAY support LiteLLM, Bifrost, the purpose-built Claude/Codex proxy, or future gateways as optional egress implementations behind `IProviderAdapter` / `AgentRuntimeProvider`.
|
||||
|
||||
Mosaic Gateway remains authoritative for:
|
||||
|
||||
- authenticated actor and tenant identity;
|
||||
- logical agent identity and connector binding;
|
||||
- authorization, approval, and policy;
|
||||
- lease epoch and stale-holder fencing;
|
||||
- audit correlation and redaction;
|
||||
- canonical handoff/checkpoint state;
|
||||
- idempotency and side-effect receipts.
|
||||
|
||||
An egress gateway MUST NOT:
|
||||
|
||||
- receive channel ingress directly;
|
||||
- authorize tools or connector ownership;
|
||||
- define Mosaic tenant or agent identity;
|
||||
- persist raw Mosaic handoffs or channel credentials;
|
||||
- bypass adapter capability negotiation;
|
||||
- silently fail over when policy, lease, or provider health is uncertain.
|
||||
|
||||
Allowed topology:
|
||||
|
||||
```text
|
||||
Discord / Matrix / CLI / web
|
||||
↓
|
||||
Mosaic Gateway: identity, authz, lease/fence, approvals, audit
|
||||
↓
|
||||
IProviderAdapter / AgentRuntimeProvider
|
||||
↓
|
||||
optional egress gateway
|
||||
↓
|
||||
upstream provider or subscription-backed OAuth session
|
||||
```
|
||||
|
||||
## Candidate assessment
|
||||
|
||||
### Purpose-built `raine/claude-code-proxy`
|
||||
|
||||
**Disposition:** Approved only for the verified emergency localhost bridge.
|
||||
|
||||
Strengths:
|
||||
|
||||
- explicit Codex device OAuth flow;
|
||||
- small operational surface;
|
||||
- Anthropic Messages translation suitable for Claude Code;
|
||||
- model and reasoning-effort enforcement;
|
||||
- straightforward loopback systemd supervision and rollback.
|
||||
|
||||
Constraints:
|
||||
|
||||
- not a Mosaic multi-tenant control plane;
|
||||
- Claude built-in channels still depend on Claude subscription entitlement and feature lookup;
|
||||
- model aliases can obscure the upstream model unless proxy policy/logs are treated as evidence;
|
||||
- no replacement for connector leasing, canonical handoff, or exactly-once effects.
|
||||
|
||||
### LiteLLM
|
||||
|
||||
**Disposition:** Candidate for a formal adapter-only prototype and terms/security review.
|
||||
|
||||
Current documentation states that ChatGPT subscription access is available through an OAuth device-code flow. LiteLLM also provides broad provider routing, virtual keys, budgets, observability, and OpenAI/Anthropic-compatible surfaces.
|
||||
|
||||
Required prototype gates:
|
||||
|
||||
- verify the exact ChatGPT subscription OAuth flow and supported models against current provider terms;
|
||||
- document token location, encryption, revocation, refresh, scope, and incident response;
|
||||
- prove tenant isolation and prevent virtual keys from becoming Mosaic principals;
|
||||
- verify streaming, tool calls, reasoning controls, cancellation, and idempotency metadata;
|
||||
- fail closed instead of selecting an unhealthy provider merely to return a result;
|
||||
- demonstrate that Mosaic audit correlation survives gateway retries/failover;
|
||||
- keep channel ingress and connector credentials outside LiteLLM.
|
||||
|
||||
Source references:
|
||||
|
||||
- [LiteLLM ChatGPT subscription provider](https://docs.litellm.ai/docs/providers/chatgpt)
|
||||
- [LiteLLM providers](https://docs.litellm.ai/docs/providers)
|
||||
|
||||
### Bifrost
|
||||
|
||||
**Disposition:** Candidate for governance/routing research; subscription OAuth compatibility unverified.
|
||||
|
||||
Useful concepts include virtual keys, budgets, rate limits, weighted load balancing, and automatic provider failover. Those features may inform Mosaic egress policy, but Bifrost virtual keys are downstream credentials—not Mosaic actors or tenants.
|
||||
|
||||
Required prototype gates:
|
||||
|
||||
- verify Codex/ChatGPT subscription OAuth rather than assuming API-key compatibility;
|
||||
- map budgets and virtual keys to server-derived Mosaic tenants without duplicating authority;
|
||||
- prove failover does not violate connector lease, approval, or exactly-once semantics;
|
||||
- ensure request/response logs are redacted before persistence;
|
||||
- disable or constrain automatic failover when policy or side-effect state is ambiguous.
|
||||
|
||||
Source references:
|
||||
|
||||
- [Bifrost overview](https://docs.getbifrost.ai/overview)
|
||||
- [Bifrost repository](https://github.com/maximhq/bifrost)
|
||||
|
||||
### `teremterem/claude-code-gpt-5-codex`
|
||||
|
||||
**Disposition:** Not selected as the emergency implementation; useful as a historical LiteLLM recipe.
|
||||
|
||||
The reviewed repository uses `OPENAI_API_KEY`, tells previously authenticated Claude users to log out, and documents a Claude Web Search schema incompatibility. Logging Claude out conflicts with the channel-entitlement requirement observed in the live Mos cutover. The repository therefore does not, as provided, satisfy subscription-OAuth plus built-in-channel continuity.
|
||||
|
||||
Source references:
|
||||
|
||||
- [Repository](https://github.com/teremterem/claude-code-gpt-5-codex)
|
||||
- [Environment template](https://github.com/teremterem/claude-code-gpt-5-codex/blob/main/.env.template)
|
||||
|
||||
## Security consequences
|
||||
|
||||
- Subscription OAuth grants are high-value credentials and require the same lifecycle controls as service credentials.
|
||||
- Downstream virtual keys reduce provider-key exposure but do not establish user, tenant, or agent authority.
|
||||
- Automatic retry/failover can duplicate tool or external side effects unless Mosaic owns operation IDs and receipts.
|
||||
- Gateway telemetry can contain prompts, tool schemas, and model output; redaction and retention policy must apply before persistence.
|
||||
- A localhost unauthenticated translation endpoint must remain loopback-only and process-isolated.
|
||||
|
||||
## Acceptance before production use
|
||||
|
||||
1. Threat model and provider-terms review approved.
|
||||
2. Credential lifecycle and revocation drill documented and exercised.
|
||||
3. Adapter contract tests pass for streaming, tools, cancellation, reasoning policy, errors, and audit correlation.
|
||||
4. Tenant-bound authorization remains entirely in Mosaic Gateway.
|
||||
5. Failure injection proves no duplicate side effects across retries or provider failover.
|
||||
6. Rollback to the prior provider path is exercised.
|
||||
7. Independent code and security reviews approve the exact deployed revision.
|
||||
|
||||
## Follow-up
|
||||
|
||||
- #754 owns cross-harness logical identity, checkpoint, receipt, adapter, and failover work.
|
||||
- #755 / PR #757 implements the first logical identity and connector lease/fencing boundary.
|
||||
- A later issue should prototype LiteLLM and Bifrost behind the provider adapter after #755 is merged and independently qualified.
|
||||
@@ -1,48 +0,0 @@
|
||||
# #758 Fleet configuration documentation IA acceptance checklist
|
||||
|
||||
**Scope:** M0 planning gate for issue #758. This checklist defines required documentation outcomes; it does not authorize source, schema, role, example, systemd, or live-fleet changes.
|
||||
|
||||
## Acceptance states
|
||||
|
||||
Use `required`, `deferred`, or `complete`. A deferred item requires a target milestone and rationale. M5 cannot exit with a required item incomplete.
|
||||
|
||||
| Path | Purpose | Owner milestone | Required evidence | State |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| `docs/PRD.md` | Normative requirements, scope, authority, lifecycle, migration, risks, and acceptance criteria | M0 | Approved requirements PR linked to #758 | required |
|
||||
| `docs/TASKS.md` | M0–M5 one-card/one-PR DAG and review gates | M0 | Every delivery card maps to acceptance criteria and dependencies | required |
|
||||
| `docs/fleet/README.md` | Fleet configuration entry point and operator decision tree | M5 | Links all accepted fleet-config pages and passes link validation | required |
|
||||
| `docs/fleet/concepts/desired-vs-observed-state.md` | Desired, generated, and observed state boundaries | M5 | Matches lifecycle contract and status JSON | required |
|
||||
| `docs/fleet/concepts/identity-class-runtime.md` | Stable identity, alias, class, runtime/provider/model policy | M5 | Matches executable schema and shared role resolver | required |
|
||||
| `docs/fleet/concepts/role-authority-and-leases.md` | Authority matrix and bounded capacity leases | M1 | Independently reviewed against role contracts | required |
|
||||
| `docs/fleet/concepts/generated-env-launch-chain.md` | `.env.generated`, `.env.local`, quarantine, and unit/launcher chain | M2 | Security review and launch-chain tests linked | required |
|
||||
| `docs/fleet/reference/roster-v2.schema.json` | Published executable schema artifact | M1 | Schema/parser parity suite consumes this artifact | required |
|
||||
| `docs/fleet/reference/roster-v2-fields.md` | Every field, default, constraint, compatibility rule, and example | M1 | Field-by-field parity review | required |
|
||||
| `docs/fleet/reference/cli.md` | Config, CRUD, lifecycle commands, JSON shapes, and exit codes | M3 | CLI contract tests and examples linked | required |
|
||||
| `docs/fleet/reference/role-classes.md` | Required/optional classes, aliases, and powers | M1 | Existing resolver validates every documented class | required |
|
||||
| `docs/fleet/reference/lifecycle-transitions.md` | Complete enabled/desired/observed transition table | M3 | Lifecycle and reboot tests linked | required |
|
||||
| `docs/fleet/reference/status-and-drift.md` | Drift planes, readiness, ownership proof, and safe output | M3 | Golden JSON/status tests linked | required |
|
||||
| `docs/fleet/how-to/create-update-delete-agent.md` | Safe CRUD and dry-run workflows | M2 | Fresh and idempotent examples validate | required |
|
||||
| `docs/fleet/how-to/start-stop-restart.md` | Transient versus persisted lifecycle operations | M3 | Matches transition tests | required |
|
||||
| `docs/fleet/how-to/configure-tess-interaction.md` | Configurable interaction instance, not hardcoded identity | M5 | Example validates through shared resolver | required |
|
||||
| `docs/fleet/how-to/configure-ultron-validator.md` | Validator instance without merge authority | M5 | Example validates and authority review passes | required |
|
||||
| `docs/fleet/how-to/customize-roles.md` | Baseline plus `roles.local` resolution and policy | M1 | No parallel resolver described or implemented | required |
|
||||
| `docs/fleet/operations/reconcile-and-recover.md` | Plan/apply, partial failure, recovery, and rollback | M3 | Failure-injection evidence linked | required |
|
||||
| `docs/fleet/operations/env-quarantine.md` | Legacy key inventory and secret-safe disposition | M2 | Security tests prove no values are emitted | required |
|
||||
| `docs/fleet/operations/systemd-tmux-troubleshooting.md` | Exact local targeting and non-destructive diagnostics | M3 | Named/default socket and unmanaged-session tests linked | required |
|
||||
| `docs/fleet/operations/backup-restore.md` | Generation backup and rollback | M4 | Migration rollback drill linked | required |
|
||||
| `docs/fleet/operations/upgrade-assets.md` | Source/installed asset drift and update behavior | M5 | Package/update test linked | required |
|
||||
| `docs/fleet/migration/v1-to-v2.md` | Normative field mapping and stopped-state preservation | M4 | Migration fixtures and canary evidence linked | required |
|
||||
| `docs/fleet/migration/example-profile-disposition.md` | Disposition of every shipped example/profile | M1 | Inventory has no unresolved item at M1 exit | required |
|
||||
| `docs/fleet/migration/legacy-class-aliases.md` | Deterministic aliases and manual-review classes | M1 | Alias/unknown-role tests linked | required |
|
||||
| `docs/SITEMAP.md` | Navigation index | M5 | Link checker passes with all required pages | required |
|
||||
|
||||
## Cross-cutting acceptance checks
|
||||
|
||||
- [ ] Every documented command has stable text and JSON behavior plus an exit-code contract.
|
||||
- [ ] Every documented schema field is accepted by the executable validator, and every accepted field is documented.
|
||||
- [ ] Examples use synthetic non-secret values only.
|
||||
- [ ] Generated files are explicitly labeled non-authoritative and rebuildable.
|
||||
- [ ] Gateway-backed `mosaic agent` records are documented as a separate control plane; no implicit convergence is promised.
|
||||
- [ ] Local M1–M5 scope excludes remote/SSH reconciliation, connector mutation, secret-reference schema, arbitrary commands/channels, and UI/gateway config convergence.
|
||||
- [ ] Independent correctness, security, and validator evidence is linked before M5 acceptance.
|
||||
- [ ] Documentation links and formatting pass repository gates.
|
||||
@@ -1,57 +0,0 @@
|
||||
# #758 Legacy shipped example and profile disposition inventory
|
||||
|
||||
**Baseline:** `origin/main` at M0 planning time. This inventory is normative input to M1; M0 changes no examples or profiles.
|
||||
|
||||
## Allowed dispositions
|
||||
|
||||
1. **Migrate:** rewrite as v2 and validate with the executable schema plus the existing baseline/`roles.local` resolver.
|
||||
2. **Compatibility fixture:** retain as explicitly versioned v1 input for migration tests; it must not be advertised as current authoring guidance.
|
||||
3. **Retire:** remove only in its own implementation PR with a replacement and deprecation note.
|
||||
|
||||
No item may remain `decision-required` when M1 exits.
|
||||
|
||||
## Fleet examples
|
||||
|
||||
| Shipped path | M0 observed concern | Planned disposition | Target card | Required evidence |
|
||||
| -------------------------------------------------------------------- | ------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------- | ----------- | --------------------------------------------------------- |
|
||||
| `packages/mosaic/framework/fleet/examples/minimal.yaml` | Uses unresolved legacy `canary`; v1 field form also requires migration | decision-required: map through existing resolver, retain as compatibility fixture, or retire with replacement | FCM-M1-04 | Explicit M1 disposition plus v2 schema/shared-resolver CI |
|
||||
| `packages/mosaic/framework/fleet/examples/coding.yaml` | Legacy `implementer`/`reviewer` aliases may be present | migrate; preserve alias cases separately in migration fixtures | FCM-M1-04 | Alias conversion and current v2 validation |
|
||||
| `packages/mosaic/framework/fleet/examples/general.yaml` | Legacy/general classes require authority review | migrate or retire unsupported roles with replacement | FCM-M1-04 | No unresolved class |
|
||||
| `packages/mosaic/framework/fleet/examples/hybrid.yaml` | Mixed runtime/provider capability combinations | migrate | FCM-M1-04 | Runtime-capability and resolver validation |
|
||||
| `packages/mosaic/framework/fleet/examples/local-canary.yaml` | Local lifecycle and socket semantics | migrate | FCM-M1-04 | Default/named socket and stopped-state fixtures |
|
||||
| `packages/mosaic/framework/fleet/examples/operator-interaction.yaml` | `operator-interaction` becomes `interaction`; Tess remains instance data | migrate | FCM-M1-04 | Alias test and interaction role resolution |
|
||||
| `packages/mosaic/framework/fleet/examples/research.yaml` | Legacy `analyst` may lack canonical contract | decision-required: map through existing resolver or retire | FCM-M1-04 | Explicit M1 disposition; no silent alias |
|
||||
|
||||
## System-type profiles
|
||||
|
||||
| Shipped path | M0 observed concern | Planned disposition | Target card | Required evidence |
|
||||
| ------------------------------------------------------------------ | ------------------------------------------------------------ | ---------------------------------------------------- | ----------- | -------------------------------------------- |
|
||||
| `packages/mosaic/framework/fleet/profiles/software-delivery.yaml` | Must represent required governance seats or explicit waivers | migrate | FCM-M1-04 | Full-profile topology validation |
|
||||
| `packages/mosaic/framework/fleet/profiles/business.yaml` | Classes must resolve through shared resolver | migrate or document waived-class policy | FCM-M1-04 | Profile validation parity |
|
||||
| `packages/mosaic/framework/fleet/profiles/marketing.yaml` | Classes must resolve through shared resolver | migrate or document waived-class policy | FCM-M1-04 | Profile validation parity |
|
||||
| `packages/mosaic/framework/fleet/profiles/personal-assistant.yaml` | Interaction/orchestration authority must remain bounded | migrate | FCM-M1-04 | Authority and topology tests |
|
||||
| `packages/mosaic/framework/fleet/profiles/research.yaml` | Potential legacy analyst/worker class ambiguity | decision-required: resolved local role or retirement | FCM-M1-04 | Explicit M1 disposition; no unresolved class |
|
||||
|
||||
## Shipped fleet service presets
|
||||
|
||||
| Shipped path | M0 observed concern | Planned disposition | Target card | Required evidence |
|
||||
| -------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------- | ---------------------------------------------------------------------------- |
|
||||
| `packages/mosaic/framework/fleet/services/operator-interaction.yaml` | Uses legacy `operator-interaction` class/tool policy and launch hints; it participates in the interaction/Tess launch contract even though it is not an example/profile | migrate to canonical `interaction` through the shared resolver, preserving Tess as instance data; retain legacy alias coverage in a dedicated compatibility fixture | FCM-M1-04 | v2 schema, shared resolver, runtime-capability, tool-policy, and alias tests |
|
||||
|
||||
No other shipped file currently exists under `packages/mosaic/framework/fleet/services/`. Future service presets added before FCM-M1-04 must be inventoried under the same migrate/compatibility/retire rule.
|
||||
|
||||
## Required compatibility fixtures
|
||||
|
||||
M1/M4 may add dedicated test fixtures rather than retaining public examples in an obsolete form:
|
||||
|
||||
- v1 snake_case and camelCase equivalents;
|
||||
- deterministic `implementer → code`, `reviewer → review`, and `operator-interaction → interaction` aliases;
|
||||
- ambiguous `worker`, `analyst`, `canary`, and unknown classes that fail pending explicit resolution;
|
||||
- schema-only `host`, `ssh`, `socket`, and top-level `connector` fields reported as unsupported for local v2 apply;
|
||||
- the observed 9-roster/12-projection mismatch represented synthetically, with three unmanaged/orphan candidates;
|
||||
- running, stopped/dead, and unknown observed-state migration cases;
|
||||
- legacy generated, allowlisted local, forbidden command/channel/credential, and unknown env keys using names and synthetic hashes only—never values.
|
||||
|
||||
## Exit rule
|
||||
|
||||
FCM-M1-04 cannot close until every inventoried example, profile, and service preset is migrated, retained as a versioned compatibility fixture, or retired with documented replacement evidence. CI must validate all shipped YAML/JSON examples, profiles, and service presets through the same executable schema and shared profile/persona resolver used by roster load, migration, and apply.
|
||||
@@ -0,0 +1,238 @@
|
||||
# Tess / Option 2 runtime-portability qualification — 2026-07-14
|
||||
|
||||
**Issue context:** #706–#711 and runtime-neutral Mos follow-up #754
|
||||
|
||||
**Qualified revision:** `d0771835542d` (`origin/main` at review time)
|
||||
|
||||
**Reviewer/runtime:** Independent Pi lane requested as `openai-codex/gpt-5.6-sol:high`
|
||||
|
||||
**Runtime resolution note:** Mosaic warned that `gpt-5.6-sol` was not present in the provider model catalog and proceeded with it as a custom model ID. This warning was part of the original qualification log and is material provenance; downstream claims must not treat catalog recognition as verified.
|
||||
|
||||
**Verdict:** REQUEST CHANGES
|
||||
|
||||
**Evidence type:** Point-in-time qualification; later commits and PR #757 must be reviewed separately
|
||||
|
||||
## Purpose and provenance
|
||||
|
||||
This report preserves the complete independent qualification that was previously available only in `/tmp/tess-option2-qualification.log`. It distinguishes passing component tests from the missing operational proof required for identity-continuous Mos failover.
|
||||
|
||||
No credential values, OAuth tokens, Discord tokens, device codes, or auth-file contents are included. Commands and results are retained so another environment can reproduce or challenge the findings.
|
||||
|
||||
---
|
||||
|
||||
# 1. Verdict
|
||||
|
||||
## **REQUEST CHANGES**
|
||||
|
||||
The current Option 2 implementation is a useful portability foundation, but it is **not qualified against AC-TESS-01..11** and is not equivalent to true same-Mos-identity failover.
|
||||
|
||||
Primary blockers:
|
||||
|
||||
1. **AC-TESS-01/02:** The required `mosaic tess` command does not exist; only `mosaic interaction` is registered (`packages/mosaic/src/commands/interaction.ts:60`). The cross-surface test proves CLI enrollment followed by Discord approval/stop, not bidirectional Discord/CLI chat streaming.
|
||||
2. **AC-TESS-04:** Fleet/tmux and Matrix providers are implemented as libraries but are not registered in the production gateway. `AgentModule` registers only Hermes (`apps/gateway/src/agent/agent.module.ts:34`).
|
||||
3. **Mos handoff is not operational or durable:** Production uses `InMemoryInteractionCoordinationPort` (`apps/gateway/src/coord/coord.module.ts:18`), with no Mos-side consumer. Restart loses handoff ownership, idempotency, activity, and results.
|
||||
4. **AC-TESS-06/10:** Restart tests are good local persistence tests, but no real connector/harness failover or exercised rollback exists. Rollback is documentation-only.
|
||||
5. **AC-TESS-08:** The parity suite validates a selected shared intersection using mocked transports. Matrix is not production-wired and tmux drops the runtime message idempotency key before delivery.
|
||||
6. **AC-TESS-09:** M5 qualification remains `not-started`; no live Discord, Matrix homeserver, tmux/Mos consumer, Claude Code/Pi/Codex failover, or deployment rollback was tested.
|
||||
7. **PR #750 mismatch:** Its description promises send-error coverage as HTTP 400, but both gateway and TUI test use HTTP 403 (`packages/mosaic/src/tui/gateway-api.interaction-errors.test.ts:25-34`).
|
||||
|
||||
### AC disposition
|
||||
|
||||
| AC | Result | Evidence |
|
||||
| --- | ----------------- | ------------------------------------------------------------------------------- |
|
||||
| 01 | **Fail** | No `mosaic tess`; no bidirectional same-session chat/stream E2E |
|
||||
| 02 | **Fail** | Generic CLI exists, but fleet/Matrix providers are unreachable in production |
|
||||
| 03 | Pass | Pi profile/model/reasoning/effective-policy tests passed |
|
||||
| 04 | **Fail** | No registered fleet provider or real Mos consumer |
|
||||
| 05 | Partial | Hermes normalization/fail-closed matrix passes; live capability path is limited |
|
||||
| 06 | Partial | PGlite restart/idempotency passes; no actual harness failover |
|
||||
| 07 | Partial | Focused denial/replay tests pass; full M5 abuse qualification absent |
|
||||
| 08 | Partial | Mocked shared-intersection parity passes; Matrix not operationally wired |
|
||||
| 09 | **Fail** | Baselines/CI green, but required E2E/security/rollback qualification absent |
|
||||
| 10 | **Fail** | Inventory incomplete/inconsistent; rollback not exercised |
|
||||
| 11 | Pass/ledger stale | Documentation and sitemap exist; plugin/catalog ledger remains unresolved |
|
||||
|
||||
---
|
||||
|
||||
# 2. Exact test commands and results
|
||||
|
||||
Initial focused attempts failed before collection because this detached worktree had no dependencies:
|
||||
|
||||
```bash
|
||||
pnpm --filter @mosaicstack/agent exec vitest run ...
|
||||
```
|
||||
|
||||
Result: startup failure, `Cannot find module 'vitest/config'`.
|
||||
|
||||
Setup used:
|
||||
|
||||
```bash
|
||||
corepack pnpm --store-dir /home/jarvis/.local/share/pnpm/store/v10 \
|
||||
install --frozen-lockfile --ignore-scripts
|
||||
```
|
||||
|
||||
Result: PASS, 1,240 packages linked.
|
||||
|
||||
```bash
|
||||
corepack pnpm turbo run build \
|
||||
--filter='@mosaicstack/gateway^...' \
|
||||
--filter='@mosaicstack/mosaic^...'
|
||||
```
|
||||
|
||||
Result: **17/17 dependency builds successful**.
|
||||
|
||||
### Focused suites
|
||||
|
||||
```bash
|
||||
corepack pnpm --filter @mosaicstack/agent exec vitest run \
|
||||
src/runtime-provider-parity.test.ts \
|
||||
src/matrix-native-runtime-provider.test.ts \
|
||||
src/tmux-fleet-runtime-provider.test.ts \
|
||||
src/durable-session.test.ts \
|
||||
src/hermes-runtime-provider.test.ts
|
||||
```
|
||||
|
||||
Result: **5 files, 39/39 tests passed**.
|
||||
|
||||
```bash
|
||||
corepack pnpm --filter @mosaicstack/gateway exec vitest run \
|
||||
src/agent/durable-session.repository.test.ts \
|
||||
src/__tests__/integration/tess-cross-surface.integration.test.ts \
|
||||
src/plugin/discord-ingress.security.spec.ts \
|
||||
src/coord/interaction-coordination.service.test.ts \
|
||||
src/coord/interaction-coordination.routing.e2e.test.ts \
|
||||
src/agent/hermes-runtime-reachability.e2e.test.ts
|
||||
```
|
||||
|
||||
Result: **6 files, 36/36 tests passed**. PGlite close/reopen recovery passed in 504 ms.
|
||||
|
||||
```bash
|
||||
corepack pnpm --filter @mosaicstack/mosaic exec vitest run \
|
||||
src/fleet/matrix-native-runtime-transport.test.ts \
|
||||
src/fleet/tess-service-profile.test.ts \
|
||||
src/commands/interaction.test.ts \
|
||||
src/tui/gateway-api.interaction-errors.test.ts
|
||||
```
|
||||
|
||||
Result: **4 files, 15/15 tests passed**.
|
||||
|
||||
```bash
|
||||
corepack pnpm --filter @mosaicstack/coord exec vitest run \
|
||||
src/__tests__/interaction-coordination.test.ts
|
||||
```
|
||||
|
||||
Result: **1 file, 7/7 tests passed**.
|
||||
|
||||
```bash
|
||||
corepack pnpm --filter @mosaicstack/gateway exec vitest run \
|
||||
src/agent/interaction.controller.test.ts \
|
||||
src/commands/command-authorization.service.spec.ts \
|
||||
src/agent/__tests__/runtime-provider-registry.service.test.ts
|
||||
```
|
||||
|
||||
Result: **3 files, 27/27 tests passed**.
|
||||
|
||||
Focused total: **124/124 tests passed** after dependency setup.
|
||||
|
||||
### Baselines
|
||||
|
||||
```bash
|
||||
TURBO_FORCE=true corepack pnpm typecheck
|
||||
```
|
||||
|
||||
Result: **42/42 tasks successful**.
|
||||
|
||||
```bash
|
||||
TURBO_FORCE=true corepack pnpm lint
|
||||
```
|
||||
|
||||
Result: **23/23 tasks successful**.
|
||||
|
||||
```bash
|
||||
corepack pnpm format:check
|
||||
```
|
||||
|
||||
Result: **PASS — all files matched Prettier style**.
|
||||
|
||||
```bash
|
||||
~/.config/mosaic/tools/woodpecker/pipeline-status.sh \
|
||||
-r mosaicstack/stack -n 1796
|
||||
```
|
||||
|
||||
Result: **SUCCESS** at `d0771835542d`; all test, build, sanitization, typecheck, lint, format, and publish steps green.
|
||||
|
||||
No tracked files outside the pre-existing `.mosaic/orchestrator/*` launcher changes were modified.
|
||||
|
||||
---
|
||||
|
||||
# 3. Stale ledger inconsistencies
|
||||
|
||||
1. `docs/tess/MISSION-MANIFEST.md` still says:
|
||||
- current milestone M1;
|
||||
- progress 0/5;
|
||||
- M2/M3/M5 not started.
|
||||
2. `docs/tess/TASKS.md` says:
|
||||
- M4-V failed;
|
||||
- M4-W-001 and TESS-PLG-001 in progress;
|
||||
- M5-V not started.
|
||||
3. Provider issue state conflicts:
|
||||
- #707–#709 remain open although M1–M3 rows are recorded done/pass.
|
||||
- #710 and #711 are closed although M4-V failed and M5-V is not started.
|
||||
4. M5 work was marked done despite depending on failed M4-V.
|
||||
5. TESS-M3-002 says `mosaic tess` is done, but only `mosaic interaction` exists.
|
||||
6. PR #750 removed stale service references from operational docs, but `docs/tess/TASKS.md` still contains `MosCoordinationService` in historical notes.
|
||||
7. `docs/tess/MIGRATION-INVENTORY.md` remains an “initial inventory” with several capabilities marked `adapt`; `M5-MIGRATION-INVENTORY.md` marks grouped capabilities deferred/fail-closed. Neither supplies the complete owner/evidence matrix AC-TESS-10 requires.
|
||||
8. TESS-M2-FUP-001 remains real: the unkeyed SHA-256 compatibility branch still exists at `durable-session.repository.ts:427-431`.
|
||||
9. TESS-PLG-001 claims catalog registration was folded into W-001, but production evidence shows provider registration in the gateway—not a completed `packages/mosaic` plugin catalog.
|
||||
|
||||
---
|
||||
|
||||
# 4. Gap to true same-Mos-identity failover
|
||||
|
||||
Current code can relaunch the same roster name under another runtime and can rebind a durable interaction session to another provider/runtime ID. That is **replacement**, not identity-continuous failover.
|
||||
|
||||
Missing pieces:
|
||||
|
||||
- No canonical logical Mos identity independent of harness-native session IDs.
|
||||
- No exclusive connector lease or monotonic fencing epoch; session rebinding is effectively last-write-wins.
|
||||
- No stale-holder rejection preventing the old harness from continuing side effects.
|
||||
- No normalized Claude Code/Pi/Codex checkpoint/import/export adapters.
|
||||
- No durable Mos coordination transport or Mos consumer.
|
||||
- No canonical handoff containing mission/task refs, git state, causal sequence, pending operations, capability requirements, and acknowledgements.
|
||||
- No end-to-end receipt journal across connectors.
|
||||
- Matrix has deterministic transaction IDs, but tmux delivery discards `RuntimeMessage.idempotencyKey`.
|
||||
- No fault-injection test transferring Mos among Claude Code, Pi, and Codex and then rolling back.
|
||||
|
||||
---
|
||||
|
||||
# 5. Minimal follow-up issue decomposition
|
||||
|
||||
| Order | Issue | Minimum acceptance criteria |
|
||||
| ----- | ------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| 1 | **Logical identity and security fencing** | Server-derived `{tenant, logicalAgentId, connectorId, harness, leaseEpoch, scopes, expiry}`; signed/fenced execution grant; stale/forged/cross-tenant grants denied and audited; no connector credential in handoffs |
|
||||
| 2 | **Durable connector lease** | PostgreSQL-backed exclusive lease with CAS, monotonic epoch, TTL/heartbeat, explicit takeover, and gateway rejection of stale holders; connectors for Claude Code, Pi, and Codex |
|
||||
| 3 | **Canonical handoff/checkpoint** | Versioned, sealed schema containing canonical mission/task/git references, checkpoint digest, causal sequence, required capabilities, pending/ambiguous operation references, and source/destination acknowledgement; no raw secrets or mandatory harness transcript |
|
||||
| 4 | **Exactly-once connector journal** | Durable operation IDs and receipts; idempotency propagated through every adapter; Matrix transaction mapping; tmux replaced or wrapped with receiver-side durable dedupe; ambiguous effects remain held for authorized reconciliation |
|
||||
| 5 | **Cross-harness failover and rollback E2E** | Real Mos identity moves Claude Code → Pi → Codex and back; inject crashes before/after lease transfer, handoff persistence, send, and acknowledgement; stale connector fenced; no duplicate side effects; canonical state preserved; rollback evidence published |
|
||||
| 6 | **Generic gateway research ADR** | Evaluate LiteLLM subscription OAuth and Bifrost concepts without adding either to core; include terms/security review, credential lifecycle, tenant mapping, budgets, failover semantics, and adapter-only prototype |
|
||||
|
||||
## Generic gateway placement
|
||||
|
||||
Allowed topology:
|
||||
|
||||
```text
|
||||
Discord / CLI / web
|
||||
↓
|
||||
Mosaic Gateway: auth, tenant scope, policy, approvals, audit
|
||||
↓
|
||||
IProviderAdapter / AgentRuntimeProvider
|
||||
↓
|
||||
optional LiteLLM or Bifrost egress proxy
|
||||
↓
|
||||
upstream provider
|
||||
```
|
||||
|
||||
- **LiteLLM ChatGPT subscription OAuth:** research-only, opt-in, behind an adapter. Subscription credentials require explicit terms, revocation, scope, token-storage, and audit review. They must never become Mosaic identity or core configuration.
|
||||
- **Bifrost:** virtual keys are downstream proxy credentials, not Mosaic principals. Budget and failover concepts may inform Mosaic routing, but tenant policy, authorization, and audit remain in Mosaic.
|
||||
- Neither product may introduce schemas into Mosaic core, receive direct calls from channels/agents, or bypass `IProviderAdapter`/`AgentRuntimeProvider`.
|
||||
- Mosaic should also correct its existing “all providers unhealthy → use one anyway” fallback behavior before adopting more automatic failover (`routing-engine.service.ts:204-212`).
|
||||
Reference in New Issue
Block a user