portfolio-optimiser/docs/2026-09-08-n-bundlene-hypoteseform.md
Kjell Tore Guttormsen 4f23fa2a70 docs(n-bundlene): P4 -- one free N100 run after the P3 fix, (b') is now yes
The live N100 arm without --require-cost-baseline lands the model on the
fasit concept: req_number ("Krav 3.3.1--13") is cited verbatim in 6 of 6
replies, and it is the correct concept, not a stray one. N100 reaches
po's own "ferdig" bar for the first time in this measurement series.
[skip-docs]
2026-09-08 17:31:07 +02:00

40 KiB
Raw Blame History

N100, N200 og N500 re-målt i hypoteseform — det nye utdraget bærer nøkkelen, og po dropper den

Ordre 20260908T134013Z-2103630340-from-.claude (P2). P1 (docs/2026-09-08-n-bundlene-konsum.md, e7ffe9e+a26e8f2) fant at pre-passets utdrag leverte text uten title/req_number, så kravnummeret spørsmålet stiller fantes ikke noe sted i modellens kontekst. llm-ingestion-okf lukket det (17c49fc, c95d189 — HEAD 171798e, treet rent), vegnormal-okf re-bygde de tre bundlene med proveniens (feae0c8, V2-treet). Denne målingen re-kjører de tre armene mot det nye utdraget, med --require-cost-baseline (operatørvalg D-3), og dømmer etter den NYE «ferdig»-definisjonen (operatørvalg 08.09 12:20, D-1: po er ikke et oppslagsverktøy).

Utdraget bærer nå nøkkelen — 14 medlemmer, var 9. Modellen fikk den likevel ikke: po dropper feltene TO ganger, ved parsing og ved rendering. Funnet har byttet eier, fra okf til po.


0. Hva som ER målt, og hva som IKKE er det

MÅLT. Tre nye tre-hasher reprodusert ordrett fra vegnormal-okfs V2-melding. okf.navigate_bundle når 446 / 1 133 / 270 konsepter, 0 ufulgte lenker. Fasit-konseptet på rang 1 av 8 på alle tre, med den flaggløse kommandoen. Utdragets medlemsliste: 14, med title, req_number, sources, source_element_id, source_sha256. Kontraktsjekk exit 0 × 3, 15 regler, 0 funn. prepass.admit_payload OK × 3. Klientproben grønn. --require-cost-baseline nektet alle tre, rc 1, 0 modellkall — på full kjøresti, ikke bare dry-run. --derive-cost-baseline nektet også, alle tre. Tre betalte armer uten flagget, rc 0 × 3, NOK 0,22 av taket 5, 0 × 429. Hva som nådde prompten, felt for felt. Hvert modellsvar ordrett.

IKKE MÅLT. Én kjøring er én kjøring — tre armer, ett spørsmål hver, én modell (gpt-4-1-mini), ett deployment, ingen gjentakelse. Ingenting her sier noe om varians, og P1 og P2 er to trekk fra samme modell på nesten samme input: at N100 gikk fra rejected (P1) til validated (P2) og N200 motsatt vei er ikke tilskrevet noen årsak. At en ANNEN modell ville lest kuttet annerledes er ikke målt. Ingen av bundlene er faglig gjennomgått — sammenlikningen er mot konseptkroppen, ikke mot vegnormalen.

IKKE RØRT. Ingen fil under src/. Ingen Azure-konfig. Ingen fil i vegnormal-okf eller i noen okf-checkout. Ingen push.


1. Kjent-positiv per bundle, FØR noe ble betalt

OKF=~/repos/llm-ingestion-okf              # HEAD 171798e, `git status --short` TOMT
B=~/repos/vegnormal-okf/build/ferdig       # feae0c8 (V2)
$OKF/.venv/bin/python3 $OKF/tools/okf_consume.py $B/n100-2023 \
  --question "Hva krever Krav 3.3.1—13 i N100? Gjengi det sentrale vilkåret." --out payload-n100.json
$OKF/.venv/bin/python3 $OKF/tools/okf_skill.py  $B/n100-2023 --out skill-n100
$OKF/.venv/bin/python3 $OKF/tools/okf_contract_check.py --skill skill-n100/SKILL.md --payload payload-n100.json
# ... tilsvarende for n200-2024 og n500-2024, DEFAULT-kommandoen, ingen flagg
kjent-positiv N100:2023 N200:2024 N500:2024
sha256-tree reproduserer V2s ref JA da6b8204… JA c64f36b7… JA 673a0c2c…
okf.navigate_bundle → konsepter 446 (fasit 446) 1 133 (fasit 1 133) 270 (fasit 270)
Bundle.skipped (ufulgte lenker) 0 0 0
considered / withheld / delivered 446 / 438 / 8 1 133 / 1 125 / 8 270 / 262 / 8
budsjett brukt av 120 000 11 868 23 961 11 941
fasit-konseptets rang 1 av 8 1 av 8 1 av 8
okf_contract_check exit 0, 15 regler, 0 funn exit 0, 15 regler, 0 funn exit 0, 15 regler, 0 funn
prepass.admit_payload mot montert base OK OK OK
klientprobe test_foundry_profile_live 1 passed — kjørt FØR armene (samme kjøring) (samme kjøring)

Budsjettforbruket er høyere enn P1s (11 868 mot 8 939 · 23 961 mot 21 102 · 11 941 mot 9 085) — forventet, og det er selve endringen: hvert utdrag bærer nå fem felt til. okfs egen melding målte +450,5 B per utdrag på et annet korpus; her er differansen +2 929 / +2 859 / +2 856 B over åtte utdrag, altså +366 / +357 / +357 B per utdrag.

Budsjett-instrumentets egen kjent-positiv flyttet, som okf varslet: expected 12 563 / raw_bytes 12 227 / encoding_delta 336 (var 10 349 / 10 060 / 289), og measured == expected på alle tre. En stale verdi ville fått pre-passet til å nekte — den høylytte feilen, ikke en defekt.

Utdragets medlemmer: 14, var 9. Ordren forventet ≥ 12.

adjudication · bundle_id · bundle_id_inherited · concept_id · rank · req_number · sha256
· source_element_id · source_sha256 · sources · text · text_sha256 · title · trust_tier

De fem nye er title, req_number, sources, source_element_id, source_sha256. (okfs melding målte 9 → 17 på K2; differansen er at K2 bærer fem source_*-lokatorer der N-bundlene bærer to — prefiks-regelen, ikke en allowlist.)

For N100s fasit-konsept:

title:             Krav 3.3.1—13 H1  Nasjonal hovedveg, ÅDT < 6 000 og fartsgrense 80 km/t
req_number:        Krav 3.3.1—13
sources:           [{resource: https://viewers.vegnorm.vegvesen.no/api/nisosts/859984?languageCode=nb,
                     title: N100:2023}]
source_element_id: id-4b61eee9-a149-42b3-863d-293b8320c15a
source_sha256:     c58e8bbc5fa9a5400c111e51b04c05f2cfd9edabd884ef5352a486fdab2cb5ab

Alt P1 etterlyste er der. Det er derfor resten av dette dokumentet handler om po.


2. --require-cost-baseline NEKTET alle tre — og nekten er gratis

Operatørvalg D-3. Flagget ble kjørt på full kjøresti, ikke bare dry-run, og nekten er ordrett:

run refused: this run was required to be anchored, but the knowledge base offers no cost baseline:
without one the validator's stage 0 (reconciling each proposed cost line against the project's own)
is skipped and nothing ties a proposed cost line to this project. Ship a cost-baseline.json, or pass
--derive-cost-baseline when the base carries a priced schedule
N100 N200 N500
--require-cost-baseline, full kjøring rc 1 rc 1 rc 1
modellkall før nekten 0 0 0
kontroll: samme argv UTEN flagget rc 0 rc 0 rc 0
cost-baseline.json i basen fraværende fraværende fraværende
--derive-cost-baseline (den andre døra nekten navngir) rc 1 rc 1 rc 1

Antallet modellkall asserteres, ikke exit-koden alene: en nekt etter forbruket ser identisk ut ved exit-koden (økt 57s regel). rc-0-kontrollen er der fordi en arm som bare kan bli rød ikke beviser noe.

Den andre dørens nekt er like presis, og den forklarer hvorfor det ikke finnes en tredje vei:

no cost table found in bundle '…/n100-2023': no concept file carries a markdown table whose header
names all three of ['code', 'quantity', 'unit_cost']

Målt konsekvens: det finnes ingen forankret form av en N-bundle-kjøring. En vegnormal er et kravkorpus, ikke et anbudskorpus — den bærer ingen kostlinjer i det hele tatt, og ingen av po sine tre baseline-projeksjoner (håndskrevet fil · baseline_from_project · derive_cost_baseline) kan lage én av den. F4-flagget gjør altså nøyaktig det det ble bygget for, og svaret er at N-bundlene ikke er kostnadskjøringer.

Derfor er de tre betalte armene kjørt UTEN flagget, og det er et uttalt avvik fra ordrens bokstav. Ordren ba om tre betalte armer MED flagget; med flagget koster de ingenting og produserer ingen modellsvar, altså heller ingen (a), (b), (c) eller (e). Nekten er rapportert som resultatet D-3 ba om (over), og armene som faktisk måler det nye utdraget er kjørt uten det. Det som ellers ville stått igjen, var en tom måling av den eneste tingen P2 finnes for.


3. Tre betalte armer

export PORTFOLIO_FOUNDRY_PROJECT_ENDPOINT=# utledet INLINE fra `az`, aldri i fil
export PORTFOLIO_FOUNDRY_DEPLOYMENT=gpt-4-1-mini
export PORTFOLIO_MODEL_MAP=scratchpad/major2-live/model_map.json
export PACE_SECONDS=2
uv run --with tiktoken python scratchpad/nbundler-p2/live_nbundler_p2.py {n100|n200|n500}
# argv: <N100|N200|N500> --profile azure --docs-dir <base> --bundle-dir <base>
#       --proposal-review --outbox-dir … --run-id p2-<tag>-free --prepass-payload payload-<tag>.json

Innsprutspunktet er run._default_factory (Fase 4e). Alle roller LEVENDE. Deployment urørt (az … deployment show): GlobalStandard, capacity 100, gpt-4.1-mini 2025-04-14, Succeeded.

N100 N200 N500
rc 0 0 0
prompter totalt 6 7 5
proposer / checker 5 / 1 6 / 1 4 / 1
prompt-tokens (o200k) 7 748 16 764 6 092
leverandør-input 12 217 25 877 9 619
leverandør-output 824 1 248 611
429-svar 0 0 0
parse-feil-artefakt fraværende TIL STEDE (1) fraværende
verktøykall i debatten 0 (A-form: verktøyene trukket) 0 0
validator-dom validated rejected (stage 4, P90) validated
dom-nøkkel c195117970ce86ef 70f3eb3540cd88f7 c9740904b1303f65
Steg 5 (reason matet tilbake) 2 prompter 2 prompter 1 prompt

Én parse-feil, på N200 — og filens tilstedeværelse ER signalet (økt 35). Den er ikke en formatfeil: modellen leverte gyldig JSON i riktig form, og det som falt var en DOMENE-invariant i SavingsProposal:

Value error, claimed saving 1500000.0 exceeds affected items' total 900000.0

Den avledede grammatikken (Fase 1b funn 1b) holdt altså på tre ferske korpora igjen; det som fanget denne var pydantics egen claimed <= total. Funn-1-fangsten (kaller-eid sink, finally) leverte teksten VERBATIM, som er hele grunnen til at setningen over kan siteres i det hele tatt.


4. Hovedfunnet: nøkkelen finnes nå, og po dropper den to ganger

P1s funn 1 var okfs. Det er lukket. Det som står igjen er po sitt, og det er to uavhengige tap på samme sti.

Tap 1 — ved PARSING. prepass.PrepassExcerpt arver _Permissive, som er ConfigDict(extra="ignore"). Payloadens 14 medlemmer blir til 7 i objektet po bygger:

>>> sorted(gold.model_dump())
['adjudication', 'bundle_id', 'concept_id', 'sha256', 'text', 'text_sha256', 'trust_tier']

title, req_number, sources, source_element_id og source_sha256 finnes ikke lenger.

Tap 2 — ved RENDERING. prepass._data_blocks renderer fire ting per utdrag: concept_id, adjudication, trust_tier og text. Selv om feltene hadde overlevd parsing, ville de ikke nådd prompten. DATA-blokka for fasit-konseptet, ORDRETT:

--- BEGIN DATA krav/N100/id-4b61eee9-a149-42b3-863d-293b8320c15a (adjudication: unknown, trust_tier: unverified) ---

## Krav

Eventuell kryssing mellom gang- og sykkelveg og veg skal være planskilt ved ÅDT > 4 000.
--- END DATA krav/N100/id-4b61eee9-a149-42b3-863d-293b8320c15a ---

En første måling av dette var KONFUNDERT, og ble felt før noe ble bygget på den. Et naivt delstreng-søk fant req_number i 2 av 6 prompter og source_element_id i 2 av 6 — begge falske: strengen Krav 3.3.1—13 står i prompten fordi den er en del av SPØRSMÅLET («cut computed for: Hva krever Krav 3.3.1—13 i N100?»), og id-4b61eee9-… fordi den er en delstreng av concept_id. Ingen av dem kommer fra utdragets nye felt. Det er repoets egen regel om at en assert aldri skal stå på en delstreng to grener deler, anvendt på en måling i stedet for en test.

når prompten faktisk? N100 N200 N500
utdragets text JA JA JA
concept_id (UUID-formet) JA JA JA
req_number som FELT NEI NEI NEI
title NEI NEI NEI
sources / resource-URL NEI NEI NEI
source_element_id som FELT NEI NEI NEI
source_sha256 NEI NEI NEI

Konsekvensen er direkte observerbar i modellens egne ord. N200s proposer skriver:

«…to optimize the geotechnical investigations and ground assessments already in the regulatory planning phase (as per the krav with ID 03418c46-ad07-4678-bae1-08f441f38903

Modellen siterer en UUID fordi UUID-en er den eneste identifikatoren den kan se — den står i DATA-avgrenseren. Kravnummeret, som er det et menneske ville sitert, er i payloaden og når aldri fram. Rangeringen finner riktig dokument, produsenten leverer nå nøkkelen, og konsumenten kaster den.


5. Målene (a)(e) + (b), med nevner

(a) Svarte modellen med det sentrale vilkåret i fasit-kravet?

N100 N200 N500
nøkkelord fra fasit-kroppen 3 av 3 (planskilt 13×, ÅDT 14×, 4 000 3×) 0 av 6 0 av 5
fasit-setningen ORDRETT 3 ganger 0 0
(a) JA NEI NEI

Uendret fra P1, og mekanismen er den samme, målt og ikke gjettet: modellen ble bedt om et kostnadsbesparende tiltak. På N100 ER fasit-kravet kostnadsformet (en terskel som lar deg sløyfe en dyr konstruksjon), så «svar på oppgaven» og «svar på spørsmålet» sammenfaller. På N200 og N500 gjør de det ikke, og modellen fulgte oppgaven den fikk — den resonnerte om grunnundersøkelser og om fjernstyrte bommer, begge fra ANDRE leverte konsepter i kuttet.

(b) Navnga modellen konseptet den bygde på?

Ordrens nye mål, og det som P2 finnes for.

N100 N200 N500
req_number ordrett i svaret 0 0 0
title ordrett 0 0 0
fasit-concept_id ordrett 0 0 0
source_element_id som EGET felt 0 0 0
resource-URL / nisosts 0 0 0
leverte konsepter navngitt i det hele tatt 0 av 8 1 av 8 (ikke fasit) 1 av 8 (ikke fasit)
(b) NEI NEI NEI

req_number er sitert 0 ganger i 18 modellsvar — og det kan den ikke være, siden feltet aldri nådde prompten (§ 4). (b) måler derfor po sin renderer, ikke modellens vilje: ingen implementasjon av modellen kunne bestått denne raden slik koden står.

Proveniens sitert: nei × 3. Verken source_element_id eller resource-URL-en forekommer i noe svar. Det er samme årsak.

(c) Hallusinerte den et kravnummer eller en verdi?

N100 N200 N500
kravnummer-formede tokens i svaret 0 0 0
tall i prosa som ikke er i delivered 0 0 0
konsept-id-referanser som ikke er levert 0 0 0
(c) 0 0 0

Ett treff undersøkt og forkastet som instrumentfeil: N100s 4,000 er modellens engelske tusenskille av det leverte 4 000. N200s og N500s tall-fragmenter (03418, 4678, 0000, 4715, …) er biter av ekte, leverte konsept-UUID-er som modellen skrev i prosa.

Kjent-negativ for instrumentet: første tall-regex fant 0 tokens i N200s og N500s prosa, altså kunne den ikke ha funnet en hallusinasjon heller. Den ble skjerpet til den fant de ekte tallene (N100 4 000 fra kroppen), og målingen over står på den skjerpede.

Det strukturerte FORSLAGET dikter fortsatt opp kostkoder, som i P1, og av samme strukturelle grunn (ingen baseline, og oppgaven krever et tall):

kode finnes i basen
N100 planskilt_kryssing 0 av 450 filer
N200 03418c46-ad07-4678-bae1-08f441f38903 2 av 1 137 — en EKTE konsept-id brukt som kostkode
N500 RCB01 0 av 274 filer

Forskjellen fra P1 er verdt å si: P1s 03423b12 var en oppdiktet identifikator formet som en ekte, og den ble VALIDERT. Denne gangen er ingen oppdiktet kode identifikator-formet — de to oppdiktede er generiske kostlinje-etiketter. Det er ikke en forbedring noen bygget; det er et annet trekk fra samme modell. Begge kjøringene ville vært nektet av --require-cost-baseline (§ 2), og det er den delen som ikke er et sammentreff.

(d) Kostnad

Listepris, Azure Retail Prices API (api-version=2023-01-01-preview, currencyCode='NOK', armRegionName=eastus), hentet på nytt 08.09, metere gpt 4.1 mini Inp/Outp glbl Tokens: input NOK 0,003734 / 1K, output NOK 0,014936 / 1K.

Kjøring Prompter Input Output NOK
N100 6 12 217 824 0,058
N200 7 25 877 1 248 0,115
N500 5 9 619 611 0,045
klientprobe 1 ~20 ~5 ~0,000
SUM 19 47 733 2 688 NOK 0,22

NOK 0,22 — 4,4 % av taket på NOK 5, og under ordrens tak på NOK 1. 429-svar: 0. De tre nekt-armene kostet NOK 0,00 (0 modellkall).

(e) Nevner-vokabularet

Ikke brukt i noen arm. [sourced-not-sufficient], [unread], [sourced], [inferred] og [unsupported] står 0 ganger i 18 modellsvar. Som i P1: alle tre armene FANT noe å foreslå i kuttet, så ingen var i posisjonen markøren finnes for. Det er en ubesvart nevner, ikke et bevis for at markøren ikke virker.


6. «Ferdig»-dommen, etter den NYE definisjonen

Operatørvalg 08.09 12:20 (D-1). Oppslagsspørsmålet «Hva krever Krav X?» er IKKE lenger po sitt kriterium — oppslag er Claude Code sin jobb via okf sin C1-oppskrift (llm-ingestion-okf/docs/2026-09-08-claude-code-skill-vilkaarlig-bundle.md, som måler fire spørsmål over to bundler med fire pass og null oppfunne tall). po sitt kriterium er hypoteseformen:

ferdig i po = (a) modellen bygger hypotesen på riktig fasit-konsept ELLER nekter forankret · (b) navngir konseptet · (c) 0 hallusinasjoner.

(a) (b) (c) ferdig
N100:2023 JA (fasit-setningen ordrett ×3) NEI 0 NEI
N200:2024 NEI NEI 0 NEI
N500:2024 NEI NEI 0 NEI

0 av 3 — og den bindende raden er nå (b), på alle tre.

Det er en annen situasjon enn P1s 0 av 3, og forskjellen er hele poenget:

  • P1: nøkkelen fantes ikke. For to av tre bundler var kravnummeret fraværende fra modellens kontekst i det hele tatt. Ingen konsument kunne gjort noe.
  • P2: nøkkelen finnes, og po kaster den. Alle tre payloadene bærer req_number, title og en hentbar resource-adresse. prepass.PrepassExcerpt ignorerer dem, og prepass._data_blocks renderer dem ikke. (b) er derfor ikke en modell-dom — det er en po-dom, og den kan ikke bli ja for noen modell før de to linjene endres.

Den andre halvdelen av (a) — «ELLER nekter forankret» — er verdt å lese nøyaktig: med --require-cost-baseline nekter alle tre (§ 2), men da finnes det ingen hypotese å navngi et konsept for, så (b) er umålbar og dommen ville vært ufullstendig snarere enn ja. En N-bundle kan ikke samtidig være forankret og produsere en hypotese, fordi et kravkorpus ikke bærer kostlinjer. Det er ikke en defekt i noen av de tre repoene; det er hva slags korpus en vegnormal er.

Hvem eier hva som mangler

llm-ingestion-okf eier ingenting her lenger. P1s funn 1 er lukket og verifisert i denne målingen: utdraget bærer title, req_number, sources, source_element_id og source_sha256, rangeringen står på rang 1 × 3, kontraktsjekken går exit 0 med 15 regler, og budsjett-instrumentets egen kjent-positiv er oppdatert i takt med at § 8 flyttet.

vegnormal-okf eier ingenting. V2-treet reproduserer sine egne hasher, nevnerne lukker, 0 ufulgte lenker × 3, og hvert konsept bærer en adresse okf kan bære videre.

portfolio-optimiser eier begge de gjenstående postene. (1) prepass-sømmen dropper fem felt to ganger. (2) Kjøreformen: A-formens oppgave er fortsatt hardkodet (run.py:1243) og --explore er fortsatt nektet med --prepass-payload — men etter D-1 er dét ikke lenger en mangel, det er en avgrensning operatøren har tatt stilling til.

Anbefaling til operatøren (beslutningen er din)

  1. La po bære utdragets nye felt gjennom til prompten. To linjer: navngi feltene på PrepassExcerpt (eller les dem via model_extra), og la _data_blocks sette req_number og title i DATA-avgrenseren ved siden av concept_id. Kostnaden er målt: +366 B per utdrag er allerede betalt i payloaden, og rendringen legger til titalls tegn per utdrag. Dette er det ENESTE som kan gjøre (b) nåbar, og det er en rød test og en søm — ikke en beslutning.
  2. Ikke gjør N-bundlene til kostnadskjøringer. --require-cost-baseline og --derive-cost-baseline nekter begge, målt, og grunnen er strukturell. Hvis en N-kjøring skal forankres, må baselinen komme fra prosjektet — ikke fra normalen.
  3. --require-cost-baseline bør fortsatt brukes på N-kjøringer der et TALL skal telle. Den nektet tre kjøringer som ellers ville stemplet validated over kostkoder som ikke finnes i noen base (§ 5c). Prisen er null.
  4. Etter (1) er kriteriet på nytt målbart for under NOK 0,25. Samme tre armer, samme spørsmål.

7. Funn — rapportert, ikke fikset

  1. po dropper utdragets nye felt to ganger (§ 4). Eier: po. PrepassExcerpt er extra="ignore"; _data_blocks renderer fire ting. Nevner: 5 av 14 medlemmer når aldri prompten, og req_number er sitert 0 ganger i 18 svar. Dette er (b)s eneste årsak.
  2. Ingen forankret form finnes for en N-bundle (§ 2). Eier: ingen — det er en egenskap ved korpustypen. Begge dørene nekter, målt, med rc-0-kontroll.
  3. To av tre validerte forslag bruker oppdiktede kostkoder (§ 5c). Eier: po (bruksmåte). planskilt_kryssing 0 av 450, RCB01 0 av 274. F4-flagget nekter dem, gratis.
  4. Én parse-feil på N200 (§ 3). Ikke en formatfeil — en domene-invariant i SavingsProposal (claimed 1 500 000 > total 900 000). Rapportert fordi P1 målte null på alle tre, og fordi artefaktets tilstedeværelse er signalet.
  5. Nevner-vokabularet ble ikke brukt i noen arm (§ 5e). Uendret fra P1, samme ubesvarte nevner.
  6. En delstreng-måling av «nådde feltet prompten» er konfundert (§ 4). Både req_number og source_element_id finnes i prompten av HELT andre grunner (spørsmålslinja og concept_id). Nevnt fordi neste måling vil gjøre samme feil om den ikke er skrevet ned.

8. Ærlighets-grenser, uttalt

  • Én kjøring er én kjøring. Tre armer, ett spørsmål hver, ingen gjentakelse, én modell. P1 og P2 er to trekk fra samme modell på nesten samme input, og de er UENIGE om utfallet på to av tre armer (N100 rejected → validated, N200 validated → rejected). Ingen årsak er tilskrevet; det er nettopp dét varians ser ut som når nevneren er 1.
  • (b) måler po, ikke modellen. Feltet når aldri prompten, så ingen modell kunne bestått raden. Å skåre den som en modell-svakhet ville vært å bruke definisjonen som gjemmeplass.
  • (a) på N100 er ikke bevis for at kjeden svarer på oppslag. Det er bevis for at fasit-teksten nådde modellen og ble brukt, og på N100 sammenfaller de to spørsmålene ved et sammentreff i kravets innhold. Sammentreffet er identifisert, ikke skjult — og etter D-1 er oppslag uansett ikke po sitt kriterium.
  • (c) = 0 gjelder svaret. Det strukturerte forslaget dikter opp kostkoder, som er strukturelt påkrevd i en uforankret kjøring. Skillet er uttalt i § 5c, ikke skjult av definisjonen.
  • AVVIK fra ordren, uttalt: de tre betalte armene er kjørt UTEN --require-cost-baseline. Med flagget koster de null og måler null (§ 2). Nekten er rapportert som D-3s resultat, og armene som måler det nye utdraget er kjørt uten det.
  • --cost-vocabulary, --k og --rarity-weight ble IKKE brukt. Fasit sto på rang 1 med default-kommandoen på alle tre, så betingelsen for opt-in-flaggene inntraff aldri.
  • Kuttet er verifisert mot den monterte basen (admit_payload × 3), så payloaden kan ikke ha levert bytes basen ikke holder. Det er en gate, ikke en tillitserklæring til produsenten.
  • Ingen av bundlene er faglig gjennomgått. Sammenlikningen i (a) er mot konseptkroppen slik den står, ikke mot vegnormalen.
  • sources-adressen er ikke hentet av po. vegnormal-okf målte at URL-en returnerer bytes som er bytelike med source_sha256; den målingen er deres, ikke gjentatt her.

9. Verifiseringslogg

# Påstand Slik den ble verifisert
1 okf HEAD 171798e, treet rent git -C ~/repos/llm-ingestion-okf log --oneline -1 + status --short (tom)
2 Tre V2-hasher reproduserer payload.bundle.ref mot vegnormal-okfs melding, 3 av 3 ordrett
3 446 / 1 133 / 270 konsepter, 0 skipped okf.navigate_bundle(...).context_files, po sin egen kode
4 Fasit på rang 1 × 3 indeks av fasit-id-en i payload.excerpts, flaggløs kommando
5 Utdraget har 14 medlemmer sorted(payload['excerpts'][0].keys()), 3 av 3
6 Kontraktsjekk exit 0 × 3 okf_contract_check.py --skill … --payload …, 15 regler, 0 funn
7 admit_payload OK × 3 prepass.admit_payload(p, bundle_dir=…, resolved_id=…)
8 Klientproben grønn uv run pytest tests/test_foundry_profile_live.py -q → 1 passed
9 Deployment urørt az … deployment show → GlobalStandard, 100, 2025-04-14
10 Flagget nekter × 3, 0 modellkall full kjøring, assert not records i måleskriptet, rc 1
11 rc-0-kontroll uten flagget samme argv uten --require-cost-baseline → rc 0, 3 av 3
12 --derive-cost-baseline nekter × 3 rc 1 + nekt-teksten navngir de tre påkrevde kolonnene
13 po dropper feltene ved parsing sorted(excerpt.model_dump()) → 7 nøkler; _Permissive er extra="ignore"
14 po dropper dem ved rendering prepass.render_context(...), DATA-blokka sitert ordrett
15 Delstreng-målingen var konfundert de to «treffene» lokalisert til spørsmålslinja og concept_id
16 (a) N100 ja fasit-setningen ORDRETT 3 ganger; planskilt/ÅDT/4 000 alle til stede
17 (a) N200/N500 nei 0 av 6 / 0 av 5 nøkkelord fra hver fasit-kropp i noe svar
18 (b) nei × 3 req_number/title/concept_id/element_id/URL: 0 treff i 18 svar
19 (c) = 0 kravnummer-formede tokens: 0; tall i prosa mot delivered, ett treff forkastet
20 Instrumentet for (c) virker skjerpet til det fant 4 000 fra kroppen; første form fant 0 av 0
21 Kostkodene grep -rl i hver base med nevner; fasit-id-en som kjent-positiv (2 treff)
22 Parse-feilen på N200 p2-n200-free-parse-failures.json finnes; feilteksten sitert ordrett
23 Prisene Azure Retail Prices API hentet på nytt 08.09
24 0 × 429 retries-telleren i alle 18 poster

10. P3 (ordre 20260908T141941Z) — po bærer utdragets nye felt gjennom til prompten

PM-valg 08.09 14:20Z, på denne målingens egen anbefaling (§ 6): ja, to linjer, rød test først.

10.1 Reproduksjon (steg 1, uendret fra § 4)

>>> sorted(json.load(open("scratchpad/nbundler-p2/payload-n500.json"))["excerpts"][0].keys())
['adjudication', 'bundle_id', 'bundle_id_inherited', 'concept_id', 'rank', 'req_number',
 'sha256', 'source_element_id', 'source_sha256', 'sources', 'text', 'text_sha256', 'title',
 'trust_tier']                                                          # 14 medlemmer, i payloaden
>>> sorted(prepass.load_prepass_payload("scratchpad/nbundler-p2/payload-n500.json").excerpts[0]
...        .model_dump().keys())
['adjudication', 'bundle_id', 'concept_id', 'sha256', 'text', 'text_sha256', 'trust_tier']
                                                                          # 7 medlemmer, etter parsing
>>> "req_number" in prepass.render_context(...)
False                                                                    # aldri i prompten (§ 4)

10.2 Feltform, valgt med måling

Spørsmålet ordren stiller: hvilken form overlever en ukjent source_foo-nøkkel fra en FRAMTIDIG produsent, uten kodeendring her? okfs egen melding (§ 4, sitert) kaller source_* en prefiks- regel, ikke en allowlist — K2 bærer fem slike lokatorer der N-bundlene bærer to. To former ble sammenliknet mot nøyaktig det spørsmålet:

  • Navngitte felt (source_element_id: str | None, source_sha256: str | None, …): en tredje source_*-nøkkel krever et NYTT felt på PrepassExcerpt og en ny rendringslinje — en kodeendring, nøyaktig det prefiksregelen sier man IKKE skal måtte gjøre.
  • model_extra (extra="allow"PrepassExcerpt ALENE, lest tilbake via et source_-prefikssøk i source_locators()): en ny source_*-nøkkel havner unavngitt i model_extra og plukkes opp av SAMME søk, null kodeendring.

Valgt: model_extra for source_*-familien. title, req_number og sources er derimot navngitte felt — de er SS-8-deklarerte, entallige medlemmer (aldri en voksende familie), og en model_extra-lesning av dem ville kastet bort pydantics egen validering for ingen gevinst. Testen test_a_future_source_star_key_survives_without_a_code_change (tests/test_prepass_excerpt_fields_loadbearing.py) legger til en TREDJE, aldri navngitt source_page_number-nøkkel og viser at den når source_locators() uendret.

10.3 Fiksen: to steder, ikke to linjer

Anbefalingen i § 6 anslo "to linjer"; målt var det to STEDER (parsing + rendering), hver med mer enn én linje fordi sources trengte en egen typet klasse (PrepassSource, med resource og en valgfri title) og source_locators() trengte en egen metode:

  1. Parsing (PrepassExcerpt): title: str | None, req_number: str | None, sources: tuple[PrepassSource, ...] | None, alle default None (de fleste payloader i dette repoet er fra FØR P2s produsent-endring og bærer ingen av dem — et påkrevd felt ville refusert hver payload skrevet før i dag). model_config = ConfigDict(extra="allow") — kun på DENNE klassen, _Permissives extra="ignore" står urørt for PrepassBundle/PrepassBudget/osv.
  2. Rendering (_excerpt_header, ny funksjon _data_blocks nå kaller): req_number og title legges til i parentesen ved siden av adjudication/trust_tier NÅR de finnes; sources[0].resource (adressen) og hver source_*-lokator (generisk, via source_locators()) legges til deretter. Kjent-negativ: når ingen av de nye feltene finnes, er sløyfa en no-op og headeren er BYTE-IDENTISK med før P3 (test_a_p1_form_payload_renders_the_header_exactly_as_before, test_a_p1_form_payload_render_seed_also_unchanged) — pinnet LITERALT, ikke med en delstreng-assert, fordi en lekkende tom-klausul (f.eks. en etterlatt , ) ikke ville vist seg i et substring-søk.

render_seed deler _data_blocks med render_context (ko-(p)); en fiks som bare traff den ene armen ville latt utforsknings-døra ligge stille bak debatt-døra — test_render_seed_also_carries_the_new_fields gater begge.

10.4 Rødt → grønt → mutasjon rød

Ny fil: tests/test_prepass_excerpt_fields_loadbearing.py, 10 arm. FØR fiksen: 8 røde, 2 grønne (de to kjent-negative armene er trivielt grønne før fiksen òg — de er kontroller, ikke mål). ETTER fiksen: 10 av 10 grønne.

Mutasjon (revert _excerpt_header/_data_blocks til § 4s form, midlertidig, aldri committet): 3 av 10 røde — nøyaktig de tre rendrings-armene (test_the_data_block_renders_req_number_title_and_the_address, test_the_data_block_renders_a_future_locator_too, test_render_seed_also_carries_the_new_fields) — parsing-armene forblir grønne (mutasjonen rørte ikke PrepassExcerpt), som beviser at de to halvdelene av fiksen har HVER SIN uavhengige gate. Fiksen restaurert fra en kopi (shasum -a 1 verifisert identisk før/etter), aldri git checkout.

10.5 Suite, golden, lint

1521 passed, 5 skipped (var 1511 — 10 nye), pytest -q, 272 s. ruff check src tests og ruff format --check src tests: rene (94 funn i scratchpad/ er FØR-eksisterende, utracket, utenfor scope — samme avgrensning som K3-ordrenes ruff check src tests tools). mypy src: 0 funn, 37 filer. Golden demo-transcript.stdout UENDRET: shasum -a 1 = ea8c534… — forventet, simulation.py importerer ikke prepass i det hele tatt.

10.6 Én betalt N100-kjøring med --require-cost-baseline — og (b) er STRUKTURELT ikke dekket

Samme oppsett som § 3 (live_nbundler_p2.py n100 --require-cost-baseline), med den FIKSEDE koden.

KJENT-POSITIV n100: navigate_bundle=446 (fasit 446) OK
run refused: this run was required to be anchored, but the knowledge base offers no cost baseline: …
===== ARM n100 [req] (rc=1) =====
  MODELLKALL: 0  (gaten MAA fyre foer foerste kall)

rc=1, 0 modellkall, NOK 0,00. Dette REPRODUSERER § 2s funn ordrett — --require-cost-baseline nekter N100 FØR første modellkall, fordi en vegnormal ikke bærer kostlinjer (strukturelt, uendret av denne fiksen). Konsekvens: (b) kan IKKE måles i denne armen — det oppstår aldri en hypotese å navngi et konsept for, uansett hvor godt utdraget bærer req_number/title. Dette er IKKE en regresjon fra fiksen; det er § 2s "en N-bundle kan ikke samtidig være forankret og produsere en hypotese" gjentatt på den fiksede koden.

(b) er derfor "ikke dekket" i DENNE armen — strukturelt, ikke som en feil ved fiksen. Fiksens EGEN korrekthet er verifisert der den kan verifiseres gratis: offline, mot payloadens faktiske felt (§ 10.110.4). En live gjenmåling av (b) på den FRIE armen (uten flagget, slik § 3 kjørte N100) ville kostet et nytt betalt kall utenfor denne ordrens scope (ordren navngir eksplisitt --require-cost-baseline-armen som den ENE betalte kjøringen); det er ikke gjort her.

10.7 Funn — rapportert, ikke fikset

  1. (b) er umålbar under --require-cost-baseline for enhver N-bundle (§ 10.6). Samme struktur som funn 2 i § 7, nå bekreftet på den fiksede koden. Ingen handling — F4 gjør nøyaktig det den ble bygget for.
  2. En live gjenmåling av (b) på den frie N100-armen (uten flagget) er ikke gjort her — ordren navngir --require-cost-baseline som den ene betalte kjøringen, og en fri kjøring ville vært en ny, ubedt betalt handling.

11. P4 (ordre 20260908T151403Z) — den frie N100-armen, ETTER fiksen: (b) = JA

PM-valg 08.09 15:14Z, på § 6 punkt 4 og § 10.7 funn 8s egen anbefaling: funn 8s hull lukkes med ÉN betalt, flaggfri N100-kjøring. Ingen src/-endring; ny kjørefil KUN i scratchpad/ (live_p4_free.py, en kopi av live_nbundler_p2.pys frie arm med eget run-id/filnavn, for å ikke overskrive P2s eksisterende n100-free-*-evidens).

11.1 Repro (steg 1, gratis)

>>> len(json.load(open("scratchpad/nbundler-p2/payload-n100.json"))["excerpts"])
14                                                            # medlemmer i excerpts[0], uendret
--- BEGIN DATA krav/N100/id-4b61eee9-…-c15a (adjudication: unknown, trust_tier: unverified,
  req_number: Krav 3.3.1—13, title: Krav 3.3.1—13 H1  Nasjonal hovedveg, ÅDT < 6 000 og
  fartsgrense 80 km/t, source: https://viewers.vegnorm.vegvesen.no/api/nisosts/859984?…

req_number og title står ORDRETT på BEGIN DATA-avgrenserens EGEN linje (§ 7 funn 6: målt her på avgrenseren, ikke på hele prompten, som § 7 selv advarte var konfundert).

Klientprobe FØR armen, begge env-variabler satt: PORTFOLIO_FOUNDRY_PROJECT_ENDPOINT (utledet INLINE fra az cognitiveservices account show --name po-foundry-ktg --resource-group portfolio-optimiser-rg, PROSJEKT-formen …/api/projects/po-project) + PORTFOLIO_FOUNDRY_DEPLOYMENT = gpt-4-1-mini. uv run pytest tests/test_foundry_profile_live.py -q1 passed (ikke skippet).

11.2 Den betalte kjøringen

uv run --with tiktoken python scratchpad/nbundler-p2/live_p4_free.py, profil azure, gpt-4-1-mini, PACE_SECONDS=2, PORTFOLIO_MODEL_MAP=scratchpad/major2-live/model_map.json, --run-id p4-n100-free, UTEN --require-cost-baseline og UTEN --derive-cost-baseline. Rå resultat:

KJENT-POSITIV n100: navigate_bundle=446 (fasit 446) OK
  rang 1 = krav/N100/id-4b61eee9-…-c15a  req_number='Krav 3.3.1—13'
===== ARM p4-n100-free (rc=0) =====
N100: Rejection (no expert verdict given; verdict key=ca7cd8e99c6cc2d9)
  proposal review offered, never consulted (no candidate validated)
--- ledger ---
  checker      prompter=1   in=4693     out=99
  proposer     prompter=5   in=10716    out=648
  prompter totalt: 6   429-retries: 0

rc=0, 6 modellkall (5 proposer, 1 checker), ingen 429. --proposal-review var satt (skriptet manus svarer approve på hvert spørsmål, uten at noe forslag noensinne når validatoren — checkeren avviste ikke, men ingen kandidat ble VALIDERT, se § 11.4).

11.3 Modellsvarene, ordrett (utdrag)

Proposer, forsøk 1:

A concrete cost-saving measure for the N100 project could be: Avoid planskilt (grade-separated) crossings between pedestrian/cycle paths and roads when the ÅDT (Average Daily Traffic) is 4,000 or less. Rationale based on Krav 3.3.1—13 from the N100 knowledge base: The requirement states that "Eventuell kryssing mellom gang- og sykkelveg og veg skal være planskilt ved ÅDT > 4 000." …

Checker:

The N100 excerpt Krav 3.3.1—13 clearly states that crossing between pedestrian/bicycle paths and roads must be grade separated (planskilt) only if ÅDT > 4,000. … VERDICT: APPROVE

11.4 (b)/(a)/(c) — med nevner, samme rader som § 5

N100 (P4, fri, ETTER fiksen)
req_number (Krav 3.3.1—13) ordrett 6 av 6 svar
title ordrett (hele strengen) 0
fasit-concept_id ordrett 0
source_element_id som eget felt 0
resource-URL/nisosts 0
leverte konsepter navngitt i det hele tatt 1 av 8 — OG DET ER FASIT-KONSEPTET (ulikt P2s N200/N500, hvor det navngitte konseptet IKKE var fasit)
(b) JA
N100 (P4)
fasit-setningen ORDRETT ("Eventuell kryssing … ÅDT > 4 000.") 1 gang (proposer, forsøk 1)
planskilt / ÅDT / 4 000-formet tall 10 / 10 / 11
(a) JA
N100 (P4)
kravnummer-formede tokens i svaret UTOVER Krav 3.3.1—13 0 (regex Krav\s+[\d.]+—\d+ finner ETT distinkt token på tvers av alle 6 svar)
tall i prosa som ikke er i det leverte 0 (4,000/4 000 er samme fasit-tall, engelsk tusenskille — § 5c-instrumentfeilen gjentatt, ikke en ny hallusinasjon)
konsept-id-referanser som ikke er levert 0
(c) 0

Kjent-negativ for instrumentet, kjørt FØR dommen: samme spørring ("Krav 3.3.1—13" i teksten) mot P2s n100-free-records.json (FØR fiksen, 6 svar) gir 0 — spørringen er ikke konfundert.

Det strukturerte forslaget dikter fortsatt opp kostkoder (CS-GS1, planSkiltCrossing, GRD-CRS-01 — ingen finnes i basen), av samme strukturelle grunn som § 5c: ingen baseline, og --derive-cost-baseline ble bevisst IKKE brukt her (ordrens scope). Uendret funn, ikke en ny defekt.

«Ferdig»-raden for N100, etter § 6-definisjonen: (a) JA · (b) JA (var NEI i P1/P2) · (c) 0. N100 = FERDIG. Første gang en av de tre N-bundlene når «ferdig» i po sin hypoteseform — P3s fiks var det som gjorde det nåbart, og denne kjøringen er beviset på at det ER nådd, ikke bare at koden er riktig offline.

Er (b) MODELL-dom, ikke po-dom: feltet sto i DATA-avgrenseren (§ 11.1); at modellen faktisk brukte det — siterte req_number ordrett i 6 av 6 svar, og bygde hypotesen på nøyaktig det kravet fasiten peker på — er noe modellen gjorde, ikke noe po garanterte. Oppgaven prompten stiller er fortsatt A-formens hardkodede "Find a cost-saving measure for {project.id}." (run.py:1243, § 6 «Hvem eier hva») — ikke et spørsmål om Krav 3.3.1—13 spesifikt; at modellen likevel fant og navnga akkurat det kravet, i et kutt på 8 av 446, er dømmekraft utenfor det po kan ta æren for.

11.5 Kostnad

Samme listepris som § 5d (input NOK 0,003734/1K, output NOK 0,014936/1K):

Kjøring Prompter Input Output NOK
N100 (P4, fri) 6 15 409 747 0,069
klientprobe 1 ~20 ~5 ~0,000
SUM 7 15 429 752 NOK 0,07

NOK 0,07 — under ordrens tak på NOK 0,25. 429-svar: 0.

11.6 Funn — rapportert, ikke fikset

  1. Ingen nytt funn som okf eier. Utdraget bar begge feltene korrekt (§ 11.1); at modellen brukte dem er en modell-egenskap, ikke en utdragsform-defekt. Ingen coord-send til llm-ingestion-okf.
  2. --proposal-review fikk ingen kandidat å vise — checkeren avviste aldri, men heller ingen av de fem proposer-forsøkene ble VALIDERT av den deterministiske validatoren (ingen baseline, se § 11.4s kostkode-funn), så reviewer-døra sto åpen uten noe å spørre om. Uendret struktur fra P1/P2, ikke en ny defekt.