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. Kingsley OS is the desktop it is worked from.
What follows is the pattern and the machinery, not the contents. Counts come from the vault on 2026-10-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.
- 1200
- wiki pages
find wiki -name '*.md' | wc -l - 522
- catalogue lines across six index files
grep -c '^- \[\[' index*.md, summed - 735
- log entries, 470 of them builds
grep "^## \[" log.md, grouped by type - 343
- task files, 217 of them done
grep -h "^status:" wiki/records/tasks/*.md | sort | uniq -c - 58
- active days between 2026-07-29 and 2026-10-14
grep "^## \[" log.md | cut -c5-14 | sort -u | wc -l
Counted on 14 Oct 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. Six index files catalogue it and an append-only log records what happened.
1200 pages, six typesOn-return briefing, Kingsley OS, glasses glance, two handhelds.
Only Kingsley OS edits wiki pages, and a person approves each file. The handhelds drop notes into an inbox folder.lint.py, selftest.py, review.py, health.py. They report and propose. None of them commits.
Page types: 164 entities, 117 concepts, 87 source summaries, 83 projects, 40 synthesis pages, 709 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. Six 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 is 375 lines on 14 Oct 2026, after a rewrite moved the history of each rule 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 735 entries, and 470 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 343 task files, 217 of them done.
- Git is the approval boundary.Agents write into the working copy. From Kingsley OS, 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: 58 active days between 2026-07-29 and 2026-10-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. Each detector stays quiet until the thing it watches is genuinely late.
- Kingsley OS. The console, drawn as a desktop: windows, a menu bar, a dock, and two skins, OS 9 Platinum or modern macOS. It runs on the always-on machine and is reachable only over a private network with a token. Twenty-three apps over the same vault: Decisions, Work, Projects, Agents, Janitor, Log, Mail, Jobs, Recipes, Marketplace, Trip, Weather, Flights, Muni Tracker, G2, PennyOS, Drive-By, OpenResearch, Mockups, Processes, System, Servers and Network. Projects is a project manager with a board per project, a roadmap by release and a dependency map across projects. Nothing fetches on a timer: a window reads when it opens, when it comes back into focus after thirty seconds, or when Refresh is pressed, and a reading that failed shows "not checked" in amber, never a blank or a zero. Its prompt box runs the real Claude Code CLI inside the vault, under the same rules. Anything it writes waits in pending changes for a person to approve, file by file.
- A glasses glance. A read-only route that returns two or three lines of overdue items, sized for a smart-glasses display.
- Two handhelds. PennyOS carries Kingsley OS away from the desk as an admin device, with the vault mirrored to it. PennyOS Mobile reaches the machine over SSH through 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.
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.
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.