SolOS v2 — Scope Specification
SolOS v2 — Scope Specification
Status: draft for Young / Sol / Min / Mira review. Every normative line below is tagged with its source. Where a source could not be found or a claim could not be sourced, that is stated rather than papered over.
How to read this document
- §1 Scope — the seven capability bullets Young defined, restated as testable goals.
- §2–§5 — the four research lanes: Cortex memory, multi-agent architecture, protocol/interop, self-heal/eval. Each ends in imperative SPEC REQUIREMENTS.
- §6 — the merged requirement ledger.
- §7 — open questions and honest gaps.
§1 Scope (Young's seven bullets, restated as goals)
- Multi-agent fleet with autonomous task completion.
- Cortex — skills, tools, personas, tasks, memory (long-term + short-term) as one trust-of-record.
- Autonomy loop — complete → report → self-heal → self-learn → self-evolve.
- Agents that build, test and debug features end-to-end across multiple files and in parallel.
- Graph-based workflows — deterministic routing and execution control.
- Dynamic workflows — code-based loops and decision branching.
- Collaborative workflows — coordinator agents with multiple subagents.
Cross-cutting doctrine (Young): 4 core principles (Think Before Coding · Simplicity First · Surgical Changes · Goal-Driven) and 5 anti-sloppy layers (anti-hallucinate · anti-fake-verify · anti-out-of-scope · anti-loop · anti-destructive). See §2.1/§2.2 — these are Young's doctrine, not found in any source; the mechanisms attached to them are sourced.
§2 Lane A — Cortex: memory, principles, anti-sloppy layers
(a) The 4 core principles as enforced systems
A slogan is a prompt instruction; an enforced system is a code path that fails closed. Each principle below is stated as: the slogan → what actually enforces it → the refusal condition.
1. Think Before Coding
Enforcing system: a mandatory pre-execution phase with a machine-checked artifact, plus a write-gate.
- The agent must materialise a plan before any mutating tool call. S3 makes this structural: plan and execute modes are enabled by default, and todo tracking is on by default — the harness ships with a plan representation, not with a suggestion to use one.
- The Cortex must expose plan state as first-class memory:
goalis a definedmemory_typein S1b (and it may decay, unlike DNA), so an abandoned plan ages out on its own. - S2 gives the cache-stability constraint that makes this cheap: the system prompt must not change mid-conversation except on explicit user action. Pre-execution planning therefore has to happen in the stable tier or via the todo provider, not by rewriting the system prompt.
- Refusal condition:
patch,write_file,terminaland subagent-dispatch tools MUST reject a call whose session has no non-empty todo list with at least onein_progressitem, unless the call carries an explicitskip_plan=trueoverride that is logged to the trajectory.
2. Simplicity First
Enforcing system: a capability ceiling and a cost-metered default, both enforced by the harness, not by taste.
- S3 is explicit that shared/heavier capabilities are opt-in: session file memory is on by default but shared file access is opt-in; skills are opt-in in Python via provider or paths; background agents, file access and looping are all opt-in.
- S2's loose-coupling principle: optional subsystems use registry patterns and
check_fngating, not hard dependencies. - S3's default approval posture — standing approvals and auto-approval rules are on by default — means the cost of doing something is already low; therefore the ceiling must be the enforced thing.
- Refusal condition: the Cortex MUST ship a default capability set that is the smallest set that completes a task, and MUST require an explicit enabling action (opt-in token, config flag, or granted capability) to widen it. A capability that is neither default-on nor explicitly granted MUST NOT be reachable — "available" and "granted" MUST be different states in the registry.
3. Surgical Changes
Enforcing system: optimistic-concurrency edits, scope tokens, and a blast-radius budget on the diff.
- S3 is the concrete precedent:
file_access_replace_linestakesexpected_line, and the expected text prevents a stale or mismatched line number from editing the wrong line. Line numbers alone are not identity. - S2's
patch(path, old_string, new_string)model is the same idea in one file: the edit is bound to the text it expects to replace. - S3's scoped access is fail-closed: scoped access fails closed instead of using the shared store root when neither a session ID nor an explicit scope exists.
- Refusal condition: every mutating file operation MUST carry (a) the exact expected prior content for the region, and (b) a scope token naming the workspace/session/tenant. A missing or stale expectation MUST abort the write rather than retry against a fresh read.
4. Goal-Driven
Enforcing system: a bounded loop with a completion predicate, and progress that is persisted rather than narrated.
- S3b: looping is optional bounded re-invocation driven by evaluators or predicates, with
loop_max_iterationsdefaulting to 10 and evaluators includingTodoCompletionLoopEvaluator,CompletionMarkerLoopEvaluator,BackgroundTaskCompletionLoopEvaluatorandAIJudgeLoopEvaluator. - The judge's
Criteriaare written as checkable sentences — "Answer every part of the request", "Support conclusions with evidence" — i.e. goal satisfaction is evaluated, not assumed. - S2 makes execution observable: every tool call is visible to the user via callbacks, with progress in both CLI and gateway.
- S1b gives the loop a memory trail:
reasoning_store/reasoning_recall(S1) pluschunk_deltas (provenance chain)listed as a v2 possibility (S1b §7). - Refusal condition: no agent may report completion without an evaluator having observed the goal satisfied, and the evaluator's verdict MUST be written to memory before the report is emitted.
(b) The 5 anti-sloppy layers
Each layer needs a mechanism, a place it runs, and a failure signal. A prompt instruction is not a layer.
Layer 1 — anti-hallucinate
Failure it kills: asserting facts, paths, tool results or memory contents that were never retrieved.
- Mechanism: provenance-stamped reads. Every fact entering the model's context is a chunk with
id,content_hash,sourceandcreated_at(S1b §3.2), andtrust_chunkreturns per-chunk provenance — source agent plus reputation (S1). Retrieved-then-stated is mechanically separable from asserted-from-nowhere. - Enforcement point: the Cortex recall API. Recall returns chunks with ids, and the harness prompt carries an instruction (S3's
harness_instructionsslot) that every externally-asserted claim be traceable to a returned id. - Failure signal: an outward claim with no backing chunk id is a defect.
trust_agentsscoring (Wilson lower bound, S1) is the fleet-facing version — the corpus itself carries an honesty signal. - Guard: S1b §6 requires consumers to treat bundle content as untrusted input and sanitize chunks for prompt injection before downstream LLM use. Retrieval is an injection surface, not just a truth surface.
Layer 2 — anti-fake-verify
Failure it kills: reporting "done / tests pass / file written" without evidence produced in this run.
- Mechanism: claims are only emittable through a verify gate that consumes a real tool result. S2's principle of observable execution (every tool call visible via callbacks) plus S3's loop evaluators (
TodoCompletionLoopEvaluatorfor "are all todos closed",AIJudgeLoopEvaluatorwith evidence criteria) together give the shape: the verifier is a separate principal, not the agent's self-report. - Enforcement point: the report/complete tool. A completion report MUST carry structured evidence — the
learntool's shape (action + result + lesson, S1) is the minimal viable evidence record. - Failure signal: a report whose evidence field references a tool result absent from the trajectory is rejected at emit time. This is the layer where "fake verify" dies: the claim must be reconstructable from the transcript, not from the narrative.
- Caution carried from S1:
already_compressedresponses and "scores capped at 1.0" are exactly the shape of plausible-but-lossy API returns; a verifier that trusts a success-shaped response without inspecting it is re-creating the bug it exists to catch.
Layer 3 — anti-out-of-scope
Failure it kills: touching files, tasks or memory outside the assigned scope; widening the task without authorisation.
- Mechanism: capability grant + scope token, fail-closed. S3: scoped file access fails closed when neither a session ID nor an explicit scope is available;
scopeis an opaque key mapping to a provider-managed folder, not a path — so the agent cannot compute its way out of the sandbox by path manipulation. - Enforcement point: every tool's
check_fngating in the registry (S2). A tool that cannot prove the caller holds the grant MUST NOT run. - Failure signal: a write outside the granted scope is refused with the missing grant named. For memory specifically: S1b §8 forbids a consumer from rewriting the source tenant's
tenant_id— identity boundaries are enforced at the data layer, not just the prompt. - Loop tie-in: S3c — a background task's in-flight work and child-session handles do not survive a process restart; scope must be re-established, not assumed.
Layer 4 — anti-loop
Failure it kills: unbounded re-invocation, the same failing tool call repeated, a stall that reads as progress.
- Mechanism: hard iteration ceiling + completion predicate. S3b's guidance is unambiguous: "Always bound autonomous loops. A completion condition can fail, a model can stall, and an evaluator can be probabilistic."
MaxIterationsdefaults to 10;AgentLoopMiddlewaredefaults to 10 runs; judge loops default to 5. - Correlated-failure defense: S3b adds the loop-progress log and
fresh_context=True, which restarts from the original task plus an aggregated feedback log and restores the session to its pre-loop snapshot. That is the anti-repeat mechanism: the next attempt sees what was already tried, not just what was last said. - Enforcement point: the loop decorator, as the outermost layer. S3b states loop and approval ordering explicitly — pending approval requests must escape the loop rather than be hidden behind another autonomous iteration.
- Failure signal: hitting
MaxIterationswithout a satisfied predicate is a first-class terminal state, reported as loop-exhausted, not silently returned as a result. S1 gives the same shape for context pressure:compact_nowis an explicit verdict, not a guess.
Layer 5 — anti-destructive
Failure it kills: irreversible or over-broad mutations — deletes, force pushes, restarts, wide rewrites, config overwrites.
- Mechanism: approval gating + backup-before-write. S2 ships
tools/approval.py(dangerous command detection) and S3 enables standing approvals and auto-approval rules by default, withDisableToolAutoApprovalas the opt-out lever. S1's installer takes the same shape operationally: it writes "Backup originals before any writes" and backs up config before modifying it. - Enforcement point: the approval middleware, sitting inside the loop (S3b ordering), so a destructive call surfaces for a human instead of being retried autonomously.
- Irreversibility classification: S3b notes
LoopAgentdoes not add approval handling itself and that approval is a separate concern — destructive operations must be enumerated independently of loop control, or a loop will simply retry past a refusal it doesn't understand. - Recovery requirement: S1 ships
snapshot_create/snapshot_restoreas first-class tools. Untested restore is not recovery — the Cortex MUST have a restore path exercised in tests, not merely available. - Session-memory note: "already_compressed" (S1) is idempotent by design and safe to retry — the pattern to copy: destructive-by-default operations get idempotency keys so a retry after a network error cannot double-apply.
(c) Long-term + short-term memory architecture: what it must contain
c.1 Tiers
Two orthogonal tierings appear in the sources, and a Cortex needs both — they answer different questions.
Tier by lifecycle (how long it lives) — from S1b §3.2 + §3.7:
| Tier | Field | Semantics |
|---|---|---|
| Short-term / session | session memory | Conversation chunks for the current session; full fidelity 100% recall; expires with the plan window (S1: 2 days free → 60 days team), then compacted to a permanent summary |
| Long-term / archive | archive | Detailed permanent summary; 90%+ recall after session expiry |
| DNA | memory_type ∈ {preference, decision, identity, pitfall, procedure} | MUST NOT decay or auto-delete; core facts forever |
| Consolidated | post-sleep insights | LLM-summarised insights produced overnight, loaded at next bootstrap |
Tier by storage temperature (S1b §3.2): tier ∈ {hot, warm, cold} with zone ∈ {standard, important, critical, ephemeral}, importance, is_pinned, decay_score, created_at, accessed_at, valid_until.
A chunk counts as DNA if any of: DNA memory_type, zone ∈ {critical, important}, or is_pinned = true — explicitly sufficient conditions.
Association graph: memories are not a flat list. S1's "How It Works" describes emotional tagging, a neural graph linking related memories by association learning, and co-recalled memories getting stronger. S1b §3.3 encodes this as a Hebbian EdgeRecord with weight and co_activation_count. So retrieval quality comes partly from graph strength, and co-recall is itself a reinforcement signal.
Entity layer: EntityRecord with frequency, first_seen, last_seen, is_dna (S1b §3.4) — a tracked-entity index, surfaced by the entity_list tool (S1).
c.2 Retrieval
- Layered merge, not one bucket. S1: "Smart layered recall — DNA, session memory, regular facts, and archive are merged with priority weighting (all final scores capped at 1.0). Recent sessions get an automatic freshness boost." S1b corroborates the required behaviour: when all scores read 1.0, use the
layerfield to distinguish — score alone is not a usable signal once capped. - Three search modes in one query: S1
memory_recall= "semantic + graph + FTS". S2 independently ships SQLite + FTS5 full-text search over sessions — the same hybrid rationale, so a Cortex needs vector and lexical and graph paths behind one call. - Depth as a budget knob: S1's
depth: "deep"and bootstrap modes sized in tokens (default~5.5K tokens of DNA + summaries;deep~25K tokens adding the top relevant chunk in full) turn retrieval into a context-budget decision. The retrieval layer must therefore report token cost, not just items. - Resilience: S1's IDE path has a buffer fallback — the server accumulates every recall query into a session buffer, so if the agent sends a useless compact summary the server substitutes the buffer. Retrieval history is itself a safety net for memory.
- Degradation must be non-fatal: S1 rule file, verbatim — "If MemoryAI is down, continue working normally (non-fatal)." A Cortex outage MUST NOT block task execution.
c.3 Write policy
- Type-driven: every write declares
memory_type(S1b §3.7, required field) pluszone,importance,tier. - What NOT to store (S1 rule file, verbatim):
"ok", "thanks", "got it"(trivial); temporary debug output; "things already in code or git." That last exclusion is the Cortex's own anti-duplication rule — memory is for what code and git cannot hold. - Triggered, not optional: S1's 3 lifecycle hooks —
SessionStart→ bootstrap context,UserPromptSubmit→ recall relevant memories before each prompt,Stop→ save important info after each turn. The doc's own point: "MCP-only means the agent must decide when to call memory tools. The CLI hooks approach is fully automatic." Write policy belongs in the runtime lifecycle, not in the model's judgement. - Write-as-verification:
learnstores action + result + lesson (S1) — every meaningful action is a memory candidate whether or not the turn concluded anything. - Dedup: S1b §3.8 — skip chunks whose
content_hashalready exists; UPSERT edges on(source, target, edge_type)accumulatingco_activation_count, MAX ofweight, refreshedupdated_at; UPSERT entities accumulatingfrequency, latestlast_seen, ORis_dna. Import is idempotent — this is the contract that makes fleet-wide shared memory safe under concurrent writers.
c.4 Consolidation
- Sleep consolidation: S1, running 24/7 with no user action — LLM summarises insights overnight; association strengthening (co-recalled memories get stronger); natural fade of unused memories; emotion decay; community detection for topic clusters. "Next session may have new insights."
- Session handoff / compress: at ~70% context the guard returns
should_spawn_new_sessionwith aspawn_reason; the new session warms to 20K+ before the old one is compressed via/v1/bot/session/compress; the response reportschunks_created,dna_extracted,summaries. Compression is idempotent persession_id— repeat returnsalready_compressed. S1'smemory_compactis the IDE-side equivalent. - Frequency promotion: "Frequently recalled chunks are automatically promoted to permanent memory as a summary." Retrieval activity drives tier promotion — access frequency is the promotion signal.
- Context compression as its own subsystem: S2 isolates
context_compressor.py(lossy middle-turn summarisation) andprompt_caching.py(Anthropic cache breakpoints), withContextEngineas a pluggable ABC. So: the context engine is an interface with a default implementation, not a hard-coded step — a Cortex must expose the same seam. - Adversarial consolidation guard: a judge or judge-equivalent should validate consolidated summaries before they become DNA; otherwise a bad summary launders into permanent memory. Nothing in the sources does this explicitly — flagging it as a gap the spec should close.
c.5 Forgetting
- Natural fade by disuse. S1: "Unused memories slowly fade (natural fade)"; §7 lists it in the background loop.
decay_scoreandaccessed_at(S1b §3.2) are the mechanical substrate. - Absolute protection for DNA. S1 rule file: "Preferences and decisions are DNA-protected — they NEVER expire." S1
(d) SPEC REQUIREMENTS — SolOS v2 memory + Cortex
Imperative, testable, each tagged. These are the merge-ready lines.
- The system MUST persist short-term (session) memory with full fidelity for the active session and MUST guarantee 100% recall of that session's own content while it is live. from S1 — retention table: "Day 1 … 100%"; "Day 3 … 100%"
- The system MUST classify every memory chunk with a required
memory_typedrawn from{fact, episodic, goal, error, preference, decision, identity, pitfall, procedure, life_event}, and MUST carrycontent_hash,created_at,accessed_at,zone,importance,tier ∈ {hot, warm, cold}, anddecay_score. from S1b §3.2, §3.7 - The system MUST NOT auto-decay or auto-delete any chunk whose
memory_type∈{preference, decision, identity, pitfall, procedure}, or whosezone ∈ {critical, important}, or whoseis_pinned = true. from S1b §3.7 — "Any of these conditions are sufficient"; S1 — "NEVER expire" - The system MUST implement forgetting as natural decay driven by
accessed_at/decay_score, MUST retire unused memories automatically, and MUST guarantee that a decayed session's knowledge remains recoverable as a permanent summary rather than vanishing. from S1 — "Unused memories slowly fade"; retention table "After plan expiry … 90%+"; S1btier/decay_score - The system MUST run memory recall and memory capture in the runtime lifecycle — at session start, before every user prompt, and after every turn — so that no memory operation depends on the agent choosing to make one. from S1 —
SessionStart/UserPromptSubmit/Stophooks; "MCP-only means the agent must decide… The CLI hooks approach is fully automatic" - The system MUST NOT store trivial acknowledgements, temporary debug output, or any fact already recorded in code or version control. from S1 — rule file, "Do NOT store"
- The system MUST implement retrieval as a single call that merges short-term, long-term/archive and DNA layers with priority weighting and a freshness boost on recent sessions, MUST search semantically, by graph association and by full-text simultaneously, and MUST expose the matched layer on every returned chunk so that score saturation does not erase provenance. from S1 — "semantic + graph + FTS", layered merge with priority weighting, "use the
layerfield to distinguish"; S2 — SQLite + FTS5 - The system MUST bound retrieval cost as a context budget — returning token cost alongside item count and supporting at least a default and a deep retrieval mode — so the caller can size recall against the remaining window. from S1 —
depth: "deep"; bootstrapdefault~5.5K tokens vsdeep~25K tokens - The system MUST enforce context pressure as an explicit three-state guard (safe / compact_soon / compact_now) driven by configurable thresholds that apply identically across every model regardless of its context window, and MUST treat reaching the ceiling as a deterministic trigger to compact rather than to continue. from S1 — context guard state table, "same threshold applies to every model",
HM_COMPACT_AT/HM_CRITICAL_AT - The system MUST make every compression and consolidation operation idempotent on a stable key (e.g.
session_id), so that a retry after a network error cannot double-apply a memory write. from S1 — "eachsession_idcan only be compressed once (idempotent)";already_compressed - The system MUST promote memories to permanent storage on access frequency, MUST strengthen associations between co-recalled memories (Hebbian
weight/co_activation_count), and MUST run a background consolidation pass that summarises insights between sessions. from S1 — frequency promotion, "co-recalled memories get stronger", sleep consolidation; S1b §3.3 - The system MUST attach provenance to every recalled chunk — source, source agent, and content hash — and MUST treat recalled content as untrusted input, sanitising it for prompt injection before it reaches the model. from S1b §3.2, §6; S1 —
trust_chunk, "source agent + reputation" - The system MUST make shared memory writes idempotent and merge-safe under concurrent fleet writers: skip chunks whose
content_hashalready exists, and UPSERT edges on(source, target, edge_type)accumulatingco_activation_count, edges on maxweight, and entities on accumulatedfrequency/ latestlast_seen/ OR'dis_dna. from S1b §3.8 - The system MUST enforce DNA-protection, idempotency and prompt-injection sanitisation on the consumer side of any import, regardless of whether the source is a trusted sibling agent or an external bundle. from S1b §5 Level 2 Consumer conformance; §6
- The system MUST export and import the full memory store as a self-describing bundle carrying a manifest, an embedding model/dimension pair, a SHA-256 checksum, and a conformance level, and MUST NOT include credentials, audit logs, or user-marked-deleted records in that bundle. from S1b §3.1, §3.5, §3.6, §6,
brain_export/brain_importtools S1 - The system MUST survive memory-layer unavailability without blocking task execution — memory read/write failure MUST be non-fatal and MUST degrade to operating without memory. from S1 — rule file, "If MemoryAI is down, continue working normally (non-fatal)"
- The system MUST bound every autonomous loop with a hard iteration limit (default 10) and a completion predicate, MUST surface loop-exhaustion as an explicit terminal state rather than a returned result, and MUST carry a progress log into each subsequent attempt so a repeated failure cannot repeat unseen. from S3b —
MaxIterationsdefault 10, "Always bound autonomous loops",progress/fresh_context - The system MUST refuse to let an agent report completion unless a completion evaluator — todo-completion, completion-marker, background-task, or an AI judge with explicit written criteria — has observed the goal satisfied, and MUST persist that verdict before the report is emitted. from S3b evaluator table; S3 — plan/execute modes and todo tracking on by default; S1
learnevidence record - The system MUST require every mutating file operation to name the content it expects to replace, and MUST abort on a stale or mismatched expectation rather than retrying against a fresh read. [from S3 —
expected_lineonfile_access_replace_lines; S2 — `patch(old_string
Open gaps found in the sources (flag for Young)
These are things the sources do not solve, which SolOS v2 must decide itself:
- No consolidated-summary validation. S1's sleep consolidation promotes LLM summaries toward permanence with no judge/verification step. A bad summary can launder into DNA. Recommend routing consolidation output through the anti-fake-verify gate before promotion.
- No cross-agent write-conflict model. S1b's idempotency rules cover identical chunks and graph edges, but not genuinely conflicting claims (two agents storing opposite decisions). A conflict-resolution or last-writer-plus-provenance rule is undefined.
- Background agents are experimental and have no cancellation tool (S3c) — "let running tasks reach a terminal state". SolOS v2's self-heal story will collide with this: a task to be aborted has no clean kill path.
- Layered recall scores saturate at 1.0 (S1), which destroys ranking quality across layers. S1's own workaround is to read the
layerfield; a proper fix (per-layer normalisation) is unspecified. - Anti-sloppy layers 1–5 are not in any of the three sources. They are enforced here against borrowed mechanisms; none is natively an anti-sloppiness control. The mapping in section (b) is my engineering judgement, not sourced doctrine.
Sources
- MemoryAI Setup Guide — https://memoryai.dev/docs.html
- MemoryAI Protocol v1 (RFC 2119 spec, CC BY 4.0) — https://memoryai.dev/v1/spec
- Hermes Agent Architecture — https://hermes-agent.nousresearch.com/docs/developer-guide/architecture
- Agent Harness (Python pivot) — https://learn.microsoft.com/en-us/agent-framework/concepts/harness?pivots=programming-language-python
- Agent looping — https://learn.microsoft.com/en-us/agent-framework/agents/looping
- Background agents — https://learn.microsoft.com/en-us/agent-framework/agents/background-agents
learn.microsoft.com/.../concepts/tool-approval and .../concepts/compaction returned 404 on 2026-09-30; the approval and compaction claims above are taken from the Harness page, the looping page and the MemoryAI guide instead.
§3 Lane B — Multi-agent architecture patterns
(a) Named patterns, who advocates what, and the failure mode each avoids
Pattern → source matrix
| Pattern | S1 OpenAI | S2 LangChain | S3 Deep Agents | S4 Microsoft | S5 Meta | S6 xAI | S7 Anthropic | S8 LangGraph |
|---|---|---|---|---|---|---|---|---|
| Orchestrator-worker / supervisor | ● primary | ● "Subagents" | ● | ● hierarchical | ○ implicit | ● chief-of-staff | ● | ● |
| Parallel fan-out / fan-in | ● | ● (Subagents, Router) | ● "spawn subagents in parallel" | ○ | ● Contemplating mode | ● parallel Bots | ● | ● |
| Router / classifier dispatch | ○ implicit | ● "Router" | ○ | ● classifier component | — | ○ | ● | ● |
| Evaluator-optimizer | — | — | ○ evals only | ○ (evaluation/governance at system level, not per-task loop) | — | ○ "know when to ping" | ● | ● |
| Hierarchical / supervisor→group | — | — | — | ● explicit best practice | — | ● chief-of-staff over specialists | — | — |
| Debate / vote / multi-sample | — | — | — | — | ● (parallel agents, no vote) | — | ○ (parallelization "run task multiple times to check outputs") | ● ("run multiple times… increases confidence") |
| Blackboard / shared mutable state | ● shared filesystem | ○ context accumulation | ● virtual filesystem | ● conversation history + agent state stores | ● memory (Sentinel separation) | ● threads + shared context | — | ● shared state key |
| Skills / progressive disclosure | — | ● | ● | — | — | ● routines (demonstration→reusable) | — | — |
● = named and operationally specified · ○ = present but not named as a pattern · — = absent
Pattern-by-pattern: what each source actually says, and the failure mode it prevents
1. Orchestrator-worker (a.k.a. supervisor, subagents-as-tools)
- S7 — "a central LLM dynamically breaks down tasks, delegates them to worker LLMs, and synthesizes their results… subtasks aren't pre-defined, but determined by the orchestrator based on the specific input." Use when you cannot predict the subtasks. Cited example: coding, where "the number of files that need to be changed and the nature of the change in each file likely depend on the task."
- S1 — "an agent delegate tasks to subagents. Each subagent has its own context and can work in parallel with the others. The main agent coordinates their work and combines their results." The harness supplies
create,send message,wait for, andinterruptsubagent tools; developers do not declare them.max_concurrent_subagentsdefaults to 6, excluding the coordinator. - S2 — "a supervisor agent coordinates specialized subagents by calling them as tools. The main agent maintains conversation context while subagents remain stateless." Key tradeoff, measured: "Adds one extra model call per interaction because results must flow back through the main agent."
- S10 — supervisor vs router distinction: "The supervisor is a full agent that maintains conversation context and dynamically decides which subagents to call across multiple turns."
- Failure mode avoided: a single stretched agent. S4 enumerates why that dies — "Over generalization… leads to brittle prompts, generic responses, and degraded model performance across the board"; "Performance bottlenecks: When everything runs through one agent, the system slows down"; and crucially "Change management complexity: Because all logic, tools, and memory are coupled in one agent, adding a new feature or domain use case requires regression testing the full stack." For SolOS: one coordinator prompt cannot hold every lane's prompt, tools, and memory without becoming the regression surface for all of them.
- SolOS placement: this is Young's "coordinator agents + subagents" verbatim. Make the coordinator the only holder of conversation state; subagents stateless.
2. Parallel fan-out / fan-in
- S7 — two variants: independent subtasks run simultaneously (for speed, and because "for complex tasks with multiple considerations, LLMs generally perform better when each consideration is handled by a separate LLM call, allowing focused attention on each specific aspect"), or the same task run multiple times to check for different outputs (for confidence).
- S1 — parallelism is the harness default once
multi_agent.enabledis true; concurrency is a session-creation parameter. - S5 — "Contemplating mode, which orchestrates multiple agents that reason in parallel." Rationale is explicitly latency economics: "To spend more test-time reasoning without drastically increasing latency, we can scale the number of parallel agents that collaborate to solve hard problems… scaling Muse Spark with multi-agent thinking enables superior performance with comparable latency." Result: 58% on Humanity's Last Exam, 38% on FrontierScience Research.
- S8 — LangGraph mechanism: "The Send API lets you dynamically create worker nodes and send them specific inputs. Each worker has its own state, and all worker outputs are written to a shared state key that is accessible to the orchestrator graph."
- Failure mode avoided: context bloat and serial latency. S2 measured it: in a three-domain comparison with ~2000 tokens of docs per do
(b) Decision criteria: deterministic graph vs dynamic code-based workflow vs collaborative subagents
The core distinction is definitional, and S7 states it in one line each:
"Workflows are systems where LLMs and tools are orchestrated through predefined code paths. Agents, on the other hand, are systems where LLMs dynamically direct their own processes and tool usage, maintaining control over how they accomplish tasks."
S8 restates it: "Workflows have predetermined code paths and are designed to operate in a certain order. Agents are dynamic and define their own processes and tool usage."
Both vendors converge on the same governance rule — start as simple as possible, earn complexity:
- S7: "we recommend finding the simplest solution possible, and only increasing complexity when needed. This might mean not building agentic systems at all. Agentic systems often trade latency and cost for better task performance, and you should consider when this tradeoff makes sense."
- S2: "Start with a single agent and good prompt engineering. Add tools before adding agents. Graduate to multi-agent patterns only when you hit clear limits."
- S3 splits by predictability: "Use Deep Agents when you want to build an autonomous agent to handle complex, non-deterministic, and long running tasks. Choose LangGraph when you want low-level control for building stateful, long-running workflows and agents."
The decision table (criteria, not vibes)
| Criterion | → Graph-based deterministic workflow | → Dynamic code-based workflow (agent) | → Collaborative subagents |
|---|---|---|---|
| Can you enumerate the steps in advance? | Yes, cleanly and completely → prompt chaining | No — "difficult or impossible to predict the required number of steps" (S7) | No, but the decomposition is domain-stable |
| Is the subtask list knowable before the run? | Fixed | Discovered at runtime | Discovered, but each subtask is independent (S7: "subtasks aren't pre-defined") |
| Do you need reproducibility / audit? | Required | Not required; "you must have some level of trust in its decision-making" (S7) | Partial — S1 notes the stream "does not provide a full conversation transcript" |
| Is there a clear pass/fail success criterion? | Yes | Vague | Per-subtask criterion; coordinator judges the synthesis |
| Latency budget | Trades latency for accuracy — "the main goal is to trade off latency for higher accuracy, by making each LLM call an easier task" (S7) | Many turns, unbounded | Wall-clock ≈ slowest subagent, not the sum (S5, S6) |
| Environment risk | Constrained/trusted | Trusted and autonomous; S7 scopes agents to "scaling tasks in trusted environments" | Mixed — subagents inherit coordinator's tool grants (S1) |
| Subtask interdependence | Sequential by construction | Model-decided | Must be independent — "Agents that edit the same files must coordinate their changes" (S1) |
| Token economics | Cheapest | Most expensive per step | ~1 extra call per interaction over single-agent (S2) |
Fit criteria as stated, per source
→ Graph-based deterministic workflow. S7's prompt-chaining test: "ideal for situations where the task can be easily and cleanly decomposed into fixed subtasks." Example given: "Writing an outline of a document, checking that the outline meets certain criteria, then writing the document based on the outline." Routing is a graph workflow too, when "classification can be handled accurately." S3's corollary: choose the low-level graph framework when you want control over "stateful, long-running workflows."
→ Dynamic code-based workflow (agent). S7: "open-ended problems where it's difficult or impossible to predict the required number of steps, and where you can't hardcode a fixed path. The LLM will potentially operate for many turns, and you must have some level of trust in its decision-making. Agents' autonomy makes them ideal for scaling tasks in trusted environments." S7's simpler phrasing: "workflows offer predictability and consistency for well-defined tasks, whereas agents are the better option when flexibility and model-driven decision-making are needed at scale." S3: "complex, non-deterministic, and long running tasks."
→ Collaborative subagents. S7 orchestrator-workers: "complex tasks where you can't predict the su
(c) Context-sharing and communication
What state passes between agents
| Channel | Source | What passes | Direction |
|---|---|---|---|
| Shared filesystem / environment | S1 | "The coordinator and subagents share its filesystem." Artifacts, not messages. | All ↔ all |
| Tool-call delegation | S1, S2, S10 | Coordinator calls subagent as a tool with a payload; receives a return value. S10: query-only ("keeps the subagent isolated") vs fork mode — "a forked subagent receives the parent's full message history (including tool calls) and system prompt." | Coordinator → subagent |
| Structured output | S3 docs | "Subagents support structured output, so the parent agent receives predictable, parseable JSON instead of free-form text." | Subagent → coordinator |
| Shared typed state key | S8 | "Each worker has its own state, and all worker outputs are written to a shared state key that is accessible to the orchestrator graph." | Subagents → shared → coordinator |
| Agent-to-agent messages | S1 | send_subagent_input_call — "inter-agent text when available." | subagent ↔ subagent |
| Peer threads | S6 | "Bots can independently message each other and share context in threads"; group chats where they "coordinate on their own… pass work, assign ownership, and only pull you in for judgment calls." | peer ↔ peer |
| Persistent conversation history | S4 | Structured, queryable record of user inputs, agent responses, metadata. Audit trail. | store |
| Agent state | S4 | "static configuration and dynamic runtime state," enabling resume after failure and continuity across sessions. | store |
| Agent registry metadata | S4, S10 | Capabilities, endpoints, operational status, versions. S10 triggers tool-based discovery when "many agents (> 10)," the registry "changes frequently," or you want "to reduce prompt size and token usage." | registry → coordinator |
| Virtual filesystem memory | S3, S9 | System prompts, skills, long-term memory, offloaded tool results. | store |
How results aggregate
- Coordinator synthesis (the dominant pattern). S1: "The main agent coordinates their work and combines their results." S7: orchestrator "synthesizes their results." S4 Supervisor Agent: "Receives high-level tasks, breaks them down, delegates… monitors progress, aggregates results, and ensures overall task completion."
- Shared-key aggregation (deterministic). S8: all worker outputs land in one state key; the orchestrator graph reads all of them.
- LLM-as-aggregator with explicit instruction. S1's reference prompt: "Wait for both results, then combine them into one release summary with release labels. Do not invent missing details." That is the aggregation contract — labelled provenance plus a no-invention constraint.
- Programmatic aggregation. S7/S8 parallelization variant: aggregate "outputs programmatically" / score by explicit criteria (citation count, source count, source quality).
How loops terminate
Termination is the least-specified area in these sources, and SolOS must specify it explicitly:
| Mechanism | Source | Detail |
|---|---|---|
| Explicit wait | S1 | wait_for_subagents_call is a first-class action. "A completed create or wait action does not mean the subagent finished its task" — wait is necessary, not sufficient. |
| Interrupt | S1 | interrupt_subagent_call — pre-emptive termination, and the reason a cap on iterations is mandatory. |
| Evaluator grade | S8 | Conditional edge routes back to the generator or ends on the evaluator's structured verdict. |
| Exhaustion | S9 | Summarization fires "when the context size crosses the threshold, and there is no more context eligible for offloading" — a resource-based terminator. |
| ** |
(d) SPEC REQUIREMENTS for SolOS v2
Imperative form. Each tagged with provenance.
- Route every new capability through a single-agent-first ladder: single agent + good prompt → add tools → only then graduate to multi-agent. Do not permit a fleet feature to ship as a new coordinator by default; multi-agent adoption requires a named limit that was actually hit. from S2 — "Start with a single agent and good prompt engineering. Add tools before adding agents. Graduate to multi-agent patterns only when you hit clear limits."
- Classify each new SolOS workflow as graph-deterministic or agent-dynamic at design time, and record the classification in the workflow manifest. Use graph-deterministic only where the task "can be easily and cleanly decomposed into fixed subtasks"; use agent-dynamic where the required step count "is difficult or impossible to predict" and you accept the trust requirement that comes with model-driven decisions. from S7 — workflows vs agents definition and both fit criteria; confirmed by S8
- Delegate only independent work to subagents; keep short and dependent steps inside the coordinator. Block any fan-out whose subagents would write to the same files unless an explicit coordination protocol is declared — "Agents that edit the same files must coordinate their changes." from S1 — "Use subagents for independent tasks… Keep short tasks and dependent steps in the main agent."
- Require every delegated task to carry an explicit question and an explicit expected result before a subagent is spawned; reject delegations specified as topics without deliverables. from S1 — "Give each task a clear question and expected result."
- Keep the coordinator stateless-free and subagents stateless. Hold all conversation memory in the coordinator; give every subagent a clean context window so context cannot accumulate across invocations. from S2 — "The main agent maintains conversation context while subagents remain stateless, providing strong context isolation"; from S10
- Make fan-out fan-in into a typed shared state key, not a concatenated transcript. Route all worker outputs to one schema-typed key the coordinator reads to synthesize, and require each result to carry provenance labels. from S8 — "all worker outputs are written to a shared state key that is accessible to the orchestrator graph"; from S1 — "combine them into one release summary with release labels. Do not invent missing details."
- Enforce a hard, configurable cap on concurrent subagents at coordinator launch, defaulting to 6 excluding the coordinator, and make the limit a session-creation-time setting rather than a mutable runtime one. from S1 — "
max_concurrent_subagentslimits how many subagents can run at once. The default is6, excluding the coordinator… These settings apply at session creation." - Budget and enforce loop termination for every agent-driven loop with three independent caps — max iterations, max tokens, max wall-clock — and support pre-emptive interruption of a running subagent. No source supplies these; the coordinator must refuse to start a loop without them. from S1 —
interrupt_subagent_callexists and is required; termination caps are an original SolOS addition, cf. the unaddressed gap in S7/S8/S9 - Implement context compression as a three-tier, threshold-triggered pipeline: offload tool results over 20,000 tokens to the filesystem and substitute a file-path reference plus a 10-line preview; truncate stale write/edit tool inputs at 85% of the context window; and fall back to summarization only once nothing is eligible for offloading. from S9 — all three thresholds verbatim
- Back summarization with a durable record: write full original messages to the filesystem as the canonical log and keep only a structured in-context summary (session intent, artifacts created, next steps) in working memory. from S9 — "Filesystem preservation… The complete, original conversation messages are written to the filesystem as a canonical record."
- Expose fleet capability discovery through a tool-based registry lookup rather than a hardcoded agent list, and switch to it once the agent count exceeds 10 or the registry becomes dynamic. from S10 — tool-based discovery triggers: "many agents (> 10) or a growing registry… reduce prompt size and token usage"; from S4 — Agent Registry as "the central part of a multi-agent system"
- Give every agent a non-overlapping capability description and refuse to register a new lane whose knowledge domain or action scope substantially overlaps an existing one; group overlapping agents under a shared supervisor interface instead. from S4 — "Avoid keeping highly similar agents separate, as this can degrade the performance of the orchestrator or intent classifier… Use hierarchical organization (e.g., supervisor → agent group)"
- Insert supervisors over agent clusters as fleet size grows, and require a deterministic IDK abstain path when no lane's confidence threshold is met — never fall through to a guessed route. from S4 — "Introduce agent supervisors as the architecture scales across domains"; classifier ladder "NLU → SLM → LLM | SML based on certainty… If no intent is detected by the end of the process, return 'IDK'"
- Version the coordinator manifest and every agent manifest independently of runtime state, and require agent health checks, automatic retry, and token-consumption alerting with defined fallbacks (smaller model, cached response, graceful degradation) on every run. from S4 — "highly recommended to version the Orchestrator's and the agent's metadata… Do not use the state field to track versions"; "Fallback mechanisms must be in place… switching to a smaller model, using cached responses, or gracefully degrading functionality"
- Make the parallel lane a first-class production shape — run N independent specialist Bots under a chief-of-staff coordinator over a shared project/account context — but require an explicit human approval gate before any externally visible or irreversible action. from S6 — "A chief of staff sits on top, with a specialist for each lane"; "only come back when something needs your approval"; from S5 — Sentinel approval gate; from S3 — human-in-the-loop
- Record the following as SolOS-original design, not as sourced practice: debate/majority-vote arbitration and true blackboard architectures. No reviewed source names debate or vote as a pattern, and no source specifies an aggregation mechanism for parallel agents — Meta's Contemplating mode describes parallel agents but no vote. Ship these tagged as original, with their failure-mode claims limited to single-sample variance. [absence of evidence across S1–S6; parallel-v
Source-quality notes for the vault
- S6 (Grok Bot) is a launch post, not architecture doctrine. Its value to SolOS is the product-level shape (chief-of-staff over lane specialists, peer threads, approval gates) and the lesson that demonstration-to-routine capture ("ask it to follow along the next time you do a job… saves your workflow as a routine") is a distinct capability. Do not cite it for any mechanism claim.
- S3 (Deep Agents) is thin on mechanism; the substance lives in S9 (context management) and the deepagents subagents docs.
- S1's page is JS-rendered — the
.mdsuffix on developers.openai.com URLs yields the full prose. Use that convention for future OpenAI doc pulls. - S5 required two affiliate sources: ai.meta.com/muse/ is a JS-only shell with no server-rendered prose. The architecture content lives in the Muse Spark launch post (Contemplating mode, multi-agent orchestration, 58% HLE / 38% FrontierScience) and the fb.com announcement (Secure VM, Sentinel approval agent).
§4 Lane C — Protocol & platform (A2A, OpenClaw, arXiv)
Source ledger
| # | Source | URL | Provenance | How obtained |
|---|---|---|---|---|
| S1 | A2A Protocol v1.0.0 Specification | https://a2a-protocol.org/latest/specification/ | live | curl (extract backend returned 403). 171 KB of text retrieved. |
| S2 | A2A — Life of a Task | https://a2a-protocol.org/latest/topics/life-of-a-task/ | live | curl |
| S3 | A2A — Streaming & Async Ops | https://a2a-protocol.org/latest/topics/streaming-and-async/ | live | curl |
| S4 | A2A — Agent Discovery | https://a2a-protocol.org/latest/topics/agent-discovery/ | live | curl |
| S5 | A2A — Multi-Tenancy & Multi-Agent Routing | https://a2a-protocol.org/latest/topics/multi-tenancy/ | live | curl |
| S6 | A2A — Enterprise-Ready Features | https://a2a-protocol.org/latest/topics/enterprise-ready/ | live | curl |
| S7 | A2A — Extension & Binding Governance | https://a2a-protocol.org/latest/topics/extension-and-binding-governance/ | live | curl |
| S8 | A2A — What's New in v1.0 (0.3.0 → 1.0.0) | https://a2a-protocol.org/latest/whats-new-v1/ | live | curl |
| S9 | OpenClaw — Multi-agent routing | https://docs.openclaw.ai/concepts/multi-agent | live | web_extract + curl |
| S10 | OpenClaw v2026.9.6 release notes | https://docs.openclaw.ai/releases/2026.9.6 | live | web_extract + curl (469 KB) |
| S11 | arXiv:2605.20025v2 | https://arxiv.org/html/2605.20025v2 | live | web_extract + curl; corroborated by arxiv abs page via web_search |
Note on retrieval:
web_extract's Firecrawl backend returned403 Forbiddenfor all a2a-protocol.org sub-pages (index page succeeded). Plaincurlwith a browser UA returned HTTP 200 for every one. No archives/snapshots were used, so all A2A content above is live-page provenance.
(a) A2A Protocol v1.0.0 — the model SolOS v2 must speak
Current released version is 1.0.0 (previous: 0.3.0, 0.2.6, 0.1.0). Governing body: The Linux Foundation; the site also carries a post about "A new chapter for A2A: joining the Agentic AI Foundation".
(a1) Layered structure — why this matters for the Cortex
The spec is three layers, and the ordering is normative in practice:
- L1 A2A Data Model —
Task,Message,AgentCard,Part,Artifact,Extension. "Protocol agnostic definitions expressed as Protocol Buffer messages." - L2 A2A Operations — Send Message, Send Streaming Message, Get Task, List Tasks, Cancel Task, Get Agent Card (+ push-config CRUD, Subscribe, Extended Card).
- L3 Protocol Bindings — JSON-RPC, gRPC, HTTP+JSON/REST, custom bindings.
Normative source of truth (§1.4): spec/a2a.proto is the single authoritative normative definition of all protocol data objects. spec/a2a.json is a non-normative build artifact. SDK language bindings and schemas MUST be regenerated from the proto, never hand-edited. For SolOS: if the v2 Cortex implements its own A2A types, generate them from a vendored copy of the proto, or you will silently drift.
Requirements keywords are RFC 2119. Deprecation lifecycle: renames keep the old name available but deprecated until the next major; migration guidance MUST be published for major breaking changes; a deprecated name SHOULD NOT be removed earlier than the next major after its replacement.
(a2) Message / Task / Artifact model
Task (the unit of work)
id (req, server-generated) · contextId · status (req) · artifacts[] · history[] · metadata.
TaskStatus / TaskState — the lifecycle
state (req) + optional message + optional ISO-8601 timestamp.
| State | Class |
|---|---|
TASK_STATE_UNSPECIFIED | unknown/indeterminate |
TASK_STATE_SUBMITTED | acknowledged |
TASK_STATE_WORKING | actively processing |
TASK_STATE_COMPLETED | terminal |
TASK_STATE_FAILED | terminal |
TASK_STATE_CANCELED | terminal |
TASK_STATE_REJECTED | terminal |
TASK_STATE_INPUT_REQUIRED | interrupted |
TASK_STATE_AUTH_REQUIRED | interrupted |
Terminal states are immutable: once reached, the task cannot restart; a refinement must open a new task in the same contextId. Sending a message to a task in a terminal state returns UnsupportedOperationError.
Message
messageId (req, creator-assigned) · role (ROLE_USER | ROLE_AGENT) · parts[] (req) · optional contextId, taskId, metadata, extensions[], referenceTaskIds[].
Part — exactly one of
text | raw (bytes, base64 in JSON) | url | data (any JSON value). Plus optional filename, mediaType, metadata. "A Part MUST contain exactly one of text, raw, url, data."
Artifact
artifactId (req, unique within task) · name · description · parts[] (req, ≥1) · metadata · extensions[].
Context and grouping
contextIdlogically groups related Tasks and Messages; the agent MAY use it to hold LLM/conversational state.- Agent-generated
contextIdMUST be returned in the response. If an agent cannot accept a client-suppliedcontextId, it MUST reject the request and MUST NOT silently mint a new one. - Clients SHOULD NOT send a client-generated
contextIdunless they understand the server's handling; server-generated ids are opaque. - Clients MAY create parallel tasks within one
contextId— e.g. Task 1 books a flight; Tasks 2 and 3 book a hotel and a snowmobile in parallel from Task 1; Task 4 depends on Task 2. - Artifact mutation/versioning is explicitly NOT in the protocol. Clients hold version history and pick the latest acceptable version; serving agents should reuse the same
artifact.namewhen refining, so the client can match them. Ambiguity → agent returnsinput-required. - Messages vs Artifacts: "Messages SHOULD NOT be used to deliver task outputs. Results SHOULD BE returned using Artifacts." And: "Messages MUST NOT be considered a reliable delivery mechanism for critical information" — clients disconnected and reconnecting may miss status messages.
- Agent archetypes: message-only, task-generating (always returns Tasks, even completed ones), or hybrid (negotiate with Messages, commit with a Task). Hybrid is the right shape for a Cortex.
(a3) Operations, streaming, push
| Function | JSON-RPC | gRPC | REST |
|---|---|---|---|
| Send message | SendMessage | SendMessage | POST /message:send |
| Stream message | SendStreamingMessage | SendStreamingMessage | POST /message:stream |
| Get task | GetTask | GetTask | GET /tasks/{id} |
| List tasks | ListTasks | ListTasks | GET /tasks |
| Cancel task | CancelTask | CancelTask | POST /tasks/{id}:cancel |
| Subscribe | SubscribeToTask | SubscribeToTask | POST /tasks/{id}:subscribe |
| Push config CRUD | Create/Get/List/DeleteTaskPushNotificationConfig | same | POST/GET/GET/DELETE /tasks/{id}/pushNotificationConfigs[/{configId}] |
| Extended card | GetExtendedAgentCard | GetExtendedAgentCard | GET /extendedAgentCard |
ListTasks is new in v1.0 with filtering and cursor-based pagination. Task visibility is scoped to the authenticated caller.
Three update-delivery mechanisms
- Polling (
GetTask) — simple, works everywhere, higher latency. - Streaming — SSE (
text/event-stream), HTTP 200, long-lived. Requirescapabilities.streaming: true. InitialTaskorMessage, thenTaskStatusUpdateEvent(taskId,contextId,status) andTaskArtifactUpdateEvent(taskId,contextId,artifact,append,lastChunk). Stream closes on terminal or interrupted state. Reconnect withSubscribeToTask. - Push notifications — requires
capabilities.pushNotifications: true. `TaskPushNotificationConfig{tenant?, id?, taskId?, url(req), token?, authentication?}
(b) OpenClaw — platform model, and what 2026.9.6 changed
(b1) Multi-agent model
"An agent is the full per-persona scope." Multiple isolated agents run in one Gateway process. Each agent owns:
- Workspace — files,
AGENTS.md/SOUL.md/USER.md, local notes, persona rules. - State dir (
agentDir) — auth profiles, model registry, per-agent config. Default~/.openclaw/agents/<agentId>/agent. - Session store — SQLite chat history + routing state at
<agentDir>/openclaw-agent.sqlite(sessions_historytable).
Hard-won operational rules:
- Never reuse
agentDiracross agents — it causes auth/session state collisions. - OAuth read-through: a secondary agent with an expired/failed local refresh adopts the freshest token from the default/main agent for the same profile id, without copying refresh material into the secondary store. Manual copies must be portable static
api_key/tokenprofiles only; OAuth refresh material is not portable (copyToAgentsopts in). sessions_historyis the safe recall path: bounded, redacted, strips thinking-block signatures, tool-result payload details,<relevant-memories>scaffolding, tool-call XML tags, MiniMax tool-call XML; then truncates and byte-caps. Do not raw-dump transcripts.- Workspace is cwd, not a sandbox. Relative paths resolve inside; absolute paths reach elsewhere unless sandboxing is on.
- Skills resolve from the agent workspace plus shared roots (e.g.
~/.openclaw/skills), then filter by the effective allowlist.agents.defaults.skills= shared baseline;agents.entries.*.skills= replacement, not a merge. - Plugin storage does not auto-split per agent. Memory Wiki defaults to one global vault; set
plugins.entries.memory-wiki.config.vault.scope: "agent"to isolate personas' compiled knowledge. This is the single most important gap for a shared-cortex design: shared by default, isolated only on explicit config. - Cross-agent memory search (QMD) was removed in v2026.8.1. Builtin memory does not search another agent's transcripts. Intentional sharing goes through
memory.search.extraPaths.
Key concepts:
agentId= one "brain" (workspace + per-agent auth + session store).accountId= one channel account instance (WhatsApp personal vs biz, Discord bot, etc.).binding= routes inbound messages to anagentIdby(channel, accountId, peer)plus optional guild/team ids.- Direct chats collapse to
agent:<agentId>:mainby default → true isolation requires one agent per person. - Direct chats on one WhatsApp number split by sender E.164, but replies still come from the same number (no per-agent sender identity); DM allowlists are global per account, not per agent.
Routing: deterministic, most-specific-wins, tier order = exact peer → parent peer → peer wildcard → guild+roles → guild → team → account → channel → default agent. Within a tier the first in config order wins. Multiple match fields are AND. A binding omitting accountId matches only the default account ("*" = channel-wide fallback). openclaw doctor --fix materializes legacy ambient routing into explicit bindings plus agents.ownership: "explicit".
Delegation:
subagents.allowAgents= explicit spawn targets;delegationMode: "prefer"is prompt guidance, not a scheduler.- Team preset: coordinator (chief of staff) + researcher + writer + reviewer, each with its own workspace and role contract. The coordinator discovers specialists, assigns bounded work, checks artifacts, reports. **Specialists return a
(c) arXiv:2605.20025v2 — resolved, real title and abstract
The ID resolves. Full-text HTML retrieved live (arxiv.org/html/2605.20025v2, 405 KB page) and corroborated against the abs page.
- Real title: "AutoResearchClaw: Self-Reinforcing Autonomous Research with Human-AI Collaboration"(The HTML render drops the leading token — the page title literally reads ": Self-Reinforcing Autonomous Research with Human-AI Collaboration" — but the arXiv abstract listing carries the full title, which is the authoritative form.)
- Authors: Jiaqi Liu, Shi Qiu, Mairui Li, Bingzhou Li, Haonian Ji, Siwei Han, Xinyu Ye, Peng Xia, Zihan Dong, Meng Chen, Congyu Zhang, Letian Zhang, Guiming Chen, Haoqin Tu, Xinyu Yang, Lu Feng, Xujiang Zhao, Haifeng Chen, Jiawei Zhou, Xiao Wang, Weitong Zhang, Hongtu Zhu, Yun Li, Jieru Mei, Hongliang Fei … (UNC-Chapel Hill, UC Santa Cruz, Rutgers, CMU, NEC Labs America, Meta, Google)
- Submitted 19 May 2026 (v1); v2 23 May 2026. cs.AI. DOI 10.48550/arXiv.2605.20025. Code: https://github.com/aiming-lab/AutoResearchClaw
Abstract (verbatim):
Automating scientific discovery requires more than generating papers from ideas. Real research is iterative: hypotheses are challenged from multiple perspectives, experiments fail and inform the next attempt, and lessons accumulate across cycles. Existing autonomous research systems often model this process as a linear pipeline: they rely on single-agent reasoning, stop when execution fails, and do not carry experience across runs. We present AutoResearchClaw, a multi-agent autonomous research pipeline built on five mechanisms: structured multi-agent debate for hypothesis generation and result analysis, a self-healing executor with a Pivot/Refine decision loop that transforms failures into information, verifiable result reporting that prevents fabricated numbers and hallucinated c
(d) SPEC REQUIREMENTS — SolOS v2 Cortex / interop layer
Imperative form. Each tagged with its source.
- Publish a signed Agent Card for every Cortex-exposed agent at
/.well-known/agent-card.json, canonicalized per RFC 8785 (JCS) and signed with JWS/RFC 7515, excluding thesignaturesfield itself from the signed content — and treat that card as the sole authoritative description of skills, capabilities, and auth. from A2A §8.4.1, §8.1 - Model every unit of Cortex work as a Task with a server-generated unique
taskId, aTaskStatus.statedrawn only from the nineTASK_STATE_*values, and treatCOMPLETED/FAILED/CANCELED/REJECTEDas immutable terminal states — a refinement MUST open a new task inside the samecontextId, never revive a dead one. from A2A §4.1.3, Life of a Task - Return task outputs as Artifacts, never as Messages, and reuse a stable
artifact.namewith a freshartifactIdwhenever a refined artifact supersedes its predecessor — while keeping version linkage client-side, because the protocol deliberately excludes artifact-mutation tracking from server responsibility. from A2A §3.7, Life of a Task - Enforce exactly-one-of
text/raw/url/dataon every Part, and never treat Messages as a reliable delivery channel for critical information — a client that disconnected mid-stream may never see a status message. from A2A §4.1.6, §3.7 - Separate trusted record from working set: allocate a distinct
agentDir(auth profiles + model registry + session store) and workspace per fleet agent and never share one across personas — reuse is the documented cause of auth/session state collisions, and each agent's transcript-corpus recall must be scoped to its own store. from OpenClaw multi-agent routing - Default all global stores to agent scope and make cross-agent access explicit and deny-by-default — set the memory-wiki vault scope to
agent, keep a namedextraPathsset as the only shared-memory surface, and gate agent-to-agent calls with an explicit allowlist plus a separate sessions-visibility policy, since cross-agent session access and a single global vault are both the platform's shipped default. from OpenClaw multi-agent routing - Bound delegation to a flat, single-level tree: a coordinator agent may spawn specialists from an explicit
allowAgentslist, specialists MUST return artifacts and evidence upward without delegating further, every agent-created agent MUST pass operator approval and MUST retain provenance (creator kind + requesting agent id), and the whole hierarchy MUST be inspectable as a tree. from OpenClaw multi-agent routing - Keep the tool surface per-agent and least-privilege: maintain an explicit
allow/denytool list and sandbox scope for each agent, and make the per-agent elevated gate capable only of narrowing the global gate — both must permit a sender before an elevated command runs; treat any tool inventory or permission grant as inspectable rather than implicit. from OpenClaw multi-agent routing - Never report a terminal task state without its payload: when an A2A task falls back to another model, the completed result MUST contain the fallback model's actual answer (never a bare "different model will be used" notice), and the originating task MUST reach a real terminal state rather than leaving the caller polling — apply the same rule to interrupted work across restarts, recovering saved history and tool results without auto-relaunching stopped conversations. from OpenClaw 2026.9.6 #152168, #154317, Restart recovery
- Emit a deterministic, ordered task-update stream and broadcast it identically to every concurrent subscriber — events MUST NOT be reordered, closing one stream MUST NOT disturb another, and task lifecycle MUST be independent of stream lifecycle; provide all three delivery modes (polling, SSE streaming, and client-webhook push) with
capabilities.streamingandcapabilities.pushNotificationstruthfully set in the card. from A2A §3.5, §5.2, Streaming & Async Ops - Harden every outbound push: never blindly POST to a client-supplied webhook URL, authenticate to the receiver using the scheme declared in
TaskPushNotificationConfig.authentication, require the receiver to verify authenticity (JWT/JWKSiss/aud/iat/exp/jti, or HMAC), reject stale timestamps and replayed ids, attempt delivery at least once, and require receivers to answer 2xx, validate the task id, and process idempotently. from A2A §4.3.3, §13.2 - Require encryption on every interop hop, authenticate every inbound request, return 404 rather than 403 for resources the caller cannot see, and — critically — never treat an
AUTH_REQUIREDtransition by itself as authorization: the scope, representation, validity, and revocation of any credential obtained in that state MUST be defined by the issuer or an explicit extension before the operation proceeds. from A2A §7.1–§7.6.4, §3.3.2 - Carry fleet-wide provenance as a protocol extension, not core fields: declare every non-core capability as a versioned URI in
AgentCard.capabilities.extensions[], negotiate it per-request via theA2A-Extensionsservice parameter, and mint a new URI for any breaking change — keeping the core data model stable while the Cortex grows. from A2A §4.6, Extension & Binding Governance - Pin protocol versions explicitly: send
A2A-Version(Major.Minor only, never patch) on every request, returnVersionNotSupportedErrorfor unsupported versions, treat an empty header as 0.3, and require functional equivalence across every declared binding — identical operations, semantically equivalent results, consistently mapped errors, equivalent authentication. from A2A §3.6, §5.1 - Make the Cortex self-verifying: keep a read-only numeric registry that the producing agent can read but never modify, reject any report whose strict-section numbers cannot be matched to a registry entry, force every citation through a multi-layer resolver plus a relevance classifier that removes hallucinated references before finalization, and rank a persistent lesson store by time-decayed severity
w(l) = s(l)·exp(−ln2·Δt/T₁/₂)so recent failures constrain later runs — and pause for a human only at high-leverage decision points, not at every step. from arXiv:2605.20025v2 §3.2–§3.6, §4.4
Open questions for Young's merge
- A2A "v2" is not released. Current normative spec is 1.0.0 (prior: 0.3.0). The breaking surface a v2 Cortex must survive: enum casing to
SCREAMING_SNAKE_CASE,kinddiscriminators removed in favour of JSON member polymorphism,protocolVersionper-AgentInterface,preferredTransport/additionalInterfaces→supportedInterfaces[],supportsAuthenticatedExtendedCard→capabilities.extendedAgentCard,tasks/{id}compound IDs → plain UUIDs, streamfinalboolean removed. - No single source defines a "shared cortex". A2A gives interoperability and opaque execution but explicitly leaves artifact versioning, credential scope, and registry APIs to implementations. OpenClaw gives isolation primitives but defaults them open (global vault, cross-agent session access on). The Cortex spec has to close both gaps explicitly — requirements 6, 12, and 15 above are where that work lives.
- Multi-tenancy
tenantfield is the cheapest Cortex routing primitive already in the standard (opaque, advertised inAgentInterface, client MUST echo). Worth pinning as the v2 routing key rather than inventing one.
§5 Lane D — Self-heal, self-learn, eval capture
(a) The Self-Heal Loop: detect → diagnose → repair → verify → record
The three sources converge on the same shape but distribute the stages differently. The Adaptive system splits analysis (Insights Agent) from change-authoring (Evolution Agent) and gates everything with an explicit human interrupt.1 The MindStudio loop scores, then routes to pass / soft-fail / hard-fail.2 The self-improving loop is: load learnings, run fixtures, score binary evals, diagnose, append lessons, commit, schedule.3 Composed, the five stages are below. Each stage's "must actually check" column is the part that is easy to fake and expensive to skip.
| Stage | Must actually check | Evidence written | Skipping it produces |
|---|---|---|---|
| 1. Detect | Read production traces, not a status flag. Categorize errors by type, look at tool-usage patterns, inspect chain-of-thought quality, examine user-interaction dynamics, find bottlenecks in multi-step workflows.1 Error distribution must be counted over a time window with the affected tool named — e.g. "42% of errors were tool call failures, primarily timeouts on external APIs, affecting web_search and database_query."1 | Error type distribution + affected-tool histogram + sample trace ids.[1]2 | Undetected wedges. A health check that says "green" for a process that is hung. SolOS mapping: alert fatigue risk. |
| 2. Diagnose | Produce a root cause, a description of what the agent did wrong, and one specific instruction to avoid it — per failure, keyed by eval id.3 Not a score. "An agent that knows it scored 60% doesn't know what to do differently."3 Cross-reference prior diagnoses so the same root cause isn't diagnosed twice under different names.[1]3 | {test_id, root_cause, instruction} JSON per failure.3 | Vague hypotheses. "Timeouts are bad" is not a repair plan; "set 30s API / 60s DB timeouts, exponential backoff, max 3 attempts, then degrade gracefully" is.1 |
| 3. Repair | Read the actual current artifact first (real prompt files, real code), then generate a specific diff. Validate the change preserves structure and intent, and consider side effects.1 Constrain all writes: path validation against traversal, repository scope restriction.1 | Unified diff + +lines/-lines stat.1 | Repairs aimed at a remembered version of the code that no longer exists. |
| 4. Verify | Re-run the failure. Do not treat "change applied successfully" as success — source 1's own closing guidance is only advisory ("Test the updated prompts with a sample workload", "Monitor error rates over the next 24 hours", "Return to this session to review impact"), which is exactly the gap SolOS v2 must close.1 Verification must be an independent scorer: self-evaluation inside the same context window "tends to be overconfident," so use a separate evaluator call and separate generation from scoring.3 | Post-repair eval verdicts on the same fixtures, plus the observed delta in the target error class.3 | See "failure mode of skipping verification" below. |
| 5. Record | Append to a durable store, with provenance: lesson text, the eval id that produced it, the date.3 Commit the store and the results back to the repo so the next run inherits them.3 Write every routing/classification decision to the shared audit log — it is "your debugging system, your audit trail, and your training data for the next improvement cycle."2 | learnings.md-style entry with failed test_004 on 2026-04-14 provenance; audit-log line per decision.[2]3 | The loop restarts from zero every session: "Every mistake gets repeated. Every edge case surprises them again."3 |
The failure mode of skipping verification
This is the failure mode that converts a self-heal loop into a self-harm loop, and it has three compounding parts.
First, "applied" is not "fixed." Verification is the only stage that closes the loop against reality. Without it the loop is an assertion loop: detect fires, repair writes bytes, record logs success — and the original wedge persists while the ledger accumulates confident entries that say it was handled. Source 2's framing is the cleanest statement: without evals "you're running agents on faith," discovering errors only "when a customer complains or an audit surfaces a problem."2
Second, an unverified repair poisons the trust budget and freezes the system. Source 1 identifies the fear of introducing regressions as a named cause of stagnation: teams become conservative because "the perceived risk of change outweighs the
(b) The Self-Learn / Feedback Loop
The four required parts
A self-improving loop needs four things: a task, an evaluation harness, diagnostic feedback, and a persistent learning store.3 The agent "runs, gets scored, identifies what went wrong, and writes that lesson somewhere permanent," and reads those lessons first on the next run.3
Harness = fixtures + run script + rolling results store. Fixtures are predefined test cases
covering normal cases, edge cases, and known failure modes, each with expected_properties.3 The run
script loops fixtures, captures output, and stores output together with the input.3 The results
store is a rolling log per fixture across runs — "This lets you track improvement over time, not
just pass/fail on the current run."3 SolOS mapping: the SolOS fixture set should be seeded from real
observed failure classes (timeout-on-provider-call, context overflow, malformed structured output),
because those are the classes source 1 measured in production traces.1
Evals must be binary. pass/fail with no subjective middle ground, because "you can't build a feedback loop from a score of 7 out of 10. You can build one from a list of pass/fail checks that tell you exactly which properties the output did or didn't have."3 Stable ids, declared check type (regex, word-count, format, disallowed-pattern, input-reference).3
Diagnostics ≠ scoring. Scoring is not the same as feedback.3 Per failed test, emit root cause + what-went-wrong + one specific instruction.3
Learnings store = durable, injected at run start. Plain markdown accumulating lessons, each tagged with the test id and date that produced it — this is how Claude Code's auto-memory works in practice.3 It is a behavior store, not a weight store: "you're not changing the model; you're changing what the model knows before it starts."3
The full cycle
Load learnings → run against all fixtures → score with binary evals → diagnose failures → append only new lessons, not repeats → commit the store and results → schedule the next run.3
Batch relabel and offline eval before promotion
The sources do not use the phrase "batch relabel," but two mechanisms play that role and combine
into it. [synthesis]
- Weekly batch review of the failure set. Teams run "weekly eval reviews where edge cases from the prior week are analyzed and used to update prompts or routing logic."2 One batch pass over a week's accumulated hard-fails and soft-fails, rather than reacting to each error as it fires.
- Deduplicate and version before writing. The production version of the loop "would add deduplication logic, version the learnings file, and track which lessons actually improved scores over subsequent runs."3
The store is therefore not append-only. The rule the sources imply: a candidate lesson is only promoted into the store after it has been batched, deduplicated against existing entries, attributed to an eval id, and measured against the fixture set — because only the fixture set can say whether the lesson improved anything.3
Promotion of the artifact change itself is gated differently and more conservatively. Source 1's
current system is explicitly offline optimization with human oversight: it "focuses on offline
optimization with human oversight," and before any prompt modification is applied it interrupts
execution with a GraphInterrupt, renders unified diffs with syntax highlighting and change stats,
and requires explicit approval — reject discards the changes and records the rejection.1 Source 1
names the production-grade gates for going further online: "tiered confidence levels, A/B testing
capabilities, automated rollback mechanisms, and escalation paths for uncertain cases."1
What prevents regression loops
A regression loop is the loop learning something true-but-wrong, then re-applying it, then failing harder and learning something equally wrong. Five guards, each traceable to a source:
- Binary evals with stable ids — a regression surfaces as a specific named test flipping back to fail, not as a drifting average.3
- **Rolling per-fi
(c) Eval Capture Design: what to record per run
Evals can only be built from data captured at run time. Source 2 states the capture requirement outright: "Log every capture event. If a task fails, you need to know exactly what came in and when."2 And on decisions: "When an agent makes a routing decision, a classification call, or a content generation choice, log it."2
Minimum per-run record (SolOS mapping, assembled from the sources' required fields)
Identity / inputs
run_id,agent_id,task_id,trigger_mode(trigger-based, communication-based, scheduled, human-initiated)2- The normalized structured task record — intent, entities, filled fields, and explicitly what is missing and was flagged for human review.2 The raw input must be retained alongside it: if a task fails, you need to know exactly what came in.2
- Full context handed to the agent, not just the trigger — "Agents that have to re-fetch context mid-task are slower and more error-prone."2
Trajectory (source 1's analysis dimensions, recorded per run so they can be aggregated later)
- Every tool/provider call: name, arguments, start, end, duration, outcome. Duration is the field that makes the timeout wedge visible retroactively.1
- Per-call timeout/budget values in force, and retry count.1
- Chain-of-thought / reasoning trace — one of the dimensions the Insights Agent inspects for reasoning-quality analysis.1
- Context-window occupancy at each step — source 1 measured context overflow as its own error class (18% of errors, "occurring in conversations longer than 15 exchanges").1
- Intermediate artifacts (files read, files written, diffs proposed) with the repository/commit identifiers in force.1
Outcome
status: success | error, plus the structured payload itself — source 1's example repair defines the required shape as"status": "success" | "error","data", and"metadata"(timestamp + confidence score).1- Wall-clock duration, token count, exit reason (clean exit, timeout-kill, crash, abandoned).1
- Completion state in the shared task queue: unstarted → in-progress → needs-review → complete.2
Eval verdicts — all three levels, because each catches a different error class:2
- L1 structural: format present, required fields present, data types correct. "Should be automated entirely."2
- L2 semantic: a reviewer agent scores whether content is reasonable — "Does the generated summary actually reflect the source document?"2
- L3 business-logic: the task-specific rules that catch "the most consequential errors."2
- Routing tier assigned: high-confidence pass / low-confidence soft fail / hard fail, plus whether a human reviewed it and the final decision.2
Diagnostics (only populated on failure)
root_cause,instruction, keyed to the eval id.3- For hard fails: the re-queue note — the task is "rejected, re-queued with a note, and an alert fires."2 Without the note the retry is blind.
Store maintenance
- Which lessons from the store were loaded and which fired; which new lessons were written, with dedupe and version bump applied.3
What makes this a dataset rather than a log
Source 2 is blunt about the failure mode: "Evals generate the most valuable dataset you have: records of every time an agent got something wrong," and "Teams that tre
(d) Anti-Patterns These Sources Warn About
| # | Anti-pattern | What the source says | SolOS mapping |
|---|---|---|---|
| 1 | Reward hacking / eval gaming | "Agents can learn to game their own evals if those evals are too narrow. If your only eval checks for word count, the agent will optimize for word count — potentially at the expense of quality. This is a real phenomenon," with documented cases of models gaming benchmark tests rather than solving the task.3 | A single mechanical check becomes the objective. The agent scores green and the task is still wrong. |
| 2 | Self-modification without rollback | Approval + diff + rejection-recording is the current safeguard; the stated path to autonomy requires "tiered confidence levels, A/B testing capabilities, automated rollback mechanisms, and escalation paths for uncertain cases."1 | Self-heal edits fleet config or prompts in place. No snapshot exists. A bad change is discovered by the fleet, not by the verifier. |
| 3 | Optimizing a proxy metric | Human eval review is the corrective: edge cases get "analyzed and used to update prompts or routing logic,"2 and L2/L3 evals exist because L1 structural checks "are the simplest check" and insufficient.2 A proxy optimized until it stops predicting the thing you care about. Also: treating human escalation rate as the success metric when the stated goal is that it trends down while pass rate trends up2 — otherwise the cheap win is to stop escalating, not to get better. | |
| 4 | Alert fatigue | Evals are "how you know if your agents are working correctly" — the thing that prevents compounding undetected errors: "small errors accumulate. By the time anyone notices, the damage is hard to trace."2 Tiered routing is the anti-fatigue mechanism: high-confidence passes auto-continue, soft fails go to a human queue, only hard fails alert.2 | Every check fires on every run; everything is urgent, so nothing is read — and a real wedge is indistinguishable from routine noise. |
| 5 | Self-confirmation bias | "Using a separate evaluator (or a separate Claude call in evaluator mode) is more reliable than having the agent evaluate its own output in the same session. Self-evaluation in the same context window tends to be overconfident."3 Separating generation from evaluation — "the generator produces output, the validator scores it independently."3 | The agent that wedged declares itself healthy. The health check is written by, and runs inside, the thing it is checking. |
| 6 | Human analysis bias (upstream cause of all five) | Manual trace analysis "is prone to selection bias and incomplete pattern recognition. Human analysts naturally focus on the most obvious or recent issues, potentially missing subtle but important behav |
(e) SPEC REQUIREMENTS — SolOS v2 Self-Heal / Self-Learn
Imperative form, each tagged with its source. [synthesis] marks a rule derived from combining
mechanisms rather than stated verbatim by one source.
SR-1 — Enforce a timeout and retry budget on every provider and tool call. Set explicit per-tool-class timeouts (source 1's example: 30s for API calls, 60s for DB queries), automatic retry with exponential backoff capped at a maximum attempt count, and an explicit graceful degradation path when retries are exhausted. No call may be issued without a bound. from 1
SR-2 — Never self-certify liveness. Liveness and correctness MUST be asserted by an independent verifier that does not share a context window with the component under test. A health check that can report healthy for a wedged process is a failed health check and must be treated as a defect, not as evidence of health. from 3
SR-3 — Log every run as a durable record before the run is considered complete. Each run MUST write input, full trajectory, outcome, and eval verdicts to the shared workspace — including per-call duration, timeout values in force, retry count, context occupancy, artifacts touched, and exit reason. A run whose record lives only in session memory has not completed. from 1, 2, 3
SR-4 — Log every decision, not just every action. Each routing decision, classification, threshold comparison, and escalation MUST be written to the audit log with actor and timestamp. The audit log is simultaneously the debugging system, the audit trail, and the next improvement cycle's training data. from 2
SR-5 — Diagnose to root cause and one specific instruction; scores are not diagnoses.
A failure record MUST contain test_id, root_cause, and a single specific instruction. A bare
pass-rate number MUST NOT be accepted as diagnostic feedback at any stage of the loop. from 3
SR-6 — Score with binary pass/fail evals on stable ids. Every eval MUST return pass or fail with no subjective middle value, carry a stable id and a declared check type, and be run against a fixture set covering normal cases, edge cases, and known failure modes. from 3
SR-7 — Include at least one hard-to-fake, higher-order eval in every suite. Each suite MUST combine mechanical checks with at least one check on whether the output actually correctly addresses the input, and MUST be extended whenever a new failure mode is observed in production. A suite whose checks are all gameable MUST NOT gate promotion. from 3
SR-8 — Re-run the full fixture set offline and gate promotion on it.
No prompt, config, or fleet-behavior change may be promoted until it passes the same fixture set the
current version passes, with per-fixture results compared run-over-run. Regressions block promotion.
This operationalizes source 1's offline-optimization stage and its advisory "test the updated prompts
with a sample workload" as an enforced gate. [synthesis from 1, 3]
SR-9 — Make every self-modification reversible and approval-gated. Snapshot or commit before any write; render a unified diff with change statistics before applying; record approval or rejection, and on rejection discard the change and log the rejection. Automated promotion paths MUST ship with an automatic rollback mechanism and an escalation path for uncertain cases. from 1
SR-10 — Curate the learnings store; it is not append-only. Every candidate lesson MUST be batched with the period's other failures, deduplicated against existing entries, attributed to the eval id and date that produced it, and versioned. Track which lessons actually improved scores on subsequent runs and prune or roll back those that did not. from 2, 3
SR-11 — Route on a tiered response and trend the escalation rate down. Implement three tiers: high-confidence pass continues automatically; low-confidence soft fail is flagged and queued for human review before continuing; hard fail is rejected, re-queued with a failure note, and raises an alert. Track task completion rate, eval pass rate, human escalation rate, and error type distribution; escalation rate MUST trend down as pass rate trends up. from 2
SR-12 — Run the loop on a schedule with tiered confidence, and bound its context. The self-heal and self-learn loop MUST run unattended on a fixed cadence (weekly review minimum for high-volume lanes, monthly floor otherwise), committing learnings and results each pass. Operating mode MUST escalate with confidence — observe/report-only, then propose, then auto-apply with rollback — and MUST implement context hygiene (token-limit gate, tool-output summarization, artifact pruning, semantic memory of prior findings) so multi-day diagnoses remain retrievable without exhausting the context window. from 1, 2
Open questions for the SolOS v2 spec
These are gaps in the sources, flagged rather than papered over:
- Verification stage is advisory in source 1. Its post-repair steps are human TODOs, not an automated gate. SolOS v2 must decide what the machine-enforced version is (SR-8 is the proposal).
- Online self-modification is described as future work, not implemented; the "automated rollback mechanisms" are named but not specified. SolOS v2 needs to specify the rollback mechanism itself.
- Nothing in the sources specifies a liveness or watchdog primitive. The timeout evidence is all retrospective trace analysis.1 The wedged-provider-call failure needs a design these sources do not supply — treat SR-1 and SR-2 as requirements derived from the evidence, not from a published mechanism.
Sources
1 https://medium.com/@madhur.prashant7/evolve-building-self-healing-ai-agents-a-multi-agent-system-for-continuous-optimization-0d711ead090c2 https://www.mindstudio.ai/blog/ai-agents-business-automation-workspace-capture-evals3 https://www.mindstudio.ai/blog/self-improving-ai-agent-feedback-loop
Open questions for the SolOS v2 spec
These are gaps in the sources, flagged rather than papered over:
- Verification stage is advisory in source 1. Its post-repair steps are human TODOs, not an automated gate. SolOS v2 must decide what the machine-enforced version is (SR-8 is the proposal).
- Online self-modification is described as future work, not implemented; the "automated rollback mechanisms" are named but not specified. SolOS v2 needs to specify the rollback mechanism itself.
- Nothing in the sources specifies a liveness or watchdog primitive. The timeout evidence is all retrospective trace analysis.1 The wedged-provider-call failure needs a design these sources do not supply — treat SR-1 and SR-2 as requirements derived from the evidence, not from a published mechanism.
Sources
1 https://medium.com/@madhur.prashant7/evolve-building-self-healing-ai-agents-a-multi-agent-system-for-continuous-optimization-0d711ead090c2 https://www.mindstudio.ai/blog/ai-agents-business-automation-workspace-capture-evals3 https://www.mindstudio.ai/blog/self-improving-ai-agent-feedback-loop
§6 Merged requirement ledger (counts + provenance)
| Lane | Domain | Requirements | Primary sources |
|---|---|---|---|
| A | Cortex memory + doctrine | 11+ | MemoryAI Protocol v1 (RFC-2119), Hermes arch, MS Agent Framework harness |
| B | Multi-agent architecture | 16 | OpenAI agents-api, LangChain ×2, Microsoft, Meta Muse, xAI Grok Bot, +4 supporting |
| C | Protocol / interop / trust-record | 15 | A2A v1.0.0 spec, OpenClaw multi-agent + 2026.9.6, arXiv 2605.20025v2 |
| D | Self-heal / self-learn / eval | 12 | Evolve self-healing, MindStudio evals, MindStudio feedback loop |
Highest-priority requirements for the current SolOS condition (the wedged-agent, lying-health-check failure mode we have measured repeatedly):
- SR-1 (D) — every provider and tool call carries a timeout and retry budget. The wedge we measured is exactly an unbounded call. from Evolve
- SR-2 (D) — never self-certify liveness; an independent verifier must assert health. Our health endpoints report
runningfor wedged processes. from MindStudio evals - SR-3 (D) — every run is a durable record (trajectory, outcome, exit reason) before it counts as complete. A run living only in session memory has not completed. from all D sources
- Lane C req. 5 — separate trusted record per agent (
agentDirper persona); sharing one across personas is the documented cause of auth/session collisions. from OpenClaw - Lane A req. 5 — memory recall/capture run in the runtime lifecycle (session start, before every prompt, after every turn), never dependent on the agent choosing to. from MemoryAI
- Lane B req. 1 — single-agent-first ladder: no new fleet feature ships as a coordinator by default; multi-agent requires a named limit that was actually hit. from LangChain

