directory of content-addressed object files (one per hash).
Verifiers ignore unknown non-normative files unless explicitly configured to reject them.
The Manifest
{
"agef_version": "0.1",
"producer": {"name": "akmon", "version": "2.0.0"},
"session": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"head": "5c1f8b2a3d4e7f6a8b1d3e2c4f6a8b9d2c3a4b5c6d7e8f9a0b1c2d3e4f5a6b7c",
"created_at": "2026-05-06T09:14:02Z",
"ended_at": "2026-05-06T09:14:18Z"
},
"hash_algorithm": "sha256",
"object_count": 12,
"event_count": 9
}
A reader who has never seen the producer can answer four things from this object: which version of the format, who wrote it, when, and how big it is. Writers must keep counts honest. Readers must reject malformed or incomplete required fields.
Default hash algorithm is sha256. Readers must support sha256 and may support blake3. Bundles that declare unsupported algorithms must be rejected. Hex appears only in the manifest (session.head) and in object filenames. Hashes inside CBOR-encoded events are 32-byte byte strings.
The Events Stream
events.bin is the substance. It is a sequence of records, each framed by a 4-byte unsigned big-endian length prefix followed by exactly that many bytes of canonical CBOR encoding one event.
Length-delimited framing was a deliberate trade. It supports partial recovery from truncation and lets a verifier scan deterministically. Producers commit to canonical CBOR per RFC 8949.
Each event encodes:
parents, an array of zero or more parent event hashes.
kind, one of the closed event kinds in v0.1.
emitted_at, a CBOR tag 1 timestamp (integer epoch seconds, or floating point for sub-second precision).
sequence, monotonic per session, starting at 0.
Linkage rules are strict in v0.1:
sequence starts at 0 and increases by exactly 1 per event.
- Every event except
SessionStart has at least one parent.
SessionStart has exactly zero parents.
- Every non-
SessionStart event in v0.1 has exactly one parent, and that parent is the hash of the immediately preceding event by sequence. Multi-parent events are reserved for future versions.
- Event hashes are computed over canonical CBOR bytes of the full event envelope.
- Event ordering in
events.bin matches sequence.
Event Kinds in v0.1 (Closed Set)
Readers must recognize exactly these kinds in v0.1. Unknown kinds are rejected.
SessionStart: opens the session, fields cwd_hash and config_hash.
UserTurn: a user prompt, field prompt_hash.
ProviderCall: a model provider call, field provider_id, an attempts[] array of AttemptRecord, optional stream_hash.
ToolCall: a tool execution, fields tool_id, input_hash, output_hash, optional side_effects_hash.
RetrievalCall: a retrieval, fields index_id, query_hash, results_hash.
PermissionGate: a policy decision, fields policy_id, decision (string, recommended lowercase verbs like allowed, denied, deferred), context_hash.
AssistantTurn: an assistant message, fields message_hash, optional tool_calls_hash.
SessionEnd: closes the session, optional summary_hash.
ProviderCall.attempts[] preserves chronological order. Each AttemptRecord has attempt_number (1-indexed), started_at, ended_at, a closed AttemptStatus, request_hash, optional response_hash, optional stream_hash, optional error_message. AttemptStatus is one of Success, RateLimited, NetworkError, ServerError, ClientError, Cancelled, or Other(string). v0.1 readers reject unknown variants.
Two design notes worth calling out:
PermissionGate.decision is open in v0.1. The spec recommends lowercase verbs but does not close the set. Closing it is a likely v1.0 change. If you are a producer, follow the recommendation now to make the v1 transition free.
AttemptStatus and EventKind are intentionally closed. The cost is that adding a new variant is a normative spec change. The benefit is that two implementations cannot legitimately disagree on the meaning of a record.
The Objects Directory
Every object referenced by an event hash field exists as a file at objects/<hex> where <hex> is the lowercase hex digest for the active hash algorithm. Object bytes hash to their filename digest. Objects are opaque bytes; AGEF v0.1 does not require MIME metadata.
A typical bundle has many small objects (prompts, tool inputs, tool outputs, file diffs) and a few large ones (full file contents). Storage is efficient because identical content hashes once.
Hashing Rules
default: sha256
optional: blake3
Readers must support sha256. They may support blake3. Within CBOR-encoded events, hashes must be encoded as CBOR byte strings (major type 2) of length 32 for both algorithms. Hex string representation is used only in manifest.json (session.head) and in object filenames. Once you internalize that, the rest of the spec falls into place.
Serialization Rules
Event payloads in events.bin use canonical CBOR (RFC 8949). manifest.json is UTF-8 JSON with sorted keys and LF endings. Timestamps in CBOR-encoded events use CBOR tag 1. Producers may emit either integer epoch seconds or floating point; readers must accept both. The reference implementation akmon-journal v0.1 emits integer epoch seconds. Timestamps in manifest.json use RFC3339 strings. Implementations may use any internal storage format; AGEF rules apply only to the bytes emitted in events.bin and to the bytes used for event hashing.
Verification Procedure
A conforming verifier runs this sequence:
- Extract the archive.
- Parse
manifest.json. Reject on schema or version failure.
- Read
events.bin using the 4-byte length-delimited framing.
- For each event: decode canonical CBOR, recompute event hash, verify
sequence monotonicity, verify all parents resolve to previously seen events, verify referenced content hashes resolve to files in objects/.
- For each referenced object: read bytes, hash with
manifest.hash_algorithm, compare to filename digest.
- Confirm
manifest.event_count equals decoded event count, manifest.object_count equals object file count, manifest.session.head equals terminal event hash, and SessionEnd hash matches manifest.session.head.
Pitfall Guide
- Hash Encoding Mismatch: Using hex-encoded strings inside CBOR events instead of raw 32-byte byte strings (major type 2). This breaks deterministic hashing and violates the spec's internal representation rules.
- Sequence & Parent Linkage Violations: Failing to increment
sequence by exactly 1 or omitting the required single parent for non-SessionStart events. This invalidates the cryptographic chain and allows silent event injection or dropping.
- Timestamp Format Inconsistency: Emitting RFC3339 strings inside
events.bin or failing to support both integer and floating-point CBOR tag 1. AGEF strictly requires CBOR tag 1 for event timestamps; RFC3339 is only valid in manifest.json.
- Object/Event Count Mismatch: Leaving
manifest.object_count or manifest.event_count out of sync with actual files/records. Verifiers will reject the bundle, and compliance audits will flag incomplete evidence.
- Unknown Event Kind/Status Handling: Silently ignoring or auto-accepting unknown
EventKind or AttemptStatus values. The spec mandates strict rejection to prevent semantic drift across producer implementations.
- PermissionGate Decision Standardization: Using arbitrary or uppercase strings for
PermissionGate.decision. While open in v0.1, deviating from recommended lowercase verbs (allowed, denied, deferred) creates unnecessary migration friction for v1.0.
- Truncation Recovery Neglect: Ignoring the benefits of 4-byte length-delimited framing. Producers and verifiers should implement stream scanning to recover valid prefix events from truncated
events.bin files, rather than failing the entire bundle.
Deliverables
- AGEF v0.1.1 Specification Blueprint: Complete architectural diagram of the
tar.zst bundle structure, cryptographic linkage model, and content-addressing workflow. Includes wire format mapping and versioning strategy.
- AGEF Compliance & Verification Checklist: Step-by-step validation matrix covering manifest schema validation, CBOR canonicalization, sequence/parent linkage verification, object hash matching, and count reconciliation.
- Producer Configuration & Bundle Generation Template: Ready-to-use configuration scaffolding for implementing AGEF producers. Includes default hash algorithm selection, timestamp formatting rules, event kind routing, and automated
tar.zst packaging scripts.