v0.7.0 - OpenClaw adapter
Stroq 0.7.0 adds a fifth agent: OpenClaw — the first adapter that runs inside the agent's own process.
OpenClaw support
stroq init --agent openclawcopies a small dependency-free JavaScript plugin into~/.stroq/openclaw-plugin/and registers it (openclaw plugins install --link+openclaw plugins enable stroq; the commands run only whenopenclawis on PATH, otherwise they are printed). Restart the Gateway afterwards. The plugin registersbefore_tool_call(priority 100, every tool) andafter_tool_call, and callsstroq hook openclaw pre|postas a child process, so the engine, rules, policy, provenance, secret-egress guard and hash-chained audit are shared with the other four adapters unchanged.- A real approval prompt. A policy
askbecomes OpenClaw'srequireApproval(allow-onceordeny, answered with/approve <id> …; a timeout blocks); adenybecomes a terminalblockwithStroq blocked this action (<rule>): …. - Fail-closed on every tool. A missing binary, a spawn error, a non-zero exit, a 10 s timeout, a non-JSON or unknown reply, a reply over 1 MiB or an aborted run all block; the CLI exits 2 with the reason on stderr on an internal error. A suspect result taints the session and is logged at
warn(observe-only hook; no warning reaches the model in this version). - The trusted working directory always wins. The plugin sends its configured
workspace(or the Gateway's cwd) and the CLI ignoresparams.cwdfor policy, so an agent cannot point the secret index at an empty directory. - Tool mapping.
exec/terminaland the shell aliases → Bash;read/write/edit/apply_patch;web_fetch,web_search/x_search; onlyask_user,progress_card,heartbeat_respond,get_goalpass through; everything else (message,browser,tts,image_generate,tool_search,tool_describe,process,code_execution, any MCP tool) ismcp__openclaw__<name>: scanned onpost, guarded onpre, fail-closed. Names are matched case-insensitively. - Every argument spelling is read and the worst decision wins; caller-supplied
file_paths/urlslists are dropped; more than 64 targets →openclaw-too-many-targets; an unreadable high-impact call →openclaw-unreadable-input. - Self-protection.
.openclaw/openclaw.json,.openclaw/plugins/,.openclaw/extensions/areconfig.self, and so areopenclaw plugins disable|remove|uninstall …andopenclaw config set plugins.…— a tainted session cannot switch the plugin off. - Resilient install. A recorded
stroq.jsonentry that no longer exists (a pruned npx cache) is skipped with a warning and the plugin falls back tostroqon PATH;initwarns when the entry lives in the npx cache;stroq doctorreports the plugin installed only when every file and the manifest id are present. - Documented limits:
askneeds an approval route (UI or chat channel); MCP server names are unknown to the plugin;process/code_executionare side-effect tools, not shells; unreadablereadparams are allowed; the plugin's config is read once at registration; plugins that run before Stroq may rewriteparams; the plugin needsplugins.entries.stroq.enabled = true(andplugins.allowwhen an allowlist is set); the wire shapes are inferred from OpenClaw's documentation and one production plugin.
Also
- The Copilot and OpenClaw adapters share one kind-to-input reader and one unreadable-input guard; the shared post-result scan was split out so Codex and Copilot stay byte-identical.
Verification
- 1345 tests across 77 files (up from 1062 / 66); CI on Node 22 and 24 runs all five demos and the attack suite (
12 scenarios: 8 blocked, 4 asked, 0 passed through). - Per-task reviews, a whole-branch security review and one fix wave, each probing the real engine and the real plugin with adversarial payloads. Found and closed before merge: generative/catalog tools exempt from the scan and the egress guard; case-sensitive tool names;
params.cwdhonoured as the working directory (plugin and CLI);stroqBinword-splitting; disabling the plugin not treated as self-tampering; a stalestroq.jsonentry locking the agent out;terminalnot treated as a shell.
Install: npm install -g @stroq/cli then stroq init (Claude Code), stroq init --agent cursor|codex|copilot|openclaw; or the release tarball attached below while npm's review holds the version.