commit d105928204802cf4e8b057b4f20da14ca8063149 Author: kaykayyali Date: Tue Jun 23 15:02:27 2026 -0400 init: lore skill — agent interface to lore.wiki.git Adds the 'lore' skill: an interface for any agent to read and write the shared homelab wiki at git.homelab.local/kaykayyali/lore.wiki.git. The skill teaches agents: * when to write to the wiki vs local memory (rule of thumb: if another agent on a different project would benefit, wiki) * the wiki's own protocol (Schema + Write Protocol + Agent Onboarding) — read those first, follow them exactly * how to draft, commit, and push via local clone + SSH * that git add -A is forbidden (dev cruft has burned the wiki) Helper scripts: * lore-sync.sh — clone or pull --rebase the wiki * lore-add.sh — stage specific files, commit, push (prompts first) The skill follows the wiki's tag taxonomy and append-only model: local memory is for the current session; the wiki is for everything worth remembering. Co-Authored-By: Claude diff --git a/README.md b/README.md new file mode 100644 index 0000000..77cb629 --- /dev/null +++ b/README.md @@ -0,0 +1,86 @@ +# lore + +The shared knowledge base for the homelab. Two parts: + +1. **`lore.wiki.git`** — the wiki itself. The cross-project, append-only + source of truth for decisions, pitfalls, patterns, entities, and + project state. Catalog: + +2. **`lore.git`** (this repo) — the agent skill that interfaces with + the wiki. Install once per agent and it knows how to read, draft, + commit, and push wiki pages following the wiki's own protocol. + +## What goes in the wiki + +Anything an agent on a *different* project might need in the future. +Decisions with rationale. Pitfalls (something broke, here's why). +Patterns (something worked, capture it). New projects, services, +facets. Project state. + +## What stays in local memory + +Session-private notes. Working memory for the current task. Drafts +of pages before they're approved. Anything project-private. + +Rule of thumb: **if another agent on a different project would +benefit, it belongs in the wiki.** Local memory is for the current +session only. + +## Install the skill + +Copy or symlink the `skills/lore/` directory into your agent's skills +directory. + +For Claude Code: + +```bash +# From this repo +ln -s "$(pwd)/skills/lore" ~/.claude/skills/lore +``` + +For other agents, follow their skill-loading convention. The skill +file is `skills/lore/SKILL.md` — the `name: lore` frontmatter and +the `description: ...` block tell the agent when to load it. + +## Use + +```bash +# Pull the latest wiki into ~/lore-wiki (clones on first run) +./skills/lore/scripts/lore-sync.sh + +# Read first +less ~/lore-wiki/Schema.md +less ~/lore-wiki/Write\ Protocol.md +less ~/lore-wiki/Agent\ Onboarding.md + +# Write — follow the protocol exactly +# Draft files in ~/lore-wiki/, update Index.md and Log.md, +# show the user the diff, then: +./skills/lore/scripts/lore-add.sh "" [...] +``` + +The skill's `SKILL.md` has the full workflow and rule set. + +## Repo layout + +``` +lore.git/ +├── README.md # this file +└── skills/ + └── lore/ + ├── SKILL.md # the agent skill + ├── references/ + │ └── QUICKREF.md # condensed Schema for fast drafting + └── scripts/ + ├── lore-sync.sh # clone / pull --rebase + └── lore-add.sh # stage + commit + push +``` + +## See also + +- Wiki: +- Wiki git: `git@git.homelab.local:kaykayyali/lore.wiki.git` +- Wiki Home: +- Wiki Schema: +- Wiki Write Protocol: +- Wiki Agent Onboarding: diff --git a/skills/lore/SKILL.md b/skills/lore/SKILL.md new file mode 100644 index 0000000..9e2aafa --- /dev/null +++ b/skills/lore/SKILL.md @@ -0,0 +1,148 @@ +--- +name: lore +description: > + Read and write the shared "lore" wiki at git.homelab.local/kaykayyali/lore.wiki.git + — the homelab's versioned, cross-project knowledge base. Sync a local clone, + draft pages following the wiki's own Schema + Write Protocol, commit + push + via SSH. Use when user says "log it", "add to lore", "wiki it", "log: ", + or when capturing shared/team knowledge (decisions, pitfalls, patterns, + entities) that other agents on other projects will need. +--- + +# lore + +Interface to the homelab shared wiki. The wiki is the source of truth for +cross-project knowledge — anything an agent on a *different* project might +need in the future. Local memory is for session-private notes; the wiki is +for everything else worth remembering. + +## Quick start + +The wiki repo: `git@git.homelab.local:kaykayyali/lore.wiki.git` +Local mirror: `~/lore-wiki/` (clone it on first use) +Browser: `https://git.homelab.local/kaykayyali/lore/wiki` + +```bash +# Read +~/lore-wiki/Index.md # the catalog +~/lore-wiki/Schema.md # conventions (READ FIRST) +~/lore-wiki/Write Protocol.md # write ritual +~/lore-wiki/Agent Onboarding.md # mandatory intro for agents + +# Write +./scripts/lore-sync.sh # pull --rebase +./scripts/lore-add.sh # add + commit + push (shows diff first) +``` + +**You MUST read [[Schema]] and [[Write Protocol]] in the wiki before the +first write in any session.** They're short, and violating them pollutes +the graph. After reading, follow the protocol exactly — it's been refined +across dozens of commits. + +## What goes in lore (vs local memory) + +| Goes in lore (wiki) | Stays in local memory | +|---|---| +| Decisions with rationale future agents need | Session-private notes | +| Pitfalls (something broke, here's why) | Working memory for current task | +| Patterns (something worked, capture it) | Pointer to wiki page if relevant | +| New project / service / system entity | Drafts of pages before approval | +| Project state, slices, closeouts | One-off observations | +| Homelab / infrastructure facts | Anything project-private | + +Rule of thumb: **if another agent on a different project would benefit, +it belongs in the wiki.** Local memory is for the current session only. + +## Workflow: read + +1. Clone once if not present: `git clone git@git.homelab.local:kaykayyali/lore.wiki.git ~/lore-wiki` +2. `cd ~/lore-wiki && git pull --rebase` at session start if you've used it before +3. Read `Index.md` for the catalog, then drill into specific pages + +If asked "do we have anything on X?" — grep before answering: + +```bash +grep -ril "X" ~/lore-wiki/ ~/lore-wiki/*/ +``` + +## Workflow: write + +The full ritual is in the wiki at `Write Protocol.md`. TL;DR: + +1. **Read first.** Check `Index.md` + `Log.md` — most things are partially + captured. Don't duplicate. +2. **Decide type:** `decision | pitfall | pattern | entity | facet | session` +3. **Draft the file** in `~/lore-wiki/
/.md` + - YAML frontmatter required (see `Schema.md`) + - Title Case With Spaces filename, matches `title:` exactly + - 2+ outbound `[[Title Case]]` wikilinks minimum +4. **Update `Index.md`** under the right section +5. **Append a one-liner to `Log.md`** with date + action + files +6. **Show the user the diff.** Wait for approval. +7. **Commit + push** via `./scripts/lore-add.sh <file>` + +**Never** `git add -A` — there is no `.gitignore` discipline enforced, and +dev cruft in `/root/lore-seed/` style paths has burned the wiki before. +Stage specific files. + +## Workflow: update existing + +1. `cd ~/lore-wiki && git pull --rebase` +2. Edit the file. Bump `updated:` in frontmatter. If it's a decision + superseded by new info, **create a new file** with `supersedes: <slug>` + in frontmatter; do not edit the old one in place. +3. Update `Index.md` if type/section changed +4. Append to `Log.md` +5. Show diff → get approval → commit + push + +## Workflow: bulk writes + +Multiple related files (e.g. project closeout)? Draft all files, update +`Index.md` and `Log.md`, show the full diff in **one** go, get **one** +approval, push in **one** commit. Don't drip-feed pages one at a time. + +## Workflow: archive + +When content is fully superseded: +1. Move file to `~/lore-wiki/_archive/<original-path>` +2. Remove from `Index.md` +3. Update pages that linked to it — replace `[[wikilink]]` with plain + text + "(archived)" +4. Append to `Log.md` +5. Show diff → push + +## Wikilink style + +**Title Case With Spaces**, always. Gitea wiki resolves title-case only. +`[[Foundry VTT]]` not `[[foundry-vtt]]`. Obsidian accepts the same form, +so files are dual-compatible. + +## Commit message format + +``` +log: <type> — <one-line summary> +``` + +Types: `create | update | bulk | cleanup | archive`. Match what you put +in `Log.md` so the log and the git history tell the same story. + +## When NOT to write + +- Passing mentions in chat +- Trivia, one-off observations +- Anything already in `Index.md` +- Agent's private procedural notes +- Anything project-private + +When in doubt, ask. "Should this go in lore?" is a fair question to pose +to the user. The protocol is "your call on what enters the wiki." + +## See also + +- `~/lore-wiki/Home.md` — what the wiki is +- `~/lore-wiki/Schema.md` — conventions, tag taxonomy, frontmatter +- `~/lore-wiki/Write Protocol.md` — the write ritual in full +- `~/lore-wiki/Agent Onboarding.md` — agent operating principles +- `~/lore-wiki/Index.md` — the catalog +- `~/lore-wiki/Log.md` — append-only action history +- `references/QUICKREF.md` — tag taxonomy + frontmatter template diff --git a/skills/lore/references/QUICKREF.md b/skills/lore/references/QUICKREF.md new file mode 100644 index 0000000..f861ebb --- /dev/null +++ b/skills/lore/references/QUICKREF.md @@ -0,0 +1,70 @@ +# Lore quick reference + +Condensed excerpt of the wiki's [[Schema]] for fast reference while +drafting. The wiki is authoritative; if anything below disagrees with +`~/lore-wiki/Schema.md`, the wiki wins. + +## Frontmatter template + +```yaml +--- +title: Page Title # matches filename exactly +created: YYYY-MM-DD +updated: YYYY-MM-DD +type: hub | meta | entity | facet | decision | pattern | pitfall | session +tags: [from taxonomy] +supersedes: <old-file-slug> # optional; decision pages only +sources: [list of source files] # optional +--- +``` + +## Page types + +- `hub` — landing pages, entry points +- `meta` — about the wiki itself +- `entity` — a specific thing (person, project, service) +- `facet` — a feature area / component +- `decision` — architectural / logical decision + rationale +- `pattern` — reusable approach that worked +- `pitfall` — something that broke + how to avoid +- `session` — per-session diary entry + +## Tag taxonomy (excerpt — see Schema.md for full) + +**Domain roots:** `hub`, `meta`, `entity`, `facet` +**Knowledge type:** `decision`, `pattern`, `pitfall`, `session` +**Subject (combine freely):** `foundry`, `homelab`, `gitea`, `dnd5e`, +`module-dev`, `playwright`, `battle-focus`, `slice-N`, `phaser`, +`colyseus`, `wh40k`, `osmosis`, `cloudflare`, `docker`, `traefik`, +`react`, `vite`, `ssh-hardening`, `gitea-actions`, `litellm`, `kanban`, +`discord` +**Status:** `shipped`, `planned`, `deprecated`, `flaky` +**Status / qualifier:** `person`, `project`, `protocol`, `infrastructure`, +`agent`, `communication`, `verification`, `testing`, `skills`, `browser`, +`kaykayyali`, `slice-closeout`, `conventions`, `deployment`, `onboarding`, +`write`, `schema`, `lore` + +## Thresholds + +- Create a page when entity/concept appears in 2+ sessions OR is + central to one session's outcome +- Add to existing page when something covered gets a new fact +- Don't create a page for passing mentions +- Split a page when it exceeds ~150 lines +- Archive when fully superseded (move to `_archive/`) + +## Update policy + +When new info conflicts with existing content: +1. Check dates — newer sources supersede older +2. If contradictory, note both with dates +3. Mark in frontmatter: `supersedes: <old-file-slug>` +4. Flag for review in `Log.md` + +## Commit message format + +``` +log: <type> — <one-line summary> +``` + +Types: `create | update | bulk | cleanup | archive` diff --git a/skills/lore/scripts/lore-add.sh b/skills/lore/scripts/lore-add.sh new file mode 100755 index 0000000..b477537 --- /dev/null +++ b/skills/lore/scripts/lore-add.sh @@ -0,0 +1,79 @@ +#!/usr/bin/env bash +# lore-add.sh — stage specific files, commit, push to lore.wiki.git +# +# Usage: +# lore-add.sh <file> [<file>...] # commit message auto-derived from Log entry +# lore-add.sh -m "log: type — summary" <file> [<file>...] +# +# Stage ONLY the files you list. Never `git add -A` — dev cruft has burned +# the wiki before. Shows diff and waits for approval before pushing. + +set -euo pipefail + +LOCAL_PATH="${LORE_PATH:-$HOME/lore-wiki}" + +if [[ ! -d "$LOCAL_PATH/.git" ]]; then + echo "error: $LOCAL_PATH is not a git repo. Run lore-sync.sh first." >&2 + exit 1 +fi + +COMMIT_MSG="" +if [[ "${1:-}" == "-m" ]]; then + COMMIT_MSG="${2:-}" + shift 2 +fi + +if [[ $# -eq 0 ]]; then + echo "usage: lore-add.sh [-m 'commit msg'] <file> [<file>...]" >&2 + exit 1 +fi + +cd "$LOCAL_PATH" + +# Pre-flight: pull --rebase to catch concurrent pushes +git pull --rebase --autostash >/dev/null + +# Confirm files exist +for f in "$@"; do + if [[ ! -e "$f" ]]; then + echo "error: file does not exist: $f" >&2 + exit 1 + fi +done + +# Show diff before staging +echo ">> diff for $*" +git diff --stat -- "$@" +echo +git diff -- "$@" +echo + +# Stage specific files only +git add -- "$@" + +echo ">> staged for commit:" +git status --short +echo + +# Derive commit message if not provided +if [[ -z "$COMMIT_MSG" ]]; then + # Try to extract the most recent log: entry from Log.md (if touched) + if git diff --cached --name-only | grep -qx "Log.md"; then + COMMIT_MSG="$(awk '/^## /{section=""; next} /^- \*\*/ && section {print; exit}' Log.md | sed -E 's/^- \*\*([^*]+)\*\*.*$/\1/' || true)" + fi + if [[ -z "$COMMIT_MSG" ]]; then + COMMIT_MSG="log: update — $*" + fi +fi + +echo ">> proposed commit message: $COMMIT_MSG" +read -r -p ">> commit + push? [y/N] " confirm +if [[ "$confirm" != "y" && "$confirm" != "Y" ]]; then + echo "aborted. staged files remain staged; reset with: git reset HEAD" + exit 1 +fi + +git commit -m "$COMMIT_MSG" +git push origin main + +echo ">> pushed. log entry will show on next sync." diff --git a/skills/lore/scripts/lore-sync.sh b/skills/lore/scripts/lore-sync.sh new file mode 100755 index 0000000..e26be60 --- /dev/null +++ b/skills/lore/scripts/lore-sync.sh @@ -0,0 +1,24 @@ +#!/usr/bin/env bash +# lore-sync.sh — pull --rebase the local lore wiki mirror +# +# Usage: +# lore-sync.sh # sync ~/lore-wiki +# lore-sync.sh <path> # sync an alternate checkout +# +# Clones the wiki repo if not present, then fast-forwards via rebase. + +set -euo pipefail + +REPO_URL="git@git.homelab.local:kaykayyali/lore.wiki.git" +LOCAL_PATH="${1:-$HOME/lore-wiki}" + +if [[ ! -d "$LOCAL_PATH" ]]; then + echo ">> cloning $REPO_URL -> $LOCAL_PATH" + git clone "$REPO_URL" "$LOCAL_PATH" + exit 0 +fi + +cd "$LOCAL_PATH" +echo ">> git pull --rebase in $LOCAL_PATH" +git pull --rebase +echo ">> done. HEAD: $(git rev-parse --short HEAD)"