open-standards/jouleclaw/jouleclaw-rs/crates/jouleclaw-jcr1/conformance/event-log-vectors.json
Transaction Science 49175df95e jouleclaw: wave-54 — event-sourced agent substrate (ActiveGraph ingest)
Ingested from ActiveGraph (Nakajima, "The Log is the Agent",
arxiv 2605.21997, May 2026 — v1.0 May 2026, MIT/Apache). The
focused web search across 5 themes (event-sourced agent runtimes,
deterministic replay + content-addressed caching, multimodal data
primitives, context compression, durable workflows) confirmed
ActiveGraph is the uncontested 2026 SOTA at the event-sourced-
substrate layer. The other four themes have alternatives but
none with the same level of articulation; this wave ingests the
typed primitive JouleClaw's receipts + cascade had been pointing
at but didn't name.

1. jouleclaw-event-log (new crate) — typed substrate.
   - EventKind { Goal | Object | Relation { from, to, edge_kind } |
     LlmReq { request_hash, prompt_summary } | LlmResp {
     request_hash, response_summary, tokens } | ToolReq { tool_id,
     args_hash } | ToolResp { tool_id, args_hash, response_summary }
     | Patch | Receipt }. The Relation variant uses `edge_kind`
     (not `kind`) to avoid the silent serde-tag collision bug.
   - Event { prev_hash, ts_ns, kind, event_hash } sealed at
     append. EventLog::append computes prev_hash from the
     previous event's hash (genesis = BLAKE3 of zero bytes for
     the first event).
   - EventLog::verify_chain catches tampering at the first
     break with the exact index.
   - replay() — deterministic fold producing a ProjectedGraph
     (goal + typed objects + typed relations + receipts), each
     element annotated with the event_hash that produced it.
   - replay_strict() — compares a fresh fold to an expected
     projection byte-for-byte under canonical JSON; returns
     ReplayError::Divergence with the diverging content hashes.
     A green strict replay is a proof the run is reproducible
     (the published ActiveGraph claim).
   - ContentAddressedCache — populates from the log's LlmResp +
     ToolResp events, indexed by the documented 2026 SOTA
     convention: LLM key = BLAKE3 over (system, user_messages,
     model_id, tool_defs, output_schema); tool key = (tool_id,
     args_hash). On replay, a behavior firing with a recorded
     hash hits cache; no new model call.
   - lineage_of(log, object_id) — given an artifact, return every
     event in its causal chain (goal that motivated it, LlmReq/
     LlmResp pair that produced it, ToolReq/ToolResp if any,
     Object event itself, Relations referencing it after creation).
   - 13 tests.

2. jouleclaw-jcr1::event_log — JCR-1 event-log/1 schema.
   - EventLogReceipt { jc_receipt, id, closed_at, steward, log_id,
     head_event_hash, chain_depth, counts: EventLogCounts,
     total_tokens }.
   - 2 conformance vectors with embedded receipt_hash.
   - 3 jcr1 event_log tests.

3. Cross-language conformance — Rust + Python + Go verifiers all
   shipped, byte-equal across the three implementations. The
   three-impl pattern (matching JCR-1 v1) is preserved.

4. Demo binary — examples/wave54_event_log_replay.rs in
   jouleclaw-stack. Builds a 9-event agent run (goal → LLM
   exchange → tool exchange → object → relation → inline receipt),
   demonstrates: (1) replay determinism; (2) strict-mode rejection
   of a tampered projection with divergence pinned to a content
   hash; (3) cache-served replay of the recorded LLM request (no
   new model call); (4) lineage trace recovering 7 events in the
   causal chain back to the goal; (5) event-log/1 JCR-1 receipt
   sealed over the log snapshot.

The triangle (conservation + cone + oracle + elicitor) stays the
type system; wave-54 adds the event-sourced substrate that any
JouleClaw agent runtime can be built ON. The log IS the agent.

Workspace check clean.

Co-Authored-By: Claude Opus 4.7 <[email protected]>
2026-06-05 13:01:12 -04:00

61 lines
2.4 KiB
JSON

{
"spec": "JCR-1 event-log v1",
"schema_id": "event-log/1",
"canonical_encoding": "JSON with sorted object keys (recursively); UTF-8; no whitespace; no float coercion. receipt_hash is BLAKE3 hex of the canonical bytes.",
"note": "Two vectors covering the two states an event-log/1 receipt can land in: a small log snapshot (goal + 2 objects + 1 relation + 1 llm_req/resp pair, 120 tokens) and a larger session snapshot (multiple LLM/tool calls, several objects, a few receipts emitted inline). Implementers in any language MUST round-trip every receipt under canonical encoding and assert byte-equal receipt_hash against the embedded value.",
"vector_count": 2,
"vectors": [
{
"n": 1,
"description": "Small log snapshot: goal + 2 objects + 1 relation + 1 LLM exchange; 120 tokens.",
"receipt_hash": "e3081135c35e31294b128ceb5d075c1b35e5ead4ab837b6aad7d03eb65f18c04",
"receipt": {
"jc_receipt": "event-log/1",
"id": "log-demo:b3abc",
"closed_at": "2026-06-05T00:00:00Z",
"steward": "did:keri:EJ9testStewardAID000000000000000",
"log_id": "log-demo",
"head_event_hash": "b3abcdef0123456789abcdef0123456789abcdef0123456789abcdef0123",
"chain_depth": 5,
"counts": {
"goal": 1,
"object": 2,
"relation": 1,
"llm_req": 1,
"llm_resp": 0,
"tool_req": 0,
"tool_resp": 0,
"patch": 0,
"receipt": 0
},
"total_tokens": 120
}
},
{
"n": 2,
"description": "Larger session snapshot: 3 goals, 7 objects, 4 relations, 3 LLM exchanges, 2 tool exchanges, 1 patch, 2 receipts emitted inline; 1450 tokens.",
"receipt_hash": "99a452d54d9767d487f411d1c147350fff39c99dea6256d5dd134b9afba7668b",
"receipt": {
"jc_receipt": "event-log/1",
"id": "log-session-7:b3def",
"closed_at": "2026-06-05T00:01:00Z",
"steward": "did:keri:EJ9testStewardAID000000000000000",
"log_id": "log-session-7",
"head_event_hash": "b3defabcdef0123456789abcdef0123456789abcdef0123456789abcdef01",
"chain_depth": 22,
"counts": {
"goal": 3,
"object": 7,
"relation": 4,
"llm_req": 3,
"llm_resp": 3,
"tool_req": 2,
"tool_resp": 2,
"patch": 1,
"receipt": 2
},
"total_tokens": 1450
}
}
]
}