How Kingsley works
Kingsley is the knowledge base and to-do system behind oddrefresh: a folder of markdown files kept by Claude Code agents, holding notes, records and side projects.
What follows is the pattern and the machinery, not the contents. Counts come from the vault on 2026-09-14, with the command beside each one.
What it is and why
Kingsley follows Andrej Karpathy's LLM Wiki pattern, published as a gist in April 2026. The core idea is to compile, not retrieve.
A typical document chatbot searches raw files every time you ask a question and keeps nothing. Here, an agent reads a source once, works it into the pages that already exist, flags where it contradicts them, and keeps the result current.
I pick the sources and decide what matters. The agent writes and maintains every page. The operational side draws on Chase AI's video The Agentic OS Setup That Will 10x Claude Code. Where the two disagree, the gist governs how knowledge is handled and the video governs how things run.
It opens in Obsidian.
- 712
- wiki pages
find wiki -name '*.md' | wc -l - 336
- catalogue lines across four index files
grep -c '^- \[\[' index*.md, summed - 289
- log entries, 192 of them builds
grep "^## \[" log.md, grouped by type - 233
- task files, 129 of them done
grep -h "^status:" wiki/records/tasks/*.md | sort | uniq -c - 30
- active days between 2026-07-29 and 2026-09-14
grep "^## \[" log.md | cut -c5-14 | sort -u | wc -l - 26/26
- planted defects the linter caught today
python3 tools/selftest.py - 0
- lint findings today
python3 tools/lint.py
Counted on 14 Sep 2026. Each number was run against the vault with the command under it.
The three layers
Sources come in at the left and are never changed. The agent compiles them into the wiki. Everything a person looks at reads the wiki. One schema file governs how the first two are written.
Page types, strict frontmatter, the contradiction policy, and every rule learned from a mistake that happened twice.
Articles, transcripts, exports, notebook scans.
Immutable. Read, never written.The compiled layer. The agent owns every file. Four index files catalogue it and an append-only log records what happened.
712 pages, six typesOn-return briefing, console, glasses glance, handheld.
Only the console edits wiki pages, and a person approves each file. The handheld can drop notes into an inbox folder.lint.py, selftest.py, review.py, health.py. They report and propose. None of them commits.
Page types: 109 entities, 112 concepts, 39 source summaries, 29 projects, 25 synthesis pages, 398 records. grep -rh "^type:" wiki | sort | uniq -c
raw/ holds sources: articles, transcripts, exports, notebook scans. It is immutable. Agents read it and never write to it.
wiki/ is the compiled layer, and the agent owns every file. Records are one file per row of what used to be a database. Four index files catalogue every non-record page in one line each. An append-only log records what happened and when.
CLAUDE.md is the schema. It tells a fresh session how the vault is built. When a mistake happens twice, it becomes a rule there. It ran to 1,192 lines in the working copy on 14 Sep 2026, after the history of how each rule came about moved out to wiki pages. wc -l CLAUDE.md
The four operations
- IngestA source goes into raw/. The agent reads all of it, discusses the key points before writing, checks whether each person or idea already has a page under another name, then updates every affected page. Ten to fifteen pages from one source is normal.
- QueryThe agent reads the catalogue first, follows links, answers with citations to specific pages, and offers to file a good answer back as a synthesis page.
- LintScripted health checks that produce a report. Fixes are proposed, not applied, with one exception: a dead link whose correct target is unambiguous.
- BuildMost of the work is shipping software. The rule is that a deploy is an ingest: what a release taught goes onto the pages about that platform, not only into the log.
The log has 289 entries, and 192 of them are builds.
The rules that keep it true
- Update cross references every time.A wiki that falls behind does not break. It quietly stops being true.
- Check for duplicates before creating a page.Search the catalogue, filenames and aliases. If the thing exists under another name, add the alias and edit that page.
- Strict frontmatter.Every page starts with a typed header, and fixed fields accept only lowercase kebab-case values. Obsidian Bases matches strings exactly, so "In Progress" and "in-progress" would count as two statuses. The allowed values live in one place, the linter, and everything else reads them from there.
- A written contradiction policy.Every page carries a confidence level. The newer source wins by default, and the older claim stays on the page with a note. A weaker new source cannot silently replace a high-confidence claim; both are flagged for a human.
- Tasks are files.Each task is its own markdown file with status, priority and a required link to its project. Bases queries file properties, and a file has room for a work log. There are 233 task files, 129 of them done.
- Git is the approval boundary.Agents write into the working copy. From the console, nothing becomes history until a person approves it, file by file, and the console refuses a commit that changes a file already in raw/.
- The history leaves the machine every night.An encrypted image of the whole vault, git history included, goes to iCloud Drive and to a NAS, seven nights kept in each. It is the one job here that runs on a clock. The NAS copy lands only on nights its share is mounted. Between 10 Aug and 14 Sep 2026 it landed on none, and iCloud carried every night. The script now tries to mount the share itself, and that has not yet been seen working at 3am.
What it runs
None of these fire on a calendar. The owner's time comes in bursts, which was measured from the log: 30 active days between 2026-07-29 and 2026-09-14.
A daily digest would pile up unread and look maintained while it is not. Surfaces trigger on return or on an event.
- The on-return briefing. When a Claude Code session starts, a hook runs a script. Under 20 hours since the last session, it says nothing. After a real gap, it reports what changed, what was last worked on, at most three decisions, and a short list of things that are fine. Eight detectors feed it. The newest three notice a review or lint pass that has not run in a while, uncommitted changes piling up, and pages nobody has revised since the day they were written. Each stays quiet until the thing it watches is genuinely late.
- The console. A small Python web server on an always-on machine, reachable only over a private network with a token. It shows open work, projects, search, a data browser that edits frontmatter only, pending changes and system health. Its prompt box runs the real Claude Code CLI inside the vault, so the same rules apply. Anything either one writes waits for approval.
- A glasses glance. A read-only route that returns two or three lines of overdue items, sized for a smart-glasses display.
- A handheld. A small keyboard device that reaches the server over SSH. Its key gets a forced command with a fixed allow-list, not a shell, and every call is logged.
The checks
lint.py
Mechanical: no model, no network, no key. It checks fields and allowed values, dead links, orphan pages, non-ISO dates, thin ingests, summaries filed as the wrong page type, projects with no next action, stale liveness claims, and names mentioned on four or more pages with no page of their own. Today it reports 0 findings.
selftest.py
Checks whether the linter can still see. It copies the vault, plants one defect per check, runs the real linter and reports a catch rate. Today it reads 26 of 26.
review.py
Reads a git diff and checks what no script can: silent overwrites, edits to raw/, guessed dates, changes that touched too few pages.
health.py
Asks whether what a page says is still true. Its weekly and monthly tiers become due after a gap rather than on a schedule. A check that could not run is reported separately, never as a clean result.
Lessons from the build
- Search is not enumeration.An audit of the old Notion workspace that crawled outward with search found 8 databases and 174 rows. The bulk export held 12 databases and 234 rows. Search cannot find what nothing links to.
- Fix the check before the content.The first lint run reported 267 findings. Three checks were wrong, and correcting them removed 249 findings without touching a page.
- A reading pass loses to a five-line check.A careful hand review found 2 done tasks with no resolution date. The script written from that finding found 12. Anything found by reading should leave a check behind.
- Hierarchy is content.Flattening a nested workspace left 206 orphans out of 296 pages. Rebuilding parent-to-child links from the export's folders fixed it.
- The vault describes itself worst.Hand-typed counts in the files a fresh session reads first fell behind within days, and no check reads prose for stale numbers. The fix was to publish the command beside the count, which is why this page does.
- Silence must not look like safety.A safety badge on one console page once showed green because a parser read nothing and treated that as a pass. That page now says "not checked" when its check could not run, and the same rule governs every other surface that reports a check.
Make your own
The prompt starts a Kingsley-style vault in an empty folder. It has Claude Code interview you first about what you want to keep and how often you will really show up. Then it sets up the raw and wiki layers, a schema with strict frontmatter, a catalogue, an append-only log, ingest, query and lint commands, and a small linter that is tested against planted defects.
Start small. The layers, the frontmatter, ingest and lint are the general core. Everything else on this page grew later, one measured failure at a time. Questions go to the Contact me button on this page.
Set up a personal knowledge vault in this empty folder. It follows Andrej Karpathy's "LLM Wiki" pattern (his gist, April 2026): you read each source once and compile it into linked pages that stay current, instead of searching raw files every time I ask a question. I choose the sources and decide what matters. You write and maintain every page. The folder should open as an Obsidian vault. Step 1. Interview me before creating anything. Ask, in one message, and wait: 1. What do I want to keep here? Examples: work notes, reading, household records, side projects. 2. What kinds of things will I track: people, tools, ideas, projects, tasks, records like a list of devices? 3. How often will I realistically show up? Daily, weekly, or in bursts with long gaps? 4. Do I want tasks tracked here, or knowledge only? 5. Is there existing material to import, and where does it live? Step 2. Create the layers: - raw/ holds source material: articles, transcripts, exports, notes. It is immutable. You read from it and never write to it. - wiki/ is the compiled layer, with subfolders entities/, concepts/, sources/, projects/, synthesis/ and records/, shaped by my answers. - index.md is the catalogue: one line per page, a written summary under 100 characters, grouped by type. - log.md is append only. Every entry starts "## [YYYY-MM-DD] type | title" so grep can parse it. Never edit a past entry. Step 3. Write CLAUDE.md, the schema. It defines each page type and a strict frontmatter block. Every page gets: type, title, aliases, created, updated, tags, confidence (high, medium or low) and sources. Each type adds only the fields it needs. Any field with a fixed list of values uses lowercase kebab-case values only, because Obsidian Bases matches strings exactly and "In Progress" and "in-progress" silently become two statuses. Include a contradiction policy: never silently overwrite; the newer source wins by default and the older claim stays on the page with a note; if the older claim is high confidence and the newer one is not, flag both and ask me. When a mistake happens twice, it becomes a rule in this file. Step 4. Create slash commands in .claude/commands/: - /ingest: move the source into raw/, read all of it, tell me the key points and which pages you plan to touch, then wait. After I reply, write a source summary page, update every affected page, add new pages to index.md, and append to log.md. - /query: read index.md first, follow links, answer with citations to specific pages, and offer to file a good answer as a synthesis page. - /lint: run the linter and report findings. Propose fixes; do not apply them. Step 5. Write tools/lint.py using only the Python standard library, no network and no model. It checks required frontmatter fields, allowed values, ISO dates, duplicate keys, dead wikilinks, pages with no inbound links, and pages missing from index.md. Keep the allowed values in one place in the script and point CLAUDE.md at them. Then plant one defect per check in a copy of the vault and confirm the linter catches each one, because a clean report and a broken linter look the same. Write these failure modes into CLAUDE.md as rules: - Under-updated cross references. One source touching ten to fifteen pages is normal. A wiki that falls behind does not break; it quietly stops being true. Err toward touching more pages. - Duplicate pages under different names. Before creating any page, search index.md, filenames and aliases for the thing and every variant. If it exists, add the new name to aliases and edit that page. - Rhythms that assume daily use. If I show up in bursts, build nothing on a daily or weekly schedule. A digest I am not there to read piles up and looks maintained while it is not. Trigger on my return, or on an event. - Silence that looks like safety. Any check that could not run must say "not checked", never pass quietly. Commit to git when setup is done, then show me the tree and the first lint report.