phase: 162_search_recall_small_sources
**Phase 162 — final verification pass (all tasks already complete; verified + docs pass)** - Verified: `_fold` (NFKD+casefold, stdlib) inside `_normalize_name` — `BESTÅ`→`besta` question side, `BÅsta.md`→`basta` path side; A2 match classes/ranking/caps/bonus untouched; FTS/cosine/A8 untouched. - Verified: `grep_document` folds both sides via the imported `_fold` (no second copy); regex-teaching lines byte-identical; 3 copy sites updated. - Verified: `regenerate_overview` appends the deterministic `Sources: <name> (<k> doc|docs)` tail (happy path only; zero-doc + `LLMError` rows byte-identical; `build_overview_prompt`/`load_kb_overview`/`build_kb_section` untouched). - Verified: `TOOLS_SECTION` grep sentence updated + D4 search-discipline sentence present **verbatim**, immediately after the grep sentence; `PERSONA`/LOW pins byte-identical (`test_prompt_lock.py`). - Measured evidence (in `.agents/reports/162_…/task04_prefix_evidence_and_battery.md` + re-measured every run by `test_under_rank_is_measured_not_assumed`): pre-fix tokens `['build','best']` → IKEA doc rank 6 (outside top-5); post-fix `['build','besta']` → suggested #1, cosine unchanged 0.382. - `uv run pytest tests/e2e/test_search_recall_small_sources.py -v --no-cov` → **7 passed** (isolated); neighbours `test_kb_overview{,_freshness} test_name_signal_read_chips test_grep_regex_teaching test_harness_aligned_tools test_agent_document_tools test_tool_call_compact` → **24 passed**. - `uv run pytest --cov=app --cov-report=term-missing` → **3756 passed**, app coverage **99%** (>90%). - `uv run ruff check .` → All checks passed; `uv run pyright` → **0 errors**. - Completion criteria: fold both ways ✅ · `Sources:` tail ✅ · TOOLS_SECTION + D4 verbatim + re-cut pins ✅ · E2E green/battery recorded/full suite/coverage/lint ✅ · docs pass ✅ · commit + dir move = harness. - Battery: 5 phase-119 questions byte-identical to the phase-119 record (GATE PASS); the 2 Besta questions **skipped loudly** — verified the 2026-09-05 replica dump has zero `ikea` matches (`grep -c -i ikea data/bor_live_kb_replica.dump.sql` = 0); rank gate stays with the owner's live KB. - Docs fixed: README — overview-tail doc + `BOR_KB_OVERVIEW_MAX_CHARS` tail-cut constraint, the phase-162 search-discipline paragraph, per-phase (not per-story) E2E wording, new "Retrieval regression battery" section; AGENTS.md — rule 4 per-phase wording + battery command in Quick reference. (The overview's expected "AGENTS.md §6 tool table" does not exist in this repo — the grep contract line lives in README's tool table, already updated.) - Deviations (recorded, not assumed): `_fold` adds `casefold` (required for the pinned `ß → ss`); `①` NFKD-decomposes to `1` (the overview's parenthetical was wrong) and is excluded by `NAME_TOKEN_MIN_LEN`; pre-fix evidence lives in the reports dir because task files are read-only for this pass. - Owner follow-up A6 (runtime, not code): add the Tuning-tab steering note "IKEA's BESTÅ assembly PDF is a live source — search it as `BESTÅ` or `AA-1272068`". - Next pending phase: none — 162 is the only entry in `todo/` (harness moves it to `complete/`).
This commit is contained in:
+19
-10
@@ -50,6 +50,7 @@ from app.models import Document
|
||||
from app.rag.prompts import (
|
||||
ORIGIN_RULE,
|
||||
PERSONA,
|
||||
SEARCH_DISCIPLINE_RULE,
|
||||
SHOW_IMAGE_CLAUSE,
|
||||
SUGGEST_INTRO,
|
||||
TOOLS_SECTION,
|
||||
@@ -286,14 +287,14 @@ def test_tools_section_markers_and_new_tool_names() -> None:
|
||||
|
||||
def test_tools_section_teaches_the_harness_shapes() -> None:
|
||||
"""Copy pins: ``ls``'s phase-63 catalog-line format, ``grep``'s
|
||||
case-insensitive exact-string locator contract (up to 20
|
||||
case- and accent-insensitive exact-string locator contract (up to 20
|
||||
``source/path:line: text`` lines, a locator not a context-adder),
|
||||
and ``read``'s combined ``source/path`` + full content. (Phase 72:
|
||||
the source-name scope clause and the combined-identity clause are
|
||||
pinned byte-for-byte in
|
||||
:func:`test_tools_section_phase72_contract_clauses`.)"""
|
||||
assert "source: X | path: Y | title: Z" in TOOLS_SECTION
|
||||
assert "case-insensitive" in TOOLS_SECTION
|
||||
assert "case- and accent-insensitive" in TOOLS_SECTION # phase 162 fold
|
||||
assert "up to 20" in TOOLS_SECTION
|
||||
assert "source/path:line: text" in TOOLS_SECTION
|
||||
assert "locator, not a context-adder" in TOOLS_SECTION
|
||||
@@ -414,20 +415,28 @@ def test_tools_section_phase118_summary_seed_read_clause() -> None:
|
||||
"| path: Y | title: Z`; to find one specific document without "
|
||||
"listing, use `grep`."
|
||||
) in TOOLS_SECTION
|
||||
# The grep clause — byte-identical.
|
||||
# The grep clause — folded contract (phase 162, LOCKED A3), up to the
|
||||
# search-discipline sentence, byte-identical.
|
||||
assert (
|
||||
"`grep` locates an exact string (case-insensitive) in the "
|
||||
"`grep` locates an exact string (case- and accent-insensitive — "
|
||||
"accents fold: `besta` matches `BESTÅ`) in the "
|
||||
"indexed documents and returns up to 20 matching "
|
||||
"`source/path:line: text` lines — a locator, not a "
|
||||
"context-adder: read the winner with `read`. A grep pattern "
|
||||
"is a plain substring, NEVER a regex — '.*' and '\\.' are "
|
||||
"literal text there; if such a pattern returns no matches, "
|
||||
"retry with the plain text you expect to see. For a normal "
|
||||
"search pass only `pattern` — its optional `path` argument "
|
||||
"limits the search to one document you already know, by the "
|
||||
"same combined `source/path` string; never a source name — a "
|
||||
"bare document path (without the source name) will not "
|
||||
"resolve there either."
|
||||
"retry with the plain text you expect to see. "
|
||||
) in TOOLS_SECTION
|
||||
# The LOCKED search-discipline sentence sits immediately after the
|
||||
# grep sentence, before the path clause (phase 162, LOCKED A4).
|
||||
assert (
|
||||
"retry with the plain text you expect to see. "
|
||||
+ SEARCH_DISCIPLINE_RULE
|
||||
+ " For a normal search pass only `pattern` — its optional "
|
||||
"`path` argument limits the search to one document you already "
|
||||
"know, by the same combined `source/path` string; never a "
|
||||
"source name — a bare document path (without the source name) "
|
||||
"will not resolve there either."
|
||||
) in TOOLS_SECTION
|
||||
# The discipline rules — byte-identical.
|
||||
assert (
|
||||
|
||||
Reference in New Issue
Block a user