Reading PIC/TRACE authorizations and Trust Records under a two-party contract (musubi-trace-terms-v0, 55 vectors on real registry records) #66
Replies: 3 comments
|
Thanks for this. Marking an act undetermined, not outside the terms, whenever whoever assembled the bundle could have swapped the evidence is the right line: a missing check should never read as a violation. Like the cA2A companion in #65, this would sit well in agentrust-io/integrations as a community-tier entry with the 55 vectors as tests, pinned to the agentrust-trace release you ran it against, so it gets re-run when the bridge changes. |
|
@imran-siddique Thank you, I will put it there. The entry will be One thing the CI will show, and I would rather say it now: 0.11.0 on PyPI ships an older schema than main (agentrust-io/trace-spec#591), so when the next release lands, some vectors may move for that reason and not because the terms layer changed. The README will name which vectors read schema-dependent fields, so a red run on a new release points at the cause. I will link the PR here when it is up. |
|
@imran-siddique The PR is up: agentrust-io/integrations#355 (integrations/horizonshield-musubi-trace-terms/, head fdbb6e9), pinned to agentrust-trace 0.11.0, with the 55 vectors as tests. On the schema point in my last reply, the answer turned out narrower than I said. The evaluator does not read the TRACE JSON Schema: it calls verify_bridge, which in 0.11.0 checks a bridge without it, and it reads Trust Records through the NENRIN intake. The one schema-dependent check is test_consumed_registry_record_passes_trace_level_0, which runs trace-tests verify --level 0 on the two registry records the vectors consume (TT01 and TT16). So on a new release, a red run there points at agentrust-io/trace-spec#591, and a red vector points at verify_bridge or at the terms layer. The README does not say this yet; I will add it with the first round of review changes. |
Uh oh!
There was an error while loading. Please reload this page.
The PIC/TRACE bridge checks one call against one signed authorization, and its text says a match is integrity, not sufficiency. A Trust Record says what ran. Neither adds calls up, and neither knows what two parties agreed. We wrote a small profile that reads both, unchanged, one layer up: under an
a2a-contract-v0that both parties signed, plus a terms annex both signed, it recomputes per call and overall whether the contractor's signed acts stayed inside the grant, the agreed counts and the agreed runtime.Code and spec: https://github.com/ogasurfproject-jpg/horizon-shield/tree/main/workers/hs-ledger/nenrin/trace-terms-v0 (Apache-2.0;
SPEC.mdis the normative text).What it calls, and does not reimplement:
agentrust_trace.intent_bridge.verify_bridge(0.11.0, pinned) decides whether a decision allows a call; our contract verifier decides whether the contract is signed; the NENRIN ledger's TRACE intake checks a Trust Record. The profile only compares what those return with what the parties agreed.What it sees that a per-call check cannot (each is a vector in
vectors/vectors.json, 55 in all):calls_exceed_terms)compare, allowed by TRACE, where the contract prohibitscompareauthorization_idcarried two callsOne design rule, after three rounds of adversarial review: an act is outside the terms only on bytes the contractor signed (the act commits by digest to the bridge, the tool call, the declaration, the PIC digests, the transcript and the Trust Record) and on signatures nobody else can forge. Whoever assembles a bundle can swap evidence or withhold a key; that makes the act
undetermined, neveroutside_terms. Every TRACE object is read in the form its RFC 8785 digest names, so an integer rewritten as an equal float cannot change a verdict.What it does not establish: anything about acts not presented (completeness needs the acts on a log the contractor cannot rewrite), that a Trust Record's claims are true (nothing appraises an attestation, as the v0.2 verifier does not), or that
executed_atis true.Materials: every authorization in the vectors is signed by
sign_bridge; the Trust Records are the summit demo record (signed by its registered producer key) and Bernstein 3.20.0 from trace-registry, unchanged, plus recordssign_recordsigns in the generator.gen_vectors.pyrebuilds the file byte for byte and CI checks that.Two questions for the maintainers:
{"profile", "authorization"}, the bytessign_bridgesigns, before handing the bridge toverify_bridge. Is that pair of bytes part of the bridge's public contract, or should a consumer rely onverify_bridgealone?relthat only points at a signed contract digest (a pointer, likecondition-appraisal) be in scope for v0.3, or is that better left to the layer above?Corrections welcome; the vectors are there to be broken.
All reactions