Files
msd-core/gsd-core/references/agent-skills-bootstrap.md
Tom Boucher 3c13903dcd feat(#1866): agent-side self-load of configured agent_skills
Each of the 22 consumer agents now self-loads its configured agent_skills
in its mandatory init step, so .planning/config.json agent_skills.<type>
reaches the agent on every runtime — including Cursor and /gsd-autonomous,
where Skill()-delegated workflow bash init did not reliably execute.

- gsd-core/references/agent-skills-bootstrap.md: shared contract
  (query + Read + dedup guard that skips when <agent_skills> is already
  in the prompt, so Claude's orchestrator-side injection never doubles)
- 22 agents/gsd-*.md: one self-load line naming the agent's own type
- gsd-core/workflows/autonomous.md: note that delegated agents self-load
- tests/agent-skills-bootstrap.test.cjs: regression + parity (CONSUMER_AGENTS
  bijection + fast-check property) — Generative-Fix-Divergence guard
- docs: ADR-1866, CONFIGURATION dual-injection How It Works, INVENTORY
  row, Changed changeset

Closes #1866
2026-07-01 20:09:01 -04:00

3.2 KiB

Agent Skills Self-Load (Bootstrap)

Shared contract. Every agent_skills consumer agent self-loads its configured skills in its mandatory init step, so a project's .planning/config.json agent_skills.<agent-type> mapping reaches the agent that actually does the work — even when the orchestrator did not run bash init (e.g. a runtime whose Skill() delegation does not reliably execute the delegated workflow's bash, such as Cursor; see open-gsd/gsd-core#1600 / #1601). This is the durable counterpart to the orchestrator-side injection documented under Agent Skills Injection.

When to run

In your mandatory init step — right after mandatory-initial-read.md / the Project skills discovery, before any other work.

Steps

  1. Dedup guard (MANDATORY). Look at your own prompt. If it already contains an <agent_skills> block, the orchestrator already injected one — skip self-load entirely. Loading a second copy wastes context on runtimes where orchestrator-side injection also runs (e.g. Claude Code). The guard is what keeps the two seams from doubling the block.

  2. Query your configured skills. Use your own agent type — the name: value in your frontmatter (e.g. an agent whose frontmatter says name: gsd-executor queries gsd-executor). The query is read-only and idempotent — it exits 0 with an empty block when nothing is configured for your type:

    _AGENT_SKILLS=$(gsd_run query agent-skills <YOUR-FRONTMATTER-NAME> 2>/dev/null || true)
    

    The runtime gsd_run resolver is the standard one from _runtime-launcher.snippet.sh; your own init already defines it.

  3. Read every listed skill. The block emits entries as @<path>/SKILL.md includes — Read each one before starting work. If the block is empty, there is nothing to do (zero overhead).

What self-load does and does not cover

Skill form Self-loads? Notes
Project-relative path (skills/my-skill) ✅ everywhere Read the @-include
Global personal (global:<name>) ✅ everywhere resolves to the runtime global skills dir, then Read
Plugin-provided (global:<plugin>:<skill>) Claude only emitted as a Skill-tool directive on Claude; skipped with a warning on all other runtimes — the plugin/Skill-tool model has no equivalent elsewhere (#1601, #1258). Not closeable on Cursor.

Notes

  • Idempotent and read-only. query agent-skills never mutates state; calling it twice (once by the orchestrator, once by the agent) is harmless because the dedup guard suppresses the second load.
  • No new config keys. This reuses the existing agent_skills map and the existing buildAgentSkillsBlock / cmdAgentSkills machinery (src/init.cts). The 22 consumer agent types are mirrored in tests/agent-skills.test.cjs (CONSUMER_AGENTS) and guarded against drift by tests/agent-skills-bootstrap.test.cjs.
  • Checkers / read-only agents. Bash is universal across consumer agents, so self-load works for plan-checkers, verifiers, and auditors too; the bootstrap assumes no tool an agent lacks.