From 13ae64cbaec8435605ba522ebd0ef6f50f1b4e57 Mon Sep 17 00:00:00 2001 From: AIOSAI Date: Wed, 15 Jul 2026 10:26:09 -0700 Subject: [PATCH] =?UTF-8?q?fix:=20unpark=20the=20parked=20CI=20reds=20?= =?UTF-8?q?=E2=80=94=20Patrick=20ruling:=20red=20CI=20is=20never=20parked.?= =?UTF-8?q?=20@prax:=20relay=20mtime-cache=20flake=20root-caused=20(test?= =?UTF-8?q?=20relied=20on=20two=20writes=20sharing=20one=20mtime-granulari?= =?UTF-8?q?ty=20window=20=E2=80=94=20true=20locally,=20false=20on=20CI)=20?= =?UTF-8?q?=E2=80=94=20os.utime=20pins=20mtime=20so=20the=20cache=20contra?= =?UTF-8?q?ct=20tests=20deterministically,=2050/50+20/20=20loops=20green.?= =?UTF-8?q?=20@hooks:=204=20Windows=20session=5Fboot=20reds=20=E2=80=94=20?= =?UTF-8?q?=5Ftmux=5Fsession=5Fexists()=20real=20subprocess=20spawn=20(no?= =?UTF-8?q?=20tmux=20on=20Windows,=20WinError=202)=20mocked=20per=20ca0962?= =?UTF-8?q?95=20convention,=20execvp=20already=20mocked=20=3D=20zero=20rea?= =?UTF-8?q?l=20spawns=20left.=201028=20prax=20+=20102=20session=5Fboot=20g?= =?UTF-8?q?reen,=20devpulse-verified.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CHANGELOG.md | 12 ++++++++++++ src/aipass/hooks/tests/test_session_boot.py | 4 ++++ src/aipass/prax/tests/test_telegram_relay.py | 4 ++++ 3 files changed, 20 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index db6805f1..09c35342 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,18 @@ PyPI version — not the changelog header. remaining Windows session_boot reds and the relay mtime-cache flake predate this PR and stay parked. +- **The parked reds, unparked — Patrick's ruling: red CI is never parked.** + "If CI is red, it's because you or I left it red." Both remaining reds fixed + by their owners the same hour. @prax root-caused the relay mtime-cache flake: + the test only passed when two writes landed in the same mtime-granularity + window (true locally, false on CI runners) — fixed by pinning mtime with + `os.utime` so the cache contract is tested deterministically, proven 50/50 + + 20/20 loops. @hooks root-caused the four Windows session_boot reds: the boot + path's `_tmux_session_exists()` ran a real `subprocess.run(["tmux", ...])` + that Windows runners can't satisfy (WinError 2) — mocked in all four tests + per the ca096295 convention, leaving `execvp` (already mocked) as the only + terminal call. Ruling recorded in compass; the "forget CI" era is over. + ## [2026-07-14] ### Fixed diff --git a/src/aipass/hooks/tests/test_session_boot.py b/src/aipass/hooks/tests/test_session_boot.py index c28c68d2..b3ef22e3 100644 --- a/src/aipass/hooks/tests/test_session_boot.py +++ b/src/aipass/hooks/tests/test_session_boot.py @@ -206,6 +206,7 @@ class TestBoot: patch.object(session_boot, "_find_live_sessions", return_value=live), patch.object(session_boot, "_read_choice", return_value=""), patch.object(session_boot, "_find_tmux_session_for_pid", return_value=None), + patch.object(session_boot, "_tmux_session_exists", return_value=False), patch(f"{_MOD}.os.execvp") as mock_exec, ): session_boot.boot(cwd=str(tmp_path)) @@ -264,6 +265,7 @@ class TestBoot: patch.object(session_boot, "_find_tmux", return_value="/usr/bin/tmux"), patch.object(session_boot, "_find_live_sessions", return_value=[]), patch.object(session_boot, "_read_choice", return_value=""), + patch.object(session_boot, "_tmux_session_exists", return_value=False), patch(f"{_MOD}.os.execvp") as mock_exec, ): session_boot.boot(cwd=str(tmp_path)) @@ -892,6 +894,7 @@ class TestExtraArgsThreading: patch.object(session_boot, "_find_tmux", return_value="/usr/bin/tmux"), patch.object(session_boot, "_find_live_sessions", return_value=[]), patch.object(session_boot, "_read_choice", return_value=""), + patch.object(session_boot, "_tmux_session_exists", return_value=False), patch(f"{_MOD}.os.execvp") as mock_exec, ): session_boot.boot(cwd=str(tmp_path), extra_args=["--permission-mode", "plan"]) @@ -1065,6 +1068,7 @@ class TestAutoNamer: patch.object(session_boot, "_find_tmux", return_value="/usr/bin/tmux"), patch.object(session_boot, "_find_live_sessions", return_value=[]), patch.object(session_boot, "_read_choice", return_value=""), + patch.object(session_boot, "_tmux_session_exists", return_value=False), patch(f"{_MOD}.os.execvp") as mock_exec, ): session_boot.boot(cwd=str(tmp_path)) diff --git a/src/aipass/prax/tests/test_telegram_relay.py b/src/aipass/prax/tests/test_telegram_relay.py index db35dc40..d4c8ad01 100644 --- a/src/aipass/prax/tests/test_telegram_relay.py +++ b/src/aipass/prax/tests/test_telegram_relay.py @@ -450,12 +450,16 @@ class TestReadControl: def test_mtime_cache_avoids_reread(self, tmp_path): """Same mtime returns cached result without re-reading the file.""" + import os + relay = _import_relay() ctrl = tmp_path / "control.json" ctrl.write_text(json.dumps({"paused": False})) setattr(relay, "CONTROL_FILE", ctrl) first = relay._read_control() + cached_mtime = ctrl.stat().st_mtime ctrl.write_text("INVALID JSON") + os.utime(ctrl, (cached_mtime, cached_mtime)) result = relay._read_control() assert result == first