Skip to content

feat: Phase 1 — zero-config verifiable Claude Code capture (korg-ledger@v1) - #8

Merged
New1Direction merged 29 commits into
mainfrom
feat/phase1-unified-verifiable-capture
Jun 15, 2026
Merged

New1Direction merged 29 commits into
mainfrom
feat/phase1-unified-verifiable-capture

Conversation

@New1Direction

Copy link
Copy Markdown
Owner

Summary

Makes Korg's core promise real for the data users actually generate: every Claude Code session is captured passively, cross-platform, into a tamper-evident korg-ledger@v1 chain that any third party can independently verify — turning the project from "a thing you set up" into "a thing that's just on."

This implements Phase 1 of the "verifiable flight-recorder for AI agents" direction (design + plans under docs/superpowers/). It unifies on the one verifiable ledger format, ships a zero-config capture hook, backfills history, and reserves the Phase-2 trust slots — all without breaking the frozen cross-language conformance vectors.

What's included

  • adapters/korg-ledger-py/ (new) — a stdlib-only, third independent conformant producer of korg-ledger@v1 (alongside the Rust crate and JS verifier). LedgerWriter hash-chains JournalEvent JSONL with HLC ordering, a strictly-earlier causality gate, HMAC mode, resume-from-tip, and a concurrency-safe append (re-reads the chain tip under an exclusive lock so overlapping writers can't fork the chain).
  • Zero-config capture (adapters/claude-code/) — make_canonical_emit + a korg-hook driver registered on PostToolUse/Stop/SubagentStop. It reuses the existing session parser, captures full richness (llm_inference, tokens, cache, tool results, the §2a causal spine) into a per-session verifiable ledger ~/.korg/sessions/<id>.jsonl, and never raises / always exits 0.
  • One-command setup (adapters/korg-setup/) — claude_settings.py idempotently registers the hook in ~/.claude/settings.json; the macOS-only launchd daemon is demoted to opt-in (--daemon).
  • Retroactive history — korg-backfill re-derives canonical per-session ledgers from every historical transcript (idempotent), plus a guarded migrator for the legacy flat ~/.korg/claude-events.jsonl.
  • Format reservation (lockstep) — event_sig is excluded from the hash preimage across all four implementations (Rust, two Python, JS); the Rust JournalEvent gains a wire-compatible event_sig field; an additive LedgerRewind variant and the external-anchor path are reserved for Phase 2.

Key design decisions

  • Per-session ledger files (not one interleaved file): one verifiable chain per causal session — dodges cross-session races, matches the per-session root, and is the shareable "verify in a browser" receipt Phase 3 will publish.
  • Full-reparse + emitted_count capture: PostToolUse fires after a tool's result lands, so re-parsing the transcript each firing captures results the buffered parser fills in by mutation (which incremental tail mode drops).
  • Backfill preferred over flat migration: source transcripts persist and are richer, so backfill produces output identical to live capture; migration is a guarded fallback that never duplicates backfill.

Test plan

All verified locally before this PR:

  • 145 Python tests pass across the three packages (korg-ledger-py / claude-code / korg-setup), incl. conformance against the frozen vectors, cross-producer verification by the spec's own oracle, idempotency, and never-raises robustness.
  • Rust: cargo test -p korg-ledger -p korg-registry green, incl. conformance_vectors_reproduce_the_frozen_oracle (frozen vectors byte-identical with the new field) and the LedgerRewind serialization test.
  • JS: node spec/korg-ledger-v1/js/conformance.mjs PASS (incl. the new event_sig excluded assertion).
  • Python spec oracle: python3 spec/korg-ledger-v1/conformance.py PASS.
  • End-to-end: the real korg-hook stdin entry point and the korg-backfill CLI both produce per-session ledgers verified clean by the independent spec oracle.

Out of scope / follow-ups

  • Plan 2b — JSONL-on-disk storage refactor for the server/runtime CapabilityJournal (internal; off the user path; capture ledgers are already JSONL).
  • Plan 6 — point recall-mcp at the per-session ledgers, add a cross-producer conformance CI gate, and the honest-docs pass.
  • Phase 2 — populate event_sig (per-event signing), external time-anchoring / transparency-log notarization, wire rewind() to append LedgerRewind.

🤖 Generated with Claude Code

@New1Direction

Copy link
Copy Markdown
Owner Author

Update: Plan 6 landed on this branch — Phase 1 is now complete in this PR.

The "Plan 6" item listed under Out of scope / follow-ups has been implemented and pushed:

  • Readers unified — recall-mcp now reads the canonical per-session ledgers (_normalize_record handles both the canonical JournalEvent shape and the legacy flat format), and its default source is ~/.korg/sessions/.
  • Cross-language conformance CI gate — a new conformance job runs the Python and JS spec oracles plus the producer/capture/setup/reader pytest suites on every push (Rust frozen-vector conformance is already gated by the existing cargo test). Verified locally: 164 green.
  • Honest docs — the claude-code adapter README now describes the verifiable per-session capture path and marks the flat claude-events.jsonl as legacy.

Still genuinely out of scope (follow-up PRs): Plan 2b (JSONL-on-disk for the server-side CapabilityJournal), and Phase 2 (populate event_sig signing + external anchoring + wire rewind() → LedgerRewind).

@New1Direction
New1Direction merged commit 6a2c87a into main Jun 15, 2026
3 checks passed
@New1Direction
New1Direction deleted the feat/phase1-unified-verifiable-capture branch June 15, 2026 00:24
New1Direction added a commit that referenced this pull request Jun 22, 2026
Lands the stacked branch 'feat/phase1-unified-verifiable-capture' (PR #8) onto main.
New1Direction added a commit that referenced this pull request Oct 5, 2026
Bump the korg runtime crates from 0.1.0 to 0.2.0 (korg-bridge keeps its own
bridge-v* line) and cut the [0.2.0] changelog section from Unreleased, filling
in the merged work it was missing (#8-#22).


Claude-Session: https://claude.ai/code/session_01QsuMoxNk88vZYnxPepuUKV

Co-authored-by: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant