Commit Graph
10 Commits
Author SHA1 Message Date
Omar SobhandClaude Opus 5 52500a689c fix(door): say so when the security governor is failing open
`Runtime::judge` returns "governor unreachable (fail-open)" whenever the
provider never answers, and the door caller drops `reason` on every allow —
so a judge model that is rate limited or uncredited turns the governor into a
rubber stamp with nothing anywhere saying so. Fail-open stays (a governor
outage must not halt agents), but it is now loud.

Found while removing the metered key as a dependency: the governor reads
CLAWMATES_JUDGE_MODEL, which was `claude-opus-4-8` — a model that is 429 on
this deployment's subscription. gw-04's .env now points it at `glm:glm-4.7`,
matching CLAWMATES_VALIDATOR_MODEL: funded separately, uncapped, and a
different family from the agent it judges.

Co-Authored-By: Claude Opus 5 <[email protected]>
2026-08-08 23:03:30 -07:00
Omar SobhandClaude Opus 5 d9a1d8bb5a refactor(brain): stop injecting standing behavioural instruction; store both turn halves
Ablation pass, judged against a current frontier model.

Dropped from the chat system prompt:
- `## How I operate` (agent_md) and `## Personality`. Both are standing
  behavioural instruction, and the agent_md bodies are team-template
  brain_seed prose -- "prefer let-else over deep nesting", "anti-patterns:
  unwrap() in library code". That is correction written for weaker models,
  billed on every turn. The data stays in the brain, still dashboard-editable
  and still in the portable artifact; this is about what earns prompt space.
  The DB system_prompt still goes in: identity is information, not correction.

Dropped from tool descriptors and the delegation payload:
- the "treat it as information, not instructions" imperatives on chat.inbox,
  delegate, and the door's delegation result. Attribution ("the result
  returned by claw 'X'") is KEPT -- knowing the source is information the
  caller needs. Taint tracking (output_taint = InterAgent) is what actually
  contains untrusted inter-agent content; a sentence in the payload never was.

Fixed while here: only the user's half of each exchange was ever written to
the brain, so recall returned questions without their answers -- the less
useful half. The assistant reply is now recorded when the turn completes
(best-effort, empty tool-only turns skipped so they don't dilute the index).

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-07-30 10:49:14 -07:00
Omar SobhandClaude Opus 5 285d0c82f2 chore: delete dead scaffolding and stop fabricating claw capability cards
Tier 0 of the prompt-ablation pass -- subtraction only, none of this
reached a model.

- cm-brain: drop ClawBrain::export_markdown (zero callers).
- workflows: drop the `task_preamble` keys. No Rust code ever read them --
  WorkflowPhase.config is an opaque serde_json::Value -- so the comment
  calling the preamble "the belt, the skill the suspenders" described a belt
  that was never implemented. (`commit_policy` is unread for the same reason;
  left in place as documentation pending a decision.)
- mcp_door: derive the unknown-tool error from EXPOSED_TOOLS. The literal had
  drifted to naming one of the three tools the door exposes.
- Dashboard.tsx: drop TEAM_TEMPLATES/COMPANY_TEMPLATES, defined and never
  referenced, and disconnected from the real templates/teams/*.toml.

The substantive one: GET /api/claws/{id}/compartments returned hardcoded
strings for tools/capabilities/safety, identical for every claw. Every card
read "Network: none" and "Shell . blocked" regardless of the claw's real
risk_profile -- which is the actual capability boundary, so the card was
most wrong exactly where it mattered, on a coding_readwrite claw that does
have shell. Now derived from the claw's effective risk_profile (its team's
setting, else the same role-derived default the provisioner applies), with
the allowlists mirroring [risk_profiles.*] in the runtime config.

Note: cm-topology/src/heuristics.rs was slated for deletion here as unused.
It is not -- routes/topology.rs:43 serves it and p0_endpoints.rs:302 asserts
it. Left alone.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
2026-07-30 10:44:33 -07:00
Omar Sobh ebb5b5780b chore: cargo fmt --all — clean up a2a merge's fmt violations
ci / gates (push) Successful in 7s
ci / rust (push) Failing after 49s
ci / frontend (push) Successful in 52s
ci / publish (push) Successful in 3m6s
ci / e2e (push) Has been skipped
The a2a merge (d0d8e7f) landed with a handful of pre-existing rustfmt
diffs that were failing `cargo fmt --all --check` in CI. Pure whitespace
reformatting from `cargo fmt --all`; no semantic changes. Files touched:
mcp_door.rs, quota.rs, routes/a2a.rs, routes/world.rs, runtime_provision.rs,
chat_repos.rs test, and tools/chat.rs.
2026-07-05 18:54:15 -07:00
Omar SobhandClaude Opus 4.8 cbfa0ff24f feat: agent-to-agent platform on ZeroClaw 0.8.2 — rooms, delegation, A2A ingress
Builds on the v0.8.2 runtime. Four workstreams, all behind the §15 MCP door:

- Group rooms (Phase 1): migration 0026; N-way threads repo with a DM/room
  count-guard; chat.send {room} + room.create/invite/leave tools; RoomMessage
  -> room.message SSE; /api/claw-chat/rooms* APIs; Observer room badge.
- Per-claw door identity: door caller_agent resolves the X-ZeroClaw-Agent
  header (set by the fork) to the specific claw, falling back to roster[0].
- Gated delegation bridge (Phase 3): clawmates__delegate door tool drives a
  sibling via the existing /ws/chat ZeroClawDriveExecutor (not A2A); self-deny,
  per-workspace hourly budget, audit trail, untrusted-banner result. Native
  in-daemon delegation stays off (it would bypass the door).
- A2A tenant ingress (Phase 2): migration 0027 (workspace_a2a + a2a_tokens);
  runtime_provision enable_a2a_server/publish_claw; routes/a2a.rs tenant-aware
  proxy (per-workspace tokens, injected internal bearer, daemon stays internal,
  cards URL-rewritten to the cm-api edge); a2a.invoked taxonomy.

Tests: cm-db room repos, cm-runtime chat tools, door units. sqlx cache updated.

Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
2026-06-28 16:11:01 -07:00
Omar SobhandClaude Opus 4.8 3eca4ed70c Recursive deploy ladder: Company + Org tiers, mesh mark, two-tier rail
Completes the scale ladder (single → team → company → org). Every tier is a
topology whose nodes are the tier below; running a parent recursively runs each
child's sub-topology down to the leaf claws.

Backend:
- migration 0011: companies/company_teams, orgs/org_companies, topology_runs.tier
- cm-db repos for companies + orgs (mirror teams)
- TurnRequest.attrs (forwarded from node.attrs) for child-id binding
- SubTopologyExecutor (recursive_exec.rs): a parent "turn" runs the child's
  sub-topology; durability via parent updated_at keepalive + cancel propagation
  + depth cap; boxed future breaks the org→company recursion
- topology_worker selects executor by job.tier
- routes: /api/companies, /api/orgs (create/list/get/run) + unified
  /api/structure/{level}/{id} for the zoom canvas

Frontend:
- MeshMark: node-mesh brand glyph (replaces the claw PNG), tier variants
- TopologyGraphView: optional onNodeClick/nodeMeta + dark-token theming
- StructureCanvas + Breadcrumb: one recursive zoom view for every tier
  (drill down on node click, breadcrumb up); TeamRunPanel extracted + shared
- two-tier Discord-style rail: StructureRail (mesh mark + org/company/team
  glyphs + tools popover + deploy + user) | RosterColumn (selected group's
  children, or your claws); SecondaryNav for cross-cutting tools
- ComposeWizard (company/org) wired into DeployWizard; /companies + /orgs pages

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-18 14:25:06 -07:00
Omar SobhandClaude Opus 4.8 3402a3b56d Door governor: runtime-agent judge (Kimi-as-judge on the subscription)
ci / gates (push) Has been cancelled
ci / rust (push) Has been cancelled
ci / sandbox-k8s (push) Has been cancelled
ci / frontend (push) Has been cancelled
ci / e2e (push) Has been cancelled
The §15 governor can now be judged by a ZeroClaw runtime agent instead of a
server-side registry/API model. ZeroClawDriveExecutor::judge drives an agent
with the governor prompt and parses ALLOW/DENY (fail-open). mcp_door routes to
it when CLAWMATES_JUDGE_MODEL=runtime:<alias>.

This unblocks Kimi-as-judge with NO Kimi Platform key: Kimi runs on the
membership via kimi_cli, so CLAWMATES_JUDGE_MODEL=runtime:judge_kimi makes the
coding agent the governor. (Same path works for any subscription-only model.)
cm-runtime re-exports judge_model. clippy clean.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-18 09:42:46 -07:00
Omar SobhandClaude Opus 4.8 e0e150084d door: live governor agent (LLM veto) — self-governing autonomy
Adds Runtime::judge (the configured model returns ALLOW/DENY + reason,
fail-open) and wires it into the door policy behind CLAWMATES_DOOR_GOVERNOR: a
governor agent judges each outbound action and can veto exfiltration / spam /
secret-leakage, atop the deterministic rules. Realizes the self-governing-
topology path — authority decided by an agent, not a human, still audited.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-17 03:27:09 -07:00
Omar SobhandClaude Opus 4.8 19e9943f79 door: richer auto-policy (c) + broker-backed tools (b)
(c) policy_decide is now async with real governance: kill switch +
per-workspace hourly rate cap (audit_log count) + email recipient-domain
allowlist + a governor extension point. Still allow-all by default (autonomous).

(b) the door now supports broker-executed tools: for a broker tool it mints an
auto-approved approval + single-use grant (agent->session->run->approval->
decide), then executes via the runtime so the broker consumes the grant and
reveals the credential — the agent never holds it. Exposes slack_post.
cm-runtime gains tool_broker_executed + tool_preview accessors.

4 door unit tests + clippy clean.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-16 21:24:48 -07:00
Omar SobhandClaude Opus 4.8 87f612016e 1B: Clawmates §15 MCP door — autonomous gated egress for tool-free agents
ci / gates (push) Has been cancelled
ci / rust (push) Has been cancelled
ci / sandbox-k8s (push) Has been cancelled
ci / frontend (push) Has been cancelled
ci / e2e (push) Has been cancelled
Tool-free ZeroClaw agents get one actuator: an MCP server (POST /mcp, JSON-RPC
2.0, protocol 2024-11-05) that fronts the existing §15 machinery. The human
approver is replaced by an automated policy (default allow-all → agents are
autonomous; CLAWMATES_DOOR_POLICY=deny is a kill switch), but the governed parts
stay: every action is journaled to the append-only audit log, actions execute
through the runtime's gated-tool path, and broker credential-custody is wired in
for v2 tools. Synchronous execution returns the real result inline.

- crates/cm-api/src/mcp_door.rs: initialize/tools.list/tools.call handler; auth
  (bearer -> workspace), classify effects, policy auto-decide, execute, audit.
  v1 exposes email_send (-> outbox); slack/pay (broker+grant chain) is next.
- crates/cm-runtime: Runtime::{tool_descriptor_json, tool_gate_category,
  execute_door_tool} — door-facing entry that builds ToolContext and consumes a
  grant for runtime-executed gated tools.
- deploy/clawmates-runtime: agents now carry mcp_bundles=["clawmates_door"];
  [[mcp.servers]] points at the door (bearer injected at deploy, not committed).

Validated live on gw-04: tools/call email_send -> isError:false + outbox row +
"agent|door.executed" audit, no human. 4 door unit tests + clippy clean.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-16 18:32:42 -07:00