# ADR-0001: Package layout — canonical types in a leaf `llm` package, root re-exports **Status:** Accepted — 2026-06-10 ## Context Provider implementations (openai, anthropic, google, ollama/foreman) must share the canonical types (Message, Request, Response, Capabilities, Model, Provider). If those types lived in the root `majordomo` package, the root could not also register built-in providers (root → provider/openai → root is an import cycle). go-llm solved this with a `v2/provider` leaf package; the kickoff sketch puts the Provider interface in `provider/provider.go` and the message types at root, which recreates the cycle. ## Decision - All canonical contract types live in the leaf package `majordomo/llm` (Message, Part, Request, Response, Option, Tool, Toolbox, Capabilities, Stream, Model, Provider, error classification). It imports nothing else in the module. - The root `majordomo` package re-exports every canonical type via type aliases (plus constructor/option wrappers), so consumers write `majordomo.Request`, `majordomo.UserText(...)` and rarely import `llm`. - The root owns assembly: Registry, Parse, env-DSN loading, the chain executor, and (from Phase 3) registration of real provider clients. - The planned `resolve/` package is folded into the root: the grammar needs registry state (aliases, providers, env fallback) at every expansion step, and a callback interface between two packages bought nothing but indirection. - `health/`, `media/`, `provider//`, `provider/fake/`, `agent/`, and `skill/` are subpackages importing `llm` (and never each other, except agent → skill). ## Consequences - No import cycles; new providers are additive subpackages. - Consumers get the flat one-import API the kickoff sketches. - Type aliases (not wrappers) mean zero conversion cost and full interchangeability between `majordomo.X` and `llm.X`. ## Alternatives considered - **Everything in root.** No cycles only if providers also live in root — a single giant package. Rejected. - **Self-registering providers via package init() side effects.** Hides wiring, breaks multi-registry isolation, surprises tests. Rejected.