Files
yvgude--lean-ctx/docs/reference/21-context-time-machine.md
wehub-resource-sync 26382a7ac6
CodeQL / Analyze (javascript-typescript) (push) Waiting to run
JetBrains Plugin / Actionlint (push) Waiting to run
CodeQL / Analyze (actions) (push) Waiting to run
CodeQL / Analyze (rust) (push) Waiting to run
JetBrains Plugin / Validation (push) Waiting to run
JetBrains Plugin / Build (push) Waiting to run
JetBrains Plugin / Test (push) Blocked by required conditions
Security Check / Security Scan (push) Waiting to run
CI / Clippy (push) Failing after 15m13s
CI / Test (ubuntu-latest) (push) Failing after 16m1s
CI / Test (macos-latest) (push) Has been cancelled
CI / Test (windows-latest) (push) Has been cancelled
CI / Build (no embeddings / no ORT) (push) Has been cancelled
CI / Format (push) Has been cancelled
CI / Cookbook (Node) (push) Has been cancelled
CI / Pi Extension (Node) (push) Has been cancelled
CI / Rust SDK (lean-ctx-client) (push) Has been cancelled
CI / Embed SDK (lean-ctx-sdk) (push) Has been cancelled
CI / Python SDK (leanctx) (push) Has been cancelled
CI / Hermes Plugin (Python) (push) Has been cancelled
CI / SDK Conformance Matrix (push) Has been cancelled
CI / Coverage (push) Has been cancelled
CI / cargo-deny (push) Has been cancelled
CI / Adversarial Safety (push) Has been cancelled
CI / Benchmarks (push) Has been cancelled
CI / Output-Quality Gate (eval A/B) (push) Has been cancelled
CI / Documentation (push) Has been cancelled
CI / CI Green (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:35:30 +08:00

5.7 KiB

Journey 21 — Context Time Machine (Snapshots)

You want a time axis on the context layer: capture what the model saw at a commit, replay why it acted, then reproduce, resume or share that exact state. This journey covers lean-ctx snapshot — git-anchored, content-addressed, Ed25519-signed snapshots that verify offline, the same trust model as the savings ledger, applied to temporal state.

Source files referenced here:

  • rust/src/cli/snapshot_cmd.rscmd_create, cmd_list, cmd_show, cmd_verify, cmd_restore, cmd_publish, cmd_import
  • rust/src/core/context_snapshot/mod.rs — module root + re-exports
  • rust/src/core/context_snapshot/types.rsCONTEXT_SNAPSHOT_V1 structs (git anchor, slices, signature)
  • rust/src/core/context_snapshot/builder.rsSnapshotOptions, build, create
  • rust/src/core/context_snapshot/digest.rscanonical_body, compute_id, finalize_id (BLAKE3 content id)
  • rust/src/core/context_snapshot/signing.rssign_snapshot, verify_snapshot (Ed25519)
  • rust/src/core/context_snapshot/timeline.rs — append-only timeline index
  • rust/src/core/context_snapshot/restore.rsRestoreOptions, GitRestore, SessionMerge, restore
  • rust/src/core/context_snapshot/publish.rsPublishOptions, PublishOutcome, ImportOutcome, publish, import
  • rust/src/core/agent_identity.rs — persistent per-machine Ed25519 keypair (shared with the savings ledger)

Contract: docs/contracts/context-snapshot-v1.md.


0. The principle

A snapshot is a distilled, signed view of the context layer at one git commit — not a copy of your repo. It bundles slices of the IR, the decisions and knowledge in play, the savings-ledger slice and the live session. The snapshot_id is a BLAKE3 hash of the canonical body, so the id is the content; an Ed25519 signature binds origin. Nothing leaves your machine unless you explicitly publish.


1. The snapshot model — CONTEXT_SNAPSHOT_V1

Defined in types.rs. A snapshot bundles:

Slice Holds Source
Git anchor Commit SHA + dirty flag at capture builder.rs (via core::git)
IR digest The distilled view the model saw builder.rs
Decisions & knowledge Session decisions + project facts builder.rs (session + knowledge)
Ledger / ROI slice Token savings booked to that point builder.rs (savings_ledger)
Session state Task, touched files, findings core::session
Signature Ed25519 over the content id signing.rs

The canonical body and id are computed in digest.rs (canonical_bodycompute_id/finalize_id, BLAKE3). Editing any byte of the body changes the id and breaks verify_snapshot.


2. The snapshot command surface

snapshot_cmd.rs dispatches on the first argument.

Command Code path Leaves machine?
snapshot create cmd_createcontext_snapshot::create (builder.rs) → sign → append timeline No
snapshot list [--json] cmd_listtimeline::* (append-only index) No
snapshot show <id> cmd_show → load snapshot by id No
snapshot verify <id> cmd_verifysigning::verify_snapshot + digest recompute No
snapshot restore <id> [--git] cmd_restorerestore::restore (SessionMerge, optional GitRestore) No
snapshot publish <id> [--out FILE] cmd_publishpublish::publish (signs if needed) Only the file you share
snapshot import <file> cmd_importpublish::import (verifies, then appends) No (any machine)

3. Capture & timeline

create (builder.rs) reads the live context layer, builds the body, computes the BLAKE3 id (digest.rs), signs it (signing.rs) and appends one JSON artifact to the append-only timeline (timeline.rs). The timeline is the spine for replay (list/show) and for the cockpit Replay view.

lean-ctx snapshot create        # context_snapshot::create → sign → timeline append
lean-ctx snapshot list --json   # timeline index, newest first
lean-ctx snapshot show <id>     # full distilled state behind one snapshot

4. Restore & resume — restore.rs

restore merges the snapshot's session back into the live session (SessionMerge); with --git it also checks out the anchored commit (GitRestore).

lean-ctx snapshot restore <id>          # session slice only
lean-ctx snapshot restore <id> --git    # also check out the anchored commit

--git refuses a dirty tree — it never silently discards uncommitted work (RestoreOptions/GitRestore guard). Replay to understand; restore to continue.


5. Share & publish — publish.rs

publish writes a single signed, portable file (PublishOutcome); import verifies it and appends it to the local timeline (ImportOutcome), idempotently. A tampered file is refused.

lean-ctx snapshot publish <id> --out ./review.ctxsnapshot.json   # PublishOptions
lean-ctx snapshot import ./review.ctxsnapshot.json               # verify → timeline

Only the snapshot body travels — never your repo, prompts or code.


6. The trust model

A verified snapshot answers two questions, both offline (signing::verify_snapshot):

  • Integrity — the body is unchanged: the BLAKE3 snapshot_id (digest.rs) and the Ed25519 signature both cover the canonical payload.
  • Origin — produced by the holder of a specific keypair (agent_identity.rs, the same per-machine key the savings ledger uses).

This is the CONTEXT_SNAPSHOT_V1 contract: trust by construction, not by claim — extended from "what you saved" to "what the model saw, when."