Expand description
Task 10C: trace wiring for extension-hosted providers (completing the
Task 10 transport coverage). Mirrors the seams in trace::anthropic /
trace::openai / trace::google with extension-specific honesty rules:
- Trace only actual IPC. A record begins only after every routing gate
has passed — provider existence, per-provider trust, trust-state
readability, and the pre-IPC cancellation check — and immediately before
the
provider_stream/provider_completecall crosses the extension process boundary. Blocked, untrusted, unavailable, or cancelled-before-start requests emit no request-attempt record. - Wire is always
None. JSON-RPC framing and serialization for the sidecar transport are owned by the extension process transport, not this routing layer — there is no buffer of exact bytes here, so no wire digest is ever claimed (same rule as the remote-broker paths). - Attempt rule (documented invariant): one outer extension turn is one
transport attempt — one record per
provider_streamcall or per outerprovider_complete/complete_provider_with_toolsturn. The tool-loop helper may invokeprovider.completeseveral times inside one turn; those interior tool-use iterations are not separate request attempts and are deliberately not counted as retries (they are successful calls, not failures — theattempt/retriesinvariant would be false for them). The record therefore never claims an interior call count. - Reserved static endpoint identity. The endpoint host is the
RFC 2606-style reserved name
extension.invalidwith static paths/provider/stream//provider/complete; the exact qualifiedplugin:provider/modelidentity travels in the validated model field. Plugin file paths, spawn commands, params, messages, tools, errors and credentials never enter a record. - Extension-controlled data is untrusted. Error text from the
extension is replaced by the static code
EXTENSION_PROVIDER_ERROR_CODE; stop reasons pass a closed mapping; usage numbers are accepted only as plain unsigned integers under known keys (never copied as raw values of any other shape).
Structs§
- Extension
Attempt - Per-turn trace state for one extension provider IPC invocation: the
optional tracer, this turn’s monotonic clock, and the shared first-event
cell. Every method is a no-op when tracing is disabled; nothing here can
fail the request. Exactly one
finish_*record is emitted — the tracer is taken on finish, so later calls can never double-emit. - First
Event Mark - Cheap cloneable handle the stream forwarder uses to mark the first model
event (first
TextDelta/ThinkingDelta/ToolUse/Usage). Set-once via compare-exchange; aNoneinterior (tracing disabled) makesmark()a no-op with zero shared state.
Constants§
- EXTENSION_
COMPLETE_ PATH - Static endpoint path for
provider.completeIPC (including the tool-loop outer turn). - EXTENSION_
ENDPOINT_ HOST - Reserved, never-routable endpoint host for extension provider records.
.invalidis an RFC 2606 reserved TLD — this can never collide with or leak a real network endpoint. - EXTENSION_
PROVIDER_ ERROR_ CODE - The only failure code an extension-controlled error may produce in a trace record — extension error text is untrusted and never copied.
- EXTENSION_
STREAM_ PATH - Static endpoint path for
provider.streamIPC.
Functions§
- begin_
extension_ tracer - Begin tracing one extension provider IPC turn. Returns
Nonewhen tracing is disabled or the qualified identity is unrepresentable — tracing can never fail or alter the provider request. - extension_
capability_ losses - Capability-driven translation report for the extension route, structural only. Known losses today:
- stop_
reason_ from_ extension - Normalize an extension-reported stop reason through a closed mapping.
Unknown values collapse to
Other; the raw string is never stored. - usage_
from_ extension_ value - Extract provider-reported usage from the extension’s free-shape
usagevalue. Only plain unsigned integers under the known keys are accepted; anything else staysNone— numbers are never fabricated and non-numeric extension content is never copied. ReturnsNonewhen no metric parses.