Managing skills 

Skills are GitHub-hosted SKILL.md files — a YAML front-matter block with a name and description plus a markdown body — that nr-llm can ingest, review, and (from Plan 1b) inject into prompts. You add a skill source that points at GitHub, sync it, and then enable the individual skills you want.

Skill management is admin-only. It lives in Admin Tools > LLM > Skills and is not delegated to other backend groups: a skill body becomes prompt context, so the two skill tables are treated as a privilege-escalation surface.

Source types 

A source has one of three types:

single_file
One SKILL.md at a fixed path in a repository. A single, explicit admin act — its skill may default to enabled.
repo
A whole repository. Every SKILL.md under the repo root, skills/<name>/, .claude/skills/<name>/ or <plugin>/skills/<name>/ is discovered. Discovered skills arrive disabled for review.
marketplace
An Anthropic marketplace.json index that lists plugins pointing at further repositories. Each entry is expanded with the repo flow. All discovered skills arrive disabled.

Adding a source 

  1. Navigate to Admin Tools > LLM > Skills.
  2. Click New Skill Source.
  3. Fill in the fields:

    Title
    Display name for the source list.
    Type
    single_file, repo or marketplace (see above).
    URL
    The GitHub URL the type expects (the SKILL.md URL, the repository URL, or the marketplace.json URL).
    Ref
    A branch or tag (for example main or v1.2.0). It is resolved once to an immutable commit SHA at sync time; all bodies are then fetched by that SHA, never by the moving branch.
  4. Click Save.

The pinned_sha, sync_status, sync_error and last_synced fields are managed by the sync run and shown read-only.

GitHub token and rate limits 

Unauthenticated GitHub API access is limited to 60 requests per hour, which is quickly exhausted by a repo or marketplace sync. Add a personal access token (a read-only, public-repo token is enough) to raise the limit and to read private repositories.

  • The token is set through the Set token action on a source, not typed into a FormEngine field. It is stored as an nr-vault UUID (envelope-encrypted), mirroring provider API-key storage — never as plaintext in TCA, YAML or the database.
  • When a sync hits the rate limit (HTTP 403 with no remaining quota), the source is set to sync_status = error carrying the reset time; state is not partially corrupted. Add a token and re-sync.

Host-allowlist prerequisite 

nr-llm enforces an app-level GitHub allowlist on every skill request: the scheme must be https and the host must be one of github.com, raw.githubusercontent.com, api.github.com or codeload.github.com. This is separate from, and in addition to, the nr-vault SSRF guard.

On hardened instances that restrict outbound HTTP through the global HTTP/allowed_hosts SSRF setting, those four GitHub hosts must be on that list, otherwise every sync fails closed. This is a deliberate prerequisite — nr-llm never silently bypasses the SSRF guard.

Syncing and the review flow 

  1. On a source, click Sync. The source moves through never_syncedsyncingok / partial / error. The syncing state also acts as a lock: a second concurrent sync on the same source is refused.
  2. partial means the per-sync file-count or wall-time bound was reached (large marketplaces); the skills fetched so far are stored.
  3. Discovered skills from repo and marketplace sources are created disabled by default. Review each one, then toggle it on with Enable.
  4. Re-sync never silently changes an enabled skill. If a re-sync recomputes a different body_checksum for an enabled skill, nr-llm auto-disables it and surfaces a diff (Review changes) so you re-confirm before it is used again. Accepting the diff re-pins the SHA atomically.
  5. A skill that disappeared upstream is marked orphaned and disabled, never silently dropped, so attachments (Plan 1b) do not vanish.

Deleting a source cascade-deletes its 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.

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 the attached skills into a delimited block and prepends it to the user prompt. The configuration system_prompt is never modified.

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 block is bounded by a conservative character budget; when it is exceeded, task-additive skills are dropped before configuration-baseline skills and each drop is logged.
  • Integrity. Each skill's body checksum is re-verified at injection time; a mismatch (tampering or a stale row) drops that skill — it is never injected.
  • 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.