Skip to content

Releases: gmickel/flow-next

flow-next v2.1.1

17 Jun 10:12
4cada36

Choose a tag to compare

Added

  • /flow-next:land accepts a bot "reviewed-clean" SHA-named comment as the silence signal (fn-65). The default silence review signal was satisfied by "an automated review of the current head + zero unresolved threads + patience window elapsed", but land detected automated reviews only via the formal reviews API. The Codex GitHub reviewer (chatgpt-codex-connector[bot]) files a formal review only when it has findings — on a clean pass it posts an issue comment instead (e.g. "Codex Review: Didn't find any major issues. Reviewed commit: <sha>") that never reaches the reviews API. So an unattended land loop would NOT auto-merge a converged-clean PR whose only change since the last finding was approved-by-silence — exactly the state land exists to merge (it bit the fn-64 land of PR #176; a human merged on judgment).
    • Comment-scan evidence source (fn-65.1): when land.reviewSignal == silence, land additionally scans issues/<n>/comments for an automated-reviewer ([bot]-suffix or land.automatedReviewers) comment matching land.cleanReviewCommentPattern that names the current head SHA. SHA tokens are explicitly extracted ([0-9a-fA-F]{7,40}, ≥7 chars, non-empty) and prefix-matched against HEAD_OID — an empty extraction never spuriously passes, and a stale-SHA or no-SHA clean comment is ignored (conservative by design). A match only ever sets AUTO_REVIEW_CURRENT=1 (never resets the reviews-API path); CI, unresolved-thread, and window gates are unchanged. Comment-driven satisfaction is observable: AUTO_REVIEW_SOURCE=comment + AUTO_REVIEW_EVIDENCE (author + matched SHA prefix) surface in --dry-run and the verdict report.
    • land.cleanReviewCommentPattern config (fn-65.1): new optional key, seeded with a structured built-in ERE ((Didn'?t find any( major)? issues|No( major)? issues found).*Reviewed commit) that requires BOTH the clean phrase AND the Reviewed commit marker — a bare "no issues" mention never satisfies the gate. Contract: null/missing (an unseeded older repo) → fall back to the built-in default; explicit empty string "" → comment scan DISABLED (pure reviews-API behavior, the real off-switch); other value → used. Scoped to silence only — approve and <login> signals are unchanged. New regression coverage in tests/test_land_config.py.
    • Docs: docs/flowctl.md land config table (new land.cleanReviewCommentPattern row — default shown as the built-in ERE, empty-disables stated), land skill workflow + SKILL.md, Codex mirror regenerated; flow-next.dev autonomous/land.mdx (silence-signal row, automated-reviewer prose, Configuration table) + changelog ship the counterpart pass.

Notes

  • Patch release — additive, opt-in, backward-compatible: empty/unset land.cleanReviewCommentPattern with a non-Codex reviewer is today's behavior exactly. The change only lets land see a clean review it currently misses; it introduces no new merge authority — CI-green, zero-unresolved-threads, and window-elapsed gates are untouched, and a clean comment never bypasses an open thread or red check.

flow-next v2.1.0

17 Jun 07:01
2f1faf3

Choose a tag to compare

Added

  • Dependency projection — tracker-sync projects depends_on_epics into tracker issue relations (fn-64 / FLOW-14). Flow specs declare cross-spec dependencies locally via depends_on_epics, but that graph stayed local-only — the board showed independent issues even though Flow knew one blocked another (it bit us in SapienXT, where the relations had to be hand-added in Linear). On push/reconcile of a linked spec, each depends_on_epics edge between two linked specs now becomes a blocked-by relation between their issues — on both Linear and GitHub, idempotently, never clobbering a relation a human added by hand. The relations counterpart to body/status/comments sync: projection, not coordination — flow stays authoritative and the tracker is never a control plane for deps.
    • Transport-blind hook (fn-64.5): the new projectDepRelations hook (modelled on the one-way projectReadiness pull) resolves edges via flowctl sync list-dep-relations, then drives the normalized adapter relation pair — setIssueRelation(issue, blockedBy) / listIssueRelations(issue) (fn-64.2, references/adapter-interface.md). The skill code does not branch on Linear-vs-GitHub; only adapter fidelity differs. Self-edges are skipped with a warning; a dependency cycle is tolerated — each declared edge projects as an independent direct relation, with no graph traversal or transitive expansion.
    • Linear adapter (fn-64.3): native issue relations — MCP save_issue blockedBy/blocks where the pinned schema exposes them, else the GraphQL issueRelationCreate rung (type: blocks, operands swapped), else a noop receipt. Idempotency via read-before-write across both relations AND inverseRelations, each canonicalized to one direction.
    • GitHub adapter (fn-64.4): native issue dependencies (GA Aug 2025) via the REST …/issues/{n}/dependencies/blocked_by endpoints where the repo/account has them (feature-detected with a GET probe; the numeric DB id, not #N; native POST uses gh api -F for the numeric issue_id, never -f), else a provenance-fenced "Blocked by" body block (<!-- flow:deps --><!-- /flow:deps --> list of #N references) — the same reduced-fidelity posture the adapter takes for status.
    • Provenance ledger + never-clobber (fn-64.1): neither platform stores relation authorship, so tracker-sync records the edges it created in a per-spec depRelations ledger (the .flow/specs/<id>.json sidecar, atomic write — entry shape {key, dep_spec, from_tracker_id, to_tracker_id, type, source, updatedAt}, where key is an opaque hash of the directed pair, never a raw issue key inline). A relation not in the ledger (native) / outside the fenced block (GitHub fallback) is never removed. New flowctl plumbing: flowctl sync list-dep-relations / set-dep-relation / clear-dep-relation, plus the identifier validator widened to accept a bare numeric N (so set-tracker-id --identifier 42 no longer fails before any adapter runs).
    • Body-merge ownership + collision rule (fn-64.5, references/body-merge.md): the GitHub <!-- flow:deps --> block is flow-owned — the canonical trackerBodyForMerge transform strips it before every hash / merge-base / divergence comparison, so flow's own dependency block never round-trips into the spec or registers as phantom tracker divergence. The collision case (a ledgered edge still in depends_on_epics but missing remotely — a tracker user removed it) is evaluated before per-side rules and emits sync defer + a queued receipt rather than silently recreating it.
    • Completed-blocker rule: a dependency whose local dep spec is done stays visible as a completed blocker on the board but does NOT feed back into Flow ready=true gating (readiness already treats done deps as satisfied — this hook must not regress that). dep_status is the local dep-spec status, never a remote fetch.
    • Tests + docs (fn-64.6): pure-stdlib unittest coverage in tests/test_tracker_sync_state.py (dep-relation add, idempotent rerun, missing-link warning, completed-blocker status, self-edge skip, bare-N identifier acceptance, fresh-spec sidecar field) plus the body-merge exclusion fixture. Docs: tracker-sync.md (new Dependency-projection section), flowctl.md (new subcommands), the adapter references, GLOSSARY.md (dependency projection, provenance ledger, completed-blocker rule).

Notes

  • This is the relations edge type the bridge was missing — body, status, and comments already synced two-way. Boundaries hold: no tracker→flow dep ingestion, no transitive/graph expansion, no readiness-model changes, GitHub Projects fields out of scope. Codex mirror regenerated and audited (no spurious ask-block injections, validators green). flow-next.dev ships the counterpart tracker-sync page + changelog + FLOW_NEXT_VERSION → 2.1.0 in the same workstream.

flow-next v2.0.0

12 Jun 13:38

Choose a tag to compare

Added

  • Optional HTML artifact mode — spec & PR render lenses (fn-62 / FLOW-12). When activated, the lifecycle skills that own the human touchpoints emit beautifully rendered, self-contained HTML pages alongside their markdown output: a render lens is a regenerable review artifact derived from a markdown source of truth — never the storage format, never parsed back as state. Markdown (and tracker-sync) stays 100% the record; users who stick with default markdown see zero change (no reference file loads, no artifacts are written, no new steps, zero token cost).
    • Activation (fn-62.1): flowctl config set artifacts.html.enabled true — seeded in flowctl config defaults (false, so config get returns a value, not null, on fresh repos; tests/test_artifacts_config.py). /flow-next:setup asks once (include-only-if-unset, like every ceremony question) and on opt-in offers the optional lavish-axi install with its session-spanning feedback model. Artifacts live at fixed deterministic paths — .flow/artifacts/<spec-id>/spec.html / pr.html, never timestamped (Lavish keys annotation sessions on the absolute file path) — committed by default so PR blob links resolve, or gitignored per project (setup offers the choice; link strategy follows git check-ignore).
    • Shared disclosure reference (fn-62.2): one progressively disclosed file, references/html-artifacts.md, loaded by participating skills only when the mode is on. Carries all generation rules plus an explicit anti-slop design contract (own instrument-panel palette/typography, no CDN fonts, zero external requests, print-friendly, staleness stamp in every footer, layered CSS-grid DAG rendering — never hand-typed SVG coordinates). Generation is agentic (the host agent reads the reference); flowctl's only contribution is the config knob.
    • Spec artifact (fn-62.3): ONE generation pathway with state-dependent rendering — spec-only business-review view before tasks exist (/flow-next:capture §5.10), the added plan layer (task dependency DAG with critical path, R-ID → task coverage matrix) once tasks exist (/flow-next:plan Step 8.5, after the refinement loop exits). The spec markdown links its lens via an idempotent marker line (replaced in place, never duplicated).
    • PR artifact (fn-62.4): /flow-next:make-pr Phase 1.5 emits a read-only review instrument — diff-derived (never from commit messages), verified against the spec's R-ID export before publishing (mismatches render as visibly flagged rows; warn-in-artifact, never blocking), churn grouped by review intent, where-to-look checklist. Committed narrowly (chore(flow): pr artifact <spec-id>, artifact file only — never git add -A); --dry-run writes no artifact; generation failure is non-fatal and the Ralph stdout contract (PR_URL= only) is untouched.
    • Lavish integration (optional, detect-on-PATH — never wrapped, bundled, or required) : with lavish-axi on PATH in an interactive session, spec artifacts open as annotation sessions; feedback is pull-only and session-spanning (queues in ~/.lavish-axi/state.json, survives agent death, any later session drains it via lavish-axi poll), and every annotation maps to a markdown-source edit followed by lens regeneration. The PR artifact never enters the annotate loop; autonomous/Ralph contexts never open a session and never poll. Absence or server idle-stop is invisible — the artifact is a self-contained static page.
    • Docs (fn-62.5): new docs/html-artifacts.md reference (GitHub-display limitation + local-open guidance included), README / teams / ralph / GLOSSARY surfaces.

Removed

  • BREAKING: the planSync.crossEpic config alias is gone (deprecated since 1.1.3; removal promised for 2.0 throughout the 1.x line). flowctl no longer reads, writes, or migrates the legacy key: reading planSync.crossSpec never falls back to a leftover crossEpic value, config get/set planSync.crossEpic is now a plain unknown-key lookup (no redirect, no deprecation warning), and flowctl init no longer mirrors legacy → canonical. A leftover crossEpic key in .flow/config.json is inert (preserved by the config merge, never read). Migration: if you still rely on it, set the canonical key once — flowctl config set planSync.crossSpec true. Regression suites converted to pin the removal (tests/test_config_alias.py, tests/test_init_crossspec_mirror.py); prose surfaces (setup workflow, docs/flowctl.md, plan-sync agent, local-dev smoke) updated to match.

Notes

  • 2.0.0 marks the leap, not an unrelated rewrite: the HTML artifact mode is fully opt-in (OFF by default — markdown-only users see zero new steps, prerequisites, or token overhead), and the only breaking change is the long-promised crossEpic alias removal above. Codex mirror regenerated and audited (references/ copy byte-identical, no spurious ask-block injections, validators green). flow-next.dev shipped the counterpart pass in the same workstream: visual-aids + pipeline pages, landing/SPECS/TEAMS/REVIEW surfaces, docs-site changelog + FLOW_NEXT_VERSION → 2.0.0.

flow-next v1.14.0

11 Jun 17:33
8be8eef

Choose a tag to compare

Added

  • /flow-next:land — the ship loop: a cadence-tick autonomous PR babysitter (fn-60 / FLOW-9). Where pilot and Ralph deliberately stop at a draft PR, land takes those PRs the rest of the way — fully autonomously, opt-in, /loop-shaped (/loop 30m /flow-next:land). One invocation is one tick: DISCOVER the open PRs the build loop authored (spec branch_name match AND the make-pr breadcrumb in the PR body — BOTH signals required before any mutation; branch-only matches are NEEDS_HUMAN, never acted on; only specs with ALL tasks done qualify — the pilot-concurrency interlock), GATE each PR read-only (durable-label skip → CI tri-state over ALL checks via gh pr checks --json bucket, never --required; empty check list inside the window = pending, never success → patience window anchored to the LAST PUSH, default 30 min → unresolved review threads → review signal → stale-approval-dismissal loop detection → mergeStateStatus), ACT with at most ONE action class per PR (bounded CI fix with strikes in $(git rev-parse --git-common-dir)/flow-next/land-strikes.json and a durable flow-next:needs-human label on exhaustion; resolve-pr dispatch with mode:autonomous; mechanical rebase only for DIRTY/BEHIND — any conflict hunk aborts to BLOCKED; or the gated merge: gh pr ready flip + explicit gh pr merge --squash --delete-branch --match-head-commit, NEVER --auto, then the post-merge tail flowctl spec close → opt-in tracker.perEvent.land.merged touchpoint → release-follow of the project's own release docs with an idempotency probe, or stop at merge), then REPORT per-PR evidence blocks and one terminal machine-greppable line: LAND_VERDICT=<MERGED|RELEASED|FIXING_CI|AWAITING_REVIEW|RESOLVING|BLOCKED|NEEDS_HUMAN|NO_WORK> prs=<n> pr=<deciding-pr-url|-> reason="<one line>" (worst-severity rule). Review convergence is configurable via land.reviewSignal: silence (default — an automated review present + zero unresolved threads + the window elapsed; bot reviewers like Codex never file formal APPROVEs), approve (formal reviewDecision), or a named reviewer login; with no automated review ever and no signal configured it never merges unreviewed (NEEDS_HUMAN). A merged-but-unclosed spec re-enters idempotently (resume close → tracker → release, never a second merge). --dry-run reports the full per-PR gate classification with zero mutations. Branch hygiene throughout: dirty-tree refusal at tick start, per-PR checkout restore + clean-tree assertion, Ralph-nesting refusal (FLOW_RALPH / REVIEW_RECEIPT_PATH). gh surfaces verified against gh 2.93.0.
  • land.* config surface with seeded defaults (fn-60.2): land.release (true), land.patienceMinutes (30), land.reviewSignal (silence), land.automatedReviewers ("" — csv allowlist supplementing the [bot]-suffix rule), land.ciFixBudget (3). Seeded in flowctl config defaults so config get returns values, not null, on fresh repos. New regression suite tests/test_land_config.py.

Changed

  • /flow-next:resolve-pr gained an autonomous mode (fn-60.2, fn-59.2 signal convention): the mode:autonomous arg token (primary) or FLOW_AUTONOMOUS=1 env (secondary) suppresses question branches only — never Ralph paths. Under autonomy the Phase-10 needs-human surface emits NEEDS_HUMAN: report lines instead of blocking, threads stay open, and the run ends with the machine-readable terminal line RESOLVE_PR_VERDICT=<RESOLVED|PENDING|NEEDS_HUMAN> threads=<n> fixed=<n> needs_human=<n> that land gates on. Bounded 2 fix-verify cycles unchanged. Its "user-triggered only" Forbidden line carries one confined exception: land may dispatch it with mode:autonomous.
  • The standing "no gh pr merge from skills" rule now has exactly one confined exception — land merges explicitly after its full gate tree passes; every other skill keeps the no-auto-merge rule (CLAUDE.md exception note included).

Notes

  • Land and Ralph are alternative autonomous drivers, never nested. Land is the pipeline terminus: with pilot (build loop) and land (ship loop) the lifecycle closes end to end — bless a spec → plan → review → work → draft PR → CI → reviews → merge → release. Codex mirror regenerated with the new land skill. Docs touched: README (count/row/third autonomous path), GLOSSARY Land term + Verdict extension, CLAUDE.md merge-rule exception, docs index, ralph.md ship-loop recipe; flow-next.dev counterpart page: /autonomous/land.

flow-next v1.13.0

11 Jun 06:28
fa8d90f

Choose a tag to compare

Added

  • /flow-next:pilot — a single-tick autonomous build-loop conductor (fn-59 / FLOW-8). One invocation is one tick: SELECT the first open + ready spec whose depends_on_epics are done and whose tasks carry no other-actor claims, ACT by dispatching exactly one stage skill, VERIFY advancement from flowctl state (or a gh-confirmed OPEN PR URL for make-pr, which has no flowctl transition), then REPORT with one terminal machine-greppable line: PILOT_VERDICT=<ADVANCED|NO_WORK|BLOCKED|NEEDS_HUMAN> spec=<id> stage=<stage> reason="<one line>". Stages are exactly plan / plan-review / work / make-pr; selection is a two-pass walk over the fn-58 ready gate with dependency + collision checks; branch handling follows the spec branch matrix (checkout existing branch for work/make-pr, --branch=new on first work tick, NEEDS_HUMAN for inconsistent all-done/no-branch state). The don't-thrash guard records healthy no-advance ticks in $(git rev-parse --git-common-dir)/flow-next/pilot-strikes.json, clears the spec's ready flag via flowctl spec unready on strike 2/2, and clears strikes when a human re-blesses via flowctl spec ready. V1 args are intentionally small: bare /flow-next:pilot, --spec <id>, --dry-run, and passthroughs --review=<backend>, --research=<grep|rp>, --depth=<level> (defaults: configured backend, grep, short). Driver recipes are host-owned, not tick-owned: Claude Code /loop v2.1.72+ (/loop 10m /flow-next:pilot, loops expire after 7 days), Claude Code /goal v2.1.139+ (/goal keep running /flow-next:pilot until it prints PILOT_VERDICT=NO_WORK, or stop after 20 turns), and Codex /goal with [features] goals = true, CLI >= 0.128.0, and a plain-text objective naming pilot + the verdict grammar.

Changed

  • /flow-next:plan, /flow-next:work, and /flow-next:make-pr now honor autonomous mode without entering Ralph (fn-59.2). The primary signal is the mode:autonomous arg token, which survives skill-invokes-skill; the secondary signal is FLOW_AUTONOMOUS=1 for process-level drivers. These signals suppress user-question branches only — they deliberately do not activate ralph-guard hooks, receipt choreography, or any FLOW_RALPH path. Under autonomy, work defaults to --branch=new, make-pr forces a draft PR and hard-errors instead of prompting, and genuinely ambiguous states surface to pilot as NEEDS_HUMAN.

Notes

  • Ralph and pilot are alternative drivers, never nested: pilot refuses under FLOW_RALPH / REVIEW_RECEIPT_PATH. Ralph remains the overnight shell harness with fresh sessions, receipts, and ralph-guard; pilot is the in-session single tick with transcript verdicts. The rp review backend still needs the RepoPrompt GUI, so unattended runs should use --review=codex, --review=copilot, or --review=none. Codex mirror regenerated with the new pilot skill (openai.yaml included). Docs touched: README, GLOSSARY Pilot / Verdict terms, ralph.md host-driven-vs-Ralph contrast, docs index; flow-next.dev counterpart page: /skills/pilot.

flow-next v1.12.0

10 Jun 20:05
5c98373

Choose a tag to compare

Added

  • Spec readiness signal — a human-owned ready flag, the entry gate for autonomous execution (fn-58 / FLOW-7). A spec now carries a ready boolean (default false) marking it "complete enough to hand to an agent" — orthogonal to status (open|done; a ready spec stays open through planning and work), human-owned or tracker-projected, never agent-inferred. The gate is strictly opt-in: non-adopters see no prompts, warnings, or badge noise anywhere.
    • flowctl spec ready <id> / spec unready <id> — idempotent toggles (no write, no updated_at bump when the flag already matches; "changed" reported in --json). The on-disk flag is lazy: the sidecar carries ready only after a toggle actually changes state (spec create never writes it; absent reads false) — zero working-tree churn for non-adopters. Every JSON read surface (show, specs, list) emits an explicit "ready": <bool>, and ready specs get a [ready] badge in specs/list output (badge only when set — no draft-noise). Task ids rejected; done specs allowed; epic ready/epic unready aliases included. New regression suite tests/test_spec_ready.py (lazy purity, idempotency, badge/JSON surfaces) wired into CI + both smoke scripts.
    • Tracker projection (tracker.readyState) — for tracker-connected repos, the /flow-next:tracker-sync discovery ceremony asks one optional, skippable question: which tracker workflow state means "ready for work"? (Linear: a workflow-state name, matched case-insensitive/trimmed — names, not state.type, since a custom "Ready" state is typically type=unstarted; GitHub: a label, pre-created idempotently — present ⇒ ready, absent ⇒ not ready, a normal state). Every pull-side sync (pull/reconcile) projects the state onto the local ready flag — one-way, tracker → local, tracker authoritative (a local spec ready is overwritten on the next sync). Change-only event-tagged receipts (silent on echo); a stale/renamed configured state warns + noop receipt + flag untouched + the sync continues. readyState lives at the tracker top level (sibling of conflictTiebreak); null = projection off.
    • Adoption-gated prompting layer — the same in-use gate (≥1 ready spec OR tracker.readyState configured) governs every new prompt, so non-adopters see zero new questions. /flow-next:capture and /flow-next:interview offer an optional end-of-authoring "Mark ready?" consent (default keep-draft; gated OFF when readyState is configured — never invite a local edit the next sync would revert; autofix never writes readiness). /flow-next:plan soft-checks readiness before the scout fan-out: not-ready + adopted ⇒ one warn-not-block question (default proceed — planning is non-destructive), with the option set split by mode (local: proceed / mark-ready-then-proceed / abort; tracker-authoritative: proceed / abort / update-tracker-state-then-rerun — local mark-ready never offered). Non-interactive/Ralph auto-proceeds with one stderr line. capture --rewrite resets readyfalse (a full re-authoring re-opens the blessing) and announces the reset only when it actually changed the flag; interview refinement never auto-resets.

Notes

  • Readiness is the shared entry gate for the forthcoming build-loop specs (fn-59/fn-60) but stands alone as backlog hygiene — knowing which specs are blessed vs still-draft. No new status value; no --ready filter flag in v1 (specs --json + jq covers selection); readiness is pull-only for tracker users (no outbound push). Both flowctl.py copies (canonical scripts/ + dogfood .flow/bin/) updated in lockstep. Codex mirror regenerated (the three net-new ask sites — capture/interview mark-ready, plan soft-check, ceremony readiness question — verified transformed to plain-text numbered prompts). Docs: GLOSSARY "Ready" term, architecture.md (lazy spec-JSON field), flowctl.md (spec ready/unready, tracker.readyState, alias rows), tracker-sync.md (readiness projection), setup usage.md.

flow-next v1.11.0

10 Jun 07:46
d7c988e

Choose a tag to compare

Added

  • Tracker-sync lifecycle hooks are now observable and forcing (fn-57 / FLOW-10). The bridge's lifecycle touchpoints (claim → In-Progress, done → comment, PR → issue link) were prose obligations an agent could silently skip — reproduced on two hosts (a Claude session and a Codex session in another project): PRs landed unlinked, issues never moved, and nothing failed. The hardening lives in the shared receipt/lifecycle layer, so it applies uniformly to every adapter (Linear, GitHub, future trackers) — and flowctl gains no tracker-mutation code: all mutations stay agent-driven through the tracker-sync skill; the deterministic additions are read-only.
    • flowctl sync receipt --event <perEvent-key> — every lifecycle dispatch's receipt now records which touchpoint it served (work.firstClaim, work.done, capture, makePr, …). Free-form (the perEvent key set is an open extension point); pre-flag receipts carry event: null and never satisfy an event-specific check. Every receipt call site in the tracker-sync skill is tagged via the caller's event: token (parsed in steps.md Phase 0); manual runs stay legitimately untagged.
    • flowctl sync check <spec-id> --events <csv> --since <iso> [--json] — the first reader of .flow/sync-runs/: a read-only, local-only audit reporting OK:<event> / MISSING:<event> per triggered touchpoint. MISSING iff the event triggered this run AND its tracker.perEvent leaf is enabled AND the bridge is active AND no receipt with a matching event tag and timestamp ≥ --since exists. Any receipt status clears (the check asserts the touchpoint ran); linkage is NOT a precondition (a never-linked spec that should have create-if-unlinked'd is exactly the miss it catches). Zero overhead for non-tracker repos: bridge inactive → silent constant-time exit 0 before any IO. Exit 0 always — output drives agent action, not the exit code.
  • /flow-next:prime seeds GLOSSARY.md from the repo (fn-57 Package B, R10). When the glossary is absent or a husk (glossary list --json total_terms == 0 — never a file-presence check), a new Phase 5.5 scans the repo for load-bearing vocabulary, proposes ~10-20 evidence-backed terms (file refs mandatory, _Avoid_ aliases on visible naming drift), and writes via flowctl glossary add only after read-back approval (--fix-all does not bypass it). A populated glossary gets a coverage report line and is never rewritten — pruning stays with /flow-next:audit.
  • /flow-next:capture joins interview as a glossary writer (R11). Capture's synthesis now runs a husk-aware new-vocabulary scan (workflow §2.7), offers genuinely-new project terms at read-back with a consent question, and writes approved terms via flowctl glossary add (§5.8) — autofix prints suggestions, never writes.
  • The glossary read path widens to where wrong-concept errors get built (R12): repo-scout / context-scout gain a Step 0.5 that surfaces only request-matched glossary entries (max 5, budget-capped — never the whole file), the work worker's re-anchor reads task-relevant terms, and impl-review (RP) + plan-review prompts add a Vocabulary criterion conditional on total_terms > 0. Every gate is total_terms == 0 → silent skip — zero behavior change without a populated glossary.
  • New docs page: docs/self-improving.md (R13) — the surfaces that compound through normal use (memory, glossary, decision records, strategy drift surfacing), with the flow-next.dev counterpart at /strategy/self-improving.

Changed

  • /flow-next:work, /flow-next:capture, and /flow-next:make-pr end every run with a tracker-sync check + bounded retro-fire (R2). Each skill runs sync check independently of the touchpoints (so a wholesale-skipped dispatch block is still caught), using an on-disk --since anchor (work → earliest claimed_at this run; capture → the spec's created_at; make-pr → the PR's createdAt) and a triggered-set --events contract (configured-but-not-triggered events are never MISSING). Any MISSING:<event> is retro-fired exactly once via the tracker-sync skill, re-checked against a fresh --since, and the final summary carries a mandatory four-state Tracker sync: slotOK | MISSING:<event> → retro-fired → OK | MISSING:<event> (retro-fire failed: <reason>) | n/a (bridge inactive). An explicit n/a proves the check ran; still-MISSING after one cycle is a recorded, visible outcome — never a block (best-effort discipline unchanged). Under Ralph, check + summary lines route to stderr (make-pr's stdout stays the single PR_URL= line; work's stdout stays clean for harness parsing). Manual recovery guidance (read the receipt note, re-fire via /flow-next:tracker-sync once transport returns) documented in tracker-sync.md.
  • /flow-next:make-pr §4.6b — deterministic post-create PR↔issue ref verify/repair (R4). §4.6a appends the non-closing Ref <identifier> line to the local body file before create — but an agent that hand-rolls gh pr create (the observed execution-fidelity gap) bypasses it. make-pr now verifies against the LIVE PR body (gh pr view --json body, never $BODY_FILE) with the same whole-line grep -qixF matcher as §4.6a, and repairs append-only via gh pr edit --body-file - when absent (65,536-char cap re-checked). Idempotent and fully non-fatal — the PR is already open.
  • flow-next.dev hero pillar grid redesigned to six pillars including the new "Self-improving / Compounds as you work." (R15) — an extensible 3-column auto-wrapping capability index, plus STRATEGY.md's new "Self-improving through normal work" track (R14).

Fixed

  • linear-mcp.md UUID correction (R9): the claude.ai Linear MCP returns identifiers (WOR-17), never UUIDs — on create AND fetch (verified live 2026-06-09) — so first-link requires the GraphQL rung (LINEAR_API_KEY) to obtain the UUID for sync set-tracker-id. The previous prose implied the MCP rung could complete a first link on its own.

Notes

  • Codex mirror regenerated (the work-phases §3c splice in sync-codex.sh now also carries the worker's glossary re-anchor line). New regression suites: tests/test_sync_check.py (19 tests — R8 silent inactive exit, MISSING predicate, any-status-clears, null-event back-compat, exit-0-always) and --event coverage in tests/test_tracker_receipts.py; both wired into CI as explicit steps. Both flowctl.py copies (canonical scripts/ + dogfood .flow/bin/) updated in lockstep (byte-identical invariant held). Docs: tracker-sync.md (observable+forcing lifecycle, MISSING-recovery), flowctl.md (sync check, --event), setup usage.md examples.

flow-next v1.10.2

08 Jun 21:02

Choose a tag to compare

Fixed

  • Plugin homepage now points at the canonical product site https://flow-next.dev instead of the stale https://mickel.tech/apps/flow-next. The homepage field in .claude-plugin/marketplace.json, plugins/flow-next/.claude-plugin/plugin.json, and plugins/flow-next/.codex-plugin/plugin.json (plus the Codex manifest's interface.websiteURL) all carried the old URL; .cursor-plugin/plugin.json was already correct, so the rest were just drift. author.url / owner.url (Gordon's personal site / GitHub) are unchanged. Also aligned the flow-next-tui package homepage and the README "Visual overview" doc row (which redundantly listed both URLs) to flow-next.dev.

flow-next v1.10.1

08 Jun 11:28
9eb7a30

Choose a tag to compare

Fixed

  • flowctl copilot impl-review no longer crashes with UnicodeDecodeError on a repo containing a non-UTF-8 source subtree (#167 — the read-side counterpart to #123). find_references() (the symbol-cross-reference collector behind gather_context_hints) ran git grep over a fixed, broad extension set (*.c *.h *.cpp *.cs *.java *.py …) and decoded the hits with a hard text=True, encoding="utf-8" and no errors=. Because gather_context_hints extracts symbols from the changed files and greps each one repo-wide, a single legacy file anywhere in the tree — e.g. a German cp1252 C/C++ subtree carrying 0xfc ü / 0xe4 ä / 0xf6 ö / 0xdf ß — was enough to abort context gathering, even when every file you actively edit is UTF-8. The collector now captures git grep output as bytes and decodes defensively (result.stdout.decode("utf-8", errors="replace")), matching the byte-then-decode pattern the diff readers already use. Behavior is unchanged for valid UTF-8 repos. Reported with measured data by VGottselig (a large Windows CAD codebase: 304 of ~5400 C/C++ files non-UTF-8).
  • flowctl forces its own stdout/stderr to UTF-8 at startup, so non-ASCII output (, umlauts) no longer aborts on a legacy console codepage such as Windows cp1252 (UnicodeEncodeError: 'charmap' codec can't encode character '→', e.g. from copilot plan-review's print(output)) (#167). main() now calls sys.stdout/stderr.reconfigure(encoding="utf-8", errors="replace") first thing, guarded so a captured or already-detached stream is left untouched. This removes the need for the PYTHONIOENCODING=utf-8 workaround.

Changed

  • /flow-next:work Verify-Completion (phase 3d) now carries a recovery heuristic for a lost/errored worker result (#167). When the host (Agent-tool) drops a long-running worker's completion report ([Tool result missing due to internal error]) — its work may be complete even though the report never arrived — the loop no longer blocks waiting for a result that will never come. It diagnoses from ground truth (flowctl show + git log + git status) and classifies: already done → proceed to plan-sync; code present but not finalized → spawn a re-anchoring continuation worker that resumes from the late phase (build → review → flowctl done) instead of restarting; nothing landed → retry normally. Skill prose only; Codex mirror regenerated.

Notes

  • Both flowctl.py copies (canonical scripts/ + dogfood .flow/bin/) updated in lockstep (byte-identical invariant held). New regression suite: tests/test_cp1252_robustness.py (reproduces the cp1252 find_references crash against a staged non-UTF-8 fixture; locks the stdio reconfigure guard and the phase-3d recovery prose, canonical + Codex mirror).

flow-next v1.9.1

06 Jun 05:55
88de18b

Choose a tag to compare

Fixed

  • /flow-next:setup now detects Cursor and writes Cursor-correct project instructions, instead of mis-detecting it as Codex. Setup's platform detection keyed only on plugin-root env vars (DROID_PLUGIN_ROOT → Droid, CLAUDE_PLUGIN_ROOT → Claude Code, else → Codex). Cursor exposes neither, so a Cursor local install fell into the Codex branch — /flow-next:setup wrote the $flow-next-plan Codex command syntax into AGENTS.md and ran .codex/ agent + hook setup, while the installer advertises Cursor usage as /flow-next:*. Setup now adds a CURSOR_AGENT + .cursor-plugin/plugin.json manifest branch (ordered before the else → codex fallback) → PLATFORM=cursor, applied at every platform-branch point in the workflow (detection, the 6b docs-status template, the Step 6 Docs question, and the Step 7 write mapping), which: writes the /flow-next:plan slash-command snippet (Cursor runs the same commands; lands in AGENTS.md, which Cursor reads), resolves flowctl via .flow/bin/flowctl, reads the version from .cursor-plugin/plugin.json, and skips the Codex-only .codex/ agent/hook copy. The detection requires both the env var and the Cursor manifest because CURSOR_AGENT is inherited by child processes — so Codex launched from a Cursor shell inherits it; the manifest (present only in a real ~/.cursor/plugins/local/flow-next install) plus a ! -d ${PLUGIN_ROOT}/codex guard (a real Cursor install excludes the codex/ mirror, so its absence rejects the shared repo source tree where all manifests coexist) keep a Codex-hosted-in-Cursor run — whether installed or run from source — correctly classified as codex. For that codex/-absence proof to hold on re-install, the installers now produce a true mirror: install-cursor.sh adds rsync --delete-excluded and install-cursor.ps1 explicitly Remove-Items the excluded dirs after robocopy /MIR (plain --delete / /MIR + /XD leave a pre-existing codex/ in place); test_install_cursor_parity.py locks both. Surfaced + hardened across five rounds of PR #162/#163 review. Codex mirror regenerated.
  • Tracker-sync create-if-unlinked now snapshots the merge base at issue-create time, even when the triggering op is comment. When the first lifecycle touchpoint for an unlinked spec was a comment op (e.g. work.done / makePr with earlier events disabled), the auto-create path created the issue and attached the tracker id but did not call sync set-merge-base / set-last-synced — and the comment path itself leaves body/status untouched, so the linked issue had no merge base. A later body sync would then hit the no-base bootstrap, treat the sync as a fast-forward projection, and could silently overwrite tracker-side edits made after the issue was created. The flow-first auto-link now snapshots the just-rendered pair (set-merge-base BOTH halves + set-last-synced) at create time — the issue body we just wrote is the renderFlowToTracker output, so the base is exact. (push-first auto-link was already covered by the push skeleton's post-write snapshot; this makes the comment/reconcile-first paths match.) Surfaced in PR #162 review. Codex mirror regenerated.