From 283bf6a04726612553d9489d839bbec475bf3dfe Mon Sep 17 00:00:00 2001 From: Rodrigo Gomes da Silva Date: Fri, 14 Aug 2026 22:10:00 -0300 Subject: [PATCH] fix(sessions): keep the interactive exclusion spelled as a literal tests/test_issue2841_show_cron_sessions_toggle.py reads this call site as SOURCE TEXT (`'("cron", "webhook", "kanban") if source_filter is None'`), so routing it through the new BACKGROUND_CLI_SOURCES constant turned a pre-existing test in the maintainer's own shard gate red for a behaviour-neutral refactor. Put the literal back at that one call site. BACKGROUND_CLI_SOURCES stays where the kanban-chip fix actually needs it (the background-source check in _interactive_row_project_id, and interactive_excluded for both recovery passes). A new test builds the expected literal FROM the constant and asserts it appears verbatim in api/models.py, so the two spellings cannot drift without failing here rather than in an unrelated file. --- api/models.py | 5 ++++- ...test_project_assigned_cli_session_limit.py | 22 +++++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/api/models.py b/api/models.py index ea641160..47f3bc47 100644 --- a/api/models.py +++ b/api/models.py @@ -8454,7 +8454,10 @@ def _load_cli_sessions_uncached( # Background sources have independent bounded passes below. Keeping them # out of this 20-row interactive window prevents a busy worker source # (especially kanban) from evicting every CLI/TUI/ACP conversation. - exclude_sources=BACKGROUND_CLI_SOURCES if source_filter is None else None, + # Spelled as a literal on purpose: tests/test_issue2841_show_cron_sessions_toggle.py + # reads this line as source text. Must stay equal to BACKGROUND_CLI_SOURCES + # (pinned by test_background_source_exclusion_literal_matches_the_constant). + exclude_sources=("cron", "webhook", "kanban") if source_filter is None else None, include_sources=None if source_filter is None else (source_filter,), ) if source_filter is None: diff --git a/tests/test_project_assigned_cli_session_limit.py b/tests/test_project_assigned_cli_session_limit.py index 972d9c49..316b871c 100755 --- a/tests/test_project_assigned_cli_session_limit.py +++ b/tests/test_project_assigned_cli_session_limit.py @@ -756,6 +756,28 @@ def test_unassigned_refill_runs_when_the_mixed_window_under_delivers( # ── Rebase guard: upstream's kanban pass shares the system-chip helper ──────── +def test_background_source_exclusion_literal_matches_the_constant(): + """The interactive exclusion stays spelled as a tuple literal. + + ``tests/test_issue2841_show_cron_sessions_toggle.py`` reads that call site as + SOURCE TEXT (``'("cron", "webhook", "kanban") if source_filter is None'``), + so replacing the literal with ``BACKGROUND_CLI_SOURCES`` turned a + pre-existing test red. The literal is therefore kept, and this test pins it + to the constant the new code paths use so the two cannot drift apart. + """ + from pathlib import Path + + source = Path(models.__file__).read_text(encoding="utf-8") + literal = ", ".join(f'"{name}"' for name in models.BACKGROUND_CLI_SOURCES) + assert f"exclude_sources=({literal}) if source_filter is None else None" in source, ( + "the interactive exclude_sources literal must list exactly " + f"BACKGROUND_CLI_SOURCES ({models.BACKGROUND_CLI_SOURCES!r})" + ) + assert '("cron", "webhook", "kanban") if source_filter is None' in source, ( + "test_issue2841_show_cron_sessions_toggle.py pins this exact substring" + ) + + def test_kanban_second_pass_still_projects_rows(fake_hermes_home, tmp_path): """The system-chip helper keeps the (sid, source) signature kanban calls.