Fact suggestions also ask about pages named in the transcript (#1342) #1357

Merged
claude-bot merged 5 commits from feat/1342-mentioned-pages into main 2026-11-06 21:03:57 +00:00
Collaborator

Closes #1342. After the 4.7.0 deploy, the prod backfill asked about nothing, because no wiki pages were linked to those sessions. Now the pass also asks about pages the transcript names.

  • Candidates: the session's linked pages, plus every live, non-proposed page in the same campaign with an allowed type whose title or alias the transcript names. It uses the existing mention_pattern and runs two queries per session, however many pages the campaign has.
  • Order and cap: linked pages first (by title), then the others by how often they're named. The cap is MAX_PAGES_PER_SESSION = 12, and anything beyond it is counted as skipped_cap on the run. A linked page the transcript never names takes no place: it was never asked about, so it no longer pushes a named page out.
  • Over-matching: a page the session didn't link can be found only by a name of at least 3 characters (MIN_MENTION_NAME) that isn't a small word: the existing stop words plus a _COMMON set (she, they, him, one, man…). Linked pages match as before, so a linked "Al" is still asked about. A real one-word name such as "Guard" still matches.
  • Unchanged: quote validation, the written-label guard, the bin, erasure and retention rules, and one pending suggestion per session, page and label.
  • Re-running prod after this ships: suggest_fact_changes_backfill(force_zero_asked=True) also takes sessions whose last run asked about 0 pages:
    celery -A app.tasks.celery_app call app.tasks.fact_tasks.suggest_fact_changes_backfill --kwargs='{"force_zero_asked": true}'

Tests:

  • an unlinked page named in the transcript;
  • an alias match;
  • the cap order with skipped_cap, and skipped_cap landing on the run;
  • linked pages that are never named take no place;
  • trashed, bot-proposed, other-campaign and no-facts pages are never candidates;
  • short and common titles;
  • a short linked title is still asked about;
  • force_zero_asked in the service and the task.

The reader guards (SEGMENT_USES, title readers) list the new reads with reasons.

Checks (docker-test, committed code):

  • lint is clean.
  • tests/wiki/test_fact_suggestions.py, test_transcript_bin_readers.py, test_title_readers.py and test_body_readers.py: 70 passed.
  • checks passes.
  • Not run: the full backend suite. CI runs it.

🤖 Generated with Claude Code

Closes #1342. After the 4.7.0 deploy, the prod backfill asked about nothing, because no wiki pages were linked to those sessions. Now the pass also asks about pages the transcript names. - **Candidates:** the session's linked pages, plus every live, non-proposed page in the same campaign with an allowed type whose title or alias the transcript names. It uses the existing `mention_pattern` and runs two queries per session, however many pages the campaign has. - **Order and cap:** linked pages first (by title), then the others by how often they're named. The cap is `MAX_PAGES_PER_SESSION = 12`, and anything beyond it is counted as `skipped_cap` on the run. **A linked page the transcript never names takes no place**: it was never asked about, so it no longer pushes a named page out. - **Over-matching:** a page the session didn't link can be found only by a name of at least 3 characters (`MIN_MENTION_NAME`) that isn't a small word: the existing stop words plus a `_COMMON` set (she, they, him, one, man…). Linked pages match as before, so a linked "Al" is still asked about. A real one-word name such as "Guard" still matches. - **Unchanged:** quote validation, the written-label guard, the bin, erasure and retention rules, and one pending suggestion per session, page and label. - **Re-running prod after this ships:** `suggest_fact_changes_backfill(force_zero_asked=True)` also takes sessions whose last run asked about 0 pages: `celery -A app.tasks.celery_app call app.tasks.fact_tasks.suggest_fact_changes_backfill --kwargs='{"force_zero_asked": true}'` **Tests:** - an unlinked page named in the transcript; - an alias match; - the cap order with `skipped_cap`, and `skipped_cap` landing on the run; - linked pages that are never named take no place; - trashed, bot-proposed, other-campaign and no-facts pages are never candidates; - short and common titles; - a short linked title is still asked about; - `force_zero_asked` in the service and the task. The reader guards (`SEGMENT_USES`, title readers) list the new reads with reasons. **Checks (docker-test, committed code):** - `lint` is clean. - `tests/wiki/test_fact_suggestions.py`, `test_transcript_bin_readers.py`, `test_title_readers.py` and `test_body_readers.py`: **70 passed**. - `checks` passes. - Not run: the full backend suite. CI runs it. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Candidates are the session's linked pages plus every live, non-proposed page
of the campaign whose title or alias the transcript names, capped at 12 a
session (skipped_cap counts the rest). Titles under 3 characters and small
words never find a page. The backfill task takes force_zero_asked.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A linked page the transcript never names has no excerpts and is never
asked, so it must not count against MAX_PAGES_PER_SESSION or push a
named page into skipped_cap. Test included.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
refactor: keep the linked-page check inside _candidates (#1342)
All checks were successful
CI / Summarisation accuracy eval harness (stub provider) (pull_request) Successful in 1m8s
CI / Backend lint (ruff) (pull_request) Successful in 33s
CI / Bot tests and audit (pull_request) Successful in 2m9s
CI / Feedback site tests (pull_request) Successful in 55s
CI / Bot/backend version sync (pull_request) Successful in 27s
CI / Docker image build (pull_request) Successful in 21s
CI / Does this change touch the recording path? (pull_request) Successful in 21s
CI / Which journeys does this change need? (pull_request) Successful in 20s
CI / Synthetic session harness (no GPU, no LLM) (pull_request) Has been skipped
CI / Frontend (shard 1/2) (pull_request) Successful in 11m32s
CI / Frontend (shard 2/2) (pull_request) Successful in 19m21s
CI / End-to-end journeys (desktop) (pull_request) Successful in 12m31s
CI / Backend migration, tests, and audit (pull_request) Successful in 1h19m38s
14ba070dd0
The title-readers guard counts reads per function; a nested helper
read as a new reader. Same behaviour.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Sign in to join this conversation.
No description provided.