Files
cc-ci/machine-docs/REVIEW-nixenv.md

6.1 KiB

REVIEW — phase nixenv (Adversary)

Phase plan: /srv/cc-ci/cc-ci-plan/plan-phase-nixenv-shared-runtime-env.md SSOT for verification. Verdicts below; cold-runs only.

Status: M1 PASS @ 2026-06-17T17:40Z (claim 8b8fc1f). M2 gated behind, not yet claimed.


M1 — PASS @ 2026-06-17T17:40Z — claim 8b8fc1f

Single-source harness runtime env — cold-verified, all 6 DoD items. Verdict formed from the phase plan (SSOT), the code, and my OWN cold builds/evals — JOURNAL-nixenv.md NOT consulted (anti-anchoring preserved).

  1. Builds succeed, both hosts (no collision). nix build .?submodules=1#…cc-ci-hetzner…toplevel → EXIT 0; …#…cc-ci…toplevel → EXIT 0. (A transient SQLite eval-cache "busy" from running both in parallel was error (ignored), not a build failure.)
  2. Single source (greps). withPackages → 1 hit (packages.nix:17 ccciPyEnv); pytest playwright → 1 hit (same line); ccciRuntimeTools defined once (packages.nix:45), referenced by cc-ci-run (:68) + both host configs. nightly-sweep.nix has NO withPackages, NO python3, NO /run/current-system/sw/bin PATH prepend — runtimeInputs = [ pkgs.cc-ci-run ] and exec cc-ci-run …. The DEFECT-3 host-PATH patch is GONE.
  3. Superset-or-equal — inspected the BUILT wrapper PATH. cc-ci-run store zxlx9jnylh7la5m48bsqb1wfm5l9r0bd export PATH carries all 15 store dirs: python3-3.12.8-env, abra-0.13.0-beta, docker-27.5.1, git-2.47.2, git-lfs-3.6.1, bash-5.2p37, coreutils-9.5, util-linux-2.39.4, curl-8.12.1, jq-1.7.1, gnused-4.9, gnugrep-3.11, gnutar-1.35, openssl-3.3.3, procps-4.0.4 — and ends :$PATH (PREPEND, inherited PATH retained → nothing from any path lost). Covers the full union of all 3 prior lists; git-lfs+openssl are the only additions. Nothing dropped.
  4. Sweep ≡ Drone entrypoint (parity by construction). Built cc-ci-nightly-sweep references the BYTE-IDENTICAL zxlx9jnylh7la5m48bsqb1wfm5l9r0bd-cc-ci-run; both hosts' pkgs.cc-ci-run resolve that SAME store path; .drone.yml:83 runs cc-ci-run runner/run_recipe_ci.py (host systemPackages wrapper = same path). Same store path ⇒ identical pyEnv + tooling + PLAYWRIGHT_BROWSERS_PATH on Drone path AND timer sweep.
  5. Host divergence removed. Both configuration.nix systemPackages lines are textually identical (pkgs.ccciRuntimeTools ++ [ pkgs.openssh ]). The pre-refactor cc-ci-vs-hetzner git-lfs one-off divergence (my prep flag #1) is ELIMINATED: built cc-ci toplevel sw/bin now contains git-lfs, openssl, script (util-linux) — tools it previously lacked. openssh correctly kept host-only (ssh client, not a recipe tool); it remains on both hosts so the Drone path's inherited PATH is unchanged for it.
  6. Future-dep propagation (by construction). ccciRuntimeTools is the lone definition; it feeds cc-ci-run.runtimeInputs (→ Drone path via .drone.yml, → sweep via exec cc-ci-run) AND both hosts' systemPackages (→ Drone runner host PATH). One edit to that list reaches every consumer. Proven structurally via the reference graph; no working-tree mutation needed.

No defects, no VETO. Faithful refactor — one shared definition, three references, DEFECT-3 class structurally eliminated. M2 (deploy via nixos-rebuild switch + live parity witness: gitea LFS roundtrip green under BOTH Drone path and a real timer fire) remains to be claimed/verified.


(prior) Cold-prep notes


Cold-prep — enumeration of the CURRENT (pre-refactor) declarations @ HEAD dd6712c

The M1 superset-or-equal proof must show the new shared set ⊇ the union of all of these. Captured from the code (SSOT), independent of any Builder narrative:

(A) nix/modules/harness.nixcc-ci-run (Drone entrypoint) runtimeInputs: pyEnv abra docker git coreutils util-linux

  • pyEnv = python3.withPackages [ pytest playwright ]
  • env: PLAYWRIGHT_BROWSERS_PATH=${playwright-driver.browsers}, PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1

(B) nix/modules/nightly-sweep.nix — sweep runtimeInputs: bash abra docker git curl jq gnused gnugrep gnutar coreutils util-linux procps

  • DUPLICATE pyEnv = python3.withPackages [ pytest playwright ]
  • same PLAYWRIGHT env
  • DEFECT-3 patch: export PATH="/run/current-system/sw/bin:/run/wrappers/bin:$PATH" (host-PATH prepend)

(C) Drone runner path — nix/modules/drone-runner.nix: PATH = mkForce "/run/current-system/sw/bin:/run/wrappers/bin" → recipe shell-outs resolve from host environment.systemPackages, NOT a runtimeInputs list.

(D) Host systemPackages (feeds C):

  • nix/hosts/cc-ci/configuration.nix: curl git jq opensshNO git-lfs
  • nix/hosts/cc-ci-hetzner/configuration.nix: curl git git-lfs jq openssh

UNION the shared set must cover (≥):

python3+pytest+playwright (pyEnv) · playwright browsers · abra docker git git-lfs coreutils util-linux bash curl jq gnused gnugrep gnutar procps openssh Plan §2 also names openssl as a recipe shell-out → expect it present too.

Pre-noted suspicions to break on M1/M2 (cold, not yet verdicts):

  1. Host divergence: cc-ci config lacks git-lfs but hetzner has it. Which config is the LIVE ssh cc-ci server running, and does git-lfs actually resolve there today? If the shared set is applied to both host configs, cc-ci should GAIN git-lfs. Verify both configs end identical.
  2. Nothing dropped: any token in the union missing from the shared set = blast-radius break.
  3. Sweep parity by construction: plan wants sweep to invoke cc-ci-run (same entrypoint) — if it instead keeps a parallel list, "single source" is not actually achieved; grep must prove no module declares its own harness dep list.
  4. DEFECT-3 patch removal: the host-PATH prepend should be gone/subsumed; if removed, git-lfs etc. must now come from the shared runtimeInputs, else the sweep regresses.
  5. Live witness: gitea test_lfs_roundtrip must stay GREEN under BOTH Drone path and a real timer fire from the unified env.