Skip to content

fix(extraction): apply the four-lens findings on the name grounding (#712) - #720

Merged
jasonssdev merged 1 commit into
mainfrom
fix/712-review-followups
Aug 15, 2026
Merged

fix(extraction): apply the four-lens findings on the name grounding (#712)#720
jasonssdev merged 1 commit into
mainfrom
fix/712-review-followups

Conversation

@jasonssdev

Copy link
Copy Markdown
Owner

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 — 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 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 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 actually reads.
  • _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.

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, mypy clean.

Lineage review-5436f9f54c1f3932, HIGH risk, canonical 4R, approved, receipt bound to this exact candidate, pre-pr gate allow.

Known residue, deliberately not chased here

This round's lenses raised further findings on the fix itself, and they are real:

  • the trailing half of the word boundary is not independently exercised (in manana the leading lookbehind already rejects, so (?!\w) is untested)
  • the docstring's stated reason for preferring lookarounds over \b is wrong\b matches beside a colon too
  • the set vs list change ("distinct rather than every line") is not observable in its test
  • nothing pins the direction the widened exemption must still fire in
  • "LABEL-ONLY" is now the wrong vocabulary for a half-threshold

These 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_text already uses, which ignores one-off labels by construction.

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
@jasonssdev
jasonssdev merged commit ca84660 into main Aug 15, 2026
6 checks passed
@jasonssdev
jasonssdev deleted the fix/712-review-followups branch August 15, 2026 12:03
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.
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.

1 participant