Expand description
Versioned, provider-neutral request trace envelope (spec §6.1, §6.4).
synaps-request-trace/1 carries bounded, safe-alphabet metadata only:
no field can hold free-form text. Every content-derived value is a count,
byte length, enum, keyed digest (ComponentDigest), or a validated
bounded identifier (TraceId / WireName — ≤256 bytes, restricted
ASCII alphabet, no whitespace/control/quotes/backslashes). Short strings
spelled from the ID alphabet remain representable — the enforced invariant
is bounded + safe, which structurally excludes prompt text, message
content, tool results, headers, query strings, and credentials of any
realistic shape. Digests are HMAC-SHA256, keyed by a random
per-installation key stored as a private regular file (0600, parent
0700, symlink- and special-file-refusing) under the Synaps base
directory — keying prevents offline dictionary confirmation of prompt
contents from a leaked trace log. Neither the key nor digest preimages are
ever logged.
Task 7 delivered the types + serde + key/digest primitives; Task 8 wires
the Anthropic transports (runtime/api.rs, runtime/api_sync.rs) into
the emission seam in emit, with structural builders in anthropic
(the normalized IR / TranslationReport arrive in Task 9; the bounded
persistence writer in Task 11). Task 10A extends the seam to the
OpenAI-compatible transports — Chat Completions and Responses/Codex —
via openai; Task 10B covers Gemini/Vertex and the cloud-invoke
routes via google; Task 10C completes the set with extension-hosted
providers via extension.
Serde contract (deliberate): optional metrics serialize as absent —
never fabricated zeros — and both absent and explicit null deserialize
to None. Struct field order is the deterministic serialization order.
Modules§
- anthropic
- Metadata-only structural description of an Anthropic Messages request (Task 8). Every function here consumes trusted structural inputs — the already-sanitized message array, the caller-supplied system prompt, the registered tool schemas, and the exact serialized wire bytes — and produces only counts, byte lengths, enums, validated IDs, and keyed digests. No raw string is ever retained.
- controls
- Explicit trace controls (Task 12, spec §5.1 raw-capture clause + §6.1
surfaces):
/trace next,/trace next content,/trace status. - diagnostics
- Cache-prefix diagnostics (Task 12, spec §6.6) and the
/contextreport. - emit
- Trace emission seam (Task 8, spec §6.2/§6.4).
- execution
- Task 27 — bounded, correlated tool-execution lifecycle metadata.
- export
- Trace export (Task 12): metadata export of persisted
synaps-request-trace/1records, explicit redacted content export, and the recursive secret redaction they share. - extension
- Task 10C: trace wiring for extension-hosted providers (completing the
Task 10 transport coverage). Mirrors the seams in
trace::anthropic/trace::openai/trace::googlewith extension-specific honesty rules: - Task 10B: trace wiring for the Google Gemini Code Assist transport
(broker-proxied
v1internal:streamGenerateContent) and the explicit cloud-invoke routes (AWS Bedrock, Azure OpenAI, Google Vertex — all broker-mediated). Mirrors the Anthropic/OpenAI seams: - openai
- Task 10A: trace wiring for the OpenAI-compatible transports — Chat
Completions (broker-proxied) and Responses/Codex (broker-proxied xAI and
direct ChatGPT-backend). Mirrors the Anthropic seam in
trace::anthropicandruntime/api.rs:
Structs§
- Attempt
Clock - Monotonic (
Instant-based) timing capture for one transport attempt. Every mark is set-once; unobserved stages stayNone(never zero). - Block
Meta - One block within a message: kind + size only.
- Cache
Activity - Latest cache diagnostics, retained for the
/contextreport. Bounded metadata only (digests, byte lengths, enums, tool IDs). - Cache
Boundary Meta - One declared cache boundary.
- Cache
Meta - Cache boundaries, stable-prefix digests, and previous-turn segment
deltas (spec §6.6). The prefix/tail digests are keyed HMAC over
canonical component bytes (see
trace::diagnosticsfor the exact canonicalization and its documented approximations) — never a re-serialization passed off as exact wire bytes. All diagnostic fields are optional for backward-compatible deserialization. - Cache
Segment Delta - Per-segment previous-turn change report plus changed-tool detail and
reuse estimates (spec §6.6). Every field is bounded metadata: enums,
validated tool IDs, and byte counts — never content. All fields are
optional/defaulted so
synaps-request-trace/1records written before this struct existed still deserialize. - Cache
Snapshot Store - Session-scoped previous-component snapshot (see module docs). Shared via
ArcinsideTraceContext; all mutation is under one internal mutex so compare-and-update is atomic per emitted request. - Collecting
Trace Sink - In-memory collector for deterministic tests.
- Component
Digest - Lowercase-hex HMAC-SHA256 output (exactly 64 hex chars). The validated
newtype makes it impossible to smuggle raw content through a digest field:
construction is only via
keyed_digestor by parsing a well-formed hex string. - Content
Capture - One-request content capture arm, attached to a
TraceContextwhen the user ran/trace next content. Fires at most once. - Content
Export - On-disk shape of the content export artifact. NOT a request trace.
- Context
Report - Structured
/contextreport: counts, bytes, enums, and counters only — never prompt/tool/skill/memory content. - Endpoint
Meta - Endpoint identity — validated host and path only; never query strings,
fragments, userinfo, or headers. Fields are private: construction is only
via
EndpointMeta::new(or deserialization, which applies the same validation). Serializes as{host, path}. - Execution
Correlation - Message
Meta - One conversation message: role and per-block metadata.
- Metadata
Export Stats - Result of a metadata export.
- Noop
Trace Sink - Disabled sink: accepts and discards.
enabled() == falselets transports skip all trace work. Production installs the Task 11 writer-backed sink (runtime::telemetry::WriterTraceSink) instead when the telemetry level warrants persistence. - Prefix
Meta - Stable-prefix metadata for cache diagnosis: bytes + keyed digest.
- Request
Anatomy - Normalized request anatomy: counts only.
- Request
Correlation - Request
Structure - Structural, metadata-only description of one outgoing request, built by a
transport-specific helper (see
trace::anthropic) from trusted inputs — includingWireMetacomputed from the exact bytes handed to reqwest. - Request
Trace - One
synaps-request-trace/1record: metadata for a single request attempt. Field order is the canonical, deterministic serialization order. - Request
Tracer - Builds and emits one record per actual transport attempt (see module docs for the record rule). Owned by a single request; not shared.
- Retry
Meta - One retry: attempt ordinal, class, and delay before the next attempt.
- System
Segment Meta - One system segment: type, size, keyed digest. No text.
- Timing
Stages - Timing stages (spec §6.4). Every stage is optional: a stage that was not
observed is
None, never a fabricated zero. Offsets are milliseconds fromsend_start_unix_ms. - Tool
Execution Event - One bounded, content-free lifecycle event. IDs and wire names use the validated trace types; result content is represented only by byte count, truncation metadata, and an optional bounded preview byte count.
- Tool
Meta - One exposed tool: stable ID, wire name, schema size + keyed digest.
- Trace
Context - Cloneable handle carrying the sink, the lazily-loaded digest key, the session identity, and metadata-only degradation counters.
- Trace
Controls - Session trace controls: one-shot arm consumed by the next request.
- Trace
Digest Key - Random 32-byte per-installation HMAC key. Zeroized on drop;
Debugis redacted so the key never reaches a log line by accident. - TraceId
- Bounded, safe-alphabet identifier — serialized as a plain JSON string.
- Trace
Schema Version - Validated schema tag — serializes as the string
synaps-request-trace/1and refuses to deserialize any other value, so a reader can never silently accept a record from a different (past or future) schema. - Trace
Status Report - Metadata-only status for
/trace status: mode, persistence path, counters. Never secrets, never content. - Translation
Loss - One translation loss / synthetic rewrite: action + element reference only.
The full
TranslationReport(Task 9) will populate these. - Transport
Outcome - Common transport outcome (spec §6.4): every transport returns this shape.
All metrics are optional — absent/unknown is
None, never a fabricated zero. The terminalTurnOutcomeis the single typed source of truth produced by the engine (spec §5.2). - Usage
Meta - Token usage with provenance. Individual metrics the provider did not
report are
None— never zero-filled. - Wire
Meta - Exact-wire metadata, computed from the very bytes handed to the transport
(Task 8).
Noneuntil a transport populates it — never re-serialized. - Wire
Name - Wire-level tool name — stricter than
TraceId: nonempty, at mostWIRE_NAME_MAX_BYTESbytes,[A-Za-z0-9_-]only (the intersection of provider tool-name grammars). Serialized as a plain JSON string.
Enums§
- Activation
Grant Ref - Block
Kind - Content-block category.
- Cache
Boundary Location - Where a cache boundary marker sits in the request.
- Cache
TtlClass - Cache TTL class of one boundary.
- Digest
Domain - Domain-separation label for keyed digests, so a digest of e.g. a system segment can never be cross-matched against a tool schema digest of the same bytes.
- Execution
Commit Status - Execution
Effect - Execution
Phase - Export
Error - Typed export failure. Every variant is metadata-only (paths, counts).
- Message
Role - Message author role.
- Report
Value - Why a
/contextline has no number: honest provenance, never a fabricated zero. - Retry
Class - Coarse retry classification.
- Segment
Change - Previous-turn comparison state for one cache segment (spec §6.6).
- Stop
Reason - Provider-assigned stop reason, normalized.
- System
Segment Kind - Trace
Arm - Current arm state.
- Trace
KeyError - Typed failure for digest-key loading.
- Translation
Action - What a provider adapter did to a non-representable element.
- Translation
Element - Which structural element was affected.
- Transport
Kind - Which wire protocol carried the request.
- Usage
Provenance - Where a usage number came from.
Constants§
- CAPTURE_
MAX_ BYTES - Upper bound on captured (post-redaction) body bytes.
- CAPTURE_
TTL - Retention window for a capture bundle.
- CONTENT_
CAPTURE_ SCHEMA - Schema tag for the ephemeral content-capture bundle. Distinct from the request-trace schema by design.
- CONTENT_
EXPORT_ SCHEMA - Schema tag of the content-export artifact. Deliberately distinct from both the request-trace and capture schemas.
- TRACE_
ID_ MAX_ BYTES - Maximum byte length of a
TraceId. - TRACE_
SCHEMA - The exact version tag of this envelope schema.
- WIRE_
NAME_ MAX_ BYTES - Maximum byte length of a
WireName.
Traits§
- Trace
Sink - Receives finished trace records. Implementations must be cheap and non-blocking: they run inline on the request path.
Functions§
- default_
capture_ dir - Default capture directory:
<synaps base dir>/trace/capture/. - default_
digest_ key_ path - Default installation-scoped key path:
<synaps base dir>/trace/digest.key. - export_
content - Export the ephemeral capture bundle for
idinto a fresh private file. Fail-closed: requiresallow_content_export, an existing unexpired bundle, and re-redacts before writing. Consumes (deletes) the bundle. - export_
metadata - Export all records whose
turn_idorrequest_idequalsidfrom the trace JSONL attrace_loginto a fresh private file atoutput. - keyed_
digest - Keyed HMAC-SHA256 component digest with domain separation. The preimage
(
bytes) is never logged or stored; only the hex MAC output escapes. - load_
or_ create_ digest_ key - Load the installation digest key, creating it on first use.
- load_
or_ create_ digest_ key_ at - Load (or atomically create) the digest key at
path. - redact_
value - Recursively redact credential-bearing keys and obvious secret-shaped values in place. Returns the number of redactions applied. Applies to nested objects and arrays at any depth.
- sweep_
expired_ captures - Delete any expired capture bundles in
dir(bounded retention sweep). - wire_
meta_ from_ sent_ bytes - Compute exact-wire metadata from the very byte buffer handed to the
transport. This is the ONLY constructor for
WireMetaused by transports — there is no re-serialization path.