/flow-next-sync
Manually trigger plan-sync to update downstream task specs after implementation drift. Use when code changes outpace specs.
$ npx -y skills add gmickel/flow-next --skill flow-next-sync --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.
- You can call itInvoke it directly when you want it.
- Slash command
/flow-next-sync
Context preview
The summary Claude sees to decide when to auto-load this skill.
Manually trigger plan-sync to update downstream task specs after implementation drift. Use when code changes outpace specs.
SKILL.md
flow-next-sync.SKILL.mdname: flow-next-sync
description: Manually trigger plan-sync to update downstream task specs after implementation drift. Use when code changes outpace specs.
user-invocable: false
Manual Plan-Sync
Manually trigger plan-sync to update downstream task specs.
Preamble
**CRITICAL: flowctl is BUNDLED - NOT installed globally.** Define once; subsequent blocks use `$FLOWCTL`:
FLOWCTL="${DROID_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}/scripts/flowctl"
[ -x "$FLOWCTL" ] || FLOWCTL=".flow/bin/flowctl"Input
Arguments: $ARGUMENTS Format: `<id> [--dry-run]`
- `<id>` - task ID `fn-N-slug.M` (or legacy `fn-N.M`, `fn-N-xxx.M`) or spec ID `fn-N-slug` (or legacy `fn-N`, `fn-N-xxx`), **or a resolvable tracker handle** (`wor-17` / `wor-17.M`) that `flowctl show` maps to the linked spec/task (fn-52.10, R16)
- `--dry-run` - show changes without writing
Workflow
Step 1: Parse Arguments
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
Parse $ARGUMENTS for:
- First positional arg = `ID`
- `--dry-run` flag = `DRY_RUN` (true/false)
**Validate ID first (handle-recognition rule, R16):**
- Do NOT gate on a hard "must start with `fn-`" check. Route the arg through `$FLOWCTL show <ID> --json` (Step 3) — flowctl's widened resolver (fn-52.10) 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 id. So `/flow-next:sync wor-17` resolves the linked spec.
- If no ID provided: "Usage: /flow-next:sync <id> [--dry-run]"
- If the arg does NOT resolve via `flowctl show` (Step 3): "Unknown ID. Use fn-N-slug (spec) / fn-N-slug.M (task), a tracker handle (wor-17), or legacy fn-N, fn-N-xxx."
Detect ID type (use the canonical id from `flowctl show`):
- Contains `.` (e.g., fn-1.2, fn-1-add-oauth.2, wor-17.2) -> task ID
- No `.` (e.g., fn-1, fn-1-add-oauth, wor-17) -> spec ID
Step 2: Validate Environment
test -d .flow || { echo "No .flow/ found. Run flowctl init first."; exit 1; }If `.flow/` missing, output error and stop.
Step 3: Validate ID Exists
$FLOWCTL show <ID> --json
If command fails:
- For task ID: "Task <id> not found. Run `flowctl list` to see available."
- For spec ID: "Spec <id> not found. Run `flowctl specs` to see available."
Stop on failure.
Step 4: Find Downstream Tasks
**For task ID input:**
# Extract spec from task ID (remove .N suffix)
SPEC=$(echo "<task-id>" | sed 's/\.[0-9]*$//')
# Get all tasks in spec
$FLOWCTL tasks --spec "$SPEC" --json
Filter to `status: todo` or `status: blocked`. Exclude the source task itself.
**For spec ID input:**
$FLOWCTL tasks --spec "<spec-id>" --json
1. First, find a **source task** to anchor drift detection (agent requires `COMPLETED_TASK_ID`):
- Prefer most recently updated task with `status: done`
- Else: most recently updated task with `status: in_progress`
- Else: error "No completed or in-progress tasks to sync from. Complete a task first."
2. Then filter remaining tasks to `status: todo` or `status: blocked` (these are downstream).
**If no downstream tasks:**
No downstream tasks to sync (all done or none exist).
Stop here (success, nothing to do).
Step 5: Gather glossary + decisions + strategy context
Three extra context types help the agent catch drift the spec text alone can't reveal: project-glossary terms (renames where the old spec used a term whose `_Avoid_` alias now appears in code), active decision constraints (current code may touch files mentioned in a decision's `Consequences` section), and strategic-intent drift (completed task contradicts an active `STRATEGY.md` track or approach).
GLOSSARY_JSON="$("$FLOWCTL" glossary list --json 2>/dev/null \
|| echo '{"groups":[],"file_count":0,"total_terms":0}')"
DECISIONS_JSON="$("$FLOWCTL" memory list --track knowledge --category decisions --json 2>/dev/null \
|| echo '{"entries":[],"legacy":[],"count":0,"status":"active"}')"
STRATEGY_CONTENT="$("$FLOWCTL" strategy read --json 2>/dev/null || echo '{}')"All three calls are best-effort — empty defaults keep the agent prompt valid when flowctl returns nothing or fails.
**Husk short-circuit** — when ALL three of the following hold, skip the extra context entirely (pass the empty defaults; the agent's husk short-circuit at the top of Phase 3b will skip the whole section):
- `GLOSSARY_JSON.total_terms == 0` (glossary missing or husk)
- `DECISIONS_JSON.count == 0` (no decision entries)
- `STRATEGY_CONTENT.sections_filled == 0` OR `STRATEGY_CONTENT == {}` (no STRATEGY.md or husk — verify with `flowctl strategy status --json | jq '.sections_filled // 0'`)
When ANY of the three has signal, pass through all three (untouched) and let the agent run the matching subsection (3b.1 / 3b.2 / 3b.3) and skip the empty ones.
When `GLOSSARY_JSON.total_terms == 0` but `file_count > 0`, every group is a husk. Husks carry no signal for drift detection — pass the JSON through untouched and let the agent skip them.
Step 6: Spawn Plan-Sync Agent
Read the cross-spec flag first — the same single config-leaf read `/flow-next:work` performs, so a repo that opted into cross-spec propagation (`planSync.crossSpec=true`) gets the SAME behavior from a manual `/flow-next:sync` as from the work-loop auto-trigger. Without this, `CROSS_SPEC` is unset and plan-sync skips the cross-spec phase entirely — the tool you reach for AFTER big drift silently checks only same-spec tasks:
CROSS_SPEC=$($FLOWCTL config get planSync.crossSpec --json | jq -r '.value')
Build context and spawn via Task tool:
Sync task specs from <source> to downstream tasks.
COMPLETED_TASK_ID: <source task id - the input task, or selected source for spec mode>
FLOWCTL: ${DROID_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}/scripts/flowctl
SPEC_ID: <spec id>
DOWNSTREAM_TASK_IDS: <comma-separated list from step 4>
DRY_RUN: <true|false>
CROSS_SPEC: <the $CROSS_SPEC value reaRead more
name: flow-next-sync description: Manually trigger plan-sync to update downstream task specs after implementation drift. Use when code changes outpace specs. user-invocable: false
Manual Plan-Sync
Manually trigger plan-sync to update downstream task specs.
Preamble
**CRITICAL: flowctl is BUNDLED - NOT installed globally.** Define once; subsequent blocks use `$FLOWCTL`:
FLOWCTL="${DROID_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}/scripts/flowctl"
[ -x "$FLOWCTL" ] || FLOWCTL=".flow/bin/flowctl"Input
Arguments: $ARGUMENTS Format: `<id> [--dry-run]`
- `<id>` - task ID `fn-N-slug.M` (or legacy `fn-N.M`, `fn-N-xxx.M`) or spec ID `fn-N-slug` (or legacy `fn-N`, `fn-N-xxx`), **or a resolvable tracker handle** (`wor-17` / `wor-17.M`) that `flowctl show` maps to the linked spec/task (fn-52.10, R16)
- `--dry-run` - show changes without writing
Workflow
Step 1: Parse Arguments
REPO_ROOT="$(git rev-parse --show-toplevel 2>/dev/null || pwd)"
Parse $ARGUMENTS for:
- First positional arg = `ID`
- `--dry-run` flag = `DRY_RUN` (true/false)
**Validate ID first (handle-recognition rule, R16):**
- Do NOT gate on a hard "must start with `fn-`" check. Route the arg through `$FLOWCTL show <ID> --json` (Step 3) — flowctl's widened resolver (fn-52.10) 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 id. So `/flow-next:sync wor-17` resolves the linked spec.
- If no ID provided: "Usage: /flow-next:sync <id> [--dry-run]"
- If the arg does NOT resolve via `flowctl show` (Step 3): "Unknown ID. Use fn-N-slug (spec) / fn-N-slug.M (task), a tracker handle (wor-17), or legacy fn-N, fn-N-xxx."
Detect ID type (use the canonical id from `flowctl show`):
- Contains `.` (e.g., fn-1.2, fn-1-add-oauth.2, wor-17.2) -> task ID
- No `.` (e.g., fn-1, fn-1-add-oauth, wor-17) -> spec ID
Step 2: Validate Environment
test -d .flow || { echo "No .flow/ found. Run flowctl init first."; exit 1; }If `.flow/` missing, output error and stop.
Step 3: Validate ID Exists
$FLOWCTL show <ID> --json
If command fails:
- For task ID: "Task <id> not found. Run `flowctl list` to see available."
- For spec ID: "Spec <id> not found. Run `flowctl specs` to see available."
Stop on failure.
Step 4: Find Downstream Tasks
**For task ID input:**
# Extract spec from task ID (remove .N suffix) SPEC=$(echo "<task-id>" | sed 's/\.[0-9]*$//') # Get all tasks in spec $FLOWCTL tasks --spec "$SPEC" --json
Filter to `status: todo` or `status: blocked`. Exclude the source task itself.
**For spec ID input:**
$FLOWCTL tasks --spec "<spec-id>" --json
1. First, find a **source task** to anchor drift detection (agent requires `COMPLETED_TASK_ID`):
- Prefer most recently updated task with `status: done`
- Else: most recently updated task with `status: in_progress`
- Else: error "No completed or in-progress tasks to sync from. Complete a task first."
2. Then filter remaining tasks to `status: todo` or `status: blocked` (these are downstream).
**If no downstream tasks:**
No downstream tasks to sync (all done or none exist).
Stop here (success, nothing to do).
Step 5: Gather glossary + decisions + strategy context
Three extra context types help the agent catch drift the spec text alone can't reveal: project-glossary terms (renames where the old spec used a term whose `_Avoid_` alias now appears in code), active decision constraints (current code may touch files mentioned in a decision's `Consequences` section), and strategic-intent drift (completed task contradicts an active `STRATEGY.md` track or approach).
GLOSSARY_JSON="$("$FLOWCTL" glossary list --json 2>/dev/null \
|| echo '{"groups":[],"file_count":0,"total_terms":0}')"
DECISIONS_JSON="$("$FLOWCTL" memory list --track knowledge --category decisions --json 2>/dev/null \
|| echo '{"entries":[],"legacy":[],"count":0,"status":"active"}')"
STRATEGY_CONTENT="$("$FLOWCTL" strategy read --json 2>/dev/null || echo '{}')"All three calls are best-effort — empty defaults keep the agent prompt valid when flowctl returns nothing or fails.
**Husk short-circuit** — when ALL three of the following hold, skip the extra context entirely (pass the empty defaults; the agent's husk short-circuit at the top of Phase 3b will skip the whole section):
- `GLOSSARY_JSON.total_terms == 0` (glossary missing or husk)
- `DECISIONS_JSON.count == 0` (no decision entries)
- `STRATEGY_CONTENT.sections_filled == 0` OR `STRATEGY_CONTENT == {}` (no STRATEGY.md or husk — verify with `flowctl strategy status --json | jq '.sections_filled // 0'`)
When ANY of the three has signal, pass through all three (untouched) and let the agent run the matching subsection (3b.1 / 3b.2 / 3b.3) and skip the empty ones.
When `GLOSSARY_JSON.total_terms == 0` but `file_count > 0`, every group is a husk. Husks carry no signal for drift detection — pass the JSON through untouched and let the agent skip them.
Step 6: Spawn Plan-Sync Agent
Read the cross-spec flag first — the same single config-leaf read `/flow-next:work` performs, so a repo that opted into cross-spec propagation (`planSync.crossSpec=true`) gets the SAME behavior from a manual `/flow-next:sync` as from the work-loop auto-trigger. Without this, `CROSS_SPEC` is unset and plan-sync skips the cross-spec phase entirely — the tool you reach for AFTER big drift silently checks only same-spec tasks:
CROSS_SPEC=$($FLOWCTL config get planSync.crossSpec --json | jq -r '.value')
Build context and spawn via Task tool:
Sync task specs from <source> to downstream tasks.
COMPLETED_TASK_ID: <source task id - the input task, or selected source for spec mode>
FLOWCTL: ${DROID_PLUGIN_ROOT:-${CLAUDE_PLUGIN_ROOT}}/scripts/flowctl
SPEC_ID: <spec id>
DOWNSTREAM_TASK_IDS: <comma-separated list from step 4>
DRY_RUN: <true|false>
CROSS_SPEC: <the $CROSS_SPEC value reaShowing the first part of this file.
Repeatable agentic engineering. The workflow layer that turns AI coding agents into a disciplined factory: durable specs, fresh-context workers, adversarial cross-model reviews, receipts. Everything in your repo, zero dependencies. Claude Code · Codex · Cursor · Droid.
Other skills on flow-next.
- /flow-next-audit
Audit .flow/memory/ entries against current code and keep, update, consolidate, replace, delete, or harden each. Use when asked to audit memory or graduate a recurring lesson into a gate.
Open skill - /flow-next-capture
Synthesize the current conversation into a flow-next spec with read-back gating. Use when asked to capture this as a spec.
Open skill - /flow-next-chart
Decision-map discovery for one oversized unclear idea before capture. Resolve one decision per invocation, brief for capture. Use when asked to chart an idea or work a chart decision.
Open skill - /flow-next-deps
Show spec dependency graph and execution order. Use when asking 'what's blocking what', 'execution order', 'dependency graph', 'what order should specs run', 'critical path', 'which specs can run in parallel'.
Open skill - /flow-next-drive
Drive any UI surface like a real user - a web app, a Chromium-backed desktop app (Electron / WebView2, reached over CDP), or a genuinely native app (macOS AppKit/SwiftUI, or a non-CDP webview) reached via the Cua Driver / Computer Use. Detects the surface, picks the best
Open skill - /flow-next-export-context
Export RepoPrompt context to a markdown file for review with an external LLM (ChatGPT, Claude web, etc.). Use when you want Carmack-level review but prefer an external model. Triggers on "export context", "export for external review", "export plan for ChatGPT", "export impl
Open skill

