Skip to content

Add problem details registry for OB errors #632

@ottonomy

Description

@ottonomy

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

  1. 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.

  2. 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.

  3. 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).
  4. 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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions