The execution layer — the harness-agnostic substrate deciding where and how agents run.

The framework / capability / sdlc-stage triad models the process layer — what an agent does across the lifecycle. This namespace models a second, orthogonal execution layer — where and how the agent runs. A runtime is the harness-agnostic substrate that provides sandbox isolation, parallelism, branch→PR flow, AFK autonomy, steering, and persistence — an agent execution substrate, not a language, container, or model runtime. It runs Claude Code, Codex, pi, … interchangeably, and could host any process framework’s skills — so it performs no SDLC stage and carries no belongs_to / implements / equivalent_to edge. It connects to the rest of the wiki at exactly one seam: the pattern namespace, via enables:. See CONVENTIONS §The execution layer.

The concepts

The general architecture these members share — the anatomy of a software factory (control plane, trigger, isolation, gates, envelopes), the four design axes, the three progressive profiles (ticket runner → monitored service → fleet factory), and the layer’s glossary (control plane, gate, envelope, intake, …) — lives on topic-software-factory, with the layer’s two architecture diagrams. This index stays navigational: the members, the patterns they supply, and the per-runtime comparison matrix as reference.

Members

RuntimeSubtypeOne-liner
sandcastlelibraryTypeScript SDK — sandcastle.run() sandboxes an agent with a branch strategy and merges commits back; built for parallelizing AFK agents and review pipelines. The embeddable pole.
warrenplatform”Coolify for coding agents” — a self-hostable control plane: dispatch ephemeral agents at your repos, watch/steer live, get a PR back. The service pole.
bernsteinplatform”Kubernetes for AI coding agents” — a goal becomes a task DAG, scheduled by pure Python with no model in the loop, run in parallel worktrees, verified before merge. The coordination pole.
sssflibrary”Agent proposes, code disposes” — a stamped Python control plane where agents are bounded phases, typed JSON envelopes cross every seam, gates verify the claims, and every event streams into SQLite live. No sandbox, no parallelism, by admission. The minimal pole.
gh-awplatform”Actions + Agent + Safety” — GitHub’s own: markdown workflows compiled into hardened Actions lock files; a read-only agent job emits typed safe outputs that separate scoped jobs apply after a threat-detection verdict. The control plane is compiled into CI, triggered by the repo’s own event stream. The event-driven pole.

One caveat on membership, recorded rather than smoothed over: the layer definition calls a runtime harness-agnostic, and sssf runs pi only in v1 (coding_agent: claude_code is schema-valid and raises). It is still filed here because agnosticism is a property of the interface — one agent_*.py module per harness behind one call site, with the second specced and stubbed — and because the agnosticism that matters most to it is at the model layer, where it is total: any provider/model-id in pi’s catalog, chosen per phase, in one run.

Patterns this layer supplies

The execution layer touches the wiki only through the patterns it enables: — each has a process-side roster (capabilities that apply it) and now an infra-side roster (runtimes that enable it):

  • pattern-worktree-isolation — sandcastle (git worktree/branch), warren (bwrap/pod), bernstein (worktree + 7 pluggable backends), gh-aw (ephemeral Actions runner + firewall container/gVisor/microVM)
  • pattern-autonomous-loop — sandcastle (AFK run()), warren (ephemeral dispatch + plan-run), bernstein (tick loop to quiescence), sssf (a bounded chain to a two-part acceptance gate), gh-aw (event/schedule-triggered “continuous X” runs with declared budgets and stop-after)
  • pattern-wave-parallelism — sandcastle (parallel run()s / fork), bernstein (declarative task DAG, topological batching)
  • pattern-session-handoff — sandcastle (session resume/fork), warren (.mulch/ prime + steer + event log), bernstein (handoff emit/claim across surfaces), sssf (agent_map.json rejoins each agent’s own context window across ADWs)
  • pattern-knowledge-compounding — warren (.mulch/ machine-consumable memory across runs), bernstein (confidence-decayed lessons + HITL-gated diary synthesis), gh-aw (cache-memory/repo-memory, integrity-scoped)
  • pattern-deterministic-gates — bernstein (named gate pipeline, required gates hard-block merge), sandcastle (exec()-gated pipeline steps), sssf (per-call gate callables + kind="code" phases; “a known command is code, not an agent”), gh-aw (compile-time scanners + a threat-detection verdict that hard-blocks every write)
  • pattern-evidence-before-claims — bernstein (janitor completion signals + gate pipeline; the agent’s own report is not an input), sssf (gates run after the agent, against the envelope’s own declarations)
  • pattern-cross-model-review — bernstein (review gate DifferentModelRequired; cross-provider verifier)
  • pattern-fresh-context-subagents — bernstein (review gate raises FreshContextViolation on a threaded implementer transcript)
  • pattern-contract-first — sssf (a typed Pydantic envelope is the interface at every seam, re-prompted until it validates) — the layer’s first supply of this pattern
  • pattern-context-engineering — sssf (two output channels only; the previous envelope injected by code, not carried in conversation; bounded output tails)
  • pattern-edit-guardrails — sssf (writes: + protected_files: enforced by diffing the repo around every call and rolling back what the agent introduced) — the layer’s first supply of this pattern; gh-aw (the structural shape: the agent job never holds a write token, so the boundary is the compiled job topology itself)

pattern-evidence-before-claims, pattern-cross-model-review and pattern-fresh-context-subagents arrived with Bernstein and named the layer’s characteristic move: patterns that were process-layer instruction everywhere else in the wiki — verify before claiming, review with a different model, review in clean context — become enforced properties of the substrate, failing loudly rather than degrading quietly when violated. The last three bullets are sssf continuing it from the light end, and they are the two layers meeting at a smaller seam than usual: a typed envelope instead of a conversation (pattern-contract-first supplied as infrastructure for the first time), and a write boundary enforced by reverting the write rather than by asking a human first (pattern-edit-guardrails, likewise).

Reference: the orchestration profile matrix

The runtime layer’s analogue of the SDLC-stage synthesis: the dimensions runtimes are compared on are orchestration concerns, not lifecycle stages. Held as this matrix (not their own node namespace) until the layer grows enough to warrant graduating them — see CONVENTIONS. topic-software-factory distills these eleven concerns into four coarser design axes; this matrix remains the fine-grained record.

Concernsandcastle (library)warren (platform)bernstein (platform)sssf (library)gh-aw (platform)
Isolationcontainer bind-mount / microVM / worktree / noneOS-level bwrap workspace or k8s pod per runworktree by default + 7 pluggable backends (docker · e2b · modal · daytona · blaxel · runloop · vercel)none — current branch, current tree; substituted by a post-hoc rollback of unauthorized writesephemeral Actions runner; optional firewall container (Squid egress allowlist), gVisor, or KVM microVM
Parallelismyou script it — parallel run()s, session forkmany concurrent runs; plan-run is serialdeclarative task DAG — [P] markers + dependency arrows, topological batching, adaptive max_agentsnone — one process, one sequence of phasesper-issue/PR/ref concurrency groups; globally one agent job per engine, queued not dropped
Coordination logicyour TypeScriptthe control plane, one run at a timedeterministic Python — zero LLM tokens on schedulingyour Python — a 40–180-line ADW script of run.phase() blockscompiled into the Actions job DAG — pre-activation → activation → read-only agent → threat detection → scoped writes
Autonomy / AFKmaxIterations + completionSignal + timeoutsephemeral dispatch→validate→push→spin-down; cron; seeds self-claimtick loop to quiescence; adaptive timeouts; retry-with-model-escalation; circuit breaker; cost kill-switcha chain runs unattended to a two-part gate (all phases green and accepted=), bounded fix/revise loopsevent/cron/fuzzy-schedule triggers; max-turns · AI-credit budgets (per-run + daily) · cooldown · stop-after · rate limits
Verificationexec()-gated — your script decidesvalidates before pushjanitor (completion signals + gate pipeline) then a fresh-session, different-model review gategates over the envelope’s claims + kind="code" quality blocks; violations return as corrections to the live sessionthreat-detection verdict gates every write; compile-time actionlint/zizmor/poutine; work quality delegated to the PR’s own CI
Steering (HITL)interactive() before handoff; no mid-run steerreal-time mid-run steer + cancelgate-shaped — permission modes, approval cards, plan-comment approval, hold leases; no mid-run steernone mid-run — the human is the first phase and the exit codetrigger-side only — roles: allowlists, manual-approval: environments, slash/label commands; no mid-run steer
Persistence / memorysession capture/resume/fork; no memory store.mulch/ cross-run memory; canopy prompts; run/cost historyconfidence-decayed lessons, per-task diaries + HITL-gated synthesis, CrossTaskKB, tiered compactionper-session only — agent_map.json resumes each agent’s context window across ADWs; nothing compoundscache-memory (Actions cache, 10GB, ~7d) · repo-memory (git branches, versioned) · per-run artifact trail
Provider-agnosticClaude Code · Codex · pi · Cursor · OpenCode · Copilotclaude-code · sapling · pi (+ canopy custom)40+ adapters — claude · codex · gemini · qwen · ollama · aider · cursor · opencode · pi · droid · copilot · …pi only (claude_code stubbed) — but fully model-agnostic per phase, a different provider/model-id per agent in one run5 engines — copilot (default) · claude · codex · gemini · pi; custom via imports only
Branch → PRbranch strategies; PR is your script’s jobbuilt-in templated auto-PRmerge queue + PR creation; opt-in issue→plan→draft-PR→revise pipeline; never auto-merges—create-pull-request / push-to-pull-request-branch safe outputs, protected-files, issue fallback; never merges
Governance / audit—run history, cost analytics, documented security postureHMAC-chained audit log, signed lineage, offline-recomputable taint verdicts, credential scoping, air-gap profilethe trace is the audit — 7 tables, 10 event types, itemised per-phase spend, gate evidence, pid table; plus writes/protected_files rollbackprompt/output/patch/firewall artifacts per run; gh aw logs/audit/health/forecast/outcomes; OpenTelemetry
Topologya library embedded in your process (local / Vercel)one container (home server) or Kuberneteslocal-first single process; optional coordinator+workers cluster mode; Helm charta stamped adws/ directory; uv run per workflow; optional Bun visualizer over the SQLite fileno server — a gh CLI extension compiling to workflows GitHub Actions runs; GHES; org rollout via gh aw deploy
Distributionlibrary / SDKplatform (UI + API + CLI + SDK)platform (task server + REST/OpenAPI + dashboard + TUI + CLI + MCP server)library, stamped from a Claude Code skill rather than imported — the code lands in your repo to be editedplatform — with a recorded caveat: a compiler + CLI onto GitHub Actions, not a deployable service

Two axes fall out of the matrix, and they are not the same axis. The first is distribution: Sandcastle and sssf hand you primitives to compose yourself, while Warren and Bernstein are deployed services that own the loop end-to-end. The second, visible only once there are several instances, is what the runtime takes responsibility for. Warren owns dispatch and steering — one agent at a time, watched live and redirectable mid-run. Bernstein owns coordination and verification — many agents at once, scheduled by code rather than by a model, with the quality gate pulled down into the substrate. sssf owns the seams — the phase boundary, the typed envelope crossing it, the gate that closes it, and the trace that records all three — and owns nothing else, deliberately. gh-aw owns authorization — what may start a run (roles, approvals, schedules, events) and what may leave one (safe outputs behind a threat verdict) — and compiles both into the CI artifact rather than enforcing them in a process. Each absorbs a process-layer concern into the runtime (Warren a learn-stage one via .mulch/, Bernstein and sssf a validate-stage one via gates), which is the recurring finding of this layer.

The library pole now has two occupants, and they divide cleanly: Sandcastle’s primitives are about the sandbox (run(), branch strategies, exec() gating, session fork) and leave the workflow to you; sssf’s primitives are about the workflow (phases, envelopes, gates, corrections) and leave the sandbox out entirely. Neither ships the other’s half, which makes them closer to complementary than competing — and makes “library vs platform” a weaker distinction than the subtype implies.

A third axis worth naming is weight, and the layer spans two orders of magnitude on it. sssf is a few hundred lines of Python you are told to edit; Sandcastle is a three-line API; Bernstein is 349 documentation pages with a compliance surface, a lineage graph, and a cluster mode. They are not competing at the same scale, and “which runtime” is partly a question of how much infrastructure the work justifies. sssf makes that explicit from the light end — “Is this overkill for a one-off feature? Yes. Prompt an agent and move on. This earns its keep when the same workflow runs a hundred times.”

The light end also demonstrates that the concerns in this matrix are separable rather than a package. sssf ships no isolation at all — current branch, current tree — and says so in its own README, listing a branch per run, a sandbox, and a merge step as “the obvious next things to build”; Sandcastle ships no memory; Warren no real parallelism; gh-aw no mid-run steering at all. Only one row is filled by all five members, and it is verification: every runtime here decided that something between the agent’s report and the merge had to be checked by code — though what is checked varies, and gh-aw marks the boundary case: its gate vets the safety of outputs (secret leaks, malicious patches) while delegating work quality to the CI of the PR it opens. That is the layer’s most-agreed claim.

The broader category

Five documented instances are the start, not the extent. The same layer includes Conductor (already referenced by gstack-context-restore as a workspace host; the canonical worktree-per-workspace, human-invoked orchestrator, a Mac app over Claude Code/Codex/Cursor), Dagger’s Container-use (isolation delivered as an MCP tool to the agent — fresh container + git branch per agent, the control plane left in the prompt), Imbue’s Sculptor (parallel per-agent Docker containers with a Pairing Mode — the HITL-maximal corner, explicitly without worktrees), Vibe-Kanban (a kanban board as the control plane over multiple harnesses; sunset — Bloop shut down in April 2026 and the project is community-maintained, so document it as historical if ingested), and the coding harnesses’ own worktree/sandbox modes — plus Warren’s own os-eco siblings (burrow, canopy, mulch, plot, sapling).

One further candidate surfaced by the software-factory synthesis remains prose-only: the OpenHands software-agent SDK — an open-source (MIT) agent runtime with an agent server, Docker sandbox lifecycle control, and remote workspaces; the open-source remote-fleet counterpart to the sandcastle+bernstein territory. Deprioritized for now as closer to the hosted IDE-agent systems than to a new quadrant — gh-aw, which filled the event-driven cell, was the ingest that changed the map.

Two of the os-eco siblings belong to a different layer: seeds and beads are stores, not runtimes — they spawn no agent and decide nothing about where one runs; Warren consumes .seeds/, not the reverse. The test is a runtime spawns loops; a store is read by them, and beads’ charter states it from the other side, naming “schedulers, swarms, release coordinators” as the layer above it and declining to encode them. mulch and canopy are memory-subtype store candidates on the same test, not runtimes. Ingest more as they warrant pages; graduate the matrix above into derived nodes if it stops scaling.

A fourth layer now leans on this boundary. The registry layer, minted 2026-09-12, brought a product that partly does this job: tessl ships tessl-launch (run a capability locally or in a cloud sandbox against a repo) and tessl-schedule (run a registry plugin on a cron, with pause, resume, and run history) — scheduled-trigger autonomy by this layer’s own taxonomy. It is filed as a registry because the unit executed is a registry plugin, the execution serves the index rather than the other way round, and there is no coordination surface at all: no fan-out, no queue, no steering, no isolation model beyond the sandbox. It runs one thing. Apply the same test used above and on the harness page — a runtime owns coordination policy — and it fails cleanly today. It may not tomorrow: the product’s own tagline is “from scaling skills to building your software factory”, and a supply platform that grows fan-out or steering becomes a member of this layer. Recorded here so the boundary is re-checked rather than rediscovered.

Boundary call recorded (2026-09-26): the Factory in builder-skills is not a member of this layer, even though it calls itself a software factory and covers every socket of the factory anatomy. It ships only instructions and borrows the scheduler, connectors, worktrees, and credentials from the host, so it spawns no loops. That fails the “a runtime spawns loops” test and puts it in the process layer. It is recorded on the software-factory topic as the 🧩 skill-pack pole, the prompt-owned control plane this layer’s members were built to move away from. Re-ingest trigger: if Builder ships a service or CLI that creates and runs the jobs itself, rather than asking the host to, re-check the call.

5 items under this folder.