---
type: manual
title: Zettelkern
description: A method for living knowledge. Plain-markdown wikis that LLM agents build, cross-reference, and keep current, with every claim traced to its source. The operational sections are field notes from production vaults.
resource: https://zettelkern.com
tags: [zettelkern, llm-wiki, knowledge-base, markdown, method]
updated: 2026-07-04
---

# Zettelkern

Zettelkern is a method for building knowledge bases that LLM agents can read,
extend, and maintain. It is practiced and published by Quellkern e.U.
(https://quellkern.com), the company that builds source-grounded systems.

This file is the manual. It is written so you can hand it to your LLM agent
(Claude Code, Codex, or any other harness) and say: **instantiate this for my
domain**. The agent builds the specifics in collaboration with you.

The operational sections (parallel agents, audits, lint as code, pipelines,
serving a non-technical owner) are field notes from production vaults, most
recently an academic literature project. Nothing in them is theoretical.

## Not our invention

Zettelkern is a practice of published, open ideas. Read the originals; they are
short and good:

1. Andrej Karpathy, "LLM Wiki: a pattern for building personal knowledge bases
   using LLMs". The founding pattern this method instantiates.
   https://gist.github.com/karpathy/442a6bf555914893e9891c11519de94f
2. The Open Knowledge Format (OKF), an open, vendor-neutral spec by the Google
   Cloud Data Cloud team that formalizes the same pattern: a directory of
   markdown files with YAML frontmatter.
   https://cloud.google.com/blog/products/data-analytics/how-the-open-knowledge-format-can-improve-data-sharing
   https://github.com/GoogleCloudPlatform/knowledge-catalog/tree/main/okf
3. Ancestors worth knowing: Vannevar Bush's Memex (1945) and Niklas Luhmann's
   Zettelkasten (one thought per slip, links between slips). Both solved the
   structure; neither solved who does the maintenance. Agents solve the
   maintenance.

What Zettelkern adds is operational discipline learned from running the pattern
in production: typed frontmatter with confidence markers, provenance rules,
parallel-agent rules, audit and lint workflows that run as code, idempotent
pipelines, sensitivity gates you can execute, and git conventions. The rest is
faithfully Karpathy's pattern in OKF-compatible files.

## The three layers

1. `raw/`: immutable sources. Articles, transcripts, papers, mail, exports.
   The agent reads them and never edits them. Filenames are date-prefixed:
   `YYYY-MM-DD-source-slug.ext`. If a source cannot be copied in, keep a
   `sources.md` that points to it by stable path or URL.
2. `wiki/`: the agent-owned layer. Small typed pages in folders such as
   `entities/`, `concepts/`, `topics/`, `decisions/`. Add a new category only
   when content genuinely does not fit, and document the addition in the
   schema.
3. The schema: the contract that makes an agent a disciplined wiki maintainer
   instead of a generic chatbot. Pick one of `AGENTS.md` or `CLAUDE.md` as the
   schema; the other is a one-line pointer to it, so every harness lands on
   the same rules. The starter kit picks `AGENTS.md`.

## The spine files

- `README.md`: five to twelve lines for humans: start here, schema there.
- `index.md`: the catalog. Every page listed with a link and a one-line
  summary, grouped by category. Updated on every ingest. Agents read this
  first; at up to a few hundred pages it replaces search infrastructure.
- `log.md`: append-only chronology. One entry per material operation with a
  grep-parseable prefix: `## [YYYY-MM-DD HH:MM] <op> | <model> | <details>`.
  Newest at the bottom; read-only queries are never logged.
  `grep "^## \[" log.md | tail -5` shows recent history.
- `overview.md`: the one-page synthesis of the whole vault. A stub is fine at
  first; the method tolerates stubs that are labeled as stubs.
- `START_HERE.md` (optional): the owner-facing entry point when a
  non-technical human shares the vault. See "Serving a non-technical owner".

## Page rules

- One topic, one file. Kebab-case, ASCII (transliterate umlauts), basename
  unique across the vault so `[[wikilinks]]` resolve from any folder.
- Fixed anatomy: one H1 matching the title, a one-to-three sentence lead, H2
  body sections, a "See also" section of links, a "Sources" section.
- Twenty to 150 lines per page. Long material belongs in `raw/`; wiki pages
  stay short and dense.
- YAML frontmatter on every page, controlled vocabulary, OKF-compatible:

```yaml
---
title: Some Topic
type: concept        # entity | concept | topic | decision | source | overview
status: draft        # stub | draft | maintained | superseded
confidence: verified # verified | partly-uncertain
updated: 2026-07-04
tags: [example]
sources: [raw/2026-07-04-some-source.md]
---
```

One trade-off from production: `[[wikilinks]]` are the default, but one vault
uses standard markdown links instead because both its chat harness and GitHub
preview render them, and its schema records the deviation and the reason.
Either choice is fine; an unrecorded choice is not. This is schema
co-evolution shown in place.

## The workflows

**Ingest.** A new source lands in `raw/`. The agent reads it, discusses key
takeaways with you, writes a summary page, updates every touched entity and
concept page (five to fifteen pages is normal), refreshes `index.md`, appends
to `log.md`. One ingest, one commit.

**Query.** Questions run against the vault: read `index.md` first, drill into
pages, answer with citations. Durable answers (comparisons, analyses,
discovered connections) are filed back into the wiki as pages. Chat history is
where knowledge goes to die.

**Lint.** Periodic health check: contradictions between pages, stale claims
superseded by newer sources, orphan pages, missing pages for concepts that are
mentioned often, broken links, gaps worth a web search. File the findings, fix
what is mechanical, queue what needs judgment. The mechanical half of this
becomes a script; see "Lint as code".

Three workflows run a small vault. At scale, two more earn their keep:

**Consolidate.** The integration pass after parallel workers ingest side by
side: extract new entities and concepts from the fresh source pages, update
`index.md` and `overview.md`, merge the pending logs chronologically into
`log.md` and delete them. One single commit. Mechanics in "Parallel agents
without conflicts".

**Audit.** Check what you ship against the vault, not the vault against
itself. Full treatment in "Audit what you ship".

## Parallel agents without conflicts

Several agents can ingest simultaneously if their write scopes are disjoint
by construction. Conflicts are prevented, never resolved.

- A worker may write exactly two paths: its assigned source page
  `wiki/sources/<slug>.md` and a unique pending log
  `wiki/log-pending/<worker>-<timestamp>.md`. Nothing else.
- `index.md`, `log.md`, `overview.md`, and every synthesis folder are
  consolidator-only. Workers read them, never write them.
- The consolidator merges the pending logs chronologically into `log.md` and
  deletes them in the same commit, so `log-pending/` is empty in steady
  state.

The writability table, straight from the schema:

```
| path                                       | worker       | consolidator       |
| wiki/sources/<assigned-slug>.md            | write (own)  | write              |
| wiki/log-pending/<worker>-<timestamp>.md   | create own   | merge, then delete |
| index.md, log.md, overview.md, synthesis   | read only    | sole writer        |
```

## Audit what you ship

A vault usually feeds a deliverable: a manuscript, a report, a filing. The
audit workflow checks that deliverable against the vault, with scripts.

- Citations are extracted from the deliverable by regex and matched against
  per-source metadata with a confidence level: exact, partial, low, none.
- The report has four tables: Matched, Review, Unmatched, Orphans. Orphans
  are sources that were ingested but never cited; each one either belongs in
  the deliverable or on a "consulted, not cited" list.
- Reports contain zero deliverable excerpts, only citation tokens. Privacy by
  architecture: the audit output can be shared without leaking the work.

Second half, page trust, for citation-heavy domains: the position of a page
inside a PDF is not the printed page number. A script detects `/PageLabels`
and records a `source_page_strategy` per source (pdf-labels, offset, none).
Extracted text carries markers like `[pdf-page 12 | source-page 3]`. A review
report marks each source as trusted versus pdf-index only, and page-numbered
citations from untrusted sources get manual verification before submission.

## Lint as code

The mechanical half of the lint workflow is a script with auto-fail rules:

- Broken relative links.
- Frontmatter schema: required keys present, `type` within the controlled
  vocabulary.
- Citation gaps. The heuristic: a paragraph with quantitative claim signals
  (numbers, percentages, comparatives) and no inline citation link gets
  flagged. Hedged phrasing is exempt.

A concrete claim without a citation fails the build; a hedge passes. That
asymmetry pushes every page toward either proper grounding or honest hedging.
Confident and uncited is the one state the vault refuses to hold.

Judgment lint stays agent work: contradictions between pages, staleness,
missing pages for concepts mentioned often, gaps worth a web search.

## Pipelines and metadata

Two rules keep scripts and humans out of each other's way.

**Metadata split.** Each source gets a `meta.yaml` with two halves.
Bibliographic fields belong to the system: enriched via API, timestamped with
`enriched_at`, tagged with `enrichment_source` (crossref, pdf-metadata,
heuristic, manual). Workflow fields belong to the human: `status` (raw,
reviewed, cited), `relevance` (core, supporting, peripheral), `methodology`.
In one line: what the system extracted versus what I am doing with it.

```yaml
title: "Some Source Title"
year: 2024
doi: 10.1234/example
enriched_at: 2026-07-01T14:02:00Z
enrichment_source: crossref
# human-owned below this line
status: reviewed
relevance: core
methodology: survey
```

**Idempotent pipeline.** Every script checks a done marker (sha256 plus
timestamp) before acting, supports `--force`, caches API responses on disk,
and logs each material operation to `log-pending/`. Slug overrides live in a
small YAML map: the human escape hatch that needs no code change.

## Serving a non-technical owner

Two audiences, one vault. The owner works only in a word processor and a chat
harness. A helper machine runs the heavy pipeline: PDF extraction, API
enrichment, audits. The vault is the interface between the two.

The owner gets `START_HERE.md` (what this is, a "what you never have to do"
list, and the daily loop: pull, ask, paste, push) plus a prompt library of
about twelve copy-paste prompts, one per recurring task.

Prompt hard rules:

- Every prompt names explicit file paths. "Summarize the project" invites
  wandering; "read wiki/sources/<slug>.md" does not.
- Citations must be page-anchored.
- The hallucination guard is written into every prompt: "if the vault has no
  source for it, say: no source in raw/".
- Anti-patterns are documented. "Write everything about X" is banned because
  it invites synthesis without grounding.

## Provenance and confidence

- Every load-bearing claim carries a citation: a raw file path, a document
  name, a dated message, or a URL.
- Distinguish evidence (from sources) from synthesis (model output). Never
  silently promote synthesis to evidence.
- Mark unverified facts explicitly (a VERIFY tag or `confidence:
  partly-uncertain`). Flip the marker when the fact is grounded.
- Flag contradictions in place ("Contradiction: ...") instead of overwriting
  the older claim.
- Volatile facts (prices, fees, dates, availability, processing times) are
  never asserted as fixed. Write "check current" and say what to check.

## Git and the log

- The vault is a git repo. One operation, one commit.
- Typed commit prefixes make the history read like a lab notebook. Core
  verbs: `ingest:`, `query:`, `lint:`, `decision:`. Verbs earned by pipeline
  work: `scaffold:`, `convert:`, `enrich:`, `audit:`, `consolidate:`,
  `refactor:`, `extract-fix:`, `plan:`. Plus `docs:` and `chore:`. Adopt what
  your vault needs and record additions in the schema.
- Log entries are model-tagged: `## [YYYY-MM-DD HH:MM] <op> | <model> |
  <details>`. Log material operations only (scaffold, convert, enrich, audit,
  ingest, consolidate, lint, refactor, extract-fix), never read-only queries.
- Decide the privacy posture at bootstrap and write it into the schema: no
  remote, private remote only, or public. For sensitive vaults, forbid public
  remotes outright.
- Renaming a page includes the sweep for inbound links, in the same commit.

The model tag turns `log.md` into an AI-usage record. See "Disclosure".

## Sensitivity boundaries

If any content must never reach a given audience, engineer that instead of
hoping: give it its own folder with a marker page, set a `sensitivity:` field
in frontmatter, and write the never-share rule into the schema. Across repos,
reference by pointer, never copy.

Make the gates executable:

- Verify repo visibility with a command before any push:
  `gh repo view --json visibility`.
- A STOP rule in the schema: before any change to repo settings, stop and ask
  the human.
- PDFs and the deliverable are gitignored by policy.
- Committing extracted fulltext is a documented copyright trade-off: decided
  once, written down in the schema.
- Audit outputs are engineered to leak nothing: citation tokens only.

A boundary you cannot execute is a hope, not a boundary.

## Disclosure

Institutions and journals increasingly require AI-usage disclosure, so keep
the answer prewritten. The vault holds a disclosure template with a
materiality matrix: what AI did (extraction, enrichment, wiki drafting,
audits) and what AI did not do (claims, conclusions, the final wording of the
deliverable). It points to `log.md` as the timestamped, model-tagged record.
When the question arrives, the evidence already exists.

## Bootstrap: instructions for the agent

You are an agent and a human just handed you this file. Do this now:

0. Either clone the starter kit at
   https://github.com/devdotbo/zettelkern-starter-kit (MIT: schema template,
   START_HERE template, prompt library, generic lint script) and adapt it, or
   build from scratch with the steps below. Both end in the same place.
1. Ask for the domain, the language of the vault, and the privacy posture.
2. Create the skeleton: `README.md`, `index.md`, `log.md`, `overview.md`
   (stub), `raw/`, `wiki/` with two or three typed folders that fit the
   domain.
3. Vendor the founding pattern: download Karpathy's `llm-wiki.md` into the
   repo root or `raw/`, marked immutable.
4. Write the schema: pick one of `AGENTS.md` or `CLAUDE.md` as the schema,
   the other is a one-line pointer; the starter kit picks `AGENTS.md`. Cover
   the layers, page anatomy, frontmatter vocabulary, the workflows, git
   rules, style rules, privacy posture, and a "current status and next steps"
   section you keep rewriting so any future session resumes cold.
5. Log the bootstrap as the first entry, commit as `chore: bootstrap vault`.
6. Ingest the first source properly. Resist bulk imports until the schema has
   survived three or four real ingests.
7. Co-evolve: when a convention proves wrong, change the schema, log the
   change, move on.

## When to call humans who have done this before

Bootstrapping a fresh vault is genuinely easy; the list above is enough.
Adapting an existing knowledge base (a Confluence space, a SharePoint tree, a
wiki nobody maintains, years of PDFs) is where experience pays: what to
migrate, what to leave, how to cut layers, how to keep provenance during the
move. That is the service Quellkern sells: hello@quellkern.com, subject
"Zettelkern".

Newsletter: occasional plain-text field notes on the method. Mail
hello@quellkern.com with subject "Zettelpost: subscribe".

---

© 2026 Quellkern e.U., Tirol, Austria. This manual is free to use, share, and
adapt with attribution. The linked originals carry their own licenses.
