P13 measured this lift and REFUSED it, because okf >=0.8.5 emits the ownership
stamp as the V1 flow mapping `generated: { by: process:okf-ingest, at: ... }`
where 0.3.2 emitted `true`, and `_carries_complete_ingest_stamp` read the new
form as NOT a stamp -- write_concept_file's forgery refusal would have shipped
DISARMED with the whole fail-closed suite green. That blocker is closed first,
red-first, and then the pin moves.
ROW 1, THE SECURITY HALF. `_claims_ingest_ownership` widens the predicate from
"reads as boolean True" to "claims ingest ownership", of which the boolean is
the pre-V1 spelling. The recogniser for the new half is `decode_flow_value` --
the module's ONE flow decoder, the same argument write_concept_file already
makes for `verified`: the writer refuses exactly what the reader can read. A
value the decoder REFUSES is therefore not an ownership claim and writes
through, which is what keeps this from collapsing into "any non-empty
generated". Two arms red before the fix; no YAML library introduced.
THE PIN. okf v0.3.2 -> v0.8.5, guard v0.3.4 -> v1.4.0 spelled `tag =`, not
`rev =`, and not the declared floor 1.2.0 -- both P13 premises hold and the
reason now lives next to the pin in pyproject.toml. The ":40" comment is
corrected: okf has ONE runtime dependency, the guard, and that is what binds
the two lines together. 27/27 imported names resolve across five modules.
THE GOLDENS, REGENERATED AS A DECISION. Seven concept files across four
examples/ingest-golden-* bundles, one line each. Two were regenerated by the
REAL materializer; the other five are derived (http/sql/mcp cannot materialize
outside the tests' stubs) and then MEASURED -- all four golden suites compare
byte for byte against what the stubs produce, and all four are green. The four
`generated == "true"` asserts now read ONE source, conftest.
expected_generated_stamp: four literals for one emitter fact are four places a
later release can leave half-corrected, which is exactly how the pre-V1 form
survived until P13 measured it. tests/test_okf.py keeps its literal on purpose
-- that one round-trips a CURATED half-stamp through our own writer.
THE BLOCK READER. Measured with the full denominator: all four delivered
knowledge bases write `sources` as a BLOCK sequence and none in flow form
(n100 446/446, n200 1133/1133, n500 270/270, r761 2756/2756 = 4605/4605), and
`evidence_for` reported `unreadable` on 4605 of 4605 -- the falsification layer
had no address for any document in any base. `okf.decode_block_mappings` is the
second CARRIER of one grammar, never a second grammar: colon-SPACE separator,
unquote_scalar, duplicate keys refused, SPEC 5.2's actor rule applied. okf's
consume.read_sources was READ for the form and not called; po calls no okf
reader, which is measured and deliberate. After: 4605 present / 4605 entries.
Reading is not a licence to WRITE -- the emitter is untouched and both writers
still refuse what decode_flow_value refuses.
THREE FINDINGS. (1) The first block reader INVENTED data on `- { k: v }` items
-- SPEC-canonical, and the shape tests/golden/block-form-provenance writes for
`verified` -- decoding it as `{'{ id': '...'}`. No arm caught it: the 5.2 actor
rule shielded the fixture by accident. Closed with a flow-decoder branch and
four new arms. (2) One of my own arms was VACUOUS, found by my own mutation M5:
it claimed to prove the colon-SPACE rule and stayed green under first-colon,
because the two rules agree on every delivered value. Renamed, labelled, and
the claim moved to the arm that actually witnesses it. (3) OPEN, and it needs
the operator: the commons-owned worked example declares its second concept
`unreadable`/`block-sequence`, which is now false for po. `shared/` is
pull-only, so closing it needs a commons amendment; the test asserts the
divergence instead of skipping it, keeping the discriminating half (the example
says two entries were seen and the reader returns exactly two).
NINE EXISTING ARMS REWRITTEN, NONE WEAKENED. All nine pinned "the block form is
unreadable" -- the behaviour this order changes. Each keeps its claim on a
specimen that is still unreadable for a reason of its own (5.2: an entry naming
no actor), or pins the REVERSED direction where the old arm stood so the change
cannot be silent. Two got STRONGER: multi-verified.md was authored for "a reader
keeping the last entry reports machine-confirmed for a concept a human signed",
and that could not be tested while the form was unreadable. Three node ids were
renamed; nothing was removed in substance.
Suite 1582 -> 1606 passed / 5 skipped. Both demo goldens byte-unchanged
(ea8c534... / ede3e2f..., shasum -a 1 of the CONTENT, never the git blob id).
ruff check / ruff format / mypy green. shared/ untouched.
Six mutations, all red against the WHOLE suite, each with its own signature:
row 1 detached (2) / block reader detached (17) / flow-item branch detached (7)
/ a stray indented line folds into an INVENTED entry (4) / separator becomes the
first colon (1 -- and that is finding 2) / the stamp expectation reverts to
"true" (4).
Order: 20260912T195112Z-995611104-from-.claude
Record: docs/2026-09-12-p13b-okf-bump.md
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
15 KiB
P13b — okf-bumpen v0.3.2 → v0.8.5 LANDET, stempelvakten lukket, blokk-sources lest
Dato: 2026-09-12. Ordre 20260912T195112Z-995611104-from-.claude (operatørsvar på P13-E).
Forutgående måling: docs/2026-09-12-p13-okf-pin-r761.md.
Ingen modellkall, ingen Azure, NOK 0.
§ 0 — Hva som ER målt og hva som IKKE er det
Målt i denne økten
| # | Påstand | Hvordan |
|---|---|---|
| 1 | (P1) Stempelvakten var inert på V1-formen | direkte kall på _carries_complete_ingest_stamp: true→True, yes→True, { by: …, at: … }→False |
| 2 | (P2) Alle fire bundler skriver sources i BLOKK-form |
grep -rl, hele nevneren: 4605 av 4605, 0 flat |
| 3 | Evidens-tilstand FØR: unreadable på 4605 av 4605 |
evidence_for over context_files i alle fire |
| 4 | Evidens-tilstand ETTER: present på 4605 av 4605, 4605 oppføringer |
samme kjøring |
| 5 | 27/27 importerte navn resolverer på okf 0.8.5 / guard 1.4.0 | hasattr over fem moduler |
| 6 | Suite 1582 → 1606 passed / 5 skipped | uv run pytest -q |
| 7 | Begge demo-goldener byte-uendret | shasum -a 1 av INNHOLDET |
| 8 | De sju golden-konseptfilene stemmer mot materialisatoren | de fire test_ingest_golden_*-suitene grønne |
| 9 | Seks mutasjoner, alle røde, hver med egen signatur | § 4 |
IKKE målt
- Ingen levende modell, ingen betalt kjøring. Ingenting her sier hva en modell gjør med en base hvis proveniens nå er lesbar.
- Ingen ekte ingest-kjøring mot et levende manifest utover suitens fixturer og stubber.
- Guard-kalibreringen (
_ACCEPTED_DISPOSITION = "warn") er bekreftet kun gjennomtest_ingest_content_gate_loadbearings egne dokumenter — guardens CHANGELOG holder dispositions eksplisitt utenfor semver-frysen, så et bredere korpus er uprøvd. - De fem http/sql/mcp-golden-linjene ble AVLEDET, ikke materialisert — se § 2.3.
- Den nye lesertilstanden er ikke wiret inn i
run_project.evidence_forer fortsatt en bibliotek-primitiv (B4-regelen, urørt); at 4605 dokumenter nå har en adresse endrer ingen kjøring av seg selv.
§ 1 — Premissene, målt før noe ble bygget
P1 — stempelvakten var inert
literal true : True
yes : True
V1 flow : False <-- formen okf >=0.8.5 faktisk skriver
P2 — alle fire bundler er blokkform, hele nevneren
| Base | Konsepter | sources-nøkkel |
BLOKK | FLAT |
|---|---|---|---|---|
| n100-2023 | 446 | 446 | 446 | 0 |
| n200-2024 | 1133 | 1133 | 1133 | 0 |
| n500-2024 | 270 | 270 | 270 | 0 |
| r761-2025 | 2756 | 2756 | 2756 | 0 |
| SUM | 4605 | 4605 | 4605 | 0 |
Ordren oppga «400 av de 400 første i hver». Den fulle nevneren er målt her og stemmer med tallet
llm-ingestion-okf selv oppga i sin v0.8.5-FYI (2756 + 446 + 1133 + 270 = 4605).
§ 2 — Utført, rad for rad
2.1 Rad 1 — stempelvakten (sikkerhetsbærende, FØRST)
Rød først: fire nye armer i tests/test_ingest_stamp_fail_closed_loadbearing.py; to av dem
røde mot den uendrede vakten (de to andre beskriver uendret oppførsel og var grønne, som de skal).
_claims_ingest_ownership er ny og er hele endringen: predikatet utvides fra «leses som boolsk
True» til «hevder ingest-eierskap», der booleanen er pre-V1-stavemåten.
Gjenkjenneren for den nye halvdelen er decode_flow_value — modulens ENE flow-dekoder, aldri en
andre kopi (kø-(p), og samme argument write_concept_file alt gjør for verified: skriveren nekter
nøyaktig det leseren kan lese). En verdi dekoderen REFUSERER er derfor ikke et eierskapskrav og
skrives gjennom — det er dét som holder regelen fra å kollapse til «enhver ikke-tom generated».
Ingen YAML-bibliotek innført (po har fortsatt 0 import yaml).
2.2 Rad 6–7 — pinnene
llm-ingestion-okf = { git = "…/llm-ingestion-okf.git", rev = "v0.8.5" }
llm-ingestion-guard = { git = "…/llm-ingestion-pipeline-security.git", tag = "v1.4.0" }
tag =, ikke rev =, og ikke 1.2.0 — begge P13-premissene står, og begrunnelsen er nå skrevet inn
i pyproject.toml ved siden av pinnen. pyproject.toml:40-kommentaren er rettet: okf-kjernen har
ÉN runtime-avhengighet, guarden, og det er dét som binder de to linjene sammen.
Etter uv lock && uv sync: okf 0.8.5 (64661c7), guard 1.4.0 (d19de8c), 27/27 navn.
2.3 Rad 3–5 og 8 — goldenene, assertene, prosaen, vakten
De to ingest-golden-file-filene ble regenerert av den EKTE materialisatoren og diffen er én
linje hver:
-generated: true
+generated: { by: process:okf-ingest, at: 2026-07-03T12:00:00Z }
De fem øvrige ble AVLEDET (http/sql/mcp kan ikke materialiseres utenfor testenes stubber — de
krever PORTEFOLJE_SQL_DSN respektive nettverks-opt-in), med hver bundles egen ingested-at.txt
som at-verdi. Avledningen er deretter MÅLT, ikke antatt: alle fire test_ingest_golden_*
sammenligner byte for byte mot det stubbene faktisk materialiserer, og alle fire er grønne. Hadde
tidsstempelet eller formen vært feil ett eneste sted, ville suiten stått rød.
De fire assertene på generated == "true" leser nå ÉN kilde: conftest.expected_generated_stamp (ingested_at). Fire literaler for ett emitter-faktum er fire steder en senere okf-utgivelse kan
etterlate halvrettet — det er nøyaktig slik pre-V1-formen overlevde i fire asserts til P13 målte
den. tests/test_okf.pys generated: true er BEVISST urørt: den runder en KURATERT halv-stempel
gjennom po sin egen skriver og er et annet faktum enn hva okf emitterer.
Prosa: ingest_mcp.py:29, okf.pys nekt-melding. Vakten (tests/test_okf_version_guard.py) pinner
nå 0.8.5 / 1.4.0, og nekt-meldingen er skrevet om fra «her er kostnaden ved å løfte» til «re-mål hva
denne utgivelsen EMITTERER som §7-stempel, og sjekk at _claims_ingest_ownership ser det» — fordi
en tredje stavemåte ville gjort vakten inert igjen uten at én test ble rød.
2.4 Steg 4 — blokk-sources-leseren
okf.decode_block_mappings er ny og er den ANDRE bæreren av ÉN grammatikk, aldri en andre
grammatikk: par-separatoren er kolon-MELLOMROM (_find_pair_separator), navn og verdier gjennom
unquote_scalar, duplikate nøkler nektet, og §5.2-regelen (en verified-oppføring må navngi en
aktør) gjelder her også. okf sin consume.read_sources ble LEST for formen og ikke kalt — po kaller
ingen okf-leser, som er målt og bevisst (P13 § 1a).
To nekter er BEHOLDT og er filens diskriminatorer: block-mapping (ingen - -oppføring åpnet)
og unsupported-flow. Uten dem ville en leser utvidet til «alt innrykket er oppføringer» bestått
hver positiv arm mens den fant på oppføringer dokumentet ikke har.
| Base | FØR | ETTER |
|---|---|---|
| n100-2023 (446) | 446 unreadable / 0 oppføringer |
446 present / 446 oppføringer |
| n200-2024 (1133) | 1133 unreadable / 0 |
1133 present / 1133 |
| n500-2024 (270) | 270 unreadable / 0 |
270 present / 270 |
| r761-2025 (2756) | 2756 unreadable / 0 |
2756 present / 2756 |
| SUM (4605) | 4605 / 0 | 4605 / 4605 |
Fixturen er en byte-identisk kopi av en EKTE levert konseptfil
(tests/fixtures/p13b-block-sources/n100-krav-4-2-5-1-3.md, shasum -a 1 8c2952d1…, lest fra
vegnormal-okf, aldri skrevet der). En håndskrevet tilnærming ville bevist at leseren håndterer den
formen jeg forestilte meg.
Lesing er ikke lov til å SKRIVE: materialize._render_sources i okf emitterer fortsatt flow,
og write_concept_file/verified_field nekter fortsatt nøyaktig det decode_flow_value nekter —
skriveren nekter altså fortsatt det leseren ikke kan lese, som er egenskapen rundturs-gaten finnes
for.
§ 3 — Tre funn under arbeidet
F1 — min egen leser fant på data (funnet ved å måle, ikke av en rød arm)
Første blokk-leser dekodet - { id: a, resource: x } — en blokk-sekvens hvis ITEMS er FLOW-mappinger,
SPEC-kanonisk og nøyaktig formen tests/golden/block-form-provenance skriver for verified — som
{'{ id': 'a, resource: x }'}. En nøkkel som ikke er en nøkkel, altså «oppfinn en oppføring
dokumentet ikke har»-feilen min egen docstring forbyr. Ingen arm fanget den: på verified nektet
§5.2-regelen den av en helt annen grunn, så fixturen som bærer formen var skjermet ved et uhell.
Lukket med en egen gren som sender item-et gjennom decode_flow_value, og med fire nye armer
(dekoding, rekkefølge, blandet bærer nektet, malformet item nektet). M3 er mutasjonen.
F2 — en av mine egne armer var vakuøs, funnet av min egen mutasjon
test_a_value_carrying_a_colon_is_split_on_colon_space_only påsto å bevise kolon-MELLOMROM-regelen.
M5 (separator → FØRSTE kolon) lot den stå GRØNN: første kolon i resource: https://… og i
title: N100:2023 ER den kolon-mellomrom finner, så de to reglene er enige om hver verdi formet som
en levert. Armen som faktisk skiller dem er test_an_item_with_no_pair_separator_is_refused — under
første-kolon dekodes - https://a.example/d til {'https': '//a.example/d'}, en nøkkel oppfunnet av
et URL-skjema. Armen er BEHOLDT som regresjonsvakt og OMDØPT + merket ærlig; kolon-MELLOMROM-påstanden
er flyttet til armen som bærer den.
F3 — commons-eksempelet erklærer nå noe som er usant for po
shared/skills/falsification-reviewer/references/example-evidence.json (commons, pull-only)
erklærer konsept 2 som state: unreadable, reason: block-sequence, items_seen: 2 for en SPEC §5.1
blokk-sekvens. po leser den nå som to oppføringer. Divergensen kan ikke lukkes herfra — det
krever et commons-amendment.
test_the_worked_example_round_trips_through_the_real_readers er skrevet om til å asserte
divergensen i stedet for å hoppe over den, og beholder den diskriminerende halvdelen: eksempelet
sier to oppføringer ble sett, og po sin leser returnerer nøyaktig to — så en leser som mistet en
oppføring, beholdt én, eller fant på en nøkkel som ikke er en nøkkel, faller fortsatt her.
Dette er en åpen sak for operatøren, ikke lukket av denne økten.
§ 4 — Mutasjonene
Alle mot HELE suiten, én per kjøring, restaurert fra scratchpad + shasum -c.
Grønn kontroll: 1606 passed / 5 skipped, begge goldener byte-uendret.
| # | Mutasjon | Røde | Signatur |
|---|---|---|---|
| M1 | _claims_ingest_ownership tilbake til literalene |
2 | KUN de to nye V1-stempel-armene — altså er rad 1 gatet av seg selv |
| M2 | blokk-leseren frakoblet read_provenance |
17 | hele blokk-lesersuiten + fem eldre B4-armer, altså uavhengige vitner |
| M3 | flow-mapping-item faller til par-løkka (F1-defekten) | 7 | de fire nye flow-item-armene + tre eldre |
| M4 | en frittstående innrykket linje folder inn i en OPPFUNNET oppføring | 4 | begge block-mapping-armene + to eldre dekoder-armer |
| M5 | separator = FØRSTE kolon i stedet for kolon-MELLOMROM | 1 | bare-skalar-armen ALENE — og dét er F2 |
| M6 | expected_generated_stamp tilbake til literalen "true" |
4 | nøyaktig de fire ingest-assertene som leser den ene kilden |
§ 5 — Suite-regnskap
| Node-ider | Kommentar | |
|---|---|---|
| Før P13b | 1582 passed / 5 skipped | P13s kontroll |
| Etter | 1606 passed / 5 skipped | +24 |
De 24: +4 V1-stempel-armer · +18 blokk-leser-armer · +2 B4-armer
(test_an_unreadable_document_yields_NO_tier, test_the_committed_block_form_fixture_is_now_READ).
Ikke et strengt supersett — tre node-ider er OMDØPT, ingen fjernet i substans:
| Gammelt navn | Nytt navn | Hvorfor |
|---|---|---|
test_a_block_form_document_is_unreadable_and_says_WHY |
test_an_undecodable_document_is_unreadable_and_says_WHY |
spesimenet måtte flytte; påstanden er uendret |
test_a_two_entry_block_document_yields_NO_tier |
test_a_two_entry_block_document_keeps_the_human_sign_off |
påstanden er nå den fixturen ble AUTORERT for |
test_a_value_carrying_a_colon_is_split_on_colon_space_only |
test_a_value_carrying_a_colon_survives_whole |
F2 |
Ni eksisterende armer er skrevet om, ingen svekket. Alle ni pinnet «blokkformen er uleselig» —
nøyaktig oppførselen ordren endrer. Hver av dem beholder sin påstand og har fått enten (a) et
spesimen som fortsatt er uleselig av en grunn av sitt eget (SPEC §5.2: en oppføring som navngir ingen
aktør, som holder både reason-tokenet block-sequence og et valgbart antall), eller (b) den motsatte
påstanden pinnet der den gamle sto, så retningsendringen ikke kan være stille. To av dem ble
STERKERE: multi-verified.md ble autorert for «en leser som beholder siste oppføring rapporterer
maskin-bekreftet for et konsept et menneske signerte», og den påstanden kunne ikke testes så lenge
formen var uleselig — nå asserteres rekkefølgen og human-reviewed.
§ 6 — Honesty limits
- Ingen betalt kjøring, ingen levende modell. At 4605 dokumenter nå har en lesbar adresse er en egenskap ved leseren, ikke et bevis på at noen kjøring blir bedre.
- De fem avledede golden-linjene er verifisert av testene mot stubbene, ikke av en materialisering jeg kjørte selv.
- F3 er ÅPEN. Commons-eksempelet erklærer fortsatt noe usant for po, og
shared/er pull-only. evidence_forer ikke wiret inn i kjørestien. B4-regelen står: systemet leser, kalleren avgjør. Ingenrun_project-oppførsel endres av denne økten.- Guard 1.4.0s kalibrering er bekreftet på en smal nevner (§ 0).
_claims_ingest_ownershipgjenkjenner to stavemåter. En TREDJE ville gjøre vakten inert igjen, og ingen test i suiten ville bli rød — det er dét vaktens nekt-melding nå sier høyt.- Blokk-formen er LEST, aldri SKREVET. po emitterer fortsatt ingen blokkform, og skriverne nekter den uendret.
§ 7 — Reproduksjon
# premissene
uv run python -c "
from portfolio_optimiser.okf import _carries_complete_ingest_stamp as f
print(f({'generated':'true','ingest_manifest':'m'}), f({'generated':'{ by: a, at: b }','ingest_manifest':'m'}))"
B=~/repos/vegnormal-okf/build/ferdig
for b in n100-2023 n200-2024 n500-2024 r761-2025; do
echo "$b konsepter=$(find $B/$b -name '*.md' ! -name index.md | wc -l) \
blokk=$(grep -rl -E '^sources:[[:space:]]*$' $B/$b --include='*.md' | grep -vc '/index.md$') \
flat=$(grep -rl -E '^sources:[[:space:]]*\[' $B/$b --include='*.md' | grep -vc '/index.md$')"
done
# evidens-tilstand foer/etter (samme skript, kjoert paa hver side av endringen)
# se docs/2026-09-12-p13-okf-pin-r761.md for navigasjonsmaalingen
# bumpen
uv lock && uv sync
uv run python -c "import importlib.metadata as m; print(m.version('llm-ingestion-okf'), m.version('llm-ingestion-guard'))"
# portene
uv run pytest -q # 1606 passed / 5 skipped
uv run ruff check . --exclude scratchpad
uv run ruff format --check . --exclude scratchpad
uv run mypy src
shasum -a 1 tests/golden/demo-transcript.stdout tests/golden/demo-transcript.stderr