From 42853d6586a1637e920de4b8f75d3de93093c62f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andr=C3=A9=20Jorge=20Lopes?= Date: Wed, 26 Aug 2026 15:52:48 +0200 Subject: [PATCH 1/2] feat(fast-feature): run unattended by replacing both human gates fast-feature had two points where it stopped and waited for a person: the ambiguity brainstorm in step 2, and the test-inventory approval in step 5, plus the one-click spawn gate inherited from phase-handoff. Neither gate is removed, both are re-implemented so they do not need a human: - Ambiguity the codebase can settle is now decided and recorded in the spec's decision log, where review can overturn it, instead of asked about. A fork that genuinely needs a product or cross-team answer is reported as a blocker rather than guessed at, which is the one case that still stops the run. - The test-inventory approval is given by an independent reviewer subagent that did not write the tests, checking AC coverage, that each test fails for the right reason, that none is tautological, and that nothing exceeds scope. Self-approval stays forbidden; a human was only ever one way to get a second pair of eyes. phase-handoff gains --unattended so the spawn gate can be skipped for runs that must not block, and fast-feature falls through to executing-plans in-session if the runtime cannot spawn without a click. --- devflow-plugin/commands/fast-feature.md | 47 +++++++++++++------- devflow-plugin/commands/phase-handoff.md | 5 ++- devflow-plugin/skills/fast-feature/SKILL.md | 47 +++++++++++++------- devflow-plugin/skills/phase-handoff/SKILL.md | 5 ++- skills/fast-feature/SKILL.md | 47 +++++++++++++------- skills/phase-handoff/SKILL.md | 5 ++- 6 files changed, 99 insertions(+), 57 deletions(-) diff --git a/devflow-plugin/commands/fast-feature.md b/devflow-plugin/commands/fast-feature.md index c8688d3..326d0b3 100644 --- a/devflow-plugin/commands/fast-feature.md +++ b/devflow-plugin/commands/fast-feature.md @@ -1,10 +1,12 @@ --- -description: [0.28.0] Use when driving a single already-specced ticket through devflow in one session — a quick ambiguity-only brainstorm, then spec, plan, and lock-tests back-to-back, spawning a new session only for the execute phase. Also the per-ticket driver that orchestrate-epic invokes. +description: [0.28.0] Use when driving a single already-specced ticket through devflow in one session, unattended, resolving ambiguity from the codebase rather than by asking, then spec, plan, and lock-tests back-to-back with an independent reviewer standing in for the human gate, spawning a new session only for the execute phase. Also the per-ticket driver that orchestrate-epic invokes. --- You are a senior engineer who moves a well-defined ticket from "assigned" to "tests locked, ready to implement" in a single focused session, then hands ONLY the implementation off to a fresh session. You do not re-litigate a ticket that already has clear acceptance criteria, and you do not fragment context across a session per phase. -**Core principle:** the standard devflow pipeline spawns a new session at every phase boundary (spec → plan → lock-tests → impl = three spawns). For a ticket that is already specced, that is friction. `fast-feature` collapses `brainstorm → spec → plan → lock-tests` into ONE session and spawns exactly once — at the execute boundary — so implementation starts cold and clean while all the planning stays in one warm context. +**Core principle:** the standard devflow pipeline spawns a new session at every phase boundary (spec → plan → lock-tests → impl = three spawns). For a ticket that is already specced, that is friction. `fast-feature` collapses `resolve ambiguity → spec → plan → lock-tests` into ONE session and spawns exactly once, at the execute boundary, so implementation starts cold and clean while all the planning stays in one warm context. + +**It runs unattended.** Every human gate in the standard pipeline is replaced by an automated equivalent: ambiguity is resolved from the codebase and recorded rather than asked about, and the test-inventory approval is given by an independent reviewer subagent rather than by a person. The one thing that still stops the run is a fork only a human can settle, which is reported as a blocker instead of guessed at. ## When to Use @@ -25,13 +27,14 @@ Do NOT use for: greenfield features that genuinely need design exploration (use flowchart TD A[Step 0: establish feature worktree for the ticket] --> B[Step 1: load context
recall + trust the provided brief] B --> C{Step 2: ACs ambiguous?} - C -->|yes, real gap| D[Quick brainstorm
ONLY the ambiguous points] - C -->|no| E[Skip brainstorm] + C -->|yes, settleable from code| D[Decide and record
in the spec decision log] + C -->|yes, needs a human| J[STOP, report the blocker] + C -->|no| E[Proceed] D --> F[Step 3: spec-feature
SKIP its terminal handoff] E --> F F --> G[Step 4: writing-plans
SKIP its terminal handoff] - G --> H[Step 5: lock-tests
through the Phase 1.8 approval gate] - H --> I[Step 6: THE ONE SPAWN
phase-handoff lock-tests to impl] + G --> H[Step 5: lock-tests
independent reviewer replaces the approval gate] + H --> I[Step 6: THE ONE SPAWN
phase-handoff lock-tests to impl, --unattended] ``` ## Step 0 — Establish the feature worktree for this ticket @@ -61,14 +64,16 @@ You may be launched cold (spawned by `orchestrate-epic` into a throwaway worktre 2. **Read the context brief** if one was provided. For every dimension it covers (PRD, design, cross-repo impact, locked decisions, security/AC constraints), treat it as authoritative and do NOT re-fetch or re-derive it. Only research dimensions the brief leaves open. 3. **Read the ticket** itself (via `acli`/Atlassian) for its acceptance criteria and scope, unless the brief already reproduces them verbatim. -## Step 2 — Quick brainstorm (ambiguity-only) +## Step 2 — Resolve ambiguity without stopping Judge whether the acceptance criteria leave a REAL, decision-changing ambiguity (a fork where two reasonable engineers would build different things). - **No real ambiguity → skip brainstorming entirely.** State one line: "ACs are unambiguous; skipping brainstorm." Go to Step 3. -- **Real ambiguity → invoke `/devflow:brainstorming`, but scope it hard**: ask ONLY about the specific unresolved forks, cap at the minimum questions needed (prefer 1–2), and stop as soon as they are resolved. Do not run the full open-ended design loop on a ticket that is already specced. +- **Real ambiguity → resolve it without stopping.** Do NOT invoke `/devflow:brainstorming`, which is an interactive loop. Instead: state each fork explicitly, pick the option most consistent with the surrounding code and the ticket's own acceptance criteria, and record the choice plus its rationale in the spec's decision log so a reviewer can overturn it in one comment. If a fork is genuinely unresolvable from the repo (it needs a product decision, another team's answer, or access you do not have), do NOT guess: stop, report the fork, and leave the ticket unstarted. + +Never invent ambiguity to justify a detour. Never guess past a fork that needs someone else's answer. -Never invent ambiguity to justify a brainstorm. Never skip a genuine one to save time. +**The line to hold:** ambiguity that the codebase can settle, you settle. Ambiguity that only a human can settle is a blocker, not a question to ask mid-run. ## Step 3 — Spec (in this session) @@ -86,26 +91,32 @@ Invoke `/devflow:writing-plans`. Its Step 0 (re-establish worktree) is a no-op h Invoke `/devflow:lock-tests`. Its Step 0 is a no-op (already in the feature worktree). Since the spec and plan were produced in THIS session, feed it their known paths directly if it cannot find a frozen-state file (its Phase 0 documents that fallback). Run it through: -- Phase 1 (write the batch of failing tests), Phase 1.5 (verify each fails for the right reason), Phase 1.7 (Test Inventory doc), Phase 1.8 (user-approval gate). +- Phase 1 (write the batch of failing tests), Phase 1.5 (verify each fails for the right reason), Phase 1.7 (Test Inventory doc). + +**Phase 1.8's user-approval gate is replaced, not skipped.** Dispatch an independent reviewer subagent that did not write the tests, give it the ticket, the spec, the plan and the Test Inventory, and have it answer: does every acceptance criterion have a test, does every test fail for the right reason today, is any test tautological (would it pass before the change), and does anything exceed the ticket's scope. Approve on its verdict, not your own. -Do NOT proceed past Phase 1.8 without explicit approval. If the trivial-change escape hatch fires (tiny plan, no new AC), follow lock-tests' own escape path (it hands off with `--no-handoff` and tells you to run `/devflow:executing-plans` here) — that is the one case where execute also stays in-session. +**Never self-approve in the same context.** The gate's purpose is a second pair of eyes; a human was only ever one way to get that. If the reviewer returns NEEDS_WORK, fix and re-dispatch. If it returns NEEDS_WORK twice on the same point, stop and report rather than looping. + +If the trivial-change escape hatch fires (tiny plan, no new AC), follow lock-tests' own escape path (it hands off with `--no-handoff` and tells you to run `/devflow:executing-plans` here) — that is the one case where execute also stays in-session. ## Step 6 — The one spawn: hand off execute -This is the ONLY phase boundary that spawns a new session. After Phase 1.8 approval, invoke: +This is the ONLY phase boundary that spawns a new session. After the reviewer approves, invoke: ``` devflow:phase-handoff --phase lock-tests --next-phase impl ``` -Run it WITHOUT `--no-handoff`. It commits the spec/plan/test-inventory docs to the branch (durability), gates on a one-click `AskUserQuestion`, and spawns the `[] [MR#] Implementation` session whose prompt leads with `/devflow:executing-plans`. That new session does the red/green/refactor against the locked tests and finishes via `/devflow:finish-feature`. +Run it WITHOUT `--no-handoff`, and WITH `--unattended` so it does not gate on an `AskUserQuestion`. It commits the spec/plan/test-inventory docs to the branch (durability) and spawns the `[] [MR#] Implementation` session whose prompt leads with `/devflow:executing-plans`. That new session does the red/green/refactor against the locked tests and finishes via `/devflow:finish-feature`. + +If the runtime cannot spawn a session without a human click, do not wait on one: continue into `/devflow:executing-plans` in THIS session and say plainly in the final report that execute did not get a cold context. Then exit. Report: spec + plan + test-inventory produced in this session, and the implementation session spawned. ## Common Mistakes - **Letting an intermediate phase spawn a session.** Steps 3 and 4 MUST suppress their `phase-handoff` — otherwise you get the very 3-spawn fragmentation this skill exists to avoid. -- **Running a full brainstorm on a specced ticket.** Ambiguity-only means you often skip it entirely. +- **Stopping to ask when the codebase already answers it.** Decide, record the decision and its rationale, and let review overturn it. - **Re-discovering what the brief already gave you.** A provided brief is trusted input, not a starting hint. - **Speccing on the wrong branch.** Step 0 must end on `feat//...`, never the default branch. @@ -114,15 +125,17 @@ Then exit. Report: spec + plan + test-inventory produced in this session, and th | Thought | Reality | |---|---| | "I'll let spec-feature hand off normally, it's simpler" | That spawns a plan session and breaks the single-session contract. Suppress it. | -| "The ACs are clear but I'll brainstorm anyway to be safe" | A specced ticket does not need a design loop. Skip it; note that you did. | +| "The ACs are clear but I'll ask anyway to be safe" | Asking is the thing this skill exists to avoid. Decide and record it. | +| "I'll approve the test inventory myself, it looks fine" | The gate is a second pair of eyes. Dispatch the reviewer. | +| "This fork is unclear, I'll pick something and move on" | Only if the codebase settles it. If it needs a product or another team's answer, stop and report. | | "The brief mentions the PRD, let me go read the whole PRD" | Per-dimension trust: the brief IS the PRD context for this run. Do not re-fetch. | | "Let me start implementing here since I'm warm" | Execute gets its own cold session (except the trivial-escape path). Spawn at Step 6. | ## Important - `spec-feature` → `writing-plans` → `lock-tests` all run in ONE session here; only Step 6 spawns. -- Never write production code in this skill — it stops at a locked, approved test inventory (Phase 1.8), then hands off. +- Never write production code in this skill — it stops at a locked, reviewer-approved test inventory, then hands off. - Always end Step 0 on the ticket's feature branch. If worktree creation fails, STOP. -- Honor lock-tests' Phase 1.8 approval gate; it is not optional. +- The test-inventory gate is not optional, but it is satisfied by an independent reviewer rather than by a human. Never satisfy it yourself. $ARGUMENTS diff --git a/devflow-plugin/commands/phase-handoff.md b/devflow-plugin/commands/phase-handoff.md index 9bd7e18..a340031 100644 --- a/devflow-plugin/commands/phase-handoff.md +++ b/devflow-plugin/commands/phase-handoff.md @@ -1,5 +1,5 @@ --- -description: [0.28.0] Hand off between phases of the devflow new-feature pipeline. Writes a frozen-state file, marks a chapter, sets the terminal title, gates on a one-click AskUserQuestion, then spawns a new session for the next phase via `mcp__ccd_session__spawn_task` so it shows up in the Claude Desktop sidebar with a deterministic title. +description: [0.28.0] Hand off between phases of the devflow new-feature pipeline. Writes a frozen-state file, marks a chapter, sets the terminal title, gates on a one-click AskUserQuestion unless `--unattended` is passed, then spawns a new session for the next phase via `mcp__ccd_session__spawn_task` so it shows up in the Claude Desktop sidebar with a deterministic title. --- You are at a phase boundary in devflow's new-feature pipeline. Capture the current state to disk, **commit the phase artefacts to the feature branch so they survive worktree removal**, mark the transition in the CURRENT session, then spawn a NEW session (`mcp__ccd_session__spawn_task`) for the next phase. @@ -13,6 +13,7 @@ You are at a phase boundary in devflow's new-feature pipeline. Capture the curre - `--phase ` (required): one of `spec`, `plan`, `lock-tests` - `--next-phase ` (required): one of `plan`, `lock-tests`, `impl` - `--no-handoff` (optional): skip everything, return immediately (escape hatch) +- `--unattended` (optional): do everything, but skip the one-click gate in step 10 and spawn directly. For runs that must not block on a human. If `--no-handoff` is present, print "phase-handoff skipped" and exit. @@ -239,7 +240,7 @@ If `--no-handoff` is present, print "phase-handoff skipped" and exit. The slash command on line 1 is your first action — invoke it now. Its Step 0 re-establishes the feature worktree from the block above; the artefacts are then the only authoritative inputs. ``` -10. **One-click handoff gate (`AskUserQuestion`).** Ask the user: +10. **One-click handoff gate (`AskUserQuestion`).** Skip this entire step when `--unattended` was passed, and go straight to step 11. Otherwise ask the user: - Question: `Phase \`\` complete. Spawn a new session for the \`\` phase? Title will be: \`\`` - Header: `Handoff` diff --git a/devflow-plugin/skills/fast-feature/SKILL.md b/devflow-plugin/skills/fast-feature/SKILL.md index 947bd0f..d28149d 100644 --- a/devflow-plugin/skills/fast-feature/SKILL.md +++ b/devflow-plugin/skills/fast-feature/SKILL.md @@ -1,11 +1,13 @@ --- name: fast-feature -description: Use when driving a single already-specced ticket through devflow in one session — a quick ambiguity-only brainstorm, then spec, plan, and lock-tests back-to-back, spawning a new session only for the execute phase. Also the per-ticket driver that orchestrate-epic invokes. +description: Use when driving a single already-specced ticket through devflow in one session, unattended, resolving ambiguity from the codebase rather than by asking, then spec, plan, and lock-tests back-to-back with an independent reviewer standing in for the human gate, spawning a new session only for the execute phase. Also the per-ticket driver that orchestrate-epic invokes. --- You are a senior engineer who moves a well-defined ticket from "assigned" to "tests locked, ready to implement" in a single focused session, then hands ONLY the implementation off to a fresh session. You do not re-litigate a ticket that already has clear acceptance criteria, and you do not fragment context across a session per phase. -**Core principle:** the standard devflow pipeline spawns a new session at every phase boundary (spec → plan → lock-tests → impl = three spawns). For a ticket that is already specced, that is friction. `fast-feature` collapses `brainstorm → spec → plan → lock-tests` into ONE session and spawns exactly once — at the execute boundary — so implementation starts cold and clean while all the planning stays in one warm context. +**Core principle:** the standard devflow pipeline spawns a new session at every phase boundary (spec → plan → lock-tests → impl = three spawns). For a ticket that is already specced, that is friction. `fast-feature` collapses `resolve ambiguity → spec → plan → lock-tests` into ONE session and spawns exactly once, at the execute boundary, so implementation starts cold and clean while all the planning stays in one warm context. + +**It runs unattended.** Every human gate in the standard pipeline is replaced by an automated equivalent: ambiguity is resolved from the codebase and recorded rather than asked about, and the test-inventory approval is given by an independent reviewer subagent rather than by a person. The one thing that still stops the run is a fork only a human can settle, which is reported as a blocker instead of guessed at. ## When to Use @@ -26,13 +28,14 @@ Do NOT use for: greenfield features that genuinely need design exploration (use flowchart TD A[Step 0: establish feature worktree for the ticket] --> B[Step 1: load context
recall + trust the provided brief] B --> C{Step 2: ACs ambiguous?} - C -->|yes, real gap| D[Quick brainstorm
ONLY the ambiguous points] - C -->|no| E[Skip brainstorm] + C -->|yes, settleable from code| D[Decide and record
in the spec decision log] + C -->|yes, needs a human| J[STOP, report the blocker] + C -->|no| E[Proceed] D --> F[Step 3: spec-feature
SKIP its terminal handoff] E --> F F --> G[Step 4: writing-plans
SKIP its terminal handoff] - G --> H[Step 5: lock-tests
through the Phase 1.8 approval gate] - H --> I[Step 6: THE ONE SPAWN
phase-handoff lock-tests to impl] + G --> H[Step 5: lock-tests
independent reviewer replaces the approval gate] + H --> I[Step 6: THE ONE SPAWN
phase-handoff lock-tests to impl, --unattended] ``` ## Step 0 — Establish the feature worktree for this ticket @@ -62,14 +65,16 @@ You may be launched cold (spawned by `orchestrate-epic` into a throwaway worktre 2. **Read the context brief** if one was provided. For every dimension it covers (PRD, design, cross-repo impact, locked decisions, security/AC constraints), treat it as authoritative and do NOT re-fetch or re-derive it. Only research dimensions the brief leaves open. 3. **Read the ticket** itself (via `acli`/Atlassian) for its acceptance criteria and scope, unless the brief already reproduces them verbatim. -## Step 2 — Quick brainstorm (ambiguity-only) +## Step 2 — Resolve ambiguity without stopping Judge whether the acceptance criteria leave a REAL, decision-changing ambiguity (a fork where two reasonable engineers would build different things). - **No real ambiguity → skip brainstorming entirely.** State one line: "ACs are unambiguous; skipping brainstorm." Go to Step 3. -- **Real ambiguity → invoke `/devflow:brainstorming`, but scope it hard**: ask ONLY about the specific unresolved forks, cap at the minimum questions needed (prefer 1–2), and stop as soon as they are resolved. Do not run the full open-ended design loop on a ticket that is already specced. +- **Real ambiguity → resolve it without stopping.** Do NOT invoke `/devflow:brainstorming`, which is an interactive loop. Instead: state each fork explicitly, pick the option most consistent with the surrounding code and the ticket's own acceptance criteria, and record the choice plus its rationale in the spec's decision log so a reviewer can overturn it in one comment. If a fork is genuinely unresolvable from the repo (it needs a product decision, another team's answer, or access you do not have), do NOT guess: stop, report the fork, and leave the ticket unstarted. + +Never invent ambiguity to justify a detour. Never guess past a fork that needs someone else's answer. -Never invent ambiguity to justify a brainstorm. Never skip a genuine one to save time. +**The line to hold:** ambiguity that the codebase can settle, you settle. Ambiguity that only a human can settle is a blocker, not a question to ask mid-run. ## Step 3 — Spec (in this session) @@ -87,26 +92,32 @@ Invoke `/devflow:writing-plans`. Its Step 0 (re-establish worktree) is a no-op h Invoke `/devflow:lock-tests`. Its Step 0 is a no-op (already in the feature worktree). Since the spec and plan were produced in THIS session, feed it their known paths directly if it cannot find a frozen-state file (its Phase 0 documents that fallback). Run it through: -- Phase 1 (write the batch of failing tests), Phase 1.5 (verify each fails for the right reason), Phase 1.7 (Test Inventory doc), Phase 1.8 (user-approval gate). +- Phase 1 (write the batch of failing tests), Phase 1.5 (verify each fails for the right reason), Phase 1.7 (Test Inventory doc). + +**Phase 1.8's user-approval gate is replaced, not skipped.** Dispatch an independent reviewer subagent that did not write the tests, give it the ticket, the spec, the plan and the Test Inventory, and have it answer: does every acceptance criterion have a test, does every test fail for the right reason today, is any test tautological (would it pass before the change), and does anything exceed the ticket's scope. Approve on its verdict, not your own. -Do NOT proceed past Phase 1.8 without explicit approval. If the trivial-change escape hatch fires (tiny plan, no new AC), follow lock-tests' own escape path (it hands off with `--no-handoff` and tells you to run `/devflow:executing-plans` here) — that is the one case where execute also stays in-session. +**Never self-approve in the same context.** The gate's purpose is a second pair of eyes; a human was only ever one way to get that. If the reviewer returns NEEDS_WORK, fix and re-dispatch. If it returns NEEDS_WORK twice on the same point, stop and report rather than looping. + +If the trivial-change escape hatch fires (tiny plan, no new AC), follow lock-tests' own escape path (it hands off with `--no-handoff` and tells you to run `/devflow:executing-plans` here) — that is the one case where execute also stays in-session. ## Step 6 — The one spawn: hand off execute -This is the ONLY phase boundary that spawns a new session. After Phase 1.8 approval, invoke: +This is the ONLY phase boundary that spawns a new session. After the reviewer approves, invoke: ``` devflow:phase-handoff --phase lock-tests --next-phase impl ``` -Run it WITHOUT `--no-handoff`. It commits the spec/plan/test-inventory docs to the branch (durability), gates on a one-click `AskUserQuestion`, and spawns the `[] [MR#] Implementation` session whose prompt leads with `/devflow:executing-plans`. That new session does the red/green/refactor against the locked tests and finishes via `/devflow:finish-feature`. +Run it WITHOUT `--no-handoff`, and WITH `--unattended` so it does not gate on an `AskUserQuestion`. It commits the spec/plan/test-inventory docs to the branch (durability) and spawns the `[] [MR#] Implementation` session whose prompt leads with `/devflow:executing-plans`. That new session does the red/green/refactor against the locked tests and finishes via `/devflow:finish-feature`. + +If the runtime cannot spawn a session without a human click, do not wait on one: continue into `/devflow:executing-plans` in THIS session and say plainly in the final report that execute did not get a cold context. Then exit. Report: spec + plan + test-inventory produced in this session, and the implementation session spawned. ## Common Mistakes - **Letting an intermediate phase spawn a session.** Steps 3 and 4 MUST suppress their `phase-handoff` — otherwise you get the very 3-spawn fragmentation this skill exists to avoid. -- **Running a full brainstorm on a specced ticket.** Ambiguity-only means you often skip it entirely. +- **Stopping to ask when the codebase already answers it.** Decide, record the decision and its rationale, and let review overturn it. - **Re-discovering what the brief already gave you.** A provided brief is trusted input, not a starting hint. - **Speccing on the wrong branch.** Step 0 must end on `feat//...`, never the default branch. @@ -115,15 +126,17 @@ Then exit. Report: spec + plan + test-inventory produced in this session, and th | Thought | Reality | |---|---| | "I'll let spec-feature hand off normally, it's simpler" | That spawns a plan session and breaks the single-session contract. Suppress it. | -| "The ACs are clear but I'll brainstorm anyway to be safe" | A specced ticket does not need a design loop. Skip it; note that you did. | +| "The ACs are clear but I'll ask anyway to be safe" | Asking is the thing this skill exists to avoid. Decide and record it. | +| "I'll approve the test inventory myself, it looks fine" | The gate is a second pair of eyes. Dispatch the reviewer. | +| "This fork is unclear, I'll pick something and move on" | Only if the codebase settles it. If it needs a product or another team's answer, stop and report. | | "The brief mentions the PRD, let me go read the whole PRD" | Per-dimension trust: the brief IS the PRD context for this run. Do not re-fetch. | | "Let me start implementing here since I'm warm" | Execute gets its own cold session (except the trivial-escape path). Spawn at Step 6. | ## Important - `spec-feature` → `writing-plans` → `lock-tests` all run in ONE session here; only Step 6 spawns. -- Never write production code in this skill — it stops at a locked, approved test inventory (Phase 1.8), then hands off. +- Never write production code in this skill — it stops at a locked, reviewer-approved test inventory, then hands off. - Always end Step 0 on the ticket's feature branch. If worktree creation fails, STOP. -- Honor lock-tests' Phase 1.8 approval gate; it is not optional. +- The test-inventory gate is not optional, but it is satisfied by an independent reviewer rather than by a human. Never satisfy it yourself. $ARGUMENTS diff --git a/devflow-plugin/skills/phase-handoff/SKILL.md b/devflow-plugin/skills/phase-handoff/SKILL.md index 4af68d3..10ad263 100644 --- a/devflow-plugin/skills/phase-handoff/SKILL.md +++ b/devflow-plugin/skills/phase-handoff/SKILL.md @@ -1,6 +1,6 @@ --- name: phase-handoff -description: Hand off between phases of the devflow new-feature pipeline. Writes a frozen-state file, marks a chapter, sets the terminal title, gates on a one-click AskUserQuestion, then spawns a new session for the next phase via `mcp__ccd_session__spawn_task` so it shows up in the Claude Desktop sidebar with a deterministic title. +description: Hand off between phases of the devflow new-feature pipeline. Writes a frozen-state file, marks a chapter, sets the terminal title, gates on a one-click AskUserQuestion unless `--unattended` is passed, then spawns a new session for the next phase via `mcp__ccd_session__spawn_task` so it shows up in the Claude Desktop sidebar with a deterministic title. --- You are at a phase boundary in devflow's new-feature pipeline. Capture the current state to disk, **commit the phase artefacts to the feature branch so they survive worktree removal**, mark the transition in the CURRENT session, then spawn a NEW session (`mcp__ccd_session__spawn_task`) for the next phase. @@ -14,6 +14,7 @@ You are at a phase boundary in devflow's new-feature pipeline. Capture the curre - `--phase ` (required): one of `spec`, `plan`, `lock-tests` - `--next-phase ` (required): one of `plan`, `lock-tests`, `impl` - `--no-handoff` (optional): skip everything, return immediately (escape hatch) +- `--unattended` (optional): do everything, but skip the one-click gate in step 10 and spawn directly. For runs that must not block on a human. If `--no-handoff` is present, print "phase-handoff skipped" and exit. @@ -240,7 +241,7 @@ If `--no-handoff` is present, print "phase-handoff skipped" and exit. The slash command on line 1 is your first action — invoke it now. Its Step 0 re-establishes the feature worktree from the block above; the artefacts are then the only authoritative inputs. ``` -10. **One-click handoff gate (`AskUserQuestion`).** Ask the user: +10. **One-click handoff gate (`AskUserQuestion`).** Skip this entire step when `--unattended` was passed, and go straight to step 11. Otherwise ask the user: - Question: `Phase \`\` complete. Spawn a new session for the \`\` phase? Title will be: \`\`` - Header: `Handoff` diff --git a/skills/fast-feature/SKILL.md b/skills/fast-feature/SKILL.md index 947bd0f..d28149d 100644 --- a/skills/fast-feature/SKILL.md +++ b/skills/fast-feature/SKILL.md @@ -1,11 +1,13 @@ --- name: fast-feature -description: Use when driving a single already-specced ticket through devflow in one session — a quick ambiguity-only brainstorm, then spec, plan, and lock-tests back-to-back, spawning a new session only for the execute phase. Also the per-ticket driver that orchestrate-epic invokes. +description: Use when driving a single already-specced ticket through devflow in one session, unattended, resolving ambiguity from the codebase rather than by asking, then spec, plan, and lock-tests back-to-back with an independent reviewer standing in for the human gate, spawning a new session only for the execute phase. Also the per-ticket driver that orchestrate-epic invokes. --- You are a senior engineer who moves a well-defined ticket from "assigned" to "tests locked, ready to implement" in a single focused session, then hands ONLY the implementation off to a fresh session. You do not re-litigate a ticket that already has clear acceptance criteria, and you do not fragment context across a session per phase. -**Core principle:** the standard devflow pipeline spawns a new session at every phase boundary (spec → plan → lock-tests → impl = three spawns). For a ticket that is already specced, that is friction. `fast-feature` collapses `brainstorm → spec → plan → lock-tests` into ONE session and spawns exactly once — at the execute boundary — so implementation starts cold and clean while all the planning stays in one warm context. +**Core principle:** the standard devflow pipeline spawns a new session at every phase boundary (spec → plan → lock-tests → impl = three spawns). For a ticket that is already specced, that is friction. `fast-feature` collapses `resolve ambiguity → spec → plan → lock-tests` into ONE session and spawns exactly once, at the execute boundary, so implementation starts cold and clean while all the planning stays in one warm context. + +**It runs unattended.** Every human gate in the standard pipeline is replaced by an automated equivalent: ambiguity is resolved from the codebase and recorded rather than asked about, and the test-inventory approval is given by an independent reviewer subagent rather than by a person. The one thing that still stops the run is a fork only a human can settle, which is reported as a blocker instead of guessed at. ## When to Use @@ -26,13 +28,14 @@ Do NOT use for: greenfield features that genuinely need design exploration (use flowchart TD A[Step 0: establish feature worktree for the ticket] --> B[Step 1: load context
recall + trust the provided brief] B --> C{Step 2: ACs ambiguous?} - C -->|yes, real gap| D[Quick brainstorm
ONLY the ambiguous points] - C -->|no| E[Skip brainstorm] + C -->|yes, settleable from code| D[Decide and record
in the spec decision log] + C -->|yes, needs a human| J[STOP, report the blocker] + C -->|no| E[Proceed] D --> F[Step 3: spec-feature
SKIP its terminal handoff] E --> F F --> G[Step 4: writing-plans
SKIP its terminal handoff] - G --> H[Step 5: lock-tests
through the Phase 1.8 approval gate] - H --> I[Step 6: THE ONE SPAWN
phase-handoff lock-tests to impl] + G --> H[Step 5: lock-tests
independent reviewer replaces the approval gate] + H --> I[Step 6: THE ONE SPAWN
phase-handoff lock-tests to impl, --unattended] ``` ## Step 0 — Establish the feature worktree for this ticket @@ -62,14 +65,16 @@ You may be launched cold (spawned by `orchestrate-epic` into a throwaway worktre 2. **Read the context brief** if one was provided. For every dimension it covers (PRD, design, cross-repo impact, locked decisions, security/AC constraints), treat it as authoritative and do NOT re-fetch or re-derive it. Only research dimensions the brief leaves open. 3. **Read the ticket** itself (via `acli`/Atlassian) for its acceptance criteria and scope, unless the brief already reproduces them verbatim. -## Step 2 — Quick brainstorm (ambiguity-only) +## Step 2 — Resolve ambiguity without stopping Judge whether the acceptance criteria leave a REAL, decision-changing ambiguity (a fork where two reasonable engineers would build different things). - **No real ambiguity → skip brainstorming entirely.** State one line: "ACs are unambiguous; skipping brainstorm." Go to Step 3. -- **Real ambiguity → invoke `/devflow:brainstorming`, but scope it hard**: ask ONLY about the specific unresolved forks, cap at the minimum questions needed (prefer 1–2), and stop as soon as they are resolved. Do not run the full open-ended design loop on a ticket that is already specced. +- **Real ambiguity → resolve it without stopping.** Do NOT invoke `/devflow:brainstorming`, which is an interactive loop. Instead: state each fork explicitly, pick the option most consistent with the surrounding code and the ticket's own acceptance criteria, and record the choice plus its rationale in the spec's decision log so a reviewer can overturn it in one comment. If a fork is genuinely unresolvable from the repo (it needs a product decision, another team's answer, or access you do not have), do NOT guess: stop, report the fork, and leave the ticket unstarted. + +Never invent ambiguity to justify a detour. Never guess past a fork that needs someone else's answer. -Never invent ambiguity to justify a brainstorm. Never skip a genuine one to save time. +**The line to hold:** ambiguity that the codebase can settle, you settle. Ambiguity that only a human can settle is a blocker, not a question to ask mid-run. ## Step 3 — Spec (in this session) @@ -87,26 +92,32 @@ Invoke `/devflow:writing-plans`. Its Step 0 (re-establish worktree) is a no-op h Invoke `/devflow:lock-tests`. Its Step 0 is a no-op (already in the feature worktree). Since the spec and plan were produced in THIS session, feed it their known paths directly if it cannot find a frozen-state file (its Phase 0 documents that fallback). Run it through: -- Phase 1 (write the batch of failing tests), Phase 1.5 (verify each fails for the right reason), Phase 1.7 (Test Inventory doc), Phase 1.8 (user-approval gate). +- Phase 1 (write the batch of failing tests), Phase 1.5 (verify each fails for the right reason), Phase 1.7 (Test Inventory doc). + +**Phase 1.8's user-approval gate is replaced, not skipped.** Dispatch an independent reviewer subagent that did not write the tests, give it the ticket, the spec, the plan and the Test Inventory, and have it answer: does every acceptance criterion have a test, does every test fail for the right reason today, is any test tautological (would it pass before the change), and does anything exceed the ticket's scope. Approve on its verdict, not your own. -Do NOT proceed past Phase 1.8 without explicit approval. If the trivial-change escape hatch fires (tiny plan, no new AC), follow lock-tests' own escape path (it hands off with `--no-handoff` and tells you to run `/devflow:executing-plans` here) — that is the one case where execute also stays in-session. +**Never self-approve in the same context.** The gate's purpose is a second pair of eyes; a human was only ever one way to get that. If the reviewer returns NEEDS_WORK, fix and re-dispatch. If it returns NEEDS_WORK twice on the same point, stop and report rather than looping. + +If the trivial-change escape hatch fires (tiny plan, no new AC), follow lock-tests' own escape path (it hands off with `--no-handoff` and tells you to run `/devflow:executing-plans` here) — that is the one case where execute also stays in-session. ## Step 6 — The one spawn: hand off execute -This is the ONLY phase boundary that spawns a new session. After Phase 1.8 approval, invoke: +This is the ONLY phase boundary that spawns a new session. After the reviewer approves, invoke: ``` devflow:phase-handoff --phase lock-tests --next-phase impl ``` -Run it WITHOUT `--no-handoff`. It commits the spec/plan/test-inventory docs to the branch (durability), gates on a one-click `AskUserQuestion`, and spawns the `[] [MR#] Implementation` session whose prompt leads with `/devflow:executing-plans`. That new session does the red/green/refactor against the locked tests and finishes via `/devflow:finish-feature`. +Run it WITHOUT `--no-handoff`, and WITH `--unattended` so it does not gate on an `AskUserQuestion`. It commits the spec/plan/test-inventory docs to the branch (durability) and spawns the `[] [MR#] Implementation` session whose prompt leads with `/devflow:executing-plans`. That new session does the red/green/refactor against the locked tests and finishes via `/devflow:finish-feature`. + +If the runtime cannot spawn a session without a human click, do not wait on one: continue into `/devflow:executing-plans` in THIS session and say plainly in the final report that execute did not get a cold context. Then exit. Report: spec + plan + test-inventory produced in this session, and the implementation session spawned. ## Common Mistakes - **Letting an intermediate phase spawn a session.** Steps 3 and 4 MUST suppress their `phase-handoff` — otherwise you get the very 3-spawn fragmentation this skill exists to avoid. -- **Running a full brainstorm on a specced ticket.** Ambiguity-only means you often skip it entirely. +- **Stopping to ask when the codebase already answers it.** Decide, record the decision and its rationale, and let review overturn it. - **Re-discovering what the brief already gave you.** A provided brief is trusted input, not a starting hint. - **Speccing on the wrong branch.** Step 0 must end on `feat//...`, never the default branch. @@ -115,15 +126,17 @@ Then exit. Report: spec + plan + test-inventory produced in this session, and th | Thought | Reality | |---|---| | "I'll let spec-feature hand off normally, it's simpler" | That spawns a plan session and breaks the single-session contract. Suppress it. | -| "The ACs are clear but I'll brainstorm anyway to be safe" | A specced ticket does not need a design loop. Skip it; note that you did. | +| "The ACs are clear but I'll ask anyway to be safe" | Asking is the thing this skill exists to avoid. Decide and record it. | +| "I'll approve the test inventory myself, it looks fine" | The gate is a second pair of eyes. Dispatch the reviewer. | +| "This fork is unclear, I'll pick something and move on" | Only if the codebase settles it. If it needs a product or another team's answer, stop and report. | | "The brief mentions the PRD, let me go read the whole PRD" | Per-dimension trust: the brief IS the PRD context for this run. Do not re-fetch. | | "Let me start implementing here since I'm warm" | Execute gets its own cold session (except the trivial-escape path). Spawn at Step 6. | ## Important - `spec-feature` → `writing-plans` → `lock-tests` all run in ONE session here; only Step 6 spawns. -- Never write production code in this skill — it stops at a locked, approved test inventory (Phase 1.8), then hands off. +- Never write production code in this skill — it stops at a locked, reviewer-approved test inventory, then hands off. - Always end Step 0 on the ticket's feature branch. If worktree creation fails, STOP. -- Honor lock-tests' Phase 1.8 approval gate; it is not optional. +- The test-inventory gate is not optional, but it is satisfied by an independent reviewer rather than by a human. Never satisfy it yourself. $ARGUMENTS diff --git a/skills/phase-handoff/SKILL.md b/skills/phase-handoff/SKILL.md index 4af68d3..10ad263 100644 --- a/skills/phase-handoff/SKILL.md +++ b/skills/phase-handoff/SKILL.md @@ -1,6 +1,6 @@ --- name: phase-handoff -description: Hand off between phases of the devflow new-feature pipeline. Writes a frozen-state file, marks a chapter, sets the terminal title, gates on a one-click AskUserQuestion, then spawns a new session for the next phase via `mcp__ccd_session__spawn_task` so it shows up in the Claude Desktop sidebar with a deterministic title. +description: Hand off between phases of the devflow new-feature pipeline. Writes a frozen-state file, marks a chapter, sets the terminal title, gates on a one-click AskUserQuestion unless `--unattended` is passed, then spawns a new session for the next phase via `mcp__ccd_session__spawn_task` so it shows up in the Claude Desktop sidebar with a deterministic title. --- You are at a phase boundary in devflow's new-feature pipeline. Capture the current state to disk, **commit the phase artefacts to the feature branch so they survive worktree removal**, mark the transition in the CURRENT session, then spawn a NEW session (`mcp__ccd_session__spawn_task`) for the next phase. @@ -14,6 +14,7 @@ You are at a phase boundary in devflow's new-feature pipeline. Capture the curre - `--phase ` (required): one of `spec`, `plan`, `lock-tests` - `--next-phase ` (required): one of `plan`, `lock-tests`, `impl` - `--no-handoff` (optional): skip everything, return immediately (escape hatch) +- `--unattended` (optional): do everything, but skip the one-click gate in step 10 and spawn directly. For runs that must not block on a human. If `--no-handoff` is present, print "phase-handoff skipped" and exit. @@ -240,7 +241,7 @@ If `--no-handoff` is present, print "phase-handoff skipped" and exit. The slash command on line 1 is your first action — invoke it now. Its Step 0 re-establishes the feature worktree from the block above; the artefacts are then the only authoritative inputs. ``` -10. **One-click handoff gate (`AskUserQuestion`).** Ask the user: +10. **One-click handoff gate (`AskUserQuestion`).** Skip this entire step when `--unattended` was passed, and go straight to step 11. Otherwise ask the user: - Question: `Phase \`\` complete. Spawn a new session for the \`\` phase? Title will be: \`\`` - Header: `Handoff` From 1e40cf9a7610e3a3f319f844fb644a59b5a0b6aa Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 26 Aug 2026 14:37:26 +0000 Subject: [PATCH 2/2] fix(fast-feature): include unattended handoff invocation in step 6 docs Co-authored-by: AndreJorgeLopes <17115089+AndreJorgeLopes@users.noreply.github.com> --- devflow-plugin/commands/fast-feature.md | 4 ++-- devflow-plugin/skills/fast-feature/SKILL.md | 4 ++-- skills/fast-feature/SKILL.md | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/devflow-plugin/commands/fast-feature.md b/devflow-plugin/commands/fast-feature.md index 326d0b3..f56ab0d 100644 --- a/devflow-plugin/commands/fast-feature.md +++ b/devflow-plugin/commands/fast-feature.md @@ -104,14 +104,14 @@ If the trivial-change escape hatch fires (tiny plan, no new AC), follow lock-tes This is the ONLY phase boundary that spawns a new session. After the reviewer approves, invoke: ``` -devflow:phase-handoff --phase lock-tests --next-phase impl +devflow:phase-handoff --phase lock-tests --next-phase impl --unattended ``` Run it WITHOUT `--no-handoff`, and WITH `--unattended` so it does not gate on an `AskUserQuestion`. It commits the spec/plan/test-inventory docs to the branch (durability) and spawns the `[] [MR#] Implementation` session whose prompt leads with `/devflow:executing-plans`. That new session does the red/green/refactor against the locked tests and finishes via `/devflow:finish-feature`. If the runtime cannot spawn a session without a human click, do not wait on one: continue into `/devflow:executing-plans` in THIS session and say plainly in the final report that execute did not get a cold context. -Then exit. Report: spec + plan + test-inventory produced in this session, and the implementation session spawned. +Then exit. Report: spec + plan + test-inventory produced in this session, and whether execution continued in-session or the implementation session spawned. ## Common Mistakes diff --git a/devflow-plugin/skills/fast-feature/SKILL.md b/devflow-plugin/skills/fast-feature/SKILL.md index d28149d..01ccff2 100644 --- a/devflow-plugin/skills/fast-feature/SKILL.md +++ b/devflow-plugin/skills/fast-feature/SKILL.md @@ -105,14 +105,14 @@ If the trivial-change escape hatch fires (tiny plan, no new AC), follow lock-tes This is the ONLY phase boundary that spawns a new session. After the reviewer approves, invoke: ``` -devflow:phase-handoff --phase lock-tests --next-phase impl +devflow:phase-handoff --phase lock-tests --next-phase impl --unattended ``` Run it WITHOUT `--no-handoff`, and WITH `--unattended` so it does not gate on an `AskUserQuestion`. It commits the spec/plan/test-inventory docs to the branch (durability) and spawns the `[] [MR#] Implementation` session whose prompt leads with `/devflow:executing-plans`. That new session does the red/green/refactor against the locked tests and finishes via `/devflow:finish-feature`. If the runtime cannot spawn a session without a human click, do not wait on one: continue into `/devflow:executing-plans` in THIS session and say plainly in the final report that execute did not get a cold context. -Then exit. Report: spec + plan + test-inventory produced in this session, and the implementation session spawned. +Then exit. Report: spec + plan + test-inventory produced in this session, and whether execution continued in-session or the implementation session spawned. ## Common Mistakes diff --git a/skills/fast-feature/SKILL.md b/skills/fast-feature/SKILL.md index d28149d..01ccff2 100644 --- a/skills/fast-feature/SKILL.md +++ b/skills/fast-feature/SKILL.md @@ -105,14 +105,14 @@ If the trivial-change escape hatch fires (tiny plan, no new AC), follow lock-tes This is the ONLY phase boundary that spawns a new session. After the reviewer approves, invoke: ``` -devflow:phase-handoff --phase lock-tests --next-phase impl +devflow:phase-handoff --phase lock-tests --next-phase impl --unattended ``` Run it WITHOUT `--no-handoff`, and WITH `--unattended` so it does not gate on an `AskUserQuestion`. It commits the spec/plan/test-inventory docs to the branch (durability) and spawns the `[] [MR#] Implementation` session whose prompt leads with `/devflow:executing-plans`. That new session does the red/green/refactor against the locked tests and finishes via `/devflow:finish-feature`. If the runtime cannot spawn a session without a human click, do not wait on one: continue into `/devflow:executing-plans` in THIS session and say plainly in the final report that execute did not get a cold context. -Then exit. Report: spec + plan + test-inventory produced in this session, and the implementation session spawned. +Then exit. Report: spec + plan + test-inventory produced in this session, and whether execution continued in-session or the implementation session spawned. ## Common Mistakes