Table of Contents generated with DocToc

RFC-AI-0006: Trusted external skill sources

Abstract

Every Magpie skill ships in one repository — apache/magpie — and reaches adopters through one mechanism: the setup skill downloads the whole framework into a gitignored snapshot, pins it in a committed lock, and symlinks the selected skills into agent dirs. There is no way to pull an individual skill or skill-family from a different repository or organization. The “External (another repo)” home in docs/extending.md exists only as a “vendor it in by hand” note, and PRINCIPLES.md §13 forbade installation from anything but the one framework snapshot.

This RFC introduces trusted external skill sources: a “redirect” pointer where a skill directory would sit, naming a remote source (a GitHub folder, an SVN/dist archive, or a git tag/branch) from which the skill and all its related files — including evals and tests — are fetched, pinned, verified, and wired in so the skill behaves identically to an in-tree one. It amends §13 to permit installation from a trusted source — one the adopter has explicitly vouched for — while keeping the snapshot-plus-pin discipline, and adds a per-organization curation layer so the owning repository/organization of every source is explicit.

Status of this document

Proposed. The design lands in phases: Phase A — this RFC, the §13 amendment, the descriptor/pointer formats under docs/skill-sources/, the org/project skill-sources.md files, and skill-and-tool-validator support — is the review checkpoint. Phase B — the setup-skill fetch/lock/symlink wiring (.apache-magpie.sources.lock, /magpie-setup skill-sources, and the adopt/upgrade/verify integration) plus a worked example — follows.

Motivation

The framework is deliberately one skill-authorship boundary (§14) with one distribution channel. That is right for the core, but it blocks three real needs already visible in the extension model:

  1. Sub-project and podling skills. An ASF sub-project or incubating podling may maintain skills specific to itself that should not live in apache/magpie yet still be adoptable by its own repos with the same ergonomics as a framework skill.
  2. Organization-private skills. A company or collective running Magpie across many repos wants to maintain a shared skill-family in one place and pull it into each repo — without vendoring copies or a submodule.
  3. Community skills. A third party maintains a useful skill-family and others want to adopt it deliberately, pinned and verified, not by copy-paste.

Today all three fall back to “clone it in by hand” — unpinned, unverified, and invisible to drift detection, verify, and the eval discipline. The machinery to do this properly already exists for the framework itself: a verified fetch (git tag/branch, or svn-zip with SHA-512 + GPG), a committed pin, a two-lock drift model, and the canonical-plus-relay symlink wiring. This RFC generalizes that machinery from one source to N named trusted sources.

The one blocker is principle, not plumbing: §13 said catalogs are “for discovery, never for installation.” This RFC narrows that to “never for untrusted installation” — an adopter-vouched, pinned, verified source is as safe to install as the framework snapshot, because it is the same mechanism.

Proposal

The three-layer trust model

Trust is layered so an organization can curate candidates while the adopter keeps the final say. Nothing is fetched until the adopter opts in.

LayerFileHomeRole
Discoverydocs/skill-sources/registry.mdin-treeEditorial index of known sources. Lists, never installs.
Org-curatedorganizations/<org>/skill-sources.mdin-tree / adopter-local org overrideAn org vouches for candidate sources its projects may adopt.
Adopter opt-in<project-config>/skill-sources.mdcommitted in the adopter repoThe install gate. Lists the trusted source ids and commits each pin. Only sources here are fetched.

This mirrors the existing project → organization → framework precedence (AGENTS.md): an org curates a default set; the adopter overrides — trusting a source the org did not curate, or declining one it did.

Source descriptor

A descriptor identifies one source and enumerates what it provides, reusing the install-method and lock vocabulary the framework snapshot already uses:

id: <source-id>                 # unique, kebab-case
organization: <org>             # owning org; must name a directory under organizations/
name: "<human-readable name>"
maintainer: "<who>"
method: <git-tag | git-branch | svn-zip>
url: <repo or archive URL>
ref: <tag | branch | version>
# verification anchor: commit (git-tag) | sha512 (svn-zip)
layout:
  skills_root: skills
  evals_root: tools/skill-evals/evals
provides:
  - skill: <name>
  - family: <prefix>-*

Pointer file — the redirect

Where a skill directory would sit, skills/<name>/source.md names the source. It is the “redirect link”; the skill body, evals, and tests are fetched into the gitignored snapshot, not committed here. It is named source.mdnot SKILL.md — so the validator's SKILL.md-gated checks (required frontmatter, name convention, injection guard) do not fire on a stub. Its frontmatter uses source: (already an allowed optional key) plus organization:, skill_path:, and evals_path:. Full format in docs/skill-sources/README.md.

Fetch, verify, pin

/magpie-setup skill-sources (and the source pass folded into adoption) reads <project-config>/skill-sources.md, then for each trusted source fetches into .apache-magpie-sources/<source-id>/ (gitignored) reusing the framework install recipes verbatim — git clone --depth=1 --branch <ref> for git methods, download + sha512sum -c + optional gpg --verify for svn-zip. Two locks record the result, exactly as for the framework snapshot:

  • .apache-magpie.sources.lock (committed) — per-source pin (method/url/ref + commit|sha512), keyed by id.
  • .apache-magpie.sources.local.lock (gitignored) — per-source fetch fingerprint (source_*, fetched_commit, fetched_at).

Drift detection, upgrade, and verify extend to these locks with the same logic already used for the framework snapshot.

Symlink and eval binding

For each provided skill, the canonical + relay symlinks are created exactly as for framework skills — .agents/skills/magpie-<name>../../.apache-magpie-sources/<id>/skills/<name>/, with per-agent relays back through the canonical entry (symlink-lint‘s no-cycles + relay-through-canonical invariants hold unchanged). Because a fetch pulls both the skills/ tree and the tools/skill-evals/evals/ tree, the eval suite’s directory-name + skill_md:-path binding resolves after the fetch, so a pulled skill is eval-able and testable exactly as in its home repo. The one requirement on a source repo is the two-tree layout, declared in the descriptor's layout: block.

Amending PRINCIPLES §13

§13's final sentence changes from “catalogs may exist for discovery, never for installation” to: catalogs exist for discovery, and installation is permitted only from a trusted source — an external org/repo the adopter has vouched for by committing its pin — under the same snapshot-plus-pin discipline (gitignored snapshot, committed lock, verified deliberate fetch, no submodules, no unpinned/unverified auto-fetch). Untrusted external sources and the adapter/organization indexes stay discovery-only.

Security model

  • Adopter-vouched, always. The <project-config>/skill-sources.md trust list is the sole authorization to fetch. Org curation and registry listing are editorial; neither triggers an install. This keeps the supply-chain decision with the party that bears the risk.
  • Pinned + verified. Every trusted source carries a verification anchor (commit for git-tag, sha512 for svn-zip). git-branch (tip-tracking, no anchor) is WIP-only, exactly as for the framework snapshot. A changed sha512 under the same version, or a branch tip that moved unexpectedly, is surfaced by drift detection — the same guard the framework snapshot already gets.
  • Blast radius is a fetched skill. A compromised source can, at worst, ship a malicious skill body — the same risk as a malicious framework skill, and mitigated the same way: skills are agent-readable markdown reviewed before they run, and the injection-guard discipline (§0) treats external content as data. A source cannot reach outside its own gitignored snapshot dir or mutate the framework snapshot.
  • Eval provenance. Evals travel with the skill from the same pinned commit, so a source cannot ship a skill whose evals are silently sourced elsewhere.
  • No transitive trust. A trusted source's own skill-sources.md (if any) is not honored — trust does not chain. An adopter trusts exactly the sources it lists, never a source-of-sources.

Drawbacks

  • A second install surface. More than one snapshot dir and lock pair to reason about, verify, and keep un-drifted. Mitigated by reusing the exact framework machinery rather than a parallel one.
  • Principle relaxation. §13 was a bright line (“never for installation”); this adds a conditional. The condition (adopter-vouched + pinned + verified) is deliberately the same bar the framework already meets, so the line moves from “one source” to “one kind of source.”
  • Layout coupling. A source must keep the framework's two-tree layout for evals to bind. Declared explicitly in layout: rather than assumed.

Alternatives considered

  • Git submodules. Rejected by §13 and the existing snapshot model — submodules are unverified, awkward under the gitignored-snapshot discipline, and pull whole repos rather than selected skills.
  • A marketplace / package manager with a resolver. Far more surface than the need; contradicts the “index for discovery, not a package manager” stance. The adopter-committed pin is the resolver.
  • Vendoring copies into the adopter repo. The status quo fallback — unpinned, invisible to drift/verify/eval, and forbidden for framework skills by §13. This RFC exists to replace it.
  • Per-skill pointer only, no per-source manifest. Insufficient for family-level pulls (<prefix>-*) and gives no single place to declare the source's identity, org, and verification anchor.

Out of scope

  • A hosted marketplace or web UI for browsing sources.
  • Transitive sources (a trusted source declaring further sources).
  • Auto-update of a source without an explicit upgrade.
  • Non-git/SVN transports beyond the three existing install methods.
  • Sourcing tool adapters or organizations externally as an install (they remain discovery-only; see docs/adapters/registry.md).

References