Skip to main content

Module writer

Module writer 

Expand description

JSONL append-only writer + rolling rotation.

RAM contract: a single event lands in two allocations (the JSON line that goes to disk + the serde_json::Value clone that goes to the broadcast hook). Rolling rotation streams through BufReader::lines into a temp file rather than slurping the whole file into a String.

§Hot-path write concurrency model

Disk persistence runs on a dedicated std::thread named zeroclaw-log-writer so record_event does not block on file I/O or fsync. The async runtime emits an event by serializing it once and try_send-ing onto a bounded std::sync::mpsc::sync_channel; when the channel is full (worker is slow or disk is stalled) the event is dropped with a tracing::warn! so a single slow disk cannot wedge an agent turn. The worker re-opens the active file per write (matching the prior single-threaded semantics — required because rolling trim and size-based rotation rename the file out from under an open handle), runs the rotation hooks inline, and calls sync_all on a periodic cadence (every SYNC_EVERY_N_WRITES writes or SYNC_INTERVAL of wall-clock time, whichever comes first). This trades per-event durability (the prior behaviour was sync_data after every write) for bounded write latency: a process crash may lose up to one sync interval of pending writes.

Constants§

EPHEMERAL_BROADCAST_MARKER
Top-level marker stamped onto a broadcast frame when it carries ephemeral_attributes (short-lived pairing secrets deep-merged into the live copy). Broadcast consumers use it to withhold the frame from any stream that is not bearer-authenticated — the frame’s secrets must fail closed rather than ride an unauthenticated /api/events subscriber. It is stamped only on the broadcast copy (never the persisted value, which drops ephemeral_attributes via serde(skip)) and is stripped by the SSE layer before delivery, so the public event shape is unchanged.

Functions§

flush_for_test
frame_carries_ephemeral_credentials
True when a broadcast frame was stamped with EPHEMERAL_BROADCAST_MARKER by record_event — i.e. it carries broadcast-only pairing secrets (QR payloads, pair codes) deep-merged into attributes.
init_from_config
llm_request_payload_policy
Resolved LLM-request-payload capture policy + the truncate cap, for the turn engine’s announce_llm_request. None when no writer is installed (the policy defaults to off, so callers treat “no writer” as “off”).
record_event
Emit one event. Always fans out to the broadcast hook + tracing event. If persistence is enabled, hands the serialized value to the disk worker via a bounded try_send. The hot path performs no file I/O.
runtime_trace_path
Public accessor for the canonical log file path. Used by the gateway’s /api/logs endpoint to know which file to stream.
strip_ephemeral_broadcast_marker
Strip the internal EPHEMERAL_BROADCAST_MARKER from a broadcast frame before it is delivered to a consumer, so the public event shape is unchanged. Returns whether the marker was present.