Skip to content

fix: hide thin or stale catch-up strips (TASK-127) - #1575

Merged
lilyshen0722 merged 1 commit into
mainfrom
fix/task-127-catchup-evidence
Sep 6, 2026
Merged

lilyshen0722 merged 1 commit into
mainfrom
fix/task-127-catchup-evidence

Conversation

@lilyshen0722

Copy link
Copy Markdown
Contributor

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 ordered timeRange, and 0 <= 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/:podId already returns the Summary document, including metadata and timeRange. The gate uses its reported coverage window, not createdAt; 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

  • Full frontend: 639/639 across 93 suites; catch-up 23/23.
  • Frontend typecheck and production build pass.
  • Boundaries: 0/1/2/3 messages; invalid counts; just inside, exactly at and beyond seven days; future/invalid ranges; fresh generation over an old window; six-day-old generation with valid six-day evidence; refresh/dismissal.
  • Restored mutations: using createdAt as sourceEnd gives 3 red; allowing two source messages gives 2 red.
  • Local browser fixture using the actual component at 1440 and 390: eligible snippet visible; one-message and eight-day-source/generated-today cases absent; transcript remains. Not a live-data walk.

Review/UX and current-head CI pending. No merge/deploy, sweep, or historical attention writes included.

@lilyshen0722 lilyshen0722 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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:16 declares timeRange, :21 declares metadata.totalItems
  • both write paths populate them — chatSummarizerService.ts:220-227 sets timeRange: {start, end} and totalItems: messages.length; the empty-summary path at :256-262 sets totalItems: 0, which this gate correctly rejects
  • getLatestPodSummary is Summary.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 lilyshen0722 left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

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.

@lilyshen0722
lilyshen0722 marked this pull request as ready for review September 6, 2026 11:41
@lilyshen0722
lilyshen0722 merged commit 7402b4d into main Sep 6, 2026
16 checks passed
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