From 70f0bc960e09edeaa65e342b0d01227f5e10dc17 Mon Sep 17 00:00:00 2001 From: Levi Neuwirth Date: Wed, 19 Aug 2026 20:01:38 +0200 Subject: [PATCH] test(gate): carry the gate's stderr into the boundary assertion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit CI on 916007b: 12 green, 2 red, both macOS Test jobs, and exactly one row --- gate_maps_an_unexecutable_helper_to_error_not_ignored, left Some(1) right Some(2). The other five SIGINT rows pass on macOS. This is the A7 portability finding the review pre-declared, and it is a real one: the gate returned 1, meaning `ignored`, for a helper it could not execute --- the exact conflation §7c forbids. The cause is not established. The leading hypothesis is that the ABI's 1 is ambiguous by construction: 1 means "ignored", and 1 is also a status shells hand back for assorted failures. On Linux an unexecutable file yields 126 and the catch-all maps it to 2; if macOS /bin/sh returns 1 instead, the two cases are the same number at the boundary and no catch-all can separate them. That would call for verdicts outside the range shells produce, which is a design change needing its own revision --- not something to patch here. This commit only makes the failure self-diagnosing: the assertion now includes the gate's stderr, which prints the raw probe status it saw. The first failure could not say which status produced it, because the message discarded stderr. Co-Authored-By: Claude Opus 5 (1M context) Claude-Session: https://claude.ai/code/session_016bqGA6s9tTUFzYpbeW3tai --- docs/active-work.md | 21 +++++++++++++++++++++ tests/gate_script_acceptance.rs | 10 +++++++++- 2 files changed, 30 insertions(+), 1 deletion(-) diff --git a/docs/active-work.md b/docs/active-work.md index 9d2dffe..5359eb2 100644 --- a/docs/active-work.md +++ b/docs/active-work.md @@ -279,6 +279,27 @@ from #171 and #215. **`72da24a`**, worktree `/home/jeans/Repos/personal/pmacs-probe-sigint`. Recover with `git fetch githubsucks && git checkout gpu-probe-sigint-teardown`. +- **CI ON `916007b`: 12 GREEN, 2 RED — both macOS `Test` jobs**, and it + is the **pre-declared A7 portability finding**, not an environment + excuse. Exactly one row: + `gate_maps_an_unexecutable_helper_to_error_not_ignored`, + `left: Some(1) right: Some(2)`. The other five SIGINT rows pass on + macOS, including both `error` cases, so helper and gate consumers are + otherwise exercised there. + - **The gate returned 1 = `ignored` for a helper it could not + execute** — the exact conflation §7c forbids. + - **Leading hypothesis, NOT yet established: the ABI's `1` is + ambiguous by construction.** `1` means "ignored", and `1` is also a + status shells return for assorted failures. On Linux an + unexecutable file yields 126, so the catch-all maps it to 2; if + macOS's `/bin/sh` returns 1, the two cases are **the same number** + at the call boundary and no catch-all can separate them. If that + holds, the fix is to move the verdicts out of the range shells + produce, or to carry them by something other than exit status + alone — a design change needing its own revision. + - The assertion now carries the gate's stderr, which prints the raw + probe status, because the first failure could not say which status + produced it. - **PR #241** (`https://github.com/levineuwirth/pmacs/pull/241`), opened 2026-08-19 from `gpu-probe-sigint-teardown` into `main`. **Not merged; awaiting review rounds.** diff --git a/tests/gate_script_acceptance.rs b/tests/gate_script_acceptance.rs index 3190fb3..b0685e7 100644 --- a/tests/gate_script_acceptance.rs +++ b/tests/gate_script_acceptance.rs @@ -209,8 +209,16 @@ fn gate_maps_an_unexecutable_helper_to_error_not_ignored() { .env("PMACS_GATE_TARGET_ROOT", root.path()) .output() .expect("run the stub-worktree gate"); - assert_eq!(out.status.code(), Some(2), "boundary failures map to 2"); let err = String::from_utf8_lossy(&out.stderr); + // The gate prints the raw probe status it saw. Carry it into every + // assertion message: this row failed on macOS with exit 1 where 2 + // was expected, and the log could not say which status produced it + // because the message discarded stderr. + assert_eq!( + out.status.code(), + Some(2), + "boundary failures map to 2; gate said:\n{err}" + ); assert!( err.contains("could not run the SIGINT guard"), "the boundary has its own wording: {err}"