Skills
A skill is a reusable, versioned, testable unit of capability that you assign to agents. Think of it as procedural memory — editable from an admin UI, not buried in code.
Skill document
{
"_id": "skill_rust_backend_development",
"name": "Rust Backend Development",
"slug": "rust-backend-development",
"version": 3,
"description": "Guidelines for implementing backend services in Rust.",
"content_markdown": "# Rust Backend Development\n\nUse axum, tokio, tracing...",
"tags": ["rust", "backend", "api"],
"required_tools": ["cargo", "shell", "git"],
"created_by": "admin",
"status": "active"
}
Skill format (authoring)
Do not make skills executable code at first. Make them structured instructions:
name: Rust API Implementation
version: 1
description: How to implement backend API tasks in Rust.
applies_to:
- backend
- rust
required_tools:
- cargo
- git
content: |
When implementing Rust APIs:
- use axum
- use serde DTOs
- add tracing instrumentation
- write integration tests
- never commit secrets
Skill kinds (over time)
| Kind | Form |
|---|---|
| instruction | markdown / YAML guidance (start here) |
| tool | wrappers around commands / APIs |
| workflow | multi-step procedures |
| verification | checklists / tests |
Skill editor (UI)
The skill editor should feel like editing a reusable prompt/toolbook:
- Skill name · Description · Markdown instructions · Examples
- Required tools · Allowed agent types
- Version history
- Test skill against a sample task
- Approve / publish
How skills enter a run
When Core assembles a run config, each attached skill is rendered into the
runtime context (system prompt + tool requirements). The nexus-skills crate
validates the skill YAML, renders markdown, and enforces semver versioning. The
worker pins the latest active version for each assigned slug.
Where skills come from
Skills can be authored three ways — all converge on the same draft → active
review gate:
- Operator-authored in the Admin UI /
POST /v1/skills. - Agent-authored — a run that solves something non-trivial can call the
skill.proposetool to capture the procedure as adraftskill (scanned for injection/exfiltration first). Re-proposing an existing slug creates the next version. This is Nexus's human-in-the-loop procedural learning — agents write skills into review, never directly into use. - Imported from an external source via
POST /v1/skills/import(a URL — GitHubblobURLs are rewritten to raw and fetched under an SSRF host guard — or inline content). Frontmatter (name/slug/description/tags) is parsed, the body is scanned, and it lands as adraftversion.
Approve a draft with POST /v1/skills/{id}/approve. Each skill carries its
source (manual / agent:<id> / import:<url>) and the scan report so a
reviewer sees exactly what tripped the input-trust check.
Hub: trust, drift, bundles
Imported skills also record a trust level (official / community /
unverified, default unverified) and a content hash. Two operations build
on that:
- Bundles —
POST /v1/skills/importwith{ "bundle": [ { "url": … }, … ] }imports many skills at once, returning a per-entry error list rather than aborting the whole batch. A bundle-leveltrustapplies unless an entry overrides it. - Drift detection —
GET /v1/skills/{id}/driftre-fetches the skill's source URL and compares the current content hash to the stored one, so you can tell when an upstream skill has changed since you imported it.
Credential scoping
A skill can declare the secrets it needs — required_environment_variables
(and, advisory, required_credential_files). At run time the worker unions these
across the agent's skills, and the runner strips every other secret-shaped env
var from shelled-out child processes. A skill gets exactly the credentials it
asked for and nothing more. See Tools.
Progressive disclosure
Agents need not be pre-loaded with every skill body. The skill.list tool
returns just names + slugs + descriptions; skill.view pulls the full markdown
of a chosen slug on demand — keeping the context window lean.