Repository navigation
Description
Spec section affected
§3.1 (Trust Record logical schema) and §3.1.1 (origin). New optional block, no change to existing required fields.
Problem
There is no way for a self-produced, hardware-attested Trust Record to reference a fact that lives outside it.
§3.1.1 gets close. origin.source_event_id is defined as "Identifier of the source event in that system, so a record traces back to it", which is exactly the shape needed. But origin is scoped to records assembled from evidence someone else produced, and the normative text is:
A record whose
origin.kindis notselfMUST carryruntime.platform: "software-only", and a verifier MUST reject it otherwise.
That rule is correct for what it was written for. An importer holding someone else's log has no quote to present, so a hardware platform value on such a record would be untrue. The consequence is the problem: today, the moment a record points at anything external, it stops being a hardware attested record.
This is not a one-off request. Three open items are the same shape:
- design: bind authorized pre-execution intent to TRACE execution evidence #179, bind authorized pre-execution intent to execution evidence
- spec: binding attributable human-approval outcomes to step_up and defer execution evidence #191, bind attributable human-approval outcomes to step-up and defer execution evidence
- A behavioural execution identifier, raised by Pavan Sudheendra (Cisco), co-chair of the AAIF Observability & Traceability WG, who is proposing that an AAIF Behaviour Trace reference a TRACE Trust Record as attached evidence while TRACE remains responsible for attesting the runtime, model and policy environment
Three instances means this wants one mechanism, not a field added per case.
Proposed change
Separate two things the spec currently conflates: where the evidence came from, which can lower assurance, and what else this record points at, which cannot.
Add an optional references block to §3.1. Assurance-neutral by construction.
| Field | Required | Meaning |
|---|---|---|
rel |
yes | Relationship type. Closed set, extensible by registration. Initial values: authorized-intent (#179), approval-outcome (#191), behavior-trace. |
id |
yes | Identifier of the referenced fact in its own system. |
resolver |
yes | Identifier of the party obliged to resolve id. |
retention |
no | How long resolver undertakes to keep id resolvable. |
digest |
no | Digest of the referenced object, when the producer has it at issue time. |
Normative rules:
referencesMUST NOT affectruntime.platform. A record carryingreferencesand nooriginblock is stillselfand still whatever its platform actually was.- The record signature MUST cover
references, per the canonicalisation in §3.2.2. - A verifier MUST NOT reject a record because an entry in
referencescannot be resolved, and MUST NOT treat a resolved reference as attested evidence. - A producer that cannot name a
resolverMUST omit the entry rather than emit it with an empty or self-asserted resolver.
The distinction that makes rule 3 safe: what the signature attests is that this record points there, not the truth of what it points at. The pointer is inside the TEE boundary; the target is not. Conflating those is exactly what the origin MUST was written to prevent, and keeping them apart is what lets a reference be assurance-neutral rather than assurance-lowering.
Backward compatibility
- Non-breaking (new optional field, informative addition)
- Breaking
Existing records do not carry references and are unaffected. Existing verifiers ignore unknown fields. No change to origin, whose MUST stays exactly as it is: this proposal does not weaken it, it stops it being used for a job it was not written for.
Motivation
Immediate: it unblocks a compositional relationship between TRACE and an AAIF working group deliverable, where TRACE is the attestation layer referenced by a behavioural model rather than a competing schema. That is a better outcome for TRACE than either merging the models or duplicating them.
Structural: #179 and #191 are both currently blocked on the same missing primitive, and both will otherwise be solved by adding a bespoke field. Two bespoke fields is a pattern; three is a design failure.
The part this proposal does not settle, and should be argued here
resolver and retention are the interesting fields and I do not think one round of review will get them right. A reference is only worth the ability to look it up later, and that is not a hypothetical: in the npm keyv compromise the poisoned packages carried valid provenance logged in a transparency service, and fifteen days later the attestations could not be fetched, because the only working index was the artifact digest and unpublishing removed the metadata holding it. The log was intact and the records were unreachable.
TRACE has the same exposure through transparency. If we add references without saying who must be able to resolve them and for how long, we inherit it and so does anyone composing on top of us. I would rather that argument happen on this issue than after the field ships.
Related issues or PRs
#179, #191. Also §7 open question 3 (transparency log operators), which bears on resolver for the transparency field and probably wants resolving alongside this.
Sponsor: not yet named. Raising the technical argument first per CONTRIBUTING, which says proposals are evaluated on the argument alone.
Activity
spec: add an assurance-neutral references block (#197) (#198)
imran-siddique commentedon Aug 23, 2026
Delivered. #198 landed the block as §3.1.2 with all four normative rules, including the two that make it safe:
referencesMUST NOT affectruntime.platform, and a verifier MUST NOT reject a record because an entry cannot be resolved.The artifact half is #199, which puts the block in
schema/trace-claim.json, the v0.2 schema copy and the pydantic model. Without it both artifacts a producer validates against still reject a record the specification permits, because the schema isadditionalProperties: falseandTrustRecordisextra="forbid". That is in flight pending two edits.One deliberate divergence from this proposal, recorded so it is not read as drift: this issue described
relas a closed set extensible by registration. On #199 I ruled it an open string with the registered values documented, because §3.1.2 says "Registeredrelvalues" while §3.1.1 says of the neighbouring field "kindis a closed set, because the value of the field is that a verifier can key on it". The two sections say different things on purpose, and closingrelwould make every new relation a schema change and a spec change at once. Same intent, no schema-level membership enforcement. If the §7 registry question later settles toward enforcement, that is where it belongs.#179 and #191 stay open. They are the bindings that consume this, not duplicates of it, and both are now expressible without an
originblock dragging the record down tosoftware-only. Which was the point.