Compare commits

..

3 Commits
master ... main

Author SHA1 Message Date
Travis Herbranson
c97d13f932 docs: README — 2026-05-24 session (skill split/backport, compile, lint, promotions, cadence draft)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 22:21:52 -04:00
Travis Herbranson
38f4431341 docs: split skill bundle into separate files + backport live compile/SKILL updates
Separated skill-wiki.md bundle into compile.md, lint.md, migration.md.
Backported compile.md and SKILL.md (skill-wiki.md) from the installed
skill at ~/.claude/skills/wiki-maintenance/ so the repo archive reflects
the shipped two-layer Sources/+Wiki/ taxonomy rather than the old flat draft.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 21:09:54 -04:00
Travis Herbranson
1435726f99 docs: clarify planning-workspace role + flesh README
This repo is the design-conversation space for the wiki-construct
project, not a deployed vault. The 403-line CLAUDE.md describes a
vault structure (flat per-domain, Content as a domain name) that
doesn't exist in this repo and was superseded by the actual live
implementation in ../wiki-vault/ (two-layer Sources+Wiki, Venture
instead of Content).

CLAUDE.md: prepended a header note framing this as the early draft
spec, pointing at wiki-vault/CLAUDE.md as canonical, and explaining
why the draft is kept (per wiki-construct-context.md's stated design-
history intent). The body of the spec is left unmodified below the
note — it's a frozen record.

README (new): explains the repo IS a planning workspace (not the
vault), maps each doc to its purpose, summarizes how the design
evolved from this draft to the live wiki-vault shape, points at
companion repos (wiki-vault, vault-mcp).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-20 07:59:20 -04:00
7 changed files with 636 additions and 553 deletions

View File

@ -1,4 +1,27 @@
# CLAUDE.md — HomeLab Wiki Vault Spec # CLAUDE.md — HomeLab Wiki Vault Spec (draft, superseded)
> **Important context for agents:** this is the **wiki-context** repo,
> which is the **planning workspace** for the `wiki-construct` project,
> not a deployed vault. The vault structure described below is an
> **early design draft** that didn't survive contact with implementation
> — when the wiki was actually built, the structure became a two-layer
> `Sources/` + `Wiki/` split, and the `Content` domain was renamed to
> `Venture`.
>
> **Canonical implementation spec:**
> [`wiki-vault/CLAUDE.md`](../wiki-vault/CLAUDE.md). Read that one when
> you're operating on the live vault.
>
> **Why this draft is kept:** as `wiki-construct-context.md` explains,
> the planning conversation captured *why* decisions were made.
> Mutating this CLAUDE.md to match the live spec would erase that
> design history. Leave it as a frozen record of the design state at
> 2026-05-04; tracker is the live `wiki-vault/CLAUDE.md`.
>
> The rest of this file is the original draft, unmodified below this
> point.
---
This file is the spec for this Obsidian vault. Any agent operating This file is the spec for this Obsidian vault. Any agent operating
on this vault reads this file first to understand the structure, on this vault reads this file first to understand the structure,

View File

@ -0,0 +1,86 @@
# wiki-context
**Planning workspace** for the `wiki-construct` project — the design
conversation and decision history behind Travis's personal LLM-maintained
wiki. This repo holds the planning docs and the bundled
`wiki-maintenance` skill files, not the wiki itself.
The actual wiki lives in [`../wiki-vault/`](../wiki-vault). Operate on
the live vault there; come here to understand *why* it's shaped the way
it is.
## Layout
```
wiki-context/
├── CLAUDE.md # Early draft spec (frozen, superseded
│ # by wiki-vault/CLAUDE.md)
├── wiki-construct-project-plan.md # Project plan with locked decisions
├── wiki-construct-context.md # Design rationale + reasoning history
├── skill/ # wiki-maintenance skill, split into files
│ ├── skill-wiki.md # = SKILL.md (in sync with installed)
│ ├── compile.md # compile procedure (in sync with installed)
│ ├── lint.md # lint procedure
│ ├── migration.md # one-time migration runbook
│ └── README.md # bundle deploy preamble
└── README.md # This file
```
## What's in each doc
| File | What it captures |
|------|------------------|
| `wiki-construct-context.md` | The *why* — the two converging conversations that produced the project, the wiki-vs-OB1 framing decision, why flat structure won, etc. The load-bearing context that future Claude sessions in this project space should read first. |
| `wiki-construct-project-plan.md` | The *what* — locked decisions, phases, tasks. Treated as a project plan, with frontmatter matching the wiki spec. |
| `CLAUDE.md` | Early draft of the wiki spec. **Frozen** as a design-history record. The vault that actually got built has a different shape — see `wiki-vault/CLAUDE.md` for the canonical current spec. |
| `skill/` | The `wiki-maintenance` skill bundle, split into its four real files (`skill-wiki.md` = SKILL.md, `compile.md`, `lint.md`, `migration.md`) plus a deploy-preamble `README.md`. `compile.md` and `skill-wiki.md` were backported from the installed skill at `~/.claude/skills/wiki-maintenance/` on 2026-05-24 so the archive mirrors the live two-layer taxonomy. |
## How the design evolved
The early CLAUDE.md drafted here proposed:
- A **flat** per-domain structure (`HomeLab/Dev/*.md` etc.)
- Four domains: Dev / **Content** / Homelab / Reference
What actually shipped in `wiki-vault/`:
- A **two-layer** structure: `Sources/` (raw inputs) + `Wiki/`
(compiled outputs)
- Four domains: Dev / **Venture** / Homelab / Reference (Content
renamed)
- Vault-mcp writes into `Sources/` via `create_artifact`;
the `wiki-maintenance` skill compiles into `Wiki/`
Both shapes are valid Karpathy-style LLM-wikis — the live one made
explicit what the draft left implicit (the Sources-vs-Wiki distinction).
## Companion repos
- [`wiki-vault/`](../wiki-vault) — the live vault; canonical spec
+ content.
- `homelab/vault-mcp/` — the MCP server that writes to the live vault
(dual-writes Postgres `petalbrain.wiki` + markdown). It also
embeds note content via Ollama into `petalbrain.public.embeddings`.
## Status
The project moved from this workspace into deployed reality in May 2026.
This repo is kept around as the design archive. Open it when you need
the rationale behind a vault decision; otherwise reach for `wiki-vault/`.
**2026-05-24 session.** Split the single-file skill bundle into its four
real files and backported `compile.md` + `skill-wiki.md` from the
installed skill (the archived copies had drifted to the old flat-structure
draft). On the live vault, ran the first steady-state compile since launch
(34 backlogged sources → indexes + 5 entity refreshes + the
`ai-memory-architecture` synthesis, plus correcting the long-standing
"OB1 = Supabase" error to pgvector:pg17/`petalbrain`), the first lint pass,
promoted 5 new entities (trellis, vault-mcp, petalbrain, knot-dns,
herbyeos), and cleaned out 8 pipeline test artifacts + 3 stale worktrees.
A compile-cadence nudge (n8n → Google Chat, triggered off a
`wiki.compile_runs` table) was drafted to keep the vault from drifting
again — see `docker/n8n/workflows/wiki-compile-nudge.json`.
The leftover `main.py` / `pyproject.toml` / `uv.lock` / `.python-version`
files at the root are uv-init artifacts; they aren't part of this
workspace's purpose.

38
skill/README.md Normal file
View File

@ -0,0 +1,38 @@
# 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.
## 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.

176
skill/compile.md Normal file
View File

@ -0,0 +1,176 @@
# 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 `Sources/` 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-plan, session-notes)
and domain from `path:` frontmatter (Dev, Venture, Homelab, Reference)
- Also check `Wiki/` for any manual edits to entity or synthesis pages
- 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 with changes, update BOTH Sources and Wiki indexes:
**Sources indexes** (`Sources/<domain>/index.md`):
- Regenerate **Active projects** list from frontmatter query
- Regenerate **Recent sessions** list (last 10 or last 30 days)
- Update **Completed projects** section
- Update `updated:` date
**Wiki indexes** (`Wiki/<domain>/index.md`):
- Update **Entities** list if entity list changed
- Update **Synthesis pages** if any were added in this run
- Update `updated:` date
**Layer indexes** (`Sources/index.md`, `Wiki/index.md`):
- Refresh cross-domain catalog for each layer
**Root index** (`index.md`):
- Refresh highlights: active projects, recent sessions, key entities
- Update counts
## 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

135
skill/lint.md Normal file
View File

@ -0,0 +1,135 @@
# 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

176
skill/migration.md Normal file
View File

@ -0,0 +1,176 @@
# 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)

View File

@ -1,30 +1,6 @@
# 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 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. 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 with a two-layer structure — Sources (raw project plans and session notes) and Wiki (compiled entity pages, topic landings, synthesis) — under four ownership domains (Dev, Venture, Homelab, Reference). Reads the vault's CLAUDE.md spec at the vault root before performing any operation.
--- ---
# wiki-maintenance # wiki-maintenance
@ -82,530 +58,3 @@ on assumptions.
pre-commit, post-commit, with reasoning in the body. pre-commit, post-commit, with reasoning in the body.
- Report concisely. Skip celebratory framing. State what was - Report concisely. Skip celebratory framing. State what was
done, what's next, what's blocked. 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.