Skills Inbox
The human-in-the-loop review queue for staged skills — the card an operator sees, the five actions, and how to recover a quarantined skill.
The Skills Inbox is where a staged skill waits for a human decision
before it goes live. Both Forge candidates (after they clear the
gates) and direct
agent writes land here. Until someone acts,
the skill is not delivered to any agent.
The Inbox is an admin surface under POST/GET /api/v1/skills-inbox/. Every
endpoint returns SKILLS_FACTORY_DISABLED if the tenant hasn't opted in.
If you've set skills_factory.sentinel.auto_promote_clean = true, clean
fully-gated Forge candidates bypass the Inbox and go straight to active —
the Inbox then only holds candidates that need attention (warnings, direct
agent writes, edits).
The card
GET /api/v1/skills-inbox/ returns the staged skills for a tenant (filter by
fleet_id; capped by skills_factory.inbox_max_pending). Each item is an
InboxCard — enough to make a decision without leaving the queue:
| Field | What it tells you |
|---|---|
name, description, summary | What the skill is and when it should fire. |
domain, tags, kind | Grouping; create vs update. |
source | forge (auto-mined), agent, or manual. |
scan_state, scan_critical, scan_warn | Sentinel result — clean with zero criticals is required to approve. |
origin, evidence | For Forge cards: the cluster (size, distinct agents, window) and the traces behind it. |
fingerprint | The cluster fingerprint (drives poison/dedup). |
content_hash, created_at, deferred_at | Provenance + queue position. |
The five actions
| Action | Endpoint | Body | Effect |
|---|---|---|---|
| Approve | POST /{slug}/approve | — | Re-scans, then staged → active only if the scan is clean — the skill goes live (pull + push). A non-clean re-scan is refused (422) and the skill stays staged; fix it with Edit. |
| Edit | POST /{slug}/edit | { content?, description?, summary? } | Revise in place; re-hashes and re-scans; stays staged for a fresh decision. |
| Reject | POST /{slug}/reject | { reason, cooloff_days? } | staged or quarantined → rejected; poison-flags the fingerprint for a cool-off (defaults to skills_factory.rejection_cooloff_days) so Forge won't immediately re-mint it. |
| Quarantine | POST /{slug}/quarantine | { reason } | staged → quarantined; held out of delivery for investigation. |
| Defer | POST /{slug}/defer | { reason? } | Leaves it staged; stamps deferred_at to push it down the queue. |
Approve/reject/quarantine return an ActionResponse with previous_status
and the new status, so the transition is auditable.
Typical workflow
- Triage the queue. Sort by
scan_state— anything notcleanneeds a closer look. For Forge cards, checkorigin/evidenceto see how strong the cluster is. - Approve the good ones — they go live immediately.
- Edit a promising-but-rough skill (tighten the
summary, fix thecontent); it re-scans and stays staged so you can approve the revision. - Reject noise with a
reason— the cool-off stops Forge re-proposing the same cluster right away. - Defer anything you're unsure about to revisit later.
Recovering a quarantined skill
A quarantined skill (Sentinel flagged a critical, or you quarantined it
manually) is held out of delivery. Approve and Edit operate only on
staged skills, so you can't fix a quarantined skill in place or force it live
past a critical scan — the one Inbox action available on it is Reject
(which also poison-flags the cluster fingerprint for a cool-off). To ship a
corrected version, publish a fixed skill afresh, or let Forge
re-propose a clean candidate once the cool-off lapses. (Direct
quarantined → staged recovery is planned lifecycle work.)
Where to look in the source
- Inbox endpoints, card model, action request bodies:
core-api/src/core_api/routes/skills_inbox.py - Status transitions:
core-api/src/core_api/services/skill_lifecycle.py
Forge
The server-side resident that mines fleet behavior into skill candidates — how it runs, how operators trigger and observe it, and the knobs that tune it.
Delivery
How an active skill actually reaches an agent — the MCP pull tier, the OpenClaw push tier, the active-only gate on both, and how the bundled usage skill differs.