fix(ci): unblock antipattern + delete duplicated TS check - #47
Merged
Conversation
…ource Two related fixes for CI checks that have been red on main for weeks (precursor to merging #46 — both unrelated to that port but blocking its clean merge). 1. .github/workflows/rsr-antipattern.yml — the "Check for TypeScript" step had two PYEOF tokens in succession but only one opening `python3 << 'PYEOF'`, leaving the second Python block dangling as bash commands. Bash interpreted `BUILTIN_GLOBS = [...]` as a command and exited 127. The first Python block already does the full TypeScript exemption check (universal allowlist + parsed .claude/CLAUDE.md table), so the duplicated second block is removed. No behaviour change beyond the workflow running to completion. 2. .github/workflows/language-policy.yml — the "Check for TypeScript files" step duplicated the rsr-antipattern check but with no allowlist beyond node_modules + *.d.ts, false-positiving on legitimate bridge files (e.g. lol/test/vitest.config.ts which lives under the *vscode*-or-tests/ universal allowlist that rsr-antipattern honours). The duplicate step is removed; the other language checks (ReScript, Go, Python, V-lang, ATS2, Java/Kotlin, Swift, Flutter/Dart, Makefiles, package.json runtime deps) all stay — they remain the single source of truth for those languages. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
hyperpolymath
added a commit
that referenced
this pull request
Jul 28, 2026
… tolerated (#557) **Owner ruling, 2026-07-28:** *"nix flakes are deprecated and to be thrown from the estate, we are only doing guix now… you can get rid of them and references to them now or opportunistically as you think is best."* The canon already said *"Guix primary; NO Nix mirror"* (2026-05-18), but **three places in this repo still read as though a flake were merely discouraged** — and one actively tells you to keep it. A maintainer following the current text would retain the flake and allowlist it. This fixes the words, not the logic. ## What changed **`spec/LANGUAGE-POLICY.adoc` §Package Management** — adds the hardened paragraph: Nix is *removed*, not deprecated-but-tolerated, and removal is a **standing opportunistic instruction** — strip it whenever you're in a repo for any reason, including the *references* (direnv `use flake`, `nix-shell` recipes, Dependabot's `nix` ecosystem, package-manager detection branches, `.gitignore`/`.gitattributes`, docs), not just the file. It also records the measured caveat: **~25% of the estate's `guix.scm` files are scaffold stubs, wrong-project, or `{{PROJECT_NAME}}` placeholders**, so the *presence* of `guix.scm` is not evidence of packaging. **`scripts/check-package-policy.sh`** — the failure guidance led with *"Do NOT simply delete the flake"*, which now reads as permission to keep it. Rewritten to lead with removal **while keeping the real engineering point that motivated it**: don't leave the repo unpackaged — make Guix real (or fill the `Containerfile`, which is Podman-verifiable where Guix isn't installable) *in the same change*. Explicitly rules out allowlisting the flake. **`.github/workflows/governance-reusable.yml`** — job renamed `Guix primary / Nix fallback policy` → **`Guix packaging policy (Nix retired)`**. There is no Nix fallback tier any more and the name was teaching the opposite of the rule. ## Rename safety — checked, not assumed A job rename changes the check-run name. A ruleset requiring the *old* context would become a **phantom required check that never reports**, blocking every merge — the known `--admin` trap. I queried the rulesets on `standards`, `trope-checker`, `hermeneia` and `hypatia`: the only required governance context is `governance / Validate Hypatia Baseline`. **Nothing requires the Guix job.** Safe. ## Verified by running it | case | result | |---|---| | Nix-only repo, past retirement date | `exit 1`, new guidance printed | | repo with `guix.scm` | `exit 0`, *"Guix … detected (primary)"* | `bash -n` clean; `governance-reusable.yml` still parses as YAML. **No behavioural change to the policy logic** — the decision procedure, grace-window variables and sealed-container detection are untouched. This changes what the estate is *told*, plus one job label. ## Companion PR `trope-checker` [#47](hyperpolymath/trope-checker#47) is the worked example: flake removed, the fake `guix-nix-policy.yml` deleted, and ten config/script/doc references de-Nixed. Its root-shape gate went FAIL → PASS with 0 failing checks. ## Scope note 61 other repos still carry a root `flake.nix` and 34 still carry the fake `guix-nix-policy.yml`. Per the ruling those are to be handled opportunistically; this PR makes the policy say so. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
hyperpolymath
added a commit
that referenced
this pull request
Jul 29, 2026
§2.1 already rules Nix retired and rightly warns against mass-deletion. The owner ruling of 2026-07-28 — *"nix flakes are deprecated and to be thrown from the estate"* — is **reconciled with that warning rather than overriding it**: removal stays a per-repo judgement made while you are *already working in the repo*. Opportunistic, never a fan-out sweep. ## What was genuinely missing **Deleting `flake.nix` does not retire Nix.** Measured on `trope-checker` ([#47](hyperpolymath/trope-checker#47)), one flake had **ten satellites**: | file | what it kept alive | |---|---| | `.envrc` | a direnv `use flake` block | | `Justfile` + `contractiles/Justfile` | a `nix-shell` recipe | | `build/setup.sh` | `nix` in package-manager detection **and** the install switch | | `install-tools.sh` | a flake-detecting branch running **ahead of Guix** | | `.github/dependabot.yml` | a `nix` `package-ecosystem` entry | | `.gitignore` / `.gitattributes` | `flake.lock` and `*.nix` rules | | `compliance/reuse/dep5` | `flake.lock` in the lockfile glob | | docs / `PLAYBOOK.a2ml` | prose | Leave any behind and the toolchain still reaches for Nix. They're now listed in §2.1. ## Two traps recorded, because both cost time - **`dependabot.yml` rejects the whole file on one malformed entry** — re-parse after removing the `nix` ecosystem. - **A root `.githooks/` is usually load-bearing** (CI runs validators straight from it) — allowlist it in `root-allow.txt`; don't "tidy" it away in passing. Plus the standing caveat, restated where it will be read: a repo whose `guix.scm` is a scaffold stub has **no working packaging** once the flake is gone. Make Guix real, or fill the sealed container, *in the same change*. ## Flagged, not resolved — the canon disagrees with itself This repo carries **two** `LANGUAGE-POLICY.adoc` files and they contradict each other: - **`./LANGUAGE-POLICY.adoc`** (this one) self-declares canonical, is the more current — §2.2 records the squisher-corpus identity clobber measured 2026-07-29 across 418 repos — and makes **Bun tier 1**. - **`./rhodium-standard-repositories/spec/LANGUAGE-POLICY.adoc`** still lists **Deno** as *"Replaces Node/npm/Bun"*. PR #51 on trope-checker cites the first; the estate `CLAUDE.md` I was working under states the second. **I have not resolved this** — it needs an owner decision on which file is authoritative. Note the Nix hardening was also added to the *other* file earlier (standards #557), so both now carry it; the runtime-tier contradiction is untouched. Renders clean under `asciidoctor`. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
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.
Summary
Two related CI fixes — both unblocking workflows that have been red on
mainfor weeks.1.
.github/workflows/rsr-antipattern.yml— heredoc syntax bugThe "Check for TypeScript" step had two
PYEOFtokens in succession but only one openingpython3 << 'PYEOF', leaving the second Python block dangling as bash commands. Bash sawBUILTIN_GLOBS = [...]as a command and exited 127. Every commit tomainsince the check was added has hit this. Same bug was inhyperpolymath/my-lang(see hyperpolymath/my-lang#13).The first Python block already does the full TypeScript exemption check honouring the universal allowlist and the parsed
.claude/CLAUDE.mdtable. The duplicated second block is removed.2.
.github/workflows/language-policy.yml— duplicate TS check with no allowlistThe "Check for TypeScript files" step did a blunt
find . -name "*.ts"filter with no allowlist beyondnode_modulesand*.d.ts. False-positived on legitimate bridge files likelol/test/vitest.config.ts, which lives under the**/test/**universal-allowlist pattern thatrsr-antipattern.ymlhonours.Two checks for the same banned-language family is also a single-source-of-truth violation. This PR removes the duplicate from
language-policy.yml;rsr-antipattern.ymlremains the canonical TypeScript-detection check. All otherlanguage-policy.ymlsteps (ReScript, Go, Python, V-lang, ATS2, Java/Kotlin, Swift, Flutter/Dart, Makefiles, package.json runtime deps) stay — they remain the single source of truth for those languages.What this PR fixes vs. what stays red
Fixed by this PR:
antipattern-checkno longer exits 127 on the heredoc syntax bug. It now runs to completion.Check for Banned Languages / Check for TypeScript filesno longer false-positives onlol/test/vitest.config.ts.Surfaces real pre-existing migration debt (out of scope for this PR):
antipattern-check / Check for ReScriptflags ~30 real.resfiles underrhodium-standard-repositories/satellites/{consent-aware-http,cccp/.../7-tentacles}/. These were previously hidden behind the heredoc crash — the check never reached this step before. The fix here unblocks the workflow's ability to surface them; the actual migration is its own multi-PR effort.Check for Banned Languages / Check for ReScript files(inlanguage-policy.yml) also flags the same.resfiles. Same observation.Hypatia Neurosymbolic Analysis (Dogfooding)—hypatia-cli.sh scan .exits 1 with no diagnostic across multiple repos. Filed at hyperpolymath/hypatia#213.So this PR doesn't turn the standards CI fully green — that would need the ReScript migration and the Hypatia scanner fix. But it does:
Why now
Both bugs surfaced while merging the affinescript#64 port work in #46. Pre-existing — unrelated to that port — but kept its merge state at
BLOCKEDuntil force-merged with--admin. Fixing now so future port PRs have less friction.Test plan
antipattern-checkrunning to completion (not exit 127).Check for Banned Languages / Check for TypeScript filesstep passes (no spurious vitest.config.ts hit).🤖 Generated with Claude Code