diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
new file mode 100644
index 0000000..0a29f4f
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.md
@@ -0,0 +1,31 @@
+---
+name: Bug report
+about: Something in agentfactory doesn't work as documented
+title: ''
+labels: bug
+assignees: ''
+---
+
+## What happened
+
+
+
+## Reproduction
+
+```bash
+# exact commands, starting from a known state
+```
+
+## Environment
+
+- OS:
+- Go version (`go version`):
+- Python version (`python3 --version`):
+- tmux version (`tmux -V`):
+- Install path: source build / quickstart.sh / quickdocker.sh
+
+## Relevant output
+
+```
+# af output, tmux capture, or hook logs
+```
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
new file mode 100644
index 0000000..55002d7
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -0,0 +1,19 @@
+---
+name: Feature request
+about: Propose a capability or improvement
+title: ''
+labels: enhancement
+assignees: ''
+---
+
+## Problem
+
+
+
+## Proposed behavior
+
+
+
+## Alternatives considered
+
+
diff --git a/.github/workflows/visibility-health.yml b/.github/workflows/visibility-health.yml
new file mode 100644
index 0000000..bce3f38
--- /dev/null
+++ b/.github/workflows/visibility-health.yml
@@ -0,0 +1,64 @@
+# Monthly repo-health watchdog: verifies the discoverability surface (topics,
+# description, release, README badges) hasn't regressed and opens a single
+# issue when it has. Checks only — never commits, never touches content.
+name: visibility-health
+
+on:
+ schedule:
+ - cron: '17 8 3 * *'
+ workflow_dispatch:
+
+permissions:
+ contents: read
+ issues: write
+
+jobs:
+ check:
+ runs-on: ubuntu-latest
+ env:
+ GH_TOKEN: ${{ github.token }}
+ REPO: ${{ github.repository }}
+ steps:
+ - uses: actions/checkout@v4
+ - name: Check discoverability surface
+ run: |
+ problems=""
+
+ topics=$(gh api "repos/$REPO" --jq '.topics | join(" ")')
+ for t in claude-code ai-agents multi-agent-systems agentic-ai golang; do
+ case " $topics " in
+ *" $t "*) ;;
+ *) problems="$problems- topic \`$t\` is missing\n" ;;
+ esac
+ done
+
+ desc=$(gh api "repos/$REPO" --jq '.description // ""')
+ [ -n "$desc" ] || problems="$problems- repo description is empty\n"
+
+ if ! gh api "repos/$REPO/releases/latest" --jq .tag_name >/dev/null 2>&1; then
+ problems="$problems- no published release\n"
+ fi
+
+ grep -q 'actions/workflows/test.yml/badge.svg' README.md \
+ || problems="$problems- CI badge missing from README\n"
+ grep -q 'img.shields.io/github/license' README.md \
+ || problems="$problems- license badge missing from README\n"
+
+ if [ -z "$problems" ]; then
+ echo "All visibility checks passed."
+ exit 0
+ fi
+
+ echo "Regressions found:"
+ printf '%b' "$problems"
+
+ title="Visibility health check: regressions found"
+ existing=$(gh issue list --repo "$REPO" --state open \
+ --search "\"$title\" in:title" --json number --jq 'length')
+ if [ "$existing" -gt 0 ]; then
+ echo "Open issue already exists — not filing a duplicate."
+ exit 0
+ fi
+
+ body=$(printf 'The monthly visibility health check found regressions:\n\n%b\nRestore these — they are the repo'"'"'s discoverability surface (topics pages, search snippets, README badges).' "$problems")
+ gh issue create --repo "$REPO" --title "$title" --body "$body"
diff --git a/CHANGELOG.md b/CHANGELOG.md
new file mode 100644
index 0000000..9f614be
--- /dev/null
+++ b/CHANGELOG.md
@@ -0,0 +1,62 @@
+# Changelog
+
+Notable changes to agentfactory. The project began 2026-05-01; snapshot tags `V001`–`V012`
+mark pre-release checkpoints. `v0.1.0` is the first formal release.
+
+## v0.1.0 — 2026-07-11
+
+First formal release, consolidating ten weeks of development.
+
+### Orchestration core
+
+- Formula system: declarative TOML workflows with steps, DAG dependencies, variables, and
+ gates; `af sling --formula` instantiation and `af prime`/`af done` step tracking (#2)
+- Agent generation from formulas: `af formula agent-gen` creates workspace, role template,
+ and hook configuration with no manual file moves (#8)
+- Skill-to-formula pipeline: `/formula-create` turns a `SKILL.md` into a runnable formula;
+ built-in skills embedded and extracted during `af install --init` (#16)
+- Prime-before-done enforcement with velocity tracking, formula skill validation, and
+ per-agent model/endpoint configuration (#43, #81)
+- Startup.json-driven `af up` with declarative agent subset selection, dispatcher
+ auto-start, and scoped watchdog (#58)
+
+### Reliability & recovery
+
+- Mandatory step execution block and fidelity hook corrections for agents drifting off
+ formula steps (#26, #28)
+- Worktree isolation hardening: dispatched agents get independent worktrees; teardown gated
+ on session termination; branch-committed skills preserved (#30, #32, #61, #69)
+- Unified reset semantics: `af sling --reset` and `af down --reset` perform identical full
+ cleanup — worktrees, open work items, runtime state, checkpoints (#40)
+- Gate locks migrated to `.runtime` with stale-PID recovery (#43)
+- Test/production tmux isolation with build-tag-gated constructor guard; compact-handoff
+ PreCompact hook for context-compression safety (#52)
+- Agents made default-branch-agnostic; regen/lint CI gates (#63)
+
+### Multi-agent coordination
+
+- Inter-agent mail over the issue store, with broadcast groups and reply threading
+- Autonomous dispatch: PR/issue label matching, multi-label AND semantics, dispatch cycle
+ locking, idle back-off, phase advancement, and issue→PR handoff (#36, #38, #79)
+- MergePatrol PR-review agent with label-based discovery (#36)
+
+### Formula & agent library
+
+- rapid-implement, rapid-increment, ultra-review formulas (#65); web-design agent with
+ consensus gate (#68); minimalworker (#52); the fable agent family — fable-implement,
+ fable-increment, fable-review (#83)
+
+### Web console
+
+- Loopback-only web console: Floor view, task slinging, dispatch status, settings, design
+ prototypes; singleton-launch rendezvous; agent detail and operator mail (#72, #81, #83)
+- Browser formula authoring (#83)
+
+### Platform & tooling
+
+- Containerized setup via `quickdocker.sh` + `quickstart.sh`; stack-agnostic customer repo
+ discovery (#56); iOS build-host configuration with ssh-agent forwarding (#48, #50)
+- Server-wide tmux mouse/clipboard UX at session creation (#77)
+- CI: unit, integration, template-regen, and supply-chain-lint jobs
+
+[Full commit history](https://github.com/stempeck/agentfactory/commits/main)
diff --git a/README.md b/README.md
index 1465aa3..f294169 100644
--- a/README.md
+++ b/README.md
@@ -1,22 +1,70 @@
-# Agentfactory
-**Why do I need Agentfactory?**
-1. You can give LLM steps to follow and at times it will use a heuristic and improvise, skipping steps
-2. Recency bias drives every prompt
-3. Improvization and Recency bias lead to bugs the next LLM builds around, compounding false assumptions
-4. No crash recovery for agents doing long-running or multi-agent operations
+# agentfactory — multi-agent orchestration for Claude Code
+
+**Turn your `SKILL.md` files into an autonomous agent workforce.** agentfactory is a
+multi-agent orchestration CLI that runs Claude Code agents through declarative TOML
+workflows — with crash recovery, context re-injection, and inter-agent mail built in.
+
+[](https://github.com/stempeck/agentfactory/actions/workflows/test.yml)
+[](go.mod)
+[](LICENSE)
+[](https://github.com/stempeck/agentfactory/releases)
+
+## Why agentfactory
+
+Long-running LLM agents fail in predictable ways. Give an agent a list of steps and at some
+point it will improvise — skip a step, substitute a heuristic, and keep going. Recency bias
+means whatever entered the context last dominates what the agent does next. When the context
+window fills and gets compressed, the agent quietly loses its identity, its place in the
+workflow, or both. And when a session crashes mid-task, there is usually nothing to recover:
+the plan lived inside the conversation.
+
+Skills (`SKILL.md` files) capture *what you know*, but a skill alone can't hold an agent to a
+workflow — the agent needs a harness. agentfactory separates the two concerns: **personas**
+stay thin (identity, startup protocol, available commands), while **workflows live in
+formulas** — declarative TOML files with steps, DAG dependencies, variables, and quality
+gates. The `af` runtime bridges them: it instantiates a formula into trackable work items,
+re-injects identity and the current step on every prompt (surviving context compression),
+checkpoints progress so a crashed agent resumes where it stopped, and gives agents a mail
+system to coordinate multi-agent work.
-SKILLs aren't enough on their own to solve this. You need an Agent with a better harness.
+## Architecture
+
+```mermaid
+flowchart LR
+ S["SKILL.md
what you know"] -- "/formula-create" --> F["formula.toml
steps · DAG deps · vars · gates"]
+ F -- "af formula agent-gen" --> A["agent workspace
thin persona + hooks"]
+ A -- "af up" --> T["tmux session
running Claude Code"]
+ T -- "af prime
context re-injection" --> T
+ T -- "af done
step advancement" --> F
+ T <-- "af mail" --> M[("inter-agent
mail")]
+ T -- crash --> C["checkpoint
resume on restart"] --> T
+```
-Agent Factory can easily harness your existing skills
+Three layers:
-**Vision:**
-You have SKILLs, now turn your SKILL.md's into your autonomous workforce.
+1. **Agent templates** (`.md.tmpl`) — thin persona shells: identity, startup protocol, commands
+2. **Formulas** (`.formula.toml`) — declarative workflows: steps, DAG dependencies, variables, gates
+3. **`af` runtime** — instantiates formulas as work items, injects context via `af prime`, tracks progress via `af done`
-**Mission:**
-Create an instruction set workflow (formula) with `/formula-create /path/to/your/SKILL.md` and generate an autonomous agentfactory agent from it with `af formula agent-gen name-of-your-formula` with simple steps or multi-agent coordination.
+Agents don't need to know their full workflow. They run `af prime` to get the current step,
+execute it, run `af done` to advance, and repeat. On context compression, `af prime`
+re-injects identity and step context automatically. Deeper reading:
+[formulas reference](docs/formulas.md) · [agent lifecycle](docs/agent-lifecycle.md) ·
+[recovery model](docs/recovery-model.md) · [architecture corpus](docs/architecture/overview.md).
-**Multi-agent orchestration CLI for Claude Code.**
-Turn your SKILL.md files into autonomous agents that execute structured workflows with context handoffs, inter-agent messaging, and crash recovery.
+## How it compares
+
+| | Workflow definition | Execution substrate | Crash / context-loss recovery |
+|---|---|---|---|
+| **agentfactory** | Declarative TOML DAGs, separate from personas | Claude Code sessions in tmux — inspectable, attachable | First-class: checkpoints + `af prime` re-injection |
+| **LangGraph** | Graphs built in Python/JS application code | Your app process calling model APIs | Checkpointing available; you build the harness |
+| **CrewAI** | Role/task definitions in Python code | Your app process calling model APIs | Not a core concern; retries at task level |
+| **Claude Code subagents** | Prompts inside one session | In-session fan-out | None — subagent state dies with the session |
+
+Honest scope: agentfactory orchestrates **Claude Code** specifically — it is not a
+model-agnostic framework. If you want programmatic graphs inside a Python app, LangGraph is
+the better fit. If you live in Claude Code and want autonomous, restartable, coordinated
+agents driven by workflows you can diff and review, that's what this is for.
## Quick Start
@@ -52,9 +100,14 @@ cd agentfactory
./quickdocker.sh
```
-This builds a container with all prerequisites, clones your target repo, and runs `quickstart.sh` inside it. When it finishes, the container is ready for `af up`.
+This builds a container with all prerequisites, clones your target repo, and runs
+`quickstart.sh` inside it. When it finishes, the container is ready for `af up`.
-A clean install now also **reveals the web console before the shell**: when it finishes it prints the loopback URL `http://127.0.0.1:/` (and opens your browser on macOS) immediately before dropping you into the interactive shell — so you no longer have to run `--web` yourself just to first see it. Use `--web` only to **re-open** the console later. See the **Web Console (optional)** section below and [`web/README.md`](web/README.md) for details.
+A clean install now also **reveals the web console before the shell**: when it finishes it
+prints the loopback URL `http://127.0.0.1:/` (and opens your browser on macOS)
+immediately before dropping you into the interactive shell — so you no longer have to run
+`--web` yourself just to first see it. Use `--web` only to **re-open** the console later. See
+the **Web Console (optional)** section below and [`web/README.md`](web/README.md) for details.
#### Using quickstart.sh (inside the docker container @ docker exec -it -u dev "af_ghusername_repo" bash)
@@ -65,7 +118,8 @@ cd ~/projects/agentfactory/
### Authenticate Claude Code
-After installation, run `claude` once to authenticate. Agents require an authenticated Claude Code session to function.
+After installation, run `claude` once to authenticate. Agents require an authenticated Claude
+Code session to function.
## Usage
@@ -80,15 +134,8 @@ af install manager
af install supervisor
```
-Add factory directories to `.gitignore`:
-
-```bash
-cat >> .gitignore << 'EOF'
-.agentfactory/
-.agentfactory/hooks/
-.agentfactory/store/
-EOF
-```
+`af install --init` automatically excludes factory directories from git via
+`.git/info/exclude` — no `.gitignore` changes needed.
### 2. Start agents
@@ -136,9 +183,11 @@ claude
# e.g. ./.claude/skills/rapid-implement/SKILL.md")
```
-This generates a `.formula.toml` file in `.agentfactory/store/formulas/`. Be patient. It can take some time.
+This generates a `.formula.toml` file in `.agentfactory/store/formulas/`. Be patient. It can
+take some time.
-NOTICE: `.claude/skills/rapid-implement/SKILL.md` was provided in case you want to try creating your first coding agent.
+NOTICE: `.claude/skills/rapid-implement/SKILL.md` was provided in case you want to try
+creating your first coding agent.
### 2. Generate an agent from your formula (your-agent-name.formula.toml -> your-agent-name)
@@ -146,7 +195,8 @@ NOTICE: `.claude/skills/rapid-implement/SKILL.md` was provided in case you want
af formula agent-gen your-agent-name
```
-This creates the agent's workspace, CLAUDE.md template, hook configuration, and registers it in `agents.json`.
+This creates the agent's workspace, CLAUDE.md template, hook configuration, and registers it
+in `agents.json`.
### 3. Rebuild af with the new agent template
@@ -154,7 +204,8 @@ This creates the agent's workspace, CLAUDE.md template, hook configuration, and
make install
```
-Required because `af prime` reads templates from the compiled binary (`go:embed`). Without this, the agent falls back to the generic supervisor template on context compression.
+Required because `af prime` reads templates from the compiled binary (`go:embed`). Without
+this, the agent falls back to the generic supervisor template on context compression.
### 4. Start the agent
@@ -170,7 +221,8 @@ af sling --agent your-agent-name "do the thing"
### Batch regeneration
-To regenerate all specialist agents from formulas and re-bootstrap the factory, run the redeploy command from the main project checkout:
+To regenerate all specialist agents from formulas and re-bootstrap the factory, run the
+redeploy command from the main project checkout:
```bash
af install --agents # regenerate all + rebuild, then bootstrap
@@ -181,13 +233,15 @@ See `USING_AGENTFACTORY.md` for preconditions, data-safety, and `--no-build` not
## Included Formulas
-| Formula | Purpose |
-|---------|---------|
-| `design-v3` | Structured design exploration with constraint verification |
-| `design` | Basic design workflow |
-| `factoryworker` | General-purpose factory worker |
-| `gherkin-breakdown` | Break work into Gherkin scenarios |
-| `mergepatrol` | PR review and merge workflow |
+Nineteen formulas ship with the factory (see [docs/formulas.md](docs/formulas.md) for the format):
+
+| Family | Formulas | Purpose |
+|---------|----------|---------|
+| Implementation | `rapid-implement`, `rapid-increment`, `fable-implement`, `fable-increment` | Structured feature implementation with quality gates |
+| Design | `design`, `design-v3`, `design-v7`, `design-plan-impl`, `rapid-soldesign-plan`, `web-design` | Design exploration with constraint verification |
+| Review | `mergepatrol`, `ultra-review`, `fable-review` | PR review, merge workflow, deep multi-pass review |
+| Root cause | `rootcause-all`, `investigate` | Failure investigation and verified root-cause analysis |
+| Utility | `factoryworker`, `minimalworker`, `gherkin-breakdown`, `github-issue` | General workers, scenario breakdown, issue authoring |
## Included Skills
@@ -254,17 +308,7 @@ When the bind is ever non-loopback (not the default), the console additionally r
session token (printed at startup) as defense-in-depth — but that is **not** a license to publish
the port; the socket stays loopback whether you reach it via the `--web` bridge or the SSH forward.
-## Architecture
-
-Agentfactory has three layers:
-
-1. **Agent templates** (`.md.tmpl`) — thin persona shells that define identity, startup protocol, and available commands
-2. **Formulas** (`.formula.toml`) — declarative workflow definitions with steps, DAG dependencies, variables, and gates
-3. **`af` runtime** — bridges the two: instantiates formulas as beads, injects context via `af prime`, tracks progress via `af done`
-
-Agents don't need to know their full workflow. They run `af prime` to get the current step, execute it, run `af done` to advance, and repeat. On context compression, `af prime` re-injects identity and step context automatically.
-
-### Key directories
+## Key directories
```
.agentfactory/
@@ -311,15 +355,35 @@ af prime # inject identity, get
af done # complete and advance to next step (used by agents)
```
+## Roadmap
+
+- **Prebuilt release binaries** (GoReleaser) so `af` installs without a Go toolchain
+- **Richer shipped formula library** — more turnkey specialist agents out of the box
+- **Gate quality improvements** — reduce fidelity-gate false positives on passive steps ([#75](https://github.com/stempeck/agentfactory/issues/75))
+- **Default dispatch workflow** included with the factory ([#73](https://github.com/stempeck/agentfactory/issues/73))
+- **Web console growth** — deeper agent detail, formula authoring in the browser
+
+Have a use case these don't cover? [Open an issue](https://github.com/stempeck/agentfactory/issues/new/choose).
+
## Contributing
-See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines, CLA requirements, and development setup.
+Contributions are welcome — see [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines, CLA
+requirements, and development setup. Good entry points are labeled
+[good first issue](https://github.com/stempeck/agentfactory/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22).
## License
AGPL-3.0. See [CONTRIBUTING.md](CONTRIBUTING.md) for commercial licensing inquiries.
### Disclaimer
-The contributors to this project take no responsibility for your agent (or their respective LLMs) actions.
-Good luck, and enjoy your Factory of Agents!
\ No newline at end of file
+The contributors to this project take no responsibility for your agent (or their respective
+LLMs) actions.
+
+---
+
+Built and maintained by **[Glenn Stempeck](https://github.com/stempeck)** ·
+[LinkedIn](https://www.linkedin.com/in/glenn-stempeck/) ·
+[Medium](https://medium.com/@glennstempeck)
+
+Good luck, and enjoy your Factory of Agents!
diff --git a/docs/agent-lifecycle.md b/docs/agent-lifecycle.md
new file mode 100644
index 0000000..ce8c11e
--- /dev/null
+++ b/docs/agent-lifecycle.md
@@ -0,0 +1,112 @@
+# Agent lifecycle: how agentfactory runs autonomous Claude Code agents
+
+Every agentfactory agent is a Claude Code session running inside a tmux session, owned and
+supervised by the `af` runtime. The lifecycle is deliberately boring: provision a workspace,
+start a session, inject identity, loop over formula steps, stop. Each stage is a CLI command
+you can run and inspect yourself, which is also what makes the system debuggable — attach to
+any agent with `af attach` and watch it work.
+
+## Provisioning: `af install`
+
+```bash
+af install --init # initialize the factory in your project root
+af install manager # provision an agent workspace from a role template
+af install supervisor
+```
+
+`--init` creates `.agentfactory/` (registry, config, formula store) and adds the
+factory-managed paths to `.git/info/exclude` — your repository stays clean without manual
+`.gitignore` edits. Each `af install ` creates a per-agent workspace under
+`.agentfactory/agents//` containing the agent's `CLAUDE.md` role template and its
+Claude Code hook configuration.
+
+Custom specialists come from formulas: `af formula agent-gen ` generates the workspace
+and registers the agent in `agents.json` — see [Formulas](formulas.md).
+
+## Starting: `af up`
+
+```bash
+af up # start all configured agents
+af up manager supervisor # start specific agents
+af up worker --model sonnet-profile # per-agent model override from models.json
+```
+
+For each agent, `af up`:
+
+1. Creates a git **worktree** owned by that agent (children dispatched from it via
+ `af sling --agent` share the same worktree).
+2. Creates a tmux session named for the agent, with mouse and clipboard behavior configured.
+3. Exports factory environment (`AF_ROOT`, …) into the session.
+4. Launches Claude Code in the agent's workspace.
+
+**Zombie detection:** if the tmux session already exists, `af up` checks whether Claude is
+actually running inside it. A live session with a dead Claude is a zombie — it is killed and
+recreated rather than reported as "already running" (`internal/session/session.go`).
+
+## Identity injection: `af prime`
+
+Agents do not carry their instructions in a long-lived prompt. On every session start, a
+Claude Code `SessionStart` hook runs:
+
+```
+af prime --hook && af mail check --inject
+```
+
+`af prime` outputs the agent's role template, session metadata, and — when a formula is
+hooked — the current step's directives. This is the mechanism that makes agents recoverable:
+identity and workflow state live on disk and in the issue store, not in the model's context
+window. See [the recovery model](recovery-model.md) for what happens on context compression.
+
+## The work loop: `af done`
+
+An agent working a formula repeats one cycle:
+
+1. `af prime` hands it the current step (id, title, directives, resolved variables).
+2. It executes the step's directives.
+3. `af done` closes the step's bead and advances to the next ready step in the DAG.
+4. Gate steps end the session instead: `af done --phase-complete --gate `.
+
+Quality enforcement happens at the loop boundary — `Stop` hooks run the quality and fidelity
+gates, so a step that skipped its directives is caught before the workflow advances.
+
+## Messaging: `af mail`
+
+Agents coordinate through mail, not shared context:
+
+```bash
+af mail send supervisor -s "Fix auth bug" -m "login.go is not checking token expiry"
+af mail send @all -s "Status" -m "…" # broadcast
+af mail inbox / read / reply -m "…" / delete
+af mail check # exit 0/1 — is there new mail?
+```
+
+Delivery is automatic: the `UserPromptSubmit` hook injects unread mail into the agent's
+context on every prompt, and `SessionStart` injects it at launch. A supervisor started with
+`af up supervisor` needs no operator attention — it picks up mail and works.
+
+## Dispatch: `af sling`
+
+```bash
+af sling --agent rapid-implement "https://github.com/org/repo/issues/42"
+af sling --formula mergepatrol --var pr=123 --agent mergepatrol
+af sling --agent worker "task" --reset # force-reset: close beads, remove worktree, clean state
+```
+
+`af sling` is how work enters the factory — from an operator, from the manager agent, or from
+the GitHub-issue dispatcher (`af dispatch`). Sessions started by sling auto-terminate when
+their formula completes.
+
+## Observing and stopping
+
+```bash
+af attach # attach to the live tmux session (watch or intervene)
+af agents list --json # machine-readable status of every configured agent
+af down worker # stop specific agents
+af down --all # stop everything
+```
+
+## Further reading
+
+- [Formulas](formulas.md) — the workflow definitions agents execute
+- [Recovery model](recovery-model.md) — crash and context-compression survival
+- [README](../README.md) · [Using Agentfactory](../USING_AGENTFACTORY.md) · [Architecture overview](architecture/overview.md)
diff --git a/docs/formulas.md b/docs/formulas.md
new file mode 100644
index 0000000..4190d2b
--- /dev/null
+++ b/docs/formulas.md
@@ -0,0 +1,122 @@
+# Formulas: declarative TOML workflows for Claude Code agents
+
+A **formula** is a declarative workflow definition in TOML. It describes the steps of a job —
+their order, their dependencies, their inputs, and the gates that block completion — separately
+from the agent that executes them. The agent doesn't memorize its workflow; the `af` runtime
+feeds it one step at a time via [`af prime`](agent-lifecycle.md) and advances via `af done`.
+That separation is what makes agent behavior repeatable: the workflow lives in a file you can
+review and version, not inside a persona prompt that drifts.
+
+## Where formulas live
+
+```
+.agentfactory/store/formulas/ # project-local (per repository)
+~/.agentfactory/store/formulas/ # global (shared across projects)
+```
+
+Files are named `.formula.toml`. Agentfactory ships with formulas for
+implementation, review, design, and issue workflows (see `internal/cmd/install_formulas/`).
+
+## Formula types
+
+| Type | Execution model |
+|------|-----------------|
+| `workflow` | Sequential steps with explicit dependencies (the common case) |
+| `convoy` | Parallel legs, then a synthesis step that depends on all of them |
+| `expansion` | Template-based step generation |
+| `aspect` | Multi-aspect parallel analysis |
+
+## Anatomy of a workflow formula
+
+```toml
+formula = "my-workflow"
+description = "What this workflow does and how it progresses."
+version = 1
+
+[inputs]
+[inputs.issue_url]
+description = "GitHub issue to implement"
+type = "string"
+required = true
+
+[vars]
+[vars.branch_prefix]
+description = "Branch naming prefix"
+source = "cli" # cli | env | literal | hook_bead | bead_title | bead_description
+default = "feature"
+
+[[steps]]
+id = "investigate"
+title = "Investigate the issue"
+description = """
+What the agent must do in this step, written as directives.
+Reference variables as {{issue_url}}.
+"""
+
+[[steps]]
+id = "implement"
+title = "Implement the fix"
+needs = ["investigate"] # DAG dependency — this step is not ready until investigate closes
+```
+
+Key fields:
+
+- **`[[steps]]`** — each has an `id`, `title`, `description` (the actual instructions), optional
+ `agent` (per-step owner overriding the formula-level `agent`), optional `needs` (dependencies),
+ and an optional `gate`.
+- **`needs`** — forms a directed acyclic graph. Validation rejects unknown IDs and cycles;
+ execution order is a topological sort (Kahn's algorithm, `internal/formula/sort.go`).
+- **`[inputs]`** — parameters callers must supply at instantiation (`--var key=val`).
+- **`[vars]`** — resolved at instantiation from the declared `source`: the command line, the
+ environment, a literal default, or the hooked work item.
+- **`gate`** — an optional blocking gate on a step (`internal/formula/types.go`); a step with
+ a gate cannot be closed until the gate resolves. Gate steps complete with
+ `af done --phase-complete --gate `, which registers the session as a gate waiter.
+
+Inspect any formula's inputs and vars without opening the file:
+
+```bash
+af formula show --json
+```
+
+## Creating a formula from a SKILL.md
+
+The `/formula-create` skill (run inside Claude Code) converts a SKILL.md — a procedural
+skill document — into a formula:
+
+```
+/formula-create /path/to/your/SKILL.md
+```
+
+It preserves the skill's phase gates as separate formula steps and writes the result to
+`.agentfactory/store/formulas/.formula.toml`.
+
+## Turning a formula into an agent
+
+```bash
+af formula agent-gen # generate workspace, CLAUDE.md template, hooks, registry entry
+af formula agent-gen -o # dry run — print the rendered CLAUDE.md to stdout
+af formula agent-gen --delete
+make install # required: af embeds role templates in the binary (go:embed)
+```
+
+Without the rebuild, the new agent falls back to the generic supervisor template after
+context compression — see [the recovery model](recovery-model.md).
+
+## Running a formula
+
+```bash
+af sling --formula --var key=val --agent # instantiate on an agent
+af sling --agent "task description" # simple task dispatch (no formula)
+af sling --formula --agent --no-launch # create step beads only, don't launch
+```
+
+Instantiation creates one work item ("bead") per step with the DAG encoded as dependencies,
+resolves variables, and (unless `--no-launch`) starts the agent's tmux session. The agent then
+loops: `af prime` → execute step → `af done` → next ready step.
+
+## Further reading
+
+- [Agent lifecycle](agent-lifecycle.md) — how sessions start, work, and stop
+- [Recovery model](recovery-model.md) — how formulas survive crashes and context compression
+- [README](../README.md) · [Using Agentfactory](../USING_AGENTFACTORY.md) · [Architecture overview](architecture/overview.md)
diff --git a/docs/recovery-model.md b/docs/recovery-model.md
new file mode 100644
index 0000000..2eefd8a
--- /dev/null
+++ b/docs/recovery-model.md
@@ -0,0 +1,102 @@
+# Recovery model: how agents survive crashes and context compression
+
+Long-running LLM agents fail in ways ordinary programs don't. The context window fills up and
+gets compressed, silently deleting the instructions the agent was following. Sessions crash
+mid-step. An agent that "remembers" its workflow only in conversation history loses it at
+exactly the wrong moment. Agentfactory's answer is to keep identity and workflow state
+**outside** the model — on disk and in the issue store — and re-inject it at every session
+boundary, so a recovered agent picks up the current step instead of improvising.
+
+## What breaks, concretely
+
+- **Context compression** — Claude Code summarizes the conversation when the window fills.
+ Step directives, variable values, and role framing can be lost or distorted in the summary.
+- **Crashes and disconnects** — the Claude process dies but the tmux session survives (a
+ zombie), or the whole session is gone and uncommitted work sits in the worktree.
+- **Recency bias** — after enough turns, early instructions stop steering behavior even
+ without compression. Improvised shortcuts compound into wrong work.
+
+## The recovery chain
+
+### 1. State lives outside the session
+
+A formula instantiation creates one bead (work item) per step, with DAG dependencies, in the
+issue store. The agent's hook (`.runtime/hooked_formula`) records which formula instance it
+is working. None of this is in the context window, so none of it can be compressed away.
+
+### 2. `af prime` re-injects identity on every session start
+
+The `SessionStart` hook runs `af prime --hook`. Prime outputs the agent's role template
+(embedded in the `af` binary via `go:embed`), session metadata, and the current step's full
+directives, computed from the ready-step frontier in the issue store. A fresh session —
+whether after a crash, a restart, or a compaction recycle — starts with the same authoritative
+context as the first one. This is why `make install` matters after `af formula agent-gen`:
+the template a recovered agent gets is the one compiled into the binary.
+
+### 3. Compaction boundaries are intercepted
+
+The `PreCompact` hook runs `af compact-handoff`, which handles the compaction boundary
+(including preventing thinking-block corruption) and hands the session off cleanly. The
+checkpoint records `compaction_handoff: true` and the compaction time, so the next session
+knows a recycle happened.
+
+### 4. Checkpoints leave breadcrumbs
+
+Whenever a session ends, `.agent-checkpoint.json` in the agent directory captures
+(`internal/checkpoint/`):
+
+| Field | Contents |
+|---|---|
+| `formula_id`, `current_step`, `step_title` | What was being worked |
+| `hooked_bead` | The work item on the agent's hook |
+| `modified_files`, `last_commit`, `branch` | Git state at checkpoint time |
+| `timestamp`, `session_id`, `notes` | Provenance and free-form context |
+
+Checkpoints are deliberately **informational** — breadcrumbs for the next session to read,
+not a database that drives recovery. Recovery decisions come from the issue store's ready
+steps and the hooked formula; the checkpoint tells the recovered agent what the previous
+session had in flight (e.g. "3 modified files on branch X, step `implement` open").
+
+### 5. Identity locks prevent split-brain
+
+Each agent workspace holds a PID-based lock at `.runtime/agent.lock`
+(`internal/lock/`). A second session claiming the same identity gets `ErrLocked` — unless the
+recorded PID is dead, in which case the lock is **stale** and is cleaned up automatically.
+Crash recovery therefore never requires manually deleting lock files.
+
+### 6. Zombie sessions are killed, not trusted
+
+`af up` distinguishes "tmux session exists" from "Claude is running in it." A tmux session
+whose Claude process died is killed and recreated. See
+[agent lifecycle](agent-lifecycle.md).
+
+## The operator's view
+
+Recovery is invisible in the normal case: restart the agent and it resumes.
+
+```bash
+af up worker # zombie or fresh — either way, a working session
+af attach worker # watch it prime itself and continue the open step
+af agents list --json # confirm status
+```
+
+If a formula instance is wedged beyond repair, reset it explicitly rather than hand-editing
+state:
+
+```bash
+af sling --agent worker "…" --reset # close beads, remove worktree, clean runtime state
+```
+
+## Design intent
+
+The invariant behind all of this: **the context window is a cache, never the source of
+truth.** Everything an agent needs to continue — who it is, what step it is on, what the
+step requires — must be reconstructible from disk. See
+[docs/architecture/overview.md](architecture/overview.md) for how this fits the wider
+system design.
+
+## Further reading
+
+- [Formulas](formulas.md) — where workflow state comes from
+- [Agent lifecycle](agent-lifecycle.md) — session start, work loop, shutdown
+- [README](../README.md) · [Using Agentfactory](../USING_AGENTFACTORY.md)