System: ISE / PDFsearch.py Related to: Problem & Resolution Report, same checkpoint
This bug is a logic/contract failure, not a portability failure. Confirmed identical behavior on both Dev and Live — it does not vary by hostname, IP, or hardware, so environment-diffing (the Dev/Live 6-environment topology) could never have caught it. This is a distinct failure class from the PDF.js "file origin" bug fixed earlier the same session, which was a portability/environment issue (Dev's boardurl pointing at the wrong host after a DB-restore mistake).
word_index_pdf.json is a single shared data structure with two independent consumers inside PDFsearch.py: word-mode lookup and phrase-mode lookup. At some point, word-mode's contract with that index changed (plain lookup → case-folded lookup via folded_index) — evidenced by _matching_words()'s own docstring, which refers to "the new case-insensitive default for plain words." Phrase-mode's lookup was never updated to match.
This is a shared-dependency change made without auditing every consumer of the thing that changed. No test existed at the time that exercised a quoted, capitalized phrase search against the newly-lowercase-only index, so the gap went unnoticed. Per existing project history, "case-sensitivity/quoting" was recorded as "unified across all 3 sources" in the v7.4 checkpoint — that claim was apparently accepted without the one test that would have disproven it for phrase mode specifically.
PDFsearch.py phrase-mode search for any capitalized or mixed-case term, on both Dev and Live (same code, same bug).MiscSearch.py and the posts-search equivalent may have the same pattern against their own word indexes, if those indexes are also lowercase-folded and their phrase-mode logic mirrors this file's. Flagged as an open item; requires those files to check.PDFIndexer.py) — the index content is correct; this is purely a query-side lookup bug.This codebase is developed by more than one AI collaborator (Claude/ChatGPT/Gemini) across sessions with no persistent shared memory of implementation history. A change to a shared structure's case convention is exactly the kind of thing that becomes invisible to whichever agent next touches a sibling consumer of that structure, unless the shared contract is written down somewhere all contributors check against — not merely implied by a comment on the function that changed. This project's own history already documents this exact failure class recurring in a different context (Gemini drafts silently regressing fixes by working from a stale base).
Per the stated project premise — "any code mod carries a chance of an unforeseen issue" — the mitigating goal is not prevention but detectability and recoverability:
test_phrase_bug.py currently exists only as a one-off diagnostic, not a permanent regression test wired into any ongoing suite.test_phrase_bug.py's core assertions into a permanent, reusable regression test for PDFsearch.py (not yet done).MiscSearch.py / posts-search for the same pattern (not yet done — files not yet reviewed).