> ## Documentation Index
> Fetch the complete documentation index at: https://docs.parmanasystems.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Execution Trust Records

> The canonical, immutable, cryptographically signed record of everything Parmana knows about a Business Transaction.

<Info>**\[AVAILABLE]**. `packages/shared/src/domain/execution-trust-record.ts`, `ExecutionTrustRecordBuilder`. CLAIMS.md 2.5.</Info>

## What it is

Every Business Transaction produces exactly one Execution Trust Record: the aggregate of
everything Parmana knows about it, built from a chain of immutable artifacts, each
referencing the one before it by ID:

```
Authority           who is empowered to authorize execution
     │              packages/shared/src/domain/authority.ts
     ▼
Authorization        the grant, with purpose and optional expiry
     │              packages/shared/src/domain/authorization.ts
     ▼
Intent               the specific action + target + parameters requested
     │              packages/shared/src/domain/intent.ts
     ▼
Business Transaction the immutable input to policy evaluation
     │              packages/shared/src/domain/business-transaction.ts
     ▼
Decision              the policy's outcome (APPROVED / REJECTED) + reason + evaluated signals
     │              packages/shared/src/domain/decision.ts
     ▼
Execution             what actually happened: status, mode, evidence
     │              packages/shared/src/domain/execution.ts
     ▼
Execution Trust Record  the aggregate: transaction + executions + overrides +
                         verifications + receipts + canonical hash + signature
                       packages/shared/src/domain/execution-trust-record.ts
```

`BusinessTransactionValidator` enforces structural consistency across the chain before
anything is evaluated, for example, `authorization.authorityId` must match
`authority.authorityId`, and `intent.authorizationId` must match
`authorization.authorizationId` (`packages/runtime/src/validators/BusinessTransactionValidator.ts:21-37`).
A Business Transaction that doesn't hang together structurally never reaches
[policy evaluation](/concepts/policies-and-the-decision).

## Why it exists

Every earlier concept on this site, policy, authorization, gateway verification, credential
isolation, produces something. The trust record is where all of it lands: one artifact you,
or anyone, can verify independently, without running Parmana at all. It's the answer to
"what actually happened," not "what was supposed to happen."

## Shape

```typescript theme={null}
export interface ExecutionTrustRecord {
  readonly trustRecordId: string;
  readonly businessTransactionId: string;
  readonly transaction: BusinessTransaction;
  readonly overrides: readonly Override[];        // append-only
  readonly executions: readonly Execution[];       // append-only
  readonly verifications: readonly Verification[]; // append-only
  readonly receipts: readonly Receipt[];           // append-only
  readonly trustRecordHash: string;
  readonly signature: Signature;
  readonly createdAt: Date;
  readonly updatedAt: Date;
}
```

## What's immutable, and what's append-only

`businessTransactionId`, `metadata`, `policy`, `signals`, and `decision` never change after
creation. `overrides`, `executions`, `verifications`, and `receipts` may only grow, nothing
is ever edited or removed from them. For `overrides` and `executions`, this append-only
invariant is what lets a `trustRecordHash` mean anything: they are inside the signed
content, so growing them changes the hash in a verifiable way. `verifications` and
`receipts` are append-only too, but for a different reason: they are outside the signed
content entirely (see below), so their append-only guarantee comes from repository API
convention rather than from the signature.

## What the hash and signature actually cover

`VerificationCrypto.canonicalRecord()` (`packages/crypto/src/VerificationCrypto.ts:46-68`)
builds the exact object that gets hashed and signed. It includes six fields:
`trustRecordId`, `businessTransactionId`, `transaction`, `overrides`, `executions`, and
`createdAt`. `hash()` and `sign()` both call it (lines 73-78 and 85-97), so the
`trustRecordHash` and `signature` cover precisely this content, no more and no less.

<Warning>
  `verifications` and `receipts` are **not** part of the hashed content, even though they are
  append-only fields on the same record (CLAIMS.md 2.5). This is intentional, not an
  oversight: a `Verification` (`packages/shared/src/domain/verification.ts:44`) carries the
  `trustRecordHash` it checked as one of its own fields. If verifications were inside the hash
  they verify, appending a new verification would change the hash, invalidating every
  verification that came before it. Keeping them outside is what lets the signed content stay
  stable while an unbounded number of verifications and receipts accumulate against it. The
  append-only guarantee for `verifications` and `receipts` comes from repository API
  convention, not from being under the signature.
</Warning>

`execution.metadata.authorizationId` **is** inside the canonically-hashed content, because
it lives under `executions`. Tampering with it changes the recomputed `trustRecordHash` and
fails verification (CLAIMS.md 2.11, `execution-authorization-wiring.test.ts`, "trust record
references the authorization").

## Minimal example: getting one back

```python theme={null}
trust_record = client.execution.execute(transaction)     # POST /execute
trust_record = client.trust_records.get(transaction_id)  # GET /trust-records/:id
```

Real example, captured from a live local run (2026-07-12), trimmed:

```json theme={null}
{
  "trust_record_id": "cabb41d7-1ab5-4cc9-a950-5c4300c6a826",
  "business_transaction_id": "be045836-0016-4c96-838e-a8934cbe0ee9",
  "executions": [
    {
      "execution_id": "8f5605e9-19ee-48e7-9863-132aa565b037",
      "decision": { "outcome": "APPROVED", "reason": "Vendor payment authorized. ..." },
      "status": "COMPLETED",
      "evidence": {
        "action": "payments:execute",
        "target": "vendor://payments",
        "parameters": { "amount": 1000, "currency": "USD" },
        "success": true,
        "attributes": { "connector": { "connectorId": "vendor-payment", "capability": "payments:execute" } }
      },
      "metadata": { "authorizationId": "7824fffb-dbb2-4046-9436-fbbd0ea777fa" }
    }
  ],
  "verifications": [{ "status": "VERIFIED", "trust_record_hash": "fdb313e8..." }],
  "receipts": [{ "algorithm": "ed25519", "receipt_hash": "5e0ab23f..." }],
  "trust_record_hash": "fdb313e82c7cd86cf5f1dfb0ab90ac72f550a67a91891ebfce9462a73e9da103",
  "signature": { "algorithm": "ed25519", "key_id": "default" }
}
```

Field names shown in `snake_case` (Python SDK decode); the wire format from the API is
`camelCase`. Source: `python/examples/quickstart/`.

## Connector evidence extends `evidence.attributes`, it does not add a new field

`ExecutionEvidence.attributes` (`packages/shared/src/domain/execution-evidence.ts`) has
always been an open `Record<string, unknown>` bag, and `ExecutionEvidenceBuilder` has
always forwarded `ExecutionResult.metadata` into it verbatim, neither changed for this
milestone. `@parmana/connector-sdk`'s `SdkConnectorExecutor` populates
`ExecutionResult.metadata.connector` with a `ConnectorEvidence` object (connector ID,
version, capability, sanitized endpoint, redacted request/response summaries, a
`connectorEvidenceHash` computed by the existing `TrustRecordHasher`, no alternative hash),
so it lands at `execution.evidence.attributes.connector` through this same, unmodified
path. Records created before `connector-sdk` existed were serialized, and hashed, without
this key; that stored content and hash are never recomputed or migrated, so old and new
records verify identically against their own stored hash.

## Next

<CardGroup cols={2}>
  <Card title="Verify a trust record independently" icon="check-double" href="/verification/overview">
    The third-party verification story, no Parmana runtime required.
  </Card>

  <Card title="Detect tampering" icon="bug" href="/concepts/content-binding-toctou">
    Mutate a record, verify, watch it fail: the negative path.
  </Card>
</CardGroup>
