Skip to content

Chart

/flow-next:chart takes one unshaped idea that is too big for a single capture session and wrapped in unknowns, and finds the route by resolving one decision at a time until the effort can be captured as one or more specs.

The unit of work is a decision (D-ID), not a build task. Chart never writes a spec and never sets ready. Its output is a briefing package (B-IDs) handed to /flow-next:capture.

Chart is an optional high-uncertainty route - not a new mandatory pipeline stage. When intent and boundaries are already stateable, skip it and capture or author the spec directly. Unsure which path fits? Use /flow-next:flow --explain.

How to run a discovery loop, and the doctrine behind it, is Discovery before capture. This page is the invocation surface.

Natural language is the primary control surface. Flags and exact subcommands are for automation, scripting, and debugging - never required vocabulary for humans.

On every invocation the skill:

  1. Infers the intended mode from what you said
  2. Asks a blocking question only when two interpretations would materially change cost or consent
  3. Reads back any state-changing interpretation before persisting
  4. Never hand-edits chart Markdown or sidecars - always flowctl chart ...
You sayMode
”Chart out multi-tenant migration”Chart - ground, propose frontier, create (resolve nothing)
“Work the next decision on fn-140”Work - claim one frontier D-ID, evidence route, re-chart
”Continue from the tenancy prototype decision”Work (pinned)
“What’s left to decide on fn-140?”Status - render only
”Continue from this tracker link: <url>”Re-enter via local ledger only
"Work the next decision on the billing chart"
/flow-next:chart fn-140
/flow-next:chart fn-140 --decision 3
  1. Re-anchor Outcome + Notes (flowctl chart show)
  2. flowctl chart frontier is the sole selection input (human pin must still appear on that frontier)
  3. Claim before any work
  4. Load full decision body only for the claimed D-ID
  5. Attended gate if needed
  6. Evidence route by type
  7. Resolve / out-of-scope / release-claim
  8. Optional sharpen in the same resolve transaction
  9. Recompute frontier; propose the next smallest uncertainty - do not execute it in this invocation
  10. Print exactly one CHART_VERDICT=... line

Every work invocation ends with exactly one greppable line and nothing after it:

CHART_VERDICT=<RESOLVED|BLOCKED|NEEDS_HUMAN|COMPLETE|NO_WORK> chart=<id> decision=<D> reason="<one line>"
VerdictWhen
RESOLVEDOne D-ID closed via resolve or out-of-scope; frontier recomputed
BLOCKEDClaim conflict, graph/store refusal, or no actionable path without human repair
NEEDS_HUMANAttended decision reached by an unattended driver - no answer write
COMPLETEChart briefable after this tick, or briefing emitted
NO_WORKEmpty frontier, skip-chart, status-only, or chart mode finished without resolving

Chart mode and status mode also print one terminal line so host /loop / /goal drivers can parse uniformly (decision=- when no D-ID was claimed).

PathRole
.flow/charts/<chart-id>.mdMap body - Outcome, Notes, Decisions ledger, Open Questions, Boundaries
.flow/charts/<chart-id>.jsonSidecar - status, decisions metadata, briefings, tracker keys, produced_specs
.flow/charts/<chart-id>/<n>.mdDecision question body
.flow/charts/<chart-id>/<n>.jsonDecision sidecar - type, attendance, status, edges, assets, answer

Chart ids share the repo prefix and allocator with specs (fn-N) but carry a distinct kind. D-IDs are chart-local (fn-140.D3), append-only, never renumbered or reused.

Optional projection when the tracker bridge is active and tracker.charts is the literal on:

  • Parent issue for the chart; child issues for decisions
  • Local chart mutations always commit first; remote projection never blocks them
  • Projection carries type, attendance, status, blocking, and safe evidence summaries
  • Parent rollups: counts, latest resolution, frontier, chart status - projection-only, never canonical
  • Provider degradation is explicit; reconcile receipts stay local-first and revisioned

URL re-entry is local ledger only. flowctl chart locate <selector> resolves a chart/D-ID, stored tracker identifier, or stored tracker URL through the local provenance ledger - no network, no title matching, no create-on-miss.

SelectorBehavior
Parent chart URLRe-anchor on local chart status + frontier
Open decision URLPin that exact open D-ID
Resolved / superseded / historical URLShow history + frontier options - never silent reassignment
Unsupported / unlinked / missingFail visibly; offer local chart-id path; mutate nothing

Always read back canonical local ID, title, and record link before claim/work.

Not required vocabulary - conversational equivalents work.

Flag / formPurpose
--statusStatus mode - render only
--decision <n>Pin a D-ID for work mode
--json on every flowctl chart subcommandMachine envelope {success, schema_version:1, command, result|error}
create --initial-map-file / --force-size --reasonAtomic chart + ceiling override (audited)
resolve --answer-file / --sharpen-file / --supersedes / --keep-dependentsClose + optional sharpen/cascade. Sharpen notes_append corrects a disproved grounding note (dated, append-only, travels into the briefing); an unknown sharpen key is an error, not a silent no-op
attach-asset --asset-fileSafe artefact while open
briefing --proposal-file / --forceConfirmed split proposal; force is draft-only
claim / release-claim [--break-stale --reason]Claims; no silent expiry (chart.claimStaleAfter, default 24h)
locate <selector>Local ledger re-entry
link-spec --briefing --spec --decisionsRecord successful capture handoff

Error classes: not_found | conflict | invalid_state | invalid_graph | stale_claim | validation | io.

Full CLI surface: CLI Reference. Config: Configuration.

You: Capture the --json export flag work - intent and boundaries are clear.
Flow --explain / chart: no consequential unknowns.
CHART_VERDICT=NO_WORK chart=- decision=- reason="no consequential unknowns; capture or direct route"
You: Chart multi-tenant rate isolation - we don't know provider limits or billing split.
# Grounding cites STRATEGY.md + existing auth modules; parks billing; opens research frontier
CHART_VERDICT=NO_WORK chart=fn-140 decision=- reason="chart created; research frontier offered for parallel work"
You: Work the next decision on fn-140
# Claims D1 research, scout returns cited limits, sharpen turns parked billing into interview
CHART_VERDICT=RESOLVED chart=fn-140 decision=fn-140.D1 reason="provider limits cited; parked billing sharpened"
You: The prototype changed direction. Preserve the old assumption and redraw.
# Asset already attached; human reaction recorded; resolve --supersedes prior D-ID
CHART_VERDICT=RESOLVED chart=fn-140 decision=fn-140.D3 reason="prototype reversed D2 assumption; cascade reported"

More journeys (skip, research fan-out, multi-spec briefing, tracker re-entry): Cookbook - Chart journeys.

  • Flow - /flow-next:flow --explain says when chart is or is not the smallest sufficient route
  • Prototype-driven specs - the doctrine chart makes executable
  • Capture - briefing handoff and criterion source tags
  • Tracker Sync - optional parent/child projection
/flow-next:chart "the idea that is still too unclear to capture"
# ... resolve decisions until briefable ...
/flow-next:capture # from the briefing package