From 294d9e2fc529670414c6130aacdd5f4080dbc178 Mon Sep 17 00:00:00 2001 From: Mathias Date: Wed, 19 Aug 2026 12:00:17 +0200 Subject: [PATCH] feat(atlas): stage 05 reflects the dispatch execution path MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The atlas described stage 05 as agentsquad only, while headless single-issue execution has run through mathias/dispatch for months and gained substantial machinery in the 2026-08-17→19 session. Four nodes added, and the stage now names both paths rather than one. - dispatch · headless issue runs — the 1-minute poll over allow-listed repos, and the rule that CI-green on the pushed commit is the only done-signal. - Two independent executors — claude or kimi (berget/Kimi-K2.6 via LiteLLM, EU-metered), routed per issue. Marked as a win, and as risk-bearing: it exists because a single provider's empty account stopped all CAD for six weeks. - Fail-closed tool policy — one policy shared by both executors, writes confined to the checkout (symlink-resolved after an escape was found live), per-run turn and USD ceilings. - Read-only PR review — status:review, no write tools, and the grounding rule that a review citing no changed file is dropped rather than published. Deliberately NOT added: the risk-tiered agentic review with ntfy escalation. That is designed (dispatch#48) and not built, and the atlas is a map of what runs, not of what is planned. Every node carries the plain-language layer the build test enforces. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_011PL5XcG68SvQqz3vGVbWbf --- internal/atlas/atlas.json | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/internal/atlas/atlas.json b/internal/atlas/atlas.json index a1e9bdb..f012d2a 100644 --- a/internal/atlas/atlas.json +++ b/internal/atlas/atlas.json @@ -34,12 +34,16 @@ {"t":"Human triggers execution","plain_t":"The go button","plain":"A person confirms the plan and its risk level, then releases the work — nothing runs until they do.","cls":"gateway","pill":"var(--amber)","d":"Ratify proposed-plan + risk tier, then dispatch.","gate":true}, {"t":"Session-Dispatch bridge","plain_t":"Hand-off to agents","plain":"The approval flips a switch that hands the signed work order over to the agents to start execution.","cls":"bridge","pill":"var(--blue)","d":"claude.ai MCP → gitea:workflow_run_trigger → cad-dispatch.yml → agentsquad. The final design→execution bridge.","tags":["workflow_dispatch"]} ]}, - {"no":"STAGE 05","short":"Build","cls":"exec","title":"Execute · agentsquad","plain_title":"Agents do the work","plain":"AI agents actually build the thing — one writes, a second independent one reviews it to avoid marking its own homework — and every step is logged for the audit trail.","path":"koala · cmd/agentsquad-serve", + {"no":"STAGE 05","short":"Build","cls":"exec","title":"Execute · agentsquad + dispatch","plain_title":"Agents do the work","plain":"AI agents actually build the thing — one writes, a second independent one reviews it to avoid marking its own homework — and every step is logged for the audit trail. Two execution paths run today: agentsquad for orchestrated multi-agent jobs, and dispatch for headless single-issue work.","path":"koala · agentsquad-serve + dispatch CronJob", "trans_label":"Change proposed","trans":"Advances when the agents finish and open a proposed change (a PR) with its audit log attached. Until there's a concrete change to test, nothing moves.","nodes":[ {"t":"Task API","plain_t":"Start a job","plain":"A request kicks off a job and hands back an id you can poll for progress.","pill":"var(--coral)","d":"POST /tasks → job id · GET /tasks/{id}. taskqueue + serve (v0.12+).","tags":["single agentsquad.yaml"]}, {"t":"Executor + reviewer loop","plain_t":"Build + independent review","plain":"One agent does the work; a second, independent agent on a different model reviews it — so nothing marks its own homework.","cls":"win","pill":"var(--coral)","d":"ADK Go + LiteLLM. Frontier models (local qwen spirals). Reviewer on distinct tier — echo-chamber prevention.","risk":true}, {"t":"dma-cli · routing + scope","plain_t":"Router & guardrails","plain":"A router sends each agent to the right AI backend and enforces what it is and isn't allowed to touch, with a confirmation gate as a guardrail.","cls":"bridge","pill":"var(--blue)","d":"Harness-config arm: routes agents to the right LLM backend. Three-layer scope policy + confirmation gate = CAD guardrail.","tags":["backend routing","scope guardrail"]}, - {"t":"assessor-loop ledger","plain_t":"Audit log","plain":"Every step is recorded in a tamper-evident log so the whole run can be audited afterwards.","d":"Attestation ledger (audit trail) + brain session_log on completion.","tags":["audit package"]} + {"t":"assessor-loop ledger","plain_t":"Audit log","plain":"Every step is recorded in a tamper-evident log so the whole run can be audited afterwards.","d":"Attestation ledger (audit trail) + brain session_log on completion.","tags":["audit package"]}, + {"t":"dispatch · headless issue runs","plain_t":"Picking up work by itself","plain":"A watcher checks the tracker every minute for issues marked ready, and runs one agent per issue on its own — no human starts it. Whether the work is really done is decided by the automated checks, never by the agent saying so.","pill":"var(--coral)","d":"CronJob polls status:dispatch in allow-listed repos (.dispatch-allow marker, fail-closed). Claims, runs, reports; CI-green on the pushed commit is the only done-signal.","tags":["1-min poll","CI is ground truth"]}, + {"t":"Two independent executors","plain_t":"Two different AI providers","plain":"The same job can be run by either of two different AI providers, chosen per issue. When one is unavailable — an empty account stopped everything for six weeks — the other still works.","cls":"win","pill":"var(--blue)","d":"executor:<name> label routes to claude (Anthropic SDK runner) or kimi (berget/Kimi-K2.6 via LiteLLM, EU-metered, Go-native loop). Provider independence after a 6-week single-provider outage.","tags":["executor: label","EU option"],"risk":true}, + {"t":"Fail-closed tool policy","plain_t":"What an agent may touch","plain":"Each agent may only use an approved short list of tools and commands; anything else is refused outright rather than asked about, since no human is watching. Its file access cannot leave its own copy of the repo, and each run has a hard limit on both steps and money spent.","cls":"gateway","pill":"var(--amber)","d":"One executor.Policy for both executors: tool + bash-prefix allowlist, closed env-prefix list, exact MCP tool names. Writes confined to the checkout (symlink-resolved, O_NOFOLLOW). Per-run turn and USD ceilings; spend ledgered against a rolling cap.","tags":["deny by default","per-run ceilings"]}, + {"t":"Read-only PR review","plain_t":"A second agent reads the change","plain":"A pull request can be handed to an agent that may only read and comment, never edit. Its review is thrown away unless it points at a file the change actually touched — which catches a reviewer that skimmed the title instead of the code. New commits re-open the review by themselves.","pill":"var(--coral)","d":"status:review → read-only tools (no write, no shell). Published only if grounded: must cite a file in the PR's changed-files list. Handling anchored to the head sha, so a push re-opens it; attempts capped per revision.","tags":["grounded or dropped","re-opens on push"]} ]}, {"no":"STAGE 06","short":"Check","title":"PR → CI","plain_title":"Automatic quality checks","plain":"The proposed change is run through automated tests and safety checks — including a check that it actually satisfies the work order's definition of done — and only a clean pass lets it continue.","path":"Gitea Actions · cd.yml (live)","generate":"ci-jobs", "trans_label":"All checks green","trans":"Advances only if every automated check passes — tests, linters, security scan, and the Oath check proving it meets the original work order. Any red gate stops it here; a passing reviewer is not enough to override a failed Oath.","nodes":[