Documentation menu

Draft elicitation, observation, and compaction APIs

These pre-release APIs implement the mutable draft’s elicitation, observation, and compaction boundaries. Generated models/codecs preserve structure; canonical validation and trusted host configuration remain necessary.

SDK Elicitation exchange / effect staging Compaction
Python agent_hooks_protocol.elicitation.validate_exchange, apply_effects agent_hooks_protocol.compaction.run_compaction
TypeScript validateElicitationExchange, applyElicitationEffects runCompaction
Go interop.ValidateElicitationExchange, interop.ApplyElicitationEffects interop.RunCompaction
Rust elicitation::validate_exchange, elicitation::apply_effects compaction::run_compaction, run_compaction_observed

Elicitation

Supply canonical request/result envelopes, an authorized immutable-body resolver, a canonical validator, and the authenticated supplier identity. Do not derive that identity from event fields. Validators enforce parent request, source and session correlation before resolving content or staging effects. Receiver pending state uses source-scoped request identity, not one slot per session.

Body-selected request/result descriptors refer to complete unchanged MCP 2025-11-25 params/ElicitResult JSON. Metadata/omit views do not resolve or upload a body. These helpers reject missing requested bodies; the interception caller applies the subscription’s configured failure policy (fail-open or fail-closed), rather than treating helper rejection as a protocol-wide fail-closed decision. Intentional metadata/omit selection is not a missing-body failure and does not establish executable validated input. Form data is checked against requestedSchema; defaults remain annotations and are not injected. validate_mode / validateElicitationMode / ValidateElicitationMode enforce independent optional form/URL support. Only an explicit MCP-origin translation interprets legacy empty capabilities as form support.

Effect application validates the complete effect list and request-local grants before publishing a candidate. Request return/deny and result content replace/merge are distinct operations; failed lists leave the input unchanged. A supplied result carries authenticated hook provenance, never fabricated human provenance. URL accept does not mean external success or trigger a completion event. After accepted changes, upload new complete JSON bytes and construct new immutable references before delivering body-selected content to the next subscriber.

Compaction

Configure ordered hooks with supplier identity, failure policy and callbacks, plus a real host generator (tests use a deterministic synthetic generator). Before hooks can replace instructions; after hooks can replace the summary. Capabilities advertise only implemented operations. Whole-list staging preserves earlier accepted changes and prevents leakage from a rejected compound response. A later changed input invalidates an earlier supplied summary. A return bound to the effective input skips generation but still runs all after controls.

The returned summary handles are internal runtime handles, not canonical wire descriptors. Preserve their logical item ID; upload exact bytes and produce credential-scope-authorized ContentItems before wire dispatch. Changed bytes require a new reference. The canonical compaction wire fixture demonstrates that binding.

Observation-only callbacks have no effect or failure-policy authority and do not gate downstream settlement. They receive isolated snapshots. Rust detached observers must be owned CompactionObserver callbacks passed to run_compaction_observed; borrowed callbacks cannot be detached safely.

Observation dispatch APIs

SDK Entry point / scheduling
Python lifecycle.dispatch_observations, daemon workers
TypeScript draft-runtime.dispatchObservations, host-supplied scheduler; interop/settlement.mjs supplies an unreferenced Node immediate scheduler
Go interop.DispatchObservations, independent goroutines
Rust observation::dispatch_observations, detached workers

Supply an already-settled snapshot, matching subscriptions, and the IDs of interceptors already called. The required prepare callback enforces host content policy and confirms selected uploads; notify sends the one-way notification. For a native boundary without interception, use an empty called set. The host owns cancellation and shutdown of transport resources; stopping execution never joins observer workers. Test-controller receipt rendezvous such as /wait-observed are not protocol acknowledgements or production interruption gates.

Chain integration

All four lifecycle adapters invoke chain dispatch from acquired and validated responses. Fail-open continues decisions; deny, flow stop, fail-closed and interrupt end decisions and dispatch remaining uncalled intercept subscriptions as hooks/observe. Already-called interceptors do not get a second copy absent a separate explicit observe subscription. Per-subscription preparation applies permissions, selection and upload confirmation before notification dispatch. There is no disposition, downgrade flag, response receipt, or observation effect.

Reproduction and limits

See elicitation, compaction, and lifecycle for tests and exact scope. These synthetic exchanges establish SDK behavior, not native harness event occurrence, production trust federation, browser completion or durable content storage.

Task lineage reference checker

Instantiate interop/task_lineage.py’s TaskLineage per receiving connection. Use accept_wire(bytes_or_text) for full JSON-RPC frames or accept(message) after strict JSON decoding. Do not combine unrelated sources or connections’ subscription-delivery retry state. require_known_parents=True is a producer-history check, not a requirement for filtered subscribers. This isolated checker does not add an adapter control protocol; task IDs do not establish delivery-byte equality or capability enforcement. See the lineage binding.

Codec and evidence limits

Generated codecs are loss-preserving structural parsers, not full validators. Required-only properties enforce presence without injecting defaults; explicit null is allowed only if all applicable schemas allow it. Known MCP transports use exact structural dispatch; extension transports remain unknown variants requiring canonical validation of their naming, location and gaps. The generator’s x-sdk-discriminator annotation does not change JSON Schema validity or declare native transport support.

Validate canonical schemas before runtime authorization and enforce cross-message rules separately. URI/time format validity does not establish safe endpoints; open envelopes and opaque native/input/output fields do not prove the absence of credentials or duplicated model content. Synthetic tests do not establish native content completeness, human approval, effective-destination reauthorization, model admission, task commits, managed-policy enforcement, production identity or delegation, replay, durability, or rollback. Independent HTTP upload-origin tests do not establish HTTPS client-certificate noninheritance.

Wire identity and upload confirmation

Subscriptions remain harness-local configuration; no subscription identifier is sent in event parameters or upload headers. JSON-RPC IDs correlate pending requests, while upload authorization derives from independently configured credentials and receiver policy, never an event ID or descriptor reference. Unknown registration/configuration fields are ignored (and may produce warnings); recognized fields remain validated. Unknown effects and operation values still reject the entire response atomically.

POST exact bytes with their length and SHA-256, without a caller-selected ref. The receiver returns HTTP 201 Created with the canonical JSON content-upload receipt {ref, size, sha256}. Validate the receipt and verify size/hash before putting only {ref} into an event body. Ready body-selected items do not repeat size/hash metadata. A retry may allocate another immutable ref; reference-conflict probing and caller-reference idempotence are not part of the binding. Upload credentials never implicitly inherit event credentials, and upload confirmation is not event acknowledgement or proof of durable storage.