v0.62.0: normalize adjacent MCP records into the SEP-2828 evidence model#221
Conversation
vaara normalize reads a SEP-2643 authorization denial, a SEP-2787 tool-call attestation, or a SEP-2817 invocation audit context and maps it onto the SEP-2828 execution-record model: which evidence plane it fills (outcome / decision-attested / decision-input), which fields it populates, and what is still missing for a complete signed record. It promotes nothing: a SEP-2817 client claim stays advisory, a SEP-2643 denial is a refused outcome, and a SEP-2787 attestation fixes the exact back-link a conformant receipt must pin and nothing else. SEP-2643 and SEP-2817 are pure standard library (base install); the SEP-2787 back-link digest reuses the receipt verifier and degrades to a reported gap without the attestation extra. Adds _normalize.py plus a public re-export, the normalize_v0 vectors (verbatim spec examples) with a Vaara-free independent checker that reproduces every case, and the test suite.
|
Warning Review limit reached
More reviews will be available in 44 minutes and 17 seconds. Learn how PR review limits work. Your organization has run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After more reviews become available, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans include higher PR review limits than trial, open-source, and free plans. In all cases, reviews become available again over time. During sustained high-volume PR review activity, CodeRabbit may temporarily slow when the next review becomes available. Please see our Fair Usage Limits Policy for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (14)
📝 WalkthroughWalkthroughThis PR adds a normalization layer that maps MCP records from adjacent SEP formats (denial, attestation, invocation audit) onto the unified SEP-2828 evidence model. It includes format detection, partial field population with advisory context, back-link digest computation for attestations, a CLI command, and comprehensive vector-based test coverage. ChangesSEP-2828 Normalization Feature
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
| "SEP-2817 is client-asserted input audit context; per its own " | ||
| "specification it MUST NOT be used as authorization evidence", |
| "it maps to the decision-input plane (the agent's stated intent), " | ||
| "the unsigned counterpart of an attested rationale, and populates no " | ||
| "required SEP-2828 field", |
| "a SEP-2787 attestation is the attested request a SEP-2828 receipt " | ||
| "answers; it fixes the exact back-link a conformant receipt must pin", |
| "plannerDeclared.intent is client-declared and bound by the issuer's " | ||
| "signature, not asserted true by the issuer", |
| "the record's own signing (alg, signature, receiptAsserted) is a " | ||
| "separate event by the recording side, not derived from the attestation", |
| "SEP-2817 is client-asserted input audit context; per its own " | ||
| "specification it MUST NOT be used as authorization evidence", |
| "it maps to the decision-input plane (the agent's stated intent), " | ||
| "the unsigned counterpart of an attested rationale, and populates no " | ||
| "required SEP-2828 field", |
| ["a SEP-2787 attestation is the attested request a SEP-2828 receipt " | ||
| "answers; it fixes the exact back-link a conformant receipt must pin", |
| "plannerDeclared.intent is client-declared and bound by the issuer's " | ||
| "signature, not asserted true by the issuer", |
| "the record's own signing (alg, signature, receiptAsserted) is a " | ||
| "separate event by the recording side, not derived from the attestation"], |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
tests/vectors/normalize_v0/README.md (1)
49-51: 💤 Low valueAdd language identifier to fenced code block.
The code block should specify
bashorshellas the language identifier for proper syntax highlighting and to satisfy markdown linting rules.📝 Proposed fix
-``` +```bash python tests/vectors/normalize_v0/_check_independent.py</details> <details> <summary>🤖 Prompt for AI Agents</summary>Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.In
@tests/vectors/normalize_v0/README.mdaround lines 49 - 51, Update the fenced
code block in README.md to include a shell language identifier for proper syntax
highlighting and linting; replace the opening fence "" before the command referencing tests/vectors/normalize_v0/_check_independent.py with "bash" (or
"shell") so the block begins withbash and the rest of the content remains
unchanged.</details> <!-- cr-comment:v1:c6e7e506e35a05abe4861e6e --> _Source: Linters/SAST tools_ </blockquote></details> </blockquote></details> <details> <summary>🤖 Prompt for all review comments with AI agents</summary>Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.Inline comments:
In@tests/vectors/normalize_v0/inputs/sep2643_url_denial.json:
- Line 5: The test vector has an inconsistent error.code type: the JSON field
"error.code" is numeric (-32042) but other SEP-2643 vectors use the string
"AUTHORIZATION_DENIAL"; update the vector so "error.code" is the canonical
string "AUTHORIZATION_DENIAL" to match the suite (or alternatively update the
normalization/validation logic to accept both numeric and string), and ensure
the change is applied to the sep2643_url_denial.json test to keep all SEP-2643
inputs consistent with the other vectors.
Nitpick comments:
In@tests/vectors/normalize_v0/README.md:
- Around line 49-51: Update the fenced code block in README.md to include a
shell language identifier for proper syntax highlighting and linting; replace
the opening fence "" before the command referencing tests/vectors/normalize_v0/_check_independent.py with "bash" (or "shell") so the block begins withbash and the rest of the content remains unchanged.</details> <details> <summary>🪄 Autofix (Beta)</summary> Fix all unresolved CodeRabbit comments on this PR: - [ ] <!-- {"checkboxId": "4b0d0e0a-96d7-4f10-b296-3a18ea78f0b9"} --> Push a commit to this branch (recommended) - [ ] <!-- {"checkboxId": "ff5b1114-7d8c-49e6-8ac1-43f82af23a33"} --> Create a new PR with the fixes </details> --- <details> <summary>ℹ️ Review info</summary> <details> <summary>⚙️ Run configuration</summary> **Configuration used**: defaults **Review profile**: CHILL **Plan**: Pro Plus **Run ID**: `10ea30be-fe2e-4bce-92da-59ade1248f23` </details> <details> <summary>📥 Commits</summary> Reviewing files that changed from the base of the PR and between 259946cccdbd3830964d6de7f8f32348a4df37b3 and 5d1f63540fed2e448c275593f0779108c08450e6. </details> <details> <summary>📒 Files selected for processing (14)</summary> * `src/vaara/attestation/_normalize.py` * `src/vaara/attestation/receipt.py` * `src/vaara/cli.py` * `tests/test_normalize.py` * `tests/vectors/normalize_v0/README.md` * `tests/vectors/normalize_v0/_check_independent.py` * `tests/vectors/normalize_v0/expected.json` * `tests/vectors/normalize_v0/inputs/sep2643_rar_denial.json` * `tests/vectors/normalize_v0/inputs/sep2643_scope_denial.json` * `tests/vectors/normalize_v0/inputs/sep2643_url_denial.json` * `tests/vectors/normalize_v0/inputs/sep2787_attestation.json` * `tests/vectors/normalize_v0/inputs/sep2817_multiturn.json` * `tests/vectors/normalize_v0/inputs/sep2817_single.json` * `tests/vectors/normalize_v0/inputs/unknown.json` </details> </details> <!-- This is an auto-generated comment by CodeRabbit for review status -->
| "jsonrpc": "2.0", | ||
| "id": 17, | ||
| "error": { | ||
| "code": -32042, |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
# Verify error code format consistency across all SEP-2643 test vectors
echo "=== SEP-2643 test vector error codes ==="
fd -e json 'sep2643' tests/vectors/normalize_v0/inputs/ --exec jq -r '.error.code' {}Repository: vaaraio/vaara
Length of output: 147
Inconsistent SEP-2643 error.code type across test vectors (numeric vs string).
tests/vectors/normalize_v0/inputs/sep2643_url_denial.json uses numeric error.code: -32042, while other SEP-2643 vectors in tests/vectors/normalize_v0/inputs/ use string error.code: "AUTHORIZATION_DENIAL". The suite/spec should treat one format as canonical (per SEP-2643) or explicitly validate both representations to keep vectors consistent.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@tests/vectors/normalize_v0/inputs/sep2643_url_denial.json` at line 5, The
test vector has an inconsistent error.code type: the JSON field "error.code" is
numeric (-32042) but other SEP-2643 vectors use the string
"AUTHORIZATION_DENIAL"; update the vector so "error.code" is the canonical
string "AUTHORIZATION_DENIAL" to match the suite (or alternatively update the
normalization/validation logic to accept both numeric and string), and ensure
the change is applied to the sep2643_url_denial.json test to keep all SEP-2643
inputs consistent with the other vectors.
…rt; bump to 0.62.0 Hardening from an adversarial review, before release: - the independent checker now reconstructs the SEP-2787-modeled envelope and digests that (matching the receipt verifier) instead of digesting the raw document bytes, and a new extension-field attestation vector pins the modeled-fields-only semantics (extra fields do not change the back-link) - a SEP-2817 userIntent flagged redacted no longer emits the cleartext - the human report escapes control characters in foreign-derived values so a crafted value cannot forge report lines - denial detection requires a denial marker before reading a bare object, so a stray top-level reason is not misread as a denial - docstrings and the README state the digest is over the modeled fields, not raw wire bytes (corrected in _receipt_verifier too) Bumps the version to 0.62.0 with the CHANGELOG entry.
|
Implements part of the SEP-2828 execution-record proposal: modelcontextprotocol/modelcontextprotocol#2828 The adjacent records |
…del (#221) vaara normalize reads an adjacent MCP record and maps it onto the SEP-2828 execution-record evidence model: a SEP-2643 denial becomes a refused outcome, a SEP-2787 attestation becomes the decision-attested back-link a conformant receipt must pin, and a SEP-2817 invocation context becomes advisory decision-input. For each record it reports which evidence plane it fills, which fields it populates, and what is still missing for a complete signed record. It promotes nothing: an unsigned client claim stays advisory. Ships the normalize_v0 vectors (verbatim spec examples plus an extension-field attestation) and a Vaara-free independent checker that reconstructs the modeled envelope and reproduces every case. Bumps to 0.62.0.
vaara normalizereads an adjacent MCP record and maps it onto Vaara's SEP-2828 execution-record model. It speaks three dialects:For each record it reports which evidence plane it fills, which SEP-2828 fields it populates, and what is still missing for a complete signed record. It promotes nothing: an unsigned client claim stays advisory, a denial is an outcome only, and an attestation fixes the back-link and nothing else, because the record's own alg, signature, and receiptAsserted are the recording side's separate signing event.
Why: the surrounding ecosystem is fragmenting into narrow, single-purpose records. Vaara is the receiving side that reads each one and files it into one evidence model, so the SEP-2828 record is where they compose.
SEP-2643 and SEP-2817 normalization is pure standard library and runs in the base install. The SEP-2787 back-link digest reuses the receipt verifier and degrades to a reported gap without the attestation extra.
Testing: new normalize_v0 vectors built from verbatim spec examples, a Vaara-free independent checker that reproduces every case including the back-link digest recomputed from raw bytes, and a 26-case suite. Full suite green at 1442 passed, ruff and mypy clean.
Summary by CodeRabbit
New Features
vaara normalizeCLI command for converting records between formats with automatic format detectionDocumentation
Tests