From c3946f403dbdf6058d2a241a25163e0ddd0e2d7d Mon Sep 17 00:00:00 2001 From: xormania <127287135+xormania@users.noreply.github.com> Date: Sun, 2 Aug 2026 15:34:46 -0400 Subject: [PATCH 1/4] test(ci): expose residual trap race --- tests/dev/security-gate-concurrency-cases.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/tests/dev/security-gate-concurrency-cases.py b/tests/dev/security-gate-concurrency-cases.py index 40553cc..47d8607 100644 --- a/tests/dev/security-gate-concurrency-cases.py +++ b/tests/dev/security-gate-concurrency-cases.py @@ -1499,10 +1499,11 @@ def test_output_limits(work: Path) -> None: ) -def residual_flood_fixture(work: Path) -> tuple[Path, Path, Path]: +def residual_flood_fixture(work: Path) -> tuple[Path, Path, Path, Path]: work.mkdir(parents=True, exist_ok=True) completion = work / "descendant-flood-completed" group_file = work / "residual-flood.group" + ready = work / "residual-flood.ready" flood = write_script( work, "residual-flood.sh", @@ -1522,7 +1523,9 @@ def residual_flood_fixture(work: Path) -> tuple[Path, Path, Path]: : > "$FLOOD_COMPLETION" exit 0 } + sleep "$FLOOD_ARM_DELAY" trap flood TERM + : > "$FLOOD_READY" while :; do sleep 1; done ) & exit 0 @@ -1536,11 +1539,12 @@ def residual_flood_fixture(work: Path) -> tuple[Path, Path, Path]: ), completion, group_file, + ready, ) def test_residual_cleanup_output_limit(work: Path) -> None: - manifest, completion, group_file = residual_flood_fixture(work) + manifest, completion, group_file, ready = residual_flood_fixture(work) small_helper = transformed_helper( work, "residual-output-limit", @@ -1566,8 +1570,10 @@ def test_residual_cleanup_output_limit(work: Path) -> None: 1, helper=small_helper, extra_env={ + "FLOOD_ARM_DELAY": "0.2", "FLOOD_COMPLETION": str(completion), "GROUP_FILE": str(group_file), + "FLOOD_READY": str(ready), }, ) check(result.rc == 125, "residual descendant output overflow returns infrastructure") @@ -1911,14 +1917,16 @@ def test_sensitivity_mutants(work: Path) -> None: if residual_mutant is not None: fixture_work = work / "mutant-residual-output" fixture_work.mkdir(parents=True, exist_ok=True) - manifest, completion, group_file = residual_flood_fixture(fixture_work) + manifest, completion, group_file, ready = residual_flood_fixture(fixture_work) result = run_gate( manifest, 1, helper=residual_mutant, extra_env={ + "FLOOD_ARM_DELAY": "0.2", "FLOOD_COMPLETION": str(completion), "GROUP_FILE": str(group_file), + "FLOOD_READY": str(ready), }, ) check( From b5c10bcf481cd4e19533492e1a75521fcdd379a8 Mon Sep 17 00:00:00 2001 From: xormania <127287135+xormania@users.noreply.github.com> Date: Sun, 2 Aug 2026 15:35:34 -0400 Subject: [PATCH 2/4] fix(ci): wait for residual trap readiness --- tests/dev/security-gate-concurrency-cases.py | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/dev/security-gate-concurrency-cases.py b/tests/dev/security-gate-concurrency-cases.py index 47d8607..dae92fd 100644 --- a/tests/dev/security-gate-concurrency-cases.py +++ b/tests/dev/security-gate-concurrency-cases.py @@ -1528,7 +1528,13 @@ def residual_flood_fixture(work: Path) -> tuple[Path, Path, Path, Path]: : > "$FLOOD_READY" while :; do sleep 1; done ) & -exit 0 +for ((attempt = 0; attempt < 500; attempt++)); do + if [ -f "$FLOOD_READY" ]; then + exit 0 + fi + sleep 0.002 +done +exit 125 """, ) return ( From a9ab07fbc96ee680cb836663911806bd30368b5b Mon Sep 17 00:00:00 2001 From: xormania <127287135+xormania@users.noreply.github.com> Date: Sun, 2 Aug 2026 15:41:23 -0400 Subject: [PATCH 3/4] test(ci): require schedule-independent arming --- tests/dev/security-gate-concurrency-cases.py | 22 +++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/tests/dev/security-gate-concurrency-cases.py b/tests/dev/security-gate-concurrency-cases.py index dae92fd..c26cc00 100644 --- a/tests/dev/security-gate-concurrency-cases.py +++ b/tests/dev/security-gate-concurrency-cases.py @@ -1499,10 +1499,12 @@ def test_output_limits(work: Path) -> None: ) -def residual_flood_fixture(work: Path) -> tuple[Path, Path, Path, Path]: +def residual_flood_fixture(work: Path) -> tuple[Path, Path, Path, Path, Path, Path]: work.mkdir(parents=True, exist_ok=True) completion = work / "descendant-flood-completed" group_file = work / "residual-flood.group" + started = work / "residual-flood.started" + arm = work / "residual-flood.arm" ready = work / "residual-flood.ready" flood = write_script( work, @@ -1523,13 +1525,15 @@ def residual_flood_fixture(work: Path) -> tuple[Path, Path, Path, Path]: : > "$FLOOD_COMPLETION" exit 0 } - sleep "$FLOOD_ARM_DELAY" + trap '' TERM + : > "$FLOOD_STARTED" + while [ ! -f "$FLOOD_ARM" ]; do sleep 0.002; done trap flood TERM : > "$FLOOD_READY" while :; do sleep 1; done ) & for ((attempt = 0; attempt < 500; attempt++)); do - if [ -f "$FLOOD_READY" ]; then + if [ -f "$FLOOD_STARTED" ]; then exit 0 fi sleep 0.002 @@ -1545,12 +1549,14 @@ def residual_flood_fixture(work: Path) -> tuple[Path, Path, Path, Path]: ), completion, group_file, + started, + arm, ready, ) def test_residual_cleanup_output_limit(work: Path) -> None: - manifest, completion, group_file, ready = residual_flood_fixture(work) + manifest, completion, group_file, started, arm, ready = residual_flood_fixture(work) small_helper = transformed_helper( work, "residual-output-limit", @@ -1576,10 +1582,11 @@ def test_residual_cleanup_output_limit(work: Path) -> None: 1, helper=small_helper, extra_env={ - "FLOOD_ARM_DELAY": "0.2", + "FLOOD_ARM": str(arm), "FLOOD_COMPLETION": str(completion), "GROUP_FILE": str(group_file), "FLOOD_READY": str(ready), + "FLOOD_STARTED": str(started), }, ) check(result.rc == 125, "residual descendant output overflow returns infrastructure") @@ -1923,16 +1930,17 @@ def test_sensitivity_mutants(work: Path) -> None: if residual_mutant is not None: fixture_work = work / "mutant-residual-output" fixture_work.mkdir(parents=True, exist_ok=True) - manifest, completion, group_file, ready = residual_flood_fixture(fixture_work) + manifest, completion, group_file, started, arm, ready = residual_flood_fixture(fixture_work) result = run_gate( manifest, 1, helper=residual_mutant, extra_env={ - "FLOOD_ARM_DELAY": "0.2", + "FLOOD_ARM": str(arm), "FLOOD_COMPLETION": str(completion), "GROUP_FILE": str(group_file), "FLOOD_READY": str(ready), + "FLOOD_STARTED": str(started), }, ) check( From 2ca15d773a8461278114e605cadc1ec55fce9d3b Mon Sep 17 00:00:00 2001 From: xormania <127287135+xormania@users.noreply.github.com> Date: Sun, 2 Aug 2026 15:42:01 -0400 Subject: [PATCH 4/4] fix(ci): synchronize residual flood arming --- tests/dev/security-gate-concurrency-cases.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/tests/dev/security-gate-concurrency-cases.py b/tests/dev/security-gate-concurrency-cases.py index c26cc00..e8e215b 100644 --- a/tests/dev/security-gate-concurrency-cases.py +++ b/tests/dev/security-gate-concurrency-cases.py @@ -1534,7 +1534,14 @@ def residual_flood_fixture(work: Path) -> tuple[Path, Path, Path, Path, Path, Pa ) & for ((attempt = 0; attempt < 500; attempt++)); do if [ -f "$FLOOD_STARTED" ]; then - exit 0 + : > "$FLOOD_ARM" + for ((ready_attempt = 0; ready_attempt < 500; ready_attempt++)); do + if [ -f "$FLOOD_READY" ]; then + exit 0 + fi + sleep 0.002 + done + exit 125 fi sleep 0.002 done