---
name: armature-coordinator
description: >
  Use when operating orchestration in an armature-managed repository — runs the
  pull loop (`arm ready` + `arm orchestrate`), scales concurrent orchestrators,
  integrates outcomes, validates citation coverage, and closes stories with a
  pull request. Manual worker dispatch remains available as a fallback path.
  Does not require a worker identity (skip worker-init). Requires arm on PATH.
compatibility: Designed for Claude Code and Gemini CLI. Requires arm on PATH.
---

# Armature Coordinator Loop (Orchestrator-First)

The coordinator manages execution flow — it does not implement features itself.
Its default job is to run and supervise orchestrators that pull from `arm ready`
and execute via `arm orchestrate`.

## Prerequisites

1. If `arm` is not found, stop and resolve this before proceeding.

2. **No worker identity required.** The coordinator skips `arm worker-init`.
   Orchestrator ops (claims, story transitions) go to the plain `<worker-id>.log`;
   if no worker ID is set, armature uses a fallback. Only workers need an identity.

3. Understand the story DAG before dispatching. Run:
   ```
   arm list --parent STORY-ID          # all tasks + statuses
   arm list --status blocked           # diagnose any blockers
   arm doctor                          # repo health check
   ```
   Fix any `doctor` errors before claiming work.

## The Coordinator Loop

```dot
digraph coordinator_loop {
    "arm ready" [shape=box];
    "Empty?" [shape=diamond];
    "Parallel?" [shape=diamond];
    "Sequential wave" [shape=box];
    "Parallel wave" [shape=box];
    "Assign slots + claim all" [shape=box];
    "render-context all" [shape=box];
    "dispatch workers" [shape=box];
    "wait + integrate" [shape=box];
    "arm validate" [shape=box];
    "transition story" [shape=box];
    "push + PR" [shape=box];
    "Done" [shape=doublecircle];

    "arm ready" -> "Empty?";
    "Empty?" -> "arm validate" [label="yes — all done"];
    "Empty?" -> "Parallel?" [label="no"];
    "Parallel?" -> "Sequential wave" [label="no deps between tasks"];
    "Parallel?" -> "Parallel wave" [label="independent tasks"];
    "Sequential wave" -> "dispatch workers";
    "Parallel wave" -> "Assign slots + claim all";
    "Assign slots + claim all" -> "render-context all";
    "render-context all" -> "dispatch workers";
    "dispatch workers" -> "wait + integrate";
    "wait + integrate" -> "arm ready";
    "arm validate" -> "transition story";
    "transition story" -> "push + PR";
    "push + PR" -> "Done";
}
```

## Step-by-Step

### 1. Survey the Story and Create a Feature Branch

```bash
arm list --parent STORY-ID
arm doctor
git checkout -b feat/STORY-ID   # create the story branch NOW, before any worker is dispatched
```

Identify which tasks are `open` and which have `blocked_by` dependencies. Group
tasks into waves — tasks within the same wave have no dependencies on each other
and can run in parallel. Tasks in different waves must run sequentially.

**Create the feature branch before dispatching any worker.** All workers commit
to this branch. If workers are dispatched without a branch, they default to
whatever branch the repo is on — typically `main` — and the story cannot be
reviewed via PR.

### 2. Find Ready Work

```bash
arm ready                              # unblocked, unclaimed tasks
```

If `arm ready` returns nothing and not all tasks are `done`, check for
dependency cycles or stalled in-progress tasks:
```bash
arm ready --explain                    # why each open task is NOT ready (blocked/claimed/missing dep)
arm list --status in-progress          # claims that may have expired
arm list --status blocked              # diagnose blockers
```

`arm ready --explain` prints a per-task diagnosis for every open task that
did not make it into the ready queue. Use it as the first step whenever the
queue looks unexpectedly empty.

### 3. Default Dispatch: Orchestrator Pull Loop

For each ready task:

```bash
arm orchestrate --issue TASK-ID
```

If it succeeds, run `arm ready` again. If it escalates, inspect task state with
`arm show TASK-ID`, resolve the issue (scope, acceptance, harness/model), then
retry orchestration.

### 4. Parallel Dispatch (independent tasks in one wave)

Run multiple orchestrator processes concurrently. Each process:
1. calls `arm ready`
2. selects a ready task
3. runs `arm orchestrate --issue TASK-ID`
4. repeats until no tasks are ready

Claim collisions are normal under concurrency. The loser should simply poll
`arm ready` again and continue with the next task.

### 5. Manual Worker Dispatch (Fallback Path)

Use this only for exceptional cases that require human-guided execution. For
manual dispatch details and log slot setup, see
`references/parallel-dispatch.md`.

---

## Manual Fallback Appendix

Everything below is for manual worker dispatch only. Do not use this appendix
for normal orchestrator pull-mode operations.

## Dispatch Protocol

Each worker's context package must contain:

0. **Skill invocation (VERY FIRST instruction):**
   ```
   You are an armature worker. Invoke the `armature-worker` skill via the Skill tool before proceeding.
   ```
   This must appear before everything else — the skill loads the worker's
   operating procedure and pre-flight checks. Workers that skip this step
   may miss critical setup steps or validations.

1. **Log slot (second instruction, before any `arm` command):**
   ```
   Before running any arm command, run: export ARM_LOG_SLOT=<assigned-slot>
   ```
   This must be the second line of the worker's prompt — immediately after
   the skill invocation and before any other instructions. See
   [Log Slots](#log-slots-for-parallel-dispatch) for why.

2. **Full `render-context` output** — this is the worker's complete task spec.
   Do not summarize it; pass it verbatim.

3. **Pre-claimed notice** — tell the worker the issue is already claimed and it
   must NOT run `arm claim` again:
   ```
   This issue has been pre-claimed. Do NOT run `arm claim`. Do NOT run `arm worker-init`.
   ```

4. **Repository location:**
   ```
   Working directory: /path/to/repo
   ```

5. **Branch** — pass the story feature branch name so the worker checks it out
   before making any commits:
   ```
   Working branch: feat/STORY-ID  — run `git checkout feat/STORY-ID` before committing.
   ```

6. **Commit instruction** — instruct the worker to stage files explicitly using
   the task's `scope` field, not `git commit -am` (which silently skips new files):
   ```
   Commit: git add <each file listed in scope> && git commit -m "feat(ISSUE-ID): ..."
   ```

**Dispatch using your platform's agent dispatch capability** — the exact tool
or API call depends on your runtime. The content above is what matters; the
mechanism is platform-specific.

> **Background agent Bash limitation:** Background agents (e.g. sub-agents
> dispatched via the API without an active terminal session) cannot inherit the
> parent session's Bash permissions. Shell commands will block silently, causing
> the worker to hang indefinitely. To avoid this, prefer one of:
> - **Direct implementation** — have the coordinator implement small, well-scoped
>   tasks itself rather than dispatching a background agent.
> - **Foreground worktrees** — create a git worktree manually and run the worker
>   in a foreground terminal session so it inherits Bash permissions from the
>   active shell.

---

## After Workers Return

Run this integration checklist after each wave completes:

### a. Check task status
```bash
arm list --parent STORY-ID            # confirm all wave tasks are done
arm list --status in-progress         # any stragglers?
```

### b. Check for scope conflicts and merge conflicts

If workers operated in separate git worktrees or branches, merge them into the
story feature branch now. Resolve any conflicts before proceeding. Check for
files that were modified by multiple workers.

### c. Mark completed tasks merged

For every task that finished in the wave, run:

```bash
arm merged --issue TASK-ID
```

This promotes each completed task from `done` to `merged` so dependent work can
unblock cleanly before the next wave begins. Do this immediately after task
status verification and before the build check.

### d. Verify build integrity
```bash
make check    # or the repo's equivalent: lint, tests, coverage
```

Do not proceed to the next wave or story close if the build is red.

### e. Check citation coverage
```bash
arm validate
```

Every issue that was touched should appear as cited. If `validate` shows
`uncited node: ID`, run:
```bash
arm source-link --issue ID --source SOURCE-UUID   # if a source doc exists
# or
arm accept-citation --issue ID --ci               # if no source, mark as self-citing
```

Repeat until `arm validate` shows no errors.

### f. Clean up worktrees

If workers used git worktrees, remove them after their branches are merged into
the story feature branch:

```bash
git worktree list                          # confirm which worktrees exist
git worktree remove <path> --force         # remove each worker worktree
git branch -d <worker-branch>             # delete the local branch if no longer needed
```

Leaving stale worktrees causes `git worktree list` clutter and can block future
worktree operations on the same path.

### g. Continue to next wave
```bash
arm ready    # next wave should now be unblocked
```

Repeat the loop from step 2.

---

## Story Completion

When `arm ready` returns empty and all tasks are `done`:

### 1. Run the Auditor (pre-merge gate)

Dispatch the **armature-auditor** skill as a subagent before any story transition.
The auditor is a five-step pre-merge gate — it must give all-clear before you
proceed.

**Invoke via the `Skill` tool:**
```
Skill("armature-auditor")
```

The auditor checks, in order:
1. Citation integrity (`arm validate` — zero ERRORs, `COVERAGE: N/N cited`)
2. Source freshness (`arm sources verify` — zero MISSING)
3. Outcome quality (concrete outcomes against acceptance criteria for each done task)
4. Scope overlap (`arm validate --strict` — zero overlap warnings)
5. Repo health (`arm doctor --strict` — exit zero)

**Do not proceed to step 2 until the auditor reports all five checks green.**
If the auditor flags issues, return them to the relevant workers for remediation,
then re-run the auditor before continuing.

### 2. Transition the story
```bash
arm transition STORY-ID --to done --outcome "brief summary of what was delivered"
```

`arm transition` will error if any uncited issues remain — the auditor in step 1
should have caught this.

### 3. Commit armature ops (single-branch mode only)

In single-branch mode, story and epic transitions generate ops that need a
mop-up commit:
```bash
git status
git add .armature/ && git commit -m "chore(STORY-ID): sync armature state"
```

In **dual-branch mode** (`git config --local armature.mode` returns `dual-branch`),
ops are automatically committed to the `_armature` branch. Omit `.armature/` from
the code commit; include only code files if any remain unstaged.

### 4. Push and open PR
```bash
git push -u origin HEAD
# Open a PR targeting your main/base branch
# PR title: the story title
# PR body: list each task ISSUE-ID and its one-line outcome
```

**One PR per story** — not per task (too many small PRs), not per epic (too
large to review). Story-level PRs give reviewers clear scope.

**CI and tag-push note:** If your CI pipeline triggers on tag pushes as well
as branch pushes, story feature branches (e.g. `feat/STORY-ID`) will not
accidentally fire tag-based workflows as long as your CI config uses a
`branches:` filter. Example for GitHub Actions:

```yaml
on:
  push:
    branches:
      - main
      - 'feat/**'
```

Without a `branches:` filter a `git push --tags` can trigger branch-push
workflows unexpectedly. If you see spurious CI runs after tagging, add or
tighten the `branches:` filter in your workflow file.

For JSON query patterns and the full command reference, see `references/commands.md`.

---

## Common Failure Modes

| Failure | Cause | Fix |
|---|---|---|
| Parallel agents share one log, attribution lost | Forgot to embed `ARM_LOG_SLOT` in each agent's prompt | Include `export ARM_LOG_SLOT=<slot>` as the first instruction in each agent's prompt before dispatch |
| Build breaks after merging parallel branches | Skipped integration verification | After each wave, run `make check` (or equivalent) on the merged result before claiming the next wave |
| `arm transition STORY-ID --to done` errors with uncited nodes | Story transitioned before all issues were cited | Run `arm validate`; for each `uncited node: ID`, run `arm source-link` or `arm accept-citation --ci`; then retry transition |
| Armature ops from story/epic transitions are never committed | Forgot mop-up commit before push | After story transition, run `git status`; if `.armature/` has changes, commit them with `git add .armature/ && git commit -m "chore(STORY-ID): sync armature state"` before pushing (single-branch mode only) |
