Blog Wiki Schema#
Pattern credit: this wiki implements Andrej Karpathy's LLM Wiki — an LLM incrementally builds and maintains a persistent wiki over raw sources.
Instructions for the LLM maintaining this wiki. The wiki is built from the
owner's blog archive (blog/WordPress.*.xml, exported to sources/).
Structure#
blog/— original WordPress WXR export. Immutable.sources/posts/<YYYY>/— one markdown file per post, converted bytools/wxr_to_md.py. Immutable. Do not edit. Frontmatter: title, date, categories, source URL.sources/_catalog.tsv— tab-separated catalog of all posts (date, year, title, categories, words, path). Regenerated by the converter script.wiki/— LLM-owned knowledge layer:overview.md— blog-wide stats (posts/year, categories). Auto-generated bytools/gen_index.py.index.md— curated wiki index (manually maintained, links topic pages + key docs).gen_index.pyno longer overwrites it.sources.md— auto-generated full catalog of all ingested posts by year. (Previously this file wasindex.md; split out soindex.mdcan be hand-curated.) Regenerate withpython3 tools/gen_index.py.schema.md— this file.log.md— append-only chronological record of all wiki operations.tools/— helper scripts (gen_index.py,build_site.py,lint_wiki.py,wxr_to_md.py,digest.py).
Conventions for synthesis pages#
- Filename:
wiki/pages/<topic>.md, one topic per page, kebab-case or Chinese titles allowed. - Every claim sourced from a post must cite the source as a relative link to
the file under
sources/posts/...(with post date). - YAML frontmatter on every page:
title,updated,sources. sources= the number of corpus posts in the page's cluster, i.e. how many catalog rows match its category keyword — not the number of citation links in the body. Compute it, don't guess:python3 -c "import csv;rows=list(csv.DictReader(open('sources/_catalog.tsv'),delimiter='\t'));print(sum(1 for r in rows if '游记' in r['categories']))"- Reference values (2026-09-18): 读书 262 · 编程 272 · 游记 51 · 太宗本纪 63 · 一日一得 22. Pages synthesizing several categories (e.g. 生活 / 人生的下半场 / 蛋壳与利他) list the count of posts actually cited.
- A "local citations" block lists the posts cited on the page;
build_site.pyrewrites those links to blog URLs at publish time. - Numeric claims must be verified, not estimated. Word counts, per-year
post counts and totals are all in
sources/_catalog.tsv— check them before publishing (e.g.grep '编程' sources/_catalog.tsv | cut -f2 | uniq -c). Do not invent titles: every post named in a timeline must exist in the catalog. - Cross-link related pages with markdown links.
- Citations to source posts use a page-relative link to the markdown file,
e.g.
https://blog.rsywx.net/2007/04/14/central-kingdom/fromwiki/pages/.tools/build_site.pyrewrites every such link to the post's original blog URL on publish (regex(?:\.\./)+sources/(posts/[^)]+\.md)); locally the markdown link still resolves to the repo file.
Workflows#
Ingest (batch)#
- Run
python3 tools/gen_index.pyto refresh overview/sources.md after new posts are converted intosources/posts/. - Read the catalog slice assigned (e.g., one year or one category).
- Read the actual post files; write/update synthesis pages:
- Year pages
wiki/pages/year-<YYYY>.md - Category/topic pages (读书, 编程, 游记, 太宗本纪, canada, ...)
- Recurring entity pages (books, technologies, people, places) as they emerge.
- Update
wiki/index.mdlinks where needed; append an entry tolog.md:## [YYYY-MM-DD] ingest | <scope>.
Query#
- Read
wiki/index.md(andoverview.md) to locate relevant pages. - Read those pages, drill into sources when needed, answer with citations.
- If the answer is worth keeping (comparisons, analyses, timelines), file it
as a new page under
wiki/pages/and log it:## [YYYY-MM-DD] query | <question>.
Lint#
Periodically check: orphan pages, missing cross-references, stale claims,
uncategorized posts worth classifying, contradictions. Log as
## [YYYY-MM-DD] lint | <notes>.
Automated checks that must pass before finishing any batch of page edits:
python3 tools/gen_index.py— refreshoverview.md/sources.md.python3 tools/build_site.py— runsmkdocs build --strict; must exit 0 and report0 left unresolvedcitation links. Also verifies everywiki/*.mdpath referenced inmkdocs.ymlnav exists.python3 tools/lint_wiki.py— must exit 0. Checks that everysources/posts/...citation and every*.mdinternal link resolves on disk, that nav targets exist, that no{{/TODO/placeholdermarkers are left behind, and that each<category>总览hub page'ssources:count matches the catalog.
Notes#
- Posts are mostly Chinese; write synthesis pages in Chinese unless asked otherwise.
- ~950 posts are "Uncategorized" — infer topics from content when synthesizing.
- Content is raw WordPress HTML; strip/skip markup noise when summarizing.
- Ingest in batches (one year or one category at a time). Stay incremental; the wiki compounds.