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
This commit is contained in:
Kjell Tore Guttormsen 2026-07-25 15:38:51 +02:00
commit 457a0f4e91

View file

@ -0,0 +1,135 @@
# 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.