test(accounting): row 6 sees a refusal, a second real corpus, and 34 of 34 mutants

Row 6 was GREEN with R761 100 % rejected: every element of a refused document
is booked as a coded rejection, so u = 0 and d = 0 and the bundle is empty.
`refused_whole` asks that question on its own now -- the build order asked for
an honest red there, and PM re-measured the green on 2026-09-18 with
`okf build` exiting 1 unseen.

A skipped row no longer leaves the verdict unqualified (`GATE GREEN (row 6 not
run: ...)`), and the exit code is non-zero locally when a corpus source is on
the machine and its row did not run. m-2.

N200 Vegbygging:2024 joins R761 as a second real corpus. R761 holds 0 `fig`,
0 formulas and 0 references, so the only real corpus could not have found the
hole in the STS role map; N200 carries 194 citations, 49 figures and 135
footnotes. A `.json` whose root holds an STS node tree is counted as STS
rather than as keys and leaves -- the container is not the content.

M-4: the review's 26 mutants, ported to the code as it stands, plus 8 for the
new checks. 34 of 34 killed. `tools/okf_gate_mutants.py` runs on a copy of the
tree, and a pattern that does not match is an ERROR and exit 2 -- a mutant
that could not be applied was never measured. That fired once, on M13, after a
refactor moved the line it edits.

m-3: `APPROVED_EXCEPTIONS` was read by no row, so approving one changed
nothing. Each pair is now checked against the witness's own vocabulary and the
run says why it moves no denominator. The gate also prints its OWN limits
beside the verdict, m-5 among them.

The product's accounting tests state the new truth instead of the old one:
`okf build --accounting` over the fixture corpus exits 1 with SIX unaccounted
elements in its own vocabulary -- its first real finding, reachable only now
that fixtures carry the constructs. Four shared element names disagree with
the witness, each pinned with its cause; one of the four is a double count
this package makes (a text box's paragraph, once inside the box and again in
the paragraph carrying it).

Three fixture defects were found and fixed while building them, each of which
would have reported a loss the build never had: a shared string table not
related to the workbook, a `graphicData` with no `uri`, and an odt
`styles.xml` without `<office:styles/>`.

Report: docs/2026-09-18-regnskapsgaten-herdet.md

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-09-18 02:48:34 +02:00
commit ed8d9d709f
Signed by: ktg
SSH key fingerprint: SHA256:JakMjO6FTBBzN0Bhfj9saOoEjaFxlSdYuZQQpM/lF9Q
11 changed files with 1146 additions and 85 deletions

View file

@ -120,7 +120,9 @@ def _slide(title: str, body: str, *, hidden: bool = False) -> str:
+ f"<p:txBody><a:p><a:r><a:t>{title}</a:t></a:r></a:p></p:txBody></p:sp>"
+ "<p:sp><p:nvSpPr><p:nvPr/></p:nvSpPr>"
+ f"<p:txBody><a:p><a:r><a:t>{body}</a:t></a:r></a:p></p:txBody></p:sp>"
+ "<p:graphicFrame><a:graphic><a:graphicData><a:tbl><a:tr>"
+ "<p:graphicFrame><a:graphic><a:graphicData "
+ 'uri="http://schemas.openxmlformats.org/drawingml/2006/table">'
+ "<a:tbl><a:tr>"
+ "<a:tc><a:txBody><a:p><a:r><a:t>Post</a:t></a:r></a:p></a:txBody></a:tc>"
+ "<a:tc><a:txBody><a:p><a:r><a:t>84.1</a:t></a:r></a:p></a:txBody></a:tc>"
+ "</a:tr></a:tbl></a:graphicData></a:graphic></p:graphicFrame>"
@ -141,11 +143,23 @@ _PPTX_PARTS: dict[str, str | bytes] = {
f'openxmlformats-officedocument.presentationml.slide+xml"/>'
for n in (1, 2)
)
+ '<Override PartName="/ppt/notesSlides/notesSlide1.xml" ContentType="application/vnd.'
+ 'openxmlformats-officedocument.presentationml.notesSlide+xml"/>'
+ "</Types>",
"_rels/.rels": _XML
+ '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">'
+ '<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/'
+ 'relationships/officeDocument" Target="ppt/presentation.xml"/></Relationships>',
"ppt/_rels/presentation.xml.rels": _XML
+ '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">'
+ '<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/'
+ 'relationships/slide" Target="slides/slide1.xml"/>'
+ '<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/'
+ 'relationships/slide" Target="slides/slide2.xml"/></Relationships>',
"ppt/slides/_rels/slide1.xml.rels": _XML
+ '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">'
+ '<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/'
+ 'relationships/notesSlide" Target="../notesSlides/notesSlide1.xml"/></Relationships>',
"ppt/presentation.xml": _XML
+ f"<p:presentation {_P}><p:sldIdLst>"
+ '<p:sldId id="256" r:id="rId1"/><p:sldId id="257" r:id="rId2"/>'
@ -171,6 +185,15 @@ _XLSX_PARTS: dict[str, str | bytes] = {
+ 'relationships+xml"/>'
+ '<Override PartName="/xl/workbook.xml" ContentType="application/vnd.openxmlformats-'
+ 'officedocument.spreadsheetml.sheet.main+xml"/>'
# Declaring the parts is not decoration. Without the sharedStrings
# override every `t="s"` cell converts to an EMPTY cell -- the fixture
# would have reported four cells lost that the build never lost.
+ '<Override PartName="/xl/worksheets/sheet1.xml" ContentType="application/vnd.'
+ 'openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>'
+ '<Override PartName="/xl/worksheets/sheet2.xml" ContentType="application/vnd.'
+ 'openxmlformats-officedocument.spreadsheetml.worksheet+xml"/>'
+ '<Override PartName="/xl/sharedStrings.xml" ContentType="application/vnd.'
+ 'openxmlformats-officedocument.spreadsheetml.sharedStrings+xml"/>'
+ "</Types>",
"_rels/.rels": _XML
+ '<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">'
@ -187,7 +210,12 @@ _XLSX_PARTS: dict[str, str | bytes] = {
+ '<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/'
+ 'relationships/worksheet" Target="worksheets/sheet1.xml"/>'
+ '<Relationship Id="rId2" Type="http://schemas.openxmlformats.org/officeDocument/2006/'
+ 'relationships/worksheet" Target="worksheets/sheet2.xml"/></Relationships>',
+ 'relationships/worksheet" Target="worksheets/sheet2.xml"/>'
# The shared string table is reached through the WORKBOOK's relationship,
# not by its path: without this line every `t="s"` cell converts empty and
# the fixture reports four cells lost that the build never lost.
+ '<Relationship Id="rId3" Type="http://schemas.openxmlformats.org/officeDocument/2006/'
+ 'relationships/sharedStrings" Target="sharedStrings.xml"/></Relationships>',
"xl/sharedStrings.xml": _XML
+ f'<sst {_S} count="{len(_XLSX_STRINGS)}" uniqueCount="{len(_XLSX_STRINGS)}">'
+ "".join(f"<si><t>{value}</t></si>" for value in _XLSX_STRINGS)
@ -237,7 +265,8 @@ _ODT_PARTS: dict[str, str | bytes] = {
+ '<manifest:file-entry manifest:full-path="content.xml" manifest:media-type="text/xml"/>'
+ "</manifest:manifest>",
"content.xml": _XML
+ f"<office:document-content {_ODT_NS}><office:body><office:text>"
+ f'<office:document-content {_ODT_NS} office:version="1.3">'
+ "<office:body><office:text>"
+ '<text:h text:outline-level="1">Drift av gangbruer</text:h>'
+ "<text:p>Gangbruer inspiseres hvert aar.</text:p>"
+ "<text:list><text:list-item><text:p>Rekkverk</text:p></text:list-item>"
@ -252,7 +281,8 @@ _ODT_PARTS: dict[str, str | bytes] = {
+ "</table:table-row></table:table>"
+ "</office:text></office:body></office:document-content>",
"styles.xml": _XML
+ f"<office:document-styles {_ODT_NS}><office:master-styles>"
+ f'<office:document-styles {_ODT_NS} office:version="1.3">'
+ "<office:styles/><office:master-styles>"
+ '<style:master-page style:name="Standard">'
+ "<style:header><text:p>Intern arbeidsversjon</text:p></style:header>"
+ "<style:footer><text:p>Vegdirektoratet</text:p></style:footer>"

View file

@ -0,0 +1,23 @@
{
"productInfo": {"meta": {"productTitle": "Label inside title"}},
"standardContent": {
"id": null, "tag": "#document", "a": {},
"c": [
{"e": 1, "t": null, "x": {"id": null, "tag": "standard", "a": {}, "c": [
{"e": 1, "t": null, "x": {"id": null, "tag": "body", "a": {}, "c": [
{"e": 1, "t": null, "x": {"id": null, "tag": "sec", "a": {}, "c": [
{"e": 1, "t": null, "x": {"id": null, "tag": "title", "a": {}, "c": [
{"e": 1, "t": null, "x": {"id": null, "tag": "label", "a": {}, "c": [
{"e": 2, "t": "84.1", "x": null}
]}},
{"e": 2, "t": "Toleranser", "x": null}
]}},
{"e": 1, "t": null, "x": {"id": null, "tag": "p", "a": {}, "c": [
{"e": 2, "t": "Toleranseklasse er gitt i tabell 84-2.", "x": null}
]}}
]}}
]}}
]}}
]
}
}