From b31822f626e3935f2c3000dcf1ff3a30c0757c08 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 28 Aug 2026 13:10:57 +0000 Subject: [PATCH] board: keep the interests backlog depth when the digest is late MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two bugs, one root: the interests tier's staleness banner and its backlog depth were mutually exclusive, and the suite could not see it because its fixtures aged with the calendar. - `_render_html` built the stale summary as "N paper(s) · ", dropping the "· M more days behind it" the fresh summary carries. That text is also what `_EXTRA_JS` swaps in via `data-stale-text`, so even a fresh render lost the depth the moment the browser recomputed staleness. A late digest is exactly when the depth matters — how many days are queued behind the one on screen is what tells you whether to keep tapping 🧹. `behind` now rides on both texts. - tests/test_board.py pinned its own dates but not its clock, so `_tree`'s "last digest: 2026-08-26" went stale on 2026-08-28 and two tests started failing on a calendar day rather than a code change. `_snap_with_remote` and `_interests` now pin `generated` the way `_inbox` already did. The failures were real, not just fixture drift: the render they caught is the one the board shows right now, with the nightly digest running late. 169 tests pass; make validate green. --- scripts/board.py | 6 +++++- tests/test_board.py | 24 +++++++++++++++++++++++- 2 files changed, 28 insertions(+), 2 deletions(-) diff --git a/scripts/board.py b/scripts/board.py index a0f613a..b325efa 100644 --- a/scripts/board.py +++ b/scripts/board.py @@ -1083,11 +1083,15 @@ def _fresh_span(fresh: dict, now_text: str, stale_text: str, f"submitting drops the {len(interest_items)} paper(s) left in " f"the {idate} batch and reveals the next day'>" f"\U0001f9f9 clear" if clear_url else "") + # `behind` rides on BOTH texts. A late digest is exactly when the + # backlog depth matters most, and dropping it from the stale variant + # hid it twice over: on a render that is already stale, and on a fresh + # render the moment _EXTRA_JS swaps in `data-stale-text`. imeta = _fresh_span( ifresh, f"{len(interest_items)} paper" f"{'s' if len(interest_items) != 1 else ''}{behind}", - f"{len(interest_items)} paper(s) · {istale_tmpl}") + f"{len(interest_items)} paper(s){behind} · {istale_tmpl}") # The batch's date IS its name — this is a backlog of days, and which # day you are looking at is the first thing to know. interests_block = ( diff --git a/tests/test_board.py b/tests/test_board.py index b8a4370..8059406 100644 --- a/tests/test_board.py +++ b/tests/test_board.py @@ -24,6 +24,15 @@ BODY_MARKER = "the-secret-claim-text-that-must-never-leak" +# The freshness/staleness banners are computed against `snapshot["generated"]`, +# so a fixture with fixed dates and a live clock ages out of its own window and +# the suite goes red on a calendar day rather than on a code change (it did, on +# 2026-08-28: the two-day-old stamp below turned stale and the assertions that +# expected a quiet day started reading the "filing may be broken" banner). Pin +# the clock to the day the tree below is written for; `_inbox` already does the +# same with its own calibrated date. +FIXTURE_NOW = "2026-08-26T09:00:00+00:00" + def _tree(tmp_path: Path) -> Path: w = tmp_path / "wiki" / "demo" @@ -67,6 +76,7 @@ def _snap_with_remote(tmp_path): """A synthetic snapshot with repo identity, as a live checkout has.""" snap = board.collect(_tree(tmp_path)) snap["owner"], snap["repo"] = "PyAutoLabs", "PyAutoMemory" + snap["generated"] = FIXTURE_NOW return snap @@ -311,7 +321,7 @@ def _inbox(tmp_path, stamp=None, papers=()): "# arXiv interests\n\nintro prose\n\n---\n") snap = board.collect(root) snap["owner"], snap["repo"] = "PyAutoLabs", "PyAutoMemory" - snap["generated"] = "2026-08-25T09:00:00+00:00" + snap["generated"] = "2026-08-25T09:00:00+00:00" # calibrated to this helper's dates return snap @@ -468,6 +478,7 @@ def _interests(tmp_path, lines, stamp=None): "# arXiv inbox\n\nintro prose\n\n---\n") snap = board.collect(root) snap["owner"], snap["repo"] = "PyAutoLabs", "PyAutoMemory" + snap["generated"] = FIXTURE_NOW return snap @@ -568,6 +579,17 @@ def test_the_backlog_depth_is_on_the_page(tmp_path): assert "1 more day behind it" in board._render_md(snap) +def test_the_backlog_depth_survives_the_stale_banner(tmp_path): + """A late digest is when the depth matters most. The stale text replaces + the summary wholesale — server-side here, and client-side via + `data-stale-text` — so it has to carry the depth too.""" + snap = _snap_with_remote(tmp_path) + snap["interests_last_digest"] = "2026-08-14" # stale against FIXTURE_NOW + html = board._render_html(snap) + assert "the nightly filing may be broken" in html + assert html.count("1 more day behind it") == 2 # rendered + data-stale-text + + def test_an_empty_interests_list_says_which_kind_of_empty(tmp_path): quiet = _interests(tmp_path, [], stamp="2026-08-26") assert "the last digest ran 2026-08-26" in board._render_md(quiet)