Skip to main content

flow-next-refine

Refine a spec or task before building: deep Q&A (business, technical, both) or a read-only research pass over external docs. Use to refine or interrogate requirements or read up on a new library.

Aller à l'installation

Informations de source

Dépôt
gmickel/flow-next
Dernière activité de la source
14 septembre 2026 à 17:40
Langue détectée de SKILL.md
anglais
Étoiles
699
Forks
55

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Explorateur de fichiers
12 fichiers

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
flow-next-refine
description
Refine a spec or task before building: deep Q&A (business, technical, both) or a read-only research pass over external docs. Use to refine or interrogate requirements or read up on a new library.
# Flow refine Refine a task/spec: conduct an extremely thorough interview and write the refined details back, or (`--scope=research`) resolve the spec's external-library unknowns from official docs and write them back. The `interview` name remains a forwarding alias for one release. **`.flow/` is the only task tracker.** A run that recorded task state in a markdown TODO, a plan file, TodoWrite, or any other tracker has broken this — all task state is read and written via `flowctl`. ### Chart boundary Existing-spec clarification stays **primary**. Interview refines a valid spec with unresolved judgment questions. Do **not** reopen discovery as `/flow-next:chart` unless the answers reveal that the **effort itself is not yet specifiable** - only then route backward to chart. Clear work that never needed a chart stays out of chart. Unsure of the hop: `$flow-next-flow --explain`. ## Preamble **CRITICAL: flowctl is BUNDLED — NOT installed globally.** `which flowctl` will fail (expected). Define once; subsequent blocks use `$FLOWCTL`: ```bash FLOWCTL="${CODEX_HOME:-$HOME/.codex}/scripts/flowctl" [ -x "$FLOWCTL" ] || FLOWCTL="<plugin-root>/scripts/flowctl" # <plugin-root> = the directory two levels above this skill's SKILL.md file (the harness gave you that file's absolute path when the skill loaded); substitute it literally [ -x "$FLOWCTL" ] || FLOWCTL=".flow/bin/flowctl" ``` **Role**: technical interviewer, spec refiner **Goal**: extract complete implementation details through deep questioning (40+ questions typical) ## Input Full request: $ARGUMENTS Accepts a Flow spec ID, a Flow task ID, a resolvable tracker handle, a file path, or nothing — recognition rules and the fetch command per type are in "Detect Input Type" below (single copy; the write-back command per type is in `references/write-back.md`). Examples: - `/flow-next:refine fn-1-add-oauth` - `/flow-next:refine fn-1-add-oauth.3` - `/flow-next:refine fn-1` (legacy formats fn-1, fn-1-xxx still supported) - `/flow-next:refine docs/oauth-spec.md` - `/flow-next:refine fn-1-add-oauth --scope=research` (external-docs pass; no questions) If empty, ask: "What should I interview you about? Give me a Flow ID (e.g., fn-1-add-oauth) or file path (e.g., docs/spec.md)" ## Setup ### Parse `--scope=business|technical|both|research` Token-safe parsing for `--scope` / `--biz` / `--tech` lives in `flowctl scope resolve` — never re-implement inline. The subcommand strips scope tokens, preserves every other token in order (Flow IDs, paths, `--docs`, `--strategy`, ...), and emits the resolved scope plus a `defaulted` flag. The resolver's fallback when no scope flag is passed is `technical` (1.0.2 backward-compat) — but the skill does NOT silently run it: when `defaulted == true`, ask the user which pass to run after Detect Input Type (see "Scope selection when no flag passed" below). `technical` applies only when that question cannot be asked. ```bash # Run BEFORE the --docs / --strategy strip block. Conflict / invalid value # → non-zero exit; SKILL propagates. # # `--raw "$ARGUMENTS"` tokenizes via shlex INSIDE flowctl — preserves quoted # paths with spaces (e.g., `/flow-next:refine --biz "docs/my spec.md"`). # Unquoted `$ARGUMENTS` would word-split into broken tokens. RESOLVED_JSON=$("$FLOWCTL" scope resolve --json --raw "$ARGUMENTS") SCOPE=$(printf '%s' "$RESOLVED_JSON" | jq -r '.scope') # true when no scope flag was passed — gates the "Scope selection when no # flag passed" question below (older flowctl without the field → false, # preserving the silent technical default). SCOPE_DEFAULTED=$(printf '%s' "$RESOLVED_JSON" | jq -r '.defaulted // false') # `remaining_args` is a JSON array of strings. Re-join with single spaces # for downstream consumption; downstream code MUST re-tokenize via the # same safe path (shlex) if it might re-encounter quoted paths. ARGUMENTS=$(printf '%s' "$RESOLVED_JSON" | jq -r '.remaining_args | join(" ")') ``` **Scope parsing, write policy, and bank selection come from `flowctl scope resolve` / `scope write-policy` / `scope bank`.** A skill that re-implements the tokenizer, the section-ownership rules, or the bank mapping inline has broken this — the two copies drift and the inline one wins silently. **`SCOPE == research` asks no questions.** Skip the doc-aware autodetect, the scope question, the question banks, and the interview rounds: run Detect Input Type below, then read [`references/research-scope.md`](references/research-scope.md) and follow it. A business, technical, or both invocation never reads it. ### Parse `--docs` / `--no-docs` / `--strategy` / `--no-strategy` flags The four doc-aware override flags must be stripped from `$ARGUMENTS` before input-type detection so they don't get confused for a Flow ID or path. Two force variables carry the result — `""` = autodetect, `"on"` = forced on, `"off"` = forced off: ```bash RAW_ARGS="$ARGUMENTS" DOC_AWARE_FORCE="" # controls glossary + decisions STRATEGY_AWARE_FORCE="" # controls strategy independently ``` **When the invocation carried ANY of `--docs` / `--no-docs` / `--strategy` / `--no-strategy`**, STOP and read [`references/doc-aware.md`](references/doc-aware.md) § Flag parsing before proceeding — it holds the strip block (both pairs mutually exclusive, negation wins on conflict), the cascade rules, the flag matrix that is the contract for each combination, and the scope × doc/strategy interaction table. A bare invocation skips it: no flag token is present, so `RAW_ARGS` is `$ARGUMENTS` unchanged (whitespace-normalized) and both force variables stay empty (autodetect). ### Doc-aware autodetect Decide whether doc-aware mode activates. `DOC_AWARE` controls glossary + decisions; `STRATEGY_AWARE` controls the strategy-conflict behavior independently. Each has three paths (forced-on / forced-off / autodetect) per the flag matrix. The default-autodetect rule is: doc-aware mode activates when **any** of three conditions has signal — `glossary.total_terms > 0` (a) OR a decision entry exists (b) OR `strategy.sections_filled >= 1` (c). The two flag pairs override (a)+(b) and (c) independently. Counting populated entries (rather than `[[ -f <file> ]]`) is deliberate — see [`references/doc-aware.md`](references/doc-aware.md) § Why counts, not file presence. ```bash # DOC_AWARE: glossary + decisions. Probes and parses fail OPEN (|| DOC_AWARE=1). DOC_AWARE=0 if [[ "$DOC_AWARE_FORCE" == "on" ]]; then DOC_AWARE=1 elif [[ "$DOC_AWARE_FORCE" == "off" ]]; then DOC_AWARE=0 else # NO pipelines in the probe — capture raw first, rc-checked; parse separately. GLOSSARY_RAW="$("$FLOWCTL" glossary list --json 2>/dev/null)" || DOC_AWARE=1 DECISIONS_RAW="$("$FLOWCTL" memory list --track knowledge --category decisions --json 2>/dev/null)" || DOC_AWARE=1 if [ "$DOC_AWARE" = "0" ]; then TERMS="$(printf '%s' "$GLOSSARY_RAW" | jq -r '.total_terms // 0' 2>/dev/null)" || DOC_AWARE=1 DECS="$(printf '%s' "$DECISIONS_RAW" | jq -r '.entries | length // 0' 2>/dev/null)" || DOC_AWARE=1 fi if [ "$DOC_AWARE" = "0" ] && { [ "${TERMS:-0}" -gt 0 ] || [ "${DECS:-0}" -gt 0 ]; }; then DOC_AWARE=1 fi fi # STRATEGY_AWARE: strategy (independent of DOC_AWARE — autodetects on its own signal) STRATEGY_AWARE=0 if [[ "$STRATEGY_AWARE_FORCE" == "on" ]]; then STRATEGY_AWARE=1 elif [[ "$STRATEGY_AWARE_FORCE" == "off" ]]; then STRATEGY_AWARE=0 else STRATEGY_RAW="$("$FLOWCTL" strategy status --json 2>/dev/null)" || STRATEGY_AWARE=1 if [ "$STRATEGY_AWARE" = "0" ]; then STRAT_FILLED="$(printf '%s' "$STRATEGY_RAW" | jq -r '.sections_filled // 0' 2>/dev/null)" || STRATEGY_AWARE=1 fi if [ "$STRATEGY_AWARE" = "0" ] && [ "${STRAT_FILLED:-0}" -ge 1 ]; then STRATEGY_AWARE=1 fi fi if [ "$DOC_AWARE" = "1" ] || [ "$STRATEGY_AWARE" = "1" ]; then echo "DOC-AWARE GATE ACTIVE — STOP. Read references/doc-aware.md before drafting the first question." fi ``` When the sentinel prints, STOP and **read [`references/doc-aware.md`](references/doc-aware.md)** before any further step, then apply its behaviors — Phase-zero glossary scan (a), fuzzy-term sharpening (b), code-versus-assertion contradiction (c), decision-record write (d), and code-vs-strategy contradiction (e). On the default no-docs path (`DOC_AWARE=0` and `STRATEGY_AWARE=0`) the interview proceeds exactly as today — do not read the file. ## Detect Input Type **Handle-recognition rule (R16):** do NOT gate on a hard "must start with `fn-`" check. Before treating a single-token arg as a file path or freeform, route it through `$FLOWCTL show <arg> --json` — flowctl's widened resolver maps a tracker key (`wor-17` / `wor-17.M`) to its linked spec/task, so a resolvable handle is the existing spec/task, never a new idea. Patterns 1-2 below are the common case; pattern 3 generalizes them to any resolvable handle. 1. **Flow spec ID pattern**: matches `fn-\d+(-[a-z0-9-]+)?` (e.g., fn-1-add-oauth, fn-12, fn-2-fix-login-bug) - Fetch: `$FLOWCTL show <id> --json` - Read spec: `$FLOWCTL cat <id>` 2. **Flow task ID pattern**: matches `fn-\d+(-[a-z0-9-]+)?\.\d+` (e.g., fn-1-add-oauth.3, fn-12.5) - Fetch: `$FLOWCTL show <id> --json` - Read spec: `$FLOWCTL cat <id>` - Also get parent spec context: `$FLOWCTL cat <spec-id>` 3. **Resolvable tracker handle**: any single-token arg (not an `.md` path) that `$FLOWCTL show <arg> --json` resolves — e.g. a Linear key `wor-17` (spec) or `wor-17.3` (task). Use the canonical id from the JSON; a `.`-containing handle is a task (fetch parent spec too), otherwise a spec. Treat exactly like patterns 1-2; never re-create. 4. **File path**: a path-like token / `.md` extension that does NOT resolve via `flowctl show` - Read file contents - If file doesn't exist, ask user to provide valid path Done when: the argument is classified as exactly one of the four patterns, every non-`.md` single-token arg was routed through `$FLOWCTL show <arg> --json` before that classification, and the target's content (spec body, task + parent spec, or file) is in hand for the scope recommendation below. ## Scope selection when no flag passed Fires ONLY when `SCOPE_DEFAULTED=true` (no `--scope` / `--biz` / `--tech` in the invocation). An explicit scope flag always wins and skips this section entirely. Runs AFTER Detect Input Type — the spec/file content is in hand, so the recommendation is informed. Ask ONE `plain-text numbered prompt` (same blocking primitive as every interview question; the tool-unreachable fallback under "Question Format" applies): - **header**: `Interview scope` - **body**: `Which interview pass should run? business = product framing (goal, users, boundaries, outcome AC — never decides architecture, stack, or APIs); technical = implementation details (architecture, API contracts, edge cases); both = business first, then technical. Recommended: <X> — <one-sentence rationale from the target's current state>. Confidence: [judgment-call].` - **options** (frozen): `business`, `technical`, `both` Derive the recommendation from the target's current state: - Biz sections empty AND tech sections empty (new idea, fresh spec, bare file) → recommend `both` — ground the product framing before any technical decision. - Biz sections populated, tech sections empty or placeholder-only → recommend `technical` — the business layer exists; fill the technical layer. - Tech sections populated, biz sections absent (1.0.2-shape solo spec) → recommend `technical` — refine in place. Set `SCOPE` to the answer and proceed exactly as if the flag had been passed — write-policy, question bank, and pass behavior all follow the chosen scope. If the question genuinely cannot be asked (tool unreachable and no plain-text answer), fall back to `technical` and say so in the interview opener. Why this exists: a PM invoking `/flow-next:refine <spec-id>` bare used to get a silent technical interrogation — stack/API questions they don't own, with skipped answers at risk of becoming rails-derived defaults. The scope question makes the business pass discoverable at the exact moment it matters. ## Interview Process **CRITICAL REQUIREMENT**: For every question, you MUST ask via the plain-text numbered prompt described below. **Ask the user via plain text.** Render the options below as a numbered list `1.` … `N.`, followed by a final option `N+1. Other — type your own answer`. Print the question, then the numbered list, then **stop and wait for the user's next message before continuing**. Parse the reply as: a bare number `1`–`N+1` → that option; the literal text of an option label → that option; free text after `Other` → custom answer. - ONLY ask via the plain-text numbered prompt - Ask in rounds: each round carries the whole frontier (see Question Order below), split across plain-text numbered prompt calls of up to 4 questions each - Expect 40+ questions total for complex specs ### Question Format: Lead with Recommendation Every `plain-text numbered prompt` body must include the agent's recommended option AND a confidence tier. Mirrors the canonical phrasing in `flow-next-audit/SKILL.md:64` ("Lead with the recommended option and a one-sentence rationale"). Pattern: - `question.body`: "<stakes>. <options summary>. Recommended: <X> — <one-sentence rationale>. Confidence: [high | judgment-call | your-call]." - `question.options`: neutral labels (no "(recommended)" markers — recommendation goes in the body; neutral options reduce anchoring) ### Plain-language question contract (field feedback, eval-validated) Applies to EVERY question, both scopes. The interviewee must be able to read a question once and answer it confidently without asking what it means — field feedback showed jargon-dense questions disempower exactly the people the interview exists to hear (baseline legibility scored 4/10 for a second-language PM; this contract scores 7.5+ at ~30% fewer tokens). - **Open the body with ONE sentence of stakes**: what this question decides, in the audience's words. - **Write for the audience in everyday words**; prefer the common word over the term of art. A term of art you genuinely need gets a plain-word gloss in ≤1 clause at first use (e.g. "counter-metrics — things we'd hate to make worse"). - **No unexplained acronyms or tool/repo shorthand.** In business scope, no implementation vocabulary (no schemas, endpoints, config keys). - **Every option description states its consequence in plain words**: "Choose this if…" / "This means…". - **Gloss referenced acceptance criteria.** When a question cites a spec R-ID, attach a short plain-words gist at first mention — "R3 (the audit line's required fields)" — never a bare "R3" the interviewee must open the spec to decode. Gist, not quote: pasting full criterion text bloats the question body. Required content and trim order (priorities — NOT a length cap; never trade required content for brevity): - **ALWAYS keep, in this order:** the stakes sentence; the recommendation + its one-sentence rationale; the confidence tier; the gloss for any term of art used; each option's consequence. - **TRIM FIRST, until the question reads in one pass:** repetition between body and options, secondary background, hedging, restated option lists.
Voir sur GitHub
Ce SKILL.md est tres volumineux, SkillsMP affiche donc ici seulement la premiere section. Voir sur GitHub