From flow-next
Creates and maintains STRATEGY.md at the repo root, capturing target problem, approach, audience, metrics, and work tracks. For new products, direction updates, or planning prompts.
How this skill is triggered — by the user, by Claude, or both
Slash command
/flow-next:flow-next-strategyThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
`flow-next-strategy` produces and maintains `STRATEGY.md` — a short, durable anchor at the repo root (peer of `README.md` / `GLOSSARY.md`) that captures what the product is, who it serves, how it succeeds, and where the team is investing. Downstream skills (`/flow-next:prospect`, `/flow-next:plan`, `/flow-next:interview`, `/flow-next:capture`, `/flow-next:sync`) read it as grounding when `secti...
flow-next-strategy produces and maintains STRATEGY.md — a short, durable anchor at the repo root (peer of README.md / GLOSSARY.md) that captures what the product is, who it serves, how it succeeds, and where the team is investing. Downstream skills (/flow-next:prospect, /flow-next:plan, /flow-next:interview, /flow-next:capture, /flow-next:sync) read it as grounding when sections_filled >= 1.
The document is short and structured on purpose. Good answers to a handful of sharp questions produce a better strategy than any amount of prose. This skill asks those questions, pushes back on weak answers, and writes the doc.
Note: The current year is 2026. Use this when dating the strategy document.
flowctl is bundled — NOT installed globally. which flowctl will fail (expected). Define once; subsequent blocks use $FLOWCTL:
FLOWCTL="${DROID_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}/scripts/flowctl"
[ -x "$FLOWCTL" ] || FLOWCTL=".flow/bin/flowctl"
Default to AskUserQuestion (call ToolSearch with select:AskUserQuestion first if its schema isn't loaded). Fall back to numbered options in chat only when the tool is unreachable in the harness or the call errors — never silently skip the question. (sync-codex.sh rewrites this to a plain-text numbered prompt in the Codex mirror.)
Ask one question at a time. Free-form responses for the substantive sections (Target problem / Our approach / Who it's for / Key metrics / Tracks). Single-select with lead-with-recommendation only for routing decisions (which section to revisit, include this optional section, foreign-file resolution).
<focus_hint> #$ARGUMENTS </focus_hint>
Interpret any argument as an optional focus: a section name to revisit (metrics, approach, tracks, problem, persona, milestones, not-working-on) or a scope hint. With no argument, proceed open-ended and let the file state decide the path.
/flow-next:prospect; tasks belong in specs and /flow-next:plan. Do not let either creep into the doc.references/interview.md)..flow/ wipe. STRATEGY.md lives at repo root, never under .flow/. The project's strategy belongs to the project, not flow-next (R18 invariant from the 0.39.0 glossary epic).Compare .flow/meta.json setup_version to the plugin version; on mismatch, escalate once per plugin version. Fail-open throughout: a missing jq, .flow/meta.json, or plugin manifest silently continues.
SETUP_VER=$(jq -r '.setup_version // empty' .flow/meta.json 2>/dev/null)
PLUGIN_JSON="${DROID_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}/.claude-plugin/plugin.json"
PLUGIN_VER=$(jq -r '.version' "$PLUGIN_JSON" 2>/dev/null || echo "unknown")
VERSION_ACK=$(jq -r '.version_ack // empty' .flow/meta.json 2>/dev/null)
if [[ -n "$SETUP_VER" && "$PLUGIN_VER" != "unknown" && "$SETUP_VER" != "$PLUGIN_VER" ]]; then
if [[ "${FLOW_RALPH:-}" == "1" || -n "${REVIEW_RECEIPT_PATH:-}" \
|| "${FLOW_AUTONOMOUS:-}" == "1" || "${ARGUMENTS:-}" == *mode:autonomous* \
|| "$VERSION_ACK" == "$PLUGIN_VER" ]]; then
echo "Local setup v${SETUP_VER} differs from plugin v${PLUGIN_VER}. Run /flow-next:setup to refresh local scripts." >&2
else
echo "FLOW_SETUP_ASK ${SETUP_VER} ${PLUGIN_VER}"
fi
fi
If the block printed a FLOW_SETUP_ASK line, before proceeding ask the user with AskUserQuestion (local setup differs from the plugin; refresh now?), offering exactly the options Refresh now, Remind me next version, Skip this run, then continue the skill whichever is chosen:
/flow-next:setup in this session (do not run setup yourself), then continue once it finishes.PJ="${DROID_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}/.claude-plugin/plugin.json"
PV=$(jq -r '.version' "$PJ" 2>/dev/null)
[[ -n "$PV" && "$PV" != "null" ]] && rm -f .flow/meta.json.tmp && jq --arg v "$PV" '.version_ack = $v' .flow/meta.json > .flow/meta.json.tmp && mv .flow/meta.json.tmp .flow/meta.json
Any other output (the one-line differs notice, or nothing) is non-blocking: continue.
0.1 — Ralph block (R17)
/flow-next:strategy is exploratory and human-in-the-loop. Autonomous loops have no business deciding repo strategy. Hard-error with exit 2 when running under Ralph.
if [[ -n "${REVIEW_RECEIPT_PATH:-}" || "${FLOW_RALPH:-}" == "1" ]]; then
echo "[STRATEGY: user-triggered only — Ralph cannot run /flow-next:strategy]" >&2
exit 2
fi
No env-var opt-in. Ralph never decides direction.
0.2 — Read file state
STATUS_JSON=$("$FLOWCTL" strategy status --json)
EXISTS=$(printf '%s' "$STATUS_JSON" | jq -r '.exists')
HUSK=$(printf '%s' "$STATUS_JSON" | jq -r '.husk')
SECTIONS_FILLED=$(printf '%s' "$STATUS_JSON" | jq -r '.sections_filled')
GENERATOR_MATCH=$(printf '%s' "$STATUS_JSON" | jq -r '.generator_match')
FILE_PATH=$(printf '%s' "$STATUS_JSON" | jq -r '.file_path // empty')
JSON fields (frozen by Task 1):
exists (bool) — file presenthusk (bool) — exists: true AND sections_filled == 0sections_filled (int) — populated required-section count (0-5)total_sections (int) — always 5 (the 5 required)last_updated (str|null) — ISO date from frontmatterfile_path (str|null) — absolute path of resolved STRATEGY.mdgenerator (str|null) — frontmatter generator valuegenerator_match (bool) — generator == "flow-next-strategy"0.3 — Subdirectory walk-up surfacing (R16)
If file_path is set and differs from ${PWD}/STRATEGY.md, surface one line in chat before any question fires:
Using repo-root STRATEGY.md at <file_path>.
This is the only line printed before routing — keep the noise floor low.
0.4 — Foreign-file resolution (R15)
If exists: true AND generator_match: false, do not write. Fire AskUserQuestion:
body: "Found a STRATEGY.md at <file_path> not generated by flow-next-strategy (generator: <generator or "missing">). Recommended: keep — do not overwrite a hand-written or external-tool strategy doc. Confidence: [your-call] — your project, your call."options:
keep → exit 0 with one-line stdout: Keeping existing STRATEGY.md unchanged.migrate → exit 0 with stderr: Multi-format migration deferred to v2. Either delete or rename the file, then re-run /flow-next:strategy to bootstrap from scratch.rewrite → second confirmation AskUserQuestion:
body: "Confirm destructive overwrite? The existing file at <file_path> will be replaced. Recommended: cancel. Confidence: [your-call]."options: confirm-overwrite → proceed to Phase 1 first-run interview; cancel → exit 0.Single-select AskUserQuestion, lead-with-recommendation, neutral option labels.
0.5 — Routing
After Ralph block, walk-up surfacing, and foreign-file resolution:
| State | Route |
|---|---|
exists: false | Phase 1 (first-run interview) |
exists: true AND husk: true AND generator_match: true | Phase 1 (first-run; husk was probably an aborted run) |
exists: true AND husk: false AND generator_match: true | Phase 2 (section-revisit update) |
Announce path in one line: Strategy doc not found — let's write it. or Found existing strategy — let's review and update.
1.1 — Load interview rules (non-optional)
Read `references/interview.md`.
This load is non-optional. The pushback rules, anti-pattern examples, and quality bar for each section live there. Improvising from memory produces a passive transcription instead of a strategy doc.
1.2 — Run the interview in section order
For each of the 5 required sections (in order: Target problem → Our approach → Who it's for → Key metrics → Tracks), follow the per-section rule in references/interview.md:
vanity, fluff, feature-list, etc.) are internal-only — never appear in question bodies.<!-- worth revisiting --> to the section body. Do not let the interview spiral.1.3 — Per-section atomic writes
After each section is captured, build the partial draft and write to STRATEGY.md via Write tool before the next question fires. last_updated bumps on every save. No draft state file. Mid-flow abandonment leaves a partially-populated file readable on disk; resume is via Phase 0 → Phase 2 routing.
The partial-draft shape: frontmatter + H1 + the captured section(s) + placeholder bodies (_Not yet captured._) for unfilled required sections. Optional sections are absent until Phase 1.4.
1.4 — Optional sections (gated by routing question)
After all 5 required sections land, ask once per optional section whether to include it. Routing question with lead-with-recommendation:
For Milestones:
body: "Do you want a Milestones section? It's only worth adding if there are externally visible dated anchors — launches, fundraises, conferences, renewals. Recommended: skip — internal schedules don't belong here. Confidence: [your-call]."options: include, skip.For Not working on:
body: "Do you want a Not working on section? Only useful for things the team keeps being tempted by — a clarity tool, not a backlog. Recommended: skip — most repos don't need it. Confidence: [your-call]."options: include, skip.A Marketing section is deliberately not offered — over-rotated for OSS-tools repos.
If include, run the per-section interview from references/interview.md (same 2-round-cap rule), then atomic-write that section. If skip, omit the section entirely from the file (do not leave an empty header).
1.5 — Mandatory read-back before final commit
After all sections captured (required + any included optional), run:
"$FLOWCTL" strategy read --json
Show the final draft body in chat. Offer one round of edits via AskUserQuestion:
body: "Draft complete. -section strategy doc, <last_updated>. Recommended: commit — the draft reflects the captured answers verbatim. Confidence: [judgment-call]."options: commit, edit-section, abandon.On edit-section, ask which section via single-select (5 required + included optional names), re-run the per-section interview, atomic-write, return to read-back.
On commit, the file is already on disk (per-section atomic writes) — this is a confirmation step, not a new write. Acknowledge with one stdout line: Strategy doc written to <file_path>. last_updated: <date>.
On abandon, leave the file as-is (partially populated is fine), exit 0.
2.1 — Summarize current state
Read the existing STRATEGY.md via flowctl strategy read --json and summarize current state in 3-5 lines so the user sees what's on file. Surface section names + 1-line excerpts.
If the focus-hint argument names a specific section, jump to that section. Otherwise, run the evidence scan (2.1b) then fire the routing question.
2.1b — Evidence scan (ground drift against the repo, not vibes)
The revisit routing otherwise ranks sections by <!-- worth revisiting --> markers + "looks weak" — pure vibes. But real drift is measurable: which declared tracks are actually shipping, and whether recent work maps to the stated direction. A maintenance run's job is to surface drift the user didn't notice — not just ask "which section feels stale?". (Ironic asymmetry otherwise: /flow-next:prospect does full repo grounding to generate ideas against this doc, while the doc itself is validated by feel.) Scan before asking:
LAST_UPDATED="$(flowctl strategy read --json 2>/dev/null | jq -r '.last_updated // ""')"
RECENT_SPECS="$(flowctl specs --json 2>/dev/null | jq -r '.specs[]? | "\(.id)\t\(.status)\t\(.title // "")"' 2>/dev/null)"
With the current ## Tracks (from 2.1), the ## Not working on list, and RECENT_SPECS, the host agent JUDGES the mapping (spec subject → track name — the same host-agent judgment prospect uses to ground candidates, NOT a keyword scorer) and surfaces drift signals:
last_updated: "Track X has had 0 specs since the strategy was last updated (<last_updated>)."## Not working on item: "Spec looks like work listed under Not working on."No specs / empty repo → skip silently (nothing to ground against). Feed the findings into 2.2.
2.2 — Section-revisit routing question (lead-with-recommendation)
Build the option list dynamically:
<!-- worth revisiting --> markers (priority candidates).Tracks section; a contradicted boundary → Not working on) — these are data-grounded priorities; list them at the top and cite the specific finding in the question body so the user revisits what the repo shows drifting, not only what feels stale.AskUserQuestion:
body: "Which section to revisit? . Recommended: <top priority section> — it carries a <!-- worth revisiting --> marker from a previous run [if applicable]. Confidence: [judgment-call] — your judgment on what feels stale."options: section names + done (no further changes).2.3 — Per-section re-interview
For the chosen section, re-run the per-section interview from references/interview.md — full pushback, NOT a rubber-stamp. After capture, atomic-write that section's new body. Untouched sections preserved byte-identical (verified by git diff --unified=0 if questioned). last_updated bumps to today's ISO date.
2.4 — Loop or exit
After a section is updated, return to the routing question — user can revisit another section or pick done. On done, run the read-back step (Phase 1.5 logic) once for confirmation, then exit.
After writing (first-run or update), surface the file's role to the user in one paragraph:
.flow/specs/ is empty (and any legacy .flow/epics/ is also empty) AND .flow/prospects/ is empty: Strategy doc written. Next, /flow-next:prospect [optional focus] generates ranked candidate ideas grounded in the strategy you just captured..flow/ is populated: Strategy doc written. Downstream skills (/flow-next:prospect, /flow-next:plan, /flow-next:interview, /flow-next:capture, /flow-next:sync) will read STRATEGY.md as grounding on next invocation.One paragraph max. No follow-up questions.
/flow-next:plan./flow-next:capture and /flow-next:plan.# <name> Strategy H1 + frontmatter) on disk — file never deleted (R23 invariant, mirrors render_glossary_file).context: fork — AskUserQuestion must stay reachable across phases.vanity / fluff / feature-list / goal-stated-as-problem are internal labels for formulating sharper follow-ups.references/strategy-template.md catches this.Marketing section is dropped on purpose; do not re-introduce it. Section order is locked.flowctl strategy {status,read,list} only. Skill writes the file directly via Write tool; no flowctl strategy add exists.The deliverable is the written STRATEGY.md itself. Surface to chat:
No internal summary printed at exit beyond the Phase 3 handoff line. The file IS the report.
npx claudepluginhub gmickel/flow-next --plugin flow-nextCreates or updates STRATEGY.md, a short durable anchor document capturing product strategy. Use when starting a product, changing direction, or grounding downstream planning skills.
Runs an interview to write or update a root-level STRATEGY.md, enforcing pushback rules against fluff, goals-as-strategy, and feature-lists. Validates existing strategy files and offers repair paths.
Interviews the user to define product strategy and writes a durable STRATEGY.md at the operating repo root. Pushes back on vague answers and activates on trigger phrases like 'what's our north star'.