Releases: gmickel/flow-next
Releases · gmickel/flow-next
flow-next v2.1.1
Added
/flow-next:landaccepts a bot "reviewed-clean" SHA-named comment as thesilencesignal (fn-65). The defaultsilencereview 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 scansissues/<n>/commentsfor an automated-reviewer ([bot]-suffix orland.automatedReviewers) comment matchingland.cleanReviewCommentPatternthat names the current head SHA. SHA tokens are explicitly extracted ([0-9a-fA-F]{7,40}, ≥7 chars, non-empty) and prefix-matched againstHEAD_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 setsAUTO_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-runand the verdict report. land.cleanReviewCommentPatternconfig (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 theReviewed commitmarker — 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 tosilenceonly —approveand<login>signals are unchanged. New regression coverage intests/test_land_config.py.- Docs:
docs/flowctl.mdland config table (newland.cleanReviewCommentPatternrow — default shown as the built-in ERE, empty-disables stated), land skill workflow + SKILL.md, Codex mirror regenerated; flow-next.devautonomous/land.mdx(silence-signal row, automated-reviewer prose, Configuration table) + changelog ship the counterpart pass.
- Comment-scan evidence source (fn-65.1): when
Notes
- Patch release — additive, opt-in, backward-compatible: empty/unset
land.cleanReviewCommentPatternwith 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
Added
- Dependency projection — tracker-sync projects
depends_on_epicsinto tracker issue relations (fn-64 / FLOW-14). Flow specs declare cross-spec dependencies locally viadepends_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, eachdepends_on_epicsedge 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
projectDepRelationshook (modelled on the one-wayprojectReadinesspull) resolves edges viaflowctl 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_issueblockedBy/blockswhere the pinned schema exposes them, else the GraphQLissueRelationCreaterung (type: blocks, operands swapped), else anoopreceipt. Idempotency via read-before-write across bothrelationsANDinverseRelations, each canonicalized to one direction. - GitHub adapter (fn-64.4): native issue dependencies (GA Aug 2025) via the REST
…/issues/{n}/dependencies/blocked_byendpoints where the repo/account has them (feature-detected with aGETprobe; the numeric DB id, not#N; native POST usesgh api -Ffor the numericissue_id, never-f), else a provenance-fenced "Blocked by" body block (<!-- flow:deps -->…<!-- /flow:deps -->list of#Nreferences) — 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
depRelationsledger (the.flow/specs/<id>.jsonsidecar, atomic write — entry shape{key, dep_spec, from_tracker_id, to_tracker_id, type, source, updatedAt}, wherekeyis 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 numericN(soset-tracker-id --identifier 42no 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 canonicaltrackerBodyForMergetransform 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 independs_on_epicsbut missing remotely — a tracker user removed it) is evaluated before per-side rules and emitssync defer+ aqueuedreceipt rather than silently recreating it. - Completed-blocker rule: a dependency whose local dep spec is
donestays visible as a completed blocker on the board but does NOT feed back into Flowready=truegating (readiness already treats done deps as satisfied — this hook must not regress that).dep_statusis the local dep-spec status, never a remote fetch. - Tests + docs (fn-64.6): pure-stdlib
unittestcoverage intests/test_tracker_sync_state.py(dep-relation add, idempotent rerun, missing-link warning, completed-blocker status, self-edge skip, bare-Nidentifier 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).
- Transport-blind hook (fn-64.5): the new
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
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, soconfig getreturns a value, not null, on fresh repos;tests/test_artifacts_config.py)./flow-next:setupasks once (include-only-if-unset, like every ceremony question) and on opt-in offers the optionallavish-axiinstall 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 followsgit 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:planStep 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-prPhase 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 — nevergit add -A);--dry-runwrites 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-axion 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 vialavish-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.mdreference (GitHub-display limitation + local-open guidance included), README / teams / ralph / GLOSSARY surfaces.
- Activation (fn-62.1):
Removed
- BREAKING: the
planSync.crossEpicconfig alias is gone (deprecated since 1.1.3; removal promised for 2.0 throughout the 1.x line).flowctlno longer reads, writes, or migrates the legacy key: readingplanSync.crossSpecnever falls back to a leftovercrossEpicvalue,config get/set planSync.crossEpicis now a plain unknown-key lookup (no redirect, no deprecation warning), andflowctl initno longer mirrors legacy → canonical. A leftovercrossEpickey in.flow/config.jsonis 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
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 (specbranch_namematch AND the make-pr breadcrumb in the PR body — BOTH signals required before any mutation; branch-only matches areNEEDS_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 viagh 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.jsonand a durableflow-next:needs-humanlabel on exhaustion; resolve-pr dispatch withmode:autonomous; mechanical rebase only for DIRTY/BEHIND — any conflict hunk aborts toBLOCKED; or the gated merge:gh pr readyflip + explicitgh pr merge --squash --delete-branch --match-head-commit, NEVER--auto, then the post-merge tailflowctl spec close→ opt-intracker.perEvent.land.mergedtouchpoint → 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 vialand.reviewSignal:silence(default — an automated review present + zero unresolved threads + the window elapsed; bot reviewers like Codex never file formal APPROVEs),approve(formalreviewDecision), 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-runreports 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 soconfig getreturns values, not null, on fresh repos. New regression suitetests/test_land_config.py.
Changed
/flow-next:resolve-prgained an autonomous mode (fn-60.2, fn-59.2 signal convention): themode:autonomousarg token (primary) orFLOW_AUTONOMOUS=1env (secondary) suppresses question branches only — never Ralph paths. Under autonomy the Phase-10 needs-human surface emitsNEEDS_HUMAN:report lines instead of blocking, threads stay open, and the run ends with the machine-readable terminal lineRESOLVE_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 withmode:autonomous.- The standing "no
gh pr mergefrom 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.mdship-loop recipe; flow-next.dev counterpart page:/autonomous/land.
flow-next v1.13.0
Added
/flow-next:pilot— a single-tick autonomous build-loop conductor (fn-59 / FLOW-8). One invocation is one tick: SELECT the firstopen+readyspec whosedepends_on_epicsare done and whose tasks carry no other-actor claims, ACT by dispatching exactly one stage skill, VERIFY advancement fromflowctlstate (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 exactlyplan/plan-review/work/make-pr; selection is a two-pass walk over the fn-58readygate with dependency + collision checks; branch handling follows the spec branch matrix (checkout existing branch for work/make-pr,--branch=newon first work tick,NEEDS_HUMANfor 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'sreadyflag viaflowctl spec unreadyon strike 2/2, and clears strikes when a human re-blesses viaflowctl 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/loopv2.1.72+ (/loop 10m /flow-next:pilot, loops expire after 7 days), Claude Code/goalv2.1.139+ (/goal keep running /flow-next:pilot until it prints PILOT_VERDICT=NO_WORK, or stop after 20 turns), and Codex/goalwith[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-prnow honor autonomous mode without entering Ralph (fn-59.2). The primary signal is themode:autonomousarg token, which survives skill-invokes-skill; the secondary signal isFLOW_AUTONOMOUS=1for process-level drivers. These signals suppress user-question branches only — they deliberately do not activate ralph-guard hooks, receipt choreography, or anyFLOW_RALPHpath. 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 asNEEDS_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. Therpreview 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.yamlincluded). Docs touched: README, GLOSSARY Pilot / Verdict terms,ralph.mdhost-driven-vs-Ralph contrast, docs index; flow-next.dev counterpart page:/skills/pilot.
flow-next v1.12.0
Added
- Spec readiness signal — a human-owned
readyflag, the entry gate for autonomous execution (fn-58 / FLOW-7). A spec now carries areadyboolean (defaultfalse) marking it "complete enough to hand to an agent" — orthogonal tostatus(open|done; a ready spec staysopenthrough 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, noupdated_atbump when the flag already matches;"changed"reported in--json). The on-disk flag is lazy: the sidecar carriesreadyonly after a toggle actually changes state (spec createnever writes it; absent readsfalse) — 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 inspecs/listoutput (badge only when set — no draft-noise). Task ids rejected;donespecs allowed;epic ready/epic unreadyaliases included. New regression suitetests/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-syncdiscovery ceremony asks one optional, skippable question: which tracker workflow state means "ready for work"? (Linear: a workflow-state name, matched case-insensitive/trimmed — names, notstate.type, since a custom "Ready" state is typicallytype=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 localreadyflag — one-way, tracker → local, tracker authoritative (a localspec readyis overwritten on the next sync). Change-only event-tagged receipts (silent on echo); a stale/renamed configured state warns +noopreceipt + flag untouched + the sync continues.readyStatelives at the tracker top level (sibling ofconflictTiebreak);null= projection off. - Adoption-gated prompting layer — the same in-use gate (≥1 ready spec OR
tracker.readyStateconfigured) governs every new prompt, so non-adopters see zero new questions./flow-next:captureand/flow-next:interviewoffer an optional end-of-authoring "Mark ready?" consent (default keep-draft; gated OFF whenreadyStateis configured — never invite a local edit the next sync would revert; autofix never writes readiness)./flow-next:plansoft-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 --rewriteresetsready→false(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
statusvalue; no--readyfilter flag in v1 (specs --json+ jq covers selection); readiness is pull-only for tracker users (no outbound push). Bothflowctl.pycopies (canonicalscripts/+ 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), setupusage.md.
flow-next v1.11.0
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 carryevent: nulland never satisfy an event-specific check. Every receipt call site in the tracker-sync skill is tagged via the caller'sevent: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 reportingOK:<event>/MISSING:<event>per triggered touchpoint. MISSING iff the event triggered this run AND itstracker.perEventleaf is enabled AND the bridge is active AND no receipt with a matchingeventtag andtimestamp ≥ --sinceexists. 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:primeseeds GLOSSARY.md from the repo (fn-57 Package B, R10). When the glossary is absent or a husk (glossary list --jsontotal_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 viaflowctl glossary addonly after read-back approval (--fix-alldoes not bypass it). A populated glossary gets a coverage report line and is never rewritten — pruning stays with/flow-next:audit./flow-next:capturejoins 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 viaflowctl 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-scoutgain 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 ontotal_terms > 0. Every gate istotal_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-prend every run with a tracker-sync check + bounded retro-fire (R2). Each skill runssync checkindependently of the touchpoints (so a wholesale-skipped dispatch block is still caught), using an on-disk--sinceanchor (work → earliestclaimed_atthis run; capture → the spec'screated_at; make-pr → the PR'screatedAt) and a triggered-set--eventscontract (configured-but-not-triggered events are never MISSING). AnyMISSING:<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-stateTracker sync:slot —OK|MISSING:<event> → retro-fired → OK|MISSING:<event> (retro-fire failed: <reason>)|n/a (bridge inactive). An explicitn/aproves 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 singlePR_URL=line; work's stdout stays clean for harness parsing). Manual recovery guidance (read the receipt note, re-fire via/flow-next:tracker-synconce transport returns) documented intracker-sync.md./flow-next:make-pr§4.6b — deterministic post-create PR↔issue ref verify/repair (R4). §4.6a appends the non-closingRef <identifier>line to the local body file before create — but an agent that hand-rollsgh 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-linegrep -qixFmatcher as §4.6a, and repairs append-only viagh 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.mdUUID 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 forsync 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.shnow 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--eventcoverage intests/test_tracker_receipts.py; both wired into CI as explicit steps. Bothflowctl.pycopies (canonicalscripts/+ dogfood.flow/bin/) updated in lockstep (byte-identical invariant held). Docs:tracker-sync.md(observable+forcing lifecycle, MISSING-recovery),flowctl.md(sync check,--event), setupusage.mdexamples.
flow-next v1.10.2
Fixed
- Plugin homepage now points at the canonical product site
https://flow-next.devinstead of the stalehttps://mickel.tech/apps/flow-next. Thehomepagefield in.claude-plugin/marketplace.json,plugins/flow-next/.claude-plugin/plugin.json, andplugins/flow-next/.codex-plugin/plugin.json(plus the Codex manifest'sinterface.websiteURL) all carried the old URL;.cursor-plugin/plugin.jsonwas already correct, so the rest were just drift.author.url/owner.url(Gordon's personal site / GitHub) are unchanged. Also aligned theflow-next-tuipackagehomepageand the README "Visual overview" doc row (which redundantly listed both URLs) toflow-next.dev.
flow-next v1.10.1
Fixed
flowctl copilot impl-reviewno longer crashes withUnicodeDecodeErroron a repo containing a non-UTF-8 source subtree (#167 — the read-side counterpart to #123).find_references()(the symbol-cross-reference collector behindgather_context_hints) rangit grepover a fixed, broad extension set (*.c *.h *.cpp *.cs *.java *.py …) and decoded the hits with a hardtext=True, encoding="utf-8"and noerrors=. Becausegather_context_hintsextracts 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 carrying0xfcü /0xe4ä /0xf6ö /0xdfß — was enough to abort context gathering, even when every file you actively edit is UTF-8. The collector now capturesgit grepoutput 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).flowctlforces 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. fromcopilot plan-review'sprint(output)) (#167).main()now callssys.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 thePYTHONIOENCODING=utf-8workaround.
Changed
/flow-next:workVerify-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.pycopies (canonicalscripts/+ dogfood.flow/bin/) updated in lockstep (byte-identical invariant held). New regression suite:tests/test_cp1252_robustness.py(reproduces the cp1252find_referencescrash 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
Fixed
/flow-next:setupnow 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:setupwrote the$flow-next-planCodex command syntax into AGENTS.md and ran.codex/agent + hook setup, while the installer advertises Cursor usage as/flow-next:*. Setup now adds aCURSOR_AGENT+.cursor-plugin/plugin.jsonmanifest branch (ordered before theelse → codexfallback) →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:planslash-command snippet (Cursor runs the same commands; lands in AGENTS.md, which Cursor reads), resolvesflowctlvia.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 becauseCURSOR_AGENTis inherited by child processes — so Codex launched from a Cursor shell inherits it; the manifest (present only in a real~/.cursor/plugins/local/flow-nextinstall) plus a! -d ${PLUGIN_ROOT}/codexguard (a real Cursor install excludes thecodex/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 ascodex. For thatcodex/-absence proof to hold on re-install, the installers now produce a true mirror:install-cursor.shaddsrsync --delete-excludedandinstall-cursor.ps1explicitlyRemove-Items the excluded dirs afterrobocopy /MIR(plain--delete//MIR+/XDleave a pre-existingcodex/in place);test_install_cursor_parity.pylocks 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 acommentop (e.g.work.done/makePrwith earlier events disabled), the auto-create path created the issue and attached the tracker id but did not callsync set-merge-base/set-last-synced— and thecommentpath 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-baseBOTH halves +set-last-synced) at create time — the issue body we just wrote is therenderFlowToTrackeroutput, so the base is exact. (push-first auto-link was already covered by thepushskeleton's post-write snapshot; this makes thecomment/reconcile-first paths match.) Surfaced in PR #162 review. Codex mirror regenerated.