Orchestrata Ultimate / Specs / 111-live-code-substrate

111-live-code-substrate: Live Multi-Agent Code Substrate

SPEC-111 turns SPEC-110's in-memory code-intelligence platform from a per-operation tool into a live, resident substrate that multiple agents edit concurrently and safely. It adds five things SPEC-110 does not have:

At a glance

Item Value
Spec directory specs/111-live-code-substrate/
Status line in the spec Draft
Requirement IDs defined 45
With a @traces citation in src/ 0 (0.0%)
With a @traces citation in tests/ 1 (2.2%)
Tracked files 3
RTM page 111-live-code-substrate

Reading this spec

This spec turns the in-memory code-intelligence platform of spec 110 from a per-operation tool into a live, resident substrate that several agents can edit concurrently and safely. Today an agent edit is a batch round trip: dispatch, work blind against files, return, re-parse, run gates, discover problems, redispatch. That loop causes the multi-hour turnaround and half-applied refactors such as the SPEC-109 gw to slot incident. The substrate collapses the loop so correctness feedback arrives as the edit happens.

It adds five things. A resident forest daemon keeps the lossless CST forest loaded for the whole session, so the cold parse cost of about 9 seconds is paid once. A multi-agent delta and merge model gives each agent an isolated, structurally shared copy of its subtree; agents only propose deltas against a base version, and deltas merge into the canonical forest through a governed, conflict-checked merge queue (described as git for ASTs). Streaming quality gates run review, lint, type-check and blast-radius per delta. A basedpyright oracle runs over in-memory buffers, never disk, as a read-only source of diagnostics and navigation. Agent-steering observability makes every node change observable, so a supervisor can detect and halt a stuck or diverging agent. The design rests on the immutability of libcst.Module: transforms return new trees, unchanged nodes are shared, and immutable data is race-free under free-threading, on Python 3.14t.

The architecture section covers the daemon, working copies, the delta model, the merge queue, the change stream, streaming gates, the oracle, checkpoint and crash recovery, steering hooks and a deterministic Prolog write-gate with an escalation loop. The 45 requirement IDs follow the functional requirement groups: REQ-111-FR1 to FR9 and NFR1. Examples: exactly one resident forest per session; checkouts are structurally shared, so concurrent checkouts of disjoint subtrees add memory proportional only to their deltas; a stale but conflict-free delta is rebased and re-validated while a conflicting one is rejected with a machine-readable reason; every applied change publishes agent id, delta id, node path and before and after hashes; a type-sensitive delta is refused if the oracle fails on the speculative post-merge forest; divergence signals are exposed as metrics; an agent gets a bounded number of retries; and a warm subtree checkout takes under 50 ms.

The spec's status line reads Draft, and no code module cites it. The requirements traceability matrix lists every ID. It tracks 3 files. No src/ symbol cites any of the 45 requirements, so measured trace coverage is 0.0%, and in tests/, 1 requirement is cited by a test-side @traces. All 45 requirements have no citing symbol, the largest groups being REQ-111-FR3 (8), REQ-111-FR9 (8) and REQ-111-FR6 (5); the behaviour may still exist in code that was never annotated.

Requirements

Checkbox is the state recorded in the requirements checklist; Traced by is the count of src/ symbols whose @traces names the ID.

ID Done Requirement Traced by
REQ-111-FR1-001 no The daemon holds exactly one resident CodemodWorkspace.forest for the session lifetime and serves subtree checkouts without re-parsing unchanged modules none
REQ-111-FR1-002 no The resident forest stays consistent with external on-disk edits via debounced watch + hash-gated incremental reparse (only changed modules) none
REQ-111-FR1-003 no A checkout never triggers a full-forest reparse; cold parse occurs at most once per daemon lifetime none
REQ-111-FR1-004 no The resident AST daemon publishes the AST snapshot from its warm cache as the single writer (atomic, byte-compatible with the CLI), on publish and after debounced changes; post-edit hooks spawn no serializer while a daemon is live (ADR-0097) none
REQ-111-FR2-001 no An agent checkout returns an immutable subtree handle plus its base version id none
REQ-111-FR2-002 no Checkouts are structurally shared (no deep copy); N concurrent checkouts of disjoint subtrees add memory proportional only to their deltas none
REQ-111-FR2-003 no An agent cannot mutate canonical forest state; the only write path is a delta submission none
REQ-111-FR3-001 no A delta is a ChangeSet carrying its base version id and node-level edits none
REQ-111-FR3-002 no The merge queue is the single writer to the canonical forest and serializes application none
REQ-111-FR3-003 no On submit, the merge queue detects structural conflicts (overlapping node ranges) AND semantic conflicts (cross-delta dependencies via the CIG) none
REQ-111-FR3-004 no A stale-but-conflict-free delta is rebased onto the current base and re-validated; a conflicting delta is rejected with a machine-readable reason none
REQ-111-FR3-005 no Merge application is atomic (txn.commit_changes) with ConcurrentEditError on a lost update none
REQ-111-FR3-006 no Every delta primitive captures its own inverse at construction; delta.invert() is total and byte-exact; non-invertible primitives are inadmissible (rope §2) none
REQ-111-FR3-007 no delta.describe() renders a structural + textual diff as a pure function with zero forest mutation (rope §2/§6) none
REQ-111-FR3-008 no Each delta records base version tokens of nodes it read/edits; the governor rejects-and-recomputes any delta whose base moved before merge (rope §6, optimistic concurrency) none
REQ-111-FR4-001 no Every applied CodeChange publishes through the async observer mesh with (agent id, delta id, node path, before/after hash) none
REQ-111-FR4-002 no Observers can subscribe to a single agent, a subtree, or the whole forest none
REQ-111-FR5-001 no On each delta, the substrate runs review, lint, type, and blast-radius gates scoped to the delta and streams findings as they complete none
REQ-111-FR5-002 no A delta failing a hard gate (type error, banned construct) is not merged none
REQ-111-FR5-003 no Gate results cite the specific node(s) and requirement/standard violated none
REQ-111-FR5-004 no Before admitting a type-sensitive delta, the oracle runs on the speculative post-merge forest (side-effect-free dry run) and the delta is refused if it fails type-check (rope §6) none
REQ-111-FR6-001 no The oracle is driven over LSP didChange with in-memory buffer text = the delta's emitted .code; it does not read the buffer from disk none
REQ-111-FR6-002 no The oracle exposes diagnostics, hover, definition, references and performs no writes none
REQ-111-FR6-003 no Oracle diagnostics are a strict superset of the current pyright gate (no type-coverage regression) none
REQ-111-FR6-004 no Reference resolution is two-stage (textual/symbol sieve → oracle semantic confirm) returning tri-state {definite, not-a-match, unsure}; unsure is surfaced to the governor, never force-applied (rope §3) none
REQ-111-FR6-005 no Oracle type results cached per CST node id with provenance (inferred-exact|inferred-fallback|unknown); a delta depending on an unknown-typed symbol is not auto-mergeable (rope §4) none
REQ-111-FR7-001 no The substrate checkpoints the canonical forest on a bounded interval and on every merge none
REQ-111-FR7-002 no A checkpoint is byte-exact: restoring it and emitting module.code reproduces the pre-crash source exactly none
REQ-111-FR7-003 no Disk source files remain the canonical, hash-verifiable ground truth; the forest is reconstructable from disk at any time none
REQ-111-FR8-001 no A supervisor can subscribe to the combined change + findings stream for any agent none
REQ-111-FR8-002 no The substrate exposes divergence signals (node-edit churn, non-decreasing findings, growing blast-radius, reddening tests) as observable metrics none
REQ-111-FR8-003 no The supervisor can halt or message an agent mid-edit through the volk event mesh none
REQ-111-FR9-001 no Every node mutation (write/create/delete) in a delta is evaluated by an exhaustive, deterministic Prolog inference gate before the delta is admissible; identical facts always yield the identical verdict none
REQ-111-FR9-002 no The gate rulebase (arch boundaries, banned constructs, absolute-import, os.environ.get, trace-coverage, constitutional constraints) is declared as Prolog rules the agent can query/introspect before editing none
REQ-111-FR9-003 no On rejection the gate returns machine-readable feedback via explain.pl (failing rule(s), offending node(s), why-not proof) sufficient to correct the mutation none
REQ-111-FR9-004 no The agent receives feedback and gets a bounded, configurable N retries to resubmit a corrected delta; each retry re-runs the gate none
REQ-111-FR9-005 no The agent is instructed and able to run a code + test validation workflow (affected code + blast-radius-selected tests) against its working-copy between retries none
REQ-111-FR9-006 no On exhausted retries / unrecoverable verdict, the substrate escalates via the governance escalation path with the full attempt + feedback history none
REQ-111-FR9-007 no Gate evaluation is incremental — only mutated nodes and dependent CIG facts re-derived, not the whole forest none
REQ-111-FR9-008 no Every gate verdict, retry count, and escalation is published on the change/findings stream for real-time supervisor visibility none
REQ-111-NFR1-001 no Warm subtree checkout completes in < 50 ms none
REQ-111-NFR1-002 no Per-delta streaming gate first-finding latency < 500 ms for a single-function delta none
REQ-111-NFR1-003 no Concurrent editing is race-free by construction (immutable shared nodes); no lock guards reader traversal none
REQ-111-NFR1-004 no Resident forest RSS stays within a documented, measured budget none
REQ-111-NFR1-005 no Checkpoint write does not block editing (async / copy-on-write snapshot) none

Code that traces this spec

No src/ symbol cites a requirement of this spec.

Checklists

checklists/requirements.md

The requirement list above comes from this file; 0 of 45 checkbox items are ticked.

Other tracked files

Full spec text

Verbatim from specs/111-live-code-substrate/spec.md; headings are pushed down two levels.

SPEC-111: Live Multi-Agent Code Substrate

Metadata

1. Overview

What

SPEC-111 turns SPEC-110's in-memory code-intelligence platform from a per-operation tool into a live, resident substrate that multiple agents edit concurrently and safely. It adds five things SPEC-110 does not have:

  1. A resident forest daemon — the lossless CST forest (SPEC-110) is loaded once and kept warm for the lifetime of a session, incrementally synced to disk changes, so no operation pays the cold parse cost (~9 s) more than once.
  2. A multi-agent delta/merge concurrency model — each agent receives an isolated, structurally-shared copy of its subtree and may only propose deltas (ChangeSets) against a base version. Agents never mutate a shared tree. Deltas are merged into the canonical forest through a governed, conflict-checked merge queue (MVCC / "git-for-ASTs").
  3. Streaming quality gates — review, lint, type-check, and blast-radius run per delta as the agent edits, not at the end of a batch. Findings stream back in real time.
  4. A type/nav oracle — basedpyright driven over in-memory buffers (never disk) as a read-only diagnostics/navigation source, feeding the streaming gates.
  5. Agent-steering observability — every node change is observable; a supervisor reads the change + findings stream to detect a stuck or diverging agent and correct or halt it in real time.
Why

Today, an agent editing code is a batch round-trip: dispatch → agent works blind against files → return → re-parse → run gates → discover problems → redispatch. That loop is the source of the multi-hour agent turnaround, and of half-applied refactors (the SPEC-109 gw→slot incident: 54 test failures from a missed rewrite, >1 day recovery). The wait was never the editing — it was the blind batch.

The substrate collapses the loop: agents edit an observable in-memory tree, every change is reviewed/linted/type-checked/blast-radiused as it happens, and only conflict-free, gate-passing deltas merge. The result is real-time correctness feedback and safe parallelism, on a Python 3.14t free-threaded runtime whose GIL is genuinely off.

How

The immutability of libcst.Module is the load-bearing property: transforms return new trees, unchanged nodes are structurally shared, and immutable data is race-free under free-threading by construction. That makes "each agent gets a copy of its subtree" nearly free in RAM and safe without locks. Deltas are the unit of change; a governed merge queue (modeled on SPEC-033) is the single writer to the canonical forest; Memgraph's MVCC write-conflict-retry (already in-stack) is the precedent for optimistic-concurrency resolution.

2. Goals / Non-Goals

Goals
Non-Goals

3. Architecture

                 ┌──────────────────────  Resident Forest Daemon (session-long)  ──────────────────────┐
   disk ◀──sync──│  canonical CST forest (SPEC-110 CodemodWorkspace) + CIG + parse cache               │
     ▲           │        ▲ merge (single writer)                    │ subtree checkout (immutable)     │
     │ checkpoint│        │                                          ▼                                  │
  (JSON snapshot)│  ┌─────────────────┐        ┌──────────────────────────────────────────────────┐    │
     │           │  │  Merge Queue    │◀─delta─│  Agent working-copy A (subtree, structurally shared)│   │
     │           │  │ (MVCC/conflict/ │◀─delta─│  Agent working-copy B ...                          │    │
     │           │  │  rebase, SPEC-33)│       └──────────────────────────────────────────────────┘    │
     │           │  └─────────────────┘                     │ every CodeChange                          │
     │           └───────────────────────────────────────────┼───────────────────────────────────────┘
     │                                                        ▼
     │                              ┌───────────────  Observable change stream (AsyncObserver)  ─────────┐
     │                              │  per delta →  review pass · ruff · basedpyright oracle · BlastRadius│
     │                              └────────────┬──────────────────────────────────┬───────────────────┘
     │                                           ▼                                  ▼
     │                                    findings stream                    Supervisor (steering)
     └── crash recovery ◀── checkpoint codec                                  stuck/divergence detection
3.1 Resident Forest Daemon

Extends CodemodDaemon (SPEC-110) to hold ONE CodemodWorkspace.forest resident for the session. watchfiles.awatch + hash-gated load_or_analyze (existing ast_live_sync.py) keep it consistent with external disk edits (git pull, another process). Open question (§8): confirm/upgrade the daemon to hold the forest across calls rather than reload per operation.

3.2 Agent Working-Copies (subtree checkout)

An agent requests a subtree (e.g. session.cli.tasks); the daemon returns an immutable handle. Because libcst nodes are immutable and structurally shared, the "copy" duplicates nothing but the path to the subtree root. Agents hold their base version id for optimistic concurrency.

3.3 Delta Model

An agent produces edits by applying TransformPasses to its copy, yielding a ChangeSet (SPEC-110) — a description of edits against a base version, never a direct mutation of canonical state. Deltas are the only thing an agent may submit.

3.4 Governed Merge Queue

The single writer to the canonical forest. On submit, it: (a) checks the delta's base version against canonical (staleness), (b) detects structural conflicts (overlapping node ranges) and semantic conflicts (via the CIG — e.g. delta A renames a symbol delta B calls), (c) rebases a stale-but-clean delta onto the new base or rejects it, (d) applies clean deltas atomically via txn.commit_changes (existing, with ConcurrentEditError detection). Modeled on SPEC-033's MergeQueue.

3.5 Observable Change Stream

Every applied CodeChange publishes through the existing AsyncObservable/AsyncObserver mesh. This is the spine of both the streaming gates and steering.

3.6 Streaming Gates (per delta)
3.7 basedpyright Oracle

basedpyright (already a declared dep) driven via the existing lsp_client.py over textDocument/didChange with in-memory buffer text = the delta's emitted .code. Read-only: diagnostics, hover, definition, references. Never reads disk; the forest is the buffer source. Distinct from the writer (SPEC-110/109) — the oracle never mutates.

3.8 Checkpoint / Crash Recovery

Periodic + on-merge checkpoint of the canonical forest to a durable snapshot (byte-exact, since module.code round-trips). On restart, reload from the snapshot without a cold re-parse. Disk files remain the ultimate canonical, hash-verifiable source.

3.9 Steering Hooks

The supervisor subscribes to the change + findings streams and computes divergence signals (repeated edits to the same node, findings not decreasing, blast-radius growing, tests reddening) to correct or halt an agent. SPEC-111 ships the hooks and signals; the decision policy is §8 research.

3.10 Deterministic Prolog Write-Gate + Escalation Loop

The hard, deterministic enforcement layer. Every node mutation in a delta — write/replace, create/insert, delete/remove — passes through an exhaustive Prolog inference gate (janus-swi, the project's "deterministic-first" doctrine) before the delta is admissible. This is the node-granularity extension of the existing governance stack (PrologSemanticReview from SPEC-110, governance.prolog_gate / GovernancePrologClient.may_execute, the constitutional rulebase).

The loop is know → attempt → gated → feedback → retry → escalate:

  1. Know (rules are introspectable). The gate's rulebase — the invariants a mutation must satisfy (architectural boundaries, banned constructs, import rules, trace-coverage, constitutional constraints) — is declared as Prolog rules the agent can query before editing. The agent knows the conditions it must cross; the gate is not a black box.
  2. Gated (deterministic verdict). On each mutation the gate evaluates the mutated node(s) + their CIG blast-radius facts and returns a deterministic verdict (same facts → same verdict). Evaluation is incremental — only mutated nodes and dependent facts are re-derived, not the whole forest.
  3. Feedback (why-not proof). On rejection the gate returns machine-readable feedback via explain.pl (the proof-tree / why-not meta-interpreter, may_execute_explained): the failing rule(s), the offending node(s), and the proof of why — sufficient for the agent to correct the mutation, not just "denied".
  4. Retry (bounded). The agent receives the feedback and gets a bounded N retries to resubmit a corrected delta; each retry re-runs the gate.
  5. Run-and-test (the agent validates, not guesses). Between retries the agent is instructed and able to run a code + test workflow — execute the affected code and the blast-radius-selected tests (FR-005 / affected_tests) against its working-copy — so a resubmission is validated, not hopeful.
  6. Escalate. When retries are exhausted or the verdict is unrecoverable, the substrate escalates through the governance escalation path (escalation_handler / pipeline_escalation) to a higher-tier model / governor / human, carrying the full attempt + feedback history.

Every gate verdict, retry, and escalation is published on the change/findings stream (§3.5, §3.9) so the supervisor sees the enforcement loop in real time.

4. User Stories

5. Functional Requirements (authoritative REQ ids)

FR-001: Resident Forest Daemon
FR-002: Agent Working-Copies
FR-003: Delta / Merge
FR-004: Observable Stream
FR-005: Streaming Gates
FR-006: basedpyright Oracle
FR-007: Checkpoint / Recovery
FR-008: Steering Hooks
FR-009: Deterministic Prolog Write-Gate + Escalation Loop

6. Non-Functional Requirements

7. Relationship to existing specs (no duplication)

8. Open Questions / Deferred Research

9. Traceability

All code implementing this spec SHALL carry @traces(spec="111", story="US-00N", reqs=["REQ-111-..."]). The requirements checklist (checklists/requirements.md) is the authoritative REQ-id source; every REQ SHALL trace to at least one test before it is marked complete.