Repository navigation
fix(vc): match W3C EdDSA RDF proof configuration - #6585
Conversation
Use Dublin Core created and the Data Integrity cryptosuiteString datatype. Check canonical hashes and an independently published W3C signature; reject content and proof-option substitutions. Earlier signatures using the nonconforming mapping must be re-signed; no legacy fallback. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Copilot review overview
Review effort: Lite
Findings: 1
Open (2)
What changed in this PR
Aligns sparq-vc EdDSA RDF proof-configuration RDF encoding with the W3C vc-di-eddsa published vectors, fixing interoperability with external signers/verifiers and adding regression coverage.
Changes:
- Update proof-config RDF mapping (
created→dcterms:created,cryptosuite→sec:cryptosuiteString-typed literal). - Add W3C published
eddsa-rdfc-2022vector verification + tamper-rejection tests. - Document the breaking incompatibility and the typed-subset limitations.
| File | Description |
|---|---|
| skills/verifiable-credentials/SKILL.md | Documents the breaking RDF mapping change and scope limitations. |
| crates/sparq-vc/src/suite.rs | Implements the corrected RDF mapping and adds a W3C proof-config regression test. |
| crates/sparq-vc/tests/w3c_eddsa_rdfc.rs | Adds end-to-end verification of the published W3C vector and tamper tests. |
| crates/sparq-vc/src/lib.rs | Updates crate-level docs to reflect W3C-matching mapping and incompatibility. |
| crates/sparq-vc/README.md | Mirrors the mapping/incompatibility notes in README documentation. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Check all returned proof configuration fields and reversed triple order. Locate exactly one tampering target by subject and predicate so fixture order changes cannot alter the intended negative cases. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Copilot review overview
Review effort: Lite
Findings: 2
Open (4)
This module-level doc now slightly contradicts the updated mapping: proof-config RDF is no longer… · New These assertions validate the inputproof.configrather than theverifiedresult. This weakens… Use the standard spelling 'Test data' instead of 'Testdata' in this doc comment. · New These tamper tests depend ondocument()'s current vector ordering (tampered[4]andpop()…
There was a problem hiding this comment.
Warning
Copilot couldn't run its full agentic review because it didn't start before the timeout. Make sure your repository has a runner available, or add a copilot-code-review.yml file specifying one with the runs-on attribute. See the docs for more details.
Copilot review overview
Review effort: Lite
Findings: 1
Open (3)
proof_config_triplesrecreates the blank node and allocates a newStringviaformat!for each… · New The test helpers useNamedNode::new_unchecked, which bypasses IRI validation and can make… · Newunique_indexallocates aVecjust to assert uniqueness and return a single index. Since this is… · New
Resolved since last review (4)
This module-level doc now slightly contradicts the updated mapping: proof-config RDF is no longer… These assertions validate the inputproof.configrather than theverifiedresult. This weakens… Use the standard spelling 'Test data' instead of 'Testdata' in this doc comment. These tamper tests depend ondocument()'s current vector ordering (tampered[4]andpop()…
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
There was a problem hiding this comment.
sparq engine
Details
| Benchmark suite | Current: 150fc49 | Previous: 4b0c17a | Ratio |
|---|---|---|---|
store_bytes_per_triple |
88 bytes |
88 bytes |
1 |
dict_bytes_per_term |
53 bytes |
53 bytes |
1 |
comp_store_bytes_per_triple |
44 bytes |
44 bytes |
1 |
store_bytes_per_triple_small |
88 bytes |
88 bytes |
1 |
wasm_bundle_bytes |
1562916 bytes |
1562916 bytes |
1 |
This comment was automatically generated by workflow using github-action-benchmark.
The aggregate-only retry passed on unchanged head This clears the aggregate CI blocker. Required independent review and normal protected merge-queue validation remain separate landing requirements; this is not a cryptographic assurance claim. |
|
Local ci-fast gate (GitHub Actions runners are down; Jesse approved merging on local runs at 20:19 UTC). The PR head e43d3bb was merged locally with main f645787 (not pushed), and every step of
Path-specific checks: Extra review pass, because this changes the proof format: an independent review recommends merging. It checked every constant against the W3C vc-di-eddsa eddsa-rdfc-2022 vector files (canonical document, document hash, proof-config N-Quads and hash, proofValue). It reverted each of the two constants and confirmed the tests then fail. It also confirmed domain, challenge and proofPurpose are still hashed, with no legacy-mapping fallback. Open follow-up: the next release needs a BREAKING changelog entry, because proofs signed under the old mapping no longer verify. Benchmark: not run. The diff changes two RDF constants in the proof configuration and touches no engine path; the sign/verify algorithm is unchanged. Generated by Claude Code |
|
Re-ran the local ci-fast gate against main 83cb3b5 (main moved): clippy pass, nextest pass (3009 run, 3009 passed, 27 skipped), doctests pass, W3C conformance 1225 + 4 = 1229 (ratchet 1229), and sparq-vc clippy and tests pass. Merging. Generated by Claude Code |
* docs: bring skills and crate READMEs back in line with main Audit every skills/*/SKILL.md and crates/*/README.md against the public API on main after this week's merges, and fix the drift: - publish status: the 12-crate crates.io set (#6663/#6646) — jsonld, engine-serialize and engine-service are now published; unpublished crates lose crates.io/docs.rs badges and `"0.1"` install snippets - default-members (#6649): introspect, canon, substrate claims - zk-query-proofs / mpc / usage-control-policy recipes now compile against current signatures (prover_toml_for, verify_manifest, revoke_prover_toml, AttestedStatusRef::clear, Session fields) - cli: reason summary to stderr (#6641), dump streaming (#4313), jsonld-compact, bench --json, flag list - substrate: #3825 float comparison boundary fixed by #6671 - vc: proof-option validation (#6589) and EdDSA config change (#6585) - lws: per-resource WAC on notifications (#6388), reclaim race (#6675) - stale API names, test paths, floors, see-also links; router lists trust-graph - trust-expression spec: last github.com/jeswr/sparq link Closes #6327 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUY53os6oSKvmT9gCqdzud * ci(notation3tests): save rust-cache only on main docs-quality quick-gates' cache-posture test fails on every PR (main too) because this step had no save-if. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUY53os6oSKvmT9gCqdzud * docs: one git source for collaborating crates in EL/QL and Arrow recipes Mixing a crates.io sparq-core/engine with a git or path sparq-reason-el, sparq-reason-ql or sparq-arrow yields distinct Dict/Query/QueryResult types, so the recipes now take every collaborating crate from git. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUY53os6oSKvmT9gCqdzud * docs: strict SERVICE egress in the quickstart; strip model tags - sparq-engine-service quickstart used with_service_egress_allow, which only blocks private addresses; it now uses with_service_egress_policy(true, ..) so only the listed host is dialled, as the comment says. - Remove leftover model tags and "Model:" notes from skills/ and crate READMEs (#6673 removed the convention). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUY53os6oSKvmT9gCqdzud * docs: redo the model-tag strip without touching code syntax The previous strip also deleted every `()` on lines carrying a tag and every " ()" across the touched files, breaking examples such as `.text()`, `.arrayBuffer()` and `Result<(), String>`. Revert it and strip only the tags themselves (plus "Model:" notes); `()` counts and spacing punctuation are now identical to before the strip in every touched file. Keeps the strict SERVICE egress quickstart. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUY53os6oSKvmT9gCqdzud * docs: restore academic-paper fence; vendored spargebra in the PROV recipe Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUY53os6oSKvmT9gCqdzud * docs: fix markdownlint hits left by the model-tag strip Spaces inside bold markers in skills/mpc, a doubled blank line in two READMEs, and an orphaned provenance comment in sparq-trust. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUY53os6oSKvmT9gCqdzud * docs: PROV recipes declare sparq-core/oxrdf; router CLI and JSON-LD status match main Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUY53os6oSKvmT9gCqdzud * docs(zk): verify_manifest API line lists all ten parameters Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUY53os6oSKvmT9gCqdzud * docs(skills): router entries are each skill's own frontmatter description The router carried frozen copies of old per-skill descriptions and status notes that had drifted from the skills (a JS import subpath the package no longer exports, SHACL strict validation and features reported as missing, stale CLI/JSON-LD notes). Each entry now reproduces the skill's current frontmatter description verbatim. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUY53os6oSKvmT9gCqdzud * docs(jsonld): CLI dump has --context only; framing is planned Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MUY53os6oSKvmT9gCqdzud --------- Co-authored-by: Claude <noreply@anthropic.com>


sparq-vcpreviously encoded Data Integritycreatedunder the security vocabulary and encodedcryptosuiteas a plain literal. Its own sign/verify round trips could agree while rejecting conforming external signatures. This corrects the mapping todcterms:createdandsec:cryptosuiteStringand adds the independently published W3C EdDSA RDF test vector, exact canonical hashes, and content/proof-field tamper controls.Compatibility: signatures produced with the earlier nonconforming mapping must be re-signed. Verification does not silently retry the legacy encoding. The API and dependency graph are unchanged. This remains a typed RDF proof-configuration subset: JSON-LD transformation, full proof-option validation, issuer/controller authorization and credential status are separate obligations.
Validation at
ca4d74c0751ffea0a81e9295c78a7fbb568b414f: independently checked the W3C published vectors, source review, preflight, actual Markdown lint and README template checks. A bounded EC2 run passed 31 tests and one doctest with all features; 25 tests and one doctest without default features; and all four restored external-vector tests. Reverting either corrected RDF mapping independently made the published-signature test fail withSignatureInvalid, as intended. Scoped all-feature/all-target Clippy passed, and all 336 source hashes and 22 lockfiles matched before/after and local Git. These test executions overlap and are not a unique-case total.The first EC2 dispatch failed before testing because its shallow checkout lacked a bundle prerequisite; that failure was retained, and the successful second attempt fetched the exact published source. Full workspace CI, conformance/performance ratchets and main-merge review remain required. No ZK query-proof credential-authentication or performance result is claimed.
Tracks
zkp-14.2; broader typed-option validation is tracked separately aszkp-14.3.Review follow-up at
ce0f3c566: the published-vector test now checks the verifier-returned configuration (including created), verifies reversed triple order, and locates exactly one tampering target by subject/predicate instead of array position. Product code and dependencies are unchanged. Targeted execution of this test-only follow-up is pending; the earlier runtime evidence remains attributed toca4d74c.Benchmark
Not run: the change replaces two RDF constants in the proof configuration (
dcterms:created,sec:cryptosuiteString), and no engine hot path changes. The local gate results are in the PR comments.Generated by Claude Code