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:
86
README.md
Normal file
86
README.md
Normal 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
148
skills/lore/SKILL.md
Normal 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
|
||||
70
skills/lore/references/QUICKREF.md
Normal file
70
skills/lore/references/QUICKREF.md
Normal 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
79
skills/lore/scripts/lore-add.sh
Executable 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."
|
||||
24
skills/lore/scripts/lore-sync.sh
Executable file
24
skills/lore/scripts/lore-sync.sh
Executable 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)"
|
||||
Reference in New Issue
Block a user