ADR-025: Wikilinks: [[CODE]] is a typed reference, and typing it changes the rules
Status Active · Filed 2026-08-04 · Issue #9 · Influenced by ADR-005 · ADR-024
Context
The bare-reference scanner is conservative by design: masking rules, an
ambiguity heuristic for low #N, prefixes that never match unregistered, and
a DP-N spelling it deliberately does not take without a #. Right for
prose — a confidently wrong link is worse than a bare code — but it leaves no
way for an author to assert a reference the heuristics would pass over, and
no syntax familiar to the Obsidian/Roam/wiki muscle memory that types
[[…]] reflexively.
ADR-024 made the reference shape general and deliberately unbundled how references are typed. This is that half (#9).
Decision
[[CODE]] and [[CODE|label]] are typed references. The inner text may be
anything the machinery can construct a target for, tried in order: a foreign
code in any registered shape (ADR-016, ADR-024),
a local scheme code — including the bare DP-3 spelling and a
document-rendered scheme’s anchor — and an issue number.
The brackets change the rules symmetrically:
- No heuristics inside.
[[#10|10]]needs no cue word — the brackets are the cue. The low-#Nambiguity rule exists to avoid guessing about prose; there is nothing to guess about here. - No silence outside. An unresolvable wikilink is a lint violation,
not a bare code left alone. This is the one deliberate exception to the
invariant that the lint never demands what
--fixcannot do (ADR-005) — the author explicitly asked, so the refusal must be explicit too (DP-1). The message names the three likely causes: a typo, an unregistered prefix, a self-link.
Wikilinks are consumed, not rendered. luria link --fix rewrites them
into ordinary markdown links — an <a href> inside a raw-HTML block, where
markdown wouldn’t render — and the committed source contains no brackets.
GitHub renders [[…]] as literal text, and sources are read directly
wherever views aren’t generated (the decisions, every fragment), so leaving
the syntax in place would trade a moment of authoring convenience for a
permanently broken reading surface.
One masking rule keeps the checks disjoint: a wikilink’s span is masked from
the prose scanner, so [[ADR-013]] is one demand (the wikilink check’s),
never two. A wikilink in backticks is a quoted specimen, as everywhere else.
Alternatives considered
- Expand at view-generation time (leave
[[…]]in sources, render on assembly). Fails exactly where the record lives: decision files and journal entries are read in place, arrived at by link, and GitHub shows them with literal brackets. The collected/generated split (ADR-012) doesn’t help — sources are a reading surface here, per the read/write boundary’s own rule that a source arrived at by link is the reading experience (ADR-021). - Make the prose scanner more aggressive instead. The heuristics exist because prose is full of code-shaped non-references; loosening them trades a typed opt-in for a global increase in wrong links. The brackets are consent, per reference.
[[target|label]]deferred. Considered and kept — it is one optional group in the regex and the label slot is where half the value lives (citing a paper by name rather than by its arxiv id).
Consequences
- The authoring loop for any reference becomes: type
[[X]], runluria link --fix(or let the lint remind you), commit plain markdown. - A lingering
[[X]]in a merged file is always a violation — either fix the code or register the prefix; there is no acknowledged state for a broken explicit reference, unlikeurl-ok’s domain where the target is hand-chosen but valid. - The fixer’s rewrite count includes expansions, so
luria linkreports them like any other fix.