build: pin toolchain versions via tracked .tool-versions#41
Merged
hyperpolymath merged 1 commit intomainfrom Apr 30, 2026
Merged
build: pin toolchain versions via tracked .tool-versions#41hyperpolymath merged 1 commit intomainfrom
hyperpolymath merged 1 commit intomainfrom
Conversation
Adds an asdf-readable .tool-versions at repo root pinning the four
runtimes that QUICKSTART-USER.adoc requires, and removes the .gitignore
line that kept it untracked. asdf convention is to commit this file —
it's the equivalent of package.json for the polyglot runtime side.
Each pin matches the version that successfully boots boj-rest with all
115 cartridges discoverable on :7700. Without these pins, the next
fresh-clone setup hits the version traps surfaced during the 2026-04-30
install:
zig 0.15.1 ffi/zig/build.zig was written against 0.15;
Zig 0.16's std.Thread API broke 14 compile
sites in catalogue/loader/guardian/federation/
coprocessor/sla/community/sdp. asdf-zig latest
currently resolves to 0.16, so without a pin
every fresh clone fails `just build`.
elixir 1.18.4-otp-25 Ubuntu 24.04 LTS apt ships Elixir 1.14, but
elixir/mix.exs declares ~> 1.15. The OTP-25
suffix matches the apt erlang-base on 24.04
(Erlang/OTP 25 / erts-13.2.2.5), avoiding a
from-source Erlang build via asdf-erlang.
idris2 0.8.0 Required for `just verify` and `just typecheck`
on the Idris2 ABI. asdf-idris2 builds from
source and needs `libgmp-dev` + `chezscheme`
from apt — pinning at least removes the moving
target.
deno 2.7.14 Required by the JS cartridge worker pool.
Without it, BojRest.JsWorkerPool falls back to
fork-per-call (~200 ms cold start per invoke).
The .gitignore line that kept .tool-versions untracked has been removed
and replaced with a comment explaining why the file is tracked.
Out of scope (deliberate):
* asdf-erlang version is left to apt's OTP 25 — switching to asdf-erlang
would let us bump Elixir to 1.18+otp-26/27 and gain newer features
but adds a 10+ min source build to every cold install.
* SPARK / gnatprove and Cranelift's clif-util are still install-time
decisions, not runtime-version pins.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced Apr 30, 2026
hyperpolymath
added a commit
that referenced
this pull request
Apr 30, 2026
) ## Summary Re-measures the date-stamped historical statements PR #40 deliberately left out of scope (because they were measurements taken on 2026-04-25 and substituting blind would have been wrong). Now refreshed against the actual repo state on 2026-04-30 after `just build` produced **111 of 115** cartridge `.so` libraries. ## Numbers refreshed | Surface | Old | New | |---|---|---| | `TOPOLOGY.md` L4 | "Updated 2026-04-25. 112 cartridges across 6 tiers." | "Updated 2026-04-30. 115 cartridges across 6 tiers (111 with `.so` built, 4 pending)." | | `TEST-NEEDS.md` L124 | "112 cartridges loaded … as of 2026-04-25" | "115 cartridges loaded … as of 2026-04-30" + the 4 not-yet-building names | | `ROADMAP.adoc` v1.0.1 (4 checkboxes) | mixed 112/checked + unchecked | bumped to 115, re-dated 2026-04-30, two unchecked items now [x] (this PR closes them) | | `ROADMAP.adoc` v1.1.0 | "99 of 106 cartridges use `mod.js`" | "4 of 115 cartridges still use `mod.js`" — the gap closed substantially | | `docs/ARCHITECTURE.md` L138 | "Once all 112 cartridges have verified `.so` builds" | 115 + parenthetical 2026-04-30 measurement | | `docs/ARCHITECTURE.md` L209–212 | "1 complete (boj-health), 111 in progress" — INVERTED | "111 with `.so` built, 4 not yet building" — actually inverts the breakdown | | `docs/READINESS.md` L75 | "Cartridge fleet (106) … 103/106 shared libs built" | "Cartridge fleet (115) … 111/115 shared libs built" | The 4 cartridges still without `.so`: **`database-mcp`**, **`echidna-llm-mcp`**, **`lang-mcp`**, **`orchestrator-lsp-mcp`**. Flagged in three places so the next investigator has a starting list. ## What this PR deliberately does NOT do - **Re-run mix test / zig test / FFI test counts.** The numbers in `READINESS.md` (`113 FFI tests`, `178 core tests`, `4 believe_me`, etc.) are last-documented values, not re-measured. The row text in `READINESS.md` honestly notes this. Test re-run is a separate follow-up. - **Re-count per-directory READMEs.** The "393 per-directory READMEs" number is also a last-documented value. Same reasoning. - **Investigate the 4 build-failing cartridges.** Their `just build` errors are out of scope here; flagged for a follow-up. - **Touch any other ARCHITECTURE / ROADMAP claims unrelated to count or build status.** ## Test plan - [ ] Visual review of the 5 changed files to make sure the numbers are coherent (115 across the board for "total"; 111 for "built"; 4 for "pending"; 2026-04-30 for "as of" dates). - [ ] CI green on the branch (will hit the same 3 pre-existing failures as #40 / #41 — TS/JS Blocker on the 6 `.ts` files, Hypatia missing GITHUB_TOKEN; admin merge expected, same as those). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
hyperpolymath
added a commit
that referenced
this pull request
Apr 30, 2026
… mix path in service unit (#43) ## Summary Three of the four sub-parts of the deferred cleanup ledger from PR #40's out-of-scope list. The fourth (port the 6 `.ts` cartridge adapters to AffineScript→typed-wasm) is delegated to a scheduled remote agent that fires 2026-05-07 and runs **one cartridge per pass**, so it stays opportunistic and reviewable. ## Changes | File | Fix | |---|---| | `.github/workflows/hypatia-scan.yml` | Adds job-level `GITHUB_TOKEN` env (Hypatia CLI calls `gh api` for Dependabot lookups; without the token it logs `Dependabot alerts unavailable: GITHUB_TOKEN not set` and the job exits non-zero). Adds `security-events: read` permission. | | `.github/workflows/rsr-antipattern.yml` | "use ReScript instead" → "use AffineScript→typed-wasm instead". Header comment + Allows banner updated to reflect estate-wide language policy 2026-04-30 (RS/TS/JS default is AffineScript; ReScript transitional / adapter-shim only). | | `.github/workflows/ts-blocker.yml` | "port to Zig or ReScript" / "use Zig or ReScript instead" → "Zig (systems) or AffineScript→typed-wasm (application)". Underlying detection unchanged. | | `elixir/boj-rest.service` | Replace hardcoded `ExecStart=/usr/bin/mix` (which is apt's 1.14, fails `mix.exs` `~> 1.15` check on Ubuntu 24.04 LTS) with `ExecStart=mix run --no-halt`. Adds `Environment=PATH` with asdf shims, cargo bin, `~/.local/bin`. Adds `ASDF_DIR` + `ASDF_DATA_DIR` so asdf shims work under systemd's clean env. Bumps cartridge-count comment 112 → 115. | ## Why these specifically PR #40 (spec drift) merged on 2026-04-30 surfaced four follow-up cleanups; this PR closes three of them. The fourth (`.ts` → AffineScript ports) was deliberately scheduled rather than rushed — verifying AffineScript readiness for each cartridge is genuinely per-cartridge work and the scheduled agent does it one at a time. The `boj-rest.service` fix in particular was discovered the hard way during the maintainer's install: the deployed unit needed a hand-patch (`~/.config/systemd/user/boj-rest.service`) to point at `~/.asdf/installs/elixir/1.18.4-otp-25/bin/mix`. Persisting the fix to the source template (with `%h` systemd-substitution + asdf shim PATH) means the next person installing on a fresh Ubuntu doesn't repeat the dance. The three pre-existing CI failures that were blocking PRs #40, #41, #42 are likely partially closed by this PR: - **Hypatia** — should now pass with `GITHUB_TOKEN` wired up. - **TS/JS Blocker** and **antipattern-check** — will *still* fail on the 6 `.ts` cartridge adapters (`academic-workflow-mcp`, `bofig-mcp`, `ephapax-mcp`, `fireflag-mcp`, `hesiod-mcp`, `sanctify-mcp`). Those are the scheduled agent's work. Admin-merge-without-CI is still expected for this PR. ## Test plan - [ ] CI shows Hypatia passing on this branch (GITHUB_TOKEN now available). - [ ] Diff visual review for the policy text — make sure no instance of "use ReScript instead" remains in the workflow files. - [ ] After merge, fresh install on a clean Ubuntu 24.04 LTS host with asdf + the toolchain-pins from PR #41: `bash setup.sh && just doctor && just deps && just build && just install-service` — confirm `boj-rest.service` starts cleanly without the `(Mix) You're trying to run :boj_rest on Elixir v1.14.0` error that was previously hit. ## Out of scope - The 6 `.ts` → AffineScript ports (scheduled, one per week from 2026-05-07, routine `trig_01X9BreihRW4AU5BdELY2QBY`). - Re-running mix test / FFI tests for grade re-validation (READINESS.md still lists the last-documented numbers per the re-measurement PR #42). - The 4 cartridges still without `.so` (`database-mcp`, `echidna-llm-mcp`, `lang-mcp`, `orchestrator-lsp-mcp`) — listed in #42 for follow-up. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <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.
Summary
Pins the four runtime versions a fresh-clone install needs to boot
boj-restwith all 115 cartridges discoverable on:7700. asdf reads.tool-versionsautomatically when youcdinto the repo, so the pins are transparent for any user already on asdf.Discovered during the 2026-04-30 install — without these pins the next person hits exactly the same traps:
zig 0.15.1ffi/zig/build.zigwas written against Zig 0.15. Zig 0.16'sstd.ThreadAPI broke 14 compile sites incatalogue/loader/guardian/federation/coprocessor/sla/community/sdp.asdf-zig latestcurrently resolves to 0.16, so without a pin every fresh clone failsjust build.elixir 1.18.4-otp-25elixir/mix.exsdeclares~> 1.15. The-otp-25suffix matches the apterlang-baseon 24.04 (Erlang/OTP 25 / erts-13.2.2.5), avoiding a from-source Erlang build viaasdf-erlang.idris2 0.8.0just verifyandjust typecheck.asdf-idris2is a source build needinglibgmp-dev+chezschemefrom apt — pinning at least removes the moving target.deno 2.7.14BojRest.JsWorkerPool. Without it, JS cartridges fall back to fork-per-call (~200ms cold start per invoke).Also removes
.tool-versionsfrom.gitignoreand replaces the line with a comment explaining why the file is now tracked. asdf convention is to commit this file — it's the polyglot equivalent ofpackage.jsonfor runtime versions.Test plan
erlang-base(OTP 25) present:git clone … && cd boj-server→ asdf reads.tool-versionsautomatically.asdf installresolves all four versions (zig, elixir, idris2, deno).just doctorreports all required tools green.just buildproduces 111.socartridges (or the current count).just install-servicebrings upboj-rest.serviceon:7700cleanly.curl localhost:7700/healthreturnscartridges_loaded:115.Out of scope
asdf-erlangversion is left to apt's OTP 25 — switching toasdf-erlangwould let us bump Elixir to 1.18+otp-26/27 and gain newer features but adds a 10+ min source build to every cold install. Separate decision.gnatproveand Cranelift'sclif-utilare install-time decisions, not runtime version pins, so they're not in here.elixir/boj-rest.servicetemplate still hardcodes/usr/bin/mix, which fails when Elixir is asdf-managed. Fixing that is in the cleanup PR alongside the AffineScript port and Hypatia env fix.🤖 Generated with Claude Code