fix(paths): de-absolute truths — REPO_ROOT placeholder normalization — dichotomy wave

The frozen corpus recorded the FREEZE-TIME checkout's absolute paths
(repo_root -> /mnt/workdrive/rune-wave-bd, crate_dir ->
/mnt/workdrive/rune-wave-bd/src/rust/<name>), so the battery failed in
every other checkout (6 subtests). Same law applied backward in repair:
absolute paths must never enter frozen truth.

- gen_paths_truth.py: derivation rows frozen REPO-RELATIVE
  ({REPO_ROOT}, {REPO_ROOT}/src/rust/<name>).
- truth_test.go: expandExpect substitutes the CURRENT root at replay
  time and FAILS any derivation row that carries a raw absolute path
  (the law is now self-enforcing).
- tests/test_paths_port.py: oracle replay substitutes identically +
  asserts the placeholder law on the corpus itself; shape test updated
  for the paths.go/phaseb.go split.

Verified: gofmt/vet/go test green in THIS worktree AND from a scratch
checkout at a different root (placeholder substitution proof); pytest
4/4, ruff clean.
This commit is contained in:
Nick committed 2026-10-13 12:39:15 +01:00
1 parent 3b89972227
commit 19a0638abd
4 files changed
+78 -20

No files matched your search

+21 -6
View File
@@ -9,7 +9,15 @@ SET (override), since env-reading is a branch.
HOME is ALWAYS frozen to a concrete value per row: expanduser-bearing
defaults ($HOME/.rune) must replay byte-stably in Go, which has no
pwd-module fallback for an unset HOME. Output: src/go/paths/truth.json
pwd-module fallback for an unset HOME.
MACHINE-BOUND LAW (no absolute paths in frozen truth): outputs derived
from the FREEZE-TIME repo root (repo_root, crate_dir) are recorded as
REPO-RELATIVE paths ("{REPO_ROOT}" for the root itself,
"{REPO_ROOT}/src/rust/<name>" for crates). Replay sides substitute the
placeholder with their CURRENT repo root before comparing. Everything
else (env overrides, compile-time defaults) is already absolute-safe.
Output: src/go/paths/truth.json
"""
from __future__ import annotations
@@ -37,13 +45,18 @@ def case(fn: str, name: str, args: dict, env: dict):
# HOME always concrete (see module docstring).
if frozen_env["HOME"] is None:
frozen_env["HOME"] = os.environ.get("HOME")
# Neutralize the freeze-time checkout: the oracle's repo_root is a
# machine-bound absolute path; the corpus records it REPO-RELATIVE.
freeze_root = paths.repo_root()
saved = {k: os.environ.pop(k, None) for k in ENV_KEYS}
try:
os.environ.update({k: v for k, v in frozen_env.items() if v is not None})
if fn == "repo_root":
expect = paths.repo_root()
expect = "{REPO_ROOT}"
elif fn == "crate_dir":
expect = paths.crate_dir(**copy.deepcopy(args))
full = paths.crate_dir(**copy.deepcopy(args))
assert full.startswith(freeze_root + "/"), full
expect = "{REPO_ROOT}" + full[len(freeze_root):]
elif fn == "deploy_root":
expect = paths.deploy_root()
elif fn == "rune_home":
@@ -100,9 +113,11 @@ doc = {
"frozen_ts": "2026-10-13T06:15:00Z",
"generator": "scripts/gen_paths_truth.py",
"note": "HOME is frozen per row so expanduser-bearing defaults "
"(rune_home) replay byte-stably in both languages; the Go "
"battery sets the row env verbatim and compares against the "
"frozen oracle output.",
"(rune_home) replay byte-stably in both languages; "
"freeze-time repo-root outputs are recorded REPO-RELATIVE "
"({REPO_ROOT} placeholder) — replay sides substitute their "
"CURRENT root. The Go battery sets the row env verbatim and "
"compares against the substituted oracle output.",
"cases": cases,
}
OUT.parent.mkdir(parents=True, exist_ok=True)
+7 -7
View File
@@ -2,7 +2,7 @@
"module": "paths",
"frozen_ts": "2026-10-13T06:15:00Z",
"generator": "scripts/gen_paths_truth.py",
"note": "HOME is frozen per row so expanduser-bearing defaults (rune_home) replay byte-stably in both languages; the Go battery sets the row env verbatim and compares against the frozen oracle output.",
"note": "HOME is frozen per row so expanduser-bearing defaults (rune_home) replay byte-stably in both languages; freeze-time repo-root outputs are recorded REPO-RELATIVE ({REPO_ROOT} placeholder) \u2014 replay sides substitute their CURRENT root. The Go battery sets the row env verbatim and compares against the substituted oracle output.",
"cases": [
{
"fn": "repo_root",
@@ -15,7 +15,7 @@
"RUNE_WR_CODE": null,
"HOME": "/home/nick"
},
"expect": "/mnt/workdrive/rune-wave-bd"
"expect": "{REPO_ROOT}"
},
{
"fn": "crate_dir",
@@ -30,7 +30,7 @@
"RUNE_WR_CODE": null,
"HOME": "/home/nick"
},
"expect": "/mnt/workdrive/rune-wave-bd/src/rust/evidence_provenance"
"expect": "{REPO_ROOT}/src/rust/evidence_provenance"
},
{
"fn": "crate_dir",
@@ -45,7 +45,7 @@
"RUNE_WR_CODE": null,
"HOME": "/home/nick"
},
"expect": "/mnt/workdrive/rune-wave-bd/src/rust/outcome_utility"
"expect": "{REPO_ROOT}/src/rust/outcome_utility"
},
{
"fn": "crate_dir",
@@ -60,7 +60,7 @@
"RUNE_WR_CODE": null,
"HOME": "/home/nick"
},
"expect": "/mnt/workdrive/rune-wave-bd/src/rust/memory_types"
"expect": "{REPO_ROOT}/src/rust/memory_types"
},
{
"fn": "crate_dir",
@@ -75,7 +75,7 @@
"RUNE_WR_CODE": null,
"HOME": "/home/nick"
},
"expect": "/mnt/workdrive/rune-wave-bd/src/rust/paths"
"expect": "{REPO_ROOT}/src/rust/paths"
},
{
"fn": "crate_dir",
@@ -90,7 +90,7 @@
"RUNE_WR_CODE": null,
"HOME": "/home/nick"
},
"expect": "/mnt/workdrive/rune-wave-bd/src/rust/a/b/c"
"expect": "{REPO_ROOT}/src/rust/a/b/c"
},
{
"fn": "deploy_root",
+25 -2
View File
@@ -5,10 +5,16 @@ package main
// with the env matrix frozen per row, HOME pinned) VERBATIM. Every row
// sets its frozen env, calls the Go port, and byte-compares against the
// frozen oracle output.
//
// MACHINE-BOUND LAW: repo-root-derived rows are recorded REPO-RELATIVE
// ("{REPO_ROOT}" placeholder); expandExpect substitutes the CURRENT
// checkout's root before comparing, so the battery passes in ANY
// checkout. Absolute paths must never enter frozen truth.
import (
"encoding/json"
"os"
"strings"
"testing"
)
@@ -63,6 +69,22 @@ func applyRowEnv(t *testing.T, env map[string]*string) {
}
}
// expandExpect — substitute the {REPO_ROOT} placeholder with the
// CURRENT checkout's root (fails the test if a derivation row carries a
// raw absolute path — that is a frozen-truth-law violation).
func expandExpect(t *testing.T, row TruthRow) string {
t.Helper()
if strings.HasPrefix(row.Expect, "{REPO_ROOT}") {
return RepoRoot() + strings.TrimPrefix(row.Expect, "{REPO_ROOT}")
}
if row.Fn == "repo_root" || row.Fn == "crate_dir" {
t.Fatalf("%s (%s): frozen expect %q is a raw absolute path — "+
"derivation rows must use the {REPO_ROOT} placeholder",
row.Fn, row.Name, row.Expect)
}
return row.Expect
}
func TestFrozenTruthReplaysVerbatim(t *testing.T) {
doc := loadTruth(t)
for _, row := range doc.Rows {
@@ -86,9 +108,10 @@ func TestFrozenTruthReplaysVerbatim(t *testing.T) {
default:
t.Fatalf("unknown frozen fn %q", row.Fn)
}
if got != row.Expect {
want := expandExpect(t, row)
if got != want {
t.Fatalf("%s (%s): got %q, want frozen oracle %q",
row.Fn, row.Name, got, row.Expect)
row.Fn, row.Name, got, want)
}
})
}
+25 -5
View File
@@ -69,13 +69,30 @@ def _apply_env(env):
os.environ[k] = v
def _expand_expect(row):
"""Substitute the {REPO_ROOT} placeholder with the CURRENT checkout's
root (mirrors expandExpect in truth_test.go)."""
expect = row["expect"]
if expect.startswith("{REPO_ROOT}"):
return paths.repo_root() + expect[len("{REPO_ROOT}"):]
if row["fn"] in ("repo_root", "crate_dir"):
raise AssertionError(
f"{row['name']}: frozen expect {expect!r} is a raw absolute "
"path — derivation rows must use the {REPO_ROOT} placeholder")
return expect
def test_frozen_truth_replays_verbatim_oracle(frozen_env):
for row in TRUTH["cases"]:
a = copy.deepcopy(row["args"])
_apply_env(row["env"])
got = CALLABLES[row["fn"]](a)
want = row["expect"]
want = _expand_expect(row)
assert got == want, f"{row['name']}: {got!r} != {want!r}"
# the placeholder law itself: no derivation row may carry an absolute
for row in TRUTH["cases"]:
if row["fn"] in ("repo_root", "crate_dir"):
assert row["expect"].startswith("{REPO_ROOT}"), row
def test_go_battery_replays_same_corpus(frozen_env):
@@ -88,12 +105,15 @@ def test_go_battery_replays_same_corpus(frozen_env):
def test_go_module_shape_name_preserving():
"""Every public Python symbol has a Go counterpart."""
"""Every public Python symbol has a Go counterpart (paths.go carries
the derivation pair + constant; phaseb.go the env resolvers)."""
main_go = (ROOT / "src" / "go" / "paths" / "paths.go").read_text()
for go_symbol in ("func RepoRoot(", "func CrateDir(", "func DeployRoot(",
"func RuneHome(", "func HarnessScripts(",
"func WaitResumeDir(", "RepoRootPath"):
phaseb_go = (ROOT / "src" / "go" / "paths" / "phaseb.go").read_text()
for go_symbol in ("func RepoRoot(", "func CrateDir(", "RepoRootPath"):
assert go_symbol in main_go, f"missing Go counterpart: {go_symbol}"
for go_symbol in ("func DeployRoot(", "func RuneHome(",
"func HarnessScripts(", "func WaitResumeDir("):
assert go_symbol in phaseb_go, f"missing Go counterpart: {go_symbol}"
def test_corpus_covers_every_public_function_and_branch():