| name | kb-upgrade |
| description | Upgrade an existing Knowledge Base to the latest plugin practices. Ensures Obsidian compatibility, structured 'When to Load' format, loading notifications, index schema, and frontmatter health. Safe and re-runnable. |
| disable-model-invocation | true |
Knowledge Base Upgrade
You are a knowledge base upgrade assistant. Your job is to audit an existing docs/kb/ knowledge base and bring it up to the latest standards: Obsidian graph-view compatibility, structured "When to Load" entries for dynamic context loading, CLAUDE.md preamble updates, index schema improvements, and frontmatter health. This is a safe, preview-first operation — all changes are shown for user approval before executing.
This command is re-runnable — idempotent checks skip items that are already up to date. Run it after updating the ai-knowledge plugin, or any time you want to verify KB health.
Date Resolution
Resolving today's date (cross-platform, CRITICAL): Never guess, infer, or increment prior dates. When this skill writes created / last-updated, resolve today's date once at the start of the write phase, then reuse that single value for every write. Try these commands in order and use the first that returns a YYYY-MM-DD string:
- macOS / Linux / WSL / Git Bash (bash, zsh, sh):
date +%Y-%m-%d
- Windows PowerShell / pwsh:
Get-Date -Format 'yyyy-MM-dd'
- Windows cmd.exe:
powershell -NoProfile -Command "Get-Date -Format 'yyyy-MM-dd'"
- Portable fallback (Node or Python available):
node -e "console.log(new Date().toISOString().slice(0,10))" or python -c "import datetime; print(datetime.date.today().isoformat())"
Only update last-updated when the file's content actually changed. Because /kb-upgrade is idempotent and re-runnable, files that are already compliant must not be rewritten or have their dates bumped.
What This Upgrade Covers
- Related body links — Ensures every KB file with
related frontmatter has a matching ## Related body section for Obsidian graph view.
- Global learnings migration — Moves inline
### Global Learnings from CLAUDE.md to docs/kb/_global-learnings.md if not already done.
- Index & log creation — Creates
docs/kb/_index.md and docs/kb/_log.md if missing.
- "When to Load" standardization — Rewrites CLAUDE.md table entries from free-text to the structured format:
`scope-globs` — keywords for efficient dynamic loading.
- CLAUDE.md preamble — Ensures the Knowledge Base section has the latest matching instructions and loading notification directive.
_index.md schema — Adds a Scope column to the All Pages table for routing context.
- Scope suggestions — Identifies KB files with empty or missing
scope and suggests patterns.
- Frontmatter completeness — Ensures all required fields are present and valid.
- Folder organization — Offers to reorganize flat KB files into category folders if the KB has grown large enough.
Instructions
CRITICAL: This command MUST NOT accept any arguments. Ignore any text provided after the command.
Step 1: Prerequisite Check
- Check for KB section in CLAUDE.md: Read the project's CLAUDE.md and look for the Knowledge Base table. If it doesn't exist, inform the user to run
/kb-init first and stop.
- Check for
docs/kb/ directory: If it doesn't exist, inform the user to run /kb-init first and stop.
- Glob for KB files: Find all
.md files under docs/kb/ (excluding docs/kb/README.md).
- If no KB files exist (other than README), inform the user: "No KB files found. Add knowledge first with
/kb-learn, /kb-add, or /kb-discover, then run this command." and stop.
Step 2: Audit Current State
Scan the KB and build a comprehensive audit report. All checks are read-only — nothing is modified in this step.
2a: Related Links (Obsidian Graph View)
For each .md file in docs/kb/ (excluding README.md):
- Read the file and parse its YAML frontmatter.
- Check
related field: Does the frontmatter have a related field with one or more references?
- Check for existing
## Related section: Does the file body already have a ## Related section with [[wiki-links]]?
- Categorize each file:
- NEEDS BODY LINKS — Has
related in frontmatter but no ## Related body section (or body section is out of sync with frontmatter).
- OK — Either has no
related references, or already has a matching ## Related body section.
- BODY LINKS ONLY — Has a
## Related body section but no related frontmatter (unusual, flag for review).
2b: Global Learnings Location
- Read CLAUDE.md: Look for a
### Global Learnings subsection under ## Knowledge Base.
- Check for
docs/kb/_global-learnings.md: Does this file already exist?
- Categorize:
- NEEDS MIGRATION — Inline global learnings exist in CLAUDE.md but
_global-learnings.md does not exist (or exists but inline section also still has content).
- ALREADY MIGRATED —
_global-learnings.md exists and CLAUDE.md has no inline global learnings content.
- NO GLOBAL LEARNINGS — Neither location has content.
2c: Frontmatter Completeness
For each KB file, verify:
- YAML frontmatter exists.
- Required fields are present:
tags, created, last-updated.
- Check
scope field: Is it present? Is it empty ("" or [])? Could a meaningful scope be inferred from the file's content, tags, or path?
- Flag files with issues as NEEDS FRONTMATTER FIX.
- Flag files with empty/missing scope where scope could be inferred as SCOPE SUGGESTED.
2d: Index & Log
- Check for
docs/kb/_index.md: Does it exist?
- If it exists, check whether its "All Pages" table has a Scope column.
- NEEDS CREATION — File doesn't exist.
- NEEDS SCOPE COLUMN — File exists but All Pages table lacks Scope column.
- OK — File exists with Scope column.
- Check for
docs/kb/_log.md: Does it exist?
- NEEDS CREATION — File doesn't exist.
- OK — File exists.
- Check CLAUDE.md table: Is
_index.md registered as pinned?
2e: "When to Load" Format
- Read the CLAUDE.md Knowledge Base table.
- For each non-pinned entry, check if the "When to Load" value follows the structured format:
- Structured format: Contains backtick-wrapped glob patterns (e.g.,
`src/api/**`) and/or keywords after an em dash (—).
- Free-text format: Natural language like "When working in packages/api/" or "When modifying database schemas".
- Categorize entries:
- NEEDS FORMAT UPDATE — Uses free-text instead of structured format.
- OK — Already uses the structured format or is
Always (pinned).
- For entries that NEED FORMAT UPDATE, read the corresponding KB file's frontmatter to get
scope and tags, and draft the new structured value:
- If
scope is a string, treat as a single-element array.
- If
scope is an array, use all elements.
- Format:
`scope-glob1`, `scope-glob2` — tag1, tag2
- If no scope:
— tag1, tag2
- If no tags:
`scope-glob1`
2f: CLAUDE.md Preamble
Check the Knowledge Base section's introductory text:
- Does it contain the 4-point matching instructions (pinned entries, scope patterns, keywords, _index.md fallback)?
- Does it contain the loading notification instruction (telling Claude to notify the user when loading a KB file)?
- Categorize:
- NEEDS UPDATE — Missing matching instructions or loading notification.
- OK — Has both.
2g: Folder Organization
- Count flat files: How many KB articles (excluding
_-prefixed files and README.md) are directly in docs/kb/ root?
- Count subfolder files: How many are in subfolders?
- If there are 5 or more flat files, flag as REORGANIZATION SUGGESTED.
- For each flat file, propose a category folder based on its tags:
- Architecture, patterns, system design →
architecture/
- Conventions, naming, coding style, API contracts →
conventions/
- Tools, workflow, infrastructure, deployment →
tools/
- Testing, test patterns →
testing/
- External, harvested, module-specific →
external/
- Other → suggest based on the dominant tag
- If fewer than 5 flat files, skip reorganization.
Step 3: Present Upgrade Report
Display the audit results:
KB Upgrade — Audit Report
==========================
## Related Links (Obsidian Graph View)
### Need body links ({count})
- {filename}.md — related: [[file1]], [[file2]]
### Already compatible ({count})
- {filename}.md — OK
## Global Learnings
Status: {NEEDS MIGRATION | ALREADY MIGRATED | NO GLOBAL LEARNINGS}
## Frontmatter Issues ({count})
- {filename}.md — {issue description}
## Scope Suggestions ({count})
- {filename}.md — suggested: `{inferred scope pattern}`
## Index & Log
- _index.md: {OK | NEEDS CREATION | NEEDS SCOPE COLUMN}
- _log.md: {OK | NEEDS CREATION}
## "When to Load" Format ({count} need update)
{If entries need update:}
- {Topic}: "{old value}" → `{new structured value}`
{If none need update:}
All entries already use the structured format.
## CLAUDE.md Preamble
Status: {NEEDS UPDATE | OK}
## Folder Organization
{If REORGANIZATION SUGGESTED:}
{count} files are flat in docs/kb/ root. Suggested reorganization:
- {filename}.md → {category}/{filename}.md
{If not suggested:}
Folder structure is fine.
## Summary
- {count} files need `## Related` body sections
- {count} global learnings to migrate
- {count} frontmatter issues to fix
- {count} scope suggestions
- {count} infrastructure files to create/update
- {count} "When to Load" entries to standardize
- CLAUDE.md preamble: {needs update | OK}
- {count} files suggested for folder reorganization
If everything is already up to date:
"Your knowledge base is fully up to date! No changes needed."
Otherwise, use AskUserQuestion:
- Header: "KB Upgrade"
- Question: "Ready to upgrade your knowledge base?"
- Options: "Apply all" | "Apply all except reorganization" | "Let me review each change" | "Cancel"
Step 4: Execute Upgrades
4a: Add ## Related Body Sections
For each file that NEEDS BODY LINKS:
-
Read the file fully.
-
Parse the related frontmatter to extract the list of referenced KB file names (without .md extension).
-
Add a ## Related section at the very end of the file:
## Related
- [[referenced-file-1]]
- [[referenced-file-2]]
-
Formatting rules:
- Add one blank line before
## Related.
- Each reference is a bullet point with a
[[wiki-link]] using the filename without .md extension.
- The
## Related section must be the last section in the file.
- Do NOT remove or modify the
related frontmatter — it is still used by Claude Code's loading logic.
- If the file already has a
## Related section that is out of sync with frontmatter, replace its content with the correct links.
-
Update last-updated in frontmatter to the date resolved at the start of Step 4 (only if the file's content actually changed in this run).
4b: Migrate Global Learnings
If global learnings NEED MIGRATION:
-
Read the ### Global Learnings section from CLAUDE.md. Extract all bullet points.
-
Create docs/kb/_global-learnings.md (or update if it exists):
---
tags: [global, cross-cutting]
related: []
created: {today's date}
last-updated: {today's date}
pinned: true
---
# Global Learnings
Cross-cutting rules and insights that apply across the entire project.
## Key Rules
- {migrated learning 1}
- {migrated learning 2}
If _global-learnings.md already exists but inline learnings also exist in CLAUDE.md, merge the inline learnings into the file (deduplicating).
-
Register in CLAUDE.md table: Add or verify a row:
| Global Learnings | docs/kb/_global-learnings.md | Always (pinned) |
-
Remove the inline ### Global Learnings section from CLAUDE.md (under ## Knowledge Base). Remove the entire subsection including the heading and all bullet points. If there's placeholder text ("No global learnings captured yet..."), remove that too.
-
Keep the <!-- kb-auto: enabled --> block if it exists — do not move or remove it.
4c: Fix Frontmatter Issues
For files with missing or incomplete frontmatter:
-
Add missing frontmatter with inferred values:
- Infer
tags from file content and path.
- Set
created and last-updated to today's date (resolved once via the cross-platform command in the Date Resolution section).
- Set
pinned to false.
- Leave
related empty initially.
-
Add ## Related body section if the file has related references (even newly added ones).
For files flagged as SCOPE SUGGESTED:
-
Present each suggestion to the user via AskUserQuestion:
- Header: "Scope Suggestion: {filename}"
- Question: "This KB file has no
scope patterns. Based on its content and tags, I suggest: {inferred scope patterns}. Accept?"
- Options: "Accept" | "Different scope" (free-text) | "Skip"
-
Update the file's frontmatter with the accepted scope value. The scope field can be a string (single pattern) or array (multiple patterns).
4d: Create/Update Index and Log
If _index.md NEEDS CREATION:
-
Read all KB files in docs/kb/ (including those in subfolders).
-
For each file, parse its frontmatter and read the first few content lines to generate a one-line summary.
-
Group files by category — infer categories from tags, folder location, and content.
-
Generate docs/kb/_index.md:
---
tags: [index, meta]
created: {today's date}
last-updated: {today's date}
pinned: true
---
# Knowledge Base Index
Auto-generated catalog of all KB articles. Updated by `/kb-*` commands. Read this file first to find relevant pages before drilling into individual articles.
## {Category Name}
- [[article-name]] — One-line summary of what this article covers
- [[another-article]] — Another summary
## Meta
- [[_global-learnings]] — Cross-cutting rules that apply everywhere
## All Pages
| Page | Summary | Tags | Scope | Last Updated |
|------|---------|------|-------|-------------|
| [[article-name]] | Summary | tag1, tag2 | `src/api/**` | YYYY-MM-DD |
-
Register in CLAUDE.md table: Add | KB Index | docs/kb/_index.md | Always (pinned) |
If _index.md NEEDS SCOPE COLUMN:
- Read the existing
_index.md.
- Find the "All Pages" table.
- Add a
Scope column header between Tags and Last Updated.
- For each row, read the corresponding KB file's
scope frontmatter and populate the Scope cell.
- If scope is a string, wrap in backticks:
`src/api/**`
- If scope is an array, join with commas:
`src/api/**`, `*.ts`
- If scope is empty/missing, leave the cell empty.
- If the file is pinned, put
_(pinned)_.
- Update
last-updated in frontmatter.
If _log.md NEEDS CREATION:
Create docs/kb/_log.md:
---
tags: [log, meta]
created: {today's date}
last-updated: {today's date}
---
# Knowledge Base Log
Chronological record of KB operations. Append-only — newest entries at the bottom.
## [{today's date}] upgrade | KB upgraded to latest practices
- Added ## Related body sections to {count} files
- {Migrated global learnings to _global-learnings.md | Global learnings already migrated}
- {Generated _index.md with {count} articles cataloged | Updated _index.md with Scope column}
- Created _log.md
- Standardized {count} "When to Load" entries
- Updated CLAUDE.md preamble
- {Reorganized {count} files into category folders | No reorganization needed}
4e: Standardize "When to Load" Column
For each table entry flagged as NEEDS FORMAT UPDATE:
- Read the KB file's frontmatter to get
scope (handle string or array) and tags.
- Build the new "When to Load" value:
- If
pinned: true: Always (pinned) (should already be correct).
- If
scope has values: format as backtick-wrapped globs, comma-separated.
- If
tags has values: append as keywords after em dash (—).
- Full format:
`scope-glob1`, `scope-glob2` — tag1, tag2
- No scope, has tags:
— tag1, tag2
- Has scope, no tags:
`scope-glob1`, `scope-glob2`
- If the KB file has no
scope and no tags: Attempt to infer from the file content and old "When to Load" text. Extract directory references from the old text (e.g., "When working in packages/api/" → packages/api/**). Flag these for the user to review if the inference is uncertain.
- Update the CLAUDE.md table row with the new "When to Load" value.
4f: Update CLAUDE.md Preamble
Replace the Knowledge Base section's introductory text (between the ## Knowledge Base heading and the table) with the latest version:
Topic-specific knowledge is stored in `docs/kb/` and loaded contextually based on the table below.
**How to use the "When to Load" column:**
1. **Pinned entries** (`Always (pinned)`): Load at the start of every conversation.
2. **Scope patterns** (backtick-wrapped globs like `src/api/**`): Load when the files you are editing or creating match any of the listed glob patterns.
3. **Keywords** (after the `—` dash): Load when the current task involves these topics, even if no file path matches.
4. **When uncertain**: Read `docs/kb/_index.md` (pinned) for article summaries and scope patterns to help decide.
**Loading notifications**: When you load a KB file, briefly notify the user so they know what context is being applied. Example: `📖 Loading KB: api-conventions.md`. Keep notifications to a single line per file.
When a KB file's frontmatter contains `related: [[other-file]]` cross-references, also read the related file(s) for full context.
Important: Preserve the <!-- kb-auto: enabled --> block and any other content after the table. Only replace the introductory paragraph(s) before the table.
4g: Folder Reorganization
Only execute if the user approved reorganization (not if they chose "Apply all except reorganization").
For each file to be reorganized:
- Create the target subfolder if it doesn't exist (e.g.,
docs/kb/architecture/).
- Move the file from
docs/kb/{file}.md to docs/kb/{category}/{file}.md.
- Update CLAUDE.md table: Change the File column from
docs/kb/{file}.md to docs/kb/{category}/{file}.md.
- Refresh the "When to Load" column: Read the moved file's
scope and tags frontmatter and regenerate the structured "When to Load" value.
- Update
_index.md: File paths in the "All Pages" table should reflect the new locations.
- DO NOT modify
[[wiki-links]] in frontmatter or body sections — Obsidian resolves [[filename]] by name, not path. Only update the CLAUDE.md table paths.
- Update
last-updated in frontmatter of moved files.
Step 5: Verify
After all changes:
- Re-read all modified files and verify:
- Every file with
related frontmatter has a matching ## Related body section.
_global-learnings.md exists and is registered in the CLAUDE.md table (if global learnings existed).
- No inline
### Global Learnings section remains in CLAUDE.md.
_index.md exists, is registered as pinned, has Scope column, and catalogs all KB articles.
_log.md exists with the upgrade entry.
- All frontmatter is valid and complete.
- All non-pinned CLAUDE.md table entries use the structured "When to Load" format.
- CLAUDE.md preamble has the 4-point matching instructions and loading notification directive.
- If reorganization was done, CLAUDE.md table paths reflect new locations.
Step 6: Update Log
Append to docs/kb/_log.md:
## [{today's date}] upgrade | KB upgraded to latest practices
- Related links: added to {count} files
- Global learnings: {migrated | already migrated | none}
- Index: {created | updated Scope column | already up to date}
- Log: {created | already existed}
- "When to Load": standardized {count} entries
- Preamble: {updated | already up to date}
- Frontmatter: fixed {count} files
- Scope: suggested for {count} files
- Reorganization: {moved {count} files | not needed | skipped by user}
Step 7: Summary
KB Upgrade — Complete
======================
## Changes Made
### Related Links Added ({count} files)
- {filename}.md — added links to [[file1]], [[file2]]
### Global Learnings
- {Moved {count} learnings from CLAUDE.md to docs/kb/_global-learnings.md | Already migrated | No global learnings}
### Index & Log
- {Generated _index.md with {count} articles across {count} categories | Updated _index.md with Scope column | Already up to date}
- {Created _log.md | Already existed}
### "When to Load" Standardized ({count} entries)
- {Topic}: "{old}" → {new structured format}
### CLAUDE.md Preamble
- {Updated with matching instructions and loading notifications | Already up to date}
### Frontmatter Fixed ({count} files)
- {filename}.md — added missing {fields}
### Scope Suggestions Applied ({count} files)
- {filename}.md — scope set to {patterns}
### Folder Reorganization ({count} files moved)
- {filename}.md → {category}/{filename}.md
- Updated CLAUDE.md table paths and "When to Load" values
## Obsidian Setup
If you haven't already, you can open `docs/kb/` as an Obsidian vault:
1. Open Obsidian → "Open folder as vault" → select `docs/kb/`
2. Press Ctrl/Cmd+G to see your knowledge graph
3. All `[[wiki-links]]` in Related sections appear as graph edges
4. Consider adding `.obsidian/` to `.gitignore`
## Next Steps
- All `/kb-*` commands now maintain the upgraded structure automatically
- Run `/kb-upgrade` again any time to verify KB health
- Use `/kb-discover` to mine source code for implicit knowledge
- Use `/kb-prune` periodically to consolidate and clean up