Forrige commit skrev en CLAUDE.md-invariant om at en betalt test far sin egen
opt-in, men gatet bare den NYE testen. test_portfolio_live.py passerer ingen
client_factory og er derfor selv en betalt kjoring - den fyrte pa
to-variabel-paret fra et bart `uv run pytest`. Invarianten var altsa halvt
usann den dagen den ble skrevet, som er nyaktig Fase 3-klassen (en pastand
flaten gjor om seg selv uten dekning).
MALT etter fiksen, med begge Foundry-vars satt og UTEN PORTFOLIO_LIVE_FULL_RUN:
test_foundry_profile_live PASSED (det billige trinnet, med vilje pa to vars)
test_portfolio_live SKIPPED (var betalt og ugatet for dette)
test_full_run_live SKIPPED
Ovrige oppfolgingspunkter fra review:
- assert_full_run_contract far ekte type hints (repoets "type hints overalt";
mypy src ser ikke tests/, sa den ville rotnet ubemerket).
- Maleprotokollen SS6 far oppsettet STATE peker pa - model-map-formen og de fire
export-linjene. Pekeren lovet noe seksjonen ikke hadde.
869 passed / 5 skipped, uendret. ruff+format+mypy rene.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GF7va4cpRiuf79kTzAi3vW
Fase 1b siste trinn: forste bundne levende kjoring over HELE run_project-stien
mot Foundry (gpt-4-1-mini). Okt 37s uttalte aerlighets-grense er lukket ved
maling: ingen -parse-failures.json i outboksen, altsa parset hvert eneste
genererings-svar. assumptions-normaliseringen virket ende-til-ende.
Utfall: rejected pa P90 (claimed 34500 > feasible 11488), checker approve.
Kjoringen KONKLUDERTE - per pre-registreringen det bestatte utfallet. De to
falsifisererne skilte lag for forste gang mot en levende modell.
FUNN storre enn den gronne testen: modellen fant opp kostkoden
EL-LIGHTING-OP-HR (null treff i kunnskapsbasen). Avvisningen var riktig men
skjedde pa 30%-cap-en, ikke stage 0 - bundelen shipper ingen cost-baseline.json,
sa S4.0-forankringen var inaktiv. Ko-fort, ikke rettet her.
Gate-designet er ovis beslutning, tatt for koding:
- TREDJE distinkt opt-in PORTFOLIO_LIVE_FULL_RUN (truthiness, 4b-invarianten).
Begge eksisterende live-tester gater pa SAMME to Foundry-variabler, sa
gjenbruk ville latt den billige proben fyre den dyre kjoringen - stigen i
maleprotokollen ville kollapset til ett trinn. MALT: den dyre SKIPPET med
begge Foundry-variablene satt.
- Asserten i EN kopi (conftest.assert_full_run_contract, ko-(p)), smal med
vilje: fravaer av parse-failures-artefaktet + at validatoren avgjorde. En
rejected BESTAR - pastanden er schema-aksept, ikke modell-dommekraft.
- Iron Law uten a betale to ganger: diskrimineringen bevist OFFLINE av
test_live_full_run_contract.py. To mutasjoner, hver sin signatur: detach
artefakt-sjekken (T1 rod ALENE) - raise ubetinget (T2 rod ALENE).
STATE-premiss korrigert: "test_foundry_profile_live dekker KUN klient-nivaet"
var upresist - test_portfolio_live.py dekket allerede fan-outen, men dens
len(runs)==1 kan ikke skille validert fra avvist og bar derfor ikke pastanden.
869 passed / 5 skipped (fra 867/4), ruff+format+mypy rene.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GF7va4cpRiuf79kTzAi3vW
Every stage of validate_proposal reasoned only about numbers the proposal itself
supplied, so an internally-consistent hallucination cleared the whole gate (F3).
A new stage 0 reconciles each affected_item against the project's CostBaseline
before the CBC solve: an unknown cost code is rejected, and a real code carrying
a quantity/unit_cost outside the configured tolerance (5% default, relative to
the baseline value) is rejected. Validation, never repair.
The baseline argument is OPTIONAL (None = pre-S4.0 behaviour), but both run
paths set it: the road path projects project.cost_items, the bundle path loads
cost-baseline.json when the bundle ships one. Bundles written before the
amendment stay un-anchored, so the commons-owned goldens run byte-identically;
a baseline that exists but is malformed still raises on both loaders.
F8: the method-specific cap now comes from the METHOD_CAPS registry (measure
type -> fraction, injectable) instead of an energy_efficiency string comparison.
The baseline format and tolerance semantics were decided locally — the commons
amendment (D-A pt. 2) never arrived, exactly as in S3.2. D7 mirroring stays open.
Three portfolio fixtures quoted cost codes belonging to OTHER projects; the new
gate caught them. They now quote each project's own lines, and the two copied
REPLIES tables import the single source instead of drifting from it.
Load-bearing measured (tests/test_s40_cost_baseline_loadbearing.py), six
mutations all red: detach the reconciliation stage; detach the magnitude
tolerance; detach the road wiring; detach the bundle wiring; ignore the injected
cap registry; make the optional loader tolerant of malformed content. Control:
with the road wiring detached the repaired portfolio fixtures still pass, so
they are not masking the seam. 597 -> 612 tests.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JdwK7bQ4BZkWH4t8MRDKb4
Closes maalbilde §5 gap #1 (the one missing "feedback-into-prompt" dataflow)
for the OKF-bundle path. Before, ExpeL was computed AFTER generation into a
discarded SessionContext, so a prior verdict could not influence any hypothesis
(context_providers=0).
- New okf.py: framework-neutral OKF bundle navigation (index + frontmatter +
cross-links), pure stdlib, no agent_framework/mcp (D7-portable), enforced by
test_okf_is_maf_free.
- verdicts.py: seed_store_from_bundle + bundle_candidate_features build the
ExpeL substrate + the pre-hypothesis query key from a bundle.
- run_project(bundle_dir=...): folds the candidate's prior verdicts into the
generation context BEFORE generate_via_llm; the road path is unchanged.
Load-bearing (maalbilde §7): test_step1_expel_loadbearing proves a prior verdict
reaches the hypothesis prompt and goes RED when the fold is detached (shown via
TDD red->green). The marker is the minted verdict id (content hash) because
docs_dir==bundle_dir lets keyword chunk-stuffing leak the realization rate;
clean layer separation is Fase 2b.
Suite 121->133 passed; mypy + ruff check clean.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MHR8iKxJRxDiDfNw8HZmWE