feat(vc): upgrade to W3C VC Data Model v2.0 (Phase 1, dual-accept)#72
Merged
Conversation
Newly issued credentials use VC v2: @context points to https://www.w3.org/ns/credentials/v2 and the timestamp fields are `validFrom` / `validUntil`. Verification is dual-accept — it still recognises legacy v1 envelopes (`issuanceDate` / `expirationDate`) so credentials minted before this migration keep verifying until the dataset rotates. Changes: - app/credentials.py: emit v2, add vc_valid_from/vc_valid_until helpers, verify_credential reads expiry via helper (accepts both shapes). - app/swarm/endorsement.py: SkillEndorsementCredential issued as v2. - app/main.py: VerifiedMusicCredential (both build paths) issued as v2. All DB-insert call-sites that used to parse vc["issuanceDate"] / vc["expirationDate"] now go through the helpers. - backfill_credentials.py, agent/ambassador.py: same helper-based read. - tests/test_credentials_vc_v2.py: 10 tests covering helper fallback semantics, v2 issuance shape, v1 legacy verify, v2 roundtrip, expiry. Out of scope (intentional): - credentialSubject.provenance.issuanceDate on Music VCs — internal moltrust vocabulary, not the W3C VC core field. - ViolationRecord — separate @context (moltrust/ns/violation/v1), not a W3C VC, no VerifiableCredential type. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Summary
@contextpoints tohttps://www.w3.org/ns/credentials/v2, timestamp fields arevalidFrom/validUntil.verify_credentialis dual-accept: still recognises legacy v1 envelopes (issuanceDate/expirationDate) so credentials minted before this PR keep verifying until the dataset rotates.vc_valid_from,vc_valid_until) replace direct field reads at every DB-insert call-site.Wire-Check (before)
Wire-Check (after)
Touched files
app/credentials.pyvc_valid_from/vc_valid_untilhelpers + dual-read inverify_credentialapp/swarm/endorsement.pySkillEndorsementCredentialemitted as v2app/main.pyVerifiedMusicCredential(both build paths) as v2; DB-insert call-sites switched to helpersbackfill_credentials.py,agent/ambassador.pytests/test_credentials_vc_v2.pyOut of scope (intentional)
credentialSubject.provenance.issuanceDateon Music VCs — internal MolTrust vocabulary, not the W3C VC core field.ViolationRecord(@context: https://moltrust.ch/ns/violation/v1) — not a W3C VC, noVerifiableCredentialtype.Test plan
pytest tests/test_credentials_vc_v2.py— 10/10 pass (server scratch checkout w/ venv)from app.main import app→ OKpython -m compileallon all touched files → clean/credentials/issueagainst staging, confirm response carriesvalidFrom/validUntilnotissuanceDate/expirationDate/credentials/verifyagainst a legacy v1 credential pulled from thecredentialstable — confirm it still validatesNotes for review
raw_vcrows incredentialstable, retire helpers.issued_at/expires_atcolumns absorb the v2 timestamps just fine via the helpers.🤖 Generated with Claude Code