Attaching and loading skills 

The partial support badge 

Each skill carries a support badge:

full
The skill is plain front-matter and prose.
partial
The body or front-matter references scripts, references/, assets/ or an allowed-tools declaration.

See ADR-035 for the full design and security rationale.

Whether a skill works on a page 

The frontmatter key page tells a consumer of the skill, such as the backend chat of nr_mcp_agent, whether a conversation with the skill needs a page:

page: required
The skill works on one page and needs it. The chat asks for a page and keeps it.
page: optional
The skill may work on a page: the page the editor shows is passed along when there is one.
page: none
The skill does not work on a page. The chat neither asks for one nor passes one along.
---
name: Write a news article
description: Drafts a news article from a few key points.
page: none
---
Copied!

A skill without the key, or with any other value, declares nothing and keeps the behaviour it had before the key existed: a process skill behaves as required, every other skill as optional. The value is read without regard to case.

The key is not part of the skill's version (ADR-229). It decides no trust and no tool, so a change of it alone neither disables an enabled skill nor invalidates its approvals, and it is not shown in the approval form's diff. A synced skill shows it read-only as Works on a page; a skill written in the backend sets it there.

Attaching skills and injecting them into prompts 

Enabled, non-orphaned skills can be attached to a Task and/or an LLM configuration via the Skills field on those records (only enabled skills are offered). At execution time, for text-generation operations only — completion, translation and task execution; never embeddings, vision or speech — nr-llm composes unapproved attached skills into a delimited block and prepends it to the user prompt. Approved instruction versions use the system-message channel described below; the stored configuration system_prompt is never modified.

A configuration has two skill fields:

  • Skills loaded on demand. An agent run lists the attached skills whose current version is approved as an instruction (and which are not process skills) by uid, name and description in the description of the builtin tool load_skill. When the task matches, the model loads one: its section joins the run's system message before the next call, the tool result confirms the load without the body, and loading the same version again appends nothing. The load re-checks the attachment, the record and the approval at that moment, and refuses a section that would leave less than 10 % of the model's context budget. A skill attached here that is not approved is neither listed nor composed. Tasks, translation and the other one-shot paths never load on demand. A process skill is attached here and is started by invocation only, for example from the chat's slash-command menu; the model never loads it.
  • Skills loaded always. Composed into every run, as described below. Every attachment that existed before the load modes is one of these. Process skills cannot be attached here.

Both fields grant the skills' declared tools (allowed-tools) from the start of a run; loading a skill grants nothing.

Composition rules:

  • Precedence. Configuration skills are the baseline, task skills are additive; the set is the union deduped by source + identifier (the configuration wins on a duplicate). The configuration block renders first.
  • Budget. The untrusted user-message block is bounded by a byte budget; when it is exceeded, task-additive skills are dropped before configuration-baseline skills and each drop is logged. Approved instruction sections are kept in full and count toward the context-window estimate. A request that does not fit even then is still sent, with a logged warning: the chat path first drops older turns, the completion path sends the prompt unchanged. No instruction section is dropped to make it fit.
  • Integrity. Each skill's version digest — over the body and the frontmatter fields the model reads — is recomputed from the stored fields at injection time; a mismatch (tampering or a stale row) drops that skill — it is never injected. A row synced before the digest existed is checked against its body checksum until the upgrade wizard or a sync writes its digest. Name, description and body are therefore read-only in FormEngine.
  • Process skills. A skill whose frontmatter sets process: true is never composed from an attachment; it is skipped with a warning. A run that invokes it composes its approved version as a system-message section of its own, Active process, ahead of the approved skills. The process governs the order of steps and the structure of answers; the approved skills keep applying to wording, terminology and safety (ADR-214).
  • Untrusted output. Skill prose is third-party text; output produced under its influence is treated as untrusted and escaped/sanitized where it is stored or rendered. Message role is defense-in-depth, not a trust boundary.

See ADR-036 for the injection design.