Maia Swarm architecture
Status: Planned (R1–R10, S17, S18, MN0–MN5 in the
roadmap); no Swarm service exists. It builds on source
candidates: vendor executor Sessions and maia mcp
(external executors), the S19 Run ledger
(coordination), and
the registered session.spawn and Session mailbox
(peer-agent protocol).
Outcome
Maia Swarm is the one orchestration layer above Maia Node across Projects. It is not another agent harness and runs no second model loop: native work runs through the Maia Agent kernel (decision), and Maia Node owns durable state, events, leases, traces and receipts. Maia is the coordination hub through which any agent or harness reaches another (decision).
operator / CLI / MCP / voice / A2A
|
Maia Swarm service
Projects, Routines, admission,
Session trees, queues, budgets
/ \
Maia Node + Agent external executor
native Sessions Sessions
Swarm runs as Effect services inside the one Control Node process (decision); moving it out later must not change operation IDs or Agent definitions. Deployment and failure model: operations. Schemas: contracts. Nouns (Agent, Agent Session, Routine, Workspace, Project): product vocabulary.
Coordinator ownership and visibility
Maia, each Workspace coordinator and each Project coordinator are distinct principals and durable owners (decision). They reuse the Maia Agent kernel but share no model Session, memory, credentials or mutable context. One trusted Control Node enforces every owner (Node enforcement).
| Owner | Owns and may discover | Excluded from its discovery surface |
|---|---|---|
| Maia / global | Its global conversation, preferences, requests and delegation records; authorized Workspace directory and permitted summaries | Other owners' scopes; an unrestricted Project/worker directory or private child context |
| Workspace | Its conversation, shared knowledge, objectives and delegation records; its own Project directory and permitted summaries | Other Workspaces, their names, Projects or activity |
| Project | Its conversation, knowledge, work, artifacts and authorized Sessions/workers | Other Projects, including siblings in the same Workspace |
| Worker | Its assignment, resources and explicitly supplied or granted Project context | Sibling workers and wider Project records unless the assignment grants those reads; all other Projects |
- Membership is not content permission: discovering a child permits only its admitted summary, never its history, tools or credentials.
- Bounded Session discovery and peer messaging follow D-166: a Session sees the Session ID, Project, role and state of the Sessions it may message. That merges no owners and grants no other owner's history, memory, tools or credentials.
- A coordinator never inherits the human client's portfolio grants. Every activation binds an exact owner kind and identity, principal, Session and policy revision; role labels grant nothing.
- Global and Workspace owners need an explicit protocol and storage extension (R3) before activation; never fake one with a caller Project ID, a synthetic operator Project or a wildcard. Existing IDs and history are migrated, or activation is refused.
- A Workspace may own several ordinary Sessions, even with no Project, repository or Execution Environment, without creating or waking a coordinator (Session ownership contract). Such a Session gains no coordinator authority, and Project execution is delegated, never obtained by reparenting.
- The human client may address any exact Session in its portfolio; that gives the receiving Project no lateral visibility. Node can deliver an exact admitted request through a Workspace boundary without waking its model. Idle coordinators hold no model stream.
- Maia mediates cross-Workspace work; a Workspace mediates cross-Project work inside it. Siblings never discover each other beyond the peer directory of D-166.
flowchart TD
Maia["Maia: authorized Workspace directory"]
Maia --> WA["Workspace A: own Project directory"]
Maia --> WB["Workspace B: own Project directory"]
WA --> PA1["Project A1: own work only"]
WA --> PA2["Project A2: own work only"]
WB --> PB1["Project B1: own work only"]
PA1 --> Workers["Assignment-scoped workers"]
The global coordinator, Maia, owns a distinct Session and principal. It routes
requests through Workspace boundaries, receives permitted results, asks for
previews and never consumes a human-only confirmation. Every request it sends
binds source message, principal, owner scope and policy revision, exact
destination, input digest, delegated rights and receipt lineage; an ambiguous
scope needs clarification. Human portfolio reads and exact controls stay
available through CLI, API and SDK when any coordinator is down, and there is
no all mutation selector or inferred fallback coordinator.
Parent-mediated delegation
The parent owns the request and its delegation record; the recipient owns the accepted work and its execution resources. Node links the exact identities instead of giving two owners one mutable task. Cross-owner delegation is not a Session-tree child and never inherits grants. It composes the existing message, task and Session owners; no task-graph product, workflow language or scheduler is added.
Before delivery the contract freezes sender and recipient owner and Session, source-message references, objective, constraints, acceptance criteria, permitted input and output classes, policy and revision fences, expiry, budgets, idempotency and receipt lineage. References and reply capabilities never reveal hidden sibling IDs. Node keeps full provenance and projects only what the recipient may see.
- A Project returns a result or an out-of-scope need to its bound parent. The parent may pass an explicitly permitted input or result to another child, never private text, titles, paths or citations merely because both children are its own; read access and model redaction are not disclosure permission.
- Replies are data, not grants. Steering or cancellation needs the rights recorded for that delegation and is settled only when observed.
- Retries reconcile the original identities. A late result after revocation, expiry or recipient replacement admits no new work.
Router-first execution and attention
This section owns routing, parallelism, work and feedback policy and role boundaries. Node owns context, journals and evaluation; presentation owns client signals and delivery; operations owns outage recovery; contracts lists the protocol obligations; R10b sequences delivery. No other scheduler, graph database, queue service or router catalog.
Roles and readiness
Maia, Workspace and Project coordinators use one scoped coordinator implementation: the same routing, context preparation, queues, journals, delegation and feedback, with different owner scope, grants, configuration, model and effort policy and budgets. Each keeps its own Session, history and context graph. An exact authorized Project request goes straight to that Project without ancestor model hops.
- Coordinators and autonomous bots combine a reasoning LLM with the shared Jev evaluation capability. Bot is a role, not a runtime or CLI resource.
- Execution workers use LLMs and their admitted tools only, with no Jev access or routing policy; central services prepare their context and model setup.
- Node validates and executes decisions. Jev supplies judgments, never grants, lifecycle truth or verification. Follow-up work uses the same admission path; replies transfer no ownership.
- Automation needs both its reasoning model and Jev. If either fails, affected new AI decisions are blocked with an explicit unavailable state; cached scores, FIFO or a fallback LLM never stand in. Manual operations, observations, safety controls and factual acknowledgements stay available, and admitted effects are reconciled, not killed or replayed.
Routing plans and bounded parallelism
- The Jev router judges eligible intents, destinations and setup without a coordinator pass per known request; complex or ambiguous requests go to a coordinator or ask for clarification.
- Code supplies candidates; the LLM may propose bounded plans referencing the original input. Keep the whole request and shared constraints ("test both; do not deploy"). Multiple intents get independent judgments.
- A plan is versioned data over registry operations, admitted Session and delegation primitives and explicit dependencies; never code, a plugin or a workflow language. Node validates targets, rights, schemas, expiry, spend bounds and confirmation rules before admission and again at execution where required. Persistent policy changes need their own preview, confirmation and receipt; model suggestions never register tools or widen authority.
- Independent branches run concurrently; a join waits only for its named inputs. Journal order records observations; it does not serialize work. Sequential gates stay: authorization before export, approval before consequential work, context compilation before a model call, observed handoff before its acknowledgement.
- Node bounds each request's branches, depth, time, candidates, retries and spend, and reconciles unknown effects instead of dispatching again. Do not mix private owners' histories to increase batching, and never claim unlimited routes, requests or parallel workers.
Work priority and separate message lanes
Human requests, coordinator task requests, worker events and user feedback are separate lanes over the same SDK, journal and delivery. Node derives authenticated origin: a task or worker report never becomes a human instruction or approval, and cancellation, receipts and confirmations are protected from background traffic.
One Jev scorer uses separate versioned rubrics for work priority and for attention. Node measures deadlines, costs, queue age and dependencies and applies deterministic eligibility, reserved control classes, fair shares, aging and capacity limits first; scores rank only inside an eligible class and keep their model, rubric, revision and expiry. No score bypasses a dependency or confirmation, starves a scope, cancels work, hides a failure or certifies completion. Without a scorer, the default until R10b, the deterministic scheduler orders work FIFO within its class. Where a Project turns ranking on, a scoring failure blocks the autonomous choices that needed it (the readiness rule) instead of falling back to FIFO; manual controls and the reconciliation of admitted effects go on.
Journal-driven acknowledgements and feedback
Work dispatch and feedback use separate bounded queues; the linked journal views stay the record of truth and feedback is a projection. State, resource and mandatory-visibility updates bypass model latency; delivered, seen and acknowledged stay separate observations; an unknown handoff keeps its original identity.
- Each accepted or queued branch and each confirmed handoff is recorded at once, and the acknowledgement fast lane reports that evidence ("two dispatched; one queued"). Received, queued, dispatched, running, completed and dispatch-unconfirmed are distinct; transport receipt does not prove executor acceptance, and an acknowledgement never replaces confirmation.
- The feedback router wakes on meaningful events, a bounded deferral deadline or a relevant context change. Its input is the original request, the originating view, feedback already delivered or seen, pending age and notification preferences. Idle is an expiring client signal, not proof of anything.
- Jev recommends relevance, grouping, timing and an allowed channel; the LLM writes an explanation only when useful. Channels: view update, attention card, grouped summary, conversation reply, opt-in speech on the originating device, bounded deferral, or no interruption. No interruption never deletes evidence or hides owed answers, approvals, failures or unknown outcomes.
- Deliveries are deduplicated and revalidated against scope, expiry and view generation; only replaceable progress is coalesced; deferral has a finite timer. Slow speech never blocks visual updates, speech is never broadcast and focus is never stolen. Under AI outage, essential status, acknowledgements and manual recovery remain.
End-to-end flow and extension boundaries
flowchart TD
Clients["Desktop and mobile input with separate focus snapshots"] --> SDK["Public SDK"]
SDK --> Gate["Node validates origin, scope and input binding"]
Gate --> Input["Accepted input journal view"]
Context["Authorized Session graph and ephemeral client context"] -.-> Router
Input --> Router["Initial Jev routing and setup judgments"]
Plans["Coordinator-proposed bounded plans"] --> ValidatePlan["Node registry and policy validation"]
ValidatePlan -.-> Router
Router --> Admit["Node approval, admission and priority policy"]
Admit --> Queue["Bounded work queue"]
Queue --> Dispatch["Dispatch independent eligible branches"]
Dispatch --> Workers["Parallel LLM-only execution workers"]
Dispatch --> Reads["Direct admitted operations"]
Dispatch --> Coordinator["Coordinator LLM when needed"]
Coordinator --> Plans
Dispatch -->|"Confirmed handoffs"| Journal["Node journal and event queues"]
Workers --> Journal
Reads --> Journal
Coordinator --> Journal
Journal -->|"Authorized follow-up evidence"| Coordinator
Journal --> Ack["Immediate factual acknowledgements and resource updates"]
Journal --> Feedback["Feedback queue: event, time and context triggers"]
Context -.-> Feedback
Feedback --> Analyze["Jev attention judgments and LLM composition when needed"]
Analyze --> Delivery["Node validates scoped feedback delivery"]
Ack --> Delivery
Delivery --> View["Originating visual, text or opt-in voice channel"]
Extend existing owners only: the protocol registry, context projection, shared evaluation rubrics, Node and Swarm admission, and client-core and platform ports. No package extraction, ambient plugins or arbitrary graph properties. Each addition declares inputs, results, errors, ownership, expiry, bounds and contract tests; freeze numeric limits before any capacity claim. PF/DF-29 owns end-to-end acceptance.
Policy boundary
coordinator, specialist, maintenance and administrator are Agent roles
only; they add no runtime type or authority. A child is a normal Agent Session
linked by parentSessionId. Swarm dispatches only Agent Sessions and Routine
ticks; Session-local task items are not scheduling truth.
| Swarm decides | Swarm does not persist or enforce directly |
|---|---|
| Project admission and hold policy | authoritative Project rows and revisions |
| Agent/Routine snapshot selection | snapshots, credentials, or provider refresh |
| Session-tree and peer-delivery policy | Session rows, events, or message delivery |
| queue fairness, quotas, and reservation plans | leases, reservations, or worker processes |
| Node/executor placement and handoff intent | assignment fencing or external state truth |
| cross-Project operator projections | JSONL evidence or repository source changes |
| voice routing to the exact attached Session | realtime audio transport or confirmation proof |
Every accepted Swarm decision invokes one registered Node operation; Node owns
the row, revision, event, idempotency record and receipt. Operation schemas
live only in packages/protocol; the grammar is in the
CLI reference.
Project inventory and admission
~/.maia/projects.jsonc and Project-local .maia follow the
configuration contracts.
Both are desired state, never authority. The operation names here are
planned.
project.inventory.syncapplies only a confirmed inventory digest at the expected registry revision. It may add or relocate exact Projects; omission never deletes, archives, holds or stops one. Relocation fails closed while the Project has a live assignment, unresolved effect, active handoff or root-dependent credential grant.project.adduses the same path. Swarm never hot-applies editor changes.- Repository configuration is untrusted until an operator admits an exact snapshot digest (discover, parse, resolve, Doctor, policy validate, candidate, preview, CAS admission, receipt). A repository change yields a candidate that cannot silently broaden tools, Connections, executors, budgets, schedules or cross-Project access; only fields on an immutable protocol allowlist may be admitted automatically.
candidate -> admitted -> active <-> held
active|held -> draining -> held|archived
admitted|active|held -> archived
held blocks new activations and Routine ticks but kills nothing. draining
blocks admission and asks running work to settle. Archive needs zero live
assignments, reservations, unresolved effects, open handoffs and pending ticks;
project.unarchive restores only a Project whose root identity and snapshot
still validate, otherwise it returns to candidate.
Project teams and home Sessions
An Agent definition may request homeSession: true: Node atomically obtains
or creates the one Session keyed by the exact owner and Agent definition
(Projects first; global and Workspace owners wait for R3). Idle, it holds no
model stream or worker lease. It wakes on a user message, a Routine tick, an
authorized peer message, an A2A task or a recovery event; concurrent wakeups
coalesce by Session revision and inbox sequence, and v1 runs one activation at
a time.
Coordinator behavior comes from an Agent definition and Skills; the role grants no tools or budget. A Project coordinator's worker children stay in that Project under depth, fan-out, capacity, Connection, executor and cost policy.
One peer-agent protocol
The planned model-facing agent tools (start_agent and its siblings) and the CLI session operations
project one durable protocol; there is no in-memory subagent. Registered today:
session.spawn links a child Session to exactly one parentSessionId (the
CLI refuses it until runtime qualification), and each Session has a durable
mailbox reached through session.message.send and session.inbox.check|ack
from an attached Session. A mailbox holds at most 256 unacknowledged
deliveries and 1 MiB of their content (mailbox_saturated); acknowledging a
delivery frees its share and the acknowledged record stays. Planned
(D-168): the acknowledged record keeps its trace,
not its subject and body. S17 makes this the
agent-to-agent channel (decision) and S18b adds the
guards (decision).
A child start atomically records Project, parent, root and child Session IDs; parent and child Agent snapshot digests; instruction digest and classification; narrowed environment and tool grants; budget reservation and deadline; placement requirements and capability evidence; tree revision, idempotency key and receipt.
Authority only narrows down the same-Project tree: a child gets at most the intersection of parent grant, child definition, Project policy and operator policy for executor, Connection, environment, network, profile, tools and budget. No intersection reaches a sibling Project. Admission is atomic against every recursive limit:
maxDepth
maxChildrenPerSession
maxSessionsPerProject
maxConcurrentActivationsPerProject
maxReservedTokens / cost / time
maxWakeupsPerMinute
maxMessageBytes / messagesPerMinute
- One parent and one root per child; cycles are rejected. Child start
validates parent, root, Project and
treeRevisionin one transaction. - Relation lifecycle:
active -> stop-requested | detached | terminal. On parent completion the definition chooseswait(until named children are terminal or a deadline),request-stop(cancellation asserted only after child terminal events) ordetach-to-project(exact transfer plan, revisions, replacement budget and receipt; refused for unresolved effects or cross-Project moves). - After a restart a reconciler finds orphaned relations without inventing a parent.
Durable messages
message: accepted -> expired
\-> rejected
delivery: available -> claimed -> processed
\-> available (visibility timeout + retry)
\-> dead-letter|expired
- A message records the Node-stamped sender, recipient, behavior
(
ask_question,assign_work,replyby default,report_progress), thread ID, optional reply-to ID, content digest and classification, idempotency key, wake disposition and recipient revision. Today'ssession.message.sendcarries recipient, subject, body and command ID; the other fields arrive with S17. - A delivery claim lasts 30 seconds with
(deliveryId, attempt)idempotency; at most five retries with exponential backoff capped at five minutes, then dead-letter. Content stays only until acknowledgement and a matching read from the recipient harness's reader, with D-168's exceptions for terminal deliveries and content no harness returns (D-168); the trace is kept 30 days unless Project policy shortens it. - Same-Project delivery is the default, whichever checkout runs each
Session. A Session may also message an exact Session ID in another Project
of its Workspace when both Projects' guards set
messageReach: workspace(D-166), within the same discovery and authorization boundaries. Today's source candidate reaches only the sender's checkout. Cross-Workspace delivery and discovery are denied; cross-owner work uses parent-mediated delegation. Unknown and inaccessible targets look the same in lookups, errors, counters and cursors. Any other exception to this denial needs a new decision, never an incidental tool grant. Revocation fences later reads, deliveries and exports but cannot erase delivered context. - Peer content is untrusted data at the recipient. It never changes tool grants, confirmation policy, Connection choice or authority. Size, rate, cost and wake limits apply before persistence. Held, archived or terminal recipients accept only exact operator recovery messages.
Swarm live control projections
Swarm decides from projections (queue, capacity, budget, Session, Routine, provider, placement, health) built from Node's post-commit authoritative records, never from a best-effort log stream. Processor partitions and checkpoints belong to operations.
Node committed events/outbox
-> SwarmObservationProcessor batch
-> projection rows + checkpoint in one transaction
-> low-latency in-process wake notification
-> normal Swarm decision
-> registered operation + event/receipt
- After a restart or lag Swarm catches up before claiming a current view. A
partition behind its freshness objective makes affected admission
blockedordegraded; Swarm never guesses from wall-clock time or a missing heartbeat. - One processor subscription covers all Projects, partitioned by a stable owner hash; an exact lease stops two consumers checkpointing one partition.
- Decisions are loop-safe: each records its input watermark and an idempotency key from kind, target, revision and trigger, so its own output event cannot trigger it again at the same revision.
- Diagnostic records never trigger placement, delegation, cancellation, budget or provider fallback.
- Coordinators never see this multi-Project view; each keeps its own discovery ceiling.
Routine model
A Routine is one trigger plus one or more steps, not a workflow language. One
step is an Agent, Skills and an instruction, as below; several steps chain with
after. "Workflow" is only a product word for a Routine with several steps,
never a runtime or CLI root. Steps, owners and event triggers are planned
(S49–S52).
{
"schemaVersion": "maia.routine.v1",
"id": "morning-triage",
"enabled": true,
"trigger": {
"kind": "cron",
"expression": "0 8 * * 1-5",
"timezone": "Europe/Paris",
"catchUp": "latest-only"
},
"target": {
"mode": "wake",
"agentRef": "project:self/coordinator"
},
"instruction": "Triage newly admitted work and delegate only actionable items.",
"requestedSkillRefs": ["project:self/issue-triage"],
"limits": {
"timeoutMs": 900000,
"maxPendingTicks": 1
}
}
scheduled -> admitted -> dispatching -> session-linked -> completed
-> skipped|coalesced|blocked|failed|cancelled
dispatching -> outcome-unknown -> reconciling -> session-linked|blocked|failed
wakeneeds a canonical home Session;startbinds the exact admitted Agent definition digest. Requested Skills are eligibility hints only.- A tick is unique on
(routineRef, routineRevision, scheduledAt), reuses its command identity on retry and uses the snapshot that planned it. A manual trigger creates a distincttriggerKind: "manual"tick. - Cron is the five-field POSIX form with a named IANA timezone (tzdb version
recorded). A nonexistent local time is skipped and recorded; a repeated one
yields one tick unless policy says
both. - Catch-up is
none,latest-only(default) or boundedall;maxPendingTicksdefaults to 1. Optional jitter is 0 to 300,000 ms, derived from the tick digest. - Disable stops planning but lets a running tick finish; cancel is separate. Retries default to zero, at most five, backoff capped at one hour.
Steps, owners and triggers (planned)
- Owner and definitions. A Routine belongs to one exact Project or, after
R3, Workspace. An Agent's Routines are those whose steps target it. There is
no global or
allowner. Agent and Routine definitions are Node-admitted snapshots: created through the CLI, API or web, or proposed by a Project's.maiaand admitted by digest like the Project inventory. Only a person confirms creating, revising, enabling or disabling an Agent, a Routine or an event source; agents and coordinators getrole_denied(S1, S18a). - Steps. A single-step Routine keeps the top-level
targetandinstruction. A multi-step Routine replaces them withsteps: a bounded, acyclic list (the protocol entry freezes the bound). Each step has a key, astarttarget for an exact Agent definition (until S49, S30's inline Session template, whose digest the tick snapshot freezes), requested Skills, optional harness, model and effort overrides checked against the Project's grants, an instruction, an optional goal (S69) andafter. Swarm records each run as one Run ledger and starts one Session per ready step; steps never wake a home Session, so they never coalesce. A person step (S50) targets an exact person, or a role after ORG1, instead of an Agent and starts no Session: it records a request in the attention inbox (R8), settlesdoneon that person's answer or review, settlesfailedat its expiry unless its escalation person answers first, and never takes an agent's answer. An answer only passes text to later steps; approving a consequential operation stays that operation's own preview and confirmation, bound to its exact target. The Node settles each agent step's task from its Session's terminal turn outcome; every Routine run, a single-step one included, is a run ledger entry (D-119). A step's retries follow the Routine retry rule, a per-step retry budget that replaces S19's three-dispatch stop for Routine runs (D-119); once they are spent, the step fails and starts none of its dependents. The run settles once, with evidence, after its last task settles. - No routing language. Steps have no conditions, loops, variables or data passing. A step's Agent decides through its Skills and may add follow-up ledger tasks to its run, within a per-run task cap that the protocol entry freezes and that counts every step and follow-up task.
- Triggers.
cron(above);manualfrom the CLI, API or web; andeventfrom an event source, matched on a declared event type and exact field filters. Node-event triggers wait for a causal-depth guard, so a run's own events never retrigger its Routine. An event tick is unique on(routineRef, routineRevision, sourceId, sourceEventId). Each distinct event gets its own tick, bounded by the source's rate cap and the Routine's pending-tick cap; overflow is recorded asblocked, never queued silently. Catch-up applies to cron only; an event that arrives during a hold is recorded asskipped. - Gates (D-174). A cron trigger may name a gate,
a command a person sets in the Routine's definition, and one exact admitted
Agent definition it runs as. After S47b the Node runs it in a sandbox at
that Agent's placement, with that Agent's grants and network policy, for at
most 60 seconds and 64 KiB of output. Exit 0 with no output records the
tick as
skippedwith reasongate_emptyand starts no Session; exit 0 with output runs the Routine, and the steps withoutafterread that output the way they read event data: size-bounded, masked and marked untrusted. Any other exit or a timeout recordsfailedwith a typed reason. A gated cron may fire every minute; empty ticks are counted per Routine and hour, not kept one by one. The gate decides only whether the trigger fires; steps still have no conditions. - Event data. The Node stores each accepted event by ID. A step reads it only through a run-scoped read that returns the source's schema-declared fields, size-bounded and marked untrusted. Event text is data: it never changes the Routine, its Agents, policy, approvals or credentials.
- Event sources. Third parties extend Maia by sending events, not by loading code. An event source is a Node record with an owner scope, declared event types with schemas, size and rate caps, and its own ingest-only credential: stored as a digest, shown once, rotated or revoked through preview and confirmation. Events enter through one ingest operation in the SDK and CLI, never a model tool. The Node checks the credential, schema and caps, deduplicates by source event ID within a retention window and records each event. A source grants no authority: only the Routine's confirmed Agents and policy run.
- Connectors. A connector is an out-of-process adapter, such as a GitHub
App. The provider calls a public URL on the connector, never the Node. The
connector verifies the signature (GitHub's HMAC), uses the provider's delivery
ID (GitHub's
X-GitHub-Delivery) as the source event ID, normalizes the event and calls ingest with the source credential. The dedupe window covers the provider's redelivery window. It runs beside the Node on the same host or reaches it over an authenticated tailnet hop (after D-056); the SSH bridge opens per invocation and suits only tests. Each connector is a new service and needs owner approval.
Session goals (planned)
S69 lets a Session, Routine step or task keep working until a check passes.
It extends the R11 AG1 session.goal.* contract in the
CLI reference with two optional fields, check and
budget, rather than defining a second contract; a goal loops only when it
carries both. Those operations are not registered today; Maia agent's
standalone /goal is local to that agent. A Session goal is a completion
condition: it never closes an S48 Project goal.
- Who changes a goal. A goal without a check stays an R11 AG1 self-goal,
which the model may manage as that contract allows. Once a person sets a
check or budget, only a person rewrites, updates, pauses, resumes or
abandons the goal or raises its budget, by preview and confirmation on a
Routine step or task; the model's
rewrite,update,doneandabandongetrole_denied, and it may only read the goal and propose a change. Only a passing check or a person recordsmet; only an evaluator or a person recordsimpossible. Standing approvals (S67) never change a goal, and event data never sets one. - Check. A command check is a person-set exact argv (stored as a digest)
and working directory. Only a recorded command item that matches it, from
the turn that just settled and after that turn's last file change, counts,
never model text; a command check works only where the adapter records
command items (Codex and Claude Code; Pi streams turn boundaries only). A
rubric check is an R10a evaluation over bounded observed items, masked as
S65 specifies, never judged by the model doing the work. A worker's
session.settle done(S29) on a goal-bearing Session is a claim, not the check. - Outcomes.
metsettles the Session asdoneandimpossibleasabandoned. At the budget the goal becomesbudget_limited: the Session settles asneeds_review(S29), a Routine step counts as failed, and no resume, auto-resume (S27) or move (S66) sends a continuation or sets a native goal. After a turn that failed, was interrupted or has an unknown outcome, the goal becomespausedwith a typed reason until a person resumes it. - Budget. Required: a Node hard turn cap, which a Workspace ceiling (E5)
can lower, plus at least one measured limit (tokens, wall time, or money
where the Connection reports usage) through
BudgetReservationV1'ssessionscope (S55). Rubric evaluation counts against it. - Loop. After a turn settles as completed and the check fails, the Node
sends one continuation: an idempotent, receipted
turn.sendthat names the goal and carries the verdict reason as bounded, untrusted data. A Node restart sends it once. No continuation is sent while a question or approval (S4b) is pending. This is stricter than D-023, which allows fallback after a verified pre-dispatch or no-output failure. A person's own turn, steer or interrupt pauses the goal and cancels a queued continuation (S26turn.cancel). A continuation is a new turn, not a fallback; the S69 decision entry records the Node as its sender. - Native goals. Claude Code's
/goalis a session-scoped Stop hook, unavailable when hooks are disabled; Maia's launch setssettingSources: []and registers only its PreToolUse guard, so whether/goalworks there is unproven. Codex exposesthread/goal/set,getandclearon the app-server; third-party sources report agoalsfeature flag and a model tool that marks a goal complete, which the official page does not show. Where a pinned version proves its native goal under Maia's launch, the adapter may set it to the same objective so the harness keeps working inside one turn with its own capabilities. Its verdict is advisory: Maia runs its own check before recordingmet, and interrupts the native loop at the budget within a bound the protocol entry freezes. The adapter clears the native goal whenever Maia's goal leavesactiveand before any resume, fallback (S60) or move (S66), which carry only Maia's record. Until that proof holds, the adapter does not set a native goal itself; worker launches leave native goals on, and a task's harness may use them (D-123). - Defaults. Goals are opt-in per step or task. Templates (S63) give steps a check and a budget, and a Workspace, Project, Agent or step policy (E5) can require or forbid goals. A step without a goal runs its turn once.
Admission, queueing, and capacity
Scheduling is bounded weighted round robin across active Projects. Inside a Project the order is operator-confirmed recovery, direct user or Maia message, due Routine tick, peer child start or wake, then evaluation or maintenance.
Priority never bypasses budgets or authority. Admission reserves worst-case
tokens, cost, concurrency slot, deadline and executor capacity in the same
transaction as queueing. Completion releases the exact reservation; an unknown
outcome keeps it until reconciliation. Overload returns a typed blocked
result naming the limiting resource, never silent queue growth. Fairness also
covers per-Connection caps, per-actor and per-Session wake-rate caps and
starvation boosting with a ceiling.
Deterministic scheduler algorithm
Each active Project has a weight 1..16, a persisted deficit, a last served
sequence and one FIFO queue per priority class. One dequeue transaction:
- drops entries of inactive Projects and releases their reservations;
- promotes an entry by at most one class after 60 seconds, never above recovery;
- visits Projects by ascending
(lastServedSequence, projectId), addingweightto each deficit (cap64); - takes the highest-priority head whose reservation still validates and whose
unit cost
1fits the deficit; - subtracts one, advances the served sequence, creates the assignment intent and marks the entry dispatched in one SQLite transaction;
- returns the entry once, with its original sequence, if assignment fails before an external call; blocks it with its reservation if the outcome is uncertain.
Deficits survive restart. A continuously eligible Project is served within (active Projects × per-Project quantum) turns unless its own budget is exhausted. Held, draining and archived Projects are never visited.
Budget reservation contract
interface BudgetReservationV1 {
readonly reservationId: string;
readonly projectId: string;
readonly sessionId: string;
readonly activationId: string;
readonly connectionId: string;
readonly scopes: ReadonlyArray<
"user" | "project" | "agent" | "session" | "connection"
>;
readonly maxInputTokens: number;
readonly maxOutputTokens: number;
readonly maxWallTimeMs: number;
readonly maxCostMicros: number;
readonly currency: "USD" | "EUR";
readonly priceCardDigest: `sha256:${string}`;
readonly concurrencySlots: number;
readonly createdAt: string;
readonly expiresAt: string;
readonly state:
"reserved" | "partially-settled" | "settled" | "released" | "unknown";
readonly revision: number;
}
A reservation checks every scope atomically. Usage is normalized to input, output, cached and reasoning tokens and cost micros against the immutable price card and settles monotonically. Missing final usage keeps the worst-case amount until reconciliation or a 24-hour operator-visible expiry; it is never silently refunded. A cost overrun blocks further activations; it never truncates a completed response.
Placement and multi-Node scale
Execution Nodes add worker capacity to the one Control Node through MN0–MN5
(roadmap).
The Control Node's SQLite store is the only durable writer and there is no HA
in v1 (operations). Execution Nodes
use the execution-only composition:
no Swarm store, no remote SQLite writes, no PlacementPlanner, no product
clients. They accept fenced assignments
(Node assignment and fencing)
and send bounded authenticated observations. Team invitations, voice and
multi-Control UI are not capacity prerequisites.
- Registration.
NodeRegistrationV1carries Node and device identity, certificate fingerprint, registration incarnation, OS and architecture, worker and protocol versions, a possibly empty inventory of prepared environments with exactworkspace_*identity evidence, execution-profile digests, CPU and memory capacity, load, heartbeat sequence and expiry. A Node with no prepared environment starts no worker. Execution Environments keep theirworkspace_*identity through the naming migration. - Heartbeats. Every 5 seconds; four misses stop placement; once the assignment lease expires the Control Node fences the epoch. Clock decisions use Control Node time.
- Assignment and handoff. An assignment binds activation, Node, worker or
executor, revision, lease epoch, capability evidence digest and expiry;
stale epochs are rejected. A handoff increments the assignment epoch before
another Node may write. Handoff is
planned -> draining -> fenced -> preparing -> assigned -> completed(failedandoutcome-unknownneed reconciliation); the destination starts only when environment provenance and capability evidence match the plan. - Environments and profiles. Placement needs an exact admitted working
directory or an explicit prepare operation; files are never assumed
replicated, and preparation grants the worker no writes. The first remote
profile is
managed-read-only; remote coding, builds and tests wait for a named per-OS containment adapter, and the unsandboxed operator profile is never eligible. - Partial outage. Projections turn stale with
observedAt, placement stops, ownership holds until lease reconciliation, and a missing heartbeat never reports work as completed or cancelled. Cross-Node views keep each source(streamOwnerId, eventSequence); there is no global event order.
Staged targets become release gates once the benchmark machine, model fakes, workload mix and baseline are committed:
| Stage | Active Sessions | Concurrent activations | Projects | Observation burst/s | Live subscribers | Gate |
|---|---|---|---|---|---|---|
| local | 100 | 25 | 10 | 5,000 | 32 | no duplicate effect under restart |
| node | 250 | 75 | 50 | 20,000 | 128 | bounded p95 queue/event/fan-out latency |
| swarm | 500 | 150 | 100 | 50,000 | 512 | recovery, fairness, replay, and processor SLOs pass |
Bursts last 60 seconds of mixed records and prove that viewers do not raise worker emissions, slow consumers are isolated, checkpoints catch up and no message or effect is lost. Load above 70% of the qualified envelope for 15 minutes signals moving optional projection processors out of process, never dropping evidence.
External executor Sessions
The v1 vendor executors (Codex CLI, Claude Code) are specified in external executors. Every external executor, including any later hosted one such as Cursor Cloud (not on the roadmap), follows these rules:
- Swarm decides admission; Node persists the normalized Session; the adapter owns vendor calls and reconciliation evidence. Guarantees are checked against fresh capability evidence before dispatch.
- Starting one is a consequential third-party effect bound to an exact repository and ref, environment, model, network and MCP policy, secret references, data and artifact policy and deadline. Remote states (busy, rate-limited, stale, outcome-unknown) stay explicit, and Maia never claims its own tools, sandbox or confirmations run inside the vendor.
- Request IDs, idempotency keys, cursors, rate-limit state and normalized
events are persisted before projection; callbacks authenticate and reject
replay. One fenced reconciler polls with
Retry-After, backs off from one second to five minutes and opens a circuit after five transport failures. Uncertainty never causes a duplicate create or send.
Voice cockpit orchestration
Text is the default input; voice is optional input and output for the exact attached Session, never a harness mode or extra authority (decision). A coordinator reasons and delegates only when addressed; direct worker or ordinary Session talk never passes through one. Clients own presentation, Providers own realtime transport and the confirmation ceremony, and R7 with PF-18/DF-18 requires text and voice parity.
text composer ------------------------> canonical Session/control operations
voice input -> realtime/tool boundary -> same exact target and command identity
|
explicit coordinator OR worker/ordinary Session
- A selected visual node is a hint until an exact input is resolved; global routing never widens a direct Session request.
- The voice model gets only
ask,status,previewandconfirm.confirmasks the authenticated client to show a confirmation; only the client callsconfirmation.consume. The one-time confirmation binds actor, device, voice Session, turn, operation and input digest, targets, revisions and expiry, and is voided by reconnect, transcript correction, drift or identity doubt. - Context is the current utterance plus a redacted rolling summary for the target, never unbounded traces or credentials.
- Without voice, text and CLI controls remain; an unavailable coordinator blocks only requests to it.
A2A boundary
A2A v1 is the external boundary for discovery, messages, tasks, artifacts and
updates; MCP stays a tool and context protocol
(decision). Node authenticates and normalizes
ingress (a2a_peers, a2a_tasks in the
Node data model); Swarm
admits each request to one exact Project. Each accepted task maps to one
internal A2A task record and one Agent Session activation, keeping external
and internal task, Session and activation identities. Peers never receive
worker leases, Connection secrets or mutation authority. A2A ingress follows
S17 on the path to an
organization's agent hub.
A2A v1 implementation profile
- Supported: the published A2A v1 HTTP profile (Agent Card discovery, task create, get and cancel, message parts, artifact references, task updates). The exact version lives in the protocol capability manifest and fixtures; unsupported extensions fail explicitly.
- Peer enrollment records the normalized Agent Card URL and digest, TLS identity, key fingerprint, allowed Project, capabilities, callback origins, content, size and rate limits, expiry and revision. Discovery is HTTPS only, resolves DNS before and after connect, rejects private, link-local and loopback addresses and cross-origin redirects, caps responses at 256 KiB and never treats card content as instructions.
- Each inbound request authenticates the peer, checks nonce and a five-minute
TTL, deduplicates
(peerId, externalTaskId, requestDigest), maps the grant to one actor and Project, and stores raw identity apart from normalized content. Retries return the samea2aTaskId.
| A2A state | Maia projection |
|---|---|
| submitted | admitted or blocked before activation |
| working | queued/starting/running activation |
| input-required | waiting interaction |
| completed | terminal succeeded plus exported artifacts |
| failed | terminal failed with redacted typed diagnostic |
| canceled | cancellation observed, not merely requested |
- Updates and callbacks use durable cursors, acknowledgements, five retries and dead-letter. Cancellation is a receipted Session operation.
- Artifact imports never fetch a peer URL without SSRF and digest checks.
- A disconnected peer does not mean task failure; reconciliation stays operator-visible.
Acceptance gates
- Concurrent starts never duplicate home Sessions or child relations; limits and budget reservations are atomic and survive restart.
- Session discovery and messaging stay within the Project by default; a
sibling Project becomes reachable only when both guards set
messageReach: workspace(D-166), which grants no access to its history, memory or credentials. A Workspace cannot discover or message sibling Workspaces until a later approved tier; human grants never widen coordinator identity. - Owner-scoped history, memory, tools, evaluation caches and resources pass the DF-22 denial matrix; a shared kernel or separate processes alone prove nothing.
- Routine ticks are unique across retries, DST and restart; fairness holds under one noisy Project.
- Scheduling uses only post-commit observations, catches up from checkpoints and never repeats a decision from its own output.
- Stale Node or worker epochs cannot append events or receipts, and external uncertainty never duplicates a create or send.
- Parent-mediated delivery and held-Session recovery require exact separate admission, disclosure rights and current revisions.
- Hostile peer or A2A content cannot change grants, confirmation policy, Connection choice or authority; peer delegation passes prompt-injection, cycle and quota tests.
- Speech cannot consume a confirmation; replay and correction fail closed.
- No Swarm operation bypasses the registry, authorization, CAS, idempotency, events or receipts, and load tests meet the committed staged thresholds.
Imported from Maia OS docs at 3dc3e07