Skip to content

Commit 4031eff

Browse files
authored
Merge branch 'main' into fix-doctor-stale-runtime-pins-83098
2 parents 16a3eef + 79be940 commit 4031eff

42 files changed

Lines changed: 3828 additions & 290 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,10 @@ Docs: https://docs.openclaw.ai
1010

1111
### Fixes
1212

13+
- Media/audio: skip empty structured sherpa-onnx transcripts instead of treating the raw JSON payload as spoken text. (#84667) Thanks @TurboTheTurtle.
14+
- Memory-core/dreaming: reuse stable narrative subagent session keys per workspace and phase while keeping per-run idempotency and bounded cleanup, so stale `dreaming-narrative-*` sessions do not accumulate. Fixes #68252, #69187, and #70402. (#70464) Thanks @chiyouYCH.
1315
- CLI/perf: keep `setup --help`, `onboard --help`, and `configure --help` out of the full wizard runtime while preserving the existing help output. (#84488) Thanks @frankekn.
16+
- CLI/perf: keep `agents --help` out of agents action/runtime imports so help, completion, and command discovery paths avoid loading the full agents runtime. (#84483) Thanks @frankekn.
1417

1518
## 2026.5.20
1619

@@ -30,6 +33,7 @@ Docs: https://docs.openclaw.ai
3033
- CLI/tasks: include stale-running task maintenance decisions in `openclaw tasks maintenance --json` so retained and reconcile candidates explain backing-session, cron, CLI, and wedged-subagent state. (#84691) Thanks @efpiva.
3134
- Codex app-server: keep system-prompt reports working when bootstrap hooks provide workspace files with only a path and content, so hook-supplied SOUL/IDENTITY/TOOLS/USER context still reports injected characters correctly. (#84736) Thanks @JARVIS-Glasses.
3235
- Providers/MiniMax music: stop advertising `durationSeconds` control and remove prompt-injected duration hints, so `music_generate` reports MiniMax duration as an unsupported override instead of suggesting MiniMax can enforce track length. Fixes #84508. Thanks @neeravmakwana.
36+
- Doctor: warn when sandbox tool policy hides configured MCP server tools before provider requests. (#84699) Thanks @nxmxbbd.
3337
- WhatsApp: update Baileys to `7.0.0-rc12`.
3438
- Build: suppress per-locale `rolldown-plugin-dts:fake-js` CommonJS dts warnings emitted while bundling the intentionally-inlined `zod/v4/locales/*.d.cts` files, so `pnpm build` output stays readable after the 0.25.1 plugin bump. Thanks @romneyda.
3539
- CLI/nodes: route lazy plugin-registration logs to stderr for JSON-mode `openclaw nodes` commands so stdout stays parseable. (#84684) Thanks @TurboTheTurtle.

docs/cli/policy.md

Lines changed: 149 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
summary: "CLI reference for `openclaw policy` channel conformance checks"
2+
summary: "CLI reference for `openclaw policy` conformance checks"
33
read_when:
44
- You want to check OpenClaw settings against an authored policy.jsonc
55
- You want policy findings in doctor lint
@@ -10,14 +10,23 @@ title: "Policy"
1010
# `openclaw policy`
1111

1212
`openclaw policy` is provided by the bundled Policy plugin. Policy is an
13-
enterprise conformance layer over existing OpenClaw settings: `policy.jsonc`
14-
defines authored requirements, OpenClaw observes the active workspace as
15-
evidence, and policy health checks report drift through `doctor --lint`.
16-
17-
This first policy slice manages configured channels. For example, IT can record
18-
that Telegram is not approved, then `doctor --lint` reports any enabled Telegram
19-
channel and `doctor --fix` can turn it off when workspace repairs are explicitly
20-
enabled.
13+
enterprise conformance layer over existing OpenClaw settings. It does not add a
14+
second configuration system. `policy.jsonc` defines authored requirements,
15+
OpenClaw observes the active workspace as evidence, and policy health checks
16+
report drift through `doctor --lint`. The final conformance signal is a clean
17+
`doctor --lint` run; policy contributes findings to that shared lint surface
18+
instead of creating a separate health gate.
19+
20+
Policy currently manages configured channels and governed tool declarations.
21+
For example, IT or a workspace operator can record that Telegram is not an
22+
approved channel provider, require governed tools to carry risk and sensitivity
23+
metadata, then use `doctor --lint` as the shared conformance gate.
24+
25+
Use policy when a workspace needs a durable statement such as "these channels
26+
must not be enabled" or "governed tools must declare approval metadata" and a
27+
repeatable way to prove that OpenClaw still conforms to that statement. Use
28+
regular config and workspace docs alone when you only need local behavior and
29+
do not need policy findings or attestation output.
2130

2231
## Quick start
2332

@@ -32,7 +41,7 @@ arbitrary plugins. The plugin remains enabled if `policy.jsonc` is missing, so
3241
doctor can report the missing artifact.
3342

3443
Policy is authored, not generated from the user's current settings. A minimal
35-
channel policy looks like this:
44+
policy for channels and tool metadata looks like this:
3645

3746
```jsonc
3847
{
@@ -45,12 +54,16 @@ channel policy looks like this:
4554
},
4655
],
4756
},
57+
"tools": {
58+
"requireMetadata": ["risk", "sensitivity", "owner"],
59+
},
4860
}
4961
```
5062

5163
The rules are the authority. A category block is only a namespace; checks run
5264
when a concrete rule is present. OpenClaw reads current `channels.*` settings
53-
and reports settings that do not conform.
65+
and `TOOLS.md` declarations as evidence, then reports observed state that does
66+
not conform.
5467

5568
Run policy-only checks during authoring:
5669

@@ -122,12 +135,64 @@ Policy config lives under `plugins.entries.policy.config`.
122135
Set `plugins.entries.policy.config.enabled` to `false` to disable policy checks
123136
for a workspace while leaving the plugin installed.
124137

138+
Tool metadata requirements are authored in `policy.jsonc` with
139+
`tools.requireMetadata`, for example `["risk", "sensitivity", "owner"]`.
140+
125141
## Accept policy state
126142

127-
The attestation hash identifies the stable claim: policy hash, evidence hash,
128-
findings hash, and whether the result was clean. It intentionally does not
129-
include `checkedAt`, so the same policy state produces the same attestation
130-
across repeated checks.
143+
Example JSON output:
144+
145+
```json
146+
{
147+
"ok": true,
148+
"attestation": {
149+
"checkedAt": "2026-05-10T20:00:00.000Z",
150+
"policy": {
151+
"path": "policy.jsonc",
152+
"hash": "sha256:..."
153+
},
154+
"workspace": {
155+
"scope": "policy",
156+
"hash": "sha256:..."
157+
},
158+
"findingsHash": "sha256:...",
159+
"attestationHash": "sha256:..."
160+
},
161+
"evidence": {
162+
"channels": [
163+
{
164+
"id": "telegram",
165+
"provider": "telegram",
166+
"source": "oc://openclaw.config/channels/telegram",
167+
"enabled": false
168+
}
169+
],
170+
"tools": [
171+
{
172+
"id": "deploy",
173+
"source": "oc://TOOLS.md/tools/deploy",
174+
"line": 12,
175+
"risk": "critical",
176+
"sensitivity": "restricted",
177+
"capabilities": ["IRREVERSIBLE_EXTERNAL"]
178+
}
179+
]
180+
},
181+
"checksRun": 6,
182+
"checksSkipped": 0,
183+
"findings": []
184+
}
185+
```
186+
187+
The policy hash identifies the authored rule artifact. The evidence block
188+
records the observed OpenClaw state used by the policy checks. The
189+
`workspace.hash` value identifies that evidence payload for the checked scope.
190+
The findings hash identifies the exact finding set returned by the check.
191+
`checkedAt` records when the evaluation ran. The attestation hash identifies
192+
the stable claim: policy hash, evidence hash, findings hash, and whether the
193+
result was clean. It intentionally does not include `checkedAt`, so the same
194+
policy state produces the same attestation across repeated checks. Together,
195+
these form the audit tuple for this policy check.
131196

132197
If a later gateway or supervisor uses policy to block, approve, or annotate a
133198
runtime action, it should record the attestation hash from the last clean policy
@@ -146,20 +211,71 @@ If policy rules change intentionally, update both accepted hashes from a clean
146211
check. If workspace settings change intentionally but policy stays the same,
147212
only `expectedAttestationHash` usually changes.
148213

214+
`openclaw policy watch` runs the same check repeatedly and reports when the
215+
current evidence no longer matches `expectedAttestationHash`:
216+
217+
```bash
218+
openclaw policy watch --json
219+
```
220+
221+
Use `--once` in CI or scripts that only need one drift evaluation. Without
222+
`--once`, the command polls every two seconds by default; use `--interval-ms` to
223+
choose a different interval.
224+
149225
## Findings
150226

151227
Policy currently verifies:
152228

153-
| Check id | Finding |
154-
| ---------------------------------- | ------------------------------------------------------------------- |
155-
| `policy/policy-jsonc-missing` | Policy is enabled but `policy.jsonc` is missing. |
156-
| `policy/policy-jsonc-invalid` | Policy cannot be parsed or has malformed rules. |
157-
| `policy/policy-hash-mismatch` | Policy does not match configured `expectedHash`. |
158-
| `policy/attestation-hash-mismatch` | Current policy evidence no longer matches the accepted attestation. |
159-
| `policy/channels-denied-provider` | An enabled channel matches a channel deny rule. |
229+
| Check id | Finding |
230+
| ---------------------------------------- | ------------------------------------------------------------------- |
231+
| `policy/policy-jsonc-missing` | Policy is enabled but `policy.jsonc` is missing. |
232+
| `policy/policy-jsonc-invalid` | Policy cannot be parsed or has malformed rules. |
233+
| `policy/policy-hash-mismatch` | Policy does not match configured `expectedHash`. |
234+
| `policy/attestation-hash-mismatch` | Current policy evidence no longer matches the accepted attestation. |
235+
| `policy/channels-denied-provider` | An enabled channel matches a channel deny rule. |
236+
| `policy/tools-missing-owner` | A governed tool declaration is missing owner metadata. |
237+
| `policy/tools-missing-risk-level` | A governed tool declaration is missing risk metadata. |
238+
| `policy/tools-missing-sensitivity-token` | A governed tool declaration is missing sensitivity metadata. |
239+
| `policy/tools-unknown-risk-level` | A governed tool declaration uses an unknown risk value. |
240+
| `policy/tools-unknown-sensitivity-token` | A governed tool declaration uses an unknown sensitivity value. |
241+
242+
Policy findings can include both `target` and `requirement`. `target` is the
243+
observed workspace thing that does not conform. `requirement` is the authored
244+
policy rule that made it a finding. Both values are addresses today, usually
245+
`oc://` paths, but the field names describe their policy role rather than the
246+
address format.
247+
248+
Example JSON finding:
249+
250+
```json
251+
{
252+
"checkId": "policy/channels-denied-provider",
253+
"severity": "error",
254+
"message": "Channel 'telegram' uses denied provider 'telegram'.",
255+
"source": "policy",
256+
"path": "openclaw config",
257+
"ocPath": "oc://openclaw.config/channels/telegram",
258+
"target": "oc://openclaw.config/channels/telegram",
259+
"requirement": "oc://policy.jsonc/channels/denyRules/#0",
260+
"fixHint": "Telegram is not approved for this workspace."
261+
}
262+
```
160263

161-
Policy findings can include `target` and `requirement`: the observed workspace
162-
thing that does not conform, and the authored rule that made it a finding.
264+
Example tool finding:
265+
266+
```json
267+
{
268+
"checkId": "policy/tools-missing-risk-level",
269+
"severity": "error",
270+
"message": "TOOLS.md tool 'deploy' has no explicit risk classification.",
271+
"source": "policy",
272+
"path": "TOOLS.md",
273+
"line": 12,
274+
"ocPath": "oc://TOOLS.md/tools/deploy",
275+
"target": "oc://TOOLS.md/tools/deploy",
276+
"requirement": "oc://policy.jsonc/tools/requireMetadata"
277+
}
278+
```
163279

164280
## Repair
165281

@@ -190,5 +306,12 @@ configured channel:
190306

191307
## Exit codes
192308

193-
`policy check` exits `0` when there are no findings at the threshold, `1` when
194-
findings are present, and `2` for argument or runtime failures.
309+
| Command | `0` | `1` | `2` |
310+
| -------------- | ----------------------------------------- | ------------------------------------------------ | ---------------------------- |
311+
| `policy check` | No findings at the threshold. | One or more findings met the threshold. | Argument or runtime failure. |
312+
| `policy watch` | No findings and accepted hash is current. | Findings exist or accepted attestation is stale. | Argument or runtime failure. |
313+
314+
## Related
315+
316+
- [Doctor lint mode](/cli/doctor#lint-mode)
317+
- [Path CLI](/cli/path)

docs/cli/skills.md

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,15 @@
22
summary: "CLI reference for `openclaw skills` (search/install/update/list/info/check)"
33
read_when:
44
- You want to see which skills are available and ready to run
5-
- You want to search, install, or update skills from ClawHub
5+
- You want to search ClawHub or install skills from ClawHub, Git, or local directories
66
- You want to debug missing binaries/env/config for skills
77
title: "Skills"
88
---
99

1010
# `openclaw skills`
1111

12-
Inspect local skills and install/update skills from ClawHub.
12+
Inspect local skills, search ClawHub, install skills from ClawHub/Git/local directories, and update
13+
ClawHub-tracked installs.
1314

1415
Related:
1516

@@ -24,6 +25,9 @@ openclaw skills search "calendar"
2425
openclaw skills search --limit 20 --json
2526
openclaw skills install <slug>
2627
openclaw skills install <slug> --version <version>
28+
openclaw skills install git:owner/repo
29+
openclaw skills install git:owner/repo@main
30+
openclaw skills install ./path/to/skill --as custom-name
2731
openclaw skills install <slug> --force
2832
openclaw skills install <slug> --agent <id>
2933
openclaw skills install <slug> --global
@@ -45,23 +49,36 @@ openclaw skills check --agent <id>
4549
openclaw skills check --json
4650
```
4751

48-
`search`/`install`/`update` use ClawHub directly. By default, `install` and
49-
`update` target the active workspace `skills/` directory; with `--global`, they
50-
target the shared managed skills directory. `list`/`info`/`check` still inspect
51-
the local skills visible to the current workspace and config. Workspace-backed
52-
commands resolve the target workspace from `--agent <id>`, then the current
53-
working directory when it is inside a configured agent workspace, then the
54-
default agent.
52+
`search` and `update` use ClawHub directly. `install <slug>` installs a ClawHub
53+
skill, `install git:owner/repo[@ref]` clones a Git skill, and `install ./path`
54+
copies a local skill directory. By default, `install` and `update` target the
55+
active workspace `skills/` directory; with `--global`, they target the shared
56+
managed skills directory. `list`/`info`/`check` still inspect the local skills
57+
visible to the current workspace and config. Workspace-backed commands resolve
58+
the target workspace from `--agent <id>`, then the current working directory
59+
when it is inside a configured agent workspace, then the default agent.
5560

56-
This CLI `install` command downloads skill folders from ClawHub. Gateway-backed
57-
skill dependency installs triggered from onboarding or Skills settings use the
58-
separate `skills.install` request path instead.
61+
Git and local directory installs expect `SKILL.md` at the source root. The
62+
install slug comes from `SKILL.md` frontmatter `name` when it is valid, then the
63+
source directory or repository name; use `--as <slug>` to override it. `--version`
64+
is ClawHub-only. Skill installs do not support npm package specs or zip/archive
65+
paths, and `openclaw skills update` updates ClawHub-tracked installs only.
66+
67+
Gateway-backed skill dependency installs triggered from onboarding or Skills
68+
settings use the separate `skills.install` request path instead.
5969

6070
Notes:
6171

6272
- `search [query...]` accepts an optional query; omit it to browse the default
6373
ClawHub search feed.
6474
- `search --limit <n>` caps returned results.
75+
- `install git:owner/repo[@ref]` installs a Git skill. Branch refs may contain
76+
slashes, such as `git:owner/repo@feature/foo`.
77+
- `install ./path/to/skill` installs a local directory whose root contains
78+
`SKILL.md`.
79+
- `install --as <slug>` overrides the inferred slug for Git and local directory
80+
installs.
81+
- `install --version <version>` applies only to ClawHub skill slugs.
6582
- `install --force` overwrites an existing workspace skill folder for the same
6683
slug.
6784
- `--global` targets the shared managed skills directory and cannot be combined

docs/gateway/config-tools.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,38 @@ Local onboarding defaults new local configs to `tools.profile: "coding"` when un
4343
| `group:agents` | `agents_list`, `update_plan` |
4444
| `group:media` | `image`, `image_generate`, `music_generate`, `video_generate`, `tts` |
4545
| `group:openclaw` | All built-in tools (excludes provider plugins) |
46+
| `group:plugins` | Tools owned by loaded plugins, including configured MCP servers exposed through `bundle-mcp` |
47+
48+
### MCP and plugin tools inside sandbox tool policy
49+
50+
Configured MCP servers are exposed as plugin-owned tools under the `bundle-mcp` plugin id. Normal tool profiles can allow them, but `tools.sandbox.tools` is an additional gate for sandboxed sessions. If sandbox mode is `"all"` or `"non-main"`, include one of these entries in the sandbox tool allowlist when MCP/plugin tools should be visible:
51+
52+
- `bundle-mcp` for OpenClaw-managed MCP servers from `mcp.servers`
53+
- the plugin id for a specific native plugin
54+
- `group:plugins` for all loaded plugin-owned tools
55+
- exact MCP server tool names or server globs such as `outlook__send_mail` or `outlook__*` when you only want one server
56+
57+
Server globs use the provider-safe MCP server prefix, not necessarily the raw `mcp.servers` key. Non-`[A-Za-z0-9_-]` characters become `-`, names that do not start with a letter get an `mcp-` prefix, and long or duplicate prefixes may be truncated or suffixed; for example, `mcp.servers["Outlook Graph"]` uses a glob like `outlook-graph__*`.
58+
59+
```json5
60+
{
61+
agents: { defaults: { sandbox: { mode: "all" } } },
62+
mcp: {
63+
servers: {
64+
outlook: { command: "node", args: ["./outlook-mcp.js"] },
65+
},
66+
},
67+
tools: {
68+
sandbox: {
69+
tools: {
70+
alsoAllow: ["web_search", "web_fetch", "memory_search", "memory_get", "bundle-mcp"],
71+
},
72+
},
73+
},
74+
}
75+
```
76+
77+
Without that sandbox-layer entry, the MCP server can still load successfully while its tools are filtered before the provider request. Use `openclaw doctor` to catch this shape for OpenClaw-managed servers in `mcp.servers`. MCP servers loaded from bundled plugin manifests or Claude `.mcp.json` use the same sandbox gate, but this diagnostic does not enumerate those sources yet; use the same allowlist entries if their tools disappear in sandboxed turns.
4678

4779
### `tools.allow` / `tools.deny`
4880

docs/gateway/sandbox-vs-tool-policy-vs-elevated.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ Available groups:
100100
- `group:agents`: `agents_list`, `update_plan`
101101
- `group:media`: `image`, `image_generate`, `music_generate`, `video_generate`, `tts`
102102
- `group:openclaw`: all built-in OpenClaw tools (excludes provider plugins)
103+
- `group:plugins`: all loaded plugin-owned tools, including configured MCP servers exposed through `bundle-mcp`
104+
105+
For sandboxed MCP servers, the sandbox tool policy is a second allow gate. If `mcp.servers` is configured but sandboxed turns only show built-in tools, add `bundle-mcp`, `group:plugins`, or a server-prefixed MCP tool name/glob such as `outlook__send_mail` or `outlook__*` to `tools.sandbox.tools.alsoAllow`, then restart/reload the gateway and recapture the tool list. Server globs use the provider-safe MCP server prefix: non-`[A-Za-z0-9_-]` characters become `-`, names that do not start with a letter get an `mcp-` prefix, and long or duplicate prefixes may be truncated or suffixed.
106+
107+
`openclaw doctor` currently checks this shape for OpenClaw-managed servers in `mcp.servers`. MCP servers loaded from bundled plugin manifests or Claude `.mcp.json` use the same sandbox gate, but this diagnostic does not enumerate those sources yet; use the same allowlist entries if their tools disappear in sandboxed turns.
103108

104109
## Elevated: exec-only "run on host"
105110

0 commit comments

Comments
 (0)