A mixed-case actions/cache reference can bypass the canonical workflow contract while still executing the same GitHub Action. A future workflow edit could therefore restore an older Bun or Playwright snapshot on main, republish its unreachable contents under the new lock key, and leave every contract test green. Every standards consumer inherits this blind spot.
Evidence
packages/standards-cli/src/cli.test.ts inventories cache steps with the case-sensitive predicate step.uses.startsWith('actions/cache'). In a disposable worktree at PR #262 repair head a21bc1a, adding sibling Actions/cache/restore@v4 steps for Bun and Playwright with unconditional prefix fallbacks left all four focused cache-contract tests green. The same mutation also passed at the repair base 977c2dfd, so the gap predates the repair and does not belong in its bounded fix round.
GitHub resolves repository and action names without this casing distinction. Both Actions/cache@v4 and actions/cache@v4 resolved to commit 0057852bfaa89a56745cba8c7296529d2fc39830 through the GitHub API and Git transport.
Concrete failure
A later canonical edit adds Actions/cache/restore@v4 before either approved restore step. On main after bun.lock changes, the approved exact restore misses, the mixed-case sibling prefix-restores the previous snapshot, and the existing lowercase save republishes inherited packages or browser families under the new exact key. The contract continues to pass because it never inventories the sibling step.
Suggested verification
Normalize each uses value before identifying actions/cache steps. Add uppercase and mixed-case sibling mutations for both Bun and Playwright, then require the focused cache-contract tests to reject every mutation. Run the full gate afterward.
Found while verifying #262.
A mixed-case
actions/cachereference can bypass the canonical workflow contract while still executing the same GitHub Action. A future workflow edit could therefore restore an older Bun or Playwright snapshot on main, republish its unreachable contents under the new lock key, and leave every contract test green. Every standards consumer inherits this blind spot.Evidence
packages/standards-cli/src/cli.test.tsinventories cache steps with the case-sensitive predicatestep.uses.startsWith('actions/cache'). In a disposable worktree at PR #262 repair heada21bc1a, adding siblingActions/cache/restore@v4steps for Bun and Playwright with unconditional prefix fallbacks left all four focused cache-contract tests green. The same mutation also passed at the repair base977c2dfd, so the gap predates the repair and does not belong in its bounded fix round.GitHub resolves repository and action names without this casing distinction. Both
Actions/cache@v4andactions/cache@v4resolved to commit0057852bfaa89a56745cba8c7296529d2fc39830through the GitHub API and Git transport.Concrete failure
A later canonical edit adds
Actions/cache/restore@v4before either approved restore step. On main afterbun.lockchanges, the approved exact restore misses, the mixed-case sibling prefix-restores the previous snapshot, and the existing lowercase save republishes inherited packages or browser families under the new exact key. The contract continues to pass because it never inventories the sibling step.Suggested verification
Normalize each
usesvalue before identifyingactions/cachesteps. Add uppercase and mixed-case sibling mutations for both Bun and Playwright, then require the focused cache-contract tests to reject every mutation. Run the full gate afterward.Found while verifying #262.