feat(ci): enforce issue traceability on the pull request - #600
Merged
Conversation
ADR-0022 moves traceability off the branch name, where it was a proxy with
perfect precision and poor recall, and onto the pull request, where the
predicate it stands in for was checked by nothing.
Validate Issue Link passes on three outcomes and says which applied, so an
exemption is visible in review rather than silent: an automation branch, the
new meta:no-issue label, or a reference in the body. It reads only the
pull_request event payload, so it needs no token and runs with permissions: {}.
Hoist the automation prefixes to workflow-level env. Validate Branch Name and
Validate Issue Link must agree on them, and a second inlined copy is how the
two silently diverge; the suite now asserts there is only one.
Add meta:no-issue to lib/labels.yml and runbooks/labels.md. ADR-0022 makes
applying it a maintainer decision, which the runbook records.
Steps 1 and 2 of #595. The context is not registered in the ruleset until it
has been observed on a real pull request, per runbooks/branch-protection.md,
and the branch pattern does not relax until after that.
Refs #595
The suite anchored its extractions on single-quoted YAML scalars. Trunk's pre-commit prettier hook rewrote the new env value to double quotes after the local run, so the pushed commit failed CI with the shape-change error while the pre-commit working tree had passed. Prettier owns YAML formatting here and rewrites scalar quoting at will, so strip one matching pair of surrounding quotes after extraction rather than depending on which style it last chose. Verified both ways: the suite passes with the value single-quoted and double-quoted, and still catches the prefixes being dropped. Refs #595
This was referenced Sep 2, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Steps 1 to 3 of #595, implementing
decisions/0022-issue-traceability-on-pull-requests.md.What lands
Validate Issue Link, a new job incommit-lint.yml. Three outcomes pass,and the job prints which applied, so an exemption is visible in review rather
than silent:
dependabot/,renovate/,copilot/,codex/meta:no-issue#123,owner/repo#123, or a full issue or pull-request URLIt reads only the
pull_requestevent payload, so it needs no token and runswith
permissions: {}. Either a closing keyword or a plain referencesatisfies ADR-0022, and both land in the body, so no API call is required.
meta:no-issueadded tolib/labels.ymlandrunbooks/labels.md. Therunbook records ADR-0022's constraint that applying it is a maintainer
decision: an agent may propose it and must not apply it on its own authority.
Automation prefixes hoisted to workflow-level env.
Validate Branch Nameand
Validate Issue Linkmust agree on them, and a second inlined copy isexactly how two checks silently diverge. The suite now asserts there is only
one definition.
Verification
scripts/test-commit-lint-policy.shgrew from 40 to 51 checks. Two of themmatter beyond the table:
lib/labels.ymlactually publishes, or applying it is impossible;
env.The suite did its job twice during this change. It failed first on the
extractor when the prefixes moved, which is the shape-change guard working.
Then it caught a real defect in the new pattern:
z-shell/.github#590, thecross-repository shorthand used throughout these issues, did not match. The
pattern now accepts all three reference forms.
Three further mutations, each reverted: renaming the exemption label to one
lib/labels.ymldoes not declare, droppingcopilot/codexfrom the sharedenv, and loosening the reference pattern to accept
#0. All three caught.actionlint,shellcheck -s bash,trunk check,validate-agent-policy.pyand the policy test suite are clean.
Ordering, which is part of the accepted decision
This pull request is step 3: the check runs here for the first time, on a real
pull request.
runbooks/branch-protection.mdnotes GitHub only accepts statuscontexts it has already observed, so step 4 registers
Validate Issue Linkin the
mainruleset only after this merges.Step 5, relaxing
Validate Branch Nameto a shape check here and inz-shell/zi, comes after step 4. Relaxing earlier would open a window withneither control active, which is the state ADR-0022 exists to close. Step 6
adds the ADR-0019 pointer and updates
AGENTS.md, and lands with step 5 so thepointer and the enforcement it describes arrive together.
Refs #595