fix(intent-bridge): compare transcript call by canonical JSON - #318
fix(intent-bridge): compare transcript call by canonical JSON#318altrudev wants to merge 1 commit into
Conversation
|
🔴 Contributor Check: HIGH
Automated check by AgenTrust Contributor Check. |
lywinged
left a comment
There was a problem hiding this comment.
This is an approval waiting on one addition. Reviewed at 63ae280 on a247244. It is posted as a comment rather than an approval because the PR is a draft and the addition below will move the head, and the maintainer-approval check only counts an approval on the commit it was given on; I will approve the head that carries the entry once you mark it ready.
The defect is real and the fix is the right shape. On main, a signed and digested call of {"approved": 1} with a transcript before.tool_call of {"approved": true} passes the transcript check; on this head it is refused. It is the identity relation the #300 review asked for in the tool-schema check, applied here where the transcript is compared: the signature covers RFC 8785 bytes, so comparing the two calls as _jcs bytes puts the transcript under the same relation as the digest it sits beside.
What I measured rather than read:
- Five lines in and one out in
intent_bridge.py, reusing the module's own_jcswrapper and thecompare_digestit already imports. - The five new tests pass. With the old comparison restored, four fail and the unchanged-call control passes.
- The four CI steps with the pinned install, on 3.11 and on 3.12: green, 1407 passed and 1 skipped.
- The new canonicalisation step cannot leak. A transcript call carrying 2^60 or NaN raises
IntentBridgeErrorfrom_jcs, becauseIntegerDomainErrorandFloatDomainErrorsubclassCanonicalizationErrorin the pinnedrfc87850.1.4.
One thing the body does not say, and the entry below should. "The existing AuthorizationMismatch result and diagnostic are preserved" holds for a call that differs. For a transcript call JCS cannot serialise, the exception moves: main raised AuthorizationMismatch from the inequality, this head raises IntentBridgeError from _jcs before the comparison is reached. Same documented base type, and the treatment the authorization, the declaration and the executed call already get, so nothing to change in the code.
The one thing to add: a CHANGELOG.md entry under Unreleased, Fixed. Both code fixes already there carry one, and it is the record a reader of the next release will have. The shape the others use: what was accepted, what is now refused, that the signed digest was never affected, and the exception note above.
…ust-io#317) Rebased onto upstream 760cc3f after the CHANGELOG-only conflict identified by maintainers. Signed-off-by: Altru.dev <altrudevelop@gmail.com>
80dbb2e to
ac1a08f
Compare
|
Second conflict in an hour, same file, and this one is mine again: merging #322 re-conflicted #318 and #323 on the Please drop the I will write the changelog entries for all of them in one maintainer commit once they land, using the wording from your PR bodies. You lose nothing: the entries still say what your changes did, and the attribution is in the commits and the PRs. Why this rather than another rebase. Every open PR in this repository appends to the same block, so each merge conflicts every other one, and the number of rebases grows with the size of the queue rather than with the size of anyone's change. Two of your PRs have now paid for that twice. The durable fix is a fragment directory, one file per change assembled at release, and I am looking at it separately.
|
Closes #317.
What
verify_bridge()now comparestranscript.before.tool_callwith the executedtool_callusing the bridge's existing RFC 8785/JCS byte definition rather than Python container equality.Python container equality aliases booleans and the corresponding integers (
True == 1,False == 0). That let a required transcript carry a JSON-distinct call while the transcript-binding check still treated it as equal to the executed call.The signed
tool_call_digestcheck was already correct and remains unchanged. This patch only makes the separately supplied transcript use the same JSON identity relation as the bridge's canonical digest layer.Regression coverage
Focused tests cover:
1vs transcript booleantrue->AuthorizationMismatch;0vs transcript booleanfalse->AuthorizationMismatch;AuthorizationMismatch.The tests also pin that ordinary Python container equality would consider each pair equal while the bridge's JCS digests differ, so reverting to the old comparison reopens the defect.
Scope
No schema, wire-format, scope, digest, signature, or authorization semantics change. The existing
AuthorizationMismatchresult and diagnostic are preserved.The branch is based directly on upstream
a247244fb0bb97aea4e60d655f36d445cca18cd5. Hosted CI is not claimed until the repository executes it; no manual workflow run is requested.DCO trailers are present on the contribution commits. AI-assistance disclosure: ChatGPT assisted with repository triage, duplicate search, reproduction design, implementation drafting, and regression construction.
altrudevreviewed the bounded claim and remains responsible for the contribution.