docs(policy): yq for reading now, KYAML sequenced behind a proof - #1009
Merged
Merged
Conversation
Owner ruling 2026-09-22, in response to "is it sensible to make the estate rule kyaml not yaml, and invest in using yq wherever it comes into things?" Measured first. 23,199 YAML files across the estate at depth 6 (excluding node_modules/target/.git/vendor): 9,261 in .github/workflows, 11,238 elsewhere under .github, 2,700 outside it. The split that matters is that the 9,261 are written by BOTS — dependabot and gh actions-lock — so a style rule imposed on them is violated on a schedule, by us, forever. Y-1, IN FORCE: every gate that READS YAML parses it with yq, never grep/sed. This is not hygiene, it is a measured recurring defect class — a grep-read key is not what the parser sees. Recorded instances: a name/uuid nested under a [package] table that grep read correctly while the loader returned nothing; gh actions-lock's extractor seeing step-level `uses:` only and calling 71 job-level reusable refs fatal orphans, turning a green repo red; allowlist globs keyed to a depth a sparse checkout had changed. Enforceable today — yq v4.53.3 is already installed. Y-2, SEQUENCED: yq for WRITING waits on a comment-preservation proof. The estate pins actions as `uses: <sha> # v7.0.1` and that trailing comment is load-bearing — a bare 40-hex string is unreviewable, and the comment is the only place the tag survives. A rewrite that strips it still parses, still runs, and is no longer reviewable, so no parse check would catch it. Y-3, SEQUENCED, scope deliberately undecided: KYAML as target authoring dialect. It is genuinely attractive — a strict subset of YAML per KEP-5295, so no new parser anywhere, and flow style with quoted values kills the Norway problem, sexagesimal coercion, 1.0-becomes-float and indentation ambiguity at source. Three things must be true first: GitHub Actions must be PROVEN to parse KYAML workflows (assuming it does is how workflows here die at startup with jobs=0, which is not a failing job and shows no honest red square); a formatter must exist, as none does outside `kubectl -o kyaml`; and comment handling must be proven — KEP-5295 is explicit that automated reformatting is lossy, go-yaml "does not always handle comments properly" so comments may be "formatted wrongly, or lost entirely". The structural point: that last precondition and Y-2's obstacle are the SAME problem. An automated rewrite risks destroying load-bearing comments whether the rewriter is `yq -i` or a KYAML formatter. So the proof is written once, against the real pin-comment corpus, and satisfies both. It also fixes the acceptance bar for both: parse-clean is not the bar — a migration producing valid, running, comment-stripped workflows has failed. Adoption order is a dependency order, six steps, one issue each: probe -> comment proof -> formatter -> owner scope ruling -> estate-authored YAML -> workflows (only if ruled in scope, and only once bot drift is resolved). Nothing in the estate is out of compliance with Y-2 or Y-3 today, because neither imposes anything today. Gates must not cite them yet. standards-map.toml gains the entry and entry_count goes 123 -> 124; Gate D caught the stale count before this commit, which is the gate working. Refs: #787 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WRvDivYwLSeVCJUrfjic3f
cicd-suite PR #32 extracts a composite's embedded shell script with `yq -r '.runs.steps[0].run'` in order to execute it under the real CI shell. A grep/sed extraction would have had to guess the block scalar's indentation and could silently have produced a different script from the one GitHub runs — the exact failure class Y-1 exists to prevent. The defect that test was written for belongs to the same family: the gate's behaviour depended on `-e`, supplied by the harness and absent from the file, so reading the file alone gave a confident verdict in the wrong direction. Refs: #787 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WRvDivYwLSeVCJUrfjic3f
Contributor
|
Warning Review limit reachedNext included review available in 31 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Advanced Run ID: 📒 Files selected for processing (2)
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. Comment |
|
This was referenced Sep 22, 2026
hyperpolymath
added a commit
that referenced
this pull request
Sep 22, 2026
…1026) Follow-up to #1009, which landed `3-practice/YAML-POLICY.adoc`. §5 fixed a six-step dependency order and stated *"Each step is a separate issue"* — but carried no issue numbers, so a reader of the policy had no way to find them. This adds the mapping and records step 1's result. ## What changed Two additions, both inside `3-practice/YAML-POLICY.adoc`: 1. §5 gains the issue mapping (#1020 → #1025) in dependency order. 2. §8 gains a changelog **row** recording step 1's discharge. No rule text is altered. Nothing is mandated that was not mandated before. ## Step 1 is discharged — measured, not assumed §3.3 precondition 1 warned this must be probed because *"the parser will surely accept it" is exactly how workflows in this estate die at startup with `jobs=0`*. It was probed, on `hyperpolymath/pons-asinorum` branch `probe/kyaml-parse` (`ac2c614`). The specific failure mode tested: `kubectl -o kyaml` emits `"on": "push"` — it **quotes** the trigger key, because YAML 1.1 reads bare `on` as boolean `true`. Had GitHub looked up the normalised key `true`, a quoted `"on"` would be a different key ⇒ no trigger ⇒ `jobs=0`. | arm | syntax | run | jobs | step marker in log | |---|---|---|---|---| | control | plain YAML | 35794781121 | **1** | `PROBE_YAML_ARM_EXECUTED` found | | subject | KYAML, `kubectl` dialect | 35794781018 | **1** | `PROBE_KYAML_ARM_EXECUTED` found | Both arms were in **one commit** and are semantically identical (verified by diffing both through `yq -o=json -P 'sort_keys(..)'`, equal after normalising only the arm labels), so any difference would be attributable to syntax alone. **Confounds excluded by construction:** pons has no `actions.lock` and neither arm carries a `uses:`, so the absent-from-lock startup death could not have produced the result. The plain-YAML control is what makes a non-zero meaningful — a bare `jobs=0` would have been unattributable. **Why the log marker rather than the green square:** `conclusion=success` alone proves nothing, since a green run can execute nothing at all. Each arm echoes a unique string, and both were grepped out of the run logs. ## What this deliberately does not do It does not advance the scope question, and the added text says so. §5 step 4 (#1023) requires an **owner ruling** and explicitly forbids inferring scope from the probe. The probe settles the *parser* dimension only — `actionlint`, `gh actions-lock`'s extractor against flow-style mappings, the estate's yq-based gates and reviewability all remain open, and are booked in #1022 and #1025. ## Note on how this was edited The shared `standards` checkout is currently mid-flight on another actor's branch (`secqual/resync-actions-lock-after-dependabot-bump`, with staged changes), so this was written through the contents API rather than that worktree — no concurrent actor's work was touched or overridden. 🤖 Generated with [Claude Code](https://claude.com/claude-code) https://claude.ai/code/session_01WRvDivYwLSeVCJUrfjic3f Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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.



Answers the owner's question of 2026-09-22:
Short answer: yes to
yq, and yes to KYAML — but not in that order, and notin one step. This adds
3-practice/YAML-POLICY.adocrecording exactly whichpart is in force today and which is sequenced behind a proof.
The three rules
yq, nevergrepcicd-suite#32).yqfor WRITINGWhy Y-2 and Y-3 share one proof obligation
This was the finding that changed the document. Grounding it in the primary
sources (KEP-5295, kubernetes.io) rather than recollection turned up that
KYAML's own specification carries the same caveat as the
yq-writing risk:So "can a tool rewrite our YAML without destroying the comments?" is a single
question sitting under two rules, not two questions. §4 states it once, with
the acceptance criterion "parse-clean is not the bar": the proof must show
every comment preserved, comment association to the right line preserved,
idempotence under
cmp, and a dropped-comment mutant must die. A round-tripthat merely parses proves nothing.
What the owner already ruled
as separate issues with an 'order' to them" — probe GitHub Actions first,
then decide scope; estate-wide adoption booked as ordered issues. §5 carries
that six-step dependency-ordered table; the issues are the follow-up.
yq: "going for 1 now 2 and we'll sort proof as part of this" — Y-1 inforce now, Y-2 next, proof in scope. That is exactly §1/§2/§4.
What it deliberately does not do
§6: it does not ban YAML, does not apply to lockfiles or third-party files, and
does not change
LANGUAGE-POLICY.adoc.Registry
standards-map.tomlgains the matching[[entry]]andentry_countgoes123 → 124. Gate D caught the stale count on the first run and passed once
corrected — recorded in the commit message as the gate doing its job.
Refs: #787
🤖 Generated with Claude Code
https://claude.ai/code/session_01WRvDivYwLSeVCJUrfjic3f