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

61 lines
3.2 KiB
Markdown

# 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](../../docs/CONFIGURATION.md#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:
```bash
_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.