# OpenTrustGraph v0

> OpenTrustGraph is the open, vendor-neutral data format Harn uses to log agent autonomy decisions as an append-only, hash-chained event stream. This page is the mdbook view of...

Website: https://harnlang.com/spec/open-trust-graph/v0.html

This page documents Harn, which is pre-1.0. Language, standard library, and CLI APIs may change. If the intended version is unclear, clarify before using this page.

---

OpenTrustGraph is the open, vendor-neutral data format Harn uses to log
agent autonomy decisions as an append-only, hash-chained event stream.
This page is the mdbook view of the canonical artifact at
[`opentrustgraph-spec/`](https://github.com/burin-labs/harn/tree/main/opentrustgraph-spec)
in the Harn repo.

The full normative content lives in three places, each linked below:

- [`spec/opentrustgraph.md`](https://github.com/burin-labs/harn/blob/main/spec/opentrustgraph.md) — record
  model, chain export model, sample event stream.
- [`opentrustgraph-spec/CONFORMANCE.md`](https://github.com/burin-labs/harn/blob/main/opentrustgraph-spec/CONFORMANCE.md)
  — RFC 2119 conformance requirements for producers, consumers, and
  verifiers.
- [`opentrustgraph-spec/schemas/`](https://github.com/burin-labs/harn/tree/main/opentrustgraph-spec/schemas/)
  — JSON Schema (`*.schema.json`) and Protocol Buffers (`*.proto`)
  definitions.

## At a glance

- **Record schema:** `opentrustgraph/v0.1`. One record per autonomy or
  control-plane decision. Records carry `agent`, `action`, `approver`,
  `outcome`, `trace_id`, `autonomy_tier`, `timestamp`, `cost_usd`,
  `chain_index`, `previous_hash`, `entry_hash`, and an extensible
  `metadata` bag. `v0.1` reserves five lineage and alert keys —
  `effects_grant`, `effects_used`, `parent_record_id`, `actor_chain`,
  and `actor_chain_alert` — so chain validators can prove that a child
  agent's `effects_used` stayed inside the parent's `effects_grant` and
  that actor-chain parentage follows the same lineage. `opentrustgraph/v0`
  records still validate
  for one patch release window per
  [`opentrustgraph-spec/CONFORMANCE.md` §5](https://github.com/burin-labs/harn/blob/main/opentrustgraph-spec/CONFORMANCE.md#5-versioning).
- **Chain export:** `opentrustgraph-chain/v0`. Wraps an ordered record
  list with `chain.topic`, `chain.total`, `chain.root_hash`,
  `chain.verified`, `chain.generated_at`, and `chain.producer`.
- **Hash contract:** SHA-256 over a canonical JSON form of the record
  with `entry_hash` removed and object keys sorted lexicographically at
  every nesting level. Stored as `sha256:<hex>`.
- **Wire formats:** JSON is canonical; Protobuf is provided as a mirror
  for streaming runtimes.

## Why an open spec

Strategic positioning aside, the practical reasons:

1. **Receipts are portable.** A cloud receipt, an IDE-host supervision
   UI screenshot, and a third-party auditor's offline verifier all read
   the same JSON envelope.
2. **Multi-runtime adoption.** Other schedulers (Temporal histories,
   Inngest events, Kafka topics) can project the same record into their
   substrate without inventing a parallel audit shape.
3. **Spec, schema, fixtures, verifier in one tree.** The artifact under
   `opentrustgraph-spec/` is small enough to vendor today and direct-
   publish as `burin-labs/opentrustgraph-spec` later without changing
   the format.

## Producing a chain export

Inside Harn, emit the canonical envelope with:

```bash
harn trust export --output chain.json
harn trust export | python3 opentrustgraph-spec/examples/python/verify_chain.py
```

The export envelope has its `chain.verified` flag set from the
underlying chain verification result, so a downstream consumer can
short-circuit on a failed export instead of re-running verification.

## Consuming a chain export

External consumers (Python, Go, TypeScript, …) follow CONFORMANCE.md
§2:

1. Validate against the chain JSON Schema.
2. Validate every record against the record JSON Schema.
3. Recompute every `entry_hash` and compare to the stored value.
4. Compare each `previous_hash` to the prior `entry_hash`.
5. Compare `chain.total` and `chain.root_hash` to the record list.

The reference Python verifier at
[`opentrustgraph-spec/examples/python/verify_chain.py`](https://github.com/burin-labs/harn/blob/main/opentrustgraph-spec/examples/python/verify_chain.py)
implements all five checks in ~150 lines using only the standard
library, and it is exercised against every fixture in
`opentrustgraph-spec/fixtures/`.

## Fixtures and test vectors

| Fixture                                 | Status   | What it exercises                                  |
|-----------------------------------------|----------|----------------------------------------------------|
| `fixtures/valid/decision-chain.json`    | accept   | Two-record chain with a control-plane promotion    |
| `fixtures/valid/tier-transition.json`   | accept   | Three-record chain ending in an approved action    |
| `fixtures/valid/effect-inheritance-chain.json` | accept | Effect inheritance plus actor-chain parentage |
| `fixtures/invalid/tampered-chain.json`  | reject   | Self-consistent record but broken `previous_hash`  |
| `fixtures/invalid/missing-approval.json`| reject   | `approval.required = true` with no approver        |
| `fixtures/invalid/actor-chain-parentage.json` | reject | Child `actor_chain` does not extend its parent |

These fixtures are normative test vectors. The Harn runtime parses them
in `crates/harn-vm/src/trust_graph.rs::tests::opentrustgraph_*` so the
spec artifact and the runtime contract stay in lockstep.

---

## Read next

- [Credential denylist reference](https://harnlang.com/sandbox-read-deny-reference.md)
- [LLM dialect ownership](https://harnlang.com/dev/llm-dialect-contract.md)
