Skip to content

docs(crosswalks): OpenProof approvals as approval-outcome references - #660

Open
antagoninc wants to merge 2 commits into
agentrust-io:mainfrom
antagoninc:openproof-approval-outcome
Open

antagoninc wants to merge 2 commits into
agentrust-io:mainfrom
antagoninc:openproof-approval-outcome

Conversation

@antagoninc

@antagoninc antagoninc commented Nov 9, 2026 •

Copy link
Copy Markdown
Contributor

What this changes

Adds an informative cross-walk and a fixture set that show a TRACE Trust Record pointing at an OpenProof approval through references with rel: "approval-outcome" (section 3.1.2). It follows the CHAP precedent (docs/crosswalks/chap-review-decisions.md, examples/chap-approval-outcome/, tests/test_chap_approval_outcome_fixtures.py).

  • docs/crosswalks/openproof-approvals.md: field mapping, verifier steps, boundary.
  • examples/openproof-approval-outcome/: five signed Trust Records, two OpenProof stores, expected.json, README. The JSON files are byte-identical to the output committed in OpenProof at d85c24a (integrations/trace/examples/).
  • tests/test_openproof_approval_outcome_fixtures.py: recomputes every verdict from the committed bytes with rfc8785 and cryptography, and verifies each record with agentrust_trace.verify_record. It does not import OpenProof.
  • One row in docs/references-registry.md, one nav entry in mkdocs.yml, one entry in examples/README.md, and one MEASURED_ELSEWHERE entry in tests/test_adequacy_all_sets.py.

Differences from the CHAP set: the id is content-derived (the SHA-256 of the approval's OpenProof signing bytes). The check covers who signed the approval: an authority key under a root-signed trust, plus a WebAuthn ES256 assertion over the approval digest. When a receipt is present, it also covers what the receiver executed under that approval.

Every check is seen failing on its own

The committed fixtures hold no private keys. A field changed in them also breaks its signature, so a check behind that signature cannot fail alone. The second commit closes this gap:

  • The test rebuilds case 01 under keys it generates at run time: root, authority, receiver, witness and the owner's P-256 passkey.
  • An unchanged rebuild must be confirmed. This is the baseline.
  • 21 single defects follow. Each changes one field, signs again and expects one verdict. They cover the trust (revoked or unnamed authority, wrong root), the approval (wrong receiver, wrong signer, content that does not hash to it), the passkey assertion (type, challenge, origin, cross-origin, relying party, user verification), the receipt (signer, kind, approval, content hash, document, version) and the checkpoint (signer, receiver, a count short of the receipt).
  • Each of 23 comparisons in the verdict logic, disabled one at a time, makes at least one test fail.

Measured

Measured on the first commit (e8e0d7e) with CI's install (pip install --require-hashes -r requirements/dev.txt, pip install --no-deps -e .), on macOS (Apple silicon) with Python 3.12.12, not on CI's Ubuntu:

  • pytest -q tests/test_openproof_approval_outcome_fixtures.py: 16 passed.

  • pytest -q tests/test_adequacy_all_sets.py: 32 passed.

  • ruff check src tests scripts: all checks passed.

  • python tools/check_dashes.py: no dashes outside examples/, spec/trace-v0.1.md.

  • pytest -q -p no:cacheprovider: 8 failed, 5267 passed, 112 skipped. On main at b938790 without this change, the same command gives 8 failed, 5250 passed, 112 skipped. The 8 failures are the same test IDs in both runs, so this change adds none:

    • three test_the_generator_reproduces_the_committed_bytes (applicability-assessment, condition-appraisal, observed-effect);
    • two in test_docs_quickstart.py;
    • test_readme_api_claims.py::test_the_readme_example_runs;
    • two worktree tests in test_review_bar.py.

    I have not investigated why they fail on macOS.

The second commit adds 22 tests (the baseline and 21 defects). I ran them, and the one-at-a-time disabling of each comparison, against a local stand-in for verify_record. The disabled comparisons are all in the test's own verdict logic, which does not call verify_record. CI on this pull request is their first run with this repository's install.

Independence

The verdict logic in the test is a second copy of openproof_trace.check() in the OpenProof repository, written by the same author. A matching verdict is therefore one source agreeing with itself, not an independent confirmation. What is independent of that author is verify_record for the Trust Records, and cryptography for every signature.

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.2 (references), informative only. No normative text changes.

Tests for a fix

Not a code or schema fix.

Changelog entry

  • OpenProof approvals as approval-outcome references. A cross-walk, docs/crosswalks/openproof-approvals.md, and five fixtures in examples/openproof-approval-outcome/ show a Trust Record pointing at an OpenProof approval. The id is derived from the approval's own signing bytes, and the digest is the RFC 8785 SHA-256 of the approved request. tests/test_openproof_approval_outcome_fixtures.py recomputes every verdict from the committed bytes without importing OpenProof, including OpenProof's Ed25519 signatures over its OPEC-1 encoding and the owner's WebAuthn assertion. The five cases are:

    • an approval executed and witnessed;
    • the same approval altered in the store after the record was issued;
    • an approval the receiver never executed;
    • an unresolvable reference, which still verifies as a record and reports the approval as unconfirmed, as section 3.1.2 rule 3 requires;
    • an approval signed by a key outside the owner's trust.

    The test also rebuilds the executed case under keys it generates at run time and checks 21 single defects, so every check behind a signature is seen failing on its own. Informative only: no schema, wire-format or normative change.

Independent read

Before opening, I gave a new AI agent session, which had seen none of this work, the repository at this commit, the diff and the OpenProof checkout. I asked it for every false or over-wide sentence and the strongest objection. It found the following, and I changed each:

  • The provenance was overstated. "Produced by a real OpenProof home" now names what the binary made (trust, approvals, receipt, checkpoint) and what the generator made in Python (Trust Records, passkey assertions, store layout, altered store).
  • I had claimed that "steps 2 to 5 each have a committed fixture". The text now says steps 2, 3 and 4 do (04, 02, 05), and that 03 is the no-receipt branch.
  • Case 05 never reaches the passkey check. The README now says it fails on the authority check, and that only the assertions of 01 and 03 are verified.
  • The OPEC-1 reference was cited for the signing domains. The domains are now cited from crates/openproof-witness/src/lib.rs and verifier.rs.
  • OpenProof requires an assertion only from the passkey's from_sequence. This is now stated, with the value in the fixtures (1).
  • G1's conditions are now stated. The fixtures meet neither of them.
  • The canonicalization text implied that agreement between two RFC 8785 implementations was measured. It was not: both sides use rfc8785, and every string is ASCII. The text now says so.
  • I added the CHAP page's boundary item "that the approval was checked before the action ran".
  • The altered-store test now compares the whole document and pins the single changed path to the entry that cases 01 and 02 cite.
  • The README's regeneration instructions would have deleted the README. They now point the generator at an empty directory.
  • It also found that several checks were never seen to fail on their own, against CONTRIBUTING's "A check that has never been seen to fail has not been verified." The second commit answers that.

Not changed:

  • CHANGELOG.md is not edited, because the pull request template asks for the bullet here instead.
  • examples/README.md does not list the CHAP set. That gap predates this change and is left for a separate edit.

Checklist

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

A cross-walk, docs/crosswalks/openproof-approvals.md, and five fixtures in
examples/openproof-approval-outcome/ show a Trust Record pointing at an
OpenProof approval by the RFC 8785 SHA-256 of the approved request.
tests/test_openproof_approval_outcome_fixtures.py recomputes every verdict
from the committed bytes, including OpenProof's Ed25519 signatures over
OPEC-1 and the owner's passkey assertion, without importing OpenProof.
Informative only: no schema, wire-format or normative change.

Signed-off-by: W. Alexander Ousley <246201964+antagoninc@users.noreply.github.com>
@antagoninc
antagoninc requested review from a team, lywinged and rajnisht7 as code owners November 9, 2026 08:25
The committed fixtures hold no private keys, so a field changed there
also breaks its signature, and the checks behind that signature were
never seen to fail alone. The test now rebuilds case 01 under keys it
generates at run time, makes one change, signs again, and expects the
matching verdict: 21 single defects across the trust, the approval,
the passkey assertion, the receipt and the checkpoint, plus a baseline
that the unchanged rebuild is confirmed.

Each of 23 comparisons in the verdict logic, disabled one at a time,
now fails at least one test.

Signed-off-by: W. Alexander Ousley <246201964+antagoninc@users.noreply.github.com>

This branch has not been deployed

No deployments
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.

1 participant