flow-next v2.1.0
·
6 commits
to main
since this release
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.