SKILL.md files under:
- Memory stores facts, preferences, entities, and past context.
- Skills store reusable procedures the agent should follow on future tasks.
- Skill Workshop is the bridge from a useful turn to a durable workspace skill, with safety checks and optional approval.
- how to validate externally sourced animated GIF assets
- how to replace screenshot assets and verify dimensions
- how to run a repo-specific QA scenario
- how to debug a recurring provider failure
- how to repair a stale local workflow note
- facts like “the user likes blue”
- broad autobiographical memory
- raw transcript archiving
- secrets, credentials, or hidden prompt text
- one-off instructions that will not repeat
Default state
The bundled plugin is experimental and disabled by default unless it is explicitly enabled inplugins.entries.skill-workshop.
The plugin manifest does not set enabledByDefault: true. The enabled: true
default inside the plugin config schema applies only after the plugin entry has
already been selected and loaded.
Experimental means:
- the plugin is supported enough for opt-in testing and dogfooding
- proposal storage, reviewer thresholds, and capture heuristics can evolve
- pending approval is the recommended starting mode
- auto apply is for trusted personal/workspace setups, not shared or hostile input-heavy environments
Enable
Minimal safe config:- the
skill_workshoptool is available - explicit reusable corrections are queued as pending proposals
- threshold-based reviewer passes can propose skill updates
- no skill file is written until a pending proposal is applied
approvalPolicy: "auto" still uses the same scanner and quarantine path. It
does not apply proposals with critical findings.
Configuration
| Key | Default | Range / values | Meaning |
|---|---|---|---|
enabled | true | boolean | Enables the plugin after the plugin entry is loaded. |
autoCapture | true | boolean | Enables post-turn capture/review on successful agent turns. |
approvalPolicy | "pending" | "pending", "auto" | Queue proposals or write safe proposals automatically. |
reviewMode | "hybrid" | "off", "heuristic", "llm", "hybrid" | Chooses explicit correction capture, LLM reviewer, both, or neither. |
reviewInterval | 15 | 1..200 | Run reviewer after this many successful turns. |
reviewMinToolCalls | 8 | 1..500 | Run reviewer after this many observed tool calls. |
reviewTimeoutMs | 45000 | 5000..180000 | Timeout for the embedded reviewer run. |
maxPending | 50 | 1..200 | Max pending/quarantined proposals kept per workspace. |
maxSkillBytes | 40000 | 1024..200000 | Max generated skill/support file size. |
Capture paths
Skill Workshop has three capture paths.Tool suggestions
The model can callskill_workshop directly when it sees a reusable procedure
or when the user asks it to save/update a skill.
This is the most explicit path and works even with autoCapture: false.
Heuristic capture
WhenautoCapture is enabled and reviewMode is heuristic or hybrid, the
plugin scans successful turns for explicit user correction phrases:
next timefrom now onremember tomake sure toalways ... use/check/verify/record/save/preferprefer ... when/for/instead/usewhen asked
- animated GIF tasks ->
animated-gif-workflow - screenshot or asset tasks ->
screenshot-asset-workflow - QA or scenario tasks ->
qa-scenario-workflow - GitHub PR tasks ->
github-pr-workflow - fallback ->
learned-workflows
LLM reviewer
WhenautoCapture is enabled and reviewMode is llm or hybrid, the plugin
runs a compact embedded reviewer after thresholds are reached.
The reviewer receives:
- the recent transcript text, capped to the last 12,000 characters
- up to 12 existing workspace skills
- up to 2,000 characters from each existing skill
- JSON-only instructions
disableTools: truetoolsAllow: []disableMessageTool: true
{ "action": "none" } or one proposal. The action field is create, append, or replace — prefer append/replace when a relevant skill already exists; use create only when no existing skill fits.
Example create:
append adds section + body. replace swaps oldText for newText in the named skill.
Proposal lifecycle
Every generated update becomes a proposal with:idcreatedAtupdatedAtworkspaceDir- optional
agentId - optional
sessionId skillNametitlereasonsource:tool,agent_end, orreviewerstatuschange- optional
scanFindings - optional
quarantineReason
pending- waiting for approvalapplied- written to<workspace>/skillsrejected- rejected by operator/modelquarantined- blocked by critical scanner findings
maxPending.
Tool reference
The plugin registers one agent tool:status
Count proposals by state for the active workspace.
list_pending
List pending proposals.
status values:
pendingappliedrejectedquarantined
list_quarantine
List quarantined proposals.
skill-workshop: quarantined <skill>.
inspect
Fetch a proposal by id.
suggest
Create a proposal. With approvalPolicy: "pending" (default), this queues instead of writing.
Force a safe write (apply: true)
Force a safe write (apply: true)
Force pending under auto policy (apply: false)
Force pending under auto policy (apply: false)
Append to a named section
Append to a named section
Replace exact text
Replace exact text
apply
Apply a pending proposal.
apply refuses quarantined proposals:
reject
Mark a proposal rejected.
write_support_file
Write a supporting file inside an existing or proposed skill directory.
Allowed top-level support directories:
references/templates/scripts/assets/
maxSkillBytes, scanned, and written atomically.
Skill writes
Skill Workshop writes only under:- lowercased
- non
[a-z0-9_-]runs become- - leading/trailing non-alphanumerics are removed
- max length is 80 characters
- final name must match
[a-z0-9][a-z0-9_-]{1,79}
create:
- if the skill does not exist, Skill Workshop writes a new
SKILL.md - if it already exists, Skill Workshop appends the body to
## Workflow
append:
- if the skill exists, Skill Workshop appends to the requested section
- if it does not exist, Skill Workshop creates a minimal skill then appends
replace:
- the skill must already exist
oldTextmust be present exactly- only the first exact match is replaced
Safety model
Skill Workshop has a safety scanner on generatedSKILL.md content and support
files.
Critical findings quarantine proposals:
| Rule id | Blocks content that… |
|---|---|
prompt-injection-ignore-instructions | tells the agent to ignore prior/higher instructions |
prompt-injection-system | references system prompts, developer messages, or hidden instructions |
prompt-injection-tool | encourages bypassing tool permission/approval |
shell-pipe-to-shell | includes curl/wget piped into sh, bash, or zsh |
secret-exfiltration | appears to send env/process env data over the network |
| Rule id | Warns on… |
|---|---|
destructive-delete | broad rm -rf style commands |
unsafe-permissions | chmod 777 style permission use |
- keep
scanFindings - keep
quarantineReason - appear in
list_quarantine - cannot be applied through
apply
Prompt guidance
When enabled, Skill Workshop injects a short prompt section that tells the agent to useskill_workshop for durable procedural memory.
The guidance emphasizes:
- procedures, not facts/preferences
- user corrections
- non-obvious successful procedures
- recurring pitfalls
- stale/thin/wrong skill repair through append/replace
- saving reusable procedure after long tool loops or hard fixes
- short imperative skill text
- no transcript dumps
approvalPolicy:
- pending mode: queue suggestions; apply only after explicit approval
- auto mode: apply safe workspace-skill updates when clearly reusable
Costs and runtime behavior
Heuristic capture does not call a model. LLM review uses an embedded run on the active/default agent model. It is threshold-based so it does not run on every turn by default. The reviewer:- uses the same configured provider/model context when available
- falls back to runtime agent defaults
- has
reviewTimeoutMs - uses lightweight bootstrap context
- has no tools
- writes nothing directly
- can only emit a proposal that goes through the normal scanner and approval/quarantine path
Operating patterns
Use Skill Workshop when the user says:- “next time, do X”
- “from now on, prefer Y”
- “make sure to verify Z”
- “save this as a workflow”
- “this took a while; remember the process”
- “update the local skill for this”
- transcript-shaped
- not imperative
- includes noisy one-off details
- does not tell the next agent what to do
Debugging
Check whether the plugin is loaded:| Symptom | Likely cause | Check |
|---|---|---|
| Tool is unavailable | Plugin entry is not enabled | plugins.entries.skill-workshop.enabled and openclaw plugins list |
| No automatic proposal appears | autoCapture: false, reviewMode: "off", or thresholds not met | Config, proposal status, Gateway logs |
| Heuristic did not capture | User wording did not match correction patterns | Use explicit skill_workshop.suggest or enable LLM reviewer |
| Reviewer did not create a proposal | Reviewer returned none, invalid JSON, or timed out | Gateway logs, reviewTimeoutMs, thresholds |
| Proposal is not applied | approvalPolicy: "pending" | list_pending, then apply |
| Proposal disappeared from pending | Duplicate proposal reused, max pending pruning, or was applied/rejected/quarantined | status, list_pending with status filters, list_quarantine |
| Skill file exists but model misses it | Skill snapshot not refreshed or skill gating excludes it | openclaw skills status and workspace skill eligibility |
skill-workshop: queued <skill>skill-workshop: applied <skill>skill-workshop: quarantined <skill>skill-workshop: heuristic capture skipped: ...skill-workshop: reviewer skipped: ...skill-workshop: reviewer found no update
QA scenarios
Repo-backed QA scenarios:qa/scenarios/plugins/skill-workshop-animated-gif-autocreate.mdqa/scenarios/plugins/skill-workshop-pending-approval.mdqa/scenarios/plugins/skill-workshop-reviewer-autonomous.md
reviewMode: "llm" and exercises the embedded reviewer pass.
When not to enable auto apply
AvoidapprovalPolicy: "auto" when:
- the workspace contains sensitive procedures
- the agent is working on untrusted input
- skills are shared across a broad team
- you are still tuning prompts or scanner rules
- the model frequently handles hostile web/email content