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
pkt.2 — coverage gap (green-but-dead): link_in_index preserves the existing
index byte-for-byte and in order on the SUCCESS path by construction, but
nothing asserted it. Byte-equality was checked only on the REFUSAL path
(test_step8_promotion_loadbearing.py Test A); other tests check mere line
MEMBERSHIP. A writer that kept every link but reordered/rewrote the existing
body would pass the whole suite — the exact ingest-spec §6 / Step-8 promotion
invariant we rely on (promoted verdict links survive re-ingest byte-for-byte).
New test uses deliberately non-sorted existing links; proven load-bearing (a
temporary `sorted()` reorder mutation flips it RED, then reverted). Test-only,
no production change.
pkt.4 — shared_root.py docstring overclaimed "Every MAF-side consumer resolves
through this ONE seam". Verified: both runtime consumers (persona, simulation)
do route through shared_root(); the 15 test modules hardcode the in-repo
fixture path deliberately (a test needing the real fixture must not be
redirected by a production env var). Scoped the claim to "runtime consumer"
rather than churning 15 test files to make a false claim true.
Full suite 415 passed, ruff + mypy clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HVHLJuwBzp7MXkrUXJYARS
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