# Flight Recorder

*A per-run, hash-linked record that includes what the run read.*

> **A Flight Recorder** is an append-only, hash-linked record kept per run: what the run read (the read manifest), what it wrote, what was allowed or denied, and who approved what. It sits beside the data and answers one question: “what may have influenced this change?”

**AN-03** · Conformance level: L1 Authority · Cluster: Work

## The problem

In a post-mortem, logs are scattered; there is no link between a “read” and the action that followed; and logs can be edited by the same administrator, or even the same agent.

More fundamentally: when a merge or a memory is suspected of being contaminated, there is no way to answer “what did that run read?”.

## How it works

- **Two kinds of content.** *Events* are recorded one by one: commits, lease issuance and revocation, gate requests and decisions, policy denials, derivations, forgetting. The *read manifest* is aggregated per run: which paths@commit, which ranges and which content hashes were read. It does not record every read call, and it never records content.
- **Every commit carries provenance metadata:** `principal`, `on_behalf_of`, `run`, `lease`, `purpose` and a reference to the read manifest.
- **A hash chain** (per day), with optional signatures and external anchoring (a second node, a bucket with object lock). The goal is “**tampering can be detected**”, not “tampering is impossible”.
- **Export:** OpenTelemetry GenAI spans, JSON Lines, or into a SIEM.
- **Privacy:** metadata only by default, no content; retention of records is independent of deletion of content; the records themselves are access-controlled.
- **`explain(commit)`:** returns the run, lease, gate decisions, read manifest and inputs behind that commit.
- **Record first, then act:** a consequential operation must first write an intent record.

## Start small

- An append-only SQLite table plus a daily hash.
- Git trailers such as `Run:` and `Lease:` in every commit message.
- Export OpenTelemetry spans into the observability stack you already have.

## Interface sketch

Illustrative only. Field names may change before specification v0.3.

*record.json*

```json
{
  "seq": 18211,
  "time": "2026-11-12T09:14:22Z",
  "kind": "commit",
  "run": "run_91ab",
  "principal": "agt_cleo",
  "on_behalf_of": "usr_wei",
  "lease": "lse_7Qk3",
  "purpose": "Draft the Q4 release notes",
  "subject": { "path": "/shared/launch/notes.md", "commit": "91ce3a7" },
  "read_manifest": "rm_5d2e",
  "decision": { "effect": "allow", "rule": "r-17" },
  "taint": { "external": true, "sensitivity": "private" },
  "prev_hash": "sha256:b3a0..."
}
```

## What the specification asks for

- A consequential operation MUST write an intent record before taking effect; if the write fails, the operation MUST fail.
- Every run MUST have a read manifest recording the paths, commits and ranges read (not the content).
- Records MUST be hash-linked and MUST be verifiable with a published command.
- `explain(commit)` MUST return the run, the lease, the gate decisions and a reference to the read manifest.
- Retention of records MUST be independent of deletion of content.

## Borrowed, and what is new

What follows is all established parts. **What is new is the read manifest:** it turns “reading” into a traceable set of inputs, so that “a contaminated merge” and “poisoned memory” can be investigated after the fact.

- [OpenTelemetry GenAI conventions](https://opentelemetry.io/docs/specs/semconv/gen-ai/)
- [Certificate Transparency](https://certificate.transparency.dev)
- [Sigstore Rekor](https://docs.sigstore.dev/logging/overview/)
- [Git trailers](https://git-scm.com/docs/git-interpret-trailers)

## Honest limits

- Without external anchoring, an administrator with root can still destroy the log.
- The records themselves contain sensitive metadata and must be controlled.
- The granularity of the read manifest is a trade-off between storage cost and traceability.

## Open questions

- How is the storage cost of read manifests kept under control at high throughput?
- How are records from several nodes merged and verified?

## Questions

### Does it record the content the agent read?

Not by default. A record holds paths, commits, ranges and content hashes: enough to point back to the original data without copying sensitive content into a log. The content stays in the Store, protected by leases and labels.

### What does “tamper-evident” mean here?

We promise only that **tampering can be detected**: records are hash-linked, so changing one breaks chain verification; with external anchoring (a second node or a bucket with object lock) it also holds up against an administrator with root. Without anchoring, an administrator can still destroy the whole log.

### Why record reads?

Because risk often comes from reading: a session that read a web page may then write a contaminated note. The read manifest lets you answer afterwards “what influenced this change?”.

## Related concepts

- [Capability Lease](https://agentnas.com/concepts/capability-lease/): A narrow authorization for one run, with an expiry and budgets. Child leases can only be narrower.
- [Trust Labels](https://agentnas.com/concepts/trust-labels/): Two small labels plus session taint enforce the Rule of Two.
- [Cascade Forget](https://agentnas.com/concepts/cascade-forget/): Delete derivatives along lineage, handle history by retention class, and report what it could not do.

---

Canonical URL: https://agentnas.com/concepts/flight-recorder/
Updated: 2026-11-11 · Draft specification v0.2 · CC BY 4.0
