fix: hide thin or stale catch-up strips (TASK-127) - #1575
Conversation
lilyshen0722
left a comment
There was a problem hiding this comment.
Gate at 184685f3. Clear. 23/23 baseline, both properties pinned, and the trap the ruling exists for is closed at the right field.
The July case is fixed where it had to be
Freshness is measured on timeRange.end — the window the summary covers — not createdAt. That is the whole point: regenerating a July summary today must not make July fresh. Mutating it back to createdAt gives 3 red, all three named for that distinction.
The count gate is on metadata.totalItems, integer-checked and < 3 rejected. Removing it gives 8 red, including the parameterised 0/1/2/undefined/-1/2.5 cases and refresh cannot replace an eligible strip with a thin or stale one. Your note said 2 for this one — I removed the gate outright rather than loosening the threshold, which is why the number is larger; not a discrepancy in the code.
The over-narrowing risk, checked
A frontend-only gate that reads two new fields hides the strip everywhere if those fields do not arrive. They do:
Summary.ts:16declarestimeRange,:21declaresmetadata.totalItems- both write paths populate them —
chatSummarizerService.ts:220-227setstimeRange: {start, end}andtotalItems: messages.length; the empty-summary path at:256-262setstotalItems: 0, which this gate correctly rejects getLatestPodSummaryisSummary.findOne(...).lean()with no.select(), and the route returns it whole, so nothing is projected away
So the strip still renders for real summaries, and the documented consequence — legacy rows without source evidence lose the strip but keep the summary surface — is a choice the comment states rather than an accident.
Unrelated but adjacent
Nothing here touches the resolution semantics or the counts. sourceAge >= 0 also rejects a window ending in the future, which is a sensible extra the ruling did not ask for and the tests cover.
lilyshen0722
left a comment
There was a problem hiding this comment.
UX-GATE: APPROVED @ 184685f — visibility gate only (source count ≥3, window end ≤7d): no render, class, or CSS change; the strip's shape is untouched and the zero state at 1440/390 is the existing no-strip state.
Summary
TASK-127 / Sam ruling 64301: hide catch-up below three messages or when the covered window is seven days old. Two-file change; independent of count PR #1574. No CSS or direction C work.
The strip requires integer
metadata.totalItems >= 3, a valid orderedtimeRange, and0 <= now - timeRange.end < 7 days. Missing evidence, future/reversed/invalid ranges, and blank content hide it. This replaces the former generation-age-only 24-hour check. Dismissal remains version-scoped; refreshed summaries pass the same gate.Evidence contract
GET /api/summaries/pod/:podIdalready returns the Summary document, including metadata and timeRange. The gate uses its reported coverage window, notcreatedAt; it does not independently audit message rows. Built-in summaries record query bounds and count; agent summaries supply these fields (and persistence defaults an omitted timeRange to the preceding hour). Correcting inaccurate agent-supplied evidence is outside this UI change. No new backend fields or migration.Verification
Review/UX and current-head CI pending. No merge/deploy, sweep, or historical attention writes included.