Given / When / Then
Given an operator runs /release-sync vN.N.N after a release, which pushes a sync/main-to-dev-after-vN.N.N branch and opens the main→dev sync PR,
When the PR-creation command fires the validate-pr-create.sh PreToolUse hook,
Then the hook blocks with Branch 'sync/main-to-dev-after-vN.N.N' missing ticket ID — even though the /release-sync skill and apexyard#458 document that sync/ branches are exempt from the ticket-ID rule (the release being synced is the ticket).
Root cause
validate-pr-create.sh (branch-ticket-ID check, ~line 480) only exempts release-cut branches:
if echo "$CURRENT_BRANCH" | grep -qE '^release/v[0-9]+\.[0-9]+\.[0-9]+(-rc[0-9]+)?$'; then
The sync/main-to-dev-after-vN.N.N pattern is absent, so the elif ticket-ID check rejects it. validate-branch-name.sh already whitelists the sync type (#458), and the sibling release exemption exists in this very hook — the sync exemption was simply never added here. The PR-title check on the same hook already accepts the sync(#N): title shape, so the title path works; only the branch-ticket-ID path is wrong.
Repro
- On the framework repo, complete a release (release PR → merge → tag).
- Run
/release-sync vN.N.N — it creates the sync branch + opens the sync PR.
- Observe the PR-creation step blocked:
Branch 'sync/main-to-dev-after-vN.N.N' missing ticket ID.
(Encountered live during the v3.0.0 release; worked around with a local edit that this ticket lands properly.)
Fix
Add the sync-branch pattern to the exemption alternation, mirroring the release-cut exemption:
if echo "$CURRENT_BRANCH" | grep -qE '^release/v[0-9]+\.[0-9]+\.[0-9]+(-rc[0-9]+)?$|^sync/main-to-dev-after-v[0-9]+\.[0-9]+\.[0-9]+$'; then
Environment
- ApexYard framework repo (
me2resh/apexyard), dev branch
- Hook:
.claude/hooks/validate-pr-create.sh
- Related: apexyard#458 (sync type whitelist),
/release-sync SKILL, validate-branch-name.sh
Severity
Medium — blocks the mandatory post-release sync PR for every release until worked around; not data-affecting. The fix is a one-line addition to the exemption regex.
Glossary
| Term |
Definition |
| release-sync |
The mandatory main→dev sync PR after each squash-release, closing SHA divergence so future release PRs are conflict-free. |
| Ticket-ID exemption |
Branches whose name encodes no tracker ID because the work is the ticket (release-cut, release-sync) skip the branch-ticket-ID validator rule. |
Given / When / Then
Given an operator runs
/release-sync vN.N.Nafter a release, which pushes async/main-to-dev-after-vN.N.Nbranch and opens the main→dev sync PR,When the PR-creation command fires the
validate-pr-create.shPreToolUse hook,Then the hook blocks with
Branch 'sync/main-to-dev-after-vN.N.N' missing ticket ID— even though the/release-syncskill and apexyard#458 document thatsync/branches are exempt from the ticket-ID rule (the release being synced is the ticket).Root cause
validate-pr-create.sh(branch-ticket-ID check, ~line 480) only exempts release-cut branches:The
sync/main-to-dev-after-vN.N.Npattern is absent, so theelifticket-ID check rejects it.validate-branch-name.shalready whitelists thesynctype (#458), and the sibling release exemption exists in this very hook — the sync exemption was simply never added here. The PR-title check on the same hook already accepts thesync(#N):title shape, so the title path works; only the branch-ticket-ID path is wrong.Repro
/release-sync vN.N.N— it creates the sync branch + opens the sync PR.Branch 'sync/main-to-dev-after-vN.N.N' missing ticket ID.(Encountered live during the v3.0.0 release; worked around with a local edit that this ticket lands properly.)
Fix
Add the sync-branch pattern to the exemption alternation, mirroring the release-cut exemption:
Environment
me2resh/apexyard),devbranch.claude/hooks/validate-pr-create.sh/release-syncSKILL,validate-branch-name.shSeverity
Medium — blocks the mandatory post-release sync PR for every release until worked around; not data-affecting. The fix is a one-line addition to the exemption regex.
Glossary