Skip to content

fix(extraction): #885 the pre-judge ceiling now names the candidates it cut - #891

Merged
jasonssdev merged 1 commit into
mainfrom
fix/pre-judge-ceiling-names-titles-885
Aug 27, 2026
Merged

fix(extraction): #885 the pre-judge ceiling now names the candidates it cut#891
jasonssdev merged 1 commit into
mainfrom
fix/pre-judge-ceiling-names-titles-885

Conversation

@jasonssdev

Copy link
Copy Markdown
Owner

Closes #885

The defect

The 24-candidate pre-judge ceiling was the only drop in the extraction pipeline that reported a bare count with no titles. In the wild run that surfaced this, every other drop named names — 4 wrong-language, 9 recombined, 10 judge, 1 staging — and this one said 7.

That contradicts the principle the module already wrote for its sibling in _unevidenced_notice:

"The titles are load-bearing, not decoration. A notice that only counted would leave the operator opening every derived document to find the one."

You cannot check against the source what you cannot name.

After

merged extraction union exceeded the 24-candidate pre-judge ceiling;
1 merged candidate(s) never reached the judge: Subject 25

Three deliberate choices

  • A separate field, not a replacement. pre_judge_dropped_titles sits beside the int. Stored runs predating it carry () and still render the half they always had; replacing the count would break reading historical data for a cosmetic gain.
  • Additive wording. The count and the ceiling explanation stay. That line is what an operator reads to understand why extraction stopped short — trading information for information is not an improvement.
  • The siblings' shape. Same _CAP_NOTICE_TITLE_LIMIT + (+N more) as every other title-bearing notice, so the extraction notices read alike.

What this does NOT fix

#885 has two halves and this closes one. Truncation is still positionalmerged[:_MAX_JUDGE_CANDIDATES] over a list concatenated in window (document) order — so the tail of a long source is what goes, regardless of quality. Naming the cut makes that observable, which is the step before fixing it. Both the field docstring and the test record it, so the next person to touch this does not have to rediscover it.

The substantive remedy — ordering candidates by something other than document position before the cut — needs measurement first and is left open.

Evidence

  • RED first: three new notice tests failed on the missing field; the fourth (a stored run with a count and no titles) passed from the start, pinning backward compatibility.
  • The end-to-end test was extended, not duplicated. It already builds 25 distinct candidates so the ceiling cuts exactly 1, and now asserts the notice names Subject 25. Mutating the implementation to take merged[:n] (the head) instead of merged[n:] (the tail) turns it red — so the assertion pins which candidate is dropped, not merely that some title appears.
  • Full suite 5658 passed, 1 skipped. ruff clean. mypy clean over 272 files.

Found during the 0.2.10 manual E2E.

🤖 Generated with Claude Code

https://claude.ai/code/session_01MZz1zEMqg4X5mDEwwfC6dj

…it cut

The 24-candidate pre-judge ceiling was the ONLY drop in the extraction
pipeline that reported a bare count with no titles. Its siblings all name
names -- discarded_titles, judged_out_titles, the wrong-language and
recombined gates. In the wild run that surfaced this, every other drop named
names (4 wrong-language, 9 recombined, 10 judge, 1 staging) and this one said
"7".

That contradicted the principle the module already wrote for the sibling
notice in _unevidenced_notice: "The titles are load-bearing, not decoration.
A notice that only counted would leave the operator opening every derived
document to find the one." You cannot check against the source what you
cannot name.

    merged extraction union exceeded the 24-candidate pre-judge ceiling;
    1 merged candidate(s) never reached the judge: Subject 25

Three deliberate choices:

- pre_judge_dropped_titles is a SEPARATE field, not a replacement for the
  int. Stored runs predating it carry () and still render the half they
  always had; replacing the count would break reading historical data for a
  cosmetic gain.
- The notice is ADDITIVE. The count and the ceiling explanation stay -- that
  line is what an operator reads to understand why extraction stopped short,
  and trading information for information is not an improvement.
- Same _CAP_NOTICE_TITLE_LIMIT + "(+N more)" shape as every sibling notice,
  so the extraction notices read alike.

Naming the cut does NOT fix #885's substantive half: truncation is still
POSITIONAL over a list concatenated in window -- i.e. document -- order, so
the TAIL of a long source is what goes. This makes that observable, which is
the step before fixing it, and both the field docstring and the test say so.

The end-to-end test was extended rather than duplicated: it already builds 25
distinct candidates so the ceiling cuts exactly 1, and now asserts the notice
names "Subject 25". Mutating the implementation to take merged[:n] (the head)
instead of merged[n:] (the tail) turns it red -- so the assertion pins WHICH
candidate is dropped, not merely that some title appears.

Full suite 5658 passed, 1 skipped; ruff clean; mypy clean over 272 files.

Closes #885
@jasonssdev
jasonssdev merged commit 271ba13 into main Aug 27, 2026
7 checks passed
@jasonssdev
jasonssdev deleted the fix/pre-judge-ceiling-names-titles-885 branch August 27, 2026 01:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pre-judge ceiling binds in the wild, cuts by document position, and names nothing it dropped

1 participant