Summary
VCDM 2.0 §7.1 Verification
defines a ProblemDetails object (modeled after
RFC 9457) with type, code,
title, and detail fields, and seeds it with a very small registry —
currently only:
PARSING_ERROR
CRYPTOGRAPHIC_SECURITY_ERROR
MALFORMED_VALUE_ERROR
RANGE_ERROR
That set is sufficient to describe generic VC failures, but it cannot
describe failures that are unique to the Open Badges data model.
Verifier implementations are already inventing ad-hoc type URIs to
fill the gap, which means:
- Verifiers disagree on the wire about how to identify the same failure.
- Wallets, registries, and dashboards can't render or branch on
OB-specific problems in a portable way.
- Conformance tests have no canonical strings to assert against.
I'd like to propose that OB 3.1 add an OB-specific Problem Details
registry, published additively in the OB vocabulary file
(purl.imsglobal.org/spec/vc/ob/vocab.html),
so verifier implementations have a stable, OB-scoped namespace of
ProblemDetails.type URIs to emit.
Example
This example may or may not be something we choose to address as
a specific case, or we may identify an umbrella category over several
similar errors to use. But to use as an example, think, does it seem
likely looking at this that there would be an Open Badges-specific
processing error that we would want to identify by code specifically?
§9.1 OpenBadgeCredential Verification
requires that the credential conforms to the OB schema, but the OB data
model encodes intra-credential relationships that JSON Schema alone
cannot validate. The clearest example is the Result →
ResultDescription link:
- §B.1.16 Result
defines result.resultDescription as a URI whose value MUST be the
id of a ResultDescription in the achievement that is being
asserted.
- §B.1.17 ResultDescription
defines that id on the achievement side.
A credential like this is schema-valid but semantically broken:
{
"credentialSubject": {
"type": ["AchievementSubject"],
"achievement": {
"id": "https://example.org/achievements/math-101",
"type": ["Achievement"],
"resultDescription": [
{ "id": "urn:uuid:aaaa", "type": ["ResultDescription"], "resultType": "LetterGrade" }
]
},
"result": [
{ "type": ["Result"], "value": "A", "resultDescription": "urn:uuid:bbbb" }
]
}
}
The result[0].resultDescription points at urn:uuid:bbbb, which does
not exist in achievement.resultDescription. None of the four
VCDM-registered problem types describes this:
- It is not a
PARSING_ERROR — the JSON parsed fine.
- It is not a
CRYPTOGRAPHIC_SECURITY_ERROR — the proof can verify.
- It is not a
MALFORMED_VALUE_ERROR — the URI is a well-formed URI.
- It is not a
RANGE_ERROR — there is no numeric or temporal range
involved.
A verifier today has to either (a) emit a generic problem with a
free-text detail (lossy, not machine-actionable) or (b) mint an
unofficial type URI like …#OBV3_INVALID_RESULT_REFERENCE
(interoperable only by accident).
The same shape applies to other OB-only constraints, e.g.:
Result.status is required when the linked
ResultDescription.resultType is Status (§B.1.16) — schema can't
enforce the conditional.
Result.achievedLevel MUST be the id of a RubricCriterionLevel in
the linked ResultDescription (§B.1.16) — same cross-reference
problem as above.
IdentityObject.identityHash MUST be derivable from the salt and
known identifier per
§9.3 — a
recipient-verification failure is OB-specific.
- An
EndorsementCredential embedded inside an OpenBadgeCredential
failing its own §9.2 verification is an OB-specific composite
failure.
Each of these would benefit from a stable, registered
ProblemDetails.type URI.
Proposal
-
Reserve an OB Problem Type namespace in the OB vocabulary file,
e.g. https://purl.imsglobal.org/spec/vc/ob/vocab.html#… or a
dedicated …/problem-types/… path, parallel to how
achievementType and resultType are enumerated today.
-
Define an initial set of OB-specific problem types corresponding
to the verification steps in §9.1–§9.3 that VCDM's registry can't
express. A list of some example problems we might decide on, derived
from verifier use cases:
Suggested type token |
Emitted when |
Spec anchor |
OB_INVALID_RESULT_REFERENCE |
result[].resultDescription references an id not present in achievement.resultDescription |
§B.1.16 |
OB_INVALID_ACHIEVED_LEVEL |
result[].achievedLevel references an id not present in the linked ResultDescription.rubricCriterionLevel |
§B.1.16 |
OB_MISSING_RESULT_STATUS |
result[].status is absent when the linked ResultDescription.resultType is Status |
§B.1.16 |
OB_RECIPIENT_VERIFICATION_FAILED |
§9.3 recipient verification ran and produced no match |
§9.3 |
OB_ENDORSEMENT_VERIFICATION_FAILED |
An embedded EndorsementCredential failed §9.2 verification |
§9.2 |
OB_UNKNOWN_ACHIEVEMENT_TYPE |
achievement.achievementType is not in the AchievementType enumeration or a registered extension |
vocab |
The exact names and level are negotiable; the important thing is that some
canonical URI exists per failure mode that we might want to document.
-
Specify minimum data so the registry is usable:
- Each entry has a stable URI (the
type value), a normative
title, the verification step that emits it, and guidance on what
detail SHOULD contain.
- Verifiers MAY emit additional
type URIs outside the registry
(matching VCDM's open-world stance), but registry entries MUST be
used when applicable.
- Consider whether OB also defines numeric
code values or leaves
code optional (as VCDM does).
-
Cross-link from OB Spec §9
so each numbered verification step in §9.1/§9.2/§9.3 names the
problem type(s) it produces on failure. This is what makes the registry
actionable for conformance testing.
Adding URIs to the vocabulary file is additive not breaking — existing 3.0
verifiers that don't recognize new type values can still treat them
as opaque strings, which is exactly what VCDM §7.1 already requires. So
the change is low-risk for deployed implementations while giving 3.1+
verifiers a portable error contract. Codes could be deprecated over time.
Summary
VCDM 2.0 §7.1 Verification
defines a
ProblemDetailsobject (modeled afterRFC 9457) with
type,code,title, anddetailfields, and seeds it with a very small registry —currently only:
PARSING_ERRORCRYPTOGRAPHIC_SECURITY_ERRORMALFORMED_VALUE_ERRORRANGE_ERRORThat set is sufficient to describe generic VC failures, but it cannot
describe failures that are unique to the Open Badges data model.
Verifier implementations are already inventing ad-hoc
typeURIs tofill the gap, which means:
OB-specific problems in a portable way.
I'd like to propose that OB 3.1 add an OB-specific Problem Details
registry, published additively in the OB vocabulary file
(purl.imsglobal.org/spec/vc/ob/vocab.html),
so verifier implementations have a stable, OB-scoped namespace of
ProblemDetails.typeURIs to emit.Example
This example may or may not be something we choose to address as
a specific case, or we may identify an umbrella category over several
similar errors to use. But to use as an example, think, does it seem
likely looking at this that there would be an Open Badges-specific
processing error that we would want to identify by code specifically?
§9.1 OpenBadgeCredential Verification
requires that the credential conforms to the OB schema, but the OB data
model encodes intra-credential relationships that JSON Schema alone
cannot validate. The clearest example is the
Result→ResultDescriptionlink:defines
result.resultDescriptionas a URI whose value MUST be theidof aResultDescriptionin the achievement that is beingasserted.
defines that
idon the achievement side.A credential like this is schema-valid but semantically broken:
{ "credentialSubject": { "type": ["AchievementSubject"], "achievement": { "id": "https://example.org/achievements/math-101", "type": ["Achievement"], "resultDescription": [ { "id": "urn:uuid:aaaa", "type": ["ResultDescription"], "resultType": "LetterGrade" } ] }, "result": [ { "type": ["Result"], "value": "A", "resultDescription": "urn:uuid:bbbb" } ] } }The
result[0].resultDescriptionpoints aturn:uuid:bbbb, which doesnot exist in
achievement.resultDescription. None of the fourVCDM-registered problem types describes this:
PARSING_ERROR— the JSON parsed fine.CRYPTOGRAPHIC_SECURITY_ERROR— the proof can verify.MALFORMED_VALUE_ERROR— the URI is a well-formed URI.RANGE_ERROR— there is no numeric or temporal rangeinvolved.
A verifier today has to either (a) emit a generic problem with a
free-text
detail(lossy, not machine-actionable) or (b) mint anunofficial
typeURI like…#OBV3_INVALID_RESULT_REFERENCE(interoperable only by accident).
The same shape applies to other OB-only constraints, e.g.:
Result.statusis required when the linkedResultDescription.resultTypeisStatus(§B.1.16) — schema can'tenforce the conditional.
Result.achievedLevelMUST be theidof aRubricCriterionLevelinthe linked
ResultDescription(§B.1.16) — same cross-referenceproblem as above.
IdentityObject.identityHashMUST be derivable from the salt andknown identifier per
§9.3 — a
recipient-verification failure is OB-specific.
EndorsementCredentialembedded inside anOpenBadgeCredentialfailing its own §9.2 verification is an OB-specific composite
failure.
Each of these would benefit from a stable, registered
ProblemDetails.typeURI.Proposal
Reserve an OB Problem Type namespace in the OB vocabulary file,
e.g.
https://purl.imsglobal.org/spec/vc/ob/vocab.html#…or adedicated
…/problem-types/…path, parallel to howachievementTypeandresultTypeare enumerated today.Define an initial set of OB-specific problem types corresponding
to the verification steps in §9.1–§9.3 that VCDM's registry can't
express. A list of some example problems we might decide on, derived
from verifier use cases:
typetokenOB_INVALID_RESULT_REFERENCEresult[].resultDescriptionreferences anidnot present inachievement.resultDescriptionOB_INVALID_ACHIEVED_LEVELresult[].achievedLevelreferences anidnot present in the linkedResultDescription.rubricCriterionLevelOB_MISSING_RESULT_STATUSresult[].statusis absent when the linkedResultDescription.resultTypeisStatusOB_RECIPIENT_VERIFICATION_FAILEDOB_ENDORSEMENT_VERIFICATION_FAILEDEndorsementCredentialfailed §9.2 verificationOB_UNKNOWN_ACHIEVEMENT_TYPEachievement.achievementTypeis not in theAchievementTypeenumeration or a registered extensionThe exact names and level are negotiable; the important thing is that some
canonical URI exists per failure mode that we might want to document.
Specify minimum data so the registry is usable:
typevalue), a normativetitle, the verification step that emits it, and guidance on whatdetailSHOULD contain.typeURIs outside the registry(matching VCDM's open-world stance), but registry entries MUST be
used when applicable.
codevalues or leavescodeoptional (as VCDM does).Cross-link from OB Spec §9
so each numbered verification step in §9.1/§9.2/§9.3 names the
problem type(s) it produces on failure. This is what makes the registry
actionable for conformance testing.
Adding URIs to the vocabulary file is additive not breaking — existing 3.0
verifiers that don't recognize new
typevalues can still treat themas opaque strings, which is exactly what VCDM §7.1 already requires. So
the change is low-risk for deployed implementations while giving 3.1+
verifiers a portable error contract. Codes could be deprecated over time.