If you have been staring at skills/bundled, skills/managed, and skills/workspace in an OpenClaw project wondering which folder is supposed to hold your shiny new Notion integration, you are not alone. The tri-layer skill system ships with OpenClaw v3.7.0 and later, and it confuses nearly everyone on first contact. This post walks through what each tier is for, why the separation exists, how install gating protects your agent in multi-tenant environments, and how the runtime decides which skill gets injected on any given turn.
Why three skill buckets exist in the first place
OpenClaw started with a single skills directory. That worked until community contributions exploded (>800 skills on ClawHub as of 2024-06) and large teams began sharing one daemon with multiple agents. Two problems showed up:
- Security & trust. Loading arbitrary npm packages inside an agent loop is a quick path to
rm -rf /. We needed guardrails. - Operational sanity. When every pull from
mainshipped 40 new skills, container sizes ballooned and cold starts tanked.
Splitting skills into Bundled, Managed, and Workspace tiers solves those issues without sacrificing the "just-npm-install-it" developer experience.
Bundled Skills: What ships in the box
Bundled skills live in the OpenClaw repository itself. Think of them as the JavaScript standard library for agents: primitives that must exist for most setups to work. As of v3.7.3 that list includes:
- browser — Chrome-DevTools-driven navigation
- shell — constrained Bash with configurable allowlist
- memory — SQLite + embedding store
- schedule — cron-style task queue
- webhook — inbound HTTP triggers
Because they ship with the tarball, Bundled skills follow OpenClaw’s release cadence. If you pull v3.8.0, you get browser v3.8.0 as well. No extra npm dance required.
When Bundled is all you need
- Green-field PoCs or hackathon demos.
- Air-gapped environments where fetching from external registries is impossible.
- Teams that prefer a single audited codebase and update on a fixed schedule.
Drawbacks
- Coarse-grained updates. You cannot hotfix
shellwithout bumping the entire OpenClaw version. - Binary bloat. Shipping Chromium inside every container hurts cold-start latency on small FaaS providers.
Managed Skills: Install-gated power features from ClawHub
Managed skills live on ClawHub—the community registry that sits somewhere between npm and VS Code Marketplace. They are installed per-agent (not global daemon) and gated by an allowlist maintained by you or your org admin.
How install gating works under the hood
- Request. You run
openclaw add clawhub://notion@1.4.2inside the agent dir. - Policy check. The daemon reads
.clawhub-policy.json:
{
"allowedMaintainers": ["notion-labs", "alice"],
"allowedScopes": ["crm", "docs"],
"semverMax": "^2.0.0"
}
- Signature verification. Each Managed skill tarball is signed with Sigstore. The daemon verifies the sig before unpacking to
skills/managed. - Runtime sandboxing. Managed skills run in a per-skill VM context with a curated
requiregraph. They cannot touchshellunless they declarecapabilities.shell:truein their manifest and your policy says that’s okay.
Managed skills give you the best of both worlds: rapid community updates and a sane security posture. On ClawCloud SaaS, policy UI sits under Settings → Skills. On self-hosted, it’s the JSON file above.
Typical use cases
- First-party integrations like Gmail, Calendar, GitHub.
- Vendor libraries that update weekly (Salesforce, Stripe).
- Anything you expect to rev faster than your OpenClaw core.
Trade-offs
- Operational overhead. Someone has to approve version bumps.
- Latency. The first cold call spins up an isolated VM; add ~10–20 ms.
Workspace Skills: Your private layer
Workspace skills are local to a single git repo or ClawCloud workspace. They never hit ClawHub, and they bypass the gating mechanism because you own the code. Physically they live in skills/workspace.
Why the separate folder instead of "just add to managed"?
Because Workspace skills skip sandboxing, you get unfettered require() power and can import native modules, long-lived connections, or corporate SDKs that ClawHub policy would otherwise block. They are perfect for:
- Internal APIs (monorepo GraphQL client, proprietary billing).
- One-off hack scripts you do not plan to maintain.
- Enterprise glue code that mixes secrets at build time.
Example skeleton
// skills/workspace/jira/index.js
module.exports = {
name: "jira",
description: "Create and query Jira tickets",
parameters: {
type: "object",
properties: {
summary: { type: "string" },
project: { type: "string" }
},
required: ["summary", "project"]
},
run: async ({ summary, project }, { env }) => {
const res = await fetch(`${env.JIRA_URL}/rest/api/3/issue`, {
method: "POST",
headers: {
Authorization: `Bearer ${env.JIRA_TOKEN}`,
"Content-Type": "application/json"
},
body: JSON.stringify({ /* jira payload */ })
})
return await res.json()
}
}
Caveats
- No automatic updates. You own the lifecycle forever.
- Zero sandboxing. A rogue
rm -rfis on you. - On ClawCloud, Workspace skills are not shareable across projects; you need to push a template or publish to ClawHub to reuse.
How the agent decides what to inject each turn
OpenClaw does not blindly expose every skill every time. Each turn (i.e., every incoming user message) the runtime executes a four-step selection pipeline:
- Capability match. Every skill declares
topicsand an optional embedding vector. The agent embeds the user request and does a cosine similarity search against all skill vectors. Threshold default is 0.78; tune viaskills.relevanceThresholdinconfig.yaml. - Policy filter. If a skill is Managed, the daemon checks the policy again at runtime—useful if ops revoked a skill mid-conversation.
- Energy budget. The planner computes an LLM token budget. If five skills pass the threshold but the prompt budget is 1,200 tokens, it will pick the highest-scoring subset that fits. Bundled skills get a +0.1 score bump as a tie-breaker.
- Contextual memory. Skills with
memory.tag = "sticky"(e.g.,shell) can request always-on presence for the session unless explicitly banned.
The final manifest is serialized into the system prompt like so:
### Available tools (2)
1. browser.navigate(url: string)
2. notion.createPage(title: string, content: string)
Then the LLM picks a tool call or returns plain text.
Choosing the right tier for your next integration
Below is a decision matrix distilled from three months of internal and community feedback:
- Is the integration open-source and broadly useful? → Publish as Managed on ClawHub.
- Does it ship secrets or proprietary binaries? → Keep it Workspace.
- Does it need deep platform hooks (
shell,browser)? → Bundled or Workspace; ClawHub policy may block those perms. - Do you require semantic version pinning across 200 agents? → Managed with strict
semverMax. - Are you optimising for smallest cold start? → Workspace compiled into your container image; disable Bundled skills you do not need via
config.yaml:
bundled:
disable:
- browser
- schedule
Migration tips for legacy projects
If you upgraded from pre-3.7 releases, all your old skills are now treated as Workspace. To migrate selectively:
- Add
"distribution": "managed"toskill.json. - Publish to ClawHub:
openclaw publish --visibility private. - Delete local copy and run
openclaw addto reinstall via the managed path.
For Bundled promotion (rare), submit a PR to openclaw/openclaw with evidence that the skill is universal and low-risk. The core team merges on a quarterly cadence.
Putting it into practice
Open a terminal in a fresh workspace and run:
# 1. create agent
npx openclaw@3.8.0 init my-agent
# 2. add a managed skill
cd my-agent
openclaw add clawhub://notion@latest
# 3. scaffold a workspace skill
mkdir -p skills/workspace/weather && cp templates/skill.js skills/workspace/weather/index.js
# 4. run locally
openclaw dev --port 8080
Notice how the runtime reports:
[skills] bundled: 5 │ managed: 1 │ workspace: 1 │ total: 7
Send a chat message: “Save this idea to Notion and show tomorrow’s weather”. You should see both notion.createPage (managed) and weather.getForecast (workspace) injected automatically while unused Bundled skills stay silent. That selective load is the whole point of the tri-tier design.
If something breaks, run openclaw doctor. It prints a per-skill health report and policy mismatches. Nine out of ten “the skill won’t show up” tickets boil down to a policy block or similarity threshold too high.
That’s it: Bundled for core primitives, Managed for community-vetted rapid iteration, Workspace for anything you can’t or won’t share. With the folders demystified, you can stop fighting the directory layout and get back to building agents that do actual work.