feat(4a): wheelen bærer shared/ som pakkede data — arbeidstreet er overstyringen
README:24 sa det rett ut: shared/ ble lest fra arbeidstreet ved kjøretid, og
derfor kunne repoet verken publiseres som wheel eller kjøre i container. Målt
før endringen: 1.0.0-wheelen bar 58 filer, null under shared/.
Endringen er én søm + én pakkelinje:
- hatchling force-include speiler shared/ byte-identisk til
portfolio_optimiser/_shared/ (wheel 122 filer, 64 under _shared/; sdist
bærer treet, målt via uv build sdist→wheel)
- shared_root() løser ved kall-tid: PORTFOLIO_SHARED_ROOT → arbeidstreets
shared/ når det finnes (en checkout er autoritativ — det holder pull-only-
subtree-kontrakten og goldenene urørt) → pakket kopi
Iron Law fulgt: tests/test_shared_packaged_data_loadbearing.py skrevet FØRST,
alle tre røde mot dagens kode (ordnings-testen felt av sin egen kontroll på at
pakket kopi finnes). Deretter fiks, deretter MÅLT mutasjon mot hele suiten:
- detach fallbacken → 1 rød (resolusjons-testen)
- detach force-include → 3 røde
- snu rekkefølgen (pakket før arbeidstre) → 1 rød (ordnings-testen, som var
grønn før fiksen — flip-mutasjonen er beviset på at den diskriminerer)
Kontroll grønn: 813 passed / 4 skipped (baseline 810/4 målt på 142bfa9 samme
økt). Goldenene byte-uendret før og etter (shasum -c på demo-transkript +
begge nav-goldens). shared/ selv er urørt.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018hfm6sWTk17Cbh6ZHYhvCu
This commit is contained in:
parent
142bfa9666
commit
f5ec8c84f6
5 changed files with 238 additions and 13 deletions
|
|
@ -1,10 +1,15 @@
|
|||
"""Resolver for the location of the shared framework-neutral core (S3, R1-forberedelse).
|
||||
"""Resolver for the location of the shared framework-neutral core (S3, R1-forberedelse; 4a pakket).
|
||||
|
||||
``shared/`` is today an in-repo directory, but is slated for extraction into its own commons repo
|
||||
(R1/S4). Every MAF-side runtime consumer (``persona``, ``simulation``) resolves its location through
|
||||
this ONE seam so the extraction is a re-point (env var), not a code change. Test fixtures pointing at
|
||||
the real in-repo bundle hardcode the path deliberately — they must not be redirected by a production
|
||||
env var. Pure stdlib — the shared core itself stays framework-free.
|
||||
``shared/`` is a pull-only subtree of the commons repo at the repository root. Every MAF-side
|
||||
runtime consumer (``persona``, ``simulation``) resolves its location through this ONE seam, so a
|
||||
re-point is an env var, not a code change. Since Fase 4a the wheel also carries a byte-identical
|
||||
mirror of the tree as packaged data (``portfolio_optimiser/_shared/``, hatchling force-include in
|
||||
pyproject.toml), so an installed distribution — and a container built from it — works without a
|
||||
checkout. Resolution order at CALL time: explicit env override → the working tree's ``shared/``
|
||||
when present (a repo checkout stays authoritative, which is what keeps the subtree contract and
|
||||
the byte-level goldens untouched) → the packaged copy. Test fixtures pointing at the real in-repo
|
||||
bundle hardcode the path deliberately — they must not be redirected by a production env var. Pure
|
||||
stdlib — the shared core itself stays framework-free.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
|
@ -14,12 +19,20 @@ from pathlib import Path
|
|||
|
||||
ENV_VAR = "PORTFOLIO_SHARED_ROOT"
|
||||
|
||||
_DEFAULT = Path(__file__).resolve().parents[2] / "shared"
|
||||
_WORKTREE = Path(__file__).resolve().parents[2] / "shared"
|
||||
_PACKAGED = Path(__file__).resolve().parent / "_shared"
|
||||
|
||||
|
||||
def shared_root() -> Path:
|
||||
"""Resolve the shared-core root at CALL time: ``PORTFOLIO_SHARED_ROOT`` if set (non-empty),
|
||||
else the in-repo default. The call-time read is what keeps the override testable and the S4
|
||||
extraction re-pointable without touching consumers."""
|
||||
else the working tree's ``shared/`` when it exists (a checkout), else the packaged copy
|
||||
shipped inside the distribution. The call-time read is what keeps the override testable and
|
||||
the ordering observable; when neither directory exists the packaged path is returned so the
|
||||
consumer's own fail-fast names the installed distribution's gap, not a checkout that was
|
||||
never there."""
|
||||
override = os.environ.get(ENV_VAR)
|
||||
return Path(override) if override else _DEFAULT
|
||||
if override:
|
||||
return Path(override)
|
||||
if _WORKTREE.is_dir():
|
||||
return _WORKTREE
|
||||
return _PACKAGED
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue