Chain plan-review-autofix, plan-wrap-autofix, repo-sync, and task-handoff into one autonomous prep step before /build-phase. Required arg --plan <path>. Default continues in-window — emits a /goal + /build-phase command pair (the /goal arms the Stop hook over the agent-completable build span); auto-compaction handles context (no forced /compact). Use --new-window for a fresh-window handoff (durable current.md write via task-handoff --next-task, then /session-wrap --end renders handoff-prompt....
Installs into .claude/skills of the current project.
Are you the author of Plan Expedite?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/aberson-plan-expedite)
---
name: plan-expedite
description: Chain plan-review-autofix, plan-wrap-autofix, repo-sync, and task-handoff into one autonomous prep step before /build-phase. Required arg --plan <path>. Default continues in-window — emits a /goal + /build-phase command pair (the /goal arms the Stop hook over the agent-completable build span); auto-compaction handles context (no forced /compact). Use --new-window for a fresh-window handoff (durable current.md write via task-handoff --next-task, then /session-wrap --end renders handoff-prompt.md and prints the Pick-up-here block).
user-invocable: true
---
# Plan Expedite
`/plan-expedite --plan <path>` runs the full plan -> sync -> handoff pipeline as one
autonomous step. Default output: TWO continue commands in order — first a `/goal
"<condition>"` line that arms the Stop hook over the agent-completable span, then the
`/build-phase --plan <path>` command — both to run **in the same window** — no forced
`/compact`, because auto-compaction handles
context on its own when it fills and the `SessionStart` re-inject hook reloads `current.md`
afterward. (A focused `/compact` before the long build is optional — see step 4.) Add
`--new-window` to hand off to a fresh window instead: a durable `current.md` write
(`task-handoff --next-task`), then `/session-wrap --end` renders the handoff to disk
(`.claude/task-state/handoff-prompt.md`) and prints the Pick-up-here block.
---
## Execution model — autonomous, invoke sub-skills via the Skill tool (HEAVY)
This skill's whole reason to exist is that the operator does not want to type `/plan-review` → wait → `/plan-wrap` → wait → `/repo-sync` → wait → `/session-wrap`. They invoked `/plan-expedite` to have those four happen as one autonomous run. Therefore:
1. **Execute, do not advise.** When invoked, you MUST invoke each sub-skill via the `Skill` tool in the order specified in the "Sub-skill chain" section. Do NOT respond by emitting the chain as text (e.g. "Next: `/plan-review` → `/plan-wrap` → `/repo-sync` → `/session-wrap` → `/build-phase`"). That listing-the-steps response is the single most common failure mode for this skill — if you find yourself about to type that sentence, stop and call the `Skill` tool instead.
2. **No mid-run confirmations.** Do not ask "Should I run /plan-review now?", "Apply autofixes?", "Proceed to /plan-wrap?", "Ready to sync issues?", or any other (y/n) gate. The operator opted into the chain by invoking `/plan-expedite`. Halt only on the cases the "Halt template" section enumerates — sub-skill non-zero exit, genuine ambiguity surfaced under "Needs your input:" requiring operator judgment, or missing sub-skill. Everything else proceeds.
3. **Minimal between-step narration.** Between sub-skill invocations, one brief sentence is enough ("plan-review returned READY with 3 autofixes applied; invoking plan-wrap"). Do not re-describe what the next sub-skill is going to do — its SKILL.md handles that.
4. **Final output is the continue command(s) (or, with `--new-window`, the Pick-up-here block), verbatim.** On default success, the final output is TWO lines in order — a `/goal "<condition>"` line (scoped to the agent-completable automated span, per Step 4 of the chain) followed by the `/build-phase --plan <path>` command — no summary, paraphrase, or "here's what to do next" preamble. With `--new-window`, the Pick-up-here block that `/session-wrap --end` prints (exact next command + digest + pointer to the rendered `handoff-prompt.md`) IS the final output; emit it as-is.
---
## When to use
- After `/plan-init` or `/plan-feature` produces a plan.md, before `/build-phase` runs.
- When you want one command instead of remembering plan-review -> plan-wrap -> repo-sync -> session-wrap in order.
- Re-running is safe: each sub-skill is idempotent on already-applied state (per autofix-applied markers from Steps 7-8) and `/plan-expedite` skips already-completed sub-skills (per `.plan-expedite-state` resume detection).
## When NOT to use
- Mid-build-phase (this skill is a PRE-build prep; /build-phase has its own flow).
- For ad-hoc plan edits without intent to ship (use individual skills directly).
- If you want to manually review autofix changes before applying (use individual skills with --no-autofix).
## Arguments
| Arg | Required | Default | Description |
|---|---|---|---|
| `--plan` | yes | -- | Path to the plan.md file (e.g., `documentation/foo-plan.md`) |
| `--new-window` | no | false | Fresh-window handoff: run `task-handoff --next-task` (durable `current.md` write) FIRST, then `/session-wrap --end` — the handoff is rendered to `.claude/task-state/handoff-prompt.md` and the screen shows the Pick-up-here block (exact next command + <=6-line digest + pointer; no word floor). Use when you want the next step in a fresh window. |
## Flow
### Stale-plan check (per BPA plan section 5 D9)
Check `plan.md`'s mtime before invoking any sub-skill. If >30 days old, print a warning but CONTINUE — do not bail:
```text
warning: plan.md was last modified <N> days ago (<date>). Autofix may reshape stale plans significantly. Continuing — review the auto-applied fixes before /build-phase if drift is a concern.
```
### Resume detection
Check for `.plan-expedite-state` JSON file in the project root (sibling to plan.md). Schema:
```json
{
"plan_path": "documentation/foo-plan.md",
"plan_mtime": 1779167384.42,
"handoff_mode": "in-window",
"completed": [
{"skill": "plan-review", "verdict": "READY", "timestamp": "..."},
{"skill": "plan-wrap", "verdict": "READY", "timestamp": "..."}
],
"halted_at": null
}
```
`handoff_mode` is `"in-window"` (default — `task-handoff --next-task`) or `"new-window"`
(`--new-window` flag — `task-handoff --next-task` then `session-wrap --end`). Recorded at
run start; used by resume logic to invoke the correct final sub-skill(s) on re-entry.
`plan_mtime` is a numeric float — seconds since the Unix epoch, as returned by `os.path.getmtime(plan_path)` or `stat -c %Y`. No timezone, no string parsing. Comparison uses a 1-second tolerance: `abs(current_mtime - state_mtime) <= 1.0`. The tolerance accommodates filesystems with different mtime precision (NTFS records to 100ns, FAT32 rounds to 2s) and avoids spurious "plan changed" detections from format-only round-trips.
Logic:
- If file does not exist: fresh run, execute all 4 sub-skills sequentially.
- If file exists AND `abs(current_mtime - state.plan_mtime) <= 1.0`: skip every sub-skill in `completed[]`. Start from the first uncompleted (or from where `halted_at` left off).
- If file exists BUT the mtime difference exceeds 1 second: plan was edited since last run; discard the resume state and start fresh.
- **Malformed state file:** if `.plan-expedite-state` exists but is invalid JSON, missing required keys (`plan_path`, `plan_mtime`, `completed`, `halted_at`), or has the wrong shape (e.g., `plan_mtime` not numeric, `completed` not a list), log a warning citing the malformation, rename the bad file to `.plan-expedite-state.malformed-<timestamp>` for forensics, and treat as a fresh run (proceed with all 4 sub-skills). Do NOT halt — an autonomous prep skill should self-heal from corrupted resume state, not require operator intervention to clear it.
Update `completed[]` with the sub-skill name and write the file back after each successful sub-skill. On halt, set `halted_at` to the sub-skill name that failed and persist.
### Sub-skill chain
Call each sub-skill below via the `Skill` tool, in order. Before the first invocation, `cd` to the project root containing `<plan-path>` (use the Bash tool). Between invocations, one brief progress sentence ("plan-review returned READY; invoking plan-wrap") is enough — do NOT re-emit the chain as prose.
**Path-passing contract:** only `/repo-sync` documents a `--plan` CLI flag in its Arguments table; `/plan-review`, `/plan-wrap`, and `/session-wrap` operate on the plan via conversation context (they read the plan path from the invoking turn's prose or from cwd). Pass the path via the `args` parameter of the `Skill` call so the sub-skill picks it up.
Read the exit code and final verdict line after each `Skill` call returns. On success, append to `completed[]` in `.plan-expedite-state` and proceed to the next sub-skill. On halt, write the halt template (see below) and stop.
1. **Invoke `plan-review` via the Skill tool** with `args: "--autofix <plan-path>"`.
- Success criteria: verdict READY, or "READY (auto-fixed N items)", or NEEDS WORK with only clarifying questions auto-answerable.
- Halt criteria: genuine ambiguity surfaced under "Needs your input:" requiring operator judgment, OR sub-skill non-zero exit, OR sub-skill missing.
2. **Invoke `plan-wrap` via the Skill tool** with `args: "--autofix <plan-path>"`.
- Success criteria: verdict READY, "READY (auto-fixed N items)", "READY WITH GAPS: M gaps" (plan-wrap-only — 0 Blockers, M≥1 Gaps, /repo-sync may proceed), or NEEDS WORK with only clarifying questions auto-answerable.
- Halt criteria: same as plan-review (genuine ambiguity under "Needs your input:" requiring operator judgment, OR sub-skill non-zero exit, OR sub-skill missing).
3. **Invoke `repo-sync` via the Skill tool** with `args: "--plan <plan-path>"` (autonomous default per Step 6 — no `--dry-run`).
- Same success / halt criteria.
4. **Invoke the final sub-skill, then emit the continue command** — depends on `--new-window`:
**Default (no `--new-window`):** Invoke `task-handoff` via the Skill tool with
`args: "--next-task build-phase"` (it writes current.md + MEMORY + push — the durable
handoff state).
- Then emit the two continue commands verbatim as the `/plan-expedite` final output,
BOTH inside ONE fenced code block (goal first, build command second) so the operator
copies both in a single action — continue in the SAME window (auto-compaction handles
context, no forced `/compact`). No preamble, no summary — the final output IS this one
block. The `/goal` arms the Stop hook over the automated span and is user-typed (a
skill cannot arm `/goal` itself), so it sits above `/build-phase`:
```
/goal "<condition>"
/build-phase --plan <plan-path>
```
- **Derive the `<condition>` from the plan, scoped to the AGENT-COMPLETABLE slice.**
plan-expedite has already read the plan, so enumerate its steps. The agent-completable
(automated) steps are the ones the agent builds end-to-end with its own tools:
`Type: code` and `Type: conditional`. NOT agent-completable: every `Type: operator`
step, every Manual M-step (M1/M2/M3), AND every `Type: wait` step — a `Type: wait`
step is an intentional build-phase halt (halt-contract class #4: the orchestrator
stops and the operator resumes in a fresh session after the clock-gated wait), so its
finish line is not reachable by the agent in-session. Build the condition over ONLY
the contiguous automated (`code`/`conditional`) steps up to the FIRST
operator / Manual-M / wait boundary — a goal that spans an operator, Manual M-step,
or wait step busy-loops forever, because the Stop hook re-fires against a finish line
the agent's own tools cannot reach. Form:
`"<plan-name> automated steps <N..M> are all marked Status: DONE in <plan-path>
(issues #<a>-#<b> closed), and `<test-cmd>` / `<typecheck-cmd>` / `<lint-cmd>` exit 0
— STOP before the operator/wait/Manual steps (M1/M2/M3, issues #<x>-#<y>); those are an
operator handoff, not part of this goal"`. Cite the GitHub issue numbers for the
automated steps and for the closing/quality-gate conditions wherever the plan makes
them derivable; omit a clause only if the plan genuinely lacks it. If the plan is
all-automated (no `Type: operator` steps, no `Type: wait` steps, and no Manual
M-steps), target ALL steps and drop the STOP-before clause.
- Record `handoff_mode: "in-window"` in `.plan-expedite-state`.
- **Optional focused reset.** A proactive `/compact` before a long build-phase gives
cleaner context than auto-compaction's best-guess summary — but it is the operator's
choice, not the default, and is never auto-emitted as the mandated output (there is no
way to trigger `/compact` programmatically). If they want it, they type it first:
`/compact Focus on build-phase for [plan-name]: step list in plan.md, issue numbers
filled, current.md has next action`.
**`--new-window` mode:** TWO invocations, in this order — the durable write MUST land
before session-wrap runs because `handoff-prompt.md` is a RENDERING of `current.md`:
the render can only carry state already on disk. The default transition RECYCLES this
window: `/clear` fires the SessionStart re-inject hook (matcher: `compact|resume|clear`),
then the operator pastes the pair. The rendered handoff + fresh-window opener remain
the closed-window alternative (the hook does not fire on plain startup):
1. **Invoke `task-handoff` via the Skill tool** with `args: "--next-task build-phase"`
— the durable `current.md` write (finished prep lands in Completed; WIP, Next
Action, and Status repoint at the build; MEMORY.md updated; commit + push). Set the
written Next Action to the SAME agent-completable `/goal "<condition>"` line
(derived per the Default-branch bullet above) followed by the `/build-phase --plan
<plan-path>` command, goal line first, so the rendered handoff carries the armed
pair.
2. **Invoke `session-wrap` via the Skill tool** with `args: "--end <plan-path>"` —
`--end` explicitly, never bare: end-window is the route `--new-window` wants, and a
bare invocation triages and may route `continue`. session-wrap renders the handoff
to disk (`.claude/task-state/handoff-prompt.md`, a rendering of the `current.md`
just written — one source of truth) and prints the Pick-up-here block per its
screen contract: digest + pointer first, then numbered Step blocks — Step 1
`/clear`, an optional `/model <pinned-default>` step when the session's model was
explicitly overridden this session, and the FINAL fenced block carrying the
`/goal` + `/build-phase` pair verbatim (goal line first). No word floor.
session-wrap's route step 1 checkpoint must preserve step 1's Next Action
verbatim (its no-regress clause) — the pair survives into the render and into
the final Step block.
- Emit session-wrap's Pick-up-here block verbatim as the `/plan-expedite` final
output. Do not paraphrase, do not summarize, do not add a preamble. VERIFY the
`/goal` + `/build-phase` pair is the block's final fenced Step — the last lines on
screen are what the operator runs. If the block arrived without the pair
(defensive), append a final Step carrying both lines in ONE fenced code block —
never as bare indented lines.
- Record `handoff_mode: "new-window"` in `.plan-expedite-state`.
The `--new-window` flag is the escape hatch for users who want the next step in a
fresh window instead of continuing in-window: durable state on disk plus a rendered
handoff file, not a wall of copy-paste text.
### Halt template (per BPA plan section 5 D8 — generic, no per-skill enumeration)
Write the following template verbatim on any sub-skill non-success exit:
```text
/plan-expedite halted at: <sub-skill name>
Reason: <captured stderr / verdict line>
Plan state: <unchanged | partially autofixed (cite which fixes applied per the autofix-applied markers in plan.md)>
GitHub state: <unchanged | issues created/updated (cite count if repo-sync ran)>
To resume: fix the cited issue, then re-run /plan-expedite --plan <path>
(already-completed sub-skills are skipped via state inference from .plan-expedite-state)
```
Stop without producing the final continue command / Pick-up-here block after printing. The `.plan-expedite-state` records `halted_at: <sub-skill name>` for resume.
Use the same five-line template regardless of which sub-skill fails (plan-review, plan-wrap, repo-sync, task-handoff, session-wrap); per-sub-skill diagnostic detail belongs in the cited stderr, not in `/plan-expedite`'s template.
## Relationship to other skills
| Skill | Role |
|---|---|
| `/plan-init`, `/plan-feature` | Produce the plan.md `/plan-expedite` operates on |
| `/plan-review`, `/plan-wrap` | Autofix sub-skills (Steps 7-8 of BPA plan) |
| `/repo-sync` | Issue-sync sub-skill (Step 6) |
| `/session-wrap` | End-window handoff sub-skill (`--new-window` only, invoked `--end` AFTER the durable `task-handoff --next-task` write; renders `handoff-prompt.md` + prints the Pick-up-here block) |
| `/build-phase` | Continues in-window from the `/goal` + `/build-phase` commands /plan-expedite emits (the `/goal` arms the Stop hook over the automated span; or, with `--new-window`, the fresh window opens from the rendered handoff carrying both) |
## Limitations
- Resume state lives in a single `.plan-expedite-state` file in the project root. Multiple concurrent `/plan-expedite` invocations on the same plan have undefined behavior — don't do that.
- Concurrent operator edits to `.plan-expedite-state` during a run have undefined behavior. Don't edit the file while `/plan-expedite` is running.
- Sub-skill failures halt the chain; resume requires manual operator inspection. By design — autofix's promise is to handle the boring cases, not the surprising ones.