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 <noreply@anthropic.com>
This commit is contained in:
kaykayyali
2026-06-23 15:02:27 -04:00
commit d105928204
5 changed files with 407 additions and 0 deletions

86
README.md Normal file
View File

@@ -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: <https://git.homelab.local/kaykayyali/lore/wiki>
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 "<file>" [<file>...]
```
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: <https://git.homelab.local/kaykayyali/lore/wiki>
- Wiki git: `git@git.homelab.local:kaykayyali/lore.wiki.git`
- Wiki Home: <https://git.homelab.local/kaykayyali/lore/wiki/Home>
- Wiki Schema: <https://git.homelab.local/kaykayyali/lore/wiki/Schema>
- Wiki Write Protocol: <https://git.homelab.local/kaykayyali/lore/wiki/Write-Protocol>
- Wiki Agent Onboarding: <https://git.homelab.local/kaykayyali/lore/wiki/Agent-Onboarding>

148
skills/lore/SKILL.md Normal file
View File

@@ -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: <type>",
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 <file> # 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/<Section>/<Title Case With Spaces>.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

View File

@@ -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`

79
skills/lore/scripts/lore-add.sh Executable file
View File

@@ -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."

View File

@@ -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)"