Feature request: declarative `requires:` and `skill-allowlist:` so subagents can lazy-load only the skills they need

Resolved 💬 2 comments Opened May 4, 2026 by devotox Closed Jun 3, 2026

Problem

When the parent session spawns a subagent (Agent tool, agent-team workflows, etc.), the subagent inherits the parent's full skill registry and tool catalog as context, even when the agent definition's Tools: whitelist is narrow.

This eager broadcast is conservative-by-default — the loader assumes any skill might be invoked transitively — but the cost compounds:

  • The skill-list text is on the order of tens of kilobytes (grows with every new skill the user installs)
  • It is injected on every subagent spawn
  • For workflows that fan out into many parallel subagents (multi-agent forge runs, kickoff discovery waves, parallel test/review passes), this dominates the per-spawn token bill

There is no way for an agent or skill author to tell the loader "this agent only uses these skills" or "this skill only invokes these other skills". The system has no declarative dependency surface, so it cannot lazy-load.

Proposed surface

Add two optional frontmatter fields:

  1. Skill frontmatter gains an optional requires: field listing other skills (e.g. /git:create-pr) and tools (e.g. Bash, Read, AskUserQuestion) the skill genuinely invokes.
  2. Agent frontmatter gains an optional skill-allowlist: field listing which skills the agent is permitted to invoke.

Loader behaviour changes:

  • On subagent spawn, inject only skills listed in skill-allowlist. If the field is absent, fall back to the closure of skills the parent context has actually used in this session (or fall back to current behaviour for backward compatibility — see below).
  • On skill invocation, walk the requires: graph to ensure transitively-needed skills are loaded.
  • Skills NOT in the closure are referenced by name only (no body); the agent can request a load on demand via a tool call or implicit trigger.

Why declarative over discovery

A discovery-based alternative — "the loader scans skill bodies for /namespace:name references and builds the graph automatically" — is appealing but fragile:

  • Skills compose dynamically. An AskUserQuestion branch may invoke different skills based on the user's choice; static analysis cannot resolve which are actually reachable.
  • String-grep for /namespace:name produces false positives in prose, examples, and forbidden-pattern tables. A skill that mentions /git:create-pr only to forbid its direct use would still pull it into the closure.
  • Authors lose control over what counts as a dependency.

Declarative requires: is explicit, reviewable, and enforceable by author-side audit tooling (which is how schema fields are typically validated in skill ecosystems already).

Backward compatibility

  • Skills without requires: keep the current eager-broadcast behaviour. No regression.
  • Agents without skill-allowlist: keep the current full-registry behaviour. No regression.
  • Migration is opt-in. High-traffic skills and agents (those that fan out into many subagents) declare first; the long tail follows over time.

Why this is distinct from a memory-injection hook

A separate request (PreMemoryLoad hook) addresses rule dual-injection from worktree symlink resolution. This request addresses skill / tool catalog eager broadcast at subagent spawn. The two share an architectural family — loader-side cost reduction — but the surfaces and fixes are different:

| Dimension | Memory-loader hook | This request |
|---|---|---|
| What is over-injected | Rule files | Skill registry + tool catalog |
| When | Session start + every memory refresh | Every subagent spawn |
| Trigger | Symlink → dual realpath resolution | Conservative "any skill might be needed" default |
| Fix shape | Pre-injection hook + content-hash dedup | Declarative requires: + skill-allowlist: + lazy load |

Filing both separately because the surfaces are distinct.

Acceptance criteria

  1. Skill frontmatter requires: field accepts a list of /namespace:name strings and tool names.
  2. Agent frontmatter skill-allowlist: field accepts a list of /namespace:name strings.
  3. On subagent spawn, the loader injects only skills resolvable from skill-allowlist (transitively closed via requires:).
  4. Absence of either field reproduces today's behaviour.
  5. A subagent attempting to invoke a skill not in its closure receives a clear error or a load-on-demand path (implementation detail).

---

View original on GitHub ↗

This issue has 2 comments on GitHub. Read the full discussion on GitHub ↗