diff --git a/docs/flow-pack/commands/flow-brainstorm.md b/docs/flow-pack/commands/flow-brainstorm.md new file mode 100644 index 00000000..60a653ba --- /dev/null +++ b/docs/flow-pack/commands/flow-brainstorm.md @@ -0,0 +1,305 @@ +--- +description: V1 naive plan → 3-read-only-agent research → 5-dim score → V2 ship/defer list +--- + + + +# flow-brainstorm: V1 → Score → V2 + +## Objective + +Turn a baseline initiative description into a scored, human-approved V2 ship/defer list ready +for `/flow-umbrella`. Produces three outputs: + +1. **V1** — flat bullet list of 5–10 candidate items, from baseline alone, unscored, labeled "V1". +2. **V2** — approved ship list + explicit defer list + X/10 one-pass confidence score. +3. **Log entry** — full decision trail appended to `.flow/brainstorm-log.md`. + +The three read-only research subagents are the engine of this command. Claude spawns exactly 3 +(Agent A — Known Issues, Agent B — Best Practices, Agent C — Dependencies) via the Agent tool, +waits for all three, then synthesizes their findings into the score table. + +This command makes NO GitHub writes. It ends by printing the approved V2 list and the next-command +pointer. All GitHub writes (issue creation, labeling, linking) belong to E3 `/flow-umbrella`. + +**DELEGATION:** Do not re-implement codebase priming. If the baseline context needs refreshing, +run `/flow-prime` first. + +## Process + +### 1. Read baseline context + +!`ls .flow/ 2>/dev/null || echo "(no .flow/ directory yet)"` + +Determine the initiative description: +- If `$ARGUMENTS` is non-empty → use it. +- Else → read `.flow/state.md` and extract the "Gap" line from the "You are here" section. +- Else → ask the user: "What initiative should I brainstorm? Provide 1–3 sentences." + +Read `.flow/brainstorm-log.md` (if it exists) to determine the current round count. The new +round will be Round N+1 (or Round 1 if the file does not exist yet). + +!`test -f .flow/brainstorm-log.md && grep -c "^## Round" .flow/brainstorm-log.md || echo "0"` + +### 2. Produce V1 — naive plan (UNSCORED) + +Generate a flat bullet list of 5–10 candidate items **from baseline knowledge only** — no research +yet. Every item must be: + +- **Unscored** — no dimension scores; plain text only. +- **Labeled "V1"** — the section heading must read `## V1 — Naive Plan (N items, unscored)`. +- **Descriptive** — format: `- : `. + +Coverage heuristics: include obvious high-value items, known technical debt, upstreams that may +be blocked, and at least one item that is likely out of scope (to stress-test the critique gate). + +### 3. Critique gate — tag V1 items (do NOT fix them) + +For each V1 item, attach zero or more flags. Flags are labels only — do not change V1 text. + +| Flag | When to apply | +|------|---------------| +| `assumption` | Relies on a fact not verified against the codebase or docs | +| `scope-creep` | Touches E3/E4/E5 behavior or an out-of-scope system | +| `no-evidence` | No concrete codebase grounding for the stated need | + +Present as: `- [assumption, scope-creep]` or `- [none]`. + +The flags guide the research agents. An `assumption`-flagged item means "Agent A should verify +this claim." A `scope-creep` flag means "Agent B should confirm boundaries." + +### 4. Spawn 3 read-only research subagents in parallel + +Invoke the **Agent tool** to spawn all three concurrently. Each subagent is read-only — it MUST +NOT write files or make GitHub writes. Pass the V1 items + critique flags in the prompt. + +**Agent A — Known Issues** + +Prompt: +``` +You are a read-only research agent. You MUST NOT write files or make GitHub writes. + +Initiative: +V1 items (with critique flags): + +Task: Read the open GitHub issues, recent git log, and .flow/state.md. +Report: + 1. Which V1 items are blocked by or related to open issues? (cite #N) + 2. Which V1 items are partially done (recent branches/PRs touching them)? + 3. Which V1 `assumption` flags are contradicted by known incidents or bugs? + +Output: concise bullet list, #N refs where applicable. Read-only. +``` + +**Agent B — Best Practices** + +Prompt: +``` +You are a read-only research agent. You MUST NOT write files or make GitHub writes. + +Initiative: +V1 items (with critique flags): + +Task: Read CLAUDE.md, AGENTS.md, docs/flow-pack-methodology.md, and .claude/rules/. +Report: + 1. Which V1 items align with or contradict current best practices? + 2. Which V1 items are already covered by an existing skill or command? (reuse opportunity) + 3. Which V1 `scope-creep` flags are confirmed — item truly belongs to E3/E4/E5? + +Output: concise bullet list. Read-only. +``` + +**Agent C — Dependencies** + +Prompt: +``` +You are a read-only research agent. You MUST NOT write files or make GitHub writes. + +Initiative: +V1 items (with critique flags): + +Task: Read pyproject.toml, frontend/package.json, docker-compose.yml, +and docs/_base/API_CONTRACTS.md. +Report: + 1. Which V1 items have unresolved upstream dependencies or API blockers? + 2. Which V1 `no-evidence` flags are confirmed — no codebase grounding found? + 3. Any dependency pinning or version conflicts that affect V1 items? + +Output: concise bullet list. Read-only. +``` + +Wait for all three agents before proceeding. + +### 5. Score V1 items on 5 dimensions + +Use agent findings as evidence for the Evidence dimension. Score each item 1–10 per dimension: + +| Dimension | 1 = low | 10 = high | Evidence dimension note | +|-----------|---------|-----------|------------------------| +| **Value** | Cosmetic / irrelevant | Core user outcome | — | +| **Risk** | Low risk, well-understood | High risk, many unknowns | Higher Risk = lower desirability | +| **Readiness** | Many blockers open | All upstreams clear | Blocked = lower score | +| **Complexity** | Trivial | Enormous effort | Higher Complexity = lower desirability | +| **Evidence** | Pure assumption | Fully verified by agents | Directly from agent reports | + +Note: Risk and Complexity score INVERSELY — a low-risk, low-complexity item scores 9–10, not 1–2. +(A high-risk item is less desirable, so it scores lower on the Risk dimension.) + +Present the score table: + +``` +| Item | Value | Risk | Readiness | Complexity | Evidence | Total | Band | +|------|-------|------|-----------|------------|----------|-------|------| +| ... | 8 | 7 | 9 | 6 | 9 | 39 | 🟡 NEGOTIATE | +``` + +Band indicators: +- `✅ SHIP` — total ≥ 40 +- `🟡 NEGOTIATE` — total 36–39 (requires human decision before V2) +- `❌ DEFER` — total < 36 (requires explicit one-clause written reason) + +### 6. Handle negotiation zone (36–39 items) + +If any items score 36–39, **STOP and surface to human** before constructing V2: + +``` +N item(s) are in the negotiation zone (score 36–39): + + - : score 38. Rationale: . + Research note: Agent B flagged this as covered by an existing skill (reuse potential). + +Decision needed for each item — respond 'ship', 'defer', or 'defer: ': +``` + +Wait for human response for each negotiate item. Record the decision in the round log. + +If all items are SHIP or DEFER, skip this step. + +### 7. Produce V2 — ship list and defer list + +**V2 ship list** (items scoring ≥ 40, plus negotiate items the human shipped): + +``` +## V2 — Ship List + +1. (score: X/50): +2. ... +``` + +**Defer list** (items scoring < 36, plus negotiate items the human deferred): + +``` +## Defer List + +- (score: X/50): DEFER — +``` + +Every defer item MUST have an explicit reason. "DEFER — not needed now" is not acceptable. +Good example: "DEFER — overlaps the existing `analyzing-ai-repos` skill; fold into /flow-prime +if deep external analysis is needed." + +**One-pass confidence score** on the V2 ship list: + +``` +One-pass confidence: X/10 — +``` + +### 8. Append to `.flow/brainstorm-log.md` + +Update rules: +- **File absent** → create with provenance header + `# /flow-brainstorm — decision log` + first round section. +- **File exists** → count existing `## Round` headings, append `## Round (N+1) — `. +- **NEVER overwrite previous rounds.** The log is append-only. + +Provenance header (write only on creation): +``` + +# /flow-brainstorm — decision log +``` + +Round section format (exact fields — one paragraph per field, bold label): + +```markdown +## Round N — YYYY-MM-DD + +**Initiative:** +**V1 (N items, unscored):** (1) (2) ... +**Critique flags:** <"item title [flags]" for flagged items, or "none"> +**Research:** spawned 3 read-only subagents (A Known Issues, B Best Practices, C Dependencies) +**Agent findings (evidence-backed):** +- A: +- B: +- C: +**5-dim scores (Value/Risk/Readiness/Complexity/Evidence, ≥40 ship):** +- V/R/Re/C/E=total ✅ SHIP / 🟡 NEGOTIATE → / ❌ DEFER +**V2 SHIP:** , , ... **DEFER:** ; ... +**One-pass confidence:** X/10 — +**User response:** +``` + +### 9. Human approval gate + +Print V2 ship list and defer list in full. Print the one-pass confidence score. + +``` +──────────────────────────────────────────── + Approve V2 ship list? + 'approve' → write log entry + print next-command pointer + 'revise: ' → adjust scores or categorizations +──────────────────────────────────────────── +``` + +After human approves, write the log entry (Step 8) with `User response: approved`. + +### 10. Gate result and next-command + +Print using the Output Format below. + +## Output Format + +``` +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + 💡 flow-brainstorm: V1 → Score → V2 +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +📋 Baseline Context + Initiative: + Source: [.flow/state.md gap | $ARGUMENTS] + Brainstorm round: N (log entry Round N appended) + +📋 V1 — Naive Plan (N items, unscored) + 1. : [flags or none] + 2. ... + +📋 Research (3 agents — parallel) + Agent A (Known Issues): <2-line summary> + Agent B (Best Practices): <2-line summary> + Agent C (Dependencies): <2-line summary> + +📋 Scoring + | Item | V | R | Re | C | E | Total | Band | + |------|----|----|----|----|----|-------|------| + ... + +📋 V2 — Approved List + Ship (N items): , , ... + Defer (M items): ; ... + One-pass confidence: X/10 + +──────────────────────────────────────────── + ✅ V2 APPROVED → .flow/brainstorm-log.md updated (Round N) +──────────────────────────────────────────── + +→ Next: /flow-umbrella +``` + +## Arguments + +`$ARGUMENTS` — the initiative description, passed as free text +(e.g., `/flow-brainstorm add batch forecasting to the system`). +If omitted, the command falls back to `.flow/state.md` Gap line; if state.md is absent, +asks the user directly. Passed through to the gate result and the next-command pointer. diff --git a/docs/flow-pack/commands/flow-epics.md b/docs/flow-pack/commands/flow-epics.md new file mode 100644 index 00000000..94c592a5 --- /dev/null +++ b/docs/flow-pack/commands/flow-epics.md @@ -0,0 +1,264 @@ +--- +description: Create phase-ordered epic issues from an umbrella decomposition, link via REST sub-issues API, and hand off to base_prp:prp-create per epic +--- + + + +# flow-epics: Epic Decomposition + +## Objective + +Read the umbrella issue's Decomposition section, create N phase-ordered epic issues +(Foundation → Parallel → Release gate) with idempotent guards, link each as a sub-issue of +the umbrella via the GitHub REST API, and hand off to `base_prp:prp-create` per open epic. +Skips epics that already exist and/or are already linked. + +## Arguments + +`$ARGUMENTS` — umbrella issue number (e.g. `368` or `#368`). Required. +If omitted, reads the active umbrella number from the "In-progress issues" block in +`.flow/state.md` (looks for the `[umbrella,flow]`-labeled entry). + +## Process + +### 1. Parse argument + +Strip `#` prefix from `$ARGUMENTS` if present. Use the result as the umbrella issue number. + +If empty, read the umbrella number from the you-are-here snapshot: + +!`cat .flow/state.md | grep "umbrella,flow" | head -1` + +Abort with ❌ if no umbrella number can be resolved. + +### 2. Fetch umbrella + +!`gh issue view --json number,title,body,labels,milestone` + +Abort with ❌ if: +- The issue is not found. +- The `umbrella` label is absent from the labels list. + +Capture: `umbrella_title`, `body`, `labels[]`, `milestone.title`. + +### 3. Extract decomposition + +Parse the body: find lines between the `## Decomposition` heading and the next `##` heading. + +For each bullet line: +- Detect phase marker from bold text: `**Foundation**` / `**Parallel**` / `**Release gate**` +- Extract scope description (used to construct epic title + Purpose body paragraph) +- Detect any embedded `#N` ref in the line (pre-existing issue pointer — use as EXISTS hint) +- Flag as `SKIP` if the line contains `(deferred)` OR if the phase is Release gate AND the + scope mentions "not yet created" or "deferred" + +**Epic title pattern** — must match existing issues exactly for idempotent search: + +``` +feat(): flow-pack +``` + +Example from live epics: `"feat(repo): flow-pack E1 — foundation (/flow-prime + tracked contract + rule + labels/milestone)"` + +### 4. Pre-flight checks + +Verify required labels exist. Use `--paginate` — repos with >30 labels require it and `gh label list` +truncates at 30 without `--paginate`, silently missing labels created later: + +!`gh api repos/{owner}/{repo}/labels --paginate --jq '.[].name' | grep -E "^(epic|flow|feat)$" | wc -l` + +Abort with ❌ if result is not `3` (one or more labels missing — create before retrying). + +Verify milestone exists: + +!`gh api repos/{owner}/{repo}/milestones --jq '[.[].title] | contains(["flow-pack-suite"])'` + +Abort with ❌ if `false`. + +Compute epic label set: take umbrella labels → remove `"umbrella"` → add `"epic"`. For umbrella +`#368` (labels: `umbrella`, `flow`) → epic labels: `epic`, `flow`, `feat`. + +### 5. Idempotent inventory + +Fetch current sub-issues of the umbrella via GraphQL: + +!`gh api graphql -f query=' + { repository(owner:"w7-mgfcode", name:"ForecastLabAI") { + issue(number: ) { + subIssues(first: 20) { nodes { number title state } } + } + } }'` + +For each epic in the decomposition (except SKIP items): + +**a. Search for existing issue by exact title:** + +!`gh issue list --search "" --json number,title \ + --jq '.[0] | "\(.number // "none") \(.title // "")"'` + +→ Record as `EXISTS #M` / `NOT_FOUND`. Verify the returned title matches character-for-character +(GitHub search is fuzzy — reject partial matches). + +**b. Check GraphQL sub-issues list:** If `#M` appears in `subIssues.nodes` → `LINKED`. Otherwise → `UNLINKED`. + +Print inventory table before any writes: + +``` +┌──────────────────────────────────────────────────────────────────────┐ +│ Phase Title summary Exists Linked │ +│ Foundation E1 — foundation ✅ #369 ✅ linked │ +│ Parallel E2 — /flow-brainstorm ✅ #371 ❌ unlinked │ +│ Parallel E3 — /flow-umbrella ✅ #372 ❌ unlinked │ +│ Parallel E4 — /flow-epics ✅ #373 ❌ unlinked │ +│ Release gate E5 — dogfood + portability ⏭️ defer — │ +└──────────────────────────────────────────────────────────────────────┘ +``` + +### 6. Create + link loop + +For each epic where `LINKED=false` AND phase is NOT `SKIP`: + +**6a. If `NOT_FOUND` → CREATE the issue:** + +Compose body using the epic body template (§ Epic body template below). + +Echo dry-run: + +``` +┌─ DRY-RUN ───────────────────────────────────────────────────────────┐ +│ gh issue create \ │ +│ --title "" \ │ +│ --body "" \ │ +│ --label epic --label flow --label feat \ │ +│ --milestone "flow-pack-suite" │ +└─────────────────────────────────────────────────────────────────────┘ +``` + +APPROVAL GATE: "Type 'approve' to create, anything else to skip." + +If approved: execute `gh issue create`; capture the returned issue number as `M`. + +RATE-DELAY: `sleep 1` + +**6b. Link to umbrella** (whether newly created or already `EXISTS` but `UNLINKED`): + +Echo dry-run: + +``` +┌─ DRY-RUN ───────────────────────────────────────────────────────────┐ +│ gh api repos/w7-mgfcode/ForecastLabAI/issues//sub_issues \ │ +│ -X POST -F sub_issue_id= \ │ +│ --header "GitHub-Next-Preview: true" │ +└─────────────────────────────────────────────────────────────────────┘ +``` + +APPROVAL GATE: "Type 'approve' to link, anything else to skip." + +If approved: execute `gh api POST`. Confirm: + +!`gh issue view --json number,title,labels` + +RATE-DELAY: `sleep 1` + +### 7. Verify + gate + +Re-fetch sub-issues via GraphQL (same query as step 5) to confirm final state. + +Count linked epics (excluding SKIP items). Print gate result and per-epic handoff. + +## Epic body template + +Use the template matching the epic's phase. Fill `` placeholders. + +**FOUNDATION epic:** + +``` +> Sub-issue of # (umbrella: ). Foundation — blocks Epics #, #, … + +## Purpose + + + +## Sub-tasks + +_To be decomposed via `issue-to-subtasks` when this epic is picked up._ +``` + +**PARALLEL epic:** + +``` +> Sub-issue of # (umbrella: ). Parallel after Foundation (E1 #). + +## Purpose + + + +## Sub-tasks + +_To be decomposed via `issue-to-subtasks` when this epic is picked up._ +``` + +**RELEASE GATE epic:** + +``` +> Sub-issue of # (umbrella: ). Release gate — closes only after Foundation + all Parallel epics close. + +## Purpose + + + +## Sub-tasks + +_To be decomposed via `issue-to-subtasks` when this epic is picked up._ +``` + +## Output format + +``` +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + 🔗 flow-epics: Epic Decomposition +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +📋 Umbrella # + Phase structure: 1 Foundation · M Parallel · 1 Release gate (deferred) + +📋 Epic inventory + [phase] [exists] [linked] + ✅ #369 E1 Foundation exists linked + ✅ #371 E2 Parallel exists ❌ not linked + ✅ #372 E3 Parallel exists ❌ not linked + ✅ #373 E4 Parallel exists ❌ not linked + ⏭️ E5 Release gate deferred — + +📋 Dry-run: writes pending (awaiting approval) + [dry-run block per epic needing a link or create] + +📋 Actions taken (after approvals) + ✅ #371 linked under #<N> + ✅ #372 linked under #<N> + ✅ #373 linked under #<N> + ⏭️ E5 deferred — skipped + +──────────────────────────────────────────── + ✅ EPICS LINKED — 4/5 epics under #<N> (E5 deferred) +──────────────────────────────────────────── + +→ Next: base_prp:prp-create per open epic: + - /base_prp:prp-create (#371 — /flow-brainstorm) + - /base_prp:prp-create (#372 — /flow-umbrella) + (E4 #373 = this PRP, currently executing) +``` + +## Reuse-map + +| Need | Tool | +|------|------| +| Codebase + context priming | `core_piv_loop:prime` | +| Epic → 5 executable subtasks | `issue-to-subtasks` skill | +| PRP authoring per epic | `base_prp:prp-create` | +| Session continuity | `writing-session-handoffs` | +| Rules audit | `audit-rules-drift` | +| Umbrella creation | `/flow-umbrella` | diff --git a/docs/flow-pack/commands/flow-umbrella.md b/docs/flow-pack/commands/flow-umbrella.md new file mode 100644 index 00000000..8b55cc59 --- /dev/null +++ b/docs/flow-pack/commands/flow-umbrella.md @@ -0,0 +1,273 @@ +--- +description: Generate and create umbrella GitHub issue from V2 ship list +--- + +<!-- provenance: flow-pack methodology stage 2 (umbrella issue creation). + Source of truth: docs/flow-pack/commands/flow-umbrella.md (tracked). + Local install: .claude/commands/flow/flow-umbrella.md (gitignored, regenerable from this file). + Recovery: cp docs/flow-pack/commands/flow-umbrella.md .claude/commands/flow/flow-umbrella.md + Full methodology: docs/flow-pack-methodology.md (§ Stage 2 — Decompose) + Agent contract: .claude/rules/umbrella-issue.md --> + +# flow-umbrella: Umbrella Issue Creation + +## Objective + +Transform the approved V2 ship list (from `/flow-brainstorm`) into a GitHub umbrella issue with +the **7-field body contract** (`umbrella-issue.md`). The umbrella becomes the root of the GitHub +issue hierarchy that `/flow-epics` populates with child epic issues. + +**DELEGATION: approval gate required before any GitHub write.** +Steps 1–5 are read-only. Step 6 blocks on explicit human approval. No issue is created until +the user types "approve." + +## Process + +### 1. Read context + +Load the working-state files produced by `/flow-prime` and `/flow-brainstorm`: + +!`cat .flow/brainstorm-log.md` + +!`cat .flow/state.md` + +Extract: +- **Initiative title** — from `$ARGUMENTS` if provided; otherwise the initiative title from the + V2 ship list header in `.flow/brainstorm-log.md` (or the `In-progress` line in the + `FLOW-PRIME:YOU-ARE-HERE` block of `.flow/state.md`). +- **V2 ship items** — the approved set from the `/flow-brainstorm` output (`## V2 ship list` + section). +- **Defer items + reasons** — items from the defer list; each needs a written one-clause reason + for the Out-of-scope section. +- **Milestone name** — from the `FLOW-PRIME:YOU-ARE-HERE` marker block (`Active milestone:` line). +- **Type label** — first token before `(` in a conventional-commit title + (`feat(repo): …` → `feat`); default `feat` if the title is not in conventional-commit format. + +**Missing brainstorm log:** if `.flow/brainstorm-log.md` is absent or has no `## V2 ship list` +section, print: +``` +ERROR: No V2 ship list found in .flow/brainstorm-log.md. +Run /flow-brainstorm first, then re-run /flow-umbrella. +``` +and stop. + +### 2. Validate prerequisites + +Check that all required labels and the active milestone exist in the repo: + +!`gh label list --json name --jq '[.[].name] | sort | join(", ")'` + +!`gh api repos/{owner}/{repo}/milestones --jq '.[] | select(.state=="open") | .title'` + +Required labels: `umbrella`, `flow`, and the type label (e.g., `feat`). + +If any label or milestone is **missing**, print the exact remediation commands and **stop** — do +not proceed to draft until all prerequisites are satisfied: +```bash +# Create missing labels (run only the ones that are absent) +gh label create umbrella --color "0052CC" --description "Multi-week initiative scope owner" +gh label create flow --color "BFD4F2" --description "Managed by the flow: command suite" +gh label create epic --color "1D76DB" --description "Delivery surface within an umbrella" + +# Create missing milestone +gh api repos/{owner}/{repo}/milestones -X POST \ + -F title="<milestone-name>" -F state="open" +``` + +### 3. Idempotency check + +Search for an open issue with the same title before drafting: + +```bash +gh issue list --state open \ + --search "<proposed issue title>" \ + --json number,title \ + --jq '.[0] // empty' +``` + +If an open issue with the same title exists: +- Print: `Umbrella #N already exists: <url> — skipping create.` +- Jump to step 9 with the existing number `N`. + +Note: a **closed** umbrella with the same title does NOT block creation — a closed umbrella means +the initiative is complete; a new one with the same name may legitimately start. + +### 4. Draft the 7-field body + +Synthesize from the context loaded in step 1. **All 7 sections are required** — a body missing +any section is not done (invariant from `umbrella-issue.md`). Use the exact section headings +below: + +```markdown +## Summary +<One paragraph: what is wrong or missing in the current state. Cite baseline artifacts +(branch, existing files, gap). Describe the problem only — not the solution.> + +## Approach +<One paragraph: architectural delta only. No new services, no new routers, no new runtime +dependencies unless explicitly justified. State what will NOT change. Reference the +durable-source split if the command-file pattern is involved.> + +## Decomposition +<Phase taxonomy — exactly ONE Foundation (blocks all), N Parallel (run concurrently after +Foundation), exactly ONE Release gate (closes ONLY after Foundation + all Parallel). +Epics do not exist yet — use "not yet created" suffixes; never invent fake issue numbers.> + +- [ ] **E1 — Foundation** (blocks E2–EN): <one-line description> — not yet created +- [ ] **E2 — Parallel**: <one-line description> — not yet created +- [ ] **EN — Release gate** (closes after Foundation + all Parallel): <description> — not yet created + +## Out of scope (explicit) +<Items from the defer list and any scope boundary. +Every line MUST end with " — reason: <one sentence>". +A blank reason is a process failure (invariant: every defer has a reason).> + +- <item> — reason: <one sentence> + +## Success criteria +<Checkbox list. Each criterion must be independently verifiable by an outside reviewer. +Specific and measurable — not "everything works".> + +- [ ] <specific, measurable outcome> + +## Risks +| Risk | Mitigation | +|------|------------| +| <risk> | <mitigation> | + +## Tracking +- Source of truth: `docs/flow-pack-methodology.md` + working state `.flow/state.md` +- Milestone: <milestone name> +- **One-pass confidence: X/10** (<one-sentence rationale>) +``` + +### 5. Dry-run echo + +Print the **exact commands to be executed** — **do not run them yet**: + +```bash +cat > /tmp/umbrella-body.md << 'BODY_EOF' +[full 7-field body — show every line exactly as it will be submitted] +BODY_EOF + +gh issue create \ + --title "<initiative title>" \ + --body-file /tmp/umbrella-body.md \ + --label "umbrella" --label "flow" --label "<type>" \ + --milestone "<milestone-name>" +``` + +> **Why `--body-file`:** multi-line markdown bodies containing backticks, code fences, and pipe +> characters cause shell quoting failures with `--body "..."`. The `--body-file` approach is +> required for umbrella bodies (available since `gh` v1.x). + +### 6. Approval gate + +Print: +``` +──────────────────────────────────────────── +Awaiting approval. Type 'approve' to create the umbrella issue. +Any other response = abort (no write). +──────────────────────────────────────────── +``` + +Wait for user input. +- **"approve"** (case-insensitive) → proceed to step 7. +- **Anything else** → print `Aborted — no issue created.` and stop. + +### 7. Execute + +Create the umbrella issue using `--body-file` for safe multi-line body handling: + +```bash +cat > /tmp/umbrella-body.md << 'BODY_EOF' +[7-field body] +BODY_EOF + +gh issue create \ + --title "<initiative title>" \ + --body-file /tmp/umbrella-body.md \ + --label "umbrella" --label "flow" --label "<type>" \ + --milestone "<milestone-name>" +``` + +Capture the output URL. Extract issue number `N` from the URL +(e.g., `https://github.com/…/issues/42` → `N=42`). + +### 8. Confirm + +Verify labels and milestone were attached: + +```bash +gh issue view <N> --json number,title,labels,milestone \ + --jq '"#\(.number): \(.title) [\(.labels | map(.name) | join(","))] milestone=\(.milestone.title // "none")"' +``` + +If any label or milestone is missing, print the remediation commands: +```bash +gh issue edit <N> --add-label <missing-label> +gh issue edit <N> --milestone "<milestone-name>" +``` + +### 9. Gate and next-command + +Gate is ✅ **UMBRELLA CREATED** when: +- Issue number `N` returned from step 7. +- All 7 body sections present. +- Labels `umbrella`, `flow`, and the type label attached. +- Milestone attached. + +Gate is ❌ **FAILED** when: +- `gh issue create` returned non-zero, OR +- Confirm step shows missing labels or milestone (and remediation was not applied). + +Print the gate result, then the next-command pointer regardless of outcome: + +``` +→ Next: /flow-epics #<N> +``` + +## Output Format + +``` +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + 🏗️ flow-umbrella: Umbrella Issue +━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ + +📋 Context + V2 ship items: N | Defer items: M + Initiative: <title> + Milestone: <name> | Labels: umbrella ✅ flow ✅ <type> ✅ + +📋 Prerequisite check + umbrella label: [✅/❌] | flow label: [✅/❌] | <type> label: [✅/❌] + Milestone <name>: [✅/❌] | Existing umbrella: [#N / none] + +📋 Dry-run + cat > /tmp/umbrella-body.md << 'BODY_EOF' + [full 7-field body] + BODY_EOF + gh issue create --title "..." --body-file /tmp/umbrella-body.md --label ... --milestone ... + +──────────────────────────────────────────── + Awaiting approval. Type "approve" to create. +──────────────────────────────────────────── + +[After approval:] + +📋 Created + ✅ gh issue create → #N: <title> + Labels: umbrella, flow, <type> | Milestone: <name> + +──────────────────────────────────────────── + [✅/❌] UMBRELLA CREATED → #N +──────────────────────────────────────────── + +→ Next: /flow-epics #N +``` + +## Arguments + +`$ARGUMENTS` — optional initiative description. Overrides the title extracted from +`.flow/brainstorm-log.md`. Example: `/flow-umbrella integrate flow-pack as the flow: command suite`. +If omitted, the initiative title is derived from the V2 ship list header in the brainstorm log.