Claude/headless agent architecture igdntn - #7
Merged
ArthurDentsTowel merged 8 commits intoJul 31, 2026
Conversation
Defines the v2 design: headless runner processes instead of terminal sessions, model-agnostic role config via foreman.config.json, backend adapters (claude-cli, codex-cli, openai-compatible), lifecycle CLI, and the @ask directive for peer communication. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019gi6oHfGAK86EwThbcE5Ge
…hitecture - Add scripts/foreman-runner.py: generic headless runner, one process per crew member. The runner owns the relay connection and message loop, with backend adapters for claude-cli (with --resume continuity), codex-cli, and any OpenAI-compatible endpoint (Ollama, OpenRouter, OpenAI, etc.). Peer communication for headless members uses @ask directive lines that the runner relays. Waits patiently for the hub at startup instead of burning its reconnect budget before the Orchestrator is up. - Add foreman.config.json: per-role backend/model config with per-project .foreman/config.json overrides. All-Claude defaults work out of the box; no model is hardcoded in scripts or role files. Gemini/Ollama/Codex are no longer requirements - any of them can be plugged into any role. - Add scripts/foreman.sh lifecycle CLI (start/spawn/stop/status/logs/clean) replacing terminal-window spawning. Runtime state lives in <project>/.foreman/ (logs, pids, worktrees), auto-excluded from git status via .git/info/exclude. Worker worktrees move from /tmp to .foreman/worktrees/. - Remove foreman-bootstrap.sh and the three per-model bridge scripts. - Update SKILL.md, README, protocol.md, and all role files for the headless design; fix protocol.md's incomplete role list. Verified with an end-to-end test against a fake relay hub and fake OpenAI-compatible server (register, readiness, task delivery, @ask resolution, final reply) plus lifecycle smoke tests in a temp repo. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019gi6oHfGAK86EwThbcE5Ge
…traffic command - architecture.md: document the traffic ledger (.foreman/traffic.jsonl, duplicate-free per-runner logging rule), the mechanical loop detector, the confirm-then-arbitrate escalation, and the arbiter quality bar (frontier-class, user-chosen, ships as SET-ME with owner-escalation fallback). - foreman.sh: new 'traffic [-f]' subcommand pretty-printing the ledger, and a startup notice when the circuit-breaker arbiter model is unset. Runner-side ledger writes and the breaker watcher land in the next commit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019gi6oHfGAK86EwThbcE5Ge
- circuit-breaker.md: rewritten as system context for the confirm/arbiter model calls (LOOP: YES/NO answer format, binding-ruling instructions, escalation ladder, arbiter quality bar). - SKILL.md: Circuit Breaker Protocol section now describes mechanical detection from the traffic ledger with confirm/arbitrate/escalate steps; Configuration notes the arbiter block users must set. - README.md: crew table, workflow description, lifecycle CLI (traffic command), and limitations updated; arbiter ships as SET-ME by design. - protocol.md: Circuit Breaker references aligned with ledger-based detection. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019gi6oHfGAK86EwThbcE5Ge
…rbiter - foreman-runner.py: TrafficLedger appends every handled message to .foreman/traffic.jsonl (duplicate-free per-runner rule; best-effort writes that never crash a runner). The circuit-breaker role now runs a breaker loop instead of the generic message loop: pure-code sliding- window loop detection over the ledger, a cheap confirm-model call on trips (false positives suppressed), and a binding forced resolution via a separately configured arbiter backend with an assembled evidence packet (transcript, CURRENT_PLAN.md, DECISIONS.md, referenced project files resolved strictly under the project root). Escalates to the owner via the Orchestrator when the Orchestrator is a party or the arbiter is unconfigured/unreachable. Status asks answered mechanically. Flagged pairs reset to WATCHING when their window drains, so later healthy exchanges re-enter via confirmation rather than stale arbitration. - foreman.config.json: circuit-breaker gains the arbiter block, shipped deliberately as model SET-ME — users must choose a frontier-class arbiter (Opus 4.8-level or better). Verified: end-to-end runner test now also confirms correct ledger contents; detector unit tests (trip threshold, flag delivery, SET-ME escalation) and a flag-reset regression test all pass. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019gi6oHfGAK86EwThbcE5Ge
- foreman-runner.py: sensitive files (.env*, .pem/.key/.p12/.pfx/.keystore, and credential/secret/token/password-named files) are excluded from the arbiter's evidence packet — the arbiter may be a third-party endpoint and must never receive project secrets. Restores a protection the old architect bridge had that was dropped in the headless rewrite. - tests/: the verification suite now lives in the repo instead of session scratch space — fake-hub end-to-end (including ledger content checks), startup-race regression, breaker detector, flag-reset regression, and a new evidence-packet secrets test. tests/run_tests.sh runs everything with no external deps, network, or models. - .github/workflows/tests.yml: CI runs the suite on every push and PR. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019gi6oHfGAK86EwThbcE5Ge
…view Adds the 'Integration: the merge workflow' section: foreman.sh merge with branch state files that survive worktree removal, cwd/detached-HEAD/dirty guards, a conflict gate that blocks other merges until the conflicted worker converges on a recorded SHA, committed-work enforcement, hook-failure vs content-conflict distinction, mkdir locking, and merge --abort restoring the recorded pre-merge branch. Cleaner is restricted to worker worktrees until its (now committed) final sweep. Each rule maps to a failure mode found by a pre-build adversarial review of the draft spec (worktree/clean race, Cleaner-vs-merge race, dead rollback state, unvalidated cwd, stale conflict resolution, silent uncommitted-work loss). Implementation lands in the next commit. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019gi6oHfGAK86EwThbcE5Ge
Implements the merge workflow spec'd in architecture.md, closing the gap where worker branches were never landed and audits inspected a tree the work hadn't reached: - spawn worker records the branch in .foreman/worktrees/worker-<n>.branch so merge can discover branches even after worktree removal. - foreman.sh merge: cwd/detached-HEAD/dirty guards, mkdir lock, first-run integration-branch creation with pre-merge branch recorded, sequential worker-number merges, hard errors on branch-name mismatch and uncommitted worker changes, zero-commit workers flagged and skipped, content conflicts distinguished from hook failures, conflict gate that blocks all other merges (with recorded SHA) until resolved or --skip, and merge --abort restoring the pre-merge branch. - Role docs: workers commit before reporting completion (with the one sanctioned conflict-resolution merge exception); Orchestrator gains the merge step before TS review/conformance/inspection, all of which now run against the integrated tree; Cleaner stays out of the main dir until its final sweep, which it commits itself. - tests/test_merge.sh: six scenarios in throwaway git repos (happy path + abort, conflict blocking, blocked gate + --skip, dirty-worktree refusal, cwd guard, zero-commit warning). run_tests.sh now also runs bash test files so CI covers them. Design was adversarially reviewed before build; every guard maps to a failure scenario from that review. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_019gi6oHfGAK86EwThbcE5Ge
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.