Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 8 additions & 1 deletion .github/workflows/links.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,14 @@ jobs:
- name: Collect external URLs from sources
run: |
mkdir -p lychee
grep -rhoE 'https?://[^"'\''<>) ]+' data/ src/content/docs/ \
# Allow `)` inside URLs (Wikipedia disambiguation titles), then strip
# a single trailing `)` only when unbalanced (handles markdown
# `[text](url)`). Drop resolver templates containing `{placeholder}`.
# Restrict to YAML/MD so lockfiles inside data/ are not scanned.
grep -rhoE --include='*.yaml' --include='*.yml' --include='*.md' --include='*.mdx' \
'https?://[^]["'\''<>[:space:]]+' data/ src/content/docs/ \
| awk '{ n=gsub(/\(/,"&"); m=gsub(/\)/,"&"); if (m>n) sub(/\)$/,""); print }' \
| grep -v '[{}]' \
| sed -E 's/[.,;:]+$//' \
| sort -u > lychee/urls.txt
echo "Collected $(wc -l < lychee/urls.txt) unique URLs"
Expand Down
5 changes: 2 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,11 @@ A contribution does not create a claim to acceptance, prioritization, publicatio

## Review tracks

Changes are routed to one of two tracks:
Changes are routed to one of three tracks:

- **Technical review** — typos, formatting, broken links, minor metadata, `last_checked` updates, uncontested aliases, build / tooling fixes. Needs automated validation and one technical reviewer.
- **Expert review** — new works, new citation systems, new corpora, contested mappings, changes to deterministic ID inputs, status changes (`active` / `deprecated` / `withdrawn` / `blocked`). Needs technical validation, a documented rationale with sources, and at least one expert reviewer.

The Board reserves decisions on legal or policy-sensitive matters (takedowns, blocking, licence policy).
- **Board reservation** — takedowns, blocking, licence policy, and other legal or policy-sensitive matters. Decided by the Association Board.

```mermaid
flowchart TD
Expand Down
57 changes: 57 additions & 0 deletions decisions/ADR-0001-conforms-to-replaces-target-kind.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# ADR-0001: Replace `target_kind` with `dcterms:conformsTo`

- **Status:** Proposed
- **Date:** 2026-06-09
- **Deciders:** @maehr
- **Tags:** spec

## Context and problem statement

`MappingAssertion.target.target_kind` was introduced as an OPTIONAL human-readable scheme hint (`"cts"`, `"wikidata"`, `"doi"`, …). The spec already says validators MUST NOT key behaviour off it and the IRI in `identifier` is authoritative. Issue [#6](https://github.com/textrefs/textrefs.org/issues/6) observes that a field with no normative weight, accompanied by Appendix B's enumerated list of "known" scheme labels, is upkeep without payoff: every new scheme means another table row to police.

Linked Art's [digital integration model](https://linked.art/model/digital/) handles the same problem with `conforms_to` pointing at the relevant specification (e.g. the IIIF profile URI), letting the IRI carry the conformance claim without a curated label registry.

## Decision drivers

- The field is already non-normative; the IRI is authoritative.
- Appendix B's label column would otherwise grow indefinitely.
- Pre-v1.0.0 — breaking field renames are still acceptable.
- Want to align with established Linked Data practice rather than invent a TextRefs-specific convention.

## Considered options

1. **Replace `target_kind` with `conforms_to`** — drop the field, introduce an optional `target.conforms_to` typed as `dcterms:conformsTo` in the JSON-LD context, accepting an IRI or array of IRIs.
2. **Deprecate `target_kind`, keep accepting it** — add `conforms_to` alongside, mark `target_kind` deprecated. Smoother for downstream consumers; carries the dead field into v1.
3. **Leave `target_kind` as-is** — no change. Fails to address the upkeep concern that prompted the issue.

## Decision

We choose **Option 1**. The replacement happens before v1.0.0 freezes the schema, so a clean break is preferable to carrying a deprecated field into the stable surface. `target.conforms_to` is OPTIONAL; the registry will not synthesise values where none are known. Multiple IRIs are allowed via array form so a target can claim conformance to several specifications.

In the JSON-LD context, `conforms_to` maps to `dcterms:conformsTo` with `@type: @id` so the value is treated as an IRI reference.

## Consequences

### Positive

- One less curated label registry to maintain.
- IRIs are self-describing; conformance claims are dereferenceable.
- Aligns with Linked Art's established pattern.

### Negative / trade-offs

- Breaking rename for any downstream consumer that read `target_kind`. Acceptable pre-v1.0.0.
- Coordinated change across two repos (`textrefs/textrefs.org` schema/docs, `textrefs/registry` YAML data).

### Follow-up actions

- [x] Update spec §10 and Appendix B.
- [x] Update the v1 JSON-LD context.
- [x] Update Zod schema, compile pipeline, and in-tree fixture.
- [x] Migrate `data/works/*.yaml` in `textrefs/registry` (carried by registry PR #1).
- [x] Bump `data/` submodule pointer to the migrated registry commit.

## Links

- Related issues / PRs: textrefs/textrefs.org#6, textrefs/textrefs.org#5, textrefs/registry#1
- External references: [Linked Art — Digital Integration](https://linked.art/model/digital/), [DCMI Terms — conformsTo](http://purl.org/dc/terms/conformsTo)
1 change: 1 addition & 0 deletions lychee.toml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ exclude = [
"^https?://([a-z0-9-]+\\.)*linkedin\\.com",
"^https?://([a-z0-9-]+\\.)*twitter\\.com",
"^https?://([a-z0-9-]+\\.)*x\\.com",
"^https?://([a-z0-9-]+\\.)*opencollective\\.com",
"^https?://localhost(:\\d+)?(/|$)",
]

Expand Down
Loading
Loading