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>
This commit is contained in:
parent
1435726f99
commit
38f4431341
38
skill/README.md
Normal file
38
skill/README.md
Normal 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
176
skill/compile.md
Normal 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
135
skill/lint.md
Normal 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
176
skill/migration.md
Normal 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)
|
||||
@ -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
|
||||
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
|
||||
@ -82,530 +58,3 @@ on assumptions.
|
||||
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.
|
||||
Loading…
Reference in New Issue
Block a user