nanobot: 2026-09-10 12:33:37
This commit is contained in:
106
skills/wiki/SKILL.md
Normal file
106
skills/wiki/SKILL.md
Normal file
@@ -0,0 +1,106 @@
|
||||
---
|
||||
name: wiki
|
||||
description: >
|
||||
Search the user's own notes — personal git note repos plus the live workspace — by
|
||||
keyword, topic or meaning. Use to answer questions about what the user has written
|
||||
down, recorded or decided, and to find which file covers a topic.
|
||||
Triggers on: "/wiki", "find in my notes", "what did I write about", "do I have notes on".
|
||||
Read-only: it never writes, edits or captures notes, and it does not answer from
|
||||
general knowledge — only from what is indexed on disk.
|
||||
---
|
||||
|
||||
# /wiki
|
||||
|
||||
Hybrid search over the user's notes. `chunks` is the single retrieval unit: FTS5 supplies a
|
||||
BM25 rank, `sqlite-vec` a vector rank, and RRF merges the two.
|
||||
|
||||
Reply to the user in their own language.
|
||||
|
||||
## Pick a layer
|
||||
|
||||
Three layers, cheapest first. Start with the one that matches the question.
|
||||
|
||||
| Question shape | Command |
|
||||
|---|---|
|
||||
| exact string, filename, hostname, IP, identifier, code | `grep <pattern>` |
|
||||
| "what do I even have about X", orientation, browsing | `toc [--source X] [--tag Y]` |
|
||||
| a topic or a paraphrase, wording unknown | `search "<query>"` |
|
||||
|
||||
```sh
|
||||
uv run skills/wiki/scripts/wiki_search.py grep "rotate_snapshots"
|
||||
uv run skills/wiki/scripts/wiki_search.py toc --source travel
|
||||
uv run skills/wiki/scripts/wiki_search.py search "jak snížit elektroodpad" --limit 5
|
||||
```
|
||||
|
||||
For the full flag reference of any subcommand:
|
||||
|
||||
```sh
|
||||
uv run skills/wiki/scripts/wiki_search.py --help
|
||||
uv run skills/wiki/scripts/wiki_search.py <subcommand> --help
|
||||
```
|
||||
|
||||
## Behavioral contract
|
||||
|
||||
**The index is a retrieval hint, never the answer.** `search` returns an excerpt to tell you
|
||||
*which file* is relevant. Before answering, read that file fresh from disk — the index can be
|
||||
up to a minute behind, and the excerpt is truncated. Never quote figures, commands or
|
||||
decisions straight from a `search` excerpt.
|
||||
|
||||
**Only markdown is indexed; `grep` sees everything.** Source code, configs and data files never
|
||||
reach `search` or `toc`. For anything code-shaped — an identifier, a flag, a function name —
|
||||
`grep` is the right layer, not a fallback. Exact match is what matters there anyway.
|
||||
|
||||
**`grep` is a regex.** Escape regex metacharacters when the user means them literally
|
||||
(`.`, `(`, `[`, `*`, `+`, `?`, `|`). It searches the files on disk, so it is always current.
|
||||
|
||||
**`search` results always look plausible.** The vector half has no distance floor: it returns
|
||||
its nearest chunks whatever you ask, so an empty result set means an empty index, not "nothing
|
||||
matches". Judge each hit against the question and say so when nothing genuinely fits — do not
|
||||
present a weak nearest neighbour as an answer.
|
||||
|
||||
**Read the notes the output prints.** Each hit shows `source:path`, the breadcrumb, and which
|
||||
half found it (`bm25 #2, vec #1`). A hit both halves rank highly is worth more than one only
|
||||
the vectors found.
|
||||
|
||||
## Notes the output may print
|
||||
|
||||
- `embeddings unavailable … FTS-only results` — the semantic half is down, so only keyword
|
||||
matching ran. Paraphrase queries will do badly; say so rather than concluding the notes are
|
||||
silent on the topic. Try `grep` with the user's own wording.
|
||||
- `N chunks still awaiting vectors` — a sync is mid-flight or was degraded. Recent notes may
|
||||
be missing from the semantic half.
|
||||
- `reindex needed: …` on stderr with exit 1 — the index was built under a different embedding
|
||||
contract. Nothing is wrong with the notes; the index has to be rebuilt (see below). Do not
|
||||
retry the query.
|
||||
|
||||
## Sources
|
||||
|
||||
Defined in `wiki/config.yaml`. Each has a stable **source id** used in output and in
|
||||
`--source`. Git sources are read-only clones under `wiki/remote/<id>/`; the `workspace` source
|
||||
indexes the live workspace. The user's repos are the canonical data — nothing here ever writes
|
||||
to them.
|
||||
|
||||
`toc --tag` filters on frontmatter tags, which only exist where the user wrote them.
|
||||
|
||||
## Indexing
|
||||
|
||||
`wiki_sync.py` runs every minute from the crontab and does all the work offline. Never index
|
||||
inside a turn: a full rebuild takes minutes and the `exec` tool times out at 60 s.
|
||||
|
||||
```sh
|
||||
uv run skills/wiki/scripts/wiki_sync.py # what cron runs; a quiet tick is free
|
||||
uv run skills/wiki/scripts/wiki_sync.py --full # wipe and rebuild
|
||||
```
|
||||
|
||||
`--full` is needed only after the embedding model, its dimensions, the query prefix or the
|
||||
chunker change — that is what a `reindex needed` message means. It re-embeds everything, so
|
||||
run it in the background and tell the user it is running, never inside a turn where they wait.
|
||||
|
||||
`log/wiki_sync.log` holds one line per event: what was indexed, `WARN` for a source that was
|
||||
skipped, and a `coverage` line naming top-level directories that hold markdown no source
|
||||
covers. Read it when `search` cannot find something the user is sure they wrote.
|
||||
|
||||
## Environment
|
||||
|
||||
- `WIKI_DB` — override the index path (tests).
|
||||
- `WIKI_CONFIG` — override the config path (tests).
|
||||
Reference in New Issue
Block a user