From 07bfbf4840b9d3c312e1e4a4c9d4d452d57b9399 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 18 Sep 2026 10:23:06 +0000 Subject: [PATCH] ci(duplicate-fix-guard): delimit the branch-name match so a longer card number cannot prefix-match MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The branch-name advisory asked `branch.includes(`issue-${n}`)`, an undelimited substring test, so a declared card number that is a PREFIX of the number in the branch name satisfied it: declaring card 186 from `claude/issue-18611-x` kept the advisory silent, which is exactly the case it exists to warn about — a fix branch naming a DIFFERENT card. The match now carries the same `(-|$)` alternation the documented pre-check uses, and the :79 comment restates that pre-check in that spelling. Advisory semantics are unchanged: still `core.warning`, never red. Probe of the predicate lifted verbatim out of the file, before -> after: `claude/issue-18611-x` warns false -> true; `claude/issue-186-real`, `claude/issue-186`, `feat/x`, `claude/issue-1186-x` and `claude/issue-0186-x` unchanged. Claude-Session: https://claude.ai/code/session_01BTeBejoPUvRHN8WdAJC6oF Co-authored-by: Claude --- .github/workflows/duplicate-fix-guard.yml | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/.github/workflows/duplicate-fix-guard.yml b/.github/workflows/duplicate-fix-guard.yml index d65954ee247..9d604938d48 100644 --- a/.github/workflows/duplicate-fix-guard.yml +++ b/.github/workflows/duplicate-fix-guard.yml @@ -78,11 +78,17 @@ jobs: // Branch-name convention (advisory, never red): a fix branch named // `claude/issue--` is discoverable by the next session - // with one `git ls-remote | grep issue-`. #4555 vs #4559 - // happened partly because the branches shared no token to grep. + // with one `git ls-remote --heads origin | grep -E 'issue-(-|$)'`. + // #4555 vs #4559 happened partly because the branches shared no + // token to grep. Both spellings delimit the number on the RIGHT: + // undelimited, `issue-186` matches `claude/issue-18611-x`, so the + // advisory stays silent for a branch naming a DIFFERENT card — + // the false negative. The `$` arm keeps the slug-less spelling + // `claude/issue-186` matching; `issue-` anchors the left, so + // `issue-1186` and `issue-0186` do not match card 186 either. // Warning only — existing branches must not go red retroactively. const branch = pr.head.ref; - if (![...mine].some((n) => branch.includes(`issue-${n}`))) { + if (![...mine].some((n) => new RegExp(`issue-${n}(-|$)`).test(branch))) { core.warning( `Branch \`${branch}\` does not name any declared issue. ` + `Convention: claude/issue-- (e.g. claude/issue-${[...mine][0]}-short-slug) ` +