fix(submit): scope per-day preserve notices to the bounded submit window

Merged
JU
14d ago
+742-9

Summary

Follow-up to #1513, flagged in its review notes. A date-bounded submit ships its declared-complete clients (scanScope.fullHistoryClients) unfiltered, so the payload dates days every other scanned client was scoped out of. On each such day the receiver emitted one Preserved X because it disappeared from this same-device resubmit notice per scanned bounded-growth client, plus a Preserved ...ms active time notice whenever the stored day carried more active time than the structurally partial incoming one. A weekly submit against a device with a long exempt-client history returned hundreds of noise lines, and the CLI prints every one of them — drowning the warnings that matter.

What changes

  • On a bounded submit that declares per-client coverage (fullHistory: false with fullHistoryClients present), both notices are suppressed on days whose every incoming cell belongs to a declared-complete client — exactly the day class the #1513 date-filter exemption introduces outside the requested window.
  • Stored data behaviour is byte-identical. The disappeared branch still runs its preserve/drop path and the active-time monotonic guard is untouched; only warnings emission changes. mergeClientBreakdownsWithRegressionGuard gains a suppressDisappearedNotices flag that gates nothing but the warnings.push.
  • Days carrying any window-covered client keep both notices (the in-window disappearance signal stays). Full-history submits are unchanged. Bounded submits from CLIs predating the per-client declaration are unchanged. Backfills are unchanged.

Why this shape

The receiver cannot see the CLI's --since/--until window, but it can see which clients were declared complete: a day whose cells all belong to declared clients is a day the window-scoped clients were filtered out of, so their absence (and the lower day active time) carries no signal. Clients declared complete keep their own disappeared handling through the parser plans, which already remove them from the per-day merge when their plan rewrote them.

Test plan

  • New route harness submitBoundedWindowNotices.test.ts (4 tests): suppression on exempt-covered days with stored cells asserted equal to the seeded values; notices kept on in-window days; old bounded CLIs (no fullHistoryClients) unchanged; full-history submits unchanged.
  • Unit byte-identity in helpers.test.ts: identical merged JSON and fold bookkeeping with the flag on/off across the disappeared, zero-token-drop, regression-preserve, and growth branches; non-disappeared warnings still emitted while suppressing.
  • Negative control: with the two source files reverted to HEAD, the 3 suppression tests fail and all controls pass.
  • bun run test — 1195 passed; bun run typecheck and bun run lint clean (pre-existing warnings only).

Summary by cubic

Suppresses the spurious per-day preserve notices that a date-bounded submit emits for days whose every incoming cell belongs to a declared-complete client, so weekly submits against devices with long exempt-client histories stop printing hundreds of noise lines that drown the real warnings.

  • On bounded submits with a per-client coverage declaration, both the disappeared and active time notices are suppressed on days the payload dates only through fullHistoryClients — the day class the #1513 date-filter exemption introduces outside the requested window.
  • Stored data behavior is identical; only warning emission changes.
  • In-window days, full-history submits, and bounded submits from CLIs predating the per-client declaration keep the notices.