-
Notifications
You must be signed in to change notification settings - Fork 0
Contract Pattern
Every extension category has a typed, versioned contract. This page is the meta-shape — the fields every contract specifies, the rules they follow, and how they interact with core.
Per-category contracts (Providers, Tools, Hooks, UI, Loggers, State Machines, Commands, Session Stores, Context Providers) conform to this pattern. Each category's page documents its category-specific shape on top.
Meta-contract guidance. This page describes the shared meta-shape that every category contract conforms to. It is not itself a per-category contract and carries no independent
contractVersion. Breaking changes to the meta-shape are recorded on the affected category contracts' changelogs; each per-category contract owns its owncontractVersion.Pre-release: contracts remain at
1.0.0. Iterations live in the existing changelog entry, not new SemVer entries. The first2.0.0bump occurs only after the first public release.
classDiagram
class ExtensionContract~T~ {
kind : CategoryKind
contractVersion : SemVer
requiredCoreVersion : SemVerRange
lifecycle : LifecycleFns
configSchema : JSONSchema
loadedCardinality : Cardinality
activeCardinality : Cardinality
stateSlot : StateSlotShape | none
discoveryRules : DiscoveryRules
reloadBehavior : ReloadBehavior
}
class LifecycleFns {
init
activate
deactivate
dispose
}
ExtensionContract~T~ --> LifecycleFns
Every field is normative (ten fields; the per-extension severity field was removed in Q-3). An extension whose contract omits a field, or mis-specifies its type, fails validation.
The category. One of: Provider, Tool, Hook, UI, Logger, StateMachine, Command, SessionStore, ContextProvider. Fixed at load; an extension cannot change category.
Semver string. The version of the category contract this extension speaks. Core refuses to load extensions whose contractVersion is incompatible with the core version it bundles. See Versioning and Compatibility.
Semver range. The core versions this extension is known to work with. Core refuses to load extensions whose range excludes the current core version.
The four lifecycle entry points: init, activate, deactivate, dispose. Semantics in Extension Lifecycle.
An extension may implement all four or a subset; unimplemented ones default to no-op. dispose is always idempotent.
A JSON-Schema-shaped document describing the extension's own configuration block. Validated at load by the Validation Pipeline. Core uses it to:
- Reject malformed config before the extension sees it.
- Route config into
host.config.readOwn(). - Produce diagnostics pointing at exact field paths.
Config schemas live in the contract, not in implementation — so the wiki can describe what a conforming extension accepts.
How many extensions of this kind may load simultaneously in a session.
-
unlimitedfor most categories. -
nfor categories with a numeric cap. -
onefor categories where only one can exist loaded at all (rare).
How many of the loaded extensions may be active at once.
-
unlimited— everything loaded can be active (Providers, Tools, Hooks, Loggers, Commands, Context Providers, UI — subscriber, interactor, and region roles coexist; see Q-9 in Cardinality and Activation). -
one— only one active at a time (Session Store). -
one-attached— only one attached at a time (State Machines; sole use of this value).
See Cardinality and Activation for the precise definitions of active vs attached.
Optional per-extension state persisted by the active Session Store alongside the session manifest — the manifest records only slot metadata (see Session Manifest § Shape); the payload itself lives in a separate persistence surface owned by the store. Contract-declared shape; core serializes and restores it. Extensions read/write via host.session.stateSlot(extId). See Extension State.
An extension without a state slot is entirely stateless across resumes. An extension with a state slot declares serialization shape and a version for drift handling.
How the extension declares itself to discovery. Category folder, naming expectations, ordering-manifest participation. Implementation details belong to code; this field is about the convention an extension conforms to.
Whether the extension can be hot-reloaded mid-session. See Extension Reloading. Options: in-turn (can reload at any stage boundary), between-turns (only outside a turn), never (requires a session restart).
Every per-category contract page in contracts/ should include, in order:
- Intent — what the category plugs in and why it is an extension.
- Contract shape — the fields on top of the meta-shape.
-
contractVersion(current) and a Changelog section. - Lifecycle — anything category-specific beyond what Extension Lifecycle documents.
- Config schema — the shape of the extension's config.
- Cardinality — loaded and active, with rationale.
- State slot — shape and drift behavior, or "none".
- Discovery path — where extensions of this kind are found.
- Ordering rules — for ordered categories (Hooks).
- Reload behavior — in-turn / between-turns / never, with rationale.
- Interaction with core — which core surfaces the extension reaches (Host API services, registries, etc.).
- Security notes — what must be true for a conforming extension.
Reference pages in reference-extensions/ must not redefine any of these fields. They link to the contract page.
Failure-handling note. Per Q-3 there is no per-extension severity field. Any extension that fails validation is disabled (omitted from the loaded set); the session continues. The TUI startup surface aggregates failures into a navigable counter (
N warnings, M errors). See Validation Pipeline.
- One category per extension. No multi-role extensions.
-
One contract version per extension load. An extension cannot speak
v1for one handler andv2for another. - Contract is normative; reference is illustrative. When text diverges, the contract wins.
- Config is validated; runtime fields are not. Runtime shape is a code concern, not a wiki concern.
-
No extension reaches another extension's state slot. Only
host.session.stateSlot(extId)and only for its ownextId.
Per-category contract pages:
| # | Category | Page |
|---|---|---|
| 1 | Providers | Providers |
| 2 | Tools | Tools |
| 3 | Hooks | Hooks |
| 4 | UI | UI |
| 5 | Loggers | Loggers |
| 6 | State Machines | State Machines |
| 7 | Commands | Commands |
| 8 | Session Stores | Session Store |
| 9 | Context Providers | Context Providers |
The meta-shape page itself is unversioned. This changelog records meta-shape changes whose contractVersion bumps land on the affected per-category contract pages.
- Dropped the per-extension severity field from the meta-shape. The eleven-field shape becomes ten.
- Failure handling: any extension failing validation is disabled rather than session-fatal; the session continues. See Validation Pipeline.
- Execution Model
- Message Loop
- Concurrency and Cancellation
- Error Model
- Event and Command Ordering
- Event Bus
- Command Model
- Interaction Protocol
- Hook Taxonomy
- Host API
- Extension Lifecycle
- Env Provider
- Prompt Registry
- Resource Registry
- Session Lifecycle
- Session Manifest
- Persistence and Recovery
- Stage Executions
- Subagent Sessions
- Contract Pattern
- Versioning and Compatibility
- Deprecation Policy
- Capability Negotiation
- Dependency Resolution
- Validation Pipeline
- Cardinality and Activation
- Extension State
- Conformance and Testing
- Providers
- Provider Params
- Tools
- Hooks
- UI
- Loggers
- State Machines
- SM Stage Lifecycle
- Stage Definitions
- Commands
- Session Store
- Context Providers
- Settings Shape
- Trust Model
- Project Trust
- Extension Isolation
- Extension Integrity
- LLM Context Isolation
- Secrets Hygiene
- Security Modes
- Tool Approvals
- MCP Trust
- Sandboxing
- Configuration Scopes
- Project Root
- Extension Discovery
- Extension Installation
- Extension Reloading
- Headless and Interactor
- Determinism and Ordering
- Launch Arguments
- Network Policy
- Platform Integration
Tools
UI
Session Stores
Loggers
Providers
Hooks
Context Providers
Commands
- First Run
- Default Chat
- Tool Call Cycle
- Hook Interception
- Guard Deny Reproposal
- State Machine Workflow
- SM Stage Retry
- Hot Model Switch
- Capability Mismatch Switch
- Session Resume
- Session Resume Drift
- Approval and Auth
- Interaction Timeout
- Headless Run
- Parallel Tool Approvals
- Subagent Delegation
- Scope Layering
- Project First-Run Trust
- Reload Mid-Turn
- Compaction Warning
- MCP Remote Tool Call
- MCP Prompt Consume
- MCP Resource Bind
- MCP Reconnect