ADR-024: A remote reference is a prefix, a delimiter and a uid — numbers are the special case

Status Active · Filed 2026-08-04 · Influenced by ADR-016 · ADR-023 · Influenced ADR-025

Context

Every remote reference assumed the Luria shape: PREFIX-SCHEME-NUMBER, with a hyphen hardcoded in the composed pattern and int(number) baked into normalisation, construction and the anchor template. That assumption is correct for citing another project’s record and wrong for the wider use the machinery is obviously good for: any externally-identified artifact with a mechanical URL. The motivating example is arxiv — a contributor wants to write ARXIV-2403.05530 in prose and have the fixer, the lint and the resolution rungs treat it exactly like SG-ADR-032.

The number assumption was not one assumption but five, spread across the composed-code regex, normalise, Remote.link, the annotation-argument parser and the url-ok label matcher — each spelling the hyphen and the digit shape independently.

Decision

A remote may declare its references’ shape:

[luria.remotes.ARXIV]
uid = "(\\d{4})[.:](\\d{4,5})"
url = "https://arxiv.org/abs/{1}.{2}"

[luria.remotes.JIRA]
delim = ":"                       # JIRA:PROJ-42 — uids may contain hyphens
uid = "[A-Z]+-\\d+"
url = "https://example.atlassian.net/browse/{uid}"
  • delim (default -) separates the prefix from the tail. Configurable because a uid’s own alphabet may include the conventional delimiter.
  • uid is a regex for the tail. Unset means the Luria scheme shape — everything works as before. Set, the tail is an opaque identifier.
  • The template indexes by position: {0}/{uid} is the whole tail, {1}… are the uid pattern’s capture groups, so one template can restructure the identifier (1234:56781234.5678).

Three rules with teeth:

  • A uid is exact, never normalised. ADR-32 and ADR-032 are one document; 2403.05530 is itself. Zero-padding an arxiv id would quietly cite a different paper, which is the ADR-016 guessing failure wearing a new costume.
  • One rung. No lockfile (it maps filenames; there are none), no code-only convention (there is no convention to fall back on). A uid remote without a url template constructs nothing, and ref-status reports the citation as dangling — say what you can’t do rather than invent (DP-1).
  • An unconfigured prefix never matches. The pattern is built from config, as always — FAKE-1234.5678 is prose, not a namespace.

The refactor this forced was overdue: the one combined regex became per-remote patterns behind two functions — references(text) for scanning and parse_code(text) for exact-match parsing — and every consumer (the fixer, the citation scan, the annotation-argument parser, the url-ok label matcher, the dangling check) now goes through them. The delimiter and tail shape are spelled in exactly one place (DP-4); the previous layout spelled the hyphen five times.

Alternatives considered

  • Overload schemes for uid families (ADR-023’s mechanism). A scheme implies documents with statuses, an index, a pending-report row; an arxiv paper has none of those. Wedging uids in would either fake frontmatter semantics for things that aren’t documents or fork the scheme code with if uid branches — the shape belongs on the remote, where “what does a reference look like” already lives.
  • Auto-linkify recognizable shapes without registration (every \w+-\d{4}\.\d{4,5} becomes an arxiv link). The rule an unconfigured prefix must never match exists because prose is full of hyphenated words in front of numbers; guessing namespaces from shape is how a tool starts editing sentences that weren’t references.
  • A dedicated [luria.links] mini-language separate from remotes. A second registry with its own prefix rules, its own pattern builder and its own url-ok story — everything the remote machinery already has, reimplemented beside it.

Consequences

  • The reference machinery is shape-agnostic end to end: the fixer writes [ARXIV-2403.05530](https://arxiv.org/abs/2403.05530) from bare prose, the lint demands it, url-ok acknowledges a hand-targeted variant (the v2 PDF, say), and --check probes template URLs directly — a uid remote with no repo is checkable per-URL rather than gated on a repository landing page.
  • luria remotes --refresh says “a uid remote — nothing to discover” rather than silently skipping.
  • Composed report keys are no longer assumed to split on a hyphen; anything reading a code’s anatomy goes through parse_code.
  • Wikilink-style insertion ([[ARXIV-2403.05530]]) is a separate, deliberately unbundled question — this decision makes the reference shape general; how references are typed is its own issue.