Skip to content

ci: drop embedded Python YAML parsing; gate inline Python - #1119

Merged
hyperpolymath merged 1 commit into
mainfrom
fix/no-inline-python
Oct 1, 2026
Merged

hyperpolymath merged 1 commit into
mainfrom
fix/no-inline-python

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

What

Python is banned estate-wide, but every Python detector matches *.py only. Python embedded in workflows, scripts and justfiles was invisible, and that is how the governance reusable's R5 gate came to parse YAML with a python3 - <<'PY' / import yaml heredoc, against YAML-POLICY Y-1 (read YAML with yq).

This PR removes that heredoc and the canary's Python YAML parser, and adds a gate so embedded Python cannot come back unseen.

Change Equivalence evidence
governance-reusable.yml R5 → bash + yq -o json + jq Old Python step vs new step: byte-identical stdout and exit code on 5 fixture trees (no dir → 0; empty dir → 0; clean rule → 0; mixed tree → 1, covering hits, a non-mapping rule, missing patterns, an invalid regex (grep rc 2), an id-less rule, a numeric id, self-reference skips, changelog skips, a missing include). One intended difference: an unparseable rule file now prints one counted ❌ [R5] error instead of a Python traceback; both exit 1.
tests/test_secret_scanner_canary.sh extraction → yq Extracted script is byte-identical to the Python one; canary 9/9; a reusable without the step still fails it (::error::canary: could not extract…, rc 1).
self-test.yml drops pip install pyyaml; yq is preinstalled on ubuntu-latest.
justfile.template python3 -c json.dumps → jq -Rs . Identical JSON on quotes, backslashes, tabs, ESC and newlines. REGISTRY.a2ml regenerated (RSR source_hash).
new scripts/check-inline-python.sh Flags python[3] -c, -m, - (stdin), <<, x.py, <<'PY' heredocs and pip[3] install on non-comment lines of *.yml *.yaml *.sh *.template Justfile justfile Containerfile.
new .machine_readable/inline-python-allow.txt Shrink-only ledger: 12 files / 19 lines of remaining debt. The gate fails on a new path, a grown count, or a stale entry (count fell → shrink the ledger in the same change).
new scripts/tests/check-inline-python-test.sh (100755) 24 cases: every form planted and caught, look-alikes and prose clean, all four ledger failure modes, two killed mutants (stale branch removed; -c form removed), and an exact-ledger check of this repo. Discovered by run-shell-test-suite.sh, so it runs in Repo self-tests.

-m and bare python3 << go beyond the originally scoped list. A broad sweep surfaced python3 -m json.tool / -m http.server, which execute Python just the same. The .a2ml scorecard check = strings and .githooks/post-checkout (only an echo) are outside the gate's file set. That is a known horizon, not a claim of zero.

Pin lines 417/1248/1355 of governance-reusable.yml are untouched. Local: full shell suite 67/67, docstring scan 100% (10/10).

🤖 Generated with Claude Code

https://claude.ai/code/session_01W5CoaksP2Bg21HpDCgFgwS

Python is banned estate-wide, yet every Python detector matches `*.py` only,
so Python embedded in workflows, scripts and justfiles was invisible. The
governance reusable's R5 gate parsed YAML with a `python3 - <<'PY'` heredoc
importing PyYAML, against YAML-POLICY Y-1 (read YAML with yq).

- governance-reusable.yml R5: ported to bash + yq + jq. Known-answer
  equality: the old Python step and the new step produce byte-identical
  output and exit codes on five fixture trees (no dir, empty dir, clean
  rule, and a mixed tree with hits, a non-mapping, missing patterns, a bad
  regex, an id-less rule, a numeric id, self-references, changelogs and a
  missing include). An unparseable rule file now prints one counted R5 error
  instead of a Python traceback; both exit 1.
- tests/test_secret_scanner_canary.sh: step extraction via yq; the
  extracted script is byte-identical to the Python one, and a reusable
  without the step still fails the canary.
- self-test.yml: drop `pip install pyyaml`.
- justfile.template: `python3 -c json.dumps` -> `jq -Rs .` (identical
  encoding on quotes, backslashes, tabs, ESC and newlines); REGISTRY.a2ml
  regenerated for the RSR source hash.
- scripts/check-inline-python.sh: flags python[3] -c/-m/-/<</x.py,
  <<'PY' heredocs and pip install on non-comment lines of *.yml, *.yaml,
  *.sh, *.template, Justfile/justfile, Containerfile. Remaining debt is the
  shrink-only ledger .machine_readable/inline-python-allow.txt (12 files,
  19 lines); a new path, a grown count or a stale entry fails.
- scripts/tests/check-inline-python-test.sh: 24 cases incl. two killed
  mutants and an exact-ledger check of this repo; discovered by
  run-shell-test-suite.sh.

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 53 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: 8db2c370-e264-42fb-93b4-b421794aeaa1

📥 Commits

Reviewing files that changed from the base of the PR and between df20618 and fff1409.

📒 Files selected for processing (8)
  • .github/workflows/governance-reusable.yml
  • .github/workflows/self-test.yml
  • .machine_readable/REGISTRY.a2ml
  • .machine_readable/inline-python-allow.txt
  • rhodium-standard-repositories/templates/justfile.template
  • scripts/check-inline-python.sh
  • scripts/tests/check-inline-python-test.sh
  • tests/test_secret_scanner_canary.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 22:24
@hyperpolymath
hyperpolymath merged commit 39ee4ec into main Oct 1, 2026
49 of 52 checks passed
@hyperpolymath
hyperpolymath deleted the fix/no-inline-python branch October 1, 2026 22:26
hyperpolymath added a commit that referenced this pull request Oct 1, 2026
…ate (#1121)

Follow-up to #1120. It clears the two remaining reds on `main`.

**Validate Hypatia Baseline (red on main):**
- hypatia#895 maps severity `warn` to `medium`. Since then, the 20
RE001/RE005 acknowledgements in `.hypatia-baseline.json` (recorded as
`warn`) no longer match, so every caller whose baseline has `warn`
entries breaks.
- `scripts/apply-baseline.sh` now treats `warn` and `medium` as one
tier.
- Measured on the failing run's 20 kept findings: 20 suppressed, 0 kept.
- New tests: warn↔medium matches in both directions, and a different
tier stays unmatched. Main's matcher fails both new positive cases
(mutant).
- The governance-reusable baseline job also floated on hypatia HEAD. It
now pins through a `hypatia-ref` input (default `51ab6496`). `HEAD`
remains accepted as an explicit opt-in for canaries.

**Repo self-tests (red on main):**
- The lock gate staged standards at a hardcoded third pin (`5f82b635`).
That pin was one change behind by construction and went stale again with
#1119.
- It now stages at `${{ job.workflow_sha }}`, the reusable's own commit,
which is exactly what the caller pinned.
- `check-lock-gate-pin-freshness.sh` and both contract tests accept that
expression. They still refuse `github.workflow_sha`/`github.sha`, which
name the caller's commit (planted negatives: all three guards go red).

**Package policy:** a caller pinned before the capability resolver
existed now gets a warning and is treated as undeclared, instead of
failing.

Local: `run-shell-test-suite.sh`, all 69 files pass. `docstring-scan
--check` passes.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

https://claude.ai/code/session_016L7GFo3yGQ2vK9YgKL2wsP

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
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