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.

Re-exports§

pub use controls::default_capture_dir;
pub use controls::ContentCapture;
pub use controls::TraceArm;
pub use controls::TraceControls;
pub use controls::TraceStatusReport;
pub use controls::CAPTURE_MAX_BYTES;
pub use controls::CAPTURE_TTL;
pub use controls::CONTENT_CAPTURE_SCHEMA;
pub use diagnostics::CacheActivity;
pub use diagnostics::CacheSnapshotStore;
pub use diagnostics::ContextReport;
pub use diagnostics::ReportValue;
pub use emit::wire_meta_from_sent_bytes;
pub use emit::AttemptClock;
pub use emit::CollectingTraceSink;
pub use emit::NoopTraceSink;
pub use emit::RequestCorrelation;
pub use emit::RequestStructure;
pub use emit::RequestTracer;
pub use emit::TraceContext;
pub use emit::TraceSink;
pub use execution::ExecutionCorrelation;
pub use export::export_content;
pub use export::export_metadata;
pub use export::redact_value;
pub use export::sweep_expired_captures;
pub use export::ContentExport;
pub use export::ExportError;
pub use export::MetadataExportStats;
pub use export::CONTENT_EXPORT_SCHEMA;

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§

BlockMeta
One block within a message: kind + size only.
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.
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.
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}.
MessageMeta
One conversation message: role and per-block metadata.
PrefixMeta
Stable-prefix metadata for cache diagnosis: bytes + keyed digest.
RequestAnatomy
Normalized request anatomy: counts only.
RequestTrace
One synaps-request-trace/1 record: metadata for a single request attempt. Field order is the canonical, deterministic serialization order.
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.
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.
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
MessageRole
Message author role.
RetryClass
Coarse retry classification.
SegmentChange
Previous-turn comparison state for one cache segment (spec §6.6).
StopReason
Provider-assigned stop reason, normalized.
SystemSegmentKind
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§

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.

Functions§

default_digest_key_path
Default installation-scoped key path: <synaps base dir>/trace/digest.key.
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.