probe_gate blames a merge for regressing every probe when the engine is simply missing nf-2fdc ← Beads

closed priority 2 task unassigned

Twinned from https://github.com/cfsh/ninefold/issues/588 by tools/beads/import_github.py's reconcile pass.

Observed live in #567's post-merge gate, on this box. The existing fail-closed guard covers a build failure and a crashed sweep; it does not cover a missing engine, which produces a complete, well-formed results table with every probe failed — indistinguishable from "the merge broke everything".

What it printed

Merging #567 on the WSL office box, on a main that did not yet carry the platform-aware Godot lookup (#573), so probe.py resolved a C:/… path that cannot exist here:

``` Godot console exe not found at C:/Tools/Godot/Godot_v4.7.1-stable_mono_win64/…_console.exe (set GODOT_EXE) … ×34 ──── probe_all results ──── ──── 0 passed, 34 failed ──── ████ FAILING HERE, PASSING IN MAIN'S BASELINE ████ File it (not filed automatically — outward-facing): gh issue create -R cfsh/ninefold \ --title "main: 572692e regressed butterbar-gate chit-budget cold-start … tonapse-home" \ --body "probe_gate on main @ 572692e. Full sweep: 0 passed, 34 failed." ```

A paste-ready issue blaming an innocent merge for regressing all 34 probes, with the real cause — no engine — printed 34 times immediately above it and nowhere in the diagnosis. The only thing that stopped the shared baseline being overwritten with "every probe on main is broken" was #567's own platform stamp, which is unrelated luck: on a Windows box whose Godot install had moved, the platform would have matched and it would have recorded.

Why the existing guard misses it

parse_sweep's finished flag is the guard, and it was hardened twice — #412 item 5 (a failed dotnet build reading as an empty sweep) and #520 F1 (a crashed probe_all exiting 1 like a normal failure). Both work because those states produce no results table or a non-1 exit code.

A missing engine produces neither symptom. probe.py:143-147 prints its diagnostic and return 1 — the same code as "a probe step failed" — so probe_all records an ordinary FAIL for every probe, emits a full table, and exits 1. Every downstream check is satisfied: table present ✓, exit 1 ✓, finished true ✓. The diff then compares a real baseline against an all-failed set and every entry reads as NEW.

⚠ The tell is *in* the data and unused: 0 passed. A sweep where literally nothing passed is far more likely to be a broken environment than 34 simultaneous regressions.

Fix shapes
Why it matters more now

Before #566 this could only happen on the one box that had Godot installed and configured, so "the engine is missing" was close to unreachable. Now any Linux box can run the merge gate, notes/machines.md documents a multi-step Godot install, and a zipfile-extracted engine without its exec bit is a documented state (#573 F3). The environment being wrong is now an ordinary condition, not an exotic one — and #389's whole lesson is that a gate reporting confidently about something it did not measure is worse than no gate.

Related: #412 item 5 and #520 F1 (the two guards this sits beside), #572 / #579 (real Linux probe divergence, which this class of false report would drown), #580 (baseline recording), #573 (the Godot lookup whose absence triggered it).

Unclaimed.

Dependencies

None.

Comments

No comments.

Add a comment