Expand description
Task 20 — capability-driven extension lifecycle (spec §7.5).
Typed inventory/classification of extension manifests plus OPTIONAL,
ADDITIVE passive deferred declarations. Absent declarations keep the
documented legacy EAGER lifecycle byte-for-byte (no protocol version
bump); present declarations are trusted local manifest expectations:
they enable spawn deferral and MUST match the runtime’s initialize
declarations exactly (names, schemas, digests) before any registration
or grant — a mismatch shuts the child down and fails closed.
Nothing in this module spawns a process or touches the network: it reads bounded local manifest data and mints dormant descriptor tools.
Structs§
- Declared
Extension Context Provider - Passive MEMORY/CONTEXT contribution provider declaration
(continuous-memory spec §7.1) — e.g. Axel’s
extension:axel-memory-manager:project-memory. DISTINCT fromDeclaredExtensionProvider(model/LLM provider metadata): this declares a dormant context-contribution capability. Discovery, schema export, status inspection, and normal first prompts never spawn the owning extension; activation is exclusively a future exact memory-context lease (task A6). - Declared
Extension Provider - Passive provider declaration, field-compatible with the runtime’s
RegisteredProviderSpecso a validated declaration can later back metadata-only registration. - Declared
Extension Provider Model - Field-compatible with
RegisteredProviderModelSpec. - Declared
Extension Tool - One passively declared tool: exactly the fields the runtime will register at initialize, pinned locally so activation can validate the live declaration against operator-known expectations.
- Deferred
Declarations - OPTIONAL additive manifest block. Absent => legacy eager lifecycle.
- Deferred
Extension Tool - A dormant, manifest-declared extension tool. Registered like any live
tool (stable
ext:<plugin>:<name>identity, schema, digest — so wire resolution, discovery, exact grants, and the execution gate all work unchanged), but its implementation is DEFERRED: executing it requires the session extension-runtime lease capability (lease lifecycle commit), which starts only the OWNING extension after the execution gate has already authorized the call. Without that capability it fails typed and spawns nothing.
Enums§
- Activation
Trigger - The earliest legitimately required activation trigger for a manifest (spec 7.5). Mixed extensions use the EARLIEST of their components — hook events fire passively during any turn, provider selection is an explicit routing choice, exact tool activation comes last; tool SEARCH alone never triggers a start.
- Deferred
Lifecycle - Extension
Class - Typed extension lifecycle classes (spec §7.5).
Constants§
- DECLARED_
DESCRIPTION_ MAX_ BYTES - DECLARED_
DISPLAY_ MAX_ BYTES - DECLARED_
MAX_ CONTEXT_ PROVIDERS - Bound on passive memory/context contribution provider declarations (continuous-memory spec §7.1). Deliberately small: one extension has no legitimate reason to contribute many distinct context surfaces.
- DECLARED_
MAX_ PROVIDERS - DECLARED_
MAX_ PROVIDER_ MODELS - Bounds for provider declarations.
- DECLARED_
MAX_ TOOLS - Bounds for passive tool declarations (parity with the MCP descriptor cache budgets).
- DECLARED_
NAME_ MAX_ BYTES - DECLARED_
SCHEMA_ MAX_ BYTES
Functions§
- classify
- Classify a manifest from its passive declarations. Pure and local.
- dormant_
extension_ tools - Build the dormant deferred tools for one manifest. Deterministic (declaration order); returns nothing for manifests without validated declarations — descriptors are never invented. Never spawns.
- earliest_
trigger - has_
context_ provider - Whether a deferred block declares at least one memory/context contribution provider (continuous-memory spec §7.1).
- validate_
deferred - Bounded validation of a
deferredblock. Static reasons only; any violation fails the WHOLE manifest closed (validated before any spawn). - validate_
manifest_ deferred - Manifest-level coupling checks for a
deferredblock (review fix A1/ A2). Passive declarations are CAPABILITY claims: cataloging a dormant tool descriptor (or provider metadata) grants the extension future runtime reach, so it MUST be backed by the exact permission the live registration would require — otherwise a manifest could obtain discoverable/activatable surface it was never authorized to register. Likewiselifecycle = "hook"without a real manifest hook subscription has NO authorized trigger and can never legitimately start: it fails closed here instead of lingering as unreachable-but-cataloged state. - validate_
runtime_ provider_ declarations - Strict initialize-time PROVIDER declaration check (Task 20 Commit B): the runtime’s registered provider specs must match the manifest’s passive declarations EXACTLY — same id set, display names, descriptions, model id sets, per-model display/context-window/ capability values, and config schemas as declared. A manifest that declares NO providers must see NO registered providers (a tool-only runtime sneaking provider metadata in is an undeclared capability). Static reasons only; callers shut the child down and fail closed.
- validate_
runtime_ tool_ declarations - Strict initialize-time declaration check: the runtime’s registered tool specs must match the manifest’s passive declarations EXACTLY — same name set (no missing, no undeclared extras) and identical canonical schema digests. Static reasons only; callers shut the child down and fail closed on any mismatch, before any registration or grant.