AI automation is everywhere now, and used well it genuinely multiplies what a team can ship.
But ubiquitous is not the same as complete. The current generation of agentic tooling still
has gaps, and PlotWarden, CogniCluster's orchestrator of ambient agents, is built to close one
of the most expensive ones.
Agentic workflows shine in constrained spaces: a well-specified task, a stable spec, a
bounded codebase, the right context, skills, and MCP servers, and oversight watching the run.
Hand an agent that, and it comes back with credible work. Real product environments are not
constrained. They are complex systems with many moving parts, where specs, features, and code
all change constantly and at once.
A workflow that was correct when it started quietly stops being correct while it runs,
hallucinations slip in and cascade through everything built on top of them, and today a human
closes that gap by hand, re-reading and re-planning between every session.
PlotWarden closes it continuously. It consumes changes wherever your specs actually live,
GitHub issues, wiki edits, and the codebase and flows themselves, and maintains two living
maps: the authoritative spec and the current state of your system, linked so it knows exactly
how they relate. When the two drift, it reconciles, and this is the part built for the real
world: it reconciles changes in flight, re-planning running work instead of restarting it.
Work that a change made stale isn't an error, it's a superseded order: finish what survived,
recall what didn't, salvage the partial. And when a change contradicts the spec or trips a red
flag, it doesn't guess. The work blocks, the conflict surfaces on a review site where your team
talks it through, and the resolution pipes straight back into the running project as ratified
truth. Humans set direction and adjudicate genuine conflicts; everything else runs ambient.
Minimal human-in-the-loop by design, not by neglect. The name is literal: in a ship's
operations room, the plot is the authoritative picture of where everything is, kept true as
every new report flows in. Keeping the plot is the job.
What exists today is stated plainly. v0.1.5 is a working scaffold: Temporal workflows, a
Postgres event log, Docker-isolated workers, and tool proxies that turn ordinary commands into
manager-reviewable evidence. 37 passing tests, 14 published invariants, one rule underneath:
workers produce evidence, never authority. APIs are unstable and the spec is public so you can
argue with it while it's still cheap to change.
01 · Architecture at a glance
One manager owns the graph. Everything else produces evidence.
The scaffold is deliberately small: a local authority layer (working name: Orchistractor)
that owns a typed software-work DAG, dispatches isolated worker jobs, records every tool
command the workers run, computes contract-aware and claim-aware invalidation over the graph,
and gates completion and merges behind epoch, hash, and policy checks.
Owns the DAG, epochs, policy, invalidation, and merge authority. A DB-backed command processor turns every consequential mutation into a durable command row, an event row, and an idempotency key. Shipped in v0.1.5
Durable execution: Temporal
A real activity adapter calls the command processor; the deterministic workflow carries only IDs and results, never graph snapshots. Production Temporal deployment is not included. Shipped in v0.1.5
Source of truth: Postgres
Graph and event log via SQLAlchemy. Every official state transition is an event. When integrations disagree, the event log wins semantic truth. Shipped in v0.1.5
Artifact plane
Run-scoped inbox, outbox, artifact, and scratch directories on the local filesystem, behind an interface intended to later use MinIO/S3. Artifact bytes are hash-verified before import. Shipped in v0.1.5MinIO/S3: Roadmap
Worker boundary: Docker + tool proxies
Deterministic docker run construction, a run-state machine, best-effort kill, and PATH-first proxy shims that record every tool command as evidence. Shipped in v0.1.5
The rule the whole design serves, quoted from the scaffold's README: "Workers can explore.
Workers can test. Workers can generate patches. Workers can propose PR comments. Workers do
not mutate official DAG state, merge protected branches, publish packages, deploy, or post
official comments. The Orchistractor does those after checking epoch, dependencies, tests,
contracts, claims, and policy."
02 · Run it locally
Five commands to the test suite and the demo.
This is the v0 path, quoted from the repository's own quickstart. It needs Python 3.12 and
nothing else: the test suite and the contract-break demo run without Temporal, Postgres, or
Docker. The repo is not public yet, so the clone step is the one placeholder.
$git clone <repo not public yet> orchistractor && cd orchistractor$python3 -m venv .venv && source .venv/bin/activate$pip install -e '.[dev]'$python -m pytest -q37 passed$make demo# examples/tiny_services/run_contract_break_demo.pyPASS: checkout is affected, notifications is preserved
Shipped in v0.1.5 · make test · make lint · make api · make demoAPI shell: make api serves FastAPI on :8088 and requires an Idempotency-Key header on consequential POSTs
A control-plane docker-compose file and two-server bootstrap scripts exist as shells
(infra/docker-compose.control.yml, scripts/bootstrap_server_a.sh,
bootstrap_server_b.sh); finishing the deployment path is
Roadmap task 9, so it is deliberately not part of this quickstart.
03 · The evidence path
One worker run: task, proxy, policy, evidence, review.
The premise, quoted from the architecture doc: "Do not ask LLMs to avoid normal commands...
The correct move is to put wrappers first in PATH. The worker believes it is using normal
tools. The manager gets the ledger." Here is the full path a single command takes.
Sequence: worker command, PATH shim, policy resolution, one of four outcomes, evidence record, outbox import, completion gate.
Inside the container, the worker runs an ordinary command such as mvn test or gh pr create. The worker image puts wrapper shims first in PATH; each shim is a 3-line exec into the proxy module.
The wrapper hands the full argv to orchistractor.tool_proxy.proxy.
The proxy loads policy: built-in defaults, plus optional task-specific JSON overrides from ORCH_TOOL_POLICY_PATH. Unknown policy names fail closed with exit code 125.
Whatever the outcome, it appends a rich record to /outbox/tool-events.jsonl: project, run, task, epoch, input commit, worker image digest, proxy version, argv, cwd, timestamps, policy and reason, stdout/stderr artifact paths with sha256 hashes, and discovered test-report paths.
The run's outbox accumulates tool-events.jsonl, build-invocations.jsonl, four intent files, and captured logs.
The outbox importer turns those files into database evidence records, gated on a _COMPLETE marker and hash checks. The completion gate then decides accepted, suspect, stale, quarantined, or rejected under the current epoch.
worker$pytest -qpolicy: proxy_local· runs the real tool, records exit code, hashes stdout/stderr, finds test reportsworker$gh pr create --title fix --body donepolicy: intent_only· no side effect; request recorded to pr-intents.jsonl for the managerworker$docker build -t app:dev .policy: proxy_remote_stub· not executed; build request recorded to build-invocations.jsonlworker$kubectl apply -f deploy.yamlpolicy: deny· refused, recorded, nonzero exitoutbox/: tool-events.jsonl · build-invocations.jsonl · pr-intents.jsonl · comment-intents.jsonl · issue-intents.jsonl · git-intents.jsonl · logs/*.stdout · logs/*.stderr
Shipped in v0.1.5 · TOOL_PROXY_VERSION = "0.1.5" · 7 dedicated tests"The proxy itself does not accept, merge, deploy, or publish anything."
04 · What exists in v0.1.5
The shipped-status table, stubs labeled in caps.
Every claim on this page wears exactly one label from this ladder. The repo's own framing,
from its README: "This repository is a buildable scaffold, not a finished product."
Shipped in v0.1.5 · code in the package, tests or notes citedDemoed locally · runnable here todayDesigned · code or docs exist, not wired or not testedRoadmap · a numbered task, not builtVision · direction, no implementation claim
Component
What it does
Evidence
Label
Command processor
Project, node, edge, contract, claim, dispatch, and kill-run commands as DB transactions with idempotency keys, event rows, and epoch advancement
python:3.12-slim with the package installed and proxy wrappers first in PATH
docker/worker-base/Dockerfile
Shipped in v0.1.5
FastAPI manager shell
API requiring Idempotency-Key on consequential POSTs
app/main.py · 198 lines
Designedshell-grade
Policy engine
Auto-ratifies objective cases to remove human-in-the-loop
core/policy.py · NO TESTS
Designedskeleton
Merge gate
Pure function: run status, support currency, poisoned claims, merge-order blockers, required tests
services/merge_gate.py · 35 lines · NO TESTS, NOT WIRED to any Git adapter
Designedwiring is Roadmap task 7
Infra shells
Control-plane compose file, systemd unit, two-server bootstrap scripts
infra/, scripts/
Designedfinish: Roadmap task 9
Tiny-services example
Billing, Checkout, Notifications graph; Billing v1 vs v2 contract-break demo, runnable without Temporal or Docker
examples/tiny_services/
Demoed locally
Git / Gitea / GitHub adapters
Manager-owned PR and merge authority
STUB: no adapters module exists in the package
Roadmap task 7
Claims service module
Dedicated claim-poisoning service
STUB: services/claims.py does not exist; poisoning itself ships inside the command processor, tested
Roadmap task 8
End-to-end demo script
scripts/demo_v0.sh
STUB: 3 lines, currently just runs the tiny-services demo
Roadmap task 10
Remote build execution
Live build runner behind proxy_remote_stub
STUB: requests recorded to build-invocations.jsonl only
Roadmap
LLM worker invocation
Real model workers inside the Docker boundary
ABSENT: explicitly not built
Roadmap
UI
Any user interface
ABSENT: explicitly not built
Roadmap · Milestone 11 extras
05 · Design invariants
Fourteen rules, reproduced verbatim.
From docs/INVARIANTS.md in the scaffold, quoted as written. Orchistractor is the
manager component's working name.
Only the Orchistractor advances epoch.
Only the Orchistractor mutates official DAG state.
Workers never merge to protected branches.
Workers may produce patches, manifests, logs, and proposed comments.
Every official state transition is an event.
Every worker run is tied to project id, task id, run id, epoch, input commit, and worker image digest.
A worker result is not mergeable unless completion is accepted under the current epoch.
A killed worker's output is quarantine-only.
A stale worker's output is quarantine-only unless explicitly salvaged.
A poisoned claim fans out to support-read consumers.
A breaking contract change fans out to consuming tasks/services.
Build/test success is evidence, not merge authority.
Artifact bytes are hash-verified before import.
Beads/Gitea/GitHub/Temporal/artifact store may disagree temporarily; Orchistractor event log wins semantic truth.
Companion invariant · Docker runner
"The Docker runner never accepts worker output. It only produces completed, quarantined, or killed run states. The outbox importer and completion gate decide whether completed bytes can become accepted evidence." (Milestone 4 notes)
Companion invariant · authority writes
"Build/test commands may be noisy and advisory; authority-owning writes are not. PR creation, official comments, protected-branch pushes, merges, deploys, publishes, and infrastructure mutations must route through the manager." (Milestone 5 notes)
Shipped in v0.1.5 · the tested components enforce these; the merge gate enforces them in design only until Roadmap task 7
06 · Tool proxy policy
Four outcomes. Unknown policies fail closed.
This section reproduces docs/TOOL_PROXY_POLICY.md in page form. Every command a
worker runs resolves to exactly one of these outcomes, and every resolution is recorded.
PROXY_LOCAL
meaning · run the real local tool
records · stdout/stderr, exit code, timestamps, cwd, argv, report paths
default for · ordinary commands: pytest, mvn test, git diff
PROXY_REMOTE_STUB
meaning · do not run; record a build-manager request
records · build-invocations.jsonl plus a matching tool event
default for · docker build, docker buildx
note · ORCH_FORCE_REMOTE_BUILD=1 extends this to mvn, dotnet, npm, and pytest build/test commands
INTENT_ONLY
meaning · no side effect; record the requested action for the manager to execute or reject, return success to keep worker ergonomics
Shipped in v0.1.5 · hardened in Milestone 5per-task overrides: command-prefix rules and per-tool defaults via ORCH_TOOL_POLICY_PATHremote builds are recorded, not executed: the live build runner is Roadmap work
07 · Failure and invalidation
A contract breaks. The graph knows who to tell.
The graph is typed: 13 node types, 14 edge types, 9 dispositions, 5 claim statuses, 4 contract
compatibility classes. Invalidation is a pure breadth-first walk over reverse consumer edges,
capped at depth 32, that classifies impact per edge type. Conservative by design: v0 can
over-invalidate slightly; it must not merge known stale work.
Flow: contract change, diff classifier verdict, BFS over typed edges, per-node dispositions, reruns and blocked merges.
1 · Classify the change
Removed fields, added required fields, or type changes are BREAKING. Only added optional fields are ADDITIVE. Otherwise COMPATIBLE; unparseable is UNKNOWN.
2 · Admit it durably
The command processor records the mutation with an idempotency key, appends an event, and advances the epoch.
3 · Walk the consumers
consumes_contract on a breaking change: repair_needed. On compatible or additive: retest. consumes_claim on poisoning: stale. reads_support on a breaking kind: suspect. depends_on: suspect or retest. implements_contract: repair_needed. validates: retest. produced_by, modifies, merge_after: merge_blocked.
4 · Apply dispositions
Affected consumers become repair_needed, stale, suspect, or blocked. Unrelated siblings are preserved. Affected runs are killed or quarantined, or repair tasks are created.
5 · Re-check at the gates
The completion gate rejects mismatched run or epoch, quarantines killed runs, marks stale-support results stale, and marks clean older-epoch work suspect. The merge gate re-checks support currency, poisoned claims, merge-order blockers, and required tests (designed; not yet wired to any Git adapter).
6 · Claims have a lifecycle
unverified, then accepted, disputed, poisoned, or superseded. Poisoning is a first-class command with support-consumer fan-out, implemented and tested inside the command processor. The full kill-candidate and repair machinery is Roadmap task 8.
Run lifecycle: requested through dispatched and completed, ending accepted and merged, or quarantined. Killed and stale output is quarantine-only.
The runnable proof today
The Billing v2 demo builds a Billing, Checkout, Notifications graph, swaps
billing_v1.schema.json for billing_v2.schema.json (amount_cents
replaced by amount_minor, a breaking change), computes the invalidation plan, and asserts that
checkout is affected while notifications is preserved.
$python examples/tiny_services/run_contract_break_demo.pyPASS: checkout is affected, notifications is preserved
Demoed locally · runs without Temporal or Dockerthe scripted end-to-end version of this story is Roadmap task 6, next up
08 · Milestones and changelog
Five milestones shipped. The test count is the growth chart.
Versions follow SemVer 0.y.z and the changelog keeps per-milestone validation blocks. The
milestone notes are summarized here because the repo is not public yet.
Cumulative passing tests per milestone, real series from the changelog: 17, 20, 26, 32, 37.Milestone 1 · v0.1.1 · DB-backed command processor · 17 tests
Consequential mutations become durable command rows, event rows, idempotency keys, and epoch advancement. Epoch advances for node creation, edge creation, contract supersession, claim creation, and claim poisoning; task dispatch records a run without advancing epoch. Claim poisoning ships here as a first-class command with support-consumer fan-out.
A real activity adapter calls the command processor. The deterministic ProjectWorkflow carries only command and result IDs, never graph snapshots or artifacts. A compat shim lets the suite run without temporalio installed. Production Temporal deployment is explicitly not included.
Milestone 3 · v0.1.3 · Artifact store and outbox importer · 26 tests
Run-scoped inbox, outbox, artifact, and scratch layout on the local filesystem. The sealed-order writer produces a hashed worker inbox envelope carrying ids, observed epoch, input commit, image digest, allowed paths, hard constraints, and tool policy. The importer requires a _COMPLETE marker, validates manifests, hash-checks patches and reports, quarantines killed runs, and re-imports idempotently.
Deterministic docker run construction, a mounted worker filesystem contract, run and task and epoch env and labels, a run-state machine with best-effort kill, and an executor seam so the tests run without Docker. The runner never accepts worker output; it only produces completed, quarantined, or killed states.
Rich tool-event records, four policy outcomes, manager-owned intents, default denials, remote-build stubs, policy-file overrides, and fail-closed unknown policies. TOOL_PROXY_VERSION is 0.1.5.
Test evidence, counted not vibed
37 test functions in the package's tests directory, counted statically with
grep -rh "def test_" tests/ | wc -l. This matches the repo's recorded pytest
result, "37 passed", in the README and the v0.1.5 changelog validation block. One more test
lives in the tiny-services example, bringing the whole-repo total to 38; 37 is the package's
own stated baseline.
Ten numbered tasks. Five shipped, one next, four designed.
The prompts directory holds exactly ten prompt-sized tasks, each deferring to the roadmap doc
as source of truth and each repeating the authority rule: the manager's DB and event log own
semantic truth; runners, Temporal, Git, and artifacts do not. States follow public-roadmap
convention: shipped, in progress, designed, exploring. No dates are promised.
Shipped
1 · DB event log and command processor · v0.1.1
2 · Temporal ProjectWorkflow wired to DB · v0.1.2
3 · Artifact store and outbox importer · v0.1.3
4 · Docker runner · v0.1.4
5 · Tool proxy hardening · v0.1.5
In progress · next
6 · Contract-aware invalidation demo, end to end and scripted: Billing v2 ratified, checkout stale with a repair task, notifications preserved, readable transition log
Designed
7 · Git/Gitea manager adapter: the manager applies worker patches, opens PRs, posts official comments, merges only if the merge gate passes
v0.1.5 is a working prototype scaffold, not a production service. APIs and schemas may change
before v1.0. The README's "not included yet" list, verbatim:
Production-ready Temporal deployment.
GitHub/Gitea merge implementation.
Real worker LLM invocation.
Full artifact import/export to MinIO/S3. The importer and runner are local-filesystem first.
Full UI.
ABAB/falsifier harness.
Beads adapter.
Merge gating is design plus completion gate
The completion gate is implemented and tested. The merge gate is a 35-line pure function with no tests and no Git wiring, so merge authority is enforced in design, not by a live merge pipeline.
OpenAPI handling is best-effort
The contract diff classifier's OpenAPI extraction targets tiny v0 demo documents, not arbitrary specs.
The demo script is 3 lines
scripts/demo_v0.sh currently just runs the tiny-services demo. The one-command full loop it is named for is Roadmap task 10.
One stale line we know about
The README's "Next step" section still says to start Milestone 5 while the changelog and status line show Milestone 5 complete. Left here so the page never claims the repo is tidier than it is.
11 · Vision archive
The design vision, kept on file.
VISION · no implementation claimstatus-labeled archive · where this material disagrees with the sections above, the sections above win
The destination is an orchestration layer for parallel AI development work where agents can
act independently but cannot bypass evidence, policy, invalidation, or manager-owned merge
authority. The current scaffold implements the control-plane primitives; the roadmap tracks
the remaining product work.
Everything below was written when Ambient Agents was a design and this site was its spec.
It is kept intact, lightly relabeled, because the ideas still steer the roadmap. The archived
thesis: "You don't build ambient agents. You compile them."
Archived vocabulary, translated
Plain term first, archived flavor second. Two terms were retired outright: the review gate (formerly "war council") and the manager / control plane (formerly "harbormaster").
Worker jobs
Archived as "the fleet". Dispatched, isolated runs; one run was "a ship".
Worker inbox envelope
Archived as "sealed orders". Now literal: the sealed-order writer ships in v0.1.5 as a hashed inbox/sealed_order.json.
Review gate
Replaces "war council". The adversarial cross-family review that convenes on invalidations and retractions.
Manager / control plane
Replaces "harbormaster". Admission control and the economic plane: budgets, throttles, kill authority.
Plan graph
Archived as "the plot". The constantly corrected operational picture everything else acts on.
Archived as "superseded orders". Handled by drain, kill with budget refund, or salvage into quarantine.
Quarantine
Kept unchanged; it was already precise, and v0.1.5 implements it in the importer, the runner states, and the enums.
Durable substrate
Archived as "the carrier". The standing Temporal workflow; missions outlive machines.
Decision queue
Archived as "one inbox". The fleet-wide human-in-the-loop queue.
VISION · archived concept scene
Archive · Act I · The blocking task
I'm building Black Skies solo: a real-time multiplayer tactical space card game with a design
target of 10,000 concurrent players in one persistent battle space. Most of the code is written
by agents. Task-level throughput stopped being my constraint months ago. Hand an agent a
well-specified task and it comes back with a credible PR. That part is solved enough.
One asymmetry stays on the table: Horizons shipped and Black Skies hasn't yet, which is exactly
why this site is framed as an experiment with a kill date instead of a victory lap.
Take the watch. Apply the reports before the plot goes stale.
I automated the typing and became the scheduler.
contact reports pile up · nobody re-plans
the plan still points here
the plot, going stale one delta at a time
the work keeps executing the stale plan
How it actually works
I've shipped this genre before. Alteil Horizons, an online card game with its own distributed
backend, took a funded company: a team working under me, B2B money, and a Kickstarter to get it
over the line. The part that took me a decade to see clearly is that most of what that team
absorbed wasn't typing. It was deltas. Design changes fanning out into task lists. Bug reports
invalidating assumptions mid-sprint. The publish schedule drifting from reality. Producers,
leads, and QA triage were a reconciliation loop, run on humans, and they earned their pay doing
it. This time the headcount is one. Agents replaced the hands. Nothing replaced the coordination
layer. The gap between those two sentences is the product.
A normal week
I ratify a design change to the engine's fan-out path. Three in-flight tasks were written
against the old interface and don't know it. A reviewer flags a real defect in a PR, which
spawns rework that should preempt two queued tasks. Six GitHub issues arrive: two are duplicates
of things already fixed, one quietly invalidates an assumption inside a mission that's currently
executing. My working architecture document and the published devblog drift apart again, and the
alignment matrix between them grows another row.
None of that is code generation. All of it is plan maintenance. Every delta partially
invalidates a DAG of planned work, and every tool I use keeps cheerfully executing the stale
version until a human re-plans. That human is me. I automated the typing and became the
scheduler. For a solo founder, plan freshness is the blocking task.
Naming the pattern
The shape of the fix is familiar from infrastructure. Kubernetes doesn't run scripts. It
reconciles observed state toward desired state through a control loop: a watch stream of
events, a declared desired state, and a controller that closes the gap.
Apply that to development work. The plan graph is desired state. The delta queue is the watch
stream: GitHub issues, PR reviews, ratified design documents, roadmap changes, budget events.
The orchestrator is the controller. It consumes deltas, mutates the DAG at safe points while
work is in flight, and dispatches ready nodes to whichever runtime fits them.
The distinction that matters: task-level automation reacts when a trigger fires. Plan-level
reconciliation decides what that trigger means for everything else in flight. Those are
different products, and the first one is already crowded.
task throughput: solved enoughplan freshness: the blocking task
Archive · Act II · Two campaigns
TODAY · AS OF JULY 2026
A new project, compiled
You have a spec and an empty repository, and you know your tools.
Today
You write the spec with a spec-driven kit (Spec Kit, OpenSpec) and decompose it into a dependency-aware graph (Beads, Taskmaster).
With the watch
The same graph compiles into a campaign: sealed orders, budgets, and gates stamped on every node.
The same evidence routes to gates that can hold a merge until the contract is met; review verdicts attach to plan nodes, not just PRs.
Today
You track spend on a gateway (Portkey) and stop runaways by hand.
With the watch
Budgets are planner inputs: recalls refund the mission, and done means the spec satisfied at the current epoch. The standing watch remains.
A living system, decomposed
You have a monolith that works, and you want DDD-bounded services that communicate over contracts, without stopping the world.
Today
You survey with a whole-codebase context tool (Sourcegraph Amp) and agents charting seams and coupling, pulling current library docs into the session as you go (Context7).
With the watch
Survey findings land as plot nodes with lineage, not documents that drift.
Today
You draw the boundary map into bounded contexts yourself; good shops use models as sparring partners, and humans own the domain boundaries.
With the watch
Unchanged on purpose. The map is a Review-pattern gate: the fleet proposes, you ratify. This gate never relaxes.
Today
You freeze behavior with characterization tests before touching anything.
With the watch
Test coverage becomes the evidence contract for every extraction node.
Today
You strangler-extract one context at a time into services with explicit contracts, old system still serving.
With the watch
Each extraction is a bounded campaign on the plot; cross-service interface changes propagate as appends, not surprises.
Today
You verify parity old-versus-new per extraction and triage differences by hand.
With the watch
Parity gates hold promotion; every difference is presumed a legacy bug until proven otherwise, and the whole migration is one governed campaign.
Halfway through either campaign, a design decision lands. Three tasks in flight are now
wrong. Today, the best answer is a person re-reading the whole board between sessions.
Under the watch, the plot re-plans: drain what survived, recall what did not, salvage the
partial work. That is the demo, below.
Archive · Act III · The kernel design
Not a workflow engine that runs a plan. A controller that keeps the plan itself correct while
a heterogeneous fleet executes it. Two loops, decoupled by a queue: the planner consumes deltas
and emits DAG mutations, the executor watches for ready nodes and dispatches them to workers.
Everything below is a consequence of taking that claim seriously on top of Temporal.
a delta arrives with its provenance envelope
the graph is data; a standing workflow interprets itmutations: append · amend · reprioritize · invalidate · retractreview gate convenes on invalidations and retractions
drain: let the worker finish; accept the result if the node survivedrecall: stop the worker, refund remaining budget to the missionsalvage: quarantine partial output for review; stale work is frequently half right
epoch bump: the plan changed while the work was in flight
drain: the node survived, the result is accepted
recall: remaining budget refunds to the mission
salvage: partial output quarantined for review
Before the system preempts paid-for work, a cross-family panel argues in front of the gate, and I keep the dissent.How it actually works
The plot is data, not workflow code
The tempting design is to express the plan as a Temporal workflow: nodes as activities, edges
as control flow. It fails immediately, because Temporal workflows are deterministic code and
this plan must mutate at runtime in response to external events. So the plan graph lives as
versioned data. Nodes carry task specs and state: pending, ready, dispatched, blocked-on-human,
done, stale. Edges are dependencies. Missions are subtrees with their own budgets and gates.
A long-lived orchestrator workflow interprets the graph rather than embodying it. That
standing workflow is the carrier, the durable Temporal substrate: missions outlive machines.
External deltas arrive as Temporal signals and updates. Signal-with-start means an inbound event either
wakes the standing orchestrator or creates it, which collapses the cold-start case.
Continue-as-new bounds event history, because a reconciler that runs for months will otherwise
drown in its own history.
The queue contract
Webhook delivery is at-least-once, so the delta queue enforces idempotency and order at
ingestion. Every delta carries a provenance envelope: source, actor identity, delivery id,
trigger lineage, and the plan epoch it was observed against. Dedup keys come from delivery
ids. Ordering is per aggregate (per repository, per mission), not global, because global
ordering is neither achievable nor needed. Actor identity and lineage are not bookkeeping.
They are the loop-safety mechanism.
In-flight mutation is a fencing problem
Here's the part I didn't expect to reuse. Mutating a DAG while workers execute against it is
the same problem as mutating partition ownership while nodes serve traffic, and Black Skies
already solves that with epoch-based lease fencing. Same discipline, different substrate. The
plan graph carries a version number per subtree. Treat versions as epochs. Every dispatched
worker is stamped with the epoch it launched under. When a delta invalidates a subtree, the
epoch bumps. Results arriving from stale-epoch workers are not errors. They are superseded
orders, handled by per-node policy.
One consistency discipline, instantiated twice: once to keep 10,000 players coherent in a
persistent battle space, once to keep a fleet of coding agents coherent under a changing plan.
Five mutation classes
Not all deltas cost the same. Append: new issue, new PR, new task; cheap, additive, safe to
apply eagerly. Amend: a node's spec changes without invalidating its subtree. Reprioritize:
ordering and budget shifts only. Invalidate: a subtree is wrong now; destructive and expensive.
Retract: work must be undone, not just stopped; rarest and most expensive.
Appends run on cheap heuristics. Invalidations and retractions are exactly where the war
council earns its place: before the system preempts paid-for work, a cross-family panel
reviews the invalidation set and captures dissent. In v1, that's the only place the gate
is mandatory. Why the panel must span model families is structural, and the non-goals
section below covers it: no vendor governs its competitors' agents.
Gates consume evidence, not vibes
A review gate is only as good as the artifacts in front of it. The review panel doesn't judge a
diff in the abstract; it judges a diff plus what the change demonstrably does. So every worker
class carries an evidence contract, and the evidence generators are adopted, never built. The
kernel's job is routing the right evidence to the right gate and holding a merge when the
evidence contract isn't met.
Current adapters, as of July 2026. Replaceable adapters, adopted rather than built. Not partnerships, not endorsements.
Completed-work demos: screencasts that cloud agent runtimes already produce
Anything with tests: CI results, the boring, primary evidence class
Black Skies arguments: load-simulation output
IFF, because two ambient systems can retrigger each other
My orchestrator reacts to GitHub events. Cursor Automations react to GitHub events. A PR
comment written by one is an event to the other. Without guards this converges to two vendor
bots arguing in a PR thread at my expense. The guards: actor-identity filters at ingestion,
lineage tags propagated onto every event the system emits, cycle detection over lineage
chains, and per-trigger budgets so that even an undetected loop exhausts a bounded allowance
and parks for human review instead of running open-ended.
The control plane: thrash has a price
A constantly fresh plan can oscillate and never finish anything. Damping is a first-class
requirement: minimum work quanta before a node is eligible for preemption, damping windows
that batch low-priority deltas, and cost-of-change accounting on every proposed mutation.
Preempting a node wastes its sunk spend plus restart and context-rebuild cost; the planner
weighs that against the cost of finishing stale work. The quiet consequence is that budget
machinery stops being a bolt-on. Spend caps, refunds, and kill authority become planner
inputs, and the planner becomes an economic scheduler optimizing freshness against cost
under a mission budget.
Standing watch, or sortie
Continuous deltas dissolve done unless you define it, so there are two campaign types with
different contracts. A standing watch never finishes and is governed by SLOs instead:
delta-to-plan-updated latency, issue-to-triaged time. A sortie must finish and carries a
protected critical path that freshness is not allowed to starve. For a sortie, done means
the spec is satisfied at the current epoch, not at the epoch the campaign started under.
Archive · Act IV · What it refuses to be
Task-level triggering is being commoditized as I write. Cursor's Automations configure
always-on agents with GitHub and Slack triggers from a plain-language description. OpenClaw
grew from a viral personal assistant into a runtime with durable multi-step flows, a unified
task ledger, and multi-agent workflow definitions. OpenHands and GitHub's Agent HQ host and
assign agents against repository events. All of it is real, all of it is useful, and all of
it reacts at the task level.
The seat above the runtimes is empty because every vendor is disqualified from sitting in it.
Four capabilities live in that empty seat
Cross-runtime authority
One plane that can dispatch, budget, preempt, and kill work regardless of which vendor executes it.
Adversarial verification as a blocking gate
Cross-model-family review with dissent capture that can hold a merge, not best-of-n sampling inside one harness.
An economic control plane
Global budgets, kill authority, and reentrancy guards across vendor bots that each only police themselves.
One inbox
Park-for-days semantics tied to durable workflows, with decision requests aggregated fleet-wide instead of scattered across per-tool sidebars.
The best tools in each category are genuinely good, and the design drives them rather than
replacing them. What I add is the seat none of them can take.
Dispatch flows down with orders and budgets. Results flow up through the gate. Decisions park in one inbox.
The seat adds the decision record beside the traces: invalidation reviews, captured dissent, and every budget event, tied to plan nodes.
How it actually works
None of it mutates a live plan, and structurally none of it can, for one reason: re-planning
is only meaningful if you have authority over all in-flight work, and no vendor governs its
competitors' agents. Cursor can't preempt a Claude Code session. OpenClaw's task ledger
doesn't see Cursor's cloud agents. The seat above the runtimes is empty because every vendor
is disqualified from sitting in it.
This is the same positional logic as Temporal versus each cloud's native workflow service.
A neutral layer, not a feature. The honest corollary: it's a position, not a technical moat,
and the price of holding it is integration surface. Which is why events get consumed at the
Git layer, where the vendors already converge, rather than through N proprietary APIs.
The refusals
No event transport. GitHub webhooks and EventBridge exist.
No agent hosting. The cloud agent platforms exist and are good.
No browser automation or test framework. Playwright, its agentic wrappers, and CI exist; the kernel consumes their output as evidence.
No IDE, no editor plugin, no new agent framework.
The product is the seat above those things, and the discipline is refusing to rebuild
anything that already has a vendor.
Archive · About the name
"Ambient agents" is LangChain's term,
introduced in January 2025. Harrison Chase
defines them as agents
that "listen to an event stream and act on it accordingly," in contrast with chat agents that
wait for a human message. The ecosystem built on that: event-driven initiation, background
operation, human-in-the-loop checkpoints through an agent inbox.
My system deviates from that definition at exactly one point, and the deviation is deliberate:
you start it in the foreground by compiling explicit intent into a campaign, and the artifact
that compilation emits is the standing ambient system (event subscriptions, handlers, budgets,
human gates, kill authority). Its compiled trigger-to-policy pairs are the sealed orders:
written in advance, opened by events. Launch is the bootstrap, not the product.
The three interaction patterns the definition names are all here: Notify is the system
flagging an event for me without acting on it, Question is a worker parking in one inbox
until I answer, Review is my ratification gate before anything consequential.
Archive · Act V · The pattern catalog
The candidates, under observation.
The compiler is only as good as its seed corpus. These patterns are that corpus: recurring
manual interventions from months of running a multi-agent pipeline on a real
distributed-systems project. Each one is written as trigger, policy, verification, because
that's the shape the compiler consumes. A pattern that can't be expressed in that shape isn't
ready to automate, which is itself useful information.
UNDER OBSERVATIONrule: real counts or nothing. No pattern ships with numbers until its baseline is measured.
TEMPLATE · EVERY ENTRY
trigger · the event that starts it
manual today · what I actually do by hand
policy · what the system should decide without me
gate · where a human stays in the loop
frequency and cost · pending measurement
automation risk · the specific way automating this goes wrong
How it actually works
The measurement protocol
Before any of this automates, one baseline week of tally marks: every manual intervention,
which pattern, minutes spent. The tally sheet becomes the before column, and it's the only
honest source for the ROI numbers this site will eventually claim. After the January dogfood,
the same sheet becomes the after column. If the delta is small, that gets published too.
Archive · Act VI · The dogfood campaign
This is a design in progress, not a product. The site is the spec, and the spec is public
because writing it in public keeps it honest. Black Skies is the design partner and the test
harness: every pattern in the catalog was extracted from real interventions on a real
project, not imagined from a whiteboard. The Black Skies backend is being hardened for edge
cases and stress tests, and the frontend is in early development.
Issue opened
Appends a triage node to the plot.
PR event
Appends a review node to the plot.
Design change ratified
Invalidates its mapped subtree. This is the headline demo: a design decision lands, and the fleet visibly re-plans around it without me touching the DAG.
a ratified design change lands on the plot
its subtree is invalidated and re-forms
the plan redraws · dispatch follows
no human touched the DAG
How it actually works
v1 ships exactly three delta classes, on GitHub webhooks plus schedules, nothing proprietary.
Review gates fire only on invalidations. Everything else is observed and logged, not gated,
because a v1 that gates everything is a v1 nobody waits for.
The measurements
The campaign has a hard date and a defined kill condition. The measurements that decide it:
interventions per week before and after, and the quality delta with the adversarial review
gate on versus off.
before
interventions per week
after
quality delta, gate on versus off
publishes either way
THE FALSIFIER, STATED UP FRONT
"If one vendor's best agent, run well, beats the governed fleet on those numbers, then this
product reduces to a feature in someone's changelog, and I'll say so. The measurements get
published either way."
archived framing · the installable v0.1.5 scaffold now lives abovethe build is public
This site plus the devblog is my portfolio. The spec, the diagrams, and the measurements publish either way, and I build in public.
Running your own agent pipeline
There was nothing to install when this was written; the v0.1.5 scaffold above is the first installable cut. The pattern catalog above is my roadmap: candidates under observation, not commitments. Follow the build and argue with the spec while it's still cheap for me to change.
Funding or hosting infrastructure
The falsifier above is my pitch: a neutral seat above the runtimes. It's a position, not a technical moat, and the price of holding it is integration surface. The only thing I'm asking for right now is argument with the spec. Anything more waits for the dogfood numbers.
12 · Docs and references
The docs index.
The repository is not public yet, so its docs are reproduced as sections of this page. When
the repo opens, these anchors will point at the files themselves.