fix(schema): runtime.platform description now matches §3.1.1 - #234
Conversation
469d582 to
7959f9d
Compare
lywinged
left a comment
There was a problem hiding this comment.
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.kindis notselfMUST carryruntime.platform: "software-only", and a verifier MUST reject it otherwise.The old description scoped
software-onlyto development-mode records, which is a strict subset of that. -
docs/schema.mdreally 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-onlyrecord. §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.jsonandsrc/agentrust_trace/schema/trace-v0.2.jsonare byte identical onmain. I reverted the packaged copy on this branch and reran:tests/test_validate.py::test_packaged_schema_matches_the_normative_schemafails, 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.jsonstill carries the old sentence word for word. That is right rather than missed: v0.1 has nooriginproperty, so for that profilesoftware-onlyreally 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"withruntime.platform: "tpm2"is refused byvalidate_json("'software-only' was expected", from theallOf/if/thenblock) and byTrustRecord.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-onlyis 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-onlyonly in development and testing." - line 191, the platform table: the
software-onlyrow 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 selfEquivalent 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
left a comment
There was a problem hiding this comment.
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.kindis notselfMUST carryruntime.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.
|
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 ( Smallest fix — make the examples explicitly non-exhaustive and add the third:
If the maintainers would rather keep the two-example enumeration as the mirror of |
7959f9d to
1f20003
Compare
|
Heads-up: I merged #236 a few minutes ago and it appended 22 lines to I ran the merge locally so you know the shape before you start:
Merge |
|
@imran-siddique have resolved the conflicts kindly have a look |
|
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 ( |
imran-siddique
left a comment
There was a problem hiding this comment.
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.
#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>
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
Spec section
§3.1.1
Checklist
git commit -s)CHANGELOG.mdupdated (for any normative change)<!-- CHANGED: #NNN: description -->in spec text