Skill System
Status: Design landing Reference epics: INK-835, INK-829, INK-833, INK-844 ADRs: ADR-016, ADR-022
A skill is a named, reusable bundle of prompt, tool orchestration, and supporting artifacts that the World Agent can invoke. Skills are portable tools scoped to a workspace — not claims about the world, not workspace content in the provenance sense, not compiled modules. They are composed at runtime by the Skill Composer subagent and executed by ordinary turns of the agent graph.
This page defines what a skill is, where it sits in the architecture, and how the subsystem fits together. Two sibling pages cover the mechanics:
- Skill Composer — the runtime composition algorithm and its I/O contract.
- Skill Storage — entity shape, SQLite schema, permissions, sync, import/export.
The category distinction
Section titled “The category distinction”The world model (see World Agent, Provenance, Submit Boundary) is about claims about the world — characters, events, places, decisions, and the links between them. Those claims carry origin and lifecycle, derive from prior claims, and cross the submit boundary to enter canonical standing.
A skill is not a claim about the world. It is a tool the agent uses to operate on the workspace. Authoring a skill is no more a world-model claim than adding a keyboard shortcut is. It is a workspace configuration change — the workspace now has one more way for the agent to do work — and it is governed by its own rules, separate from the world-model invariants.
This distinction is the load-bearing commitment of the subsystem (decision D31).
The practical consequences:
- No submit boundary on skill CRUD. Creating, updating, deleting, or importing a skill does not produce a deviation record and does not require promotion from
candidatetocanonical-allowed. There is no draft-skill limbo. - No provenance fields on skill definitions. A skill does not have
origin,lifecycle, derivation links, or deviation records. It has its own attribution (source:system,user,imported; author; version). - Writes by a skill still cross the boundary. When a skill runs and produces content — a character page, a candidate digest, a deviation callout — those writes flow through the submit boundary like any other agent write. The skill is the tool; the content is the claim.
- Separate storage. Skills live in their own tables in
inklings.db, outside the world-content schema and outside Agent Memory. Detail: Skill Storage.
What a skill is
Section titled “What a skill is”A skill is a package with four parts:
- Metadata. Name, description, version, author, source, declared model variants, parameter schema. In the canonical authoring format, this is the YAML frontmatter of the skill’s
.mdfile — fields includename,description,version,author,license,required_scopes(capability set),allowed_roles, andinput_schema/output_schema. - Prompt framing. Authored prose describing what the skill is for, what assumptions are in play, what success looks like. The Skill Composer turns this into the prompt’s opening for a specific invocation. In the canonical format, this is the body of the
.mdfile, structured by section conventions the Composer consumes at compose time. - Artifacts. Typed supporting resources the skill draws on during composition. Current kinds:
Description(expanded prose the agent should hold in context),Approach(how-to narrative),PromptTemplate(MiniJinja template the Composer may render with invocation inputs),Example(input/output pair used as a few-shot). Artifact kinds are a closed set — new kinds require a design pass. - Tool surface. The MCP tools (see MCP System) the skill expects to use, with any narrowing constraints. The Composer bounds the planner’s tool availability to this set; it never expands the caller’s capability set.
A skill also carries an invocation contract: input schema, output schema, progress-reporting shape, named interrupt points. Together with the parameter schema on metadata, this is what lets a caller hand work to the skill and know what comes back.
A skill is not an executable. It is a reusable description the Composer assembles into a concrete turn at runtime.
Canonical authoring format
Section titled “Canonical authoring format”Markdown with YAML frontmatter is the canonical format for authoring, sharing, and transporting skills. The SQLite record (see Skill Storage) is a cache and index derived from this source — not the source itself.
A skill file is a single .md file. The frontmatter declares the skill’s identity and contract:
---name: draft-scene-outlinedescription: Produces a beat-by-beat scene outline for a given narrative context.version: 1.0.0author: overlund-medialicense: MITrequired_scopes: - read:pages - write:candidatesallowed_roles: - worldbuilderinput_schema: scene_context: string tone: stringoutput_schema: outline: string---The markdown body holds the prompt framing and any structured sections the Skill Composer consumes — approach narrative, examples, template blocks. The body is authored prose with section headings; it is not a programming language. Body-section conventions are pinned by ADR (see Skill Storage).
Import and export are lossless round-trips: importing a .md file parses frontmatter and body into the SQLite cache; exporting a SQLite record reconstructs the original .md. Distribution — personal export, marketplace publishing, workspace sharing — travels as .md files (or tarballs of them). There is no separate .json manifest or multi-file bundle.
The in-app editor writes through the same SQLite record; the round-trip guarantee means any in-app edit can be exported back to canonical .md at any time.
Runtime composition, not compilation
Section titled “Runtime composition, not compilation”Earlier framings treated a skill as a compiled artifact — a DSPy module trained on examples, producing a state blob that the sidecar loaded and ran. That framing is fully retired (decision D5). A skill is not a DSPy-compiled artifact; there is no skill-compilation pipeline, no optimizer, no trained module, no state blob, no fallback path to a compiled mode. DSPy’s current role in the project is as the LLM programming layer inside sidecar nodes — see LLM System and ADR-022 — which is an unrelated concern.
Instead: when the World Agent decides to apply a skill, the Skill Composer subagent reads the skill package, the current user request, and the available tool surface, and composes the turn’s prompt and subgraph shape on the spot. The composed shape is ephemeral — it lives for the duration of the turn. The skill package, not a compiled version of it, is the durable artifact.
The trade-offs:
- A skill’s definition can be edited directly; the next invocation reflects the edit immediately. No rebuild step.
- Changing model, provider, or available tools does not require recompiling any skill.
- A skill is readable as prose by the author, not opaque as a serialized module.
- Each invocation pays the composition cost — one Skill Composer subagent call. In practice this is small relative to the invocation itself.
See Skill Composer for the composition algorithm and I/O contract.
The Skill Composer subagent
Section titled “The Skill Composer subagent”The Skill Composer is a specialized LangGraph subagent running in the Python sidecar. It is dispatched from the main graph the same way any other subagent is dispatched (see Agent Core System); there is nothing privileged about its mechanics.
When the planner decides to apply skill S to the current request, it hands the Composer:
- The skill package (metadata, framing, artifacts, tool surface, contract).
- The current user request and relevant context pulled from the four-tier Agent Memory System.
- The caller’s resolved capability set and the available tool surface.
The Composer returns:
- A concrete prompt tailored to this invocation.
- A subgraph shape — which tools are expected, what sequencing is likely, where interrupts may fire, what the exit condition is.
The main graph then runs that shape as a subgraph on the same thread_id. State, memory, and the checkpointer are shared with the parent turn.
The Composer does not invent tools the caller doesn’t already hold, does not bypass the submit boundary, and does not produce a persistent artifact. It produces a plan for one invocation.
The Composer itself is authored — its system prompt and behavior live in the sidecar as ordinary code. There is no “Composer-composing-itself” recursion.
Full algorithm, I/O contract, and capability-bounding rules: Skill Composer.
How a skill is invoked
Section titled “How a skill is invoked”A skill is invoked through one of three paths, all of which funnel through the same composition step:
- Explicit worldbuilder request. The worldbuilder asks for a skill by name or description in a conversation. The planner recognizes it and dispatches the Composer.
- Agent-selected. The planner recognizes that an available skill fits the current request and dispatches the Composer without an explicit ask.
- Scheduled. A scheduled task (see Scheduling System) names the skill as the work to perform. On fire, the scheduler hands control to the agent graph, which dispatches the Composer.
In all three, the Composer’s role is the same. The only difference is where the invocation request came from.
A skill cannot be invoked if its permission record (per-workspace; see Skill Storage) disables it, or if the current channel or autonomous-task context is not in the skill’s allowed-contexts list. Permissions are a gate in front of the planner, not a check the skill itself runs.
Skills, tools, and capabilities
Section titled “Skills, tools, and capabilities”A skill is composed of MCP tools; it is not itself an MCP tool to the outside world. The distinction matters.
- A tool is a single operation (read a page, write a candidate, search memory). Tools are exposed over MCP and listed in the caller’s capability set.
- A skill is a named composition of tools under a framing. Skills are not exposed over MCP to other callers; they are invoked through the planner.
A skill’s effective capability set is the intersection of the tools it declares it needs and the capabilities the invoking turn already holds. A skill cannot escalate. If the caller lacks write capability on a channel, a skill dispatched from that turn cannot write to the channel no matter what the skill declares.
See Permission System for capability scoping.
Writes produced by a skill
Section titled “Writes produced by a skill”Content a skill writes during execution is ordinary agent-produced content. It crosses the Submit Boundary with origin: agent-produced and enters as lifecycle: candidate. The author triages those writes the same way they triage any agent-produced content.
A skill cannot produce canonical content on its own. A skill cannot bypass the submit boundary. A skill’s writes are indistinguishable at the boundary from any other agent write — the fact that the agent was running a skill when it wrote is metadata on the invocation, not on the resulting content.
Skill composition (skills calling skills)
Section titled “Skill composition (skills calling skills)”A skill’s subgraph may dispatch another skill. When the Composer produces a shape that includes a sub-skill call, the runtime treats it as ordinary subagent dispatch — a nested Composer call for the sub-skill, followed by a subgraph run.
This composition is not hidden. A skill that declares it may invoke another skill lists that sub-skill alongside its tools in the package. The author reading the parent skill sees the sub-skills it uses; following the reference opens the sub-skill’s package.
A nested sub-skill invocation is capability-bounded by the top-level caller’s capability set, not by the parent skill’s declared tool surface. The tool surface declares intent; the capability check is always against the caller.
What a skill is not
Section titled “What a skill is not”- Not a compiled module. No serialized artifact, no trained weights, no state blob, no “fall back to compiled” path.
- Not an optimizer. The Composer composes from authored content. There is no gradient tuning, no example-based compilation, no trainer.
- Not a process. A skill’s execution is a subgraph in the sidecar, not a spawned OS process.
- Not ambient. A skill that has not been installed and enabled in the workspace cannot be invoked. The agent does not have unnamed skills it applies silently.
- Not world content. Skills do not carry
origin,lifecycle, derivation, or deviation. Skill CRUD does not cross the submit boundary. - Not agent memory. Skills are not part of the four-tier memory system. A skill reads memory through the same MCP memory tools any turn uses.
- Not a provider abstraction. A skill’s composed turn uses the LLM System through whichever model the planner selects. A skill package can declare preferred model variants; it does not ship with a provider.
The skill surface in the product
Section titled “The skill surface in the product”From the author’s point of view, the skill surface supports a small number of actions:
- Install / import. Bring a skill into the workspace from a
.mdfile, from another workspace, or (marketplace browsing and publishing are not implemented; themarketplacesource value is reserved). Import is an acknowledged source-trust action with a capability preview; it is not gated by the submit boundary. Detail: Skill Storage. - Edit. Change the framing, artifacts, tool surface, or contract of a skill. An edit takes effect on the next invocation. No rebuild.
- Enable / disable. Per-workspace toggle, independent of whether the skill package remains installed.
- Scope. Choose which channels and which autonomous-task contexts a skill is invokable in. Stored in
skill_permissions; syncs across the author’s devices. - Invoke. Ask for a skill by name in a conversation, or let the planner select one.
- Observe. Read the planner’s record of which skill was invoked, when, and with what outcome. The subsystem records per-invocation metadata (skill id, used artifacts, success/failure) alongside the turn record. Detailed per-artifact trace logging is not implemented.
The author does not see a “submit skill” or “canonicalize skill” affordance. Those belong to world-model claims and do not apply here.
A workspace’s skill set — including bundled, user-authored, and imported skills — syncs across the author’s devices for that workspace. skill_permissions rows sync alongside the skills, so a skill’s invocability in a given channel or autonomous-task context is consistent across devices.
The sync is last-writer-wins by updated_at, the same conflict resolution used for other sync’d workspace tables. There is no owner-only or authored-by-user restriction on the sync scope — any skill present in the workspace on one device is expected on the author’s other devices for the same workspace.
Whether skills also follow the author across workspaces (so installing a skill in workspace A makes it available when opening workspace B) is a separate question, deferred to Skill Storage.
Marketplace
Section titled “Marketplace”Marketplace browsing and publishing are not implemented. The marketplace source value is reserved in the schema and the transport format’s frontmatter; the skill CRUD paths treat it like any other imported skill. There is no marketplace UI, no marketplace API, and no marketplace-specific install path at this time.
Relationship to other systems
Section titled “Relationship to other systems”- Agent Core System — skills run as subgraphs dispatched by the main graph; the Composer is itself a subagent subgraph.
- Skill Composer — composition algorithm and I/O contract.
- Skill Storage — entity shape, schema, permissions, sync, import/export.
- MCP System — the tools a skill uses are ordinary MCP tools; the Composer’s skill-management tools (
create_skill,update_skill,list_skills,add_artifact) are exposed back to the sidecar over MCP. - LLM System — a skill’s composed turn uses model access through this system.
- Agent Memory System — a skill reads memory the same way any turn does; it has no memory tier of its own.
- Scheduling System — skills can be invoked as scheduled work.
- Permission System — a skill’s effective capability set is bounded by the invoking caller.
- Submit Boundary — skill CRUD does not cross this boundary; writes produced by a skill do.
What this page does not do
Section titled “What this page does not do”- It does not describe the composition algorithm. See Skill Composer.
- It does not describe storage schema, permissions schema, or sync mechanics. See Skill Storage.
- It does not describe the authoring UI for skill packages. That is a frontend concern.
- It does not describe how skills are searched or recommended for invocation. See MCP System for the skill-search tool and the planner’s dispatch logic.
- It does not describe subagent dispatch mechanics. See Agent Core System.
Was this page helpful?
Thanks for your feedback!