Merge pull request 'fix: bind Refs parser to one token' (#252) from build/234-bind-refs-token into main

Reviewed-on: heavy-duty/ceremony#252
Reviewed-by: glm-bot-andresmgsl <andres+5@heavyduty.builders>
Reviewed-by: kimi-bot-andresmgsl <andres+4@heavyduty.builders>
Reviewed-by: claude-bot-andresmgsl <andres+1@heavyduty.builders>
This commit is contained in:
andres 2026-08-24 18:15:11 +00:00
commit 46458ba8cd
3 changed files with 33 additions and 8 deletions

View file

@ -208,14 +208,14 @@ claim_reclaim_marker() { # $1 = last activity epoch
refs_references() { # PR body on stdin -> local issue numbers named by Refs refs_references() { # PR body on stdin -> local issue numbers named by Refs
awk ' awk '
{ {
line = $0 rest = tolower($0)
lower = tolower(line) while (match(rest, /(^|[^[:alnum:]_-])refs[[:space:]:]+(#|([[:alnum:]_.-]+\/)?[[:alnum:]_.-]+#)[0-9]+/)) {
if (match(lower, /(^|[^[:alnum:]_-])refs[[:space:]:]+/)) { token = substr(rest, RSTART, RLENGTH)
line = substr(line, RSTART + RLENGTH) sub(/^.*refs[[:space:]:]+/, "", token)
if (line ~ /^(#|([[:alnum:]_.-]+\/)?[[:alnum:]_.-]+#)[0-9]+/) { print token
sub(/[.(;].*/, "", line) # Retain the token final byte so ^ cannot turn a concatenated
print line # alphanumeric suffix into a fresh keyword boundary (#234).
} rest = substr(rest, RSTART + RLENGTH - 1)
} }
} }
' | issue_references \ ' | issue_references \

3
changelog.d/234.md Normal file
View file

@ -0,0 +1,3 @@
### Fixed
- Refs-based issue-flow transitions now bind each declaration to its immediately following reference token, so later issue prose cannot release or preserve unrelated claims (#234).

View file

@ -101,6 +101,28 @@ check "empty labels do not exempt a claimed issue" 0 "SWEEP" claim_clock_exempt
refs_body=$'Refs #12\nAlso refs: #8 and heavy-duty/rig#4.\nCloses #99\nNot refs-ish #7\nfix refs parsing from #200\nCloses #40; refs: none\nRefs #175 (split from #150)' refs_body=$'Refs #12\nAlso refs: #8 and heavy-duty/rig#4.\nCloses #99\nNot refs-ish #7\nfix refs parsing from #200\nCloses #40; refs: none\nRefs #175 (split from #150)'
check "Refs parser returns only references owned by a valid Refs marker" 0 "" \ check "Refs parser returns only references owned by a valid Refs marker" 0 "" \
test "$(refs_references <<<"$refs_body")" = $'8\n12\n175' test "$(refs_references <<<"$refs_body")" = $'8\n12\n175'
# A Refs declaration binds one token, never the prose that follows it; every
# later occurrence starts a fresh declaration (#234).
# shellcheck disable=SC2016 # backticks are the fixture's literal Markdown
crew_round_line='- **Claude verified the safe `Refs #52`, TDD provenance, and inherited #65 CI failure.**'
check "Refs parser ignores issue prose after the bound token" 0 "" \
test "$(refs_references <<<"$crew_round_line")" = 52
check "Refs comma-list narrowing is deliberate" 0 "" \
test "$(refs_references <<<'Refs #8, #9')" = 8
check "a cross-repo Refs token stays non-local" 0 "" \
test -z "$(refs_references <<<'Refs heavy-duty/rig#4')"
check "prose after a cross-repo Refs token stays non-local" 0 "" \
test -z "$(refs_references <<<'Refs heavy-duty/rig#4, #12')"
check "parenthesized prose after a local Refs token is ignored" 0 "" \
test "$(refs_references <<<'Refs #175 (split from #150)')" = 175
check "every Refs occurrence on one line contributes its bound token" 0 "" \
test "$(refs_references <<<'Refs #8. Refs #9.')" = $'8\n9'
check "a concatenated Refs spelling is not a second keyword occurrence" 0 "" \
test "$(refs_references <<<'Refs #8Refs #9')" = 8
check "lowercase refs in unrelated prose declares nothing" 0 "" \
test -z "$(refs_references <<<'fix refs parsing from #200')"
check "Refs without a following token declares nothing" 0 "" \
test -z "$(refs_references <<<'Closes #40; refs: none')"
open_records=$'BODY\tRefs #5\nCLOSING\t9\nBODY\tRefs heavy-duty/rig#112\nBODY\tRefs #5\nCLOSING\t5' open_records=$'BODY\tRefs #5\nCLOSING\t9\nBODY\tRefs heavy-duty/rig#112\nBODY\tRefs #5\nCLOSING\t5'
check "open PR linkage unions closing and local Refs body references" 0 $'5\n9' \ check "open PR linkage unions closing and local Refs body references" 0 $'5\n9' \
open_pr_issues <<<"$open_records" open_pr_issues <<<"$open_records"