fix(gate): add nix to the pytests check β 10 handle tests could not run in the sandbox - #290
Merged
Merged
Conversation
β¦un in the sandbox scripts/tests/test_opencode_config.py's `nix_eval()` shells out to `nix-instantiate --eval` to pin the GENERATED handle values from nix/agent-handles.nix, and calls pytest.fail() β NOT skip β when the binary is absent, deliberately: 'a skip here is how a wrong kubeconfig path ships'. `nix` was not in the check's nativeBuildInputs, so all 10 test_handles_resolve_to_the_exact_expected_paths[...] cases failed in the nix sandbox and passed on every dev host. This was INVISIBLE until #289: it hid behind the gate being red for an unrelated reason. Its sibling defect is the exact complement β session_insight's test_patterns_cover_bash_guard fails only where ~/.claude/hooks/bash-guard.py is DEPLOYED and skips in the sandbox. Both came from #276. MEASURED, not predicted (the pure-eval argument was a prediction; this is the check's own output): scripts/tests before collected=959 passed=949 failed=10 scripts/tests after collected=959 passed=959 failed=0 TOTAL collected=4353 passed=4351 skipped=2 failed=0 skips pinned 2, observed 2 nodetests files=14 tests=468 pass=468 fail=0 nix flake check all checks passed Identical collected count with failures to zero β the 10 PASS rather than merely stopping to fail. The 10-failure diagnosis was confirmed first by a positive control on a dev host: stripping PATH to python alone reproduced exactly '10 failed, 455 passed' in that file. COST, stated as deliberately as the nodejs one above it: +30 store paths, 22 of them the nix closure (nix-{util,store,expr,main,flake,fetchers,cmd} incl. -dev outputs, plus boost and libarchive), and a nixpkgs bump moving `nix` now invalidates this check's cache β the same trade already accepted for nodejs. Bought: 10 tests that structurally cannot run without it, pinning that the handles every agent shell exports resolve to exact paths. Rejected DEVHOST_TARGETS as the alternative: it keeps the closure small but weakens the pin to 'runs only where someone remembers to run it', which is the failure mode this whole area keeps hitting. Also adds nix-instantiate to REQUIRED_TOOLS so a missing binary is ONE named precondition failure instead of 10 unexplained assertion failures deep in the run β that guard's entire purpose. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Contributor
Author
Also green on the merged tree with #291Beyond this PR's own green ( Both PRs touch So the two are safe to land in either order as a pair; on current |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
nix flake checkis green end to end with this. Third and last of the three regressions #276 shipped.The bug
scripts/tests/test_opencode_config.py'snix_eval()shells out tonix-instantiate --evalto pin the generated handle values fromnix/agent-handles.nix, and callspytest.fail()β not skip β when the binary is absent. That is deliberate and correct:nixwas not in thepytestscheck'snativeBuildInputs, so all 10test_handles_resolve_to_the_exact_expected_paths[...]cases failed in the nix sandbox and passed on every dev host.It was invisible until #289 β it hid behind the gate being red for an unrelated reason. Its sibling is the exact complement:
session_insight'stest_patterns_cover_bash_guardfails only where~/.claude/hooks/bash-guard.pyis deployed, and skips in the sandbox. So #276's three regressions each concealed the others; that lesson is in #287.Measured, not predicted
I argued in review that
agent-handles.nixis{ home }: {β¦}with no nixpkgs import and no fetch, so--evalis a pure evaluation needing no daemon, network or store realisation. That was a prediction. This is the check's own output:scripts/testsbeforescripts/testsafterIdentical collected count with failures to zero β the 10 pass, they did not merely stop running. That was the distinction asked for, and a count is the only thing that shows it: a target that is accepted but not executed looks the same from outside.
The diagnosis was confirmed by a positive control first, on a dev host: running that file with
PATHstripped to python alone reproduced exactly10 failed, 455 passed, naming the same 10 tests.Cost, stated as deliberately as the
nodejsparagraph above itnixclosure βnix-{util,store,expr,main,flake,fetchers,cmd}including-devoutputs, plusboostandlibarchive.nixnow invalidates this check's build cache β the same trade already accepted fornodejs.Bought: 10 tests that structurally cannot run without it, pinning that the handles every agent shell exports (
$DEVRC,$HOMELAB,$KC_*, β¦) resolve to the exact expected paths.Rejected alternative β
DEVHOST_TARGETS. It keeps the closure small, but weakens the pin to "runs only where someone remembers to run it", which is precisely the failure mode this whole area keeps hitting. Preserving fail-not-skip was the point.Also
nix-instantiateadded toREQUIRED_TOOLS, so a missing binary becomes one named precondition failure rather than 10 unexplained assertion failures deep in the run β that guard's entire purpose. It binds the pre-push tier too, which is safe here: both hosts are NixOS.Scope
Branched off
88eb6d0, not stacked on anything β it touchesflake.nixwhere #289 touchedrun-tests.sh. Deliberate: stacking buys nothing for orthogonal changes and carries thegh pr merge --delete-branchhazard that auto-closes a child PR GitHub then refuses to reopen.Process note
The wrapper around this run reported exit 0 for the pipeline while the meaningful status lived in the log β
$?read the trailingecho. Every number above is read from the build log, not from an exit status. Same class as therc=$?case documented in #287.π€ Generated with Claude Code