Skip to content

ci: gates read workflows with yq (Y-1), then KYAML pilot (Y-3) - #1115

Merged
hyperpolymath merged 4 commits into
mainfrom
feat/kyaml-pilot-provisioning-gate
Oct 1, 2026
Merged

hyperpolymath merged 4 commits into
mainfrom
feat/kyaml-pilot-provisioning-gate

Conversation

@hyperpolymath

@hyperpolymath hyperpolymath commented Oct 1, 2026 •

Copy link
Copy Markdown
Owner

What

YAML-POLICY Y-1: the gates that judge a workflow now get their verdict from a YAML parser (yq) instead of a line grep.

Update: the Y-3 pilot (provisioning-check-reusable.yml converted to KYAML) was taken out of this PR by revert 37d67cc8. governance / Workflow security linter (a required check) runs the duplicate-key checker from a standards checkout pinned at 317101e (governance-reusable.yml lines 417/1248/1355), not this PR's fixed copy, so the KYAML file false-failed. The pilot moves to a follow-up PR that bumps that pin to this PR's merge commit and converts the file together (branch feat/kyaml-pilot-provisioning-convert). The pilot evidence below describes that follow-up.

This is a single-file pilot. It is not the scope ruling in #1023 (KYAML step 4/6). It adds evidence for that ruling and for #1022. The comment proof is #1021's harness.

Why the gates had to come first

On a KYAML workflow, each of these gates either falsely failed a correct file (the quote and comma ended up inside the captured ref, or ^permissions: never matched) or went blind (it never saw a uses: inside { … }):

Gate KYAML failure before Now
.githooks/validate-actions-lock.sh false-fail (…@sha",) yq; an unparseable file fails closed
.githooks/validate-permissions.sh (pre-commit and pre-push) false-fail (^permissions:) yq has("permissions"); falls back to grep with a warning if yq is missing
scripts/lock-selfcheck.sh false POISON yq; unparseable gives UNEXAMINED, not consistent
scripts/check-action-pins-resolve.sh blind yq refs
scripts/update-actions-lock.sh (reusable coverage) rejected KYAML callers and accepted a run:-body decoy yq refs
scripts/check-workflow-duplicate-keys.sh blind to flow duplicates flow documents normalised with yq -P before the scan
governance-reusable.yml permissions check false-fail yq; falls back to grep with a warning if yq is missing
Mustfile actions-sha-pinned blind to quoted tag pins optional quote and comma in the pattern

Evidence

Known answers on main's block-style tree:

  • validate-actions-lock and lock-selfcheck produce identical ref sets: 29 refs and 111 pairs.
  • validate-permissions gives identical output on all 58 workflows.
  • check-action-pins-resolve drops exactly two # uses: comment examples, which never execute.

Mutant suites. Each was run against the new and the old script:

Suite New Old
scripts/tests/validate-actions-lock-test.sh (new) 5/5 fails 3
scripts/tests/lock-selfcheck-test.sh (new) 5/5 fails 2 (exits 0 on the poison and unparseable commits)
scripts/tests/validate-permissions-test.sh (new) 6/6 fails 1 (the KYAML positive)
scripts/tests/check-workflow-duplicate-keys-test.sh (+5 KYAML cases) 17/17 fails 2
scripts/tests/update-actions-lock-test.sh (+3 KYAML / decoy cases) pass accepted the run: decoy
scripts/tests/check-action-pins-resolve-test.sh 35/35 n/a

The full scripts/run-shell-test-suite.sh passes (66 files). Docstring scan over the range: 8/8 documented.

Pilot conversion:

  • Data-equal. The sort_keys JSON of the block and KYAML forms is cmp-identical.
  • Idempotent. Re-emitting the KYAML is byte-identical.
  • Comments. tools/yaml-comment-proof (KYAML step 2/6 — comment-preservation proof (shared by Y-2 and Y-3) #1021) kyaml arm: PASS, 26/26 comments preserved, 0 moved, 0 dropped. 8 blank lines are lost; this is cosmetic.
  • actionlint. It reports only the known job.workflow_sha false positive (actionlint 1.7.7), the same as on main.
  • gh actions-lock --no-fix. Its one finding (the signed-push-smoke.yml local action) is identical on main.

Not proven: GitHub's runtime parse of this reusable. That needs a caller run. #1020 showed that Actions parses KYAML in general.

Known Y-1 gaps outside this PR

These are filed as findings, not fixed here:

  • scripts/check-lockfile-drift.sh:86: the regex can't match the opening ", so it silently skips a KYAML workflow. This runs only from the estate detector lockfile-drift-detect.yml, not as a PR gate.
  • .githooks/validate-sha-pins.sh: catches an unpinned quoted ref (checked with a planted mutant). It would, however, false-fail a quoted local action ("./x") and is blind to a one-line { uses: … }. yq never emits that form, and the pilot has no local action.
  • Hypatia RE001/RE003/RE005 and pin_integrity.ex:56 don't recognise a quoted uses:. That is in the hypatia repo.

🤖 Generated with Claude Code

https://claude.ai/code/session_01W5CoaksP2Bg21HpDCgFgwS

hyperpolymath and others added 3 commits October 1, 2026 18:54
YAML-POLICY Y-1: a verdict about a workflow must come from a parser.
Each of these gates read `uses:`/`permissions:` by line grep, which only
sees block style. On a KYAML workflow they either falsely failed (the
quote and comma were captured into the ref) or went blind (a pin inside
`{ uses: ... }` was never seen):

- validate-actions-lock.sh, lock-selfcheck.sh, check-action-pins-resolve.sh,
  update-actions-lock.sh: refs come from yq; an unparseable file fails
  closed instead of contributing zero refs.
- check-workflow-duplicate-keys.sh: flow documents are normalised with
  yq -P before the line scanner runs (yq keeps duplicates, so the
  scanner still sees them).
- governance-reusable.yml: top-level permissions via yq has("permissions"),
  with a warned grep fallback on a runner without yq.
- Mustfile actions-sha-pinned: optional quote/comma in the pattern.
- lock-selfcheck.sh: its existing MPL-2.0 SPDX line moves from line 41
  to line 2 so the staged SPDX hook sees it (identifier unchanged).

Known answers on main's block-style tree: identical ref sets for
validate-actions-lock (29) and lock-selfcheck (111 pairs);
check-action-pins-resolve drops exactly two `# uses:` comment examples
that never execute. New KYAML cases and mutants fail against the old
scripts and pass against the new ones.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W5CoaksP2Bg21HpDCgFgwS
The pre-commit/pre-push permissions hook grepped `^permissions:`, which
never matches a KYAML workflow (every key sits inside `{ ... }`), so a
KYAML file that does declare permissions was rejected. Ask yq
has("permissions") instead; an unparseable file is an error, not a
pass. Without yq the grep is kept with a warning -- it can only
false-fail KYAML, never false-pass.

Known answer: identical output to the old hook on all 58 of main's
workflows. scripts/tests/validate-permissions-test.sh: 6/6; the old
hook fails its KYAML positive case.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W5CoaksP2Bg21HpDCgFgwS
Single-file pilot of YAML-POLICY Y-3, produced verbatim by
`yq -p yaml -o kyaml '.'` (yq v4.53.3). Not the #1023 scope ruling.

Verified locally:
- data-equal: sort_keys JSON of block and KYAML forms cmp-identical
- idempotent: re-emitting the KYAML is byte-identical
- tools/yaml-comment-proof (#1021): kyaml arm PASS, 26/26 comments
  preserved, 0 moved, 0 dropped; 8 blank lines lost (cosmetic)
- the gates fixed in the previous commits read it correctly
  (validate-actions-lock, validate-permissions, duplicate keys,
  governance permissions check, Mustfile pin pattern)

Not proven: GitHub's runtime parse of this reusable needs a caller run.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W5CoaksP2Bg21HpDCgFgwS
@coderabbitai

coderabbitai Bot commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 26 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used the included review currently available.

Learn how review limits work.

Review configuration:

⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Advanced

Run ID: 590c9fb5-25f2-4035-a5b4-f17b76bb8754

📥 Commits

Reviewing files that changed from the base of the PR and between 0187ccd and 37d67cc.

📒 Files selected for processing (14)
  • .githooks/validate-actions-lock.sh
  • .githooks/validate-permissions.sh
  • .github/workflows/governance-reusable.yml
  • .machine_readable/contractiles/must/Mustfile.a2ml
  • scripts/check-action-pins-resolve.sh
  • scripts/check-workflow-duplicate-keys.sh
  • scripts/lock-selfcheck.sh
  • scripts/tests/check-action-pins-resolve-test.sh
  • scripts/tests/check-workflow-duplicate-keys-test.sh
  • scripts/tests/lock-selfcheck-test.sh
  • scripts/tests/update-actions-lock-test.sh
  • scripts/tests/validate-actions-lock-test.sh
  • scripts/tests/validate-permissions-test.sh
  • scripts/update-actions-lock.sh
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Autopilot is currently an internal CodeRabbit preview.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@hyperpolymath
hyperpolymath enabled auto-merge (squash) October 1, 2026 17:59
governance / Workflow security linter runs the duplicate-key checker from a
standards checkout pinned at 317101e, not this PR's fixed copy, so the KYAML
file false-fails until the fix is on main and the pin is bumped. The pilot
moves to a follow-up PR (branch feat/kyaml-pilot-provisioning-convert) that
bumps the pin and converts the file together.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W5CoaksP2Bg21HpDCgFgwS
@hyperpolymath
hyperpolymath merged commit 13b872c into main Oct 1, 2026
52 checks passed
@hyperpolymath
hyperpolymath deleted the feat/kyaml-pilot-provisioning-gate branch October 1, 2026 18:09
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant