Skip to main content

Module lifecycle

Module lifecycle 

Source
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§

DeclaredExtensionProvider
Passive provider declaration, field-compatible with the runtime’s RegisteredProviderSpec so a validated declaration can later back metadata-only registration.
DeclaredExtensionProviderModel
Field-compatible with RegisteredProviderModelSpec.
DeclaredExtensionTool
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.
DeferredDeclarations
OPTIONAL additive manifest block. Absent => legacy eager lifecycle.
DeferredExtensionTool
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§

ActivationTrigger
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.
DeferredLifecycle
ExtensionClass
Typed extension lifecycle classes (spec §7.5).

Constants§

DECLARED_DESCRIPTION_MAX_BYTES
DECLARED_DISPLAY_MAX_BYTES
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. deferred.context_providers is not one of them: it is ignored, so a manifest that declares only that classifies like one with an empty deferred block.
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
ignored_context_provider_notice
The line to log when a manifest still declares a context provider (the deferred.context_providers key with anything in it, or the context_providers.register permission), None when it declares neither. The extension loads as if the declaration were absent: its tools and hooks work, and nothing starts it “on a memory lease”, because no such lease exists any more.
validate_deferred
Bounded validation of a deferred block. Static reasons only; any violation fails the WHOLE manifest closed (validated before any spawn).
validate_manifest_deferred
Manifest-level coupling checks for a deferred block (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. Likewise lifecycle = "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.