fix(kb): confirm retrievability with a filtered query, classify TEXT_INDEXED - #908
Open
DerrickF wants to merge 2 commits into
Open
fix(kb): confirm retrievability with a filtered query, classify TEXT_INDEXED#908DerrickF wants to merge 2 commits into
DerrickF wants to merge 2 commits into
Conversation
…EXT_INDEXED Two findings from running yesterday's fix, plus the handoff entries for both and for #901. The probe could not find its own document ----------------------------------------- `wait_until_retrievable` searched for the document *id as the query text* and checked whether that document came back in the top 5. A document id means nothing to an embedding model, so the search returned whatever the reranker preferred. Measured in dev with two documents present: query=DOC-40e985680a63 -> 5 chunks, ALL from DOC-db44eaf8f072 FOUND: False A perfectly retrievable document reported as not retrievable. It scales the wrong way: the more documents a knowledge base holds, the less likely the target lands in an unfiltered top-5, so every upload to a mature knowledge base would burn its poll budget and dead-letter — worse than the bug #901 fixed. It only ever worked while the knowledge base held exactly one document, where anything returned was necessarily the right thing. Now an `equals` filter on `document_id`, so a non-empty result IS proof and an empty one is a true negative. `equals` is already in ISOLATION_SAFE_FILTER_OPERATORS; a prefix operator would let DOC-1 confirm DOC-10. Verified against dev: each document returns 5 of its own chunks, a fabricated id returns none. TEXT_INDEXED is not in the SDK's enum ------------------------------------- The live service returned `TEXT_INDEXED` for a document with image extraction enabled — text searchable, media still processing — and the packaged model's `DocumentStatus` enum does not list it. So status handling must not be derived from that enum. Treated as in-flight rather than done: completing at that point would tell a user an image-only page is ready while the vision model is still running, which is the report this module exists to prevent. Unrecognised statuses now default to "keep waiting" too, so the next value AWS adds does not dead-letter documents. Also simplifies the flow: arriving to find a document already in flight used to raise immediately, which relied on redelivery that Lambda caps at 2 attempts. Both entry paths — just submitted, and found mid-flight — now share one bounded wait. Test-suite fix: an autouse fixture shortens the poll budgets. With the real 600 s budget the file took 20 minutes; it is now under 6 seconds. This is exactly why those constants are resolved at call time rather than bound as default arguments. `_FakeBackend` now models a knowledge base holding OTHER documents, and honours the filter. Without that, a probe ignoring its filter still passes — which is precisely how the query-by-id probe survived until a second document existed. Mutations verified caught: probe unfiltered, filter switched to a prefix operator, and TEXT_INDEXED dropped from the in-flight set. The third initially SURVIVED, because the unknown-status fallback also waits, making the mutation behaviour-equivalent; resolved by asserting the only thing that genuinely differs — that the status is classified rather than falling through the unknown branch. Not every surviving mutant means a missing test. Handoff: findings 37-39 recorded, including that §5.30's wrong constant had a second home nobody grepped for, and a correction — yesterday's claim that a measured 0.9 s gap "confirmed" the 0.75-1.03 s figure was false, since the fabricated timestamp meant it measured ingest-return to retrievable instead. 454 passed across lambdas/supply_chain/architecture; ruff clean.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Two findings from running yesterday's fix (#901), plus handoff entries for both and for #901 itself.
The probe could not find its own document
wait_until_retrievablesearched for the document id as the query text and checked whether that document came back in the top 5. A document id carries no meaning to an embedding model, so the search returned whatever the reranker preferred. Measured in dev with two documents present:A perfectly retrievable document, reported as not retrievable.
It scales the wrong way. The more documents a knowledge base holds, the less likely the target lands in an unfiltered top-5 — so every upload to a mature knowledge base would burn its full poll budget and dead-letter. That is worse than the bug #901 fixed. It only ever worked while the knowledge base held exactly one document, where anything returned was necessarily the right thing.
Now an
equalsfilter ondocument_id: a non-empty result is proof, an empty one is a true negative.equalsis already inISOLATION_SAFE_FILTER_OPERATORS— a prefix operator would letDOC-1confirmDOC-10. Verified against dev: each document returns 5 of its own chunks, a fabricated id returns none.TEXT_INDEXEDis not in the SDK's enumThe live service returned
TEXT_INDEXEDfor a document with image extraction enabled — text searchable, media still processing — and the packaged model'sDocumentStatusenum does not list it. So status handling must not be derived from that enum.Treated as in-flight, not done: completing there would tell a user an image-only page is ready while the vision model is still running, which is the exact report this module exists to prevent. Unrecognised statuses now default to "keep waiting" as well, so the next value AWS adds does not dead-letter documents.
Also
Arriving to find a document already in flight used to raise immediately, relying on redelivery that Lambda caps at 2 attempts. Both entry paths — just submitted, and found mid-flight — now share one bounded wait.
Test-suite fix: an autouse fixture shortens the poll budgets. With the real 600 s budget this file took 20 minutes; it is now under 6 seconds. That is precisely why those constants are resolved at call time rather than bound as default arguments.
_FakeBackendnow models a knowledge base holding other documents, and honours the filter. Without that, a probe that ignores its filter still passes — which is how the query-by-id probe survived until a second document existed.Mutations
startsWithTEXT_INDEXEDdropped from in-flightThe third is worth reading. Removing
TEXT_INDEXEDis behaviour-equivalent — the unknown-status fallback also waits, so the document is handled identically and every behavioural assertion still passed. The honest resolution was to assert the only thing that genuinely differs: that the status is classified, rather than falling through the unknown branch and logging a warning for a state we have already seen in production. Not every surviving mutant means a missing test; some mean the mutation changes nothing.Handoff
Findings 37–39 recorded, plus two things worth carrying forward:
0.75–1.03 s) had a second home nobody grepped for. When a wrong constant is found, look for its other copies.indexedAtit was measuring ingest-return → retrievable, not INDEXED → retrievable. A number agreeing with your expectation is not confirmation.454 passed across
lambdas/supply_chain/architecture; ruff clean.