Skip to main content

Module trace

Module trace 

Source
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 /context report.
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/1 records, 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::google with extension-specific honesty rules:
google
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::anthropic and runtime/api.rs:

Structs§

AttemptClock
Monotonic (Instant-based) timing capture for one transport attempt. Every mark is set-once; unobserved stages stay None (never zero).
BlockMeta
One block within a message: kind + size only.
CacheActivity
Latest cache diagnostics, retained for the /context report. Bounded metadata only (digests, byte lengths, enums, tool IDs).
CacheBoundaryMeta
One declared cache boundary.
CacheMeta
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::diagnostics for 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.
CacheSegmentDelta
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/1 records written before this struct existed still deserialize.
CacheSnapshotStore
Session-scoped previous-component snapshot (see module docs). Shared via Arc inside TraceContext; all mutation is under one internal mutex so compare-and-update is atomic per emitted request.
CollectingTraceSink
In-memory collector for deterministic tests.
ComponentDigest
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_digest or by parsing a well-formed hex string.
ContentCapture
One-request content capture arm, attached to a TraceContext when the user ran /trace next content. Fires at most once.
ContentExport
On-disk shape of the content export artifact. NOT a request trace.
ContextReport
Structured /context report: counts, bytes, enums, and counters only — never prompt/tool/skill/memory content.
EndpointMeta
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}.
ExecutionCorrelation
MessageMeta
One conversation message: role and per-block metadata.
MetadataExportStats
Result of a metadata export.
NoopTraceSink
Disabled sink: accepts and discards. enabled() == false lets transports skip all trace work. Production installs the Task 11 writer-backed sink (runtime::telemetry::WriterTraceSink) instead when the telemetry level warrants persistence.
PrefixMeta
Stable-prefix metadata for cache diagnosis: bytes + keyed digest.
RequestAnatomy
Normalized request anatomy: counts only.
RequestCorrelation
RequestStructure
Structural, metadata-only description of one outgoing request, built by a transport-specific helper (see trace::anthropic) from trusted inputs — including WireMeta computed from the exact bytes handed to reqwest.
RequestTrace
One synaps-request-trace/1 record: metadata for a single request attempt. Field order is the canonical, deterministic serialization order.
RequestTracer
Builds and emits one record per actual transport attempt (see module docs for the record rule). Owned by a single request; not shared.
RetryMeta
One retry: attempt ordinal, class, and delay before the next attempt.
SystemSegmentMeta
One system segment: type, size, keyed digest. No text.
TimingStages
Timing stages (spec §6.4). Every stage is optional: a stage that was not observed is None, never a fabricated zero. Offsets are milliseconds from send_start_unix_ms.
ToolExecutionEvent
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.
ToolMeta
One exposed tool: stable ID, wire name, schema size + keyed digest.
TraceContext
Cloneable handle carrying the sink, the lazily-loaded digest key, the session identity, and metadata-only degradation counters.
TraceControls
Session trace controls: one-shot arm consumed by the next request.
TraceDigestKey
Random 32-byte per-installation HMAC key. Zeroized on drop; Debug is redacted so the key never reaches a log line by accident.
TraceId
Bounded, safe-alphabet identifier — serialized as a plain JSON string.
TraceSchemaVersion
Validated schema tag — serializes as the string synaps-request-trace/1 and refuses to deserialize any other value, so a reader can never silently accept a record from a different (past or future) schema.
TraceStatusReport
Metadata-only status for /trace status: mode, persistence path, counters. Never secrets, never content.
TranslationLoss
One translation loss / synthetic rewrite: action + element reference only. The full TranslationReport (Task 9) will populate these.
TransportOutcome
Common transport outcome (spec §6.4): every transport returns this shape. All metrics are optional — absent/unknown is None, never a fabricated zero. The terminal TurnOutcome is the single typed source of truth produced by the engine (spec §5.2).
UsageMeta
Token usage with provenance. Individual metrics the provider did not report are None — never zero-filled.
WireMeta
Exact-wire metadata, computed from the very bytes handed to the transport (Task 8). None until a transport populates it — never re-serialized.
WireName
Wire-level tool name — stricter than TraceId: nonempty, at most WIRE_NAME_MAX_BYTES bytes, [A-Za-z0-9_-] only (the intersection of provider tool-name grammars). Serialized as a plain JSON string.

Enums§

ActivationGrantRef
BlockKind
Content-block category.
CacheBoundaryLocation
Where a cache boundary marker sits in the request.
CacheTtlClass
Cache TTL class of one boundary.
DigestDomain
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.
ExecutionCommitStatus
ExecutionEffect
ExecutionPhase
ExportError
Typed export failure. Every variant is metadata-only (paths, counts).
MessageRole
Message author role.
ReportValue
Why a /context line has no number: honest provenance, never a fabricated zero.
RetryClass
Coarse retry classification.
SegmentChange
Previous-turn comparison state for one cache segment (spec §6.6).
StopReason
Provider-assigned stop reason, normalized.
SystemSegmentKind
TraceArm
Current arm state.
TraceKeyError
Typed failure for digest-key loading.
TranslationAction
What a provider adapter did to a non-representable element.
TranslationElement
Which structural element was affected.
TransportKind
Which wire protocol carried the request.
UsageProvenance
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§

TraceSink
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 id into a fresh private file. Fail-closed: requires allow_content_export, an existing unexpired bundle, and re-redacts before writing. Consumes (deletes) the bundle.
export_metadata
Export all records whose turn_id or request_id equals id from the trace JSONL at trace_log into a fresh private file at output.
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 WireMeta used by transports — there is no re-serialization path.