[AVAILABLE].
packages/shared/src/domain/execution-trust-record.ts, ExecutionTrustRecordBuilder. CLAIMS.md 2.5.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: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.
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
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.
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
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
Verify a trust record independently
The third-party verification story, no Parmana runtime required.
Detect tampering
Mutate a record, verify, watch it fail: the negative path.