Every HMAC-SHA256 audit chain makes one promise: if a record is modified, the chain breaks. This is integrity. But if someone silently deletes a record instead of modifying it, the remaining chain looks intact. The gap is invisible. air-trust v0.5.0 adds session-scoped completeness detection so you get two guarantees: records were not changed, and records were not dropped.
air-trust v0.5.0 adds session_seq and prev_session_seq fields to every record. The verifier checks for gaps, duplicates, rewinds, and missing lifecycle boundaries.pip install air-trust==0.5.0. Fully backward compatible with v0.4.0 chains.Integrity proves records were not changed after being written. Completeness proves records were not dropped or silently deleted from a session. They are independent properties: a chain can have perfect integrity (no modified records) while being incomplete (missing records that were quietly removed). For EU AI Act Article 12 compliance, you need both.
Imagine an AI agent that makes six tool calls in a session. Your audit chain records all six. Each record is HMAC-signed and chained to the previous one. If an auditor asks "was this log tampered with?", you can answer confidently: no, the chain is intact. But what if one of those calls - the one that accessed a customer database - was quietly removed before the auditor arrived? The remaining five records still verify. The chain is intact. The log is incomplete.
For Article 12, this matters. The regulation requires that high-risk AI systems maintain logs that "enable the monitoring of the operation." Monitoring means seeing everything. If an operator can delete inconvenient records without detection, the logging requirement is satisfied in letter but not in spirit.
The core distinction: Integrity answers "were these records changed?" Completeness answers "are any records missing?" HMAC-SHA256 gives you the first. Monotonic sequence numbers give you the second.
Every record in a session gets two new fields: a session_seq (monotonic counter starting at 0, incrementing by 1 for each record) and a prev_session_seq (pointing to the previous record's sequence number, or -1 for the first record). Both fields are included in the HMAC payload, so they are tamper-evident. If someone changes a sequence number, the chain hash breaks. If someone deletes a record, the gap between consecutive sequence numbers becomes visible.
| Field | Type | Meaning |
|---|---|---|
session_seq | integer | Monotonic counter starting at 0. Increments by 1 for each record in the session. |
prev_session_seq | integer | The session_seq of the previous record. -1 for the first record. |
A session also gets three lifecycle record types:
session_start - Must be the first record in the session. Establishes the session boundary.checkpoint - Optional waypoints during the session. Useful for long-running agent loops.session_end - Should be the last record. A missing session_end means the session crashed or was interrupted - the verifier flags it.The verifier performs two independent passes over the audit chain. Pass 1 checks integrity (unchanged from v0.1.0): replay the chain from genesis and recompute every HMAC hash. Pass 2 checks completeness (new in v0.5.0): group records by session_id, verify that sequence numbers increase by exactly 1, confirm lifecycle boundaries, and flag gaps, duplicates, or rewinds.
The output is structured JSON with clear separation between integrity and completeness results:
{
"integrity": {
"valid": true,
"records": 47,
"broken_at": null
},
"completeness": {
"sessions_checked": 3,
"sessions_complete": 2,
"sessions_incomplete": 1,
"issues": [
{
"session_id": "d4e5f6...",
"issue": "gap",
"expected_seq": 5,
"actual_seq": 7,
"record_index": 23
}
]
}
}
The severity levels distinguish between tamper evidence and suspicious anomalies:
| Issue | Severity | What it means |
|---|---|---|
| Chain hash mismatch | FAIL | A record was modified. Trust is broken. |
| Sequence gap | WARN | A record appears to be missing from the session. |
| Duplicate sequence | WARN | Two records claim the same position. Possible replay. |
| Sequence rewind | WARN | The counter went backward. Possible replay or corruption. |
| Missing session_start | WARN | First record is not a lifecycle boundary. Possible truncation. |
| Missing session_end | INFO | Session may have crashed or is still running. |
Install or upgrade to air-trust v0.5.0 with pip install air-trust==0.5.0. If you already use air_trust.session(), you get completeness for free. Every event written inside the session block automatically gets a session_id and sequence numbers - including adapter events from wrapped LLM clients.
import air_trust
# Adapter events inherit the session_id automatically
with air_trust.session("my-pipeline") as s:
client = s.trust(OpenAI())
# This LLM call gets session_seq=1, prev_session_seq=0
result = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "Hello"}]
)
s.log("Result validated") # session_seq=2
Verify from Python:
result = air_trust.verify()
print(result["integrity"]["valid"]) # True
print(result["completeness"]["issues"]) # []
Or from the CLI:
# Human-readable output with PASS / WARN / FAIL tiers
python3 -m air_trust verify
# JSON output for CI/CD pipelines
python3 -m air_trust verify --json
Session completeness is a session-scoped guarantee, not a universal one. The SPEC.md v1.1 includes a threat model with four explicit scope limits. Being transparent about what a security primitive does not cover is as important as explaining what it does.
chain.write() for a particular action, there is no record to be missing. Completeness proves the chain is gap-free, not that the chain captured everything important.session_start emitted), there is nothing to check. Completeness only applies to sessions that exist in the chain.For sessions that were started and recorded, air-trust v0.5.0 can detect if records were dropped, duplicated, reordered, or if the session ended abnormally. It cannot prove that all sessions that should have existed do exist, or that all important actions were submitted to the chain.
This is meaningful for Article 12 because it proves the logging system itself is functioning correctly for the sessions it monitors. Combined with integrity checking, it gives auditors the strongest evidence available that the audit trail is reliable.
Yes. The v1.1 spec is additive-only. Records from v0.4.0 or earlier without session_seq fields still verify for integrity. The completeness verifier only checks records that carry v1.1 fields. Mixed chains with both v1.0 and v1.1 records work fine. No existing field meanings change, and the verify() output keeps the top-level valid, records, and broken_at keys for backward compatibility alongside the new integrity and completeness sections.
Session completeness closes the single-agent gap. The next frontier is cross-agent attestation: when Agent A calls Agent B, can both sides prove the handoff happened? That requires bilateral signatures (Ed25519, not HMAC), a signed envelope protocol, and a way to correlate audit records across system boundaries. air-trust v0.6.0 adds signed handoffs as the first step toward this goal.
If cross-agent attestation or co-attestation is something you need, open a discussion on GitHub - that signal influences the roadmap.
Integrity proves records were not changed after being written, using HMAC-SHA256 chaining. Completeness proves records were not dropped or silently deleted, using monotonic sequence numbers where gaps indicate missing records. You need both to trust an audit trail for EU AI Act compliance.
Every record within a session gets a monotonically increasing session_seq number starting at 0 and a prev_session_seq pointing to the previous record. The verifier checks that sequences increase by exactly 1 with no gaps, duplicates, or rewinds. A missing number means a record was dropped.
No. Session completeness proves the chain is gap-free within recorded sessions. It cannot prove that all important events were submitted to the chain in the first place, or that sessions which should have started actually did. It is a session-scoped guarantee, not a universal one.
Article 12 requires that high-risk AI systems have logging designed to enable monitoring of operation. Integrity alone tells an auditor that logs were not tampered with. Completeness tells the auditor that logs were not selectively deleted. Together, they provide the strongest evidence that the logging system is functioning correctly.
Yes. The v1.1 spec is additive-only. Records from v0.4.0 or earlier without session_seq fields still verify for integrity. The completeness verifier only checks records that carry v1.1 fields. Mixed chains with both v1.0 and v1.1 records are explicitly supported.
Add gap detection to your AI agent audit chain. Prove records were not dropped.
pip install air-trust==0.5.0
GitHub · PyPI · SPEC.md v1.1 · Changelog
Last updated: April 17, 2026. This article is reviewed and updated to reflect the latest air-trust releases and specification changes.