query: let her search the live web before she reads the ZIMs

The offline encyclopedia was the only world source, and it reads what was true
when the ZIM was built. A self-hosted SearXNG now asks first and Kiwix is the
fallback for an empty result, an unreachable instance or no line out. Owner's
ruling, 2026-08-02.

internal/websearch is deliberately thin: no rewriter (SearXNG ranks through
real engines, so the Russian question goes out as he asked it), no page fetch,
no cache. It cannot read the store, so only the query string can leave the box.

The personal boundary is unchanged and still sits above this source, so a
question about him is never searched.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01BFaeSbLMEVG5ey8tejU3y2
This commit is contained in:
kami
2026-08-02 02:24:36 +04:00
parent a103708a08
commit 14e98334ad
11 changed files with 720 additions and 17 deletions
+33 -3
View File
@@ -73,6 +73,36 @@ What it does and does not do:
- feed notes are **not** part of recall. "что я говорил про X" searches what he
said; headlines are read back only by asking about the feeds.
### Searching the web (`search`, also off by default)
There is no `search` block either, so no query leaves the LAN. Switching it on
points her at a self-hosted SearXNG:
```json
"search": {
"url": "http://searxng:8080",
"max_results": 4,
"snippet_runes": 1500,
"language": "auto",
"timeout": "8s"
}
```
- the instance needs `json` in its `search.formats` (settings.yml). A stock
SearXNG answers 403 to `format=json`, and then every search fails;
- the question goes out **verbatim**, in the language he asked it. There is no
rewriter here, unlike Kiwix: SearXNG ranks through real engines;
- only the query string leaves the box. `internal/websearch` cannot read the
store, so no note, fact, persona block or history can travel with a search;
- a question about him never becomes a query. The personal boundary in the
query chain stops the walk above this source;
- this runs **before** Kiwix. A live search reads what is true today and the
ZIMs read what was true when they were built, so the ZIMs are the fallback:
an empty result, an unreachable instance or a dead line falls through to
them and she never says the search failed;
- `engines` narrows the search to named engines, e.g. `"duckduckgo,wikipedia"`.
Empty means whatever the instance has enabled.
### Reading a page (`crawl`, also off by default)
There is no `crawl` block either, so no page is fetched. Two halves, separately
@@ -95,9 +125,9 @@ switched:
a fallback and not a habit;
- `watches` re-reads a fixed list on its interval and writes a note when the
text changed. Like the feeds, it announces nothing;
- the answer path sits behind his memory and his notes, and ahead of the model
answering from what it remembers. Kiwix is not wired into the chain yet. A
local read costs nothing, so anything local goes first;
- the answer path sits behind his memory, his notes, the web search and the
ZIMs, and ahead of the model answering from what it remembers. A page he
named is an instruction, so it is read last and only when he named one;
- `robots.txt` is fetched first and obeyed with no override; a `Disallow` is a
refusal she says out loud. `Crawl-delay` is waited out before the page is
fetched, and a delay longer than the turn fails the read instead of hanging