Conversation
The Lint Commits caller declared workflow-level `permissions: {}` and then
called `commit-lint.yml`, whose `commit-message` job requests `contents: read`.
A called workflow cannot hold more permission than its caller job, so every run
was rejected at run creation: 20 of 20 recent runs recorded `startup_failure`
with zero check runs and no logs, and the commit-message, PR-title, and
branch-name policy was never evaluated.
Collapse the caller into `commit-lint.yml`, which now triggers on
`pull_request` into `main` and keeps `workflow_call` for other repositories.
That is the shape used by the other reusable suites here and by z-shell/zi,
where the same three jobs pass.
`workflow_call` input defaults do not apply to a `pull_request` run, so the
patterns now fall back in the job step. Without that, the empty trailer pattern
would match every commit and the empty branch pattern would pass every branch.
Drop the unused `pull-requests: read` from the commit-message job; it reads git
only, and a lower ceiling is one less permission a future caller must grant.
Closes #575
Learning capture for #575. A caller workflow with `permissions: {}` caps every nested job at no permissions, so the run is rejected at creation with no logs and actionlint stays silent. Record the failure shape, the two-repository precedent for self-triggering shared workflows, and the workflow_call input default trap that comes with them.
The PATTERNS.md addition in this branch feeds test_repair_2_consumer_parser_outputs_match_frozen_golden, which hashes the visible markdown of seven consumer surfaces. Refresh the digest the same way #582 did for its skill edit. Verified the golden passes unchanged against PATTERNS.md from main, so the branch content is the only input that moved.
This was referenced Sep 2, 2026
ss-o
added a commit
that referenced
this pull request
Sep 2, 2026
The digest covers seven consumer surfaces, PATTERNS.md and .github/README.md among them, so editing any of them fails Validate Agent Instructions with nothing but two bare SHA-256 strings. Nothing in AGENTS.md, runbooks, decisions, or the scoped instructions records that, so #582 and #586 both discovered the regeneration step by failing CI. Attach the seven paths and the procedure to the assertion's msg=, where the person who needs it is already looking. One argument covers every surface. Closes #588
This was referenced Sep 2, 2026
ss-o
added a commit
that referenced
this pull request
Sep 2, 2026
Validate Branch Name became a blocking required check here after #586, and it rejected two shapes that are not a naming discipline problem. copilot/ and codex/ join dependabot/ and renovate/ in the always-allowed prefixes, because a coding agent picks those names rather than the pull-request author. The pattern becomes ^(feature|bug|hotfix)-[1-9][0-9]*(-[a-z0-9]+)*$, so a descriptive slug may follow the issue id, which the old trailing anchor rejected on branches such as feature-478-repo-settings-audit. The issue id stays mandatory for author-chosen branches, so decisions/0019 is unchanged in substance. Shapes carrying no issue id at all, code/, fix/, feat/, docs/, ci/, chore/, remain rejected; admitting those would reverse the issue-linked naming the ADR decided and belongs in an ADR amendment. Verified with a table over 18 branch names covering both new allowances, the existing bot prefixes, next, and the shapes that must keep failing. Closes #590
This was referenced Sep 2, 2026
ss-o
added a commit
that referenced
this pull request
Sep 2, 2026
Three defects have shipped in commit-lint.yml. #575 could not start at all and took 53 runs to notice. The empty-pattern trap found during #586 would have flagged every commit and passed every branch. #587 failed open on a large commit message. Two of the three were silent, and nothing automated caught any of them. Add a suite that extracts every pattern from the workflow rather than restating it, so the test cannot drift into a second source of truth, and assert the constructs as well as the patterns: no grep -q on the trailer pipeline, an in-step fallback for each pattern, and no workflow_call input default that a pull_request run would ignore. Verified by mutation. Six deliberate regressions were introduced one at a time and every one failed the suite: reintroducing grep -q, removing a fallback, loosening the branch pattern to accept feature-0, dropping the copilot and codex prefixes, widening the trailer pattern to ban human co-authors, and raising the subject cap past 72. Closes #592
This was referenced Sep 2, 2026
ss-o
added a commit
that referenced
this pull request
Sep 2, 2026
Section 4 required a default on every workflow_call input. Two shipped workflows contradict that for two independently correct reasons. zsh-lint.yml declares both its inputs required, and a default on a required input is unreachable because the caller always supplies the value. commit-lint.yml declares workflow_call alongside pull_request. GitHub scopes the inputs context to a reusable or manually triggered workflow, so on a pull_request run it is empty and the declared defaults never apply. #586 removed them for that reason; #597 now asserts no such default exists. Split the bullet into three clauses so the rule matches both shapes. This is a mandatory surface, so as written an agent would have edited both workflows back into defects. Instruction impact review is recorded in the pull request. Closes #598
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.
Root cause
lint-commits.ymldeclared workflow-levelpermissions: {}and then calledcommit-lint.yml, whosecommit-messagejob requestscontents: read. Acalled workflow's jobs cannot hold more permission than the caller job, so
GitHub rejected the run at creation time. Every run since the workflow landed
in #517 recorded
startup_failure:No check runs and a 404 on the logs endpoint, which is why the failure stayed
invisible.
actionlintpasses the pair cleanly, so nothing local caught it.The other two causes suggested in #575 are not involved. The regex defaults are
single-quoted YAML scalars and parse literally, and a local
./reusablereference resolves normally for a same-repository
pull_request.Fix
commit-lint.ymlnow carries thepull_requesttrigger and concurrency groupitself and keeps
workflow_callfor other repositories.lint-commits.ymlisdeleted. That is the shape already proven in this repository by
labels-sync-test.yml,repo-settings-audit-test.yml, andlabeler-config-audit-test.yml, and inz-shell/zi:.github/workflows/commit-lint.yml,where the same three jobs report success.
A second defect would have surfaced the moment the workflow started running.
workflow_callinput defaults are not applied to apull_requestrun, wherethe
inputscontext is empty, soDISALLOWED_TRAILER_PATTERNandBRANCH_PATTERNwould both have expanded to the empty string. An emptygrep -Epattern matches every line, which means every commit would have beenflagged as carrying a bot trailer and every branch name would have passed
silently. The fallbacks now live in the job steps as
: "${VAR:=default}", andthe
on.workflow_call.inputs.*.defaultvalues are gone so there is one sourceof truth per pattern.
The unused
pull-requests: readis dropped from thecommit-messagejob. Itreads git history only, and a lower ceiling is one less permission a future
caller has to grant.
PATTERNS.mdrecords the caller-permission ceiling and the input-default trap.Verification
actionlintandtrunk checkare clean on both files.[bot]trailer is blocked,a human
Co-authored-byis allowed, a plain subject is unaffected, andbug-575matches the branch pattern whilecode/fooandnextdo not.errors=0 checked=2.Validate Commits,Validate PR Title, andValidate Branch Nameshould all appearand pass here for the first time.
Follow-up for a maintainer
mainruleset still requires no status checks. Once the three contextsare observed on this pull request they can be added to
required_status_checks.runbooks/branch-protection.mdnotes that GitHubonly accepts contexts it has already seen. Because the workflow is no longer
nested, the contexts are
Validate Commits,Validate PR Title, andValidate Branch Name, without acommit-lint /prefix.code/*orcodex/*branch will failValidate Branch Nameagainst^(feature|bug|hotfix)-[1-9][0-9]*$from decisions/0019. That is the policyworking rather than a regression from this change. Widening the pattern is a
separate decision.
Closes #575