Skip to content

Claude/headless agent architecture igdntn - #7

Merged
ArthurDentsTowel merged 8 commits into
mainfrom
claude/headless-agent-architecture-igdntn
Jul 31, 2026
Merged

Claude/headless agent architecture igdntn#7
ArthurDentsTowel merged 8 commits into
mainfrom
claude/headless-agent-architecture-igdntn

Conversation

@ArthurDentsTowel

@ArthurDentsTowel ArthurDentsTowel commented Jul 31, 2026

Copy link
Copy Markdown
Contributor
  • removed needles opening of additional terminal instances, and replaced with a headless version of workers in their own work trees.

claude added 8 commits July 31, 2026 02:37
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
@ArthurDentsTowel
ArthurDentsTowel merged commit 62adba9 into main Jul 31, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants