From 00f5c35ec8c164c450cbb6d7bdfd18c31fb82b2b Mon Sep 17 00:00:00 2001 From: EMRG Evolution Date: Fri, 7 Aug 2026 11:54:16 +0800 Subject: [PATCH] =?UTF-8?q?emrg:=20fix=20flaky=20session=20ID=20uniqueness?= =?UTF-8?q?=20test=20=E2=80=94=2016-bit=20=E2=86=92=2032-bit=20entropy?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit generate_session_id() used secrets.token_hex(2)[:4] (16 bits, 65536 possibilities). The 10-sample uniqueness test collides ~0.07% per run (birthday paradox) — observed on master push run 31145421676 (PR CI green, master push red: 'assert 9 == 10'). Suffix now uses 4 random bytes (8 hex chars = 32 bits): collision probability drops ~65500x to ~1e-8 per run. Format remains s_YYMMDD_HHMM_xxxxxxxx; all existing format assertions still pass. 502 tests green. --- emrg/session.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/emrg/session.py b/emrg/session.py index 8e60a0ac..b32019d7 100644 --- a/emrg/session.py +++ b/emrg/session.py @@ -31,17 +31,23 @@ def generate_session_id(cwd: Path) -> str: - """Generate a human-friendly session ID: s_YYMMDD_HHMM_xxxx.""" + """Generate a human-friendly session ID: s_YYMMDD_HHMM_xxxxxxxx. + + Suffix uses 4 random bytes (32 bits of entropy) — a 2-byte suffix + (16 bits, 65536 possibilities) made the 10-sample uniqueness test + flaky via the birthday paradox (~0.07% collision per run; observed + on CI master push run 31145421676). + """ now = datetime.now() prefix = f"s_{now.strftime('%y%m%d_%H%M')}_" sessions_dir = cwd / ".emrg" / "sessions" for _ in range(100): - suffix = secrets.token_hex(2)[:4] + suffix = secrets.token_hex(4) sid = prefix + suffix if not (sessions_dir / sid).exists(): return sid - # Fallback: use longer suffix - suffix = secrets.token_hex(4)[:8] + # Fallback: same 4-byte entropy (loop exhaustion is astronomically rare) + suffix = secrets.token_hex(4) return prefix + suffix