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:
Kjell Tore Guttormsen 2026-07-03 01:10:05 +02:00
commit cebba7d954
4 changed files with 110 additions and 15 deletions

View file

@ -38,12 +38,19 @@ from agent_framework_openai import OpenAIChatCompletionClient
from portfolio_optimiser.persona import load_persona_example
from portfolio_optimiser.run import RunResult, run_project
from portfolio_optimiser.shared_root import shared_root
from portfolio_optimiser.validator import ValidatedProposal
from portfolio_optimiser.verdicts import VerdictStore, promote_verdict, seed_store_from_bundle
_BUNDLE_DIR = Path(__file__).resolve().parents[2] / "shared" / "examples" / "bygg-energi-mikro"
_PROJECT_ID = "BYGG-KONTOR-NORD"
def _default_bundle_dir() -> Path:
"""The demo bundle under the shared core, resolved at CALL time via ``shared_root()`` (env
``PORTFOLIO_SHARED_ROOT`` re-points it the S4 extraction seam)."""
return shared_root() / "examples" / "bygg-energi-mikro"
# A VALID SavingsProposal for BYGG-KONTOR-NORD: total = 300000 x 1.0, P90 = 0.30 x 300000 = 90000,
# claimed 30000 <= 90000 -> validates on the first attempt (no `assumptions` -> degenerate MC).
_VALID_PROPOSAL = (
@ -246,7 +253,7 @@ def main(argv: list[str] | None = None) -> int: # pragma: no cover - console tr
import tempfile
work = tempfile.mkdtemp(prefix="po-sim-")
result = asyncio.run(simulate_learning_loop(str(_BUNDLE_DIR), work))
result = asyncio.run(simulate_learning_loop(str(_default_bundle_dir()), work))
print("=" * 78)
print("OFFLINE SIMULATION — scripted agent replies, NO real model.")