portfolio-optimiser-claude/docs/2026-07-25-d-a-amendment-forslag.md
Kjell Tore Guttormsen 457a0f4e91 docs(portfolio): D-A approved in full — D7's proposed amendment text with measured anchors
The operator approved the whole D-A bundle on 2026-07-25: the four spec
corrections (C-F2/C-F3/C-F4/C-F5), brief §7 (the projection contract over the
ledger), and the C-P1 collision resolved by RE-SCOPING semantic retrieval
rather than amending the frozen "structural, never textual" rule.

This is D7's contribution to the text, not the decision itself (that is
protocolled in the main repo's shared queue) and not the amendment (shared/ is
a PULL-ONLY subtree — the text must land in commons and be pulled by both
siblings). Each point carries the verbatim spec anchor it changes, proposed
RFC 2119 wording, and what we MEASURED about compatibility rather than what we
assume.

Two things are stated as open rather than settled, because they are:
- A2 (cost baseline): the golden bundle has no cost-baseline.json, so an
  unconditional requirement would change the fasit bytes for both stacks. Our
  wording requires a baseline only for runs that can spend; if the amendment
  chooses otherwise, the fasit change must be planned in both repos.
- A5 (rounding): the divergence is live — our monetary figures are unrounded,
  MAF rounds one. The proposed rule lands on our current behaviour, which is
  exactly why it cannot be decided here. Neither side patches unilaterally.

Code anchors re-verified against the working tree this session (the ledger fix
earlier today shifted valuereport line numbers), not copied from STATE.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01MQu2xxwedckjU56byu1aUG
2026-07-25 15:38:51 +02:00

8.5 KiB
Raw Blame History

D-A-bolken — godkjent 2026-07-25, forslag til amendment-tekst (D7-siden)

Hva dette er: operatøren godkjente 2026-07-25 HELE D-A-bolken som én amendment — de fire spec-rettelsene (C-F2/C-F3/C-F4/C-F5), brief-§7 (projeksjons-kontrakten over hovedboken), og C-P1-kollisjonen løst ved re-scoping (ikke ved å amendere det frosne §3 Steg 1-prinsippet). Dette dokumentet er D7-repoets bidrag til teksten: spec-anker, foreslått normativ ordlyd, og hva vi har MÅLT om kompatibilitet.

Hva dette IKKE er: beslutningen selv. Den protokollføres i hovedrepoets delte kø. shared/ er en PULL-ONLY subtree — amendment-teksten kan ikke committes herfra; den må landes i commons og hentes av BEGGE søsken. Ordlyden under er et forslag, ikke en vedtatt tekst.

0. Prosedyre (uendret mal)

amendment i commons → koordinert git subtree pull i BEGGE repo (samme commons-commit) → begge suiter grønne → deretter én byggsesjon per punkt, failing test først (§11). Ingen av søsknene retter ensidig — heller ikke rundingen i A5, som er en LIVE divergens.

A1 — Validator: den nominale grensen må gate (C-F2 → sesjon C2.7)

Anker: §3 Steg 4 pkt. 2 beregner «maximum feasible saving ... 0.30 × Σ quantity·unit_cost», men pkt. 4 blokkerer KUN over p90. §7.1 har ingen invariant som binder usikkerhetsbåndet til unit_cost, og båndet forfattes av modellen selv.

Foreslått ordlyd (to tillegg):

  • §3 Steg 4, nytt pkt.: «A claim above nominal_feasible MUST yield the same distinct rejection type as pkt. 4, regardless of the percentiles. The structural block is evaluated against BOTH bounds; the deterministic bound is never advisory.»
  • §7.1, ny IR-invariant: «When an item carries an uncertainty band, low ≤ unit_cost ≤ high MUST hold; a band that excludes the unit cost is a schema violation, not an input.»

Kompatibilitet (målt på D7-siden, ikke antatt — review-2026-07.md §1 C-F2): golden-claim 30 000 ≤ nominal 90 000 (passerer); alle ikke-tomme bånd i repoets fixtures omslutter unit_cost ([0.8,1.2]∋1.0 · [0.70,1.40]∋1.0 · (0.70,1.50)∋1.0; resten tomme). Verken fasit-eksemplet eller eksisterende testdata brytes.

A2 — Kostbaseline: claim må avstemmes mot noe utenfor modellens egne tall (C-F3 → C4.0)

Anker: ingenting i bundle-formatet bærer en kostbaseline. §3 Steg 4 pkt. 1 regner kun på selv-deklarerte linjer, så en diktet kostlinje passerer validering (kjørt bevis: XX-DIKTET, 1e6 × 10 → claim 2,9 MNOK stemplet validated).

Foreslått ordlyd: «A bundle MAY carry a cost baseline projection (cost-baseline.json). When present, every affected_items code MUST reconcile against it, fail-closed: an unknown code or a quantity above the baseline's is a rejection of the same distinct type as §3 Steg 4 pkt. 4. A run that calls a model MUST have a baseline — a bundle without one MUST be refused at startup (§10), never run unreconciled.»

Åpent underspørsmål amendmenten MÅ svare på: skal baselinen være obligatorisk for ALLE kjøringer, eller kun for kjøringer som kan bruke penger? Vårt forslag er formulert som det siste, med vilje: fasit-bundelen (shared/examples/bygg-energi-mikro/) har ingen cost-baseline.json, så et ubetinget krav ville endret fasit-bytene og dermed §7-fasiten for begge stacker. Feilscenarioet C-F3 beskriver er dessuten live-stien. Velger amendmenten likevel «obligatorisk overalt», må fasit-endringen planlegges eksplisitt i begge repo.

A3 — Ledende / i OKF-lenker skal forstås, ikke hoppes over (C-F4 → C2.8)

Anker (verbatim, §3 Steg 1): «Targets containing a path separator are out-of-bundle and MUST be skipped.» OKF-spec-en anbefaler bundle-rot-relativ /-form — spec-en er altså spec-tro implementert mot en spec-feil.

Foreslått ordlyd: «A target with a LEADING / is bundle-root-relative and MUST be resolved against the bundle root. Any other path separator remains out-of-bundle and MUST be skipped. Resolution stays boundary-checked against the bundle directory, fail-closed — the leading slash changes the base, never the boundary.»

Merknad til hovedrepoet: MAF-planen har i dag ingen byggsesjon for F4-implementasjonen på sin side; den bør legges til når D-A lander, ellers divergerer stackene på et punkt amendmenten nettopp harmoniserer.

A4 — Seeding må nøkles på dommens EGNE features (C-F5 → C3.2, folder inn R-8)

Anker (verbatim, §3 Steg 1): «Seeding: every type: verdict file in the bundle becomes a store entry keyed on those candidate features» — «those» er bundelens ENE IR-projeksjon, så dommer om ulike tiltak får identisk nøkkel.

Foreslått ordlyd: «A seeded verdict MUST be keyed on ITS OWN candidate features when its frontmatter carries them (the promotion gate, §6, writes them); the bundle's IR projection is the fallback for hand-authored seeds that do not. Two verdicts about different candidates MUST NOT share a retrieval key.»

Nyanse (D7-målt): id-halvdelen av MAFs F5-funn er allerede løst her — verdict_id leses verbatim fra frontmatter, load-bearing-bevist. Det er feature-halvdelen som står igjen.

A5 — Projeksjons-kontrakten over hovedboken (brief-§7 — meldt uavhengig fra BEGGE stacker)

Anker: ingen. Method-spec-en nevner ikke hovedbok eller verdirapport i det hele tatt (verifisert: 0 treff på «ledger»). Spec-en sier hva som skal produseres, ikke hva en projeksjon over resultatene må garantere — derfor traff begge søsken samme hull samme døgn og måtte ta samme tre skjønnsvalg.

Formen vi foreslår: kontrakten bindes til projeksjonens ARITMETIKK og fullstendighet, ikke til hovedbokens filformat. Det holder brief pkt. 6 åpen (formatene forblir stack-lokale til en eventuell konvergens via verktøykassa) og lukker likevel divergensen som gjør «samme kapabilitet» forenlig med ulike totaler på identiske inndata.

Foreslått ordlyd (tre regler, én per skjønnsvalg):

  1. Runding: «Monetary figures MUST NOT be rounded in the projection — neither per row nor on the total. Rounding is a rendering concern and MUST NOT change a persisted figure. Derived non-monetary ratios MAY be rounded, at a fixed documented precision.»
  2. Null kvalifiserende rader: «A report MUST be produced even when no row qualifies. Every figure the expert layer has not supplied MUST be UNMARKED (null), never 0 — a zero that means "unjudged" is a false claim (§1).»
  3. Renhet: «The projection MUST NOT restate provenance fields. It is a view over the layers it reads; provenance is asserted once, by the run that produced it (§9).»

Divergensen er live, ikke uenighet: vi runder ingen kronebeløp (kun deriverte andeler, 6 siffer — _SHARE_DIGITS, valuereport.py:61); MAF runder ett monetært beløp. Regel 1 slik den er formulert lander på D7s nåværende oppførsel, og det er nettopp derfor den ikke kan vedtas herfra — begge sider venter på amendmenten, ingen patcher unilateralt. Regel 2 og 3 er allerede D7s oppførsel (_corrected, valuereport.py:182-194: pending og adjusted_unquantified gir None, aldri 0 — og rejected gir 0.0 fordi NULL er dommen, ikke et fravær av den; report_payload, valuereport.py:424) og pkt. 3 er også MAFs valg.

A6 — C-P1: semantisk henting re-scopes (INGEN spec-endring)

Anker (verbatim, §3 Steg 1): «Ranking is structural, never textual — surface text MUST NOT contribute to similarity.» Den delte D-C-planen (cosine over tekst) kolliderer direkte.

Vedtatt retning: re-scoping, ikke amendment. Det frosne prinsippet består; semantisk henting bygges på strukturelle kjennetegn alene. Konsekvens for planene i begge repo: rad 13 (K17) forblir GATED på D-C, men gaten er nå «D-C re-scopet», ikke «D-C som skrevet».

Verifisering (hvordan vi vet at bolken faktisk har landet)

  1. Commons har amendment-commiten; BEGGE repo har hentet SAMME commit (git log shared/ viser samme squash-hash i begge).
  2. Begge suiter grønne rett etter pull, FØR noen byggsesjon starter — amendmenten alene skal ikke rødne noe (den utvider spec-en; A1s stramming er målt kompatibel, A2s valg avgjør om fasit må endres).
  3. Deretter én sesjon per punkt, failing test først: C2.7 (A1) · C4.0 (A2) · C2.8 (A3) · C3.2 (A4) · verdirapport-kontrakten (A5, treffer K11-koden her).
  4. A5 er ikke ferdig før BEGGE stacker produserer samme total på identiske inndata — det er testen som beviser at divergensen faktisk er lukket, ikke at ordlyden finnes.