Every rootfs on the fleet had sat on Claude Code 2.1.223–2.1.226 since August while the container tier moved to 2.1.276, and nothing recorded either. GLM and Kimi exist only as microVM backends, so "have we upgraded GLM and Kimi" is this change and the rebuild it drives. Pins. All four agent-* images pin 2.1.276 — as separate ARGs, since Docker has no include and each file has to stay reproducible alone — and scripts/fc-build-rootfs.sh refuses to build if they disagree, naming the odd one out. They had already drifted (claude 226, the rest 223) under comments saying "same version on purpose". Between 2.1.226 and 2.1.276, 2.1.265 and 2.1.275 each broke every turn on ANTHROPIC_BASE_URL endpoints, which is how glm and kimi reach `claude` inside a VM; the container-tier verification never exercised that path, so the VM runs on those backends are the real test. Provenance. `VmOutcome` carries the rootfs the node reported booting and the guest's own `claude --version`; `launch_microvm_phase` persists both as `checkpoint.vm` beside `records` (the two readers parse only `records`) and names them in its log line. "Which image and CLI did this mission run on" is a query now. Independence. `evaluator` derived the implementer family from a constant `"anthropic"`, true while every backend was Claude on Anthropic. With glm and kimi rootfs it made a glm mission judged by glm:glm-5.3 read as `independent = true` — the one claim that path exists to make honestly. `implementer_family(missions.backend)` mirrors `microvm_credential_for`; the subscription judge is now independent exactly when the agent did NOT run on Anthropic. Harness. `verify-mission-delivery.sh glm|kimi` run the microvm scenario on each backend and add the proof the mission itself cannot give: the placed node's journal must show the VM dialling that provider's host, never being denied it, and dialling nothing else but the forge — a model's self-report is measured worthless here. `assert_cli_version` reads checkpoint.vm. The stale scratch-repo default (dead since the 09-14 wipe) is the re-synced id. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01WZb5A2kfVfjpdwSochkuHz
63 lines
3.4 KiB
Docker
63 lines
3.4 KiB
Docker
# Claude Code pointed at a model running on the NODE ITSELF.
|
|
#
|
|
# The third variation on one idea: `agent-claude` talks to Anthropic,
|
|
# `agent-glm` to z.ai, `agent-kimi` to Moonshot, and this one to the Ollama
|
|
# already installed on every GPU node. Ollama has served a native
|
|
# Anthropic-compatible `/v1/messages` since v0.14, so this costs an env contract
|
|
# rather than a translation layer — MEASURED on both nodes: a tools request
|
|
# comes back with a well-formed `tool_use` block and `stop_reason=tool_use`.
|
|
#
|
|
# Why the base URL is loopback INSIDE the guest, not a hostname:
|
|
#
|
|
# The VM has no network interface. `fcagent` listens on 127.0.0.1:11434 and
|
|
# pumps to vsock 9003, where `clawmates-node::local_model` splices it onto the
|
|
# node's own `127.0.0.1:11434`. There is no destination anywhere in that path —
|
|
# it is a pipe to a fixed address, so a compromised guest cannot redirect it.
|
|
# `NO_PROXY` already contains 127.0.0.1, so this bypasses the egress proxy
|
|
# rather than trying to CONNECT through it.
|
|
#
|
|
# Build (on a node with a GPU — architect or tank):
|
|
#
|
|
# ssh architect "cd ~/clawmates && \
|
|
# docker build -f images/agent-ornith/Dockerfile -t clawmates/agent-ornith:dev images/agent-ornith/"
|
|
# scripts/fc-build-rootfs.sh architect clawmates/agent-ornith:dev local-ornith 8G
|
|
#
|
|
# Building it ONLY on GPU nodes is deliberate and is the whole placement story:
|
|
# a node advertises `rootfs-local-ornith.ext4` in `capabilities.rootfs`, and
|
|
# `nodes::online_for_backend` already filters on exactly that. No GPU capability
|
|
# key, no migration — morpheus simply never offers this backend.
|
|
FROM clawmates/agent-toolchain:dev
|
|
|
|
# Pinned to the SAME version as agent-claude and agent-glm. A run that differs
|
|
# by provider should differ by nothing else, or "the local backend behaved
|
|
# differently" is ambiguous between the model and the harness.
|
|
# 2.1.276, 2026-09-18. Between 2.1.226 and here, 2.1.265 and 2.1.275 each broke
|
|
# every turn on ANTHROPIC_BASE_URL endpoints (HTTP 400) — the path the glm and
|
|
# kimi images use — and 2.1.276 is the first version after both that is fixed.
|
|
# All four agent-* images pin the SAME version; scripts/fc-build-rootfs.sh
|
|
# refuses to build if they drift. Bump them together, on purpose, and run a
|
|
# mission on each backend before promoting (see deploy/clawmates-runtime/Dockerfile
|
|
# for the same rule on the container tier).
|
|
ARG CLAUDE_CODE_VERSION=2.1.276
|
|
RUN npm install -g "@anthropic-ai/claude-code@${CLAUDE_CODE_VERSION}" \
|
|
&& npm cache clean --force \
|
|
&& rm -rf /root/.npm \
|
|
&& claude --version
|
|
|
|
# `ornith-fleet:9b`, NOT `ornith:9b`. Ollama defaults to a ~2K context window
|
|
# whatever the model card says, and it truncates silently: MEASURED, stock
|
|
# ornith:9b reported input_tokens=2050 for a 48000-word prompt and answered as
|
|
# though nothing had been dropped. The fleet tag pins num_ctx=131072 and is
|
|
# created by `scripts/fleet-model-setup.sh`. An agent turn is exactly the
|
|
# workload that would hit the default and never say so.
|
|
ENV HOME=/root \
|
|
CLAWMATES_AGENT_CLI=claude \
|
|
ANTHROPIC_BASE_URL=http://127.0.0.1:11434 \
|
|
ANTHROPIC_MODEL=ornith-fleet:9b \
|
|
ANTHROPIC_SMALL_FAST_MODEL=ornith-fleet:9b
|
|
RUN mkdir -p /root/.claude
|
|
|
|
# No provider key of any kind. `microvm_credential_for` hands this backend a
|
|
# literal placeholder because Ollama ignores the bearer and Claude Code refuses
|
|
# to start without one. There is no secret in this image and none reaches it.
|