docs: python 3.11/3.12 coexistence on FreeBSD; correct the Pillow rationale

Reconcile the toolchain + capability docs with clawdie-iso #84 (FreeBSD
PYTHON_DEFAULT=3.11):

- TOOLCHAIN.md: the FreeBSD column claimed `py312-*` flavors; reality is
  python312 (app) + python311 (pkg default, transitive), with py311-* prebuilt
  and py312-* absent in the quarterly repo. Added the 3.11/3.12 coexistence note
  ("3.12 floor" = floor for our code, not a ban on the base's 3.11).
- CAPABILITY-ROUTING.md: corrected the imprecise "Pillow dropped on FreeBSD"
  rationale. The blocker was the missing py312-pillow flavor, not Pillow itself;
  the prebuilt py311-pillow is available, so image-render can be restored on
  FreeBSD via 3.11. Clarified screenshot also needs a display (XFCE operator
  image yes, headless osa no → image-render only there).

prettier + layered_soul validate clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Sam & Claude 2026-06-21 09:44:49 +02:00
parent c11df1ac75
commit 2fd29cead7
2 changed files with 42 additions and 26 deletions

View file

@ -44,14 +44,14 @@ Implemented 2026-06-19 (colibri PR #83), using the `socat`-over-Tailscale approa
## [LIVE] Capability vocabulary (initial) ## [LIVE] Capability vocabulary (initial)
| Piece | Status | Action | | Piece | Status | Action |
| ----- | ------ | ------ | | --------------------- | ---------------------------------------------- | ------------------------------ |
| Capability vocabulary | tags are free-form (`rust`, `python`, `linux`) | Agree a shared tag set (below) | | Capability vocabulary | tags are free-form (`rust`, `python`, `linux`) | Agree a shared tag set (below) |
Flat, explicit tags — the matcher does exact string comparison, no implied hierarchy. Flat, explicit tags — the matcher does exact string comparison, no implied hierarchy.
Sourced from the probe and recorded per host in [`HOST-MATRIX.md`](./HOST-MATRIX.md). Sourced from the probe and recorded per host in [`HOST-MATRIX.md`](./HOST-MATRIX.md).
| Category | Tags | | Category | Tags |
| -------- | ---- | | --------- | ------------------------------------ |
| OS | `linux`, `freebsd` | | OS | `linux`, `freebsd` |
| Isolation | `docker`, `freebsd-jail` | | Isolation | `docker`, `freebsd-jail` |
| Display | `gui`, `screenshot`, `wayland` | | Display | `gui`, `screenshot`, `wayland` |
@ -65,16 +65,24 @@ Hosts advertise only what they truly have. Actual registered agents (2026-06-19)
`image-render` — the media/compute lane. **No** `screenshot`/`gui` (headless VM), no `docker`. `image-render` — the media/compute lane. **No** `screenshot`/`gui` (headless VM), no `docker`.
- **debby / hermes-debby (Linux):** `linux`, `docker`, `shell`, `gateway`, `hermes`, `tailscale`. - **debby / hermes-debby (Linux):** `linux`, `docker`, `shell`, `gateway`, `hermes`, `tailscale`.
- **osa / hermes-osa (FreeBSD):** `freebsd`, `shell`, `gateway`, `tailscale`, `rc.d`, `pf`, - **osa / hermes-osa (FreeBSD):** `freebsd`, `shell`, `gateway`, `tailscale`, `rc.d`, `pf`,
`nginx`, `acme`, `hermes` — no `image-render` (Pillow dropped on FreeBSD). `nginx`, `acme`, `hermes` — no `image-render` **today**. Not because Pillow is unavailable:
the blocker was that the `py312-pillow` flavor isn't in the quarterly repo. The prebuilt
**`py311-pillow`** _is_ available (FreeBSD's pkg default is 3.11, present transitively —
clawdie-iso #84), so `image-render` can be restored on FreeBSD by adding `py311-pillow` and
running it on 3.11. (`screenshot` additionally needs a display — see the worked example.)
## [DESIGN] Worked example: the tmux-screenshot skill ## [DESIGN] Worked example: the tmux-screenshot skill
This illustrates the routing flow (now runnable over the [LIVE] cross-host topology above): This illustrates the routing flow (now runnable over the [LIVE] cross-host topology above):
1. FreeBSD image drops Pillow — stays lean (`pkg-list` carries only `python312`). 1. FreeBSD ships no `py312-pillow` flavor in the quarterly repo, so the image has stayed
lean. **But** the default-flavor `py311-pillow` is prebuilt and `python311` is already
present (clawdie-iso #84), so `image-render` can be restored on FreeBSD via `py311-pillow`
on 3.11. `screenshot` additionally needs a **display** — the XFCE operator image has one
(so screenshots work there), but headless osa does not (image-render only).
2. The skill manifest declares `required_capabilities: ["image-render"]` (or `screenshot`). 2. The skill manifest declares `required_capabilities: ["image-render"]` (or `screenshot`).
3. Only a Linux host advertises these — today **domedog** carries `image-render`/`ffmpeg` 3. Only a Linux host advertises these — today **domedog** carries `image-render`/`ffmpeg`
(osa dropped Pillow). `screenshot` additionally needs a display, so a *headless* host (osa dropped Pillow). `screenshot` additionally needs a display, so a _headless_ host
does not qualify for it. does not qualify for it.
4. Colibri routes the task to a matching host automatically — **proven 2026-06-19: an 4. Colibri routes the task to a matching host automatically — **proven 2026-06-19: an
`image-render` task routed to domedog**; with no match it parks until a capable agent appears. `image-render` task routed to domedog**; with no match it parks until a capable agent appears.

View file

@ -11,8 +11,8 @@ Probe before trusting this table — facts come from `scripts/verify_facts_probe
## Baseline versions ## Baseline versions
| Tool | Standard | Linux (Debian/Ubuntu) | FreeBSD 15 (pkg) | Manager / source | | Tool | Standard | Linux (Debian/Ubuntu) | FreeBSD 15 (pkg) | Manager / source |
| ----------- | ------------------ | ---------------------------- | ----------------------- | --------------------------------- | | ---------- | ------------------- | ------------------------------ | -------------------------------------------------------------------------------------------------------------------- | -------------------------------- |
| **Python** | **3.12** (floor) | `python3.13` (debby) — ≥ floor | `python312` + `py312-*` | system pkg + **uv** for venvs | | **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 | | **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) | | **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 | | **Rust** | stable (pinned) | rustup 1.95.0 | `rust` (pkg) | `rust-toolchain.toml` per repo |
@ -73,10 +73,18 @@ Consensus of operator + Hermes + Claude. Standardize on **Python 3.12 floor** ev
drifting (debby Docker 3.13, domedog 3.12, OSA 3.11). 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 - **No code blocker:** `hermes-bsd/pyproject.toml` already allows `>=3.11,<3.14`; Hermes
scripts use `env python3`. scripts use `env python3`.
- **FreeBSD packaging reality:** OSA's FreeBSD quarterly repo publishes `python312`, but - **FreeBSD 3.11/3.12 coexistence (clawdie-iso #84):** FreeBSD's `PYTHON_DEFAULT` is **3.11**,
not the matching `py312-aider_chat`, `py312-pillow`, `py312-pip`, or `py312-pygobject` so system pkgs (git, libinput, npm-node24, …) pull `python311` transitively. `python312` is
flavors yet. Keep Python package-flavored extras out of `pkg-list-*.txt` until they the **application** Python and wins the `python3` symlink via `sort -V`. Both coexist
exist; install those tools into explicit Python 3.12 venvs with uv/pip when needed. 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)).
- **ISO direction:** `clawdie-iso` should carry `python312`, version-agnostic `python3` - **ISO direction:** `clawdie-iso` should carry `python312`, version-agnostic `python3`
symlinks in `build.sh`, and `python3 -m venv` calls. Drop packages such as `gnumeric` symlinks in `build.sh`, and `python3 -m venv` calls. Drop packages such as `gnumeric`
when they keep the old Python flavor alive transitively. when they keep the old Python flavor alive transitively.