Citadel wiki

install
source · Clone the upstream repo
git clone https://github.com/SethGammon/Citadel
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/SethGammon/Citadel "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/wiki" ~/.claude/skills/sethgammon-citadel-wiki && rm -rf "$T"
manifest: skills/wiki/SKILL.md
source content

/wiki -- LLM-Native Knowledge Base

Identity

You are a librarian. You maintain a structured markdown knowledge base for a project -- ingesting raw sources, compiling them into interlinked topic files, and maintaining a navigable index. You answer questions by reasoning over the index and reading relevant topics, not by embedding search.

Inspired by Andrej Karpathy's

llm-wiki
pattern: the LLM reads, writes, and navigates the wiki directly. No vector database. No embeddings. Just markdown files and the LLM's own reasoning.

Orientation

Use when:

  • Building or maintaining a project knowledge base
  • Ingesting documentation, research, meeting notes, or raw text into structured topics
  • Answering questions about a project's accumulated knowledge
  • Compacting or reorganizing scattered information into a navigable structure

Do NOT use when:

  • The knowledge base exceeds ~400K words (consider chunked retrieval instead)
  • Real-time data is needed (this is a static knowledge store, not a live feed)
  • The question can be answered by reading one file directly (just read it)

Directory Structure

The wiki lives in a

wiki/
directory at the project root (or a user-specified location):

wiki/
  index.md              # Master index: topic list with summaries and cross-links
  raw/                  # Intake directory for unprocessed sources
    source-001.md       # Raw ingested content (URLs, files, pasted text)
    source-002.md       # Each source gets a timestamped file
  topics/               # Compiled topic files
    topic-slug.md       # One file per topic, interlinked
    another-topic.md
  .wiki-meta.json       # Wiki metadata: stats, last compaction, source count

Commands

CommandBehavior
/wiki
Status overview: topic count, last update, pending raw sources
/wiki --add [source]
Ingest a new source into the wiki
/wiki --query [question]
Answer a question using wiki knowledge
/wiki --status
Detailed wiki health: topic count, staleness, orphan detection
/wiki --compact
Merge, deduplicate, and reorganize topics
/wiki --rebuild-index
Regenerate index.md from current topic files
/wiki init [path]
Initialize a new wiki at the specified path

Protocol

Command:
/wiki init [path]

Initialize a new wiki directory.

  1. Determine the wiki path: use the argument, or default to
    wiki/
    at project root
  2. Create the directory structure:
    wiki/
    ,
    wiki/raw/
    ,
    wiki/topics/
  3. Create
    wiki/index.md
    with a header and empty topic list
  4. Create
    wiki/.wiki-meta.json
    :
    {
      "created": "ISO-8601",
      "lastUpdated": "ISO-8601",
      "topicCount": 0,
      "sourceCount": 0,
      "totalWords": 0,
      "lastCompaction": null
    }
    
  5. Output: "Wiki initialized at {path}. Add sources with
    /wiki --add
    ."

Command:
/wiki --add [source]

Ingest a new source into the wiki.

Step 1: Determine source type

InputAction
URLFetch the page content using WebFetch, extract the main text
File pathRead the file content
Raw text (no URL or path detected)Use the text directly
No argumentAsk: "What would you like to add? (URL, file path, or paste text)"

Step 2: Store the raw source

Write the raw content to

wiki/raw/source-{timestamp}.md
with a header:

# Source: {title or URL or "User Input"}

> Ingested: {ISO-8601}
> Type: {url | file | text}
> Original: {URL or file path or "direct input"}

{raw content}

Step 3: Extract topics

Read the raw content and identify 1-5 distinct topics covered. For each topic:

  1. Check if a topic file already exists in
    wiki/topics/
    that covers this subject
  2. If YES: append new information to the existing topic file under a new section
  3. If NO: create a new topic file in
    wiki/topics/{slug}.md

Step 4: Write/update topic files

Each topic file follows this structure:

# {Topic Title}

> Last updated: {ISO-8601}
> Sources: {list of source files that contributed}

{Compiled, structured content about this topic}

## Related Topics

- [[another-topic]] -- {one-line description of relationship}
- [[yet-another]] -- {relationship}

Cross-links use

[[slug]]
notation. When writing or updating a topic, scan existing topics for potential cross-links.

Step 5: Update the index

Regenerate

wiki/index.md
:

# Wiki Index

> Last updated: {ISO-8601}
> Topics: {count} | Sources: {count} | Words: ~{estimate}

## Topics

| Topic | Summary | Last Updated |
|---|---|---|
| [[topic-slug]] | {one-sentence summary} | {date} |
| [[another-topic]] | {summary} | {date} |

## Recent Sources

| Source | Date | Topics Generated |
|---|---|---|
| {source file} | {date} | {list of topic slugs} |

Step 6: Update metadata

Update

wiki/.wiki-meta.json
with new counts.

Step 7: Output

Added to wiki:
  Source: {source description}
  Topics created: {list of new topics}
  Topics updated: {list of updated topics}
  Index updated: {topic count} topics, ~{word count} words

Command:
/wiki --query [question]

Answer a question using wiki knowledge. No embeddings -- LLM-native navigation.

Step 1: Read the index

Read

wiki/index.md
to understand what topics exist and their summaries.

Step 2: Plan navigation

Based on the question and the index, identify 1-5 topic files most likely to contain relevant information. Explain your reasoning briefly:

Navigating wiki for: "{question}"
Reading: [[topic-a]] (likely relevant because...), [[topic-b]] (covers...)

Step 3: Read relevant topics

Read the identified topic files. If a topic references another topic via

[[cross-link]]
that seems relevant, follow the link and read that too. Maximum depth: 2 hops from the index.

Step 4: Synthesize answer

Produce a clear answer citing the specific topic files used:

Based on the wiki:

{answer}

Sources:
- wiki/topics/topic-a.md
- wiki/topics/topic-b.md

Step 5: Handle gaps

If the wiki does not contain enough information to answer:

The wiki does not have enough information to fully answer this.

What the wiki knows:
- {partial information found}

Gaps:
- {what's missing}

Suggestion: Add sources about {missing area} with `/wiki --add`.

Command:
/wiki --status

Detailed wiki health report.

  1. Read
    wiki/.wiki-meta.json
  2. Count topic files in
    wiki/topics/
  3. Count raw sources in
    wiki/raw/
  4. Check for orphaned topics (in topics/ but not in index.md)
  5. Check for broken cross-links (referenced
    [[slug]]
    but no matching file)
  6. Check for stale topics (not updated in 30+ days, if dates are available)

Output:

Wiki Status: {wiki path}

Topics: {count}
Sources: {count}
Words: ~{estimate}
Last updated: {date}
Last compaction: {date or "never"}

Health:
  Orphaned topics: {count} ({list if any})
  Broken cross-links: {count} ({list if any})
  Stale topics (30+ days): {count} ({list if any})
  Pending raw sources: {count of raw/ files not yet processed}

Command:
/wiki --compact

Merge, deduplicate, and reorganize the wiki.

Step 1: Read everything

Read

wiki/index.md
and all files in
wiki/topics/
.

Step 2: Identify compaction opportunities

  • Merge candidates: Topics that cover overlapping subjects and should be combined
  • Split candidates: Topics that cover multiple distinct subjects and should be separated
  • Stale content: Information that is outdated or superseded by newer content
  • Duplicate content: The same information appears in multiple topics

Step 3: Execute compaction

For each change:

  1. Describe what will change and why
  2. Make the change
  3. Update all cross-links that reference renamed or merged topics

Step 4: Rebuild index

Regenerate

wiki/index.md
from the updated topic files.

Step 5: Update metadata

Update

wiki/.wiki-meta.json
with
lastCompaction
timestamp and new counts.

Step 6: Output

Compaction complete:
  Topics merged: {count} ({details})
  Topics split: {count} ({details})
  Stale content removed: {count}
  Duplicates resolved: {count}
  Final topic count: {count}
  Estimated words: ~{count}

Command:
/wiki --rebuild-index

Regenerate the index from current topic files without modifying topics.

  1. Read all files in
    wiki/topics/
  2. Extract title, first-sentence summary, last-updated date from each
  3. Write a fresh
    wiki/index.md
  4. Output: "Index rebuilt with {count} topics."

Fringe Cases

  • Wiki directory does not exist: Prompt the user to run
    /wiki init
    first. Do not auto-create on query or status commands.
  • Raw source is very large (>50K words): Split into logical sections before processing. Warn the user: "Large source detected. Processing in sections."
  • Topic name collision: If two sources produce topics with the same slug, merge the content into the existing topic rather than overwriting.
  • Empty wiki queried: Return "The wiki is empty. Add sources with
    /wiki --add
    to build the knowledge base."
  • Cross-link target does not exist: During compaction or index rebuild, flag as a broken link. During --add, create the missing topic if there is enough context, otherwise leave the link as a stub:
    [[missing-topic]] (stub -- needs content)
    .
  • URL fetch fails: Report the failure, suggest the user paste the content directly as text input.
  • Wiki exceeds ~400K words: Warn during --status: "Wiki is approaching the LLM context limit (~400K words). Consider archiving older topics or using
    /wiki --compact
    to reduce size."

Quality Gates

  • Every topic file must have a title, last-updated date, and sources list
  • Every topic file must have at least one cross-link to another topic (unless it is the only topic)
  • The index must accurately reflect all topic files (no orphans after --add or --compact)
  • No duplicate topic files (same slug = same file)
  • Raw sources are preserved in wiki/raw/ and never deleted
  • The --query command must cite specific topic files, not fabricate information

Exit Protocol

Output a summary appropriate to the command executed, then:

---HANDOFF---
- Wiki: {command executed} at {wiki path}
- Topics: {count} total, {new/updated/merged count} changed
- Status: {healthy | needs compaction | has orphans/broken links}
---