Skip to content

docs(adr): 0005 — Skill contract (v1)#273

Open
EmersonBraun wants to merge 1 commit intomainfrom
foundation/adr-0005-skill
Open

docs(adr): 0005 — Skill contract (v1)#273
EmersonBraun wants to merge 1 commit intomainfrom
foundation/adr-0005-skill

Conversation

@EmersonBraun
Copy link
Copy Markdown
Owner

Summary

Fifth ADR of Phase 0 — formalizes Skill as pure declarative configuration: a system prompt + optional examples + tools/delegates by name reference. 12 invariants (S1-S12).

Builds on #267 (Adapter), #270 (Tool), #271 (Memory), #272 (Retriever).

Merge order: #267#270#271#272#273 (rebase each on main as merged; conflicts only on the ADR README index).

The load-bearing distinction

A tool is a function the model calls. A skill is a persona the model becomes.

Confusing them is the recurring failure mode in agent libraries (LangChain's "agents" half-conflate them). This contract makes the distinction explicit through three invariants:

  • S10 No execute, no return value — skills are activated, not invoked
  • S11 Pure declaration, no I/O at definition — skills are data, not code
  • S5 Tools by reference, not inline — skills compose with whatever registry exists

Highlight invariants

  • S1 Name is identity — same regex as Tool T1, shared registry namespace by convention
  • S3 systemPrompt is the soul — required, non-empty; everything else supports it
  • S4 Examples are few-shot, not test cases — single-turn pairs in v1
  • S5 Tools by reference (array of names) — runtime resolves at activation
  • S6 Delegates by reference — same shape, scales to multi-agent topologies
  • S7 Cycles are runtime concerns — contract permits, runtime detects/terminates
  • S9 onActivate is for dynamic tools only — narrow escape hatch for per-user/tenant credentials
  • S10 No skill.run() — distinguishes skill from tool absolutely

Trade-offs accepted

  • No multi-turn examples in v1 (encode in prompt prose for now; v2 may extend)
  • onActivate is the only function in an otherwise pure-data contract — accepted because per-user dynamic tools are real
  • Tools by reference creates a registry dependency — correct trade for shareability
  • No per-skill versioning in contract — metadata.version is convention; manifest spec ([F3] #69 — Skill marketplace with versioning #182) will formalize

Unlocks

Test plan

  • Doc renders on GitHub
  • ADR index updated
  • No code changes — pure documentation
  • Reviewer: 12 invariants match packages/skills/src/* (researcher, critic, summarizer, coder, planner)?
  • Reviewer: does the "skill ≠ tool" distinction land cleanly?
  • Reviewer: is onActivate the right escape hatch shape?

Refs #214 #211

Formalizes Skill as pure declarative configuration — system prompt,
optional examples, tools/delegates by name reference, light config.
12 invariants (S1-S12).

Key decisions:
- A skill is what the model BECOMES, not what it CALLS (vs Tool)
- Pure declaration enables marketplace, sharing, agent-generated skills
- Tools by reference (not inline) enables reuse and composition
- Delegates by reference scales to multi-agent topologies (#157)
- No skill.run() — runtime activates, no method to implement
- onActivate is the narrow escape hatch for dynamic per-user/tenant tools

Confusing skills with tools is the recurring failure mode in agent
libraries (LangChain's 'agents' do this). This contract makes the
distinction load-bearing.

Unblocks:
- Skill marketplace (#181) — JSON-serializable, versionable
- Multi-agent topologies (#157) — supervisor/swarm/hierarchical via delegates
- Skill manifest spec MCP-aligned (#182) — at most a few standardized metadata keys
- agentskit ai (#144) — agents generating skills emit pure JSON

Refs #214
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant