--- 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 ` | | "what do I even have about X", orientation, browsing | `toc [--source X] [--tag Y]` | | a topic or a paraphrase, wording unknown | `search ""` | ```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 --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//`; 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).