## What Problem This Solves Skill Workshop experience review ran as an isolated agent with a re-rendered 60k-character transcript, its own bootstrap, and a trimmed tool surface. Every review was a cold request: no prompt-cache reuse, a large re-serialized trajectory, and a reasoning/tool profile that differed from the foreground turn. Autonomous updates could target any workspace skill, size limits allowed 40 KB skills to grow unchecked (one deployed workspace hit a 21 KB `SKILL.md`), the collection reviewer had to re-list every skill in its plan and read them under a fixed 24k-character budget (a 16-skill workspace failed every pass with "Read every current skill before reconciling"), collection review only recorded successes so a failing pass retried on every Gateway restart, and `openclaw skills curator status` showed nothing about what the last reviews did. ## Why This Change Was Made - **Warm fork.** Experience review now continues the finished turn from the same in-memory session prefix (same session identity, bootstrap, skills prompt, tool schemas, `promptCacheKey`), appends one short review message, and runs with `sessionPersistence: "detached"` so nothing it writes reaches the foreground transcript or session record. Only `skill_workshop` executes; every other tool keeps its schema for cache parity and fails with a next-step message. The gate wraps the core tool list before Code Mode / Tool Search compaction, so catalog-hidden tools stay gated while `tool_call`/`exec` remain callable. `src/agents/embedded-agent-runner/run/attempt.skills-policy.test.ts` asserts identical system-prompt and tool digests between a foreground turn and its review, and that `tool_call` reaches `skill_workshop` but not `read` during review. Code Mode swarm globals (`phase`, `log`, `agents.run`) are the `sessions_spawn` capability and gate on the same allowlist, so a review cannot emit foreground lifecycle events or launch collectors. The review shares the foreground session, so it no longer retires that session's MCP runtime on run end; it reuses the warm runtime like any turn. Accepted tradeoff: the review inherits foreground tool construction (it creates the session MCP runtime only when the session has none, and spawns per-attempt LSP servers only when configured), because splitting tool construction from the foreground turn would break the cache-parity invariant this PR exists for. - **One apply owner, rechecked at the write boundary.** `src/skills/workshop/autonomous-apply.ts` decides apply-vs-pending for both the post-review loop and foreground repair: creates and updates to Workshop-authored skills apply; updates to user-authored skills stay pending with a recorded reason. `applySkillProposalTransition` rechecks path-based ownership under the commit lock for non-operator actors (agent, or no actor), so a claim released after the pre-check cannot let an agent write a user-authored skill; gateway and CLI operators still approve any pending proposal. The user-authored pending write runs under the same commit lock and rereads the row, so an operator apply that lands first is kept. The old `auto-apply.ts` path and name-based `listWorkshopAuthoredSkillNames` are deleted. - **Sparse collection plan and model-relative reads.** The collection reviewer returns only `write` and `drop` entries; unlisted skills stay untouched, so a 16-skill workspace no longer has to restate 16 keeps. The skill read budget is derived from the model's context window (35%) instead of a fixed 24k characters, with the 10,000-character skill cap still enforced per skill. No windowed read parameters: a skill is read whole or not at all. - **Weekly cadence.** Collection review runs once every 7 days instead of daily (`REVIEW_INTERVAL_MS`), matching how slowly a skill library actually changes; the attempt is recorded before the model starts, so a failed pass does not retry on every restart. - **Lean cap.** `AUTONOMOUS_SKILL_MAX_CHARS = 10,000` in `src/skills/workshop/collection-contracts.ts` is enforced by the tool and by collection reconcile; an oversized skill may only shrink. Tool description, experience prompt, and collection prompt were rewritten around procedures-not-records, one trigger per branch, and "NOTHING_TO_LEARN is the correct answer for most turns". - **Detached runs end quietly.** A detached run writes no transcript or session record and runs under the foreground session key, so `attempt-finalize` now skips agent_end side effects for it: plugins do not observe the review as a foreground turn, and a deep review cannot schedule a successor review of itself. - **Recorded outcomes.** Experience review records `applied | proposed | nothing | failed` with usage; one attempt per turn, drop on error. `openclaw skills curator status` prints the last collection and experience review outcome. ## User Impact - Default `auto` mode: experience review reuses the foreground prompt cache and skips message/other tool execution, so review cost is one bounded continuation instead of a cold re-render. - Autonomous edits touch only Workshop-authored skills; handwritten skills surface as pending proposals for operator approval. - Autonomous `SKILL.md` results stay ≤ 10,000 characters. - Collection review runs weekly and succeeds on larger skill libraries. A workspace with no recorded attempt reviews at the first daily check after Gateway start; an upgraded install keeps its recorded last attempt and reviews once it is older than 7 days. The 10,000-character cap applies to the next autonomous write; existing oversized skills are only ever shrunk. - `openclaw skills curator status` shows the last collection and experience review outcome, time, and tokens. - Docs: https://docs.openclaw.ai/tools/self-learning, https://docs.openclaw.ai/tools/skill-workshop Related: #123866, #128871 both patch skills above the reviewer read budget; this PR caps autonomous skill size and restricts oversized skills to shrink-only rewrites. ## Evidence - Live gateway (Linux, Telegram, `xai` provider) at `133ffe3`: manual experience review on a real foreground turn → `nothing` (usage: 0 uncached input, 13,902 cached, 36 output — the forked review hit the foreground prompt cache); manual collection review over the workspace → `succeeded`; the three oversized skills were rewritten under the cap (21,002 → 9,449; 11,882 → 7,735; 10,300 → 7,413 bytes, originals in `skill-workshop/collection-backups/`), the rest untouched, and the pre-PR "Read every current skill before reconciling" failure is gone. The next foreground turn's automatic experience review recorded `nothing` and `openclaw skills curator status` shows both outcomes. The apply recheck, MCP-runtime change (`26e821f`), and detached agent_end skip (`7e4a506`) landed after that run and are covered by the regression tests below. - `pnpm test src/skills/workshop src/agents/tools/skill-workshop-tool src/gateway/server-methods/skills` plus `src/agents/embedded-agent-runner/run/attempt.skills-policy.test.ts`, `src/agents/embedded-agent-runner/run/attempt.tool-search-catalog-abort.test.ts`, `src/cli/skills-cli.curator.test.ts`, `src/agents/harness/tool-surface-bridge.test.ts` — green. New regression tests (`service.test.ts` agent-vs-operator apply on a user-authored skill and operator apply kept over a stale pending snapshot; `experience-review.apply.test.ts` no `cleanupBundleMcpOnRunEnd`; `attempt-phase-lifecycle.test.ts` no agent_end for a detached run; `code-mode-swarm.test.ts` swarm globals refused under the review allowlist) fail on the pre-fix code. - Dependent sweep: 46 test files importing the touched modules — green. - `oxfmt`, `scripts/run-oxlint.mjs` on changed files, `git diff --check` — clean. - `pnpm tsgo && pnpm check:test-types` on Blacksmith Testbox — clean. - Local ClawSweeper review (`gpt-5.6-terra`, high): `133ffe3` raised two findings (ownership recheck removed from the apply boundary; review retiring the shared session's MCP runtime), fixed in `26e821f`; `26e821f` raised one (detached review re-entering agent-end scheduling), fixed in `7e4a506`; `7e4a506` raised three: pending write racing an operator apply and Code Mode swarm globals bypassing the execution gate, both fixed in `e4b4322`; "prove detached review does not start configured MCP or LSP runtimes" is skipped as the cache-parity tradeoff stated above (LSP tool schemas come from the LSP runtime; the MCP runtime is session-owned and already warm). Maintainer decision on `e4b4322`: accepted — a detached review reuses the session MCP runtime and re-spawns configured per-attempt LSP servers exactly like a foreground turn; it still cannot execute them. - Unrelated CI on `26e821f`/`7e4a506`: `check-lint-core-2` (`max-lines` in `src/gateway/server-methods/models-list-result.ts`, unused param in `models.test.ts`, both from #129332) and `checks-node-compact-small-8` (`doctor-auth.profile-health.test.ts`, Claude CLI auth from #129052) fail identically on `main` run 32857954734; `checks-node-compact-small-31` pins plugin SDK export counts (`4340` vs `4342`) that #129052 moved — this PR touches no `src/plugin-sdk` file. On `e4b4322` the failing set is the same twelve `checks-node-compact` shards that fail on `main` run 32857954734 (`large-5/12/13/14/15/18/22`, `small-8/14/20/21/26`) plus `small-31`; `check-lint-core-2` passes here. None are fixed here; #129357 carries the `main` fix. - LOC (raw numstat): production +712 / −664 (net +48; the four review-fix commits after the live run add +76 / −26); tests + docs +1269 / −1238 (net +31).
18 KiB
summary, read_when, title
| summary | read_when | title | |||||
|---|---|---|---|---|---|---|---|
| CLI reference for `openclaw skills` (search/install/update/verify/list/info/check/workshop) |
|
Skills |
openclaw skills
Inspect local skills, search ClawHub, install skills from ClawHub/Git/local directories, verify ClawHub skills, and update ClawHub-tracked installs.
Related:
- Skills system: Skills
- Skill Workshop: Skill Workshop
- Skills config: Skills config
- ClawHub installs: ClawHub
Commands
openclaw skills search "calendar"
openclaw skills search --limit 20 --json
openclaw skills install @owner/<slug>
openclaw skills install @owner/<slug> --version <version>
openclaw skills install skills-sh:<owner>/<repo>/<slug>
openclaw skills install git:owner/repo
openclaw skills install git:owner/repo@main
openclaw skills install ./path/to/skill --as custom-name
openclaw skills install @owner/<slug> --force
openclaw skills install @owner/<slug> --force-install
openclaw skills install @owner/<slug> --acknowledge-clawhub-risk
openclaw skills install @owner/<slug> --acknowledge-install-policy-warning
openclaw skills install @owner/<slug> --agent <id>
openclaw skills install @owner/<slug> --global
openclaw skills update @owner/<slug>
openclaw skills update @owner/<slug> --force
openclaw skills update @owner/<slug> --force-install
openclaw skills update @owner/<slug> --acknowledge-clawhub-risk
openclaw skills update @owner/<slug> --acknowledge-install-policy-warning
openclaw skills update @owner/<slug> --global
openclaw skills update --all
openclaw skills update --all --agent <id>
openclaw skills update --all --global
openclaw skills verify @owner/<slug>
openclaw skills verify @owner/<slug> --json
openclaw skills verify @owner/<slug> --version <version>
openclaw skills verify @owner/<slug> --tag <tag>
openclaw skills verify @owner/<slug> --card
openclaw skills verify @owner/<slug> --global
openclaw skills list
openclaw skills list --eligible
openclaw skills list --json
openclaw skills list --verbose
openclaw skills list --agent <id>
openclaw skills info <name>
openclaw skills info <name> --json
openclaw skills info <name> --agent <id>
openclaw skills check
openclaw skills check --agent <id>
openclaw skills check --json
openclaw skills curator status
openclaw skills curator status --json
openclaw skills workshop propose-create --name "qa-check" --description "QA checklist" --proposal ./PROPOSAL.md
openclaw skills workshop propose-update qa-check --proposal ./PROPOSAL.md
openclaw skills workshop list
openclaw skills workshop inspect <proposal-id>
openclaw skills workshop revise <proposal-id> --proposal ./PROPOSAL.md
openclaw skills workshop apply <proposal-id>
openclaw skills workshop reject <proposal-id> --reason "Not reusable"
openclaw skills workshop quarantine <proposal-id> --reason "Needs security review"
search, update, and verify use ClawHub directly. install @owner/<slug>
installs a native ClawHub skill. install skills-sh:<owner>/<repo>/<slug> asks
ClawHub to resolve an external listing to its exact synchronized GitHub commit;
OpenClaw does not download from skills.sh. These entries are shown as
Not scanned by ClawHub, and that trust state is preserved through updates
and verification. Claimed or ClawHub-scanned skills use @owner/<slug>.
install git:owner/repo[@ref] clones an unmanaged Git skill, and install ./path copies a local skill directory. By default, install,
update, and verify target the active workspace skills/ directory; with
--global, they target the shared managed skills directory. list/info/check
still inspect the local skills visible to the current workspace and config.
Workspace-backed commands resolve the target workspace from --agent <id>,
then the current working directory when it is inside a configured agent
workspace, then the default agent.
Git and local directory installs expect SKILL.md at the source root. The
install slug comes from SKILL.md frontmatter name when it is valid, then
the source directory or repository name; use --as <slug> to override it.
--version is ClawHub-only. Skill installs do not support npm package specs
or zip/archive paths, and openclaw skills update updates ClawHub-tracked
installs only.
Gateway-backed skill dependency installs triggered from onboarding or Skills
settings use the separate skills.install request path instead.
When security.installPolicy returns warn in an interactive terminal,
OpenClaw prints the reason and findings, then asks type: '<skill>' to install anyway (or update anyway). If the fully rendered review exceeds 4,000
characters, OpenClaw fails closed before prompting; reduce or coalesce the
policy output first. A matching answer evaluates the staged skill
again before continuing. Declined and non-interactive direct CLI commands stop
before commit; after review, --acknowledge-install-policy-warning is the
explicit noninteractive approval for every warning in that command invocation.
Every approved warning is re-evaluated before continuing. Automatic and managed
skill installs cannot use that flag themselves. Use an equivalent direct CLI
command when one exists; otherwise, change security.installPolicy to return
allow for the reviewed request, then retry the managed flow. Neither --force
nor the acknowledgement overrides block or a policy failure.
Notes:
| Flag/behavior | Description |
|---|---|
search [query...] |
Optional query; omit it to browse the default ClawHub search feed. |
search --limit <n> |
Caps returned results. |
install git:owner/repo[@ref] |
Installs a Git skill. Branch refs may contain slashes, such as git:owner/repo@feature/foo. |
install ./path/to/skill |
Installs a local directory whose root contains SKILL.md. |
install --as <slug> |
Overrides the inferred slug for Git and local directory installs. |
install --version <version> |
Applies to native ClawHub skill refs, not skills-sh: refs; the mirrored reference already identifies the exact synchronized commit. |
install --force |
Overwrites an existing workspace skill folder for the same slug. |
update --force |
Replaces a tracked skill even when its installed files no longer match recorded install digests. Without it, updates preserve local changes. Pre-digest installs require one forced update before later updates can be verified. Force those skills individually; --all --force also replaces skills with detected local edits. |
install/update --force-install |
Installs a pending GitHub-backed ClawHub skill before ClawHub's scan completes. |
--global |
Targets the shared managed skills directory; cannot combine with --agent <id>. |
--agent <id> |
Targets one configured agent workspace; overrides current working directory inference. |
update @owner/<slug> |
Updates a single tracked skill. Add --global to target the shared managed skills directory instead of the workspace. |
update --all |
Updates tracked ClawHub installs in the selected workspace, or the shared managed skills directory with --global. |
verify @owner/<slug> |
Prints ClawHub's clawhub.skill.verify.v1 JSON envelope by default. --json is accepted as the explicit machine-output spelling. Bare slugs are accepted for compatibility when the skill is already installed or unambiguous; owner-qualified refs avoid publisher ambiguity. |
verify provenance |
When ClawHub returns server-resolved source provenance, verify JSON also includes a commit-pinned openclaw.verifiedSourceUrl. Unavailable or self-declared source URLs stay only in the raw provenance envelope and are not promoted. |
verify version selector |
verify uses .clawhub/origin.json for installed ClawHub skills, so it verifies the installed version against the registry it came from. --version and --tag override the version selector but keep that installed registry when origin metadata exists. |
verify --card |
Prints the generated Skill Card Markdown instead of JSON. Exits non-zero when ClawHub returns ok: false or decision: "fail"; unsigned signatures are informational unless ClawHub policy changes. |
| Skill Card fingerprint | Installed ClawHub bundles can include a generated skill-card.md. OpenClaw treats verification as a ClawHub server decision and does not reject an installed skill just because that generated card changes the bundle fingerprint. |
check --agent <id> |
Checks the selected agent's workspace and reports which ready skills are actually visible to that agent's prompt or command surface. |
workshop --agent <id> |
Accepted before or after a Workshop leaf command, for example workshop --agent <id> list or workshop list --agent <id>. If both are provided, the leaf value wins. |
curator --json |
Accepted before or after a Curator leaf command, for example curator --json status or curator status --json. |
list |
Default action when no subcommand is provided. |
list/info/check output |
Rendered output goes to stdout. With --json, the machine-readable payload stays on stdout for pipes and scripts. |
curator status --json |
Returns legacy age-based lifecycle state written by older releases. Weekly collection review does not use this state. |
Community ClawHub skill installs and updates check trust before downloading.
Versioned community archive releases use exact-release trust metadata.
Resolver-backed GitHub skills rely on ClawHub's install resolver to enforce
scan and force-install policy before it returns a pinned commit; use
--force-install to install a pending GitHub-backed skill before that scan
completes. Malicious or blocked community releases are refused. Risky
community releases require review and --acknowledge-clawhub-risk when a
non-interactive command should continue after that review. Official ClawHub
skill publishers and bundled OpenClaw skill sources bypass this release-trust
prompt.
Remove a ClawHub skill
Use the standalone ClawHub CLI to remove a ClawHub-tracked skill. If the CLI is not installed, install it explicitly first:
npm i -g clawhub
clawhub uninstall @owner/my-skill
The CLI asks for confirmation before deleting the skill directory and its
.clawhub/lock.json entry. Use the installed skill's owner-qualified name or
bare slug, not its original skills-sh: reference.
Select the same root where the skill was installed: the agent workspace for an
agent-specific skill, or the OpenClaw state directory for a shared skill
installed with --global:
clawhub --workdir /path/to/agent-workspace uninstall @owner/my-skill
clawhub --workdir ~/.openclaw uninstall @owner/my-skill
If OPENCLAW_STATE_DIR is set, use that configured state directory for shared
skills instead:
clawhub --workdir "$OPENCLAW_STATE_DIR" uninstall @owner/my-skill
The default skills watcher picks up the removal on the next agent turn. If watching is disabled, start a new session.
Skill Workshop
openclaw skills workshop manages pending skill proposals in the selected
workspace. Proposals are not active skills until applied. For proposal
storage, support-file safeguards, Gateway methods, and approval policy, see
Skill Workshop.
openclaw skills workshop propose-create \
--name "qa-check" \
--description "Repeatable QA checklist" \
--proposal ./PROPOSAL.md
openclaw skills workshop propose-create \
--name "qa-check" \
--description "Repeatable QA checklist" \
--proposal-dir ./qa-check-proposal
openclaw skills workshop propose-update qa-check --proposal ./PROPOSAL.md
openclaw skills workshop list
openclaw skills workshop inspect <proposal-id>
openclaw skills workshop revise <proposal-id> --proposal ./PROPOSAL.md
openclaw skills workshop apply <proposal-id>
openclaw skills workshop reject <proposal-id> --reason "Duplicate"
openclaw skills workshop quarantine <proposal-id> --reason "Needs security review"
propose-create, propose-update, and revise also accept --goal <text>
and --evidence <text> to record the proposal's motivation and supporting
notes alongside the --proposal/--proposal-dir content.