Every phase verdict this session was Anthropic grading Anthropic, and the boot
log said so on each start:
validator_preflight: no CLAWMATES_VALIDATOR_MODEL — phase verdicts are
judged by the house model, which is NOT an independent check
`evaluator.rs` already preferred a cross-provider judge and refused to call a
same-family one `independent`; the local stack simply had no non-Anthropic
credential. It now carries the same `glm` provider gw-04 has had all along —
`format = "anthropic"` is load-bearing, since z.ai's OpenAI-compatible endpoint
is ToS-throttled for raw SDK access while its Anthropic-format one is not.
Model: glm-5.3, the newest z.ai lists (4.5, 4.5-air, 4.6, 4.7, 5, 5-turbo,
5.1, 5.2, 5.3 as of 2026-08-17). gw-04 still runs glm-4.7.
glm-5.3 is a REASONING model: it emits a `thinking` block before its JSON. Our
SSE parser ignores `thinking_delta` and keeps the text, so the wire shape is
compatible — but on a realistic phase-evidence prompt it spent 819 of the
evaluator's 1024 output tokens. A longer phase would truncate the verdict, and
a truncated verdict parses as empty and FAILS CLOSED, burning one of the
phase's passes on a judge that never answered — precisely how mission 01a00bbb
lost a pass. max_tokens raised to 2048.
Measured before wiring: asked to judge 25 commits claiming INT-01..INT-25 with
tests passing, glm-5.3 returned met=false because the evidence never
established what the brief actually required. That skepticism is the point of
an independent judge.
Boot now reports: `validator_preflight: independent validator glm:glm-5.3
answered`.
The key lives in .env (gitignored), never in this file.
Co-Authored-By: Claude Opus 5 <[email protected]>
Clawmates on Docker Compose
A single-node deployment of the whole platform — the same images the Kubernetes/Helm path uses, with the same §15 security topology. This is the air-gapped appliance route; it is equally usable as a simple self-host.
What runs
| Service | Role |
|---|---|
postgres |
database (named volume pgdata) |
broker |
the secret broker — credentials never leave it; reachable only over a private socket volume shared with the server |
socket-proxy |
allow-listed Docker API so the server can spawn agent sandboxes and nothing else |
server |
API + streaming gateway + agent runtime + scheduler |
frontend |
the Next.js web app |
Networks core, secrets_net, sandbox_net, and engine_net are all
internal: true; only edge is published. Agent sandboxes run with no
network at all (egress is the browser container's alone).
Quick start
cd deploy/compose
cp .env.example .env
# Edit .env: set POSTGRES_PASSWORD and CLAWMATES_BOOTSTRAP_OWNER_PASSWORD.
# Either build the images locally...
docker compose build
# ...or load them from a signed release bundle (see deploy/airgapped/install.sh).
docker compose up -d
The server self-migrates on boot and, if CLAWMATES_BOOTSTRAP_OWNER_PASSWORD
is set, provisions the first Owner + workspace once (a no-op on every later
boot). Then open:
- App → http://localhost:3000
- Sign in with
CLAWMATES_BOOTSTRAP_OWNER_EMAIL/…_PASSWORD. - API health → http://localhost:8080/healthz
Configuration
Host- and secret-specific values come from .env (overlaid onto
clawmates.toml at runtime — CLAWMATES_* env always wins). The knobs:
| Concern | Where | Notes |
|---|---|---|
| DB password | .env POSTGRES_PASSWORD |
also forms the server/broker DSN |
| Image tag | .env CLAWMATES_VERSION |
latest after a local build, or a release version |
| First owner | .env CLAWMATES_BOOTSTRAP_* |
password set = bootstrap on first boot |
| LLM | clawmates.toml [llm] |
openai_compat (default, point base_url at vLLM/Ollama/llama.cpp) or anthropic (+ ANTHROPIC_API_KEY in .env) |
| Auth | clawmates.toml [auth] + .env AUTH_MODE |
local (default) or clerk (see docs/clerk.md) |
| Tracing | .env CLAWMATES_TELEMETRY__OTLP_ENDPOINT |
unset = logs only, no egress |
Using Anthropic instead of a local model
In clawmates.toml:
[llm]
provider = "anthropic"
model = "claude-sonnet-4-6"
and set ANTHROPIC_API_KEY in .env.
The broker master key — back it up
On first boot the broker generates its encryption key into the broker_key
volume and logs a reminder. Every stored credential is unrecoverable
without it. Back it up:
docker compose cp broker:/etc/clawmates-broker/broker.key ./broker.key.backup
Operations
docker compose ps # status
docker compose logs -f server # follow server logs
docker compose pull && docker compose up -d # upgrade to a new CLAWMATES_VERSION
docker compose down # stop (keeps volumes/data)
docker compose down -v # stop AND delete all data
Production notes
- Put a TLS-terminating reverse proxy in front of ports 3000/8080; the SSE
gateway needs response buffering off (the Helm ingress sets this; nginx:
proxy_buffering off;with long read timeouts). socket-proxymounts the Docker socket read-only and exposes only the container lifecycle verbs — verified bycrates/cm-sandbox/tests/socket_proxy.rs.- The full bring-up is exercised end to end by
scripts/rehearse-install.sh(verify a signed bundle →docker load→compose up→ assert the login page serves), which also runs in the release pipeline.