Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
## Unreleased

### Added: Guard enforcement, the wire from a detector finding to pause/stop/kill, off by default behind three locks (carries #5367) (2026-09-03)
- **Why:** clawmetry.com and the Rootconf talk present a kill switch for rogue agents. Manual Stop/Pause/Resume and the eight detectors were both live, but nothing connected them: a session flagged as stuck at 2 AM got a badge in a list nobody was looking at. This closes that gap without changing the default behaviour of a stock install. The homepage line "Detectors warn. They do not act." stays true until an operator opens all three locks on purpose.
- **What:** (1) A pure policy engine (`clawmetry/policy_engine.py`) turns detector incidents plus operator policies into at most one decision per session, strongest action winning, with escalation ladders (pause now, kill in five minutes if still matching). (2) The daemon evaluates policies on every detector tick; a decision reaches a process only when the policy's own action is enforcing (new policies default to `monitor`, which records what it would have done and touches nothing), the node has `CLAWMETRY_POLICY_ENFORCE=1` (default 0), and the entitlement check passes, failing closed. Each rung fires at most once per session, durably, keyed on the decision-log primary key so a daemon restart cannot re-fire it. (3) A Guard tab ranks flagged sessions by spend at risk with capability-resolved Pause/Resume/Stop/Kill beside each, policy CRUD with dry-run review, and the decision log; the same controls sit on every session row. (4) One actuator module (`clawmetry/guard_actuator.py`) serves the tab, the daemon and the cloud relay, resume included. The control endpoint acts on the store's own copy of the session id and working directory, never on request strings, and refuses a session the store does not know. (5) Windows gets native actuators (`NtSuspendProcess`/`NtResumeProcess`, console Ctrl+C, `taskkill /T` then `TerminateProcess`) with every ctypes call typed. (6) An OpenClaw pause reports `advisory_only` when no enforcement proxy is in the loop instead of claiming a hold that holds nothing. Also fixed on the way: namespaced family session ids (`claude_code:<id>`) were refused by the control endpoint's allowlist, so their buttons returned 400.
- **Verified:** 7 new test files, 110 tests: three-lock gating, ladder ordering and restart durability, strongest-action-wins, per-session capability refusal (Cursor CLI yes, Cursor editor no), the policies API, Windows argtypes, and the stored-copy contract of the control endpoint. CodeQL on the PR went from 10 new alerts (1 critical) to none, confirmed with a local `python-security-extended` run before pushing. Product record: requirement "Guard Enforcement: acting on a finding" (REQ-GUARD-CTL-001 to 004) and its blueprint, both at factory.8090.ai; drift-bot reported no drift on the merged head.

### Security: what leaves the machine is now exactly what the docs say, and less of it (carries #5463) (2026-09-03)
- **Why:** a prospect declined to run ClawMetry on sensitive coding work. Rather than argue, every request the released daemon makes to ClawMetry Cloud was captured against a local listener and each field marked plaintext or sealed. The sealed/plaintext split held: transcripts, tool output, logs, memory files and the machine scan leave only as AES-256-GCM ciphertext, and the key never appeared in any request. Four things did not meet the bar a security reviewer holds.
- **What:** (1) The account key rides only in the `X-Api-Key` header. The claim watcher and `clawmetry status` used to put it in a query string once per daemon start, where the server records the request line. (2) Transcript quality scoring is opt-in: `CLAWMETRY_EVALS_ENABLED=1` or `"evals": true` in `~/.clawmetry/config.json`. It posts a redacted transcript excerpt to a third-party model with your own key, and a key in the environment is no longer taken as consent. (3) Runtime configuration files (`settings.json`, `settings.local.json`, `openclaw.json`, MCP manifests) are excluded from the cloud memory push, sealed or not; they stay in the local Memory tab. (4) Every cloud-relayed action is written to `~/.clawmetry/audit.db` on arrival, accepted or refused, so the node owner has their own record of what the service asked. `docs/EGRESS.md` is rebuilt from the capture with per-path cadence, plaintext versus sealed columns, the inbound control channel and its opt-in, third-party defaults, and a five-minute recipe to repeat the capture.
Expand Down
Loading