Skip to content

Mapping projection uses a denylist, so draft and deprecated mappings emit unqualified direct edges #45

Description

@maehr

Resolved in v0.1.0

Fixed by f5a037f (PR #86). Closed by #4.

The projection now gates on RETIRED_STATUSES — deprecated, withdrawn, blocked — instead of TOMBSTONE_STATUSES. A deprecated assertion no longer emits a live edge. TOMBSTONE_STATUSES stays for the two remaining uses, which are about broken resolution, because a deprecated record still resolves.

Option 1 was declined. A draft assertion still projects. TextRefs' guarantees attach to CanonicalReference, and the Work projection is enrichment that never claimed review. standard/schema/work.ts, specification.md §6, json-ld.md and api/openapi.yaml now state that, instead of implying a promise the standard does not make.

Published output does not change. Every record in data/ is draft, so nothing is deprecated today and dist/dump/works.jsonl is byte-identical. The fix closes the hole before a demotion happens.

The code quoted below predates ADR-0006. exactMatch and closeMatch no longer exist. Read them as alternateOf and isReferencedBy.


Found while reviewing #4.

scripts/compile.ts derives the direct exactMatch / closeMatch arrays on Work by skipping only tombstoned assertions:

for (const m of src.mappings ?? []) {
  if (TOMBSTONE_STATUSES.has(m.status)) continue;   // withdrawn | blocked
  (m.relation === "exactMatch" ? exactMatches : closeMatches).push(m.identifier);
}

A denylist means draft and deprecated mappings also project into the published SKOS edges. Since ADR-0003 demoted all registry data to draft, every seed mapping currently ships as an unqualified skos:exactMatch / skos:closeMatch from the work IRI — with no status qualifier attached to the edge itself, unlike the reified MappingAssertion it came from.

A consumer that only follows the direct edges cannot tell a reviewed equivalence from an unreviewed draft one.

Two ways out:

  1. Switch to an allowlist (candidate / active), so drafts stay visible only as reified assertions. This is the behaviour the docs originally described ("accepted mapping assertions") and would emit no direct edges at all until the first promotion.
  2. Keep the current behaviour and leave the docs saying "non-tombstoned", as they do now after fix(spec): resolve normative contradictions before the v0.1.0 tag #44.

Option 1 seems right — the projection exists to be a convenience for consumers who trust the edge, and a draft edge is precisely the one that should not be trusted. Worth deciding before any consumer starts relying on the arrays.

Docs to update alongside whichever way this goes: specification.md §6, json-ld.md § Mapping relations, standard/schema/work.ts, and the Work.exactMatch / closeMatch descriptions in api/openapi.yaml.

Activity

  1. changed the title [-]Work SKOS projection uses a denylist, so draft and deprecated mappings emit unqualified skos:exactMatch[/-] [+]Mapping projection uses a denylist, so draft and deprecated mappings emit unqualified direct edges[/+] on Aug 12, 2026
  2. maehr commented on Aug 12, 2026

    @maehr
    MemberAuthor

    Retitled for ADR-0006, which replaced the SKOS relations with alternateOf / isReferencedBy. The behaviour this issue reports is unchanged — only the vocabulary moved, so this is not obsolete:

    for (const m of src.mappings ?? []) {
      if (TOMBSTONE_STATUSES.has(m.status)) continue;   // withdrawn | blocked
      mappingEdges[m.relation].push(m.identifier);
    }

    Still a denylist, so draft and deprecated assertions still project into the direct edges on Work, still without a status qualifier on the edge itself. And since ADR-0004 keeps all registry data at draft, every seed mapping in v0.1.0 ships this way — a consumer following only the direct edges cannot tell a reviewed equivalence from an unreviewed draft one.

    The two options in the original description carry over verbatim; only the relation names change. The docs to update alongside are now specification.md §6, json-ld.md § Mapping relations, standard/schema/work.ts, and the Work.alternateOf / isReferencedBy descriptions in api/openapi.yaml.

    Ships as-is in v0.1.0 — all data is draft and carries no persistence promise, so nothing is frozen by the tag.

  3. maehr commented on Aug 24, 2026

    @maehr
    MemberAuthor

    Resolved on staging in f5a037f (#86), and split — one half fixed, one half declined.

    Fixed: deprecated no longer projects. The gate excluded only withdrawn and blocked, so a mapping the registry had retired kept emitting a live, unqualified edge. That contradicted the standard's own definitions — common.ts calls deprecated/withdrawn/blocked the states for records that have left active use, and specification §12 defines deprecated as "retained but no longer recommended". The projection is now gated on the set that already meant exactly that, renamed SUPERSEDABLE_STATUSES → RETIRED_STATUSES. TOMBSTONE_STATUSES stays for the two resolution-breakage checks; a deprecated record still resolves.

    Declined: the allowlist on draft. TextRefs' guarantees attach to CanonicalReference — identity, persistence, resolution. The Work projection is enrichment and never claimed review, so gating it on promotion would buy a guarantee the standard does not make.

    It would also cost real capability. All 24 seed mappings are draft, and the compiled Work carries no back-link to its assertions — /id/work/{key}.json publishes the record verbatim and there is no /reg/mapping/ index. Under an allowlist, v0.1.0 works would lose their only machine-readable path to Wikidata, and restoring it would mean adding a mappings field, a context term, and an ADR — a large change to repair damage the allowlist itself caused.

    So the docs now say what the arrays are for instead of implying a promise: specification §6 and json-ld.md state that the arrays enrich the work, make no claim about review, and that a consumer needing status reads the MappingAssertion.

    Nothing ships differently. Every record in data/ is draft, so no assertion is deprecated today — dist/dump/works.jsonl is byte-identical before and after (b35b36e2…). The fix closes the hole before a demotion ever happens. #68 §4 needed no revision.

  4. added
    addressed-in-v0.1.0Addressed in the v0.1.0 release (PR #4)
    bugSomething isn't working
    standardThe published specification and schemas
    and removed
    enhancementNew feature or request
    on Aug 25, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    addressed-in-v0.1.0Addressed in the v0.1.0 release (PR #4)bugSomething isn't workingstandardThe published specification and schemas

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions