Link Resolution

A language model writes [[Attention Is All You Need]]. The file it saved is attention-is-all-you-need.md. Every other viewer treats those as different things and shows you a dead link.

Detangle tries thirteen rules in order and stops at the first that matches. The order matters: exact answers are always preferred over clever ones.

The chain

#RuleMatches
1Exact vault path[[wiki/setup/index]]wiki/setup/index.md
2Note-relative patha sibling file, from the linking page's own folder
3Case-sensitive filename[[setup]]setup.md anywhere in the vault
4Path suffix[[setup/index]]docs/setup/index.md
5Case-insensitive filename[[Setup]]setup.md
6Normalized name[[Attention Is All You Need]]attention-is-all-you-need.md
7Alias or titlea name from aliases:, title:, or the first H1
8Identifierid:, uid:, permalink: or slug: from frontmatter
9Folder index[Setup](wiki/setup)wiki/setup/index.md
10Encoding variantpercent-encoding, and Unicode composed against decomposed
11Extension probe![[diagram]]assets/diagram.png
12Nearest nameoffered as a suggestion, never followed automatically
13Placeholdernothing matched; the link is reported, not hidden

Markdown links swap steps 1 and 2: [text](setup.md) in a CommonMark file means the file beside this one, and every other tool in the world reads it that way.

Normalization

Steps 5 onward compare normalized names. Normalizing means: Unicode NFC, percent-decode, trim, drop a known extension, backslashes to forward slashes, lowercase, then collapse every run of spaces, underscores and dots into a single hyphen.

So My Note.md, my_note, My%20Note and my.note are all the same name.

Provenance

Every resolved link carries the rule that resolved it, and the reader shows it:

A viewer that guesses without telling you is worse than one that fails loudly. The whole design here is that a guess is always visible as a guess.

Ambiguity

When a rule matches more than one file, Detangle picks the shortest path, then alphabetical order, and marks the link ambiguous. Every candidate is listed, and choosing one is remembered for that vault.

Anchors

A fragment is matched against the raw heading text first (case-insensitively, which is the Obsidian rule), then the github-slugger slug including its -1/-2 dedup counters, then ^blockid markers, then Logseq id:: uuids, then #L10-L20 line ranges, then #page=N.

An anchor that matches nothing never fails the link — you still land on the page, with a warning.

See also Formats and Link Doctor.