Skip to content

fix(classifier): match flashback/throwback after publisher brand prefix#3480

Merged
koala73 merged 3 commits into
mainfrom
fix/classifier-publisher-prefix-flashback
Apr 28, 2026
Merged

fix(classifier): match flashback/throwback after publisher brand prefix#3480
koala73 merged 3 commits into
mainfrom
fix/classifier-publisher-prefix-flashback

Conversation

@koala73

@koala73 koala73 commented Apr 28, 2026

Copy link
Copy Markdown
Owner

Summary

  • Brief 2026-04-28-0801 shipped "CBS News Radio flashback: D-Day, Invasion of Normandy in 1944" as severity=critical in slot Add shareable map state URLs and Copy Link button #3, two days after PR fix(classifier): two-layer historical-retrospective downgrade (L1 + L3) #3429 (f37216d04) shipped the historical-retrospective downgrade.
  • Root cause: HISTORICAL_PREFIX_RE in _classifier.ts was anchored with ^ so flashback / throwback only matched at title position 0. Publishers prepend their brand ("CBS News Radio", "BBC", "NPR") before the marker token, defeating the anchor. The keyword path then matched invasion unimpeded → critical.
  • Fix shipped in three commits on this branch:
    1. 5ec9892 — initial relax of the prefix anchor to word-boundary.
    2. f61fae5 — tightened to two-branch form after Greptile P2: anchored at start OR brand-prefix slot (Title-Case prefix words + marker + optional qualifier + colon). Adds 5 negative tests covering sentence-form occurrences ("Markets see flashback to 2008 crisis…"), so the L3b LLM-cache guard at list-feed-digest.ts:547 doesn't widen its blast radius.
    3. fc1fcbf — bumps CLASSIFY_CACHE_PREFIX v4 → v5 in lockstep across all three sites (_shared.ts, list-feed-digest.ts doc-comment, ais-relay.cjs) so existing cache entries that promoted these titles to critical evict immediately rather than waiting for natural TTL.
- const HISTORICAL_PREFIX_RE = /^(?:science history|throwback|flashback)\s*:?/i;
+ const HISTORICAL_ANCHORED_PREFIX_RE =
+   /^(?:science history|throwback|flashback)\s*:?/i;
+ // No `i` flag — Title-Case enforcement on the brand prefix is load-bearing.
+ const HISTORICAL_BRAND_PREFIX_RE =
+   /^(?:[A-Z][\w'&-]*\s+){1,4}(?:[Tt]hrowback|[Ff]lashback)(?:\s+[A-Za-z]+)?\s*:/;

Test plan

  • 8 new test cases under news-classifier-historical-downgrade.test.mts:
    • 3 positive — CBS News Radio, BBC, NPR brand-prefix forms (incl. the exact title from brief 2026-04-28-0801)
    • 5 negative — Markets see flashback to 2008 crisis…, Stocks suffer flashback to March 2020 crash, Tesla stock throwback after split, AI flashback to 2023 boom: Nvidia earnings beat, lowercase-leading sentence
  • All 61 / 61 in news-classifier-historical-downgrade.test.mts + news-classifier-llm-historical-guard.test.mts pass
  • news-classify-cache-prefix-audit.test.mjs passes — all 3 sites in lockstep on v5
  • npm run typecheck + npm run typecheck:api — pass
  • Touched-file lint clean (pre-existing repo warnings unaffected)
  • npm run test:data — 7601 / 7601 pass
  • node --test tests/edge-functions.test.mjs — 178 / 178 pass
  • esbuild bundle of all 19 edge entries — pass
  • npm run lint:md — pass
  • npm run version:check — pass
  • CI on PR: biome / typecheck / unit / changes×3 / mintlify-slugs / Vercel deploy / gate — all green

Brief 2026-04-28-0801 surfaced "CBS News Radio flashback: D-Day,
Invasion of Normandy in 1944" as severity=critical in slot #3, two
days after PR #3429 shipped the historical-retrospective downgrade.

Root cause: HISTORICAL_PREFIX_RE was anchored with `^` —
`/^(?:science history|throwback|flashback)\s*:?/i` — so flashback /
throwback only matched at title position 0. Publishers prepend their
brand ("CBS News Radio", "BBC", "NPR") before the marker token, which
defeated the anchor. The keyword path then matched `invasion`
unimpeded → critical.

Fix: word-boundary match for flashback / throwback (unambiguous
markers regardless of position); science history stays anchored
since it's an editorial-slot prefix that's only retrospective at
the start of a headline.

  /(?:^science history\s*:?|\b(?:throwback|flashback)\b)/i

Regression test added under the existing
news-classifier-historical-downgrade suite covering CBS News Radio,
BBC, and NPR brand-prefix forms. All 56 cases in that file plus the
56 cases across the historical-downgrade + LLM-cache-guard tests
still pass.
@vercel

vercel Bot commented Apr 28, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
worldmonitor Ready Ready Preview, Comment Apr 28, 2026 5:46am

Request Review

@greptile-apps

greptile-apps Bot commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a regex anchor bug in HISTORICAL_PREFIX_RE that caused brand-prefixed flashback/throwback headlines (e.g. "CBS News Radio flashback: D-Day…") to bypass the historical-retrospective downgrade and ship as critical. The fix replaces the ^-anchored match for throwback/flashback with a \b word-boundary match while keeping science history anchored, exactly scoping the change to the affected tokens.

Confidence Score: 4/5

Safe to merge; the fix is surgical and well-tested with only a minor speculative false-positive edge case at P2.

No P0 or P1 issues found. The one P2 comment flags that \bflashback\b is not strictly confined to retrospective-segment uses and a non-retrospective mid-sentence occurrence (e.g. PTSD coverage) alongside a CRITICAL keyword could cause a false downgrade — a scenario not currently covered by a negative test. The fix itself is correct for the stated regression and all existing plus new test cases pass.

No files require special attention; the P2 concern is in _classifier.ts at the new HISTORICAL_PREFIX_RE.

Important Files Changed

Filename Overview
server/worldmonitor/news/v1/_classifier.ts Regex loosened for throwback/flashback from ^-anchored to \b word-boundary anywhere in title; science history anchor preserved. Fix is logically correct for the stated regression; minor P2 concern that \bflashback\b can match non-retrospective mid-sentence uses.
tests/news-classifier-historical-downgrade.test.mts Three new hasHistoricalMarker cases (CBS, BBC, NPR brand-prefix forms) and one full classifyByKeyword integration case covering the exact failing title from brief 2026-04-28-0801; all cleanly organised under existing describe blocks.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["Incoming headline\ne.g. 'CBS News Radio flashback: D-Day...'"] --> B["classifyByKeyword(title)"]
    B --> C["hasHistoricalMarker(title)"]
    C --> D{"HISTORICAL_PREFIX_RE\n/(?:^science history\\s*:?|\\b(?:throwback|flashback)\\b)/i"}
    D -- "match (e.g. 'flashback' word boundary)" --> E["isRetrospective = true"]
    D -- "no match" --> F["Check other markers\n(HISTORICAL_PHRASE_RE, FULL_DATE_RE, …)"]
    F --> G{"Any marker?"}
    G -- yes --> E
    G -- no --> H["isRetrospective = false"]
    B --> I["matchKeywords(lower, CRITICAL_KEYWORDS)\ne.g. 'invasion' → match"]
    E --> J{"isRetrospective?"}
    H --> J
    I --> J
    J -- true --> K["Return info / keyword-historical-downgrade\nconfidence 0.85"]
    J -- false --> L["Return critical / keyword\nconfidence 0.9"]

    style K fill:#90EE90
    style L fill:#FF6961
Loading

Reviews (1): Last reviewed commit: "fix(classifier): match flashback/throwba..." | Re-trigger Greptile

Comment on lines +247 to +248
const HISTORICAL_PREFIX_RE =
/(?:^science history\s*:?|\b(?:throwback|flashback)\b)/i;

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 \bflashback\b can fire on non-retrospective medical/narrative uses

flashback can appear in current-event headlines outside of the retrospective-segment context — e.g. "Veteran's flashback triggers meltdown on base" or "Abuse survivor's flashback described in court". If any CRITICAL/HIGH keyword also appears (here meltdown), the title would be downgraded to info, suppressing a real alert.

The risk is low given how rarely such phrasing appears alongside CRITICAL keywords in hard-news syndication, but the assertion in the comment that flashback is "always retrospective by definition" is slightly overstated. A negative regression test covering a non-retrospective mid-sentence flashback (e.g. "Veteran flashback triggers meltdown on base" → level critical) would document the accepted boundary explicitly and catch any future broadening of the pattern.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. Tightened in f61fae5.

Replaced the bare word-boundary form with two explicit branches:

  1. ANCHORED (original behavior): marker at title position 0 — Throwback Thursday:, Flashback:, Science history:.
  2. BRAND-PREFIX: 1-4 Title-Case prefix words + marker + optional qualifier word + colon. Catches CBS News Radio flashback:, BBC Throwback Thursday:, NPR Flashback Friday: while rejecting sentence-form occurrences.
const HISTORICAL_ANCHORED_PREFIX_RE =
  /^(?:science history|throwback|flashback)\s*:?/i;
// No `i` flag — Title-Case enforcement on the brand prefix is load-bearing.
const HISTORICAL_BRAND_PREFIX_RE =
  /^(?:[A-Z][\w'&-]*\s+){1,4}(?:[Tt]hrowback|[Ff]lashback)(?:\s+[A-Za-z]+)?\s*:/;

The brand-prefix branch deliberately requires (a) Title-Case prefix words and (b) an editorial-slot colon after the marker. Both gates together reject the realistic false-positive shapes you were worried about for the L3b LLM-cache guard.

Added 5 negative tests covering them:

  • Markets see flashback to 2008 crisis as bonds tumble → false (no colon)
  • Stocks suffer flashback to March 2020 crash → false (no colon)
  • Tesla stock throwback after split → false (no colon)
  • AI flashback to 2023 boom: Nvidia earnings beat → false (qualifier slot overruns; colon not adjacent)
  • markets see flashback: bonds tumble → false (lowercase first word fails Title-Case gate)

All existing positive tests still pass (61/61 across news-classifier-historical-downgrade.test.mts + news-classifier-llm-historical-guard.test.mts).

Reviewer P2 on PR #3480: widening flashback/throwback to bare
word-boundary match also broadens the L3b LLM-cache guard at
list-feed-digest.ts:547, which force-demotes ANY cached LLM hit
to info when hasHistoricalMarker is true. A current-event headline
that incidentally uses "flashback" / "throwback" as a comparison
word ("Markets see flashback to 2008 crisis as bonds tumble") would
be wrongly suppressed even though the marker isn't acting as a
retrospective framing token.

Replace the broad word-boundary form with two explicit branches:

  1. ANCHORED: marker at title position 0 (original behavior —
     "Throwback Thursday:", "Flashback:", "Science history:").

  2. BRAND-PREFIX: 1-4 Title-Case prefix words + marker + optional
     qualifier word + colon. Catches the brand-prefixed forms
     ("CBS News Radio flashback:", "BBC Throwback Thursday:",
     "NPR Flashback Friday:") while rejecting sentence-form uses.

The brand-prefix branch deliberately requires (a) Title-Case
prefix words (rejects "markets see flashback…"), AND (b) an
editorial-slot colon after the marker (rejects "Markets See
Flashback To 2008 Crisis As Bonds Tumble"). The Title-Case gate
uses a non-i regex so [A-Z] enforces actual capitalization rather
than getting case-folded.

Adds 5 negative tests for the realistic false-positive cases the
reviewer was worried about — "Markets see flashback to 2008
crisis", "Stocks suffer flashback to March 2020 crash", "Tesla
stock throwback after split", "AI flashback to 2023 boom: Nvidia
earnings beat", and a lowercase-leading sentence form. All
existing positive tests still pass (61/61 in the historical-
downgrade + LLM-cache-guard suite).
Evicts cache entries that landed under the pre-publisher-prefix-fix
classifier — brand-prefixed retrospective titles like "CBS News Radio
flashback: D-Day, Invasion of Normandy in 1944" had been promoted to
severity=critical via the `invasion` keyword and persisted in the
classify cache. The new brand-prefix branch in _classifier.ts (PR
#3480 commits 5ec9892 + f61fae5) re-rules those rows on next
touch; v5 forces immediate eviction rather than waiting for natural
TTL on every poisoned entry.

Three lockstep sites updated atomically per the cache-prefix-bump-
propagation-scope learning:
  - server/worldmonitor/intelligence/v1/_shared.ts:20 (canonical writer)
  - server/worldmonitor/news/v1/list-feed-digest.ts:511 (doc-comment)
  - scripts/ais-relay.cjs:3172 (relay inline helper)

The news-classify-cache-prefix-audit static-analysis test enforces
lockstep — passes after this change.
@koala73
koala73 merged commit 07202db into main Apr 28, 2026
11 checks passed
@koala73
koala73 deleted the fix/classifier-publisher-prefix-flashback branch April 28, 2026 05:58
fuleinist pushed a commit to fuleinist/worldmonitor that referenced this pull request May 9, 2026
…ix (koala73#3480)

* fix(classifier): match flashback/throwback after publisher brand prefix

Brief 2026-04-28-0801 surfaced "CBS News Radio flashback: D-Day,
Invasion of Normandy in 1944" as severity=critical in slot #3, two
days after PR koala73#3429 shipped the historical-retrospective downgrade.

Root cause: HISTORICAL_PREFIX_RE was anchored with `^` —
`/^(?:science history|throwback|flashback)\s*:?/i` — so flashback /
throwback only matched at title position 0. Publishers prepend their
brand ("CBS News Radio", "BBC", "NPR") before the marker token, which
defeated the anchor. The keyword path then matched `invasion`
unimpeded → critical.

Fix: word-boundary match for flashback / throwback (unambiguous
markers regardless of position); science history stays anchored
since it's an editorial-slot prefix that's only retrospective at
the start of a headline.

  /(?:^science history\s*:?|\b(?:throwback|flashback)\b)/i

Regression test added under the existing
news-classifier-historical-downgrade suite covering CBS News Radio,
BBC, and NPR brand-prefix forms. All 56 cases in that file plus the
56 cases across the historical-downgrade + LLM-cache-guard tests
still pass.

* fix(classifier): tighten flashback/throwback to editorial-slot syntax

Reviewer P2 on PR koala73#3480: widening flashback/throwback to bare
word-boundary match also broadens the L3b LLM-cache guard at
list-feed-digest.ts:547, which force-demotes ANY cached LLM hit
to info when hasHistoricalMarker is true. A current-event headline
that incidentally uses "flashback" / "throwback" as a comparison
word ("Markets see flashback to 2008 crisis as bonds tumble") would
be wrongly suppressed even though the marker isn't acting as a
retrospective framing token.

Replace the broad word-boundary form with two explicit branches:

  1. ANCHORED: marker at title position 0 (original behavior —
     "Throwback Thursday:", "Flashback:", "Science history:").

  2. BRAND-PREFIX: 1-4 Title-Case prefix words + marker + optional
     qualifier word + colon. Catches the brand-prefixed forms
     ("CBS News Radio flashback:", "BBC Throwback Thursday:",
     "NPR Flashback Friday:") while rejecting sentence-form uses.

The brand-prefix branch deliberately requires (a) Title-Case
prefix words (rejects "markets see flashback…"), AND (b) an
editorial-slot colon after the marker (rejects "Markets See
Flashback To 2008 Crisis As Bonds Tumble"). The Title-Case gate
uses a non-i regex so [A-Z] enforces actual capitalization rather
than getting case-folded.

Adds 5 negative tests for the realistic false-positive cases the
reviewer was worried about — "Markets see flashback to 2008
crisis", "Stocks suffer flashback to March 2020 crash", "Tesla
stock throwback after split", "AI flashback to 2023 boom: Nvidia
earnings beat", and a lowercase-leading sentence form. All
existing positive tests still pass (61/61 in the historical-
downgrade + LLM-cache-guard suite).

* chore(classifier): bump CLASSIFY_CACHE_PREFIX v4 → v5

Evicts cache entries that landed under the pre-publisher-prefix-fix
classifier — brand-prefixed retrospective titles like "CBS News Radio
flashback: D-Day, Invasion of Normandy in 1944" had been promoted to
severity=critical via the `invasion` keyword and persisted in the
classify cache. The new brand-prefix branch in _classifier.ts (PR
koala73#3480 commits 5ec9892 + f61fae5) re-rules those rows on next
touch; v5 forces immediate eviction rather than waiting for natural
TTL on every poisoned entry.

Three lockstep sites updated atomically per the cache-prefix-bump-
propagation-scope learning:
  - server/worldmonitor/intelligence/v1/_shared.ts:20 (canonical writer)
  - server/worldmonitor/news/v1/list-feed-digest.ts:511 (doc-comment)
  - scripts/ais-relay.cjs:3172 (relay inline helper)

The news-classify-cache-prefix-audit static-analysis test enforces
lockstep — passes after this change.
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