Imported from TheElysium/agent-workflow (
.claude/skills/dev-workflow/SKILL.md). Install upstream withnpx skills add TheElysium/agent-workflow --skill dev-workflow. Copyright stays with the author.
Multi-phase workflow. The main session is the default orchestrator.
Phase 1 — Understand & Spec
git statusbefore any edit. Uncommitted work belongs to a prior task: land it or ask the user first. Adocs/tasks/<slug>.mdstatus header that doesn't match the tree = prior session ended without its commit.- Locate the spec: user message,
docs/,*.mdfiles, or issues. - Extract: requirements, acceptance criteria, edge cases, explicit out-of-scope.
- Non-trivial spec (T1 with new behavior, T2, architectural impact) → dispatch
spec-criticon the extracted spec before planning.STRUCTURED→ proceed.NEEDS_CLARIFICATION→ interview the user with its question list. - Restate the spec in the plan before writing any code (problem, solution, implementation decisions, out of scope). Do not hardcode file paths in the spec or PRD — keep them at the
file:linelevel in delegation prompts only. - If the spec is ambiguous, incomplete, or missing → interview the user, one question at a time, each with your recommended answer. If a question can be answered by exploring the codebase, explore instead of asking. Never guess requirements.
- Design check: sketch the modules to build or modify. Favor deep modules (rich functionality behind a small, stable, testable interface); confirm the sketch with the user before coding.
- Delegate heavy codebase exploration to
explore/bulk-reader. Giveexplorea question, not a territory: "where is X computed today, and is there more than one implementation?" beats "map the X module".
Output format: the restated spec as short structured prose (Problem / Solution / Decisions / Out of scope); interview questions one at a time, each with the recommended answer.
Phase 2 — Plan
- Any task with 3+ steps → maintain a tracked todo list, kept up to date in real time.
- Decompose into vertical slices (tracer bullets): each slice cuts through every layer end-to-end and is demoable or verifiable on its own. Prefer many thin slices over few thick ones.
- Classify each slice:
HITL(needs a human decision or review) orAFK(implementable and mergeable autonomously). Prefer AFK. - HITL slices: split so every pure decision or mapping lives in a unit-tested module; only the irreducibly manual part (actor wiring, hardware-in-the-loop) sits outside TDD. Write the manual QA script (exact click path, expected state, expected state after undo/delete) before implementing, not after.
- Order slices by dependency (blockers first).
- For non-trivial or architectural changes, propose the approach and get agreement before coding.
- Persist the plan: for tasks spanning multiple sessions, create
docs/tasks/<slug>.mdwith the extracted spec, decisions, todo state, and gate status. Sessions read it before resuming. The status header (current slice, commit, next step) is updated in the same commit as the slice it describes — never as a follow-up edit. - Memory is compressed, not accumulated. On task closure, compress
docs/tasks/<slug>.mddown to the durable outcome (final spec, decisions, retrospective lessons) and mark it archived; only open tasks stay as live plan files. Never grow an exhaustive journal — the file must shrink to knowledge at closure. - Log subagent metrics as a line in
docs/tasks/<slug>.mdat each subagent's completion — every subagent, every round, gate-keeper and re-review included. Format:subagent | tokens | tool_uses | duration | retries | review_iterations | gate_failures | outcome. Token counts come from the usage sink, not estimates:scripts/usage-report.sh --since <task-start-ts>aggregates.usage/usage.jsonl(fed by the opencodeusage-logplugin and the Claude CodeSessionEndhook). Conversation compaction erases them; the plan file is the only durable record. These lines aggregate into cost per successful task (tokens spent per mergeable change) — not cost per agent.
Output format: a tracked todo list (todo tool), slices with HITL/AFK labels and dependency order — no narrative paragraph.
Phase 3 — Implement
- Evidence-first implementation is mandatory: no significant change without verifiable proof. TDD (red-green-refactor) is the default proof for behavior-changing code, but the proof form must match the change type:
| Change type | Required proof |
|---|---|
| Business logic, API, parsing, algorithms, services | TDD: red → green → refactor |
| Mechanical refactor, config, migrations, code deletion | Existing suite green + typecheck (behavior unchanged) |
| Pure UI / visual work | Manual-QA script (written before implementing) |
| Prototype / throwaway | Proof form declared explicitly in the spec |
| Review fixes | Edit the test first, watch it fail, then fix (TDD again) |
- Review fixes go through TDD too: edit the test first, watch it fail, then change the implementation.
- Lint: follow the project's configured linter; if none, apply a strict default for the stack (e.g.
clippy -D warnings,ruff --strict,eslintstrict) and tell the user. - Cyclomatic complexity: target ≤ 10 per function. Above the threshold → refactor or explicitly justify.
- Apply the stack's formatter.
- Run SAST when available; if the tool is missing, propose installing it (never skip silently — see Phase 4).
Output format: a summarized diff (files touched + why), never a full code dump in the reply — the code lives in the files.
Phase 4 — Verify (mandatory gate)
- Two distinct gates; both must pass before a task is done:
- Engineering gate — lint + typecheck + build + tests + SAST, run by
gate-keeper. - Intent gate — does the implementation satisfy the user's intent (acceptance criteria, edge cases, no out-of-scope changes)? Carried by the
reviewer(dimension 1); the delegation prompt must always provide the spec/acceptance criteria.
- Engineering gate — lint + typecheck + build + tests + SAST, run by
- Gate commands come from the project's
.gates.ymlat the repo root (see below). If it is missing, creating it with the user is the first action of the session — before implementation, not at the first gate run. Never run gates from a command list hand-copied into prompts. - SAST is non-skippable: at minimum
gitleaks(secrets) plus the stack's audit tool. A gate-keeper run that skipped SAST is a failed gate. - A task with a failing gate (engineering or intent) is never "done".
.gates.yml convention
At the repo root of every project:
stack: rust # free-form: rust | go | node | python | tauri...
lint: cargo clippy -- -D warnings
typecheck: cargo check
build: cargo build
test: cargo test
sast: cargo audit && gitleaks detect
format: cargo fmt --check # optional
gate-keeperreads it verbatim, runs each key, and reports a structured pass/fail per command (never interprets results).- Accepted gaps are recorded in
.gates.ymlitself, as a dated comment on the affected key (# gitleaks not installed — gap accepted 2026-09-14). A RED on a non-skippable step is surfaced and decided the first time it appears; a workaround repeated across two slices is fixed or recorded as an accepted gap — never carried as a habit. - Local enforcement is the default: gates run before a task is done and before commit — no CI needed. CI mirroring
.gates.ymlas.github/workflows/ci.ymlis optional, only for projects whose CI you control. - Dispatch
gate-keeperas its own explicit step after everyimplementerrun, even for a slice that looks trivial — never let therevieweror the orchestrator absorb the gate run informally. - UI/visual work that no automated gate can catch → an explicit manual-QA todo item (e.g. "run the app, click through X"), never implicit. An open manual-QA item on a surface blocks starting the next slice that builds on that same surface.
Output format: a structured pass/fail table per .gates.yml command, with no interpretation or rephrasing.
Phase 5 — Git
- One branch per task:
feat/<scope>,fix/<scope>,chore/<scope>. - Conventional Commits (feat, fix, chore, docs, refactor, test) — short, present tense.
- Committing without asking is allowed (on the task branch).
- Push only when the user explicitly asks (a permission prompt will confirm). No force-push, no hook bypass, no secrets in commits.
Output format: the commit message in strict Conventional Commits, one summary line plus short bullets when needed.
Multi-agent rules
- Subagents start with a fresh context: every delegation prompt must be self-contained (extracted spec, exact task,
file:lineanchors, stack conventions, acceptance criteria). Never rely on session context. - Include known environment constraints in every delegation prompt (CI toolchain gaps, OS quirks, host-dependent test hazards).
- Subagent outputs: structured bullets only, no file dumps.
- Launch independent delegations in the same message to parallelize.
gate-keeperandreviewerare both read-only on the same tree — dispatch them in parallel after implementation. - Reviewer delegation: every reviewer prompt includes the output of
scripts/review-checklist.sh(deterministic, per-file checklist) plus the spec/acceptance criteria; the reviewer must cover every listed file. Checklist > ~10 files → split into parallelreviewerruns, each with its own sub-checklist; aggregate verdicts (a single REQUEST_CHANGES blocks). LLM review never enters.gates.yml— gates stay reproducible. - When splitting parallel
implementerwork, balance by estimated workload, not only file ownership — an uneven split keeps the critical path as long as the heaviest task. - Parallel hypothesis testing (optional, expensive): for major architectural decisions on HITL slices, explore 2–3 candidate designs via parallel
implementerruns against throwaway branches, then evaluate and keep the best. Never use by default — the cost must be justified by the decision's irreversibility. - Keep agent definitions stable (favors prompt caching).
Agent roster
spec-critic— challenges the spec before planning; on non-trivial specs (T1 with new behavior, T2).implementer— substantial coding; proof form per Phase 3 evidence table; parallelize on independent tasks.gate-keeper— verification commands only; after every implementation.reviewer— read-only peer review of the diff; carries the intent gate (dimension 1) and catches cross-layer inconsistency no gate can catch. Commit only after APPROVE + green gates.explore,bulk-reader— phase 1 exploration.code-writer— test scaffolding and repetitive code matching existing patterns.- Re-review loop: after REQUEST_CHANGES, fix everything, then send the corrected diff back to the same reviewer (resume the session when possible). A commit requires a final APPROVE on the latest diff — an old APPROVE never carries over; gates stay green between rounds. Review fixes go through TDD too: edit the test first, watch it fail, then change the implementation.
Flow for a substantial task: spec → decompose → explore (parallel) → implementer (TDD, parallel) → gate-keeper → reviewer → fix/re-review loop → commit (no push) → next todo.