Wikilinks¶
Context
The citation and crosslinking contract for an agent-maintained wiki. When the agent answers a query from the wiki, it cites wiki notes — not raw URLs and not prose hand-waving. When the agent writes new wiki content, it wires every claim to a note. This note defines how those links are written so they resolve in Obsidian, survive MkDocs compilation, and stay greppable for lint passes.
Precedence: agents.md is the normative contract; this note elaborates its link rules with worked syntax and observed failure cases. On conflict, agents.md wins — update it first, then this note.
Why Wikilinks Are the Citation Unit¶
In the LLM Wiki pattern, the agent is a librarian: its answers must be auditable back to sources. Wikilinks are the right citation unit for three reasons:
- Traceability is two-hop and stable. An answer cites a wiki note; the note cites the original URL (the vault's rule:
synthesis note -> reference note -> original URL). When a source URL rots, exactly one note is repaired and every past answer that cited it remains valid. - The graph is the knowledge. Obsidian's link graph and backlink panes expose which notes are load-bearing and which are orphans — the primary signal for the weekly lint pass.
- They compile. The
mkdocs-roamlinks-pluginconverts wikilinks to standard links in the published site, so one syntax serves both the local vault and the public knowledge base.
The Citation Chain¶
Agent answer
└─ cites: [Wikilinks](<./wikilinks.md>) <- wiki note (stable surface)
└─ cites: [Karpathy's llm-wiki gist](https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f) <- original URL
Rules for the agent when answering:
- Cite the narrowest note that supports the claim — a section anchor beats a whole note, a whole note beats a domain index.
- Cite the note, never the URL, in answers and in wiki prose. URLs live in the Sources section of a note, nowhere else.
- If no note covers the claim, create the note first (or add a reference note), then cite it. A claim with no citable note is not yet knowledge.
- When two notes disagree, cite both and flag the conflict in the newer note — do not silently pick a winner (that is the Conflict Resolution question in the index).
Scoping Rules¶
Wikilinks resolve by path-suffix matching: [ai-agents/llm-fundamentals/index](<../llm-fundamentals/index.md>) matches any file whose path ends with ai-agents/llm-fundamentals/index.md. Short links therefore resolve by accident today and break by rename tomorrow. The vault's contract:
| Form | Verdict | Example |
|---|---|---|
| Folder-scoped | required | [ai-agents/llm-fundamentals/operations#speculative-decoding](<../llm-fundamentals/operations.md#speculative-decoding>) |
| Bare note name | forbidden (ambiguous) | [index](<../../tools-catalogue/index.md>), [architecture](<../../storage/ceph/architecture.md>) |
| Block reference | forbidden | [[note^abc123]] — breaks MkDocs compilation |
Relative ([../note](<../../../note>)) |
forbidden | use vault-scoped form instead |
| Unscoped with alias | forbidden | [[My Note]] — fine in generic Obsidian, ambiguous here |
Bare [index](<../../tools-catalogue/index.md>) and [disclaimer](<../../disclaimer.md>) are the two accepted exceptions (vault-root pages). Anchors use the GitHub-style heading slug: ## Speculative Decoding becomes #speculative-decoding.
Syntax Gotchas (each one has broken a real link in this vault)¶
- Backticks kill links. A wikilink inside inline code is dead text:
`[ai-agents/llm-wiki/wikilinks](<./wikilinks.md>)`renders as literal text and lint tools count it unresolved. Write links as links. - Escape pipes in tables. Inside a Markdown table, the alias separator must be escaped or it splits the cell:
[DFlash 2](<../../llm-inference/dflash2/index/.md>). - Case matters at build time. macOS (APFS) resolves
[[Note]]tonote.md; GitHub Pages and MkDocs do not. Write targets in their exact on-disk case. - Spaces in markdown-link targets need
%20—](ref - name.md)breaks,](ref%20-%20name.md)resolves. Wikilinks handle spaces natively; prefer them for note-to-note links. - No trailing-slash directory links (
[x](topic/)) — MkDocs cannot resolve them; always link the explicitindex.md.
Writing Links for the Published Site¶
The public build only publishes knowledge/, compiles wikilinks via the roamlinks plugin, and uses awesome-pages navigation. Practical consequences:
- Link targets must exist under
knowledge/— a wikilink intoprojects/ormeta/publishes as a dead link. - Relative Markdown links must use explicit file paths (
[Architecture](../../storage/ceph/architecture.md),[Comparisons](comparisons/dflash2-vs-eagle3-vs-mtp.md)), never directory paths. - Every new folder needs a
.pagesfile or its pages are invisible in the sidebar.
Lint Hooks¶
The weekly lint pass (see Operations) checks exactly these invariants: every [[...]] target resolves by suffix match, every link is folder-scoped, no links inside code spans, no orphan notes, and every note cited by an answer exists. The vault-maintenance skill's audit checklist automates each check.
Sources¶
- Vault conventions:
agents.md(Wikilinks, SSG Compatibility, Interconnection Rules sections) - mkdocs-roamlinks-plugin — wikilink-to-markdown compilation used by the public build (v0.3.2, pinned in
requirements.txt) - Obsidian help: Internal links — resolution and alias semantics