---
name: apt:run
description: "Full pipeline — plan, execute, verify, and review in one command"
apt-skill-version: {{APT_VERSION}}
stage: execute
intent: implement
when_to_use: "The user wants the full pipeline (plan → execute → verify → review) in one invocation, not just a single stage."
user_invocable: true
internal: false
spawns_agent: false
agent_name: null
task_context: self-managed
default_execution_mode: auto
execution_modes:
  - auto
  - step
  - plan-mode
  - plan-only
allowed-tools: "Bash, Read, Write, Edit, Grep, Glob, Task"
argument-hint: "apt:run [task description] [--skip-review] [--phase-mode auto|agent-team|sub-agents|sequential] [--spar-gates plan[,execute]]"
gates: 
  - constitution-read
  - constitution-coverage
config_keys:
  - parallelization.enabled
  - parallelization.max_agents
---
<objective>
Run the full Aperant pipeline: plan a task, execute all subtasks, verify the implementation, and optionally review the code. This is the one-command experience — from task description to verified, reviewed code.

As of C32 the STANDARD and DEEP auto pipelines **terminate on review** (`plan → execute → verify → review`). Pass `--skip-review` to stop after verify; for trivial work the QUICK track still skips planning entirely.
</objective>

<your_environment>
- **Working directory:** The project root (where you were invoked)
- **apt-tools path:** `node packages/framework/bin/apt-tools.mjs` or the locally installed `apt-tools` binary
- **Constitution:** Read `AGENTS.md` in the project root if it exists
- **Skills:** This command orchestrates apt:plan, apt:execute, apt:verify, and apt:review
</your_environment>

<state_files>
## State Files

**Reads:**
- `AGENTS.md` — Project constitution

**Writes (via sub-skills):**
- `spec.md` — From apt:plan
- `implementation_plan.json` — From apt:plan
- `build-progress.json` — From apt:execute
- `qa_signoff.json` — From apt:verify
- `review.json` — From apt:review (unless --skip-review)
</state_files>

<process>

## 1. Initialize

1. Read `AGENTS.md` if it exists
2. Parse task description from `$ARGUMENTS` (everything before flags)
3. Parse flags: `--skip-review`, `--dry-run`, `--phase-mode <mode>`, `--spar-gates <comma-list>`.
   - `--spar-gates <plan|execute|plan,execute>` (FRAMEWORK-RFC-001) — comma-separated stage list to auto-fire `/apt:spar` after. Per-invocation override of `.aperant/config.local.json` `spar.enabled`. On QUICK track, print the verbatim hard-reject line and discard the flag (Fast Path Guarantee — CLAUDE.md):

   ```
   [apt:run] --spar-gates ignored for QUICK track (Fast Path Guarantee)
   ```

   On STANDARD / DEEP / DEBUG tracks, the flag is honored and consumed by §3b (plan gate) and §4b (execute gate). Default is to fall back to merged-config `spar.enabled` semantics — see §3b / §4b for the full resolution order. The flag accepts only `plan`, `execute`, or `plan,execute` — any other value is rejected with `[apt:run] --spar-gates accepts plan, execute, or plan,execute`.

```bash
node packages/framework/bin/apt-tools.mjs state .
```

## 1b. Resolve Orchestration Mode

Run reconcile to determine the effective orchestration strategy for this pipeline run. Pass the task's track via `--track <quick|standard|deep>` so per-track defaults from `.aperant/config.json:orchestration.per_track` apply (roundtable 2026-05-14 R7):

```bash
node packages/framework/bin/apt-tools.mjs reconcile . --track {track}
```

**Per-invocation override:** if the user passed `--phase-mode {auto|agent-team|sub-agents|sequential}` on the invocation, use that value as `PHASE_MODE` directly (it wins over both `per_track` and the global `phase_delegation`). Still call reconcile so `review_mode` and `debate_mode` are resolved against host capabilities.

Parse the result and display:

```
[APT] Orchestration: phase_delegation={resolved.phase_delegation} | review={resolved.review_mode} | debate={resolved.debate_mode}
```

If `downgrades` is present in the result, display each downgrade warning:

```
[APT] Warning: {downgrade.field} requested '{downgrade.requested}' but host does not support it — using '{downgrade.resolved}'. {downgrade.reason}
```

Store `resolved.phase_delegation` (or the explicit `--phase-mode` override) as `PHASE_MODE` for use in the pipeline steps below.

## 2. Create Feature Branch (or task worktree)

If `.aperant/config.json` has `task_isolation.worktree_per_task: true` AND the host supports worktrees, use task-level isolation instead of a plain branch checkout:

```bash
node packages/framework/bin/apt-tools.mjs task create . --description "{task}" --track {track} --autonomy {autonomy}
```

Parse `worktree.worktree_path`, `worktree.branch`, and `worktree.base_branch` from the result. For every subsequent step in this pipeline, prefix Bash commands with `cd {worktree_path} &&` OR pass `worktree_path` as the spawned agent's `cwd`. `apt-tools` commands still receive the project root as their `<project-dir>` — they must hit the main repo's `.aperant/`, which is shared across worktrees. The task directory (`.aperant/tasks/{task-id}/`) is absolute and lives in the main repo, so spec/plan/progress artifacts remain shared regardless of which tree you edit code in.

Otherwise fall back to the legacy branch flow:

```bash
git checkout -b apt/{sanitized-task-name}
```

Sanitize: lowercase, replace spaces/special chars with hyphens, truncate to 50 chars.

If branch already exists (re-run), switch to it:
```bash
git checkout apt/{sanitized-task-name}
```

## 3. Stage 1 — Plan (apt:plan)

Execute the apt:plan workflow inline:

1. Assess complexity of the task description
2. Investigate codebase for relevant files and patterns
3. Write `spec.md` with requirements and acceptance criteria
4. Create `implementation_plan.json` with subtask breakdown
5. Commit plan artifacts

```bash
node packages/framework/bin/apt-tools.mjs commit "plan: create implementation plan for {task}" --files spec.md implementation_plan.json
```

**Output:** spec.md, implementation_plan.json

**Spar hint surface (FRAMEWORK-RFC-001).** If merged-config `spar.hint === true` AND `spar.enabled === false`, print:
```
[apt] plan complete. /apt:spar available before next stage. (skill, not auto-fire)
```
Skip the print on `spar.enabled === true` (the gate handler in §3b already fires).

If `--dry-run` flag is set:
```
Dry run complete. Plan created but not executed.
- Spec: spec.md
- Plan: implementation_plan.json ({n} subtasks)

Remove --dry-run to execute the full pipeline.
```
Exit.

## 3b. Stage 1.5 — Spar Gate (plan)

**FRAMEWORK-RFC-001 — auto-fire `/apt:spar` after the plan stage when consent is on.**

Resolve effective gates:

1. **Track gate.** If track is `QUICK`, **skip this entire section** and continue to §4. QUICK is hard-exempt per CLAUDE.md Fast Path Guarantee. If the user passed `--spar-gates` on a QUICK invocation, §1 already printed the verbatim hard-reject and discarded the flag.
2. **Read merged config** via `loadMergedProjectConfig(.)`:

   ```bash
   node packages/framework/bin/apt-tools.mjs config show . --merged
   ```

   Parse `spar.enabled` (boolean) and `spar.partner` (`'codex' | 'claude' | 'gemini' | null`). When `spar.enabled === true`, build default gates by track: `["plan"]` for STANDARD, `["plan", "execute"]` for DEEP.
3. **Per-invocation override.** If the user passed `--spar-gates <list>` on the `/apt:run` invocation (parsed in §1), the explicit value WINS over merged-config defaults (per-invocation precedence — classic config precedence).
4. **Gate check.** If `"plan"` is not in the resolved gate list, skip the rest of this section.

If `"plan"` is in the resolved gate list, dispatch the spar gate.

**Compose the topic frame (1–2 sentences).** Prefer `spec.md` §Scope (the first paragraph under the `## 1. Scope` heading). If spec.md has no `## 1. Scope` heading (QUICK-skipped or non-PRD-shaped — Open Q4 graceful fallback), use the task description passed to `/apt:run`.

**Dispatch `/apt:spar`** with the topic frame. **Pipeline-mode invocation MUST carry `--timeout-ms 120000`** (2-min Bash-rung fast-fail per spec §4.6 "Pipeline-mode timeout rationale" — pipeline gates run under a tighter budget than manual `apt:spar`). **NO `--rounds` flag** (per FRAMEWORK-BUG-038 fix — pipeline gates always defer to the skill default; passing `--rounds 1` would re-introduce the Round 1 unilateral-terminate bug). When `spar.partner` is set in merged config, append `--with <partner>`; when null, omit `--with` and let `apt:spar` use the host-default-partner mapping in `apt-spar/SKILL.md` §3.

```
/apt:spar --timeout-ms 120000 [--with <partner>] <topic-frame-from-spec.md-or-task-description>
```

**Pipeline-mode timeout rationale.** `apt-spar/SKILL.md:198` "Timeout calibration" notes that modern partner CLIs commonly spend multiple minutes doing real Read/Grep/Bash investigation, justifying the manual-mode 5-min Bash-rung / 15-min MCP-rung defaults. Pipeline-mode partner queries are NARROWER than manual: the gate prompt is a focused 1-2-sentence frame on a specific just-completed stage, not open-ended brainstorming. 2 minutes is adequate for that narrower scope, and `partner-unreachable` (the rung ladder exhausts within 2 min) skips the gate cleanly without blocking the pipeline. Worst-case DEEP wall budget: 2 gates × 3 rounds × 2 min = 12 min (vs ~90 min before this clamp under MCP-rung partner degradation). MCP-rung tightening is out of scope per Open Q5 — see spec §4.6.

**Consent-on but partner-null inline prompt.** If `spar.enabled: true && spar.partner === null` (consent given but no partner detected at install — graceful skip path), prompt the user inline before dispatch (the inline prompt's dispatch ALSO carries `--timeout-ms 120000` and NO `--rounds` flag):

```
[apt:run] Sparring auto-fire is enabled but no partner was set at install. Pick one now ([1] codex / [2] claude / [3] gemini / [s] skip this gate):
```

Map response → invoke `/apt:spar --timeout-ms 120000 --with <id> <topic-frame>` (no `--rounds`), or skip the gate. Do NOT write the choice back to `config.local.json` automatically — the user re-runs `/apt:setup` → Pipeline → Sparring Auto-Fire to persist.

**After spar returns to natural convergence:**

1. Read the spar termination headline (printed inline by `apt:spar/SKILL.md` §9 Layer 1).
2. Capture the Layer 2 file path from the `Full detail:` line of the headline (e.g. `.aperant/spar/<slug>-<YYYYMMDD-HHMMSS>.md`).
3. Append both the one-line headline summary AND the Layer 2 file path into the executor's spawn context for §4 (the executor reads spar findings before subtask 1).

If the gate emits `partner-unreachable` (rung ladder exhausted within timeout), skip the gate cleanly and continue to §4 — do NOT fail the pipeline.

## 4. Stage 2 — Execute (apt:execute)

Branch on `PHASE_MODE`:

**If `PHASE_MODE` is `"agent-team"`:**
Use TeamCreate to spawn agents for each phase. The team handles plan → execute → verify → review as a coordinated unit.

**If `PHASE_MODE` is `"sub-agents"` (default Claude Code behavior):**
Spawn a dedicated sub-agent for each phase using the Agent tool. Each phase agent gets isolated context.

**If `PHASE_MODE` is `"sequential"` (inline, works on any CLI):**

Execute the apt:execute workflow inline:

1. Read implementation_plan.json
2. For each pending subtask (in dependency order):
   a. Read affected files
   b. Implement changes per subtask description
   c. Run subtask verification
   d. Commit atomically
   e. Update subtask status to "completed"
3. Write build-progress.json
4. Flip lifecycle to `verifying` so Stage 3 finds the task in the correct from-state (idempotent; quick tasks no-op):
   ```bash
   node packages/framework/bin/apt-tools.mjs task update . --id {task-id} --lifecycle-phase verifying
   ```

**Checkpoint state:** `build-progress.json` is written after every subtask. That file is the durable resume point — do NOT self-estimate context and do NOT voluntarily exit. Keep executing until the plan is complete or a risk gate stops you. If the harness auto-compacts mid-pipeline, re-read `implementation_plan.json` + `build-progress.json` and continue from the next pending subtask. The `--continue` flag exists for human-initiated resumes (`/apt:pause` + new session), not for agent-initiated bailouts.

**Output:** All subtasks completed, build-progress.json updated

**Spar hint surface (FRAMEWORK-RFC-001).** If merged-config `spar.hint === true` AND `spar.enabled === false`, print:
```
[apt] execute complete. /apt:spar available before next stage. (skill, not auto-fire)
```
Skip on `spar.enabled === true` (the gate handler in §4b already fires).

## 4b. Stage 2.5 — Spar Gate (execute)

**FRAMEWORK-RFC-001 — auto-fire `/apt:spar` after the execute stage on DEEP (or explicit user opt-in).**

Same resolution logic as §3b, but the gate name is `"execute"` and the topic frame is composed from `build-progress.json` (1–2 sentences summarizing the diff that just landed, e.g. "N subtasks completed against the M-file plan; the largest change touched <path>"). If `build-progress.json` is missing or empty, fall back to the task description (Open Q4 graceful fallback).

**Track gate:** if track is `QUICK`, skip this section entirely (Fast Path Guarantee). Default gates from merged-config `spar.enabled === true` only include `"execute"` on DEEP. STANDARD does NOT enter this block by default; DEEP does. User-passed `--spar-gates plan,execute` opts STANDARD into this block too (per-invocation precedence).

**Gate check:** if `"execute"` is not in the resolved gate list, skip this section.

If `"execute"` is in the resolved gate list, dispatch as in §3b — same pipeline-mode budget:

```
/apt:spar --timeout-ms 120000 [--with <partner>] <topic-frame-from-build-progress.json>
```

**NO `--rounds` flag** (per FRAMEWORK-BUG-038 — pipeline always defers to skill default). Same `--timeout-ms 120000` 2-min Bash-rung fast-fail as §3b. Same inline-prompt path for the `enabled: true && partner === null` graceful-skip case (the inline-prompt dispatch ALSO carries `--timeout-ms 120000`).

After spar returns, parse the termination headline + Layer 2 path and append both into the verifier's spawn context for §5 (the verifier reads execute-gate spar findings alongside its de-anchored re-read).

`partner-unreachable` skips the gate cleanly — pipeline continues to §5.

## 5. Stage 3 — Verify (apt:verify)

**De-anchored re-read (PHASE_MODE=sequential only — roundtable 2026-05-14 R2):**

When `PHASE_MODE` is `"sequential"` and the same agent that ran Stage 2 is about to run Stage 3 in the same context window, treat the boundary as an attention reset before proceeding. The agent MUST:

1. **Re-read `spec.md` from disk** — do not rely on its in-context summary from earlier in the conversation
2. **Re-read the diff from disk** via `git diff {base_branch}...HEAD` — verify what was actually written, not what was intended
3. **Adopt adversarial QA posture** — for the duration of Stage 3 you are not the implementer; you are reading this code for the first time, asking "what does this break?" rather than "did I do this right?"
4. **Ignore your prior reasoning chain** — the executor's "why I did it this way" rationalization is in-window but MUST NOT anchor the verifier's reading. If a finding conflicts with prior reasoning, prefer the finding

This block exists because the roundtable's STANDARD-track de-anchoring relies on prompt-level discipline rather than fresh-context isolation. The exit condition: if verify completeness+correctness scores drop >0.5 points across 10+ STANDARD tasks measured under R6 telemetry, flip `orchestration.per_track.standard` to `"sub-agents"` (R3 — the named fallback preserved from Systems Analyst + Risk Analyst dissent). See `.aperant/roundtables/phase-mode-per-track-20260514/REPORT.md` §Dissenting Views.

Sub-agents and agent-team modes skip this block — they get fresh-context isolation by spawning, which makes the de-anchored re-read redundant.

**Spar findings context (FRAMEWORK-RFC-001).** If §3b or §4b dispatched `/apt:spar`, the verifier MUST read the Layer 2 file (`.aperant/spar/<slug>-<YYYYMMDD-HHMMSS>.md`) before scoring — both gate files when DEEP fired both gates. Spar findings flagged as `parallel call-outs` in the Layer 2 file may require `qa_signoff.json` `notes` entries even when not blocking. The headline summary already lives in the verifier's spawn context (appended by §3b / §4b); the Layer 2 read is the load-bearing detail loop.

Execute the apt:verify workflow inline:

1. Check all subtasks completed
2. Run test suite
3. Run type checker
4. Run linter
5. Review changed files against spec
6. Score on 4 dimensions (completeness, correctness, quality, coverage)
7. Fix all issues found — every severity, not just critical (up to 4 iterations: first 2 discovery, last 2 verification-only)
8. Write qa_signoff.json
9. If `status` is `approved` or `approved-with-notes`, flip lifecycle to `reviewing` so Stage 4 (or `/apt:ship` when review is skipped) finds the task in the correct from-state. Skip this step entirely on `rejected`:
   ```bash
   node packages/framework/bin/apt-tools.mjs task update . --id {task-id} --lifecycle-phase reviewing
   ```

**Output:** qa_signoff.json with status

**Spar hint surface (FRAMEWORK-RFC-001).** If merged-config `spar.hint === true` AND `spar.enabled === false`, print:
```
[apt] verify complete. /apt:spar available before next stage. (skill, not auto-fire)
```
Skip on `spar.enabled === true` (no verify-stage gate exists in v2 — see spec §8 Out of Scope; this nudge surfaces /apt:spar as a manual option only).

If `qa_signoff.json` status is `"rejected"` after max iterations:
```
Verification failed after {n} iterations. Issues remain:
{list critical issues}

Review qa_signoff.json for details.
Fix manually and re-run /apt:verify
```
Stop pipeline (do not proceed to review).

## 6. Stage 4 — Review (apt:review)

**Skip if** `--skip-review` flag is set.

**De-anchored re-read (PHASE_MODE=sequential only — roundtable 2026-05-14 R2):**

Same attention-reset discipline as Stage 3 applies before review starts. In sequential mode the reviewer is the same agent that planned, executed, and verified — the rationalization chain is in-window. Before the 6-pass loop:

1. **Re-read `spec.md` and `qa_signoff.json` from disk** — do not summarize from in-context recall
2. **Re-read changed files** at their post-execution state via `git show HEAD:{path}` or direct Read
3. **Adopt fresh-reviewer posture** — you are reading this code as if a colleague wrote it, not as if you wrote it. The 6 review passes (logic / security / quality / architecture / performance / docs-coherence) are independent lenses; treat each lens as a fresh adversarial reading

Pattern reference: `packages/core/src/workflows/sparring/engine.ts` implements this exact discipline for sparring reviewers (fresh `streamText` per lens, lens prompt in system slot). This SKILL.md block is the same idea applied to verify/review in a single-context pipeline.

Execute the apt:review workflow inline (see `apt-review/SKILL.md`):

1. Load context — spec, QA results, constitution
2. Review all changed files across 6 passes (logic, security, quality, architecture, performance, docs-coherence)
3. Fix all findings — every severity, up to 4 iterations (first 2 discovery, last 2 verification-only). `docs-drift` `auto-update` findings are patched inline; `flag-drift` findings are surfaced only in `review_findings.md`, never auto-edited.
4. Update task documentation — review.json, qa_signoff.json (re-score if fixes changed quality), build-progress.json
5. Write review.json with final findings and assessment. The `docs_policy` at `.aperant/config.json.docs_policy` controls per-surface behavior; defaults in `packages/framework/templates/docs-policy-defaults.json`.

`lifecycle_phase` stays at `reviewing` after this stage — /apt:ship handles the next transition (`reviewing → shipped-pending-merge`).

**Output:** review.json (written to task directory)

**Spar hint surface (FRAMEWORK-RFC-001).** If merged-config `spar.hint === true` AND `spar.enabled === false`, print:
```
[apt] review complete. /apt:spar available before next stage. (skill, not auto-fire)
```
Skip on `spar.enabled === true` (no pre-ship gate exists in v2 — see spec §8 Out of Scope).

**This is the task review, not the PR review.** It runs inline without sub-agents. For heavy multi-agent PR review, use `/apt:pr-review` separately.

## 7. Pipeline Summary

Render the phase rail panel verbatim — branch glyphs `┌─ │ └─`, status glyphs `✓` (done) / `●` (active) / `○` (pending/skipped), inline metrics per row drawn from the artifacts written across §3–§6:

```
[APT] Pipeline Complete: {task description}
┌─ Phase rail: {short task name} ───────────────────
│  Phase 1 Plan       ✓  {n} subtasks
│  Phase 2 Execute    ✓  {completed}/{total} subtasks, {k} commits
│  Phase 3 Verify     ✓  {qa_status} {completeness}/{correctness}/{quality}/{coverage}
│  Phase 4 Review     ✓  {assessment} {scores}, {findings_count} findings ({fixed} fixed)
└───────────────────────────────────────────────────
Branch: apt/{sanitized-task-name}
Artifacts: spec.md · implementation_plan.json · build-progress.json · qa_signoff.json · review.json
```

Substitute live values from the on-disk artifacts: `build-progress.json.completed_subtasks.length` for the commits count, `qa_signoff.json.verdict` + `scores` for verify, `review.json.assessment` + `scores` + `findings.length` for review. Use `●` for a stage still in flight (e.g. verify rejected mid-rerun), `○` only for a stage skipped entirely. The `[APT] Pipeline Complete` header above the panel is the backward-compat marker for external log-grep tooling — keep it.

**Always end with a "What's Next" recommendation:**

```
{If review assessment is "approve" and QA approved:}
-> Recommended: /apt:ship — create PR for this task
   Also: /apt:pr-review (deep multi-agent review) | manual review

{If review assessment is "request-changes":}
-> {n} issues remain. Fix them manually, then re-run /apt:review
   Also: /apt:verify to re-score after fixes

{If QA rejected and review not reached:}
-> Verification failed. Fix issues and re-run /apt:verify
```

```bash
node packages/framework/bin/apt-tools.mjs commit "pipeline: complete {task}" --files spec.md implementation_plan.json build-progress.json qa_signoff.json review.json
```

## 8. Lifecycle transitions

Lifecycle phase transitions are handled by the child skills themselves.
`apt:execute` flips `planned` → `in-progress` at start (lifecycle = `executing`)
and at success-end (lifecycle = `verifying`). `apt:verify` flips lifecycle =
`reviewing` on the approved verdict (skipped on `rejected`). `apt:review`
leaves lifecycle at `reviewing` — the from-state `/apt:ship` expects for its
atomic `reviewing → shipped-pending-merge` flip. `/apt:ship` then flips
`reviewing → shipped-pending-merge`, and `/apt:close-task` later flips
`shipped-pending-merge → completed` after the PR merges. The pipeline wrapper
does not need to record or drain anything beyond ensuring each child-skill
stage runs to its success-end.

</process>
</output>
