fix(governance): honour .hypatia-ignore / inline pragma in banned-language checks - #120
Merged
Merged
Conversation
…nguage files The ReScript/Go/Python anti-pattern steps did a naive `find` with no exemption path, ignoring the estate's declared machine-readable escape (`.hypatia-ignore` rule `cicd_rules/banned_language_file` + inline `# hypatia:ignore` pragma) that the Hypatia scanner itself honours. Re-emergence of a banned default despite a declared escape is a tooling defect per the Explicit-Escape Principle. Adds a shared exemption filter to those three checks; non-exempt files still fail (verified), clean repos no longer false-fail under pipefail. Unblocks hypatia#270 (and transitively #271), whose intentionally exempted criterion bench scripts were tripping the shared gate. Refs standards#72 Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Uh oh!
There was an error while loading. Please reload this page.
🔍 Hypatia Security ScanFindings: 101 issues detected
View findings[
{
"reason": "Issue in quality.yml",
"type": "missing_workflow",
"file": "quality.yml",
"action": "create",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Issue in security-policy.yml",
"type": "missing_workflow",
"file": "security-policy.yml",
"action": "create",
"rule_module": "workflow_audit",
"severity": "medium"
},
{
"reason": "Action hyperpolymath/standards/.github/workflows/governance-reusable.yml@main needs attention",
"type": "unpinned_action",
"file": "governance-reusable.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Action hyperpolymath/standards/.github/workflows/governance-reusable.yml@main needs attention",
"type": "unpinned_action",
"file": "governance.yml",
"action": "pin_sha",
"rule_module": "workflow_audit",
"severity": "high"
},
{
"reason": "Python file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/standards/standards/a2ml-templates/state-scm-to-v2.py",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
},
{
"reason": "TypeScript file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/standards/standards/a2ml/bindings/deno/mod.ts",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
},
{
"reason": "TypeScript file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/standards/standards/lol/test/vitest.config.ts",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
},
{
"reason": "TypeScript file detected -- banned language",
"type": "banned_language_file",
"file": "/home/runner/work/standards/standards/k9-svc/bindings/deno/mod.ts",
"action": "flag",
"rule_module": "cicd_rules",
"severity": "critical"
},
{
"reason": "believe_me undermines formal verification (1 occurrences, CWE-704)",
"type": "believe_me",
"file": "/home/runner/work/standards/standards/lol/src/abi/Locale.idr",
"action": "flag",
"rule_module": "code_safety",
"severity": "critical"
},
{
"reason": "Wildcard CORS -- restrict to specific origins or use env var (1 occurrences, CWE-942)",
"type": "js_wildcard_cors",
"file": "/home/runner/work/standards/standards/consent-aware-http/examples/reference-implementations/deno/aibdp_middleware.js",
"action": "flag",
"rule_module": "code_safety",
"severity": "high"
}
]Powered by Hypatia Neurosymbolic CI/CD Intelligence |
This was referenced May 30, 2026
hyperpolymath added a commit
that referenced
this pull request
Aug 7, 2026
…y fall (#591) ## Why A GitHub issue is a **boolean**. Much of what this estate tracks in issues is an **integer that changes every week**. An audit of the 697 open estate issues on 2026-08-07 found what that costs: | Issue | Claimed | Measured 2026-08-07 | | |---|---|---|---| | `standards#309` | ~45 banned `.py` files | **176** | ~4× wrong, unchallenged for ten weeks | | `standards#308` | ~12,000 PMPL headers | **4,968** | 59% paid down, unrecorded | | `reposystem#138` | Nix in 63 repos | **67** | grew, unnoticed | The purest case is `.git-private-farm`, where a bot mints the same measurement as a **new issue** on every run: ``` #104 07-05 rustsec: 138 open advisories (34 high/critical) #105 07-06 rustsec: 136 open advisories (34 high/critical) #107 07-07 rustsec: 139 open advisories (34 high/critical) #117 08-01 rustsec: 156 open advisories (54 high/critical) #119 08-02 rustsec: 156 open advisories (54 high/critical) #120 08-03 rustsec: 155 open advisories (53 high/critical) ``` Six issues carrying one number, plus three more for mirror drift. This PR adds a register that holds the integer, so the tracker can go back to holding booleans. ## What | File | Role | |---|---| | `.machine_readable/Debtfile.a2ml` | the register — same `### <id>` block shape as `Mustfile.a2ml` | | `scripts/check-debtfile-structure.sh` | structural half — rejects a **hollow entry** (a number with no probe) | | `scripts/run-debtfile.sh` | executable half — re-measures every probe; `--write` lowers ceilings | | `scripts/check-debt-ratchet.sh` | ceilings may fall, never rise silently | | `.github/workflows/debt-measure.yml` | weekly re-measure → opens **one PR**, never an issue | ## Why not a contractile The name fits the convention exactly (`Mustfile`, `Trustfile`, `Bustfile`, `Dustfile`, `Intentfile`). The placement does not: 1. **The contractile CLI does not exist.** `reposystem/contractiles/cli/` is an *empty directory*; five of six verbs have no runner. 2. **Only `must` executes**, via hand-written bash — the pattern copied here. 3. **`EXEMPTION-MECHANISMS.adoc` already rejects declarations with no reader** (`.hypatia-ignore`: *"never read by anything. Reject."*). A seventh verb would be exactly that. 4. **No verb fits** — `bust` is fault-injection drills, `dust` is exnovation, `intend` is roadmap. If the CLI is ever built, this absorbs as the `debt` verb with no rename. ## Why not a sixth exemption mechanism It **absorbs two conventions the estate already invented**: - `debt.a2ml` (`gitbot-fleet`, `flat-mate`, `rpa-elysium`, `chronicles-of-slavia`; ADR-002) - Exemption **Layer 4b** — debt stored as a Markdown table inside `.claude/CLAUDE.md`, rows `\| glob \| count \| rationale \| unblock-condition \|`, regex-parsed, in **19 repos** Sibling to the exemption ratchet, governing a different population: - `check-exemption-ratchet.sh` — debt you **excused**: *"did you quietly excuse more?"* - `check-debt-ratchet.sh` — debt you **measured**: *"did the number go up?"* ## Probe discipline — all learned the hard way in this PR - **No fallback.** A probe that fails is a hard failure. A counter returning 0 on error is indistinguishable from zero debt, and zero is the state that passes. - **Three candidate probes were rejected for manufacturing debt.** Two matched **comments** (usage examples in `codeql-reusable.yml`; a comment explaining why a script does *not* use `python3`); one counted the test files themselves. - **The register must not count itself.** The first live run breached on `todo-fixme-markers` (278 > 277) and `pmpl-licence-headers` (590 > 589) *purely because writing the entries down created the strings they search for*. Licensing debt is `policy: flag-only` — measured and reported, **never acted on**, per the standing owner directive in `.claude/CLAUDE.md`. ## Verification ``` debtfile-structure-test.sh 14 passed, 0 failed run-debtfile-test.sh 16 passed, 0 failed debt-ratchet-test.sh 12 passed, 0 failed just debt-measure · HOLDING [low ] docs-md-not-adoc 309 · HOLDING [high ] gate-scripts-without-tests 31 · HOLDING [medium ] shell-scripts-missing-spdx 2 · HOLDING [low ] todo-fixme-markers 277 · HOLDING [medium ] pmpl-licence-headers 589 ``` Each suite proves its gate **can fail** and was mutation-tested. The runner suite was itself found to be a fake gate during authoring — piping into `expect` ran it in a subshell, so counters were discarded and a real failure would still have exited 0 — and fixed. Workflows re-verified as parsing (`debt-measure.yml` initially did **not**: a multi-line `git commit -m` put continuation lines at column 1 and ended the YAML block scalar — the estate's own broken-workflow class, caught before merge). `actions.lock` updated; duplicate-key linter clean across 39 files. ## Rollout Wired as job `debt-ratchet` in `governance-reusable.yml`, so **every caller picks it up on next run with no per-repo PR**. Tier **🟡 CHECK** — MUST NOT be a required status check. Promotion to 🔴 GATE only after two clean weekly measure cycles. Adoption is opt-in: a repo with no `Debtfile.a2ml` is not in violation; a repo that has one must have a well-formed one. 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- 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 freeto 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
The shared
governance-reusable.ymlLanguage / package anti-pattern policyjob enforces the TypeScript ban with a full exemption mechanism, but the ReScript / Go / Python checks were crudefindone-liners with no escape. They ignored the estate's declared machine-readable exemption —.hypatia-ignorerulecicd_rules/banned_language_fileand the inline# hypatia:ignore … cicd_rules/banned_language_filepragma — even though the Hypatia scanner itself honours it.Per the Explicit-Escape Principle (Refs standards#72): re-emergence of a banned default despite a declared, tool-honoured escape is a tooling defect, not a policy violation.
Symptom this fixes
hyperpolymath/hypatia#270(a 1-line CI pin) and transitively #271 areBLOCKEDbecause two intentionally-exempted criterion bench scripts (scripts/check-bench-regression.py,scripts/update-bench-baselines.py— carrying the inline pragma, listed in.hypatia-ignore, documented in.hypatia-exemptions.md, used bytests.yml) trip this shared gate. The defect is estate-wide; fixing it here resolves every consumer of the shared bundle.Change
Replaces the three crude checks with a single exemption-aware step. A file is exempt from
cicd_rules/banned_language_fileiff it is listed in.hypatia-ignorefor that rule or carries the inline pragma in its first 8 lines.Verification (dry-run,
bash -eo pipefail).pyadded → FAIL (enforcement preserved)grep -v/pipefail false-fail; the old behaviour was preserved via|| true)Refs standards#72