chore(runtime): promote v0.8.4 from canary to the default image
ci / gates (push) Failing after 6s
ci / rust (push) Skipped
ci / frontend (push) Skipped
ci / e2e (push) Skipped
ci / publish (push) Skipped

Every mission on gw-04 was already running v0.8.4 — pinned by
CLAWMATES_RUNTIME_IMAGE in .env. The canary is retired: the default tag
`clawmates-runtime:sync` now IS that image, the override is commented out,
and the built-in default is the single source of truth again.

Promoting it exposed why the pin was load-bearing in the first place. The
default tag resolved to zeroclaw 0.8.3 — two releases behind what was
actually running — and the REGISTRY copy of the same tag was a different
image again, 849MB against 2.31GB, without the Rust toolchain. A host that
pulled `sync` rather than retagging it would have lost the on-green test
gate with every probe still reporting success.

A moving tag pointing somewhere old resolves perfectly, starts perfectly,
and runs old code. Nothing anywhere said which image a mission got, so two
things now do:

- mission_runtime logs the image it resolved and whether that came from
  the env override or the built-in default, once at startup.
- runtime_preflight probes `zeroclaw --version` alongside the other tools
  and prints every tool's VERSION, not just that it is present. A presence
  check passes happily on an image two releases behind, which is exactly
  what happened here and was found by running the binary by hand.

Rollback is a retag: `clawmates-runtime:pre-v084-default` on gw-04 holds
the previous default, and .env.pre-v084-default holds the previous pin.

Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
Omar Sobh
2026-08-11 13:57:08 -07:00
co-authored by Claude Opus 5
parent d810fc0a86
commit cdc45bd082
2 changed files with 38 additions and 7 deletions
+17 -2
View File
@@ -37,6 +37,11 @@ struct Dependency {
}
const DEPENDENCIES: &[Dependency] = &[
Dependency {
argv: &["zeroclaw", "--version"],
needed_for: "driving every container-tier turn; the version is also how \
a runtime image that silently rolled back is noticed",
},
Dependency {
argv: &["cargo", "--version"],
needed_for: "the on_green_tests gate for Rust repos; without it every \
@@ -193,10 +198,20 @@ pub fn report_at_boot() {
let missing: Vec<&ToolStatus> = tools.iter().filter(|t| !t.present).collect();
if missing.is_empty() {
let names: Vec<&str> = tools.iter().map(|t| t.program.as_str()).collect();
// The VERSIONS, not just the names. A tag that quietly
// points at an older build passes a presence check
// perfectly: gw-04's default tag was two zeroclaw releases
// behind while every probe said "present", and the only way
// anyone found out was running the binary by hand.
let detail: Vec<String> = tools
.iter()
.map(|t| format!("{}={}", t.program, t.detail))
.collect();
eprintln!(
"runtime_preflight: `{container}` has all {} expected tools ({})",
"runtime_preflight: `{container}` has all {} expected tools ({}){}",
tools.len(),
names.join(", ")
names.join(", "),
detail.join("; ")
);
return;
}