Validation Receipt Schema¶
Status: Active
Last reviewed: 2026-02-11
Schema version: govzero.ledger.v1
Parent ADR: ADR-0.0.24 (Validation Receipt Temporal Anchoring)
Overview¶
Validation receipts anchor ADR/OBPI validation events to specific git commits, enabling "valid as of" semantics. When an ADR is validated, a receipt records the exact commit SHA, so later drift detection can determine whether code has changed since the last audit.
Purpose¶
- Temporal anchoring: Every validation event is tied to a git commit
- Drift detection: Compare current HEAD against the last validation anchor to detect changes
- Audit trail: Machine-readable evidence of when and by whom validation occurred
- Separation of concerns: Validation receipts live in their own ledger, complementing the OBPI audit ledger
Relationship to OBPI Audit Ledger¶
| Aspect | OBPI Audit Ledger | Validation Receipt Ledger |
|---|---|---|
| File | obpi-audit.jsonl |
adr-validation.jsonl |
| Scope | Per-brief status audits | Per-ADR validation events |
| Purpose | Track OBPI status transitions | Anchor validation to git state |
| Schema | obpi-audit, covers-map, etc. |
validation |
Both ledgers share the govzero.ledger.v1 base schema (LedgerEntryBase) for consistency.
Entry Schema¶
validation¶
Records a validation event tied to a specific git commit.
{
"type": "validation",
"timestamp": "2026-02-10T14:30:00Z",
"schema_version": "govzero.ledger.v1",
"agent": "claude-code",
"session_id": "2026-02-10-adr-024-validation",
"adr_id": "ADR-0.0.24",
"event": "validated",
"anchor": {
"commit": "de80292",
"tag": "v0.0.24",
"semver": "0.0.24"
},
"evidence": {
"tests_passed": true,
"test_count": 15,
"coverage_percent": 48.5,
"gate2_pass": true
},
"attestor": "human:jeff"
}
Common Fields (inherited from LedgerEntryBase)¶
| Field | Type | Required | Description |
|---|---|---|---|
type |
"validation" |
Yes | Entry type discriminator |
timestamp |
string | Yes | ISO 8601 UTC timestamp (Z-suffixed) |
schema_version |
string | No | Schema version (default: govzero.ledger.v1) |
agent |
string | No | Agent that created the entry |
session_id |
string | No | Session identifier for grouping |
Validation-Specific Fields¶
| Field | Type | Required | Description |
|---|---|---|---|
adr_id |
string | Yes | ADR identifier (format: ADR-X.Y.Z) |
event |
string | Yes | One of: validated, completed, compliance_check |
anchor |
object | Yes | Temporal anchor (see below) |
evidence |
object | No | Evidence payload (test results, coverage, etc.) |
attestor |
string | Yes | Human attestor (must be human:<name>, e.g., human:jeff). Only humans can attest — agents record evidence via the agent field. |
For OBPI-scoped completion receipts (obpi_receipt_emitted with receipt_event=completed),
runtime evidence must include value narrative + key proof semantics, and
heavy-lane parents (any kind) or foundation-kind parents (any lane) require
explicit human-attestation evidence fields.
REQ-proof inputs follow the
OBPI Runtime Contract, including required
name/kind/source/status fields and optional scope / gap_reason.
Completed receipts also preserve the transaction snapshot needed for later
reconciliation:
scope_audit.allowlistscope_audit.changed_filesscope_audit.out_of_scope_filesgit_sync_state(branch, remote, dirty, ahead/behind, divergence, actions, warnings, blockers)recorder_sourcerecorder_warnings
If git anchoring degrades after completion is already allowed, gzkit records the
warning in recorder_warnings and keeps the completion decision intact rather
than retroactively rewriting the brief state.
Operationally, gzkit expects the final completed OBPI receipt to be emitted only
after the guarded uv run gz git-sync --apply --lint --test ritual has
succeeded. Later brief/ADR sync edits may still occur, but the completion
receipt itself should anchor the already-synced implementation state.
ValidationAnchor Fields¶
| Field | Type | Required | Description |
|---|---|---|---|
commit |
string | Yes | Git SHA, 7-40 lowercase hex characters |
tag |
string | No | Git tag if HEAD is tagged at validation time |
semver |
string | Yes | ADR semver version (e.g., 0.0.24) |
Event Types¶
| Event | When Used |
|---|---|
validated |
ADR passes Gate 5 audit and is marked Validated |
completed |
ADR passes Gates 1-4 and is marked Completed |
compliance_check |
Periodic or on-demand compliance verification |
Ledger File Location¶
Validation receipts are stored per-ADR alongside the existing OBPI audit ledger:
Example:
docs/design/adr/adr-0.0.x/ADR-0.0.24-validation-receipt-temporal-anchoring/logs/adr-validation.jsonl
Edge Case Behavior¶
| Scenario | Behavior |
|---|---|
| Ledger file does not exist | read_receipts() returns empty list |
| Ledger file is empty | read_receipts() returns empty list |
| Malformed JSONL line | Skipped with warnings.warn(); valid entries still returned |
| Duplicate receipts for same commit | All are preserved (idempotency is caller's responsibility) |
Python API¶
Creating and Writing Receipts¶
from pathlib import Path
from gzkit.ledger import Ledger, audit_receipt_emitted_event
ledger = Ledger(Path(".gzkit/ledger.jsonl"))
event = audit_receipt_emitted_event(
adr_id="ADR-0.3.0",
receipt_event="validated",
attestor="Jeffry Babb",
evidence={"scope": "ADR", "adr_completion": "completed"},
)
ledger.append(event)
Reading Receipts¶
from pathlib import Path
from gzkit.ledger import Ledger
ledger = Ledger(Path(".gzkit/ledger.jsonl"))
# Read all audit receipt events
all_receipts = ledger.query(event_type="audit_receipt_emitted")
# Filter by ADR
adr_receipts = ledger.query(event_type="audit_receipt_emitted", artifact_id="ADR-0.3.0")
See Also¶
- Ledger Schema — Base schema and OBPI audit entry types
- Layered Trust Architecture — Tool layer model
- ADR Lifecycle — Status transitions
- Python module:
src/gzkit/ledger.py