agentleFS
AirMileAirMile/claude-config/skills/dev-manual/SKILL.md

dev-manual

Skill0 starsChanged 4 months agoMITView on GitHub

Use when a /dev-ship run parked after auto-verify. Use with /dev-manual.

The file

Files
SKILL.md

Manual (dev-ship pipeline tail)

Owns the back half of the dev pipeline for a feature /dev-ship already carried through build and auto-verify: the manual test round (with its fix/debug rounds), refactor, and finalize/merge. Not a separate pipeline — it resumes the same ship checkpoint and reads the same dev-ship/references/ files, named per phase below, rather than duplicating them. /dev-ship {feature} resumes into the same place; this skill exists so the parked hand-off has a name that says what happens next.

Trigger: /dev-manual {feature} (the feature name is required — there is no no-arg pickup; a ship checkpoint is always feature-scoped).

Workflow

Phase tracking — MANUAL 0 owns when this fires (after the checkpoint is confirmed) and its Todo carries the ToolSearch. Call TaskCreate with these 4 items (it always creates them pending — no initial-status param exists), then immediately follow with one TaskUpdate per item the checkpoint already shows as done, setting it completed directly — never leave all 4 sitting pending:

  1. MANUAL 0: Resume + worktree/app
  2. MANUAL 1: Manual round (walkthrough + fix/debug)
  3. MANUAL 2: Refactor + finalize/merge
  4. MANUAL 3: Report

A park (a debug-ladder park, a fix-round "Otherwise" park, or a finalize halt-for-team) leaves its MANUAL N item in_progress — never completed — until the parked work actually resolves on a later resume; a park is a stopping point, not a finished phase.

MANUAL 0 — Resume + worktree/app

Todo: Resolve main_root FIRST and route per the branches below. Only the checkpoint branches seed or mark tasks — load their tools at that point with ToolSearch query="select:TaskCreate,TaskUpdate" (both are deferred), never upfront: the VERIFY-card and not-found branches mark nothing, so an eager load is dead weight on two of the three branches. If they don't resolve, skip task tracking and continue; each phase below opens with its own transition line either way. main_root = (git worktree list --porcelain | head -1 | awk '{print $2}' — always resolve this first, cwd may already be inside a feature worktree where .project/session/ is not shared).

test -f "$main_root/.project/session/ship-{feature}.json" fails → there is no open ship run for this feature. Before refusing, check for a live VERIFY pickup card: node ~/.claude/scripts/backlog-load.js "$main_root" guard-items, filter type === "VERIFY" and status !== "CANCELLED" and not shipped, match against verify-{feature} (or {feature} is itself that card's name — strip the verify- prefix to get the underlying feature for the dossier lookup below).

  • Found → Read .claude/skills/dev-manual/references/deferred-reverify.md and follow it in full — this is a short standalone round, not a ship resume: do not seed the 4-item TaskCreate list above, nothing here maps to MANUAL 0-3.
  • Not found → Print: "No open ship run for {feature} — start one with /dev-ship {feature}, if this is a small change rather than an in-flight ship use /dev-tweak instead, or if a verify-{feature} VERIFY card exists on the backlog once its blocker ships, re-invoke to run its deferred re-verify round." Stop here — do not seed TaskCreate, nothing to track.

Checkpoint exists → read it (this routing step is the phase's own work — MANUAL 0 skips in_progress and marks straight to completed once a branch resolves below), confirm pipeline: "dev" (a design/game checkpoint under the same feature name is a different pipeline entirely — refuse with the same message as above if it doesn't match).

Staleness pre-check (belt-and-suspenders — independent of whatever shared/WORKTREE.md § 4.6 does later in MANUAL 1's own worktree-switch step): DEFAULT=$(git symbolic-ref --short HEAD); git log --oneline "worktree-{feature}..$DEFAULT" | wc -l. Zero → say nothing.

Determine isolation once, here. Run git -C "$main_root" rev-parse --git-dir. Refused → this session is worktree-isolated; note that, and for the rest of this run address every path explicitly instead of redirecting git. Works → not isolated. Both probes in this pre-check read refs, not a working tree, so a worktree's own git dir answers identically; from inside the worktree resolve the default branch as git rev-parse --abbrev-ref origin/HEAD | sed 's|origin/||' instead. Isolated → print "NOTE: staleness pre-check skipped — git is sandbox-restricted here; MANUAL 2's merge still surfaces any conflict." and continue. This check is advisory, never a gate.

Non-zero → the commit count alone does not predict cost, so probe for a real overlap before wording the note. git merge-tree --write-tree --name-only "$DEFAULT" "worktree-{feature}" exits 1 on conflict and lists the conflicting paths from its second line on (line 1 is the tree oid); it writes nothing to the working tree.

  • Exit 0 → "NOTE: worktree-{feature} is {N} commit(s) behind {default branch} — merges clean; MANUAL 1's worktree switch rebases it automatically, nothing for you to do."
  • Exit 1 → not a visibility note, a scheduled cost. Print: "NOTE: worktree-{feature} is {N} commit(s) behind {default branch} AND conflicts with it in: {paths}. MANUAL 2's merge WILL stop on this — budget for dev-ship/references/merge-conflict-resolution.md before finalize. Not a reason to stop now."

Two git calls, no working-tree mutation — this surfaces the drift and its real cost even when MANUAL 1's switch takes the skip-because-already-in-worktree fast path, and never replaces WORKTREE.md's own staleness-rebase.

Run node ~/.claude/scripts/ship-checkpoint.js route {feature} and branch — every branch below marks MANUAL 0 → completed (routing resolved) and seeds the rest of the TaskCreate list per the stated statuses:

Cross-check before trusting "phase3-completion": the router derives this purely from whether every entry in manual.items is resolved — it never re-reads how many items the round was supposed to walk. Mind the two paths: the ledger is top-level manual.items, a sibling of results (ship-checkpoint.js's route reads cur.manual), while the item list is results.verify.remainingManualItems. Probing results.manual returns null, which is indistinguishable from "no ledger yet" and silently routes a half-finished round to completion. Compare both directions before believing it:

  1. results.verify.remainingManualItemsCount (when present) against the length of the results.verify.remainingManualItems array — a count larger than the array means the array was truncated.
  2. The length of remainingManualItems against the number of entries in manual.items — a ledger covering fewer items than the array means the walkthrough never reached them.

Either side short → the checkpoint is malformed or the round is simply unfinished, and the router's "nothing to test" verdict is not trustworthy. Direction 2 is the common real case: a resume that walked some items, resolved them, and stopped — every ledger entry is resolved, so route reports completion while items sit unwalked. Do not route to MANUAL 2 on it; go to MANUAL 1 and run the walkthrough for the items not yet present in manual.items (the same filter phase-3-manual-finalize.md § Resume entry bullet 8 uses). Compare the ids as strings. AGENT 2 writes remainingManualItems[].id as a number, while ship-checkpoint.js item rejects any id that is not a non-empty string (exit 5, before any write) — so the ledger carries String(id) and a raw === against the verify array never matches. Get this wrong and the filter silently re-walks every already-verdicted item. Only a genuine array/count mismatch (direction 1) needs the user: print it and ask how to proceed (re-run auto-verify to regenerate the array, or reconstruct it from plan.verificationProfile). Never silently skip the manual round on either.

  • "phase12" → build/auto-verify hasn't completed yet — this skill's job hasn't started. Print: "Build/auto-verify for {feature} hasn't finished — resume with /dev-ship {feature} instead." Stop here (mark MANUAL 0 → completed regardless — the routing check itself finished, only the ship run hasn't).
  • "phase3-manual" → the common case. Mark MANUAL 0 → completed, MANUAL 1 → in_progress, leave MANUAL 2/3 pending, then go to MANUAL 1.
  • "phase3-completion" → no manual items were left (or the ledger already fully resolved). Mark MANUAL 0 → completed, MANUAL 1 → completed (nothing to walk), MANUAL 2 → in_progress, leave MANUAL 3 pending, then skip straight to MANUAL 2 (there is no manual round to run).
  • "phase4" / "phase4-finalize-only" → manual round and completion already ran on a prior resume; only refactor/finalize (or just finalize) remains. Mark MANUAL 0 → completed, MANUAL 1 → completed, MANUAL 2 → in_progress, leave MANUAL 3 pending, then go straight to MANUAL 2.

Note: the branch table above already made every mark it names — later sections only mark what it didn't cover.

MANUAL 1 — Manual round (walkthrough + fix/debug)

Print first: MANUAL 0 → MANUAL 1: checkpoint resumed, manual round starting. Phases run tens of tool calls long; the task list alone leaves the user without a marker for where the run is.

Todo: mark MANUAL 1 → in_progress. Read .claude/skills/dev-ship/references/phase-3-manual-finalize.md and follow it from § Resume entry — it re-enters the worktree (Step 1), relaunches the app (Step 2), then routes per open ledger item (debug tiers, fix-plan gate, or the item-by-item walkthrough) exactly as a /dev-ship {feature} resume would. This section owns the full loop — findings ledger, fix rounds, debug-ladder escalation with its difficulty triage and toolbox (shared/DEBUG-LADDER.md, shared/DEBUG-TOOLBOX.md), tweak offload to the backlog — through to the DONE completion write (its own Step 3). Nothing here is dev-manual-specific — it is the identical reference /dev-ship itself would read on a resume; this skill just starts here directly instead of routing through /dev-ship's own PHASE 0/1/2.

On completion, that file's Step 3 already hands off to orchestration.md § 5 internally — continue there (MANUAL 2 below) rather than re-deriving the transition.

App already running — the norm on desktop/native/terminal projects: the user has it open, and that is often why they invoked this skill. phase-3-manual-finalize.md § Step 2 only covers the case where you launch it. Do not relaunch blindly, and do not skip Step 2 either — a process started before this resume may hold a build older than the branch under test. Apply that file's No hot reload → confirm the running build another way rule in full (it owns the reasoning and the disk-vs-process distinction); the only addition here is that its teardown then kills only what you started yourself, so a pre-existing instance is left running.

Reconstructing the completion-sync payload: unlike a same-session /dev-ship run, dev-manual never has AGENT 2's structured result in context — phase-3-manual-finalize.md § Step 3's completion-sync payload (requirements[] verdicts, checklist{} statuses) must be reconstructed from the checkpoint's results.verify (autoPass/autoTotal, failedAt, autoDecisions) plus this round's own manual ledger. Do not read the verdicts out of feature.json#requirements[]/#tests.checklist[] — AGENT 2 is ordered to leave them alone (prompts/verify.md: "DO NOT run completion-sync's DONE transition"), so on this path every checklist entry still reads status: "pending" and requirements[].status is absent. Read feature.json for the item ids, titles and requirementId mapping only; the verdicts come from the checkpoint. An acceptance whose condition never occurred is "skip", not "PASS". Translate the vocabularies: completion-sync.js validates against PASS|FAIL|BLOCKED|UNCLEAR (requirements) and PASS|FAIL|skip (checklist) and exits 6 on anything else, before any write — so a "pending" or "passed" forwarded verbatim from feature.json fails the whole call.

Ledger writes from inside the worktree. MANUAL 1 runs worktree-isolated by construction (Step 1 switched the session in), and the harness rejects compound Bash there — a heredoc, a cat > file <<EOF, or a multi-line loop all fail as "too complex to verify". A realistic ship-checkpoint.js item payload does not fit on one line, so: Write the JSON to the session scratchpad, then run the single plain command node ~/.claude/scripts/ship-checkpoint.js item {feature} manual < {scratch-path}. Same for patch. Do not rediscover this per write.

MANUAL 2 — Refactor + finalize/merge

Print first: MANUAL 1 → MANUAL 2: manual round done, refactor starting.

Todo: mark MANUAL 1 → completed, MANUAL 2 → in_progress.

STOP — check where the session stands before entering § 5. MANUAL 1's Step 1 may have switched the session into worktree-{feature} (shared/WORKTREE.md § Switch), which would make it worktree-isolated — the harness then refuses every git -C "$main_root" …, including § 5's own pre-spawn target-clean check (d) and the merge itself. MANUAL 0 already determined isolation, but that switch may have changed the answer, so re-run the same probe rather than trusting the earlier one. Use git -C "$main_root" status --porcelain as the probe here — check (d) needs that output anyway, so it costs nothing extra.

  • It works → the session was launched in the worktree rather than switched into it, so ExitWorktree has no session to end and returns a no-op error (the same case finalize.md's own ExitWorktree note documents). Do not call it. Stay put and name every target path explicitly from here on.
  • It is refused → the session is worktree-isolated. Call ExitWorktree(action: keep) now — the worktree stays on disk and AGENT 3 gets its path from the pointer file, so nothing downstream needs the session to sit inside it.

Two traps either way: § 5's scriptPath must be absolute, and finalize.md's PR probe must be handed the branch literally (--head worktree-{feature}) — once off the branch git branch --show-current answers main, so the verbatim command would probe the wrong one.

Read .claude/skills/dev-ship/references/orchestration.md § 5 and follow it: refactor (AGENT 3) + optional security triage (AGENT S), then finalize (solo-merge or halt-for-team, per .claude/skills/dev-ship/references/dev-verify/references/finalize.md). This is the same reference /dev-ship's own PHASE 4 reads — no dev-manual-specific variant.

§ 5's post-merge target-branch verification (run the suite on the target before cleanup) is not optional on a resume — it is the one obligation MANUAL 0's staleness probe cannot cover, since that probe is a snapshot taken at resume and commits landing during the run are invisible to it. The rule itself lives in § 5; do not restate it here.

"phase3-completion" entry (from MANUAL 0): first run orchestration.md § 4 (the no-manual completion — Step 1 + Step 3 of phase-3-manual-finalize.md only) before § 5, exactly as /dev-ship's own no-manual path would.

"phase4-finalize-only" entry: refactor already ran on a prior resume — skip the refactor spawn, but still run § 5's two non-refactor obligations before finalizing: (a) the deferred-items transparency line (orchestration.md § 5) when the checkpoint's manual.items[] holds any verdict: "deferred" entry — reword "refactor + merge" to "merge"; the disclosure belongs before the merge, not only in the closing report; and (b) the archive-reconcile guard — never skip the reconcile because the project's backlog.json looks inconsistent with it; say so to the user instead of silently matching precedent.

MANUAL 3 — Report

Print first: MANUAL 2 → MANUAL 3: merged, writing the report. (Or halted in place of merged when finalize took the halt-for-team route.)

Todo: mark MANUAL 2 → completed, MANUAL 3 → in_progress. Read .claude/skills/dev-ship/references/phase-5-report.md and follow it — shared with /dev-ship's own PHASE 5, the only difference being which phase-tracking unit gets marked in_progress/completed (MANUAL 3 here). Mark MANUAL 3 → completed per that file's own closing Todo.

Failure recovery

Same as /dev-ship: a failed workflow leaves the checkpoint on disk (status: "failed") rather than completing it — re-run /dev-manual {feature} (or /dev-ship {feature}, identical result) to retry, or go straight to .claude/skills/dev-ship/references/debug-round-heavy.md (non-ledger entry) for a repeated build/verify failure. This skill never resumes a "phase12" failure itself (see MANUAL 0's refusal above) — that retry always goes through /dev-ship.

Crash between the merge and the checkpoint deletion. The checkpoint still says phase4-finalize-only while the branch is already merged and deleted, so a re-run routes to MANUAL 2 and finalize.md's Branch Resolution dead-ends on "No worktree found". That is the shape of a finished ship, not a broken one — do not re-merge. Confirm both: the default branch's tip is the merge commit (git log --oneline -1), and the feature sits in .project/archive/backlog-archive.json#archived[] with shipped: true. Both hold → run § 5's post-merge reconcile (re-stamp shippedSha, state-push), delete the checkpoint, go to MANUAL 3. Either fails → the merge never landed; re-enter MANUAL 2 normally.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.