Skip to content

fix(schema): runtime.platform description now matches §3.1.1 - #234

Merged
imran-siddique merged 3 commits into
agentrust-io:mainfrom
rajnisht7:doc-trace-claim
Sep 2, 2026
Merged

fix(schema): runtime.platform description now matches §3.1.1#234
imran-siddique merged 3 commits into
agentrust-io:mainfrom
rajnisht7:doc-trace-claim

Conversation

@rajnisht7

@rajnisht7 rajnisht7 commented Aug 28, 2026

Copy link
Copy Markdown
Contributor

What this changes

Schema description of runtime.platform said software-only is only for dev-mode records. But §3.1.1 also requires software-only on any record whose origin.kind isn't self a different, broader rule. docs/schema.md already states both cases; the schema description was the odd one out.

Closes #232

Type of change

  • Editorial (typo, link fix, clarification: no normative effect)
  • Non-breaking spec change (new optional field, new platform profile, informative addition)
  • Breaking spec change (requires 14-day comment period and Project Lead sign-off)
  • Schema change
  • Example addition

Spec section

§3.1.1

Checklist

  • DCO sign-off on all commits (git commit -s)
  • CHANGELOG.md updated (for any normative change)
  • Breaking changes marked with <!-- CHANGED: #NNN: description --> in spec text
  • Backward compatibility statement included (for breaking changes)

@rajnisht7
rajnisht7 requested a review from a team as a code owner August 28, 2026 19:00

@lywinged lywinged left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The substance holds. I checked each claim in the description against the tree rather than taking it on trust, and all of it stands. Four notes follow. The first two are worth doing before this merges, and both are edits to text rather than to the change itself. The third is a second site of the same defect. The fourth is out of scope.

What I verified

  • The rule really is broader than the old description. §3.1.1 says:

    A record whose origin.kind is not self MUST carry runtime.platform: "software-only", and a verifier MUST reject it otherwise.

    The old description scoped software-only to development-mode records, which is a strict subset of that.

  • docs/schema.md really did already say both cases. Lines 98 and 107, dev-mode execution and a record transcribed from another vendor's control plane. The schema description was the odd one out, as the PR says.

  • The widened prohibition is supported. The new sentence extends "must never be treated as attested evidence" from dev-mode records to every software-only record. §3.1.1 backs that: "nothing about naming your producer makes unattested evidence attested."

  • Both schema copies are updated, and nothing relies on the author having remembered. schema/trace-claim.json and src/agentrust_trace/schema/trace-v0.2.json are byte identical on main. I reverted the packaged copy on this branch and reran: tests/test_validate.py::test_packaged_schema_matches_the_normative_schema fails, 827 passed. So the sync is held by a test, and this PR satisfies it.

  • The third copy is correctly left alone. src/agentrust_trace/schema/trace-v0.1.json still carries the old sentence word for word. That is right rather than missed: v0.1 has no origin property, so for that profile software-only really does mean only a development record.

  • Nothing about validation changes. The rule already has two enforcers, and I checked that both bite rather than reading them: a record carrying origin.kind: "log-import" with runtime.platform: "tpm2" is refused by validate_json ("'software-only' was expected", from the allOf / if / then block) and by TrustRecord.model_validate (from _origin_cannot_claim_hardware). This is text catching up with behaviour, which is why the suite is unchanged at 828.

1. The commit message, worth fixing before merge rather than after

The commit is titled initial commit with an empty body, and on this repository that subject is what lands on main. Two commits already show it:

e7e2eca  initial commit (#229)
c7958b9  initial commit (#227)

Both of those pull requests had descriptive titles, and each contributed exactly one non merge commit, titled initial commit. So whatever the squash setting is here, the observed result is that the commit subject reaches main and the pull request title does not. Merging this as it stands makes three.

One git commit --amend and a force push fixes it while the branch is still yours, and after the merge it is not fixable. This PR's own title, fix(schema): runtime.platform description now matches §3.1.1, is already a good subject and matches the convention the rest of the log follows.

2. Two things in the description, one of which CONTRIBUTING has a rule about

Spec section is filled in as None, and Schema change is unticked while the diff modifies two schema files. Editorial is right about the effect, since a description does not participate in validation, so this is not a process objection. The reason to name the section anyway is CONTRIBUTING:

Schema changes (schema/trace-claim.json)

Schema changes must track normative spec changes. A schema PR without a corresponding spec PR (or reference to a merged one) will not be merged.

§3.1.1 is exactly the merged text this tracks, and it is already the argument the description makes, so writing §3.1.1 in that field costs nothing and removes a reason to bounce it. No sponsor question arises either way: the same page puts "schema changes tracking an already-merged spec change" in the set that needs none.

While that field is open, the same edit can carry the other half. #232 reports this exact defect, and the CHANGELOG line cites it, but neither the description nor the commit carries a closing keyword, so merging this leaves #232 open for someone to close by hand. Closes #232 in the description fixes that at merge time.

3. The same sentence survives in one tutorial

This closes #232 at the site the issue names. The narrower claim it reports is stated once more, in docs/tutorials/hardware-attestation-platforms.md:

  • line 8: "Why software-only is only safe for development and testing"
  • line 60: "This platform value exists so a development record can never be mistaken for a hardware-backed record"
  • line 62: "Use software-only only in development and testing."
  • line 191, the platform table: the software-only row reads "None: development only"

Line 62 is the one a producer can act on and reach the wrong value by: a record whose origin.kind is log-import or third-party-control-plane MUST carry software-only, and that is neither development nor testing. Same defect as #232, second file.

Whether that belongs in this PR or in its own is yours to pick. I mention it because a reader who finds the corrected schema description and then the tutorial gets the contradiction back.

4. A mirror that holds by coincidence, non blocking

The schema conditional matches by enumeration. Abridged from the allOf entry:

"if": { ... "kind": { "enum": ["third-party-control-plane", "log-import"] } ... }

_origin_cannot_claim_hardware matches by negation:

if self.origin is None or self.origin.kind == "self":
    return self

Equivalent today, because kind is closed at three values. If a fourth is ever added, the model keeps enforcing and the schema silently stops. The $comment on that same allOf entry says it "Mirrors the cross-field check in the reference model, so a validator that only reads this schema enforces it too", which is what a later reader would rely on. Not a defect in this PR and outside its scope. I name it because this PR is about the schema's text agreeing with the rule, and that comment is a claim about the same agreement.

Once the commit is retitled and the description carries the section and the closing keyword, I have nothing blocking on this one. Notes 3 and 4 are yours to take or leave.

imran-siddique
imran-siddique previously approved these changes Aug 28, 2026

@imran-siddique imran-siddique left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Checked this against the spec text rather than the issue. §3.1.1 at e7e2ecab68cf3534c7d5fcb7e9a6f089fcb7d592 is stronger than the PR body claims:

A record whose origin.kind is not self MUST carry runtime.platform: "software-only", and a verifier MUST reject it otherwise.

So the schema description was not merely narrower than the docs, it was understating an explicit MUST, in the one text an integrator reads next to a validator. Correct fix, and updating both schema/trace-claim.json and src/agentrust_trace/schema/trace-v0.2.json identically is right since they are byte-identical copies.

Non-blocking, for whoever merges next: #233 and #236 also append to CHANGELOG.md, so whichever of the three lands first will conflict the other two there. #233 and #236 additionally both touch src/agentrust_trace/sign.py.

Approving. Releasing held runs.

@chernistry

Copy link
Copy Markdown
Contributor

Coming in as the #232 filer: this fixes the narrowing I reported, aligns the texts the same way #172 was resolved, and the closing MUST-never sentence is stronger than my original wording. Thank you for picking it up.

One reading gap survives from the old text into the new, and since it is my sentence being implemented I would rather flag it here than after merge. The description now enumerates two situations — a development-mode execution, or a record assembled from evidence produced outside the runtime — but there is a third class the lead clause covers and neither example names: a production runtime emitting records for its own executions (origin.kind: self) with no hardware root of trust in its stack. The whole argument of #232 was that a reader takes this description as complete and has no reason to look further; an enumeration that omits a producer class recreates that, one step removed.

Smallest fix — make the examples explicitly non-exhaustive and add the third:

Hardware platform providing the root of trust. software-only marks any record with no hardware root of trust — for example a development-mode execution, a production runtime with no TEE in its stack, or a record assembled from evidence produced outside the runtime (origin.kind other than self requires this value; see spec 3.1.1). Such records must never be treated as attested evidence.

If the maintainers would rather keep the two-example enumeration as the mirror of docs/schema.md, then "for example" alone still closes the gap. Either way this is a wording note, not an objection to the fix.

@imran-siddique

imran-siddique commented Aug 29, 2026

Copy link
Copy Markdown
Member

Heads-up: I merged #236 a few minutes ago and it appended 22 lines to CHANGELOG.md, which has conflicted this branch. That is my sequencing, not anything you did, and my approval above still stands.

I ran the merge locally so you know the shape before you start:

Merge origin/main (currently ``) into doc-trace-claim, keep both CHANGELOG entries, push, and I will merge on the green.

@rajnisht7

Copy link
Copy Markdown
Contributor Author

@imran-siddique have resolved the conflicts kindly have a look

@chernistry

Copy link
Copy Markdown
Contributor

Conflicts look resolved from here — thanks for turning it around. One wording note from my #232 comment is still open, and it is a one-word fix rather than a change to the diff: the new description enumerates two situations, and a production runtime emitting for its own executions (origin.kind: self) with no TEE in its stack is a third class the lead clause covers but neither example names. Adding "for example" before the enumeration closes it on its own, without adding the third case or diverging from docs/schema.md. Not an objection to the fix, and not worth holding the merge if the maintainers would rather take it separately — but it is cheaper now than as a follow-up issue.

@imran-siddique imran-siddique left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Conflicts resolved cleanly, and the rebase also removed two stray duplicate ### Fixed headings in CHANGELOG.md that had crept in from earlier merges. Both schema copies carry the same text. Merging.

@chernistry your remaining note is right and I am taking it. The lead clause covers three classes and the enumeration names two: a production runtime emitting for its own executions, origin.kind: self, with no TEE anywhere in its stack, is covered by "no hardware root of trust" and named by neither example. "For example" before the enumeration closes it without adding a case or diverging from docs/schema.md.

I am not holding this merge for one word, as you suggested. I will push it as a follow-up myself rather than send @rajnisht7 another round trip.

Worth noting that the third class you identified is the same one under argument in #242, where the proposal was to require an all-zero runtime.measurement for production software-only records. I have ruled against that there: a software-only record with no hardware root can still carry a real software commitment, and all-zero is reserved for a producer making no commitment at all. Your third class is a first-class citizen, not an edge case, which is another reason to name it as an example rather than to legislate it away.

@imran-siddique
imran-siddique merged commit 78b504f into agentrust-io:main Sep 2, 2026
5 of 6 checks passed
imran-siddique added a commit that referenced this pull request Sep 2, 2026
#234 aligned the schema description with spec 3.1.1, but its enumeration
reads as exhaustive. The lead clause is "no hardware root of trust"; the
two named situations are a development-mode execution and a record
assembled from evidence produced outside the runtime. A production runtime
emitting for its own executions, origin.kind self, with no TEE anywhere in
its stack, is covered by the lead clause and named by neither, so the
description narrowed the rule again in a smaller way.

"For example" restores the reading without adding a case or diverging from
docs/schema.md. Both schema copies carry it.

Raised by @chernistry on #232 and again on #234.


Claude-Session: https://claude.ai/code/session_012yyHFd4YA35oNUjhrztJSb

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

schema: the software-only description states a narrower rule than §3.1.1 mandates

4 participants