Three insertions in commands/ultraexecute-local.md so every session-end path produces or refreshes .session-state.local.json (Handover 7): - Phase 2.55 (Check 1, line ~376): write status=stopped on dirty-tree pre-flight stop before parallel session-spawn - Phase 4 (line ~773): write status=stopped when entry condition fails - Phase 8 (line ~1151): canonical convergence — every completed/failed/ stopped/partial run refreshes the state file using atomicWriteJson + validator verification Phase 2.3 (validate exit) and Phase 5 (dry-run) intentionally skip the write — neither path is resumable. Validator errors warn but never block the run; progress.json remains authoritative. [skip-docs] rationale: README + CLAUDE.md updates land in Step 11. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1367 lines
49 KiB
Markdown
1367 lines
49 KiB
Markdown
---
|
||
name: ultraexecute-local
|
||
description: Disciplined plan executor — single-session or multi-session with parallel orchestration, failure recovery, and headless support
|
||
argument-hint: "[--project <dir>] [--fg | --resume | --dry-run | --validate | --step N | --session N] [plan.md]"
|
||
model: opus
|
||
allowed-tools: Read, Write, Edit, Bash, Glob, Grep, AskUserQuestion
|
||
---
|
||
|
||
# Ultraexecute Local
|
||
|
||
Disciplined executor for ultraplan plans. Reads a plan file, detects if it has
|
||
an Execution Strategy (multi-session), and either executes directly or
|
||
orchestrates parallel headless sessions — all to realize one plan.
|
||
|
||
Designed to work identically in interactive and headless (`claude -p`) mode.
|
||
|
||
## Phase 1 — Parse mode and validate input
|
||
|
||
Parse `$ARGUMENTS` for mode flags:
|
||
|
||
1. If arguments contain `--project <dir>`: extract the directory path.
|
||
- Resolve `{dir}` (trim trailing slash).
|
||
- Set **project_dir = {dir}**.
|
||
- Derive implicit file path: `{dir}/plan.md`.
|
||
- If `{dir}` does not exist or `{dir}/plan.md` is missing:
|
||
```
|
||
Error: project directory missing plan.md: {dir}
|
||
Run /ultraplan-local --project {dir} to produce it.
|
||
```
|
||
- If no explicit `<plan.md>` argument is provided after flag parsing,
|
||
use the derived `{dir}/plan.md`. If a `<plan.md>` argument IS provided,
|
||
use that path but keep `project_dir` set (user may be pointing at a
|
||
recovery session spec inside the project).
|
||
- Continue parsing remaining flags (they combine with `--project`).
|
||
2. If arguments contain `--fg`: extract the file path. Set **mode = foreground**.
|
||
3. If arguments contain `--resume`: extract the file path. Set **mode = resume**.
|
||
4. If arguments contain `--dry-run`: extract the file path. Set **mode = dry-run**.
|
||
5. If arguments contain `--validate`: extract the file path. Set **mode = validate**.
|
||
6. If arguments contain `--step N` (N is a positive integer): extract N and the file path.
|
||
Set **mode = step**, **target-step = N**.
|
||
7. If arguments contain `--session N` (N is a positive integer): extract N and the file path.
|
||
Set **mode = session**, **target-session = N**.
|
||
8. Otherwise: the entire argument string is the file path. Set **mode = execute**.
|
||
|
||
If no path is provided (and `--project` was not used to derive one), output
|
||
usage and stop:
|
||
|
||
```
|
||
Usage: /ultraexecute-local <plan.md>
|
||
/ultraexecute-local --project <dir>
|
||
/ultraexecute-local --fg <plan.md>
|
||
/ultraexecute-local --resume <plan.md>
|
||
/ultraexecute-local --dry-run <plan.md>
|
||
/ultraexecute-local --validate <plan.md>
|
||
/ultraexecute-local --step N <plan.md>
|
||
/ultraexecute-local --session N <plan.md>
|
||
/ultraexecute-local --project <dir> --resume
|
||
/ultraexecute-local --project <dir> --session N
|
||
|
||
Modes:
|
||
(default) Auto — multi-session if plan has Execution Strategy, else foreground
|
||
--project Resolve plan.md inside an ultrabrief project folder; progress.json
|
||
is written there too
|
||
--fg Force foreground — all steps sequentially, ignore Execution Strategy
|
||
--resume Resume from last progress checkpoint
|
||
--dry-run Validate plan and show execution strategy without running
|
||
--validate Schema-only check — parse steps + manifests, no security scan, no execution
|
||
--step N Execute only step N (foreground)
|
||
--session N Execute only session N from the plan's Execution Strategy
|
||
|
||
Examples:
|
||
/ultraexecute-local .claude/plans/ultraplan-2026-04-06-auth-refactor.md
|
||
/ultraexecute-local --project .claude/projects/2026-04-18-jwt-auth
|
||
/ultraexecute-local --project .claude/projects/2026-04-18-jwt-auth --resume
|
||
/ultraexecute-local --fg .claude/plans/ultraplan-2026-04-06-auth-refactor.md
|
||
/ultraexecute-local --session 2 .claude/plans/ultraplan-2026-04-06-auth-refactor.md
|
||
/ultraexecute-local --dry-run .claude/plans/ultraplan-2026-04-06-auth-refactor.md
|
||
/ultraexecute-local --validate .claude/plans/ultraplan-2026-04-06-auth-refactor.md
|
||
```
|
||
|
||
If the file does not exist, report and stop:
|
||
```
|
||
Error: file not found: {path}
|
||
```
|
||
|
||
Report detected mode:
|
||
```
|
||
Mode: {execute | resume | dry-run | step N | session N}
|
||
Project: {project_dir or "-"}
|
||
File: {path}
|
||
```
|
||
|
||
## Phase 2 — Detect file type and parse structure
|
||
|
||
Read the file. Determine whether it is an **ultraplan** or a **session spec**:
|
||
|
||
- **Session spec**: contains `## Dependencies` with `Entry condition:` AND `## Scope Fence`
|
||
AND `## Exit Condition` sections.
|
||
- **Ultraplan**: contains `## Implementation Plan` with numbered `### Step N:` headings
|
||
but no `## Scope Fence`.
|
||
|
||
If neither structure is detected, report and stop:
|
||
```
|
||
Error: unrecognized file format. Expected an ultraplan or session spec.
|
||
```
|
||
|
||
### Parse steps
|
||
|
||
Extract every `### Step N: {description}` heading (in order). For each step, extract:
|
||
- **Files** — file paths to create or modify
|
||
- **Changes** — what to modify
|
||
- **Reuses** — existing code to leverage (informational)
|
||
- **Test first** — test to run before implementation (optional)
|
||
- **Verify** — command to run after implementation
|
||
- **On failure** — recovery action (revert/retry/skip/escalate)
|
||
- **Checkpoint** — git commit command after success
|
||
- **Manifest** — YAML block following Checkpoint (v1.7+)
|
||
|
||
If a step is missing `On failure`, default to `escalate` and record a parse warning.
|
||
If a step is missing `Verify`, record a parse warning.
|
||
|
||
### Parse the Manifest block (v1.7+)
|
||
|
||
Read the plan header for a `plan_version` marker. Treat ≥ `1.7` as strict
|
||
mode; absence or <1.7 as legacy mode.
|
||
|
||
**Strict mode (plan_version ≥ 1.7):**
|
||
- Every step MUST have a `Manifest:` block with a YAML fenced payload.
|
||
- Parse the YAML. Required keys: `expected_paths` (list), `min_file_count`
|
||
(integer), `commit_message_pattern` (string), `bash_syntax_check` (list),
|
||
`forbidden_paths` (list), `must_contain` (list of `{path, pattern}` dicts).
|
||
- Validate each `commit_message_pattern` compiles as a regex (use a tolerant
|
||
parser — do not execute untrusted input against shell).
|
||
- If any step is missing its Manifest, or YAML is malformed, STOP with:
|
||
```
|
||
Error: plan_version=1.7 but step {N} has invalid/missing Manifest.
|
||
Re-run planning-orchestrator — plan is not executable.
|
||
```
|
||
|
||
**Legacy mode (no plan_version, or < 1.7):**
|
||
- Synthesize a minimal manifest per step:
|
||
- `expected_paths` ← step's `Files:` list
|
||
- `min_file_count` ← `len(expected_paths)`
|
||
- `commit_message_pattern` ← regex-escape first 3 words of Checkpoint msg
|
||
- `bash_syntax_check` ← auto-detect `.sh` in Files
|
||
- `forbidden_paths` ← []
|
||
- `must_contain` ← []
|
||
- Record `legacy_plan: true` in the progress file.
|
||
- Emit warning: `Legacy plan (v1.6 or earlier) — manifests synthesized with
|
||
reduced audit precision.`
|
||
|
||
### Parse Session Manifest (session specs only)
|
||
|
||
If the file is a session spec (v1.7+), parse the `## Session Manifest` block
|
||
into a YAML dict. Preserve `session_manifest.*` fields for Phase 7.5 audit.
|
||
If missing and `plan_version ≥ 1.7`, record a parse warning but continue —
|
||
the per-step manifests are still available for audit.
|
||
|
||
### Parse session spec fields (if applicable)
|
||
|
||
- **Entry condition** from `## Dependencies`
|
||
- **Touch list** and **Never-touch list** from `## Scope Fence`
|
||
- **Exit condition** checklist from `## Exit Condition`
|
||
|
||
### Parse Execution Strategy (if present)
|
||
|
||
If the plan contains an `## Execution Strategy` section, extract:
|
||
- Each `### Session N: {title}` with its Steps, Wave, Depends on, and Scope fence
|
||
- The `### Execution Order` with wave definitions
|
||
|
||
Set **has_execution_strategy = true**.
|
||
|
||
Report:
|
||
```
|
||
Type: {plan | session-spec}
|
||
Steps: {N}
|
||
{if has_execution_strategy}: Execution Strategy: {S} sessions across {W} waves
|
||
{if session spec}: Entry condition: {text}
|
||
{if session spec}: Scope fence: {N} touch, {N} never-touch
|
||
{if warnings}: Warnings: {list}
|
||
```
|
||
|
||
## Phase 2.3 — Validate-only mode exit (if mode = validate)
|
||
|
||
**If mode = validate, stop after Phase 2 parsing** and emit a schema-only
|
||
report. Do NOT run security scan, do NOT touch progress files, do NOT
|
||
execute any steps. This gives the user a fast sanity-check of plan
|
||
schema compliance without side effects.
|
||
|
||
**Preferred path (since v3.1.0):** invoke the plan validator directly. It
|
||
returns the same diagnostic info Phase 2 derives in prose, with stable
|
||
error codes for downstream tooling:
|
||
|
||
```bash
|
||
node ${CLAUDE_PLUGIN_ROOT}/lib/validators/plan-validator.mjs --strict --json "{path}"
|
||
|
||
# When --project is in scope and progress.json exists, also validate it:
|
||
[ -f "{project_dir}/progress.json" ] && \
|
||
node ${CLAUDE_PLUGIN_ROOT}/lib/validators/progress-validator.mjs --json "{project_dir}/progress.json"
|
||
```
|
||
|
||
Map the validator's `code` field to the error templates below (e.g.
|
||
`PLAN_FORBIDDEN_HEADING` → "Detected heading format" branch). When both
|
||
calls exit 0, render the READY report. Otherwise render FAIL with the
|
||
validator's first error code + message.
|
||
|
||
If Phase 2 parsing succeeded (no fatal errors, every step has a valid
|
||
Manifest block in strict mode, or synthesized manifests in legacy mode):
|
||
|
||
```
|
||
=== Schema Validation: READY ===
|
||
File: {path}
|
||
Type: {plan | session-spec}
|
||
plan_version: {1.7 | legacy}
|
||
Steps: {N}
|
||
Manifests: {N valid | N synthesized (legacy)}
|
||
Warnings: {count}
|
||
{if warnings}: - {each warning on own line}
|
||
|
||
Plan is schema-compliant. Safe to run:
|
||
/ultraexecute-local {path}
|
||
```
|
||
|
||
If Phase 2 parsing failed (unrecognized format, missing Manifest in strict
|
||
mode, malformed YAML, invalid regex):
|
||
|
||
```
|
||
=== Schema Validation: FAIL ===
|
||
File: {path}
|
||
Reason: {specific error from Phase 2}
|
||
|
||
{if format not recognized}:
|
||
Detected heading format: {e.g. "### Fase 1:", "## Phase 1"}
|
||
Expected: "### Step N: <description>"
|
||
Fix: re-run /ultraplan-local — planning-orchestrator must emit v1.7 format
|
||
|
||
{if missing manifest}:
|
||
Step {N} has no Manifest block (plan_version=1.7 requires one per step)
|
||
Fix: re-run /ultraplan-local — planning-orchestrator must include manifest YAML
|
||
|
||
{if malformed YAML or invalid regex}:
|
||
Step {N}: {specific YAML/regex error}
|
||
Fix: edit the plan manually or re-run /ultraplan-local
|
||
```
|
||
|
||
Exit after emitting the report. Do not continue to Phase 2.4 or later.
|
||
|
||
## Phase 2.4 — Pre-execution security scan
|
||
|
||
**Runs for all modes except dry-run and validate** (those modes exit earlier or have their own report format).
|
||
|
||
Scan every `Verify:` and `Checkpoint:` command in the parsed plan against the
|
||
executor security denylist. This catches dangerous commands before execution begins.
|
||
|
||
### Extract commands
|
||
|
||
For each step in the plan, extract the command string from:
|
||
- `Verify:` field (the shell command after the backtick-quoted command)
|
||
- `Checkpoint:` field (the git commit command)
|
||
|
||
Also extract Exit Condition commands if present.
|
||
|
||
### Check against denylist
|
||
|
||
For each extracted command, check against these patterns:
|
||
|
||
**BLOCK patterns (stop execution immediately):**
|
||
|
||
| Pattern | Threat |
|
||
|---------|--------|
|
||
| `rm` with both `-r` and `-f` flags (any order) | Recursive force delete |
|
||
| `chmod 777` or `chmod -R 777` | World-writable permissions |
|
||
| `curl`/`wget` piped to `bash`/`sh`/`zsh` | Remote code execution |
|
||
| `eval` with `$`, backtick, or `$(` | Code injection via eval |
|
||
| `mkfs` or `dd` writing to `/dev/sd*`, `/dev/nvme*`, `/dev/hd*` | Disk destruction |
|
||
| `shutdown`, `reboot`, `halt`, `poweroff` | System shutdown |
|
||
| `:(){ :\|:& };:` pattern | Fork bomb |
|
||
| `base64` piped to `bash`/`sh` | Obfuscated code execution |
|
||
| `crontab -e` or writing to `/etc/cron*` | Persistence via cron |
|
||
| `kill -9 -1` or `pkill -9 -1` | Kill all user processes |
|
||
| `history -c` or truncating `~/.bash_history` | Evidence destruction |
|
||
|
||
**WARN patterns (report but continue):**
|
||
|
||
| Pattern | Concern |
|
||
|---------|---------|
|
||
| `npm install --save`, `pip install`, `cargo add` | Dependency changes during execution |
|
||
| `git push --force` | History rewrite |
|
||
| `git reset --hard` | Discard uncommitted changes |
|
||
|
||
### Scan output
|
||
|
||
For each match:
|
||
```
|
||
Security scan: Step {N} — {description}
|
||
Command: {command}
|
||
{BLOCKED | WARNING}: {pattern name}
|
||
```
|
||
|
||
**If ANY BLOCK pattern is found:**
|
||
|
||
```
|
||
SECURITY SCAN FAILED: {count} dangerous command(s) found in plan.
|
||
|
||
Blocked commands:
|
||
Step {N}: {command} → {reason}
|
||
|
||
This plan contains commands blocked by the executor security policy.
|
||
The plan may have been tampered with or contain hallucinated dangerous commands.
|
||
|
||
Options:
|
||
1. Review and fix the plan file: {path}
|
||
2. Use --dry-run to inspect all commands without executing
|
||
3. Use --fg for interactive execution (hooks provide additional protection)
|
||
```
|
||
|
||
Stop execution. Do NOT continue to Phase 2.5.
|
||
|
||
**If only WARN patterns found:** Continue execution but include warnings in the
|
||
pre-execution summary. Report them in the final output under "Security advisories."
|
||
|
||
**If clean:** Report `Security scan: PASS ({N} commands checked)` and continue.
|
||
|
||
## Phase 2.5 — Execution strategy decision
|
||
|
||
Determine how to execute this plan:
|
||
|
||
**Run as single session (foreground)** when ANY of these are true:
|
||
- `--fg` flag is set
|
||
- `--step N` mode
|
||
- `--resume` mode
|
||
- `--session N` mode (runs only that session's steps, foreground)
|
||
- Plan has no `## Execution Strategy` section
|
||
- Plan has Execution Strategy with only 1 session
|
||
|
||
**Run as multi-session (parallel orchestration)** when ALL of these are true:
|
||
- mode = `execute` (default, no --fg)
|
||
- Plan has `## Execution Strategy` with 2+ sessions
|
||
- At least one wave has 2+ sessions (parallelism possible)
|
||
|
||
**Run as multi-session (sequential orchestration)** when:
|
||
- mode = `execute` (default, no --fg)
|
||
- Plan has `## Execution Strategy` with 2+ sessions
|
||
- All sessions are in different waves (no parallelism, but still separate sessions)
|
||
|
||
For single-session: continue to Phase 3.
|
||
For multi-session: jump to Phase 2.6.
|
||
|
||
Report:
|
||
```
|
||
Strategy: {single session | N sessions (M parallel, K sequential)}
|
||
```
|
||
|
||
## Phase 2.55 — Pre-flight safety checks
|
||
|
||
**Only runs for multi-session parallel execution.** These checks prevent the
|
||
catastrophic data loss that occurs when parallel sessions share a working directory.
|
||
|
||
### Check 1 — Clean working tree
|
||
|
||
Run `git status --porcelain`. If there are ANY uncommitted or untracked changes:
|
||
|
||
```
|
||
Error: working tree is not clean. Parallel execution requires a clean git state.
|
||
Uncommitted changes are invisible to worktrees and will be lost during merge.
|
||
|
||
Untracked/modified files:
|
||
{output of git status --porcelain}
|
||
|
||
Commit or stash your changes, then re-run.
|
||
To run sequentially instead: /ultraexecute-local --fg {plan-path}
|
||
```
|
||
|
||
Stop execution. Update progress with `status: "stopped"`.
|
||
|
||
**Also write `.session-state.local.json`** (Handover 7) — this surfaces the
|
||
stopped state to `/ultracontinue` so the next session can prompt the user to
|
||
clean the working tree before resuming. Write atomically alongside `progress.json`:
|
||
|
||
```json
|
||
{
|
||
"schema_version": 1,
|
||
"project": "{project_dir}",
|
||
"next_session_brief_path": "{project_dir}/brief.md",
|
||
"next_session_label": "{current session label, or 'Continue'}",
|
||
"status": "stopped",
|
||
"updated_at": "{ISO-8601 now}"
|
||
}
|
||
```
|
||
|
||
Verify with `node lib/validators/session-state-validator.mjs --json
|
||
{project_dir}/.session-state.local.json`. On validator failure, emit a warning
|
||
to stderr but do NOT block the stop; `progress.json` is still authoritative.
|
||
|
||
### Check 2 — Plan file is tracked by git
|
||
|
||
Run `git ls-files --error-unmatch {plan-path} 2>/dev/null`. If the plan file is
|
||
untracked (exit code != 0):
|
||
|
||
```bash
|
||
git add {plan-path}
|
||
git commit -m "chore: track plan file for parallel execution"
|
||
```
|
||
|
||
Report: `Plan file committed for worktree visibility.`
|
||
|
||
This ensures every worktree created from HEAD will have the plan file.
|
||
|
||
### Check 3 — Scope fence overlap validation
|
||
|
||
For each wave that has 2+ sessions, validate that no file appears in the Touch
|
||
list of two different sessions in the same wave:
|
||
|
||
1. For each session in the wave, extract the "Touch" list from the Execution Strategy.
|
||
2. For each pair of sessions (A, B) in the same wave, compute the intersection
|
||
of their Touch lists.
|
||
3. If any intersection is non-empty:
|
||
|
||
```
|
||
Error: scope fence overlap detected in Wave {W}.
|
||
Sessions {A} and {B} both touch: {overlapping files}
|
||
These sessions cannot safely run in parallel.
|
||
|
||
Fix the Execution Strategy in the plan, or use --fg for sequential execution.
|
||
```
|
||
|
||
Stop execution. This is a defense-in-depth check — the planning-orchestrator
|
||
should have prevented this, but verifying at execution time catches plans
|
||
that were manually edited or have bugs.
|
||
|
||
### Check 4 — Stale worktree cleanup
|
||
|
||
Run `git worktree list`. If any worktrees with paths containing
|
||
`ultraplan-sessions/{slug}/worktrees/` exist from a previous failed run:
|
||
|
||
```bash
|
||
git worktree remove --force {stale-path} 2>/dev/null
|
||
git worktree prune
|
||
```
|
||
|
||
Also check for stale branches:
|
||
```bash
|
||
git branch --list "ultraplan/{slug}/*" | while read b; do
|
||
git branch -D "$b" 2>/dev/null
|
||
done
|
||
```
|
||
|
||
Report: `Cleaned {N} stale worktrees and {N} branches from previous run.`
|
||
|
||
If cleanup fails, report the manual commands and stop.
|
||
|
||
After all 4 checks pass:
|
||
```
|
||
Pre-flight: PASS (clean tree, plan tracked, no overlaps, no stale worktrees)
|
||
```
|
||
|
||
## Phase 2.6 — Multi-session orchestration (worktree-isolated)
|
||
|
||
**Only runs for multi-session execution.** This phase creates isolated git
|
||
worktrees for each parallel session, launches headless child sessions in their
|
||
own worktrees, merges results back sequentially, and cleans up. After this
|
||
phase, jump directly to Phase 8 (final report).
|
||
|
||
**CRITICAL SAFETY RULE:** Every parallel `claude -p` session MUST run in its own
|
||
git worktree. Never launch two sessions in the same working directory. This rule
|
||
exists because parallel git operations in a shared worktree cause index corruption,
|
||
race conditions, and repository destruction.
|
||
|
||
### Step 0 — Billing safety check (MANDATORY)
|
||
|
||
Before launching ANY `claude -p` process, check the environment:
|
||
|
||
```bash
|
||
echo "${ANTHROPIC_API_KEY:+SET}"
|
||
```
|
||
|
||
If the result is `SET`, **STOP** and warn the user. `claude -p` sessions with
|
||
`ANTHROPIC_API_KEY` in the environment bill the **API account** (pay-per-token),
|
||
not the user's Claude subscription (Max/Pro). Parallel Opus sessions can cost
|
||
$50–100+ per run.
|
||
|
||
Use AskUserQuestion with these options:
|
||
|
||
**Question:** "ANTHROPIC_API_KEY is set in your environment. Parallel `claude -p`
|
||
sessions will bill your API account, not your Claude subscription. How do you
|
||
want to proceed?"
|
||
|
||
| Option | Description |
|
||
|--------|-------------|
|
||
| **Use --fg instead (Recommended)** | Run all steps sequentially in this session using your subscription. No extra cost. |
|
||
| **Continue with API billing** | Launch parallel sessions. Each session bills your API account at token rates. |
|
||
| **Stop** | Cancel execution. Unset ANTHROPIC_API_KEY first, then re-run. |
|
||
|
||
If the user chooses `--fg`: restart execution with mode = foreground (jump back
|
||
to Phase 3, single-session).
|
||
|
||
If the user chooses `Continue`: proceed with Phase 2.6 Step 1.
|
||
|
||
If the user chooses `Stop`: report "Execution cancelled — billing safety check"
|
||
and stop.
|
||
|
||
If `ANTHROPIC_API_KEY` is NOT set: proceed silently to Step 1.
|
||
|
||
### Step 1 — Create session infrastructure
|
||
|
||
```bash
|
||
REPO_ROOT="$(git rev-parse --show-toplevel)"
|
||
SESSION_DIR="$REPO_ROOT/.claude/ultraplan-sessions/{slug}"
|
||
WORKTREE_DIR="$SESSION_DIR/worktrees"
|
||
LOG_DIR="$SESSION_DIR/logs"
|
||
mkdir -p "$WORKTREE_DIR" "$LOG_DIR"
|
||
ORIGINAL_BRANCH="$(git rev-parse --abbrev-ref HEAD)"
|
||
```
|
||
|
||
Record `REPO_ROOT`, `WORKTREE_DIR`, `LOG_DIR`, and `ORIGINAL_BRANCH` for use
|
||
in subsequent steps. All paths must be absolute.
|
||
|
||
### Step 2 — Execute waves with worktree isolation
|
||
|
||
For each wave (in order):
|
||
|
||
**2a. Create worktrees for this wave's sessions:**
|
||
|
||
For each session N in this wave:
|
||
```bash
|
||
BRANCH_NAME="ultraplan/{slug}/session-{N}"
|
||
WORKTREE_PATH="$WORKTREE_DIR/session-{N}"
|
||
git worktree add -b "$BRANCH_NAME" "$WORKTREE_PATH" HEAD
|
||
```
|
||
|
||
If `git worktree add` fails (e.g., branch exists from a crashed run):
|
||
```bash
|
||
git branch -D "$BRANCH_NAME" 2>/dev/null
|
||
git worktree add -b "$BRANCH_NAME" "$WORKTREE_PATH" HEAD
|
||
```
|
||
|
||
If it still fails, report the error, mark this session as failed, and skip it.
|
||
|
||
Report:
|
||
```
|
||
Worktree created: session-{N} → {WORKTREE_PATH} (branch: {BRANCH_NAME})
|
||
```
|
||
|
||
**2b. Launch sessions in this wave (each in its own worktree):**
|
||
|
||
For each session N in the wave:
|
||
```bash
|
||
cd "$WORKTREE_PATH" && claude -p "/ultraexecute-local --session {N} {plan-path}" \
|
||
--allowedTools "Read,Write,Edit,Bash,Glob,Grep" \
|
||
--permission-mode bypassPermissions \
|
||
> "$LOG_DIR/session-{N}.log" 2>&1 &
|
||
```
|
||
|
||
Key rules:
|
||
- `$WORKTREE_PATH` is the absolute path to the session's worktree
|
||
- `$LOG_DIR` is an absolute path in the main worktree (NOT inside the session worktree)
|
||
- `{plan-path}` is the same relative path — it works because the worktree has
|
||
the same repo content from HEAD
|
||
- If the wave has only 1 session, run without `&` (no background needed)
|
||
- Track PIDs for parallel sessions
|
||
|
||
**2c. Wait for wave completion:**
|
||
|
||
```bash
|
||
wait {PID1} {PID2} ...
|
||
```
|
||
|
||
**2d. Check results after each wave:**
|
||
|
||
For each session in the wave, read its log file (in `$LOG_DIR`, always accessible
|
||
from the main worktree) and grep for `"ultraexecute_summary"`. Parse the JSON to
|
||
determine:
|
||
- Did the session complete? (`result: "completed"`)
|
||
- Did it fail? (`result: "failed"` or `"stopped"`)
|
||
|
||
If ANY session in the wave failed:
|
||
```
|
||
Wave {W} FAILED: Session {N} failed at step {S}.
|
||
Stopping — later waves depend on this wave.
|
||
See log: {LOG_DIR}/session-{N}.log
|
||
```
|
||
Do NOT merge. Do NOT start later waves. Jump to Step 4 (cleanup), then Phase 8.
|
||
|
||
If all sessions in the wave passed: continue to Step 2e.
|
||
|
||
**2e. Merge session branches back (SEQUENTIAL, one at a time):**
|
||
|
||
Return to the main worktree:
|
||
```bash
|
||
cd "$REPO_ROOT"
|
||
```
|
||
|
||
For each session N in the wave (in order):
|
||
```bash
|
||
git merge --no-ff "ultraplan/{slug}/session-{N}" \
|
||
-m "merge: ultraplan session {N} — {session-title}"
|
||
```
|
||
|
||
If the merge succeeds (exit code 0): continue to next session.
|
||
|
||
If the merge fails (conflict):
|
||
```bash
|
||
CONFLICTS="$(git diff --name-only --diff-filter=U)"
|
||
git merge --abort
|
||
```
|
||
|
||
Report:
|
||
```
|
||
Wave {W} MERGE CONFLICT: Session {N} branch conflicts with merged state.
|
||
Conflicting files:
|
||
{CONFLICTS}
|
||
|
||
Session {N} log: {LOG_DIR}/session-{N}.log
|
||
Aborting further merges. Sessions already merged in this wave are preserved.
|
||
```
|
||
|
||
Mark remaining sessions as "merge-failed". Jump to Step 4 (cleanup), then Phase 8.
|
||
|
||
**2f. Remove worktrees for completed wave:**
|
||
|
||
After successful merge of all sessions in the wave:
|
||
```bash
|
||
for each session N in the wave:
|
||
git worktree remove "$WORKTREE_DIR/session-{N}" --force
|
||
git branch -d "ultraplan/{slug}/session-{N}"
|
||
done
|
||
git worktree prune
|
||
```
|
||
|
||
Report: `Wave {W}: {N} sessions merged, worktrees cleaned up.`
|
||
|
||
Continue to the next wave.
|
||
|
||
### Step 3 — Run master verification
|
||
|
||
After all waves complete and merge successfully, run the plan's `## Verification`
|
||
section commands to verify the integrated result.
|
||
|
||
### Step 4 — Cleanup (ALWAYS runs, even on failure)
|
||
|
||
This step MUST execute regardless of how Step 2 exited — success, failure, or
|
||
merge conflict. It is the worktree equivalent of a `finally` block.
|
||
|
||
```bash
|
||
cd "$REPO_ROOT"
|
||
|
||
# Remove any remaining worktrees
|
||
for wt in "$WORKTREE_DIR"/session-*; do
|
||
[ -d "$wt" ] && git worktree remove "$wt" --force 2>/dev/null
|
||
done
|
||
git worktree prune
|
||
|
||
# Remove session branches
|
||
git branch --list "ultraplan/{slug}/*" | while read branch; do
|
||
git branch -D "$branch" 2>/dev/null
|
||
done
|
||
|
||
# Clean up empty directories
|
||
rmdir "$WORKTREE_DIR" 2>/dev/null
|
||
```
|
||
|
||
Report:
|
||
```
|
||
Cleanup: {N} worktrees removed, {N} branches deleted.
|
||
```
|
||
|
||
If cleanup fails for any worktree, report but do not fail:
|
||
```
|
||
Warning: failed to remove worktree {path}. Manual cleanup:
|
||
git worktree remove {path} --force && git worktree prune
|
||
```
|
||
|
||
### Step 5 — Aggregate results
|
||
|
||
Collect all session summaries into an aggregated report. Jump to Phase 8.
|
||
|
||
### --session N mode
|
||
|
||
When mode = `session N`:
|
||
1. Find session N in the Execution Strategy
|
||
2. Extract its step numbers (e.g., Steps: 4, 5, 6)
|
||
3. Extract its scope fence (Touch / Never touch lists)
|
||
4. Execute ONLY those steps, in order, using the single-session protocol (Phase 3→7)
|
||
5. Enforce the session's scope fence as if it were a session spec's scope fence
|
||
6. Report results for those steps only
|
||
|
||
This mode is used internally by Phase 2.6 when launching child sessions.
|
||
It can also be used manually to re-run a specific session.
|
||
|
||
When `--session N` is invoked inside a git worktree (as done by Phase 2.6), all
|
||
git operations (add, commit) apply to the worktree's branch. The session does not
|
||
need to know it is in a worktree — git handles this transparently.
|
||
|
||
## Phase 3 — Progress file setup
|
||
|
||
The progress file location depends on whether `--project` is in use:
|
||
|
||
- **With `--project <dir>`:** progress lives at `{project_dir}/progress.json`.
|
||
- **Without `--project`:** progress lives at
|
||
`{plan-dir}/.ultraexecute-progress-{slug}.json`, where `{slug}` is the plan
|
||
filename without extension.
|
||
|
||
**Session-scoped naming:** When `mode = session N`:
|
||
- With `--project`: `{project_dir}/progress-session-{N}.json`.
|
||
- Without `--project`: `{plan-dir}/.ultraexecute-progress-{slug}-session-{N}.json`.
|
||
|
||
This prevents merge conflicts when parallel sessions each write their own
|
||
progress file.
|
||
|
||
### Progress file schema
|
||
|
||
```json
|
||
{
|
||
"schema_version": "1",
|
||
"plan": "{path}",
|
||
"plan_type": "{plan | session-spec}",
|
||
"started_at": "{ISO-8601}",
|
||
"updated_at": "{ISO-8601}",
|
||
"mode": "{execute | resume | step}",
|
||
"total_steps": 0,
|
||
"current_step": 0,
|
||
"status": "{in-progress | completed | failed | stopped}",
|
||
"steps": {
|
||
"1": { "status": "pending", "attempts": 0, "error": null, "completed_at": null, "commit": null }
|
||
},
|
||
"entry_condition_checked": false,
|
||
"exit_condition_checked": false,
|
||
"summary": null
|
||
}
|
||
```
|
||
|
||
### Mode-specific behavior
|
||
|
||
**mode = execute (fresh):**
|
||
- If a progress file exists with status `in-progress` or `failed`: warn that
|
||
`--resume` is available, then wait 3 seconds (`sleep 3`) and start fresh.
|
||
This allows headless runs to proceed without blocking.
|
||
- Otherwise: create the progress file with all steps in `pending` status.
|
||
|
||
**mode = resume:**
|
||
- If no progress file exists: start from step 1 (same as fresh execute).
|
||
- If progress file exists: find the first step with status != `passed`.
|
||
```
|
||
Resuming from step {N}. {M}/{total} steps already completed.
|
||
```
|
||
|
||
**mode = dry-run:**
|
||
- Do NOT create or modify the progress file.
|
||
|
||
**mode = step N:**
|
||
- Create the progress file if it does not exist.
|
||
- Only step N will be executed.
|
||
|
||
## Phase 4 — Entry condition check (session specs only)
|
||
|
||
**Skip for ultraplans.** Skip in dry-run mode (report what would be checked instead).
|
||
|
||
Read the entry condition. Evaluate it:
|
||
|
||
- `"none"` or similar → pass immediately
|
||
- References git state (e.g., "git status clean") → run `git status --porcelain`
|
||
- References passing tests → run the specified command
|
||
- References a previous session → check `git log --oneline` for commit pattern
|
||
|
||
If the entry condition **fails**:
|
||
```
|
||
Entry condition FAILED: {condition text}
|
||
Reason: {what was checked, what was found}
|
||
Complete the prerequisite first, then re-run.
|
||
```
|
||
Update progress file with `status: "stopped"`. Stop execution.
|
||
|
||
**Also write `.session-state.local.json`** (Handover 7) with the same
|
||
`status: "stopped"` and `next_session_brief_path` pointing at the brief that
|
||
the failed entry-condition session was supposed to consume. This lets
|
||
`/ultracontinue` surface the stop in the next session. Use the same atomic
|
||
write pattern + validator check as Phase 2.55. On validator failure, warn
|
||
but do not block.
|
||
|
||
If the entry condition **passes**:
|
||
```
|
||
Entry condition: PASS
|
||
```
|
||
Update `entry_condition_checked: true` in the progress file.
|
||
|
||
## Phase 5 — Dry-run report (dry-run mode only)
|
||
|
||
**Only runs when mode = dry-run.** Produces a validation report, then stops.
|
||
|
||
```
|
||
## Dry Run Report: {filename}
|
||
|
||
**Type:** {plan | session-spec}
|
||
**Steps:** {N}
|
||
|
||
### Step Validation
|
||
|
||
| Step | Description | Verify | On failure | Checkpoint | Issues |
|
||
|------|-------------|--------|------------|------------|--------|
|
||
| 1 | {desc} | {cmd} | {action} | {msg} | {none / missing X} |
|
||
|
||
### File References
|
||
|
||
{For each file in Files: fields, check existence with Glob}
|
||
- {path}: EXISTS | NOT FOUND {(marked as new file) | (unexpected — may be missing)}
|
||
|
||
### Entry / Exit Conditions (session specs)
|
||
|
||
{What would be checked}
|
||
|
||
### Execution Preview (only when plan has Execution Strategy)
|
||
|
||
If `has_execution_strategy = true`, show a preview of multi-session orchestration:
|
||
|
||
```
|
||
**Sessions:** {S} across {W} waves
|
||
|
||
| Wave | Session | Steps | Depends on | Command |
|
||
|------|---------|-------|------------|---------|
|
||
| 1 | Session 1: {title} | {nums} | none | `claude -p "/ultraexecute-local --session 1 {path}"` |
|
||
| 1 | Session 2: {title} | {nums} | none | `claude -p "/ultraexecute-local --session 2 {path}"` |
|
||
| 2 | Session 3: {title} | {nums} | S1, S2 | `claude -p "/ultraexecute-local --session 3 {path}"` |
|
||
```
|
||
|
||
Check billing status via `echo "${ANTHROPIC_API_KEY:+SET}"` and report:
|
||
```
|
||
Billing: ANTHROPIC_API_KEY is {SET — parallel sessions will bill API account | NOT SET — sessions will use subscription}
|
||
```
|
||
|
||
### Verdict
|
||
|
||
{READY | NEEDS ATTENTION — N issues found}
|
||
```
|
||
|
||
Stop after the dry-run report. Do not execute anything.
|
||
|
||
## Phase 6 — Step execution loop
|
||
|
||
The core execution phase. Runs for modes: `execute`, `resume`, `step`.
|
||
|
||
### Determine starting step
|
||
|
||
- **execute**: step 1
|
||
- **resume**: first step where status != `passed`
|
||
- **step N**: step N only
|
||
|
||
### For each step
|
||
|
||
Update progress: `steps.{N}.status = "running"`, `current_step = N`, `updated_at = now`.
|
||
|
||
```
|
||
--- Step {N}/{total}: {description} ---
|
||
```
|
||
|
||
#### Sub-step A — Scope fence check (session specs only)
|
||
|
||
Before touching any file, verify that every file in the step's `Files:` field is
|
||
in the session spec's Touch list (or is a new file to create). If ANY file is in
|
||
the Never-touch list:
|
||
|
||
```
|
||
SCOPE VIOLATION: Step {N} requires {file} which is in the never-touch list.
|
||
Escalating — this step cannot be executed within this session's scope.
|
||
```
|
||
|
||
Treat this as an automatic `escalate`. Jump to the stop-and-report logic.
|
||
|
||
#### Sub-step B — Test first (if present)
|
||
|
||
If the step has a `Test first:` field:
|
||
1. If test file is marked `(new)`: note it will be created during implementation.
|
||
2. If test file exists: run it. Expect failure (RED state).
|
||
3. If test unexpectedly passes: warn but continue — step may already be done.
|
||
|
||
Do not block on test-first failures — they are expected.
|
||
|
||
#### Sub-step C — Implement changes
|
||
|
||
Read the step's `Files:` and `Changes:` fields. Implement exactly as described.
|
||
|
||
**Rules:**
|
||
- Follow `Changes:` exactly — do not improvise, add scope, or optimize
|
||
- Use Edit for modifications, Write for new files
|
||
- If `Reuses:` references existing code, read that code first for context
|
||
- Only touch files listed in `Files:` — nothing else
|
||
|
||
#### Sub-step D1 — Command verification
|
||
|
||
**Security check (mandatory):** Before running the Verify command, check it against
|
||
the executor security denylist. If the command matches ANY of these patterns,
|
||
**refuse to execute** — treat as `On failure: escalate` regardless of the plan's
|
||
On failure setting:
|
||
|
||
- `rm -rf` or `rm -fr` with any path
|
||
- `chmod 777` or `chmod -R 777`
|
||
- Pipe-to-shell: `curl ... | bash`, `wget ... | sh`, `base64 ... | bash`
|
||
- `eval` with variable expansion: `eval $VAR`, `eval $(cmd)`, `` eval `cmd` ``
|
||
- `mkfs`, `dd` writing to block devices (`/dev/sd*`, `/dev/nvme*`)
|
||
- `shutdown`, `reboot`, `halt`, `poweroff`
|
||
- Fork bomb patterns
|
||
- `crontab` writes, `/etc/cron*` modifications
|
||
- `kill -9 -1` or `pkill -9 -1` (kill all processes)
|
||
- `history -c` or truncating `~/.bash_history`
|
||
|
||
If matched:
|
||
1. Do NOT execute the command
|
||
2. Set step status = "failed"
|
||
3. Log: `SECURITY: Verify command blocked — matches executor denylist: {pattern name}`
|
||
4. Apply `On failure: escalate` regardless of the plan's On failure setting
|
||
5. Include in final report under a "Security blocks" section
|
||
|
||
If the command passes the security check, run it:
|
||
|
||
Run the `Verify:` command exactly as written, via Bash.
|
||
|
||
**Rules:**
|
||
- Always a fresh run — never trust prior results
|
||
- Exit code is the authoritative truth:
|
||
- Exit 0 + expected output (if specified) = **PASS**
|
||
- Exit non-zero = **FAIL** regardless of output text
|
||
- Exit 0 but wrong output = **FAIL**
|
||
|
||
```
|
||
Verify: {command}
|
||
Result: {PASS | FAIL} (exit code {N})
|
||
{if FAIL}: Output (first 10 lines): {output}
|
||
```
|
||
|
||
**Step 0 sentinel:** if the Verify command exits `77` AND the step's manifest
|
||
has `sandbox_preflight: true`, do NOT treat as a normal failure. Set step
|
||
status = `blocked` and apply `On failure: escalate`. Skip D2 manifest
|
||
verification (nothing to verify for a read-only sandbox test). Commit none —
|
||
jump straight to Phase 7 with a structured "sandbox-blocked" reason.
|
||
|
||
If **PASS**: proceed to Sub-step D2 (manifest verification).
|
||
|
||
#### Sub-step D2 — Manifest verification
|
||
|
||
After the Verify command passes, verify the step's Manifest block. This is
|
||
the objective completion predicate: a step is not passed until its manifest
|
||
holds, regardless of Verify exit code.
|
||
|
||
**Checks to run (in order):**
|
||
|
||
1. **Expected paths exist:** for each `expected_paths` entry, verify the
|
||
file exists in the repo. Count how many exist.
|
||
2. **min_file_count satisfied:** count from (1) must be ≥ `min_file_count`.
|
||
3. **Forbidden paths untouched:** for each `forbidden_paths` entry, run
|
||
`git diff --name-only HEAD~{attempts} HEAD -- {path}` (since this step
|
||
began). Any modified forbidden path = fail.
|
||
4. **Bash syntax check:** for each entry in `bash_syntax_check` AND any
|
||
`.sh` file that appears in `git diff --name-only HEAD~1 HEAD` (safety
|
||
net for unlisted scripts), run `bash -n {path}`. Non-zero exit = fail.
|
||
5. **must_contain patterns:** for each `{path, pattern}` pair, run
|
||
`grep -E "{pattern}" {path}`. No match = fail.
|
||
|
||
**On manifest failure:**
|
||
|
||
```
|
||
Manifest verification FAIL for step {N}:
|
||
- {which check failed with detail}
|
||
```
|
||
|
||
Apply the step's `On failure:` clause (same as Sub-step D1 failure). Increment
|
||
attempts. Manifest failures count against the retry cap equally with command
|
||
failures.
|
||
|
||
If all manifest checks pass: proceed to Sub-step F (checkpoint).
|
||
|
||
Record per-step manifest audit result in progress file:
|
||
`steps.{N}.manifest_audit = "pass" | "fail"`,
|
||
`steps.{N}.manifest_drift = [{check: reason, ...}]` on fail.
|
||
|
||
#### Sub-step E — On failure handling
|
||
|
||
If **FAIL**, read the `On failure:` clause. Apply the retry cap: **maximum 2 retries**
|
||
(3 total attempts). Track attempts in `steps.{N}.attempts`.
|
||
|
||
**`On failure: revert`**
|
||
- If attempts < 3: analyze the failure, re-implement with adjustments, re-verify.
|
||
```
|
||
Attempt {A}/3 failed. Retrying...
|
||
```
|
||
- If attempts == 3: revert this step's changes:
|
||
```bash
|
||
git checkout -- {files from Files: field}
|
||
```
|
||
Record failure. **Do NOT proceed to next step.** Jump to Phase 7.
|
||
|
||
**`On failure: retry`**
|
||
- If attempts < 3: use the alternative approach described in the On failure clause.
|
||
- If attempts == 3: revert and stop. Jump to Phase 7.
|
||
|
||
**`On failure: skip`**
|
||
- Mark step as skipped regardless of attempt count. Continue to next step.
|
||
```
|
||
Step {N}: SKIPPED (non-critical per plan)
|
||
```
|
||
Update `steps.{N}.status = "skipped"`.
|
||
|
||
**`On failure: escalate`**
|
||
- Stop immediately regardless of attempt count.
|
||
```
|
||
Step {N}: ESCALATED — requires human judgment
|
||
```
|
||
Commit all completed work before stopping. Stage ONLY files from steps with
|
||
`status: "passed"` in the progress file — collect their `Files:` fields. Never
|
||
use `git add -A` (risks staging secrets, binaries, or unrelated work).
|
||
```bash
|
||
git add {files from passed steps' Files: fields} && git commit -m "wip: ultraexecute-local stopped at step {N} — escalation needed"
|
||
```
|
||
Jump to Phase 7.
|
||
|
||
#### Sub-step F — Checkpoint
|
||
|
||
Run the `Checkpoint:` git commit command exactly as written in the plan.
|
||
|
||
If the commit fails (nothing to commit, etc.): warn but do NOT fail the step.
|
||
The step's verification already passed — the commit is bookkeeping.
|
||
|
||
```
|
||
Step {N}: PASS (committed: {hash})
|
||
```
|
||
|
||
**Commit-message-pattern check:** after the commit succeeds, read the HEAD
|
||
commit message (`git log -1 --pretty=%s`) and match it against the step's
|
||
`commit_message_pattern`. Mismatch does NOT fail the step (verification
|
||
already passed) but is recorded as `checkpoint_drift: {expected_pattern,
|
||
actual_message}` in the progress file. Phase 7.5 audit reports drift as
|
||
an advisory.
|
||
|
||
Update progress: `steps.{N}.status = "passed"`, `steps.{N}.commit = {hash}`,
|
||
`steps.{N}.completed_at = now`, `steps.{N}.manifest_audit = "pass"`.
|
||
|
||
### Step mode exit
|
||
|
||
If mode = `step N`: after completing step N (pass or fail), skip remaining steps
|
||
and jump to Phase 8 (final report).
|
||
|
||
## Phase 7 — Exit condition check (session specs only)
|
||
|
||
**Skip for ultraplans.** Run only when all steps passed (not on early stop).
|
||
|
||
Run each exit condition command from the `## Exit Condition` checklist:
|
||
|
||
```
|
||
Exit condition check:
|
||
- [ ] {command} → {PASS | FAIL}
|
||
- [ ] {command} → {PASS | FAIL}
|
||
```
|
||
|
||
If all pass: `exit_condition_checked: true` in progress file.
|
||
If any fail: record which failed. Include in final report.
|
||
|
||
## Phase 7.5 — Manifest audit (independent)
|
||
|
||
**Runs for all modes except dry-run.** This is the last-line-of-defense
|
||
check: it ignores the executor's own per-step bookkeeping and re-verifies
|
||
session-wide state directly from the filesystem and git log. If the audit
|
||
disagrees with the executor's self-report, the audit wins.
|
||
|
||
This phase exists because agents can hallucinate completion. Phase 7.5
|
||
produces an independent truth based on objective state, not self-narrative.
|
||
|
||
**Steps:**
|
||
|
||
1. **Enumerate expected paths:** aggregate `expected_paths` across every
|
||
step manifest (and the session_manifest, if present). Deduplicate.
|
||
|
||
2. **Filesystem check:** for each expected_path, confirm the file exists.
|
||
|
||
3. **Commit-count check:** count commits since session-start
|
||
(`git rev-list --count {start_sha}..HEAD`). Expected count =
|
||
number of steps with `status=passed` (excludes Step 0 if sandbox_preflight).
|
||
|
||
4. **Commit-message pattern sweep:** walk `git log {start_sha}..HEAD` and
|
||
confirm each commit matches one of the declared
|
||
`commit_message_patterns` (in any order — order is advisory).
|
||
|
||
5. **Bash syntax sweep:** for every `.sh` file in
|
||
`git diff --name-only {start_sha} HEAD`, run `bash -n`. Collect failures.
|
||
|
||
6. **Forbidden-path sweep:** for each `scope_forbidden` entry, check
|
||
`git diff --name-only {start_sha} HEAD -- {path}` is empty.
|
||
|
||
Compare the audit result against the executor's `progress.status`:
|
||
|
||
- **Audit pass + progress=completed:** status stays `completed`.
|
||
- **Audit fail + progress=completed:** OVERRIDE to `partial`. The executor
|
||
believed it was done; the filesystem says otherwise. This is the Wave 1
|
||
hallucination case — the audit is the defense.
|
||
- **Audit fail + progress=failed/stopped:** status stays as-is; drift is
|
||
informational.
|
||
|
||
Record in progress file:
|
||
- `manifest_audit.status = "pass" | "drift"`
|
||
- `manifest_audit.drift_details = [{check, expected, actual}, ...]`
|
||
|
||
## Phase 7.6 — Recovery dispatch (multi-session parent context only)
|
||
|
||
**Preconditions:**
|
||
- This is the parent ultraexecute invocation (not a child `--session N`)
|
||
- Phase 7.5 reported `drift`
|
||
- `recovery_depth < 2` (hard cap to prevent infinite loops)
|
||
|
||
**Skip otherwise.** Recovery in child context or at depth 2+ escalates to
|
||
the user for manual resolution.
|
||
|
||
**Synthesize a recovery session spec:**
|
||
|
||
1. Determine the missing step numbers from `manifest_audit.drift_details`
|
||
(steps whose expected_paths are absent or whose commits are missing).
|
||
2. Read the original session spec. Copy only the missing steps (preserving
|
||
their Manifest blocks) into a new file:
|
||
`{output_dir}/session-{N}-recovery-{depth}.md`
|
||
3. Populate `## Recovery Metadata`:
|
||
- `recovery_of: {original session spec path}`
|
||
- `recovery_depth: {current depth + 1}`
|
||
- `missing_steps: [N, M, ...]`
|
||
- `entry_condition_override: "previous partial session committed at {sha}"`
|
||
- `parent_progress_file: {path}`
|
||
4. Prepend the synthetic Step 0 pre-flight (same as normal session specs).
|
||
5. Set `recovery_dispatched = true` in parent progress file.
|
||
|
||
**Invoke the recovery session:**
|
||
|
||
```bash
|
||
cd "$WORKTREE_PATH" && claude -p "/ultraexecute-local --session {N} {recovery spec path}" \
|
||
--allowedTools "Read,Write,Edit,Bash,Glob,Grep" \
|
||
--permission-mode bypassPermissions \
|
||
> "$LOG_DIR/session-{N}-recovery-{depth}.log" 2>&1
|
||
```
|
||
|
||
Wait for the recovery session to complete. After it returns, re-run Phase
|
||
7.5 audit one more time. If it still drifts at `recovery_depth=2`:
|
||
|
||
```
|
||
RECOVERY EXHAUSTED: session {N} drifted after 2 recovery attempts.
|
||
Missing: {steps and details}
|
||
Status: partial (recovery_depth=2, escalated to user)
|
||
```
|
||
|
||
Do NOT dispatch a third recovery. Report to the user.
|
||
|
||
## Phase 8 — Final report
|
||
|
||
Always produce a final report.
|
||
|
||
Update progress file: `status` to `completed`/`failed`/`stopped`, `updated_at`, `summary`.
|
||
|
||
**Also atomically write `.session-state.local.json`** (Handover 7) at this
|
||
convergence point — every successful, failed, stopped, or partial run that
|
||
reaches Phase 8 must produce or refresh the state file. Schema:
|
||
|
||
```json
|
||
{
|
||
"schema_version": 1,
|
||
"project": "{project_dir}",
|
||
"next_session_brief_path": "{determined from Execution Strategy: next session's brief path, or current brief path if last session}",
|
||
"next_session_label": "{label of next session from Execution Strategy, or 'Complete' if last}",
|
||
"status": "{same as progress.json status — completed | failed | stopped | partial}",
|
||
"updated_at": "{ISO-8601 now}"
|
||
}
|
||
```
|
||
|
||
Use `lib/util/atomic-write.mjs` (`atomicWriteJson`) — same crash-safety as
|
||
`progress.json`. Then verify: `node lib/validators/session-state-validator.mjs
|
||
--json {project_dir}/.session-state.local.json`. On validator failure, warn
|
||
to stderr but do NOT block — Phase 8 must always reach the final report.
|
||
|
||
This single insertion covers every multi-session execution path that
|
||
converges here (Path A: successful single session, Path B: `--session N`
|
||
explicit, Path C: compaction-survival recovery, Path D: standard plan
|
||
completion). Phase 2.55 and Phase 4 cover the early-stop paths E1/E2.
|
||
Phase 2.3 (validate exit) and Phase 5 (dry-run) intentionally do not write
|
||
— neither path is resumable.
|
||
|
||
```
|
||
## Ultraexecute Local Complete
|
||
|
||
**Plan:** {path}
|
||
**Type:** {plan | session-spec}
|
||
**Mode:** {execute | resume | step N}
|
||
**Result:** {COMPLETED | FAILED at step N | STOPPED (escalation) | PARTIAL (N/total passed)}
|
||
|
||
### Step Results
|
||
|
||
| Step | Description | Result | Attempts | Commit | Manifest |
|
||
|------|-------------|--------|----------|--------|----------|
|
||
| 0 | Sandbox pre-flight | PASS | 1 | — | n/a |
|
||
| 1 | {desc} | PASS | 1 | abc1234 | pass |
|
||
| 2 | {desc} | FAIL | 3 | — | — |
|
||
| 3 | {desc} | — | 0 | — | — |
|
||
|
||
### Manifest Audit (Phase 7.5)
|
||
|
||
- **Status:** {pass | drift}
|
||
- **Drift details:** {enumerated; empty on pass}
|
||
- **Recovery dispatched:** {true | false}
|
||
- **Recovery depth:** {N}
|
||
- **Legacy plan:** {true | false}
|
||
|
||
### Summary
|
||
|
||
- Passed: {N}/{total}
|
||
- Skipped: {N}
|
||
- Failed: {N}
|
||
- Not reached: {N}
|
||
- Blocked (sandbox): {N}
|
||
|
||
{if all passed + exit condition passed}:
|
||
All steps completed. Exit condition: PASS.
|
||
|
||
{if failed/stopped}:
|
||
### Failure Details
|
||
|
||
Step {N}: {description}
|
||
On failure: {action}
|
||
Error: {error output, first 20 lines}
|
||
Attempts: {N}
|
||
|
||
### What Remains
|
||
|
||
{Numbered list of unexecuted steps}
|
||
|
||
To resume: /ultraexecute-local --resume {path}
|
||
```
|
||
|
||
**Result vocabulary (v1.7, strict):**
|
||
- `completed` — all steps passed AND Phase 7.5 manifest audit passed
|
||
- `partial` — steps passed per executor but Phase 7.5 found drift, OR
|
||
Phase 7.6 recovery incomplete
|
||
- `blocked` — Step 0 sandbox pre-flight exited 77; no real work attempted
|
||
- `failed` — a step failed and On failure was revert/retry (retry cap hit)
|
||
- `stopped` — On failure: escalate triggered
|
||
|
||
**JSON summary block** (always at the end, machine-parseable):
|
||
|
||
```json
|
||
{
|
||
"ultraexecute_summary": {
|
||
"plan": "{path}",
|
||
"plan_type": "{plan | session-spec}",
|
||
"plan_version": "{1.7 | 1.6 | legacy}",
|
||
"result": "{completed | partial | blocked | failed | stopped}",
|
||
"steps_total": 0,
|
||
"steps_passed": 0,
|
||
"steps_failed": 0,
|
||
"steps_skipped": 0,
|
||
"steps_not_reached": 0,
|
||
"steps_blocked": 0,
|
||
"failed_at_step": null,
|
||
"exit_condition": "{pass | fail | skipped | n/a}",
|
||
"manifest_audit": "{pass | drift | n/a}",
|
||
"drift_details": [],
|
||
"recovery_dispatched": false,
|
||
"recovery_depth": 0,
|
||
"legacy_plan": false,
|
||
"progress_file": "{path}"
|
||
}
|
||
}
|
||
```
|
||
|
||
The `ultraexecute_summary` key makes it grep-able in log files from headless runs.
|
||
|
||
## Phase 9 — Stats tracking
|
||
|
||
Append one record to `${CLAUDE_PLUGIN_DATA}/ultraexecute-stats.jsonl`:
|
||
|
||
```json
|
||
{
|
||
"ts": "{ISO-8601}",
|
||
"plan": "{filename only}",
|
||
"plan_type": "{plan | session-spec}",
|
||
"mode": "{execute | resume | dry-run | step}",
|
||
"result": "{completed | failed | stopped | partial}",
|
||
"steps_total": 0,
|
||
"steps_passed": 0,
|
||
"steps_failed": 0,
|
||
"steps_skipped": 0,
|
||
"failed_at_step": null
|
||
}
|
||
```
|
||
|
||
If `${CLAUDE_PLUGIN_DATA}` is not set or not writable, skip silently.
|
||
Never let stats failures block the workflow.
|
||
|
||
## Hard rules
|
||
|
||
1. **No AskUserQuestion for execution decisions.** All execution decisions come
|
||
from the plan's On failure clauses. If the plan says escalate, stop and
|
||
report — never ask. **Exception:** the billing safety check in Phase 2.6
|
||
Step 0 MUST ask before spending money on the user's API account.
|
||
|
||
2. **No scope creep.** Only touch files listed in the step's `Files:` field.
|
||
If a file outside the list seems to need changing, record it as a finding
|
||
in the final report — do not touch it.
|
||
|
||
3. **Exit code is truth.** The Verify command's exit code is authoritative.
|
||
Non-zero = FAIL regardless of output. Zero with wrong output = FAIL.
|
||
|
||
4. **Fresh verification.** Re-run the Verify command from scratch every time.
|
||
Never trust cached or prior results.
|
||
|
||
5. **Retry cap = 3 attempts.** Initial + 2 retries, then stop. Never loop forever.
|
||
|
||
6. **Never corrupt completed work.** Only revert files from the failing step.
|
||
Never touch files from earlier passed steps.
|
||
|
||
7. **Checkpoint discipline.** Run the Checkpoint commit exactly as written.
|
||
Do not combine, reorder, or skip checkpoints on passed steps.
|
||
|
||
8. **Scope fence enforcement.** For session specs: never modify files in the
|
||
Never-touch list, regardless of what the Changes field says.
|
||
|
||
9. **Progress file is ground truth.** Resume uses the progress file, not git log.
|
||
|
||
10. **No sub-agents.** The executor reads and implements directly.
|
||
No Agent tool, no TeamCreate, no delegation.
|
||
|
||
11. **Worktree isolation is mandatory for parallel execution.** Every parallel
|
||
`claude -p` session MUST run in its own git worktree. Never launch two or
|
||
more sessions in the same working directory. This rule has no exceptions.
|
||
Sequential (single-session) execution does not require worktrees.
|
||
|
||
12. **Worktree cleanup is unconditional.** Before producing the final report
|
||
(Phase 8), always remove all worktrees and session branches created during
|
||
this execution, even if the run failed or was stopped. Leaked worktrees
|
||
consume disk space and block future runs. If automated cleanup fails,
|
||
report the manual cleanup commands in the final report.
|
||
|
||
13. **Merge sequentially, abort on conflict.** After a parallel wave completes,
|
||
merge each session's branch into the main branch one at a time with
|
||
`--no-ff`. If any merge produces a conflict, run `git merge --abort`,
|
||
report the conflicting files, and do not attempt further merges. Never use
|
||
`--force` or `--strategy-option theirs/ours` to silently resolve conflicts.
|
||
|
||
14. **Verify command security check.** Before executing any `Verify:` or
|
||
`Checkpoint:` command, check it against the executor security denylist
|
||
(Sub-step D). If the command matches a blocked pattern, escalate
|
||
immediately — do not execute, do not retry.
|
||
|
||
15. **No writing outside the repository.** During step execution, never write
|
||
files outside the git repository root (`git rev-parse --show-toplevel`).
|
||
Exception: `.claude/` paths for plans, progress files, and stats.
|
||
This prevents escape-from-repo attacks where a plan step modifies home
|
||
directory or system files.
|
||
|
||
16. **No writing to security-sensitive paths.** Never write to `.git/hooks/`
|
||
(git hook injection), `~/.ssh/`, `~/.aws/`, `~/.gnupg/`, `.env` files,
|
||
shell configs (`~/.zshrc`, `~/.bashrc`, `~/.profile`), or
|
||
`.claude/settings.json` / `.claude/hooks/` (infrastructure self-modification).
|
||
|
||
17. **Manifest is the completion predicate.** A step may not be marked passed
|
||
if its manifest does not verify, regardless of the Verify command's exit
|
||
code. The manifest is the objective contract — Verify is necessary but
|
||
not sufficient. For v1.7+ plans: a Verify pass with a manifest fail sets
|
||
step result to `failed` and triggers the On-failure clause. For legacy
|
||
v1.6 plans: synthesized manifests apply with the same force, but
|
||
`legacy_plan: true` is logged in progress.
|
||
|
||
18. **Last-activity rule.** The executor's final tool call before writing
|
||
Phase 8 must be a manifest check (Phase 7.5 audit), never an arbitrary
|
||
file review. This prevents the "hallucinated completion" failure mode
|
||
where a transcript ends on an unrelated Read and the agent self-reports
|
||
`completed` without verifying. If Phase 7.5 has not run, the executor
|
||
may not emit `result: completed` under any circumstances.
|