The release report in R6's form: premises re-measured, the one-line lockfile diff, the README lines the tag would have made false, the gates, and the acceptance gate run from a local `git archive v0.8.5` export. Two bookkeeping figures in K3-25's report corrected after re-measuring: the tests/ call denominator was 129 occurrences on 128 lines (not 112 across 13), and the outside-tests figure was 19 on 17 lines in 5 files (not 129, which was the tests/ number written into the wrong paragraph). The "exactly 1 changed result" finding is unaffected. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
15 KiB
R7: release v0.8.5
A patch release with no new functionality and one change that reaches outside
this repository: okf.parse_frontmatter is public API, and after K3-24 it
returns a flow STRING for a block sources: where it returned an EMPTY string.
The tag carries what rounds 23, 24 and 25 landed and no tag had -- K3-23's
link_in_signal instrument, K3-24's block-sources fix in all three flat
frontmatter readers, and K3-25 making the reading without the door's link line
consume's default. No behaviour change in src/ beyond the version string,
the guard pin untouched at v1.4.0, no push.
Tag: v0.8.5, local and annotated, on 64661c7 (chore(release): 0.8.5).
v0.8.4 stays on 69dc51f, v0.8.3 on 0963dfa, v0.8.2 on b6c54e9,
v0.8.1 on 3daf983 and v0.8.0 on 4d1f9d3 -- verified with
git tag --points-at, all five still resolve there.
1 What this round did, and what it did not
Did: the version on the three lines it lives on (pyproject.toml:7,
src/llm_ingestion_okf/__init__.py:79, and the package's entry in
uv.lock:550), CHANGELOG.md's ## [Unreleased] to
## [0.8.5] — 2026-09-12 with the em dash copied from the [0.8.4] head, the
five @v0.8.4 install lines to @v0.8.5, the two pairing paragraphs, the tag
history list, README's test counts and its history parenthesis, and one local
annotated tag.
Did NOT: move the guard pin, which stays at v1.4.0 on all six tracked places;
move the dependency floor >=1.2,<2.0, which R6 measured and deliberately left
standing as an operator decision; add a rule, an extractor, an arm or a flag;
move --shell-parent, --pdf-outline or --bold-title, all three still OFF
and all three operator questions with numbers already delivered; touch
skills/; rewrite docs/; or push anything.
link_in_signal's default is K3-25's delivery, not this round's. This round
releases it.
2 Premises, re-measured
Every premise the order carried was reproduced before anything was edited.
| premise | measured here |
|---|---|
| inbox empty | find ~/.claude/coord/llm-ingestion-okf/inbox/ -type f | wc -l = 0, rc 0 |
| order queue | 0 pending, 1 claimed (this order); K3-25's order already archived |
git status --short |
empty |
| HEAD | 06c057f; git log --oneline 7faa380..HEAD = exactly K3-25's three commits (3816ed5, 38320cd, 06c057f), nothing else |
| five tags stand | v0.8.0 4d1f9d3, v0.8.1 3daf983, v0.8.2 b6c54e9, v0.8.3 0963dfa, v0.8.4 69dc51f, all git cat-file -t = tag |
| remote | refs/heads/main = 150c726; all five v0.8* tags present, v0.8.4^{} = 69dc51f. R6's tag backlog is gone, so the push list is ONE line |
okf check rules |
len(contract_check.RULES) = 17 in the work tree and 17 from the tag. K3-25 added none |
| suite | 1827 collected, 1826 passed, 1 skipped, rc 0 (pytest -q and pytest --collect-only -q, repo root, [extract] installed) |
| ruff | 0.16.6, the version R4, R5 and R6 measured |
The order's line numbers had moved, as it warned: CHANGELOG.md's [0.8.4]
head is at 103, not 82, and README's fourth install line at 589, not
580. Every number used here was read off this base.
The CHANGELOG's [Unreleased] block held 5 posts under 4 headings when
this round started -- ### Added (K3-23), ### Changed (K3-25), ### Fixed
(K3-24), ### Changed (K3-24, two posts) -- counted with
sed -n '9,102p' CHANGELOG.md | grep -c '^- ' and grep -n '^### ', not read.
Gate 1 was already closed by K3-25. The order expected K3-23's Added post
to still end in "in a later round", a sentence the tag would falsify. It does
not: the post now says the recommendation was "carried out in the same
unreleased block below". The query that could find it is the joined one --
tr '\n' ' ' < CHANGELOG.md | grep -c 'in a later round' = 0 -- run beside the
known-positive tr '\n' ' ' < CHANGELOG.md | grep -c 'recommended as' = 1, so
the zero is a measurement. Nothing was edited.
Gate 2 was open and one post was written. K3-24's ### Fixed post says the
rendering "is a READING projection, not a claim that the value is writable",
but names no cost and no denominator. One post was added under ### Changed
carrying the measurement in section 7 below. It is the only post in the
[0.8.5] block this round wrote; the other five moved byte-identically,
verified by diffing the old block's non-heading lines against the new block's
(the only addition is the 13 lines of the new post; the two K3-24 ### Changed
posts appear on both sides unchanged).
The two ### Changed headings were merged into one, in the order Added,
Changed, Fixed: K3-25's post, then K3-24's two, then the new one. Each post
body moved byte-identically and no other line changed. Leaving both would also
have been legal; one was chosen because a single version block with two
identically named sections is a reader's problem, not a record.
3 The lockfile
pyproject.toml and __init__.py were corrected first, then uv lock was run
and the diff measured. Exactly one line, the okf version at uv.lock:550:
0.8.4 -> 0.8.5. No other package moved. The guard lines :546 and :578
are untouched and still carry v1.4.0. tests/test_guard_adapter.py passed
21 of 21 afterwards -- the check that uv lock did nothing to the guard it
was not asked to do.
R6's diff was four lines, three of them the pin's. This round's is one, because the pin does not move.
4 README lines the tag would otherwise make false
- The five install lines (
README.md:12,:62,:77,:589,llms.txt:9), measured on this base, not quoted from the order. - The two pairing paragraphs.
README.md:66-67and:80-81each had ONE number to correct this round, not two: the okf tag. The guard tagv1.4.0stays in both, andREADME.md:76-- the pip fallback that installs the guard -- was not touched at all. - The tag history list: a
v0.8.5row as "the current tag", written from this round's own CHANGELOG wording and carrying seventeen rules as measured here, not copied from the row above;v0.8.4demoted from "the current tag" to past by striking those three words and nothing else;v0.8.3,v0.8.2,v0.8.1,v0.8.0andv0.7.0untouched. The row makes no claim about the guard pin, so README'sv1.4.0count stays at 4. - The test counts (
:950-952): 1783/1782/1 of 2026-09-11 to 1827/1826/1 of 2026-09-12, both measured here. - The sentence that follows them -- "the figure published before the
v0.8.2release was the PASSED count, andpytest --collect-only -qreported one more" -- was left standing, because it is still true on this round's numbers: 1827 is exactly one more than 1826, and the one is the skip. - The history parenthesis: 1783 becomes a past leg ("through the
v0.8.4release, after K3-22 and K3-21") and the current figure becomes thev0.8.5release's, after K3-23, K3-24 and K3-25. Changing only the date would have made the previously published figure disappear rather than become history.
tests/test_docs_promises.py (5 of 5) and tests/test_packaging.py
(6 of 6) were run after the README and version edits, both green.
5 Two bookkeeping figures in K3-25's report
Both were re-measured rather than taken from the order, and both were wrong in the published file.
- Paragraph 2 said
tests/holds 112 call occurrences of the four functions across 10 files, of which 13 pass the parameter. Measured: 129 occurrences on 128 lines across 10 files, with 20 lines passinglink_in_signal=. The substantive finding -- exactly 1 changed result -- stands, and1 of 112became1 of 129. - Paragraph 5 said 129 hits outside
tests/. Measured: 19 occurrences on 17 lines across 5 files. The 129 is thetests/figure written into the wrong paragraph. Of the 19, 8 fall outsideconsume.py: one is prose inCLAUDE.mdand four are that report counting itself.
Both corrections name what the wrong number actually was, so a reader meeting the old figure elsewhere can place it.
6 The gates
Run after git add and after the commit, never before:
| gate | result |
|---|---|
ruff check src tests tools |
All checks passed (ruff 0.16.6) |
ruff format --check . |
132 files already formatted |
mypy src |
Success: no issues found in 21 source files |
pytest -q |
1826 passed, 1 skipped, rc 0 |
Grep criteria, each with a control:
| query | result |
|---|---|
grep -n 'okf\.git@v0\.8\.4' README.md llms.txt |
0 hits, rc 1 |
grep -c 'okf\.git@v0\.8\.5' … |
README 4, llms.txt 1 = 5 -- the known-positive that makes the zero above a measurement |
grep -n 'v0\.8\.4' README.md llms.txt |
2, both named: README.md:102 the tag-history row, README.md:959 the history parenthesis. Not 0, and not to be made 0 |
grep -n 'v1\.4\.0' pyproject.toml uv.lock README.md |
pyproject 1, uv.lock 2, README 4 -- unmoved, which is what says the pin was not touched |
grep -n 'v1\.3\.0' pyproject.toml README.md llms.txt |
0 hits, rc 1 |
grep -rn 'v0\.7\.0|0\.7\.0' README.md docs llms.txt CLAUDE.md | wc -l |
35 lines over 8 docs/ files -- unchanged. README's one hit is the v0.7.0 tag-history row and stays |
7 The acceptance gate: installation FROM THE TAG
Local export only. git archive v0.8.5 | tar -x into
/private/tmp/okf-r7-scratch/r7-install/export, then
uv sync --frozen --extra extract (plain --frozen drops [extract] and
mypy src falls on pdfplumber). No uv tool install, no --force, no
uninstall: the operator's own okf at /Users/ktg/.local/bin/okf was read and
left alone. Everything below ran from <export>/.venv/bin/.
| row | denominator | result |
|---|---|---|
| version | 1 | importlib.metadata.version('llm-ingestion-okf') = 0.8.5 |
| guard version | 1 | llm-ingestion-guard = 1.4.0, unmoved |
uv lock --check |
1 | rc 0, captured directly |
contract_check.RULES |
1 | 17, equal to the work tree's |
okf check on the shipped skill |
1 | rc 0, conformant: 17 rules over 3 excerpts and 0 withheld entries, 0 findings |
okf project on the five-document folder |
5 documents | 26 concepts, 52 md files, 0 of 5 left out -- R6's numbers to the unit |
| HTML corpus | 828 documents | proposed 828 plan(s); 0 document(s) with no boundary; 0 unreadable, 6 015 md |
| R761 XML | 110 source files, 1 at top level | 2 761 concepts over 2 737 directories, of which 11 and 12 hold two each; document directory is r761-prosesskoden/, not the UUID |
| hit@1 / @8 / @50 on R761 | N = 6 scored of 8 asked | 6/6 · 6/6 · 6/6 |
| known-positive rank | 1 | rank 1 at the default k and rank 1 at k 50 |
| known-negative (K3-17) | 1 question | rank 1 = the RITB section (6 793 B), rank 2 = «Prøvedrift» (10 590 B); both concepts present and delivered |
block sources: read to 0 empty |
4 605 files | see below |
| the flow string through PyYAML | 4 605 files | see below |
The hit@1 row matters more this round than last, because K3-25 makes
link_in_signal=False the default and that is a ranking change on a published
payload form. K3-23's claim was that none of the five shipped bundles carries
the door's link line, so the row should not move. It did not: every S1-S6 row
is rank 1, the known-positive is rank 1 at both k, and S1's spent is
31 031 -- the value STATE records for the default reading.
The four bundles, read from the tag's bytes. Source directory, named
because it is not named in K3-24's report:
/Users/ktg/repos/vegnormal-okf/build/ferdig/. Chosen after verifying its
denominators against K3-24's table first: files carrying a frontmatter block
are 2 757 / 447 / 1 134 / 271 for r761-2025, n100-2023, n200-2024,
n500-2024, exactly K3-24's. Of those, the ones carrying a BLOCK sources:
are 2 756 / 446 / 1 133 / 270 = 4 605. All three flat readers
(materialize.parse_frontmatter, structure._split_frontmatter,
profiles._split_frontmatter) return a non-empty value on 0 empty of each,
reading nothing but the bundles.
The known-positive control for that zero. The same read with v0.8.4's
flat reader (git archive v0.8.4 src/llm_ingestion_okf into scratch,
sys.path.insert) returns EMPTY on 2 756 / 446 / 1 133 / 270 -- 4 605 of
4 605, K3-24's before-numbers to the file. The instrument can find, so the zero
is a measurement.
The reservation, measured and not asserted. The string
parse_frontmatter now returns for a block sources: was passed to
yaml.safe_load on each of the same 4 605 files. It is read back on 0 of
4 605. The reason is visible in one value:
[{ resource: https://…/api/nisosts/859990?languageCode=nb, title: N500:2024 }]
The ? opening the query string ends the flow scalar, and PyYAML raises
ParserError while parsing a flow mapping. So the fix is an improvement for a
consumer who read the empty value and concluded the address was absent, and a
REGRESSION for a consumer who passed the return value straight to a YAML
reader: they now get a parse error where they got something empty that parsed.
The emitter materialize._render_sources still writes flow, so no bundle bytes
move. PyYAML 6.0.3 is a dev dependency and the export carries it; this row was
measured with the export's interpreter, and reproduced identically with the
work tree's.
8 Honesty limits
- One machine, one interpreter, a LOCAL export. The installation is
measured on one Intel Mac from
git archive v0.8.5, not from the Forgejo tag, which does not exist until the operator pushes. It is not a portability claim and not a claim that the channel works. okf project's 26 is ONE corpus of five documents -- a regression control, not a sample.- 828 of 828 and 2 761 of 2 761 are ONE publisher's files from ONE product.
- hit@1 and the known-positive rank are 6 scored questions and ONE known-positive on ONE bundle, against a fasit someone else set.
- The known-negative is ONE constructed question on ONE small bundle.
- The four bundle rows are ONE producer's four bundles from ONE generator. "0 empty" says nothing about a bundle someone else built, and the directory they were read from is named above because K3-24's report does not name it: the denominators match K3-24's table, which is the evidence it is the same material, not a certificate that it is the same directory.
- The grep criterion is deliberately NOT "0 hits on
v0.8.4". Two occurrences remain and must. The zero onokf.git@v0.8.4ran beside a known-positive that returned 5, so it is a measurement and not a query that could never match. okf.parse_frontmatterCHANGES PUBLIC READ BEHAVIOUR. A consumer who passed its return value forsourcesto a YAML reader and got something empty that parsed now gets a parse error: PyYAML reads the returned string back on 0 of 4 605 block files. That is a regression for them even though it is a fix for everyone who read the empty value as an absent address. It is stated here, in the CHANGELOG and in the tag-history row, because a release that sells a read fix without saying who it costs lies by omission.- "The tag installs" is not "the tag is correct". No functionality is verified here beyond what K3-23, K3-24 and K3-25 already measured; the rows above prove the exported bytes run and reproduce the counts the repository already published.