Introduction
Akmon is a tamper-evident evidence and verification layer for AI agents. It sits on top of whatever agent you already run, through OpenTelemetry or with Akmon's own reference agent. Every session becomes a portable, content-addressed, cryptographically signed record that someone else can verify for themselves.
The point that matters most: a third party can check a signature offline with nothing but openssl, with no Akmon install and no cloud service.
That is the whole pitch. When an AI agent changes something, you may have to prove later what it actually did, to a regulator or auditor who does not trust you and does not run your tools.
Under the EU AI Act, the high-risk logging obligations in Article 12 and Annex IV start to apply on 2 August 2026.
Akmon is producer-agnostic. The verification chain is the product, not the agent. This page explains the problem Akmon is designed to solve, the design choices behind it, what ships in v2.x (latest v2.2.0, AGEF v0.1.3), and where Akmon is intentionally not trying to compete.
v2.2.0 highlights
v2.2.0 is the trust-layer release. It turns Akmon into a producer-agnostic evidence and verification layer and makes that claim provable end to end. The toolchain:
- Import any agent:
akmon otel import <trace.json>turns an OpenTelemetry GenAI trace into an AGEF session. It reads the current v1.37 structured form and the older v1.36-and-earlier message-event form that most deployed agents still emit. The capture level is recorded honestly (imports arestructural, never dressed up as a full recording). - Generate a key:
akmon bundle keygen --out k.pk8 --public-out k.pubcreates an Ed25519 signing key (PKCS#8 v2). - Sign:
akmon bundle sign <bundle> --key k.pk8adds an offline Ed25519 signature over the session head. - Attest an operator:
akmon bundle attest <bundle> --key op.pk8 --operator-id you@org --role approverrecords the accountable person behind a session. - Verify:
akmon bundle verify <bundle> --verify-key k.pub --require-signaturechecks integrity, the signature, any operator attestation, and the capture level. - Prove with openssl:
akmon bundle prove-openssl <bundle> --verify-key k.pub --out-dir proofwrites the statement, signature, and public key so anyone can check the signature with plainopenssl. - Verify on its own:
agef-verify <bundle> --verify-key k.pubis a small, separate binary for auditors that does not need the full Akmon install.
See the release notes and the walkthrough, from an OTEL trace to an offline openssl proof.
The problem Akmon was built to solve
When an AI agent changes something, you may have to prove later what it actually did. The person asking could be a regulator, a security reviewer, or an incident team, and it might be years after the fact. They may not trust you, and they may not run your tools. The blocker is usually not raw model capability. The blocker is evidence quality.
Most agent telemetry cannot stand up to that. It lives in process memory, or in mutable, unsigned spans, and "the AI did it" is not an answer anyone will accept. Teams repeatedly run into the same questions:
- What exactly did the agent read?
- What tools did it call?
- What side effects happened on disk or in shell?
- Which policy decision allowed each side effect?
- Can a third party verify the record's integrity and authorship without trusting you?
In many tools, those answers are partial or ephemeral. You get a useful session in the moment, but weak forensic value later. That gap is acceptable for low-risk prototyping. It is a hard stop for regulated release workflows.
Akmon treats the evidence itself as the thing you ship. It takes a session, either your own or one from any OpenTelemetry-instrumented agent, and turns it into a sealed record. Someone else can then check that record's integrity and authorship independently, with standard tools, even on a machine that has never heard of Akmon.
Provider lock-in is the second recurring failure mode. Model quality, latency, legal terms, and cost change over time. If your agent workflow depends on one provider's roadmap, your engineering process inherits that business risk. Regulated teams and enterprise teams often need optionality: local models for sensitive code paths, hosted models for throughput, and explicit controls over where prompts go.
Operational portability is the third issue. Real engineering happens in mixed environments:
- local laptops,
- remote SSH sessions,
- CI runners,
- hardened enterprise hosts,
- restricted network segments.
If the agent requires a specific IDE plugin stack or heavyweight runtime chain, adoption collapses outside a narrow desktop workflow. Akmon is built for those constraints first.
The design decisions (and why)
Single binary
Akmon ships as a standalone Rust binary. That has practical effects beyond install convenience.
- Runtime state is explicit and portable.
- Environment drift is reduced relative to dynamic plugin/runtime stacks.
- CI and remote-host deployment stay simple.
If two machines run the same Akmon version, behavior is easier to reason about and support. Troubleshooting tends to focus on policy, provider config, repository state, or model behavior rather than host runtime mismatch.
Bring your own key / bring your own model
Akmon supports Anthropic, OpenAI, OpenRouter, Groq, Azure OpenAI, Bedrock, OpenAI-compatible endpoints, and Ollama. Model selection remains an operator decision.
That matters for:
- commercial leverage,
- legal and data-boundary control,
- outage resilience,
- per-task cost/performance tuning.
The objective is not to force one "best model." The objective is to keep model strategy decoupled from tooling adoption.
Typed permission boundaries
Akmon treats tool operations as explicit capabilities, not implicit side effects. Reads, writes, shell execution, and network actions are mediated through policy and approval flow.
This creates a clear boundary:
- the model can request an action,
- the runtime can enforce policy,
- the operator can review and approve or deny.
That boundary is critical in environments where side effects must be reviewable and explainable.
Session evidence as a first-class output
Most tools treat logs as support artifacts. Akmon treats the session artifact as a product output.
A useful AI run is not just "did it produce code." A useful AI run is "can we verify what happened and carry that evidence through review, CI, and audit."
Context discipline
Akmon encourages explicit context shaping rather than perpetual thread growth. Teams typically get better outcomes when they separate work into:
- exploration,
- planning/specification,
- implementation and verification.
This reduces context drift and makes outcomes easier to reproduce.
The evidence and verification model
Akmon records each session as a content-addressed event journal with cryptographic chain integrity. That gives a reviewer a concrete object to inspect instead of reconstructing behavior from partial logs. The session, whether Akmon produced it or it came in from another agent's trace, is then exported as a portable AGEF bundle that can be signed and verified anywhere.
At a high level:
- Events are linked in order and integrity-checked.
- A bundle can carry an offline Ed25519 signature over the session head, and an operator attestation that records the accountable person.
- A third party can verify integrity and authorship with
agef-verify, or with plainopensslafterakmon bundle prove-openssl, with no Akmon install required. - Two sessions can be compared structurally and at field level.
- Sessions Akmon produced itself can be replayed deterministically against recorded providers and tools.
Akmon implements AGEF v0.1.3 as a practical reference implementation for portable AI-agent session evidence. v0.1.3 adds two optional pieces on top of the hash chain: offline Ed25519 signatures and operator attestations. Both are optional, so a plain bundle stays small and older readers keep working. The goal is operational interoperability and independent verifiability, not vendor-specific lock-in.
Command surface
The verification chain is the core:
otel importto bring in any OpenTelemetry GenAI trace (v1.37 structured and the legacy v1.36-and-earlier message-event form),bundle keygen,bundle sign, andbundle attestto produce a key, sign the head, and record an operator,bundle verify,agef-verify, andbundle prove-opensslfor integrity, signature, attestation, and capture checks, including offlineopensslproof,bundle export/bundle import,inspect,diff, andredactfor portable and sanitized handoff,chat/--taskfor Akmon's own reference agent, withaudit,evidence,verify, andreplayfor full-capture sessions.
These commands are meant to compose. A common pattern for an imported session is:
- import a trace with
otel import, - export it as a bundle and sign it,
- verify integrity, signature, and capture level,
- emit an
opensslproof a stranger can check.
Who Akmon is for
Akmon targets teams that must prove what AI did, not just benefit from what AI suggested.
Aerospace and avionics teams
For organizations working under DO-178C-style qualification and evidence pressure, session traceability and deterministic replay reduce ambiguity during review.
Medical device software teams
For IEC 62304-oriented development, controlled side effects and audit-ready artifacts support stronger change documentation and risk controls.
Automotive software teams
For ISO 26262-influenced workflows, reproducible agent behavior and explicit evidence chains improve confidence in AI-assisted modifications.
Finance and enterprise controls teams
For SOC 2 or similar control environments, the session artifact model helps demonstrate governance over AI-driven code changes.
Defense and high-assurance environments
For CMMC-style and restricted-network contexts, single-binary deployment, policy boundaries, and provider flexibility are practical adoption requirements.
Platform and SRE teams
For teams running large automation surfaces in CI, structured outputs and verifiable artifacts make autonomous tasks easier to gate and monitor.
What Akmon is intentionally not
Akmon is opinionated about scope. That includes clear non-goals.
- It is not trying to replace IDE-native completion workflows.
- It is not optimized for maximum "chat polish" over evidentiary rigor.
- It is not tied to a single model provider's product strategy.
- It is not built around opaque, non-replayable agent behavior.
Those tradeoffs are deliberate. Akmon prioritizes reviewability, operational control, and portability over broad UX coverage.
Practical usage guidance
Use model tiers intentionally
Use lower-cost models for exploration and mechanical edits. Use stronger models for architecture or multi-file reasoning. This keeps cost predictable without forcing one model for every task.
Keep project context explicit
Maintain AKMON.md with constraints, architecture notes, and decision boundaries.
High-quality local context usually improves output quality more than longer ad-hoc prompts.
Treat evidence generation as part of done
In regulated workflows, task completion includes evidence readiness. A run is not complete until required verification and artifact checks pass.
Gate automation with policy and verification
For headless workflows, use explicit policy, budget limits, and integrity checks so autonomous runs fail closed when constraints are violated.
Adoption notes for regulated teams
Teams adopting Akmon in regulated contexts usually move in phases instead of switching everything at once.
Phase 1: Observe
Start by running scoped tasks with full session capture enabled. Focus on understanding evidence quality and policy fit before broad automation.
Phase 2: Constrain
Introduce tighter policy defaults and approval rules for writes, shell, and network operations. Treat denied operations as useful feedback about control boundaries, not as friction to bypass.
Phase 3: Verify
Standardize post-run verification steps in CI and review checklists. Require session integrity checks for categories of changes where auditability is mandatory.
Phase 4: Operationalize
Package repeatable workflows for common engineering tasks and gate them with policy and evidence requirements. The goal is consistent, reviewable operation rather than maximal autonomy.
This phased approach keeps rollout practical:
- engineers get immediate utility,
- governance teams get deterministic evidence,
- reliability standards are raised without blocking delivery.
Where to go next
- Install and first run: Getting Started
- Headless automation: Headless mode
- Interactive usage: Interactive mode
- Policy controls: Policy profiles
- Core terms: Glossary
- Reviewer handoff: Regulated reviewer flow
- Session comparison: Session diff reference
- Architecture for contributors: Contributing architecture
Trust and threat model
Documented for Akmon 2.2.0.
Who this is for
Security engineers, auditors, and reviewers who need to understand exactly what a verified Akmon record proves, what it does not prove, and the cryptographic and threat assumptions behind it. Read this before you rely on an Akmon bundle as evidence.
What a verified record proves
Akmon turns an AI agent session into a portable, content-addressed record. Verification answers a small, precise set of questions. Treat each one independently.
- Integrity. The session record is internally consistent and nothing was altered after the fact. Every object is content-addressed by SHA-256, the events form a hash-linked chain, and the head is the hash of the terminal event. Re-hashing the objects and rewalking the chain reproduces the head. If any byte changed, the head changes and verification fails.
- Which key sealed it. When the bundle carries an Ed25519 signature, a successful check with a public key you supply proves that the holder of the matching private key signed this exact head. It proves the key, not the person.
- Which operator key claims accountability. When the bundle carries an operator attestation, a successful check with an operator public key you supply proves that the holder of that key signed a statement binding the session head to a set of self-asserted identity fields. Again, this proves the key, not the named person.
What a verified record does NOT prove
These boundaries are deliberate. State them plainly to anyone who consumes the evidence.
- It does not make the agent safe or correct. Akmon records what happened. It does not judge whether the agent's actions were good, safe, authorized, or free of error. A faithfully recorded, cryptographically sound bundle can still describe a bad session.
- It does not certify compliance. Akmon produces evidence that supports record-keeping obligations. It is not a certification and does not guarantee that any regulation or control was satisfied. See Compliance and evidence.
- A signature proves which key signed, not who holds it. Binding a key to a person or organization is out of band. Akmon has no view into who controls a private key. If you want a name, you must establish key ownership through your own channels.
- An imported trace is structural, not a full recording. A session brought in through
OpenTelemetry records
capture_level: structural. It captures the shape of the session, not a complete, replayable recording. Only Akmon's own bundled reference agent producescapture_level: full, which replays deterministically. Do not read a structural import as a full recording.
Cryptographic design
- Content addressing. Every object (events, payloads, referenced blobs) is named by its SHA-256 digest. The name is a commitment to the bytes.
- Hash-linked event chain. Each event commits to its predecessor, forming a chain. The head is the hash of the terminal event, so the head commits to the entire directed acyclic graph of objects reachable from it. One head value pins the whole record.
- Head signature. An Ed25519 detached signature is computed over a domain-separated
AGEF-SIG-v1statement (a canonical ASCII block: version tag, AGEF version, hash algorithm, session id, and head, each on its own line). Domain separation means the signed bytes cannot be mistaken for any other kind of signed message. Signing is offline and requires no network. - Operator attestation. A separate, additive Ed25519 signature is computed over an
AGEF-OPERATOR-v1statement, which binds the session head and session id to the operator's self-asserted identity fields. It is independent of the head signature and never alters the event chain.
Signatures live in manifest.signatures[] (AGEF v0.1.2) and operator attestations live in
manifest.operator_attestations[] (AGEF v0.1.3). Akmon implements AGEF v0.1.3. Ed25519 is provided
by the ring crate, which is already in the tree.
Threat scenarios and how they are handled
- Tampering with any event or object. Changing any byte changes that object's SHA-256 name, which breaks the chain link that referenced it, which changes the terminal event hash, which changes the head. Any head signature computed over the old head no longer verifies. Tampering is detected, not silently accepted.
- Transplanting an attestation onto another session. The operator attestation binds the head and the session id, so an attestation lifted from one bundle does not verify against a different session. Accountability claims cannot be moved between records.
- Stripping signatures or attestations (honest limitation). Signatures and operator attestations
are additive manifest metadata. An intermediary who controls the file can remove them and the
remaining record still verifies for integrity. Cryptography cannot prove the absence of something
that was removed. The mitigation is policy, not math: a verifier that cares must pass
--require-signatureand/or--require-operator(or--require-operator-key) and supply the trusted keys. Presence cannot be proven cryptographically. It can only be required by the verifier. - Substituting a different signing key. Verification only trusts keys you supply. A bundle signed
by an unknown key reports
unverified_no_key, notverified. You decide which keys are authoritative.
Key trust model
Key trust is out of band, by design.
- There is no PKI, no DID, no certificate authority.
- There is no transparency log.
- There is no key distribution or discovery mechanism in Akmon.
You obtain the signer's and operator's public keys through a channel you already trust (a signed release, a key published by a known party, an exchange inside your own perimeter), and you supply those keys at verification time. Akmon proves that the holder of a given key signed a given record. Whether you trust that key is your decision, made outside Akmon.
Supply chain
- Implemented in Rust.
- A
cargo-denygate keeps advisory-bearing crates out of the dependency tree. - Ed25519 is provided by
ring, already present in the tree, so the trust layer adds no new cryptographic dependency. - Build inputs are kept reproducible.
- An SBOM and
SHA256SUMSare published with each release so you can pin and verify what you ran.
What a verifier must do, in order
Each step is independent. A later step does not rescue an earlier failure.
- Integrity first. Re-hash the objects and rewalk the chain to reproduce the head. If integrity fails, stop. Nothing else matters.
- Head signature. If you require provenance, pass
--require-signaturewith the trusted signer public key. A pass proves which key sealed this head. - Operator attestation. If you require named accountability, pass
--require-operator(or--require-operator-key) with the trusted operator key. A pass proves which operator key claimed the session. - Capture level. If you require a full, replayable recording, pass
--require-capture full. A structural import will fail this check, which is the correct and honest outcome.
The mechanics of running each step, including the standalone verifier and the plain openssl path,
are covered in Verifying evidence (for auditors).
See also
- How Akmon works
- Verifying evidence (for auditors)
- Compliance and evidence
- Glossary
- akmon bundle verify
- akmon bundle prove-openssl
How Akmon works
Documented for Akmon 2.2.0.
Who this is for
Engineers and architects who want a clear picture of how Akmon records an AI agent session, how the trust layer attaches without changing that record, and how a third party verifies it offline. This page describes the model. For the security boundaries, read Trust and threat model.
The producer-agnostic model
Akmon is an evidence and verification layer that sits on top of whatever agent you run. There are two
ways a session becomes an Akmon record, and they differ in fidelity. Akmon labels the difference
honestly with a capture_level so a reader is never misled.
| Producer | How it enters Akmon | capture_level | Replayable | Notes |
|---|---|---|---|---|
| Akmon bundled reference agent | Run directly under Akmon | full | Yes, deterministically | The gold-fidelity reference producer. |
| Any agent via OpenTelemetry | akmon otel import <trace.json> | structural | No (replay refuses it) | Captures the shape of a GenAI trace, not a complete recording. |
The bundled coding agent is the reference producer, not the headline. The point of Akmon is that the
record and its verification are the same regardless of who produced the session. A regulator or
auditor verifies a bundle the same way whether it came from Akmon's own agent or from an imported
trace. What changes is only how much the record can claim, and that claim is carried in
capture_level.
akmon otel import reads the OTLP/JSON OpenTelemetry GenAI form. It accepts both the v1.37 structured
form and the legacy v1.36-and-earlier message-event form, and records capture_level: structural in
both cases.
The AGEF substrate
Every session, from either producer, lands on the same substrate: the AGEF format.
- Events. The session is a sequence of events. Each event commits to its predecessor, forming a hash-linked chain.
- Object store. Events and their payloads are stored as content-addressed objects, each named by its SHA-256 digest. The name is a commitment to the bytes.
- Head. The head is the hash of the terminal event. Because the chain is hash-linked, the head commits to the entire directed acyclic graph of objects reachable from it. One value pins the whole record.
- Portable bundle. A session exports to a single
tar.zst.akmonfile containing the manifest, the event stream, and the referenced objects. The bundle is self-contained and moves between machines, organizations, and air-gapped environments without any Akmon service. - Manifest. The manifest describes the bundle and carries the head plus the optional trust-layer fields described next.
The additive trust layers
Provenance and accountability are layered on top of the AGEF substrate without touching it. This is the important property: adding or checking trust never changes the event chain or the head.
manifest.signatures[](AGEF v0.1.2). Zero or more Ed25519 detached signatures over the domain-separatedAGEF-SIG-v1statement (which commits to the head). Added byakmon bundle sign. The signing key is created byakmon bundle keygen, which produces an Ed25519 PKCS#8 v2 key that theringcrate accepts.manifest.operator_attestations[](AGEF v0.1.3). Zero or more separately-signedAGEF-OPERATOR-v1operator-identity claims, each binding the head and session id to self-asserted identity fields. Added byakmon bundle attest.
Both fields are optional. A bundle with neither still verifies for integrity. Because they are additive metadata, an intermediary can strip them, so a verifier that requires them must say so with the require flags and supply trusted keys. See Trust and threat model.
Akmon implements AGEF v0.1.3. Ed25519 is provided by the ring crate.
The verification chain
Verification runs as a sequence of independent stages. A later stage does not compensate for an earlier failure, and each stage trusts only the keys and requirements you supply.
- Integrity. Re-hash every object and rewalk the event chain to reproduce the head. This is the foundation. If it fails, stop.
- Head signature. Check
manifest.signatures[]against a trusted signer public key. With--require-signaturea missing or unverifiable signature is a hard failure. - Operator attestation. Check
manifest.operator_attestations[]against a trusted operator public key. With--require-operatoror--require-operator-keya missing or unverifiable attestation is a hard failure. "Verified" attaches to the key, not the self-asserted name. - Capture level. With
--require-capture full, a structural import fails. This keeps a structural record from being treated as a full, replayable one.
These stages are exposed by akmon bundle verify.
The standalone verifier and the openssl path
Verification does not require a full Akmon install, and the strongest form does not require Akmon at all.
agef-verify. A standalone binary that performs the bundle integrity, signature, operator, and capture checks without the full Akmon CLI. Install it on its own (Homebrew tap or release binary). See agef-verify.- Plain
openssl.akmon bundle prove-opensslwrites the exact signed statement bytes, the raw signature, and the public key in PEM form, plus the preciseopenssl pkeyutl -verifycommand. A third party then verifies the Ed25519 signature with stockopensslalone: no Akmon binary, no cloud, no need to trust the producer. This step needs OpenSSL 3.x; the macOS LibreSSLopensslcannot verify Ed25519.
That openssl path is the point of the whole design. The record is portable and content-addressed, the signature is a standard detached Ed25519 signature over a canonical statement, and the only thing a verifier needs is the public key they already trust.
See also
- Trust and threat model
- Verifying evidence (for auditors)
- Compliance and evidence
- Glossary
- akmon bundle verify
- agef-verify
- akmon bundle prove-openssl
Verifying evidence (for auditors)
Documented for Akmon 2.2.0.
Who this is for
An auditor, regulator, or counterparty who received an Akmon .akmon bundle and a public key and
wants to check it independently. You may be working air-gapped, you may not run Akmon, and you do not
need to trust whoever produced the bundle. This page shows you how to verify the record and how to
read the outcome. For the underlying guarantees, see Trust and threat model.
What you should have
- The
.akmonbundle file. - The signer's public key (and, if accountability matters, the operator's public key), obtained through a channel you trust. Key trust is out of band; Akmon does not distribute keys.
Three ways, increasing independence
Pick the level of independence the situation calls for. Each proves the same record; they differ in how much you must trust the producer's tooling.
1. Akmon's own verifier
If you have Akmon installed, this is the most convenient path. It runs every stage of the verification chain.
akmon bundle verify /path/to/session.akmon \
--verify-key signer.pub.hex \
--require-signature \
--operator-key operator.pub.hex \
--require-operator \
--require-capture full
Drop the require flags you do not need. Without --require-signature an unsigned or unknown-key
bundle is reported, not failed; with it, missing provenance is a hard failure. The same applies to
the operator and capture requirements.
2. The standalone verifier
agef-verify is a minimal binary that performs the bundle integrity, signature, operator, and
capture checks without the full Akmon agent CLI. Install it on its own (Homebrew tap or release
binary). Use this when you want to verify without bringing in the whole agent.
agef-verify /path/to/session.akmon \
--verify-key signer.pub.hex \
--require-signature
It also accepts --operator-key and --require-operator with the same semantics as
akmon bundle verify.
3. Plain openssl, no Akmon at all
This is the strongest form of independence: verify the Ed25519 signature with stock openssl and
nothing else. First, someone with Akmon (possibly the producer, possibly you) emits the proof
artifacts:
akmon bundle prove-openssl /path/to/session.akmon \
--verify-key signer.pub.hex \
--operator-key operator.pub.hex \
--out-dir ./proof
That writes statement.bin (the exact signed bytes), signature.bin (the raw 64-byte signature),
and pubkey.pem (the signer's public key in PEM form), plus the operator equivalents when
--operator-key is given. Then you verify the head signature with OpenSSL 3.x:
openssl pkeyutl -verify -pubin -inkey ./proof/pubkey.pem -rawin -in ./proof/statement.bin -sigfile ./proof/signature.bin
A valid signature prints a success line and exits 0. To check the operator attestation, run the
same command against the operator_pubkey.pem, operator_statement.bin, and
operator_signature.bin files. The exact commands are also printed by prove-openssl.
Note the requirement: you need OpenSSL 3.x. The macOS system openssl is LibreSSL and cannot
verify Ed25519 (it lacks -rawin and cannot load the key). Use an OpenSSL 3.x build.
How to read the outcome
A verification result is not a single yes or no. Read each signal for what it actually says.
- Verified. Integrity holds, and any provenance or accountability you required checked out against a key you supplied. You can conclude the record was not altered and that the holders of the named keys sealed and (if attested) claimed it. You still cannot conclude the agent was correct or that any person holds the key; that is out of band.
- Invalid (hard fail). Integrity failed, or a check you required did not pass. Do not rely on the record. If integrity failed, the bytes were altered or corrupted and nothing downstream is trustworthy. Stop here.
- Unverified, no key. The bundle carries a signature (or attestation), but you did not supply a
matching trusted key, so it reports
unverified_no_key. This is not a failure on its own. It means you have not yet established provenance. Obtain the right key out of band and re-run, or require it explicitly if its absence should fail. - Unattributed. No operator attestation is present, or none verifies against a key you trust. The record may still have integrity and a valid head signature, but no operator key has claimed accountability for the session. If you need a named, key-backed claim, treat this as insufficient and require it.
capture_level: structuralversusfull. A structural record (an OpenTelemetry import) captures the shape of the session, not a complete recording, and it cannot be replayed deterministically. A full record (Akmon's own reference agent) is a complete, replayable recording. If your evidence needs a full recording, require it with--require-capture full; a structural import will fail that check, which is the honest result. Do not read a structural import as a full recording.
A note on stripped trust metadata
Signatures and operator attestations are additive manifest fields. An intermediary who controls the file can remove them, and the remaining record still verifies for integrity. Cryptography cannot prove that something absent was once present. If provenance or accountability matters to you, do not rely on a signature merely being present in a bundle you happened to receive. Require it with the flags above and supply the trusted keys, so a stripped or unknown-key bundle fails rather than passes quietly. See Trust and threat model.
See also
- Trust and threat model
- How Akmon works
- Compliance and evidence
- akmon bundle verify
- agef-verify
- akmon bundle prove-openssl
- Regulated reviewer flow
Compliance and evidence
Documented for Akmon 2.2.0.
Who this is for
Compliance, risk, and security teams evaluating whether Akmon helps with record-keeping obligations for AI agents. This page frames what Akmon does and does not do, and maps its capabilities to a few common frameworks at a high level. None of it is legal advice.
Honest framing
Akmon produces durable, signed, independently-verifiable evidence about what an AI agent did. When an agent changes something you may later have to account for, an Akmon record lets a third party confirm offline that the record was not altered and which key sealed it. That supports record-keeping obligations.
It stops there, deliberately. Akmon is not a certification, and it does not guarantee compliance with any regulation or control. Producing good evidence is one part of a control. The rest, including key management, control implementation, retention, access governance, and the legal interpretation of what an obligation requires, belongs to your organization. A verified bundle proves integrity and key-backed provenance. It does not prove that the agent was correct or that any obligation was met. See Trust and threat model for the precise boundaries.
High-level mapping
The mapping below is descriptive, not a legal claim. It states what Akmon provides and where the boundary sits. Treat the framework references as orientation, and validate the specifics with your own teams.
EU AI Act, Article 12 and Annex IV record-keeping
The EU AI Act places record-keeping and technical-documentation obligations on high-risk AI systems. The high-risk logging obligations in Article 12, and the technical-documentation expectations in Annex IV, start applying on 2 August 2026.
- What Akmon provides. A portable, content-addressed, hash-linked record of an agent session,
optionally sealed with an offline Ed25519 signature and an operator-identity attestation. The
record is tamper-evident and verifiable by a third party offline, including with stock
openssl. That is durable, independently-checkable evidence of what an agent session contained. - The boundary. Akmon does not decide whether your system is high-risk, what must be logged, how long records must be retained, or whether your documentation satisfies Annex IV. It does not manage your signing keys or establish who holds them. Those determinations and controls are yours.
NIST AI RMF, MEASURE 2.8
The NIST AI Risk Management Framework's MEASURE function calls for mechanisms to track, document, and verify AI system behavior, including MEASURE 2.8 on tracking and traceability.
- What Akmon provides. A verifiable, traceable record of agent sessions that a reviewer can check
independently, with an honest
capture_levelthat distinguishes a full, replayable recording from a structural import. That supports the traceability and documentation MEASURE 2.8 contemplates. - The boundary. Akmon supplies evidence and verification. It does not perform your risk measurement, set your thresholds, or judge whether observed behavior is acceptable. The measurement program and its conclusions are yours.
SOC 2, CC7.x and CC8.1
SOC 2's common criteria include monitoring of operations (CC7.x) and change management (CC8.1).
- What Akmon provides. Signed, verifiable evidence about agent-driven activity and changes, which can feed monitoring and change-management evidence: what an agent session did, recorded tamper-evidently, with optional key-backed provenance and operator accountability.
- The boundary. Akmon is one evidence source. The design and operating effectiveness of your controls, the completeness of your monitoring, the governance of who reviews what, and the management of the keys that make a signature meaningful are all your responsibility. Auditor acceptance of any evidence is determined in your audit, not by Akmon.
Capture honesty
Compliance use depends on not overstating what was recorded. Akmon labels every record with a
capture_level:
- A session run under Akmon's own bundled reference agent is
full: a complete, deterministically replayable recording. - A session brought in through an OpenTelemetry import is
structural: the shape of the session, not a complete recording. It cannot be replayed, andakmon bundle verify --require-capture fullfails on it.
Require the capture level your obligation actually needs, and do not present a structural import as a full recording.
Validate with your own legal and compliance teams
Akmon helps you produce evidence. It does not interpret the law and it does not certify you. Whether a given record satisfies a given obligation, how long you must retain records, how you govern and protect signing keys, and how you implement and evidence the surrounding controls are decisions for your own legal and compliance teams. Validate any use of Akmon for a regulatory or audit purpose with those teams before you rely on it.
See also
- Trust and threat model
- How Akmon works
- Verifying evidence (for auditors)
- Regulated reviewer flow
- Glossary
Glossary
Documented for Akmon 2.2.0.
Who this is for
Readers who want consistent terminology across Akmon tutorials, references, and review workflows.
What you will have at the end
- Canonical meanings for Akmon terms used in docs and CI policy discussions.
Prerequisites
- None.
Trust and evidence terms
- AGEF: the Agent Evidence Format, an open format for portable AI-agent session evidence. SHA-256 content-addressed objects, a hash-linked event chain, and a portable
tar.zstbundle. Akmon implements AGEF v0.1.3. The format is the interoperability layer; Akmon is one reference implementation. See the AGEF specification. - Bundle: a portable
.akmonarchive (AGEFtar.zst) containing the manifest, the event stream, and the referenced objects, suitable for transport, import, and offline verification. A bundle is the unit you sign, ship, and verify. - Head: the terminal event hash of a session, the single value that commits to the entire hash-linked chain. Because every event links to the prior one, the head fixes the whole record. Signatures are taken over the head, not over individual events.
- Signature: an offline Ed25519 signature over the session head, recorded in
manifest.signatures[](AGEF v0.1.2). The signed payload is the canonicalAGEF-SIG-v1statement. It is produced byakmon bundle signwith a key fromakmon bundle keygen, and is verifiable byakmon bundle verify,agef-verify, or plainopensslafterakmon bundle prove-openssl. It answers who attested to the session, a property internal tamper-evidence alone cannot provide. - Operator attestation: a separately signed
AGEF-OPERATOR-v1claim recorded inmanifest.operator_attestations[](AGEF v0.1.3) that binds the session head to operator identity fields (id, display name, role, org), produced byakmon bundle attest. Verification attaches trust to the key, never to the self-asserted string; trust in the name is established out of band. An attested bundle verified without a trusted key reportsunverified_no_key, which is not a failure on its own. - Capture level: an honest record of how completely a session was captured, either
fullorstructural. Akmon never overstates this. - Full capture: a session recorded by Akmon's own reference agent. It contains enough to replay deterministically and passes
akmon bundle verify --require-capture full. - Structural capture: a session imported from another agent's OpenTelemetry trace via
akmon otel import. It records the structure of what happened but is not a full recording.akmon bundle verify --require-capture fullfails on it, andakmon replayrefuses it.
Runtime and review terms
- Session: one run context identified by a UUID and recorded as linked events.
- Artifact: an output file produced by a run (for example evidence JSON, audit JSONL, or a
.akmonbundle). - Evidence: a structured JSON artifact (
evidence.v1) summarizing replay metadata, policy and tool outcomes, and verification context. - Verify: an integrity check.
akmon verifyvalidates the on-disk journal hash chain and session invariants;akmon bundle verifyandagef-verifyvalidate a portable bundle, optionally its signature and operator attestation. - Replay: deterministic re-execution and comparison of a recorded session (
akmon replay). Only full-capture sessions from Akmon's own agent replay; OTEL imports are refused. - Policy: an allow and deny control layer over tool, file, network, and shell actions, including profile and pack merging.
- Capability: an action class available to the runtime and model through registered tools and commands.
- Audit log: a JSONL chain capturing auditable events for a session (
.akmon/audit/<session-id>.jsonl). - Policy profile: a built-in baseline policy (
dev,staging,prod) selectable by CLI or config. - Policy pack: an operator-maintained TOML or JSON policy layer merged on top of profile defaults.
- Sentinel: a replacement object marker used by
akmon redactto remove sensitive object bytes while preserving structure.
Verification
Use this glossary as the canonical reference when terms differ between teams or review templates.
Troubleshooting
- If a term is missing, check the reference pages first and then update this glossary in the same PR as the feature or docs change.
Regulated Reviewer Flow
Documented for Akmon 2.2.0.
Who this is for
Reviewers, tech leads, compliance engineers, and external auditors validating AI-assisted sessions. This page is the checklist from a received bundle to a verification-ready, signature-backed handoff.
It covers both kinds of session Akmon handles: sessions imported from another agent's OpenTelemetry trace (structural capture) and sessions produced by Akmon's own reference agent (full capture). The verification chain is the same; only the capture level and the availability of replay differ.
What you will have at the end
- A repeatable checklist that ends in an independently verifiable signature.
- A clear decision on whether a bundle is review-ready and safe to distribute.
Prerequisites
- A
.akmonbundle, or a completed Akmon run with a session ID. - The signer's public key (64 hex characters) for any signature you must check, established through your own out-of-band trust process.
- OpenSSL 3.x if you intend to reproduce the proof with plain
openssl.
Steps
1. Verify bundle integrity, signature, and operator identity
For a received bundle, this is the primary check. It validates the hash-linked event chain, the manifest head, the offline Ed25519 signature over that head, and any operator attestation.
akmon bundle verify session.akmon \
--verify-key signer.pub.hex \
--require-signature \
--operator-key operator.pub.hex
"Verified" attaches to the key, not to the self-asserted operator name. A bundle that carries an attestation but is verified without a trusted key reports unverified_no_key, which is informational, not a failure.
An auditor who does not run the full Akmon CLI can use the standalone binary for the same integrity and signature checks:
agef-verify session.akmon --verify-key signer.pub.hex --require-signature
2. Enforce capture level when the use case demands a full recording
akmon bundle verify session.akmon --verify-key signer.pub.hex --require-capture full
This passes only for full-capture sessions from Akmon's own agent. It correctly fails on OTEL imports, which are structural. Decide up front which categories of change require full and gate accordingly.
3. Reproduce the proof offline with openssl (when zero-trust verification is required)
If a counterparty does not trust your tools, hand them the proof artifacts and the exact command.
akmon bundle prove-openssl session.akmon --verify-key signer.pub.hex --out-dir proof
openssl pkeyutl -verify -pubin -inkey proof/pubkey.pem -rawin -in proof/statement.bin -sigfile proof/signature.bin
A valid signature prints Signature Verified Successfully. This needs only OpenSSL 3.x, no Akmon install.
4. For full-capture own-agent sessions, also check the on-disk chain and evidence
When the artifacts live in a local repository rather than arriving as a bundle:
SESSION_ID="<session-uuid>"
akmon audit verify ".akmon/audit/${SESSION_ID}.jsonl"
akmon evidence verify ".akmon/evidence/${SESSION_ID}.json"
akmon verify "${SESSION_ID}"
5. Replay for behavioral divergence (full capture only)
akmon replay "${SESSION_ID}" --format json | tee replay.json
Replay applies to full-capture sessions from Akmon's own agent. OTEL imports are refused for replay because a structural capture does not contain enough to reproduce execution.
6. Export, sign, and (if needed) redact for archive or external review
akmon bundle export "${SESSION_ID}" --output "${SESSION_ID}.akmon"
akmon bundle sign "${SESSION_ID}.akmon" --key signer.pk8
If sensitive content must be removed, create a derivative redacted bundle and re-verify it before distribution:
akmon redact "${SESSION_ID}" \
--output "${SESSION_ID}-sanitized.akmon" \
--object <object-hash> \
--reason "compliance redaction"
Verification
A handoff is review-ready when:
akmon bundle verify ... --require-signatureexits0, and the signature checks against a key you trust out of band,- the capture level matches what the use case requires (
--require-capture fullwhere mandated), - for zero-trust handoff,
openssl pkeyutl -verify ...printsSignature Verified Successfully, - for full-capture sessions, replay is pass or divergences are explicitly accepted,
- any redacted bundle still passes
akmon bundle verifybefore it leaves your control.
Troubleshooting
- If
bundle verifyfails, stop the review and inspect the violation category before proceeding. - If
--require-capture fullfails on an imported session, that is expected. Treat the session as structural evidence, not as a replayable recording. - If
opensslcannot verify the signature, confirm OpenSSL 3.x rather than LibreSSL. - If
replaydiverges, treat it as a change-detection signal and triage expected versus unexpected drift. - If bundle verification fails, do not distribute the bundle externally.
How Akmon relates to other tooling
Akmon is not a competitor to the coding agent you already run. It is an evidence and verification layer that sits on top of one. The useful question is not "Akmon or tool X." It is "what does Akmon add to a stack that already has an agent, and where does it overlap with governance tooling you may already use."
This page places Akmon against two neighbors that people reasonably confuse it with: the agents that produce sessions, and the governance and ledger systems that try to make those sessions trustworthy. Where a vendor leads, this page says so.
The layer Akmon occupies
Most agent tooling is a producer. It runs a model, calls tools, and changes things. Its telemetry is usually built for live observability: traces and spans that help you debug a run while it is fresh.
Akmon is a consumer and a verifier. It takes a session, either from its own bundled reference agent or from any OpenTelemetry-instrumented agent through akmon otel import, and turns it into a portable, content-addressed, hash-linked AGEF record. That record can be signed offline with Ed25519, can carry a separately signed operator attestation, and can be verified by a third party with no Akmon install and no cloud, using agef-verify or stock openssl after akmon bundle prove-openssl.
So the comparison is not feature-for-feature against an agent. It is: does the record survive contact with someone who does not trust you and does not run your tools, possibly years later. That is the gap Akmon fills.
Relation to agent and coding tooling
Akmon is producer-agnostic by design. Its own bundled coding agent is the reference, gold-fidelity producer (it records full capture and replays deterministically), but it is not the headline. The headline is the verification chain, and that chain accepts sessions from agents Akmon did not write.
| Dimension | Akmon (evidence and verification layer) | Typical coding or agent tool |
|---|---|---|
| Primary role | Records, signs, and verifies sessions as evidence | Produces sessions by running a model and tools |
| Output you keep | Portable, signed, content-addressed AGEF bundle | Live trace or chat transcript, often ephemeral |
| Third-party verification | Offline, signature-checked, no Akmon needed (openssl/agef-verify) | Usually requires the vendor's stack to interpret |
| Producer coupling | Producer-agnostic via OpenTelemetry import | The agent is the product |
| Capture honesty | Records full or structural explicitly; never overstates | Varies; replay fidelity often unstated |
If you already have an agent you like, Akmon does not ask you to replace it. It asks for its OpenTelemetry trace, and gives you back a record you can prove later.
Relation to governance and ledger tooling: a fair Microsoft comparison
The closest neighbors to Akmon are not coding agents. They are the systems that try to make agent activity auditable. Microsoft ships the most prominent ones, so it is worth being precise and fair about where each fits.
- The Microsoft Agent Governance Toolkit uses a hash chain with HMAC. That gives tamper-evidence within a trust domain that holds the shared secret, but HMAC is symmetric: anyone who can verify can also forge, and there is no standalone verifier a distrusting third party can run. Akmon uses an asymmetric Ed25519 signature over the session head, so a verifier checks authorship with a public key and cannot forge a new one. Akmon also ships
agef-verifyand theopensslproof path for verification with no Akmon install. - Azure Confidential Ledger does provide signed, tamper-evident records, but it is Azure-locked and not agent-aware. The trust anchor is the Azure service. Akmon's bundle is cloud-independent and agent-aware: the record is a portable file, the signature is verifiable offline, and the format models agent sessions (events, tool calls, capture level, operator) rather than generic ledger entries.
- Microsoft Foundry's own documentation states that its traces cannot support full replay. Akmon distinguishes capture levels explicitly: a reference-agent session records
fullcapture and replays deterministically, while an OpenTelemetry import recordsstructuralcapture, andakmon replayrefuses to claim a structural import is replayable.
Where Microsoft leads, plainly: distribution, ecosystem integration, and the gravitational pull of an existing Azure footprint. If your organization is standardized on Azure and Microsoft's agent stack, those tools meet you where you already are, and Akmon is complementary rather than a replacement. Akmon's contribution is the portable, signed, cloud-independent, offline-verifiable record on top of whatever you run. The two layers compose: produce and govern in your platform of choice, then seal the session into a record a regulator or counterparty can verify without trusting that platform.
Where this matters
When an AI agent changes something, you may later have to prove what it did, to a regulator, an auditor, or an incident team who does not trust you and does not run your tools. Under the EU AI Act, the high-risk logging obligations in Article 12 and Annex IV start applying on 2 August 2026. Akmon helps you produce evidence for that kind of obligation, and for NIST AI RMF (MEASURE 2.8) and SOC 2 (CC7.x, CC8.1) workflows. It is not a certification and does not by itself guarantee compliance; validate fit with your own legal and compliance teams.
Choosing what to use
- Keep your agent. Use Akmon to import its trace and produce a verifiable record. Different teams can standardize on different agents and still hand back the same kind of evidence.
- If you are deep in Azure and Microsoft's governance stack, keep it, and use Akmon as the portable, offline-verifiable layer on top for records that must leave that trust domain.
- Use Akmon's own bundled reference agent when you want gold-fidelity
fullcapture and deterministic replay, not because it is trying to win on coding UX.
The realistic stack is layered, not exclusive: an agent to do the work, a governance platform if you have one, and Akmon to turn the result into something a stranger can verify.
Common mistakes
- Comparing Akmon to a coding agent on response quality. That is the producer's job; Akmon verifies the record, whatever produced it.
- Assuming HMAC-chained logs give third-party non-repudiation. They do not; symmetric verification is also symmetric forgery.
- Treating a
structuralOTEL import as a full recording. It is an honest transcription, not a replayable capture. - Deferring compliance and deployment fit until late adoption, then discovering the evidence does not verify outside your own tools.
Introduction and Security model.
akmon bundle keygen
Documented for Akmon 2.2.0.
Who this is for
Anyone who needs to sign an Akmon bundle. akmon bundle sign requires an Ed25519 private key in
raw PKCS#8 v2 DER form, and this command is the supported way to create one. Without it there is
no first-class way to make a usable signing key, and openssl genpkey does not fill the gap
(see the honesty note below).
What you will have at the end
- A PKCS#8 v2 DER private key at
--out(raw bytes, no PEM armor), created with0600permissions on unix. This is the exact byte formakmon bundle sign --keyconsumes. - The signer's public key as 64 hex characters, surfaced on stderr (human mode) or in the JSON
report, and optionally written to
--public-out. - The signer's key_id (lowercase hex SHA-256 of the public key), the same value recorded in
manifest.signatures[].key_id.
Distribute the public key (hex) to verifiers; they use it with akmon bundle verify --verify-key
or akmon bundle prove-openssl --verify-key. Keep the private key secret.
How it works
keygen generates a fresh Ed25519 keypair, writes the private key (PKCS#8 v2 DER) to --out, and
derives the raw 32-byte public key from it. It never writes a bundle, manifest, or any signature.
it only produces the key material. The private key is written via a file opened with mode 0600
(owner read/write only) at create time on unix, so there is no window where the key exists with
broader permissions.
Steps
Generate a key:
akmon bundle keygen --out signer.pk8
Generate a key and also write the public key for verifiers:
akmon bundle keygen --out signer.pk8 --public-out signer.pub.hex
Then sign and verify a bundle:
akmon bundle sign /path/to/audit.akmon --key signer.pk8
akmon bundle verify /path/to/audit.akmon --verify-key signer.pub.hex --require-signature
Optional flags
--public-out <FILE>: also write the public key as exactly 64 hex characters (no trailing newline) to this file, ready for--verify-key.--force: allow overwriting an existing--out(and--public-out). Off by default: keygen refuses to clobber an existing private key.--format human|json: defaulthuman. JSON emits KeygenReportV1 withtool,akmon_version,key_path,public_out(ornull),public_key_hex, andkey_id.
Exit codes
| Code | Meaning |
|---|---|
0 | Key written; public key hex and key_id surfaced |
3 | I/O error, refuse-to-clobber (pass --force to replace), or key generation failure |
Security notes
- Keep the private key secret. Anyone holding it can forge signatures attributed to you. Only ever distribute the public key (hex).
- On unix the private key is created with
0600permissions at create time (never a broader-then- narrowed window). A--forceoverwrite re-asserts0600on the file before any bytes are written. - On Windows there is no
0600enforcement; the file inherits the parent directory's NTFS ACLs. Store the key in a directory that only you can read.
Honesty note: openssl is not a substitute
openssl genpkey -algorithm ed25519 (even with -outform DER) emits a PKCS#8 v1 key, which the
ring library Akmon uses rejects, so such a key cannot sign an Akmon bundle. Use
akmon bundle keygen to produce a usable PKCS#8 v2 key.
See also
akmon sign
Documented for Akmon 2.2.0.
Who this is for
Reviewers and operators who need an independent, detached attestation over a recorded session. Akmon's journal is tamper-evident by construction (a merkle hash chain), but tamper- evidence proves internal consistency, not provenance. A signature over the session head lets a third party verify who attested to the session, the property auditors ask for when "logs from the party being audited" are not sufficient on their own.
What you will have at the end
- A detached signature (or transparency-log entry) over a session's head hash, produced by your own signing tool.
How it works
Akmon does not embed a signer here. akmon sign reads the session's head hash from the journal
and invokes a command you configure under [signing] in ~/.akmon/config.toml (Decision D-05).
For the native detached-signature path (no external signing hook), use
akmon bundle sign, which signs an exported bundle with an Ed25519 key made byakmon bundle keygen.openssl genpkeyis not a substitute forkeygen: it emits PKCS#8 v1, whichringrejects.
Headless runs (akmon --task …) invoke the same hook automatically after the session is
persisted when [signing] is configured. Signing is best-effort: failures are logged to stderr as
akmon: sign (auto): … and do not change the run's exit code. Use akmon sign when you need an
explicit failure exit code or JSON report.
- The command is read only from the trusted per-user config, never from repo-local or project files, so cloning a malicious repository cannot inject a command to run.
- It runs via
argv(no shell): configured values are not word-split or shell-interpreted. - In the configured arguments, every
{head}and{session_id}token is substituted with the session head hash (hex) and session UUID. - The same values are exported to the command environment as
AKMON_SESSION_HEADandAKMON_SESSION_ID. - The command is terminated if it exceeds
timeout_secs(default60).
Prerequisites
- A session UUID from a completed Akmon run.
- A
[signing]command configured in~/.akmon/config.toml.
Configure the signing command
# ~/.akmon/config.toml
[signing]
command = ["/usr/local/bin/akmon-sign.sh"] # script reads $AKMON_SESSION_HEAD
timeout_secs = 60
A minimal wrapper that signs the head with cosign keyless:
#!/usr/bin/env bash
# /usr/local/bin/akmon-sign.sh
set -euo pipefail
printf '%s' "$AKMON_SESSION_HEAD" \
| cosign sign-blob --yes --output-signature "akmon-${AKMON_SESSION_ID}.sig" -
Or sign with GPG using token substitution instead of the environment:
[signing]
command = ["gpg", "--detach-sign", "--armor", "--output", "akmon-{session_id}.sig", "-"]
Steps
- Sign a session by UUID.
akmon sign <session-id>
- Use JSON for automation.
akmon sign <session-id> --format json
- Use optional flags as needed:
--journal <PATH>--format <human|json>(defaulthuman)
Exit codes
| Code | Meaning |
|---|---|
0 | Signing command completed successfully |
1 | Signing command ran but failed (non-zero exit or timeout) |
2 | Usage error (no signing command configured) |
3 | I/O or environment error (journal/session not found, command not spawnable) |
Verification
akmon sign <session-id> --format json | jq '.success'
Expected result: true when the configured signing command exits 0.
Troubleshooting
exit 2: no[signing]command configured; add one to~/.akmon/config.toml.exit 3: session/journal access error or the signing executable could not be spawned; check the UUID,--journalpath, and that the program in[signing] commandexists onPATH.exit 1: the signing command itself failed; inspect its output, or the JSONexit_code/timed_outfields.
See also
akmon bundle attest
Documented for Akmon 2.2.0.
Who this is for
Operators who want to bind a named human (or service account) and a role to an AGEF bundle's
session, answering "who claims to have operated this session", on top of the bundle's integrity
hash chain and any head signature. akmon bundle attest records a signed AGEF-OPERATOR-v1
operator attestation in manifest.operator_attestations[]. Verifiers later check it with
akmon bundle verify --operator-key or
agef-verify --operator-key.
The honesty point: trust attaches to the KEY, not the name
An attestation is a signature over the four self-asserted identity fields (operator_id,
display_name, role, org) plus the session head. Verification proves only that the holder of
a particular private key signed those fields. It does not prove the person is who the
operator_id string claims. Trust in the identity is out-of-band: a verifier decides which
key_id (public key) they trust, by some external process (an HR directory, a key-distribution
ceremony, a signed roster), and only then does the self-asserted name carry weight. Verification
surfaces the name verbatim but the trust signal is operator_key_verified against a key the
verifier supplied. Akmon never claims the name is true on its own.
What you will have at the end
- The same bundle with one more entry appended to
manifest.operator_attestations[]. The write is atomic (temp file + rename) and purely additive: the event hash chain, theAGEF-SIG-v1head statement, any existing head signatures, and theprove-opensslhead bytes are byte-untouched. - The attester's key_id (lowercase hex SHA-256 of the operator public key) and the operator public key as 64 hex characters, surfaced on stderr (human mode) or in the JSON report.
Prerequisites
- A
.akmonbundle on disk (signed or unsigned). - An Ed25519 private key in raw PKCS#8 v2 DER form, as produced by
akmon bundle keygen --out. (openssl genpkeyemits PKCS#8 v1, which the signing path rejects. See the keygen honesty note.) - A stable
--operator-id(an email, employee id, or service account). It is required and must not contain a newline or carriage return.
Steps
Generate an operator key and attest a bundle in place:
akmon bundle keygen --out operator.pk8 --public-out operator.pub.hex
akmon bundle attest /path/to/audit.akmon --key operator.pk8 --operator-id ops@example.com --role approver
Then distribute operator.pub.hex to verifiers (out-of-band) and have them verify:
akmon bundle verify /path/to/audit.akmon --operator-key operator.pub.hex --require-operator
Optional flags
--display-name <NAME>: human-readable display name (signed). Defaults to empty.--role <ROLE>: role the operator acted in, for exampleapprover(signed). Defaults to empty.--org <ORG>: organization the operator belongs to (signed). Defaults to empty.--output <FILE>: write the attested bundle here instead of attesting in place.--format human|json: defaulthuman. JSON emits BundleAttestReportV1 withtool,akmon_version,bundle_path,session_id,operator_id,role,key_id,public_key_hex, andoutput_path. The private key is never printed.
Note on head signatures (O9)
If the bundle already carries a head signature, attest leaves agef_version untouched so the
existing AGEF-SIG-v1 signature stays valid; on an unsigned bundle it stamps the current spec
version. Either way the attestation is built from the manifest's current agef_version, so it is
self-consistent. Attesting never invalidates a previously verifiable head signature.
Exit codes
| Code | Meaning |
|---|---|
0 | Attestation appended and bundle written |
1 | Bundle read or integrity error |
2 | Invalid private key, or an operator identity field is empty (operator-id) or contains a newline/carriage return |
3 | I/O error (bundle unreadable, key unreadable, or bundle write/rename failed) |
See also
akmon bundle verify
Documented for Akmon 2.2.0.
Who this is for
Reviewers and CI jobs that need to validate a portable .akmon bundle without writing to a
local journal. This is the preferred Akmon entrypoint for bundle-only verification (Item 4.3).
What you will have at the end
- Confirmation that the bundle's objects, event chain, and manifest head are internally consistent, or a structured violation list.
Prerequisites
- Path to a
.akmonbundle file.
Steps
akmon bundle verify /path/to/audit.akmon
akmon bundle verify /path/to/audit.akmon --format json
Optional flags:
--allow-extra-files: tolerate unknown files inside the archive (default is strict reject).--format human|json: defaulthuman.
Operator identity (--operator-key)
akmon bundle attest records signed operator attestations on a bundle. To
check them at verify time:
--operator-key <HEX_FILE>: a trusted operator Ed25519 public key (64 hex chars). Repeatable. Eachmanifest.operator_attestations[]entry is verified against the supplied keys; a matching, cryptographically valid attestation reports outcomeverified. An attested bundle verified without a trusted key reportsunverified_no_key, not a failure on its own.--require-operator: fail (exit 1) unless at least one operator attestation verifies against an--operator-key.--require-operator-key <HEX_FILE>: fail unless that specific key has a verified attestation. Repeatable; each listed key is also trusted for verification.
"Verified" attaches to the key, not the name. The JSON operators[] entries carry the
self-asserted operator_id/role/org strings verbatim, but the only trust signal is the distinct
boolean operator_key_verified (outcome verified) against a key you supplied. A self-asserted
identity never reads as key-verified without a trusted key; trust in the name is out-of-band.
akmon bundle verify /path/to/audit.akmon --operator-key operator.pub.hex --require-operator --format json
Exit codes
| Code | Meaning |
|---|---|
0 | Bundle passed all integrity checks |
1 | Verification failed |
3 | I/O or environment error |
Verification
akmon bundle verify /path/to/audit.akmon --format json | jq '.passed'
Expected result: true for a valid exported bundle.
Equivalents
| Command | Notes |
|---|---|
akmon bundle verify | Preferred; no journal access |
akmon bundle import --verify-only | Legacy alias; same checks and JSON schema |
agef-verify | Standalone binary; no Akmon CLI |
See also
agef-verify
Documented for Akmon 2.2.0.
Who this is for
Auditors, compliance reviewers, and CI pipelines that must verify an AGEF .akmon bundle
without installing or running the Akmon agent CLI. agef-verify is a minimal binary that
depends only on akmon-bundle (manifest, framing, objects, and store-independent integrity
checks).
What you will have at the end
- Confirmation that a portable bundle's objects, event chain, and manifest head are internally consistent, or a structured list of violations.
Prerequisites
- A
.akmonbundle file on disk.
Usage
agef-verify /path/to/audit.akmon
agef-verify /path/to/audit.akmon --format json
Optional flags:
--allow-extra-files: tolerate unknown files inside the archive (same semantics asakmon bundle import).--format human|json: defaulthuman.
Operator identity (--operator-key)
agef-verify checks operator attestations recorded by akmon bundle attest
with the same flags as akmon bundle verify:
--operator-key <HEX_FILE>: a trusted operator Ed25519 public key (64 hex chars). Repeatable. Eachmanifest.operator_attestations[]entry is verified against the supplied keys.--require-operator: fail (exit 1) unless at least one operator attestation verifies against an--operator-key.--require-operator-key <HEX_FILE>: fail unless that specific key has a verified attestation. Repeatable; each listed key is also trusted for verification.
"Verified" attaches to the key, not the name. The JSON carries the self-asserted
operator_id/role/org strings verbatim, but the only trust signal is the distinct boolean
operator_key_verified (true only for outcome verified against a key you supplied). Trust in the
name is out-of-band.
agef-verify /path/to/audit.akmon --operator-key operator.pub.hex --require-operator --format json
Exit codes
| Code | Meaning |
|---|---|
0 | Bundle passed all integrity checks |
1 | Bundle read succeeded but verification failed (or non-I/O parse/integrity error) |
3 | I/O or environment error (path not found, not a file, cannot render JSON) |
JSON output
--format json emits BundleVerifyReportV1, the same shape as
akmon bundle import --verify-only --format json, so automation can share jq filters. The
akmon_version field carries the agef-verify crate version.
agef-verify /path/to/audit.akmon --format json | jq '.passed'
Infrastructure errors (cannot open or parse the archive) emit VerifyInfraErrorV1 with
tool: "agef-verify".
Relation to Akmon
| Tool | Scope |
|---|---|
akmon verify <session-id> | On-disk journal / redb store |
akmon bundle verify | Same bundle checks as agef-verify, embedded in Akmon |
akmon bundle import --verify-only | Legacy alias of bundle verify |
agef-verify | Bundle file only; no journal, no agent |
See also
akmon bundle prove-openssl
Documented for Akmon 2.2.0.
Who this is for
Auditors, regulators, and counterparties who want to verify an Akmon bundle's Ed25519 signature
with stock openssl alone, no Akmon binary, no cloud, no lock-in. This is the reproducible
proof of Akmon's offline-verifiability guarantee (metric F.1): the signature format is a standard
PureEd25519 detached signature over a canonical ASCII statement, so any third party can check it.
What you will have at the end
Three files in --out-dir plus a copy-paste openssl command:
statement.bin: the exactAGEF-SIG-v1bytes that were signed (the session-head commitment).signature.bin: the 64-byte raw detached Ed25519 signature, extracted from the bundle manifest.pubkey.pem: the signer's public key in SPKI PEM form (the formopensslcan ingest).
The command signs nothing and never modifies the bundle. It reads the bundle, reconstructs the signed statement, extracts the matching signature, and re-encodes the supplied public key.
With the optional --operator-key flag it additionally emits three operator-attestation artifacts
(operator_statement.bin, operator_signature.bin, operator_pubkey.pem) so the bundle's
AGEF-OPERATOR-v1 operator attestation is verifiable with stock openssl too. See the
--operator-key section below.
Prerequisites
- A signed
.akmonbundle produced byakmon bundle sign. The signing key is made withakmon bundle keygen. Note thatopenssl genpkeyemits PKCS#8 v1, whichringrejects, so it is not a substitute forkeygen. - The signer's public key as 64 hex characters in a file, the same artifact
akmon bundle keygen(--public-out) /akmon bundle signproduces andakmon bundle verify --verify-keyconsumes. - OpenSSL 3.x for the verification step. Stock LibreSSL (the macOS
/usr/bin/openssl) cannot verify Ed25519: it lacks-rawinand cannot load Ed25519 keys. Use an OpenSSL 3.x build.
Steps
Emit the artifacts:
akmon bundle prove-openssl /path/to/audit.akmon --verify-key signer.pub.hex --out-dir ./proof
Then verify offline with OpenSSL 3.x (the command is also printed by the step above):
openssl pkeyutl -verify -pubin -inkey ./proof/pubkey.pem -rawin -in ./proof/statement.bin -sigfile ./proof/signature.bin
A valid signature prints Signature Verified Successfully and exits 0. Tampering with
statement.bin (or using the wrong signature) makes openssl print Signature Verification Failure and exit non-zero.
Optional flags:
--operator-key <HEX_FILE>: also emit the operator-attestation artifacts (see below).--out-dir <DIR>: directory for the artifacts (default: current directory).--format human|json: defaulthuman. JSON emits BundleProveReportV1 with the artifact paths and the exactopenssl_command(plus anoperatorblock when--operator-keyis given).
Operator attestation with --operator-key
--operator-key is optional and additive: without it, the output (the three files, the human
text, and the JSON) is exactly as above. With it, the command additionally reads the operator's
raw Ed25519 public key (64 hex characters, the public half of the key that made an
akmon bundle attest operator attestation), finds the matching attestation in
manifest.operator_attestations[], and emits three more files into --out-dir:
operator_statement.bin: the exactAGEF-OPERATOR-v1bytes that were signed (the session head bound to the four self-asserted operator identity fields).operator_signature.bin: the 64-byte raw detached Ed25519 signature from the attestation.operator_pubkey.pem: the operator's public key in SPKI PEM form.
The --verify-key (head signature) artifacts are unchanged; the operator files sit alongside them.
The JSON gains an operator block with key_id, the self-asserted operator_id and role,
the three artifact paths, and the operator openssl_command. As with attestation, what openssl
proves is that the holder of the operator key signed those fields. Trust in the name is
out-of-band (see akmon bundle attest).
akmon bundle prove-openssl /path/to/audit.akmon \
--verify-key signer.pub.hex --operator-key operator.pub.hex --out-dir ./proof
Verify the operator attestation offline with OpenSSL 3.x (also printed by the step above):
openssl pkeyutl -verify -pubin -inkey ./proof/operator_pubkey.pem -rawin -in ./proof/operator_statement.bin -sigfile ./proof/operator_signature.bin
Exit codes
| Code | Meaning |
|---|---|
0 | Artifacts written; the printed openssl command(s) are ready to run |
1 | No signature matches --verify-key (unsupported/malformed); or --operator-key has no matching/unsupported/malformed operator attestation |
3 | I/O or environment error (bundle, --verify-key, or --operator-key unreadable, malformed archive, out-dir not writable) |
How this proves the wedge
The signature in manifest.signatures[] is a PureEd25519 signature over the deterministic
AGEF-SIG-v1 statement (version tag, AGEF version, hash algorithm, session id, and head, each on
its own LF-terminated line). prove-openssl writes those exact bytes verbatim and the raw 64-byte
signature, and wraps the public key in the RFC 8410 SPKI encoding openssl expects. Nothing about
the verification depends on Akmon, only on openssl and the public key the verifier already
trusts.
See also
akmon bundle export
Documented for Akmon 2.2.0.
Who this is for
Teams exporting a portable, verifiable session artifact for handoff, audit, or archive.
What you will have at the end
- A
.akmonbundle generated from one journal session. - Optional JSON metadata for automation.
Prerequisites
- Source session UUID.
- Access to source journal and write permission for output path.
Steps
akmon bundle export <session-id> [OPTIONS]
akmon bundle export <session-id> \
[--output <path>] \
[--journal <path>] \
[--format <human|json>]
- Export with defaults:
akmon bundle export <session-id>
- Export to explicit path:
akmon bundle export <session-id> --output /path/to/audit.akmon
- Use JSON in CI:
akmon bundle export <session-id> --format json
Exit codes
| Code | Meaning |
|---|---|
0 | Bundle written successfully |
1 | Reserved (not currently emitted) |
2 | Usage error (for example, output path already exists) |
3 | I/O or environment error (journal/session not found, missing object in store, write failure) |
Verification
akmon bundle export <session-id> --format json | jq '.output_path'
Expected result: output path is returned and command exits 0.
Bundle format
An .akmon bundle is a tar.zst archive containing:
manifest.jsonevents.binobjects/<hex>
Troubleshooting
- If export fails with output-exists error, choose a new
--outputpath. - If export fails with session/journal errors, verify UUID and
--journallocation. - Export does not replace integrity checks; run
akmon verifybefore export when required.
See also
akmon bundle import: ./bundle-import.mdakmon verify: ./verify.mdakmon inspect: ./inspect.md- AGEF specification
akmon bundle import
Documented for Akmon 2.2.0.
Who this is for
Teams validating and ingesting portable .akmon bundles into local journals.
What you will have at the end
- A verified bundle (
--verify-only) or imported session. - Clear handling for collisions and archive validation failures.
Prerequisites
- Path to a
.akmonbundle file. - Write access to target journal if ingesting.
Steps
akmon bundle import <bundle-path> [OPTIONS]
akmon bundle import <bundle-path> \
[--journal <path>] \
[--format <human|json>] \
[--verify-only] \
[--allow-extra-files] \
[--rename-to <NEW_UUID>]
- Validate bundle only (no local writes):
akmon bundle verify /path/to/audit.akmon
(akmon bundle import … --verify-only is a legacy alias with identical behavior.)
- Import into journal:
akmon bundle import /path/to/audit.akmon
- Resolve session-id collisions with rename:
akmon bundle import /path/to/audit.akmon --rename-to <new-uuid>
- Use JSON output in CI:
akmon bundle import /path/to/audit.akmon --verify-only --format json
Exit codes
| Code | Meaning |
|---|---|
0 | Bundle imported successfully (or verified successfully with --verify-only) |
1 | Bundle validation failed (AGEF integrity/structure violation) |
2 | Usage/recoverable import error (for example, session collision without suitable --rename-to) |
3 | I/O or environment error (bundle not found, unwritable journal, local store corruption) |
Verification
akmon bundle import /path/to/audit.akmon --verify-only --format json | jq '.passed'
Expected result: true for valid bundle, otherwise false with violations and exit 1.
Validation checks (AGEF alignment)
Import validation aligns with AGEF structural/integrity requirements, including:
- Manifest parse/schema-required fields
events.binframe decoding (length-prefixed canonical CBOR events)- Event hash-chain integrity
- Object closure (all referenced hashes present)
- Object byte re-hash (bytes match hash key)
- Head consistency (
manifest.session.headmatches terminal event hash) - Session boundary invariants (
SessionStartfirst,SessionEndterminal) - Sequence continuity (
0..n-1) - Strict unknown-content handling by default (unknown event tags/statuses/extra archive files rejected unless flags permit)
Troubleshooting
- If import exits
2for collision, rerun with--rename-to <NEW_UUID>. - If verify-only exits
1, inspect JSONviolationscategories. - If import exits
3, check bundle path, journal permissions, and disk availability.
See also
- akmon bundle verify
- agef-verify: standalone bundle verifier (no Akmon CLI)
akmon bundle export: ./bundle-export.mdakmon verify: ./verify.mdakmon inspect: ./inspect.md- AGEF specification
akmon inspect
Synopsis
Inspect one on-disk session journal and display its event contents.
akmon inspect <session-id> [OPTIONS]
akmon inspect <session-id> \
[--journal <path>] \
[--format <human|json>] \
[--verbose] \
[--resolve] \
[--binary <meta|hex|base64>]
Description
akmon inspect reads a stored session from the local Akmon journal and prints the event timeline with kind-specific fields. It is a read-only inspection command: no session data is created, modified, or deleted.
Use it when you need to review what happened in a session, debug tool/model behavior, or prepare audit evidence review. A reviewer can use inspect to see exactly what was said, what provider attempts occurred, what tools ran, and which hashes connect each step.
akmon inspect and akmon verify are complementary. inspect shows contents; verify checks integrity and tamper evidence. In v2.0.0 both are substrate-only commands and both target one session by UUID.
Arguments
<session-id> (required)
Hyphenated UUID assigned at AgentSession construction.
Example:
akmon inspect 550e8400-e29b-41d4-a716-446655440000
Options
--journal <path> (optional)
Journal directory to inspect. If omitted, Akmon resolves the default per-user journal path ($XDG_STATE_HOME/akmon/journal, per D-04).
--format <human|json> (optional, default: human)
Select output format:
human: terminal-friendly multi-line output.json: machine-readableInspectReportV1.
--verbose (optional)
Expands human output from summary to full detail: full hashes, parent hashes, emitted_at, and full provider attempt records. Has no effect on JSON output (JSON always includes full detail).
--resolve (optional)
Resolves referenced object hashes from local object storage and includes content-aware renderings (UTF-8 text or binary metadata). Without --resolve, inspect shows hash references only.
--binary <meta|hex|base64> (optional, default: meta)
Display mode for non-UTF-8 resolved content:
meta:<binary, N bytes, hash: ...>hex: first 64 bytes as lowercase hex pairs, then truncation footer if neededbase64: first 128 base64 characters, then truncation footer if needed
hex and base64 require --resolve. meta can be provided without --resolve, but has effect only when objects are resolved.
Exit codes
| Code | Meaning |
|---|---|
0 | Session displayed successfully |
1 | Reserved (not currently emitted by inspect) |
2 | Usage error (for example, --binary hex without --resolve) |
3 | I/O or environment error (journal/session not found, read failure) |
Output formats
Human (default, summary)
session: 550e8400-e29b-41d4-a716-446655440000
events: 4
journal: /home/user/.local/state/akmon/journal
[0] SessionStart hash=8b2a3f7c...
cwd_hash: 1f3a5b2e...
config_hash: 4e1d92a8...
[1] UserTurn hash=5c9d1e41...
prompt_hash: d7ac9f11...
[2] ProviderCall hash=9a7f220e...
provider: anthropic-claude
attempts: 1 (1 Success)
stream_hash: 0f23cd18...
[3] AssistantTurn hash=31b8f501...
message_hash: 69ea4bd9...
Human (verbose)
[2] ProviderCall hash=9a7f220e7fd7f52a0b9c6ec8337f9c0da52dc1a4f8e96767bfac44e5f3c4f2d0
parent: 5c9d1e41c9eb7b468b3f31c30d0495a6708ec61862db2f3ea1df1c53de2b9581
emitted_at: 2026-01-15T14:32:10.123Z
provider: anthropic-claude
attempts:
[1] status=Success started=14:32:10.123 ended=14:32:12.234
request_hash: 0a4d4c95b4...
response_hash: a4fbc71e2c...
stream_hash: 0f23cd18b1...
Human (resolve, text)
[1] UserTurn hash=5c9d1e41...
prompt_hash: d7ac9f11...
prompt:
| how do I configure the policy engine to allow shell
| commands matching a specific prefix without prompting
| each time?
Human (resolve, binary)
[4] ToolCall hash=cc77e1ab...
tool: read_file
input_hash: a1b2c3d4...
input: <binary, 1024 bytes, hash: a1b2c3d4...>
| a1 b2 c3 d4 e5 f6 ... (truncated, 960 more bytes)
JSON (--format json)
{
"akmon_version": "2.1.0",
"agef_version": "0.1.1",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"journal_path": "/home/user/.local/state/akmon/journal",
"events": [
{
"sequence": 1,
"event_hash": "5c9d1e41c9eb7b468b3f31c30d0495a6708ec61862db2f3ea1df1c53de2b9581",
"parent_hashes": [
"8b2a3f7c1ef0ea7e80f772f8f84f86b16f5527cd51ff8b0a464f157c4cd5c757"
],
"emitted_at": "2026-01-15T14:32:09.942Z",
"kind": {
"type": "user_turn",
"prompt_hash": "d7ac9f11f8069ce39f5df1863fcef84f8f46406fdb6f866f9317dbf2ca6fcb53",
"prompt_text": "how do I configure the policy engine?",
"prompt_size": 43
}
}
]
}
InspectReportV1
akmon_version: Akmon CLI version that produced this report.agef_version: AGEF specification version implemented by the substrate.session_id: session UUID (hyphenated lowercase).journal_path: resolved absolute journal directory used.events: array ofInspectEventin sequence order.
InspectEvent
sequence(u64): event sequence number (0-indexed).event_hash(string): lowercase hex-encoded event hash.parent_hashes(string[]): lowercase hex-encoded parent hashes.emitted_at(string): ISO 8601 UTC timestamp.kind(InspectEventKind): tagged event payload.
InspectEventKind
kind is a tagged enum with type discriminator (snake_case):
session_start:cwd_hash,config_hash, and with--resolveoptionalcwd_text/cwd_size,config_text/config_sizeuser_turn:prompt_hash, and with--resolveoptionalprompt_text/prompt_sizeprovider_call:provider_id,attempts,stream_hash, and with--resolveoptionalstream_text/stream_sizetool_call:tool_id,input_hash,output_hash,side_effects_hash, and with--resolveoptionalinput_text/input_size,output_text/output_size,side_effects_text/side_effects_sizeretrieval_call:index_id,query_hash,results_hash, and with--resolveoptionalquery_text/query_size,results_text/results_sizepermission_gate:policy_id,decision,context_hash, and with--resolveoptionalcontext_text/context_sizeassistant_turn:message_hash,tool_calls_hash, and with--resolveoptionalmessage_text/message_size,tool_calls_text/tool_calls_sizesession_end:summary_hash, and with--resolveoptionalsummary_text/summary_size
InspectAttempt
attempt_number(u32): 1-indexed attempt number.status(string): attempt status name.started_at(string): ISO 8601 UTC timestamp.ended_at(string): ISO 8601 UTC timestamp.request_hash(string): lowercase hex-encoded request hash.response_hash(string | null): response hash when present.stream_hash(string | null): stream transcript hash when present.error_message(string | null): provider error message when present.request_text/request_size,response_text/response_size,stream_text/stream_size: present only with--resolveand only when content is available.
InspectError
Infrastructure failures use this JSON shape:
{
"akmon_version": "2.1.0",
"category": "session_not_found",
"error": "cannot open journal ...: session not found: 550e8400-e29b-41d4-a716-446655440000"
}
akmon_version: Akmon CLI version that produced the error.category: one of:journal_not_foundsession_not_foundinspect_infrastructure_error
error: human-readable diagnostic message.
Examples
1) Inspect a session (default summary)
$ akmon inspect 550e8400-e29b-41d4-a716-446655440000
2) Verbose inspection
$ akmon inspect 550e8400-e29b-41d4-a716-446655440000 --verbose
3) Show resolved content (text and binary metadata)
$ akmon inspect 550e8400-e29b-41d4-a716-446655440000 --resolve
4) Show binary payloads as hex preview
$ akmon inspect 550e8400-e29b-41d4-a716-446655440000 --resolve --binary hex
5) JSON output for CI
$ akmon inspect 550e8400-e29b-41d4-a716-446655440000 --format json | jq '.events | length'
6) JSON with resolved user text
$ akmon inspect 550e8400-e29b-41d4-a716-446655440000 --format json --resolve \
| jq '.events[] | select(.kind.type == "user_turn") | .kind.prompt_text'
7) Custom journal path
$ akmon inspect 550e8400-e29b-41d4-a716-446655440000 --journal /tmp/my-journal
What inspect shows
inspect can display these event kinds:
SessionStartUserTurnProviderCall(including attempt details)ToolCallPermissionGateAssistantTurnSessionEndRetrievalCall(if present in journal; reserved for future Akmon emission)
RetrievalCall support is included for forward compatibility with AGEF and v2.0 planning; Akmon v2.0.0 does not emit it in normal runs.
What inspect does not do
- It does not verify integrity or tamper evidence (
akmon verifydoes that). - It does not modify session state (read-only journal access).
- It does not fetch content from external systems (resolution reads only local journal object bytes).
- It does not decode domain-specific binary encodings beyond UTF-8 detection and preview rendering.
Programmatic / CI usage
- Use
--format jsonandjq(or your parser) to query events by kind and field. - Use exit codes (
0/2/3) to handle success, usage issues, and missing journal/session cases. --resolveincreases read cost with total resolved object size; skip when hashes are sufficient.- Output is deterministic for the same session contents (covered by integration test
t_inspect_output_stability).
See also
akmon verify: ./verify.md- AGEF specification: github.com/radotsvetkov/agef
akmon export/akmon import(Item 4.3, coming)
akmon redact
Documented for Akmon 2.2.0.
Who this is for
Teams generating sanitized derivative bundles for external review without exposing sensitive object content.
What you will have at the end
- A derivative
.akmonbundle with selected objects replaced by redaction sentinels. - A reproducible command trail with explicit rationale (
--reason).
Prerequisites
- Source session UUID.
- Object hashes to redact (typically found via
akmon inspect --resolve). - Writable destination path for
--output.
Steps
akmon redact <session-id> [OPTIONS]
akmon redact <session-id> \
--output <path> \
--object <hash> [--object <hash> ...] \
--reason <text> \
[--journal <path>] \
[--format <human|json>]
- Create sanitized derivative bundle:
akmon redact <session-id> \
--output sanitized.akmon \
--object <object-hash> \
--reason "PII removal"
-
For multiple objects, repeat
--object. -
Verify derivative bundle before sharing:
akmon bundle import sanitized.akmon --verify-only
Exit codes
| Code | Meaning |
|---|---|
0 | Derivative bundle written successfully |
1 | Reserved (not currently emitted by redact) |
2 | Usage error (output exists, invalid hash format, object not in session, missing required flag) |
3 | I/O or environment error (journal/session not found, write failure, unreadable referenced object) |
Verification
akmon redact <session-id> --output sanitized.akmon --object <object-hash> --reason "compliance" --format json | jq '.objects_redacted_count'
Expected result: positive redacted-object count and exit 0.
Sentinel format
Redacted objects are replaced by canonical-CBOR sentinel objects with this payload:
{
"akmon_redacted": true,
"original_hash": "<hex of original>",
"original_size": 1024,
"reason": "<text from --reason>",
"redacted_at": "<RFC3339 timestamp>"
}
Troubleshooting
- If output path exists, choose a new
--outputtarget. - If
--objectis rejected, confirm lowercase hex hash and that it is referenced in source session. - Redaction does not verify source integrity automatically; run
akmon verify <session-id>first when required.
See also
akmon replay
Documented for Akmon 2.2.0.
Who this is for
Engineers replaying recorded sessions to detect divergences and regression behavior.
What you will have at the end
- A replay pass/fail report (
defaultorstrictmode). - Optional persisted replay session in a target journal.
Prerequisites
- Source session UUID.
- Journal access to source session.
Steps
akmon replay <session-id> [OPTIONS]
akmon replay <session-id> \
[--journal <path>] \
[--mode <default|strict>] \
[--persist --persist-to <path>] \
[--format <human|json>]
- Run default replay:
akmon replay <session-id>
- Use strict mode if you want tighter mismatch handling:
akmon replay <session-id> --mode strict
- Use JSON in CI:
akmon replay <session-id> --format json
- Persist replay output only with explicit target:
akmon replay <session-id> --persist --persist-to /path/to/replay-journal
Exit codes
| Code | Meaning |
|---|---|
0 | Replay completed with no divergences (passed: true) |
1 | Replay completed with divergences (passed: false) |
2 | Usage error (invalid arguments or invalid flag combinations) |
3 | I/O or environment error (missing source session, malformed source, unwritable persist target, etc.) |
Verification
akmon replay <session-id> --format json | jq '.passed'
Expected result: true for equivalent replay; false if divergences are detected.
Examples
1) Replay a session with default mode
$ akmon replay 550e8400-e29b-41d4-a716-446655440000
2) Replay in strict mode
$ akmon replay 550e8400-e29b-41d4-a716-446655440000 --mode strict
3) JSON output for CI
$ akmon replay 550e8400-e29b-41d4-a716-446655440000 --format json | jq '.passed'
4) Persist replay output in a target journal
$ akmon replay 550e8400-e29b-41d4-a716-446655440000 \
--persist \
--persist-to ./replay-journal
5) Replay from a non-default journal
$ akmon replay 550e8400-e29b-41d4-a716-446655440000 --journal /custom/journal
Troubleshooting
- If
--persistfails, ensure--persist-tois provided and writable. - If replay cannot load source data, validate
--journalpath and source session UUID. - If replay fails with divergences, inspect JSON
divergencesfor event-level mismatch details. - For integrity-first workflow, run
akmon verify <session-id>before replay.
See also
akmon diff
Synopsis
akmon diff <session-a> <session-b> [OPTIONS]
akmon diff 550e8400-e29b-41d4-a716-446655440000 6ba7b810-9dad-11d1-80b4-00c04fd430c8 \
[--journal <path>] \
[--resolve] \
[--format <human|json>]
Description
akmon diff compares two recorded sessions in the same journal scope and reports structural and field-level divergences. Both UUIDs must exist under the selected journal directory (default: $XDG_STATE_HOME/akmon/journal unless --journal is set).
Use diff for evidence-side regression checks (two runs of the same workflow), replay validation (source session vs replayed session in one store), and audit explanations (“what changed between these two session heads?”).
Comparison is lockstep by event sequence. When event kinds or counts diverge, diff reports a structural break and stops further alignment for that pair.
Arguments
<session-a>, <session-b> (required)
Hyphenated UUIDs of the two sessions to compare.
Options
--journal <path> (optional)
Journal directory containing journal.redb for both sessions. If omitted, Akmon uses the default journal location.
--resolve (optional)
Dereference content hashes for comparable fields and attach byte-level summaries (resolved or resolved_skip_reason on each divergence in JSON). Without this flag, comparison uses hash and structural summaries only.
--format <human|json> (optional, default: human)
human: terminal-oriented summary; divergences list is capped at 10 entries (same cap asakmon replayhuman output), with a footer pointing to JSON for the full list.json:DiffReportV1as pretty-printed JSON on standard output.
Exit codes
| Code | Meaning |
|---|---|
0 | Compared successfully; sessions are equivalent (matches: true) |
1 | Compared successfully; divergences or structural break (matches: false) |
2 | Usage error (for example malformed session UUID caught as a load error in edge paths; most parse failures exit via Clap with code 2) |
3 | Infrastructure error (journal resolution failure, missing session, load/precondition failure, store access failure, print failure) |
Output formats
Human (default)
First lines mirror the replay report shape: command line, indented stats (mode, events compared, per-session event counts, divergence count, matches: yes|no). When comparison fails, optional structural break: and divergences: sections follow, with expected: / actual: lines per divergence. With --resolve, divergences may include resolved: byte summaries or resolve skipped: reasons.
JSON
Pretty-printed DiffReportV1 (schema owned by the akmon-diff crate). Suitable for CI ingestion and golden tests.
See also
- akmon replay: replay comparison and exit-code discipline aligned with diff
- akmon inspect: single-event inspection;
--resolvepreview rules are aligned with diff resolve mode
Phase 6 (Item 6.3). v2.0.0 ships CLI diff with human and JSON reporting, integration tests, and a single shared journal.redb open when loading both sessions so redb per-process locking is respected.
akmon verify
Documented for Akmon 2.2.0.
Who this is for
Reviewers, CI engineers, and operators validating recorded session integrity before trusting artifacts.
What you will have at the end
- A pass/fail integrity decision for one session UUID.
- Optional JSON output suitable for CI gates.
Prerequisites
- A session UUID from a completed Akmon run.
- Access to the journal directory (default or custom).
Steps
- Run verification on a session UUID.
akmon verify <session-id>
- Use JSON for automation.
akmon verify <session-id> --format json
- Use optional flags as needed:
--journal <PATH>--format <human|json>(defaulthuman)--verbose
Exit codes
| Code | Meaning |
|---|---|
0 | Verification succeeded (no violations) |
1 | Verification completed and found violations |
2 | Usage error (argument parsing/CLI contract) |
3 | I/O or environment error (journal/session/infrastructure failure) |
Verification
akmon verify <session-id> --format json | jq '.passed'
Expected result: true for an intact session; non-zero exit with violations/errors otherwise.
What verify checks (AGEF Section 13 alignment)
- Parent chain integrity: each non-start event points to the expected prior event.
- Sequence integrity: event sequences are contiguous (
0..n-1). - Event hash recompute: canonical CBOR event bytes hash to stored event hashes.
- Object presence: each referenced object hash resolves in object storage.
- Object byte re-hash: resolved object bytes hash back to referenced object hashes.
- Head consistency: stored session head equals the terminal event hash.
- SessionEnd invariants: exactly one
SessionEnd, and it is terminal.
Troubleshooting
exit 2: invalid CLI usage; re-checkakmon verify --help.exit 3: session/journal access error; verify UUID and--journalpath.exit 1: integrity violation found; inspect JSONviolationsfor exact category.
See also
Record who approved an AI change
Documented for Akmon 2.2.0.
Who this is for
An operator or approver who has to put their name, backed by a key, behind an AI agent session. If your process needs a human to sign off on what an agent did, for example to satisfy a human-oversight requirement such as EU AI Act Article 14, this page shows how to attach a key-backed operator attestation to a bundle and how a verifier later confirms it offline.
The session itself is produced separately (by Akmon's reference agent or imported from an OpenTelemetry trace) and exported to a .akmon bundle. This use case is about the sign-off layered on top of that bundle.
What you end up with
- An operator key pair that identifies you as the approver.
- A
.akmonbundle carrying a signedAGEF-OPERATOR-v1attestation that binds youroperator_idandroleto the session head. - A public key a verifier can use, out of band, to confirm that the holder of your operator key approved the session, with
akmon bundle verify --require-operator-key.
The honest boundary: trust attaches to the key, not the name
An operator attestation is a signature over four self-asserted identity fields (operator_id, display_name, role, org) plus the session head. Verifying it proves only that the holder of a particular private key signed those fields. It does not prove that the person is who the operator_id string says. The name is a claim; the key is the trust anchor.
A verifier establishes which key belongs to which person out of band, through your own process: an HR directory, a signed roster, a key-distribution ceremony. Only after a verifier has decided to trust a specific key does the self-asserted name carry weight. Akmon never asserts the name is true on its own.
What this does prove: the holder of operator key K approved this exact session, with the role they stated, and the attestation is bound to this bundle's head so it cannot be transplanted onto a different session.
What it does not prove: that the named person physically pressed a button, that the agent's work was correct, or that any obligation was met. Those are out of band.
Steps
- Generate an operator key. Keep the private key secret; you will distribute only the public key.
akmon bundle keygen --out operator.pk8 --public-out operator.pub.hex
- Attest the bundle with your operator id and role. The attestation is appended in place and is purely additive: the event hash chain and any existing head signature are left byte-untouched.
akmon bundle attest /path/to/session.akmon \
--key operator.pk8 \
--operator-id approver@example.com \
--display-name "A. Approver" \
--role approver \
--org "Example Corp"
-
Distribute
operator.pub.hexto verifiers out of band, through the channel your process trusts. This step is what makes the name meaningful later; without it a verifier only sees a self-asserted string. -
The verifier requires that specific operator key to have a valid attestation.
akmon bundle verify /path/to/session.akmon \
--operator-key operator.pub.hex \
--require-operator-key operator.pub.hex
This exits 0 only when the named key has a cryptographically valid attestation on the bundle. With --require-operator instead, any one trusted operator key satisfies the gate; with --require-operator-key the gate names a specific key. Without any trusted key supplied, an attested bundle reports unverified_no_key, which is informational rather than a failure. A verifier who does not run Akmon can use the standalone agef-verify with the same flags.
Combine with a head signature
Operator sign-off answers "who approved this". The bundle's head signature answers "is the record intact and from a trusted producer". They are independent and complementary. A typical sealed handoff requires both:
akmon bundle verify /path/to/session.akmon \
--verify-key signer.pub.hex --require-signature \
--operator-key operator.pub.hex --require-operator-key operator.pub.hex
See also
- akmon bundle attest
- akmon bundle keygen
- akmon bundle verify
- Trust and threat model
- Regulated reviewer flow
- Verify evidence on an air-gapped machine
Verify evidence on an air-gapped machine
Documented for Akmon 2.2.0.
Who this is for
An auditor, regulator, or counterparty who received a .akmon bundle and a public key and needs to check it independently. You may be on an air-gapped machine, you may not run Akmon, and you do not need to trust whoever produced the bundle. This page shows three ways to verify, in increasing order of independence, and how to read the outcome honestly.
What you should have
- The
.akmonbundle file. - The signer's public key as 64 hex characters, and, if accountability matters, the operator's public key, both obtained through a channel you trust. Key trust is out of band; Akmon does not distribute keys.
Three ways to verify
Each method checks the same record. They differ in how much of the producer's tooling you must trust.
1. Akmon's own verifier
If you have Akmon installed, this runs every stage of the chain in one command.
akmon bundle verify /path/to/session.akmon \
--verify-key signer.pub.hex \
--require-signature \
--operator-key operator.pub.hex \
--require-operator \
--require-capture full
Drop the require flags you do not need. Without --require-signature, an unsigned or unknown-key bundle is reported, not failed; with it, missing provenance is a hard failure. The same applies to the operator and capture requirements.
2. The standalone verifier
agef-verify is a minimal binary that performs the bundle integrity, signature, operator, and capture checks without the full Akmon agent. Install it on its own (Homebrew tap or release binary). Use this when you want to verify without bringing in the whole agent.
agef-verify /path/to/session.akmon \
--verify-key signer.pub.hex \
--require-signature
It accepts --operator-key, --require-operator, and --require-operator-key with the same semantics as akmon bundle verify.
3. Plain openssl, no Akmon at all
This is the strongest independence: verify the Ed25519 signature with stock openssl and nothing else. Someone with Akmon (the producer, or you on a connected machine) first emits the proof artifacts; the artifacts then travel to the air-gapped machine, where only openssl is needed.
akmon bundle prove-openssl /path/to/session.akmon \
--verify-key signer.pub.hex \
--operator-key operator.pub.hex \
--out-dir ./proof
That writes statement.bin (the exact signed bytes), signature.bin (the raw 64-byte signature), and pubkey.pem (the signer's public key in PEM form), plus the operator equivalents (operator_statement.bin, operator_signature.bin, operator_pubkey.pem) when --operator-key is given. Then verify the head signature:
openssl pkeyutl -verify -pubin -inkey ./proof/pubkey.pem -rawin -in ./proof/statement.bin -sigfile ./proof/signature.bin
A valid signature prints a success line and exits 0. To check the operator attestation, run the same command against operator_pubkey.pem, operator_statement.bin, and operator_signature.bin. The exact commands are also printed by prove-openssl.
OpenSSL 3.x note: you need OpenSSL 3.x for this step. The macOS system openssl is LibreSSL and cannot verify Ed25519; it lacks -rawin and cannot load the key. Use an OpenSSL 3.x build.
How to read the outcome
A verification result is not a single yes or no. Read each signal for what it actually says.
- Verified. Integrity holds, and any provenance or accountability you required checked out against a key you supplied. You can conclude the record was not altered and that the holders of the named keys sealed and, if attested, claimed it. You still cannot conclude the agent was correct or that any person holds the key; that is out of band.
- Invalid (hard fail). Integrity failed, or a check you required did not pass. Do not rely on the record. If integrity failed, the bytes were altered or corrupted and nothing downstream is trustworthy. Stop here.
- Unverified, no key (
unverified_no_key). The bundle carries a signature or attestation, but you did not supply a matching trusted key, so provenance is not yet established. This is not a failure on its own. Obtain the right key out of band and re-run, or require it explicitly if its absence should fail. - Unattributed. No operator attestation is present, or none verifies against a key you trust. The record may still have integrity and a valid head signature, but no operator key has claimed accountability. If you need a named, key-backed claim, treat this as insufficient and require it.
capture_level: structuralversusfull. A structural record (an OpenTelemetry import) captures the shape of the session, not a complete recording, and cannot be replayed deterministically. A full record (Akmon's own reference agent) is a complete, replayable recording. If your evidence needs a full recording, require it with--require-capture full; a structural import will fail that check, which is the honest result. Do not read a structural import as a full recording.
A note on stripped trust metadata
Signatures and operator attestations are additive manifest fields. An intermediary who controls the file can remove them, and the remaining record still verifies for integrity. Cryptography cannot prove that something absent was once present. If provenance or accountability matters, do not rely on a signature merely being present in a bundle you happened to receive. Require it with the flags above and supply the trusted keys, so a stripped or unknown-key bundle fails rather than passes quietly.
See also
- Verifying evidence (for auditors)
- Trust and threat model
- akmon bundle verify
- agef-verify
- akmon bundle prove-openssl
- Record who approved an AI change
Assemble a signed evidence pack for a regulated release
Documented for Akmon 2.2.0.
Who this is for
A release or compliance owner who must hand a reviewer or auditor a defensible, independently verifiable record of the AI-assisted work that went into a regulated release. This page walks the full assembly: gather the relevant sessions, export and sign them, capture operator sign-off, and verify with the requirements your obligation actually needs, so the pack a reviewer receives can be checked offline without trusting your tooling.
What you end up with
- One signed
.akmonbundle per relevant session, sealed with an Ed25519 head signature. - An operator attestation on each bundle recording who approved it, backed by a key.
- A verification result that holds the signature present and, where required, the capture level full.
- A pack a reviewer can verify independently with Akmon, the standalone
agef-verify, or plainopenssl.
Before you start
Create a signing key once and publish the public half to reviewers out of band.
akmon bundle keygen --out signer.pk8 --public-out signer.pub.hex
Keep signer.pk8 secret. The reviewer trusts the public key, not your machine, so the channel you use to hand over signer.pub.hex is what gives the signature meaning.
Steps
- Produce or import the relevant sessions.
For work done by Akmon's own reference agent, run the task and note the session id; this is a full-capture, replayable recording.
akmon --yes --output json --task "implement and test the release change" | tee run.json
SESSION_ID="$(jq -r '.session_id' run.json)"
For work done by another agent that is OpenTelemetry-instrumented, import its trace; this is a structural record, the shape of the session and not a full recording.
akmon otel import /path/to/trace.json --journal ./journal --format json
- Export each session as a portable bundle.
akmon bundle export "${SESSION_ID}" --output "${SESSION_ID}.akmon"
- Sign the bundle's head offline.
akmon bundle sign "${SESSION_ID}.akmon" --key signer.pk8
- Attest operator sign-off, binding the approver's key and role to the session.
akmon bundle attest "${SESSION_ID}.akmon" \
--key operator.pk8 \
--operator-id approver@example.com \
--role approver
See Record who approved an AI change for the operator key setup and the honest boundary: the attestation proves the holder of the operator key approved the session, not that the named person did. Trust attaches to the key, established out of band.
- Verify the pack with the requirements the obligation needs. Require a present, valid signature, and require full capture only where the obligation calls for a complete recording.
akmon bundle verify "${SESSION_ID}.akmon" \
--verify-key signer.pub.hex --require-signature \
--operator-key operator.pub.hex --require-operator-key operator.pub.hex \
--require-capture full
A full-capture reference-agent session passes --require-capture full. A structural OTEL import fails that check, which is the honest result; for those sessions, drop --require-capture full and treat the bundle as structural evidence rather than a replayable recording. Do not present a structural import as a full recording.
What the reviewer receives and how they check it
Hand the reviewer the signed .akmon bundles and the public keys (signer.pub.hex, and operator.pub.hex if accountability matters). The reviewer establishes key trust through their own process and then verifies independently, with no need to trust your machine:
- With Akmon:
akmon bundle verify <bundle> --verify-key signer.pub.hex --require-signature. - Without the full agent:
agef-verify <bundle> --verify-key signer.pub.hex --require-signature. - With nothing but openssl: you emit
akmon bundle prove-openssl <bundle> --verify-key signer.pub.hex --out-dir proof, and the reviewer runs the printedopenssl pkeyutl -verify ...command (OpenSSL 3.x; macOS LibreSSL cannot verify Ed25519).
The full reading guide for outcomes (verified, invalid, unverified_no_key, unattributed, structural versus full) is in Verify evidence on an air-gapped machine.
The honest boundary
A verified pack proves integrity and key-backed provenance: the records were not altered and the holders of the named keys sealed and approved them. It does not prove the agent was correct, that any person holds a key, or that any regulatory obligation was met. Akmon helps you produce evidence for obligations such as EU AI Act Article 12 and Annex IV record-keeping, NIST AI RMF MEASURE 2.8, and SOC 2 CC7.x and CC8.1, but it is not a certification and does not guarantee compliance. Require the capture level your obligation actually needs, and validate any regulatory use with your own legal and compliance teams. See Compliance and evidence for the precise boundary.
See also
- Compliance and evidence
- Regulated reviewer flow
- akmon bundle export
- akmon bundle sign
- akmon bundle attest
- akmon bundle verify
- Record who approved an AI change
- Verify evidence on an air-gapped machine
Tutorials overview
Documented for Akmon 2.2.0.
Akmon is a producer-agnostic, tamper-evident evidence and verification layer for AI agents. It sits on top of whatever agent you run, an OpenTelemetry-instrumented agent of your own or Akmon's bundled reference agent, and turns each session into a portable, content-addressed, cryptographically signed record. A third party can verify that record offline with nothing but openssl: no Akmon install, no cloud, no need to trust whoever produced it.
These tutorials are organized by perspective of usage. Find the role you are working in and start there. The trust chain is the same across roles; what differs is what you produce, what you sign, and what you check.
Before you start
Complete:
- Installation
- Quick start, which walks the full trust flow: keygen, otel import, sign, verify, prove-openssl, openssl
- optional provider setup if you plan to run the bundled reference agent
Recommended baseline command:
akmon --version
The developer producing evidence
You run an agent and want a verifiable record of what it did. If your agent is OpenTelemetry-instrumented, you import its trace; if you use Akmon's reference agent, you get a full-capture, replayable recording. Either way you end with a signed bundle a reviewer can check.
| Tutorial | Outcome |
|---|---|
| Third-party OTEL trace to offline openssl proof | Import an OpenTelemetry trace, sign it, verify it, and prove the signature with plain openssl, no Akmon install on the verifier's side. This is the producer-agnostic headline path and needs no Akmon agent at all. |
| Local-first developer flow (Ollama) | Run the reference agent fully local and air-gap-friendly, and still emit a portable, signed, independently verifiable record. |
The operator or approver signing off
You are accountable for a change and must put your name, backed by a key, behind a session. You attest the bundle with an operator key, and a reviewer can later confirm offline which key claimed it. Trust attaches to the key, not to the self-asserted identity string.
| Page | Outcome |
|---|---|
| Record who approved an AI change | Generate an operator key, attest a bundle with your operator id and role, distribute the public key out of band, and let a verifier require that specific key. |
The auditor verifying
You received a .akmon bundle and a public key, possibly on an air-gapped machine, and you do not run Akmon. You check integrity, signature, operator attestation, and capture level, and you read the outcome honestly.
| Page | Outcome |
|---|---|
| Verify evidence on an air-gapped machine | Verify with akmon bundle verify, with the standalone agef-verify, or with plain openssl against prove-openssl artifacts, and read outcomes correctly. |
The release or compliance owner assembling a pack
You gather the sessions for a regulated release, sign them, capture operator sign-off, and hand a reviewer a pack they can independently check. You require the signature and capture level the obligation actually needs.
| Page | Outcome |
|---|---|
| Assemble a signed evidence pack for a regulated release | Produce or import sessions, export and sign bundles, attest operator sign-off, and verify with --require-signature and --require-capture. |
| CI headless governance flow | Make CI fail unless a signed, verified evidence bundle exists, on top of the audit, evidence, and SLO gates. |
| Enterprise policy rollout | Stage dev, staging, then prod policy profiles, tie the recorded policy_hash to evidence, and hand reviewers a signed bundle. |
Honest scope
Akmon helps you produce evidence. A session run under the bundled reference agent is full capture and replays; an OpenTelemetry import is structural, the shape of the session and not a full recording, so akmon bundle verify --require-capture full fails on it and replay refuses it. Akmon can help you produce evidence for obligations such as EU AI Act Article 12 and Annex IV record-keeping, NIST AI RMF MEASURE 2.8, and SOC 2 CC7.x and CC8.1, but it is not a certification and does not guarantee compliance. Validate any regulatory use with your own legal and compliance teams. See Compliance and evidence for the boundary.
Troubleshooting prerequisites
- If
opensslcannot verify a proof on macOS, you are on LibreSSL. Use OpenSSL 3.x. - If
akmon bundle signrejects a key, regenerate it withakmon bundle keygen(it produces the required PKCS#8 v2 form). - If
--require-capture fullfails on an imported session, that is expected. Imports arestructural. - If provider calls fail in the reference agent, verify keys and model names first.
Related: Glossary, Regulated reviewer flow, Verifying evidence, Trust and threat model, headless mode.
Tutorial: Local-first developer flow (Ollama)
Documented for Akmon 2.2.0.
Time estimate: 15-25 minutes
Complexity: Beginner
Who this is for
Developers who want a fully local Akmon workflow, with no provider API calls leaving the machine, that still produces a portable, signed, independently verifiable record of the session. This is the local-first, air-gap-friendly path: the model runs on your hardware through Ollama, and the evidence the agent produces can be handed to a reviewer and checked offline with nothing but a public key.
What you will have at the end
- One interactive local session and one equivalent headless JSON run, using a model served by Ollama.
- Verified audit and evidence artifacts for review.
- A signed
.akmonbundle that a third party can verify offline, including with plainopenssl, without trusting your machine.
Prerequisites
akmon --versionprints your current build (2.2.0for this release).ollamais installed and running, with the model you intend to use already pulled, so no network is needed at run time.- You are inside a git repository.
- A signing key, created once with
akmon bundle keygen --out signer.pk8 --public-out signer.pub.hex. Keepsigner.pk8private; publish onlysigner.pub.hex.
Steps
- Pull a local model and verify Akmon. Pulling ahead of time means the run itself needs no network.
ollama pull qwen2.5-coder:7b
akmon --version
- Start interactive mode with the local model and the
devpolicy profile.
cd /path/to/your-repo
akmon --model qwen2.5-coder:7b --policy-profile dev chat
- Run one controlled implementation request.
add validation to the registration handler and update tests
Expected result: Akmon asks for approvals before write actions.
- Run an equivalent headless task for machine-readable artifact output.
akmon --model qwen2.5-coder:7b --yes --output json \
--task "add validation to the registration handler and update tests" \
| tee run.json
- Extract the session ID and verify the recorded artifacts.
SESSION_ID="$(jq -r '.session_id' run.json)"
akmon audit verify ".akmon/audit/${SESSION_ID}.jsonl"
akmon evidence verify ".akmon/evidence/${SESSION_ID}.json"
akmon verify "${SESSION_ID}"
- Export the session as a portable bundle and sign it offline.
akmon bundle export "${SESSION_ID}" --output "${SESSION_ID}.akmon"
akmon bundle sign "${SESSION_ID}.akmon" --key signer.pk8
akmon bundle verify "${SESSION_ID}.akmon" --verify-key signer.pub.hex --require-signature
Everything here runs locally. The model inference is Ollama on your machine, and the keygen, sign, and verify steps are offline Ed25519 operations that never contact a network. The result is a self-contained record you can move to a reviewer.
Air-gap note
Both the inference and the trust chain work without a network. Pull the model once while connected, then the run, the signing, and the verification all work on an isolated machine. The reviewer's side is offline too: they can verify the signed bundle with akmon bundle verify, the standalone agef-verify, or plain openssl against prove-openssl artifacts. See Verify evidence on an air-gapped machine.
What gets recorded in evidence
- Session metadata (session, model, and provider context, here the local Ollama model).
- Tool execution and reliability metrics.
- Replay metadata and the policy and tool-registry hashes.
- Paths to the audit and evidence artifacts for review handoff.
A reference-agent run is full capture, so the session is deterministically replayable and akmon bundle verify --require-capture full passes on its bundle.
How a reviewer validates this
- Confirm
akmon verify <session-id>exits0. - Confirm
akmon audit verifyandakmon evidence verifyboth succeed. - Confirm
akmon bundle verify ... --verify-key signer.pub.hex --require-signatureexits0with averifiedsignature outcome. - Inspect
run.jsonfields (session_id,status,reliability_metrics,replay_metadata) for expected run characteristics.
Verification
jq '{session_id,status,reliability_metrics,replay_metadata}' run.json
Expected result: a JSON object with a non-empty session_id and status.
Troubleshooting
- If Ollama is unavailable, check
ollama psand retry. - If provider resolution is unexpected, run
akmon config explain-provider. - If the first local response is slow, warm it with
ollama run qwen2.5-coder:7bonce before rerunning. - If
akmon bundle signrejects the key, regenerate it withakmon bundle keygen;openssl genpkeyemits PKCS#8 v1, which the signing path rejects.
See also
Tutorial: CI headless governance flow
Documented for Akmon 2.2.0.
Time estimate: 25-35 minutes
Complexity: Intermediate
Who this is for
Platform and release teams running Akmon non-interactively in CI who want the pipeline to fail unless a session produced a signed, independently verifiable evidence bundle. The own-agent audit, evidence, and SLO checks still run, but here they feed a single artifact a reviewer or auditor can verify offline.
What you will have at the end
- A reproducible headless run command with a budget cap.
- Own-agent integrity gates (
audit,evidence,verify) and SLO and trend gates. - A signed
.akmonbundle, exported from the session and verified in CI withakmon bundle verify --verify-key --require-signature, so the gate that matters is provenance, not just that the agent ran.
Prerequisites
- CI runner has
akmoninstalled. - Runner has provider credentials (for example
ANTHROPIC_API_KEY) or a local model setup. - Repository has write access to
.akmon/output paths. - A signing key is available to CI as a secret. Generate it once with
akmon bundle keygen --out signer.pk8 --public-out signer.pub.hex, keepsigner.pk8secret (inject it from your CI secret store at runtime), and commit or publish onlysigner.pub.hex.
Steps
- Execute a headless run with JSON output and a budget cap.
akmon --yes --output json \
--max-budget-usd 2.00 \
--task "run cargo test and summarize failures" \
| tee run.json
- Extract the session ID and run the own-agent integrity checks.
SESSION_ID="$(jq -r '.session_id' run.json)"
akmon audit verify ".akmon/audit/${SESSION_ID}.jsonl"
akmon evidence verify ".akmon/evidence/${SESSION_ID}.json"
akmon verify "${SESSION_ID}"
- Enforce per-run SLO thresholds and the trend gate.
akmon slo verify ".akmon/evidence/${SESSION_ID}.json" \
--thresholds .github/akmon/slo.toml \
--strict
akmon slo trend ".akmon/evidence/${SESSION_ID}.json" \
--baseline-dir .akmon/evidence/history \
--window 20 \
--strict
- Export the session as a bundle and sign it offline.
akmon bundle export "${SESSION_ID}" --output "session.akmon"
akmon bundle sign "session.akmon" --key signer.pk8
- The governance gate: require a present, valid signature against the published public key.
akmon bundle verify "session.akmon" \
--verify-key signer.pub.hex \
--require-signature \
--require-capture full
akmon bundle verify exits 0 only when the bundle's objects, event chain, and manifest head are internally consistent and the head signature verifies against signer.pub.hex. With --require-signature, a missing or stripped signature is a hard failure (exit 1) rather than a quiet pass. A reference-agent run is full capture, so --require-capture full passes here; it would correctly fail on a structural OTEL import. Exit 3 indicates an I/O or environment error. This is the gate that proves a verifiable record exists, not merely that the agent finished.
- Wire the same sequence into CI. The bundle verification step is the one that blocks the merge.
- name: Run Akmon headless
run: akmon --yes --output json --max-budget-usd 2.00 --task "run tests and summarize failures" | tee run.json
- name: Extract session ID
run: echo "SESSION_ID=$(jq -r '.session_id' run.json)" >> $GITHUB_ENV
- name: Verify audit, evidence, and session integrity
run: |
akmon audit verify ".akmon/audit/${SESSION_ID}.jsonl"
akmon evidence verify ".akmon/evidence/${SESSION_ID}.json"
akmon verify "${SESSION_ID}"
- name: Enforce SLO and trend guardrails
run: |
akmon slo verify ".akmon/evidence/${SESSION_ID}.json" --strict
akmon slo trend ".akmon/evidence/${SESSION_ID}.json" --baseline-dir .akmon/evidence/history --window 20 --strict
- name: Export and sign the evidence bundle
run: |
printf '%s' "${AKMON_SIGNING_KEY_B64}" | base64 -d > signer.pk8
akmon bundle export "${SESSION_ID}" --output session.akmon
akmon bundle sign session.akmon --key signer.pk8
rm -f signer.pk8
- name: Gate on a signed, verified bundle
run: akmon bundle verify session.akmon --verify-key signer.pub.hex --require-signature --require-capture full
- name: Upload the signed evidence bundle
uses: actions/upload-artifact@v4
with:
name: akmon-evidence
path: session.akmon
AKMON_SIGNING_KEY_B64 is the base64 of signer.pk8, stored as a CI secret. The private key is written only for the signing step and removed immediately.
What gets recorded in evidence
- Reliability metrics used by
slo verifyandslo trend. - Replay metadata hashes, including the policy and tool-registry hashes, for deterministic validation context.
- Provider resolution and session-level run status.
The same content is what the exported bundle commits to and the head signature seals, so the artifact CI uploads is exactly what a reviewer verifies later.
How a reviewer validates this
- Confirm all own-agent integrity commands exit
0. - Confirm
akmon bundle verify session.akmon --verify-key signer.pub.hex --require-signatureexits0with averifiedsignature outcome. - Confirm
--require-capture fullpasses for the reference-agent run. - Confirm CI artifacts include the signed
session.akmonandrun.jsonfor retained runs.
A reviewer who does not run Akmon can verify the uploaded bundle with the standalone agef-verify or with plain openssl; see Verify evidence on an air-gapped machine.
Verification
jq '{session_id,status,reliability_metrics}' run.json
Expected result: non-empty session_id, an explicit status, and a reliability metrics object.
Troubleshooting
- If CI fails before Akmon starts, verify provider credentials in the runner environment.
- If
akmon bundle signrejects the key, regenerate it withakmon bundle keygen;openssl genpkeyemits PKCS#8 v1, which the signing path rejects. - If
bundle verify --require-signaturefails, the signature is missing, stripped, or does not matchsigner.pub.hex. Confirm the signing step ran and the public key matches the private key in CI. - If
slo verifyfails, inspect the threshold file and theviolationsoutput. - If policy denials block the run, inspect
policy_denials_totalin metrics and reconcile with the configured profile and packs. - Failure behavior is intentional: non-zero exits from
audit,evidence,verify,slo, andbundle verifyshould fail pipeline gates.
See also
- akmon bundle verify
- akmon bundle sign
- akmon bundle keygen
- Assemble a signed evidence pack for a regulated release
- Regulated reviewer flow
Tutorial: Third-party OTEL trace to offline openssl proof
Documented for Akmon 2.2.0.
Time estimate: 15-20 minutes
Complexity: Intermediate
Who this is for
Teams whose agents are already instrumented with a third-party OpenTelemetry GenAI
instrumentation, who want a signed, standalone-verifiable audit record of a session, and
auditors who must check that record with stock openssl alone: no Akmon binary, no cloud,
no vendor lock-in.
This is the headline trust loop, end to end, on what real agents emit today: a real-framework OTLP trace becomes an AGEF bundle that a counterparty verifies offline. It is producer-agnostic; it does not require Akmon's own agent at all. It is the concrete answer to the gaps competitors leave: HMAC-only or unsigned manifests, no standalone verifier, cloud-locked verification, and "cannot replay."
What you will have at the end
- An AGEF bundle built from a third-party OpenTelemetry GenAI trace.
- An Ed25519 signature over the session head, verifiable by anyone who trusts the public key.
- Three artifacts (
statement.bin,signature.bin,pubkey.pem) that a third party verifies with OpenSSL 3.x and nothing else.
The fixture
This walkthrough uses the checked-in fixture
crates/akmon-cli/tests/fixtures/openai_v2_weather_legacy.otlp.json. It is a representative,
illustrative OTLP/JSON trace that models the default emission of the
opentelemetry-instrumentation-openai-v2 Python instrumentation, in the legacy (<= v1.36)
message-event form (gen_ai.system.message / gen_ai.user.message / gen_ai.choice span
events). It is hand-authored to match that documented shape, contains no real user data or
PII, and, because that instrumentation does not capture message content unless
OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT is enabled (default off), carries no
message bodies. See crates/akmon-cli/tests/fixtures/README.md for the full provenance note.
Prerequisites
akmoninstalled and onPATH.- OpenSSL 3.x for the final verification step. Stock LibreSSL (the macOS
/usr/bin/openssl) cannot verify Ed25519: it lacks-rawinand cannot load Ed25519 keys.
Steps
- Import the third-party OTEL trace into a fresh AGEF session.
akmon otel import crates/akmon-cli/tests/fixtures/openai_v2_weather_legacy.otlp.json \
--journal ./journal --format json
The JSON report records capture_level, the provider/tool counts, and the new session_id:
{
"capture_level": "structural",
"provider_calls": 1,
"tool_calls": 1,
"turns_emitted": 0,
"turns_suppressed_no_content": 1,
"semconv_version": "1.37.0",
"session_id": "de52d29b-e7ee-4f53-8526-3c479d4f8c37"
}
- Export the session as an AGEF bundle.
akmon bundle export <session-id> --journal ./journal --output ./audit.akmon
- Sign the bundle's session head with an Ed25519 key and publish the public key (hex).
akmon bundle sign ./audit.akmon --key signer.pk8 --format json
- Verify integrity and the signature, requiring a signature to be present.
akmon bundle verify ./audit.akmon --verify-key signer.pub.hex --require-signature --format json
- Emit the standalone verification artifacts.
akmon bundle prove-openssl ./audit.akmon --verify-key signer.pub.hex --out-dir ./proof
- Verify offline with OpenSSL 3.x alone (this command is also printed by the step above).
openssl pkeyutl -verify -pubin -inkey ./proof/pubkey.pem -rawin -in ./proof/statement.bin -sigfile ./proof/signature.bin
A valid signature prints Signature Verified Successfully and exits 0. Tampering with
statement.bin (or using the wrong signature) makes openssl print Signature Verification Failure and exit non-zero.
Optional: bind an operator identity
The head signature proves the bundle's integrity is authentic, but says nothing about who
operated the session. To attach a named operator (and have it verify offline too), generate an
operator key, attest, and pass --operator-key to verify and to prove-openssl.
akmon bundle keygen --out operator.pk8 --public-out operator.pub.hex
akmon bundle attest ./audit.akmon --key operator.pk8 --operator-id ops@example.com --role approver
akmon bundle verify ./audit.akmon --verify-key signer.pub.hex --require-signature \
--operator-key operator.pub.hex --require-operator --format json
akmon bundle prove-openssl ./audit.akmon --verify-key signer.pub.hex \
--operator-key operator.pub.hex --out-dir ./proof
The last step emits three more files alongside the head-signature artifacts:
operator_statement.bin, operator_signature.bin, operator_pubkey.pem, and a third party
verifies the operator attestation with OpenSSL 3.x alone:
openssl pkeyutl -verify -pubin -inkey ./proof/operator_pubkey.pem -rawin -in ./proof/operator_statement.bin -sigfile ./proof/operator_signature.bin
Trust the key, not the name. Verification proves only that the holder of operator.pub.hex
signed the operator_id/role claims. It does not prove the person is who the name says. A
verifier decides which operator key they trust out-of-band (a directory, a roster, a key
ceremony); only then does the self-asserted name carry weight. See
akmon bundle attest.
Honesty: this is STRUCTURAL capture, not full replay
The source instrumentation did not capture message content (the content-off default), so Akmon
imports the trace as capture_level=structural: metadata only. This is surfaced, not hidden:
- The import report and
akmon bundle verify --format jsonboth report the level asstructural(under/capture/level). - The full-capture gate correctly fails on this bundle:
akmon bundle verify ./audit.akmon --require-capture full
This exits 1: a metadata-only OTEL import must never read as VERIFIED-full. The integrity and
signature still verify (the evidence is intact and authentic); what is absent is the
verbatim message content, so no byte-level or full replay is implied from imported telemetry.
A note on versions: the fixture's source form is the legacy <= v1.36 message-event
convention, while Akmon records source_semconv 1.37.0 in the signed session config for all
imports regardless of the source form (a hardcoded constant). The recorded value is therefore not
a faithful descriptor of the source form; this is documented in the fixture README and is cosmetic.
How a reviewer validates this
- Confirm
akmon otel importexits0and reportscapture_level=structural. - Confirm
akmon bundle verify --verify-key --require-signatureexits0with averifiedsignature outcome and/capture/levelequal tostructural. - Confirm
akmon bundle verify --require-capture fullexits1. - Confirm the OpenSSL 3.x command exits
0for the emitted artifacts and non-zero whenstatement.binis tampered.
Verified by an automated test
This entire chain (import, export, sign, verify, --require-capture full failure,
prove-openssl, and the real openssl positive/tamper-negative legs) is asserted as ONE flow by
t_e2e_otel_legacy_trace_to_openssl_proof in
crates/akmon-cli/tests/e2e_otel_to_openssl_integration.rs, against the same fixture. A companion
test, t_e2e_otel_proof_artifacts_byte_identical, locks the emitted artifacts byte-for-byte
without requiring openssl, so the proof holds even where the openssl leg skips. Doc and test cannot
drift.
Troubleshooting
- If the openssl step reports
unable to loador usage text, you are likely on LibreSSL. Use an OpenSSL 3.x build (the verification command needs-rawinand Ed25519 support). - If
akmon bundle signrejects the key, generate a PKCS#8 v2 Ed25519 key; some tools emit PKCS#8 v1, which the signing path rejects.
See also
Tutorial: Enterprise policy profile rollout
Documented for Akmon 2.2.0.
Time estimate: 30-45 minutes
Complexity: Advanced
Who this is for
Platform and security teams introducing policy governance for AI agents, moving from developer-friendly defaults to production guardrails, and tying the policy that governed a run to the signed evidence a reviewer receives.
What you will have at the end
- A staged rollout flow across
dev,staging, andprod. - An organizational policy pack with deterministic merge behavior.
- Evidence that records which policy governed each run, through the recorded
policy_hash, so a reviewer can confirm the run was governed by the profile you intended. - A signed bundle that carries that evidence, verifiable offline.
Prerequisites
- Repository contains an
.akmon/directory. - You can run headless tasks (
akmon --task ...). - Team agrees on approval and CI gate expectations.
- A signing key for the evidence handoff, created with
akmon bundle keygen --out signer.pk8 --public-out signer.pub.hex. Keep the private key secret and publish only the public key.
Steps
- Establish a baseline with the built-in
devprofile.
akmon policy show-effective --profile dev
akmon --policy-profile dev --task "list API modules and summarize auth boundaries"
- Add an organizational policy pack.
Create .akmon/policy-packs/org.toml:
[tools]
deny = ["shell"]
[network]
deny_domains = ["*"]
Inspect the effective result:
akmon policy show-effective --profile dev --policy-pack .akmon/policy-packs/org.toml
- Roll into
stagingfor CI-like gating.
akmon policy show-effective --profile staging --policy-pack .akmon/policy-packs/org.toml
akmon --policy-profile staging --policy-pack .akmon/policy-packs/org.toml --yes --output json \
--task "run non-mutating checks and summarize findings" | tee staging-run.json
- Promote to
prodand validate the expected denials.
akmon policy show-effective --profile prod --policy-pack .akmon/policy-packs/org.toml
akmon --policy-profile prod --policy-pack .akmon/policy-packs/org.toml \
--task "run shell command: cargo test"
Expected result: a command path involving shell is denied by policy.
- Confirm an allowed read-heavy workflow still succeeds.
akmon --policy-profile prod --policy-pack .akmon/policy-packs/org.toml \
--task "list auth module files and summarize"
Merge precedence:
profile < packs < project-local policy < CLI override
Tie the policy to the evidence
The effective policy that governed a run is recorded in that run's evidence as a policy_hash in the replay metadata. This is the link between governance and proof: the same effective policy that policy show-effective describes is the one whose hash is committed to the evidence and, in turn, sealed by the bundle's head signature.
Inspect the recorded hash for a governed run:
SESSION_ID="$(jq -r '.session_id' staging-run.json)"
jq '.replay_metadata.policy_hash' ".akmon/evidence/${SESSION_ID}.json"
Because the same effective policy produces the same policy_hash, two governed runs under the same profile and packs commit to the same value. A reviewer can compare that hash across runs to confirm the policy did not change between them, and can match it to the profile your rollout documents as approved for that environment.
Hand reviewers a signed bundle
Export the governed session, sign it offline, and verify the signature. The reviewer then receives a bundle whose sealed evidence includes the policy_hash, so the governance context travels with the proof.
akmon bundle export "${SESSION_ID}" --output "${SESSION_ID}.akmon"
akmon bundle sign "${SESSION_ID}.akmon" --key signer.pk8
akmon bundle verify "${SESSION_ID}.akmon" --verify-key signer.pub.hex --require-signature
A reviewer can verify this offline with akmon bundle verify, the standalone agef-verify, or plain openssl; see Verify evidence on an air-gapped machine.
What gets recorded in evidence
- Policy decision counters (
allow,deny,prompted). - Decision samples and the replay-metadata
policy_hashfor the effective policy. - Reliability metrics, including denial events in governed runs.
How a reviewer validates this
- Compare
akmon policy show-effectiveoutput across profiles to confirm each environment's guardrails. - Confirm the expected deny behavior appears for prohibited capabilities.
- Confirm the recorded
policy_hashmatches the profile approved for the environment, and is stable across runs that should share a policy. - Verify the signed bundle with
akmon bundle verify ... --require-signature.
Anti-patterns
- Moving directly to
prodwithout staging validation. - Using ad hoc CLI overrides in CI without documenting the governance rationale; an override changes the effective policy and therefore the
policy_hash. - Interpreting denial-heavy runs as failures without checking policy intent.
- Distributing an unsigned bundle when the reviewer must establish provenance.
Troubleshooting
- If policy file parsing fails, validate TOML syntax and paths.
- If the effective view is empty, confirm the selected profile and packs are actually passed.
- If two runs you expected to share a policy show different
policy_hashvalues, an override or project-local policy changed the effective merge; reconcile with the precedence order above.
See also
Installation
Documented for Akmon 2.2.0.
Who this is for
Engineers and auditors installing Akmon on macOS or Linux. Two binaries ship from this project:
akmon, the full evidence and verification layer (import, sign, attest, verify, prove, and the bundled reference agent).agef-verify, a small standalone verifier. An auditor who only needs to check a bundle can install this one binary, without the full Akmon CLI.
If you only receive signed bundles to verify, install agef-verify (or use plain openssl, see the quick start). If you produce evidence, install akmon.
What you will have at the end
- An
akmonbinary onPATH(and optionallyagef-verify). - A verified installation (
akmon --version). - A clear fallback from Homebrew to prebuilt binaries to a source build.
Prerequisites
- Shell access on macOS or Linux.
curlavailable for the prebuilt-binary path.- Homebrew for the tap path.
Rust 1.88+only if building from source.- OpenSSL 3.x only if you intend to verify Ed25519 signatures with plain
openssl. The macOS system/usr/bin/opensslis LibreSSL and cannot verify Ed25519.
Option 1: Homebrew tap (recommended)
The tap is live. It installs both binaries and keeps them updated through brew upgrade.
brew tap radotsvetkov/akmon
brew install akmon
brew install agef-verify
Verify:
akmon --version
# e.g. akmon 2.2.0
agef-verify --version
Option 2: Prebuilt binaries
Each GitHub release publishes platform binaries for both tools plus a SHA256SUMS file. The asset names are akmon-darwin-arm64, akmon-darwin-x86_64, akmon-linux-x86_64, and the matching agef-verify-* names. These are slim builds (--no-default-features, no bundled semantic index).
Download and verify the checksum
Always verify the checksum before running a downloaded binary. The release SHA256SUMS file is the reference.
macOS, Apple Silicon
mkdir -p ~/bin
base=https://github.com/radotsvetkov/akmon/releases/latest/download
curl -fsSL -L "$base/akmon-darwin-arm64" -o ~/bin/akmon
curl -fsSL -L "$base/SHA256SUMS" -o /tmp/SHA256SUMS
# Confirm the line for akmon-darwin-arm64 matches your file
shasum -a 256 ~/bin/akmon
grep akmon-darwin-arm64 /tmp/SHA256SUMS
chmod +x ~/bin/akmon
macOS, Intel
mkdir -p ~/bin
base=https://github.com/radotsvetkov/akmon/releases/latest/download
curl -fsSL -L "$base/akmon-darwin-x86_64" -o ~/bin/akmon
curl -fsSL -L "$base/SHA256SUMS" -o /tmp/SHA256SUMS
shasum -a 256 ~/bin/akmon
grep akmon-darwin-x86_64 /tmp/SHA256SUMS
chmod +x ~/bin/akmon
Linux, x86_64
mkdir -p ~/bin
base=https://github.com/radotsvetkov/akmon/releases/latest/download
curl -fsSL -L "$base/akmon-linux-x86_64" -o ~/bin/akmon
curl -fsSL -L "$base/SHA256SUMS" -o /tmp/SHA256SUMS
sha256sum ~/bin/akmon
grep akmon-linux-x86_64 /tmp/SHA256SUMS
chmod +x ~/bin/akmon
Install agef-verify the same way, substituting the agef-verify-* asset name.
Shell PATH (zsh example), if akmon is not found:
echo 'export PATH="$HOME/bin:$PATH"' >> ~/.zshrc
source ~/.zshrc
Install to /usr/local/bin (needs admin)
sudo curl -fsSL -L https://github.com/radotsvetkov/akmon/releases/latest/download/akmon-darwin-arm64 \
-o /usr/local/bin/akmon && sudo chmod +x /usr/local/bin/akmon
Use the correct asset name for your platform, and verify the checksum before first run.
Troubleshooting downloads
| Symptom | Cause and fix |
|---|---|
| Checksum line does not match | Re-download. A mismatch means a partial download or a tampered file. Do not run it. |
Permission denied writing to /usr/local/bin | Use ~/bin plus PATH, or prefix sudo on both curl and chmod. |
Small file, or Not: command not found when running akmon | GitHub returned an HTML error page (often a 404). Confirm a release exists with that asset name. Check with file ~/bin/akmon, which should report Mach-O or ELF, not HTML. |
curl: (56) Failure writing output | Destination directory missing or not writable. Run mkdir -p ~/bin or fix permissions. |
Verify
akmon --version
# e.g. akmon 2.2.0
Option 3: From source
git clone https://github.com/radotsvetkov/akmon
cd akmon
# Slim build, no semantic indexing, smaller binary
cargo build --release --no-default-features
# Full build, with semantic indexing
cargo build --release
mkdir -p ~/bin
cp target/release/akmon ~/bin/
cp target/release/agef-verify ~/bin/
Or install directly with cargo:
cargo install --git https://github.com/radotsvetkov/akmon akmon
cargo install --git https://github.com/radotsvetkov/akmon agef-verify
Verification
command -v akmon
akmon --version
akmon --help
Expected result: all commands succeed and print usage or version output.
Troubleshooting
- If
akmonis not found, add~/bintoPATHand restart your shell. - If a downloaded file is HTML, verify the release asset name and tag availability.
- If
opensslcannot verify a signature on macOS, you are likely on LibreSSL. Install OpenSSL 3.x (see akmon bundle prove-openssl). - For provider failures after install, run
akmon doctor providers.
Using over SSH
Akmon is a single static binary. Copy it to any remote machine:
scp ~/bin/akmon user@remote:~/bin/
ssh user@remote
export PATH="$HOME/bin:$PATH"
akmon --version
Using in Docker
FROM debian:bookworm-slim
RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates curl \
&& rm -rf /var/lib/apt/lists/* \
&& curl -fsSL -L \
https://github.com/radotsvetkov/akmon/releases/latest/download/akmon-linux-x86_64 \
-o /usr/local/bin/akmon && chmod +x /usr/local/bin/akmon
WORKDIR /workspace
ENTRYPOINT ["akmon"]
Using in CI
# GitHub Actions example
- name: Install Akmon
run: |
sudo curl -fsSL -L https://github.com/radotsvetkov/akmon/releases/latest/download/akmon-linux-x86_64 \
-o /usr/local/bin/akmon && sudo chmod +x /usr/local/bin/akmon
- name: Verify a bundle
run: |
akmon bundle verify build/session.akmon --verify-key signer.pub.hex --require-signature --format json \
| jq .passed
For auditors who only verify, install just the standalone binary:
- name: Install agef-verify
run: |
sudo curl -fsSL -L https://github.com/radotsvetkov/akmon/releases/latest/download/agef-verify-linux-x86_64 \
-o /usr/local/bin/agef-verify && sudo chmod +x /usr/local/bin/agef-verify
Uninstalling
rm -f ~/bin/akmon ~/bin/agef-verify /usr/local/bin/akmon /usr/local/bin/agef-verify
rm -rf ~/.akmon # removes config, sessions, audit logs
If you installed through Homebrew:
brew uninstall akmon agef-verify
brew untap radotsvetkov/akmon
Quick Start
Documented for Akmon 2.2.0.
Who this is for
Engineers and compliance reviewers who want one end-to-end pass through the thing that makes Akmon useful: take an agent session, seal it, sign it, and prove to a third party what happened, with nothing but openssl on the other end.
Akmon is a producer-agnostic evidence and verification layer. This quick start uses a session from any OpenTelemetry-instrumented agent (an OTLP/JSON GenAI trace). The same flow applies to sessions from Akmon's own bundled reference agent. The verification chain is the point; the agent that produced the trace is interchangeable.
What you will have at the end
- A signed, portable
.akmonbundle made from an agent trace. - A verification that passes integrity, signature, and operator-attestation checks.
- An offline proof a stranger can verify with plain
openssl, no Akmon install required.
Prerequisites
akmon --versionreports2.2.0.- An OpenTelemetry GenAI trace file on disk (OTLP/JSON). Akmon reads the v1.37 structured form and the older v1.36-and-earlier message-event form that most deployed agents still emit.
- OpenSSL 3.x for the final
opensslstep. The macOS systemopensslis LibreSSL and cannot verify Ed25519.
The trust flow
1. Generate a signing key
openssl genpkey emits a PKCS#8 v1 key that the ring library rejects, so it cannot sign an Akmon bundle. Use keygen, which produces the PKCS#8 v2 key Akmon accepts (and sets 0600 on unix).
akmon bundle keygen --out signer.pk8 --public-out signer.pub.hex
Keep signer.pk8 secret. Distribute only signer.pub.hex (64 hex characters) to verifiers.
2. Import an agent trace
Turn the OpenTelemetry trace into an AGEF session. Akmon records an honest capture level: imported traces are structural, not a full recording, and are never dressed up as one.
akmon otel import trace.json --journal .akmon/journal
3. Export and sign the bundle
Export the session to a portable bundle, then add an offline Ed25519 signature over the session head (the AGEF-SIG-v1 statement).
akmon bundle export <session-id> --output session.akmon
akmon bundle sign session.akmon --key signer.pk8
4. (Optional) Attest the accountable operator
Record a separately signed operator-identity claim. Verification attaches trust to the key, never to the self-asserted string; key trust is established out of band.
akmon bundle attest session.akmon \
--key signer.pk8 \
--operator-id you@org \
--role approver
5. Verify
Check integrity, signature, and (if attested) operator identity in one command.
akmon bundle verify session.akmon \
--verify-key signer.pub.hex \
--require-signature \
--operator-key signer.pub.hex
Because this session came from an OTEL import, it is structural. Adding --require-capture full here would correctly fail: that gate is reserved for full-capture sessions from Akmon's own reference agent.
6. Emit an offline proof
Write the exact bytes a third party needs, plus the openssl command to check them.
akmon bundle prove-openssl session.akmon \
--verify-key signer.pub.hex \
--out-dir proof
This writes statement.bin, signature.bin, and pubkey.pem into proof/.
7. Verify with plain openssl
This is the step that proves there is no lock-in. It runs on any machine with OpenSSL 3.x, with no Akmon installed.
openssl pkeyutl -verify -pubin -inkey proof/pubkey.pem -rawin -in proof/statement.bin -sigfile proof/signature.bin
A valid signature prints Signature Verified Successfully and exits 0. Tampering with statement.bin makes openssl print a verification failure and exit non-zero.
Verification
The flow is complete when:
akmon bundle verify ... --require-signatureexits0.openssl pkeyutl -verify ...printsSignature Verified Successfully.
For an auditor who has only the bundle and the public key, the standalone binary does the same integrity and signature checks without the full Akmon CLI:
agef-verify session.akmon --verify-key signer.pub.hex --require-signature
Running Akmon's own reference agent
The bundled agent is the gold-fidelity producer: its sessions capture at full and replay deterministically. To produce one instead of importing a trace, start a session in a repository:
cd /path/to/your-repo
akmon
End it with /exit. A full-capture session can then be exported, signed, and proven exactly as above, and additionally supports akmon bundle verify ... --require-capture full and deterministic akmon replay.
Troubleshooting
- If
opensslcannot verify the signature, confirm you are on OpenSSL 3.x, not LibreSSL. See akmon bundle prove-openssl. - If
akmon bundle signrejects a key, regenerate it withakmon bundle keygen. Anopenssl-made key will not work. - If
--require-capture fullfails on an imported session, that is expected. Imports arestructural. - If a provider call fails while running the reference agent, run
akmon doctor providers.
Provider Setup
Choosing a provider
| Provider | Best for | Approx. cost |
|---|---|---|
| Ollama | Privacy, offline work, free | Free |
| Anthropic | Highest quality | $0.80 to 15 per million tokens |
| OpenRouter | Model flexibility, one key | Varies by model |
| Groq | Speed, cheap inference | $0.05 to 0.59 per million |
| OpenAI | GPT models | $0.15 to 5 per million |
| Azure OpenAI | Enterprise, compliance | Same as OpenAI |
| Amazon Bedrock | AWS environments, VPC | Same as Anthropic |
Ollama
No API key needed:
# Install from https://ollama.com
ollama pull qwen2.5-coder:7b # recommended for code
ollama pull llama3.2 # faster, lighter
ollama pull deepseek-coder-v2 # excellent for code
akmon chat # auto-detects Ollama
akmon chat --model qwen2.5-coder:7b # explicit
Anthropic
export ANTHROPIC_API_KEY=sk-ant-...
akmon chat --model claude-haiku-4-5-20251001 # fast, cheap
akmon chat --model claude-sonnet-4-6 # balanced
akmon chat --model claude-opus-4-6 # best quality
OpenRouter
One key, 500+ models, automatic failover:
export OPENROUTER_API_KEY=sk-or-...
# Model format: "provider/model-name"
akmon chat --model anthropic/claude-haiku-4-5
akmon chat --model meta-llama/llama-3.3-70b-instruct
akmon chat --model deepseek/deepseek-chat
akmon chat --model google/gemini-2.0-flash
Groq
export GROQ_API_KEY=gsk_...
akmon chat --model llama-3.3-70b-versatile
akmon chat --model llama-3.1-8b-instant # extremely fast
OpenAI
export OPENAI_API_KEY=sk-...
akmon chat --model gpt-4o
akmon chat --model gpt-4o-mini
Azure OpenAI
akmon chat \
--azure-endpoint https://your-resource.openai.azure.com/openai/deployments/your-deployment \
--azure-key your-key \
--model gpt-4o
Amazon Bedrock
export AWS_ACCESS_KEY_ID=...
export AWS_SECRET_ACCESS_KEY=...
export AWS_DEFAULT_REGION=us-east-1
akmon chat --bedrock \
--model anthropic.claude-haiku-4-5-v1:0
Supported Bedrock models (examples, check AWS for current list):
anthropic.claude-haiku-4-5-v1:0anthropic.claude-sonnet-4-6-v1:0anthropic.claude-opus-4-6-v1:0meta.llama3-8b-instruct-v1:0meta.llama3-70b-instruct-v1:0
Custom OpenAI-compatible endpoint
LM Studio, Mistral, Together AI, or any OpenAI-compatible API:
akmon chat \
--openai-compatible-url http://localhost:1234/v1 \
--model your-model-name
Saving configuration
Use the config wizard instead of setting env vars every session:
akmon config
Or set in ~/.akmon/config.toml:
[model]
default = "claude-haiku-4-5-20251001"
anthropic_key = "sk-ant-..."
# Or for OpenRouter:
# default = "anthropic/claude-haiku-4-5"
# openrouter_key = "sk-or-..."
Per-provider pages: Ollama, Anthropic, and the rest under Providers in the sidebar.
Troubleshooting flow (akmon doctor providers + akmon config explain-provider)
Routing behavior is unchanged. These commands only explain which resolver branch would win for your current --model, flags, and ~/.akmon/config.toml.
Walkthrough: “Why am I on Ollama instead of OpenAI?”
-
Show the resolution trace (text or JSON):
akmon config explain-provider akmon config explain-provider --jsonRead
selected_provider, then scancandidates[]inpriority_orderorder. Each row states why a branch was skipped, matched, or would have failed (named prerequisites only, no secrets). -
Cross-check health and endpoints:
akmon doctor providers akmon --output json doctor providersThe JSON report includes the same
provider_resolutionblock plus reachability and masked key checks. -
Fix the first issue that applies: missing env vars or flags listed under
missing_prerequisites, Azure endpoint/key mismatch, or Ollama not running. Then re-run step 1.
Doctor-only checklist
Run:
akmon doctor providers
JSON mode:
akmon --output json doctor providers
Use this flow:
- Fix all
base_url/endpointsanity failures first. - Fix missing key/auth checks for the provider you actually run with.
- Resolve reachability failures (network, DNS, firewall, service down).
- Re-run doctor until active provider is healthy.
Common pitfalls flagged by doctor:
- Azure endpoint missing deployment path (
/openai/deployments/<name>/chat/completions) - OpenAI-compatible endpoint set without key
- OpenRouter/OpenAI key missing while model selection implies that provider
- Ollama URL valid but service unreachable (
ollama servenot running)
Local reliability troubleshooting (Ollama)
When local runs stall or return empty output:
- Check server/process state first:
ollama ps
- Warm the model before long tasks:
ollama run <model>
- If the session has drifted to large context:
- use
/clear, then retry
- use
- If tool-heavy tasks keep stalling:
- switch to a known tool-capable local model, for example:
/model qwen2.5-coder:7b
Akmon now emits consistent loading/status hints in both streaming and buffered paths, and timeout/no-output errors include recovery actions so operators can recover without guesswork.
Configuration
Documented for Akmon 2.2.0.
Who this is for
Engineers configuring Akmon for repeatable local use, CI usage, and policy/evidence-aware operation.
What you will have at the end
- A valid
~/.akmon/config.toml. - A clear precedence model: CLI flags > environment > config file.
- Verified provider routing and masked config inspection commands.
Prerequisites
akmon --versionworks.- You have either local Ollama or hosted provider credentials.
- You can run commands in a terminal where
~/.akmon/is writable.
Steps
- Run the interactive setup wizard (optional, quickest start).
akmon config
Expected result: Akmon writes ~/.akmon/config.toml.
- Inspect the effective stored config safely.
akmon config show
Expected result: keys are masked in output.
- Set or update common values with explicit subcommands.
akmon config model set qwen2.5-coder:7b
akmon config ollama-url set http://localhost:11434
- Verify provider resolution for the current model and environment.
akmon config explain-provider
Expected result: deterministic provider decision trace with candidate reasons.
- If you manage credentials in file form, use top-level keys from
AkmonGlobalConfig.
default_model = "qwen2.5-coder:7b"
ollama_url = "http://localhost:11434"
# anthropic_api_key = "sk-ant-..."
# openrouter_api_key = "sk-or-..."
[architect]
planner_model = "llama3.2"
[policy]
profile = "dev"
packs = [".akmon/policy-packs/team.toml"]
Verification
akmon config path
akmon config show --json
akmon doctor providers
Expected result:
- config path resolves to
~/.akmon/config.toml - JSON output parses cleanly
- doctor reports either healthy provider checks or actionable failures
Troubleshooting
akmon config --jsonwithout subcommand is invalid by design; useakmon config show --json.- If TUI scrollback is missing, export with
/transcriptto.akmon/transcript_export.md. - If provider selection is unexpected, compare
akmon config explain-providerwith your env vars. - Store secrets in environment variables for CI rather than committing config files.
Model context and cost estimates (model_estimates)
model_estimates rows are optional hints for context window and rough USD estimation.
[[model_estimates]]
pattern = "haiku-4-5"
context_window_tokens = 200_000
# Optional: USD per 1M tokens (override built-in defaults when you know list pricing)
input_per_million_usd = 1.0
output_per_million_usd = 5.0
cache_read_per_million_usd = 0.1
# Shown in /context as a reminder (not enforced by Akmon)
note = "Check Anthropic console for RPM/TPM and tier limits."
See also Environment variables and Configuration reference.
Ollama (local)
Free, offline-capable inference on your machine. No API key required.
Setup
Install Ollama, then:
ollama pull qwen2.5-coder:7b
# or: llama3.2, deepseek-coder-v2, etc.
Akmon
akmon chat
akmon chat --model qwen2.5-coder:7b
Override base URL if needed (see Environment variables for AKMON_OLLAMA_URL).
When to use
- Privacy-sensitive code
- No cloud spend
- Air-gapped or flaky networks
See also Provider setup.
Anthropic
Claude models via the Anthropic API, a strong default for quality on code tasks.
Auth
export ANTHROPIC_API_KEY=sk-ant-...
Or anthropic_key in ~/.akmon/config.toml (prefer akmon config key set).
Examples
akmon chat --model claude-haiku-4-5-20251001
akmon chat --model claude-sonnet-4-6
akmon chat --model claude-opus-4-6
Model ids depend on what Anthropic exposes; check their docs for current strings.
Notes
- Prompt caching can reduce cost; Akmon surfaces cache read tokens in the TUI. See Cost transparency.
More: Provider setup.
OpenRouter
One API key for many hosted models. Model ids use a provider/model form.
Auth
export OPENROUTER_API_KEY=sk-or-...
Examples
akmon chat --model anthropic/claude-haiku-4-5
akmon chat --model meta-llama/llama-3.3-70b-instruct
akmon chat --model deepseek/deepseek-chat
Notes
- Pricing and rate limits vary per underlying model.
- Akmon’s cost estimate is heuristic when pricing tables do not list every id.
More: Provider setup.
OpenAI
GPT-family models via the OpenAI API.
Auth
export OPENAI_API_KEY=sk-...
Examples
akmon chat --model gpt-4o
akmon chat --model gpt-4o-mini
Use the exact deployment names your account supports.
More: Provider setup. For Azure, see Azure OpenAI.
Groq
Very fast inference for supported open models.
Auth
export GROQ_API_KEY=gsk_...
Examples
akmon chat --model llama-3.3-70b-versatile
akmon chat --model llama-3.1-8b-instant
See Groq’s model list for current ids.
More: Provider setup.
Azure OpenAI
Enterprise-hosted OpenAI-compatible deployments.
Flags / env
akmon chat \
--azure-endpoint https://YOUR_RESOURCE.openai.azure.com/openai/deployments/YOUR_DEPLOYMENT \
--azure-key YOUR_KEY \
--model gpt-4o
Environment variable names may map to AZURE_OPENAI_*; see Environment variables.
Notes
--modelshould match your deployment name.azure_api_versiondefaults are CLI-configurable.
More: Provider setup.
Amazon Bedrock
Run Claude and other models inside AWS.
Auth
Typical environment:
export AWS_ACCESS_KEY_ID=...
export AWS_SECRET_ACCESS_KEY=...
export AWS_DEFAULT_REGION=us-east-1
Use IAM roles on EC2/EKS where possible instead of long-lived keys.
CLI
akmon chat --bedrock \
--model anthropic.claude-haiku-4-5-v1:0
Supported model ids change with AWS; consult Bedrock documentation for the latest inventory.
More: Provider setup.
Custom OpenAI-compatible endpoints
Any server that speaks the OpenAI Chat Completions (or compatible) HTTP API, for example LM Studio, vLLM, LiteLLM, Together, Mistral, or a corporate gateway.
CLI
akmon chat \
--openai-compatible-url http://localhost:1234/v1 \
--openai-compatible-key optional-if-your-proxy-needs-it \
--model your-local-model-name
Tips
- URL usually ends with
/v1for OpenAI-style routers. - Model string must match what the server exposes as
model. - TLS and auth are your responsibility (reverse proxy, VPN, etc.).
More: Provider setup.
Interactive mode
Interactive mode is the default way to work with Akmon when you want close control over prompts, permissions, and step-by-step execution.
akmon chat
What the UI is showing you
The TUI is designed around operational awareness:
- conversation transcript and tool calls,
- approval prompts for side effects,
- session/provider/model identity,
- context/token/cache/cost signals.
It is not just chat; it is a control surface for autonomous execution.
Typical interaction pattern
- give focused task,
- review tool calls and approvals,
- inspect diffs before writes,
- run verification commands,
- iterate until completion.
Example starting prompt:
Add input validation to user registration, update tests, and run verification commands after each file change.
Status and context indicators
Key footer/top indicators usually include:
- session id,
- model/provider,
- cumulative input/output tokens,
- cache read tokens,
- cost estimate,
- context usage bar/percentage.
For long runs, monitor context percentage and compact/reset before quality drifts.
Slash commands that matter most
/modelswitch model mid-session,/plancreate plan-only turn,/contextview context budget and thresholds,/costinspect usage/cost breakdown,/copycopy latest assistant response.
Approval flow
When the model requests writes or command execution:
- inspect proposed action/diff,
- approve once or for session where appropriate,
- deny if scope drifts.
Use session-wide allowances carefully; they trade control for speed.
Policy profiles in interactive sessions
You can run interactive sessions with enterprise policy profiles/packs:
akmon chat --policy-profile dev
akmon chat --policy-profile staging --policy-pack .akmon/policy-packs/org.toml
Inspect the final merged configured policy before starting:
akmon policy show-effective --profile staging --policy-pack .akmon/policy-packs/org.toml
Common mistakes and troubleshooting
- Mistake: broad vague prompts ("fix everything").
- Fix: split by subsystem and expected verification.
- Mistake: ignoring context/cost indicators in long sessions.
- Fix: use
/contextand continue in focused phases.
- Fix: use
- Mistake: approving shell writes blindly.
- Fix: check command intent and command scope before allow.
See also slash commands, plan mode, and headless mode.
Headless mode
Headless mode is for CI and scripted runs.
Basic run
akmon \
--model claude-haiku-4-5-20251001 \
--yes \
--max-budget-usd 2.00 \
--output json \
--task "run cargo clippy and fix warnings"
Default artifacts:
- audit:
.akmon/audit/<session-id>.jsonl - evidence:
.akmon/evidence/<session-id>.json
CI governance flow
# run
akmon --yes --output json --task "run unit tests and summarize failures" | tee run.json
# verify trust artifacts
akmon audit verify .akmon/audit/<session-id>.jsonl
akmon evidence verify .akmon/evidence/<session-id>.json
# enforce SLO policy
akmon slo verify .akmon/evidence/<session-id>.json --strict
# enforce trend regression gate
akmon slo trend .akmon/evidence/<session-id>.json \
--baseline-dir .akmon/evidence/history \
--window 20 \
--strict
JSON report fields
Headless JSON includes:
- lifecycle fields (
status,exit_reason,result), - usage/cost fields,
- additive
replay_metadata, - additive
reliability_metrics.
Use exit_reason + command exit code for CI gating.
Exit code guidance
akmonrun: process exits non-zero on runtime/config failures.akmon audit verify:0valid,1invalid/missing.akmon evidence verify:0valid,1invalid/missing.akmon slo verify:0pass,1violation,2invalid input/config.akmon slo trend:0pass,1violation,2invalid input/config.
Common mistakes
- Running unattended jobs without
--max-budget-usd. - Parsing only old JSON fields and ignoring additive metrics/replay blocks.
- Using broad tasks instead of scoped, verifiable tasks.
Plan mode
Plan mode performs read-only analysis and produces implementation plans without changing files.
akmon --plan --task "your task"
Why plan mode exists
Large tasks fail when implementation starts before scope is understood. Plan mode separates discovery from execution:
- map relevant files and constraints,
- produce ordered implementation steps,
- define verification per step,
- execute later with lower risk.
What is allowed in plan mode
- read/list/search tools,
- optional semantic search when enabled,
- no write/edit/patch tool registration.
This is structural read-only behavior, not just "please don't write."
Recommended workflow
akmon --plan \
--model claude-haiku-4-5-20251001 \
--task "Design migration from sqlite auth sessions to redis-backed sessions with rollback strategy"
Then:
ls .akmon/plans
$EDITOR .akmon/plans/<latest>.md
akmon --task "Implement the approved plan in .akmon/plans/<latest>.md step by step"
What a good plan should contain
- target files/modules,
- ordered steps,
- risk notes and migration impact,
- verification commands after each step,
- rollback hints.
TUI usage
- run
/plan, - submit task,
- review plan,
- run
/implementwhen approved.
Common mistakes and troubleshooting
- Mistake: skipping plan review before implementation.
- Mistake: one giant implementation step instead of checkpoints.
- Mistake: missing verification commands in plan.
Plan mode pairs naturally with architect mode and spec workflow.
Architect mode
Architect mode runs a planner phase and implementation phase in one command.
Why use architect mode
It is useful when you want:
- cheap/fast planning model,
- stronger implementation model,
- less manual handoff between plan and execution.
Basic command
akmon --architect \
--planner-model llama3.2 \
--model claude-haiku-4-5-20251001 \
--task "Refactor database layer to use connection pooling with migration-safe rollout"
How the phases differ
| Phase | Model | Tool scope | Output |
|---|---|---|---|
| Planner | --planner-model | read-oriented analysis | ordered plan |
| Implementer | --model | full policy-checked tool set | code + verification |
Practical model strategy
- use low-cost local/cloud model for planning,
- use Haiku/Sonnet-class model for implementation complexity,
- reserve expensive models for hard reasoning bottlenecks.
Suggested usage pattern
- run architect command,
- inspect generated plan artifacts,
- review first implementation diff before broad approvals,
- continue in focused increments.
Common mistakes and troubleshooting
- Mistake: planner model too weak to map architecture.
- Fix: upgrade planner model for complex repos.
- Mistake: no budget cap in long implement phases.
- Fix: combine with
--max-budget-usd.
- Fix: combine with
- Mistake: skipping post-plan review.
- Fix: verify plan assumptions before writes.
Related: plan mode, headless mode, configuration.
Spec Workflow
For building new features from scratch with structured planning. Three phases: requirements, then design, then tasks, then implementation.
Overview
# Phase 1: Generate requirements
akmon spec auth-system "JWT authentication with refresh tokens"
# Phase 2: Generate technical design (after reviewing requirements)
akmon spec auth-system design
# Phase 3: Generate implementation tasks
akmon spec auth-system tasks
# Implement one task at a time
akmon spec auth-system implement
Artifacts live under .akmon/specs/<name>/.
Phase 1: Requirements
akmon spec payment-flow \
"Stripe payment integration with webhook handling \
and subscription management"
Produces .akmon/specs/payment-flow/requirements.md with user stories, acceptance criteria, scope, and open questions.
Phase 2: Design
akmon spec payment-flow design
Reads requirements.md, analyzes the codebase, and writes design.md with architecture, new components, modified files, and data flow.
Phase 3: Tasks
akmon spec payment-flow tasks
Writes tasks.md with checkboxes, dependencies, and sized work items.
Implementation
akmon spec payment-flow implement
Akmon picks the first unchecked task, implements it, checks it off, and stops for human review. Re-run for the next task.
This human-in-the-loop per task pattern limits runaway changes that drift from the spec.
See also
- CLI reference for exact
akmon specsyntax and flags.
akmon init
Analyzes your project and generates AKMON.md, structured project memory used in every session.
Usage
cd your-project
akmon init
- Detects stack (languages, frameworks, tooling).
- Writes or updates
AKMON.mdwith product context, architecture, conventions, and sprint sections. - If other tools already left context files (
CLAUDE.md,.cursorrules, …), you can runakmon importfirst to synthesize them intoAKMON.md.
Why run it
Sessions with AKMON.md get better, more consistent answers because the model sees your conventions upfront.
TUI
In akmon chat:
/init
Same operation from inside the interactive UI.
See also
AKMON.md guide
AKMON.md is the highest-leverage file in an Akmon project. It is loaded at session start and continuously influences planning, tool selection, and verification behavior.
Why AKMON.md matters more than a one-off prompt
Prompts are ephemeral. AKMON.md is persistent and reused every run. If you encode architecture boundaries and verification commands in this file, the agent can follow them automatically across turns and sessions.
Examples:
- if
AKMON.mdsaysverify: cargo check 2>&1 | head -20, the agent tends to run that after edits, - if it says
repository pattern only, the agent is less likely to generate active-record style shortcuts, - if it says
no unwrap() in library crates, reviews and fixes stay aligned.
Anatomy of an effective AKMON.md
Use concise sections:
- Product: what this project does and key constraints,
- Architecture: module boundaries and forbidden dependencies,
- Conventions: code style, error handling, naming, test policy,
- Verification: canonical commands per change type,
- Current sprint: immediate goals and priorities.
Example: Rust service
# Payment Service
Stripe payment processing microservice.
Rust 1.75 + Axum 0.7 + PostgreSQL + SQLx.
## Architecture
- domain/: pure business logic
- ports/: trait interfaces
- adapters/: db/http/stripe implementations
- application/: orchestration layer
Never import adapters into domain.
## Error handling
Use thiserror in domain, anyhow in orchestration.
## Verification
After Rust file: cargo check 2>&1 | head -20
After business logic: cargo test domain 2>&1
After handlers: cargo test integration 2>&1
Example: Python FastAPI
# User Analytics API
FastAPI + PostgreSQL + Redis event tracking.
## Layout
src/api/routes/
src/services/
src/repositories/
src/models/
src/schemas/
## Conventions
- routes -> services -> repositories
- no direct repository calls from routes
- strict schema validation
## Verification
After Python file: python -m py_compile {file}
After models: alembic check
After routes: pytest tests/api/ -x -q
The 2000-character rule
AKMON.md appears in many model calls. Oversized context inflates recurring input tokens and reduces room for live task reasoning.
Practical guideline:
- target <= 2000 characters,
- keep durable details in
AKMON.md, - move long implementation plans into
.akmon/specs/*.md.
Maintenance workflow
- initialize or refresh with
akmon init, - edit manually or via
/update-context, - review after major architecture changes,
- keep
Current sprintup to date.
Common mistakes and troubleshooting
- Too vague: "clean code, best practices" is not actionable.
- Too long: giant prose blocks are expensive and low signal.
- Missing verification commands: agent cannot infer your CI expectations reliably.
- Stale sprint section: leads to drift and irrelevant actions.
Importing Context
If you have been using another AI coding tool, your project
may already have context files. Akmon can synthesize them into AKMON.md.
Supported tools
| Tool | Context files |
|---|---|
| Claude Code | CLAUDE.md, .claude/CLAUDE.md |
| Codex / OpenCode | AGENTS.md |
| Cursor | .cursorrules, .cursor/rules/*.mdc |
| Gemini CLI | GEMINI.md |
| Kiro | .kiro/steering/*.md, .kiro/specs/ |
| Windsurf | .windsurfrules, .windsurf/rules/ |
| GitHub Copilot | .github/copilot-instructions.md |
| Cline / RooCode | .clinerules, .roo/rules/ |
| Aider | .aider.conf.yml |
| Generic | AGENTS.md, llms.txt |
Basic usage
cd your-project
akmon import
Akmon scans context files and uses your configured model to build AKMON.md.
Preview without writing
akmon import --dry-run
Import from a specific tool only
akmon import --from claude-code
akmon import --from cursor
akmon import --from kiro
Overwrite existing AKMON.md
akmon import --force
In the TUI
When no AKMON.md exists, the welcome screen may suggest /import. Run it to perform the same synthesis from inside akmon chat.
See also
Exporting Context
Export AKMON.md to native formats for other AI tools, useful for teams using mixed workflows.
Export to all tools
akmon export --all
Typical outputs include CLAUDE.md, AGENTS.md, .cursor/rules/akmon.mdc, .kiro/steering/akmon.md, Copilot instructions, Windsurf rules, Cline rules, etc. (exact set follows the CLI help for your version).
Export to a specific tool
akmon export --tool claude-code # writes CLAUDE.md
akmon export --tool codex # writes AGENTS.md
akmon export --tool cursor # writes .cursor/rules/akmon.mdc
akmon export --tool kiro # writes .kiro/steering/akmon.md
akmon export --tool gemini # writes GEMINI.md
akmon export --tool copilot # writes .github/copilot-instructions.md
akmon export --tool windsurf # writes .windsurfrules
akmon export --tool cline # writes .clinerules
Preview without writing
akmon export --all --dry-run
Workflow for multi-tool teams
- Maintain
AKmon.mdas the single source of truth. - Run
akmon export --allafter meaningful updates. - Commit exports alongside
AKMON.mdif your team wants them in-repo.
Exported files should carry a banner like:
<!-- Generated from AKMON.md by Akmon -->
<!-- Edit AKMON.md, then run: akmon export --tool claude-code -->
See also
Rust Projects
Akmon detects Rust projects from Cargo.toml and applies Rust-oriented conventions and framework hints via the project intelligence layer.
Auto-detection
When Akmon finds Cargo.toml:
- Language profile Rust
- Workspace members when present
- Framework hints from dependencies (
axum,actix-web,tokio,sqlx,diesel,ratatui,clap,tauri,bevy, …)
Conventions (steering)
Typical guidance injected for Rust codebases:
thiserrorfor library errors,anyhowfor application binaries (where appropriate)- Avoid
.unwrap()in production paths - Prefer borrowing over unnecessary clones
- Document public items (
rustdoc) - Use
spawn_blockingfor CPU-heavy work inside async runtimes
Framework-specific notes (e.g. Axum handlers stay thin and delegate to services; SQLx query! and pools) are added when dependencies match.
Example: plan an Axum API
cargo new my-api && cd my-api
# add axum, tokio, sqlx, serde, thiserror, anyhow …
akmon --plan \
--task "build a REST API with user authentication,
PostgreSQL via SQLx, JWT tokens,
layered architecture (handler to service to repository),
and proper error handling"
Then implement when satisfied with the plan.
Example: explore a workspace
cd my-workspace
akmon chat
explain how akmon-core relates to akmon-tools
and what the data flow is between crates
Common Rust tasks
| Task | Prompt |
|---|---|
| Error handling | replace unwrap() calls with proper Result handling |
| Testing | add unit tests for the authentication module |
| Documentation | add rustdoc to all public items in src/lib.rs |
| Clippy | fix all clippy warnings in the workspace |
See Semantic search for --index usage on large Rust trees.
Python Projects
Akmon detects Python projects from pyproject.toml, requirements.txt, or setup.py.
Auto-detection
Framework hints may include:
- FastAPI, Django, Flask
- Pandas / Polars
- Scrapy, Celery
- PyTorch / HuggingFace
Conventions (steering)
Typical guidance:
- Type hints on public functions
- Pydantic v2 at API boundaries where applicable
pathliboveros.path- Context managers for resources
- No bare
except:
Example: FastAPI service
mkdir my-api && cd my-api
uv init
uv add fastapi uvicorn sqlalchemy asyncpg pydantic alembic
akmon init
akmon --plan --task "build a FastAPI service with JWT auth,
SQLAlchemy async + PostgreSQL, Alembic migrations,
Pydantic v2 schemas, APIRouter per domain"
Example: Django performance
the order listing page is slow. analyze ORM queries
and fix N+1 issues with select_related / prefetch_related
Common Python tasks
| Task | Prompt |
|---|---|
| Types | add type hints to functions under src/ |
| Tests | add pytest coverage for the auth module |
| Linting | fix ruff warnings project-wide |
TypeScript Projects
Akmon detects TypeScript from tsconfig.json and frameworks from package.json dependencies.
Auto-detection
- Next.js (App Router patterns)
- React
- NestJS
- Prisma, Drizzle, tRPC, Hono
Conventions (steering)
strict: true- Avoid
any: preferunknown+ narrowing - Zod (or similar) at API boundaries
- Path aliases instead of deep relative imports
- Discriminated unions for state machines
Example: Next.js
npx create-next-app@latest my-app --typescript --app
cd my-app
akmon init
add authentication with your chosen stack (e.g. auth library + DB)
using Server Actions where appropriate
Common TypeScript tasks
| Task | Prompt |
|---|---|
| Types | replace any with proper types |
| Validation | add Zod schemas to API handlers |
| Tests | add Vitest tests for auth helpers |
Go Projects
Akmon detects Go projects from go.mod and frameworks from module requirements.
Auto-detection
- Gin, Echo, Chi, Fiber
- Cobra CLIs
- GORM, sqlc, ent
errgrouppatterns
Conventions (steering)
- Check every error; never silently discard with
_ - Accept interfaces, return concrete types
context.Contextfirst on I/O boundaries- Table-driven tests with
t.Run
Example: Gin API
mkdir my-api && cd my-api
go mod init example.com/my-api
go get github.com/gin-gonic/gin gorm.io/gorm gorm.io/driver/postgres
akmon init
akmon --plan --task "REST API for a blog with Gin, GORM + Postgres,
JWT middleware, handler to service to repository layout"
Common Go tasks
| Task | Prompt |
|---|---|
| Errors | find ignored errors and handle them |
| Context | thread context through service methods |
| Tests | add table-driven tests for package X |
Other Languages
Akmon includes profiles beyond Rust, Python, TypeScript, and Go, for example JavaScript, Java, C#, Elixir, Swift, Kotlin, Dart, C++, Zig, and more. Detection uses manifests (pom.xml, *.csproj, mix.exs, Package.swift, pubspec.yaml, …).
JavaScript (no tsconfig.json)
Conventions steer toward ES modules, const/let, modern syntax, and async/await.
Java
Spring / Quarkus / Micronaut hints: records for DTOs, constructor injection, Optional, try-with-resources.
C#
ASP.NET Core: nullable reference types, records, async all the way through.
Elixir
Phoenix / LiveView: contexts, supervisors, {:ok, _} / {:error, _} tuples.
Swift / iOS
SwiftUI patterns, async/await, avoiding force unwraps in production paths.
Kotlin / Android
Compose-first guidance, coroutines, data classes.
Dart / Flutter
const constructors, separation of UI and logic, common routing libraries.
Run akmon init so AKMON.md captures stack-specific conventions your team cares about beyond auto-detection.
Semantic search
Semantic search lets Akmon find relevant code by meaning, not only exact keyword matches.
When to use it
Use semantic search for questions like:
- "where do we validate JWTs?",
- "what code handles retry/backoff?",
- "where is this business rule enforced?"
It is especially useful when symbols are named inconsistently across a large codebase.
Enabling semantic search
Run Akmon with indexing enabled:
akmon chat --index
On first run, the index build may take time depending on repository size.
Practical workflow
- ask a high-level question,
- review candidate files from semantic results,
- use exact text search/read tools to verify before editing.
Semantic search should guide exploration, not replace source validation.
Cost and context implications
Semantic search can reduce wasted context by narrowing file reads to likely matches instead of broad brute-force scans.
Best practice:
- use semantic search for discovery,
- follow with targeted file reads and scoped edits.
Common mistakes and troubleshooting
- Mistake: treating semantic results as ground truth.
- Fix: always confirm by reading source files.
- Mistake: expecting semantic indexing in slim builds.
- Fix: verify your build/runtime mode and
--indexusage.
- Fix: verify your build/runtime mode and
- Mistake: indexing generated/vendor directories.
- Fix: ensure ignore files exclude noisy paths.
See also CLI reference and Capabilities.
Git integration
Akmon uses git context to improve planning and verification, and can perform git operations under policy controls.
What git-aware workflows unlock
- better change understanding (
diff,log,status), - safer review loops (small commits per step),
- easier rollback when automation goes wrong.
Operation classes
| Class | Examples | Typical approval posture |
|---|---|---|
| Read-only | status, diff, log, show | often auto-approved in --yes mode |
| Mutating | add, commit, stash, restore, branch operations | explicit confirmation or stricter policy |
Auto-commit strategy
akmon --auto-commit --task "Fix clippy warnings file by file and verify after each change"
When used correctly, this creates small auditable commits that are easier to review and revert.
Prompt patterns that work well
Summarize git diff HEAD~1 in terms of behavior changes and test risk.
Draft a Conventional Commit message for currently staged changes.
Compare this branch to main and list missing tests.
Recommended safety flow
- ask for analysis (
status,diff), - apply focused edits,
- run verification commands,
- commit only after green checks.
Common mistakes and troubleshooting
- Mistake: one huge commit for many unrelated edits.
- Fix: split by concern and verify each.
- Mistake: running destructive git commands without review.
- Fix: keep interactive approval on for mutating commands.
- Mistake: trusting commit message generation without diff review.
- Fix: always inspect final staged diff before commit.
MCP integration guide
MCP (Model Context Protocol) lets Akmon call external tools on demand: databases, issue trackers, internal APIs, docs systems, and more.
What MCP gives you
Without MCP, developers often paste large external context (schema dumps, issue text, docs) directly into prompts. That is expensive and fragile. MCP changes this model: the agent requests only the data it needs, when it needs it.
Benefits:
- keeps large datasets out of the core prompt context,
- improves context-window efficiency,
- reduces manual copy/paste operations,
- allows repeatable integrations across projects.
Setting up MCP servers
Example configuration in ~/.akmon/config.toml:
[[mcp_servers]]
name = "postgres"
command = "npx"
args = ["-y", "@modelcontextprotocol/server-postgres", "postgresql://localhost/myapp"]
[[mcp_servers]]
name = "github"
command = "npx"
args = ["-y", "@modelcontextprotocol/server-github"]
env = { GITHUB_PERSONAL_ACCESS_TOKEN = "ghp_..." }
[[mcp_servers]]
name = "filesystem"
command = "npx"
args = ["-y", "@modelcontextprotocol/server-filesystem", "/Users/you/documents"]
Then inspect:
akmon config mcp list
akmon config mcp test postgres
akmon config mcp test github
Real workflow: database-driven development
Scenario: you need SQLAlchemy models from a live schema and do not want to paste DDL.
akmon --model claude-haiku-4-5-20251001
Prompt:
Use available MCP tools to inspect the PostgreSQL schema, then generate SQLAlchemy models and CRUD routes that match current tables and relationships.
Expected behavior:
- agent discovers MCP tools for postgres,
- queries schema metadata via MCP tool calls,
- writes model files from real schema,
- verifies via project test/lint commands.
Real workflow: GitHub issue execution
Prompt:
Use GitHub MCP to read issue #47, implement the requested change, and create a commit message referencing the issue number.
Expected behavior:
- reads issue content directly from GitHub,
- finds local files to change,
- produces implementation + verification commands,
- prepares commit summary linked to issue context.
Real workflow: external filesystem context
Prompt:
Read ~/documents/api-spec.md via filesystem MCP and update this repository's API handlers to match it.
This is useful when specs, contracts, or governance docs live outside the repository root.
Building a custom MCP server (minimal Python example)
#!/usr/bin/env python3
import json
import sys
TOOLS = [{"name": "hello_company", "description": "Returns internal greeting"}]
for line in sys.stdin:
req = json.loads(line)
method = req.get("method")
rid = req.get("id")
if method == "tools/list":
print(json.dumps({"id": rid, "result": {"tools": TOOLS}}), flush=True)
elif method == "tools/call":
name = req.get("params", {}).get("name")
if name == "hello_company":
print(json.dumps({"id": rid, "result": {"content": "hello from internal system"}}), flush=True)
else:
print(json.dumps({"id": rid, "error": {"message": "unknown tool"}}), flush=True)
Wire this script as an MCP server command in config.
Safety and policy model
MCP is not a bypass:
- calls still pass through Akmon policy checks,
- potentially destructive actions can still require confirmation,
- audit logs still record actions and outcomes.
MCP governance policy dimensions
In configured policy mode, MCP is governed by explicit server/tool rules:
[mcp.servers]
allow = ["github-prod"]
deny = ["*"]
[mcp.tools]
allow = ["search_issues"]
deny = ["*"]
This example allows exactly one server/tool pair and denies all others.
Fail-closed behavior:
- missing or malformed MCP context denies,
- ambiguous MCP context (same tool name from multiple servers) denies,
- parent policy modes without configured MCP rules deny.
Audit enrichment for MCP actions
Policy and MCP tool outcome audit rows include:
mcp_servermcp_tooldecision_reason(policy rows)
Treat MCP servers like production dependencies: least privilege, scoped credentials, and explicit ownership.
Common mistakes and troubleshooting
- Server starts locally but
mcp testfails: check command path and env vars. - Tool missing in session: verify server is enabled and reachable from runtime shell.
- Slow responses: reduce response size in MCP server output; return focused payloads.
- Risky action exposure: split read-only and write-capable tools into separate servers/credentials.
- MCP call denied by policy: check
[mcp.servers]and[mcp.tools]allow/deny rules, then inspect auditdecision_reason. - Unexpected fail-closed deny: ensure MCP tool names are unique across servers or scope policy to one server.
Audit log
Documented for Akmon 2.2.0.
The audit log is the tamper-evident decision trail of a reference-agent session. When Akmon's own bundled agent runs, it writes a per-session JSONL audit log where each row is hash-linked to the row before it. This is part of what earns a reference-agent session its full capture level: every policy decision and tool outcome is recorded in order, and the order cannot be changed after the fact without detection.
This is a producer-side artifact of the reference agent. An OpenTelemetry import carries whatever the third-party trace emitted at structural capture level, not this chain.
Why this matters
When an AI agent changes something, "it changed some files" is not enough to put in front of a reviewer or an auditor. The audit log answers the operational questions:
- what the model requested,
- what the policy allowed, denied, or prompted on,
- what commands and files were executed,
- when and why a session stopped.
The hash chain adds one more property on top: a third party can confirm the log was not edited or reordered after the run.
Log location
Typical path:
.akmon/audit/<session-id>.jsonl
The session id is shown in UI and session output, and links runtime behavior to log artifacts.
Verification
akmon audit verify .akmon/audit/<session-id>.jsonl
akmon --output json audit verify .akmon/audit/<session-id>.jsonl
Exit codes:
0: chain valid1: invalid, missing, or tampered audit file
Typical event categories
- policy decisions (
allow,deny,prompted), - tool lifecycle (requested, executed, completed, failed),
- usage and cost-related summaries,
- session lifecycle transitions (start, done, error).
Each JSONL row also includes tamper-evident chain metadata:
schema_version("audit_chain.v1"),event_index,prev_hash,event_hash,- an optional
session_final_hashon the final row.
Example lines:
{"schema_version":"audit_chain.v1","event_index":0,"event_hash":"...","event_kind":"policy_evaluation","timestamp":"2026-04-06T14:23:11Z","permission":"write_file","path":"src/main.rs","verdict":"allow","reason":"user confirmed"}
{"schema_version":"audit_chain.v1","event_index":1,"prev_hash":"...","event_hash":"...","session_final_hash":"...","event_kind":"tool_call","timestamp":"2026-04-06T14:23:15Z","tool":"shell","args":{"command":"cargo check"},"result":"ok"}
Downstream parsers should deserialize each line as AuditChainRecord and read the original event payload from .event (flattened fields like event_kind remain present in JSON).
How the audit log relates to the verification layer
The audit chain is the runtime ledger. The evidence artifact and the AGEF bundle are the portable, signable records built on top of it.
- For replay workflows, pair this audit chain with the CLI JSON
replay_metadatahashes (policy_hash,config_hash,tool_registry_hash, and the optionalprompt_assembly_hash) to validate run prerequisites before replaying. - Akmon evidence artifacts (
.akmon/evidence/<session-id>.json) include the linkedaudit_log_path, the audit validation result, and the final chain hash, so CI can verify replay, audit, and tool/file outcomes together. - A signed AGEF bundle then carries the whole session head under an offline Ed25519 signature, so the integrity the audit chain establishes locally can be checked by a third party offline. See Evidence artifact and Security model.
Migration note
If you previously parsed each line as a plain AuditEvent, migrate to AuditChainRecord and validate:
schema_version == "audit_chain.v1",- monotonic
event_index, prev_hash/event_hashchain integrity,session_final_hashonly on the final record.
Useful queries
# show only denied actions
jq 'select(.verdict? == "deny")' .akmon/audit/*.jsonl
# list all file-write decisions
jq 'select(.permission? == "write_file")' .akmon/audit/*.jsonl
Retention and operations
- treat audit logs as operational artifacts,
- rotate or archive old logs,
- avoid committing logs to git unless policy requires it.
Example retention sweep:
find .akmon/audit -type f -mtime +30 -delete
Common mistakes and troubleshooting
- Missing logs: confirm audit logging is enabled in your workflow or config, and that the run was a reference-agent session (OTEL imports do not produce this chain).
- Unparsable lines: use a line-by-line JSON parser (
jq -c) and detect malformed rows early. - Chain verification failure: a line was modified, reordered, or truncated. Re-export the original audit artifact and verify with the same file bytes.
- Secrets concern: logs should not contain API keys. If they appear, rotate keys and report immediately.
See also Security model, Evidence artifact, and Cost transparency.
Policy profiles and packs
Documented for Akmon 2.2.0.
Policy profiles and packs govern Akmon's own reference agent. They decide what side effects the bundled agent may take and how strictly each environment is locked down. This is a producer-side control: it shapes the behavior of a reference-agent run, and the effective policy is hashed into the run's evidence so a reviewer can detect governance drift. It does not apply to imported third-party OpenTelemetry traces, which carry only what the producing agent emitted.
Akmon supports enterprise policy rollout with reusable profiles and composable packs, so the same governance inputs can move from a developer laptop to a hardened CI runner without rewriting rules.
Built-in profiles
dev: read-friendly, controlled writes, restricted shell and network.staging: stricter write, shell, and network posture thandev.prod: highly restrictive, explicit-deny posture for side effects.
Profiles map to the existing PolicyConfig schema (filesystem, shell, network, tools).
Policy packs
Policy packs are local TOML or JSON policy files layered on top of a selected profile.
Default discovery path:
.akmon/policy-packs/*.toml
.akmon/policy-packs/*.json
Additional packs can be added with repeatable CLI flags:
akmon --policy-pack .akmon/policy-packs/org.toml --policy-pack .akmon/policy-packs/team.toml --task "..."
Malformed selected packs fail closed with an explicit error.
Deterministic precedence
Effective policy merge order:
- built-in profile,
- packs,
- project-local policy (
.akmon/policy.tomlor.akmon/policy.json), - CLI override (
--policy-override).
Within each layer, list fields append and deduplicate while keeping the last occurrence, so higher-precedence layers keep later rule order. Evaluation within a rule list is deterministic: explicit deny wins, and the most specific matching rule is selected.
Inspect effective policy
Use:
akmon policy show-effective --profile staging --policy-pack .akmon/policy-packs/org.toml
akmon --output json policy show-effective --profile prod
This prints the final merged policy and the exact source order used.
Governance provenance in evidence
The effective policy after the merge is hashed into the run's evidence as replay_metadata.policy_hash. Because the hash is deterministic, any change to the selected profile or to pack contents changes the hash. A CI or PR system can therefore detect a policy-governance change between runs even when the behavioral effect is subtle. This is what makes the policy layer auditable rather than merely enforced. See Evidence artifact.
Rollout guidance
Typical enterprise rollout:
- Start with
devplus narrow team packs. - Tighten shell, network, and tool scope in
staging. - Lock production automation to
prodplus an audited, minimal override pack. - Enforce evidence and SLO checks in CI after policy changes, and gate on
policy_hashto catch unreviewed governance drift.
For a step-by-step rollout, see the Enterprise policy rollout tutorial.
See also
Evidence artifact
Documented for Akmon 2.2.0.
Who this is for
Developers, reviewers, and compliance engineers who need a portable, machine-checkable record of what a reference-agent run did, for CI gating and audit handoff.
Where the evidence artifact sits
Akmon is an evidence and verification layer. The evidence artifact is the CI-facing summary of a reference-agent run. It is a deterministic JSON document that links the run's replay metadata, audit-chain integrity, policy decisions, tool timeline, reliability metrics, and touched files into one object a pipeline can verify in a single step.
It is distinct from the portable AGEF bundle. The evidence artifact is for in-repo CI gating. The AGEF bundle is for external, offline, signed handoff. They are complementary, and a regulated workflow usually produces both: the evidence artifact gates the merge, the signed bundle is the record a third party verifies later. See Security model for the verification layer, and the audit chain it builds on in Audit log.
This artifact comes from Akmon's own reference agent, which records full capture. An OpenTelemetry import is a structural capture and does not produce this artifact.
What you will have at the end
- A clear model of what Akmon records in evidence artifacts.
- Commands to validate artifact integrity and enforce reliability gates in CI.
Prerequisites
- A completed headless reference-agent run (
akmon --task ...) that emitted artifacts.
Steps
- Run a headless session to produce evidence.
akmon --task "run tests and summarize failures" --output json --yes | tee run.json
- Locate the evidence artifact path.
Akmon writes a deterministic evidence artifact per successful or budget-stopped headless run:
.akmon/evidence/<session-id>.json
You can override the location with --evidence-path <path>.
- Verify the evidence and its linked audit chain:
akmon evidence verify .akmon/evidence/<session-id>.json
Why it exists
The artifact is designed for CI and PR automation and links:
- replay metadata (
replay_metadatahashes), - audit-chain integrity (
audit.audit_chain_valid,session_final_hash), - the policy decision summary,
- the tool execution timeline and aggregates,
- reliability and SLO metrics,
- touched files and verification outcomes.
Schema version
Artifacts include:
evidence_schema_version(currentlyevidence.v1)
Consumers should validate the schema version before strict parsing.
Example
{
"evidence_schema_version": "evidence.v1",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"generated_at": "2026-04-20T12:34:56.000Z",
"replay_metadata": {
"hash_algorithm": "sha256",
"provider_name": "ollama",
"model_id": "llama3.2",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"policy_hash": "...",
"config_hash": "...",
"tool_registry_hash": "...",
"prompt_assembly_hash": "..."
},
"audit": {
"audit_log_path": ".akmon/audit/550e8400-e29b-41d4-a716-446655440000.jsonl",
"audit_chain_valid": true,
"session_final_hash": "..."
},
"policy": {
"allow": 8,
"deny": 1,
"prompted": 2,
"decision_samples": ["allow:read_file:..."]
},
"tools": {
"timeline": [{"name": "read_file", "success": true, "message": "ok"}],
"total": 1,
"success": 1,
"failure": 0
},
"files_touched": ["src/main.rs"],
"verification": {
"outcomes": [],
"unavailable_reason": "verification commands not collected in this run"
},
"reliability_metrics": {
"tool_calls_total": 1,
"tool_calls_success": 1,
"tool_calls_failure": 0,
"tool_latency_ms_total": 14,
"tool_latency_ms_avg": 14,
"tool_latency_ms_p95": 14,
"policy_denials_total": 0,
"retries_total": 0,
"timeouts_total": 0
},
"notes": []
}
Validation
akmon evidence verify checks schema support, replay metadata shape, the linked audit-chain integrity, and session hash consistency.
Exit codes:
0: evidence valid1: evidence invalid, missing, or tampered
Verification
SESSION_ID="$(jq -r '.session_id' run.json)"
akmon evidence verify ".akmon/evidence/${SESSION_ID}.json"
Expected result: the command exits 0 and reports valid schema and session linkage.
From in-repo evidence to a signed, offline-verifiable bundle
The evidence artifact proves integrity to a party who can run Akmon against your repository. To hand the same session to a party who does not trust you and does not run your tools, export it as a signed AGEF bundle:
- Generate a signing key once:
akmon bundle keygen --out signer.pk8 --public-out signer.pub. - Export and sign the session:
akmon bundle export <session-id> --output session.akmon, thenakmon bundle sign session.akmon --key signer.pk8. - Optionally record the accountable operator:
akmon bundle attest session.akmon --key operator.pk8 --operator-id you@org --role approver. - The recipient verifies with
akmon bundle verify session.akmon --verify-key signer.pub --require-signature, or with the standaloneagef-verify, or with stockopensslafterakmon bundle prove-openssl.
The evidence artifact and the bundle are anchored to the same content-addressed session, so the session_final_hash you gated on in CI is the head the signature covers.
Enforcing SLOs in CI
You can enforce reliability guardrails directly against evidence:
akmon slo verify .akmon/evidence/<session-id>.json --strict
Example GitHub Actions step:
- name: Enforce Akmon SLO guardrails
run: |
akmon slo verify .akmon/evidence/${SESSION_ID}.json \
--thresholds .github/akmon/slo.toml \
--strict
Trend and regression check against prior evidence history:
- name: Detect reliability regressions
run: |
akmon slo trend .akmon/evidence/${SESSION_ID}.json \
--baseline-dir .akmon/evidence/history \
--window 20 \
--strict
Troubleshooting
- If evidence verify fails, confirm the artifact path and JSON validity.
- If session linkage errors appear, ensure the audit and evidence files are from the same session.
- If SLO gates fail, inspect thresholds and
reliability_metricsfields before relaxing policy.
Policy provenance and hash impact
Evidence keeps the replay metadata policy_hash, which is computed from the effective runtime policy mode and config after the profile, pack, project-local, and override merge. Any change in the selected profile or pack contents deterministically changes policy_hash, so CI and PR systems can detect policy-governance drift even when behavior changes are subtle. See Policy profiles and packs.
Migration note
Treat evidence_schema_version as required for parsers and reject unknown versions. reliability_metrics is additive and stable-keyed for CI automation.
See also
Security model
Documented for Akmon 2.2.0.
Akmon is an evidence and verification layer for AI agents. Its security model has two halves, and they are deliberately separate.
The first half is the verification layer, which is the product. It does not trust the producer. A signed AGEF bundle can be checked offline, by a third party, with nothing but openssl. The trust you place in a record comes from a public key you already hold, not from anything the producer asserts about itself.
The second half is the runtime control surface of Akmon's own reference agent. When you run the bundled agent, side effects pass through typed permissions, sandbox boundaries, and policy. Those controls are what let a reference-agent session record an honest full capture level. They are not the trust boundary for an imported third-party trace. An OpenTelemetry import records what the trace contained, at structural capture level, and the verification layer never pretends a structural import is a full recording.
This page covers both halves. Read it as: what a verifier can rely on without trusting you, then what the reference agent enforces at runtime.
What the verification layer guarantees
The verification layer makes claims that hold regardless of who produced the session.
- Integrity. AGEF objects are SHA-256 content-addressed and the event chain is hash-linked. Any change to any recorded byte changes the head, and the head is what gets signed.
akmon bundle verifyand the standaloneagef-verifyrecompute the chain and reject a tampered bundle. - Authorship. An optional offline Ed25519 signature (
akmon bundle sign) covers the session head through the canonicalAGEF-SIG-v1statement. A verifier checks it against a public key supplied out of band. No network, no Akmon install required for the math:akmon bundle prove-opensslemits the exact bytes and theopenssl pkeyutl -verifycommand. - Accountability. An optional operator attestation (
akmon bundle attest) records a separately signedAGEF-OPERATOR-v1claim about the accountable person. Verification attaches trust to the attesting key, never to the self-assertedoperator_id,role, ororgstrings. A name is only as trustworthy as the key that signed it, and that key trust is established out of band.
These properties are what make a session usable as evidence in front of a party who does not trust you and does not run your tools.
Trust attaches to keys, not to strings
This is the single most important property to internalize. The operator_id, role, and org fields in an attestation are self-asserted strings carried verbatim. The only trust signal is whether a distinct attestation verifies against a key you supplied with --operator-key. A session attested with no trusted key on hand reports an unverified status, which is not a failure on its own, just an absence of established trust. You decide which keys to trust, and you do that through your own out-of-band process.
Offline and producer-independent
The verifier does not have to trust the machine that produced the bundle, the agent that ran, or the operator's claims. A signature check needs three inputs: the signed statement bytes, the detached signature, and a public key the verifier already trusts. akmon bundle prove-openssl writes all three to a directory and prints the openssl command. Stock OpenSSL 3.x verifies it. This is the floor under every other claim on this page: if the cryptography does not check out with a tool the verifier already trusts, nothing else matters.
Capture honesty
Akmon never overstates what a record contains.
- A reference-agent session, run by Akmon's own bundled agent, records
fullcapture. It captured the events it claims to have captured, and it can be replayed deterministically. - An OpenTelemetry import (
akmon otel import) recordsstructuralcapture. It is a faithful transcription of what the trace carried, not a full recording.akmon bundle verify --require-capture fullfails on it, andakmon replayrefuses it.
--require-capture full is the gate to use when a workflow must reject anything weaker than a full recording. Capture level is part of the record, so a verifier sees the honest level and decides whether it meets their bar.
The reference agent runtime: side-effect control
The rest of this page concerns Akmon's own reference agent. The risk it manages is not model output text. The risk is model-triggered side effects:
- writing files,
- running shell commands,
- accessing network resources,
- mutating git state.
The reference agent mediates each of these through sandboxing, typed permissions, and policy, and records every decision in the audit chain. That mediation is what earns the full capture level. None of it applies to imported third-party traces, which carry only what the producing agent emitted.
Sandbox boundaries
File operations are constrained to project boundaries. Path traversal attempts are blocked. This prevents prompt-driven writes to unrelated filesystem locations in normal operation.
Permission classes
| Class | Typical actions | Default posture |
|---|---|---|
| Read | list/read/search | easier to auto-approve (--yes) |
| Write | write/edit/patch | requires explicit confirmation/policy allow |
| Shell | command execution | allowlisted/confirmed paths |
| Network | web fetch/MCP-backed actions | policy-checked and traceable |
| Git mutating | add/commit/restore/etc. | confirmed or explicitly policy-approved |
Diff-first approvals
For file changes, Akmon can present unified diffs before final approval. This gives human review at the moment side effects happen, not only at the end.
For automation and CI, file-modifying tools also expose dry_run validation:
- run
patch/apply_patch/edit/write_filewithdry_run: true, - inspect the returned
file_change_set(mode: "dry_run",summary,risk, per-filechanges), - execute the same tool call without
dry_runonly when risk and diffs are acceptable.
Policy-as-code (Configured)
Configured policy mode supports declarative allow/deny rules for:
- filesystem read/write paths,
- shell command prefixes,
- network domains,
- tool names,
- MCP server names and MCP tool names.
Evaluation is deterministic: explicit deny wins, and the most specific matching rule is selected within each rule list.
MCP governance hardening (fail-closed)
MCP tool calls are governed by dedicated policy dimensions:
mcp.servers.allow/mcp.servers.denymcp.tools.allow/mcp.tools.deny
Execution posture is fail-closed:
- missing MCP context (server/tool) denies,
- ambiguous MCP context denies,
- parent policy modes without configured MCP rules deny,
- explicit deny rules win over allow matches.
MCP calls still pass normal permission checks after MCP policy approval. There is no bypass path.
Enterprise policy profiles and packs
Akmon supports reusable policy governance inputs for org rollout:
- built-in profiles (
dev,staging,prod), - policy packs loaded from
.akmon/policy-packs/*.toml|json, - a project-local policy file (
.akmon/policy.tomlor.akmon/policy.json), - an optional CLI override (
--policy-override).
Precedence is explicit and deterministic:
profile < packs < project-local < CLI override
This enables staged hardening from development to production without changing the underlying permission classes. See Policy profiles and packs for the full rollout model.
Recommended posture:
dev: fast local iteration with controlled side effects.staging: tighter shell/network/tool posture for pre-prod automation.prod: explicit-deny heavy posture with minimal mutation surface.
The selected profile and pack contents feed the effective policy, and the effective policy is hashed into evidence as policy_hash. A governance change is therefore visible to CI even when the behavioral effect is subtle.
Nested/subagent safety ceiling
spawn_subagent runs under a strict parent permission ceiling:
- nested sessions never seed broad "allow all writes" approvals,
- parent interactive mode is downgraded to read-oriented nested execution with no implicit side effects,
- tool eligibility is pre-filtered with policy evaluation using tool-name context,
- side-effect decisions still pass through normal permission checks at dispatch time.
This closes the class of escalation where a nested run could gain broader write/shell/network rights than the parent session posture.
Before:
- nested bootstrap pre-seeded broad interactive allow replies,
- side-effect tools could be available in nested runs even when parent posture was read-only.
After:
- nested runs fail closed when confirmations cannot be satisfied safely,
- nested tool access is a subset of parent policy capability.
Network and SSRF posture
web_fetch applies protections against common private-address and metadata-endpoint abuse patterns. This reduces risk from prompt injection that tries to exfiltrate internal data.
Secrets handling
Operational guidance:
- keep keys in environment variables or secured config paths,
- never paste production credentials into prompts,
- rotate credentials immediately if leakage is suspected,
- store signing keys (the
.pk8files fromakmon bundle keygen) the way you would store any private signing material. Akmon writes them0600on unix, but their security after that is your custody process.
What --yes is and is not
--yes is a productivity flag, not a blanket "do anything" bypass. It primarily streamlines read-oriented operations. Mutating actions remain policy-gated.
Reliability metrics are observability only
Run and evidence reliability counters (tool success rates, denials, retries, timeouts) are for operational visibility and SLO monitoring. They do not grant permissions and do not bypass policy enforcement. See Reliability and SLO metrics.
Common mistakes and troubleshooting
- Mistake: treating a
structuralOTEL import as if it were a full recording.- Fix: gate strict workflows with
akmon bundle verify --require-capture full, and use replay only on reference-agent sessions.
- Fix: gate strict workflows with
- Mistake: trusting an operator name because it appears in a bundle.
- Fix: trust the attesting key. Verify with
--operator-keyand establish key trust out of band.
- Fix: trust the attesting key. Verify with
- Mistake: enabling broad shell access in unattended workflows.
- Fix: restrict with precise allow patterns in a
prodprofile or pack.
- Fix: restrict with precise allow patterns in a
- Mistake: assuming audit logs replace code review.
- Fix: use logs plus normal review and CI controls.
- Mistake: storing sensitive logs or signing keys in version control.
- Fix: keep
.akmon/artifacts and key material out of source control unless policy requires it.
- Fix: keep
See also
Reliability and SLO metrics
Documented for Akmon 2.2.0.
Akmon emits lightweight run-level reliability metrics in headless JSON output and in evidence artifacts. These are an observability signal for Akmon's own reference-agent runs. They make a run measurable in CI and operations without adding heavy tracing overhead.
These counters are observability only. They do not grant permissions and do not bypass policy enforcement. They describe how a reference-agent run behaved; they do not change what it was allowed to do. See Security model for the enforcement boundary, and Evidence artifact for where these metrics are persisted.
Why this exists
A run that produces correct code but fails a quarter of its tool calls is not a healthy run, and a regulated pipeline needs to see that before it ships. These counters turn run health into a number CI can gate on, alongside the integrity and policy checks that the evidence artifact already carries.
Metrics schema
reliability_metrics includes:
tool_calls_totaltool_calls_successtool_calls_failuretool_latency_ms_totaltool_latency_ms_avgtool_latency_ms_p95(null when no tool calls occurred)policy_denials_totalretries_totaltimeouts_total
Starter SLO targets
Use these as a baseline, then tune by repo and workflow:
- tool success rate at or above 95 percent (
tool_calls_success / tool_calls_total), - timeout rate under 2 percent of tool calls for stable pipelines,
- a predictable policy denial ratio for your mode:
- a higher ratio in strict or read-only modes is expected,
- sudden spikes in implementation mode should be investigated.
CI alerting pattern
Run with JSON output:
akmon --output json --task "..." > run.json
Example checks with jq:
jq -e '
.status == "completed"
and (
.reliability_metrics.tool_calls_total == 0
or (.reliability_metrics.tool_calls_success / .reliability_metrics.tool_calls_total) >= 0.95
)
and .reliability_metrics.timeouts_total < 3
' run.json
Or enforce directly with built-in guardrails:
akmon slo verify run.json --thresholds .akmon/slo.toml --strict
Trend regression detection
Guard against quality drift using historical baseline artifacts:
akmon slo trend .akmon/evidence/current.json \
--baseline-dir .akmon/evidence/history \
--window 20 \
--strict
akmon slo trend selects the last N valid baseline samples deterministically, then compares current metrics to baseline aggregates (median for rates, mean for totals and latency deltas).
Scope and limitations
retries_totaltracks session-level continuation retries currently visible inakmon-query.timeouts_totaltracks timeout outcomes visible in session, model, and tool paths.- Provider-internal retry loops that are fully hidden behind provider clients are not counted separately.
See also
Cost guide
Akmon is explicit about token usage and estimated spend so you can manage AI work as an engineering budget, not a surprise invoice.
What actually drives costs
For coding agents, the largest cost driver is usually cumulative input tokens, not output tokens. Each model call resends core context plus recent conversation history.
Real session example:
- 35 API calls
- 672k input tokens
- 35k output tokens
- 258k cache-read tokens
- total around $0.68
Using Haiku rates:
- input: 672000 * $0.80 / 1M = $0.5376
- output: 35000 * $4.00 / 1M = $0.1400
- cache reads: 258000 * $0.08 / 1M = $0.0206
Prompt caching and why it matters
Cached prompt reads are much cheaper than fresh prompt tokens. Akmon surfaces cache usage in the footer and session summary so you can see when repeated context is becoming efficient.
Interpretation:
- high cache read ratio often means repeated shared context is being billed at discount rates,
- low cache ratio with high input often indicates noisy/volatile context.
Cost by task type
| Task | Model | Typical cost | Notes |
|---|---|---|---|
| Single-file edit | Haiku | $0.01-$0.03 | few turns |
| 3-5 file feature | Haiku | $0.05-$0.20 | moderate context |
| Build small app from scratch | Haiku | $0.30-$0.80 | many turns |
| Complex refactor | Haiku | $0.20-$0.50 | exploration heavy |
| Architecture design | Sonnet | $0.50-$2.00 | stronger reasoning |
Model selection strategy
- Haiku: default for most implementation work.
- Sonnet: architecture and hard reasoning spikes.
- GPT-4o-mini: strong budget option if OpenAI is preferred.
- Ollama local models: free token cost, but lower capability and potentially higher latency.
For local models, "free token cost" still carries operational tradeoffs:
- cold-start latency can be significant on first request,
- smaller local context windows can trigger no-output/context-overflow failure modes,
- tool-calling reliability varies by model family.
Use Akmon's local status hints and remediation guidance (/clear, ollama ps, model switch) to recover quickly.
Practical cost controls
Use multiple levers together:
--max-budget-usdfor hard stop,- plan/spec workflow to avoid repeated exploratory context,
- smaller focused tasks,
- context hygiene (
/clearwhen a session gets noisy), - use
/contextand/costduring long runs.
For automated runs, pair budget caps with evidence/SLO checks:
akmon --yes --output json --max-budget-usd 1.50 --task "..." | tee run.json
akmon slo verify run.json --thresholds .akmon/slo.toml
Common mistakes and troubleshooting
- Mistake: using premium models for trivial edits.
- Mistake: allowing sessions to drift into repeated read loops.
- Mistake: ignoring cache/read metrics and only watching final cost.
- Fix: split work by phase and use cheaper models for discovery.
Capabilities reference
Documented for Akmon 2.2.0.
This page is a practical map of what Akmon can do. Akmon is a producer-agnostic, tamper-evident evidence and verification layer for AI agents. The verification chain is the core capability; the bundled reference agent is one way to feed it, not the headline.
Evidence and verification (the core)
| Capability | Command | Why it matters |
|---|---|---|
| Import any agent's trace | akmon otel import <trace.json> | Brings OpenTelemetry GenAI traces (v1.37 structured and legacy v1.36-and-earlier message-event form) into AGEF; records an honest capture level |
| Content-addressed, hash-linked record | (format) | SHA-256 objects and a hash-linked event chain make the session tamper-evident by construction |
| Generate a signing key | akmon bundle keygen | Ed25519 PKCS#8 v2 key that akmon bundle sign accepts; openssl genpkey cannot produce one |
| Offline signature over the head | akmon bundle sign | Adds an Ed25519 signature over the session head, the AGEF-SIG-v1 statement |
| Operator attestation | akmon bundle attest | Records a separately signed operator-identity claim; trust attaches to the key, not the name |
| Verify integrity, signature, capture | akmon bundle verify | Checks the chain, the signature, operator attestation, and --require-capture full |
| Standalone verifier | agef-verify | Verifies a bundle with no full Akmon install, for auditors |
| Offline proof with plain openssl | akmon bundle prove-openssl | Emits statement.bin, signature.bin, pubkey.pem, and the exact openssl command; needs OpenSSL 3.x |
| Portable transport | akmon bundle export / bundle import | Moves a sealed session between machines and tools |
| Inspect, compare, redact | akmon inspect, akmon diff, akmon redact | Read a bundle, compare two sessions structurally and by field, remove sensitive bytes while preserving structure |
The standard pattern for an imported session: import a trace, export and sign the bundle, verify integrity and signature, then emit an openssl proof a stranger can check.
Capture honesty
Akmon never overstates how much it captured.
| Source | Capture level | Replay | --require-capture full |
|---|---|---|---|
| Akmon's own reference agent | full | Replays deterministically | Passes |
| OpenTelemetry import | structural | Refused | Fails (by design) |
The bundled reference agent (gold-fidelity producer)
Akmon ships a coding agent that produces full-capture sessions. It is the reference producer, not the product. Its own-agent verification surface:
akmon audit verify,akmon evidence verify, andakmon verifyfor the on-disk journal, audit chain, and evidence artifact,akmon replayfor deterministic playback,akmon slo verify --strictfor reliability thresholds.
Operating modes (reference agent)
| Mode | Command | Best use case |
|---|---|---|
| Interactive | akmon chat | supervised iterative implementation |
| Headless | akmon --yes --task "..." | CI and automation |
| JSON reporting | --output json | machine-readable orchestration |
| Plan-only | --plan | read-only scoping before edits |
| Architect | --architect | plan and implement with a model split |
| Spec workflow | akmon spec ... | structured requirements, design, and tasks |
Runtime and packaging
| Capability | Why it matters |
|---|---|
| Single Rust binary | predictable behavior across laptop, SSH host, CI runner |
Standalone verifier binary (agef-verify) | auditors verify without installing the full agent |
| Optional feature set | choose slim or full builds by environment needs |
| Terminal-first UX | works where editor plugins are unavailable |
Model and provider support (reference agent)
The bundled agent supports local and cloud providers:
- Ollama (offline and local),
- Anthropic,
- OpenAI-compatible providers,
- OpenRouter, Groq, Azure, Bedrock.
Model selection is per-task, which keeps cost and capability tuning an operator decision rather than a tooling lock-in.
Policy and safety capabilities
- permission-gated side effects,
- write diff confirmation flows,
- sandboxed filesystem boundaries,
- auditable tool and policy events.
Cost and observability capabilities
- token and cache visibility in the UI,
- cost estimates and run summaries,
- JSONL audit trail for runtime evidence.
Automation capabilities
- headless runs with budget caps,
- structured JSON run output,
- a script-friendly command model for batch operations and CI gates.
Known non-goals
- no hosted SaaS runtime (you run it),
- no mandatory IDE dependency,
- no guarantee that third-party model APIs are available,
- no certification or compliance guarantee. Akmon helps you produce evidence for frameworks like the EU AI Act, NIST AI RMF, and SOC 2; validate fit with your own legal and compliance teams.
Next steps: tutorials overview, reviewer flow, security model.
CLI Reference
Documented for Akmon 2.2.0.
Who this is for
Engineers and CI maintainers who need an accurate command-surface overview before using the command-specific reference pages. Akmon is an evidence and verification layer first; the trust commands are the core of the surface, and the bundled reference agent is one producer that feeds them.
What you will have at the end
- The trust command surface (import, key, sign, attest, verify, prove).
- The reference-agent command surface and global flags.
- Pointers to per-command reference pages for stable automation.
Prerequisites
- Akmon installed and runnable (
akmon --version). - For producing evidence with the bundled agent, a project repository.
The trust commands (core)
These are the producer-agnostic evidence and verification commands. They operate on bundles and traces, not on a running agent.
# Bring any agent's OpenTelemetry trace into AGEF (honest capture level)
akmon otel import trace.json --journal .akmon/journal
# Make an Ed25519 signing key (openssl genpkey cannot make a usable one)
akmon bundle keygen --out signer.pk8 --public-out signer.pub.hex
# Export, then sign the session head offline
akmon bundle export <session-id> --output session.akmon
akmon bundle sign session.akmon --key signer.pk8
# Record the accountable operator (trust attaches to the key, not the name)
akmon bundle attest session.akmon --key signer.pk8 --operator-id you@org --role approver
# Verify integrity, signature, operator attestation, capture level
akmon bundle verify session.akmon --verify-key signer.pub.hex --require-signature
# Emit an offline proof anyone can check with plain openssl (OpenSSL 3.x)
akmon bundle prove-openssl session.akmon --verify-key signer.pub.hex --out-dir proof
Inspect exact flags before scripting:
akmon otel import --help
akmon bundle keygen --help
akmon bundle sign --help
akmon bundle attest --help
akmon bundle verify --help
akmon bundle prove-openssl --help
akmon bundle export --help
akmon bundle import --help
The standalone verifier is a separate binary for auditors who do not install the full agent:
agef-verify session.akmon --verify-key signer.pub.hex --require-signature
The reference agent
The bundled coding agent is the gold-fidelity producer of full-capture sessions.
# Interactive TUI
akmon
# Headless run
akmon --task "run tests and summarize failures" --output json --yes
Inspect top-level help for current global options and subcommands:
akmon --help
Verification
Run a no-side-effect check on command availability:
akmon --help
akmon config --help
akmon policy --help
akmon slo --help
Expected result: commands parse and help exits 0.
Troubleshooting
- If a command in this page differs from your binary, treat
akmon --helpas the source of truth. - If
akmon bundle signrejects a key, regenerate withakmon bundle keygen. Anopenssl-made key is PKCS#8 v1 and will not work. - If
opensslcannot verify a proof on macOS, you are on LibreSSL. Use OpenSSL 3.x. - For provider or auth routing confusion in the reference agent, run
akmon config explain-provider. - For failed provider setup, run
akmon doctor providers.
Top-level subcommands
Trust and evidence:
otel importbundle keygenbundle signbundle attestbundle verifybundle prove-opensslbundle exportbundle importsignverifyinspectdiffredactreplay
Reference agent and governance:
chatinitnewconfigdoctorauditevidenceslopolicyscoutspecimportexport
Common global flags
--task <TEXT>: headless task run.--model <MODEL>: active model id.--yes: auto-approve read-only tools.--output <text|json>: output format.--audit-log <PATH>: override audit JSONL output path.--evidence-path <PATH>: override evidence JSON path.--policy-profile <dev|staging|prod>: select built-in policy profile.--policy-pack <PATH>: add policy pack (repeatable).--policy-override <PATH>: highest-precedence override file.--web-fetch: enableweb_fetchtool.--yes-web: auto-approveweb_fetchto allowed public URLs.--mcp-server <URL>: register MCP tools from a remote server (repeatable).--index: load or build semantic index.--plan: read-only planning mode.--architect: two-phase planner and implementation mode.--planner-model <MODEL>: planner model override.--continue: resume last project session.--session <ID_OR_PREFIX>: resume specific session.--name <TEXT>: session display name.--max-budget-usd <USD>: headless spend cap.--add-dir <DIR>: add sandbox directory (repeatable).--dossier <PATH>: inject scout dossier context.--fallback-model <MODEL>: fallback on repeated 429 or 529 (headless).
Command-specific references
Trust and evidence:
- akmon bundle keygen
- akmon sign
- akmon bundle verify
- akmon bundle attest
- akmon bundle prove-openssl
- agef-verify
- akmon bundle export
- akmon bundle import
- akmon verify
- akmon inspect
- akmon redact
- akmon replay
- akmon diff
Trust and governance commands
akmon audit verify <PATH>
Verify tamper-evident audit chain integrity.
akmon audit verify .akmon/audit/<session-id>.jsonl
akmon --output json audit verify .akmon/audit/<session-id>.jsonl
Exit codes:
0: valid chain1: invalid or missing audit file
akmon evidence verify <PATH>
Verify evidence schema, replay metadata shape, and linked audit consistency.
akmon evidence verify .akmon/evidence/<session-id>.json
akmon --output json evidence verify .akmon/evidence/<session-id>.json
Exit codes:
0: valid evidence1: invalid or missing evidence
akmon slo verify <PATH>
Evaluate run and evidence reliability metrics against thresholds.
akmon slo verify .akmon/evidence/<session-id>.json --strict
akmon slo verify run.json --thresholds .akmon/slo.toml
akmon --output json slo verify run.json --min-tool-success-rate 0.95
Exit codes:
0: all enabled checks pass1: threshold violation(s)2: invalid input or config
akmon slo trend <CURRENT_PATH>
Compare current metrics against a historical baseline window.
akmon slo trend .akmon/evidence/current.json \
--baseline-dir .akmon/evidence/history \
--window 20 \
--strict
akmon --output json slo trend run.json \
--baseline-file .akmon/evidence/r1.json \
--baseline-file .akmon/evidence/r2.json
Exit codes:
0: no regression violations1: regression violations (or strict-mode skipped checks)2: invalid input, config, or baseline setup
akmon policy show-effective
Print the effective merged policy and its source layers.
akmon policy show-effective --profile staging
akmon policy show-effective --profile prod --policy-pack .akmon/policy-packs/org.toml
akmon --output json policy show-effective --policy-override /tmp/policy.toml
Exit codes:
0: command succeeded (with or without configured policy sources)1: merge or load error (invalid pack, ambiguous local policy, parse failure)
akmon config explain-provider
Print a deterministic provider resolution trace for the effective CLI model and merged ~/.akmon/config.toml. This command is explainability only: it does not change routing rules and mirrors the same selection as LlmConnectConfig::resolve.
akmon config explain-provider
akmon config explain-provider --json
akmon --output json config explain-provider
The JSON object includes selected_provider, selected_reason, model_id, optional resolution_error, and candidates[] (each with provider, eligible, reason, missing_prerequisites, priority_order). Secrets are never echoed, only named prerequisites.
Pair this with akmon doctor providers when debugging: explain-provider answers which branch won and why, while doctor checks reachability and credential sanity.
akmon doctor providers
Run provider preflight diagnostics with actionable remediation hints.
akmon doctor providers
akmon --output json doctor providers
The report includes a provider_resolution block (same schema as akmon config explain-provider) so you can correlate routing decisions with health checks in one JSON payload.
Checks include:
- key and env presence (masked),
- endpoint format sanity,
- endpoint reachability (where applicable),
- auth mode mismatch hints,
- model hint availability probes where feasible.
Exit codes:
0: active or required provider health checks passed1: critical misconfiguration or unreachable required provider
akmon scout --task "..."
Run bounded, read-only repository scouting and write a structured dossier.
akmon scout --task "find MCP policy enforcement path"
akmon scout --task "TUI state boundaries" --max-files 300 --out .akmon/context/tui-scout.json
akmon --output json scout --task "docs CI checks"
Key flags:
--task: required scout question.--max-files: upper bound for scanned files (default200).--out: dossier output path (default.akmon/context/scout-<timestamp>.json).--max-budget-usd: optional cap (scout itself has zero model spend).
Exit codes:
0: dossier generated and written successfully1: scan or write failure2: invalid input (empty task, invalid bounds, invalid budget)
--dossier <PATH> ingestion
Use a previously generated dossier to seed implementation context:
akmon scout --task "provider routing and doctor coverage" --out .akmon/context/providers.json
akmon --dossier .akmon/context/providers.json --task "implement provider explainability"
Invalid or malformed dossier files fail fast before session start.
Headless JSON output shape
Example (akmon --output json --task "..."):
{
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "completed",
"exit_reason": "completed",
"result": "Done",
"tool_calls": 6,
"files_written": ["src/main.rs"],
"usage": {
"total_input_tokens": 12100,
"total_output_tokens": 830,
"total_cache_read_tokens": 2100
},
"cost_usd": 0.04,
"replay_metadata": {
"hash_algorithm": "sha256",
"provider_name": "ollama",
"model_id": "llama3.2",
"session_id": "550e8400-e29b-41d4-a716-446655440000",
"policy_hash": "...",
"config_hash": "...",
"tool_registry_hash": "...",
"prompt_assembly_hash": "..."
},
"reliability_metrics": {
"tool_calls_total": 6,
"tool_calls_success": 6,
"tool_calls_failure": 0,
"tool_latency_ms_total": 132,
"tool_latency_ms_avg": 22,
"tool_latency_ms_p95": 40,
"policy_denials_total": 0,
"retries_total": 0,
"timeouts_total": 0
},
"provider_resolution": {
"selected_provider": "ollama",
"selected_reason": "Resolution succeeded: selected provider `ollama` (same outcome as `LlmConnectConfig::resolve`).",
"model_id": "llama3.2",
"candidates": [
{
"provider": "bedrock",
"eligible": false,
"reason": "Skipped: Bedrock is considered only when `--bedrock` is set or `AWS_ACCESS_KEY_ID` is present.",
"priority_order": 1
}
]
}
}
The provider_resolution field is additive (automation may ignore it). When present, candidates lists every resolver branch in priority order with human-readable reasons; it is safe to log (no secret values).
Tool output parsing notes
When a run executes file-modifying tools (write_file, edit, patch, apply_patch), successful tool outputs are JSON strings that include a file_change_set payload:
type: "file_change_set"mode: "applied"ormode: "dry_run"changes[]plussummaryplusrisk
CI consumers should parse changes[] as canonical and may continue accepting files[] as a backward-compatible alias.
Evidence output location
By default, headless runs write:
.akmon/evidence/<session-id>.json
Override with:
akmon --task "..." --evidence-path /tmp/run-evidence.json
Slash Commands
Documented for Akmon 2.2.0.
In akmon chat, type / then command name. Use /help in-session as runtime source of truth.
Session & navigation
| Command | Description |
|---|---|
/help | Show command list |
/exit (/quit, /q) | Save and exit |
/clear | Clear UI + chat context (--hard also clears spec markdown cache) |
/reset | Start a new session (saves current first) |
/sessions | Session picker |
/resume <id-prefix> | Resume by session ID prefix |
Project memory
| Command | Description |
|---|---|
/init | Generate or refresh AKMON.md |
/import | Import external tool context |
/export | Export AKMON.md to another format |
/update-context | Open AKMON.md in $EDITOR and reload |
/new <name> | Scaffold a new project in current directory |
Models
| Command | Description |
|---|---|
/model | Show/set model for next turns |
/models | Alias for /model |
/architect | Next message uses planner then main model |
Planning & specs
| Command | Description |
|---|---|
/plan | Next message runs in read-only plan mode |
/implement | Run the last captured plan |
/edit-plan | Edit latest plan in $EDITOR |
/view-plan | View latest plan in overlay |
/spec | List feature specs under .akmon/specs |
Insight & diagnostics
| Command | Description |
|---|---|
/cost | Token/cost summary |
/audit | Session audit log view |
/context | Context-window usage breakdown |
/config | Settings UI for model estimates |
/index | Semantic index status |
/doctor | Provider key/status summary |
/mcp | MCP setup hints and configured servers |
/copy | Copy last assistant response |
/transcript (/export-chat) | Export chat to .akmon/transcript_export.md |
Verification
Run akmon chat, then /help, and verify command list contains the expected set for your build.
Configuration reference
Documented for Akmon 2.2.0.
Who this is for
Operators and maintainers who need the exact supported keys in ~/.akmon/config.toml.
What you will have at the end
- A code-accurate list of user config keys and sections.
- Confirmed policy/SLO sections used by current CLI commands.
Prerequisites
- Akmon installed and runnable.
Steps
- Resolve the active config file path.
akmon config path
- Inspect current config safely.
akmon config show
akmon config show --json
- Edit only supported keys listed below.
Top-level keys (AkmonGlobalConfig)
default_model = "llama3.2"
ollama_url = "http://localhost:11434"
# Provider credentials (prefer env vars in CI)
# anthropic_api_key = "sk-ant-..."
# openrouter_api_key = "sk-or-..."
# openai_api_key = "sk-..."
# groq_api_key = "gsk_..."
# azure_openai_endpoint = "https://.../chat/completions"
# azure_openai_api_key = "..."
# azure_api_version = "2024-02-01"
# openai_compatible_url = "http://127.0.0.1:1234/v1"
# openai_compatible_api_key = "..."
Core model keys
default_model = "llama3.2"
ollama_url = "http://localhost:11434"
Provider credentials can be set via env vars or config fields.
Architect defaults ([architect])
[architect]
planner_model = "llama3.2"
Display settings ([display])
[display]
theme = "auto" # auto | dark | light
MCP servers ([[mcp]])
[[mcp]]
name = "github"
url = "https://mcp.example.com"
enabled = true
scope = "user" # user | project
Policy governance ([policy])
[policy]
profile = "dev" # dev | staging | prod
packs = [".akmon/policy-packs/org.toml", ".akmon/policy-packs/team.toml"]
profile selects built-in defaults. packs adds extra policy layers.
Effective precedence:
- selected built-in profile,
- policy packs,
- project-local policy (
.akmon/policy.tomlor.akmon/policy.json), - CLI override (
--policy-override).
Within a layer, list fields append and deduplicate while keeping later precedence order.
Policy rule schema (PolicyConfig)
Policy packs/local/override files use the same rule schema:
[filesystem.read]
allow = ["src/**", "Cargo.toml", "README.md"]
deny = ["src/**/secrets/**"]
[filesystem.write]
allow = ["src/**", "tests/**"]
deny = [".git/**", "**/*.pem"]
[shell]
allow_prefixes = ["cargo ", "rustfmt "]
deny_prefixes = ["cargo publish", "rm -rf "]
[network]
allow_domains = ["api.github.com", "*.rust-lang.org"]
deny_domains = ["169.254.169.254", "*.internal.local"]
[tools]
allow = ["read_*", "search", "shell"]
deny = ["shell_force", "write_secret"]
[mcp.servers]
allow = ["github-prod", "jira-main"]
deny = ["*"]
[mcp.tools]
allow = ["search_*"]
deny = ["delete_*", "admin_*"]
Engine behavior is deterministic:
- explicit deny beats allow,
- most specific rule wins in a rule list,
- no matching allow means deny.
For MCP actions, fail-closed behavior also applies:
- malformed/missing MCP context denies,
- ambiguous MCP context denies,
- parent policy modes without configured MCP rules deny.
Reliability defaults ([slo] and [slo.trend])
[slo]
min_tool_success_rate = 0.95
max_timeout_rate = 0.02
max_tool_failure_rate = 0.05
max_retries_total = 3
max_timeouts_total = 2
min_tool_calls_total = 5
[slo.trend]
max_success_rate_drop_abs = 0.05
max_timeout_rate_increase_abs = 0.02
max_failure_rate_increase_abs = 0.03
max_retries_increase_ratio = 1.0
max_latency_avg_increase_ratio = 0.50
min_baseline_samples = 5
max_policy_denial_rate is supported by akmon slo verify CLI thresholds, but is not part of [slo] defaults in AkmonGlobalConfig.
Model estimates ([[model_estimates]])
[[model_estimates]]
pattern = "haiku-4-5"
context_window_tokens = 200000
input_per_million_usd = 1.0
output_per_million_usd = 5.0
cache_read_per_million_usd = 0.1
note = "Pricing/context hint for local estimation."
Verification
akmon config show --json
akmon policy show-effective --profile dev
akmon slo verify .akmon/evidence/<session-id>.json --strict
Expected result: config parses, policy can render effective configuration, and SLO settings are consumed.
Troubleshooting
- If
akmon config showfails, validate TOML syntax and remove unknown keys. - If policy packs fail to load, check file paths and TOML/JSON parse errors from
akmon policy show-effective. - If SLO commands fail on thresholds, check whether you are using CLI overrides vs
[slo]defaults.
Tools reference
Akmon’s agent invokes tools the model chooses from a fixed registry. Availability depends on mode (for example plan mode registers read-only tools) and CLI flags (--web-fetch, --index, --shell-allow, …).
Categories
Read & navigate
- read_file: read a file inside the sandbox.
- list_directory: list directory entries.
- search: ripgrep-style content search.
Edit
- write_file: create/overwrite (with confirmation and diff preview).
- edit / patch-style tools: apply targeted edits (with confirmation where configured).
Dry-run diff preview (file_change_set)
File-modifying tools support a deterministic diff payload that can be inspected before writes:
patchandapply_patchsupportdry_run: true.write_fileandeditalso supportdry_run: truefor preview-first workflows.- When
dry_runistrue, tools still run full validation and diff generation, but skip disk mutation.
file_change_set success payload shape:
type: alwaysfile_change_setmode:appliedordry_runchanges[]: canonical per-file diff entries (path,diff,lines_added,lines_removed,lines_changed)summary: aggregate line/file countsrisk: heuristic risk classification (low,medium,high)files[]: backward-compatible alias ofchanges[]
Practical flow:
- Run
patch(orapply_patch) withdry_run: true. - Parse
summary+riskand inspect eachchanges[i].diff. - Re-run the same call without
dry_runto persist changes (mode: "applied").
Git
- git: status, diff, log, add, commit, etc. (see Git integration).
Network
- web_fetch: HTTPS fetch with SSRF protections (optional via flag).
Semantic
- semantic_search: embedding search when
--indexand full build (see Semantic search).
MCP
Dynamic tools from configured MCP servers (MCP).
Permissions
The security model and policy engine decide auto-approval vs confirmation. Writes and dangerous operations require explicit approval unless your mode says otherwise.
Scout workflow (read-only)
akmon scout is a bounded read-only analysis workflow that generates a context_scout.v1 dossier under .akmon/context/.
- Uses read signals only (filesystem listing/reading/search-like path analysis).
- Does not invoke write/edit/patch/apply_patch/shell side effects.
- Emits deterministic sorted sections (
scanned_paths,key_entrypoints,candidate_files,related_tests) and explicit truncation indicators when bounds are hit.
Schema
Each tool exposes a JSON Schema for arguments; the model must call with valid JSON. Errors and outputs are fed back to the model and logged to the audit log.
Environment Variables
Documented for Akmon 2.2.0.
Who this is for
Users configuring Akmon via environment (shell, CI, secret managers) instead of storing credentials in ~/.akmon/config.toml.
What you will have at the end
- A verified list of environment variables recognized by the current CLI/provider resolver.
- A clear provider-resolution order for debugging.
Prerequisites
- Akmon installed and runnable (
akmon --help).
Steps
- Export provider variables needed for your route.
Provider keys
ANTHROPIC_API_KEY
OPENROUTER_API_KEY
OPENAI_API_KEY
GROQ_API_KEY
AZURE_OPENAI_ENDPOINT
AZURE_OPENAI_API_KEY
AWS_ACCESS_KEY_ID # Bedrock
AWS_SECRET_ACCESS_KEY
AWS_SESSION_TOKEN # optional
AWS_DEFAULT_REGION
- Use CLI help to verify current env-backed flags.
akmon --help
akmon config --help
akmon doctor providers --help
- Inspect effective routing decision:
akmon config explain-provider
Detection order (matches LlmConnectConfig::resolve)
Akmon evaluates providers in a fixed priority order (first successful branch wins). This is introspection-only documentation. The runtime resolver is unchanged when you run explain commands.
- Amazon Bedrock if
--bedrockis set orAWS_ACCESS_KEY_IDis present (requires loadable AWS credentials includingAWS_SECRET_ACCESS_KEY). - Native Claude (
claude-*without/) viaANTHROPIC_API_KEYor, if absent, OpenRouter with ananthropic/<model>slug whenOPENROUTER_API_KEYis set. - OpenRouter for
org/modelids containing/(requiresOPENROUTER_API_KEY). - Azure OpenAI when both
AZURE_OPENAI_ENDPOINTandAZURE_OPENAI_API_KEYare set (plusapi-version). - OpenAI when
OPENAI_API_KEYis set and the model id matches OpenAI chat heuristics (gpt-*,o1*, …). - Groq when
GROQ_API_KEYis set and the model id matches Groq heuristics (llama*,mixtral*). - Custom OpenAI-compatible URL when
--openai-compatible-url(or config) is set, which requires a key for that branch. - Ollama heuristics for local-style model ids, else Ollama default fallback.
Use akmon config explain-provider to print the same order with per-branch reasons for your current model and env. Use akmon config show (masked) to inspect stored config.
Additional runtime variables used by Akmon
EDITOR # used by `akmon config edit` and TUI edit flows
AKMON_DEBUG_GIT # enables git root discovery debug logging
Wizard vs env vs config.toml
akmon config(no subcommand) interactively writes~/.akmon/config.toml.- The same settings usually have environment variable equivalents listed in the sections above (handy for CI, containers, or secret managers).
- Advanced fields (Architect defaults,
[display], MCP entries) are often easiest to edit in TOML or viaakmon config mcp …; see Configuration andakmon config --help.
Verification
akmon config show --json
akmon config explain-provider
Expected result: provider prerequisites are reported without printing raw secrets.
Troubleshooting
- If Bedrock is unexpectedly selected, check whether
AWS_ACCESS_KEY_IDis set. - If slash model IDs fail, ensure
OPENROUTER_API_KEYis available. - If Azure is partially configured, set both
AZURE_OPENAI_ENDPOINTandAZURE_OPENAI_API_KEY.
Release notes: v2.2.1
Why this release
v2.2.1 is a reliability and security hardening release for the trust core introduced in v2.2.0. It closes a decompression-bomb vector on bundle reads, caps several unbounded stream-reassembly buffers, fixes a crash on non-ASCII provider error text, makes the git tool's subprocess handling actually timeout-safe, unifies akmon bundle verify and agef-verify onto one shared pass/fail implementation so the two verifiers cannot silently diverge, and resolves three supply-chain advisories. No new features, no format changes, no breaking changes.
Top fixes
- Decompression-bomb guard on bundle reads. A malicious or oversized
.akmonarchive could previously expand without bound duringread_bundle, exhausting memory on the machine verifying it. Reading now caps total decompressed bytes and fails closed with a newBundleError::BundleTooLarge. - Unbounded provider stream buffers capped. The Anthropic, OpenAI-compatible, and Ollama streaming readers, and the Bedrock event-stream frame reader, now cap how much they buffer while waiting for a delimiter, instead of growing without bound against a broken or hostile endpoint.
- Crash on non-ASCII provider error text fixed. Error-body truncation panicked when a byte offset landed inside a multi-byte UTF-8 codepoint; truncation is now always character-boundary-safe.
- Git tool subprocess reliability. Git subcommands now share a single async, timeout-guarded runner that actually kills the child process on timeout, instead of leaking a process and a runtime thread.
akmon bundle verifyandagef-verifyunified. Both binaries now call one shared implementation of the report shape and pass/fail policy, eliminating duplicated trust-decision logic that could previously drift between them. Output is unchanged.- Supply-chain advisories resolved. Updated
bitstream-io,anyhow, andcrossbeam-epochto clear a yanked transitive dependency and two RUSTSEC advisories. No manifest changes.
See CHANGELOG.md for the complete list.
Upgrade notes
- Safe upgrade from v2.2.0. AGEF stays at v0.1.3; no bundle format, journal format, or CLI flag changes.
- All fixes are additive hardening; existing journals and bundles remain readable and byte-identical on write.
Verification checklist
akmon --version # should report 2.2.1
agef-verify --version # should report 2.2.1
sha256sum --check SHA256SUMS
Docs links
- Release notes: v2.2.0 (the trust-layer release this hardens)
- Changelog
Release notes: v2.2.0
Why this release
v2.2.0 is the trust-layer release. It cements Akmon as the producer-agnostic, tamper-evident
evidence and verification layer that sits on top of whatever agent
you already run, and makes that claim provable: a third party can verify an Akmon bundle's
signature, and now its operator attestation, offline with nothing but openssl, no Akmon
binary, no cloud. Everything is additive; existing journals and bundles remain readable.
Top user-facing wins
- Import any agent (OpenTelemetry GenAI):
akmon otel import <trace.json>turns an OTLP/JSON trace into a verifiable AGEF session, including the legacy v1.36-and-earlier message-event form that most deployed instrumentations still emit by default, not only the v1.37 structured attributes. Capture fidelity is honest: imports arecapture_level=structural(metadata only), never silently presented as a full recording. - Generate a signing key:
akmon bundle keygenproduces a usable Ed25519 key (PKCS#8 v2) with a0600private-key file. (openssl genpkeyemits PKCS#8 v1, which is rejected.) - Verify offline with stock
openssl(metric F.1):akmon bundle prove-opensslemitsstatement.bin/signature.bin/pubkey.pemso anyone can check a signature with no Akmon and no cloud. - Operator-identity binding (AGEF v0.1.3):
akmon bundle attestrecords a separately-signedAGEF-OPERATOR-v1claim binding an accountable operator/human to a session, addressing the EU AI Act Art. 14 / Art. 12(3) "which operator" requirement without PKI, DID, or cloud.akmon bundle verifyandagef-verifygain--operator-key/--require-operator;prove-openssl --operator-keymakes the operator claim openssl-verifiable too. Verification attaches trust to the key, never to the self-asserted identity string. - Standalone
agef-verifyis now shipped in the release alongsideakmon, with SHA-256 checksums and an SBOM, so auditors can verify on an air-gapped machine.
Upgrade notes
- Safe, additive upgrade from v2.1.0. AGEF bumps from 0.1.1 to 0.1.3, but the bumps are minor/additive:
0.1.1/0.1.2readers still read0.1.3bundles and ignore the optionalsignatures[]/operator_attestations[]fields. Unsigned/unattributed bundles serialize byte-identically. - The
AGEF-SIG-v1head signature and theprove-opensslbyte output are unchanged by the operator layer: adding an operator attestation never invalidates an existing head signature. - The canonical AGEF specification (
radotsvetkov/agef) is being updated to v0.1.3 in lockstep.
Verifying your download
Each release publishes SHA256SUMS. After downloading, check it:
sha256sum --check SHA256SUMS
Release notes: v2.1.0
Why this release
v2.1.0 hardens the v2.0.0 session loop for real daily use: resume works against the journal, tool dispatch is schema-validated, config.toml fields actually apply, and several deterministic crash paths are closed. AGEF v0.1.1 and the evidence substrate are unchanged.
Top user-facing wins
- Session resume:
-c,--continue-last, and TUI/resumereopen the journal graph instead of failing withsession already exists. - Repeat-limit crash fix: hitting the
read_file/list_directoryexploration cap no longer exits withInvalidTransition(#1). - Tool argument validation: LLM tool calls are checked against each tool's JSON Schema before dispatch (including MCP proxies).
- Config.toml wiring:
default_model,ollama_url, enabled[[mcp]]servers, andfirst_token_deadline_msare honored; invalid config files warn instead of silently resetting. - Scout + diff dry-run:
akmon scoutproduces bounded planning dossiers; file tools supportdry_runwith stabilizedfile_change_setpayloads.
Upgrade notes
- Safe upgrade from v2.0.0. Existing journals and AGEF bundles remain readable.
- CLI flags still override
~/.akmon/config.tomlwhen set to non-default values (e.g. explicit--model,--ollama-url). - Tool output parsers should prefer
changes[]over legacyfiles[]in file-modifying tool results (files[]remains as alias).
Verification checklist
akmon --version # should report 2.1.0
# Resume should not fail on second run with same session id
akmon --yes --task "hello" --output json
akmon -c --yes --task "continue from before" --output json
# Config warning (optional smoke test with intentional typo in config.toml)
akmon doctor
Docs links
- Configuration reference
- Release notes: v2.0.0 (baseline evidence model)
- Changelog
Release notes: v2.0.0
Why this release
Akmon v2.0.0 is the production-ready release that turns each agent session into evidence for regulated engineering. Every session is now a tamper-evident, content-addressed, replayable artifact suitable for audit, compliance evidence, and post-incident review.
Top user-facing wins
akmon diff: structural and field-level comparison between two recorded sessions, with optional--resolvefor byte-level content diffs.akmon replay: deterministic re-execution of recorded sessions against playback providers and tools, with strict and default comparison modes.akmon bundle: portable AGEF v0.1.1 session archives for evidence sharing across environments.akmon redact: compliance-driven content removal producing derivative bundles with sentinel objects.- AGEF v0.1.1: Akmon is the reference implementation. Bundle format and session evidence structure are now spec-stable for downstream tooling.
Upgrade notes
v2.0.0 reads sessions written by v1.8.x. Sessions written by v2.0.0 may use the AGEF v0.1.1 schema and should not be downgraded to v1.8.x without verification.
No CLI flag breaks; existing scripts targeting akmon run, akmon audit, akmon evidence, akmon slo, and akmon doctor continue to work unchanged.
Verification checklist
# Confirm install
akmon --version # should report 2.0.0
# Verify a clean session round-trip
akmon --yes --task "echo hello" --output json | tee run.json
akmon audit verify .akmon/audit/<session-id>.jsonl
akmon evidence verify .akmon/evidence/<session-id>.json
# Try the new diff command
akmon diff <session-a> <session-b>
Docs links
Release notes: v1.8.2
Why this release
v1.8.2 is an operability and trust release: provider routing is fully explainable and diagnosable without changing resolver behavior. Introspection mirrors LlmConnectConfig::resolve() deterministically; no routing algorithm changes.
Top user-facing wins
- Deterministic
ProviderResolutionTrace: structured trace (selected_provider,selected_reason,model_id, orderedcandidates[]witheligible,reason,missing_prerequisites,priority_order) matching the real resolver priority. Secrets are never echoed; only named prerequisites. akmon config explain-provider: print the trace in the terminal or as JSON (--jsononconfig, or global--output json).akmon doctor providers: includes the sameprovider_resolutionblock in text and JSON alongside existing health checks.- Headless
--output json: run summary JSON includes additiveprovider_resolutionfor automation (same schema as above).
Upgrade notes
- No routing or CLI semantics changes for provider selection; this release adds diagnostics only.
- Pair
config explain-provider(why this branch won) withdoctor providers(keys, endpoints, reachability).
Verification checklist
akmon config explain-provider
akmon config explain-provider --json
akmon doctor providers
akmon --output json doctor providers
# After a headless run with --output json, inspect provider_resolution on stdout
Docs links
Release notes: v1.8.1
Why this release
v1.8.1 is a stability and operability hardening release focused on trustworthy day-2 operation: deterministic provider diagnostics, fail-closed MCP governance, docs reliability gates, internal TUI maintainability, and stronger local-model reliability behavior.
Top user-facing wins
- Provider preflight command:
akmon doctor providerswith actionable remediation and CI-friendly exit codes. - MCP governance hardening with explicit server/tool policy dimensions and enriched audit context.
- Deterministic docs quality checks in CI (mdBook, links, CLI snippets, JSON snippets, fixtures).
- Local-model reliability improvements for Ollama (adaptive timeouts, unified status hints, clearer remediation).
- TUI internal state decomposition that improves maintainability without UX/command changes.
Upgrade notes
- No CLI breaking changes in this release.
- For configured policy + MCP environments, define explicit
[mcp.servers]and[mcp.tools]allow rules. - For local-model-heavy workflows, warm models (
ollama run <model>) before long tasks and use/clearwhen context becomes noisy.
Verification checklist
akmon doctor providers
akmon --output json doctor providers
akmon audit verify .akmon/audit/<session-id>.jsonl
akmon evidence verify .akmon/evidence/<session-id>.json
akmon slo verify .akmon/evidence/<session-id>.json --strict
Docs links
Release notes: v1.8.0
Why this release
v1.8.0 makes Akmon a practical trust runtime for AI-assisted engineering by combining policy governance, tamper-evident auditing, replay/evidence artifacts, and enforceable reliability gates into one operator workflow.
Top user-facing wins
- Deterministic policy controls with reusable profiles/packs (
dev,staging,prod). - Verifiable execution trail (
akmon audit verify,akmon evidence verify). - Replay metadata for forensic reproducibility in structured output.
- Reliability metrics exposed in run reports and evidence artifacts.
- CI-ready guardrails (
akmon slo verifyandakmon slo trend).
Migration checklist
- Update audit parsers to
AuditChainRecord(schema_version: "audit_chain.v1"). - Update run report parsers to accept additive
replay_metadataandreliability_metrics. - Validate evidence using
evidence_schema_version. - Adopt policy precedence model:
profile < packs < local < CLI override.
Verification checklist
akmon --yes --output json --task "run tests and summarize failures" | tee run.json
akmon audit verify .akmon/audit/<session-id>.jsonl
akmon evidence verify .akmon/evidence/<session-id>.json
akmon slo verify .akmon/evidence/<session-id>.json --strict
akmon slo trend .akmon/evidence/<session-id>.json --baseline-dir .akmon/evidence/history --window 20 --strict
Tutorials
Development Setup
Prerequisites
- Rust matching
rust-versionin the repoCargo.toml - Git
Clone
git clone https://github.com/radotsvetkov/akmon
cd akmon
Build
# Slim / faster, no default feature bundles
cargo build --release --no-default-features
# Full: semantic indexing and related deps
cargo build --release
Test & lint (maintainer expectations)
RUSTFLAGS='-D warnings' cargo test --workspace
cargo clippy --workspace -- -D warnings
Crate map
| Crate | Role |
|---|---|
akmon-cli | Binary entry |
akmon-core | Sandbox, policy, FSM, audit |
akmon-config | Configuration |
akmon-models | LLM backends |
akmon-tools | Built-in tools |
akmon-query | Agent session / context |
akmon-index | Semantic index |
akmon-tui | Ratatui front-end |
Dogfood
cargo build --release
./target/release/akmon chat
Pull requests
- Clear description + tests where feasible
- No unwrap in library crates
rustdocon new public APIs
Akmon is distributed under the Apache License 2.0 (see repository LICENSE).
Architecture guide for contributors
This document explains how Akmon is organized internally and how the core agent loop works.
Crate structure
akmon/
├── crates/
│ ├── akmon-cli/ # binary entry point, args, command routing
│ ├── akmon-core/ # policies, sandbox, shared types, security primitives
│ ├── akmon-config/ # config loading and provider resolution inputs
│ ├── akmon-models/ # provider adapters and stream normalization
│ ├── akmon-tools/ # tool implementations
│ ├── akmon-query/ # agent loop, context assembly, session lifecycle
│ ├── akmon-tui/ # ratatui UI and runtime bridge
│ └── akmon-index/ # optional semantic index
The agent loop (akmon-query/src/session.rs)
At a high level:
- build prompt/context bundle,
- call provider stream,
- process deltas and stop reason,
- execute tool calls when requested,
- append tool results to context,
- continue loop until model ends with no pending tools.
Stop-reason behavior:
ToolUse: execute tools, continue loop,EndTurn+ tool calls: execute then continue,EndTurnwith no tool calls: complete run,MaxTokens: perform continuation strategy where applicable.
This loop is why Akmon behaves like an autonomous worker, not a one-response chatbot.
Context assembly order
Effective ordering in practice:
- project/system steering (
AKMON.mdand base system instructions), - optional specs/handoff context,
- language/profile hints,
- conversation history,
- dynamic extras (todos/memory blocks).
The order prioritizes stable steering first, then volatile task state later.
Provider abstraction
akmon-models normalizes provider-specific behavior into common stream events and model errors so akmon-query can remain provider-agnostic.
Responsibilities include:
- mapping provider payloads to
StreamEvent, - retry handling where provider-specific (for example rate limits),
- first-token/stream timeout behavior,
- provider display and model-specific heuristics.
TUI state decomposition (akmon-tui)
TuiApp remains the composition root, but state is now split into focused internal modules under crates/akmon-tui/src/state/:
composer: input buffer + cursor behavior (insert/paste/backspace/delete/left/right/submit),overlay_state: overlay/modal state, confirmation gate state, ask-followup state, slash autocomplete selection/suppression,session_telemetry: token/tool counters, touched files, and context-warning bookkeeping,provider_runtime: provider/runtime status such as provider label, run flags, iteration progress, stream cursor, and ollama probe.
Why this helps:
- lower regression risk by reducing mixed responsibilities in
app.rs, - easier targeted tests for state transitions,
- clearer ownership when adding new TUI logic without changing UX behavior.
This refactor is intentionally internal: behavior and command semantics stay the same while maintainability/testability improve.
Contributor guideline for TUI changes:
- put new input-edit semantics in
state/composer.rs, - put overlay transition rules in
state/overlay_state.rs, - put counters/usage accumulation in
state/session_telemetry.rs, - put runtime/provider status updates in
state/provider_runtime.rs, - keep
TuiAppfocused on orchestration and event routing.
Permission system path
Before tool execution:
- derive concrete permission requirement from tool + args,
- evaluate policy mode (deny/auto/interative),
- request user confirmation if needed,
- execute tool only after allow.
This is enforced centrally in session execution flow, not left to individual tools.
Adding a tool
- implement
Tooltrait inakmon-tools, - define permission requirements and argument schema,
- register in tool registry,
- add unit tests and integration path checks,
- document in
docs/src/reference/tools.md.
Common mistakes and troubleshooting
- Mistake: adding side effects in a read-oriented tool.
- Mistake: bypassing policy path for convenience.
- Mistake: returning unstructured errors that break UX/reporting.
- Fix: keep tool outputs structured and route all side effects through permission-checked paths.
Adding a provider
Providers live in akmon-models. Each backend implements the LlmProvider trait (streaming completions, auth, and provider-specific request shaping).
Steps (overview)
- Backend module: add a submodule under
crates/akmon-models/src/for the API (HTTP, signing, streaming parse). - Implement
LlmProvider: map Akmon’s generic message/tool format to the vendor API; handle token usage and errors. - Wire config: extend
akmon-config/ CLI parsing for keys, base URLs, and model id conventions. - Detection: update provider auto-detection order (env vars, flags) in CLI/config.
- Tests: unit-test request JSON and response parsing with fixtures; avoid live API calls in CI.
Conventions
- No
.unwrap()in library code; use typed errors (thiserror). - Never log secrets; use existing
Secrettypes fromakmon-corewhere applicable. - Document new flags and env vars in user docs (
docs/src/providers/, CLI).
See also
- Architecture: crate graph and
LlmProvider. - Development setup: build and test commands.
Changelog
User-facing changes are tracked in the repository’s CHANGELOG.md at the root of the Akmon project.
- Format: Keep a Changelog
- Versions: Semantic Versioning
View online
Open the file on GitHub:
https://github.com/radotsvetkov/akmon/blob/main/CHANGELOG.md
Releases
Tagged releases and binaries are published from the same repo:
https://github.com/radotsvetkov/akmon/releases
When contributing, add a short note under the appropriate ## [x.y.z] section in CHANGELOG.md with your PR.
Security policy
The same reporting rules and scope are maintained in the repository root as SECURITY.md for GitHub's security features.
Akmon is an evidence and verification layer. The properties that matter most to its users are integrity, authorship, and offline verifiability of AGEF records. A flaw that lets a tampered record verify as valid, or that lets a signature or operator attestation be forged or bypassed, is the most serious class of issue this project can have. Reports in that area are prioritized accordingly.
Reporting vulnerabilities
Do not open public issues for undisclosed security problems.
Contact the maintainer privately (see the GitHub profile and the repository security instructions). Include:
- a description and the impact,
- reproduction steps,
- affected versions or commits if known,
- optional patch ideas.
Target initial response: 48 hours, best effort.
Scope
In scope:
- Verification-layer integrity. Any way to make
akmon bundle verify,agef-verify, or theopensslproof path accept a tampered AGEF bundle, a broken hash chain, or a forged or mismatched Ed25519 signature. - Operator-attestation trust. Any way to make a self-asserted operator identity read as key-verified without a matching trusted key, or to attach a valid attestation to a session it did not authorize.
- Capture-honesty bypass. Any way to make a
structuralimport pass--require-capture full, or to make a non-replayable session report as replayable. - Sandbox bypass or path traversal outside the repository root in the reference agent.
- SSRF bypasses in
web_fetch. - Secret leakage through logs, errors, or persistence.
- Permission or policy bypass leading to silent destructive actions in the reference agent.
Out of scope:
- Physical access scenarios.
- Social engineering.
- Trusting an attacker-supplied public key. Key trust is established out of band by the verifier; a verifier who chooses to trust a malicious key is outside the model.
- Issues solely inside third-party dependencies (report those upstream).
Design reference
Read the Security model for how Akmon's verification layer and reference agent are intended to behave, including what trust attaches to keys rather than to self-asserted strings.
License
Akmon is licensed under the Apache License, Version 2.0.
The full text is in the repository root as LICENSE.
Why Apache 2.0 for an AI agent tool?
Apache 2.0 is widely used for infrastructure and developer tooling. For projects like Akmon, which bundles local-first coding agents, automation glue, and integrations with other tools, it offers:
- Clear redistribution terms when you ship Akmon inside containers, internal CLIs, or custom distributions.
- Explicit patent grant language, which matters when you combine agent runtimes with proprietary stacks or enterprise policies.
- Compatibility with many corporate open-source approval processes compared to more ambiguous or custom terms.
If you embed Akmon or ship derivative work, keep the LICENSE file and any required notices with your distribution, and follow the Apache 2.0 attribution requirements for modified files.