Format follows Keep a Changelog. This project uses Semantic Versioning; the bundle format carries its own independent version number, documented in docs/protocol.md.
W5 work, ahead of the next tag. See docs/roadmap.md.
- Chunk-granular SSE record and replay, verified against a real flushing upstream: one recorded chunk per flush, those boundaries reproduced on replay, and the first event reaching the agent before the stream ends rather than being buffered.
LlmRequest.Streamingis now populated by the recorder — anAccept: text/event-streamheader or a top-level"stream": truein the JSON body — where previously only the synthetic bundle generator ever set it, so every real bundle understated its own traffic.- MCP servers recorded behind the mediator: a JSON-RPC 2.0
tools/callrequest and its response are recognised and recorded asToolCallRequest/ToolCallResult, correlated by a newExchangefield on each, added alongside the ordinaryLlmRequest/LlmResponseChunk/LlmResponseEndtranscript that already covers the same exchange and that replay already matches against.
v0.1, standing alone as a complete artifact: containment, deterministic replay, forking, and tamper-evident audit anchored in a public transparency log. Verified end to end on kernel 6.17 — the demo records, verifies, replays equal, forks with an injection stripped, and renders; a run is anchored in the public Sigstore log and its inclusion checked from a second machine that never saw the run. See docs/roadmap.md and docs/build-log.md.
hark fork -at N [-patch FILE]— replays a recorded prefix, checking it action by action against the parent as it happens, applies a patch to the response at the branch point, and goes live from there. Refuses in three distinguishable ways rather than overstating a fork it did not perform:FORK-DIVERGED,FORK-INCOMPLETE,FORK-UNPATCHED.hark report— renders a bundle as one self-contained HTML file. No server, no framework, no JavaScript, no external request.- Transparency-log anchoring:
hark run -anchorandhark fork -anchorsubmit the signed tree head to Sigstore Rekor;hark verifyfetches the entry, checks it covers this run, and recomputes the log's root from the inclusion proof. Anchoring is never fatal — a log that is down must not mean a run cannot be recorded. hark verify -offlineand-rekor URL.-upstream HOST=ADDRand-upstream-ca FILEonrunandfork, recorded inRunStartso a bundle cannot claim it reached a host it did not.demo/— the prompt-injection incident, hermetic: no API key, no cost, no network.- Benchmark harnesses for mediated-call overhead (p50/p99), replay wall time, log size by event kind, and verify and inclusion-proof cost at 100k events.
- ADR-0008 (a fork is a verified prefix and a live suffix) and ADR-0009 (upstream redirection is recorded, not hidden).
- A real credential could reach the log.
buildEnvappended the placeholder to the supervisor's environment instead of replacing the inherited variable, and CPython keeps the first of a duplicated name, so an operator runningAPI_KEY=... hark runhanded the agent the real value.Broker.ContainsSecret— documented as the recorder's assertion and called by nothing — is now wired in, and refuses to write such an event at all. - Landlock rule handles are opened before capabilities are dropped, and
Launchrefuses up front when a granted path is unreachable by a process with no capabilities. A clone in a mode-0750 home directory is the ordinary case. - Credential substitution happens in playback too, so a replayed bundle contains the
SecretInjectedevents its recording does. The digest stops comparingValueHash, which a replay cannot have. - A data race between
ServeandClosein the shim, and an exported field that invited another.
- The mediator decides playback per exchange rather than per connection, and dials upstream lazily, which is what lets a fork hand over mid-connection. A replayed run still opens no outbound connection at all.
- The shim gained a fork mode: recorded clock and RNG values up to the branch point, real ones after.
- Bundle format version 1: header, hash-chained frames, sealed footer.
internal/hashchain— domain-separated BLAKE3 leaf, node and chain constructions.internal/mmr— append-only Merkle Mountain Range with O(log n) inclusion proofs, verifiable without the tree.internal/logfmt— 16 event kinds, canonical CBOR payloads, frame codec.internal/signer— Ed25519 signed tree heads.internal/bundle— writer, reader and end-to-end verifier that recovers the verified prefix of a damaged or truncated bundle.internal/runid— ULID run identifiers.hark verify, with-keyfor pinning and exit codes distinguishing verified, broken and truncated.hark inspect,hark prove(generate and check),hark keygen.hark synth, which writes a synthetic prompt-injection bundle with-corruptand-truncateoptions so the verifier can be exercised before the recorder exists.
hark bisect exits 2. See docs/roadmap.md.