Will ChenWill Chen
← Writingsystem design

How I built a wiki that agents maintain

A blog is finished-shaped, which is why I never posted. A wiki assumes it is unfinished, and a folder of markdown is something an agent can maintain.

Will ChenWill Chen7 min

MY OWN LEXICON was a glossary of terms for how my own behaviour works, each with the definition I meant rather than the dictionary one. The list kept growing and the entries referred to each other, so what it wanted was not a longer glossary but a set of pages that point at one another and accumulate.

Motivation

The obvious way to publish thinking is a blog, and I did not want one:

  • a post is finished when you post it, so the pressure is on before you write anything
  • the format gives you no way to say that an idea is still moving

A wiki inverts all of it:

  • everything in it is assumed to be a constant work in progress
  • its articles stand alone, so a reader can take them one at a time
  • the links between them carry a relationship a chronological feed cannot express

The empty vault problem

The usual blank page problem is a shortage of things to say, and this was the reverse. Years of ideas had gone into chat transcripts, so the material existed in a form nobody could read: scattered across hundreds of conversations, each buried mid-exchange in something else. Writing the wiki meant saying all of it again.

The shape of the problem: the material is written down but not addressable, and the cost of making it addressable is a second full pass by the person who least wants to do it.

That settles who the maintainer is before it settles anything else. If I was not going to do the second pass, something that would had to, which turns the tool question into one requirement: whatever I picked had to be a thing an agent could operate.

Adjacent work: Obsidian

I asked Claude what tool to use, given that an AI would be maintaining the wiki, and it suggested Obsidian. I turned that down for a bad reason: Obsidian felt like going backwards, an older and less interesting tool than whatever I thought I should be using, so the rejection was on status rather than function.

What changed was noticing what an Obsidian vault actually is. A folder of markdown files. Everything that makes it a wiki is a convention layered on plain text: a link is a page name in double brackets, and the graph is what you get from reading all the files and following those brackets. None of it requires Obsidian to be running.

Three things come free from that description:

  • the graph edges already exist, because wiki links are edges
  • the graph is queryable, because libraries exist that walk an Obsidian vault
  • maintenance becomes a file-editing problem, which is the one thing coding agents are unambiguously good at

Nothing about Obsidian changed between my rejecting it and my adopting it, only which description of it I was holding, and the one that worked was the one naming the parts an agent can operate.

Seeding the first articles

I wrote a system prompt describing what the wiki was for and how its articles should read, then fed the agent a couple of seminal articles and brain dumps I already had. It started producing pages, and the pages were right.

The first articles became the models for every article after them, and not because I told the agent to imitate them. Every new article gets written with the related existing articles pulled into context, so the register those early pages set keeps being resampled downstream.

Style, tone and philosophical alignment all propagate from the first few pages. That makes editing them the highest-leverage editing on the project, in a window that closes while the vault still holds a handful of articles.

Why it works says something about what you are talking to.

  • Describe the register and every word covers an enormous range of actual writing. Precise, unhurried, sceptical of its own claims. The model has to pick somewhere in that range before it can write a sentence, and it picks the most typical version, because typical is what it has most of. The most typical version of "precise and sceptical" is the same voice everything else has.
  • Hand it three articles and there is no conversion step and nothing to interpret. A language model works by continuing text, so a sample is not a description of the target, it is a point already standing on it. Continuing in the manner of what precedes is the one operation the machine is built out of.

A style guide asks the model to construct a target from words and then aim at it. An exemplar hands it the target. That is why the first few articles were worth more attention than any hundred that came after: I was not writing articles, I was writing the specification, and it happened to be shaped like articles.

The vault reached 78 articles and 26,145 lines on three agent definitions:

.claude/agents/wiki-article-writer.md   239 lines
.claude/agents/wiki-context-finder.md    62 lines
.claude/agents/wiki-reviewer.md         221 lines

The sizes are the division of labour. The finder needs sixty lines to say what to go and read, and the writer and the reviewer need about four times that each, because both of them are being told what good looks like.

Agent roles

The requirement underneath is that the pipeline has to run without me in it. A wiki I supervise article by article is a wiki I am writing, which is the work I was trying to avoid.

I started with a single agent that wrote articles. What broke it was context drift: as a session ran long, the instructions I had given at the start stopped governing what came out at the end, and I found myself re-explaining the same constraints every few articles. Re-instructing an agent that has forgotten is more effort than the writing it saves.

So I divided the work into roles, each existing for a different and specific reason.

  • Writer. Came first, because writing the articles was the job.
  • Context finder. Came second, because the writer needed to read before it could write. Its stated purpose is graph quality rather than convenience: it surfaces the pages that relate to a new concept so that connections get made, which improves the edge density of the graph. A wiki whose articles do not link is a folder.
  • Reviewer. Came third, from the most useful observation of the three. I kept having to remind the writer what the wiki was for, and I could not make those reminders stick by putting them into the writer's own prompt. An instruction that has to survive a long generation does not survive it. Moving it into a separate pass, run after the writing, made it hold.

The reviewer's job is narrower than quality control. Its own definition puts certainty calibration at the top, in capitals, above everything else it checks, and pairs the failures with their replacements rather than only banning things. The load-bearing section of the file, trimmed of its surrounding instructions:

### 1. Certainty Calibration (HIGHEST PRIORITY)

**RED FLAGS - Flag immediately:**
- "The brain literally implements X"
- "Research proves/shows that..."
- "This is not metaphor, this is actual mechanism"
- Deterministic predictions ("this will cause Y")
- Universal statements ("everyone experiences X")

**GOOD PATTERNS - Encourage:**
- "Appears to use X-like processes"
- "Observed in N=1 experience that..."
- Probabilistic language ("tends to", "often", "in this case")
- Explicit caveats ("This worked for Will, test it yourself")

**ACTION:** For every claim, ask: "Is this presented as useful heuristic or
scientific truth?"

Every red flag has a good pattern beside it, which is the part that makes it work: an agent told only what to avoid will avoid it by saying nothing.

The wiki explains behaviour in computational language, which is a lens rather than a discovery, and one agent's entire job is stopping the other agents from forgetting that.

Build order and run order differ:

  • built writer, context finder, reviewer
  • runs context finder, writer, reviewer

What it produced

The wiki got a web reader with retrieval search over it. The part that mattered more is that dropping a chat transcript into the vault updates the existing articles rather than adding one to the end.

The mechanism is the context finder running in the direction it was written for. Its stated job is identifying which existing pages should be updated given new material, before any update happens.

Handed a transcript it returns four things:

  • every page that discusses the concept, uses related terminology, or would be affected by a change to it
  • how each of those pages currently treats the concept, and in what language
  • the existing cross-links and their directions
  • the inconsistencies between them

The fourth is what makes this reconciliation instead of appending:

  • a list of affected pages tells the writer where to add text
  • a list of the conflicts between how those pages already describe the thing tells it what has to change

Changing it is the work a second full pass by hand would otherwise have been, so the transcription problem that stopped me at the beginning was handed to the thing that generated the transcripts.

Separation against a single pass

Everything above has a mechanism behind it. This part does not, and I would rather say so than invent one.

The three agents contain the same instructions I would put in a single prompt. Nothing is added by splitting them. I have tried the single prompt, asking for research and writing and review in one pass, and the output is worse, reliably enough that I stopped testing it.

Two candidate explanations, and I cannot tell which is true:

  • Attention. A long prompt carrying three jobs means every instruction competes with every other one, and the review instructions lose because they are about text that does not exist yet at the moment the prompt is read.
  • The input. A reviewer run separately is reading a finished draft, which is a different and much more specific thing to be looking at than an intention to write one. A critic needs an object, and until the draft exists there is nothing to criticise.

They predict different futures:

  • crowding dissolves as context windows grow
  • the object never does, and the separation is permanent

I do not know which, and the honest position is that I kept the three agents because the three agents work.