Skip to content

docs(adr): 0002 — Tool contract (v1)#270

Merged
EmersonBraun merged 1 commit intomainfrom
foundation/adr-0002-tool
Apr 14, 2026
Merged

docs(adr): 0002 — Tool contract (v1)#270
EmersonBraun merged 1 commit intomainfrom
foundation/adr-0002-tool

Conversation

@EmersonBraun
Copy link
Copy Markdown
Owner

Summary

Second ADR of Phase 0 — formalizes the Tool contract implicit in packages/core/src/types/tool.ts and packages/tools/src/*.

Builds on ADR 0001 (Adapter).

What's included

  • docs/architecture/adrs/0002-tool-contract.md — 3 core types, 12 invariants (T1-T12), stability tier stable, rationale, trade-offs, alternatives considered, open questions.
  • ADR index updated.

Why now

Before Fase 3 adds dozens of tools (GitHub, Linear, Slack, Google Workspace, Stripe, Supabase, browser, etc.) and before the MCP bridge (#167) publishes/consumes tools across ecosystems, we need a contract that:

Key invariants (the important ones)

  • T1 Name is identity — strict regex, unique within registry
  • T2 Schema is the contract — JSON Schema 7, authoritative for inputs
  • T3 Validate at boundary — runtime validates before calling execute
  • T4 Execute optional — declaration-only tools are first-class (MCP-friendly)
  • T6 AsyncIterable streaming — mirrors Adapter contract for progressive tools
  • T9 Confirmation explicit — no timeout auto-approve; security-critical
  • T10 No side effects at definition time — enables static discovery and tree-shaking

Trade-offs made explicit

  • JSON-only arguments (T5) — Buffer/Date must be serialized; matches wire format
  • No per-invocation auth in v1 — deferred to future ADR if strong case emerges
  • Typed return values via generics deferred — a future ADR will add ToolDefinition<TArgs, TResult>

Unlocks

Test plan

  • Doc renders on GitHub
  • ADR index updated
  • No code changes — pure documentation
  • Reviewer: T1-T12 match current tools in packages/tools/src/?
  • Reviewer: any invariant that blocks a real use case?

Refs #214 #211

Formalizes the Tool contract. Defines 12 invariants (T1-T12) covering
identity, schema validation, execution, lifecycle, and streaming:

- Name is identity (T1) with strict regex
- JSON Schema 7 as the authoritative arg description (T2)
- Validation at the boundary before execute (T3)
- Execute-optional (T4) enables MCP bridge and delegated tools
- JSON-serializable output (T5) matches the wire format
- Streaming via AsyncIterable mirrors Adapter (T6)
- Idempotent init (T7), best-effort dispose (T8)
- Explicit confirmation gate, no auto-approve timeout (T9)
- Pure definitions, no side effects at construction (T10)
- Error-as-status, throwing only for bugs (T11)

Also updates ADR index (0001 + 0002 accepted).

Builds on ADR 0001 (Adapter). Together they unblock the MCP bridge
(#167), schema-to-type inference (#130), human-in-the-loop (#158),
and the tool sandbox (#163).

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