llm-wiki
LLM wiki kit
Created by Mehmet Goekce
Published in MehmetGoekce/llm-wiki. Publisher page
168 GitHub stars
What it is
Build Karpathy's LLM Wiki with Claude Code. L1/L2 cache architecture. Logseq + Obsidian support.
Summary from the brain’s metadata
Build Karpathy's LLM Wiki with Claude Code. L1/L2 cache architecture. Logseq + Obsidian support. Build Karpathy's LLM Wiki with Claude Code. Two-layer cache architecture (L1/L2). Supports Logseq and Obsidian.
How it works
Memory model: LLM wiki
AutoGineer overview, from the brain’s own files
Memory model: LLM wiki. Folders: .github (agent config, 5 files); docs (docs, 7 files); examples (examples, 2 files); templates (templates, 8 files).
| Folder | Role | Files |
|---|---|---|
| .github | agent-config | 5 |
| docs | docs | 7 |
| examples | examples | 2 |
| templates | templates | 8 |
| .claude-plugin | folder | 3 |
| openspec | folder | 23 |
Requirements
Works with: Claude Code
Set it up
Clone the repository at the commit AutoGineer scanned:
git clone https://github.com/MehmetGoekce/llm-wiki.git && cd llm-wiki && git checkout 5fa5ee7d49a4346eeb1d92c1de7bf649e7654e91Point Claude Code at .claude-plugin/icon.png: it does not read that file on its own.
cd llm-wiki && claude
AutoGineer scanned these files at commit 5fa5ee7.
- Not scanned by AutoGineerThe author’s README also describes installing it as a Claude Code plugin marketplace. Read its install section: AutoGineer did not scan that path. https://github.com/MehmetGoekce/llm-wiki/blob/5fa5ee7d49a4346eeb1d92c1de7bf649e7654e91/README.md#quick-start
- Not scanned by AutoGineerThe author’s README also describes installing it from a clone of its repository. Read its install section: AutoGineer did not scan that path. https://github.com/MehmetGoekce/llm-wiki/blob/5fa5ee7d49a4346eeb1d92c1de7bf649e7654e91/README.md#quick-start
Created by Mehmet Goekce. Published in MehmetGoekce/llm-wiki. Licence: MIT License.
Usage
From the brain’s own files
- ${user_config.wiki_path} (the "Wiki root:" line): your Logseq graph or Obsidian vault
- ${CLAUDE_PLUGIN_ROOT} (the setup workflow): the clone, so that setup finds templates/
Documentation by Mehmet Goekce
llm-wiki
Image: License: MIT Image: Release Image: Stars Image: Top Language Image: Last Commit
Build Karpathy's LLM Wiki with Claude Code. Two-layer cache architecture (L1/L2). Supports Logseq and Obsidian.
graph TB
subgraph "Every Session — Auto-loaded"
L1[L1: Claude Memory]
L1R[Rules & Gotchas]
L1I[Identity & Preferences]
L1C[Credentials]
L1 --> L1R
L1 --> L1I
L1 --> L1C
end
subgraph "On Demand — /llm-wiki query"
L2[L2: Wiki]
L2P[Projects & History]
L2W[Workflows & Processes]
L2K[Research & Learning]
L2 --> L2P
L2 --> L2W
L2 --> L2K
end
NEW[New Knowledge] --> ROUTE{Quick rule?}
ROUTE -->|Yes| L1
ROUTE -->|No| L2
USER[User Query] --> CLAUDE[Claude Code]
CLAUDE --> L1
CLAUDE -->|Deep question| L2What is this?
Image: Wiki graph view after setup Your wiki after a few ingests — interconnected knowledge pages in Logseq's graph view.
In April 2026, Andrej Karpathy published a gist called "LLM Wiki" that got 5,000+ stars in days. The idea: let an LLM maintain a structured, cross-referenced wiki for you. Feed it raw sources, it extracts facts, links them together, and keeps everything consistent. The wiki becomes a persistent, compounding artifact instead of a graveyard of stale notes.
Everyone loved the concept. Almost nobody built one. The gist describes what to build, not how to wire it up with real tools, real files, and real workflows. llm-wiki is the implementation. It uses Claude Code as the LLM brain and either Logseq or Obsidian as the wiki UI, with a two-layer cache architecture that turned out to be the key insight Karpathy's gist does not mention.
Why use this?
5-minute setup. Install the plugin, run
/llm-wiki setup, and you have a schema, namespaces, and git tracking. No manual design needed.Claude becomes your wiki maintainer.
/llm-wiki ingestupdates 5-15 pages with cross-references from a single source.L1/L2 architecture. Auto-loaded rules in memory (L1) + deep knowledge in the wiki (L2). No other tool has this.
Built-in quality checks.
/llm-wiki lintfinds orphan pages, stale content, broken refs, and credential leaks.Logseq + Obsidian. Use whichever you already have. No tool switch required.
Quick Start
As a Claude Code plugin (recommended)
claude plugin marketplace add MehmetGoekce/llm-wiki
claude plugin install llm-wiki@mehmetgoekceOn Claude Code 2.1.275 or later, one line inside a session does the same:
/plugin install llm-wiki --marketplace MehmetGoekce/llm-wikiClaude Code asks for one value, the Wiki root: your Logseq graph or Obsidian vault. The directory may be empty or not exist yet. Then, in any project:
/llm-wiki setup
/llm-wiki ingest "your first source"
/llm-wiki query "what do I know about X?"
/llm-wiki lint/llm-wiki setup asks which tool you use and which namespaces you want, then creates the Schema,
Dashboard, hub pages, Access-Log and llm-wiki.yml. The wiki starts sparse and gets denser with
every ingest. New releases reach you through the plugin; nothing to copy.
Tested with Claude Code 2.1.296.
Without the plugin
Clone the repository and copy the skill into the project that should use it:
git clone https://github.com/MehmetGoekce/llm-wiki.git ~/llm-wiki
mkdir -p ~/myproject/.claude/commands
cp ~/llm-wiki/SKILL.md ~/myproject/.claude/commands/wiki.mdIn the copy, replace two placeholders with absolute paths:
${user_config.wiki_path}(the "Wiki root:" line): your Logseq graph or Obsidian vault${CLAUDE_PLUGIN_ROOT}(the setup workflow): the clone, so that setup findstemplates/
On Linux (on macOS, write sed -i '' instead of sed -i):
sed -i -e 's|\${user_config.wiki_path}|/home/you/notes/wiki|g' \
-e 's|\${CLAUDE_PLUGIN_ROOT}|/home/you/llm-wiki|g' \
~/myproject/.claude/commands/wiki.mdThen run /wiki setup in that project. The copy is invoked as /wiki <command>, stays at the
version you copied, and needs the clone to stay where it is. The plugin is the recommended path.
The rest of this README writes /llm-wiki <command>. With a copied skill, type /wiki <command>.
Moving from a copied skill to the plugin
Install the plugin, enter your existing wiki directory as Wiki root, and delete the copied
.claude/commands/wiki.md from your project. The wiki itself needs no change.
Coming from v1.6.0
The plugin's commands lost their second part: /llm-wiki:wiki ingest is now /llm-wiki ingest, and
/llm-wiki:setup is now /llm-wiki setup. Update the plugin and use the new names.
The L1/L2 Architecture
This is the part not in Karpathy's gist, and it turned out to be the most important design decision.
When you start building a wiki, the instinct is to put everything in one place. That is wrong. Some knowledge must be available in every session, before you even ask a question -- things like "max 2-3 SSH calls to the VPS, never 10+" or "always use ISO 8601 dates." If the LLM has to query the wiki to learn these rules, it has already made the mistake.
Other knowledge only matters in specific contexts. The full history of a project. A detailed API workflow. Loading all of this into every session wastes the context window.
The solution maps to a concept every engineer knows: CPU cache hierarchy.
| Layer | What | Size | Loading | Contains |
|---|---|---|---|---|
| L1 | Claude Code Memory | ~10-20 files | Auto-loaded every session | Rules, gotchas, identity, credentials |
| L2 | Wiki (Logseq/Obsidian) | ~50-200 pages | On-demand via /llm-wiki query | Projects, workflows, research, deep knowledge |
graph TB
subgraph "Every Session — Auto-loaded"
L1[L1: Claude Memory]
L1R[Rules & Gotchas]
L1I[Identity & Preferences]
L1C[Credentials]
L1 --> L1R
L1 --> L1I
L1 --> L1C
end
subgraph "On Demand — /llm-wiki query"
L2[L2: Wiki]
L2P[Projects & History]
L2W[Workflows & Processes]
L2K[Research & Learning]
L2 --> L2P
L2 --> L2W
L2 --> L2K
end
NEW[New Knowledge] --> ROUTE{Quick rule<br/>or gotcha?}
ROUTE -->|Yes| L1
ROUTE -->|No| L2
USER[User Query] --> CLAUDE[Claude Code]
CLAUDE --> L1
CLAUDE -->|Deep question| L2The routing rule is simple: Would the LLM making a mistake without this knowledge be dangerous or embarrassing? Then it belongs in L1. Would the mistake be merely inconvenient? Then L2.
Credentials are a special case -- they must live in L1 because the wiki is typically git-tracked. The L1 memory directory is excluded from git, making it the only safe place for secrets.
For the full deep-dive, see docs/l1-l2-architecture.md.
Commands
| Command | Description |
|---|---|
/llm-wiki ingest <source> | Process a source (URL, file, text), update 5-15 wiki pages |
/llm-wiki query <question> | Two-stage search via hub index, synthesize answer with source attribution |
/llm-wiki prune [--months N] | LRU-Demote: evict cold pages from the live index (default 6 months) |
/llm-wiki prune --l1 | L1-Verification: classify L1 rules, check due behavior claims against local evidence, re-verify / demote / delete |
/llm-wiki lint [--fix] | Health check: orphans, stale pages, broken refs, index drift, credential leaks, due L1 claims |
/llm-wiki status | Metrics dashboard: page count, health, hot/cold profile, recent changes |
Ingest Flow
Ingest is the core operation. When you run /llm-wiki ingest "deployed v2.0 to production", here is what happens:
graph LR
SRC[Source<br/>URL / File / Text] --> A[Phase 1<br/>Analyze & Extract]
A --> B[Phase 2<br/>Scan Wiki<br/>Find affected pages]
B --> C[Phase 3<br/>Update Pages<br/>Create new / Append]
C --> D[Phase 4<br/>Quality Gate<br/>Properties? Cross-refs?<br/>No credentials?]
D --> E[Phase 5<br/>Report<br/>Pages touched / Warnings]
E --> GIT[git commit]Phase 1 -- Analyze & Extract. Claude reads the source and extracts entities, facts, relationships, and dates. It classifies each piece by domain (business, technical, content, etc.) and checks whether it belongs in L1 (quick rule) or L2 (deep knowledge).
Phase 2 -- Scan Wiki. Claude reads the schema, then scans existing pages to find which ones the new information affects. If you mention a tool that already has an entity page, it knows to update that page too.
Phase 3 -- Update Pages. New pages get all required properties from the schema. Existing pages get new facts appended; when a fact supersedes a stated state (a status, a deadline, a decision), the block is rewritten and the old wording moves into a collapsed History -- nothing is deleted, and the current state stays on top. Target: 5-15 page touches per ingest.
Phase 4 -- Quality Gate. Before committing: Do all pages have required properties? Does every page have at least one cross-reference? Are there credential patterns in the content?
Phase 5 -- Report. Summary of pages created, updated, cross-references added, and any warnings.
Query
Query is two-stage, the way a CPU resolves an address before touching memory. Stage 1 (routing): Claude reads only the hub ### Index pages of the candidate namespaces — a cheap list of routing lines ([[page]] -- description #tags) — and picks the 3 most relevant pages by description. This is the wiki's page table. Stage 2 (read): it opens only those full pages and synthesizes an answer with source attribution. A full-text grep over every page is the L3 fallback, used only when routing finds nothing. Each full-page read is logged to an append-only Access-Log together with the routing reason it was picked (the matched index description or grep term) — so the log records not just what loaded but why, and it feeds prune. If the query reveals a gap, it offers to create a new page.
Prune
Prune is the eviction layer that keeps routing precise as the wiki grows. It reads the Access-Log, finds cold pages (no read in N months, default 6), and evicts them from the live index — the routing line moves from the hub ### Index to ### Archive and the page is marked archived::. This is demotion, not deletion: the file stays in place, every incoming [[link]] stays valid, and the page is still found by the L3 grep fallback (and re-promoted automatically if queried again). Crucially, prune never renames or moves a file — the wiki tool links by page name, so a move would break every backlink. Run it on a schedule (the command does not self-schedule).
--l1 is the L1 counterpart. Access frequency cannot find stale L1 rules — every L1 file loads every session, so a stale rule never looks cold; it shows up as the agent confidently acting on an outdated assumption. So L1 files carry a claim class: asserts-current-behavior: true for claims about a system's current state (a path, flag, version, quirk) and false for decisions and preferences, which never go stale. Behavior claims carry a verified date. /llm-wiki prune --l1 classifies unclassified files (it proposes, you confirm), checks due claims against read-only local evidence, and lets you re-verify, demote the rule to L2 as history, or delete it. It does not warn mid-session when a stale rule is about to justify an action — Claude Code loads L1, so there is no hook for that; it is on the roadmap.
Lint
Lint is the automated health check. It scans every wiki page and checks 13 rules: orphan pages (no incoming links), stale content (last updated 90+ days ago but still marked high-confidence), missing required properties, broken references, hub completeness, index drift (an active page with no routing line, or a routing line with no page), archived-in-live-index (a demoted page still routed), empty pages, weak cross-referencing, credential patterns, L1/L2 duplicates, due L1 claims (behavior claims whose verified date is missing or older than l1_verify_days), and block bloat (a block grown past 600 characters of prose, or an updated:: value used as a change log). Run with --fix and Claude auto-repairs what it can — including backfilling missing routing lines into hub indexes.
The Schema
The schema is the contract between you and the LLM. Without it, the LLM creates inconsistent pages -- one uses status: active, another state:: running, a third has no status field at all. With a schema, every page follows the same structure and automated quality checks become possible.
The schema defines:
8 namespaces (Business, Tech, Content, Projects, People, Learning, Reference, Careers)
5 page types (Entity, Project, Knowledge, Feedback, Hub) with required properties
Lint rules for automated health checks
L1/L2 boundary so the system knows where new knowledge should be routed
For the complete schema reference, see docs/schema-reference.md.
Logseq vs. Obsidian
Both wiki apps are supported. Choose based on your preference:
| Logseq | Obsidian | |
|---|---|---|
| Properties | property:: value (inline) | YAML frontmatter |
| Format | Outliner (- prefix on every line) | Flat markdown |
| File names | Wiki___Tech___Strapi.md | Wiki/Tech/Strapi.md |
| Links | [[Wiki/Tech/Strapi]] | [[Wiki/Tech/Strapi]] |
| Backlinks | Automatic (graph-native) | Via plugin or core feature |
| Block addressing | Every line is a block | Paragraph-level |
| License | AGPL-3.0 (open source) | Proprietary (free for personal use) |
Logseq shines when the LLM is doing the writing -- its outliner format means every block is independently addressable, so appending new content never disrupts existing structure.
Obsidian is better if you do a lot of manual editing -- flat markdown is more natural to write by hand, and the plugin ecosystem is massive.
For a detailed comparison with migration paths, see docs/logseq-vs-obsidian.md.
Before & After
The difference between a dead wiki and a living one is page quality.
Before -- a placeholder created when the page was first made:
- type:: knowledge
- domain:: content
- ## Newsletter
- To be filled via /llm-wiki ingest.After -- synthesized from multiple sources over several ingest operations:
- type:: knowledge
- domain:: content
- confidence:: high
- created:: 2026-03-15
- updated:: 2026-04-07
- ## Company Newsletter
- Monthly newsletter targeting existing clients and prospects.
- ### Metrics
- | Metric | Value | As of |
|--------|-------|-------|
| Subscribers | ~240 | 2026-04-01 |
| Open rate | 38% | 2026-04-01 |
| Cadence | monthly | -- |
- ### Content Strategy
- 1 technical deep-dive + 1 business insight per issue
- Always include a CTA to the latest blog post
- Subject lines: question format performs 2x better
- ### Open Questions
- Segment list by industry vertical?
- A/B test send time (Tuesday AM vs Thursday AM)?
- ### Cross-References
- [[Wiki/Content/Blog]] -- Source content
- [[Wiki/Content/LinkedIn]] -- Promotion channel
- [[Wiki/Reference/Workflows]] -- Publishing workflowEvery number has a date. Decisions have rationale. Open questions are explicit. Cross-references connect to related pages.
Configuration
Setup creates llm-wiki.yml in your wiki root. You can also create it manually:
# llm-wiki.yml
tool: logseq # or "obsidian"
wiki_path: ~/Documents/MyWiki/
pages_dir: pages # relative to wiki_path
memory_path: ~/.claude/projects/my-project/memory/
l1_verify_days: 90 # optional: re-verify L1 behavior claims after N days
namespaces:
- Business
- Tech
- Content
- Projects
- People
- Learning
- Reference
- Careers
# Lint settings
lint:
stale_threshold_days: 90
min_cross_refs: 1
credential_patterns:
- "token::"
- "password::"
- "secret::"
- "api.key::"
# Ingest settings
ingest:
target_page_touches: [5, 15] # min, max pages per ingest
append_only: true # never delete content; superseded state moves to a collapsed History
# Language (for multilingual wikis)
language:
business: en # Language for business content
tech: en # Language for technical contentTrade-offs
No system is perfect. Some things to know:
The schema feels overengineered at first. With 10 pages, defining 5 page types and 8 lint rules seems like overkill. Past 50 pages, you will be grateful for the consistency. Define the schema early -- it is much harder to retrofit one later.
Two systems means you need a clear boundary. Having both L1 and L2 means you could accidentally put the same information in both places. The lint rule for L1/L2 duplicates exists precisely for this reason.
Parallel agents can conflict. If you have multiple Claude sessions writing to wiki files simultaneously, concurrent edits can cause conflicts. Treat wiki files as a shared resource.
Start with fewer hub pages. Let them emerge organically from ingest operations rather than creating empty hubs upfront.
Documentation
FAQ — Common questions before you install
Troubleshooting — Setup, integration, and runtime issues
L1/L2 Architecture — Why two layers, how to route knowledge
Schema Reference — Page types, properties, lint rules
Logseq vs. Obsidian — Detailed comparison and migration notes
Privacy
llm-wiki has no backend and collects nothing. It is a skill and a few shell scripts that run inside your own Claude Code session.
Wiki pages, the access log and
llm-wiki.ymlare written to your local Logseq graph or Obsidian vault and stay there. Whatever you ingest ends up in those files, including names or contact details if the source contains them.If you set
memory_path, the skill also reads your local Claude Code memory directory:querymay consult it,lintreports rules that are due for a check, andprune --l1classifies, updates, moves or deletes memory files, each one only after you confirm it.lintnever prints the content of a memory file. Withoutmemory_paththe skill does not touch that directory.The skill and the scripts send nothing to the author or to any third party. There is no telemetry.
The only network access is the page fetch that
ingestmakes when you pass a URL as the source.Commits are local. Nothing is pushed unless you push your wiki yourself.
Claude reads the content you work with in order to do the work. That processing is covered by your own Claude plan and Anthropic's terms, not by this plugin.
Credits
Inspired by Andrej Karpathy's LLM Wiki gist
Built with Claude Code
License
MIT -- see LICENSE for details.
SKILL.md
name: llm-wiki description: Maintain a persistent LLM wiki in Logseq or Obsidian. Subcommands - setup (one-time, creates the wiki), ingest a source into wiki pages, query the wiki, prune cold pages or stale L1 rules, lint, status, import existing notes. argument-hint: "<setup|ingest|query|prune|lint|status|import> [args]"
/llm-wiki - LLM Wiki
Persistent knowledge management powered by Claude Code. Maintains a structured wiki in Logseq or Obsidian using the L1/L2 cache architecture.
Architecture: L1/L2 Cache Model
L1 = Claude Memory (auto-loaded): Rules, gotchas, identity, credentials
L2 = Wiki (on-demand): Projects, workflows, research, deep knowledge
Two cache mechanisms keep L2 precise as it grows:
Hub-Index-Routing — L1's auto-loaded memory index has no L2 counterpart by default. Each hub page carries an
### Indexof routing lines (one per child:[[link]] -- description #tags).querybecomes two-stage: read the cheap hub indexes -> pick the 3 most relevant pages by description -> read only those full pages. This is the wiki's "page table / TLB" — no more grep-over-everything.LRU-Demote —
querylogs every page hit;pruneevicts cold pages (no access in N months) from the live index. Eviction != deletion: the file stays (markedarchived::), still greppable as an L3 fallback, all[[links]]intact. Access-frequency eviction — the missing CPU-cache mechanism.
One mechanism keeps L1 honest:
L1-Verification — access frequency cannot find stale L1 rules: every L1 file loads every session, so a stale rule never looks cold. It shows up as the agent confidently acting on an outdated assumption. L1 files therefore carry a claim class:
asserts-current-behavior: true(a path, command, flag, version, quirk — can silently go stale) orfalse(a decision, preference, identity — never stale), plusverified: <date>for behavior claims.lintreports claims pastl1_verify_days;prune --l1checks them against read-only evidence and lets the user re-verify, demote to L2, or delete.
Arguments
/llm-wiki ingest <source> Process source, create/update wiki pages
/llm-wiki query <question> Search wiki (two-stage via hub index), synthesize answer
/llm-wiki prune [--months N] LRU-Demote: evict cold pages from the live index (default 6 months)
/llm-wiki prune --l1 [--batch N] [--days N]
L1-Verification: classify L1 rules, check due claims, re-verify/demote/delete
/llm-wiki lint [--fix] Health check: orphans, stale, broken refs, index drift
/llm-wiki status Wiki metrics and health overview (incl. hot/cold profile)
/llm-wiki import Import existing notes into wiki format
/llm-wiki setup One-time: create the wiki skeleton and llm-wiki.yml in the wiki rootWorkflow
<role> Wiki maintainer for a personal or team knowledge base. You process source material and distribute extracted knowledge across wiki pages, maintain cross-references, and ensure structural integrity. </role>
<context> ## Configuration
Wiki root: ${user_config.wiki_path}
The wiki root above is set by the plugin's "Wiki root" option, or written in by hand for a copied skill. If it is not a filesystem path but an unexpanded placeholder (it starts with a dollar sign and a brace), stop and tell the user: "Wiki root is not configured. Set it in the llm-wiki plugin settings, or replace the placeholder in a copied skill (see README)." Never guess a wiki root.
Read llm-wiki.yml from the wiki root FIRST (every command except setup, which creates it). If the
file is missing, stop with: "llm-wiki.yml not found in <wiki root>. Run /llm-wiki setup to create one." If its wiki_path
names a different directory than the wiki root above, warn once, naming both paths, and continue
with the wiki root above. The config determines:
tool: logseq or obsidianwiki_path: path to the graph/vaultpages_dir: where pages live (relative to wiki_path)memory_path: L1 memory directory (optional; without it, L1 features are skipped)l1_verify_days: days until an L1 behavior claim is due for re-verification (optional, default 90; invalid value -> warn and use 90)namespaces: configured top-level namespaces
Tool-Specific Format Rules
Logseq Mode
Every line starts with
-(outliner format)Properties:
property:: valuesyntax on first lines (NO YAML frontmatter)File naming: Triple-underscore for namespaces (
Wiki___Tech___Strapi.md)All files are flat in the
pages/directorySub-items indented with tab +
-Headings inside blocks:
- ## Heading
Obsidian Mode
Standard flat markdown (no
-prefix required)Properties: YAML frontmatter (
---\ntype: knowledge\n---)File naming: Folder hierarchy (
Wiki/Tech/Strapi.md)Namespaces map to directories on disk
Headings: Standard
## Headingsyntax
Both Tools
Cross-references:
[[Wiki/Namespace/Page]]syntaxSchema page: Read
Wiki/Schema(orWiki___Schema.md) for conventionsLinks are bidirectional (backlinks panel in both tools)
ISO 8601 dates (YYYY-MM-DD)
L1/L2 Boundary
L1 (Memory, auto-loaded): Rules, gotchas, identity, credentials — things Claude must know EVERY session
L2 (Wiki, on-demand): Projects, workflows, research — queried via /llm-wiki when needed
Routing rule: "Would a mistake without this knowledge be dangerous/embarrassing? -> L1. Merely inconvenient? -> L2."
Credentials MUST stay in L1 (wiki is git-tracked!)
</context>
<workflow> ## Workflow: ingest (Default)
Phase 1 - Source Analysis:
Identify source type (URL -> WebFetch, file path -> Read, text -> parse directly)
Extract: entities, facts, relationships, dates, decisions
Classify: business, technical, content, project, learning, reference
L1/L2 Check: Is this a quick rule/gotcha? -> Recommend Memory. Deep knowledge? -> Wiki
Phase 2 - Wiki Scan:
Read llm-wiki.yml for tool config
Read Schema page for current conventions
Check target pages: do they exist? (Glob for wiki pages)
Read existing target pages
Identify: pages to create, pages to update, cross-refs to add
Phase 3 - Page Operations (target: 5-15 page touches):
Create new pages with all required properties (per Schema)
Update existing pages — current state on top, history collapsed (format: § State + History):
A new fact that supersedes nothing -> append it as a new block
A new fact that supersedes a stated state -> REWRITE the block's headline, properties and "Next step" in place; move the superseded wording, dated, into the block's collapsed
Historychild (newest first). Never append "Status <date>: ..." sentences to running proseDelete nothing: every superseded statement stays readable in the history
Maintain the hub routing line (REQUIRED for every created/updated page): in the hub's
### Indexsection, set/update the routing line —[[Wiki/NS/Page]] -- <one-sentence description, <=120 chars> #tag #tag. New page -> append a line; refocused page -> refresh the description. The description is the routing key for query Phase 0 — keep it terse, distinctive, no filler ("Notes about ...").Add cross-references between all affected pages
Set updated:: property (or YAML updated field) on all modified pages — the date only, no change note. What changed belongs in the commit message (hubs: also one line in the collapsed
## Change log)
Phase 4 - Quality Gate:
All new pages have required properties (per Schema)?
All pages have at least 1 cross-reference?
Every new/updated active page has a routing line in its hub
### Index? (else it is unroutable)No credentials in wiki content?
Count page touches (warn if < 5 or > 20)
Phase 5 - Report:
Summary: pages created, pages updated, cross-refs added
List any warnings or skipped items
Workflow: query
Phase 0 - Routing (Stage 1, cheap index read):
Parse question -> identify candidate namespaces (Business, Tech, Content, Projects, People, Learning, Reference, Careers, plus any configured in llm-wiki.yml)
Read ONLY the hub page for each candidate namespace, NOT every full page
Match the routing lines in the hub's
### Index(title -- description #tags) against the questionPick the 3 most relevant child pages (max 5). This is the "page table" — index, not full scan
Phase 1 - Targeted Read (Stage 2, only the chosen pages):
Read ONLY the 3-5 pages chosen in Phase 0 (max 3 loaded simultaneously, JIT — batch if needed)
L3 fallback when routing yields nothing useful (namespace unclear, hub index missing/empty, no routing line matches): classic grep across all wiki pages -> top 3-5. This is the slow backing-store scan and should be the exception, not the default
If needed, also read L1 Memory for complete picture
Phase 1b - Access Logging (LRU signal + routing transparency):
For each page ACTUALLY read in full, append one line to the Access-Log page (Wiki/Reference/Access-Log):
- <ISO-date> -- [[Wiki/NS/Page]] -- query -- matched: "<reason>"matched:reason = the "and why" of the routing (loading transparency): on index routing (Phase 0) the hub### Indexrouting description / #tag that matched the question; on the L3 fallback the grep term that found the page. Keep it short (<= 60 chars), in quotes. The log then shows not just WHICH page loaded but WHY it was picked for this question — surfaced via/llm-wiki statuscache profile.Append-only, NO per-query git commit (non-structural — see Constraints)
If the L3 fallback hits an archived page (
archived::set) — a re-hit on an evicted page: offer to re-promote it — move its routing line back into the hub### Index, drop the archived:: property
Phase 2 - Synthesize:
Combine information from multiple wiki pages
Note confidence levels (from page properties)
Check staleness (updated dates)
Formulate comprehensive answer with source attribution
Phase 3 - Optional Write-Back:
If query reveals a wiki gap -> offer to create/update pages
If synthesis produces a useful summary -> offer to file as new page
User must confirm before any writes
Phase 4 - Output:
Answer with source pages: "Sources: Wiki/Tech/Deployment, Wiki/Reference/Gotchas"
Flag stale or low-confidence sources
Suggest related pages
Workflow: prune (LRU-Demote, scheduled)
Purpose: evict cold pages from the live hub index so two-stage routing stays precise as the wiki grows. Demotion != deletion — the file stays, only its routing line leaves the live index. Cache analogy: eviction from the index/TLB; data remains in the backing store (greppable as L3). Meant as a periodic run (default cadence N = 6 months) — wire it via your scheduler; the command does NOT self-schedule.
Phase 1 - Access Profile:
Read llm-wiki.yml first (tool mode, paths)
Read the Access-Log page (Wiki/Reference/Access-Log)
Determine last access per page (newest log entry; never logged -> use created:: as a proxy)
Threshold: no access in N months (default 6, via --months N)
EXEMPT from demotion: hub pages (type hub), Schema, Dashboard, the Access-Log itself, and status:: active projects (never evict in-flight work, even if unread)
Phase 2 - Demote Candidates:
List candidates (page -- last access -- age in months) and SHOW the user before any write
For each confirmed candidate:
Add archived:: <today> — the canonical "demoted" marker, valid on any page type (NEVER touch created::/updated::). For entity pages (whose status enum allows it) ALSO set status:: archived; for project/knowledge pages do NOT set an out-of-enum status value (see specs/schema.md REQ-565/566)
Move the routing line from the hub's
### IndexVERBATIM into the hub's### Archivesection (move, not delete)Do NOT rename the page / do NOT move the file to another namespace — the tool links by page name, a rename would break every incoming link (broken-ref storm). The file stays in place
Incoming links therefore stay valid; the page is only out of routing, not out of the graph
Phase 3 - Report + Commit:
Demoted list, new live-index size per namespace, hot pages (top access) for contrast
Git commit (structural change: hub index + page properties)
Note: next prune due in N months — user may wire it via their scheduler
Workflow: prune --l1 (L1-Verification)
Purpose: find L1 rules that make claims about current behavior and check them against evidence before
they keep steering sessions. Separate from L2 eviction: prune --l1 never evicts L2 pages, plain prune
never touches L1. L1 is NOT git-tracked — there is no undo, so every write needs confirmation.
Phase 1 - Scope:
Read llm-wiki.yml first. No
memory_path-> "memory_path not configured — L1 mode unavailable." and abortScan every L1 memory file EXCEPT the index file (e.g. MEMORY.md — an index, not a rule). Its lines are auto-loaded too: keep them in step whenever a rule is corrected, demoted, or deleted
Batch size 10 (
--batch N); window =l1_verify_days(--days Noverrides)Read
asserts-current-behaviorandverifiedfrom the frontmatter top level OR ametadata:block
Phase 2 - Classify (up to one batch of unclassified files — no asserts-current-behavior key):
Propose true/false per file with a one-line reason:
true = falsifiable claim about a system's current state (path, command, flag, version, port, API, tool quirk, external behavior)
false = decision, preference, identity fact, or rationale
Mixed file (decision + behavior claim) -> propose true and suggest splitting it into two files
User confirms the batch or overrides single items. Write ONLY confirmed values
NEVER set
verifiedwhile classifying — a new behavior claim stays due until evidence is checked
Phase 3 - Gather Evidence (up to one batch of due rules; never-verified first, then oldest verified):
Due =
asserts-current-behavior: trueAND (verifiedmissing OR older than the window)Extract what the rule names: file paths, commands, flags, versions, ports, config keys, URLs
READ-ONLY and LOCAL: check existence, read files, search contents, read dependency manifests, run commands only with
--version/--help. NEVER run commands with side effects, write, deploy, or touch remote state. NEVER fetch remote contentVerdict per CLAIM (a rule usually makes several):
supports/contradicts/inconclusive, with what was checked and what was foundEvidence basis per claim:
executed(read-only command),source(read the implementing code, not run), orfile(existence/content). Behavior observable only with side effects ->sourceor inconclusiveOverall verdict: contradicts if any claim contradicts; supports if all checked claims support; else inconclusive. Mark it partial when claims stayed unchecked, and name them
Not checkable locally (external service, pricing, third-party policy) ->
inconclusive, "not locally verifiable"Credential rules: report only whether the referenced location exists — NEVER print the value
The verdict is input for the user, not an action
Phase 4 - Act (per rule, user chooses):
Recommend by verdict: supports -> re-verify; contradicts -> demote (history still useful) or delete; inconclusive -> re-verify only if the user confirms the claim from their own knowledge
Re-verify: set
verified: <today>. Oncontradicts, offer it ONLY together with a corrected rule text; write both together. Correct every place the claim appears: body, frontmatterdescription(loaded via the index), and the rule's index lineDemote to L2: first show a carry-over summary (what the history block keeps / what is dropped and why / file path to read it in full). Append a history block (
source:: l1-demotion, date) to the most relevant wiki page found via hub-index routing — or create a page via the ingest path. ONLY after the wiki write succeeds: delete the L1 file. Credential rules are NEVER demoted (only re-verify or delete)Delete: show the carry-over summary (nothing is kept) and the file path, then remove the L1 file
Before removing any L1 file: search the other L1 files and the index for references (file name and
name). Demote -> rewrite them to the wiki page; delete -> list them and fix on confirmation. Remove only this file's pointer from the index; if the index line points to several files, show it before/afterSkip -> file untouched, stays due for the next run
Phase 5 - Report + Commit:
Counts: classified (true/false), re-verified, demoted, deleted, skipped; remaining unclassified + due
Git commit for wiki pages changed by demotion (plus pending Access-Log appends). L1 is git-excluded — nothing to commit there
Out of scope: warning at the moment a due rule is about to justify an action. Claude Code loads L1, not llm-wiki — there is no hook to enforce that gate, so do not claim one.
Workflow: lint
Phase 1 - Scan:
Find all wiki pages (glob pattern depends on tool)
For each page: read properties, count links, check updated date
Build link graph (page -> pages it references)
Phase 2 - Check Rules (from Schema):
Orphan Detection: pages with 0 incoming links (excluding hubs)
Stale Detection: updated > 90 days ago AND confidence high
Missing Properties: pages without type-specific required properties
Broken References: links pointing to non-existent pages
Hub Completeness: hub pages missing children in their namespace
Index Drift: routing line in a hub
### Indexwith no matching page (orphaned), OR an active (non-archived) page with no routing line in its namespace hub (unroutable -> only findable via L3 grep)Missing Index Description: routing line with no description text after the
--separatorArchived-in-Live-Index: an archived page (
archived::set) still in### Indexinstead of### Archive(unclean prune)Credential Leak: regex scan for token/password/secret patterns
Empty Pages: pages with only properties, no content
Cross-ref Minimum: pages with fewer than 1 outgoing link
L1/L2 Duplicates: same info in Memory AND Wiki -> warning
Block Bloat (warning):
a block (Obsidian: a paragraph) with > 600 characters of prose outside
History/Change logblocks — code blocks, tables and the Access-Log page don't count -> "split into state + history"an
updated::value (page or section) that is more than an ISO date
L1 Verification Due (only if
memory_pathis set; skip the L1 index file):warning per L1 file with
asserts-current-behavior: trueandverifiedmissing or older thanl1_verify_days— report file name, verified date (or "never"), age in daysinfo: ONE line with the count of unclassified L1 files (no
asserts-current-behaviorkey)asserts-current-behavior: falseis never flagged, regardless of agenever print L1 file bodies (L1 may hold credentials); suggest
/llm-wiki prune --l1
Phase 3 - Report:
Group findings by severity (critical, warning, info)
Counts: total pages, healthy pages, issues found
Per issue: page name, issue type, suggested fix
Phase 4 - Auto-Fix (only with --fix flag):
Add missing hub entries
Backfill routing lines: an active page with no index entry -> generate a routing line from the page title + first content block (as a one-sentence description) + its existing #tags, insert into the hub
### Index(bootstraps old hubs that only carry bare link lists)Clean index drift: remove orphaned routing lines (page gone); move archived pages from
### Indexto### ArchiveDowngrade stale confidence from high to stale
Move
updated::notes out (Block Bloat): cut the value to the date, move the rest verbatim (one line per date, newest first) into the page's collapsed## Change log. Do NOT auto-restructure oversized blocks — deciding what the current state is needs judgmentCreate stub pages for broken links
Add cross-references where obvious connections exist
NEVER write to L1 files, not even with --fix (L1 Verification Due has no auto-fix)
Git commit after fixes
Phase 5 - Dashboard Update:
Update Dashboard page with current health metrics
Timestamp the lint run
Workflow: status
Phase 1 - Metrics:
Count wiki pages
Break down by namespace
Break down by type (entity, project, knowledge, feedback, hub)
Find oldest and newest updated dates
Count total cross-references
Phase 2 - Health:
Lightweight lint (no file modifications)
Report: orphans, stale pages, broken refs, index drift
Phase 2b - Cache Profile (from the Access-Log page):
Hot pages: most-queried pages (last 30 days) — top 5
Cold pages: active pages with last access > N months (demote-ready for the next prune)
Live-index size per namespace (routing lines in
### Index) vs. archive-index sizeLast prune run (newest archived:: date) + a recommendation when the cold-page count is high
Routing transparency: break down the most frequent
matched:reasons per hot page from recent log lines — shows not just WHICH pages are hot but WHY (which index description / grep term pulls them). Surfaces mis-routing: a page always hit via the same grep term instead of its index line signals a weak/missing routing description in its hub### Index
Phase 3 - Activity:
Git log for wiki changes (last 7 days, last 30 days)
Most recently updated pages
Pages with most incoming links
Phase 4 - Output:
Formatted dashboard with metrics
Comparison to last status run (if Dashboard page exists)
Workflow: setup
One-time. Creates the wiki skeleton in the wiki root: Schema, Dashboard, one hub page per namespace,
the Access-Log page and llm-wiki.yml. You render the bundled templates and write the files
yourself with the Read and Write tools; git runs through Bash. Create nothing besides the files
listed in Phase 3, and never overwrite an existing file. Do not write a script or an inline
program (python3 -c, heredoc) to do this; use the tools step by step.
Phase 1 - Check:
If
llm-wiki.ymlexists in the wiki root: report that the wiki is already set up, show itstoolandnamespaces, and stop without changing anything. Only if the user then asks to add missing pages, continue with the values from the existing config; Phase 3 skips every file that already exists.If the wiki root exists and is not a directory: stop with an error naming the path.
Templates live in
${CLAUDE_PLUGIN_ROOT}/templates/logseq/and${CLAUDE_PLUGIN_ROOT}/templates/obsidian/. If that path still starts with a dollar sign and a brace, stop and tell the user: "This is a copied skill and the clone path is not filled in. Replace the CLAUDE_PLUGIN_ROOT placeholder in the copied file with the path of your llm-wiki clone (see the README)."
Phase 2 - Ask the user, in one message:
Tool: Logseq or Obsidian. If the wiki root contains a
logseq/directory suggest Logseq, if it contains.obsidian/suggest Obsidian.Namespaces: default
Business Tech Content Projects People Learning Reference, or their own space-separated list.Claude Code memory directory for the L1 features (optional, usually
~/.claude/projects/<project>/memory/).If the wiki root is not a git repository: whether to initialize git there.
Validate before writing anything, and ask again on an invalid answer:
Tool must be Logseq or Obsidian.
Every namespace must match
^[A-Za-z][A-Za-z0-9-]*$; name the invalid ones.Read the four templates of the chosen tool (
Schema.md,Dashboard.md,Hub.md,Access-Log.md). If one cannot be read, stop with the path you tried.Expand a leading
~in the memory path to the home directory. Do not check that it exists.git: if the user wants git init or the root is a repository, check
git --version. Without git, warn that the git steps are skipped and continue.
Phase 3 - Create:
Run
date +%Y-%m-%donce. This is DATE for every file.mkdir -p "<wiki root>". Use the absolute root without a trailing slash from here on.Targets, in this order.
<ns>stands for each namespace in the order the user gave.Page Logseq ( pages_dir: pages)Obsidian ( pages_dir:empty)Template Schema pages/Wiki___Schema.mdWiki/Schema.mdSchema.mdDashboard pages/Wiki___Dashboard.mdWiki/Dashboard.mdDashboard.mdHub per namespace pages/Wiki___<ns>.mdWiki/<ns>/_index.mdHub.mdAccess-Log pages/Wiki___Reference___Access-Log.mdWiki/Reference/Access-Log.mdAccess-Log.mdConfig llm-wiki.ymlllm-wiki.yml(below) The Access-Log page is created even when Reference is not one of the namespaces.
Check which targets exist with one Bash call (
test -eper path, relative to the root). Existing targets are skipped, whatever their content. Do not rely on the Write tool to refuse.Git init, only if the user agreed and the root has no
.git:git -C "<root>" init. Then, if there is no.gitignore, write one with these lines (each followed by a newline):Logseq:
logseq/bak/,logseq/.recycle/,.DS_Store,.logseq/Obsidian:
.obsidian/workspace.json,.obsidian/workspace-mobile.json,.DS_Store,.trash/
Write each page that does not exist: the template text with these placeholders replaced, and nothing else changed. Keep every character, tab, line break and the final newline of the template. Do not reformat, translate, shorten or extend it.
{{DATE}}: DATE{{NAMESPACES}}(Schema):Wiki/<ns>for each namespace, joined by a comma and a space, for exampleWiki/Tech, Wiki/Content{{NAMESPACE_LINKS}}(Dashboard): one line per namespace, joined by a single newline, with no newline after the last one. Logseq line: a tab character, then- [[Wiki/<ns>]]. Obsidian line:- [[Wiki/<ns>]].{{NAMESPACE}}(Hub): the namespace of that hub page
Write
llm-wiki.ymllast, if it does not exist. Exactly these lines, each followed by a newline. An empty value is written as the key and colon with nothing after it (pages_dir:):# llm-wiki configuration # Generated by llm-wiki on <DATE> tool: <logseq|obsidian> wiki_path: <absolute wiki root> pages_dir: <pages, or empty for Obsidian> memory_path: <memory path, or empty> namespaces: - <first namespace> - <next namespace, one line each>After each target, print
Created: <label>orSkipped (already exists): <label>. Label:Wiki/<page>for Logseq pages (Wiki/Reference/Access-Log), the relative path for Obsidian pages,llm-wiki.ymlfor the config,.gitignorefor the ignore file.Commit, only if the root is a git repository and this run created at least one file. Stage exactly the created files by path, never anything else:
git -C "<root>" add -- <created paths>, then commit with this message (N = number of namespaces):wiki: initial setup via llm-wiki Schema, Dashboard, and hub pages for <N> namespaces. Tool: <logseq|obsidian> Generated by https://github.com/MehmetGoekce/llm-wikiIf the commit fails, warn and leave the files uncommitted; do not stop.
Phase 4 - Report:
Files created and skipped, the path of
llm-wiki.ymlNext steps: open the wiki in the chosen tool, try
/llm-wiki ingest "<a first source>", then/llm-wiki statusIf the current project contains
.claude/commands/wiki.md: tell the user that an older copied/wikiskill is installed as well and that deleting that file avoids running two versions. Do not delete it yourself.
Workflow: import
Phase 1 - Inventory:
Scan source directory for markdown files
Classify each file by content type
Identify potential namespace mapping
Phase 2 - Conversion:
Convert to wiki format (tool-specific: outliner or flat markdown)
Add required properties (type, created, updated, source)
Convert internal links to Wiki/... cross-references
Phase 3 - Create Pages:
Create hub pages first
Create content pages
Update all hub pages with children links
Phase 4 - Verification:
Run lint on imported pages
Report: pages imported, issues found
Git commit with import summary
</workflow>
<formats> ## Hub-Index-Routing (format)
Every hub page (type hub) carries two sections that query Phase 0 reads and ingest/prune maintain.
A routing line is [[link]] -- description #tags, one per child page.
Logseq (outliner):
- ## Tech
- ### Index
- [[Wiki/Tech/Strapi]] -- Strapi 5 CMS, ports, deploy + migration gotchas #strapi #deploy
- [[Wiki/Tech/PM2]] -- PM2 process management on the VPS, cwd/reload bug #pm2 #deploy
- ### Archive
- [[Wiki/Tech/Legacy-Foo]] -- (demoted 2026-06-07) old Foo stack, replaced by Bar #archivedObsidian (flat markdown):
## Tech
### Index
- [[Wiki/Tech/Strapi]] -- Strapi 5 CMS, ports, deploy + migration gotchas #strapi #deploy
- [[Wiki/Tech/PM2]] -- PM2 process management on the VPS, cwd/reload bug #pm2 #deploy
### Archive
- [[Wiki/Tech/Legacy-Foo]] -- (demoted 2026-06-07) old Foo stack, replaced by Bar #archivedRules:
Description <=120 chars, distinctive (it is the routing key), no filler ("Info about ...")
Tags mirror the page's own #tags — multi-match across tags is fine
### Index= live (routable).### Archive= evicted (only L3 grep finds the page)The hub child list IS the routing index — there is no separate index file
Access-Log (format)
Page: Wiki/Reference/Access-Log (Wiki___Reference___Access-Log.md / Wiki/Reference/Access-Log.md)
— an append-only LRU signal + routing transparency, one line per page read:
Logseq:
- access-log:: true
- type:: reference
- ## Log (append-only, newest at bottom)
- 2026-06-07 -- [[Wiki/Tech/Strapi]] -- query -- matched: "Strapi 5 -- ports, deploy, migration"
- 2026-06-07 -- [[Wiki/Projects/GEO]] -- query -- matched: "L3-grep: geo strategy"Obsidian:
---
access-log: true
type: reference
---
## Log (append-only, newest at bottom)
- 2026-06-07 -- [[Wiki/Tech/Strapi]] -- query -- matched: "Strapi 5 -- ports, deploy, migration"
- 2026-06-07 -- [[Wiki/Projects/GEO]] -- query -- matched: "L3-grep: geo strategy"Rules:
Log ONLY pages actually read in full (not the hub-index reads from Phase 0)
matched:field (routing transparency) = why the page was picked for this question: the matched hub### Indexrouting description / #tag (index routing) or the grep term (L3 fallback), <= 60 chars, in quotes. Makes loading auditable — not just WHAT loaded but WHY. Legacy lines withoutmatched:stay valid (the field is additive, optional-backward)Append-only, NO per-query git commit (non-structural; rides along with the next prune/lint/ingest commit)
prune/status parse the date +
[[page]]from fixed positions (split on--); thematched:suffix is irrelevant to LRU aggregation and does not affect parsingThis page is exempt from orphan / stale / demote rules
State + History (format)
A block that changes over time (a task, a decision, a host's status) shows the current state on top and, collapsed below it, how it got there.
Logseq:
- 🔴 Decommission staging VM — due [[2026-09-29]]
status:: open
ticket:: OPS-195
decision:: run benchmark B1 first, then delete (2026-09-12)
- **Next step:** run B1, otherwise default A (check volumes, delete)
- Cost: trial credit until 09-30, ~$1/day after
- History
collapsed:: true
- 2026-09-12 decided B1 only; host unchanged
- 2026-09-07 fact check: trial ends 09-30, VM is emptyObsidian:
### 🔴 Decommission staging VM — due 2026-09-29
status: open · ticket: OPS-195 · decision: run benchmark B1 first, then delete (2026-09-12)
**Next step:** run B1, otherwise default A (check volumes, delete)
> [!note]- History
> - 2026-09-12 decided B1 only; host unchanged
> - 2026-09-07 fact check: trial ends 09-30, VM is emptyRules:
Headline = one line: status marker, task, due date. No bold in the headline
Properties only for queryable fields (status, due, ticket, decision, blocker)
"Next step" = first child and the only bold text in the block
Context children one line each (cost, current reading, details link) — no prose over ~600 characters
History= last child, collapsed (Logseqcollapsed:: true, Obsidian folded callout[!note]-), one line per date, newest firstOn update, OVERWRITE headline / properties / next step; the old wording becomes a history line. Mark interim states that never happened
(superseded)Hubs:
updated::holds the date only; change notes live as lines in a collapsed## Change logsection (one sub-block per hub section), newest first
L1 Frontmatter (format)
L1 memory files keep their existing frontmatter; llm-wiki adds two optional keys. Top level:
---
name: pm2-reload-npm-start
description: PM2 reload breaks when the app was started via npm start
asserts-current-behavior: true
verified: 2026-06-15
---Or inside an existing metadata: block (write where the file already keeps its metadata):
---
name: no-ai-attribution
description: No AI attribution in commits or published content
metadata:
type: feedback
asserts-current-behavior: false
---Rules:
true= claim about a system's current state;false= decision / preference / identity / rationaleverifiedonly ontruerules, ISO date, set only by re-verify inprune --l1No key = unclassified: counted by lint, never flagged as due
Writes MUST NOT reorder or remove other frontmatter keys
The L1 index file (e.g. MEMORY.md) carries neither key
</formats>
<constraints> - NEVER store credentials, passwords, or API tokens in wiki pages (wiki is git-tracked!) - Delete nothing, but overwrite stale state: superseded statements move verbatim into the block's collapsed `History` (§ State + History) — never append "Status <date>:" addenda to running prose. Blocks without a new state stay untouched - NEVER modify non-wiki pages (existing notes, journals, etc.) - LRU-Demote evicts from the index ONLY — it NEVER renames pages or moves files. The tool links by page name; a move would break every incoming link. Demote = routing line out + archived:: marker (status:: archived too, for entity pages); the file stays in place and stays greppable (L3) - The Access-Log append is non-structural — NO git commit per query; it rides along with the next prune/lint/ingest commit (avoids read-churn in the git-tracked wiki) - Every active page belongs in exactly one hub `### Index` — ingest sets the routing line, else the page is unroutable (only findable via L3 grep). lint --fix backfills missing lines - L1 is NOT git-tracked: every L1 write (classify, re-verify, demote, delete) needs per-item confirmation; show a carry-over summary and the file path before removing one. Evidence checks are read-only and local - ALWAYS read llm-wiki.yml first to determine tool and paths - ALWAYS use correct format for the configured tool (outliner vs. flat markdown) - Properties: tool-specific (property:: value for Logseq, YAML frontmatter for Obsidian) - Max 3 wiki pages loaded simultaneously (JIT retrieval) - Git commit after every structural change - L1 feedback rules belong in Memory, NOT in the wiki - New quick rules/gotchas -> recommend Memory, not Wiki - New projects/workflows/research -> Wiki - Dates: ISO 8601 (YYYY-MM-DD) </constraints>
58 files · 2 not served here
- .claude-plugin/icon.png (not served here)
- .claude-plugin/marketplace.json
- .claude-plugin/plugin.json
- .github/ISSUE_TEMPLATE/bug_report.md
- .github/ISSUE_TEMPLATE/config.yml
- .github/ISSUE_TEMPLATE/feature_request.md
- .github/PULL_REQUEST_TEMPLATE.md
- .github/SECURITY.md
- .gitignore
- ATTRIBUTION.md
- CHANGELOG.md
- CONTRIBUTING.md
- LICENSE
- README.md
- SECURITY.md
- SKILL.md
- config.example.yml
- docs/diagrams.md
- docs/faq.md
- docs/graph-view.png (not served here)
- docs/l1-l2-architecture.md
- docs/logseq-vs-obsidian.md
- docs/schema-reference.md
- docs/troubleshooting.md
- examples/before-after.md
- examples/l1-memory-examples.md
- openspec/AGENTS.md
- openspec/changes/archive/2026-10-11-add-plugin-packaging/design.md
- openspec/changes/archive/2026-10-11-add-plugin-packaging/proposal.md
- openspec/changes/archive/2026-10-11-add-plugin-packaging/specs/config.md
- openspec/changes/archive/2026-10-11-add-plugin-packaging/specs/plugin.md
- openspec/changes/archive/2026-10-11-add-plugin-packaging/specs/setup.md
- openspec/changes/archive/2026-10-11-add-plugin-packaging/tasks.md
- openspec/changes/remove-shell-scripts/design.md
- openspec/changes/remove-shell-scripts/proposal.md
- openspec/changes/remove-shell-scripts/specs/config.md
- openspec/changes/remove-shell-scripts/specs/plugin.md
- openspec/changes/remove-shell-scripts/specs/setup.md
- openspec/changes/remove-shell-scripts/tasks.md
- openspec/project.md
- openspec/specs/config.md
- openspec/specs/ingest.md
- openspec/specs/l1-l2-routing.md
- openspec/specs/lint.md
- openspec/specs/plugin.md
- openspec/specs/prune.md
- openspec/specs/query.md
- openspec/specs/schema.md
- openspec/specs/setup.md
- templates/logseq/Access-Log.md
- templates/logseq/Dashboard.md
- templates/logseq/Hub.md
- templates/logseq/Schema.md
- templates/obsidian/Access-Log.md
- templates/obsidian/Dashboard.md
- templates/obsidian/Hub.md
- templates/obsidian/Schema.md
- wiki.md
Advantages
- 5-minute setup. Install the plugin, run /llm-wiki setup, and you have a schema, namespaces, and git tracking. No manual design needed. evidence: README.md
- Claude becomes your wiki maintainer. /llm-wiki ingest updates 5-15 pages with cross-references from a single source. evidence: README.md
- L1/L2 architecture. Auto-loaded rules in memory (L1) + deep knowledge in the wiki (L2). No other tool has this. evidence: README.md
- Built-in quality checks. /llm-wiki lint finds orphan pages, stale content, broken refs, and credential leaks. evidence: README.md
- Logseq + Obsidian. Use whichever you already have. No tool switch required. evidence: README.md
Limitations
- The schema feels overengineered at first. With 10 pages, defining 5 page types and 8 lint rules seems like overkill. Past 50 pages, you will be grateful for the consistency. Define the schema early -- it is much harder to retrofit one later. evidence: README.md
- Two systems means you need a clear boundary. Having both L1 and L2 means you could accidentally put the same information in both places. The lint rule for L1/L2 duplicates exists precisely for this reason. evidence: README.md
- Parallel agents can conflict. If you have multiple Claude sessions writing to wiki files simultaneously, concurrent edits can cause conflicts. Treat wiki files as a shared resource. evidence: README.md
- Start with fewer hub pages. Let them emerge organically from ingest operations rather than creating empty hubs upfront. evidence: README.md
Security
Risk level: No risk found
This brain runs
Agent instructions that run or fetch something (18)
SKILL.md:Run /llm-wiki setup to create one." If its `wiki_path` names a different directory than the wiki root above, warn once, naming both paths, and continue with the wiki root above.SKILL.md:Meant as a periodic run (default cadence N = 6 months) — wire it via your scheduler;SKILL.md:READ-ONLY and LOCAL: check existence, read files, search contents, read dependency manifests, run commands only with `--version` / `--help`.SKILL.md:Evidence basis per claim: `executed` (read-only command), `source` (read the implementing code, not run), or `file` (existence/content).SKILL.md:Skip -> file untouched, stays due for the next runSKILL.md:Timestamp the lint runSKILL.md:Last prune run (newest archived:: date) + a recommendation when the cold-page count is highSKILL.md:Comparison to last status run (if Dashboard page exists)SKILL.md:git: if the user wants git init or the root is a repository, check `git --version`.SKILL.md:Run `date +%Y-%m-%d` once.SKILL.md:Git init, only if the user agreed and the root has no `.git`: `git -C "<root>" init`.SKILL.md:Commit, only if the root is a git repository and this run created at least one file.SKILL.md:Run lint on imported pagesSKILL.md:decision:: run benchmark B1 first, then delete (2026-09-12)SKILL.md:- **Next step:** run B1, otherwise default A (check volumes, delete)SKILL.md:status: open · ticket: OPS-195 · decision: run benchmark B1 first, then delete (2026-09-12)SKILL.md:**Next step:** run B1, otherwise default A (check volumes, delete)openspec/AGENTS.md:git is optional.
Attribution and licence
- Created by
- Mehmet Goekce
- Declared authors
- Mehmet Goekce (declared in .claude-plugin/plugin.json)
- Publisher
- Mehmet Gökçe (Community)
- Source
- MehmetGoekce/llm-wiki · commit 5fa5ee7
- Licence
- MIT License (files served here)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by Mehmet Goekce.
Install from source
2 of its files are not served here, so there is no ZIP. MehmetGoekce/llm-wiki at 5fa5ee7