tracker-sync: reserve Linear Done for merged PRs; In Review after make-pr — fn-66#178
Conversation
…d In Review rung - status-sync.md flow→normalized map is now flowToNormalized(spec, prEvidence): terminal done/verified require a MERGED PR probe; local completion necessary, not sufficient (R1). Open PR → in-review rung (R2); closed-unmerged → non-terminal + NEEDS_HUMAN (R6). who-wins / deadlock-first ordering untouched. - linear-ladder.md + github.md + adapter-interface.md updated in lockstep: transport-blind terminal-write-requires-merge-evidence invariant (R8). - Worked fixtures S-G..S-J with EXACT expected states: no-PR all-done → stays In Progress (no advance); open-PR → In Review; merged-PR → Done; closed-unmerged → non-terminal + NEEDS_HUMAN (R7). - Regenerated Codex mirror. Task: fn-66-tracker-sync-reserve-linear-done-for.1 Claude-Session: https://claude.ai/code/session_01A295VQ42CDSgVTTPgkBY4x
…s/probe-error; S-G preserve rule Addresses impl-review NEEDS_WORK (3 findings): - in-review rung now has an explicit reconcile-loop branch (was only in the flow→normalized table; S-H setStatus(in-review) previously fell through to conflictTiebreak). Push fires only on a real open-PR signal. - S-G no-PR preserve rule promoted from fixture-only to policy: prEvidence=none projects in-review but the loop KEEPS an existing valid non-terminal state (no forced in-progress→in-review advance, no terminal). - prEvidence enum extended with `ambiguous` + `probe-error`; both (and closed-unmerged) route to a single non-terminal + NEEDS_HUMAN branch. Unknown branch_name / gh failure is probe-error, never `none`/`merged`. Terminal reachable ONLY from unambiguous MERGED. S-J extended to cover them. - Regenerated Codex mirror. Task: fn-66-tracker-sync-reserve-linear-done-for.1 Claude-Session: https://claude.ai/code/session_01A295VQ42CDSgVTTPgkBY4x
…minal / makePr→In Review / land.merged→Done-on-merge (fn-66.2) - completionReview (work phases.md 3g + retro-fire + SKILL table): comment-shaped verdict/R-ID coverage, NEVER terminal Done; ceremony seeds completionReview=comment (R4) - makePr: In Review status push rides the unconditional bridge-active PR-link path, not gated behind perEvent.makePr (R2) - land.merged: SOLE Done driver, active-by-default when bridge active, self-checks the GitHub MERGED probe before terminal write (R3/R10) - steps.md push/reconcile setStatus: merge-evidence gate via flowToNormalized(spec, prEvidence); manual reconcile MAY terminal-write Done iff MERGED (per-write invariant) - flowctl.py land.merged default documented (active-by-default, MERGED-gated); schema default stays off (fn-52.1 invariant); +test_land_tracker_event.py round-trip - docs/tracker-sync.md: invert spec-completion-review-owns-Done claim; perEvent table + unconditional-paths prose updated - Codex mirror regenerated; bundled .flow/bin/flowctl.py synced (dual-copy invariant) - full suite (1110) + ci_test.sh (67) green Task: fn-66-tracker-sync-reserve-linear-done-for.2 Claude-Session: https://claude.ai/code/session_01A295VQ42CDSgVTTPgkBY4x
… fix stale Done-owner prose (fn-66.2) - land.merged: TRACKER_TERMINAL_OK now selects the dispatch op explicitly (push on clean MERGED, comment-only + NEEDS_HUMAN otherwise) — land no longer trusts the caller's merge claim (review #2, R3) - land workflow.md: fix collapsed list item (RELEASED.4. → separate line) (review #5) - docs/tracker-sync.md recovery: work.completionReview recovered via comment, not push (review #3, R4) - github.md: closing-ref bypass prose → land.merged Done projection, not spec-completion-review (review #4) - docs/teams.md + flowctl.md: invert completionReview-owns-Done claims; land.merged active-by-default; make-pr In Review unconditional - Codex mirror regenerated (land/workflow.md, github.md) Task: fn-66-tracker-sync-reserve-linear-done-for.2 Claude-Session: https://claude.ai/code/session_01A295VQ42CDSgVTTPgkBY4x
…eremony + dispatch grammar (fn-66.2) - steps.md:56 duplicate discovery ceremony seed: completionReview reconcile → comment; line-60 'one exception' → 'two exceptions' (make-pr link/In Review + land.merged) (review #1, R4/R10) - make-pr dispatch grammar: operation token back to canonical 'operation: push <spec-id>, event: makePr' (PR URL / In Review as evidence prose, not in the op token); same for the §5.7 retro-fire path (review #2, R2) - work/phases.md completionReview dispatch examples: drop 'verdict + R-ID coverage' from the op token → canonical 'operation: comment <spec-id>, event: work.completionReview' - Codex mirror regenerated Task: fn-66-tracker-sync-reserve-linear-done-for.2 Claude-Session: https://claude.ai/code/session_01A295VQ42CDSgVTTPgkBY4x
…ional paths (fn-66.2) - flowctl.py:1024 header comment no longer claims a stray enabled=true 'does nothing until a specific event is opted in' — calls out the two fn-66 unconditional bridge-active paths (make-pr link/In Review + land.merged Done-on-merge) (review #1, R10) - bundled .flow/bin/flowctl.py synced (dual-copy invariant) Task: fn-66-tracker-sync-reserve-linear-done-for.2 Claude-Session: https://claude.ai/code/session_01A295VQ42CDSgVTTPgkBY4x
…t NO_WORK (fn-66.3) - All-done + open PR: explicit greppable PILOT_VERDICT=DEFERRED_TO_LAND (stage=land), not a silent skip→NO_WORK collapse - All-done + no PR (FLOW-15 case): always classifies make-pr, never NO_WORK - Closed-unmerged / missing-branch / merged-but-open-spec stay NEEDS_HUMAN - Register DEFERRED_TO_LAND in SKILL.md verdict grammar + land stage; update classification table + crash-class note - Regenerate Codex mirror Task: fn-66-tracker-sync-reserve-linear-done-for.3
…r (fn-66.3) - ralph.md Codex /goal verdict grammar + Claude /goal recipe now name DEFERRED_TO_LAND and route it to land, not a pilot re-run Task: fn-66-tracker-sync-reserve-linear-done-for.3
…ion bump 2.1.2 - audit confirms fn-66.1/.2/.3 already inverted tracker-sync.md/teams.md "completion-review owns Done" → "land.merged owns Done" + In Review documented - decision record Consequences: In Review actively projected at make-pr; Done gated on GitHub MERGED probe (projection-not-coordination unchanged) - CHANGELOG 2.1.2 (Fixed: merge-evidence gate + In Review; Changed: pilot DEFERRED_TO_LAND) - version bump 2.1.1 → 2.1.2 across all manifests; Codex mirror regenerated Task: fn-66-tracker-sync-reserve-linear-done-for.4 Claude-Session: https://claude.ai/code/session_01A295VQ42CDSgVTTPgkBY4x
…use stale pre-merge MERGED_PR_NUM (fn-66 R3/R10, completion-review)
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d17861278e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…open-PR→In Review and merged→Done precede local task/completion rows (fn-66, PR #178 review) Two P1s: (A) all-done OPEN spec + open PR mapped in-progress not in-review (make-pr push no-op); (B) ungated/unknown-completion merged spec stayed in-review so land.merged never wrote Done. Reordered the table prEvidence-first; added fixtures S-K/S-L. Codex mirror regenerated.
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d6d9d593bc
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
…not push (full re-render clobbers tracker edits) — fn-66, PR #178 review push(spec) renders the full spec body + writeIssue before status, so opening a PR could overwrite human tracker-side edits just to flip In Review. reconcile runs the 3-way body merge that preserves edits and sets In Review in the same op. Codex mirror regenerated.
|
@codex review |
|
Codex Review: Didn't find any major issues. 👍 Reviewed commit: ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
If Codex has suggestions, it will comment; otherwise it will react with 👍. Codex can also answer questions or update the PR. Try commenting "@codex address that feedback". |
What & why
tracker-sync pushed Linear
Doneon local Flow completion (all tasks done + completion-reviewSHIP) even with no merged PR — a SapienXT spec with no PR landed on the board asDoneand a human had to drag it back.Doneis a claim that the work shipped, so this was a correctness bug, not cosmetic.This makes the status policy lifecycle-accurate:
Doneis reserved for merge-confirmed PRs, an open PR maps toIn Review, completion-review never completes the issue, and pilot never declaresNO_WORKfor an all-done spec that hasn't shipped.R-ID coverage
flowToNormalized(spec, prEvidence); terminalDoneneedsMERGEDevidencestatus-sync.mdIn Reviewon the unconditional bridge-active PR-link pathmake-pr/workflow.mdland.merged→Doneonly on a fresh post-mergeMERGEDre-probe (sole driver)land/workflow.mdwork/phases.md, tracker-syncSKILL.md/steps.mdmake-pr; open PR →DEFERRED_TO_LAND; neverNO_WORKpilot/workflow.mdDone(NEEDS_HUMAN/non-terminal)status-sync.md,pilot/workflow.mdstatus-sync.mdgithub.md,adapter-interface.mdland.mergedactive-by-default when bridge active; per-write merge-evidence invariant incl. manual reconcileflowctl.py,test_land_tracker_event.pyCritical changes — where to look
references/status-sync.md— the policy core:flowToNormalized(spec, prEvidence)with aprEvidenceenum (merged|open|closed-unmerged|none|ambiguous|probe-error); terminal impossible withoutMERGED; In Review rung; fixtures S-G..S-J. Who-wins / deadlock ordering untouched (gate is upstream).flow-next-land/workflow.md—land.mergedis the sole Done driver, active-by-default when the bridge is active, and (completion-review fix) re-probesMERGEDfresh after the merge rather than reusing the stale pre-mergeMERGED_PR_NUM(which is empty on the normal OPEN→merge path — would've silently skipped the Done push).flow-next-work/phases.md+ tracker-syncSKILL.md/steps.md— completionReview dispatchreconcile→comment; setStatus merge-evidence guard.flow-next-make-pr/workflow.md— In Review on the unconditional PR-link path.flow-next-pilot/workflow.md+SKILL.md— newDEFERRED_TO_LANDverdict (open PR), no-PR all-done → make-pr, neverNO_WORK.flowctl.py(+ dogfood copy) —land.mergeddefault; newtest_land_tracker_event.py. Codex mirror regenerated; flow-next.dev updated (gmickel/flow-next.dev@5c53197, 2.1.2).Decision context
The merge-evidence gate is a per-write invariant on the outbound terminal write — no touchpoint or manual
/flow-next:tracker-syncreconcile writesDonewithout aMERGEDprobe (so a manual reconcile can still recoverDoneonce a merge exists). Three distinct evidence-backed states end to end: done locally (In Progress) → in review (open PR) → shipped (merged). Two bugs caught + memory'd during the work: the policy-map needing a matching reconcile branch; and "invert a policy claim → sweep ALL surfaces" (both ceremony copies, docs, CLI header).Verification
python3 -m unittest discover -s plugins/flow-next/tests, 1110);ci_test.sh67/0.land.mergedactivation, theflowToNormalized(spec, prEvidence)shape, per-write recovery).MERGED_PR_NUMDone-skip (R3/R10).🤖 Generated with Claude Code via
/flow-next:make-pr