testsAndMisc/python_pkg/archwiki_rag
Krzysztof kuhy Rudnicki f15f00f3fe Re-point paths for the ~ reorganisation (home-tidy)
Also bumps the 16 meta/requirements pins the freshness gate flagged
(anthropic 1.5.0, numpy 2.5.3, pytest-randomly 5, flake8-bugbear 26.9.9,
ruff 0.16.7, pyright 1.1.414, selenium 4.49.0, hypothesis 6.168.0, lxml
6.1.3, pipdeptree 4.2.5, the two types-* stubs) and Flutter 3.47.3 in
meta/.fvmrc. One test still expected the pre-move ~/mcp-servers path.

The pre-commit hook fed .zsh files to shfmt and shellcheck, neither of
which parses zsh (SC2148/SC1071), so no zsh file could be committed since
the hook was tightened on 2026-08-22; those now get `zsh -n` instead. The
hook's own shfmt pass also staged its reformat of 8 shell files.

CI_GREEN_SKIP because main is red on exactly the dependency-freshness
finding this commit fixes, which is the documented use of that flag.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AwtowrowDXx6ccmWVPkCaF
2026-09-11 20:50:19 +02:00
..
tests Fix a test that only passed in a directory named testsAndMisc 2026-08-23 14:53:29 +02:00
__init__.py archwiki_rag: offline semantic search over the Arch Wiki 2026-08-10 15:33:18 +02:00
__main__.py Re-point paths for the ~ reorganisation (home-tidy) 2026-09-11 20:50:19 +02:00
_reindex_entry.py archwiki_rag: offline semantic search over the Arch Wiki 2026-08-10 15:33:18 +02:00
cli.py Re-point paths for the ~ reorganisation (home-tidy) 2026-09-11 20:50:19 +02:00
constants.py archwiki_rag: offline semantic search over the Arch Wiki 2026-08-10 15:33:18 +02:00
convert.py archwiki_rag: offline semantic search over the Arch Wiki 2026-08-10 15:33:18 +02:00
install.sh archwiki_rag: offline semantic search over the Arch Wiki 2026-08-10 15:33:18 +02:00
README.md Re-point paths for the ~ reorganisation (home-tidy) 2026-09-11 20:50:19 +02:00
reindex.py Grade against 3.14 too, not just run on it 2026-08-29 11:50:39 +02:00
sync.py archwiki_rag: offline semantic search over the Arch Wiki 2026-08-10 15:33:18 +02:00

archwiki_rag

Offline Arch Wiki corpus for the knowledge-rag MCP server. Gives Claude semantic search across the whole ArchWiki without a network round-trip, so questions can be asked by symptom rather than by page title:

why doesn't my systemd user unit see DISPLAY under i3

Why this exists

The only Arch-specific MCP server in the wild (nihalxkumar/arch-mcp) fetches wiki pages over the network and bundles pacman install/remove/update, PKGBUILD checks and system stats that duplicate the local yay-mcp. This package uses the arch-wiki-docs dump that is already on disk instead, and does nothing but search.

Usage

# One-time setup: dependencies, corpus, MCP config, pacman hook.
./install.sh

# Manual refresh.
PYTHONPATH=~/src/testsAndMisc python3 -m python_pkg.archwiki_rag sync --reindex

# Query it.
claude-archwiki

Then, in the session, search_knowledge("...") against the archwiki server.

Design notes

Three non-obvious constraints shaped this package. All three come from reading the knowledge-rag source rather than its docs.

Markdown, not text. knowledge-rag chunks .md files with a heading-aware splitter and everything else with a blind fixed-width one. ArchWiki pages are heavily sectioned, so emitting real ##/### headings is what makes chunk boundaries land on section breaks instead of mid-sentence. HTML is not a supported suffix at all, so conversion is mandatory regardless.

Never rewrite an unchanged file. The incremental reindex decides a document is current by comparing stored mtime and size, not content. arch-wiki-docs regenerates all ~2500 files on every release, so writing unconditionally would bump every mtime and re-embed the entire corpus on each upgrade. sync.py compares rendered output against what is on disk and skips identical pages; this is the single most load-bearing behaviour in the package, and test_sync.py asserts it directly.

Subpages are nested. Systemd/User lives at en/Systemd/User.html, not en/Systemd_User.html. A non-recursive glob silently misses 164 pages, many of them the most useful ones. iter_pages uses rglob and the documents tree mirrors the dump's layout.

Store isolation

The corpus lives in its own store, ~/.local/share/knowledge-rag-archwiki, not the shared ~/.local/share/knowledge-rag. Roughly 27k Arch chunks would otherwise dominate both the BM25 index and the embedding space of any other corpus kept there. claude-rag and claude-archwiki are separate sessions against separate indexes.

Refresh guards

The pacman hook fires unattended, so reindex.py refuses to run when either:

  • a claude-archwiki session already holds the store's instance lock (knowledge-rag's own lock is taken only by its main(), so importing the orchestrator directly would bypass it), or
  • the machine is already under load (1-minute load average above 1.5 per core).

The load guard, not a GPU one: knowledge-rag ships the CPU-only onnxruntime build, whose execution providers are AzureExecutionProvider and CPUExecutionProvider. There is no CUDA provider, so despite the 3090 in this box the embedding pass runs on the CPU and saturates roughly every core for several minutes. A VRAM check would have looked reassuring and never fired.

Deferring is safe: the converted Markdown is already on disk, so the next run picks up exactly where this one stopped.