fix(extraction): apply the four-lens findings on the name grounding (#712) - #720
Merged
Conversation
PR #719 was approved with no blocker, but four lenses raised real defects in the advisory it shipped. Two of them were found independently by the resilience and reliability lenses, which is usually the sign a finding is about the code rather than about taste. WORD BOUNDARIES. The grounding was a raw substring test, so a short name was "found" inside any unrelated word containing it -- `Ana` in `mañana`, `Vega` in `Vegas`. That silently un-fires the advisory exactly where it matters most: a short fabricated name is both the easiest to hallucinate and the easiest to hit by accident. The declared bias table names the false negatives this check accepts, and this was not among them; it was a bug. The boundary is `(?<!\w)`/`(?!\w)` rather than `\b` so `Ana:` in a transcript still matches. THE LABEL-ONLY EXEMPTION WAS ALL-OR-NOTHING. `all()` over every matched label let a single `Presenter:` line disable the exemption for an entire AMI transcript and re-flag every role-titled participant. It is now half of the DISTINCT labels: a transcript with one longer label still does not state its participants' real names. THE LEGACY PATH REPORTED NOTHING. `cli/main.py` picks `extract_concept_union if union_judge else extract_concept`, and only the union path computed the advisory -- so with `union_judge` off, participants were stored and nothing was surfaced. That is the "computed but never read" defect #690 already spent a PR diagnosing, one function over. Also: the coverage report's RENDERED line still read `anchor-less discards`, the one part of that file a human reads. And `_participant_unreadmitted_notice` now records WHY its single-cause claim holds and what would invalidate it -- the field is a complement, not a cause, and slice 3's budget lane is exactly the change that would make the wording a lie before any test noticed. Each fix is mutation-confirmed against its exact target line with `__pycache__` purged; reverting any one fails its own test and no other. Suite 4802 -> 4806. Refs #712
This was referenced Aug 15, 2026
jasonssdev
added a commit
that referenced
this pull request
Aug 16, 2026
…surement (#734) Slice 3's two-lane participant budget exists to stop participants evicting subjects from `_UNION_BACKSTOP = 20`. D4 made its own reopen trigger explicit — "a stored run whose participant lane actually truncates" — and that trigger was tested against every stored run in every participant-bearing harness: the backstop has never bound. Largest retained set on record is 9 objects (stage_attrition, 45 runs), 7 with --participants on (participant_anchor, 9 runs), at most 5 participant candidates ever produced, p_max 3. Owner ruling: close slice 3 unshipped with the evidence, not deferred — the same disposition as task 2.4, and the same discipline applied to six rejected prompt treatments. Spec merge audit found three mismatches between the specs and shipped code: - `Stub Rejection at Judge Re-Admission` was still in openspec/specs and had been contradicting shipped code since #719 retired that gate. Removed. - The re-admission scope requirement named `_MEETING_SHAPED_TITLE_RE`, stale since #673. Corrected to `_is_meeting_shaped` (title OR content). - The participant-name-grounding delta described the label-only exemption as "matched solely via the speaker-label path". The shipped code never consults `_is_meeting_shaped`; it exempts when at least half the distinct labels are <= 2 characters. Rewritten to the shipped rule, with the `Presenter:` case from PR #720's review pinned as its own scenario. The two slice-3 delta requirements were dropped rather than merged, so openspec/specs never claims the lane exists. Also corrects `_PARTICIPANT_CAPTURE_SYSTEM_PROMPT`'s docstring, which still claimed its candidates are gated like every other participant candidate and that a name-only answer is discarded downstream. Both were false after #719. Task 2.9 grepped docs/ and not src/. The prompt still asks for an anchor; it is a quality request now, never a precondition. Phase 5 verification run at archive: ruff, ruff format and mypy clean over 215 files; full suite 4813 passed, 1 skipped. Review: lineage review-bc5738249503bfaf, medium risk, review-reliability, APPROVED with zero findings, receipt valid at pre-commit.
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.
Follow-up to #719. Applies the review findings that PR raised, rather than letting them sit behind an approved receipt.
Two of the three were found independently by the resilience and reliability lenses, which is usually the sign a finding is about the code rather than about taste.
Word boundaries
Grounding was a raw substring test, so a short name was "found" inside any unrelated word containing it —
Anainmañana,VegainVegas. That silently un-fires the advisory exactly where it matters most: a short fabricated name is both the easiest to hallucinate and the easiest to hit by accident.The declared bias table names which false negatives this check accepts. This was not among them — it was a bug.
The label-only exemption was all-or-nothing
all()over every matched label let a singlePresenter:line disable the exemption for an entire AMI transcript and re-flag every role-titled participant. It is now half of the distinct labels: a transcript with one longer label still does not state its participants' real names.The legacy path reported nothing
cli/main.pypicksextract_concept_union if union_judge else extract_concept, and only the union path computed the advisory — so withunion_judgeoff, participants were stored and nothing was surfaced. That is the "computed but never read" defect #690 already spent a PR diagnosing, one function over.Also
anchor-less discards— the one part of that file a human actually reads._participant_unreadmitted_noticenow records why its single-cause claim holds and what would invalidate it: the field is a complement, not a cause, and slice 3's budget lane is exactly the change that would make the wording a lie before any test noticed.Verification
Each fix mutation-confirmed against its exact target line with
__pycache__purged — reverting any one fails its own test and no other. Suite 4802 → 4806 passed, 1 skipped.ruff,ruff format,mypyclean.Lineage
review-5436f9f54c1f3932, HIGH risk, canonical 4R, approved, receipt bound to this exact candidate,pre-prgateallow.Known residue, deliberately not chased here
This round's lenses raised further findings on the fix itself, and they are real:
mananathe leading lookbehind already rejects, so(?!\w)is untested)\bis wrong —\bmatches beside a colon toosetvs list change ("distinct rather than every line") is not observable in its testThese go to one final PR rather than another review-of-the-fix cycle. The exemption threshold in particular deserves a better rule than "half the distinct labels" — most likely the recurring-speaker notion
_transcript_shaped_textalready uses, which ignores one-off labels by construction.