Files
openclaw/docs/tools/skill-workshop.md
Ayaan Zaidi b0c27e2d8f fix(skills): fork the foreground session for lean experience review (#129282)
## 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).
2026-08-25 20:27:25 +05:30

28 KiB
Raw Permalink Blame History

summary, read_when, title, sidebarTitle
summary read_when title sidebarTitle
Create and update workspace skills through Skill Workshop review
You want the agent to create or update a skill from chat
You need to review, apply, reject, or quarantine a generated skill draft
You are configuring Skill Workshop approval, autonomy, storage, or limits
You want to understand where self-learning proposals are reviewed
Skill Workshop Skill Workshop

Skill Workshop is OpenClaw's governed path for creating and updating workspace skills. Through this path, agents and operators create a proposal (pending draft with content, target binding, scanner state, hashes, and rollback metadata) that becomes a live skill only when applied.

Skill Workshop writes workspace skills only. It never touches bundled, plugin, ClawHub, extra-root, managed, personal-agent, or system skills.

How it works

  • Proposal first: generated content is stored as PROPOSAL.md, not SKILL.md.
  • Apply is the only live write: create, update, and revise never change active skills.
  • Workshop-owned updates: creates target the workspace skills/ root; updates are allowed only when an applied Workshop create proposal owns the workspace-relative skill directory. Handwritten and externally installed workspace skills remain read-only.
  • No clobber: create fails if the target skill already exists.
  • Hash bound: update proposals bind to the current target hash and go stale if the live skill changes before apply.
  • Scanner gated: apply reruns the security scanner before writing. Only critical findings block apply; warn-level findings remain visible but do not block it.
  • Recoverable: apply writes rollback metadata before touching live files.
  • Revision atomic: create and revise flush a complete immutable proposal generation, publish it with an atomic rename, then sync its parent directory where supported before publishing the SQLite record and event together. Process interruption exposes either the complete previous generation or the complete new one.
  • Consistent surfaces: chat, CLI, and Gateway all call the same service.

Lifecycle

create/update -> pending
revise        -> pending
evaluate      -> pending
apply         -> applied
reject        -> rejected
quarantine    -> quarantined
target change -> stale

Only a pending proposal can be revised, applied, rejected, or quarantined.

Collection review

In auto mode, the Gateway starts one isolated collection-review session per agent workspace each week. The session can only read skills and submit one atomic collection reconciliation listing only changes. It keeps distinct useful skills, rewrites weak ones, consolidates overlap, and drops junk or stale fragments. Choosing auto intentionally authorizes those rewrites and drops without a second approval for Workshop-owned paths only; propose and off do not run collection review.

The reviewer reads each skill it intends to change. Unlisted skills stay untouched. Skills without applied Workshop create provenance are read-only; Workshop-owned skills may receive write or drop. A new skill created during collection review is recorded as an automatically applied create proposal, which makes that directory Workshop-owned. Disabled and agent-filtered skills stay untouched.

Skills that predate ownership tracking, including skills that earlier reconcile runs created directly, have no applied create proposal. Skill Workshop intentionally classifies them as user-authored and read-only. It manages only skills it creates and records from now on.

Shared workspaces use the union of each agent's allowed skills only when provider, model, and resolved auth identity match. Reconciliation must leave every sharing agent at least one visible skill. OpenClaw validates and scans every write before changing the workspace, serializes collection edits with a workspace lease, and retains one backup under the state directory. The changed collection appears in new agent runs; running sessions keep their existing skill snapshot.

To undo the last completed cleanup, ask the agent to restore the skill collection. It uses skill_workshop action restore_collection under the same workspace lock. Restore refuses if any affected skill changed after cleanup.

The weekly attempt is persisted per workspace before the model starts. Gateway restarts do not repeat a failed or successful attempt within 7 days. Review is admitted only for collections of at most 200 skills and 240,000 total SKILL.md bytes. Larger collections stay unchanged. The reconciled result must stay inside the same byte limit.

Every completed review records its kept, written, and dropped skill names in the shared state database, including the reason for each drop. OpenClaw retains the latest 90 outcomes per workspace.

Collection rewrites and merges produce SKILL.md files at or below 10,000 characters. A skill already above the cap can only become shorter. User-authored skills stay untouched.

Chat

Ask the agent for the skill you want; it calls skill_workshop and returns a proposal id.

Learn from recent work

Use /learn to route the current conversation or named sources into the best matching pending proposal or live skill, creating a skill only when needed:

/learn
/learn docs/runbook.md and https://example.com/guide; focus on recovery

With no request, /learn asks the agent to distill the reusable workflow from the current conversation. With a request, the agent treats paths, URLs, pasted notes, and conversation references as sources while honoring focus, scope, and naming requirements. It gathers the sources with its existing tools, then calls skill_workshop to revise a matching pending proposal, update a matching live skill, or create a proposal when neither exists.

The resulting proposal stays pending; /learn never applies it. Review and apply it through the normal approval flow or with openclaw skills workshop.

Create:

Make a skill called morning-catchup that runs my Monday inbox routine.

Update an existing workspace skill:

Update trip-planning to also check seat maps before booking.

If a skill used in the current turn proves wrong or incomplete, the agent reads the live skill and creates a targeted patch proposal. A runtime receipt limits this flow to skills used in that run. Autonomous mode off disables repair, propose leaves the patch pending until explicitly applied, and auto scans and applies it immediately. The repaired skill is loaded by new sessions; the running session keeps its original skill snapshot.

Iterate on a pending proposal:

Show me the morning-catchup proposal.
Revise it to also flag anything marked urgent.
Apply the morning-catchup proposal.

Agent-initiated apply, reject, and quarantine run without an additional approval prompt by default. Set skills.workshop.approvalPolicy to "pending" to require operator approval before those actions.

When approval is required, the prompt identifies the proposal id and target skill, and shows the proposal description, support-file count, and body size. Approval requests are bounded to finish before the agent tool watchdog. If no decision arrives before the prompt expires, the lifecycle action does not run: the proposal stays pending and unchanged. Decide later in the Skill Workshop UI or run openclaw skills workshop apply|reject|quarantine <proposal-id>. Agents should not retry an expired lifecycle action in a loop.

CLI

# Create
openclaw skills workshop propose-create \
  --name morning-catchup \
  --description "Daily inbox catch-up: triage, archive, surface, draft, plan" \
  --proposal ./PROPOSAL.md

# Update an existing workspace skill
openclaw skills workshop propose-update trip-planning --proposal ./PROPOSAL.md

# List and inspect
openclaw skills workshop list
openclaw skills workshop inspect <proposal-id>

# Revise before approval
openclaw skills workshop revise <proposal-id> --proposal ./PROPOSAL.md

# Run installed plugin evaluators against the exact current draft
openclaw skills workshop evaluate <proposal-id>

# Close out
openclaw skills workshop apply <proposal-id>
openclaw skills workshop reject <proposal-id> --reason "Duplicate"
openclaw skills workshop quarantine <proposal-id> --reason "Needs security review"

Every subcommand takes --agent <id> (target workspace; defaults to cwd-inferred, then the default agent) and --json (structured output). propose-create, propose-update, and revise also take --goal <text> and --evidence <text> to record proposal context alongside --proposal. evaluate runs through the live Gateway plugin registry, snapshots the current proposal revision before dispatch, and accepts --correlation-id <id> for external orchestration.

Plugin evaluation and lifecycle hooks

Gateway plugins can extend Skill Workshop without owning proposal storage or live skill writes:

  • skill_proposal_evaluate receives an exact candidate bundle and, for update proposals, the complete baseline skill. It returns attributed findings, metrics, and an optional pass, revise, or block decision.
  • skill_proposal_changed observes durable created, revised, evaluation_completed, applied, rejected, quarantined, and stale events.
  • skill_changed observes committed live skill created, updated, and removed events from Workshop and supported install/uninstall paths.

Evaluations are explicit from the CLI, Control UI, Gateway skills.proposals.evaluate method, or agent skill_workshop action. Results are stored on the exact proposal revision and in the append-only proposal event ledger. Evaluator failures remain attributed results; only a completed decision: "block" prevents apply. Apply also revalidates the evaluated target tree, so any live skill asset drift requires a fresh evaluation.

The lifecycle supports external optimization loops without embedding one. Controllers can consume skills.proposals.events.list, evaluate an exact revisionHash, revise with expectedRevisionHash and correlationId, then continue from the returned event sequence. OpenClaw does not schedule, auto-revise, or decide when such a loop should stop.

Proposal content

While pending, the proposal is stored as PROPOSAL.md with proposal-only frontmatter:

---
name: "morning-catchup"
description: "Daily inbox catch-up: triage, archive, surface, draft, plan"
status: proposal
version: "v1"
date: "2026-05-30T00:00:00.000Z"
---

On apply, Skill Workshop writes the active SKILL.md and removes the proposal-only fields: status, proposal version, and proposal date.

Support files

Use --proposal-dir when the proposed skill needs files beside PROPOSAL.md:

openclaw skills workshop propose-create \
  --name weekly-update \
  --description "Friday wrap-up: stats, highlights, next week's top three" \
  --proposal-dir ./weekly-update-proposal

The directory must contain PROPOSAL.md. Support files must live under assets/, examples/, references/, scripts/, or templates/. Skill Workshop scans, hashes, and stores them with the proposal, then writes them beside the live SKILL.md only on apply.

Rejected support-file paths: absolute paths, hidden path segments, path traversal, overlapping paths, executable files, non-UTF-8 text, null bytes, and paths outside the standard support folders.

Agent tool

The model uses skill_workshop with one required action: create | read | patch | update | revise | list | inspect | evaluate | apply | reject | quarantine | history | restore_collection. Other parameters apply depending on the action:

Parameter Used by Notes
name create, inspect, revise Required for create; resolves a pending proposal by name otherwise
description create, update, revise Max 160 bytes
skill_name read, patch, update Existing skill name or key
old_string, new_string patch Exact current text and its replacement; read the skill first
proposal_content create, update, revise Required for create/update; omit on revise to preserve the body
support_files create, update, revise Array of { path, content }
goal, evidence create, update, revise Free-text context
proposal_id inspect, revise, evaluate, apply, reject, quarantine Target proposal
artifact_path inspect PROPOSAL.md or one listed support-file path
expected_revision_hash evaluate, apply, reject, quarantine Rejects a stale orchestration step
correlation_id evaluate, revise, apply, reject, quarantine External run or experiment correlation
reason apply, reject, quarantine Optional
query, status, limit list Filter/paginate; limit max 50, default 20

inspect returns proposal metadata, a bounded artifact manifest, and one complete artifact when it fits the selected model's context budget. It selects PROPOSAL.md by default. Set artifact_path to read one support file separately. When the selected artifact does not fit, the result omits its body, reports the original size, and points to smaller per-artifact reads or the unbounded operator CLI command shown above.

Agents must use skill_workshop for generated skill work and must not create or change skill or proposal files directly. This rule is advisory and prompt-enforced. A hard guard is not currently possible at the tool-policy seam.

`skill_workshop` is a built-in agent tool and is included in `tools.profile: "coding"`. If a stricter policy hides it, add `skill_workshop` to the active `tools.allow` list, or use `tools.alsoAllow: ["skill_workshop"]` when the scope uses a profile without an explicit `tools.allow`. Sandboxed runs do not construct the host-side Skill Workshop tool, so run proposal review actions from a normal host-side agent session or the CLI.

Self-learning

After substantial work, an isolated background review can turn corrections and successful procedures into Workshop proposals; see Self-learning. Set skills.workshop.autonomous.mode to propose to create pending proposals, or to auto to apply scanner-approved captures through the normal Workshop service. The Control UI Workshop tab shows whether self-learning is on; use the config setting to choose all three modes.

Scan past sessions

The Control UI can review older work without enabling autonomous self-learning. Open Plugins → Workshop and select Find skill ideas. The scan starts with the newest eligible sessions and reviews a bounded window of substantial work. It skips cron, heartbeat, hook, subagent, ACP, plugin-owned, and internal review sessions, plus conversations with fewer than six model turns.

The reviewer uses the selected agent's configured model and receives a secret-redacted, size-bounded transcript bundle. It applies the same conservative bar as experience review: a concrete recovery pattern or a stable procedure that would remove at least two future model or tool calls. Routine work and one-off facts should produce no proposal.

One scan can create or revise at most three pending proposals. It cannot apply, reject, quarantine, or edit a live skill. The Workshop shows cumulative coverage, for example 20 sessions reviewed · Jun 18today · 2 ideas found. Select Scan earlier work to continue from the persisted oldest-session cursor. After the available history is exhausted, the action becomes Scan new work.

Historical review is manual even when skills.workshop.autonomous.mode is off. Each click starts a model run, so provider pricing and data-handling terms apply. The cursor and coverage counts are stored in the shared OpenClaw state database; transcript content is not copied into scan state.

In propose and auto modes, OpenClaw can review one finished substantial turn after the agent system becomes idle. The review continues the foreground request prefix, so the provider can reuse its prompt cache. Review transcript and session metadata changes stay detached. It can draft one pending create, patch, or update. In auto mode, creates and Workshop-authored updates use the scanner-gated apply path. User-authored updates stay pending for operator review. A failed review is logged and dropped after one attempt.

See Self-learning for enablement, eligibility, privacy and cost details, the proposal threshold, and troubleshooting.

Approval and autonomy

{
  skills: {
    workshop: {
      autonomous: {
        mode: "auto",
      },
      allowSymlinkTargetWrites: false,
      approvalPolicy: "auto",
      maxPending: 50,
      maxSkillBytes: 40000,
    },
  },
}
Setting Default Effect
autonomous.mode "auto" "off" disables autonomous capture, "propose" creates pending captures, and "auto" applies captures and runs weekly cleanup that can rewrite or drop Workshop-owned skills.
allowSymlinkTargetWrites false Lets apply write through workspace skill symlinks whose real target is listed in skills.load.allowSymlinkTargets.
approvalPolicy "auto" "auto" skips an additional prompt for agent-initiated apply, reject, or quarantine (the agent still has to call the action). "pending" requires approval.
maxPending 50 Caps pending and quarantined proposals per workspace (1-200).
maxSkillBytes 40000 Caps manual and foreground proposal body size in bytes (1024-200000). Autonomous results have a 10,000-character cap.

In propose and auto modes, an isolated run of the selected model decides whether the completed trajectory clears the evidence-gated proposal bar. The foreground model is not prompted to learn before it replies. The background reviewer preserves the foreground run as proposal provenance, cannot access general agent tools, and cannot make lifecycle decisions. In auto mode, the capture pipeline applies every autonomous proposal only after the isolated run completes. Existing-skill changes require a complete read receipt and content-hash binding before they are eligible for that apply step. The review starts only when the foreground runtime reports its resolved model and that skill_workshop was actually available. Restrictive or unknown tool policy therefore fails closed and creates no proposal.

See Self-learning for the complete autonomous review behavior and safety model.

Proposal descriptions are always capped at 160 bytes, independent of maxSkillBytes.

Gateway methods

Method Scope
skills.proposals.list operator.read
skills.proposals.inspect operator.read
skills.proposals.historyStatus operator.read
skills.proposals.historyScan operator.admin
skills.proposals.create operator.admin
skills.proposals.update operator.admin
skills.proposals.revise operator.admin
skills.proposals.requestRevision operator.admin
skills.proposals.apply operator.admin
skills.proposals.reject operator.admin
skills.proposals.quarantine operator.admin
skills.curator.status operator.read
skills.curator.pin operator.admin
skills.curator.unpin operator.admin
skills.curator.restore operator.admin

skills.curator.status also reports the latest collection and experience review outcome per workspace. The other curator methods manage lifecycle state written by older releases. Weekly review does not use age, pin, or overlap state.

requestRevision is Gateway-only (no CLI or agent-tool equivalent): it forwards free-text revision instructions to the owning agent's chat session instead of replacing PROPOSAL.md directly, for UIs that ask the agent to revise rather than submit literal new content.

historyStatus and historyScan are Control UI support methods. historyScan accepts direction: "older" | "newer"; it always leaves results as pending proposals.

Storage

<OPENCLAW_STATE_DIR>/
  state/openclaw.sqlite
  skill-workshop/proposals/<proposal-id>/
    generations/<generation-id>/
      PROPOSAL.md
      assets/
      examples/
      references/
      scripts/
      templates/

Default state directory: ~/.openclaw.

  • state/openclaw.sqlite: canonical proposal records, the active generation reference, lifecycle status, origin attribution, and apply rollback metadata.
  • Each generation contains one PROPOSAL.md and all of that revision's support files. Revision publication never overwrites the active generation in place.
  • Generation files are flushed before publication. After the complete bundle is renamed into place, OpenClaw syncs the generations/ parent directory where the platform supports directory flushing, before committing SQLite state. Platforms that report directory synchronization as unsupported retain atomic rename and process-interruption safety, but do not claim power-loss durability for that directory entry.
  • Support files remain beside their generation's PROPOSAL.md so operators can review the proposed skill as a normal directory.

Proposals created by older releases can still reference the earlier root-level PROPOSAL.md layout. The stored record identifies that bundle directly; the next successful revision moves the proposal onto the generation layout and retires the previous bundle.

openclaw doctor --fix imports the previous proposals.json, proposal.json, and rollback.json metadata into SQLite after verifying each proposal, then removes the migrated JSON files. If an agent's configured workspace changes, its earlier proposals remain listed with a previous-workspace marker instead of disappearing.

Limits

Limit Value
Description 160 bytes
Proposal body skills.workshop.maxSkillBytes (default 40,000; hard ceiling 200,000 bytes)
Autonomous SKILL.md 10,000 characters, or strictly shorter when already over the cap
Support files 64 per proposal
Support file size 256 KiB each, 2 MiB total
Pending + quarantined proposals skills.workshop.maxPending per workspace (default 50)

Troubleshooting

Problem Resolution
Skill proposal description is too large Shorten description to 160 bytes or less.
Skill proposal content is too large Shorten the proposal body or raise skills.workshop.maxSkillBytes.
Target skill changed after proposal creation Revise the proposal against the current target, or create a new proposal.
Proposal scan failed Inspect scanner findings, then revise or quarantine the proposal.
untrusted symlink target Configure skills.load.allowSymlinkTargets and enable skills.workshop.allowSymlinkTargetWrites only for intentional shared skill roots.
Support file paths must be under one of... Move support files under assets/, examples/, references/, scripts/, or templates/.
Proposal does not show in list Check the selected --agent workspace and OPENCLAW_STATE_DIR.
Agent cannot call skill_workshop Check the active tool policy and run mode. coding includes the tool; restrictive tools.allow policies must list it explicitly, and sandboxed runs must use a normal host-side agent session or the CLI.

Tool-policy diagnostic

In propose and auto modes, openclaw doctor runs the core/doctor/skill-workshop-tool-policy check for the default agent. If policy hides skill_workshop, the warning names the first excluding config layer and the exact allow or alsoAllow change to make. Older runbooks may still use openclaw plugins inspect skill-workshop; that command now explains that Skill Workshop is built in and prints the same policy hint when applicable.