Lifts the 'an agent uses a SKILL.md pack' concept out of a host and into the
harness:
- run.Ports.SkillPacks (SkillPackActivator) — nil-safe port; the executor folds
a loaded agent's pack catalog into the system prompt and adds a skill_use
loader tool to the toolbox (uses the existing ra.SystemPrompt + toolbox seams)
- run.RunnableAgent.SkillPacks + persona.Agent.SkillPacks (+ skill_packs YAML,
extends-inherit, ToRunnable) — the Agent noun is now pack-aware
- skillpack.Activator — the battery's default port impl (resolve names → packs →
catalog + skill_use), with a per-run BundleStager factory the host plumbs;
satisfies the port structurally (no import of run)
- agentbuiltins: ships gifsmith, a portable focused GIF/MP4 render agent that
uses the gif pack — references tool/tier/pack NAMES only, no host coupling
A host now wires run.Ports.SkillPacks instead of carrying its own activation
glue. Tests: Activator resolution + gifsmith loads through persona→RunnableAgent.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Replace Activate's stagedDir string with a BundleStager callback invoked
lazily inside skill_use: when the model loads a pack with bundled files, the
host stages them (mort: into run-scoped file storage) and the returned note is
appended to the body so the model knows how to reach them. A nil stager (or a
stager error) degrades gracefully to just listing the file names.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Real issues from the PR review:
- security: readTree now skips symlinks (a pack with SKILL.md -> /etc/passwd
or scripts/x -> ../../.ssh/id_rsa could read host files); covers file and
dir symlinks, incl. within a git subpath
- security: GitSource rejects url/ref beginning with '-' (git arg injection)
and clones with '--' separator; --filter=blob:none (blobless partial clone)
instead of full-history clone
- correctness: Subscribe no longer swallows a non-ErrNotFound store error from
GetByName (would create a duplicate subscription); handles *GitSource as well
as GitSource in the URL/subpath extraction
- correctness: pinTo no longer renames a subscription, so Apply can't silently
collide two subscriptions when an upstream pack changes its name
- validation: isKebab rejects leading/trailing/consecutive hyphens; BOM-
prefixed SKILL.md now parses (matches the doc comment)
- robustness: Catalog/Activate/renderPackBody/Stage guard nil/malformed packs
- test cleanup: Syncer.Store field renamed Cache (collided with the Store
interface); test NewID returns distinct ids
- tests: symlink-skip, BOM, strict-kebab, nil-pack-safety
Deferred (advisory perf, documented): PackCache stores raw trees so activation
re-parses; CheckAll is serial. Both fine at expected scale.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
New additive, nil-safe battery for subscribing to skill packages in the
Anthropic agent-skills format (SKILL.md manifest + bundled files):
- Manifest/ParseManifest: SKILL.md frontmatter+body parse & validation
(name/description required, allowed-tools passthrough, kebab/length limits)
- Tree/Pack/LoadPack: self-contained file set, order-independent content
digest (the pin identity + change signal), bundled-file listing, traversal-
safe staging
- Source (DirSource, GitSource): Fetch returns tree + resolved ref; git clones
to temp, reads subpath into memory, cleans up (self-contained tree)
- Subscription + Store + content-addressed PackCache, with Memory defaults
- Syncer: Subscribe pins; Check records a PENDING update but never moves the
pin; Apply is the only re-pin (supply-chain guard — upstream can't silently
change what an agent runs)
- Activate: resolved packs -> majordomo agent.Skill (catalog instructions +
one skill_use tool) for progressive disclosure; Stage materializes files
Third distinct 'skill' concept, deliberately separate from executus/skill
(saved-agent noun) and majordomo/skill (eager capability bundle). Mort-side
wiring (convars, .skillpack commands, Agent.SkillPacks, allowed-tools shim)
is a later, separate step. Full unit + hermetic local-git tests; gofmt/vet
clean; race-tested.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>