init commit to create the project

This commit is contained in:
Travis Herbranson 2026-05-04 20:37:26 -04:00
commit 0f1347b362
10 changed files with 1498 additions and 0 deletions

10
.gitignore vendored Normal file
View File

@ -0,0 +1,10 @@
# Python-generated files
__pycache__/
*.py[oc]
build/
dist/
wheels/
*.egg-info
# Virtual environments
.venv

1
.python-version Normal file
View File

@ -0,0 +1 @@
3.12

404
CLAUDE.md Normal file
View File

@ -0,0 +1,404 @@
# CLAUDE.md — HomeLab Wiki Vault Spec
This file is the spec for this Obsidian vault. Any agent operating
on this vault reads this file first to understand the structure,
the page types, and the rules. Procedures (compile, lint,
migration) live in the `wiki-maintenance` skill on herbydev — this
file is the spec they reference.
## Purpose
This vault is Travis's personal knowledge wiki. It holds project
plans, session notes, entity pages for recurring people/systems/
tools, topic landing pages, and synthesis pages.
The vault is organized for **human browsing in Obsidian**, not for
autonomous agent consumption. Agents update the wiki on explicit
human invocation. Agents reference the wiki only when explicitly
pointed at a file.
## Vault structure
Flat structure under four ownership domains. No `Projects/`,
`Sessions/`, or `Reference/` subfolders within domains.
```
HomeLab/
├── CLAUDE.md # this file
├── index.md # top-level catalog
├── log.md # append-only event log
├── Dev/
│ ├── index.md # Dev domain landing
│ └── *.md # all Dev pages, flat
├── Content/
│ ├── index.md # Content domain landing
│ └── *.md # all Content pages, flat
├── Homelab/
│ ├── index.md # Homelab domain landing
│ └── *.md # all Homelab pages, flat
└── Reference/
├── index.md # cross-domain entity landing
└── *.md # cross-domain entity pages, flat
```
A fourth ownership domain may be added later (likely `Personal`).
Reserved space; not active yet.
## Folder ownership rules
- **Dev** — coding projects, dev environment, language explorations,
AI/ML experiments, DeFi research, tooling
- **Content** — PBS planning, recipes, brand assets, content
campaigns, anything Jenny might eventually touch
- **Homelab** — infrastructure, networking, hardware, sysadmin,
storage, deployments
- **Reference** — cross-domain entities (Lovebug, OB1, herbydev,
Jenny, Sunnie, KeePassXC, Tailscale, etc.) — things that span
multiple domains and don't sit cleanly in one
Cross-domain content: prefer the domain where the *primary
ownership* lives. If genuinely cross-cutting and entity-shaped,
put in `Reference/`. If genuinely cross-cutting and project-shaped,
pick one domain and tag with the others.
## Page types
Five types. No others without explicit user request.
### Project page
A project page is the primary unit. One per active or recently
active project. The 30-second orientation document.
**Frontmatter:**
```yaml
---
project: <slug> # unique slug, lowercase-dashes, matches filename
type: project
status: active # active | paused | completed | archived
path: <domain> # Dev | Content | Homelab | Reference
tags:
- <tag>
created: YYYY-MM-DD
updated: YYYY-MM-DD
---
```
**Required sections:**
- **Current state** — 2-4 sentences, what's happening right now
- **Decisions locked** — bulleted, dated as needed
- **Open questions** — what's stuck or deferred
- **Sessions** — backlinked list of related session notes
- **Related** — wikilinks to entities, topics, other projects
**Filename:** `<slug>.md` (e.g., `ob1-deployment.md`,
`wiki-construct.md`)
### Session note
What happened in a working session. Top-level artifact, not a
child of any project. May reference a project via wikilinks but
does not live inside it.
**Frontmatter:**
```yaml
---
project: <slug> # if related to a project; otherwise omit
type: session-notes
status: active # usually active; occasionally archived
path: <domain>
tags:
- <tag>
created: YYYY-MM-DD
updated: YYYY-MM-DD
---
```
**Required sections:**
- **Outcomes** — what came out of the session
- **Topics covered** — what was discussed
- **Key learnings** — what was learned, briefly
- **Follow-ons** — checkbox list of follow-up tasks, if any
**Filename:** `YYYY-MM-DD-<slug>.md` (date prefix for chronological
sort)
### Entity page
A recurring character in Travis's world. People, systems, tools,
hardware, services that show up across multiple projects or
sessions and benefit from a stable home page.
**Frontmatter:**
```yaml
---
type: entity
path: <domain> # or Reference for cross-domain
tags:
- <tag>
created: YYYY-MM-DD
updated: YYYY-MM-DD
---
```
**Required sections:**
- **What it is** — one paragraph
- **Current state** — present-tense status
- **Where it lives** — host, repo, URL, path as applicable
- **Related projects** — wikilinks
- **History** — terse, dated notes of significant events
**Filename:** `<entity-slug>.md` (e.g., `lovebug.md`, `herbydev.md`,
`ob1.md`)
### Topic landing / index
Domain-level catalog and prose overview. One per ownership
domain (`<domain>/index.md`). Plus the top-level `index.md` that
spans all domains.
**Frontmatter:**
```yaml
---
type: topic-landing
path: <domain>
tags:
- landing
updated: YYYY-MM-DD
---
```
**Required sections:**
- **Current state** — agent-written prose, 3-5 sentences, what's
going on across this domain right now
- **Active projects** — list of projects with `status: active`,
one-line current state for each, link to project page
- **Recent sessions** — most recent session notes (last ~10 or
last 30 days, whichever is shorter)
- **Key entities** — entity pages relevant to this domain
- **Synthesis pages** — list of any synthesis pages scoped to
this domain
- **Completed projects** — collapsed or smaller section,
`status: completed` or `archived`
The agent maintains these on every compile pass. They are
generated from frontmatter queries plus a short prose
"current state" the agent updates.
### Synthesis page
Cross-cutting analysis. Pulls from multiple existing pages and
produces a synthesized view. Generated by the agent during
compile when it identifies a worth-synthesizing pattern.
**Frontmatter (sources field is required):**
```yaml
---
type: synthesis
path: <domain> # or Reference for cross-domain
tags:
- <tag>
sources:
- "[[<wikilink-to-source-1>]]"
- "[[<wikilink-to-source-2>]]"
- "[[<wikilink-to-source-3>]]"
created: YYYY-MM-DD
updated: YYYY-MM-DD
---
```
**Required sections:**
- **Synthesis** — the cross-cutting analysis itself
- **Sources** — narrative discussion of what each source
contributed; each claim should be traceable to one or more
sources
- **Open questions** — gaps or contradictions surfaced during
synthesis
**Filename:** `synthesis-<topic-slug>.md` (e.g.,
`synthesis-memory-architecture.md`)
**Synthesis page rules:**
- Sources are required; no synthesis page without them
- Every substantive claim should trace to a source via prose
attribution
- Claims that are agent inference (not directly in any source)
must be flagged as such in the prose
- Synthesis pages are the highest-risk page type for lossy
compression and get extra lint scrutiny
- The agent generates synthesis pages during compile when a
pattern emerges; do not generate one per compile run by
default
## Tag conventions
Tags answer "what is this about." Wikilinks answer "what
specific thing does this involve." Prefer wikilinks for
specific named things; use tags for topical categories.
### Starter tag list (curated)
**Topics:**
`claude-code`, `mcp`, `dispatch`, `tailscale`, `proxmox`,
`docker`, `ansible`, `authelia`, `traefik`, `obsidian`, `n8n`,
`pgvector`, `embeddings`, `terminal`, `automation`, `git`
**Lifecycle (also valid as `status:` frontmatter values):**
`active`, `paused`, `completed`, `archived`
**Project / system handles (rare — prefer wikilinks for these):**
`ob1`, `lovebug`, `sunnie`, `wiki`, `pbs`
### Adding a new tag
A new tag requires:
1. The user explicitly asks for it, OR
2. The agent encounters a recurring topical category that
appears in 3+ pages and would benefit from cross-referencing,
AND raises it for confirmation in the compile session summary
Do not add tags silently. Do not let the tag list grow
unconstrained.
## Entity promotion rules
A topic earns its own entity page when:
- It's referenced by name in 2+ projects, OR
- It's referenced in 3+ session notes, OR
- It's a piece of infrastructure (host, service, tool) that
Travis uses recurringly
Below this threshold, references stay as inline text or tags.
When promoting a topic to an entity page, the agent:
1. Creates the entity page with the standard sections
2. Updates referencing pages to use wikilinks instead of plain
text
3. Notes the promotion in the compile session summary
## Git protocol
The vault is a git repo. Compile runs use a two-commit pattern.
### Pre-compile commit
Before any compile-run writes:
```
pre-compile: <human-readable reason>
```
This captures the vault state before the agent touches anything.
If the compile run produces unwanted output, `git reset --hard`
to this commit to roll back.
### Post-compile commit
After all compile-run writes:
```
compile: <one-line summary>
Pages touched: <list>
Pages created: <list>
Entities promoted: <list>
Synthesis pages written: <list>
Contradictions flagged: <list>
Tags proposed: <list>
```
The body is the audit trail. `git log --oneline` shows the
compile history; `git show <commit>` shows what changed and why.
### Other commits
Lint runs commit as `lint: <summary>` if they make automatic
fixes (broken wikilinks, missing frontmatter fields). Manual
edits by Travis commit with whatever message Travis writes.
## What the agent does and does not do
**Agent does:**
- Compile runs when invoked
- Lint runs when invoked
- One-time migration when invoked
- Generates the five page types per spec
- Maintains topic landings and indexes
- Promotes entities when threshold is met (with notification)
- Writes synthesis pages when a worth-synthesizing pattern
emerges (with full source provenance)
- Two-commit git protocol on every compile run
- Reports findings in session summary
**Agent does not:**
- Run autonomously. Every operation is human-initiated.
- Restructure folders without explicit confirmation
- Delete pages without explicit confirmation
- Add new tags silently (proposes them in the compile summary)
- Generate concept pages or comparison pages (not in spec)
- Write synthesis pages on every compile run by default
- Modify pages outside the wiki (no edits to source code, no
changes to OB1, no changes outside the vault path)
- Skip the git protocol
## Lint scope
When invoked for a lint pass, the agent checks:
- **Broken wikilinks** — links to pages that don't exist
- **Orphan pages** — pages with no inbound wikilinks (may be
legitimate; flag for review, do not auto-delete)
- **Missing required frontmatter fields** — per page type spec
- **Inconsistent frontmatter values**`status:` not in valid
set, `path:` not matching folder, `type:` not in valid set
- **Stale `updated:` dates** — pages whose content has changed
but `updated:` is older than the most recent edit
- **Synthesis page integrity** — sources still exist, sources
still say what the synthesis claims they say, no source has
been substantially edited since synthesis was written
- **Cross-page contradictions** — the same fact stated
differently across pages
- **Index/landing freshness** — landing pages reflect current
vault state
Lint reports findings. It auto-fixes only mechanical issues
(missing dates, broken wikilinks where the target is obvious).
Anything substantive goes to the user for review.
## Operational invariants
- The vault is the source of truth for itself. The agent reads
the vault, computes changes, writes the vault.
- `log.md` is append-only. Never edit existing entries.
- `index.md` files are agent-maintained. Travis can edit them,
but the agent will reconcile on the next compile.
- Project pages, session notes, and entity pages may be edited
by either Travis or the agent. The most recent `updated:` date
wins for "current state" sections; structural changes by the
agent should preserve any user-added content unless explicitly
instructed otherwise.
- Synthesis pages are agent-authored but human-reviewed. Travis
may edit them; the agent should respect those edits and not
silently overwrite.
## Versioning
This file evolves with the vault. Changes to CLAUDE.md commit
with message `spec: <what changed>`. Major spec changes (new
page type, new folder, new operation) warrant a session note
documenting the rationale.

0
README.md Normal file
View File

6
main.py Normal file
View File

@ -0,0 +1,6 @@
def main():
print("Hello from wiki-context!")
if __name__ == "__main__":
main()

7
pyproject.toml Normal file
View File

@ -0,0 +1,7 @@
[project]
name = "wiki-context"
version = "0.1.0"
description = "Add your description here"
readme = "README.md"
requires-python = ">=3.12"
dependencies = []

611
skill/skill-wiki.md Normal file
View File

@ -0,0 +1,611 @@
# wiki-maintenance Skill Bundle
This document contains the four files that make up the
`wiki-maintenance` skill on herbydev. Lovebug deploys these to
`~/.claude/skills/wiki-maintenance/` during the build phase.
The skill bundle structure:
```
~/.claude/skills/wiki-maintenance/
├── SKILL.md # name, description, procedure overview
├── compile.md # detailed compile procedure
├── lint.md # detailed lint procedure
└── migration.md # one-time migration runbook
```
Each file below is the full content for that file. Copy each
section verbatim into the file at the matching path.
---
## File: `SKILL.md`
```markdown
---
name: wiki-maintenance
description: Use this skill when the user asks to update, compile, lint, or migrate their personal wiki vault. Trigger phrases include "update the wiki", "compile the wiki", "lint the wiki", "migrate the wiki", or any variation referring to maintenance of the LLM Wiki at the configured vault path. The skill maintains a Karpathy-style LLM Wiki of project plans, session notes, entity pages, topic landings, and synthesis pages, organized in a flat structure under four ownership domains. Reads the vault's CLAUDE.md spec at the vault root before performing any operation.
---
# wiki-maintenance
This skill maintains Travis's personal LLM Wiki vault. It does not
hold the spec — the spec lives at `<vault-root>/CLAUDE.md`. This
skill holds the procedures.
## Vault location
The vault root is the path the user has identified as their
HomeLab Obsidian vault. If the path is not stated in the session
plan and the user has not provided it in the conversation, ask.
## Operations
This skill performs three operations. Each has its own procedure
file:
- **Compile** — run the wiki compile loop. Procedure:
`compile.md`. Triggers: "update the wiki", "compile the wiki",
"run a compile", or similar.
- **Lint** — run health checks against the vault. Procedure:
`lint.md`. Triggers: "lint the wiki", "check the wiki",
"audit the wiki", or similar.
- **Migrate** — one-time migration of an existing vault to the
four-folder flat structure. Procedure: `migration.md`.
Triggers: "migrate the wiki", "reorganize the vault",
"set up the wiki structure", or similar.
## Pre-flight (every operation)
Before any operation, read these files in order:
1. `<vault-root>/CLAUDE.md` — the vault spec
2. `<vault-root>/log.md` — the event log; identifies the last
compile/lint/migration timestamp
3. The relevant procedure file from this skill
If any required file is missing, stop and report. Do not proceed
on assumptions.
## Operating principles
- Every operation is one-shot. No autonomous follow-up.
- Stop at confirmation gates specified in the procedure files.
Wait for explicit user confirmation.
- Never modify files outside the vault.
- Never run autonomously across multiple operations in one
invocation. If the user wants compile-then-lint, treat them
as two requests.
- All git operations follow the protocol in `CLAUDE.md`
pre-commit, post-commit, with reasoning in the body.
- Report concisely. Skip celebratory framing. State what was
done, what's next, what's blocked.
```
---
## File: `compile.md`
```markdown
# Compile Procedure
The compile operation reads recent vault changes, updates affected
pages, refreshes landings and indexes, generates synthesis pages
when warranted, and commits the result.
## Pre-flight
1. Read `<vault-root>/CLAUDE.md` (the spec)
2. Read `<vault-root>/log.md` (find timestamp of last compile
entry)
3. Confirm the vault is in a clean git state. If there are
uncommitted changes:
- If they are user edits in progress, stop and ask the user
to commit or stash before proceeding
- If they are leftovers from a failed prior run, stop and
report — do not auto-clean
## Step 1: Identify changes since last compile
- List all files in the vault with `mtime` newer than the last
compile timestamp from `log.md`
- Read those files in full
- Categorize: new files, edited files
- For each, identify its `type:` (project, session-notes,
entity, topic-landing, synthesis)
- If a file has no frontmatter or invalid frontmatter, flag it
but proceed with best-effort categorization
## Step 2: Pre-compile commit
Make a single commit capturing the vault state before any
writes:
```
git add -A
git commit -m "pre-compile: <reason>"
```
Where `<reason>` is the trigger phrase or a one-line summary of
what's about to be processed (e.g., "compile run, 3 new
sessions and 2 project edits").
## Step 3: Update affected pages
For each project page touched by recent changes:
- Refresh the **Current state** section based on session notes
added since the last update
- Add new session notes to the **Sessions** section as
wikilinks
- Update **Decisions locked** if recent sessions captured new
decisions
- Update **Open questions** based on recent activity
- Update the `updated:` frontmatter date
For each entity page referenced by recent changes:
- Update **Current state** if relevant
- Add new related projects/sessions to **Related projects**
section
- Append a History entry if a significant event occurred
- Update the `updated:` frontmatter date
## Step 4: Entity promotion check
For any topic referenced in 2+ projects or 3+ sessions that
does not yet have an entity page, propose promotion:
- Add to a `promotions:` list in the compile summary
- Do not auto-create. The user reviews the proposed promotions
and triggers a follow-up compile if any are approved.
(Exception: if the user's invocation explicitly authorized
auto-promotion for this run, proceed and create the pages.)
## Step 5: Synthesis check
Look for cross-cutting patterns warranting a synthesis page:
- Multiple sessions/projects converging on the same theme
- A pattern of decisions across projects that benefits from a
unified statement
- A body of related entities that lacks a connecting page
If such a pattern is identified:
- Draft a synthesis page per the spec in `CLAUDE.md`
- Required: `sources:` frontmatter listing every page it pulls
from
- Required: prose attribution for each substantive claim
- Required: explicit flag for any agent-inference claim not
directly in a source
Do not generate synthesis pages aggressively. One per compile
run is the norm; zero is fine. Three is suspicious.
## Step 6: Refresh topic landings and indexes
For each domain folder containing changes:
- Update `<domain>/index.md`:
- Refresh the **Current state** prose section
- Regenerate **Active projects** list from frontmatter query
- Regenerate **Recent sessions** list (last 10 or last 30
days)
- Update **Key entities** if entity list changed
- Update **Synthesis pages** if any were added in this run
- Update **Completed projects** section
- Update `<domain>/index.md`'s `updated:` date
Update the top-level `index.md`:
- Refresh the cross-domain catalog
- Update counts and recent-activity sections
## Step 7: Append to log.md
Append a single entry:
```markdown
## [YYYY-MM-DD HH:MM] compile | <one-line summary>
- Pages touched: <list>
- Pages created: <list>
- Entities promoted: <list, or "none">
- Synthesis pages written: <list, or "none">
- Tags proposed: <list, or "none">
- Contradictions flagged: <list, or "none">
- Notes: <free-text observations, if any>
```
## Step 8: Post-compile commit
```
git add -A
git commit -m "compile: <one-line summary>" -m "<body with same fields as log entry>"
```
## Step 9: Session summary
Report back to the user with:
- One-line summary of what was done
- Counts: pages touched, created, promoted, synthesized
- Anything flagged for user review (proposed promotions,
proposed tags, suspected contradictions)
- Anything that didn't get done and why (e.g., file with
invalid frontmatter, file the agent wasn't sure how to
categorize)
- Next step suggestion (lint pass, or nothing)
## Stop conditions
Stop and report (do not proceed) if:
- Vault has uncommitted changes that are not from this run
- `CLAUDE.md` is missing or unreadable
- A page has malformed frontmatter that the agent cannot
resolve confidently
- Git operations fail
- A proposed write would delete user content (always preserve;
flag for review)
## What this procedure does not do
- Restructure folders
- Delete pages
- Rename files
- Modify pages outside the vault
- Run lint (separate operation)
- Run a second compile pass after the first
```
---
## File: `lint.md`
```markdown
# Lint Procedure
The lint operation health-checks the vault and reports findings.
It auto-fixes mechanical issues only. Substantive issues go to
the user for review.
## Pre-flight
1. Read `<vault-root>/CLAUDE.md`
2. Read `<vault-root>/log.md`
3. Confirm the vault is in a clean git state. If not, ask the
user whether to proceed (lint is read-mostly, but auto-fixes
would commit on top of uncommitted work)
## Checks
### 1. Broken wikilinks
For every wikilink `[[<target>]]` in the vault:
- If the target file exists, OK
- If the target file does not exist:
- If the link is unambiguous (target name uniquely matches a
file with a different slug), auto-fix
- Otherwise, flag for user review with the source page and
line number
### 2. Orphan pages
Pages with no inbound wikilinks. List but do not act. Some
orphans are legitimate (top-level indexes, brand-new pages).
### 3. Frontmatter validation
For every page:
- `type:` must be one of: `project`, `session-notes`, `entity`,
`topic-landing`, `synthesis`
- `status:` (where present) must be one of: `active`, `paused`,
`completed`, `archived`
- `path:` must match the actual folder location
- `created:` must be present and ISO date format
- `updated:` must be present, ISO date format, and >= `created:`
- Page-type-specific required fields per `CLAUDE.md` spec
Auto-fix: missing `updated:` (set to `created:` or file mtime),
`path:` mismatched with folder (correct the field).
Flag for user review: missing `type:`, invalid `type:`,
malformed dates that can't be inferred.
### 4. Stale `updated:` dates
If a file's content has been edited (mtime newer than the
`updated:` frontmatter date by more than 1 day), refresh the
date. Auto-fix.
### 5. Synthesis page integrity
For every page with `type: synthesis`:
- Every page in the `sources:` list must exist. Flag any
missing.
- For each source, check whether its content has substantively
changed since the synthesis page's `updated:` date. If yes,
flag the synthesis page as potentially stale — do not
auto-rewrite.
- Verify the synthesis page has a **Sources** section with
prose attribution, not just the frontmatter list.
### 6. Cross-page contradictions
Best-effort check for the same factual claim stated
differently across pages. This is heuristic — flag candidates
for user review. Do not auto-resolve.
### 7. Tag hygiene
- Tags used on only one page may be candidates for retirement
(or for the page using a wikilink instead). List but do not
act.
- New tags introduced since the last lint pass: list, ask user
to confirm they should remain in the curated tag set.
### 8. Index and landing freshness
- For each `<domain>/index.md`, check that **Active projects**
list matches the actual `status: active` projects in the
domain. If out of sync, flag (do not auto-fix; that's
compile's job).
- Same check for **Recent sessions** and **Synthesis pages**
sections.
## Auto-fix commit
If any auto-fixes were made, commit:
```
git add -A
git commit -m "lint: <one-line summary of fixes>" -m "<list of fixes>"
```
If no auto-fixes were made, no commit.
## Lint report
Report to the user:
- **Auto-fixed** — what was fixed (with counts)
- **For your review** — what was flagged
- Broken wikilinks (with source pages and line numbers)
- Frontmatter issues (with file paths)
- Stale synthesis pages (with names and reasons)
- Suspected contradictions (with pages and details)
- New tags (with usage counts and example pages)
- Stale indexes (suggest running compile)
- Orphan pages (informational only)
- **Suggested next step** — usually a compile run if lint
found stale indexes or substantive changes
## Stop conditions
Stop and report if:
- `CLAUDE.md` is missing or unreadable
- Git operations fail
- The vault appears corrupted (no recognizable structure)
## What this procedure does not do
- Rewrite synthesis pages
- Delete orphan pages
- Modify page content beyond auto-fix scope
- Run compile
- Run migration
```
---
## File: `migration.md`
```markdown
# Migration Runbook
One-time procedure. Migrates an existing Obsidian vault to the
four-folder flat structure defined in `CLAUDE.md`. After
migration, normal compile/lint operations take over.
## Pre-flight
1. Read `<vault-root>/CLAUDE.md`
2. Confirm the vault is in a clean git state. If not, stop and
ask user to commit or stash.
3. Confirm with the user that this is a migration run, not a
compile run. Migration is destructive (file moves) and
one-shot.
4. Confirm the vault has not already been migrated (check for
existence of `Dev/`, `Content/`, `Homelab/`, `Reference/`
folders at root with the expected structure). If already
migrated, stop and report.
## Phase 1: Survey
Walk the entire vault. Produce a survey report.
For each existing file:
- Current path
- Filename
- Detected `type:` (from frontmatter, or inferred from
content/path if frontmatter is absent)
- Inferred ownership domain: Dev, Content, Homelab, or Reference
- Proposed new path under the four-folder structure
- Proposed new filename (apply naming conventions: project pages
as `<slug>.md`, sessions as `YYYY-MM-DD-<slug>.md`)
- Any concerns: ambiguous ownership, missing frontmatter,
unclear type, etc.
Group the report:
- **By proposed domain** — easy review of "is everything in Dev
actually Dev?"
- **Concerns** — separate section listing every file that needs
user judgment
- **Wikilinks affected** — count of internal links that will
need rewriting
Save the survey report as `<vault-root>/migration-survey.md`.
### Stop condition: present survey, await user approval
Do not proceed to Phase 2 until the user has reviewed the
survey and given explicit go-ahead. Allow the user to correct
specific entries; re-survey if they do.
## Phase 2: Move
Once survey is approved:
### Pre-move commit
```
git add -A
git commit -m "pre-migration: vault state before move" || true
```
(`|| true` because the vault may already be clean.)
### Create the four-folder structure
```
<vault-root>/Dev/
<vault-root>/Content/
<vault-root>/Homelab/
<vault-root>/Reference/
```
If any of these already exist, leave them alone.
### Move files
For each file in the survey:
1. `git mv <old-path> <new-path>` — preserves history
2. If the filename changed, the `git mv` reflects that
3. If the file's frontmatter has a `path:` field, update it to
the new domain
4. If the file is a session note and lacks `created:` /
`updated:` dates, infer from filename (if date-prefixed) or
git history
### Rewrite wikilinks
Walk every file in the migrated vault. For every wikilink:
- If the target moved or was renamed, update the wikilink to
point at the new name
- Use Obsidian's wikilink resolution rules (filename-based, not
path-based, so most wikilinks won't need rewriting unless
files were renamed)
### Post-move commit
```
git add -A
git commit -m "migration: moved <N> files to four-folder structure" \
-m "<short summary of what moved where>"
```
### Stop condition: present post-move state, await user approval
Report:
- Files moved: <count>
- Files renamed: <count>
- Wikilinks rewritten: <count>
- Concerns or skipped files: <list>
Do not proceed to Phase 3 until user confirms the post-move
state is correct.
## Phase 3: Initial compile
Run the compile procedure (see `compile.md`) with one
modification: this is a first-run compile against a freshly-
migrated vault, so:
- Generate `index.md`, `Dev/index.md`, `Content/index.md`,
`Homelab/index.md`, `Reference/index.md` from scratch
- Generate `log.md` if absent, with a single initial entry:
`## [YYYY-MM-DD HH:MM] migration | initial migration complete`
- Promote obvious entities (Lovebug, OB1, herbydev, Sunnie,
Jenny, etc.) automatically — these are known to clear the
promotion threshold
- Generate at most one synthesis page if a clear cross-cutting
pattern is present in existing content; otherwise none
### Stop condition: present compile output, await user approval
Standard compile reporting plus a "first-run" callout
highlighting:
- Entities auto-promoted (with rationale)
- Initial topic landings created
- Any pages where the agent's categorization felt uncertain
User reviews. Iterate if needed. Migration is done when user
confirms.
## Final commit
After user approval of the initial compile output:
```
git commit --allow-empty -m "migration: complete"
```
This marker commit is the boundary between migration and
steady-state operations. Future compile runs treat any change
after this commit as in-scope.
## Stop conditions (any phase)
Stop and report if:
- Git operations fail
- A user-confirmed move would overwrite an existing file
- A wikilink rewrite is ambiguous (multiple plausible targets)
- The vault is in an unexpected state at any phase boundary
## What this procedure does not do
- Run as part of a normal compile cycle
- Re-run automatically after completion
- Modify content beyond moves, renames, and wikilink rewrites
- Generate aggressive synthesis at first-run (one max)
- Delete files (skipped or unclear files stay where they are
with a flag)
```
---
## Deployment notes (for the build session, not part of the skill files)
When Lovebug deploys this skill to herbydev:
1. Create directory: `mkdir -p ~/.claude/skills/wiki-maintenance`
2. Write each of the four files above to that directory:
- `~/.claude/skills/wiki-maintenance/SKILL.md`
- `~/.claude/skills/wiki-maintenance/compile.md`
- `~/.claude/skills/wiki-maintenance/lint.md`
- `~/.claude/skills/wiki-maintenance/migration.md`
3. Verify file permissions allow Claude Code to read them
4. Smoke-test: invoke "test the wiki skill" through Dispatch.
The skill should load (the agent should report the skill name
in its preamble or be able to describe what it does).
The skill is vault-agnostic. The vault path is provided per
invocation. If a future second vault exists (e.g., a separate PBS
vault for Jenny), the same skill works against it as long as that
vault has its own `CLAUDE.md` following the spec.

8
uv.lock generated Normal file
View File

@ -0,0 +1,8 @@
version = 1
revision = 3
requires-python = ">=3.12"
[[package]]
name = "wiki-context"
version = "0.1.0"
source = { virtual = "." }

196
wiki-construct-context.md Normal file
View File

@ -0,0 +1,196 @@
# Wiki Construct — Project Context
This file captures the reasoning behind the wiki-construct project
decisions. Future conversations in this Claude.ai project should
read this to understand *why* the decisions are what they are, not
just what they are. This is project context, not a deliverable.
## Origin
The project came out of two converging conversations:
1. A review of Karpathy's LLM Wiki gist (April 2026) — an idea
for using an LLM to incrementally compile a structured wiki
from raw sources, sitting between the user and their corpus.
The gist is intentionally abstract; it describes the pattern
and tells the reader to instantiate it with their LLM.
2. A research session on AI memory architecture — established
that Travis's "build my own harness" instinct was actually a
"build my own memory layer" need. OB1 (NateBJones-Projects/OB1)
was identified as the right adoption target for the Lovebug-
facing memory layer.
The wiki and OB1 ended up framed as **two complementary memory
systems with mostly disjoint audiences**:
- **Wiki = Travis's interface to his own thinking.** Slow,
deliberate, organized for human browsing in Obsidian. Lovebug
reads it only when explicitly pointed at a file.
- **OB1 = Lovebug's working memory.** Fast, voluminous,
semantic search via MCP, captured automatically from sessions.
This framing is the load-bearing decision. It collapsed
architectural confusion that had built up about "should the wiki
be agent-readable" — answer: no, not in the first-class sense.
It's a human tool. Agents can read files when pointed at them,
but the wiki is not designed for autonomous agent consumption.
## Why flat structure won
Earlier drafts had nested subfolders inside each ownership
domain: `Dev/Projects/<slug>/`, `Dev/Sessions/`, `Dev/Reference/`.
Travis pushed back on this with a use case: "I won't navigate
folders — I'll go to an index." Fine-grained folders solve a
problem he doesn't have.
The flat structure works because:
- The index page (`<domain>/index.md`) is the navigation surface,
not the file tree
- Frontmatter (`type:`, `tags:`, `status:`) does categorization
better than folders, because it's multi-dimensional
- Obsidian's graph view and backlinks panel make wikilink-based
navigation more useful than folder-based
- Folders only matter to the agent (where to write new files)
and to git, both of which are happy with flat
Travis's user story: "I built a PBS CLI tool, where did I put
that project plan?" → flat structure means it's listed on
`Content/index.md`, found in seconds. Not buried four folders
deep.
## Why five page types (synthesis included)
The Karpathy spec has entity, concept, comparison, synthesis as
page types. Earlier draft proposed dropping all but entity and
adding project, session-notes, topic-landing — four types total.
Travis pushed back on dropping synthesis. Reasoning he gave:
"It's the thing I want. I'd rather turn it off later than have
to adjust to include it." Plus git-as-recovery mitigates the
silent-corruption risk.
So the final spec includes synthesis as a real page type, with
two safety controls:
1. **Sources required** — every synthesis page lists the pages
it pulled from, so provenance is traceable
2. **Lint scrutiny** — synthesis pages get extra checks during
lint (sources still exist, sources still say what synthesis
claims they say, no source has been substantially edited)
Concept pages and comparison pages are dropped. They felt like
spec extras for a research-paper-heavy corpus, not an
operational vault of project plans and session notes. Add them
later if a gap is felt.
## Why the skill pattern won
Earlier proposed: a `CLAUDE.md` at the vault root holding both
spec and procedures, invoked via session plans through Dispatch
that pointed at it explicitly.
Travis pushed back: how is that different from a skill? You're
just doing the trigger-routing manually instead of letting the
runtime do it.
He was right. Lovebug confirmed Claude Code on herbydev does
load skills from `~/.claude/skills/`, so the skill pattern works
through Dispatch. The split is:
- **Skill** (`~/.claude/skills/wiki-maintenance/`) — procedures
(compile, lint, migration). Vault-agnostic. Loaded by the
runtime when trigger phrases match.
- **CLAUDE.md** (vault root) — spec (page types, frontmatter,
folder ownership, tags, git protocol). Vault-specific. Read
by the skill at the start of every operation.
This means session plans through Dispatch can be one-line
trigger phrases ("update the wiki"). The skill description
handles routing. CLAUDE.md handles the spec. No
session-plan-with-pointer required.
## Sessions are top-level, not children of projects
Travis clarified: a session note is whatever happened in a
working session that produced enough learning to capture but
didn't crystallize into a project. Sessions may reference
projects via wikilinks but do not live inside them.
There are *also* coding-session notes captured by the agent
during code execution — those live in the coding project's repo
(eventually OB1), not in the wiki. The wiki holds Travis's
sessions. OB1 will hold the agent's session captures.
This distinction kept getting blurred and finally settled here.
## What's deferred
These were considered and explicitly deferred:
- **Wiki-aware extraction** — extractor doesn't read the wiki.
Phase 2 if at all.
- **OB1 integration** — the wiki is decoupled from OB1. They
feed the same eventual context-assembler but don't share
infrastructure now.
- **Jenny's interface** — a future PBS-public web surface that
reads from the wiki. Out of scope.
- **Public template repo**`trucktrav/homelab-templates` for
hosting the schema doc publicly. Phase 2.
- **Pre-compact hook for Dispatch transcript capture** — that's
OB1 territory.
- **Concept and comparison pages** — Karpathy spec extras. Add
if a gap is felt.
## Success metric
Travis's metric, restated: *"The wiki is working when I can go
to it, find info, without starting at a bunch of files in a
bunch of different folders and trying to remember what is
what."*
Concrete version: he can answer "what's going on with X?" for
any active project in under 30 seconds, without grepping. If
the user story above (PBS CLI tool) takes more than two clicks,
the wiki is failing.
## Naming / labels worth keeping consistent
- **The project:** `wiki-construct`. The construction phase,
distinct from the wiki itself once operational.
- **The vault:** "the wiki vault" or "the HomeLab vault". Same
thing.
- **The skill:** `wiki-maintenance`. Lives at
`~/.claude/skills/wiki-maintenance/` on herbydev.
- **The spec file:** `CLAUDE.md` at the vault root. Always
capitalized that way (per Anthropic convention).
- **The harness:** Dispatch (which invokes Claude Code on
herbydev). When discussing the agent that performs operations,
call it Lovebug or "the agent" — both are fine.
- **The two memory systems:** "the wiki" and "OB1". Don't try
to rename them or unify the framing.
## Open items (deferred decisions)
- Fourth ownership folder name (likely `Personal`, decided when
needed)
- Dataview vs. agent-maintained indexes — Dataview is native to
Obsidian and handles frontmatter queries; agent-maintained
gives more control over prose sections. Pick during Phase B
deploy.
- Whether top-level `Reference/` stays or folds into a domain
later. Lean: keep it.
- Exact tag list. Will emerge during Phase C migration.
## Related projects
- **`ob1-deployment`** — the parallel memory system for
Lovebug. Six-phase deployment plan, Tailscale-only initially,
Authelia deferred until Jenny's interface lands.
- **`second-brain`** (older project plan) — the extraction
pipeline + LLM wiki idea, before the wiki/OB1 split was
cleanly framed. Some of its scope rolled into wiki-construct
(the wiki side) and some into ob1-deployment (the harness
memory side). The "context assembler" concept from
second-brain remains relevant for Phase 2 future work.

View File

@ -0,0 +1,255 @@
Subject: [n8n] -t Tech/Projects -p wiki-construct
---
project: wiki-construct
type: project-plan
status: active
path: Tech/Projects
tags:
- homelab
- obsidian
- knowledge-management
- claude-code
- skill
- llm-wiki
created: 2026-05-04
updated: 2026-05-04
---
# Wiki Construct — Project Plan
## Concept
Build the personal LLM-maintained wiki construct on the homelab,
based on the Karpathy LLM Wiki pattern. Scoped to be the visible
face of personal knowledge — organized synthesis I can browse and
reference in Obsidian, not a memory layer for agents. Lovebug and
other agents may reference the wiki when explicitly pointed at it,
but the wiki is not designed for autonomous agent consumption.
The wiki is one of two complementary memory systems being built:
- **Wiki** — my curated knowledge journey, slow, deliberate,
organized for human browsing.
- **OB1** — Lovebug's working memory, fast, voluminous, organized
for semantic recall via MCP.
The two systems are parallel, not unified. They share no
infrastructure beyond eventually feeding the same context-assembler
in some Phase 2 future.
## Architecture
Three layers, per the Karpathy pattern:
1. **Raw sources** — existing markdown files captured via the
email-to-vault pipeline. Immutable.
2. **Wiki** — LLM-maintained markdown files in the Obsidian vault.
Five page types, flat structure under four ownership domains.
3. **Spec + procedures**`CLAUDE.md` at the vault root holds the
spec; a `wiki-maintenance` skill on herbydev holds the procedures
(compile, lint, migration). The skill is invoked through Dispatch.
## Decisions locked
### Scope
- [x] Phase 1 deliverable: working wiki with all five page types,
migrated from existing vault content
- [x] Phase 2 deferred: OB1 integration, wiki-aware extraction,
Jenny's interface, public template repo
- [x] Wiki is for me. Agents reference it when I point at them at
it, not autonomously.
### Structure
- [x] Four ownership domains: `Dev`, `Content`, `Homelab`, plus one
reserved slot (likely `Personal`, decided later)
- [x] Flat structure below the ownership domain — no `Projects/`,
`Sessions/`, `Reference/` subfolders. All files live directly
under the domain folder.
- [x] Top-level `Reference/` for cross-domain entities that don't
fit cleanly in one domain (Lovebug, OB1, herbydev, Jenny, Sunnie)
- [x] Categorization handled by frontmatter (`type:`, `tags:`),
not by folder hierarchy
- [x] Indexes and topic landings are auto-maintained, generated
from frontmatter queries
### Page types (five)
- [x] **Project page** — what I'm working on, current state,
decisions, open questions, sessions, related
- [x] **Session note** — what I did or thought through. Sessions
are top-level artifacts, not children of projects. They may
link to projects via wikilinks.
- [x] **Entity page** — recurring characters in my world (Lovebug,
OB1, herbydev, Sunnie, Jenny, Tailscale, KeePassXC, etc.)
- [x] **Topic landing / index** — domain-level catalog and prose
overview, mostly machine-maintained
- [x] **Synthesis page** — cross-cutting analysis with required
source provenance. Agent generates during compile when it
identifies a worth-synthesizing pattern. Subject to lint
scrutiny.
### Operations
- [x] **Capture** — existing email-to-vault pipeline, no changes
- [x] **Compile** — agent-driven, on demand, invoked through
Dispatch via the wiki-maintenance skill
- [x] **Lint** — agent-driven, on demand, invoked through Dispatch
- [x] **Reference** — I navigate Obsidian indexes and pages; agents
read files when pointed at them
- [x] No autonomous agent behavior. Every wiki maintenance
operation is human-initiated.
### Skill pattern
- [x] Skill lives at `~/.claude/skills/wiki-maintenance/` on
herbydev
- [x] Trigger phrases: "update the wiki", "compile the wiki",
"lint the wiki", "migrate the wiki"
- [x] Skill bundle: `SKILL.md`, `compile.md`, `lint.md`,
`migration.md`
- [x] Procedures live in the skill (vault-agnostic). Spec lives
at `<vault-root>/CLAUDE.md` (vault-specific). They reference
each other.
- [x] Session plans through Dispatch are thin — just the trigger
phrase; the skill handles routing
### Git protocol
- [x] Two commits per compile run: `pre-compile: <reason>` and
`compile: <summary>`
- [x] Compile commit body includes reasoning: pages touched,
pages created, entities promoted, contradictions flagged,
synthesis pages written
- [x] Git log is the audit trail; `git reset` is the rollback
- [x] Lint pass after suspicious compile runs; review diffs
before pushing
### Tags
- [x] Curated starter list, not a free-for-all
- [x] New tags require a real reason
- [x] Anything that looks like a tag but feels like an entity
should be a wikilink to an entity page instead
## Out of scope
- Wiki-aware extraction (extractor doesn't read the wiki)
- OB1 integration (separate project; deferred until OB1 baseline
is operational)
- Jenny's interface (separate project; PBS-public web surface,
served from PBS site eventually)
- Pre-compact hook for Dispatch transcript capture (OB1 territory)
- Public GitHub template repo
- Automated synthesis page generation outside compile runs
- Concept pages and comparison pages (Karpathy spec extras —
skip until felt as a gap)
## Open items
- [ ] Fourth ownership folder name (deferred until needed; likely
`Personal`)
- [ ] Dataview vs. agent-maintained indexes — Dataview is native
to Obsidian and lighter; agent-maintained gives more control.
Decide during deployment.
- [ ] Exact tag list (will emerge during migration; start small)
- [ ] Whether to keep top-level `Reference/` or fold cross-domain
entities into `Homelab/` (lean toward keeping it separate)
## Build phases
### Phase A — Draft artifacts
Produce the three deliverables: the project plan (this file),
`CLAUDE.md` for the vault root, and the `wiki-maintenance` skill
bundle (`SKILL.md`, `compile.md`, `lint.md`, `migration.md`). All
drafted in the Claude.ai project session preceding the build.
### Phase B — Deploy artifacts
Hand-off session through Dispatch. Lovebug:
- Creates the new four-folder structure in the vault
- Drops `CLAUDE.md`, `index.md`, `log.md` at the vault root
- Installs the `wiki-maintenance` skill at `~/.claude/skills/`
- Initializes the vault git repo (if not already)
- Verifies the skill loads correctly with a smoke-test invocation
("test the wiki skill" or similar)
### Phase C — Migration
Three-step, agent-driven, user-confirmed at each step:
1. **Survey** — agent walks current vault, produces report:
what's there, current folder, proposed new home in
four-folder structure. User reviews and corrects.
2. **Move** — agent moves files according to confirmed plan,
fixes wikilinks as it goes, commits.
3. **Compile** — first compile run on migrated vault. Generates
project pages from existing project plans, entity pages for
obvious characters, topic landings. User reviews, corrects,
agent updates.
## Tasks
### Phase A — Draft
- [ ] Draft `wiki-construct.md` project plan (this file)
- [ ] Draft `CLAUDE.md` for vault root
- [ ] Draft `SKILL.md` for wiki-maintenance skill
- [ ] Draft `compile.md` procedure
- [ ] Draft `lint.md` procedure
- [ ] Draft `migration.md` runbook
- [ ] Project knowledge file for the Claude.ai project context
### Phase B — Deploy
- [ ] Hand off draft artifacts to Lovebug via Dispatch session
- [ ] Lovebug creates four-folder structure in vault
- [ ] Lovebug deploys `CLAUDE.md`, `index.md`, `log.md` to vault
root
- [ ] Lovebug installs skill at `~/.claude/skills/wiki-maintenance/`
- [ ] Initialize vault git repo (or confirm existing one)
- [ ] Smoke-test the skill: invoke "test the wiki skill" through
Dispatch and verify it loads, reads CLAUDE.md, and reports back
### Phase C — Migration
- [ ] Trigger migration: "migrate the wiki to the new structure"
- [ ] Review survey report from agent
- [ ] Confirm move plan
- [ ] Review post-move state
- [ ] Trigger first compile run
- [ ] Review compile output (project pages, entity pages, topic
landings, synthesis pages if any)
- [ ] Iterate on prompts if any page type is consistently wrong
### Phase 1 done when
- [ ] Vault is reorganized into four ownership domains, flat
- [ ] All five page types exist in the vault with real content
- [ ] At least one synthesis page exists with proper source
provenance
- [ ] Topic landing pages list active projects, recent sessions,
key entities
- [ ] Top-level `index.md` orients across all four domains
- [ ] Git history shows clean compile commits with usable
reasoning
- [ ] **Success metric:** I can answer "what's going on with X"
for any active project in under 30 seconds, without grepping
## Notes
- The skill pattern means session plans through Dispatch can be
one-line trigger phrases. The skill description does the
routing.
- CLAUDE.md is portable across vaults (each vault gets its own).
The skill is vault-agnostic and works against any vault that
has a CLAUDE.md following the spec.
- Synthesis pages are the one place where lossy compression risk
is real. Sources-required + lint pass + git diff review are
the three controls.
- Migration is one-shot. After migration, the wiki is
operational and compile runs are the steady-state operation.