📝 2_Risk_Analysis_Report.mdv4.2 · 2026-09-05

Risk Analysis Report

System: ISE / PDFsearch.py Related to: Problem & Resolution Report, same checkpoint

Failure classification

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).

Root cause, process level

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.

Blast radius

Multi-agent process risk (contributing factor)

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).

Standing exposure going forward

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:

Recommendation

  1. Promote test_phrase_bug.py's core assertions into a permanent, reusable regression test for PDFsearch.py (not yet done).
  2. Check MiscSearch.py / posts-search for the same pattern (not yet done — files not yet reviewed).
  3. Any future change to a shared index/data structure's format or convention should explicitly enumerate every consumer of that structure before being considered complete, rather than relying on it being remembered.