331 behind, 54 ahead. The previous scan said 218 and its conclusion about the egress commit was wrong, so it is marked superseded rather than edited. Merge cost is smaller than the number suggests: 660 files changed upstream, 52 by us, and **18 overlap**. `claude_cli.rs` — the provider every mission runs through — exists in our tree and in zero upstream files, so it cannot conflict. The find worth recording is not a feature. Upstream defaulted skills to compact injection on 2026-08-05 (#8313), then restored the full default for v0.8.x on 2026-08-13 (#9913). Eight days. That is our `index` arm, tried at larger scale and pulled back out of the stable line — evidence bearing directly on our own open question of whether to flip the default, and with our own data at n=1 per arm it argues for more pairs before flipping, not fewer. Their documentation also states plainly what ours should: "Compact mode reduces prompt size; it is not an isolation boundary for untrusted skill sources." Progressive disclosure is a token optimisation. It is not a security control. Also noted, as a documented limit rather than a surprise: upstream fixed case-insensitive allowlist matching (#9568) and symlink-escape path resolution (#9384) in their command gate. Ours resolves no paths, so a symlink to `curl` defeats it. Co-Authored-By: Claude Opus 5 <[email protected]> Claude-Session: https://claude.ai/code/session_01WZb5A2kfVfjpdwSochkuHz
5.5 KiB
ZeroClaw upstream, scanned against what we run — 2026-08-27
Our fork (git.redclaw.dev/osobh/zeroclaw) sits 331 commits behind
upstream/master and 54 ahead. The previous scan in
TOOL-CALL-ARCHITECTURE.md said 218; that number is stale and its conclusion
about the egress commit was wrong — see MISSION-EGRESS.md.
Upstream since our merge base (a56c345d51, v0.8.4): 198 fixes, 35 features,
25 docs, 24 tests. The scan below filters that to what touches how ClawMates
uses the runtime: claude_cli as the mission provider, the gateway RPC and WS,
pairing, the skills door, and the claude→kimi→glm fallback chain.
Merge cost
| files we changed | 52 |
| files upstream changed | 660 |
| overlap | 18 |
claude_cli.rs exists in our tree and in zero upstream files, so the
provider that runs every mission cannot conflict. The overlap is concentrated in
providers/{factory,catalog,lib,compatible}.rs, runtime/agent/{loop_,turn, system_prompt}.rs, gateway/ws.rs and config/schema.rs. A full merge is a
real piece of work but not an unbounded one.
Tier 1 — take these
841f28c7f1 fix(gateway): serialize config writes so a flush can't erase
concurrent updates (#9519). The one I would take first. Upstream added a
config_write_lock around "the read-mutate-save-swap critical section of every
HTTP" config write. Our pinned gateway has no such lock — the mutexes in
gateway/src/lib.rs are for rate limits, keys, cancellation and the SOP engine.
We make two config writes per mission, on adjacent keys:
providers.models.claude_cli.default.settings (hooks — orchestrator:341)
providers.models.claude_cli.default.mcp_config (skills door — orchestrator:980)
Stated honestly: ours are sequential and awaited, so this is a latent hazard, not a demonstrated bug in our deployment. It earns first place because the failure mode is one this codebase has hit repeatedly — two writers of one document, second wins, no error — and because the loser here is either the security gate or the skills door, both of which fail silently and invisibly.
eadaee0b62 fix(providers): redact Anthropic credential fragments (#10092).
We forward provider credentials into mission containers and log heavily around
them. Credential fragments in logs are a live risk for us specifically.
47adb9863e fix(gateway): harden unauthenticated /api/pair against lockout
bypass (#9438). We mint a pairing code per mission container. The gateway port
is not published to the host, but mission containers share clawmates_edge, so
one mission's container can reach another's gateway. A pairing lockout that can
be bypassed is a cross-mission path.
49ba8064d3 + 0b1a715c72 + 0cba80e422 — reliable-fallback accounting and
served-model logging. We run claude→kimi→glm and care which one answered;
these make the fallback's own account of itself accurate.
Tier 2 — take the idea, not the code
Upstream's skills system is not ours: mission skills go through our delivery path and our MCP door. The findings still apply.
d04b345bda honor always-inject frontmatter in compact prompt mode (#9520).
Upstream compact mode has an always: true escape hatch — a skill that stays
fully injected no matter the mode. Our skills table has no such column
(id, workspace_id, title, author, description, body, installs, created_at, name, when_to_use, tags, source_kind, current_version, updated_at), and our
delivery A/B produced exactly the failure it prevents:
workspace-repo-commit-protocol scored Trigger=FAIL in the index arm because
no agent fetched it. An always-inject flag is the missing piece.
9ea4f3371a → 633c06f7c5 — the default, and the reversal. Upstream
defaulted skills to compact injection on 2026-08-05, then restored the full
default for v0.8.x on 2026-08-13. Eight days. That is direct evidence for
our own open question of whether index should become the default: someone
larger tried the same move and pulled it out of the stable line. It does not
tell us they were right, and their reason is in an issue rather than the commit
— but with our own evidence at n=1 per arm, it argues for more pairs before
flipping a default rather than fewer.
Their documentation also carries a line worth adopting verbatim in spirit: "Compact mode reduces prompt size; it is not an isolation boundary for untrusted skill sources." Progressive disclosure is a token optimisation. It is not a security control, and ours should not be described as one.
86f03d2d75 match command allowlist names case-insensitively (#9568) and
7388987b55 resolve shell command path arguments to block symlink escapes
(#9384). Different codebase, same bug class as the one we fixed in
vm_tool_gate yesterday. Our gate resolves no paths and follows no symlinks, so
/tmp/link-to-curl -d @secret … defeats it. Worth knowing as a documented limit
rather than pretending otherwise.
Tier 3 — situational
53cba1dddeopt-in multi-arch Alpine image — we hand-build arm64 today.4282a5564agateway chat WebSocket keepalive — we already hardened our side.0db7d999ashared egress policy — chat tier only; seeMISSION-EGRESS.mdfor why it cannot reach a mission'scurl.6d76787556per-server custom CA trust for MCP — our door is plain HTTP inside docker; no value today.
Not relevant
zerocode (21), the channel integrations (WhatsApp, Telegram, Matrix, Slack),
hardware/uno-q, the installer, and the Nostr dependency work. None of it is on
a path ClawMates executes.