Aller au contenu

Roadmap — remaining delivery work

Outcome and status

As an organization, I run my agent workforce on infrastructure I control. Agents, Routines and tasks run as governed workflows across my computers, master VPS and enrolled servers; evaluators score and route the work; every configuration and policy change is previewed, confirmed and receipted. Agents operate the system within their grants through the CLI, SDK, MCP and API; people confirm consequential changes and manage the system through a personal agent by chat or voice, or through the terminal, Desktop, mobile and, after S52's decision, web. The master VPS is the authoritative Control Node in this deployment; closing Desktop does not lose server-owned work. Missing connectivity must never look like success. The global Maia coordinator belongs to the user within that authority; clients share its durable history, not mutable focus. All product views migrate to the shared json-render catalog, with Jev-backed adaptive composition and independently bounded UI engines. Renderer/provider faults and noisy clients must not stop admitted Maia/worker execution or starve healthy clients; qualification uses explicit measured budgets, not a zero-contention claim.

Meta harness (D-123). Maia is also the meta harness: through the Node, Sessions of any supported harness (Codex, Claude Code, Pi, the Maia agent, ACP agents) message, ask, hand off to, delegate to and share context with Sessions of any other harness, first on one Node, later across Nodes. Each is a Node-owned operation (S17, S28, S29, S40–S42): the Node stamps the sender and owns order, delivery, authorization and receipts. No harness talks to another directly, and no vendor feature becomes authority.

Product direction (owner, 22 October 2026). Maia is an AI operating system for organizations, self-hosted: one Node is the single source of truth, and clients, agents and harnesses are replaceable. It stays simple at any size (a five-person team starts from the defaults and a large enterprise grows the same model) and open to any harness and model, closed frontier, open-weight or custom. Every operation ships in the CLI first. A personal agent serves power users who want control, not a mass-market chat app. The priorities: Maia is enterprise-first, not a chat manager. It manages workflows: Agents, Routines and tasks (S49–S53), with evaluations, scorers and routers (S8, R10a, R10b, S62) routing, ranking and scoring the work a person would otherwise sort through in a chat; a person still confirms consequential changes. The organization layer is mostly configuration and policy management (E5): every change previewed and receipted, and confirmed by a person or a standing approval (S67). Chat and voice, including the personal agent, are a thin human layer over the same operations. Improvement goes beyond revising Skills, Routines and workflows: decisions and usage become datasets that tune custom models for a company's agents, evaluators and routers (S68). Replacing the maintainers' daily Pi harness (R11) stays a dogfood milestone, not the product outcome. Work follows the delivery plan.

This is the remaining-work plan, not a list of shipped features. Completed foundation work is removed from the backlog; reuse it rather than reimplementing it. Historical scope and preserving migrations are recorded in Workspace hierarchy delivery; the operation registry and maia help --json own source availability. A tested source candidate is not automatically release-qualified. In particular, existing Project metadata code needs its outstanding acceptance closed, not a second implementation. No runtime test is claimed by this documentation update.

  • Planned: bounded work may start after its listed entry conditions (entries below that say Next mean this).
  • Dependent: implement after the specified contracts/slices pass.
  • Blocked: named evidence or authority is missing; denial remains enforced.
  • Later: not on the first complete portfolio journey's critical path.

The executable acceptance specification is split into portfolio user stories and portfolio dogfood suites. The suites are specified, not yet all implemented or passing. Each owning slice must add its runnable tests, commands, fixtures and evidence before claiming completion.

Scope and non-negotiable boundaries

  • Workspace exclusively names the organizational scope grouping Projects; Execution Environment names a checkout, Git worktree or admitted private working directory. Execution Node is the host; Execution Profile is its permission/containment policy. None of these labels grants team or execution access. Current container.*/container_* organization and workspace.*/workspace_* execution contracts retain their meaning through R1b's versioned transition and required deprecation window. Preserve existing IDs, events, receipts, repositories and filesystem identities.
  • One Control Node owns durable truth across these Workspaces. In the requested deployment it runs on the master VPS, with optional workers on that host (not in the first version, where no Session runs on the control Node's host). Desktop is the full client; its computer runs an enrolled Execution Node for local-to-the-user work. Additional servers are enrolled capacity. “Local” is labelled relative to the actual host, never guessed from the client location. Multiple independent Control Nodes are not required for this pool.
  • For v1, the user approved vendor executors as workers: Codex CLI through codex app-server and Claude Code through the Agent SDK driving the installed claude, each bound to a named account and contained by the vendor sandbox that Maia configures (decision record). Approved (D-116, D-118): OpenShell replaces that containment as a mandatory dependency of every Node (S47); the vendor sandbox stays until S47 ships. Maia Agent remains the native worker backend for later slices; existing official Pi integration is reused behind its narrow adapter. Other installed harnesses remain separately reviewed adapters, not ambient discovery or implied new dependencies.
  • Maia, Workspace and Project coordinators are separate owners/principals with isolated history, memory, grants, credentials and activation resources. Maia discovers its authorized Workspaces; a Workspace discovers only its own Projects; a Project coordinator cannot discover siblings (a Session's bounded peer directory under D-166 grants no history, tools, credentials or delegation). Human portfolio access is not inherited by any brain. Cross-scope work uses parent-mediated delegation, not lateral peer bridges. Shared kernel code and one trusted Node do not merge owners. See the ownership contract.
  • CLI/API/SDK must manage every supported control action without Jev, voice, or coordinator agents. No coordinator needs to be created/woken for manual work. Optional intelligence cannot grant authority or invent completion.
  • CLI first. Every operation ships through the protocol registry → public SDK → Node → built CLI first; its MCP tools and HTTP API are generated from the same registry or mechanically checked against it. Agent, voice, Desktop, web and mobile projections of an operation follow only after its CLI path passes the slice's acceptance, and a client never adds an operation the CLI lacks. Presentation-only features (theme, keyboard use, dictation) have no CLI surface. Use Effect services/layers, scoped resources, typed failures and interruption; React only renders.
  • Consequential changes preserve preview, trusted confirmation, revisions, idempotency and receipts. Spoken “yes” does not replace human-only confirmation. “All my Projects” is an authorized paginated read, never an unbounded mutation.
  • Text is the default composer in every global, Workspace/Project coordinator, worker and ordinary Session. Voice is an optional input/output mode for the same exact target, not a separate chat or mandatory global-coordinator hop. Mic is off until explicit activation. All supported voice actions have text controls; voice/provider/permission failure leaves text available. See PF-18/DF-18.
  • Voice and bounded automation are now in the product backlog, superseding their deferral in the original hierarchy-only slice. The user additionally selects json-render for full product-UI composition and Jev for adaptive presentation. R9a must qualify exact official package versions, transitive closure, Effect Schema compatibility and platform parity before dependency changes. This docs update installs nothing and approves no unrelated dependencies, microphone capture, paid calls, credentials, live migrations/restarts, remote-host access or deployed services.
  • Keep raw audio unretained and transcript persistence opt-in. Artifacts, source text, model output and external events are data, not permission or instructions to bypass the control plane. Read access does not imply provider-export consent.

Delivery plan

The order follows the product direction. Phases overlap: a slice starts once its own dependencies hold, and slices within a phase run in parallel where they can. Each line names the slice, its status and what it waits for; the linked section owns its deliverable, entry conditions and acceptance, and a slice is done only when that acceptance passes. Every slice ships CLI first: a Desktop, web, mobile or voice view of an operation starts only after its CLI path passes, and views that need the web client (S52) wait for Phase 5. Done work is in completed slices, source organization and Effect boundaries.

Parallel lanes and critical path

Agents build in parallel: one unit of work (one operation end to end) per worktree and pull request, under the self-hosting rules. The phase lines below own each slice's dependencies, and a slice starts the moment they hold; the SH1 planner derives readiness from them. Lanes say which slices share code and run side by side. Canary-only publishing (D-185) is a source candidate and the dogfood Node then runs each canary (RL1). These lanes and the phase lines are the one delivery order: "Start now", the first-version table, the ready-to-develop sequence and R11's admissions are views over them and add no other order. A source candidate needs qualification, not reimplementation.

PD0 parallel delivery, first. Today nearly every new operation edits the same few files, so parallel pull requests conflict and rebase each other. One short serialized window fixes that:

  • The CLI bundle test pins exact bytes, a hash, the unpacked size and the entry count, under a hard ceiling raised only by measured growth, to 385 KiB at most (D-181). PD0 sets an explicit budget for the remaining roadmap with a recorded reason, or splits the bundle, and keeps only that budget plus M0's per-change record.
  • The existing per-feature registry (MAIA_FEATURE_REGISTRY, 90 of about 176 methods) grows to every method, so the method list, exposure map, contract unions and export barrels are assembled from it. The public-export snapshot and CLI grammar digest are kept per feature.
  • Counts pinned in tests (feature registry, receipt list, the reviewed coordinator tools, the Desktop method allowlist) are derived from the registry.
  • The lint baseline is split by rule; it still only shrinks.
  • CI handles a merge_group trigger in change scoping and its workflow test, so the owner can turn on a merge queue; a merge queue and a code-owners file stay optional repository settings (D-124).
LaneSlices, in dependency orderLeads to
Workflow runtimeS26, S28, S29, S30; S27, S49, S17, S42's show and handoff, S19's convergence; S50; S51, S53, S65, S55, S63, S48; S60a, G1, S69, S54; S60's harness switching, S21, S42's previewsFV, then SH1
Containment and harnessesS13, S11b, S47a; S47b on Linux, then macOS; R2, S57b, S47c with each harness, S23 then S12c for Pi, S25, S31–S41; S47e, S47f, S47d; R11SH2
IntegrationsS24 for Pi and Maia agent, S57a; S61a; S75, S71; S73a–S73f, S61b, S72; R5; S43SH2
Observability and controlT0–T3, S56, S15, S20, S70, S12t, S12r, S12e, S12f, S16, CE1; S59, R8a; S74; the rest of R8, T4–T7SH2
Release and fleetRL0–RL3; RL2's handshake, RL4, RL8, MN0, S7; RL6, MN1, S58, MN2–MN5 (R6), S66, S9; RL5, RL7, self-managed recipesSH3
First versionFV1–FV11, with MN1, its minimal placement slice, E2a's Linux backend, S12e and S12f's summaryCutover
FoundationPD0, DX1–DX7, R0, SO, DEP, TQ, EF2, M0, R1, SDK1, TC1; qualifying S10, S11, S12d, S14, S18, S19, S22, S44, S45 and CLI1; R1b, R3Every lane
Foundations trackF0–F10Every lane
Agent integrationAI0–AI3FV
Routines and triggersRT0–RT3, LB1FV, then Cutover
Zero-impact updatesZU0–ZU3RT3
Organization and enterpriseBootstrap, S2, E1, E2a; ORG1, ORG3, E5's model; ORG2, ORG4–ORG7, E2–E4, E5's joinsEnterprise
IntelligenceR10a; S8, R10b, S62; S68, R4, S67Phase 3, 5
ClientsS46 and DP1 qualification, S12d's pushed terminals; DP2a; DP2b pages, DP2c, S52, S64, R7, R9, R9a, R1aPhase 5
Rust terminal/process hostRN0; RN1 (alongside the terminal track)Terminal multiplexer
Terminal multiplexerEV0–EV7, MP0–MP5, TM0, TM1a, TM2a, TM3, TM11; TM2b; TM4; TM5–TM9 with D1-prep, D1a0–D1a2, D2a–D2c; TM1b; TM10; D1b and later views after S50, S60a, S59, G1FV

A remaining slice missing from this table is a defect the SH1 planner reports. "FV" is the first version; "Cutover" is the first production migration.

Critical path (each arrow waits for what precedes it):

  • S30 → TM9; TM0–TM11, the terminal multiplexer (D-175), then with S2 → FV1–FV11 (with MN1, its minimal placement slice, E2a's Linux backend, S12e and S12f's summary) → the lab → a short soak on Maia's own repository → the production migration (D-150)
  • S47a → S47b on Linux → S61a's Connection and reads (the cutover path takes the first version's key-custody rule instead, D-150)
  • S30 → S49 → S50 → S53 and S65 → S60a and S75; S2 and S49 → S61a's Agent writes
  • R1 → R3 → R8a; T1–T3, S56's run spans and R8a → S74; S74 and S61a → SH2
  • RL0–RL3 → RL4 → RL6 (with S70) → SH3

Milestones, in order: SH0 now, the terminal multiplexer, the first version, the production migration (D-150), then SH1, SH2 (the production deployment's read-only shadow runs beside it) and the breadth of Phases 3–6. Neither the first version nor the cutover waits for SH1 or SH2.

The milestones end at the public launch, around early 2027. Maia stays on the canary channel before and after it (D-202): there is no stable release, and latest names the newest canary.

Early dogfood checkpoint (D-183): ship an installable Linux-hosted Claude Code/Codex path before full Alpha 1. Qualify its client, fleet routing, panes, approvals, manual/scheduled Project Routines and disconnect/restart recovery on Maia's own repository; publish commands and gaps. Then migrate daily workflows gradually, one scheduler per job. Full Alpha 1 and production migration retain their gates; each supported workflow keeps the existing security and credential-custody requirements.

Start now

Entry conditions hold and no owner decision is pending:

  • Foundation tracks: R0 acceptance closure; SO0, SO1 and SO1a; DEP0, DEP1 and TQ0; M0b, M0c and M0d; R1 portfolio reads and schema-only inspection; R10a offline contract work (sequence).
  • Enterprise: E1 disclosure, scanning, threat model and review gates (licensing, support period and signing wait for decisions) (enterprise); the first-owner bootstrap, building the specified team Workspace (a rename is a later migration; specification).
  • Swarm: S2 grants (S2a is done); S15 and S17 (wave 3); S13 (wave 4); S16 lock kind; S20 capability enablement registry (Node holds wait for MN0, capability holds and capability.revoke for that registry); S12t trace without content (D-168), then S12r purge on archive and after 30 days (D-128) (v1 table).
  • Workflows: S26, S28's metadata search (its content reads after S12t), S29 and S30, then S23 Pi on Linux host containment (macOS after R2; its OpenShell sandbox with S47c) (harnesses).
  • Secrets: E2a (D-122).
  • Release: RL0–RL3; RL8's security mark, daily scan and runbook (distribution).
  • Agent gates: DX4's Dependabot alert triage before new feature slices (D-126), then DX1, DX3 and DX7 with PD0 (DX).
  • Parallel delivery and dogfood: PD0 first, then SH0 (self-hosting); then the terminal multiplexer, the first version and the production migration's critical path first (first version, production migration).
  • Terminal multiplexer (Alpha 1): TM0, TM1a, TM2a, TM3's Session streams, TM9's routine run and TM11 (terminal multiplexer).
  • Rust terminal and process host: RN0 once the toolchain is installed (native track, D-182).
  • First version: after the terminal multiplexer (D-175), FV2, FV6 and FV7 start from main; the rest follow the prerequisites the section names.
  • Observability: T0–T2 and S56, T3 once S19 and S22 qualify (telemetry).

Decisions that block work

The critical path's owner decisions are settled (D-056 and D-118 to D-128, 22 October 2026), except the worker transport and the screen engine.

DecisionUnblocks
Worker transport: how a worker reaches its control Node (first version, D-150)FV remote workers, MN1 placement
Screen engine, picked from TM0's measurements (D-175)TM2b
Browser client decision entry, deferred until DP2 ships (owner, 22 October 2026)S52, S64, web views of S56/S59/S67
Node-sent goal continuations where a harness has no native goal (D-123)S69
One Session spanning harnesses (open; separate Sessions need none)S60 continuity
Standing approvals, global owner kind, focus memory, voice rulesS67
R10a's exclusion of worker toolsAgent eval tools in S62
Provider terms for training, training service, personal dataS68
S8 dependency, Gateway key and paid callsS8
LICENSE, support period and release signing; CRA product class (counsel)E1 licensing and signing, E4
Organization aggregate, roles and their reach, owner recovery, identity modelORG1–ORG7
License and seat model for self-hosted installsORG5 seats
A managed client credential (pairing is D-056)ORG1, tailnet paths, remote clients
Extension manifest, first-party location and signing (D-114)S73, S61b
One egress mechanism for outbound calls (D-071 per connector)S72, outbound webhooks
Executor approvals (S31, S33, S34); account pool decisions (S43); M0eThose slices
Advisory feed host, signing key and its custody (own key or release signing)RL8 feed and verification
Default security auto-apply policyRL8 auto-update
Revocation's reach: warn, refuse to start, or stop a running NodeRL8 revocation
Third-party release-age exclusions (D-016, D-065): keep or make exactDEP3

Self-hosting — SH0–SH3

Maia's own development is its first production deployment (plan), one step ahead of production:

  • SH0 now, on shipped source candidates and with no pending decision. A coordinator through maia mcp plans units as a run ledger graph; Codex and Claude Code worker Sessions edit one unit each in their own worktree; the coordinator pushes each branch to a fork without running its code, so CI runs it with a read-only token and no secrets; a branch changing .github/ waits for a person first; a person reviews and merges. Owner direction (23 October 2026, D-150): SH0 runs as soon as possible on a server, on a Node driven through the canary CLI that replaces the current agent platform there, and agent work on this repository moves onto it.
  • SH1 after S49, S50, S53, S65 and R8a: Maia's planner (on a schedule and on demand), builder and review Routines run the roadmap, still pushing through SH0's path.
  • SH2 after S61a, S47b, S57a and S74: this repository is the first production deployment, with GitHub through Maia and no person's credentials in a launch.
  • SH3 after RL6: the dogfood Node takes each canary that passes its gates without losing a run.

Terminal multiplexer — TM0–TM11

Planned, first (owner direction, 28 October 2026, D-175). Maia's own terminal multiplexer, in Rust, for macOS, Linux and Windows, using less CPU, memory and disk per terminal than tmux. It runs on D-141's Nodes over SSH, and needs neither the worker transport nor MN1.

Alpha 1 is TM0–TM11 with S30 qualified. From one terminal, a person and their agents:

  • run Claude Code and Codex on several servers;
  • attach and detach from any computer;
  • manage Project Routines grouped by Workspace, without naming a server.

Each action is a CLI command with JSON output, and a model tool unless it is human-only, like a person's terminals (D-178). Workspace-owned Routines follow R3.

SliceDeliverableWaits for
TM0Source candidate (#100, #107): benchmark pnpm metrics --suite terminal (suite) against tmux, GNU screenmain
TM1aDone, Source candidate (#111): Linux terminals: PTY path, interactive tier, shell allow-list, a program instead of the shellmain
TM1bWindows terminals through ConPTY; amends RL7's exclusion of a native Windows NodeTM1a's contract
TM2aDone, Source candidate (#110): output in a bounded memory buffer, never in SQLite; a Node restart loses itmain
TM2bRust screen engine per terminal in the process host: snapshots, text reads, waits, framesTM0's engine pick; TM2a to qualify
TM3Items over one SSH bridge: Source candidate (#119); frames, full frame after lag, dimmed panes: after TM2bmain; RL2 to qualify; frames: TM2b
TM4Rust client and maia terminal attach <id>: one pane, extended keys, mouse, resize, controller takeover, detachTM2b, TM3
TM5Panes and tabs: splits, focus, zoom, resize, prefix key, closing a pane apart from its terminal, layout restoreTM4; D1a2
TM6Workspace and Project views: a sidebar from a Node attention read, a tab per Project, go-to by state, Session panesTM5; D1a1, D2a, D2b
TM7Agent terminals: an agent opens, writes to, reads, waits on, closes and lists its own, as model tools and maia terminal commandsTM2b, TM6, S12t
TM8Copy mode: vi motions, search, mouse selection, copying on the person's actionTM5
TM9FV8's routine run; agents' Routine tools as configured (D-178); a Routine view per Project (D2c); node rename, disable, enableS30; views: TM6
TM10Qualification: each terminal below tmux and the Node's base within budget (D-177) on all three platforms; daily terminal work moves to MaiaTM0–TM9, TM11; RL7's Windows CLI
TM11Done, Source candidate (#102, #108, #113): an exact ID selects its Node; lists merge every Node; agent loop and MCP route by IDmain

Contracts freeze before each slice starts:

  • TM1: each platform's tier and shell allow-list, proven on the lab VM and on Windows.
  • TM2a: terminal.read reports the cursor_expired gap; cursors survive a restart.
  • TM2b: frames and their bounds; reads (visible, recent); waits (a pattern, or the exit).
  • TM4: key encoding, takeover, D-161's exits, the binaries, the Rust binding.
  • TM5: D-175's keys.
  • TM7: ownership, the cap, containment, takeover, deadlines, the trace.
  • TM11: the refusal when two Nodes hold one ID.
  • EV0a: the event envelope and kind registry (spec).
  • EV0e: journal retention. The pruner is a dormant source candidate; pruned-history markers (D-191) and their client rendering have landed; the pruner is enabled next.

Rust terminal and process host — RN0–RN1

Planned, alongside Alpha 1 (D-182). Maia Node stays in services/node on TypeScript/Effect, including authorization, durable state, orchestration and database migrations. Rust is limited to the terminal screen engine/client (TM2b, TM4) and the native process/PTY host; Desktop keeps its existing Tauri shell. These are bounded adapters or clients, with no independent business authority.

SliceDeliverableWaits for
RN0Pinned toolchain, Cargo workspace (crates/), gates/CI, registry-generated terminal binding with parity, Node baseline metricsmain; crate approvals
RN1Replace the C process/PTY helper in Rust under the same bounded protocol and lifecycle tests; compare the complete Node/helper footprintRN0

RN1 and TM2b may land in either order, preserving the screen-engine link. Node keeps validation, lifecycle and receipts. S47 replaces worker containment while retaining terminal/PTY and screen hosting; agent terminals stay inside Session containment. The former RN2–RN5 Node rewrite and migration handoff leave the plan.

Terminal multiplexer parity — MP0–MP5

Planned, alongside TM0–TM11. Parity with the reference multiplexer where agents and people depend on it. MP names these units so they do not collide with R1 or S1.

SliceDeliverableWaits for
MP0Source candidate: the terminal suite prints per-terminal and whole-server footprints for any tool, including the reference multiplexer through an adapter kept outside the repository; reported, not gatedTM0
MP1Source candidate: session.wait: maia session wait --until <state> --timeout <d>main
MP2Source candidate: every Node-reaching command honors --node and --json, enforced by a parity test: each succeeding leaf prints one ok:true JSON line, mcp writes JSON-RPC frames alone, and login codex --name signs in on the --node Node (success results of the other leaves: later unit)TM11
MP3Source candidate: --name (an alias of --title) and --cwd on session create; named keys on terminal input write (one --text and one --keys per call; repeatable --key with TM4; --cwd for Agent Sessions backed by Codex or Claude is a follow-up)main
MP4Source candidate: an orchestrator Session answers its children's questions (D-186)main
MP5An open "Node base footprint" item, and a follow-up unit that cuts the Node's idle baseMP0

Event slices EV0–EV7 are defined in the event design. EV3 adds outbound hooks (D-187); EV4 adds node health (resource events and maia node stats). Events that match terminal output wait for TM2b.

Foundations — F0–F10

F0 done; F1–F5 Source candidate; F6–F10 Planned (D-189). Make the codebase easy for people and agents to extend, in small steps, with no big-bang rewrite: every PR keeps main green. The current and target architecture and the sequence are in ARCHITECTURE.md.

  • F0: The architecture audit, the current and target architecture, D-189
  • F1: Dependency graph ratchet (cycle membership and edges by kind): scripts/quality/dependency-graph.mjs, baseline
  • F2: Package and adapter ownership checks: scripts/quality/package-ownership.mjs, rules
  • F3: SDK node-changes cycle: removed from the F1 baseline
  • F4: Node connection/harness cycle: removed from the F1 baseline
  • F5: One unsafe SQL boundary (decode rows): controller-policy decodes its rows; the sql-row-assertion rule and its baseline keep the rest from growing
  • F6: Immediate-transaction consolidation: inImmediateTransaction and the immediate-transaction rule (rules); the helper copies moved first, the inline sites follow
  • F7: Unwired configuration cleanup: the unwired resolver, writer and jsonc-parser are removed; a reachability ratchet keeps new unwired files out
  • F8: Storage contract ownership
  • F9: Client cycles; CLI lazy dependencies separately
  • F10: Node-local ID consolidation

The event core keeps its own order, EV0a → EV0b → {EV0c, EV0d} → EV0e. Lint enforces the module boundaries in CI. Agent-friendly documentation: a map of the repository, how to add a feature, a README per module, and files under about 400 lines.

Agent integration — AI0–AI3

Planned (D-190), after MP5 and EV0c and before EV1. Maia ships its own agent Skills and installs them into every harness it detects, so an agent in any of them can drive the Maia CLI with no manual setup. Skills go through the pinned skills CLI (D-170); the foundations rules apply (one owner module per primitive, files under about 400 lines).

EV1a and EV1b (Session activity: contract, then migration and hooks) no longer wait for AI2 and AI3; the owner's 11-01 direction is to carry on with EV1. EV1c (the public kind, session.show and session.list) still waits for AI3.

SliceDeliverableWaits for
AI0Bundled, versioned Maia Skills (Sessions and Nodes, then events and hooks as EV2 and EV3 ship their commands; --node and --json), with a CI check that fails when a Skill names a command or flag the CLI does not haveMP5, EV0c
AI1amaia agents detect --json: installed harnesses and their versions, locally or with --node (Source candidate, #163)AI0
AI1bUser-scope Skills folders in agents detect, from the bundled exact-pinned skills CLI run as a registered skills-listing process on Linux hard containment (Source candidate; macOS and Windows report unsupported)AI1a
AI1cProject-scope Skills folders in agents detect, with its own containment design (Planned)AI1b
AI2maia skills install, update, uninstall and status through the pinned skills CLI: idempotent, never replacing an edited folder, offered by maia setup and updated on a Maia upgrade (details in D-190)AI1
AI3Install, update and uninstall tests per harness in temporary home folders; README sectionAI2

Routines and triggers — RT0–RT3

Planned (owner direction, 31 October 2026). Maia replaces external session runners and multiplexers: recurring loops, watches and polling run as Maia Routines that start or steer Claude Code and Codex CLI Sessions. RT builds on the Routine operations S30 ships (source candidate, #57), the planned S50 Routines and S51 event triggers, and the routine model in agents, routines and triggers; it adds no second runtime. RT0 feeds the first version; RT1–RT3 land before the cutover, except inbound events, which wait for S51 (after S50, after the cutover). Dates are targets: a slice starts the moment its dependencies hold.

SliceDeliverableTargetWaits for
RT0Qualifies S30's scheduled Sessions (persisted cron schedules, no overlap, capacity admission, at most one catch-up after a restart) and adds a missed-run policy per Routine (skip or catch up once), concurrency limits and output that stays quiet unless something changed30 Nov 2026S30 (#57), EV0e
RT1Source candidate: configurable CPU, memory and state-volume disk headroom admission for Session create/start/resume, including scheduled starts, with typed refusals and telemetry. Remaining scope planned: event triggers: a Routine fires on journal events (EV1's Session activity, EV2's feeds) and on Node CPU, memory and disk events (EV4); an open task moves to another Session when its owner stays idle for a set time, across Nodes through the control Node (LB1); dispatch and scheduled starts are refused, with an event, when CPU, memory, disk or provider quota is below its headroom; results can leave through outbound hooks (EV3, optional for the first version); inbound webhooks arrive through S51's ingest operation15 Jan 2027RT0, EV1, EV2, EV4, EV7, LB1; inbound: S51
RT2Watch and polling recipes (pull request and CI state, health, schedules) and a migration guide for moving existing external loops into Maia Routines21 Jan 2027RT0, RT1
RT3Session-runner parity: Maia fully replaces an external session runner or multiplexer for these loops, ahead of the public launch (estimate; re-derived when the terminal rows it needs are planned)26 Feb 2027RT2, MP5, ZU1b, ZU2b, the terminal rows fleet loops need (TM0, TM1a, TM2a, TM3, TM4, TM11)
LB1One read that joins run-ledger tasks with Session activity across Nodes, printed by the CLI, with no new store; it carries the cross-Node move of an idle owner's task through the control Node5 Jan 2027EV1c

Acceptance (binding). The move off an external session runner is complete only when each of these is shown on real Sessions on at least two Nodes and recorded as a receipt or a test:

  1. A Session that goes idle, finishes a turn, fails, waits for approval, crosses a context-window threshold or crosses a provider-quota threshold produces an event within 2 seconds on its own Node and within 5 seconds on a control Node. The payload holds IDs and class codes only, never prompt text, command text, paths or secrets, and a canary-string test proves it.
  2. A task handed to a Session on another Node is acknowledged: the receiver records a receipt and the acknowledgement is an event; a retry with the same idempotency key creates no second task.
  3. One read shows every lane, its owner, its task and its activity across all Nodes, from structured state and not from files.
  4. A Routine moves an open task when its owner has been idle for a set time, within exact-ID, count and receipt bounds, and never to a Session without capacity.
  5. Every cross-Node control command leaves a receipt that names the acting principal and the target Node.
  6. Dispatch and scheduled starts are refused when CPU, memory, disk or provider quota is below its headroom, with an event that says which.
  7. No model turn is spent only to watch another Session.
  8. Idle, blocked and context-threshold alerts reach a person without that person polling: through a watching client first, outbound hooks (EV3) when they land.
  9. Updating or restarting a Node never stops a running Session (ZU0–ZU2).

Maia's own Sessions emit lifecycle events through Maia as soon as EV1 lands (target mid-November 2026, which holds only if AI3 lands first; until then the Node's own internal activity events are the dogfood). RT0 moves the project's own watch loops onto Maia on 30 November 2026.

Zero-impact updates — ZU0–ZU3

Planned (owner requirement, 1 November 2026; D-196). Updating, restarting or rolling back a Node never stops a running Session, terminal or harness, so canaries can land often on every machine without breaking work. Automatic updates follow the canary channel only (D-202). ZU0–ZU2 gate RT3: no machine moves off an external session runner before they ship. Dates are best cases until the ZU0 spikes land on 10 November; the lead re-estimates them then.

SliceDeliverableTargetWaits for
ZU0The contract: which start-up recovery rules an adopted process keeps or re-earns (credentials, the crash fence, abandoned approvals, no retry while an adopted owner lives); a deterministic dummy Session; update.started, update.done and update.rolled_back registered; spikes for helpers that outlive the Node and for a contained target that cannot reach the helper socket10 Nov 2026none
ZU1aProcess-host helpers outlive the Node: control over a private local socket, a bounded output buffer replayed by byte offset (an overflow is a gap event), a lease timeout, helpers in their own systemd unit that a Node restart never touches (rendered by remote/host/unit.ts), re-adoption from the journal and Session state; terminals and Codex Sessions adopted live; the upgrade/downgrade CI suite on CI Linux runners, which starts live dummy Sessions and terminals and fails if any process dies, any output byte is lost or any approval is orphaned, red on current main20 Nov 2026ZU0
ZU1bClaude Code SDK Sessions drain, then resume: an update waits until each is between turns (30 minutes by default, then the machine is skipped and retried later), recycles the idle process and resumes it by session ID; no turn is ever cut; pending approvals survive a restart; suite green on Linux1 Dec 2026ZU1a
ZU2aAutomatic canary updates through the remote install and rollback path (a source candidate), pulled by each Node on its own schedule and including the bridge launcher: npm registry signature and provenance check, side-by-side staging, preflight migrations on a copy of the state, swap, health check (Node ready, every adopted Session answers, a journal append succeeds), automatic rollback, last three versions kept and never one a live Session still uses; update.* events through the event core8 Dec 2026ZU1a
ZU2bCompatibility and rollout: skew counted in release IDs, so release N and N-1 work together (node.hello minimum, tolerant readers, a minimum-reader schema version, expand/contract migrations tested by opening N's database with the N-1 binary, the helper protocol as its own version); rings by exact Node ID, one pilot machine first, a soak gate, at most one update per machine every 6 hours; a pause and kill switch; no update while a machine is short on CPU, memory or disk15 Dec 2026ZU2a
ZU3macOS equivalent, a soak at the active-Session cap, the downgrade matrix and an N-2 skew test22 Jan 2027ZU2b

The first ZU release cannot keep or roll back Sessions started before it.

First version — FV1–FV11

Planned, after the terminal multiplexer (owner direction, 23 October 2026, D-150; order, 28 October 2026, D-175): one Node, two Workspaces, and Routines with Skills that run Claude Code and Codex Sessions on remote servers and workers. It runs on host containment and does not wait for S47. The rollout order is in the cutover.

Acceptance examples (Todo is the GitHub Projects v2 Status field set to Todo; other filters, such as type and assignee, apply on top):

  • A cron Routine whose dispatcher starts one child Session per Todo bug assigned to a person; each child ships its fix to main through a pull request.
  • An hourly Routine whose dispatcher starts implementer Sessions for Todo issues, at most N at a time; the Node enforces N through the Connection's session cap (D-097).
  • Sessions of different harnesses message each other within a Project, and across Projects of a Workspace that both allow it (D-152, D-166).
  • Maia installs Session-scoped hooks and small Skills, never into a person's global harness configuration.
  • One control Node runs a Routine's Session on a remote worker.
  • A Routine reads what each of its Claude Code and Codex Sessions did (S12e, S12f) and acts on it, and any capture gap shows in that read.
SliceDeliverableWaits for
FV1S30's Routine template gains Agent, role and worktreeS30; S49's Agent reference
FV2Done, Source candidate (#62): orchestrator children: a Session starts and steers its own (D-151)main; steering a running turn: S26b
FV3One-shot children stop when doneS30
FV4Project Skills at launch: S49's Agent skills, pinned by the lock's hash, delivered to Codex and Claude Code workers (D-170)S49's Skill references; S13's lock reads
FV5aWorker to control ChangeSet transfer: streaming artifact.put and artifact.get with a digest and size bound (D-150)MN1
FV5The first part of S61a: GitHub App Connection, a generic issue list and show, Node-owned publish (commit, push, pull request, merge under a D-116 grant)S2, FV5a, E2a's Linux backend
FV6Source candidate: startup-configurable Node Session cap (default 8) and account default (2), bounded at 64; live preview/confirm changes remain plannedmain
FV7Dev-lab scenario with bare remotes and a fake GitHub on loopbackmain; the full run: MN1
FV8Done, Source candidate (#98, TM9a): routine run <id>, a manual fire; ships in TM9 (D-175)S30
FV9S17 messaging for vendor Sessions (D-152, D-166): the mailbox tools for Session credentials first, the wake after S26main; the wake: S26
FV10A per-Session Maia kit: Claude Code in-process observation hooks and FV4's Skills, each recorded with its digest and removed with the SessionFV4, S12e
FV11Run caps, the first part of S65: wall time, turns, tokens and cost on a Routine, Agent or Workspace; the Node enforces them, fails closed and receipts each stopS30, S12f summary

Each slice freezes these points in its contract before it starts:

  • FV1: a fire fixes the template's revision and the Agent's digest when it is planned; a disabled or missing Agent fails the fire, with its reason, before any Session exists.

  • FV2: the shipped D-151 child controls qualify apart from the new steering; tests cover a foreign child's refusal, depth and cap limits and an unknown outcome.

  • FV3: only what S30 does not already do: what proves a child is done, what stays open for review, and what a failed or unknown turn leaves running.

  • FV4: eligibility by qualified identity, digests resolved from the lock, a missing Skill refusing the launch with its reason, and which digest a resumed Session uses (Skills).

  • FV5 and FV5a: the transfer names its exact source and destination, base revision, manifest and size bounds, and reconciles an interrupted transfer; publish binds to the inspected change, the exact remote head and the grant, and reconciles a lost response.

  • FV6: default 8, today's value; a preview, a confirmation and a receipt; lowering it below the running count stops nothing and admits nothing new until the count is under it; concurrent admissions never exceed it; it survives a restart.

  • FV7: its scenarios and evidence are listed; a pass with a fake GitHub and bare remotes does not qualify enrollment, key custody or the transport.

  • FV8: a manual fire reuses the fire and run identity and the busy rule (triggerKind: "manual"), is idempotent, and races a cron fire safely, with no second scheduler.

  • FV9: acceptance comes in three parts: reach (both Projects allow it, the bounded peer directory, one resource_not_found for unknown and unreachable, revocation), Sessions without write access, and the wake; D-168's transit rule applies.

  • FV10: each hook and Skill is captured by S12e, recorded with its digest, and leaves nothing in a person's global configuration.

  • Remote workers are in the first version: MN1's execution-only worker and a minimal placement slice (transport pending an owner decision; scoped separately; MN2–MN5 stay in multi-server), and the worker → control ChangeSet transfer, which publishing from a worker needs. Harness authentication on a worker belongs to the user: the user logs Claude Code and Codex in on each worker through the harness's own login, and Maia detects and uses it but never reads, stores or moves the credential. Enrollment is the D-136 terminal ceremony, and revoke and narrow use the local operator bearer, until the managed administrator credential replaces both (D-150). Artifacts move by streaming artifact.put and artifact.get with a digest and size bound (D-150). The control Node runs on Linux first; macOS and other operating systems are Planned (D-150).

  • Key custody: the GitHub App key, the commit signing key and installation tokens stay in the control Node. In the first version no Session of any kind runs on the control Node's host, neither a worker nor a coordinator; Sessions run only on remote workers. This is S61a's condition for the first version and the cutover, in place of S47b. Linux custody needs E2a's systemd credentials backend.

  • Commit identity is a per-Workspace setting. The first version supports a named person's identity and signing key held by the control Node (the owner's own configuration; users configure it later, D-150); other modes, such as the GitHub App's own identity, come later. The App pushes, opens pull requests and merges under a D-116 grant.

  • Commit signing key (D-150): the user provides it; Maia discovers the available keys and offers to create one.

  • Publication policy: commit identity, signing requirement, merge method and pull request policy are typed Workspace and Project policy admitted through E5, never hardcoded: Project intent may live in .maia, Workspace policy goes through its API, and Skills describe the approved procedure. The Node enforces the policy and fails closed.

  • Observability: the first version needs S12e and S12f's summary for Claude Code and Codex. Pi follows S23. Maia's Session-scoped observation hooks (FV10) carry only Session identity, do nothing without the Session credential, never block the harness, and are recorded at every firing. The Node derives state from the structured record, not from hooks. The permission guard is not an observation hook: it keeps waiting for approval and failing closed.

  • Prerequisites in flight: S30, S2, S26 and E2a. The table's last column gives each slice's dependencies; FV10 comes last.

The first production migration

Planned, as soon as possible (owner direction, 22 October 2026): Maia replaces existing agent deployments, CLI and SDK first, on remote servers and workers (D-150). Order: the first version passes the lab (FV7); the same Routines soak for a short time on Maia's own repository; then the first production deployment, then the second, one Routine at a time, each enabled by the owner. Its plan, baseline, cutover gates and phases (FR0–FR6) live in a separate migration plan. It runs on today's host containment and waits only for the first version, the lab and the soak, not for S47a, S47b, SH1 or SH2, which stay in the roadmap as later milestones.

After the cutover (production parity; the migration plan tracks it): S50, S53, S60a, S65, S55, S24, S57a, S15, S59, S56's run spans, T1 beyond Claude Code and Codex usage, T2–T3, R8a, S74, S63, S70, S75, S7, RL3, RL4, RL6 and S42's show and handoff.

Phase 0 — finish the foundation in flight

  • R0, R0a, R0b, M0: acceptance closure, source organization (SO2–SO7 after SO0–SO1a), Effect and dependency work (EF2, TQ1, TQ2 dependent; DEP2 deferred), measurement (M0a source candidate) (sequence).
  • R1, R1b, R3: portfolio reads and scope, naming (scheduled with its schema work), persistent Workspace conversations and delegation (after R1) (R1, R1b, R3, ownership).
  • Open swarm slices: S12 follow-ups, S13, S14 (RL2 and streams over the bridge), S15, S16, S17, S19 follow-up (one Run storage), S20, S24 for Pi and Maia agent (swarm).
  • Source candidates to qualify: S10, S11, S12d, S14, S18, S19, S22, S26, S30, S44, S45, CLI1, DP1 and S46.

Phase 1 — enterprise foundation

  • E1 disclosure and supply chain: now, except licensing, support period and signing, which wait for their decisions.
  • S2 grants per Workspace and Project: source candidate (D-147).
  • S47a, S47b OpenShell foundation and vendor executors: next (D-116, D-118; S47); R2 usable local execution launches after S47b; each S47c integration ships with its executor slice, S47e action policy after S47b, S13 and E5's model, and S47d comes last.
  • E5 configuration and policy management: its model after S49 and S54, then joined to S13, S47, S55 and S57 as each ships.
  • E2a managed secret store (D-122: macOS Keychain, systemd credentials on Linux) now, before MN1 and the new production Control Node; the Keychain backend (D-139) and the Linux backend (E2b, D-155) are source candidates, and Linux qualification on the target host is pending. Until a profile opts in, S24 and S61a keep keys in owner-only files in the Node root.
  • S57a required gateway after S2 and S24, S57b its network rule after S47b (agent operations).
  • First-owner bootstrap, rebuilt from its specification: source candidate (release-disabled; qualification pending), before MN0.
  • ORG1, ORG3 members, roles and service accounts: after the bootstrap, MN0, S2 and the managed client credential; ORG2 sign-in after MN1; ORG4–ORG7 after ORG1 and the slices each names (organizations and people).
  • E2 product controls: with ORG1–ORG2, MN0–MN1 and RL4–RL5; E3 AI governance: with S49; E4 audits: after E1, E2 and E5 (enterprise).

Phase 2 — workflows

  • S26, S28, S29: next (wave A); S30 is a source candidate; S27 after S26.
  • S49 Agents after S30; S50 Routines after S49 and S19 (D-119); S51 event triggers after S50; G1 native Session goals after FV11's run caps (D-162); S69 Session goals after S26, S29, S55 and its decision entry, in steps and tasks after S50 and S53 (agents and routines).
  • S53 tasks after S50; S48 Project goals, then S54 Workspace goals and rules after R3.
  • S55 budgets; S60a agent reliability after S49 and S65, harness switching after S47b and its decision; S65 run control after S49 and S50 (FV11, its run caps, after S30 and S12f's summary); S61a GitHub (D-121): its Connection and reads after S47b, or, for the first version and the cutover, under the first version's key-custody rule (D-150); Agent-authorized writes after S2 and S49 (FV5, its first part); S73 extensions in the order its bullet gives, then S61b after S73a–S73c; S74 alerts after T1–T3, S56's run spans and R8a, its merge views with S61b; S75 import after S49, S50 and S53, its goal import after S48 and S54; S70 pause and resume after S19, S26 and S29, other targets with their slices; S71 tool connections after S2, S13, S47b and E5's model (D-127) (agent operations).
  • R8a the attention inbox after R1 and R3, the rest of R8 after R4; R5 finish and review work, whose reviewed GitHub capability is S61a.

Phase 3 — evaluation and learning

  • R10a evaluation foundation: next (R10a); S8 decision layer after R10a and its approvals; R10b adaptive consumers after R10a (R10b).
  • S62 datasets after S49 and S50, its eval runs after S8; S68 datasets to custom models after S62 and R10a.
  • R4 Workspace and Project learning (learning).

Phase 4 — execution at scale and operations

  • RL2 handshake, then S58 server setup after S47b, MN1 and RL3–RL4; S7 Session caps after S2 (FV6, its configurable cap, comes first, for the cutover).
  • MN0–MN5 Execution Nodes and R6 local plus remote pool (multi-server); MN1's execution-only worker and a minimal placement slice come first, for the first version (D-150; transport pending an owner decision); S66 Session move and sleep after MN4.
  • S59 fleet view: CLI in parallel, web after S52.
  • T0–T7 telemetry (telemetry) and S56 tracing in parallel; S63 templates after S49 and S50, its backups earlier on their own.
  • S7, S9 scale and VPS qualification; S31–S41 more harnesses and agent features after their approvals; S21 and S42's previews later.

Phase 5 — human layer

Client projections and the personal agent, each after its CLI path:

  • S52 web client after its decision entry, deferred until DP2 ships, then the web views of S56, S59 and S64 (S64's CLI reads after S53); S67 personal agent after S49, S50, R3, R10 and ORG1 (personal agent).
  • R7 text and voice (voice), R9 and R9a clients (R9a), R1a external coordinator (R1a), the master VPS and portfolio scale journeys.
  • S72 notifications after R8, S51 and ORG1, once the egress decision lands; its chat channel with S67 (agent operations).
  • DP2 full Desktop app: DP2a once DP1 qualifies, each DP2b page after its CLI path (DP2).
  • R11 Pi replacement: dogfood milestone (R11).
  • Terminal dashboard maia dashboard (D-161, amended by D-175): its Session view, approvals and launcher open as panes of the terminal multiplexer, and D1a1, D1a2 and D2a–D2c join that milestone ahead of the first version; D1b and the later views stay here. D0 decision entries and docs. D1-prep, which also fixes Desktop: P1 per-Node freshness, authentication and reconnect backoff; P2 Workspace and Project to Node maps; P3 the SDK's epoch_changed; P4 publishing @maiaos/client-core (source candidate until its first canary; the owner enabled its manageDistTags); P5 the Node API answering socket overflow with saturated. D1a0 (source candidate, #84) the pi-tui adapter, its one ceiling raise, and exit 130 in help --json; D1a1 the read-only Tree (the SDK's deadlineAt, client-core's admission wrapper and the CLI's shared retry helper; the deadline, Tree and status bar, and the connection layer merged in #85, #88 and #121, the rest of D1a1 open); D1a2 navigation and keys; D1b Agents, once Session reads carry their Agent; D2a chat; D2b approvals and questions; D2c new runs and Routine pause and resume. Later, each after its owner slice: Routine run sub-trees (S50), queued work (S60a), Servers (S59), terminals and goals (G1). Before S72, the dashboard rings the terminal bell and marks its title when a new attention item arrives.

Phase 6 — distribution and release

  • RL0–RL3 next, RL4 after them, RL5 after the owner's signing identities, RL6 seamless updates after RL4 and S70, RL7 Windows CLI and SDK after RL3–RL4, Windows Desktop after DP2a and its design, RL8 security releases after RL4, self-managed deployment recipes after S58 and RL4 (managed version); release and dogfood gates apply to every release.

Later: S21, S43, agent discovery and messaging between organizations (never shared authority) from the organization agent hub, more chat connectors, shared browser profiles, governed browser and computer use (after S71 and S47c), and short-lived Execution Nodes from an operator-run provisioner.

Enterprise readiness and certification

Planned (owner direction, 22 October 2026). The EU Cyber Resilience Act binds Maia once it is sold in the EU: vulnerability reporting applies from 11 September 2026 and all rules from 11 December 2027. SOC 2 Type II and ISO 27001 certify vllnt's own processes, not the self-hosted product; ISO 42001, OWASP ASVS level 2 and the OWASP LLM and agentic lists set product targets. The enterprise readiness plan owns gaps, order and evidence.

  • E1 Disclosure and supply chain. Public reporting channel and security.txt; CRA 24-hour, 72-hour and 14-day reporting runbook; signed releases with SLSA provenance; code, dependency and secret scanning; a threat model; LICENSE, CHANGELOG and a support period of at least 5 years.
  • E2 Product controls. People, roles and sign-in through organizations and people (ORG1–ORG2); a tamper-evident audit log (a signed hash chain over receipts, events and traces, D-169; ORG5 searches and exports it); a managed secret store (E2a, D-010) and encryption at rest; TLS beyond loopback (MN0–MN1); enforced retention and deletion (S12r); backups (S63); signed updates (RL4, RL5).
  • E5 Configuration and policy management. One versioned model for Workspace and Project configuration and policy (Agents, Routines, rules, budgets, gateway and containment policy), each part keeping its owner (S13, S47's Maia policy layer, S54, S55, S57): Project configuration as code in the Project's .maia admitted by digest, Workspace configuration through the API (a Workspace .maia scope needs an ARCHITECTURE.md change). Workspace defaults (limits and rules, never grants) apply where a Project sets nothing; a Project may narrow limits (budgets, caps, hosts, tools), add rules and never remove or weaken a Workspace rule or required gateway, even with a person's approval: that change is made in the owning Workspace policy (D-124); an Agent never inherits a person's or a parent scope's grants (D-005). Preview with a diff, confirmation, receipt, drift detection and rollback, which follows the same rules; every allow or deny names its rule and revision.
  • E3 AI governance. AI risk and impact assessment; agents identify as AI in PRs and comments (AI Act Art. 50); a model-provider inventory with data use and retention; dataset and tuned-model lineage (S68).
  • E4 Audits. Security management system and evidence; an annual third-party penetration test; SOC 2 Type II, then ISO 27001 and ISO 42001; CRA conformity, with the product class confirmed by counsel.

Order: E1 now, except licensing and signing; E5's model after S49 and S54; E2 with ORG1–ORG2; E3 with S49; E4 after E1, E2 and E5. Acceptance for each slice is in the enterprise readiness plan.

Organizations and people

Planned (owner direction, 22 October 2026). Many people share one organization on one Control Node. Each person has an account, roles on exact scopes, their own devices, inbox and personal agent (S67); agents keep their own grants and never inherit a person's role (D-005). The track builds on the team Workspace design (first owner, then MN0 grants, then members; the deleted first-owner prototype is rebuilt first) and ships CLI first: every administration action is an operation with a CLI command before any admin view in a client. Roles, commands, MCP tools and views come from the protocol registry or are checked against it.

Simplicity rules:

  • One organization per Control Node; another organization is another Node, never a shared tenant.
  • After the first-owner bootstrap, first-run setup creates one empty Workspace for Projects, from a template once S63 ships. A one-person organization sees no teams, roles or policies until a second person joins.
  • A few built-in roles; a custom role starts as a copy, and each area offers only view or manage.
  • Each step up is opt-in: invitations, then automatic membership for a verified domain, then directory sync.
  • Every change previews its impact, such as how many people a policy removes, and leaves a receipt naming its person; a role change applies from the next request.

The slices:

  • ORG1 Members, teams and roles. Invite a person to the organization with roles on exact Workspaces or Projects: one use, expiring, revocable. Accept, suspend, reactivate and deactivate, never delete, so receipts keep their actor. Built-in roles: owner, admin, member, viewer, auditor (reads audit and configuration only) and guest (named Projects, with an expiry). A role applies to the organization, a Workspace or a Project, and an admin of one Workspace administers nothing outside it; teams hold roles, and a person's access is the union of their own and their teams' grants. Custom roles use permissions generated from the registry's scopes and risk classes. Nobody grants a role above their own, and widening one's own access needs another person's confirmation. Agents are principals too, each with an accountable person and a role on its Node never above that person's (D-180). access explain names the grants behind each allow or deny. The last owner cannot leave or be demoted, suspended, deactivated or deprovisioned. Each member gets their own attention inbox (extending R8), task assignments and mentions (S53) and budgets (S55); their Sessions run in S47 sandboxes like any other, with credentials leased per Session; separate OS users per person stay open.
  • ORG2 Sign-in and directory. OIDC sign-in, then SAML 2.0; SCIM 2.0 provisioning of people and groups; verified domains, whose people must sign in through the organization's identity provider, keeping one local admin as a fallback; MFA with passkeys or TOTP for local accounts; session policy with idle and absolute timeouts, an optional network allow list and a fresh sign-in before a consequential confirmation. A person previews and confirms the directory connection, each domain rule and the group-to-team mapping; changes from a sync then apply under that policy with receipts naming their source. Automatic membership grants at most the member role, never admin or owner, and a sync that would change more than a confirmed number of people stops for a person. Deprovisioning suspends the person and revokes their sessions, devices, tokens and, once S67 exists, standing approvals within a bound the entry sets.
  • ORG3 Service accounts and tokens. Non-person principals for CI and integrations, each with an accountable person, exact scopes never above that person's grants, an expiry and rotation; personal access tokens whose grants their person issues, never above that person's own (as in S67). Admins list and revoke both. Each confirms only what its role allows (D-180); an extension's never confirms.
  • ORG4 Approval policies and access reviews. Per scope and risk class, the role that may confirm each operation; a two-person rule for chosen operations, where the requester never confirms their own request; for a request from any non-person principal (Agent, Routine, service account or token), its accountable person is the requester. The approver's confirmation binds the operation, input digest, revision, expiry and target set, and the receipt names requester and approver. Requests go to the inboxes of eligible people and expire; a standing approval (S67) never satisfies a two-person rule. Roles also limit which Connections, models and tools their holders' work may use (E5). An access review is a Routine (S50) that lists each grant for a named person to keep or revoke. Roles replace person-only confirmation (S1, D-180).
  • ORG5 Audit, usage and administration. Audit search over receipts and events by person, agent, scope, operation and time, with a dated catalog of audit events, export, and streaming to a security monitoring system as an approved egress, over E2's tamper-evident log; usage and cost per person, team, Agent and Project (T1–T3, S55); seats and a signed offline license file for self-hosted installs (owner decision); an administration overview in the CLI, then in clients.
  • ORG6 Data controls and offboarding. Retention per organization and Workspace, extending S12r beyond Session streams; legal hold of an exact scope, shown in every purge preview, that suspends deletion and wins over an erasure request; export of a person's data and of a Workspace; erasure of a person's personal data: receipts and the audit log hold only a stable person ID, never personal data (sign-in and invitation events carry IDs or digests, never emails or addresses), so erasure leaves the chain intact. The organization is the data controller; Maia supplies the tools. Offboarding transfers a departing person's Agents, Routines, tasks and schedules and their pending requests to a named person: the preview lists exact IDs and the confirmation binds that list. Their Connections and any standing approvals are disabled, never transferred, and the recipient sets up their own. The accountable person of each Agent (S49) and Routine (whoever last confirmed it) moves with the transfer. Data stays on the organization's Nodes, and a model allow list (S57, E3) limits where prompts go.
  • ORG7 Isolation between people and delegation. On a shared Node each person's personal agent and Sessions run under a separate OS user or container with their own home, credentials, worktrees and context, so no person's files, credentials or memory reach another's agent. One person delegates to another's agent only by a consent that names the exact scope, operations and expiry, is revocable and leaves receipts; the delegate acts within the narrower of both grants and never confirms for the delegator.

Order: ORG1 and ORG3 after the first-owner bootstrap, MN0, S2 and the managed client credential (D-056 pairing, accepted, plus a new credential decision), with ORG1's inbox and assignment parts after R8 and S53 (per-member budgets are S55's person and team scopes, after ORG1); ORG2 after ORG1, MN1 and E2a; ORG4 after ORG1, E5, R8 and S50; ORG5 after ORG1, E2's audit log, T1–T3 and S55; ORG6 after ORG1, S12r, S49, S50 and S53; ORG7 after ORG1, S47b and S67; client views after their CLI. Entry: a decision entry naming the organization aggregate (the specified team Workspace), the built-in roles and whether a Workspace role reaches its Projects, owner recovery (the specified bootstrap has no replace-owner path), the managed client credential that lets an invited person's device sign in before ORG2, the deprovisioning bound, and the identity model change: service accounts as a principal kind, and organization and Workspace roles in the request context beside the target's Project grants.

Acceptance for each slice is in the enterprise readiness plan.

v1: external brain and vendor executors

Next, user-prioritized. Claude Code or Codex CLI acts as the brain through the public CLI and a shipped Skill; Maia Node runs vendor executor Sessions bound to named accounts. Decisions, spike evidence, account and pool rules are in the decision record. Each slice follows protocol → SDK → Node → CLI and ships only with its own failure-path tests.

Primary goal, as soon as possible: from Claude Code (or Codex), drive tens of Projects and Workspaces and hundreds of Claude Code and Codex workers through the maia plugin: Skills plus MCP talking to the Node, with the desktop app showing the same Node state live. Three layers, in this order:

  1. Primitives, never agentic. Node, protocol, SDK, CLI, MCP and API expose deterministic operations: create, start, send, wait, observe, interrupt, stop and resume, with revisions, receipts and bounded monitoring. Every control and monitoring operation works from the CLI and the MCP and is battle-tested at scale before orchestration builds on it.
  2. Orchestration lives in Skills. The swarm emerges from how a brain combines the primitives (fan-out, join, supervise, retry, review). Maia adds no hidden planner or agent loop.
  3. Optional decision layer for mass work. A decision model (Jev through the Vercel AI Gateway, or the connected Codex/ChatGPT account) splits intents, classifies, routes and scores over supplied options; a stronger LLM plans the open-ended parts. It proposes; the Node validates and grants nothing. Every control action stays available without it.

Swarm fast track (owner priority, 2 October 2026). Pilot swarms of Codex, Claude Code (Agent SDK), Pi and Maia agent workers through Maia, on the local Node and on remote Nodes, as soon as possible. This track goes before the remaining R0b migrations of packages/agent and services/node; new and touched code is Effect-first anyway, because the R0b gates reject any new gap.

  1. Local swarm, in parallel: S5 coding workers (write access in a worktree per Session, session diff, session archive); S23 Pi and Maia agent as executors; S18a worker credentials and S18b fan-out guards; S24 gateway Connections.
  2. Local swarm, then: S19 Run ledger and S12b maia session attach, then the S22 swarm Skills that drive them from Claude Code or Codex.
  3. Remote Nodes, in parallel with step 1: S10 install and service automation and a minimal S14 (maia node install <host> over SSH, the SSH stdio bridge, CLI and MCP --node <name>). Each Node signs in its own accounts; credentials are never copied between Nodes. SSH first; Tailscale stays optional reachability.
  4. Evaluate S25 Pi Durable for durable Pi sessions and workers under Node authority before adopting it.
  • S2. Grants per Workspace/Project and connectionPool single/rotate. Status: Source candidate (D-147).
  • S7. Hundreds of concurrent Sessions across accounts and hosts; raise the Node cap (8 today) and per-account caps (2 by default, at most 16) from measurements; on Linux, first keep a worker from changing the modes of shared or sibling cgroup control files (review finding F1). Status: Dependent on S2.
  • S8. Decision layer: a Node-owned evaluation operation (Jev through the Gateway, or a Codex/ChatGPT-account Session) that Skills call to split, classify, route and score. Status: Dependent on R10a; dependency, Gateway key and paid-call approval.
  • S9. The D-150 topology dogfooded end to end: a Linux control Node with remote workers, driven from Claude Code and the desktop app. A Mac control Node is a later host qualification. Status: Dependent on MN0 and MN1 with its minimal placement slice; the first step, an independent VPS Node reached over SSH, works today (D-141).
  • S10. Autonomous remote execution node: given SSH access, maia (or an agent through the Skill) probes the host, installs a pinned private runtime and the Linux process host, registers a user service and enrolls it, with no manual steps. Status: Source candidate: maia-node remote probe, install, rollback and uninstall over SSH (pinned runtime, systemd user unit with Delegate=yes, manifest-scoped uninstall), checked on the VPS; the release ships the maia CLI worker MCP launches (D-112); enrollment on MN1.
  • S11. Discovery and adoption: list existing Claude Code and Codex sessions (metadata only: id, working directory, repository, last activity, live or ended) and Git repositories; propose Projects; adopt an ended session by resuming it under a Maia Session. Status: Source candidate (2 Oct 2026): discovery.sessions.list, session.history.read, session.adopt.preview/confirm, maia import scan, maia session adopt, adopt-confirm and history (D-078); the third-party workspace importer was removed (D-082). Desktop onboarding (source candidate): the Work panel's Get started scans metadata (titles on request), registers repositories, previews and natively confirms adoption. In source: an adopted Session's liveness is rechecked before every resume (Claude live and unreadable-record tests; Codex relies on attestation). Not built: one-click use of signed-in CLIs (connection.detect).
  • S11b. Automatic onboarding (D-171): every supported harness's sessions join Maia with no per-session step. Scans at Node start, on a built-in Routine and on demand; every origin but Maia's own; on by default and visible only to the person whose harness ran it; trace without content; an Unassigned list with one confirmation to register a repository; ended sessions claimed as stopped Maia Sessions; running ones observed through S13-managed hooks that fail open; each executor slice adds its source and hook. Acceptance: a session started in a vendor CLI appears after one scan, and its turns stream through the hook while it runs; no other person sees it; an ended session is claimed exactly once, and a resume while another client runs it is refused; a Codex session without a trusted hook and gap-free evidence is claimed only after an attestation; turning onboarding off removes every unchanged hook entry it installed, reports edited ones as drift and keeps the claims; a stopped Node never blocks a harness. Status: Planned, after S11's qualification, S13's managed items, S30, and S12t's reader qualification and trace-only cutover for each onboarded executor.
  • S12. Live Session streaming and attach: S12a live lane replacing the 5-second observation poll; S12b item vocabulary, Codex adapter, session.attach, maia session attach; S12c Claude and Pi adapters; S12d Desktop timeline and pushed terminals. Design, spec. Status: S12a, S12b, S12c Claude done (source candidates): Codex items, delta to CLI line p95 36 ms (1 Session), 39 ms (100), ≤ 2.8 durable writes/s, catch-up p95 23 ms; Claude items p95 35 ms (1), 37 ms (100) (D-081); S12d Desktop Session timeline source candidate (native session_attach relay, live items, resync, Changes, archive and resume, approval answers; fixture-proven, real Desktop run pending); next: pushed terminals; Pi after S23 qualifies.
  • S13. Single harness configurator: config.resolve, plan, apply, drift, import; adapters for Claude Code, Codex, Pi and Cursor; Skills through the pinned skills CLI, its skills-lock.json the only pin, with maia skills status, check and a reviewed update (D-170, Skills); an unpinned Skill is a candidate until it is in the lock; per-Node application with drift reports. E5 owns policy semantics; S13 resolves one admitted snapshot and emits each harness's files, and today's config.toml, config.jsonc and .maia/maia.json are transitional inputs to it. AI2 delivers its Skills commands for Maia's bundled Skills first (D-190). Design. Status: Next: wave 4; the skills CLI pin (1.7.0) is recorded, and worker Skills bypass it (worker Skill at launch).
  • S14. Fleet in minutes: maia node install <host> over SSH installs the pinned runtime and service (RL3), the node.hello handshake (RL2) checks compatibility, an SSH stdio bridge carries requests and S12 streams, and the CLI, MCP and Desktop address several Nodes; the caller chooses the Node for each Session, reading capacity from S15 (placement policy lives in Skills). Status: Source candidate: maia node install | register | list | remove (register: a running Node, D-176), CLI and MCP --node over the SDK's SSH bridge, pinned executors; run on the VPS (D-080); Desktop addresses registered Nodes over the same bridge with a Node label, filter and per-Node New Session, polling them every 15 s (D-088); next: RL2, S12 streams over the bridge (TM3), then maia node rename and maia node disable | enable (TM9): registration only, with a revision check and a receipt; holding a Node's execution stays with S20.
  • S15. Host and agent observability: machine CPU, memory, disk, temporary directory and processes; per-agent metrics and disk use; maia port list joining listening sockets, process trees and leases; admission refuses new Sessions past stated thresholds. Spec. Slice 1 (D-167): node.resources.show, one read of the Node's environment (version, operating system, architecture, containment, executors), host CPU, load and memory, disks, admission and account capacity, and the usage of each Session the caller may see. Every value is measured or absent with a reason. SDK; CLI maia node resources (with --node); the worker MCP tool show_node_resources in both roles; the dashboard's Servers view later. Then thresholds, per-Session disk use and history (S59). Status: Next: wave 3.
  • S16. Leases: one advisory table with kinds port (Node allocation, stable preferred port, connect and bind probes) and lock (exact keys); release on owner cleanup, TTL and Node epoch; MAIA_SESSION_ID, MAIA_WORKSPACE_SLUG, MAIA_PORT and MAIA_PORTS injected; no kernel enforcement. Design, spec. Status: port kind done (source candidate): maia port, MCP, automatic release, MAIA_PORTS for Codex and Claude; next: lock kind, Pi injection, listener mapping (S15).
  • S17. Agent-to-agent messaging: enable the registered session.message.send, session.inbox.* and run.inbox.*; by exact Session ID; Node-stamped sender; durable per-inbox order with cursors and receipts; peer content delivered as data, never consent. Reach (D-166): every Session of a Project by default, whichever checkout or worker runs it; two Projects of one Workspace when both guards set messageReach: workspace (maia project guard set); later, links between exact Workspaces and Nodes (MN1, A2A). session.list follows the same rule. A message's subject and body stay in the Node only until the recipient acknowledges it and its harness's reader returns them with a matching digest; the trace keeps the rest (D-168). Spec. Status: Source candidate (slice 1): the worker tools session_message_send, session_inbox_check and session_inbox_ack, within one checkout of one Node (across servers); next: Project reach and the workspace setting (D-166), the mailbox for read-only Sessions, then the wake on arrival after S26 (FV9).
  • S18. Roles, plugins and guards: S18a Session-bound worker credential and, on Linux, Landlock read denial of the Node runtime directory and auth file (Codex trees: deny entries in Codex's own profile instead, D-110); S18b guards (depth 1 by default, live children per parent, messages per minute, leases per Session); a Session starts and steers only its own children, to a configurable, bounded depth (D-151); S18c Codex and Claude Code launch maia mcp --worker with the Session credential; the worker Skill uses role-scoped MCP tools. Spec. Status: S18a and S18b source candidate: Linux read denial proven on a hostile target (Linux 7.0 arm64, release and ASan builds); Session lists scoped to the credential's Project (D-092); S18c source candidate (D-095): worker MCP through both vendor launch configs, unchanged sandboxes; real SQLite/loopback and vendor-fake proof.
  • S19. Run ledger over executor Sessions: run.ledger.* drives Codex and Claude Code Sessions as dispatches; run ledger task list --ready; run ledger task settle with outcome, Session, turn and evidence; the standalone ledger stops a task after three failed dispatches, and Routine runs follow their per-step retry budget (D-119); session observe gains an attention value. Spec. Status: Source candidate: 20-task graph on fake Codex and Claude Code executors in 1.8 s (21 dispatches); coordinator restart before the first dispatch and mid-run (a lost dispatch replayed) rebuilt from the ledger and session list. Pending: Linux VPS run, task reopen, local-v1 convergence (below).
  • S20. Emergency hold and kill switches: hold and release of one exact Project, Connection, Node or capability, and capability.revoke; new work rejected at once, running work fenced at the next safe edge; receipts and events. Design, spec. Status: Projects and accounts done (source candidate, schema v44): maia hold, held admission errors (p95 ≤ 3.3 ms over HTTP), stop holds end runtimes; next: the capability enablement registry, then capability targets and capability.revoke; Node targets after MN0.
  • S21. Process registry: maia process start, list, logs, stop projecting the specified execution.process.* contract; processes tied to their Session, a port lease taken automatically, bounded logs, and a bounded wait for a pattern in a process's output (logs --follow --match); an agent stops only its own processes. Status: Later; its ownership rules start with agent terminals (TM7, D-175).
  • S22. Skills catalog: orchestrator maia-orchestration, maia-swarm-plan, maia-swarm-supervise, maia-swarm-review; worker maia-worker, maia-worker-review; each with at least three evaluation scenarios and measured outcomes. Design, format and lifecycle. Status: Source candidate: maia-worker injected into every coding Session at launch (a worktree copy, given to Codex as developer instructions per D-105, which connection detect and maia doctor check the installed Codex still honours; a launch plugin for Claude Code), checked against worker MCP tools, with a per-Project opt-out; S18c wires maia mcp --worker into both vendor launch configs; next: the other Skills and evaluation scenarios, wave 4, and a distinct name for the CLI guidance Skill that voice pins, which shares maia-orchestration with the plugin Skill (its digest pin, descriptor references and tests change together).
  • S23. Pi and Maia agent as swarm executors: session create --executor pi|maia-agent on Pi 1.0.0 (D-067), with model providers from maia login, the D-067 extension-safety proof and credential leasing, observed and stopped like Codex and Claude Code Sessions; session.spawn already names both harnesses. The managed worker runs the full kernel today (Pi's default tools plus the safety, task, goal and process extensions; the Node never sets toolProjection), so the executor declares an exact tool projection per Session, and third-party Pi harnesses join only through a digest-pinned admission record, the exact launch environment and a runtime extension check. Status: Next: wave A of executor harnesses (un-paused 2 Oct 2026, scheduled beside S26–S30); S24 gateway follow-up after it.
  • S24. Gateway Connections: Connection kind gateway points every executor at one AI gateway with a validated base URL and an owner-only API key file. Status: Done for Claude Code and Codex (source candidate); Pi and Maia agent follow-up. Spec.
  • S25. Pi Durable evaluation, done 2 October 2026: wait; AG3a rebuilds the managed worker's Pi context from its own Pi session. Status: Evaluated: wait; AG3a after S12b. Evaluation.
  • DP1. Desktop daily-driver foundation (source candidate, 2 October 2026): 73 Node operations exposed through feature descriptors and one node_request bridge, native macOS confirmation for consequential and destructive requests, Node detection or a supervised maia-node --desktop child (owned children drain on quit, signals or host crash through a private parent pipe; attached Nodes stay running), named profiles and an unsigned local .app (Desktop README, D-076). Next: the cockpit (P1.4–P1.5), a Linux dialog and the visual qualification of the sheet.
  • S44. SDK-first client parity, phase 1 (source candidate, 3 October 2026): @maiaos/sdk gains planSessionCreation, createSessions (task lines to running Sessions with a first turn; a retry replays unsettled items with the same command IDs; each outcome carries its steps' receipts and a failed step's command ID), awaitSessionRunning, classifyClientError returning one MaiaError and watchNodeChanges over a cursor-resuming StreamRelay; session.list lists the whole Node with states and attention filters and each listed Session's attention value; the CLI adds session create --message|--prompt-stdin|--from-file, session list --all [--state] [--attention] and session start --wait. client-core now uses them for creation, Node-reported attention and whole-Node pages (D-083).
  • S45. Use the installed CLIs as they are: connection.detect (MCP connection_detect) reads each installed Claude Code and Codex CLI's path, version and sign-in on the Node without reading a credential; maia setup (connection.system.preview/confirm, Desktop native sheet) makes each usable one a system-default Connection with an approved executable. Status: Source candidate (3 Oct 2026, D-084): a Codex turn ran through a model-proxy provider. Claude endpoint skips now suggest explicit gateway registration through the shared detect/setup result. Not built: system-default Claude Sessions with a settings.json endpoint (needs a containment decision), Codex env_key endpoints, approval of a CLI off the Node's PATH. Freshness (Source candidate, D-148): connection detect --refresh compares each installed CLI with the newest version a public registry names and proposes the vendor's update command or maia integration plan; connection update-policy set <cli> <off|notify> keeps the choice on the approval. Planned: auto, adopt vendor-installed updates after a verified artifact and an atomic approval.
  • CLI1. CLI command tree, slice 1: one tree of feature fragments authors every command once (usage, availability, operations, kind, summary, example), checked leaf by leaf against the protocol inventory; -h/--help on every node, maia help --json with the whole tree and the agent contract, usage errors with usage and hint, global options anywhere before --. Slice 2: scope-first paths as a clean break with "did you mean", two-phase leaves (--dry-run, --confirm-stdin, a y/N prompt only at a terminal), MAIA_PROFILE/MAIA_NODE/MAIA_NO_INPUT, durations, doctor, completion, dispatch from the tree with leaf-owned formatters. Slice 3: every resource argument takes an ID, an ID prefix or a unique name or Session title, resolved by the Node's reference.resolve before the command sends exact IDs (ambiguity lists candidates); a missing required --project/--workspace comes from the current folder (the Node maps the path), then the selected Workspace; JSON gains resolved; Session titles (session create --title, first line of the first turn, session rename); list leaves print plain header tables; the SDK's typed call serves descriptor-bound operations. Next: --schema, the worker-credential default. Status: Source candidate (3 Oct 2026, D-103, D-106, D-107); Node follow-ups (D-108): turns report model calls, saturated names admission or account, setup repeats the cap, turn_failed attention.
  • S46. Composer dictation (3 Oct 2026): a microphone in the Session composer and the task dock turns speech into draft text with macOS on-device recognition (no server fallback, no audio kept), mod+shift+D to start or stop, Escape to cancel, and a system/English/French toggle. Platform input like the keyboard: no Node operation, SDK or CLI surface; the text leaves through the dock's own send (D-089). Status: Source candidate; headless renderer and Rust tests pass; live dictation fixture verified by the owner; in-window check pending.
  • S47. OpenShell containment, mandatory on every Node: every agent run in a Node-supervised OpenShell sandbox; Maia policy is the only authored policy, compiled per Session into OpenShell policy; replaced worker-containment machinery and vendor OS sandboxes retire, while terminal/PTY and screen hosting remain (D-182). Spec. Status: Planned (owner direction, 22 Oct 2026): dependency approved (D-116), official SDK path decided (D-118); qualification pending.

Done rows (SP, S1, S2a, S3, S3b, S3c, S4a, S4b, S4c, S5 and S6) are in completed slices.

Swarm coordination slices

Design: swarm coordination. Every slice follows protocol → SDK → Node → CLI → MCP, ships with contract tests for each operation, failure-path and restart tests, and records measured numbers in its completion note. A target that is not met blocks completion; it is not waived. Measurements run on the developer Mac and on the Linux VPS unless the slice says otherwise.

WaveSlices (parallel within a wave)
1S16 port kind, S12a live lane, S20 emergency hold
2S16 lock kind, S12b attach with the Codex adapter, S18a worker credential, S19 Run ledger
3S17 messaging, S18b guards, S12c Claude and Pi adapters, S15 observability
4S13 configurator, S18c plugins, S22 Skills, S12d Desktop, S5 isolation and review
5S14 fleet, S21 process registry, S7 scale qualification

S12 follow-ups. S12t: trace without content (D-168). Every field that holds conversation content keeps a trace (IDs, actors, kind, state, outcome, times, sizes, usage, a digest and a native reference) and holds the text only in transit: until the consumer has it and the harness's reader returns it with a matching digest. S12t owns content reads: they go through that reader, are gated by a content class per caller and masked on read (S65's key masking moves here), and report content_unavailable for what a harness deleted or compacted. Each executor first passes the executor qualification. One executor switches at a time, after its reader qualifies; a purge with a preview and a receipt then removes stored content, keeping content in transit. Receipts keep digests and content-free outcomes. Full transcripts still load on demand. session history read, which today returns text and one-line tool summaries, widens to every item with its full content, page by page, and S28's session.items.read uses the same reader. Live attach and streaming stay as they are (D-077). S12r: purge a Session's trace records when it is archived (S5) and 30 days after its last activity (D-128), under a Workspace retention policy with a byte cap per Session. S12c for Pi waits for S23.

S12e Complete capture. No blind spot: while the Node runs a Session, it traces every event of every enabled capability from the harness's structured output, never from terminal text, and keeps no copy of the content (D-168). That covers messages, tool and command results, file changes, approvals and permission decisions, errors and usage. It also covers plans, nested tasks, hook firings, compaction, and model and effort changes, each as a bounded item. A trace states each output's size. Result metadata the harness provides, such as an exit status or several results, is kept, and what it does not provide is marked unavailable. Whatever a bound or an unknown kind removes is counted by reason, durably, on its turn, or on the Session when no turn is open, so a loss survives a restart. A tool-only turn and an over-long response settle with their items intact. Pi and the Maia agent report items and usage like every other harness, after S23. Capture comes before capability: lifting a launch restriction (subagents, hooks, more tool servers) ships with its capture. Some exclusions stay by design: raw reasoning (D-077, D-081), native history that Maia did not run (D-078), and provider error text, which is kept as a reason code. A Workspace policy decides whether a Routine refuses a harness whose capture is incomplete or only flags it.

SDK1 Public subscription subset. Companies building on Maia get one published, versioned SDK subset: its operations and the observation subscription (signed cursors, gap and reset frames) that the target observation client generates from the protocol. Acceptance: a reconnect resumes from its cursor with no loss or duplicate; a revoked grant ends the subscription with a typed reason; an epoch change and a retention gap each arrive as an explicit frame; the subset follows the compatibility rules. It adds no event bus. Status: Planned, after S12t.

TC1 Tool conventions. Every model-facing tool follows D-172: verb-first snake_case names declared on each projection, the maia__ and <connection>__ namespaces, the common built-in names and parameters, and lowercase error codes with a hint. Acceptance: a mechanical check passes for every tool's format and uniqueness, and each tool maps to exactly one operation (except maia__tool); maia mcp and maia mcp --worker list only the new names; the plugin and worker Skills and the voice orchestrator prompt name only tools that exist; the worker Skill stays within its cap. Status: Planned, before R11 AG2 and before any new tool ships.

CE1 Context and call efficiency (D-173). Maia keeps each harness's fixed context and tool calls low and proves it with numbers. CE1a: a fixed-context budget per role and executor (instructions, Skill bodies and tool schemas; Codex measured with codex debug prompt-input, the others from their launch options), checked in tests with no model call; the worker Skill carries orchestrator text only for orchestrators. CE1b: the lab suite agent (benchmarks) runs a fixed task set through the dev lab and records, per task, input, cached input, output and reasoning tokens, model calls, tool calls and the pass rate, plus the cached share of the first call after an idle gap; replay evals cap tool calls for maia-orchestration and maia-worker. Each run spends model usage, so the owner approves it, and CI never runs one. CE1c: per-Agent defaults (reasoning effort, prompt-cache lifetime, compaction threshold, vendor instructions a role cannot use) change only when a CE1b comparison shows fewer tokens or calls at an equal pass rate, and each change cites its run. CE1d: context stats per Session: the model's window, the tokens in it and the share used, the fixed prefix and each compaction, from the harness's own report (Codex's token-usage notification, which carries the window; Claude Code's context-usage read in summary mode, which makes no token-count calls), with per-category counts where the harness gives them (system prompt, tools, tool-server tools, memory files, messages) and never their text or paths (D-168); shown by session observe and S12f's summary, with a warning before a Session nears compaction. Acceptance: the budget test fails when a role's fixed context grows past its pinned bound without a reviewed raise; CE1b has a baseline for Codex and Claude Code; with S26's wait, a child that settles before the wait's deadline costs its coordinator one wait call and no polling; CE1d reports each Codex and Claude Code Session's window use within one turn of a change, and an executor without a report shows it as unavailable. Status: Planned; CE1a and CE1d now, CE1b after the dev lab runs agent tasks, CE1c after CE1b.

S12f Capture read. session.summary reads what a Session, turn or Routine run did without its transcript: items by kind; tool, command, file and error counts; declined requests; losses by reason and incomplete coverage; tokens, cost, model and duration. Item content comes from S28's session.items.read through the harness's reader, with S12t's content classes and masking (D-168). Routines, evaluators and policies act on these reads; Maia does not manage the chat. Protocol, SDK, Node, CLI and MCP. The summary needs only T1 for Claude Code and Codex, and comes before FV11. The rest of S65 follows the cutover.

S16 leases. Acceptance: no port granted twice under 50 concurrent acquirers; a port held by another process on 127.0.0.1, ::1 or a wildcard address is never granted (macOS and Linux); acquire p95 under 10 ms; release within 1 s of the owner Session's cleanup proof; expiry and restart reconciliation under a test clock; lock contention returns the holder and --wait returns within its bound.

S20 emergency hold. Acceptance: a hold rejects new Session, turn and dispatch admissions for its exact target within 100 ms; running work on the target is fenced within 2 s at the next safe edge with typed outcomes; release restores admission; preview, confirmation, receipt and event for each hold; no all target.

Specs and completion notes for S1, S4b, S12a–S12c, S18a–S18c, S24, S25, S26 and S30 are in completed slices.

S19 Run ledger. Acceptance: a 20-task graph runs to completion over executor Sessions; --ready lists exactly the unblocked tasks; settle records outcome and evidence; a coordinator restarted mid-run rebuilds its state from the ledger and the Node's Session list; three failed dispatches stop a standalone task, and a Routine run's task follows its retry budget (D-119); attention values match Session states in tests.

S19 follow-up: one Run storage. The Run ledger has its own tables beside the local-v1 terminal Run (decision). Converge the local-v1 Run onto the ledger (D-119). Its consumers today: the CLI run commands and compact output (apps/cli/src/orchestration), the Desktop terminal bridge's reviewed run.* methods (apps/desktop/src-tauri/src/terminal_bridge.rs), the Node admin monitor reads (services/node/src/admin-monitor), execution attempt placements and relocations, and the S17 run.inbox and run.question operations.

S17 messaging. Acceptance: delivery p95 under 100 ms locally; per-inbox order kept over 10,000 messages; idempotent send by command id; the sender is Node-stamped and cannot be forged by message content; delivery to a busy target queues as turn input through its adapter; across harnesses, a Codex Session and a Claude Code Session of one Project exchange messages and questions through the Node in both directions, with the same order, receipts and authorization and no direct path between them. A wake to a target blocked on an approval is refused with a typed reason and no side effect. A wait that times out never counts as non-delivery: a retry reconciles the prior receipt first.

S15 observability. Acceptance: sampling at 1 Hz costs under 1% of one CPU core; maia port list attributes listeners started by Sessions to the right Session on macOS and Linux; thresholds refuse new Sessions with the stated reason.

S22 Skills. Acceptance: each Skill has at least three evaluation scenarios run against the real CLI; the swarm Skills complete a recorded fan-out, supervise and review scenario with N = 1, 3 and 8 workers, and the completion note reports wall time, tokens, retries and human escalations.

S7 scale qualification. Acceptance: 8, 16 and 50 concurrent executor Sessions on one Node; report Node CPU and memory, streaming latency p95, admission latency and failure counts; the Node cap is raised only to a measured, stable level.

S47 OpenShell containment

Planned; dependency approved (D-116, D-118). NVIDIA OpenShell becomes a mandatory core dependency: every Node supervises its own OpenShell gateway, and every agent run (Codex, Claude Code, Pi, Maia agent, S31–S34 harnesses and S21 processes) runs in an OpenShell sandbox, with no native fallback and no opt-out. A Node without a qualified OpenShell runtime refuses worker launches with a typed error. No version is pinned yet; S47a pins it, and nothing is installed or implemented yet. Until S47 ships, Sessions run on host containment, as the first version and the cutover do (D-150).

Design, sub-slices S47a–S47f, entry conditions, known gaps and affected slices: S47 OpenShell containment.

Executor harnesses and agent workflow

Planned (owner request, 2 October 2026; S43 added 3 October 2026; S48 added 22 October 2026). More executor harnesses, and the agent-workflow features that make a swarm usable every day. Nothing in this section is a source candidate yet, and this update installs nothing. Slice IDs continue the swarm numbering. Vendor API names were checked on 3 October 2026 in the app-server schema generated by the installed codex-cli 0.160.0 and in the type declarations of the pinned Claude Agent SDK 0.3.285; anything else is marked unverified.

Every slice follows protocol → @maiaos/sdk → Node → CLI → MCP → client-core → Desktop; the Deliverable column names each exposure. These rules hold for every row:

  • The Node is the only authority. It admits executors and owns queues, schedules, lineage, usage and receipts; agents and clients propose through operations.
  • Each executor launches with an exact environment: an approved executable pinned by digest, allow-listed variables, and its own per-Session config and home directories. It runs under a stated containment profile. An executor whose containment is not qualified runs read-only, or not at all. Executors without a vendor sandbox rely on Maia's host containment: Linux first, macOS after R2's local hard-containment adapter.
  • No ambient credential reads. A credential comes from a Maia Connection and reaches a worker only through its launch environment. It never appears in argv, logs, receipts or observation.
  • Consequential actions follow preview → confirmation → compare-and-set and idempotency → receipt. Examples: admitting an executor, enabling auto-resume, creating a schedule, handing off a worktree, or closing another Session's preview. S18a roles, S18b guards, S2 grants and S20 holds bound every agent tool.
  • Real vendor runs use Codex. Other executors are proven on recorded fixtures and fakes until the owner approves a real run.
  • New dependencies are listed below as needs owner approval. None is installed now.
WaveSlices (parallel within a wave, in dependency order)
A: usable soon, on existing primitivesS26 queue, S26b steer, S27 auto-resume, S28 Session control MCP, S29 agent Session tools, S30 scheduled Sessions, S23 Pi and Maia agent (swarm table)
B: new executorsS31 ACP adapter, S32 ACP registry agents, S33 Cursor, S34 OpenCode 2, S35 Grok, S36 Antigravity
C: cross-cuttingS37 fork, S38 model or provider switch, S39 native subagent lineage, S40 Session as context, S41 delegate_task, S42 worktree handoff and previews
LaterS43 model gateway with an account pool (blocked on owner decisions)

Executor coverage: Codex (S3, S5) and Claude Code (S6, S5) are source candidates; Pi and Maia agent come with S23; Cursor with S33; OpenCode 2 with S34; Grok with S35; Antigravity with S36; other Agent Client Protocol agents with S31 and S32.

  • S26. Server-side turn queue. The Node already keeps up to 8 pending turns per Session (turn.queued). turn.send dispatches in send order after the running turn settles. Add turn.queue.list and turn.cancel for a queued turn. SDK; CLI maia session turn queue, maia session turn cancel; MCP turn_queue_list, turn_cancel; client-core queue state. Status: Done for the queue, list and cancel, Source candidate (23 Oct 2026, #65). Client-core already carries queuedTurns; cancel controls in the clients are deferred. Next: session turn wait and MCP turn_wait also end when a waited Session needs a person (an approval or a question), with their own result reason naming the attention, never as a settled turn; session turn send --wait sends and waits in one call. The orchestrator role gets the same wait (wait_turn under D-172), and the wait operation gets its own longer request deadline, so one call holds until a waited turn settles, needs a person or reaches that deadline, and a coordinator spends a few calls per child instead of one every 4 seconds (D-173). S26 also owns the wake of an idle parent when a child settles; S17's wake on message arrival (FV9) reuses that path.
  • S26b. Turn steer, split from S26 (D-144). Planned. turn.send mode steer injects into the running turn through the executor's native steer. Codex steers through turn/steer with the required expectedTurnId (codex-cli 0.163.0 generated JSON schema); Claude Code 2.1.309 refuses, because in a stream-json probe a mid-turn message joined the running turn only at the next tool boundary, ran as a separate turn during text generation, and carried no turn guard or acknowledgement; Pi waits for S23.
  • S27. Auto-resume at limit reset. Today turn.send refuses while the Connection's limitedUntil lies ahead. Under a confirmed per-Project policy (off by default), a send to a limited Session queues instead (S26). At limitedUntil the Node resumes the limited Sessions of that Connection and dispatches their queued turns, scheduled on the Effect clock, within caps (Sessions resumed per Connection per reset, attempts per Session). Events and receipts name the policy and the person who confirmed it. SDK project.autoresume.preview/confirm; session observe shows the wait and the reset time; CLI; MCP read; Desktop badge. Status: Dependent on S26.
  • S28. Complete Session control MCP. maia mcp already covers Session create, start, list, show, observe, events, history read, stop, resume, archive and diff, and turn send, show, wait and interrupt. Gaps: session.search (scoped search over titles and trace metadata first, then bounded content search through each harness's reader that reports its coverage and unavailable sources (D-168); filtered by read grants before counting, cursor-paged, at most 100 results) and session.items.read (items by cursor, content read from the harness: the transcript without a live attach), which waits for S12t's reader, content classes and masking. The tools of S26, S29 and S37–S42 join as each lands. SDK; CLI maia session search, maia session items; MCP. Status: Next: wave A.
  • S29. Agent Session tools: reuse the shipped session.rename; session.title.generate (a deterministic title from the first prompt; a model-written title waits until an operator journey shows the deterministic one and rename fall short); session.link.add/remove (a pull request URL recorded as data, with no hosting side effect: PR creation stays with R5); session.settle with outcome done, abandoned or needs_review and evidence, and session.reopen. Role scope: a worker acts only on its own Session, an orchestrator on its children, a person on any Session they may write. Archive stays a human preview and confirmation (S5). Receipts and session.updated events. SDK, CLI, MCP, client-core. Status: Next: wave A.
  • S30. Scheduled Sessions, the minimal part of R8 pulled forward: routine.create.preview/confirm, routine.list, show, pause, resume and disable. A cron expression and time zone (Effect's Cron module, no new dependency) fire one Session from a stored template (Project, executor, Connection, model, prompt) and send its first turn. No overlap: a fire is skipped while the previous fire's turn is unsettled. Missed fires while the Node was down run at most once at start. Minimum interval 15 minutes; at most 20 enabled schedules per Project. Holds (S20) and guards apply. SDK; CLI maia routine; MCP read; Desktop list. R8 keeps connectors and the attention inbox. Status: Source candidate (28 Oct 2026, #57): the registered Routine operations, the Node scheduler (which also stops each finished routine Session to free its slot), SDK, maia routine with FV8's routine run and the MCP read tools; the Desktop list is not built. Ships as the first Routines (S50) (D-142).
  • S31. Generic Agent Client Protocol (ACP) executor adapter. One Effect adapter speaks ACP over stdio to an admitted agent: session/new, session/prompt, session/update and session/cancel map to Maia Session, turn, S12 items and interrupt; session/request_permission maps to S4b approvals and is refused until S4b lands, never auto-approved. Maia advertises no ACP client filesystem or terminal capability, so agents use their own tools inside Maia's containment. executor.acp.catalog.list reads one pinned registry snapshot and records its digest; Maia never scans PATH or editor configuration. executor.acp.admit.preview/confirm records the admission: registry entry, version, distribution digest, exact command, arguments and environment allow-list, auth method, containment profile. session create --executor acp:<admission>. SDK; CLI maia executor acp catalog|admit|list; MCP read; Desktop picker. Needs owner approval: an ACP client library (@agentclientprotocol/sdk; name and version to verify) or a small JSON-RPC client on Effect; the registry URL. Status: Dependent on S12c, owner approval and host containment (Linux first).
  • S32. ACP registry agents: other agents listed in the ACP registry (checked 3 October 2026), each through one S31 admission record, a recorded fixture of its ACP messages and a containment qualification against decoys (as in S5). Each signs in through maia connection login into its own per-Connection directory, never the user's home. No per-agent code unless a fixture shows a gap. Needs owner approval: each agent's executable and account. Status: Dependent on S31.
  • S33. Cursor through the official Cursor SDK (@cursor/sdk, public beta), not the CLI. Local runtime only; Cursor cloud agents run outside Node containment and stay out of scope. The SDK runs in an out-of-process Maia worker behind an Effect adapter, as Pi does. The API key is a Connection (maia login cursor --api-key-stdin, an owner-only file, CURSOR_API_KEY in the launch allow-list). SDK events map to S12 items. The SDK's local tool sandbox is unverified, so the worker runs under Maia's host containment and write access waits on a decoy qualification. SDK; CLI session create --executor cursor; MCP; Desktop. Needs owner approval: @cursor/sdk and Cursor API-key billing. Status: Next: wave B, after approval.
  • S34. OpenCode 2. One opencode serve per Session on a Node-leased loopback port (S16), with a per-Session server password and per-Session config and data directories. Maia calls the pinned V2 HTTP API (OpenAPI 3.1) through Effect HttpClient, so no client package is needed, and maps its event stream to S12 items. Maia keeps the trace (D-168); whether this executor's server keeps its events is unverified, and without that its content is live only. Models come from a Maia Connection, an S24 gateway first. Host containment, Linux first. SDK; CLI session create --executor opencode; MCP; Desktop. Needs owner approval: the @opencode/cli 2.x executable, admitted by digest; @opencode/client only if HttpClient against the spec falls short. Status: Dependent on S12c and owner approval.
  • S35. Grok. The ACP registry lists a grok-build entry. If xAI publishes it (unverified), Grok joins through one S31 admission record, as in S32. Otherwise a spike names an official headless surface (CLI, SDK or ACP) before any adapter. Needs owner approval: the executable and account. Status: Dependent on S31 and publisher verification.
  • S36. Antigravity. The ACP registry lists an antigravity-acp entry. If Google publishes it (unverified), Antigravity joins through one S31 admission record. Otherwise a spike names an official headless surface first; without one the slice is blocked. Needs owner approval: the executable and account. Status: Dependent on S31 and publisher verification.
  • S37. Session fork from a turn: session.fork (source Session, turn, optional Connection) creates a child Session that records its lineage (source Session and turn). It uses native fork where it exists: Codex app-server thread/fork with lastTurnId (in codex-cli 0.160.0) and the Claude Agent SDK forkSession option with resumeSessionAt (in 0.3.285). OpenCode 2's parent_session_id and every other executor are unverified, so they fork by seeding a new native session from the source Session's transcript, read through its harness up to the turn (the AG3a mechanism, D-168). A write Session's fork gets a new worktree branched from the source worktree's current commit; files are not rewound to the turn, and the result says so. SDK; CLI maia session fork; MCP session_fork; Desktop "fork from here". Status: Dependent on S12c and AG3a.
  • S38. Switch model or provider mid-Session: session.model.set takes effect at the next turn. Same vendor: a native switch (Codex turn/start model, Claude Agent SDK setModel, both in the installed versions). Another vendor or Connection: the Node starts a new native runtime generation of the same Maia Session, seeded from the previous harness's transcript through its reader and checked against the Session trace (as AG3a, D-168), keeps the earlier native session ID in history and records an event and a receipt. SDK; CLI maia session model set; MCP; Desktop picker. Status: Dependent on S37's seeding and AG3a.
  • S39. Native subagents as child Sessions. Map Claude Code Task subagents (task_started messages, parent_tool_use_id, agent_id) and Codex sub-agent threads (SubAgentSource thread_spawn with parentThreadId, collab agent tool calls) into S12 items and read-only child Session records with model, status and history. session list --tree and session.lineage.show. The vendor owns a native child, so it is interrupted through its parent. SDK; CLI; MCP; Desktop lineage view. Status: Dependent on S12c.
  • S40. A Session as context: context.attach adds a bounded excerpt of Session B to Session A's next turn through the R1 context manifest. The excerpt is a summary or the last user and assistant messages (8 KiB by default; no tool or command output unless asked), quoted as data with its source Session and revision. Read scope is checked against the caller's grants on B, and provider-export consent is required when B lies in another Workspace. @<session> completion and dragging from the Session list are client-core projections of the same SDK call. SDK; CLI maia session turn send --context-session <id>; MCP parameter; Desktop. Status: Dependent on R1 context manifests.
  • S41. delegate_task agent tool: one tool (MCP, and a Pi and Maia agent tool) that creates and starts a child Session on any admitted executor, Connection and model, sends its first turn, records it as an S19 Run ledger dispatch and returns the child to wait on. Built on session.spawn/session.create, the S18 orchestrator role, S18b guards, S2 grants and S20 holds; a child gets only the executors and Connections granted to the parent's Project. SDK; CLI maia session delegate; MCP delegate_task; Desktop lineage. Status: Dependent on S18b guarding session.spawn, S19 and wave B for other executors.
  • S42. Worktree handoff and preview tools. Worktrees (S5): session.worktree.show (path, branch, base, changed files) and session.worktree.handoff.preview/confirm (moves an idle or stopped Session's worktree and branch to another Session of the same Project, with compare-and-set on both). Previews: preview.list joins S21 processes, S16 port leases and S15 listeners into Session-owned loopback URLs; preview.close stops the owner's process and releases its lease. An agent closes only its own previews; a person closes any after confirmation. SDK; CLI maia session worktree, maia preview list|close; MCP; Desktop. Status: show and handoff Next (S5 is done); previews dependent on S21 and S15.
  • S43. Model gateway with an account pool. The owner connects several vendor accounts (Claude Pro or Max, ChatGPT and Codex, Gemini and others), and the Node serves OpenAI-compatible /v1/responses, /v1/chat/completions and /v1/models and Anthropic-compatible /v1/messages endpoints, routing each request across the pool: round-robin or fill-first, failover on limits, resume at reset (S27). Accounts sign in, and model calls run, through Pi's official provider OAuth layer (@earendil-works/pi-ai, already a dependency), the Node's provider pools and credential leasing. Maia workers reach it as an S24 gateway Connection pointing at the Node; other CLIs use a revocable gateway client key. Loopback by default; tailnet exposure only through the device-authorization design for remote client access (pairing accepted in D-056); never Funnel. SDK; CLI maia gateway status|accounts|keys; MCP read; Desktop usage view. Owner decisions: (1) it changes the rule that Maia never reads, stores or proxies a vendor credential, because pooled accounts' OAuth tokens would live in the Node secret store; (2) the provider-terms risk of proxying subscriptions, accepted for the current setup, decided again for this slice; (3) the exposure scope; (4) the vendor-compatible HTTP routes are a protocol extension. See also the same rule in vendor executors and D-071. Status: Later (owner, 3 Oct 2026); blocked on owner decisions.
  • S48. Project goals. Each Project keeps a bounded list of Node-owned goals (objective, success criteria, constraints, status active, paused, done or abandoned, revision): project.goal.list and show (MCP project_goal_list and project_goal_show for coordinators and the Project's workers), and two-phase project.goal.preview/confirm to create, revise, pause, resume, finish or abandon one. Run ledger tasks and Sessions may name a goal, and show lists them with their settled outcomes as evidence. Project Sessions receive the active goals in their context manifest (R1). CLI maia project goal list|show|set|done|abandon; Desktop shows goals on the Project. Status: Planned (owner request, 22 Oct 2026).

S26b steer. Acceptance: a steer is refused under an emergency hold; command ID, input digest and target are reserved durably before the executor is called, so a retry after a lost receipt never reaches the executor twice; the Codex acknowledgement is checked against expectedTurnId; a steer whose expectedTurnId no longer runs fails with turn_not_active and queues nothing; an executor without native steer returns steer_unsupported and never queues silently.

S27 auto-resume. Acceptance, under a test clock: the limited Sessions of one Connection resume within 5 s after limitedUntil, and each queued turn dispatches once; a Connection disabled, held or limited again before the reset resumes nothing; the per-reset cap stops the rest with a typed reason and leaves their turns queued; a Node restart during the wait still resumes once; without the confirmed policy nothing resumes and a send keeps today's retryable saturated refusal; every resume has an event and a receipt.

S28 Session control MCP. Acceptance: registry parity stays at 0 findings and the MCP budget test (D-070) still passes; search never returns or counts a Session outside the caller's grants (tested with a denied Workspace); metadata search over 10,000 Sessions and 1 million trace records has p95 under 200 ms on the developer Mac (SQLite FTS5 over titles and trace metadata, never content (D-168), present in the bundled node:sqlite of Node 24.19); item reads return at most 500 items per page and resume exactly after their cursor; a Codex worker and a Claude Code worker read each other's Session items through the same tools and item shape, within their read grants.

S29 agent Session tools. Acceptance: a worker renaming or settling another Session gets role_denied before any handler; an orchestrator reaches only its own children; rename and settle compare-and-set on the Session revision (a stale revision fails) and replay their receipt for a repeated command id; a link that is not an https URL is refused; settle never archives, stops or removes a worktree; a failed title generation keeps the old title and returns a typed error; the role rules hold identically for a Codex and a Claude Code worker.

S31 ACP adapter. Acceptance: a fixture ACP agent completes a prompt with streamed items, cancel and restart; a digest mismatch, an extra environment variable or a changed argument refuses the launch; without an admission record nothing launches; a permission request is refused before S4b and afterwards reaches a person, never auto-approved; under containment the agent cannot read decoys in $HOME, sibling worktrees or Maia's runtime directory; the registry is fetched only by an explicit catalog read. Any real run uses a Codex-backed ACP agent, if the owner approves one.

S32 ACP registry agents. Acceptance per agent: an admission record, a recorded-fixture replay test, a decoy containment test and a login that writes only its per-Connection directory. An agent whose sign-in needs an ambient config file or a write to the user's home is refused with the reason stated.

S33 Cursor. Acceptance: fixture tests map SDK events to items, interrupt and stop; a scan finds the API key in no argv, log, receipt or observation; a cloud runtime request is refused; a missing key fails at create with a typed error; a changed SDK digest or an extra launch variable refuses the launch; vendor permission prompts are refused until S4b; write profiles are refused until a decoy containment qualification passes.

S34 OpenCode 2. Acceptance: one server per Session, bound to 127.0.0.1 on a leased port, refusing requests without its password; a server crash marks the Session failed and resume starts it on a new lease; an OpenAPI digest that differs from the pinned one, a changed executable digest or an extra launch variable refuses the launch; permission prompts are refused until S4b; under containment the server cannot read decoys in $HOME, sibling worktrees or Maia's runtime directory; trace records survive a Node restart, and content is read through OpenCode's qualified reader or reports content_unavailable (D-168), with live-only content labelled.

S35 Grok and S36 Antigravity. Acceptance: the publisher and distribution are verified and recorded before admission; then each meets S32's per-agent acceptance.

S37 fork. Acceptance: forking at turn 4 of a 10-turn Codex fixture gives a child whose native history ends at turn 4 while the source is unchanged; the Claude path is proven on a fixture with forkSession and resumeSessionAt; a seeded fork carries no secrets or hidden reasoning (the AG3a checks); forking from a turn still in progress is refused; lineage shows in session show and survives a restart.

S38 model or provider switch. Acceptance: a switch takes effect at the next turn, never mid-turn; a cross-vendor switch keeps the Maia Session ID and records both native IDs; a failed new runtime leaves the previous one resumable; a model outside the Connection's catalog is refused; a repeated command id replays the receipt.

S39 native subagent lineage. Acceptance: Claude Code and Codex fixtures with 3 subagents each give 3 child records with the right parent, model, status and items; a child whose final event is lost resolves as unknown when the parent completes, never completed; stopping a child directly is refused and names the parent interrupt; the lineage read is bounded and cursor-paged. Until S39, S12e records nested tasks as bounded items on the parent turn; S39 promotes them to child Sessions.

S40 Session as context. Acceptance: attaching a Session the caller cannot read fails and leaks no content; a cross-Workspace attach without export consent fails; the excerpt never exceeds its bound, carries no tool output by default and records its source Session and revision in the turn's context manifest; a Codex Session's excerpt attaches to a Claude Code Session's turn, and the reverse, under the same bound and manifest.

S41 delegate_task. Acceptance: 100 delegations with a live-children limit of 8 give 8 children and 92 typed guard errors with no partial Session; a caller without the orchestrator role gets role_denied; an executor or Connection not granted to the Project is refused; each child appears once in the Run ledger and in its parent's lineage; a held Project refuses delegation; a Codex Session delegates to a Claude Code child, and the reverse, with the same operation and guards.

S42 worktree handoff and previews. Acceptance (show and handoff close on the handoff checks, previews on the rest): a handoff from a running Session or to another Project is refused; concurrent handoffs of one worktree commit once; branch and files are unchanged by a handoff, also between a Codex and a Claude Code Session; preview.list attributes a Session's dev server to the right Session on macOS and Linux; an agent closing another Session's preview gets role_denied; closing releases the lease within 1 s.

S43 model gateway (later). Acceptance sketch, not yet testable; numbers are set when the owner decisions are made: N accounts per provider; round-robin and fill-first routing with limit-aware failover; no token in logs, receipts or observation; per-account usage visible; a Codex request through the gateway completes and streams; with every account limited, a request fails with a typed error naming the earliest reset time; a non-loopback bind is refused without the device-authorization design; adding an account and creating or revoking a client key go through preview, confirmation and receipt; the HTTP routes are checked against the protocol registry.

S48 Project goals. Only a person confirms a goal change: a coordinator or worker reads goals and may request a preview, and the Node refuses it every confirmation (S1, S18a). No agent verdict, settled task or evaluation closes a goal (R11 port map). Maia agent's per-Session goal stays Session-scoped and may name a Project goal. Workspace goals and roll-ups are not in this slice. Acceptance: create, revise, pause, resume, finish and abandon each produce a receipt; a stale expected revision fails and changes nothing; a retry with the same command ID replays its receipt; a coordinator's or worker's confirmation gets role_denied; a goal or task from another Project is never listed or linked; the next turn of a Project Session carries the current goal digest in its context manifest.

Dependencies that need owner approval. S31: an ACP client library or a small JSON-RPC client on Effect, and the registry URL. S32, S35 and S36: each agent's executable and account. S33: @cursor/sdk. S34: the @opencode/cli 2.x executable, and @opencode/client only if needed. S43: no new package (@earendil-works/pi-ai is already present), but the owner decisions above. S26–S30, S37–S42 and S48 need no new dependency.

Agents, routines and triggers

Planned (owner direction, 22 October 2026). These slices ship CLI first: protocol → SDK → Node → CLI, with MCP tools and the HTTP API from the same registry; the web client (S52), Desktop and mobile follow. A workflow is a Routine with steps, not another runtime, and third parties extend Maia with event sources, never with code in the Node (routine model).

  • S49 Agents. Versioned Agent definitions per Project, then per Workspace after R3: harness (Claude Code, Codex, Pi or Maia agent, an ACP agent), Connection, model, effort, an ordered fallback list of these, Skills, instruction, limits, an accountable person, an optional manager Agent for escalation and review routing, a placement (local OpenShell by default, a named remote sandbox after S47f) and an optional home Session; list, show, and two-phase create, revise and disable. session create --effort ships first; an unsupported effort is rejected, never mapped. Maia builds no harness but Maia agent. Its CLI noun is maia agents; maia agent keeps launching Maia agent (D-120). Status: Source candidate (#53): Project Agents with agents.list, agents.show (MCP read) and the two-phase agents.change.preview and agents.change.confirm (create, revise, disable; a disabled Agent is final), maia agents, and session create --agent for Claude Code and Codex. Not built: Workspace scope, ACP, remote placement, limits, re-enable, fallback routes (S60a), Skill references (S22) and a Node-enforced sessions: single (D-163).
  • S50 Routines. Per Project or Workspace, listed per Agent: one trigger, then one step (Agent, Skills, instruction, optional harness, model and effort overrides, and a goal once S69 adds it) or steps chained with after, each run one Run ledger graph. A person step waits for an exact person (a role after ORG1) to approve, review or answer, with an expiry that fails the step and an optional escalation person; ORG4's two-person rule applies. Cron and manual triggers; pause, resume, run now, and run history with live step status, each run a sub-tree with paged history (D-163). S30's schedules ship as the first Routines. After S47b, a cron trigger may name a gate (D-174): a person-set command run in a sandbox as one exact Agent named by the gate, with that Agent's placement and grants, whose output alone decides whether a Session starts, so a Routine polls a source without an S51 connector at no model cost and may fire every minute. Acceptance for the gate, under a test clock: an empty gate starts no Session and counts one skip; a gate's output reaches the step masked; a timeout fails the fire with a typed reason; an ungated trigger under 15 minutes is refused.
  • S51 Event triggers. Event sources and one ingest operation (SDK and CLI, no model tool): a source posts typed events with its own revocable credential, so a GitHub App connector can start a Routine. Each connector is a new service needing owner approval; Node-event triggers wait for a loop guard. Extends R8.
  • G1 Native Session goals (D-162). Extends the planned session.goal.* contract with person-only set and clear beside its show: the Node sends the harness's native goal and refuses a Session that no FV11 run cap bounds; each harness needs its own proof.
  • S69 Session goals. A Session, Routine step or task can carry a goal: an objective, a check and a mandatory budget; work continues across turns until the check passes. Maia owns the goal and its loop (design): a command check runs a person-set command and reads its adapter-recorded exit code, a rubric check uses a separate evaluator (R10a), and the Node sends each continuation as a receipted turn.send, never while a person's answer is pending or after a failed, interrupted or unknown turn. Only a person changes a goal or its budget. Where a pinned harness proves its native goal works under Maia's launch (Claude Code /goal, Codex thread/goal/*), the adapter uses it inside a turn for the harness's full capability; its verdict is advisory and Maia's check decides. Opt-in per step, with a check and budget in templates (S63); a Workspace, Project, Agent or step policy (E5) can require or forbid goals. Extends the planned session.goal.* contract, unregistered today. A task opens a harness Session that may use that harness's native goal; worker launches leave native goals on (D-123). Entry: a decision entry for Node-sent continuations where a harness has no native goal, and the per-harness proof.
  • S52 Web client. The shared client served by the Node on loopback behind a short-lived bootstrap token, like node monitor, for Agents, Routines, runs, step status and event sources, over the S49–S51 operations the CLI already runs. Entry condition: a decision entry that replaces the no-browser-client rule (ARCHITECTURE.md, client architecture, D-049) and defines the browser session, Origin and CSRF checks, person-bound confirmations and the remote path.

Order: S30 first (cron Routines with an inline Session template), then S49, S50 after S19 (D-119), S51; S69 for Sessions after S26, S29 and S55 (rubric checks after R10a and S65), then for steps and tasks after S50 and S53; S52 after its decision entry, deferred until DP2 ships, and the S49–S51 CLI.

Acceptance. A failed step starts none of its dependents and the run settles once with evidence; a person step resumes only on that person's answer, fails at its expiry and never accepts an agent's answer; a tick retried with its identity creates one run; an event from an unknown or revoked source, or a repeated source event ID, starts nothing; an injection payload in an event changes no policy; a source cannot start a Routine outside its scope; an agent confirming an Agent, Routine or source change gets role_denied; each mutation previews, confirms and leaves a receipt. A goal settles once with evidence when its check passes, it is judged impossible, its budget runs out or a person clears it; a worker's claim that the check passed, or its change to its goal or budget, is refused; no continuation follows a pending question, a failed, interrupted or unknown turn, or a person's own turn; a restart sends one continuation; after a budget stop, resume or move starts none; event data never sets a goal.

Agent operations

Planned (owner direction, 22 October 2026). What running teams of agents needs beyond S47–S52. The feature coverage map assigns each requested feature to a slice or marks it open or not planned.

  • S53 Tasks. Nested tasks: parent, owner (Agent or person), status, blocks, branch and PR links; the owner wakes when the last child settles; tree and wait in the CLI, a board view in clients; each Routine run is a task tree. Evolves the Run ledger, never a second engine. D-119 settles its model: the run ledger is the one task primitive, with a per-step retry budget for S50 and S60 dispatch.
  • S54 Workspace goals and rules. After S48 and R3: Workspace goals over Project goals with horizons, milestones and a focus agents read first, linked to tasks, Routines and Agents through tools, SDK and CLI; versioned Workspace and Project rules every Session reads. An agent may preview a change, such as pausing a Routine; only a person confirms.
  • S55 Budgets. Extends BudgetReservationV1 with Workspace and Routine scopes and money, then person and team scopes after ORG1: reserve before a run, warn, then hold at the limit; report per run, task, Routine, Agent and Project, then per person and team. Extends R8's budget attention.
  • S56 Tracing. W3C trace context from the client request through Node, Session, turn, tool and model call; trace views that extend R1 context inspect to each turn, in the CLI first and later the web client; a run span records queue wait (enqueue to dispatch) and wake-to-start (trigger to the linked turn.started); opt-in continuous OTLP export, a new egress needing owner approval (T7 stays one-shot).
  • S57 Required gateway. A Project or Workspace names the gateway Connection every vendor Session must use, such as a subscription proxy (D-071's per-gateway decision still applies). S57a: the Node refuses any other Connection for every harness; each launch sets only that gateway's URL and key and clears competing keys, subscription tokens and vendor logins, never falling back to a person's sign-in; maia connection test <gateway> --executor <kind> probes the wire protocol that harness needs (Responses for Codex, Messages for Claude Code) and lists the gateway's models; each harness slice (S23, S31–S36) adds its gateway mapping before admission. S57b: S47 network rules allow only the gateway host, with no approval that reopens model hosts. Extends S2, S13 and S24.
  • S58 Server setup. Extends maia node install (S10, S14): the release comes from its channel by digest (RL3, RL4), with no local artifacts; the preview shows the host-key fingerprint and confirmation pins it; the probe adds S47 checks. After MN1, SSH delivers its one-use challenge and the server enrolls as an Execution Node that connects outbound and reconnects with capped backoff, replacing per-command SSH bridges that a host's SSH rate limit can block. Each failure is classified from a closed set as transient (retry) or needs-operator (stop and report). Reconnecting never installs, updates, restarts or prompts. SSH stays for install, update, repair and sign-in.
  • S59 Fleet view. Extends maia node list and the terminal dashboard's Servers view (D-161), with a web view after S52: Nodes, Execution Nodes and live workers (Session, role, Project, heartbeat carrying the D-167 resource record) with T2 CPU, memory and disk history; agents read it within their grants. Each host shows its failure reason and next attempt, and a Routine checks fleet health from this read.
  • S60 Agent reliability. S49 fallback lists applied under D-023, never for R10a/R10b automation, with quota cooldowns. A harness switch keeps continuity: one Session keeps each Connection's native session; the next harness gets a budgeted, S12t-masked handoff from the Session's trace and its previous harness's transcript (original request, recent turns, commands, file changes) and its diff, with references a coding worker reads through its worker MCP, and a harness used before resumes its native session with only the turns it missed. Switches happen between turns: after output, the turn settles and a person, orchestrator or S69 continuation sends the next (D-023). Reasoning, tool state and approvals never transfer. Entry: a decision entry letting one Session span harnesses. S60a, needing neither: per-task run profiles; resume after a Node restart without replaying effects; reuse a reviewer's Session; skip a tick when nothing changed; the scheduler's aging and coalescing with a work-in-progress cap; a stuck task escalates through R8. S60a also owns the visible queue of D-163: queued rows with one reason and their wait time, expired entries, and a cron's if-busy: queue | skip.
  • S61 GitHub. Agents never use a person's gh or Git credentials. S61a, built in: a GitHub App Connection kind (one App per Workspace, numeric owner pins, a token per repository and permission, a person-confirmed write identity) and GitHub operations through the CLI, SDK and maia mcp within D-070's budget, with a merge feed attributing each merged pull request to its task and runs. Issue selection is a generic Projects v2 field, label or assignee filter. S61b, the first Maia verified extension (S73): Skills, review and triage templates, and a service linking issues and pull requests to S53 tasks, with signed webhooks or polling for a private Node. No admin merge; every GitHub write, Git push included, is a Node operation checked against current grants before a credential is attached, with pushes bound to the inspected commits and expected head; paths and workflow files a policy protects need their own grant (D-124); GitHub writes, merging included, are Workspace configuration, tools a person grants to exact Agents for exact repositories, with branch protection enforcing checks and reviews, and an ungranted write asks a person (D-116) (design). Extends R5.
  • S62 Evals and datasets. Named Workspace evals (R10a questions and rubrics, call stats) that an evaluation activation runs through S8; monitors score runs, reviews, drift, hallucination and duplicates as evaluation activations (EVAL.md, eval.run); typed datasets (rows linked to work, JSONL export, snapshots) agents read and append to. Agent eval tools need an owner decision on R10a's worker exclusion.
  • S63 Templates and backups. A Workspace template installs default Agents and Routines, such as a monitor and a run review, by preview; maia template export writes an existing Workspace as a versioned template that apply rebuilds on any Node. Backup and restore (maia node backup, operations) ship on their own and wait for no template.
  • S64 Web workflow tools. Search, filters and Jev grouping (R10b) over tasks, Routines and runs, as SDK reads with CLI flags first, which wait for no client; Cmd+K and keyboard-only use in the web client (S52). Later, when operators struggle to author the Routine contract: a visual Routine editor whose graph is the after list, with live step status.
  • S65 Run control. Wake rules per Agent and Routine (mention or assignment only) and a reason on every wake that starts nothing; refuse work for an Agent that cannot run; per-run token, context and turn caps that compact or restart; a quota governor keeping each Connection under its window and staggering starts; labels. S47 providers keep keys out of the sandbox; S12t masks held key values and key-, token- and PEM-shaped strings on every content read (D-168). Caps read S12f's per-run summary and never recount.
  • S68 Datasets to custom models. S62 datasets also fill from decisions: confirmations and rejections, edits to previews, answers, review verdicts, routing choices, eval labels and task outcomes, each row with provenance, masked on read (S12t) and kept under a dataset policy its owner confirmed. A Routine can snapshot a dataset and start a tuning job on a provider's fine-tuning API or the company's own trainer, within a budget (S55), through an approved trainer adapter run as a Routine task; Maia builds no job engine, and an adapter starts only for a named consumer with its terms and budget. A tuned model is evaluated against its base on a held-out snapshot (R10a); a person confirms admitting it to the model catalog (R10) with its lineage (dataset snapshot, base model, job), and it can roll back. Agents, evaluators and routers may then pin it (S49, S62). Models stay open: closed frontier, open-weight and custom endpoints join as Connections (S24), and harnesses grow through S31–S36. Entry: owner decisions on provider terms for training on model outputs, where training runs (a new service needs approval) and personal data in datasets (GDPR, E3).
  • S66 Session move and sleep. Move a Session to another Node between turns: drain, fence, carry its worktree and native session by digest, and resume there (MN4 handoff, never live process migration). Moves run both ways between an Execution Node on a person's computer and a server's, so work continues while a laptop sleeps; each harness qualifies its native session carry on its own (Codex, Claude Code and Pi first), the preview refuses a Node without that harness or the Session's Connection, and a claimed onboarded Session moves like any other (D-174). An idle Session's harness stops after a set time and resumes on the next turn.
  • S70 Pause and resume. Pause exact Sessions, runs and Projects, then Routines, Agents, task trees and Execution Nodes with their slices; at most 64 per pause, never all. Running turns end at their next edge or a deadline, harnesses stop as session.stop does, and new work queues instead of failing as under an S20 hold; resume works as session.resume does and runs queued work in order, but a Session with an unknown outcome stays fenced. An Execution Node pause is a cordon (design).
  • S71 Tool connections. The Node speaks MCP through the official SDK, pinned behind one Effect adapter (D-127). Admit MCP tool servers per Workspace by exact version and digest: a local one runs inside the Session's sandbox, a remote one is an approved endpoint on its own Connection. An Agent gets named tools; harnesses reach them only through Maia's MCP endpoint for the Session, where each tool is allow, ask (a Maia approval) or off, S47 providers inject credentials outside the sandbox, a person answers a secret request without the value reaching model context, and every call leaves a receipt. Vendor tool servers stay off in launches until admitted; a tool server never owns Workspace, Project or task truth.
  • S73 Extensions. Third-party and Maia verified extensions package optional Skills, Agent and Routine templates, rules, tool servers, event sources, one sandboxed service and eval rubrics; never Node code, protocol operations, Connection kinds, client views or grants. Each is pinned by digest, previewed with every capability it asks for, confirmed by a person, receipted, and reversible by disable and rollback; Maia verified ones pass a conformance suite and ship signed, and a Workspace policy can allow verified ones only (design, D-114). S73a inert parts after S49, S50 and S54; S73b tool servers after S71; S73c services and event sources after S47b, S51 and ORG3; S73d third-party sources after E1's signing decision and E5's model; S73e authoring (maia extension new and dev, built with Maia itself), for inert parts with S73a and for executable parts with S73b and S73c. Later: S73f the public directory, whose review gate admits nothing unreviewed (directory), after S73d and once at least two independently maintained extensions need distribution; until then digest manifests, local installation, admission review, conformance, disable and rollback carry extensions.
  • S74 Alerts. Workspace thresholds over any authorized measurement view: queue wait, wake-to-start, failure rate by cause, lost runs and quota errors, read from T1–T3 and S56's run spans; each breach raises one attention item (R8) and, once S72 ships, a notification. S61b adds the coding views over S61a's merge feed, such as runs and cost per merge: every execution attempt in a window, retries, failures and reused Sessions included, over the pull requests a Maia task opened that merged in it.
  • S75 Import. maia import reads another agent platform's export through its API, read-only, and previews every Agent, Routine (disabled), Skill, goal, Project and repository binding for a person to confirm; never secrets or run history; idempotent by source ID. Open tasks import by source ID with their issue or pull request links, and export back by exact ID for a rollback. Goals import once S48 and S54 ship; until then the preview lists them as skipped.
  • S72 Notifications. Attention items (R8) reach a person by email, mobile push or one chat connector they choose, with quiet hours and delivery receipts. A message names the item and links to a trusted client screen; nothing is confirmed in a channel. Pairing a channel account to an ORG1 person needs that person's confirmation in a trusted client, and inbound chat to the personal agent arrives as an untrusted S51 event. Each connector is a new service needing owner approval.

Order: S53 after S50; S54 after S48 and R3; S57a after S2 and S24, S57b after S47b; S60a after S49 and S65, harness switching after S47b and its decision; S58 after S47b, MN1 and RL3–RL4; S61a's Connection and reads after S47b (for the cutover, the key-custody rule, D-150), its Agent writes after S2 and S49, S61b after S73a–S73c; S74 after T1–T3, S56's run spans and R8a, its merge views with S61b; S75 after S49, S50 and S53, its goal import after S48 and S54; S62, S63's templates and S65 after S49 and S50, S63's backup and restore on their own; S64's CLI reads after S53, and its web view and S59's after S52; S66 after MN4; S68 after S62 and R10a; S70 after S19, S26 and S29, each further target with its slice; S71 after S2, S13, S47b and E5's model (D-127); S72 after R8, S51, ORG1 and the egress decision, its chat channel with S67; S55, S56 and S59's CLI in parallel. Later: shared browser profiles, more chat connectors, one role model for people and agents, and more harnesses. No extension code runs in the Node; extensions (S73) compose existing primitives.

Acceptance for each slice is in agent operations acceptance.

Personal agent

Planned (owner direction, 22 October 2026). Maia has two layers. The foundation (Node, protocol, SDK, CLI, MCP and HTTP API) is the product: enterprise workflow, configuration and policy management that agents are to operate fully, each operation callable by an agent within its grants and with the same validation, confirmation and receipts (today S1 still refuses agents the person-only operations). On top sits a thin human layer: each person can manage Workspaces and Projects through one personal agent. Everything it does is a foundation operation, so nothing depends on chat.

  • S67 Personal agent. The global Maia coordinator as each person's single entry point: one chat, in text in the CLI first, then continued across Desktop, mobile and the web client (S52), with voice in clients after the voice contract. It sets up and runs Workspaces, Projects, Agents and Routines through tools generated from the protocol registry, with its own Skills and scheduled turns such as a daily briefing over admitted summaries. It is built from primitives: an Agent with its own grants, its Skills and Routines over owner-scoped reads and R4, with no runtime of its own.
  • Manages, never works. No file, shell, repository, network, credential or worker tools. It delegates through the Workspace and Project boundary (R3): the recipient owns accepted work, its Agents run it as tasks, Routines or Sessions, and the personal agent steers only what the delegation allows and reports results in the chat.
  • Access. Its own grants, issued by its person, never above theirs and never inherited (D-005): the global ceiling is the authorized Workspace directory, admitted summaries and delegation results.
  • Focus. Each submitted turn records its focus, one Workspace or Project, shown as a marker in the chat; each client keeps its own focus, and a change never retargets an open command. A turn loads only global context and its own focus's turns and memory.
  • Memory. Global memory from unfocused turns and memory per focus from that focus's turns, built only from its own chat under a learning policy its person confirmed, and hidden once the person loses that access. Promoting it to Workspace or Project knowledge is a separate action by the person.
  • Standing approvals. A person may pre-approve exact operations on an exact scope with input bounds and an expiry, revocable; each use binds the exact operation and input digest and leaves a receipt. Only a turn the person started may use one, never an event, Routine or other agent's turn, and never after the turn loaded untrusted content (event data, PR text, web pages, delegation results). Never approvable: approvals themselves, the personal agent's definition, Skills and policy, memory promotion, goals (S48), rules (S54), grants, Connections and credentials, event sources, containment, budgets, Session goals (S69), an Agent with wider grants, merges (S61) and operations under a two-person rule (ORG4).
  • Entry. A decision entry that defines standing approvals (amending S1 and S18a for their exact scope), a global owner kind for scheduled turns (S50), focus-partitioned global memory (coordinator learning) and the voice rules for both, and names the personal agent across R1a, R10b, the portfolio voice contract and the cockpit.

Order: after S49, S50, R3, R10 and ORG1's person identity; CLI chat first, then Desktop and mobile, and the web view after S52; voice after the portfolio voice contract.

Acceptance. It never lists, reads or changes a Workspace or Project its person cannot; an action outside every standing approval previews and waits for the person, and an agent's confirmation still gets role_denied; a revoked or expired approval stops the next action; text from events, PRs, web pages or other agents never creates, widens or triggers an approval; Project work it requests runs as work owned by that Project, never in its own turn; a turn in one focus never loads another focus's turns or memory; each action names its person and approval in its receipt; with the agent unavailable, the same operations stay usable through the CLI and clients; a voice turn uses an approval only as the voice rules in its entry allow.

Ready-to-develop sequence

R IDs are delivery slices, PF IDs are user stories, and DF IDs are dogfood suites. They are documentation identifiers, not new runtime resources or operation IDs. Every row ships only its supported bounded slice; no fake success paths or empty UI controls stand in for missing Node operations.

R0a is the cross-cutting source-organization and remediation track below. It closes structural and shared-boundary gaps alongside the owning product slices; it is not permission for a big-bang rewrite or a prerequisite to migrate every unrelated file before delivering a bounded feature.

R0b is the cross-cutting Effect, dependency and test-quality track below. Its phases run between product slices and keep every gate green.

M0 is the continuous-measurement track below. Every change shows its size, speed and health deltas; regressions need a fix or an accepted reason.

Slice / statusEntry conditions and remaining deliverableOwning code after protocol/SDKExit stories / suites
R0 — acceptance closure / NextReconcile existing Project create/rename CLI candidate with current source, artifact digest and independent review. Preserve existing accepted container/Project work. Close packaging, parity or acceptance failures without bypassing exhausted task/review gates. Record exact supported operations and release-disabled reasons.apps/cli, services/node application tests; existing protocol/SDK consumersExisting metadata regression tests; DF-00, DF-01
R1 — portfolio reads and scope / NextBuild on accepted container/Project reads; add offline per-command --schema inspection (PF/DF-26), retaining current wire meanings through R1b. Add missing bounded Workspace/Project/Session snapshots, authoritative graph read projections, per-client selection, context manifests, event coverage/cursors and scoped search. Filter by coordinator discovery ceilings as well as human grants before traversal/counting. Separate selected UI detail from command authority. No global mutable focus singleton.Node observation/storage/configuration; packages/client-corePF-01/02/13/22/24/26; DF-01/02/09/22/24/26
R2 — usable local execution / Next, launch blocked on containmentFreeze the OS/profile matrix and qualify the chosen local hard-containment adapter. Add repository-free directory authority and exact environment preparation without inventing a new Project identity. Preserve local placement, durable history and restart behavior. Unsupported shell/filesystem guarantees fail closed.Node environment/session/process owners; packages/agentPF-02, PF-05; DF-03, DF-04, DF-10
R3 — persistent conversations and delegation / DependentR1; R10 additionally gates automated LLM + Jev coordinator behavior; R2 gates environment/code execution, not ordinary Workspace conversation metadata. Support multiple ordinary Sessions in an empty Workspace without a Project/repository/Execution Environment or coordinator. Closed Maia/Workspace/Project owners and separate Session histories/grants; canonical-home uniqueness is not ordinary-Session uniqueness. Preserve lifecycle/replay/history and owner-aware activation gates. Project execution stays separately admitted through parent-mediated delegation; no sibling discovery beyond a Session's D-166 peer directory.Node Session/message/grant owners, agent tools, client corePF-03/04/13/22; DF-04/05/09/22
R4 — Workspace/Project learning / DependentR1 for manual library/retrieval; R3 and R10 for automatic conversational learning. Automatically build and maintain scoped KBs, memory and reusable Skills from submitted requests, corrections and evidenced work under a confirmed learning policy. Future workers reuse relevant admitted context without manual saving. Include provenance, correction/forgetting, strict owner-partitioned retrieval/caches, explicit Project-to-Workspace promotion and export controls; see the learning contract below.Node context/artifact/resource/storage owners, agent context adapterPF-06/22; DF-06/22
R5 — finish and review work / DependentR2/R3 and R4 output references. Multi-repository environment bindings, diff/test evidence, artifact previews/downloads, reviewed integration/merge/export and conflicts. Freeze a concrete reviewed Git/hosting capability before PR side effects; keep offline Git fixtures as the default.Node execution/artifact/effect owners, CLI review, client inspectorsPF-07; DF-07
R6 — local plus remote pool / DependentMN0 may start in parallel with R1/R2. Deliver MN0–MN5 below using R1/R2/R3 contracts. Identity, secret handling and destination containment are prerequisites, not optional network polish. Remote read-only and remote coding are separate qualifications.Node enrollment/placement/process/reconciliation, agent adapterPF-05, PF-08, PF-14; DF-03, DF-08, DF-10
R7 — text and voice everywhere / Dependent, early read sliceV0 read/clarification follows R1 and authenticated voice transport. V1 worker control follows R3 and the selected local/remote operation's qualification; V2 live audio follows explicit device/provider approval. Text-first direct controls and same-target voice in every Session; no mandatory coordinator hop. Manual/media controls remain independent of Jev; AI routing follows R10 readiness. See voice contract below.Node voice/routing/services, SDK voice policy, packages/client-core, platform audio adaptersPF-09–PF-12, PF-18; DF-11, DF-12, DF-13, DF-18
R8 — attention and recurring work / DependentR1/R3/R4; R8a, the inbox alone, needs only R1/R3. One attention inbox for approvals, failures, unknown outcomes, finished outputs and budgets; R10 adds journal-driven, selectively delivered feedback, not another truth store. Schedules are S30's and S50's Routines; R8 adds separately admitted connectors for PR/CI/issues/messages with event dedupe, retry/reconcile, revocation and retention.Node Routine/message/observation/Connection ownersPF-15, PF-16; DF-14
R9 — connected client and release / Dependent per capability; R9a migrationR9a migrates all product-view composition to json-render through the shared SDK/catalog, independent client engines and Jev-assisted bounded presentation. Project/worker controls follow each accepted business slice; do not wait for every future view or live evaluator. Qualify multi-client fairness/faults, Desktop accessibility/reconnect/packaging and physical mobile parity.apps/client, packages/client-core, apps/desktop, platform transportsPF-01–PF-18 as exposed, PF-27/28; DF-09/13/15/16/18/27/28
R10 — evaluation foundation / Next contracts; adaptive consumers / DependentR10a: scope-bound evaluation with internal/SDK/CLI and granted coordinator/bot projections, excluding worker evaluation tools. R10b: router-first LLM + Jev automation, central setup/context, bounded work/feedback queues and R9a presentation. Manual controls and lifecycle tracking remain independent of AI readiness.Node evaluation/context owners; existing client componentsPF-17/23/24/29; DF-17/23/24/29

R0a — scope-first organization and architecture remediation

Approved plan; strict lint tooling is a separate deliverable from migration and runtime fixes. The source-organization specification owns the complete folder/export/test contract, target package layouts, reviewed findings, phase acceptance and recovery. Keep existing packages and authority: protocol -> public SDK -> Node -> CLI -> applicable client/voice projections. Every ordinary implementation scope has an export-only index and colocated tests. Use explicit native/framework exceptions, never blanket source ignores. Legacy violations stay visible in the shrink-only baseline until the owning migration closes; new violations fail at once.

PhaseDeliverable and ownerEntry / exit and product mapping
SO0 — baseline / NextIntegration and scope owners freeze current hashes, peer ownership, exports, runner discovery, budgets and existing failures. Recheck the historical audit; do not assume its nine parity findings still apply.Exact bounded scope, retained baseline and independent review path; no takeover or dirty-tree reset.
SO1 — parity and status / NextProtocol/SDK/CLI tooling closes actual registry/help drift and reconciles component status. Preserve authored request-binding checks while reducing duplicated metadata.Current-target parity and contract tests pass; source-present, integrated, verified and release-qualified stay distinct. R0.
SO1a — tooling hardening / NextQuality/ESLint, hook, build and package owners close the open review gaps; partly closed by SO1b.SO0; reliable discovery/cache/staged checks, boundary/framework fixtures, meaningful scope review, config-policy agreement and parser guards. Independent evidence gates SO2 per affected surface.
SO2 — structural pilot / Dependent per scopeThe SDK node/ and voice/ splits in remaining target splits; the earlier pilot moves are done (SO6a–g). Move implementation/tests together; indexes export only; public package imports stay stable.SO0/SO1 plus accepted SO1a checks for the affected surface; nested tests collected, scoped checks and public artifact/import parity pass. Structural moves separate from behavior fixes.
SO3 — request lifecycle / DependentSDK and client-core consolidate Effect-owned orchestration, cleanup and uncertain mutation acknowledgements behind the existing public facade.Pre/post-dispatch cancellation, timeout, malformed/correlation failures, original-key reconciliation and affected mutation regression tests. No blind replay or loss of operation-specific binding.
SO4 — client isolation / DependentR1/R7 protocol/SDK/Node owners separate local focus from command authority and replace refresh-driven global voice-context eviction with owned bounded admission.Two-client target/refresh races, stale/wrong-owner denial, reconnect and durable-work survival; R1b wire compatibility retained. PF/DF-28 qualifies the declared multi-client minimum.
SO5 — observation delivery / DependentNode/SDK observation owners separate commit wake-up from heartbeat, bound each observer and preserve control/worker fairness.Event-after-empty-read regression, real replay/gap/cancel/slow-consumer tests, bounded overload and measured existing latency/DF-28 budgets. R1/R9.
SO6 — remaining scopes / IncrementalThe other listed splits (client-core observation/ with its slice, CLI root composition); keep React thin and native adapters explicit, and remove obsolete internal forwarders after consumer migration.Per-scope contract/build/import/renderer checks; measured artifact/startup impact where relevant. Full layout completion requires zero outstanding structural errors, not suppressions.
SO7 — presentation / DependentR9a owners qualify dependencies/catalogs, migrate deterministic product composition, then qualify Jev-backed AI mode after R10a.PF/DF-27 view parity and PF/DF-28 isolation/fault/performance evidence. Trusted authored components, Effect Schema and provider-down operation remain required.
MF0 — modular features M0 / Source candidateEach feature descriptor sits beside its protocol scope; projections.coordinator replaces agent (D-102); coordinator tools and the allowlist derive from descriptors; Node dispatch keeps context; the SDK checks bindings instead of copying them.40 coordinator and 7 worker tools equal main; parity 0; D-113 checks the receipt filter and SDK call lists against descriptors. Next: M1 with CLI slice 1.

Done phases SO1b, SO1c and SO6a–SO6g are in source organization.

Recommended order: SO1 and SO1a -> SO2 -> SO3 -> SO4 -> SO5 -> incremental SO6 -> SO7, with source-organization migrations in the SO6a-SO6g order (services/node last; SO6e and SO6f landed before SO6c and SO6d), and SO0 repeated for each admission. Harden test discovery and lint-cache inputs first, then staged validation, fixture safeguards and dependency/framework checks. SO1/SO1a may proceed together where their ownership is coordinated. Shared tooling and each pilot's applicable runner/platform checks must pass before SO2; explicitly tracked cases for other packages gate their own migrations, not an unrelated repository-wide rewrite. Independent scopes may proceed in parallel once ownership and contract dependencies are clear. R2/R6 containment, R3 owner-aware conversations, R4 learning, native devices and release qualification retain their own gates; a renderer migration does not fix shared context or stream latency.

Enforcement exit: root/client/site ESLint entrypoints reject forbidden layouts at error severity; real-config positive/negative fixtures and tooling checks pass. SO1a additionally requires trustworthy execution/cache/staged evidence and the specified boundary checks; the earlier layout-fixture pass does not close these new findings. Keep detailed acceptance in the canonical source-organization plan. No automatic structural fixer, new lint dependency, shared-floor weakening or production source relocation is part of this tooling admission. Report whole-tree legacy and unrelated failures explicitly; fixture success is not a clean-repository claim. The final repository gates remain pnpm check:quality and pnpm test.

R0b — Effect everywhere, minimal dependencies and robust tests

Owner direction (2 October 2026). Maximize Effect across the monorepo, keep only the dependencies that are strictly needed (Effect, Pi, @vllnt/* and Vercel packages such as the AI SDK are allowed; framework requirements are kept with a recorded reason), and prefer tests that exercise real boundaries over mocks, which can hide defects behind false positives. Each track ends in a mechanical check, not a document.

  • EF2 — Effect everywhere / Dependent. Migrate each package to Effect services, layers, Config, Schema and platform modules; React rendering and native, Tauri, Expo and Pi adapters stay thin boundaries. Acceptance: gap count 0 outside the allow-list, enforced by lint rules at error severity with a shrink-only baseline like SO1c.
  • DEP0 — dependency review / In progress. Inventory every dependency with its real use, weight and an Effect or built-in replacement. Acceptance: owner decision list in the decision log.
  • DEP1 — dependency minimum / In progress. Remove or replace each approved candidate, one commit per package. Acceptance: dependency and lockfile package counts fall; a policy check fails on any new dependency outside the allow-list without a decision entry.
  • DEP2 — upstream @vllnt footprint / Deferred. @vllnt/eslint-config: make preset plugins optional peers, root entry exports only base and nodejs, other presets by subpath; a breaking 3.0.0 tracked in vllnt/eslint-config#24 (a lazy root re-export breaks require() and Yarn PnP). @vllnt/ui: kept as is by owner decision; all 46 dependencies are used, and optional integration peers would break webpack builds of consumers that miss them (Turbopack builds pass). Acceptance: after eslint-config 3.0.0: drop the Convex packageExtensions entry and the handlebars override, and add the preset plugins as dev dependencies where their presets are used (root turbo; client react; site nextjs). Measured: a nodejs-only consumer 407 → 167 packages, the root 377 → 176.
  • DEP3 — dependency selection policy / Dependent on DEP1. Node built-ins and existing official capabilities come first. Acceptance: the allow-list DEP1 checks records, per entry, an owner, a reason, a review date and the decision entry that admitted it; a check fails on a direct dependency outside it, on an expired review date (renew with a reason, or remove) and on a release-age exclusion outside Maia's own scopes unless it names one exact version, a reason and an expiry (the third-party entries wait for their decision); M0's health suite gains dependencies.closure per published package (direct plus transitive packages) with a ceiling at the measured value that only shrinks.
  • TQ0 — test baseline / In progress. Measure line and branch coverage per package, inventory mocks of owned code, and list timing-sensitive tests. Acceptance: published numbers per package; every flaky test named with its cause.
  • TQ1 — real-boundary tests / Dependent. Replace mocks of owned code with real SQLite, loopback HTTP, temporary processes and directories, and Effect test layers (TestClock); fixtures only for third-party vendor APIs; contract tests for every operation. Acceptance: mocks of owned code at 0 outside an allow-list; timing tests deterministic.
  • TQ2 — coverage and test-strength gates. Coverage floors per package that only rise, and a mutation-testing pilot on the protocol and SDK to find assertions that cannot fail. Acceptance: floors enforced in CI; pilot report with surviving mutants triaged.

EF0 and EF1 are done (completed phases, progress notes).

DX — agent developer experience and CI gates

Owner direction (22 October 2026). Give agents and people one fast, machine-readable inner loop and CI that enforces quality, performance, efficiency and security, with the fewest external packages: Node built-ins, Git, GitHub-native features and the tools already in use (TypeScript, ESLint, Prettier, Turborepo, pnpm). The repository already has change-scoped CI, SHA-pinned actions, hooks with fix hints, shrink-only baselines and M0's metric budgets; DX closes the gaps an agent hits (details). A new package or paid service needs its decision entry.

  • DX1 One verify command. pnpm verify grows from check:changed: Turborepo's affected selection, a plan of what runs and why, per-check time limits, and one NDJSON report of findings (gate, rule, file, line, message, fix) built from ESLint's JSON formatter, tsc, the lint policy (which gains rule IDs and lines), Prettier and the test runners' own reporters. CI turns the same records into annotations. AGENTS.md names it first.
  • DX2 Budgets. The planned dx.hook.* metrics, a dx.verify.s metric and the pull request's CI wall time land in M0 as trends that warn and never fail, as M0's policy holds for shared-runner wall time; every check and CI job keeps a hang timeout that fails. A blocking timing budget needs a reference machine and an M0 policy change.
  • DX3 Merge safety. One aggregate required check that reads every job's result, so a skipped job never leaves a check unreported; merge_group triggers (PD0); heavy jobs after merge; a revert-first rule for a red main branch (bisect, revert, re-land with a regression test).
  • DX4 Security and supply chain. First, triage the open Dependabot alerts on the default branch (79 on 22 October 2026, 5 critical). Then: the staged secret guard and blob-size cap rerun in CI over each pull request; pnpm audit fails on high and critical advisories without a recorded exception; the lint policy keeps workflows at no default token permissions, persist-credentials: false and no pull_request_target; pnpm's blockExoticSubdeps, strictDepBuilds and trustPolicy: no-downgrade join the 7-day release age; Dependabot security and grouped version updates with a cooldown; npm provenance and GitHub artifact attestations on publish (E1). Approved (D-126): zizmor for workflow files and cargo-deny for the Desktop's Rust crates, pinned and CI-only, and GitHub Secret Protection's push protection; paid code scanning and dependency review are not used.
  • DX5 Tests to trust. No automatic retries; a quarantine file names each flaky test with its issue and expiry, and a check fails on an expired entry; a scheduled stress run on main finds flakes; every bug fix carries a test that fails without it; coverage floors only rise (TQ2).
  • DX6 Performance on demand. M0's comparison runs for a pull request on request and after every merge, with Welch's test, a maximum regression and written noise rules for triage; size budgets use node:zlib.
  • DX7 Agent guardrails. A pull request template with evidence (unit ID, commands run and results, metric deltas, AI disclosure) and a check that the body carries it; a warning past the unit-of-work size; gate files protected through the owner's policy (D-124) and repository settings (rulesets, code owners).
  • DX8 Dogfood lab (source candidate, D-133). pnpm dev:lab runs one to four isolated Nodes with Codex and Claude Code through a gateway Connection to a local model proxy, with a capped, read-only live smoke and evidence (details). Codex passes the live smoke. The Claude Code case was blocked by the 256 MiB executable bound, which D-145 lifts for harness CLIs; its live smoke has not been rerun since. Phase 3 (source candidate): pnpm dev:lab scenario stress runs a bounded Codex load on an offline loopback fake gateway, injects 5xx, malformed and stalled streams, records latency, throughput, Node memory and CPU as a maia.metrics/v1 snapshot, and fails on an unexpected outcome or a leftover. Planned next: a scenario with real work in a fixture repository (phase 2).

Order: DX4's alert triage first, before new feature slices (D-126); DX1, DX3 and DX7 with PD0; DX2 and DX6 with M0; DX5 with TQ1–TQ2. Acceptance: an agent's change gets its plan, findings and verdict from one command with no human-only output; a red main branch is reverted within one working day; no pull request merges with a high or critical advisory unrecorded; a workflow change adding pull_request_target or broad token permissions fails CI.

M0 — continuous measurement

Owner direction (2 October 2026). Measure the whole ecosystem on every update, show improvements and regressions, and make regressions trigger action, with tooling that scales and needs no service (decision, design).

PhaseDeliverableAcceptance
M0a — first slice / Source candidateA metric catalog with owners, units, directions, noise classes and thresholds; the maia.metrics/v1 snapshot; pnpm metrics; pnpm metrics:compare (base built in a temporary worktree, interleaved runs, Welch's t-test); a metrics CI job on pushes to main with artifact baselines and Metrics-Accepted trailers.Tooling tests for statistics (against t-table values), schema, verdicts, acceptance, collectors and the workflow; a real snapshot and a real comparison against origin/main~3; pnpm check:quality green. Pending: the first CI run on main.
M0b — Node benchmarks / NextNode package scripts for the port-lease, hold and an accepted loopback mutation benchmark.pnpm metrics --suite node reports every node metric on macOS and Linux; the runner calls package scripts, not Vitest scope filters.
M0c — developer loop / NextHooks record their own durations; CI job minutes and per-package test time come from the Actions API.dx.hook.*, dx.ci.job.minutes and dx.test.s in snapshots; the CI job summary shows them.
M0d — health from R0b / In progressCollect the EF1 Effect-gap count, the TQ0 mocks of owned code and named flaky tests, and coverage per package.effect.gaps, tests.owned_mocks, tests.flaky.known and coverage.lines per package, each with a fail threshold once its R0b gate exists.
M0e — feedback and history / Owner decisionComparisons on pull requests, durable history past 90 days, or a hosted service (open decisions).The owner's choice is in the decision log and live in CI.

Schema-only CLI inspection — R1

Approved target, not implemented. Add --schema (default output) and --schema=input|output to registered resource commands, using the schema-only rules. Users inspect the command they intend to use, not a separate contract subsystem. Return only deterministic, versioned, self-contained JSON Schema from the installed artifact; --json is redundant. Input is normalized operation parameters; output is that command/version's full ordinary JSON success/error response. No runtime IDs or inputs are required, and schema mode never executes the operation, reads stdin, resolves profiles/credentials, creates transports, starts/connects to Node, loads runtime plugins, calls providers or mutates state. Reject runtime/streaming options, unsupported forms and missing schemas without execution fallback.

Extend protocol-owned generation, shared SDK/schema artifacts and the existing CLI command parser/output path; do not add a new service, validator, general operation dispatcher or dependency. Existing Node handlers/authorization remain unchanged. Registered candidate commands may expose schemas without becoming executable; unknown future plural names stay unknown. Preserve R1b meanings and normal command/Agent passthrough behavior. CLI, SDK and admitted tool projections share definitions, while active tool visibility stays Session/activation-bound.

Owners: protocol schema/registry generation, SDK artifacts, CLI parser/help and output tests. Exit: PF-26/DF-26: complete raw-schema output, no-effect sentinels, no Node/credentials/network/stdin requirements, deterministic bundled references, representable schema/error fixtures, parser/size/failure cases, surface parity and existing-command regressions. This R1 foundation does not wait for autonomous coordinators, Jev, remote execution or completion of every snapshot view.

R1b — Workspace and Execution Environment naming

Approved documentation target; implementation to be scheduled with dependent schema work, not an immediate rename or a blocker for unchanged supported reads. The naming contract is authoritative. Reserve Workspace for organization and Execution Environment for execution; use Execution Node and Execution Profile for host and permissions. Remove Container/Execution Workspace from new product labels while retaining explicitly labelled current-source and historical references.

  • Freeze a versioned compatibility decision: organizational container.* becomes workspace.*; execution workspace.* becomes environment.*. Organizational containerId and execution workspaceId become distinct new-version workspaceId and environmentId fields. Do not silently reuse a method or change an old request's meaning; mismatched contracts fail closed.
  • Preserve exact old identities, memberships, Session/assignment links, grants, filesystem paths, events, history, receipts and original retry/confirmation bindings. Define retained-ID validation and any storage migration/refusal; no prefix rewriting, duplicate aggregates or parallel Node writer.
  • Implement protocol → SDK → Node → built CLI → applicable agent/voice/client projections. Coordinate R1 snapshots, R2 environments and R3 owner schemas against the same mapping; do not implement two competing naming models.
  • Qualify mixed-version reads/mutations, old proof/receipt reconciliation, wrong-kind/version denial, empty/populated migration, rollback, backup/restore and downgrade refusal before release or separately approved live migration. Follow the contract's deprecation policy rather than permanent ambiguous aliases.

Owners: protocol registry, existing Node organization/environment/storage owners and their SDK/CLI/client projections. Exit: PF-25 / DF-25 plus affected existing metadata, Session, placement and confirmation regression tests. This slice neither adds a hierarchy level nor approves runtime implementation now.

Ordinary Workspace Sessions — R3

The Session ownership contract requires multiple ordinary conversations owned directly by a Workspace, even with zero Projects. This is core R3 scope, not a new roadmap slice or merely an optional coordinator feature. Creation must require no Project, repository or Execution Environment and must not create or wake a coordinator. Keep exact ownership separate from ordinary/coordinator designation and home-Session uniqueness. Same-owner histories, provider contexts and Session-specific grants remain isolated; shared knowledge follows explicit grants/learning policy.

Extend existing Session operations and owner-aware configuration/context paths in protocol → SDK → Node → built CLI → applicable agent/voice/client order. Qualify conversation-only activation separately; no synthetic Project, ambient working directory, hidden environment or broadened execution tools. R2 remains required for environment/code execution, not a reason to block ordinary metadata/history reads. R1b supplies compatible names; current Project Session contracts remain valid and unsupported new owner combinations are refused until qualified.

Exit: PF-03/PF-22, DF-22's empty-Workspace/multiple-Session cases, and WP-20/21 client acceptance. Prove explicit create/list/show/history and supported continuation, restart, concurrent creates, lost-response replay, per-Session and cross-owner denial, revocation, stable ownership after Project creation/delegation, and old Project Session compatibility. No runtime implementation is claimed here.

Coordinator ownership admission — R1/R3/R4

The Swarm contract owns the strict visibility tree and delegation semantics; Node owns enforcement. R1 filters all catalogs, search, graph edges, counts and cursors before exposure. R3 freezes closed global/Workspace/Project owner identities, ordinary Session multiplicity versus canonical-home uniqueness, grants and preserving migration/refusal behavior, then adds bounded delegation through existing message/task/Session owners. No synthetic operator Project, human-grant inheritance, direct sibling bridge or new workflow runtime. A dormant Workspace model does not remove its authority boundary.

The requester owns its delegation record; the recipient owns accepted work and workers. Correlation and reply references cannot reveal hidden siblings. Parent sharing needs explicit content permission; lineage stays protected on Node. Decomposition preserves source references, shared constraints, acceptance criteria and dependencies; parallel independent work never bypasses scope or confirmation. R4 partitions all derived knowledge, retrieval and invalidation by exact owner.

Exit: PF-22/DF-22 plus PF-03/DF-05 and PF-06/DF-06. Separate processes or prompts are not full isolation: code-capable profiles also require R2/R6 containment and cross-owner filesystem/network/credential denial evidence. Existing unsupported owner kinds remain blocked until their registry, storage and client contracts pass.

R9a — full json-render UI and isolated client engines

User-selected migration target; next for inventory/contract admission, dependent implementation, not current runtime support. The presentation runtime specification and protocol requirements own this slice. Full migration covers every product-view composition, not only AI response cards. Shared registered components preserve trusted confirmations, receipts, navigation, specialized canvas/terminal/media engines and native ports. Only platform bootstrap and minimal renderer recovery stay outside the renderer. No parallel legacy product backend or free-form generated UI code.

  1. Inventory and dependency gate: reconcile the mounted UI/state matrix and retained components; map each view/action to registry, SDK inputs/results, platform admission and tests. Mark future owner-aware/graph/worker views as missing rather than implementing fake data. Pin the minimum official json-render packages and closure; verify Effect Schema compatibility, Expo/Tauri/native rendering, accessibility, licenses and reversible artifact rollout before installing. No handwritten duplicate operation validators.
  2. Protocol and SDK: freeze finite catalog/spec/patch schemas, authenticated view identity and generation, source/policy revisions, negotiation, errors, stream cancellation/reset and mechanical action parity. Keep presentation and authoritative resource updates distinct. New business operations still finish their ordinary CLI-first slice; no standalone generation API or renderer HTTP.
  3. Node and isolation: compose approved specs from authorized resource reads. Use Node-owned bounded presentation workers for process-risk generation and Jev evaluation, outside critical control/worker paths. Enforce per-view/client/ principal/global quotas, fair scheduling and control reserves, safe result reuse, slow-consumer fencing and finite lifetime. No second authority/service.
  4. Full deterministic migration: move the currently supported shell, portfolio, conversation, questions, inspectors, preferences and trusted surfaces to the catalog; preserve all baseline states, failure paths and exact receipts. Specialized widgets remain authored. Keep narrow crash recovery independent; delete superseded view composition only after parity passes. Unsupported future capabilities remain honestly unavailable. Reconnect restores Node truth, not stale client ownership, and never replays a mutation or kills server work.
  5. Jev-backed adaptive runtime: after R10a, use bounded authorized Choices/ Scores/Booleans to select targets, evidence and components. Deterministic code builds specs. Exact manual views bypass inference; provider-down keeps manual views/control usable and reports affected AI mode unavailable. No call per client/render/audio chunk, no model authority over confirmations, no hidden paid retry and no focus stealing or cross-owner context export.
  6. Qualification: PF-27/DF-27 closes the complete view inventory; PF-28/DF-28 tests independent user-level Maia history versus client focus/media, at least 8 admitted clients, 2x-ceiling overload, UI/presentation-worker faults, malformed streams, auth/cache isolation and paired p95 performance. Meet existing absolute client budgets and at most 10% healthy-client/control/worker p95 degradation on frozen matched fixtures. Record capacity/host limits; no full isolation or performance claim without evidence. Physical audio/mobile remain separate gates.

Dependencies: R1 supplies scoped reads/graph/observations, R3 supplies user-level and ordinary Workspace Sessions, R10a supplies the evaluator required for AI mode, R2/R6 supply execution containment. Deterministic catalog migration can proceed against existing admitted operations while those larger slices remain gated. Paused tasks are not resumed by this roadmap or a peer message; owners must admit work through their existing review/resource controls. No runtime/dependency/provider change is performed by this documentation slice.

Owners: protocol registry and SDK; Node observation/evaluation/worker owners; packages/client-core, apps/client, Desktop/mobile platform adapters. Exit: PF-27/PF-28, DF-27/DF-28 plus affected DF-02/09/10/17/18/20/22/24 and existing mounted UI/terminal/voice/interaction regression tests. The first adaptive journey is attention -> worker comparison -> exact inspector -> trusted proposal.

R10a — reusable semantic evaluation foundation

Next contract slice, independently of autonomous coordinators. Implement the Node semantic evaluation contract in protocol → SDK → Node → built CLI → admitted agent tools order. One Effect service exposes Choice, ordered Score and Boolean probability on bounded shared state with named questions, inline or exact versioned rubrics. Internal services, granted coordinators/bots and authorized external coordinators share one implementation. Execution-worker tools exclude direct evaluation; central setup/context can use it on their behalf. Coordinator-selected questions are supported beyond initial routing.

Freeze owner/export grants, result/error semantics, question/byte limits, stable invocation/receipt reconciliation, retention, deadlines and cumulative budgets. Provide disabled/live/deterministic Layers; validate distributions and preserve provider-specific uncertainty. This is distinct from frozen Agent/Routine eval.run experiments; no speculative operation name is advertised as available. Review the experimental AI SDK/provider compatibility closure before dependency changes. Approval of this documentation does not authorize new packages, live credentials, paid calls or production activation.

Exit: PF-23/DF-23. Offline deterministic contract work can start now; live Jev qualification needs explicit provider/data/spend approval and observed evidence. Disabled/unavailable evaluation must leave ordinary SDK/CLI/Node controls usable.

R10b — qualified adaptive consumers

Dependent on R10a and each owning deterministic baseline; documentation target, not implemented automation. The canonical Swarm flow uses one scoped coordinator implementation for Maia, Workspace and Project: LLM + Jev with distinct grants/context/configuration/budgets. Execution workers stay LLM-only. No separate router framework, scheduler, graph database or queue service is planned.

  1. Minimum CLI-first slice: one already-supported read operation, an authenticated input lane, initial Jev routing, Node admission, bounded queue/journal records and evidence-backed dispatch acknowledgement before a delayed result. Freeze protocol → SDK → Node → CLI contracts and deterministic Effect tests first; no UI prerequisite.
  2. Central preparation: R1/R3 provide exact owners and authoritative graph sources; Node maintains scoped Session context projections and compiles bounded manifests. Provider policy admits model/effort candidates; Jev judges relevant context/setup. Preserve required constraints and reject stale, forbidden or unsupported selections.
  3. Parallel branches and follow-ups: bounded plan data references existing registry operations, destinations and dependencies. Independent branches proceed concurrently; named joins alone wait. Add fair admission, deadlines, cancellation, backpressure, per-owner/global limits and priority provenance. Initial evaluation composition allows one parallel assessment and at most one evidence-dependent follow-up; deeper coordinator loops require separately admitted cumulative budgets.
  4. Linked journals and selective feedback: keep human input, internal requests, worker events and feedback distinct over shared infrastructure. Work/attention queues project Node events; acknowledgements distinguish queued from confirmed handoff. Add advisory Jev work/attention scores and event/time/context-triggered grouping, bounded deferral and deduplication. Preserve mandatory visibility and owed answers.
  5. Client context and delivery: R9a adds independent ephemeral Desktop/mobile focus snapshots, input-generation binding and json-render visual updates. Text/voice are selective, scope-bound and consented, not broadcasts. Do not steal focus or rewrite queued command targets. R7 owns media; AI feedback cannot delay work or receipts.
  6. Outage and qualification: required LLM/Jev loss blocks affected automation with typed unavailability, not deterministic/alternate-model AI fallback. Manual controls, resource views and reconciliation continue. Recover exact identities before retry; qualify scope, restarts, fairness, freshness, retention and existing performance gates.

Owners: protocol registry, SDK, existing Node/Swarm/evaluation/context/provider services, Agent projections and client-core/platform adapters; no new package is implied. Exit: PF/DF-29 plus PF/DF-17/23/24 and applicable R9a DF-27/28. Compare relevance, missed constraints, abstention, injection resistance, latency and cost against labeled deterministic baselines. Independent current-artifact review is required; correlated scores are not verification. Hundreds of concurrent jobs is a measured capacity target, not a property inferred from provider API quotas.

R1a — external coordinator through CLI and Desktop

Next, alongside R1; no autonomous coordinator prerequisite. An authorized external assistant must be able to work through the public CLI now: publish a scoped question or progress update, let Desktop project it, and read the recorded human response back. It must not write renderer state, impersonate a running Maia coordinator, or fabricate an activation/worker lease. Reuse existing primitives; implement the missing planned interaction operations through Protocol → SDK → Node → CLI before mounting their client projection.

Start with bounded text and selection cards, including accessible Yes/No buttons. Use the existing interaction contract, not arbitrary generated HTML, JavaScript, commands or callback URLs. Freeze the external-request origin, exact Project/Session scope and record-only response contract before implementation; an idle Session is not a waiting activation. Node owns revisions, expiry, cancellation, answer validation, receipts and reconnect recovery. Show provenance, target, pending/stale/answered state and honest delivery failures. A first dogfood question can ask whether routine progress updates should be shown; its answer changes no execution permission.

An ordinary answer never becomes consequential approval. For an action card, reuse an already accepted operation's exact preview and trusted human confirmation; show its normalized effect, target, revision and expiry, and reconcile its receipt. The requesting assistant cannot approve its own proposal. Blocked Project metadata acceptance is not bypassed; start approval dogfood with an independently accepted, reversible operation on a disposable target.

R10 may later rank relevant questions or select admitted presentation variants once this deterministic loop works. Jev does not generate executable UI, hide required approvals, answer for the user or authorize an operation. Required AI failure stops that automation, while the same manual text and buttons remain usable. This bounded R10 pilot does not wait for autonomous coordinators or authorize new dependencies. Exit evidence is a real CLI publish → native card → explicit human answer → CLI read journey, plus wrong-scope, stale, replay, expiry, cancellation and provider-down tests.

R11 — replace the daily Pi harness

Next for inventory/contract work; implementation depends on the owning R slices. Inventory every extension/action and user resource under the explicitly selected .pi/agent source. Reuse official Pi primitives already supplied by maia agent; port reviewed behavior with provenance, not ambient configuration, credentials or live runtime state. The observed source has 33 pi-* extension directories, plus agent definitions, prompts and Skills; names alone do not prove enabled or working features.

The migration plan defines AG0–AG5, source manifests, owner mapping, local-vs-managed behavior, failure tests and reversible cutover. The existing capability disposition inventory remains the single feature/action map; do not add another plugin or scheduler. Every source action needs a verified equivalent or an explicit user-accepted deviation. Unimplemented/unsafe capabilities remain blockers to a full replacement claim, not silently deleted from the checklist. Existing safety/task/goal/process ports are extended only for measured missing behavior, not copied again.

Owners: packages/agent interaction/resource adapters, protocol/SDK, Node runtime authority, Swarm orchestration, CLI/TUI and Desktop projections. Exit: PF-19/PF-20/PF-21 and DF-19/DF-20/DF-21, plus all affected existing suites. No modification to the running Pi harness or default shell launcher is part of this documentation update.

R11 port map

The reviewed port (D-069) and its source-to-slice map are in the migration plan.

First implementation admissions

Order comes from the delivery plan. This list only says what each R admission inspects first.

  • R11-AG0: freeze the secret-free Pi feature/action and resource manifest; read source-owner docs/tests, record license/revision/digests and map each behavior before porting. Never execute source startup hooks for discovery.
  • R0 and R0a-SO0/SO1/SO1a: inspect the existing candidate, current layout/parity failures and ownership, then recover their acceptance paths. Do not relaunch duplicate work or mark it accepted because historical tests passed. R0a's first structural pilot follows the current baseline, affected parity closure and accepted SO1a tooling-hardening checks.
  • R1 and R1a: finish the smallest authorized portfolio read/snapshot contract and DF-01/02 fixtures. In parallel, freeze and implement the external-coordinator question/answer loop above; deterministic typed cards precede optional adaptive presentation, and no autonomous coordinator is required.
  • R2 and MN0 in parallel: name the containment/identity prerequisites and supported host matrix. Their contract/denial work can progress without live workers, models, cloud accounts, SSH access or a running production Node.
  • R3 plus R7-V0: freeze distinct owner/visibility and parent-delegation contracts, then deterministic conversations and synthetic transcript fixtures. Run DF-22 discovery/ownership denials before admitting coordinator scopes. Do not activate microphones or emulate execution while containment is blocked.
  • R10a in parallel: freeze the shared evaluation contract and deterministic SDK/CLI/agent call path. Do not wait for R10b UI optimization or block R1–R4 on a provider; SDK upgrades and live evaluation retain separate approval gates.

For each admission record: exact operation IDs reused/added, schemas/errors, actor/grants, surface exposure, revision/confirmation policy, migrations and recovery, bounds/deadlines, owner files, failure tests, PF/DF mapping and an independent review path. A contract gap is named work in that slice, not a reason to add a parallel framework. This plan is ready to start contract slices; it does not pretend every future wire schema or platform adapter is frozen.

Multi-server worker execution within one control domain

One Control Node places fenced assignments on enrolled execution supervisors, reusing the Node executable's reduced execution-only composition and the existing HTTP/WebSocket transport (the transport awaits an owner decision, D-150). Design, diagram, enrollment, placement, heartbeat, handoff and containment rules: multi-server execution.

StageRequired deliverableEntry / exit
MN0Registry/SDK machine principal, runtime/channel/storage contract (startup grammar: MN1/MN2), administrator bootstrap dependency, operation gap inventory, schema/bounds and supported host matrixNo runtime launch; contract and denial tests; DF-03/08 fixtures
MN1Enroll, inspect, rotate, revoke exact NodeMN0 + qualified identity/transport/secrets; replay/expiry/foreign-domain denial
MN2Prepare an exact environment and place one read-only workerMN1 + qualified profile; resource reservation and idempotent launch; no implicit write authority
MN3Observe, steer/cancel, transfer artifacts and reconcile receiptsMN2; cursors, stale fences, lost acknowledgements and slow-observer tests
MN4Two-server pool plus local capacity; drain/handoff/recoveryMN3; capacity races, partition/reboot, unknown effects and nonduplication; DF-08/10
MN5Project/client/voice projections of actual placement and readinessMN3/R1 and relevant R7/R9 portions; manual parity, no inferred health

MN0 status: Source candidate. The machine principal, assignment, lease and evidence schemas, the bounds, the MN1 gap inventory, the host matrix and the DF-03/08 L0 manifest are in the repository. No transport mints a machine principal and nothing launches a worker; MN1 waits for E2a and a managed administrator credential (the first version enrolls through the D-136 ceremony until it exists, D-150). MN0 defines no execution-only startup mode or CLI help: that grammar moves to the slice that adds the mode (MN1 or MN2), which freezes it with its own tests.

Detailed owners: Node composition, process and spool, enrollment, placement. No remote release claim until real multi-host DF-08/10 and approved provider qualification pass; localhost mocks alone are insufficient.

Control Node host and full Desktop delivery

This is the primary requested deployment: the full Desktop controls a Control Node and its workers, with no decorative controls. Reuse R6 enrollment and placement and R9's one Expo/Tauri application; Desktop owns input and rendering only. Full control, connectivity, availability, host prerequisites, data boundary and operator validation are in the design.

Full Desktop app — DP2

Planned: the complete Desktop, minimal and keyboard-first, on D-091's routed pages and the client-core command registry (specification).

  • DP2a shell. The dock (the personal agent once S67 ships), Details on every item, a generated menu bar and shortcut sheet, keyboard-only journeys and the performance gates in M0, on DP1's shipped operations. It adds no Node operation (its menu event needs the Desktop permission review), so it starts once DP1 qualifies.
  • DP2b pages. Tasks, attention, Agents, Routines, fleet, pause and resume, organization and audit pages, each after its CLI path.
  • DP2c design revisions. Agents improve the Pencil baseline in reviewed copies, never the owner's canvas; dogfooding drives each next revision.
  • Mandatory gates. Every journey works from the keyboard alone, and the performance gates in the specification (input within two frames, launcher 50 ms, route change 100 ms, cold start 800 ms at p95 in the real app) fail the release on a miss or a 10% regression.

Dozens of Workspaces from one interface

R1/R9/R11 must qualify PF-20/DF-20 with a deterministic baseline of 24 Workspaces, 96 Projects, 1,000 retained Sessions and 24 simultaneous worker activations spread across laptop capacity, VPS-local capacity and two Execution hosts. Use a 2x fixture and declared saturation cases; these are test targets, not shipped capacity claims or authorization for paid workers.

One authorized aggregate feed plus bounded detail reads powers portfolio search, attention, Project navigation and concise spoken answers. Never launch one stream, coordinator model loop or evaluator call per displayed Project. Keep inactive coordinators dormant and context scoped; explicit concurrency/spend reservations limit actual work. Test duplicate spoken names, pagination, restricted clients, rapid text/voice target switches and stale server state at this scale. Measure p95 UI focus/event delivery, memory/CPU/queue/spool use and voice round-trip costs against the owning client/operations budgets before a capacity claim.

Status (2 Oct 2026): source candidate. The Desktop Work cockpit (decision) loads one bounded index, follows one observe.events feed and reads runtime health once per interval; Playwright measures it on a synthetic 24/96/1,056 fixture and its 2x case (key-to-paint p95 about 31 ms, two frames, in headless Chromium). Since 3 Oct 2026 it serves routed pages in one app shell behind a Node boot gate, with search, filter and page in the URL (decision). The index load reads Workspaces with their Projects from container.index.list pages of 500 rows (since 3 Oct 2026: 1 request instead of 505 for 500 Workspaces, limits 1,000 Workspaces and 2,000 Projects; decision), pages one whole-Node session.list (S44), the attention list orders the reasons the Node reports, failures are classified by the SDK and Desktop changes arrive through the SDK's watchNodeChanges. The Session page mounts the live Session view with its composer and dictation in the shell's dock, and /nodes narrows every page to one registered Node or shows them combined. DF-20 with real Nodes and 24 live activations remains open.

Portfolio voice contract

Text is the default input and complete fallback; the user may primarily choose voice. Both are peer interfaces to the same message/control operations, never privileged operators. Reuse existing bounded text and voice boundaries; close readiness gaps instead of making another backend or requiring every request to traverse a model agent.

Rules for text and voice peers, capture targets, confirmations and failures: portfolio voice contract.

Shared observability, automatic learning and optional optimization

R1 first extends actual domain reads and existing observation ingress into bounded authorized snapshots, not a new monitoring backend. Include Node identity/epoch, principal/scope/policy revision, observed time, source revisions, coverage, signed cursors and reset reasons. Preserve per-owner sequence and causal links without inventing global ordering. Recheck grants on pagination, replay, content fetch and export; isolate slow observers and bound spools/fan-out.

R4 adds automatic Workspace/Project learning, not just a manually populated library. Coordinators turn eligible requests, corrections, decisions and evidenced worker results into scoped knowledge, memory and reusable Skills. After the user confirms the bounded learning policy, ordinary low-risk updates publish and are reused automatically; users do not need to approve every note or write Skills by hand. Wider sharing, executable additions and permission/configuration changes still require their own explicit approval. Project-to-Workspace promotion is an exact reviewed scope change, never implicit inheritance of private Project data.

The coordinator learning contract owns scopes, provenance, automatic authoring/admission/use, correction, revocation, forgetting, budgets and official Cursor/Claude references. It supersedes the manual-only/blanket no-automatic-memory interpretation, not the ban on ambient history injection or self-modifying authority. Snapshot state, durable knowledge and reusable procedures remain distinct. Workers receive bounded, attributed context and exact admitted Skill versions, never every conversation in a prompt.

Manual knowledge storage/retrieval remains deterministic. Automatic R4 learning uses the shared coordinator path after R10 admission, not an independent learning brain. The Node context contract owns authorized retrieval, Jev selection, code-compiled manifests and mandatory constraints; the provider contract owns central model/effort setup. R10a/R10b above own delivery and qualification, including unavailable-AI/manual-recovery behavior. This plan does not authorize new packages, provider calls or production activation.

Local telemetry (T0–T7)

Design: local telemetry. Data stays on each Node; export is an explicit capability; telemetry produces reports, never automatic changes. Defaults: basic on for stable builds (once published); every level on for canary and development builds, with a first-run notice; export always off until a person enables it. Storage and CPU figures below are targets to measure, not observations.

SliceDeliverableAcceptance
T0Consolidate the existing diagnostics: one schema constant, metric factories instead of module-level descriptors, stderr for warnings only, span sampling (errors, slow and root spans), diagnostics.ndjson, 7-day retentionIdle Node writes at most 50 KB/h; a second in-process profile sees every metric; existing tests pass
T1Turn usage for Claude Code, Codex and Pi: tokens, cost, model and duration settled with each turn, including failed and interrupted turns (tokens already ship for Claude Code and Codex)100% of completed fixture turns carry usage; Claude per-turn cost sums to the SDK total within 0.1%; no content fields; failed and interrupted fixture turns carry usage or an explicit unavailable marker, never invented zeroes
T2telemetry.sqlite, telemetry.status, telemetry.query (usage, node), telemetry.purge, levels with basic onRollup under 0.2% of one core at idle; 128-row batch commits at p99 under 10 ms; under 1 MB/day at 50 Sessions × 20 turns; expired rows gone within 1 h; query usage p95 under 100 ms over 90 days
T3Skill, Run and harness views (after S19 and S22)Figures for the S22 N = 1, 3 and 8 scenarios match a hand count
T4Loopback OTLP/HTTP JSON receiver for Claude Code and Codex (detailed, opt-in)At least 95% of fixture events mapped to the right Session; unauthenticated, foreign-Session, oversized and protobuf requests rejected; no identity attributes stored; under 1% of one core with 8 Sessions; under 20 MB/day at 1,000 turns
T5CI runs, jobs, steps and test results pulled per Project (opt-in)100 runs synced in under 60 s; re-sync creates no duplicates; flaky tests reported
T6Federated queries across Nodes (after S14)A three-Node query returns per-Node coverage; no content crosses Nodes
T7Export capability with preview, confirmation and receiptPreview shows exact classes, counts and bytes; standard tools read the bundle; revocation works

Later boundaries, not prerequisites for the first portfolio journey

Direction: an organization's agent hub

Maia is the coordination hub for any agent and harness. An organization runs a Maia Node that people's agents (Claude Code, Codex, Pi, external A2A agents) connect to; they delegate to each other through it with Node-stamped identity, grants, human approvals and receipts. v1 slices focus on one user's swarms, organizations and people adds the people, and every v1 slice keeps this path open: a generic principal model in S18 (human, Session, external peer), principal- and grant-based messaging in S17, the Run ledger and receipts as the audit trail, A2A ingress after S17, and no network exposure before remote authentication (MN0). The designs already exist in team Workspaces and control Nodes and the Node identity and tenancy model.

Required before an organization deployment: people, roles, sign-in and per-person budgets (ORG1–ORG7), authenticated remote access (MN0–MN1) and isolation between people on a shared Node (ORG7). Current containment, and S47 sandboxes once built, bound a Session's process tree, not its OS user. Later: agent discovery and messaging between Nodes and organizations over A2A, so a Codex Session and a Claude Code Session on different Nodes can exchange messages, each Node stamping and receipting its side, never shared authority (another organization is another Node).

  • Team and independent Control Nodes: verified owner/device identity precedes grants and machine enrollment; full invitations, roles, per-user Project grants and per-client context then precede cross-domain client pairing. Keep separate connections, secure credentials, epochs and caches per Control Node. Never federate authority or retarget an open command on Node switch. Preserve legacy execution workspace_* identities through the R1b Execution Environment naming migration. See bootstrap canary.
  • Moving a Session between workers: planned once sandbox containment exists (S47, S66); the owner's goal is that it is easy. The first version places a Session on a worker when it starts (D-150).
  • Inventory/configuration and attachment TUI: finish missing contract parity for admitted versioned inventory/configuration and Session attachments using existing owners; no separate terminal backend or dashboard prerequisite.
  • A2A/external brains/backends: preserve one durable internal task/session lineage for each accepted A2A task. MCP supplies bounded tools/context, not orchestration truth. Codex/Claude brains use public CLI/SDK operations and explicit grants; being a brain does not add its worker backend. Vendor worker backends are the separately approved v1 slices above.
  • Presentation: accessible lists/search/inbox and the connected Project journey precede scale-oriented 2D topology and optional 3D. Reuse the shared Expo/Tauri client; web export remains internal, not a standalone product, unless S52's decision entry replaces that rule. Native mobile follows Desktop with real secure-storage/audio/pairing evidence.

Distribution: channels, CI/CD, updates and compatibility

Design: Release, update and compatibility. Canary only, long-term: CI publishes a canary for the newest green push to main (D-185, source candidate) and moves latest to it. There is no stable, next or nightly channel and no promotion, not at the public launch either (D-202). Automatic updates (ZU) follow canary builds only. Each stage ships on its own.

StageDeliverableStatus
RL0Publish pipeline: build once, test the tarballs, publish the same bytes through OIDC, install them back from npm (D-132); one Node tarball with the darwin-arm64 and linux-x64 process hosts, installed and started on both (D-134); upgrade-from-published smoke tests on macOS and LinuxSource candidate; Linux until a canary installs on it; upgrade tests next
RL1version.txt lockstep version; canary only (D-185, D-202; source candidate), with latest following the newest canary of main; tagged GitHub pre-releases; changelog from Conventional Commits; fast CI (cached pnpm store and Turborepo cache, affected-only pull requests, sharded tests, macOS and Linux native-host jobs)Source candidate (D-132); changelog and sharded tests next
RL2node.hello handshake in protocol, SDK, Node, CLI and desktop; Node reports version, channel and commit; tolerant response readers; operation-registry diff check in CI; skew policy and protocol_incompatible errors naming the side that is behind; a missing capability disables only the action that needs it; version skew alone never restarts a workerPlanned
RL3One home ~/.maia with versions inside (versions/<v>, current, profiles, run/) and an automatic, backed-up migration from the split state, observability and runtime directories; one installer for macOS and Linux (private pinned runtime, LaunchAgent or systemd user unit pinned to an exact version, cgroup delegation); maia remote install <host> over SSHPlanned; side-by-side install and switch of an exact canary on darwin-arm64 is a source candidate (D-137); the Linux process host needed exists (source candidate)
RL4Update checks in the Node, notices in the CLI; maia update (side-by-side install, preflight, drain, backup, switch, restart, verify, rollback, receipt); auto/notify/off policies (auto is ZU2a's updater, D-196); maia node update --host for remote NodesDependent on RL0–RL3; the offline release update (install and select on a stopped profile) is a source candidate (D-140)
RL5Desktop: signed Tauri updater with one canary feed, Node update from the appDependent on RL1 and the owner's signing identities and public release host
RL6Seamless updates, superseded in part by ZU0–ZU2 (D-196): Sessions keep running instead of pausing; what remains here is maintenance windows, pools and harness approvals. Original scope: auto no longer needs an idle Node; the update pauses work (S70), switches, verifies and resumes it, or rolls back and resumes; maintenance windows; pools one Node at a time, a pilot Node first; new harness versions after a person's approval. DesignDependent on RL4 and S70; pools on MN4 and S66
RL7Windows CLI and SDK, connecting to a Node on macOS, Linux or WSL2; Windows Desktop only after a remote-only bootstrap, transport, credential custody and a reviewed Windows confirmation dialog exist, failing closed until then as Linux does; no native Windows Node host in v1 but TM1b's terminals (D-175)CLI and SDK after RL3–RL4; Desktop after DP2a and that design
RL8Security releases: a security mark (severity, advisory ID), installable on every supported channel within hours; a signed advisory and revocation feed the Node and CLI verify, cache and enforce; receipted auto-update under owner policy, staged across a fleet; compromised-dependency runbook and daily scan. DesignCI half now; Node and CLI after RL4; fleet after MN1 and RL6

Managed version

A managed version is planned; it is developed and tracked outside this repository (D-205). Self-managed deployment recipes live here, after S58 and RL4, so self-hosters need nothing else.

Release and dogfood gates

Run the applicable owning tests and the repository release gates:

pnpm check:quality
pnpm test

The dogfood specification defines fixtures, expected outcomes, faults, artifact capture, safety and cleanup for DF-00–DF-29. Do not claim those suites ran merely because this plan or generic tests pass.

Every delivered story requires registry/SDK/Node/built-CLI agreement, failure-path checks, and independent current-target review. UI/voice stories also require rendered interaction and connected native evidence. Record blocked checks, unsupported hosts, unavailable providers and skipped manual gates separately.

The Pi-replacement milestone also requires the R11 action manifest fully accounted for, reversible cutover and independent user sign-off; source directory names or passing read-only tests cannot establish behavioral parity. The scaled master-VPS Desktop claim separately requires DF-20/21 on qualified hosts.

The portfolio release requires complete text-only and voice/text-switching journeys in every Session kind, plus manual and voice portfolio control across at least two Workspaces, multiple Projects, local capacity and two remote hosts; inspection/steering/cancellation; library and reviewed outputs; budget denial; stale/ambiguous target handling; disconnect/restart and receipt reconciliation. Read-only remote qualification alone cannot pass the coding journey.

Preserve migration backups and rollback tests, packed provenance/notices, clean-host install/update recovery, redacted evidence and absence of leaked secrets. No screenshot, narrative summary, zero-exit launcher, optional evaluator score or timer-only run can certify completion. Promote status only for the exact tested capability/platform and retain the evidence outside disposable profiles; cleanup must not touch a developer's repositories or live Node.

Authoritative implementation owners

Update the owning specification when a slice freezes a contract; do not maintain competing schemas, operation names or lifecycle definitions in this roadmap.

Imported from Maia OS docs at 3dc3e07