Files
clawmates/docs/NEXT-SESSION.md
T
Omar SobhandClaude Opus 5 5a11fae0d6
deploy / test (push) Successful in 4m39s
deploy / build (push) Successful in 1m0s
docs: container-tier gate and telemetry shipped; CI failures were disk
Records the verified result (10 tool.call, 4 file.touch on a real mission),
how hooks succeed where stream-json could not, the production state and its
rollback, and the three same-shaped bugs the live test found.

Also records that CI's build failures were disk pressure from my own manual
runtime builds on gw-04 — not code — and that a docs-only commit was the
first casualty, which made it look like a regression.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-21 07:11:02 -07:00

6.8 KiB
Raw Blame History

Where this left off — 2026-08-20

Read CAPABILITY-REVIEW.md for the system picture, TOOL-CALL-ARCHITECTURE.md for the current investigation, and SKILL-USE-BASELINE.md for the measurement.

State of the tree

Everything is pushed. main is at 128b423; the fork's merge/upstream-v0.8.4 is at db1c50966. The local suite is green — 106 test binaries, zero build errors, frontend builds.

Container-tier tool gate + telemetry — SHIPPED 2026-08-21

The tier that actually runs missions now has both, verified end to end on a real mission (locally first, then deployed):

tool.call   10    Bash 6, Read 3, Write 1
file.touch   4    research/tapproof.md

That is the first time the container tier has ever been observable.

How, after stream-json failed. Claude Code runs its tools inside its own subprocess, so they never reach ZeroClaw's executor and never become a TurnEvent::ToolCall. Hooks bypass that entirely: claude -p --settings <doc> honours PreToolUse and PostToolUse, so the gate blocks and the tap records without ZeroClaw being involved at all.

Pieces: --settings on claude_cli (fork be9c34b1c), container_tool_hooks writes both hook scripts and one settings document into the mission container, set_claude_cli_settings points the provider at it, and phase_runner::drain_finished_container_phases collects the tap into mission_events (idempotent by truncation — no cursor column).

Production state: server on f6e6037; CLAWMATES_RUNTIME_IMAGE=clawmates-runtime:hooks in /opt/clawmates/.env (backup at .env.bak.prehooks; rollback = restore it and recreate). Note that host uses legacy docker-compose, not the v2 plugin.

Not yet observed in production — no prod mission has run since the flip. Prod auth is Clerk, so a mission cannot be launched from here by password. The check when one runs:

ssh gw-04 'docker logs clawmates_server_1 2>&1 | grep -E "per-mission runtime image|drained .* tool call"'

Three bugs the live test found, all the same shape

Each left every other link looking correct:

  1. The settings document pointed PostToolUse at a path the installer never wrote. Claude Code does not complain about a missing hook command — it records nothing. A test now compares the document's commands against the files the installer creates.
  2. The mission container uses CLAWMATES_RUNTIME_IMAGE, not the shared clawmates-runtime container — it was on an older image whose daemon schema had no settings field, so the prop write returned 404 path_not_found.
  3. The drain used connect_with_local_defaults(); the server reaches Docker through a socket proxy, so it failed — and returned Ok(()) silently.

CI: build failures were disk, not code

Runs 503506 failed at build with an unreadable log, and the first casualty was a docs-only commit. Cause: building runtime images by hand on gw-04 competes with CI for the same 150G volume; the frontend image build lost. docker builder prune reclaimed 34GB (22G → 57G free) and the next run went green. The build job now writes breadcrumbs, a df -h snapshot, and which services actually pushed — the failing runs had pushed server, aborted on frontend, and left :latest unmoved, which surfaced three steps later as "the deploy did not happen".

Operational note: do not build images by hand on gw-04 while CI may run.

Then, in order

  1. Prove the PreToolUse gate in a real VM. vm_tool_gate is unit-tested and shell-tested on the host; it has never run in a guest. Four of its bugs were found only by executing the generated script, and two of them (syntax error, IFS) produce a gate that looks installed while being fully closed or fully open. Check /root/toolgate/denied.jsonl after a mission that tries something denied.

  2. Give the direct-session tier a tap. It is the one tier with no observability at all — session_executor::run_session is a single container_exec::exec returning a string. Same settings document, written into a container instead of a VM.

  3. Deploy the door we already built (docs/TOOL-CALL-ARCHITECTURE.md §3). Create /zeroclaw-data/clawmates-mcp.json, add a door-shaped provider alias, bind mission claws to it. This is config, not code — the provider feature is ours and shipped. It would also make clawmates_skills genuinely reachable, which is the precondition for moving skills from inlined bodies to progressive disclosure and making Skill-Use Trigger measurable the way the paper defines it.

  4. Pull upstream's egress policy0db7d999a feat(plugins): add shared egress policy foundation (#9137). We are 218 commits behind; this is the one item identified as worth taking, and it is defence for a problem we have not solved.

Open decisions that are yours

  • Self-authoring scope. Agents now apply their own skill_candidate items with no human click (CLAWMATES_SKILL_SELF_AUTHORING=0 restores the gate). identity_refinement and brain_consolidation still wait for a human, because they change what an agent IS rather than adding a procedure it can consult. Say if you want those autonomous too.
  • Skill-Use Compliance coverage. Most skills still score not_applicable — we cannot tell whether they changed anything. small-focused-commits and tdd-red-green-refactor are the next candidates and both need the repository diff rather than the turn text.

Deliberately not done

  • The mission executor swap (running turns through ProviderExecutor or the chat Runtime). The blockers are structural, not wiring: cm-runtime's files tool rejects absolute paths by construction, shell runs in a per-agent sandbox with no mission mount, ToolContext carries no path or VM handle, and approvals key on (session_id, message_id). The cheap fixes deliver what it was wanted for.
  • cm-brain offline tests — 6 of 9 need live clawbrainhub.com. Stubbing means reproducing an external registry protocol we have no spec for.
  • Graph memory / clawhdf5-agent — in the workspace manifest, used by no crate. Measure against a baseline before migrating.

Two corrections made this session, worth remembering

  • "Missions can't call tools at all" was wrong. They call Bash and Write with permissions pre-accepted. The gap was observing and gating, not having.
  • Raw test counts are a bad coverage metric. They pointed at cm-safety, whose seven tests already covered its critical paths, and missed a Slack replay hole that let one captured request authenticate forever.

The recurring shape, now seven times over: a claim in a comment or a doc, believed and never checked. Every significant finding this session came from running the thing rather than reading about it.