portfolio-optimiser-commons/docs/plan/2026-07-26-v1-generated-felt-okf-v0.2.md
Kjell Tore Guttormsen 3de702b937 docs(plan): V1 §6 — rekkevidde-forbeholdet korrigert, og funnet under funnet
llm-ingestion-okf svarte at (d) er gjennomførbar og målte to grunner til at den
slår deres egen (b). Den ene korrigerer oss: konflikten er ikke bare normativ.
Fasitsettene finnes hos implementasjonene, `generated` ligger på :8 inne i
prefikset i fire filer, så :280-halvdelen fyrer ved deres neste release.
Reprodusert her, inkl. _is_ingest_owned (materialize.py:131-150).

Kontrollen avdekket et selvstendig punkt ingen har meldt: :29 sier "the SHARED
golden extractions" i bestemt form, men det finnes TO disjunkte sett — okf har
orders/products/metrics/status, po-claude har costs/edge/meta, og de eneste
felles navnene (index.md) er byte-ulike. Commons har aldri hatt settet.
Konformansleddet er derfor ikke-testbart i dag. Ikke en del av V1, ikke i køen —
tatt med fordi det avgjør hvor tungt :29-argumentet veier.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XYkLsRfSBBUjULS219Fy8X
2026-07-26 17:11:45 +02:00

255 lines
15 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# V1 — hvilken form skal `generated` ha i ingest-spec etter OKF v0.2?
> **Status:** beslutningsunderlag for operatøren. Fire opsjoner med målt kostnad, ingen
> anbefaling. Utløst av `llm-ingestion-okf` (coord, 2026-07-26) som spør fordi authorship er
> vår: deres DEFAULT-profil staterer ingest-spec §5, og «ingen lokale spec-endringer» er deres
> stående non-goal.
>
> Underlaget rører ingen spec-tekst. `ingest-spec.md` står uendret på `bfa5a9b`/`9801d35`.
Beslektet: `2026-07-25-amendment-underlag.md` (køen av ratifiserbare punkter — V1 hører hjemme
der hvis den ratifiseres), `2026-07-25-b1-nav-golden-normative-status.md` (samme form).
---
## 1. Det som ikke er oppe til vurdering
- **Ærlighetsregelen selv** (`ingest-spec.md:33-34`, avledet av `method-spec.md:26`) er
*unwaivable*. Alle fire opsjoner under oppfyller den. Spørsmålet er hvilken **form**
merkingen har, aldri **om** den finnes.
- **Eierskaps-stempelets funksjon** (`:70`, `:82`): at re-materialisering bare rører egne filer,
og at en kurert skriver avviser det *komplette* stempelet. Ingen opsjon svekker den regelen.
- **`ingested_at` som eksplisitt påkrevd argument** (`:139-143`). Ingen opsjon innfører
wall-clock. Der `at` finnes, bindes den til `ingested_at`.
- **Hastegrad.** `llm-ingestion-okf` er *ikke* blokkert: deres v0.2-støtte kommer som en ny
profil ved siden av DEFAULT, additivt. Ingenting her er en brannslukking.
## 2. Premissene, verifisert
`llm-ingestion-okf`s to påstander er kontrollert mot kilden, ikke overtatt:
- **Oppstrøms:** OKF v0.2 (`GoogleCloudPlatform/knowledge-catalog`, `okf/SPEC.md`) definerer
`generated: { by, at }`, og `generated.by` er **REQUIRED within `generated`**, typet som en
aktør per §7. Aktørkonvensjonen har **tre** former: `<producer>/<version>` for agenter og
verktøy, `human:<id>` for en person, `process:<id>` for en automatisert prosess.
- **Toleransen dekker det ikke.** v0.2 sier at konsumenter «MUST NOT reject documents with
unrecognized fields» og ikke skal avvise for *manglende valgfrie* felter eller *ukjente*
nøkler. Ingen setning pålegger en leser å svelge en **kjent nøkkel med feil type**.
`llm-ingestion-okf`s lesning holder.
- **Historikken frikjenner valget.** `generated` var ikke reservert i v0.1. Ingen innførte en
defekt; v0.2 tok navnet etterpå.
**Én forbeholdsrad:** deres egen plan (`okf-v0.2-alignment.md`) slår fast at spec-en er lest på
`main` — en gren, ikke en tag — og at «an enumeration read off a moving branch is a premise, not
a fact». Vår kontroll traff samme bevegelige gren. **Ingen frossen spec-tekst bør endres før
oppstrømsversjonen er pinnet til en commit.** Det gjelder O1, O2 og O3 likt.
## 3. `generated` bærer to laster i vår spec, ikke én
Dette er funnet som former underlaget, og grunnen til at opsjonssettet ikke er tre.
Nøkkelen opptrer 7 ganger som kontraktsreferanse, fordelt på fem seksjoner. De deler seg på
**to akser** som ingen av dem navngir:
| Last | Hvor | Hva den svarer på | Hvem leser den |
|---|---|---|---|
| **Ærlighetsmarkør** | §1 `:34`, §7 `:214` | «er dette maskingenerert?» | en leser/presentatør av bundelen |
| **Eierskapspredikat** | §3 `:70`, §3 `:82`, §11 `:275` | «hvilke filer eier ingest — og hva skal en kurert skriver avvise?» | materialiseringen og dør C |
Oppstrøms `generated { by, at }` er **provenance/attribusjon** — den første lasten, ikke den
andre. v0.2 har ingen skriveeierskaps-semantikk; feltet er valgfritt, konsument-skrivbart og
fritt for enhver aksesskontrollmening.
Konsekvensen er ikke at feltet ikke *kan* bære begge, men at en opsjon som flytter
eierskapspredikatet over på et oppstrømsdefinert felt **må uttale det**: predikatet går fra en
literal-sjekk (`generated == true`) til en parse-og-match på et felt hvis grammatikk oppstrøms
eier og fritt kan revidere. Konjunksjonen med `ingest_manifest` — vår egen nøkkel, ikke reservert
oppstrøms i noen versjon — bærer fortsatt uforfalskbarhet-mot-uhell, så stempelet kollapser
ikke. Men `:82`s «permitting either field alone» må omformuleres: under v0.2 vil *kurert*
innhold legitimt kunne bære en `generated`-mapping med en helt annen `by`.
## 4. Spørsmålet
> Skal `generated` i ingest-spec §5/§7 forbli den literale `true`, anta v0.2-formen
> `{ by, at }` — og i så fall med hvilken aktørstreng — eller skal vår markør flytte til en
> nøkkel oppstrøms ikke eier?
## 5. Opsjonene, med målt kostnad
Kostnad er talt som **kontraktslinjer som må skrives om** av de 7 (`:34`, `:70`, `:82`, `:152`,
`:214`, `:275`, `:309`).
**Det som ikke koster noe i noen opsjon:** §5s formkrav overlever uendret. Prefikset er «OKF
line-oriented `key: value`» (`:150`) og «All values MUST be single-line» (`:158`) — v0.2s
kanoniske form for `generated` er en **inline flow mapping** på én linje, så den er single-line
og line-oriented allerede. `:153` («additional frontmatter keys MAY follow») er heller ikke i
veien. Ingen opsjon tvinger fram en rikere frontmatter-modell i *specen*.
### O0 — la `generated: true` stå, dokumentér avviket
**0 av 7 linjer.** Ingen frossen tekst røres; ingenting går i ratifiseringskøen. Eneste
tilføyelse er en merknad om at nøkkelen kolliderer med et v0.2-definert felt.
Kostnad: DEFAULT fortsetter å emittere en v0.2-definert nøkkel med v1-verdi. En v0.2-leser har
ingen plikt til å akseptere den (§2). Kollisjonen forsvinner ikke — den venter.
**Reverserbar.** Ja.
### O1 — v0.2-form med produsent-aktør (`llm-ingestion-okf`s anbefaling)
`generated: { by: "llm-ingestion-okf/<versjon>", at: <ingested_at> }`, predikatet utledet av
`generated.by`.
**5 av 7 linjer** (`:34`, `:70`, `:82`, `:214`, `:275`). `:152` og `:309` navngir bare nøkkelen
og overlever.
**Denne opsjonen kolliderer med en eksisterende normativ setning — se §6.** Kostnaden er ikke
bare fikstur-regenerering.
**Reverserbar.** Nei — frossen normativ tekst.
### O2 — v0.2-form med produsent-nøytral aktør
`generated: { by: "process:<fast id>", at: <ingested_at> }`. v0.2 §7 tillater eksplisitt
`process:<id>` for en automatisert prosess (verifisert, §2). Aktøren navngir da **prosessen
specen definerer**, ikke verktøyet som kjørte den.
**5 av 7 linjer** — nøyaktig samme som O1. Den eneste tekstlige forskjellen mot O1 er
aktørstrengen; den avgjør til gjengjeld §6.
Kostnad: `generated.by` identifiserer ikke lenger *hvilket* verktøy som produserte filen.
Produsent-identitet må da bo i implementasjonens egen logg. Om det er et tap eller et krav
avhenger av §6.
**Reverserbar.** Nei.
### O3 — døp om vår markør, la `generated` være fri
Vår markør flyttes til en nøkkel oppstrøms ikke eier; `generated` overlates til v0.2-semantikk.
**7 av 7 linjer** — også `:152` (prefiks-lista) og `:309` (kryss-sjekk-tabellen), fordi nøkkelen
selv skifter navn. Dyrest i tekst.
Til gjengjeld: predikatet bevares **eksakt** som en literal-sjekk, aksene i §3 skilles ved
konstruksjon, og kollisjonen kan ikke gjenoppstå ved neste oppstrømsrevisjon. v0.2 forbyr det
ikke — de nye feltene er valgfrie oppstrøms.
Kostnad: interop-tapet er reelt. En v0.2-leser som spør «er dette maskingenerert?» via
`generated` får ikke svar. Ærlighetsregelen er oppfylt internt, men ikke lesbar for formatets
egne lesere — som er en del av hvorfor vi ligger i OKF i det hele tatt.
**Reverserbar.** Nei.
## 6. Funnet som omformer opsjonssettet (ikke en anbefaling)
**O1 som formulert kolliderer med konformansleddet i §1.**
- `ingest-spec.md:29`: en konform implementasjon MUST «reproduce the shared golden extractions
(§11) byte for byte».
- `ingest-spec.md:267`: `expected-bundle/` er «compared file by file, **byte for byte**».
- `ingest-spec.md:280`: sømmen `Golden regression` fyrer når «any byte of a golden extraction's
expected bundle diverges».
- `generated` ligger i det **obligatoriske ordnede prefikset** (`:149-152`) — altså inne i de
bytene.
Med `by: "llm-ingestion-okf/<versjon>"` bærer en **delt** fasit én produsents navn og
versjonsnummer. Da følger to ting mekanisk:
1. **Ingen annen konform implementasjon kan reprodusere fasiten byte for byte.** Kravet i `:29`
gjelder enhver konform implementasjon, ikke den som lagde fikstursettet. Kravet blir
uoppfyllbart ved konstruksjon for alle andre enn én.
2. **`Golden regression` fyrer på hver versjonsbump av biblioteket** — uten at noen kontrakt har
endret seg. Sømmen slutter å måle det den er satt til å måle.
O2 unngår begge: aktørstrengen er da specens, ikke produsentens, og bytene forblir
produsent-nøytrale. O0 og O3 berører ikke spørsmålet.
**Merk hva funnet ikke er.** Det er ikke et argument for O2 og mot O1 i seg selv. Operatøren kan
gyldig svare at fasit-klassen aldri får mer enn én produsent, eller at `generated` skal ut av
det byte-sammenlignede prefikset. Men da er *det* valget som må ratifiseres — funnet sier bare
at O1 ikke kan vedtas uten samtidig å ta stilling til `:29`.
### 6.1 Rekkevidde-forbeholdet, korrigert 2026-07-26
Første utgave skrev at konflikten er «normativ, ikke observerbar — den utløses den dagen commons
publiserer sin første ingest-fasit». **Det var for snevert, og `llm-ingestion-okf` korrigerte
det med en måling.** Riktig bilde, etter kontroll i alle tre trær:
- `examples/ingest-golden-*` finnes fortsatt **ikke i commons** — og har aldri gjort det
(`git log --all -- 'examples/ingest-golden-*'` → tomt).
- Men fikstursettene **finnes hos implementasjonene**, og `generated` ligger i bytene:
fire filer hos `llm-ingestion-okf`, alle på `:8`, inne i prefikset. **Del (ii) av funnet —
at `Golden regression` (`:280`) ville fyre på hver versjonsbump — er derfor observerbar i
dag, ikke i framtiden.** Den utløses ved deres neste release.
### 6.2 Funnet under funnet: «the shared golden extractions» har ingen referent
Kontrollen for 6.1 avdekket noe som gjelder uavhengig av hele V1-spørsmålet, og som ingen har
meldt:
| Repo | `examples/ingest-golden-*/expected-bundle/` |
|---|---|
| commons | finnes ikke, har aldri funnes |
| `llm-ingestion-okf` | `ingest-orders.md`, `ingest-products.md`, `ingest-metrics.md`, `ingest-status.md` (+ 3 `index.md`) |
| `portfolio-optimiser-claude` | `ingest-costs.md` ×2, `ingest-edge.md`, `ingest-meta.md` (+ 2 `index.md`) |
**Overlappet i innholdsfiler er null.** De eneste sammenfallende navnene er `index.md`, og de er
byte-ulike (ulik oppsummering, ulike lenkemål — verifisert med `cmp`).
`ingest-spec.md:29` krever at en konform implementasjon reproduserer «**the shared** golden
extractions (§11) byte for byte». Bestemt form forutsetter ett sett. Det finnes to, begge
lovlig navngitt etter konvensjonen i `:259-260`, ingen av dem publisert her. **Konformansleddet
er dermed ikke-testbart i dag** — ikke fordi fasiten mangler, men fordi det er to av dem, og
hver implementasjon reproduserer sin egen per konstruksjon.
Dette er et **selvstendig punkt**, ikke en del av V1, og det er ikke i køen. Det er tatt med
her fordi det avgjør hvor tungt `:29`-argumentet i §6 veier: argumentet er ikke «dette bryter
en delt fasit vi har», men «dette sementerer at en delt fasit aldri kan oppstå».
## 7. Det som ikke er commons' å avgjøre
- **Hvilken opsjon som velges.** Spec-teksten er frossen; endringer går gjennom
ratifiseringskøen. V1 er punkt nummer 8 hvis den ratifiseres — den står **utenfor** de 7 i
`2026-07-25-amendment-underlag.md` og fortrenger ingen av dem.
- **Hva `llm-ingestion-okf` gjør i sin egen v0.2-profil.** Den er additiv og deres authorship.
Bare DEFAULT staterer vårt lag.
- **Om produsent-identitet skal logges et annet sted** (O2s pris). Implementasjonens valg.
## 8. Det som ikke endres uansett utfall
Ærlighetsregelen, eierskapsstempelets funksjon, `ingested_at`-argumentet, §5s single-line- og
line-oriented-krav, og `ingest_manifest` som stempelets andre halvdel. Ingen opsjon rører
`method-spec.md` — nøkkelen forekommer ikke der (`grep -c '\`generated' method-spec.md` → 0).
---
## Verifiseringslogg
| Påstand | Sjekk | Resultat |
|---|---|---|
| v0.2 definerer `generated: { by, at }` | `okf/SPEC.md` @ `main`, hentet 2026-07-26 | «generated: { by: reference_agent/gemini-2.5-pro, at: 2026-06-20T22:53:05Z }» |
| `by` er påkrevd | samme | «generated.by: REQUIRED within `generated`. An actor (§7).» |
| Aktørkonvensjonen har tre former | samme, §7 | `<producer>/<version>` / `human:<id>` / `process:<id>` |
| `timestamp` er superseded | samme | «`timestamp` is superseded by `generated.at`» |
| Toleransen gjelder ukjente, ikke feiltypede | samme | «MUST NOT reject documents with unrecognized fields»; lista dekker manglende valgfrie + ukjente |
| Oppstrøms er lest på en gren, ikke en tag | `llm-ingestion-okf/docs/plan/okf-v0.2-alignment.md` | «`main` on 2026-07-26 — a branch, not a tag» |
| Kontraktsreferanser til nøkkelen | `grep -n '\`generated' ingest-spec.md` | 7 linjer: `:34 :70 :82 :152 :214 :275 :309` |
| Nøkkelen finnes ikke i method-spec | `grep -c '\`generated' method-spec.md` | 0 |
| Ærlighetsregelen er unwaivable | `ingest-spec.md:33-34`, `method-spec.md:26` | «unwaivable» begge steder |
| Stempelet er `generated: true` + `ingest_manifest` | `ingest-spec.md:70`, `:82` | ordrett sitert over |
| Dør C avviser kun det komplette stempelet | `ingest-spec.md:82-85` | «while permitting either field alone» |
| `generated` ligger i det ordnede prefikset | `ingest-spec.md:149-152` | 7 nøkler, `generated` er den sjuende |
| Prefikset er åpent bakover | `ingest-spec.md:153` | «additional frontmatter keys MAY follow it» |
| Single-line-kravet holder for flow mapping | `ingest-spec.md:150`, `:158` | «line-oriented `key: value`» / «All values MUST be single-line» |
| Konformans krever byte-lik delt fasit | `ingest-spec.md:29` | «reproduce the shared golden extractions (§11) byte for byte» |
| Fasiten sammenlignes byte for byte | `ingest-spec.md:267`, `:280` | «byte for byte» / «any byte … diverges» |
| Ingen ingest-fasit finnes i commons | `ls -d examples/ingest-golden-*` | ingen treff |
| …og har aldri funnes | `git log --all -- 'examples/ingest-golden-*'` | tomt |
| `generated` ligger i fasit-bytene hos okf | `grep -rn '^generated' llm-ingestion-okf/examples/ingest-golden-*/expected-bundle/*.md` | 4 filer, alle `:8` |
| …inne i det ordnede prefikset | `sed -n '1,9p' .../ingest-orders.md` | 7 nøkler `:2-8`, `generated` sist |
| Predikatet nøkler på literalen i dag | `materialize.py:131-150` | `frontmatter.get("generated") != "true"` + stem-match |
| To disjunkte fasitsett finnes | `comm -12` over begge trærs `expected-bundle/*.md` | kun `index.md`-navn felles |
| …og de felles `index.md` er ulike | `cmp` på `ingest-golden-file/.../index.md` | ULIKE |
| §1 sier «**the shared** golden extractions» | `ingest-spec.md:29` | bestemt form, én mengde forutsatt |
| `ingested_at` har ingen wall-clock-default | `ingest-spec.md:141` | «there is NO wall-clock default» |
| Spec-tekst uendret siden 07-21 | `git log --oneline -- ingest-spec.md` | `bfa5a9b`, forrige `7aa53fc` — ingen commit etter |