Add AI entry points, conf schema, and folder docs

ai_index.sh and ai_query.sh follow the usual conventions — fail-closed gate,
root check, lock, dry-run, status — with Node doing only the vector maths and
SQLite blobs, the same split api_cache_writer.sh uses for PHP.

AI_* and HOST*_OLLAMA_* land in both confs and both templates in this pass.
Everything ships off: AI_ENABLED false, every AI_ASSIST_* false, conf writes
disabled with an empty whitelist. Nothing in the ecosystem consults it.
This commit is contained in:
Gmer4Lfe
2026-08-02 01:21:24 -04:00
parent b00688bad1
commit 6a959fb5e4
7 changed files with 785 additions and 9 deletions
+69 -2
View File
@@ -1,7 +1,13 @@
# Varaverk AI Integration — Design Notes
**Status: design only. Nothing below is built.** No Varaverk script calls Ollama, and no
`AI_*` variable exists in any conf yet. Captured 2026-08-01 so the reasoning survives.
**Status: retrieval is built; integration is not.** As of 2026-08-02 the `AI_*` and
`HOST*_OLLAMA_*` variables exist in both confs and both templates, and `AI/` holds a working
index and query path — see the RAG section at the end of this document and `AI/README-AI.md`.
Everything else below remains design only. **No Varaverk script consults AI.** Every
`AI_ASSIST_*` toggle is false, `AI_CONF_WRITE_ENABLED` is false with an empty whitelist, and
host resolution across the mesh is specified but not implemented. Originally captured
2026-08-01 so the reasoning survives.
Ollama itself *is* installed, tuned and verified on HOST1 — `qwen2.5-coder:14b` for
generation, `nomic-embed-text` for embeddings, 16k context, pinned to the RTX 3080. See
@@ -490,3 +496,64 @@ new — the machinery already exists and was audited this session.
possibly credentials pasted by a user.
- Is a 7B worth it to buy context + parallelism headroom, or is 14B quality worth the
serialisation? Defer until an actual problem is felt.
---
## RAG — built 2026-08-02
Retrieval is live. `AI/` holds the implementation; `AI/README-AI.md` documents it in full. What
follows is only what changed relative to the plan recorded above.
**Corpus is larger than estimated.** ~2,950 chunks across ~180 files, not the 690 header chunks
projected. Sub-chunking is why — see below.
**Named-paragraph sub-chunking was necessary, and was not in the plan.** Section-level chunks
alone were too coarse. `rsync.sh` documents fourteen safeguards in one 2.8k-char
`OPERATIONAL SAFEGUARDS` block; a query about one of them scored 0.558, below unrelated chunks,
because the other thirteen dominated the vector. Splitting on the named-paragraph titles the
header convention already uses took the same query to 0.718 and first place. The parent section
name is carried onto each sub-chunk so routing still works.
**Two chunker bugs worth remembering.** The last section in a header (RUNTIME MODES in bash,
DEPENDS ON in a page) ran to EOF and swept up every unrelated comment in the file —
`scheduler.php` alone produced an 11k-char chunk of unrelated inline comments. And title
detection must require the *next* line to be indented; without that, any wrapped prose line
became a spurious chunk boundary mid-sentence.
**Section routing is a boost, not a filter.** Intent detection is a heuristic and must not be
able to exclude the chunk holding the answer. `--section=` forces a hard filter when wanted.
**Vectors arrive pre-normalised.** `nomic-embed-text` returns L2-normalised vectors (measured
norm 1.0000001), so cosine is a plain dot product. No normalising step, no magnitude cache.
**`node:sqlite` over a native module.** Still flagged experimental, chosen because it needs no
native compilation on Unraid. Acceptable because the index is disposable — if a Node upgrade
breaks it, rebuild takes minutes. PHP reads the same float32 blobs with `unpack('f*', $blob)`
when the UI needs them.
**Retrieval quality, measured.** 9/10 top-3 hit rate on known-answer questions; the tenth had
the answer at ranks 2 and 3, so 10/10 for answer-present-in-context at k=6. Full retrieval plus
generation runs about 43s warm.
### The finding that validated the whole thing
First real end-to-end question asked which variable controls the mover's grace window. The model
answered `MOVER_STOP_TIMEOUT`, "defaults to 30 seconds", citing `mover_stop.sh CONFIGURATION`.
Variable correct; the 30 was wrong — the real value is 300. The model was quoting the header
verbatim. **The header was stale.**
A sweep for the same pattern found six stale `(default: N)` claims across the repo — all
corrected in the same pass. This is the operating principle for the folder:
> Retrieval is exactly as accurate as the documentation it points at. When an answer looks
> wrong, check the cited source before blaming the model.
It also means the index is a documentation-drift detector, not only a question-answering tool.
### Still deliberately not built
Nothing consults this. Every `AI_ASSIST_*` toggle is false, `AI_CONF_WRITE_ENABLED` is false
with an empty key whitelist, and no watchdog, cleanup or fallback path calls it. Host resolution
across the Tailscale mesh is specified above but not implemented — `ai_index.sh` and
`ai_query.sh` currently require a local `HOST*_OLLAMA_URL` and fail with a clear message when it
is empty, rather than silently probing the mesh.