CLAUDE.md · git:20260821.ae0a18c · 2026-08-21 · sha256 920721ed6d21a0b0

CLAUDE.md git:20260821.ae0a18cA

Immutable. This exact content is served forever at /api/v1/blob/920721ed6d21a0b0.

# Agentfactory

Agentfactory — standalone multi-agent orchestration CLI.

## Build Commands

- `make sync-formulas` - sync build formulas from `internal/cmd/install_formulas` to `.agentfactory/store/formulas`
- `make build` — build the `af` binary
- `make build-webui` — build the optional web console (`webui`) from its own module (`web/go.mod`)
- `make test` — run unit tests (root module only — `go test ./...`)
- `make install` — build and install to `~/.local/bin/af`
- `make test-integration` — run integration tests (should only run in CI)
- `make clean` — remove build artifacts

The web console is a **separate Go module** (`web/go.mod`), so root `make test` does NOT run its
tests — run them directly with `cd web && go test ./...` (CI covers them via the `web-unit` job).

## Dependencies

- Go 1.24+
- Python 3.12 — required by the in-tree MCP issue-store server (`py/issuestore/`); install.go's `checkPython312` enforces the version at runtime
- jq — used by quality gate hook
- claude CLI — optional, for quality gate evaluation

## Project Structure

```
cmd/af/              Entry point
internal/
  checkpoint/        Session crash recovery (formula/step state, git state, timestamps)
  claude/            Claude Code settings templates (autonomous, interactive)
  cmd/               CLI commands (see below)
  config/            Config loading (factory.json, agents.json, messaging.json, dispatch.json)
  formula/           Formula system (TOML parsing, DAG validation, topo sort, variable resolution)
  issuestore/        Store interface over any underlying datastore
  lock/              Identity lock with PID-based stale detection
  mail/              Mail system (mailbox, router, issuestore-backed storage)
  session/           Agent session lifecycle (tmux start/stop, Claude launch, zombie detection)
  templates/         Role templates (manager, supervisor, and many more specialist roles)
  tmux/              tmux subprocess wrapper (create, attach, send-keys, capture, readiness)
hooks/               Quality gate scripts (source copies)
web/                 Optional web console — SEPARATE Go module (web/go.mod)
  cmd/afweb/         Web console entry point (builds the `webui` binary)
  internal/
    server/          Loopback HTTP server, routing, handlers
    exec/            Command-injection-safe `af` exec wrapper + --var validation
    readmodel/       Honest agent read-model (Phase-0 status + tmux liveness)
    config/          Settings read/write over the af config-set CLI
    dispatch/        Dispatch-status reader
    formschema/      Formula input-schema reader
    proto/           On-disk prototype server (.designs/)
    rendezvous/      Singleton-launch rendezvous (.runtime/webui_server.json)
    feedback/        Gate-verify feedback writer
    entrypoint/      Launch-guard helpers
    web/             Embedded static assets (index.html, app.js)
```

## CLI Commands

- `af root` — print factory root path
- `af prime [--hook]` — inject role context into Claude Code session at startup
- `af mail send|inbox|read|delete|check|reply` — inter-agent messaging via beads
- `af install --init` / `af install <role>` — factory and agent workspace setup
- `af up [agents...]` — start agent tmux sessions (all or specified)
- `af down [agents...] [--all]` — stop agent tmux sessions (factory-wide teardown is operator-only)
- `af attach <agent>` — attach to a running agent's tmux session
- `af done` — close current formula step, advance workflow
- `af formula agent-gen <file>` — generate agent shell from formula TOML
- `af sling --formula <name>` — instantiate a formula (create step beads, resolve DAG, optionally launch)
- `af sling --agent <name> "task"` — dispatch a task to a specialist agent
- `af agents list --json` — list configured agents with live status as a JSON array (machine-readable contract)
- `af formula show --json` — print a formula's inputs and vars as JSON
- `af dispatch status --json` — show dispatcher status and dispatch history as JSON (always exits 0; branch on `.state`)
- `af config dispatch set` / `af config startup set` / `af config messaging set` — replace dispatch.json / startup.json / messaging.json from a JSON document on stdin. Every setter's decode is STRICT (an unknown top-level key is rejected, never silently dropped and erased on write-back) while every loader stays tolerant, and each cross-checks agent references against agents.json before writing — a missing or unreadable agents.json is fatal, not skipped. All three, plus `config statusline set`, accept an optional `--if-content-hash=<sha256>` compare-and-set precondition: the write proceeds only if the file still matches the digest the caller read (mismatch ⇒ non-zero exit, file untouched; flag omitted ⇒ unconditional write)
- `af config fingerprint --json` — print `{"state":"ok","fingerprint":"<sha256>"}`, a digest of the config schema THIS binary speaks, recomputed in memory from the canonical structs rather than baked in at build time. Reads no config and needs no factory root, so a consumer can call it before knowing whether the cwd is a factory (always exits 0; branch on `.state`)
- `af improvement [on|off] [--agent <name>] | complete` — toggle/show the continuous-improvement hook (AND-gated, default off); `complete` finishes a pending improvement session
- `af telemetry [on|off|status|report|usage]` — toggle run measurement (default off; takes effect at the next session launch), show where data is going, print the local per-step timing table, or query the backend for token usage and session metrics (`usage` always exits 0; branch on `.state`)
- `af statusline [on|off|status|render]` — toggle/show the Claude Code session statusline, or render one tick of it from a session payload on stdin (render-time; seeded on at install; `status` also reports the token counter and stale agents)
- `af config statusline set` / `af config statusline get` — replace statusline.json from a JSON document on stdin (the `elements` list, plus an optional `color` key — ANSI color renders ON by default, disable with `"color":false` or the `NO_COLOR` env var; every element is on by default), or print the effective config back
- `af config models show|set|check|attest` — print the model registry with secrets redacted, replace models.json from a JSON document on stdin, probe a profile's endpoint transport **and its per-class model coverage** (one verdict per requestable class; any unserved class or missing `claude-*` gateway alias is a non-zero exit), or record a fitness attestation (required before a non-loopback profile can launch; a profile is a plain map of env exports, and `set` validates every one of them)
- `af recovery reset <agent>` — clear an agent's context-exhaustion recovery breaker after investigating a `RECOVERY HALTED` escalation (operator-only; mutates breaker state only — it does not relaunch the agent, `af up` does)

## Architecture

`./USING_AGENTFACTORY.md` includes up-to-date current usage information with commands that all exist and are in active use.

## Code comments

Code should "read like a book". Code comments should ONLY exist when it makes sense to explain WHY the code is doing what it does. Having to maintain comments in-addition to code is a maintenance burden (and comments diverge), code is truth. Comments should be minimal or ideally, not exist at-all UNLESS they add VALUE to the code. IFF they add VALUE to the code, we should still ask the question, WHY? Is the code not self-describing? Are we introducing a hack or work-around that someone needs to know about? WHY? ONLY IFF you can reason about WHY the comment should exist, then it can exist.