feat(shared-root): S3 — configurable shared-root resolver with load-bearing override test
One call-time resolver (env PORTFOLIO_SHARED_ROOT, default the in-repo shared/) consumed by both MAF-side readers of the shared core: persona._example_path() (the _EXAMPLE_PATH monkeypatch seam is kept) and simulation._default_bundle_dir() (replaces the _BUNDLE_DIR module global). De-risks the S4 extraction: re-pointing the commons becomes an env var, not a code change. Override test proves the marker follows a tmp copy of the whole shared tree; both detach points proven RED. Suite 155->157. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AaQCFnfsh3tfq1VfzdJpoi
This commit is contained in:
parent
5de1c93b69
commit
cebba7d954
4 changed files with 110 additions and 15 deletions
|
|
@ -17,16 +17,20 @@ import json
|
|||
from dataclasses import dataclass
|
||||
from pathlib import Path
|
||||
|
||||
# Module-global so tests can monkeypatch it; read at CALL time inside the loader (never frozen into
|
||||
# a default argument), which is what makes the simulation's persona genuinely artifact-driven.
|
||||
_EXAMPLE_PATH = (
|
||||
Path(__file__).resolve().parents[2]
|
||||
/ "shared"
|
||||
/ "skills"
|
||||
/ "expert-reviewer"
|
||||
/ "references"
|
||||
/ "example-verdict.json"
|
||||
)
|
||||
from portfolio_optimiser.shared_root import shared_root
|
||||
|
||||
# Test seam: when set (monkeypatched), wins over the resolver. Read at CALL time inside the loader
|
||||
# (never frozen into a default argument), which is what makes the simulation's persona genuinely
|
||||
# artifact-driven.
|
||||
_EXAMPLE_PATH: Path | None = None
|
||||
|
||||
_EXAMPLE_SUBPATH = Path("skills") / "expert-reviewer" / "references" / "example-verdict.json"
|
||||
|
||||
|
||||
def _example_path() -> Path:
|
||||
"""The persona example's location: the test seam if set, else resolved under ``shared_root()``
|
||||
(env ``PORTFOLIO_SHARED_ROOT`` re-points it — the S4 extraction seam)."""
|
||||
return _EXAMPLE_PATH if _EXAMPLE_PATH is not None else shared_root() / _EXAMPLE_SUBPATH
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
|
|
@ -42,9 +46,9 @@ class PersonaExample:
|
|||
|
||||
def load_persona_example() -> PersonaExample:
|
||||
"""Read the persona's canonical example verdict. Fail-fast: a missing file raises
|
||||
``FileNotFoundError`` and a missing key raises ``KeyError`` (required input). Reads
|
||||
``_EXAMPLE_PATH`` at call time so the path is patchable."""
|
||||
data = json.loads(_EXAMPLE_PATH.read_text(encoding="utf-8"))
|
||||
``FileNotFoundError`` and a missing key raises ``KeyError`` (required input). Resolves the
|
||||
path at call time (``_example_path``) so both the test seam and the env override are live."""
|
||||
data = json.loads(_example_path().read_text(encoding="utf-8"))
|
||||
return PersonaExample(
|
||||
decision=data["decision"],
|
||||
rationale=data["rationale"],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue