## 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).
Prevent ClawHub skill updates from silently replacing locally modified files. Verify recorded install digests at the rollback boundary, restore on mismatch, and require explicit --force for unverifiable legacy installs.
Co-authored-by: yetval <yetvald@gmail.com>
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
Replace divergent per-skill curation with one daily isolated collection review that can consolidate, rewrite, create, and drop writable skills atomically.
Autonomous auto mode remains automatic. Adds bounded review, transactional recovery, durable cadence, shared locking, and reuse-first /learn behavior.
Co-authored-by: Ayaan Zaidi <hi@obviy.us>
Update OpenClaw ClawHub docs and user-facing copy for canonical owner-qualified skill routes.\n\nEvidence:\n- pnpm docs:list\n- pnpm test src/plugins/clawhub.test.ts src/cli/plugins-cli.install.test.ts src/gateway/server-methods/skills.clawhub.test.ts ui/src/ui/views/skills.test.ts\n- pnpm exec oxfmt --check --threads=1 docs/clawhub/cli.md docs/clawhub/publishing.md docs/cli/skills.md docs/help/faq.md docs/start/showcase.md docs/tools/creating-skills.md docs/tools/skills.md src/gateway/server-methods/skills.clawhub.test.ts src/plugins/clawhub.test.ts src/plugins/clawhub.ts ui/src/ui/views/skills.test.ts\n- git diff --check\n- exact-head hosted CI passed for 8530374388d8a73235b2ac8444b95a4a4c7d0f1c\n\nNote: repo-native scripts/pr prepare-run was attempted; local broad pnpm test was stopped after unrelated existing failures in agent/media/provider shards, while hosted exact-head CI and targeted ClawHub route/copy validation were green.
Summary:
- Adds `--global` to `openclaw skills install` and `openclaw skills update`, routing ClawHub installs and updates to the shared managed skills root with docs, changelog, and CLI command tests.
- Reproducibility: not applicable. as a bug reproduction; this is a new CLI feature request. Source inspection confirms current `main` lacks `--global`, and the source PR includes after-fix terminal proof for the new path.
Automerge notes:
- PR branch already contained follow-up commit before automerge: fix(cli): address skills global review
- PR branch already contained follow-up commit before automerge: feat(cli): support installing skills to shared global directory via -…
Validation:
- ClawSweeper review passed for head 6eb7187fc1.
- Required merge gates passed before the squash merge.
Prepared head SHA: 6eb7187fc1
Review: https://github.com/openclaw/openclaw/pull/83705#issuecomment-4480023577
Co-authored-by: Hongwei Ma <marvae24@gmail.com>
Co-authored-by: clawsweeper <274271284+clawsweeper[bot]@users.noreply.github.com>
Co-authored-by: clawsweeper[bot] <274271284+clawsweeper[bot]@users.noreply.github.com>
Approved-by: takhoffman
Co-authored-by: takhoffman <781889+takhoffman@users.noreply.github.com>