fix: guard cross-repo issue references #63
No reviewers
Labels
No labels
attention
blocked
blocker:ci-red
blocker:conflict
blocker:drill-pending
blocker:unrequested
bug
claimed
documentation
enhancement
epic
merge-next
needs-ruling
needs-triage
offsite
post-merge
ready
release
scope:docs
scope:guards
scope:labels
scope:release-flow
stale
state:addressing
state:bots-reviewing
state:building
state:needs-human
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: heavy-duty/ceremony#63
Loading…
Reference in a new issue
No description provided.
Delete branch "build/61-cross-repo-reference-guards"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #61
Summary
Worklog
FLAG_CROSS_REPOprecedence and theblocked-cross-repoAPI-edge comment.blocked-cross-repocomment is idempotent across two sweeps.## Unreleased.Acceptance criteria
epic_referenceson the real #1 task list omits#112and retains every local reference.rig#112andheavy-duty/box#9drop;(#13),#14/#15, and#11, #12survive.FLAG_CROSS_REPO.FLAG_CROSS_REPO.Verification
bash test/issueflow-reconcile.test.sh— 50 passed, 0 failedbash test/run.sh— 13 test files passed, 0 failedbash .github/scripts/shellcheck-all.sh— 29 tracked scripts cleanbash .github/scripts/actionlint-all.sh— 6 workflows cleanepic_references—2–16, 18, 19, 23, 24, 30, 32, 50, 55–58, 61; no phantom112DRY_RUN=1sweep completed against the live repository3935bf8🔎 reviewing head
3935bf82d9🔎 reviewing head
3935bf82d9Verdict: approve
Reviewed against #61 (acceptance criteria + D1–D5) at head
3935bf82d9a76e03a28ac8954c77f1a973d4343f.Spec / acceptance
issue_references+blocked_reference_records/epic_referencesrig#112/heavy-duty/box#9drop;(#13),#14/#15,#11, #12survive (D2)FLAG_CROSS_REPO, not READY / FLAG_UNPARSEABLE (D3)FLAG_CROSS_REPO(false-promotion pin)blocked-cross-repocomment idempotent across two sweepsensure_commentmarker## UnreleasedLive epic #1 body through
epic_references:2–16, 18, 19, 23, 24, 30, 32, 50, 55–58, 61— no phantom112. Cross-repo link token classifies asCROSS\trig#112.Correctness notes
FLAG_CROSS_REPOis checked before empty-refs / READY, so a declaration that only names siblings cannot promote and is not misdiagnosed as unparseable.FLAG_CROSS_REPO(no label flip) — matches “triage flips by hand.”Verification (this review)
bash test/issueflow-reconcile.test.sh— 50 passed, 0 failedbash test/run.sh— 13 test files passed, 0 failedNon-blocking
None that gate merge. Optional later polish:
blocked_referencesandblocked_cross_referenceseach re-walk the body; a single parse into locals + cross would be slightly cheaper, not required by the issue.Meets every acceptance row of #61. Approve.
Approve — head
3935bf82d9a76e03a28ac8954c77f1a973d4343f.Reviewed against issue #61's spec and acceptance criteria; all seven hold, verified by running rather than reading:
issue_references(actions/issueflow-reconcile/issueflow-reconcile.sh:108) classifies the whole token before number extraction; bothblocked_referencesandepic_referencesroute through it. Two parsers, one regex — the drift class is closed.rig#112,heavy-duty/box#9, and[rig#112](…)classify CROSS;(#13),#14/#15,#11, #12classify LOCAL. Also confirmed a PR-URL with a#issuecomment-…fragment yields no phantom reference, and#10'spossessive prose still parses local. Each spec'd shape is also pinned by its own test case.FLAG_CROSS_REPOtakes precedence over bothREADYandFLAG_UNPARSEABLE, with the all-local-closed-plus-cross-repo false-promotion case pinned explicitly — and theblocked-cross-repocomment is a distinct diagnosis, not the unparseable one.2–16, 18, 19, 23, 24, 30, 32, 50, 55–58, 61—#112absent, nothing else lost.+38 −0on the test file); the full issueflow suite passes unmodified:bash test/issueflow-reconcile.test.sh→ 50 passed, 0 failed.blocked-cross-repocase passes against a fakegh; the marker mechanism is the sameensure_commentused by every other warning.## Unreleasedper the house convention.Suite caveat, not caused by this PR:
bash test/run.shshows 5 failing test files, allpackage-jsoncases, and they fail identically on a cleanmaincheckout — this environment has no node/npm, and the affected code paths are untouched by this diff. shellcheck/actionlint binaries are likewise absent locally, so those two verification lines I take from the PR's report plus CI.One non-blocking observation:
FLAG_CROSS_REPOalso fires when local blockers are still OPEN, so an issue that is legitimately blocked on open locals and names a cross-repo dep gets the "triage flips by hand" comment a little early. It is one idempotent comment and the advice is not wrong; the builder may consider gating the flag behind "locals resolved" if the noise ever matters.Ship it.
🔎 reviewing head
3935bf82d9Approve — head
3935bf8.I verified rather than opined: ran the suites, probed the classifier with adversarial inputs, and re-ran the parser against the live epic body.
What I ran and saw:
bash test/issueflow-reconcile.test.sh— 50 passed, 0 failed.bash test/run.sh— 13 files passed..github/scripts/shellcheck-all.shclean. All required checks green on3935bf8.epic_references:2–16, 18, 19, 23, 24, 30, 32, 50, 55–58, 61— no phantom112, matching the PR's recorded verification even on the newer body. The fixture carries thePR [rig#112](…)row verbatim per the corpus rule.[rig#112](url)in a link label → CROSS;(heavy-duty/box#9), #11,#12→ cross dropped, locals kept;Blocked by rig#9(the false-promotion body from the issue) →FLAG_CROSS_REPO, neverREADY; a URL fragment like#issuecomment-99matches nothing. The awk is mawk-safe (index/substr, no escapes).issue_referenceshelper feeds both parsers;FLAG_CROSS_REPOtakes precedence inblocked_decisionbefore the empty-refs check, so a cross-only declaration can never be misdiagnosedFLAG_UNPARSEABLE; the third argument defaults empty so existing two-arg calls are untouched. The comment interpolation is injection-safe by construction — the token regex admits no backticks, quotes, or$.Non-blocking observations (no action required for this PR):
blocked_reference_recordstruncates at the first.— which a markdown link's URL always contains.Blocked by [rig#112](https://github.com/…) and #14.therefore drops the trailing local#14. The decision is stillFLAG_CROSS_REPO(conservative, stays blocked), and this is strictly better than pre-PR behavior, which read a phantom local#112from the same shape. If link-wrapped refs inBlocked byprose ever become house style, the truncation deserves its own discussion — it predates this PR and is out of scope here.cross_refsis non-empty,reference_statesis still called on the local refs though the result is unused — a few wasted API calls per sweep, harmless.a/b/c#9classifies CROSS (correct) but the comment names it asb/c#9— cosmetic, unreachable with real GitHub owner/repo names.Every acceptance criterion on #61 is met and pinned by a test that would fail without the fix. Ship-worthy; over to the human once the panel converges.
Closing round summary
What shipped
FLAG_CROSS_REPOand posts the idempotentblocked-cross-repotriage comment.TRIAGE.md, and the behavior change is recorded underCHANGELOG.md→Unreleased.Rounds
3935bf8): shipped the implementation and additive contract coverage. Grok, Kimi, and Claude each approved this exact head. No corrective commit was required after review; all observations were explicitly non-blocking.Verified
bash test/issueflow-reconcile.test.sh— 50 passed, 0 failedbash test/run.sh— 13 test files passed, 0 failed in the builder environment and CI2–16, 18, 19, 23, 24, 30, 32, 50, 55–58, 61; no phantom112DRY_RUN=1sweep against the live repository3935bf8; PR reports clean and mergeablePost-merge residue
No merge blocker remains. Reviewers recorded optional follow-up observations only: the blocker parser's pre-existing period-based sentence truncation around Markdown URLs; duplicate body walks / avoidable local-state API calls when cross-repo refs already determine the outcome; potentially early but harmless
FLAG_CROSS_REPOsignaling when open local blockers coexist; and cosmetic rendering of degenerate multi-slash repository tokens. Per scope discipline, none was folded into #61.