2026-06-17 14:12:22 +02:00
|
|
|
# Toolchain Baseline (cross-platform)
|
|
|
|
|
|
|
|
|
|
**Goal: the same frameworks and language runtimes across all hosts and OSes**, so an
|
|
|
|
|
agent relocated between Linux and FreeBSD finds an identical toolchain. Version drift
|
|
|
|
|
is a survivability bug — if debby and OSA disagree on Python or Node, a script that
|
|
|
|
|
works on one can silently fail on the other.
|
|
|
|
|
|
|
|
|
|
Probe before trusting this table — facts come from `scripts/verify_facts_probe.py
|
|
|
|
|
--build-tools`, not memory. Update the row when you bump a host.
|
|
|
|
|
|
|
|
|
|
## Baseline versions
|
|
|
|
|
|
2026-06-21 09:44:49 +02:00
|
|
|
| Tool | Standard | Linux (Debian/Ubuntu) | FreeBSD 15 (pkg) | Manager / source |
|
|
|
|
|
| ---------- | ------------------- | ------------------------------ | -------------------------------------------------------------------------------------------------------------------- | -------------------------------- |
|
|
|
|
|
| **Python** | **3.12** (floor) | `python3.13` (debby) — ≥ floor | `python312` (app) + `python311` (pkg default, transitive); `py311-*` flavors prebuilt, `py312-*` absent in quarterly | system pkg + **uv** for venvs |
|
|
|
|
|
| **uv** | ≥ 0.11 | `uv` 0.11.21 | `uv` (pkg) — confirm | standalone binary |
|
|
|
|
|
| **Node** | **24 LTS** (target) | `fnm` → v24.16.0 (debby) | `node24` + `npm-node24` | **fnm** (Rust, cross-platform) |
|
|
|
|
|
| **Rust** | stable (pinned) | rustup 1.95.0 | `rust` (pkg) | `rust-toolchain.toml` per repo |
|
|
|
|
|
| **Go** | latest stable | `go` 1.24.4 (debby) | `go` (pkg) | only where a Go component exists |
|
|
|
|
|
| **Zig** | 0.15.2 | `~/.local/bin/zig` | manual | pinned (herdr build dep) |
|
|
|
|
|
| **tmux** | latest stable | `tmux` | `tmux` | system pkg |
|
2026-06-17 14:12:22 +02:00
|
|
|
|
|
|
|
|
## Conventions
|
|
|
|
|
|
|
|
|
|
### Python — never pin the version in a shebang
|
2026-06-17 14:57:36 +02:00
|
|
|
|
2026-06-17 14:12:22 +02:00
|
|
|
- Scripts use `#!/usr/bin/env python3`. **No `python3.11` / `python3.12` shebangs.**
|
|
|
|
|
- The interpreter is selected by a **symlink provided at image/host setup time**, so a
|
|
|
|
|
future bump (3.12 → 3.13) is a one-line change in one place, not a sweep across scripts.
|
|
|
|
|
- **FreeBSD ISO build provides the symlink** (FreeBSD pkg ships `python3.12` but no bare
|
|
|
|
|
`python3`):
|
|
|
|
|
```sh
|
|
|
|
|
# in clawdie-iso build.sh, version-agnostic:
|
2026-06-17 14:57:36 +02:00
|
|
|
py_bin=$(ls "${MOUNT_POINT}/usr/local/bin"/python3.* 2>/dev/null \
|
|
|
|
|
| sed 's@.*/@@' | grep -E '^python3\.[0-9]+$' | sort -V | tail -1)
|
|
|
|
|
ln -sf "${py_bin}" "${MOUNT_POINT}/usr/local/bin/python3"
|
|
|
|
|
ln -sf "${py_bin}" "${MOUNT_POINT}/usr/local/bin/python"
|
2026-06-17 14:12:22 +02:00
|
|
|
```
|
|
|
|
|
- venv creation calls `python3 -m venv` (resolves via the symlink) — **not** `python3.12 -m venv`.
|
|
|
|
|
- **uv is the standard venv/dependency manager** across all OSes. Prefer `uv venv` / `uv pip`
|
|
|
|
|
/ `uv sync` over raw `python -m venv` + `pip` so resolution and lockfiles match everywhere.
|
|
|
|
|
uv itself is interpreter-agnostic and picks up whatever `python3` resolves to.
|
|
|
|
|
|
|
|
|
|
### Node — LTS only, one major across the matrix
|
2026-06-17 14:57:36 +02:00
|
|
|
|
2026-06-17 14:12:22 +02:00
|
|
|
- Standard target: **Node 24 LTS** (FreeBSD already ships `node24`; npm 11).
|
2026-06-17 16:34:01 +02:00
|
|
|
- **Resolved 2026-06-17:** debby switched to Node 24 via `fnm` (system Node 20 remains
|
|
|
|
|
for OS-level tools, but all Clawdie/agent workloads use 24). FreeBSD already on 24.
|
|
|
|
|
One step remains: bump the Hermes Dockerfile `node_source:22` → `24` to match.
|
2026-06-17 14:12:22 +02:00
|
|
|
- `package.json` engines floor stays generous (`>=20`) but installed runtime tracks the
|
|
|
|
|
agreed LTS. Never run a non-LTS Node major in production.
|
|
|
|
|
|
|
|
|
|
### Rust / Go / Zig
|
2026-06-17 14:57:36 +02:00
|
|
|
|
2026-06-17 14:12:22 +02:00
|
|
|
- Rust: pin per-repo with `rust-toolchain.toml` (channel `stable`) so FreeBSD pkg `rust`
|
|
|
|
|
and Linux rustup resolve the same toolchain. TLS via rustls (no openssl-sys) for the
|
|
|
|
|
`x86_64-unknown-freebsd` Tier-2 target.
|
|
|
|
|
- Go: only where a Go component exists; track latest stable.
|
|
|
|
|
- Zig pinned at 0.15.2 (herdr); bump deliberately.
|
|
|
|
|
|
|
|
|
|
### Managed tools (tmux, codex, pi, zot, …)
|
2026-06-17 14:57:36 +02:00
|
|
|
|
2026-06-17 14:12:22 +02:00
|
|
|
- These are agent/utility tools, not language runtimes. Track latest stable from the
|
|
|
|
|
platform package manager; record notable pins here when they matter.
|
|
|
|
|
- Pi is being retired (see consolidation on zot + Colibri). Codex stays (osa, ISO builds).
|
|
|
|
|
|
|
|
|
|
## Python 3.12 standardization (decision, 2026-06-17)
|
|
|
|
|
|
|
|
|
|
Consensus of operator + Hermes + Claude. Standardize on **Python 3.12 floor** everywhere.
|
|
|
|
|
|
|
|
|
|
- **Rationale:** available on Debian 13 and FreeBSD 15 via pkg; has needed stdlib
|
|
|
|
|
(`zoneinfo`, `match`/`case`); avoids 3.13 bleeding-edge quirks. Unifies a stack that was
|
|
|
|
|
drifting (debby Docker 3.13, domedog 3.12, OSA 3.11).
|
|
|
|
|
- **No code blocker:** `hermes-bsd/pyproject.toml` already allows `>=3.11,<3.14`; Hermes
|
|
|
|
|
scripts use `env python3`.
|
2026-06-21 09:44:49 +02:00
|
|
|
- **FreeBSD 3.11/3.12 coexistence (clawdie-iso #84):** FreeBSD's `PYTHON_DEFAULT` is **3.11**,
|
|
|
|
|
so system pkgs (git, libinput, npm-node24, …) pull `python311` transitively. `python312` is
|
|
|
|
|
the **application** Python and wins the `python3` symlink via `sort -V`. Both coexist
|
|
|
|
|
intentionally — "3.12 floor" is the floor for _our_ code, not a ban on the 3.11 the base
|
|
|
|
|
drags in.
|
|
|
|
|
- **FreeBSD packaging reality:** OSA's quarterly repo publishes `python312`, but not the
|
|
|
|
|
matching `py312-aider_chat`, `py312-pillow`, `py312-pip`, or `py312-pygobject` flavors yet —
|
|
|
|
|
only the **default-flavor `py311-*`** are prebuilt. Keep `py312-*` extras out of
|
|
|
|
|
`pkg-list-*.txt` until they exist; install those into explicit 3.12 venvs with uv/pip when
|
|
|
|
|
needed. **Exception worth noting:** for Pillow, the prebuilt `py311-pillow` is available, so
|
|
|
|
|
`image-render` can run on the already-present 3.11 instead of compiling Pillow into a 3.12
|
|
|
|
|
venv (see [`CAPABILITY-ROUTING.md`](./CAPABILITY-ROUTING.md)).
|
2026-06-17 14:57:36 +02:00
|
|
|
- **ISO direction:** `clawdie-iso` should carry `python312`, version-agnostic `python3`
|
|
|
|
|
symlinks in `build.sh`, and `python3 -m venv` calls. Drop packages such as `gnumeric`
|
|
|
|
|
when they keep the old Python flavor alive transitively.
|
2026-06-17 14:12:22 +02:00
|
|
|
|
|
|
|
|
_See [`AGENTS.md`](../AGENTS.md) for the agent matrix and [`HOST-MATRIX.md`](./HOST-MATRIX.md)
|
|
|
|
|
for per-host hardware facts._
|