Repository navigation
Secondary formats: vc+jwt, CAIP-261, i,j,v CSV, AT Protocol/Nostr labels, schema.org - #27
Open
harlantwood wants to merge 3 commits into
Open
harlantwood wants to merge 3 commits into
harlantwood wants to merge 3 commits into
Conversation
- jose: Trust Atom credentials secured as application/vc+jwt (VC-JOSE-COSE), alg Ed25519 (RFC 9864; legacy EdDSA accepted on verify). The payload is exactly the unsecured v1 credential (JCS), so signing is deterministic; verification is as strict as the Data Integrity path (typ, kid = issuer's did:key method, no crit/b64, strict base64url, v1 profile, no JWT claims). - export: shared "current atoms" loader (signed credentials verified, replaced ones dropped, latest per source/target/content), plus CAIP-261 PeerTrustCredential export and import (one credential per source and target, as the spec's supersession rule requires), the OpenRank/EigenTrust i,j,v CSV (non-positive edges dropped by default), unsigned AT Protocol labels (with neg retractions) and Nostr NIP-32 kind 1985 event templates, and schema.org Review/Rating JSON-LD. - api + wasm + node + d.ts: signVcJwt, verifyVcJwt, toPeerTrust, fromPeerTrust, toIjvCsv, toAtprotoLabels, toNostrLabels, toSchemaOrg. - CLI: trust convert --to vc-jwt|caip-261|ijv-csv|atproto-label| nostr-label|schema-org, --from vc-jwt|caip-261; trust verify accepts vc+jwt tokens. - Golden files in test-vectors/exports; JS interop with jose (byte- identical JWTs both ways); docs in doc/formats/. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UdKneRqUnsbv1t7NyvcT68
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UdKneRqUnsbv1t7NyvcT68
…laude/export-formats-bsuvj4
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
TL;DR
Trust Atoms can now be signed as
application/vc+jwt(W3C VC-JOSE-COSE,alg: Ed25519) and verified as strictly as Data Integrity, and exported to CAIP-261PeerTrustCredential(import too), the OpenRank/EigenTrusti,j,vCSV, unsigned AT Protocol labels and Nostr NIP-32 events, and schema.orgReviewJSON-LD. All of it is pure core code behindapi, and the same functions are in wasm, node,d.tsandtrust convert.Stacked on #26 (v1 formats: CIDv1 IDs, strict profile,
replaces). Its base isclaude/v1-formats-bsuvj4. Once #26 merges it will be retargeted tomaster. It composes with #23 (Reputon) because it uses the sameconvertshape:--tois optional when--fromis given, and there is anInputFormatenum. Expect a small textual merge incli.rs/commands.rs/api.rs.What it does
application/vc+jwt(trustgraph_core::jose)Payload is exactly the unsecured v1 credential, written as JCS. The protected header is
{"alg":"Ed25519","cty":"vc","kid":"did:key:z…#z…","typ":"vc+jwt"}, also canonical. Signing is therefore deterministic, and thejoselibrary produces byte-identical tokens (checked in CI).alg: we writeEd25519(RFC 9864, Oct 2025, deprecates polymorphicEdDSA). On verify we also acceptEdDSA, because adid:keyEd25519 key makes it unambiguous.Verification is as strict as the DI path. It requires:
typ=vc+jwt, andctyabsent orvccritorb64kid= the issuer'sdid:keyMultikey method (VC-JOSE-COSE §4.1.1)validFromand noproofJWT claims (
iss/iat/exp/vc) are rejected because they are not in the profile, which also keeps verification clock-free. Unknown header params are ignored (RFC 7515).credentialIdof a JWT is the CID of its bytes.idis the same atom ID as the DI form.Exports (
trustgraph_core::export)replaces) are dropped, and the latest atom per source/target/content wins, the same rules as the lens.issuanceDate, 2018 context).content↔scope,value↔level(number),extra.reason↔reason[].i,j,vCSV:i,j,v, rows sorted, RFC 4180 quoting.--negative keepwrites them anyway.--topicfilters.{ver:1, src (must be a DID), uri, val, neg?, cts}.trusted/distrusted, ortrusted-<topic-slug>. The spec says no numbers.neglabels retract what superseded atoms would have labelled.#atproto_labelkey.kind:1985templates, namespacenet.trustgraph.nostr:npub1…→ptag (bech32 checked),nostr:note1…→e, anything else →r.@graphofReviews:@idisipfs://<atom ID>author/itemReviewedRatingwithratingValue,bestRating: 1,worstRating: -1, andreviewAspectSurfaces
api, wasm, node, d.ts:signVcJwt,verifyVcJwt,toPeerTrust,fromPeerTrust,toIjvCsv,toAtprotoLabels,toNostrLabels,toSchemaOrg.trust convert --to vc-jwt|caip-261|ijv-csv|atproto-label|nostr-label|schema-org--from vc-jwt|caip-261--to vc-jwtsigns with--key.trust verifyand the input reader accepteyJ…tokens, one per line.doc/formats/{vc-jwt,caip-261,ijv-csv,labels,schema-org}.md, each citing its primary sources. Also README format table, architecture API table, and protocol §10.test-vectors/exports/(one input with the W3C test key, one output per format), regenerated byte-for-byte bytests/exports.rs.Size
WebAssembly: 645 KiB (260 KiB gzipped), up from 558 KiB on the base branch. The 1 MiB budget still holds, with no new Rust dependencies: base64url and bech32 are small hand-rolled modules.
Verified
cargo fmt --all --checkRUSTFLAGS=-D warnings:cargo clippy --workspace --all-targets --lockedon stable and on+1.99cargo clippy -p trustgraph-core --all-targets --lockedon stable and on+1.99cargo clippy --target wasm32-unknown-unknown -p trustgraph-core -p trustgraph-wasmRUSTDOCFLAGS=-D warnings cargo doc --workspace --no-deps --lockedscripts/check-core-purity.shcargo test --workspace --lockedon stable and on 1.85 (MSRV)scripts/build-wasm-package.sh, thensmoke.mjs(wasm node + web) andinterop.mjs(wasm).interop.mjsnow includesjose@6.2.12:jwtVerify(alg: Ed25519,typ: vc+jwt)EdDSAtyp, missingkid,iat, avcwrapper andcritsmoke.mjsandinterop.mjspnpm run typecheckNot in this PR
vc+jwtin the local store and using it in the lens. For now, convert with--from vc-jwt.#atproto_label) and Nostr (secp256k1 Schnorr). This needs non-Ed25519 keys and is deliberately not added.eddsa-jcs-2022proof on exported CAIP-261 credentials, and a published CAIP-261 JSON Schema. The spec requirescredentialSchemabut publishes none.eddsa-rdfc-2022proof,vc+sd-jwt/vc+cose. SD-JWT VC, BBS and mdoc are out of scope.🤖 Generated with Claude Code
https://claude.ai/code/session_01UdKneRqUnsbv1t7NyvcT68
Generated by Claude Code