Skip to content

feat(release): publish a generic all-in-one stack image - #506

Merged
thedancingdeveloper merged 1 commit into
devfrom
feat/generic-aio
Sep 2, 2026
Merged

feat(release): publish a generic all-in-one stack image#506
thedancingdeveloper merged 1 commit into
devfrom
feat/generic-aio

Conversation

@thedancingdeveloper

Copy link
Copy Markdown
Contributor

The release stack was the inverse of what it is published for: no INSTALL_AI_CLIENTS line at all, so engine/Dockerfile's false default won, and INSTALL_CADASTRE_MCP=true. It shipped the maintainer's estate MCP to strangers while withholding the two CLIs the product exists to run. Nothing was red, because nothing asserted either half.

A release now builds the generic shape — claude and codex, no estate integrations, the lean pod base — and deploy/stack.compose.yml runs it with only an .env. build.yml's dev/prod branch builds keep the estate rule and layer Cadastre and theclawbay on top of the same base, which is the parity model stated one level up from engine/Dockerfile's "the private path is the public path plus configuration".

The verification that did not exist

vogt-verify-agent-clis does not prove the CLIs are present and never did. It is a shadow detector: check_tool returns 0 when the system path does not exist, check_package returns 0 unless the binary is executable, and agent-versions.resolved is written unconditionally — so it is green on a CLI-free image. It answers "is a persisted $HOME copy shadowing the image's?", not "is there an image copy?".

The release smoke test now runs claude and codex. That is the only thing separating a generic release from a silent reversion to the CLI-free one (#23).

#505, folded in

The pin moves 2.1.2362.1.258: Claude Fable 5.1 arrived in 2.1.257, and the pin is deliberately unwalkable at runtime (#196), so a stale one can only be fixed by a rebuild. npm install -g exiting 0 is not evidence that claude runs — the tarball ships bin/claude.exe as a stub resolved by postinstall — so the build now runs it against the pin. That is the packaging that broke 2.1.237 (#147/#148) and held the pin for months.

Verified in a clean node:22-bookworm container: 2.1.258 installs non-stub, claude --version prints 2.1.258 (Claude Code) as root with no config, the guard passes, and it correctly rejects a wrong version.

A trap that bit twice

# inside a build-args: | block is content, not a comment, and reaches buildx as a build arg. build.yml already carried a note saying so because the mistake had been made once; it was made again while writing this change. It is now test_no_build_args_block_contains_a_comment over both workflows instead of a comment in one — confirmed to fail on an injected comment before being kept.

Docs

DEPLOYMENT.md §1.1 compares the three shapes and states the AIO's dev-pod posture plainly (sudo, sshd, DooD, no read_only); §7 replaces the "CLI-free by design" claim with the generic-vs-estate tag table; CUSTOMISATION.md gains the FROM vogt-stack@sha256:... worked example, which is how the private overlays are actually built. Four sites said "no engine image is published" — true of the engine alone, and now stated that way.

Supersedes

Closes #505. #502 and PR #503 are closed as resolved-by-design: their stated harm (pin latest, get an agent-less pod) disappears once the release carries the CLIs, and #502's "stop tagging latest" proposal inverts once vogt-stack is the supported public AIO.

Not in scope

Plan steps 2 (thin Dockerfile.pod) and 3 (GHCR visibility flip) are deliberately held: step 2 is gated on the private overlay parity-validating on vogt-dev, and step 3 should follow the first generic release so the first public digest is not the Cadastre-carrying v0.4.0.

Verification

uv run pytest 1315 passed / 25 skipped / 91% coverage · mypy clean · ruff check + format --check clean · check_docs.py clean · docker compose -f deploy/stack.compose.yml config renders.

🤖 Generated with Claude Code

https://claude.ai/code/session_01RzFCTnWGff1k4FyX1HQCYM

The release stack was the inverse of what it is published for: no
`INSTALL_AI_CLIENTS` line at all, so `engine/Dockerfile`'s `false` default
won, and `INSTALL_CADASTRE_MCP=true`. It shipped the maintainer's estate MCP
to strangers while withholding the two CLIs the product exists to run.
Nothing was red, because nothing asserted either half.

A release now builds the generic shape — claude and codex, no estate
integrations, the `lean` pod base — and `deploy/stack.compose.yml` runs it
with only an `.env`. `build.yml`'s dev/prod branch builds keep the estate
rule and layer cadastre and theclawbay on top of the same base, which is the
parity model stated one level up from `engine/Dockerfile`'s "the private path
is the public path plus configuration".

`vogt-verify-agent-clis` does not prove the CLIs are present and never did.
It is a shadow detector: `check_tool` returns 0 when the system path does not
exist, `check_package` returns 0 unless the binary is executable, and
`agent-versions.resolved` is written unconditionally, so it is green on a
CLI-free image. The release smoke test now runs `claude` and `codex`, which
is the only thing separating a generic release from a silent reversion to the
CLI-free one (#23).

Also #505: the pin moves 2.1.236 -> 2.1.258, since Claude Fable 5.1 arrived
in 2.1.257 and the pin is deliberately unwalkable at runtime (#196), so a
stale one can only be fixed by a rebuild. `npm install -g` exiting 0 is not
evidence that `claude` runs — the tarball ships `bin/claude.exe` as a stub
resolved by `postinstall` — so the build now runs it against the pin. That is
the packaging that broke 2.1.237 (#147/#148) and held the pin for months.

`#` inside a `build-args: |` block is content, not a comment, and reaches
buildx as a build arg. `build.yml` already carried a note saying so because
the mistake had been made once; it was made again here, so it is now a test
over both workflows instead of a comment in one.

Docs: DEPLOYMENT §1.1 compares the three shapes and states the AIO's dev-pod
posture plainly (sudo, sshd, DooD, no `read_only`); §7 replaces the
"CLI-free by design" claim with the generic-vs-estate tag table;
CUSTOMISATION gains the `FROM vogt-stack@sha256:...` worked example that is
how the private overlays are actually built. Four sites said "no engine image
is published", which was true of the engine alone and is now stated that way.

Refs #505
@thedancingdeveloper
thedancingdeveloper merged commit ba6baf1 into dev Sep 2, 2026
24 of 26 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant