← Changelog

Every Link Form Works, and Nothing Needs Converting

Obsidian wikilinks, with or without .md, and markdown links are all valid now. A new resolver shows where each one lands.

Path
changelog/2026-11-05_01.md
Authors
Michael Staton
Augmented with
Claude Code on Claude Opus 5.5
Tags
Context-Vigilance · Links · OKF · Survey

Why Care?

We write links the way Obsidian does, and thousands of them already exist across our repos. Rewriting them to suit a tool would be the wrong way round: the tools should read what people actually write. So now they do, and no doc had to change.

We also wanted a straight answer to a simple question: do these links go anywhere? Across the whole Lossless tree, 4,682 of 5,093 links resolve. The rest are mostly links to docs not written yet, or names that match more than one file.

What's New?

  • A new default for new docs: [[specs/Payment-Retry-Policy|Payment Retry Policy]] , the file's path with no .md , then the display text. Obsidian doesn't need the extension, and our docs were already written this way.

  • Every other form stays valid: a path with .md , a bare [[File-Name]] , [[File-Name#Heading|Display Text]] , and regular markdown links.

  • A link resolver, links.py : it reports where every link lands, which ones point at a moved file, and which match several docs. It never edits a doc.

  • The site reads them all: several link forms that used to break on the site now work.

  • An OKF export, okf_export.py : it writes a strict Open Knowledge Format copy for any tool that needs one, and your docs stay as they are.

How it Works

The resolver tries the path first, then a unique filename in the bundle, the repo, and the whole tree. If several files match, it reports the link as ambiguous instead of guessing. If none match, it reports the link as unwritten, which is fine for a doc that doesn't exist yet.

BASH
python3 agent-skills/survey/scripts/links.py [PATH] --scope repo   # or tree, lineage

Across the tree, it found:

Result Links
Resolved 4,682
Unwritten 298
Ambiguous 113

Of the resolved links, 80 have a path that's gone but a filename that still finds the doc, usually after a move. Most ambiguous links are skill names that exist in more than one place.

Under the Hood

The site. It used to turn a path with no .md into a GitHub URL that returned a 404 when the doc wasn't on the site. It also dropped heading links, broke on the escaped pipe a wikilink needs inside a table, and rewrote links shown as examples in code. Relative markdown links went through untouched and were dead on the page. Now each link goes to its page on the site, or to its file on GitHub, or stays as plain text if there's nothing to point at. Code is left as written.

Two more dead links on the site. The source link on doc pages used a lowercased slug, and GitHub paths are case-sensitive, so it returned a 404. It now uses the file's real path. The one-repo survey examples linked to files on the machine that generated them; they now link to GitHub.

The export. In the copy, Draft becomes OKF's draft , with the original kept in context_v_status . A doc with no status exports as draft , because OKF reads a missing status as stable , a claim nobody made. Wikilinks become relative markdown links inside a bundle and GitHub URLs across bundles. Private docs and client or collaborator bundles stay out by default.

Still rough. Heading anchors can miss on headings with version numbers, because LFM builds those IDs differently: "Release, 0.5.1" becomes release-05 , and our link code gives release-051 . No doc in this repo links to a heading yet. The export also leaves a few wikilinks unconverted, such as ones wrapped across lines, and we haven't run it through an outside OKF tool.