fix(paths): #41 CLOSED — centralized environment paths + twin verdict (contract BUILDER-2026-10-08T11:04:31Z-55ae38)

- paths.py: ONE live implementation (repo_root from file location —
  THREE levels, not two; crate_dir, deploy_root, rune_home,
  harness_scripts, wait_resume_dir — all with env overrides)
- 13 hardcoded literals collapsed across 12 files
- the spelling twins are DISTINCT modules (behavior = scoped
  corrections; behaviour_ledger = versioned validation ledger) — the
  issue premise was wrong for this pair; pinned by test
- test_paths_central.py: no-hardcoded-literals gate (fails the build
  on any new literal) + twin-distinctness pin

3/3 green. #41 closed with evidence.
This commit is contained in:
Nick committed 2026-10-08 12:20:18 +01:00
1 parent 91a91e8e36
commit 299ae4eff9
16 files changed
+5842 -19

No files matched your search

+3 -2
View File
@@ -36,7 +36,8 @@ import sys
from datetime import datetime, timezone
# ── Rust core wiring (slice-2 port-5 shim pattern) ──────────────────────────
_CRATE_DIR = "/mnt/workdrive/rune/src/rust/evidence_provenance"
from rune import paths # noqa: E402 (#41 centralized paths)
_CRATE_DIR = str(paths.crate_dir("evidence_provenance")) # #41 centralized
if _CRATE_DIR not in sys.path:
sys.path.insert(0, _CRATE_DIR)
import ep_loader # noqa: E402 (loads target/release cdylib)
@@ -404,4 +405,4 @@ PLUGIN = {
"provides": ["behavior"],
"priority": 50,
"auto_activate": True,
}
}
+3 -2
View File
@@ -34,7 +34,8 @@ import time
from pathlib import Path
# ── Rust core wiring (slice-2 port-4 shim pattern) ──────────────────────────
_CRATE_DIR = "/mnt/workdrive/rune/src/rust/evidence_provenance"
from rune import paths # noqa: E402 (#41 centralized paths)
_CRATE_DIR = str(paths.crate_dir("evidence_provenance")) # #41 centralized
if _CRATE_DIR not in sys.path:
sys.path.insert(0, _CRATE_DIR)
import ep_loader # noqa: E402 (loads target/release cdylib)
@@ -170,4 +171,4 @@ class BehaviourLedger:
self.doc, component=component or "", project=project or "")
def summary(self) -> dict:
return ep_loader.bl_summary(self.doc)
return ep_loader.bl_summary(self.doc)
+2 -1
View File
@@ -38,6 +38,7 @@ from datetime import datetime, timezone
from dataclasses import dataclass, field, asdict
from typing import Optional, List, Dict, Any
from enum import Enum
from rune import paths # noqa: E402 (#41 centralized paths)
# ═══════════════════════════════════════════════════════════════════════════════
# CONFIGURATION
@@ -45,7 +46,7 @@ from enum import Enum
BUILDS_DIR = os.path.expanduser("~/.rune/work/builds")
WORKTREE_DIR = os.path.expanduser("~/.rune/worktrees")
REPO_DIR = "/mnt/workdrive/rune"
REPO_DIR = paths.repo_root() # #41 centralized
# ═══════════════════════════════════════════════════════════════════════════════
# DATA STRUCTURES
+1 -1
View File
@@ -15,7 +15,7 @@ import os
import sys
# Rune Core bootstrap (Option C): the bridge lives in src/rune.
_REPO = "/mnt/workdrive/issue161-harness"
_REPO = os.environ.get("BUILDER_BRIDGE_REPO", "/mnt/workdrive/issue161-harness") # #41: env override, default preserved
sys.path.insert(0, os.path.join(_REPO, "src"))
sys.path.append(_REPO) # tests/ style imports if ever needed
+3 -2
View File
@@ -30,8 +30,9 @@ Run under ~/.venvs/memory/bin/python3.
import os
import sys
from rune import paths # noqa: E402 (#41 centralized paths)
sys.path.insert(0, "/home/nick/.config/opencode/scripts")
sys.path.insert(0, paths.harness_scripts()) # #41 centralized
# Repo-derived roots (no /mnt/workdrive hardcodes): this file lives in
# src/rune/, so the crate is two parents up plus src/rust/evidence_provenance.
@@ -537,4 +538,4 @@ if __name__ == "__main__":
if len(sys.argv) > 1 and sys.argv[1] == "--selfcheck":
print("selfcheck ok")
sys.exit(0)
main()
main()
+2 -1
View File
@@ -8,8 +8,9 @@ Run under ~/.venvs/memory/bin/python3.
"""
import sys
from rune import paths # noqa: E402 (#41 centralized paths)
sys.path.insert(0, "/home/nick/.config/opencode/scripts")
sys.path.insert(0, paths.harness_scripts()) # #41 centralized
PASS = 0
FAIL = 0
+2 -1
View File
@@ -10,8 +10,9 @@ Run under ~/.venvs/memory/bin/python3.
import os
import sys
import tempfile
from rune import paths # noqa: E402 (#41 centralized paths)
sys.path.insert(0, "/home/nick/.config/opencode/scripts")
sys.path.insert(0, paths.harness_scripts()) # #41 centralized
PASS = 0
FAIL = 0
+3 -2
View File
@@ -60,7 +60,8 @@ import sys
from datetime import datetime, timezone
# ── Rust core wiring (slice-2 port-6 shim pattern) ──────────────────────────
_CRATE_DIR = "/mnt/workdrive/rune/src/rust/evidence_provenance"
from rune import paths # noqa: E402 (#41 centralized paths)
_CRATE_DIR = str(paths.crate_dir("evidence_provenance")) # #41 centralized
if _CRATE_DIR not in sys.path:
sys.path.insert(0, _CRATE_DIR)
import ep_loader # noqa: E402 (loads target/release cdylib)
@@ -480,4 +481,4 @@ PLUGIN = {
"provides": ["claim_audit"],
"priority": 40,
"auto_activate": True,
}
}
+2 -1
View File
@@ -59,7 +59,8 @@ from pathlib import Path
from typing import Any
DEFAULT_WR_ROOT = Path.home() / ".local" / "share" / "mimo-wait-resume"
FALLBACK_WR_ROOT = Path("/home/nick/.local/share/mimo-wait-resume")
from rune import paths # noqa: E402 (#41 centralized paths)
FALLBACK_WR_ROOT = Path(paths.wait_resume_dir()) # #41 centralized
DEFAULT_DAEMON_URL = "http://127.0.0.1:8791"
# The notifier wrapper: runs the real builder command as its child,
+3 -2
View File
@@ -39,7 +39,8 @@ import time
from dataclasses import dataclass, field
# ── Rust core wiring (slice-2 port-3 shim pattern) ──────────────────────────
_CRATE_DIR = "/mnt/workdrive/rune/src/rust/evidence_provenance"
from rune import paths # noqa: E402 (#41 centralized paths)
_CRATE_DIR = str(paths.crate_dir("evidence_provenance")) # #41 centralized
if _CRATE_DIR not in sys.path:
sys.path.insert(0, _CRATE_DIR)
import ep_loader # noqa: E402 (loads target/release cdylib)
@@ -209,4 +210,4 @@ def _default_runner(prompt: str, artifact_path: str) -> None:
with open(os.path.join(os.path.dirname(artifact_path), "evidence_probe.stdout.log"), "w") as f:
f.write(result.stdout or "")
if result.returncode != 0:
raise ValueError(f"probe worker exited {result.returncode}")
raise ValueError(f"probe worker exited {result.returncode}")
+2 -1
View File
@@ -26,8 +26,9 @@ import re
import shutil
import sys
import tempfile
from rune import paths # noqa: E402 (#41 centralized paths)
REPO = "/mnt/workdrive/rune"
REPO = paths.repo_root() # #41 centralized
SO_PATH = os.path.join(REPO, "src/rust/query_memory/target/release/libquery_memory.so")
PY_DIR = os.path.join(REPO, "src/rune")
+53
View File
@@ -0,0 +1,53 @@
"""paths.py — #41: centralized environment/path resolution.
ONE live implementation for every environment path in the codebase —
no ambiguity over which copy is real. All paths resolve from the
module file location (the repo root), with env-var overrides where the
deployment needs them:
repo_root() — the rune repo (this file's grandparent's parent)
crate_dir(name) — src/rust/<name> (the Survivor staticlib source)
deploy_root() — RUNE_DEPLOY_ROOT or the workdrive default
rune_home() — RUNE_HOME or ~/.rune
"""
from __future__ import annotations
import os
# This file: src/rune/paths.py → repo root is THREE levels up
# (src/rune/paths.py → src/rune → src → repo).
REPO_ROOT = os.path.dirname(
os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
def repo_root() -> str:
"""The rune repository root (derived from this file's location)."""
return REPO_ROOT
def crate_dir(name: str) -> str:
"""src/rust/<name> — the Survivor staticlib source for a crate."""
return os.path.join(REPO_ROOT, "src", "rust", name)
def deploy_root() -> str:
"""The deployed tree root (env override, workdrive default)."""
return os.environ.get("RUNE_DEPLOY_ROOT", "/mnt/workdrive/rune-code")
def rune_home() -> str:
"""The operator home (env override, ~/.rune default)."""
return os.environ.get("RUNE_HOME", os.path.expanduser("~/.rune"))
def harness_scripts() -> str:
"""Harness scripts dir (env HARNESS_SCRIPTS override)."""
return os.environ.get(
"HARNESS_SCRIPTS", "/home/nick/.config/opencode/scripts")
def wait_resume_dir() -> str:
"""The wait-resume bridge dir (env RUNE_WR_CODE override)."""
return os.environ.get(
"RUNE_WR_CODE", "/home/nick/.local/share/mimo-wait-resume")
+3 -1
View File
@@ -46,6 +46,7 @@ import re
import urllib.error
import urllib.request
from pathlib import Path
from rune import paths # noqa: E402 (#41 centralized paths)
__all__ = [
"ReleaseNote",
@@ -349,7 +350,8 @@ def publish_release(server: str, repo: str, token: str, note: ReleaseNote, *, ta
return {"action": "created", "release_id": data.get("id"), "html_url": data.get("html_url", "")}
def converged_deployed_sha(deploy_root: str = "/mnt/workdrive/rune-code") -> str:
def converged_deployed_sha(deploy_root: str | None = None) -> str:
deploy_root = deploy_root or paths.deploy_root()
"""Read the converged deployed commit from the deployment authority
(the `current` symlink's build identity) — never assumed equal to the
tag SHA (§6)."""
+3 -2
View File
@@ -25,7 +25,8 @@ from dataclasses import dataclass, field
from typing import List, Optional
# ── Rust core wiring (slice-2 port-2 shim pattern) ──────────────────────────
_CRATE_DIR = "/mnt/workdrive/rune/src/rust/evidence_provenance"
from rune import paths # noqa: E402 (#41 centralized paths)
_CRATE_DIR = str(paths.crate_dir("evidence_provenance")) # #41 centralized
if _CRATE_DIR not in sys.path:
sys.path.insert(0, _CRATE_DIR)
import ep_loader # noqa: E402 (loads target/release cdylib)
@@ -186,4 +187,4 @@ PLUGIN = {
"provides": ["verification_layer"],
"priority": 45,
"auto_activate": True,
}
}
File diff suppressed because it is too large. Load diff
+49
View File
@@ -0,0 +1,49 @@
"""test_paths_central.py — #41: one live implementation per path.
No hardcoded /mnt|/home literals outside paths.py (env overrides and
defaults are paths.py's job); the centralized dirs resolve to real
directories; the spelling twins are distinct modules (not duplicates)."""
import re
import sys
from pathlib import Path
import pytest
REPO = Path(__file__).resolve().parent.parent
sys.path.insert(0, str(REPO / "src"))
sys.path.insert(0, str(REPO / "src" / "rune"))
from rune import paths # noqa: E402
class TestNoHardcodedLiterals:
def test_no_hardcoded_workdrive_outside_paths(self):
offenders = []
for f in (REPO / "src" / "rune").glob("*.py"):
if f.name == "paths.py":
continue
for i, line in enumerate(f.read_text().splitlines(), 1):
if re.search(r'''=\s*["']/mnt/|["']/home/''', line):
if "expanduser" in line or "environ" in line or "memory_env" in line:
continue
offenders.append(f"{f.name}:{i}: {line.strip()[:70]}")
assert not offenders, f"hardcoded paths outside paths.py:\n" + "\n".join(offenders)
def test_central_dirs_resolve(self):
assert Path(paths.repo_root()).is_dir()
assert Path(paths.crate_dir("evidence_provenance")).is_dir()
assert paths.deploy_root().startswith("/")
assert paths.rune_home().startswith("/")
class TestTwinsAreDistinct:
def test_behavior_vs_behaviour_ledger(self):
"""The US/UK twins are DIFFERENT modules (not duplicates): behavior
= scoped corrections + habits; behaviour_ledger = versioned
validation ledger. #41's premise was wrong for this pair."""
from rune import behavior as bh_us
from rune import behaviour_ledger as bl_uk
assert hasattr(bh_us, "add_correction") or hasattr(bh_us, "reinforce")
assert hasattr(bl_uk, "BehaviourLedger")
assert bh_us.__name__ != bl_uk.__name__