policy: bun-first runtime order; name the ban's exemption classes - #575
Conversation
The banned list already carried rescript, yet 71 repos across the estate hold a rescript.json — the policy was declared and never enforced, and it never said WHERE a banned language is legitimately allowed to live, so there was nothing to enforce against. - banned-exempt-repo-classes names the only three homes: <lang>-ecosystem, adapter, mcp. Anywhere else a banned language is a defect regardless of how it arrived. (rescript's homes: rescript-ecosystem, and the adapter in proven.) - js-runtime-order makes bun the default. Deno was bought for its Rust implementation and paid for in compatibility tax; bun wins on the thing that actually decides, and Deno's longevity is not a safe bet to build a 400-repo estate on. Deno stays second for existing code, pnpm third, npm last resort. - ruby joins the banned list alongside typescript, rescript, go, python. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
| # js-runtime-order: preference for anything needing a JS runtime or package | ||
| # manager. Take the first that can do the job; drop to the next only when it | ||
| # genuinely cannot. | ||
| # bun — the default. Compatibility decides, and bun has it. | ||
| # deno — second. Kept for existing code; not chosen for new work. Walking | ||
| # everything through Deno was a real cost, and its longevity is not | ||
| # a safe bet to build on. | ||
| # pnpm — third, when a real node_modules layout is unavoidable. | ||
| # npm — last resort only. | ||
| js-runtime-order = ["bun", "deno", "pnpm", "npm"] |
There was a problem hiding this comment.
⚠️ Bug: js-runtime-order contradicts canonical Deno-first policy
The new js-runtime-order = ["bun", "deno", "pnpm", "npm"] directly contradicts two canonical sources that this template must not diverge from. docs/JS-RUNTIME-POLICY.adoc (:status: ACTIVE, self-described "canonical estate-wide policy") mandates the hierarchy Deno > Bun > pnpm > npm (lines 31-58), and rhodium-standard-repositories/spec.scm/language-policy.scm lists bun under banned-languages with replacement deno (lines 58-59) in a file marked "FROZEN 2025-12-27 / immutable in v1.x". Making bun the default in the template while the canonical policy still ranks Deno first — and bans bun outright — leaves the estate with two authoritative-but-opposite rules and no gate can satisfy both. Either land the change to the canonical doc/scm through their change procedure first, or hold this template change until that policy is actually re-authorised.
Was this helpful? React with 👍 / 👎
|
|
||
| # banned: Languages the agent must NEVER use, even if asked. | ||
| banned = ["typescript", "rescript", "go", "python", "makefile"] | ||
| banned = ["typescript", "rescript", "go", "python", "ruby", "makefile"] |
There was a problem hiding this comment.
💡 Quality: 'ruby' banned in template but absent from canonical banned list
The template adds ruby to banned, but the canonical language-policy.scm banned-languages list (frozen v1.x) does not contain ruby, and its allowed-languages list still classes rescript as "Primary application code" while the template bans it. The template's language constraints are drifting from the canonical machine-readable policy. If ruby is genuinely to be banned estate-wide, add it to the canonical policy through the applicable change procedure so the two stay in sync; otherwise the template asserts a ban no canonical source backs.
Was this helpful? React with 👍 / 👎
There was a problem hiding this comment.
Configure merge blocking · Maintainers can dismiss this review.
|
Note Automatic reviews are paused because your trial's included automatic processing has been used for this period. Upgrade now, or comment "Gitar review" to run a review anytime. Code Review
|
| Compact |
|
Important
Your trial ends in 5 days — upgrade now to keep code review, CI analysis, auto-apply, custom automations, and more.
Was this helpful? React with 👍 / 👎 | Gitar



Two policy gaps found while auditing the estate, both of the same shape: a rule was declared and nothing could enforce it.
The ReScript ban was real but unenforceable
bannedhas carriedrescriptall along. Yet 71 repos across both orgs hold arescript.json. The reason nothing caught it: the policy never said where a banned language is legitimately allowed to live, so there was no predicate to check against — only a list with no notion of a sanctioned exception.banned-exempt-repo-classescloses that. There are exactly three legitimate homes:<lang>-ecosystem— the repo that exists to hold that language's world (rescript-ecosystem)adapter— a bounded translation layer to a foreign ecosystem (the ReScript adapter inproven)mcp— an MCP server for one specific external thingAnywhere else, a banned language is a defect regardless of how it arrived. A ban is about stopping a language spreading through the estate, not pretending it doesn't exist — interoperating with an ecosystem means writing in it, in one bounded, named place.
Bun becomes the default JS runtime
js-runtime-order = ["bun", "deno", "pnpm", "npm"].Deno was chosen for its Rust implementation and paid for in compatibility tax — walking everything through it was a standing cost. Bun wins on the thing that actually decides, and Deno's longevity isn't a safe bet on which to rest a 400-repo estate. Deno stays second for existing code rather than being ripped out; pnpm third when a real
node_moduleslayout is unavoidable; npm last resort only.Worth stating plainly for the record: bun's runtime is Zig, not Rust — Deno is the Rust one. The Rust rewrite wave in JS-land is the tooling (Oxc, Rolldown, Biome, SWC). So this trades Rust for Zig, which is arguably more consistent with an estate whose FFI layers, game-server-admin core and audio NIFs are already Zig.
rubyalso joins the banned list alongside typescript, rescript, go, python.What this does not do
It changes the template, so newly generated repos inherit it. Existing repos are unaffected — the 71
rescript.jsonrepos need a separate remediation pass, and enforcing the new predicate needs a gate that can readbanned-exempt-repo-classesand fail on a violation. Both are follow-ups; this PR is the policy those follow-ups would enforce.🤖 Generated with Claude Code