--- summary: "Create and update workspace skills through Skill Workshop review" read_when: - 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 title: "Skill Workshop" sidebarTitle: "Skill Workshop" --- Skill Workshop is OpenClaw's governed path for creating and updating workspace skills. Agents and operators never write `SKILL.md` directly through this path — they 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. - **Workspace scoped:** creates target the workspace `skills/` root; updates are allowed only for writable workspace skills. - **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. - **Recoverable:** apply writes rollback metadata before touching live files. - **Consistent surfaces:** chat, CLI, and Gateway all call the same service. ## Lifecycle ```text create/update -> pending revise -> pending apply -> applied reject -> rejected quarantine -> quarantined target change -> stale ``` Only a `pending` proposal can be revised, applied, rejected, or quarantined. ## Chat Ask the agent for the skill you want; it calls `skill_workshop` and returns a proposal id. Create: ```text Make a skill called morning-catchup that runs my Monday inbox routine. ``` Update an existing workspace skill: ```text Update trip-planning to also check seat maps before booking. ``` Iterate on a pending proposal: ```text 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` show an approval prompt by default. Set `skills.workshop.approvalPolicy` to `"auto"` to skip it in trusted environments. ## CLI ```bash # 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 # Revise before approval openclaw skills workshop revise --proposal ./PROPOSAL.md # Close out openclaw skills workshop apply openclaw skills workshop reject --reason "Duplicate" openclaw skills workshop quarantine --reason "Needs security review" ``` Every subcommand takes `--agent ` (target workspace; defaults to cwd-inferred, then the default agent) and `--json` (structured output). `propose-create`, `propose-update`, and `revise` also take `--goal ` and `--evidence ` to record proposal context alongside `--proposal`. ## Proposal content While pending, the proposal is stored as `PROPOSAL.md` with proposal-only frontmatter: ```markdown --- 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`: ```bash 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 | update | revise | list | inspect | apply | reject | quarantine`. 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` | `update` | Existing skill name or key | | `proposal_content` | `create`, `update`, `revise` | Stored as `PROPOSAL.md`; capped by `skills.workshop.maxSkillBytes` | | `support_files` | `create`, `update`, `revise` | Array of `{ path, content }` | | `goal`, `evidence` | `create`, `update`, `revise` | Free-text context | | `proposal_id` | `inspect`, `revise`, `apply`, `reject`, `quarantine` | Target proposal | | `reason` | `apply`, `reject`, `quarantine` | Optional | | `query`, `status`, `limit` | `list` | Filter/paginate; `limit` max 50, default 20 | Agents must use `skill_workshop` for generated skill work. They must not create or change proposal files through `write`, `edit`, `exec`, shell commands, or direct filesystem operations. `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. ## Approval and autonomy ```json5 { skills: { workshop: { autonomous: { enabled: false, }, allowSymlinkTargetWrites: false, approvalPolicy: "pending", maxPending: 50, maxSkillBytes: 40000, }, }, } ``` | Setting | Default | Effect | | -------------------------- | ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `autonomous.enabled` | `false` | Lets OpenClaw create pending proposals from durable conversation signals after a successful turn. | | `allowSymlinkTargetWrites` | `false` | Lets apply write through workspace skill symlinks whose real target is listed in `skills.load.allowSymlinkTargets`. | | `approvalPolicy` | `"pending"` | `"pending"` requires an approval prompt before agent-initiated `apply`, `reject`, or `quarantine`. `"auto"` skips the prompt (the agent still has to call the action). | | `maxPending` | `50` | Caps pending and quarantined proposals per workspace (1-200). | | `maxSkillBytes` | `40000` | Caps proposal body size in bytes (1024-200000). | 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.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` | `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. ## Storage ```text /skill-workshop/ proposals.json proposals// proposal.json PROPOSAL.md rollback.json assets/ examples/ references/ scripts/ templates/ ``` Default state directory: `~/.openclaw`. - `proposal.json`: canonical proposal record. - `proposals.json`: fast listing index, rebuildable from proposal folders. - `PROPOSAL.md`: pending skill proposal. - `rollback.json`: recovery metadata written before apply changes live files. ## Limits | Limit | Value | | ------------------------------- | -------------------------------------------------------------------- | | Description | 160 bytes | | Proposal body | `skills.workshop.maxSkillBytes` (default 40,000; hard ceiling 1 MiB) | | 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. | ## Related - [Skills](/tools/skills) for load order, precedence, and visibility - [Creating skills](/tools/creating-skills) for hand-written `SKILL.md` basics - [Skills config](/tools/skills-config) for the full `skills.workshop` schema - [Skills CLI](/cli/skills) for `openclaw skills` commands