From eb366415232ff250c7b586e1ee4a97d0de95d96b Mon Sep 17 00:00:00 2001 From: Gmer4Lfe Date: Sun, 2 Aug 2026 13:09:17 -0400 Subject: [PATCH] Expose --kind on ai_query so definitional questions can reach the prose The index already stored chunk origin and search.js already filtered on it; only the wrapper refused the flag. Intent routing boosts PURPOSE for "what is X", which buried README.md and made the system answer that it had no definition of itself. --- AI/README-AI.md | 15 +++++++++++++++ AI/ai_query.sh | 25 +++++++++++++++++++++++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/AI/README-AI.md b/AI/README-AI.md index 480cc44..f06cfc0 100644 --- a/AI/README-AI.md +++ b/AI/README-AI.md @@ -59,6 +59,20 @@ Applied as a **score boost, not a filter**. Intent detection is a heuristic, and must never be able to exclude the one chunk that holds the answer. `--section=NAME` forces a hard filter when you actually want one. +The boost still has a blind spot worth knowing about: **definitional questions.** "What is +Varaverk?" matches the `PURPOSE` intent, so every script's one-line PURPOSE gets boosted above +the top-level prose that actually answers it — and the model correctly replies that the context +does not define the system. The corpus is fine; `README.md` is indexed. The routing simply +buries it. `--kind=readme` is the hard filter for that case: + +```bash +bash AI/ai_query.sh --kind=readme "what is Varaverk" +``` + +`--kind` filters on where a chunk came from — `header`, `readme`, `manual`, `template`, `doc` — +and composes with `--section`. Prefer it over `--section` for "what is" and "why does this +exist" questions, where the answer is narrative rather than a header field. + --- ## ━━━ NAMED-PARAGRAPH SUB-CHUNKING ━━━ @@ -154,6 +168,7 @@ bash AI/ai_index.sh --status # size, counts, last build bash AI/ai_query.sh "what stops rsync and the mover running at once" bash AI/ai_query.sh --search "why are the cache writers lockless" bash AI/ai_query.sh --section=CONFIGURATION "which variable sets the mover grace period" +bash AI/ai_query.sh --kind=readme "what is Varaverk" # definitional / narrative bash AI/ai_query.sh --json "..." # for other scripts ``` diff --git a/AI/ai_query.sh b/AI/ai_query.sh index 4dfb483..ff8cd40 100755 --- a/AI/ai_query.sh +++ b/AI/ai_query.sh @@ -104,6 +104,12 @@ # ai_query.sh --section=CONFIGURATION "your question" # Restrict retrieval to one header section. # +# ai_query.sh --kind=readme "what is Varaverk" +# Restrict retrieval to one chunk origin: header, readme, manual, template, doc. +# Use this for definitional and narrative questions. Intent routing boosts header +# sections such as PURPOSE, which answers "what does this script do" well but buries +# the top-level prose that explains what the system *is*. --kind=readme reaches it. +# # ai_query.sh --json "your question" # Machine-readable output for other scripts. # @@ -119,18 +125,32 @@ source "${SCRIPT_DIR}/../load_config.sh" detect_hosts -SEARCH_ONLY=false; JSON=false; STATUS=false; SECTION=""; QUERY="" +SEARCH_ONLY=false; JSON=false; STATUS=false; SECTION=""; KIND=""; QUERY="" for arg in "$@"; do case "$arg" in --search) SEARCH_ONLY=true ;; --json) JSON=true ;; --status) STATUS=true ;; --section=*) SECTION="${arg#*=}" ;; + --kind=*) KIND="${arg#*=}" ;; --*) echo "Unknown option: $arg" >&2; exit 1 ;; *) QUERY="$arg" ;; esac done +# --kind is a hard filter on chunk origin; --section filters the header section within a +# chunk. They answer different questions and compose: --kind=readme --section=PURPOSE is +# meaningful. Validated here rather than in the CLI so a typo costs nothing — an unknown kind +# silently matches no rows, which reads as "the index has no answer" and is the most +# misleading failure this tool can produce. +if [[ -n "$KIND" ]]; then + case "$KIND" in + header|readme|manual|template|doc) ;; + *) echo "Unknown --kind=$KIND (expected: header, readme, manual, template, doc)" >&2 + exit 1 ;; + esac +fi + CLI="${SCRIPT_DIR}/lib/cli.js" DB="${AI_INDEX_DB:-${DATA_DIR}/ai_index.db}" @@ -156,7 +176,7 @@ if [[ "${AI_ENABLED:-false}" != "true" ]]; then exit 0 fi -[[ -z "$QUERY" ]] && { echo "usage: ai_query.sh [--search] [--section=NAME] \"your question\"" >&2; exit 1; } +[[ -z "$QUERY" ]] && { echo "usage: ai_query.sh [--search] [--section=NAME] [--kind=KIND] \"your question\"" >&2; exit 1; } [[ -f "$DB" ]] || { error "No index at $DB — run AI/ai_index.sh first"; exit 1; } [[ -f "$CLI" ]] || { error "missing $CLI"; exit 1; } command -v node >/dev/null 2>&1 || { error "node not found"; exit 1; } @@ -169,6 +189,7 @@ fi _args=("--db=${DB}" "--url=${OLLAMA_URL}" "--query=${QUERY}") [[ -n "$SECTION" ]] && _args+=("--section=${SECTION}") +[[ -n "$KIND" ]] && _args+=("--kind=${KIND}") [[ "$JSON" == true ]] && _args+=(--json) if [[ "$SEARCH_ONLY" == true ]]; then