# ROADMAP — agreed path forward Status: planning aligned with owner 2026-09-03. Feature work follows this order unless the owner re-orders. Design notes below are commitments about intent, not implementation — each milestone still gets its own issue, tests, and BUILD-LOG phase. ## Standing decisions (owner, 2026-09-03) - **Pi is the main TUI harness** and the reference checkpoint. Multi-harness (Codex, Claude, OpenCode) comes after pi is stable as the primary seat. - **CI is deferred.** Gitea runs on slow hardware; local suites + verify are the quality gate. Revisit when code volume justifies runners. - **The user never manually runs release.sh.** The system determines what is installed and self-aligns (M16). - **Tooling documentation is agent-accessible** via the ms-tools skill (M17), referenced from AGENTS.md. - **Capability restriction becomes progressive and role-based** (M18), porting prior Mosaic Stack concepts where they fit the file-based runtime. ## M16 — Release self-determination Problem: after `reset.sh` the activation pointer is gone and the owner had to know about `scripts/release.sh activate`. The system must determine what is actually installed. Design: - New `release.sh ensure` (also invoked automatically by the launchers via `common.sh`): compares desired (`RELEASE`) vs packaged image vs active pointer. - Fast path (drift = pointer missing/mismatched, image already packaged): restore the pointer without a health gate — the release was previously health-gated; reset is data loss, not a new release. - Slow path (new version in RELEASE, or image missing): package beside → full health gate (exact-marker model run) → atomic pointer swap. This is the M3 gate-then-flip, now automatic. - Acceptance: post-`reset.sh`, the next `hello.sh`/`agent.sh` self-restores activation with zero manual release commands; a bumped `RELEASE` auto- activates after its health gate; a failing health gate leaves the previous release active and records the refusal. ## M17 — ms-tools skill + role-scoped skill lifecycle (DESIGN REVISED per owner) Problem: agents without supplied tooling invent their own, even when a functional method exists. Skills must reach non-conductor seats as role-scoped subsets, with an explicit lifecycle. Design (owner-specified): - Two machine-scoped directories under the data root: - `/skills-enabled/` — loadable by agents - `/skills-available/` — installed but disabled - Lifecycle: **install** → available · **activate** → enabled · **deactivate** → back to available · **uninstall** → removed. A skill not in skills-enabled is not enabled or available for use. - Launch resolution: role contracts declare skill NAMES; the runner resolves each against skills-enabled and passes `--skill ` explicitly. `--skill` necessarily negates `--no-skills` (explicit provision wins). Contracted-but-not-enabled → **refuse the launch loudly** (a silently under-equipped seat is the exact failure mode this prevents). - Containerization removes ambiguity: agents get only what is explicitly provided; no discovery, no ambient skill leakage. - Interfaces: CLI first (`mosaic skill install|activate|deactivate|uninstall|list`), TUI and WebUI frontends call the same tooling later. - The ms-tools skill is the first shipped skill (tooling reference for conductor/vanilla sessions); role contracts then grant subsets per seat. ## M18 — Seat-role progressive capability restriction Problem: capability restriction exists but is per-task/per-mission only. Seats (agent identities) need governing ceilings that tasks cannot escalate past — the M9 intersection chain extended: **role ceiling ∩ mission grant ∩ task grant = effective**. Design: - `roles/.json` (role contracts, tracked): `roleVersion`, `name`, `tools` ceiling (subset of pi built-ins), `network: "none"|"api-only"|` `"open"` (declared now, enforced when network policy lands), `paths` (future). - Resolution chain in the runner: seat role contract ∩ mission capabilities ∩ task capabilities → effective tools (existing intersection logic, one more link). Empty at any stage = tool-free run, loudly recorded. - agent.json keeps `role` (already shipped in M15) — it now binds to `roles/.json`. - Porting note: prior Mosaic Stack role/policy concepts inform this design, but implementation is fresh on the file-based runtime (the standing repository exclusion applies until the owner points at specific prior files to port). - Adapters unchanged: `MOSAIC_TOOLS` already carries the effective set. ## M19 — Harness auth tooling (pi checkpoint) Problem: auth is manual (`/login`, `auth.json`); multi-account and multi-harness stacking have no tooling. Current facts (observed): one `auth.json` holds multiple providers (anthropic, openai-codex, zai observed on the host) — provider stacking already works. Multiple accounts per provider is the open question (the owner runs two Claude accounts; openai-codex multi-account desired). Design direction (pi-first checkpoint): - `scripts/auth.sh status` — per-provider auth report (which providers have credentials, source: auth.json vs env), no secrets printed. - Multi-account: investigate pi's auth schema for per-provider account entries; if unsupported natively, model accounts as named auth files (`auth..json`) with a conductor-level selector — runtime-injected per launch, same pattern as the read-only credential mount. - Claude/Codex/OpenCode adapters stay parked; the auth tooling is harness-neutral so it serves them when they arrive. ## M20+ — Unified `mosaic` CLI and the stack succession path Direction (owner): a unified `mosaic` CLI (`mosaic --check`, `mosaic tui`, `mosaic yolo `, `mosaic skill ...`, `mosaic release ensure`, ...). Much larger task; channel-dispatcher doctrine harvested from `fleet/bin/mosaic` (HARVEST.md #1). Succession trajectory (owner): the v2 line is actively building the REPLACEMENT for the mosaicstack/stack repo. At the appropriate level of usurpation, v2 content becomes THE next-branch content on mosaicstack/stack — a full refactor-and-replace with a functional system. Not ready yet. Open decision at usurpation time: whether v2 reorganizes to the stack monorepo layout (`packages/*` — continuity with existing tooling) or keeps its flat structure and defines the new convention (clean break). Reference for either: harvest worktree `~/src/mosaic-stack-worktrees/v2-harvest` (branch `next` @ 0db2d19a) and `packages/mosaic` (CLI), `packages/auth`. Usurpation criteria to be defined before any replacement (proposed: functional parity of P0 operations on the v2 runtime + owner sign-off). ## Explicitly deferred - CI runners (owner: Gitea hardware is slow; local suites are the gate) — revisit as code volume grows. - Network egress policy enforcement (declared in role contracts at M18; enforcement is its own milestone). - Push automation (push stays an explicit act). - Second real adapter; fleet/multi-agent; knowledge storage; portal. ## Completed reference (see docs/plans/CURRENT.md log) M1 config-driven hello · M2 missions/tasks · M3 release model · M4 adapter seam · M5 workspaces/capabilities · M6 sessions · M7 ergonomics · M8 conductor loop · M9 mission capability policy · M10 retention · M11 session forking · M12 auto-apply policy · M13 interactive TUI agent · M14 live user context · M15 agent seats + roles/ convention.