Arm C changed the proposal on 6 of the 12 sampled documents and moved the K3 category counts by ZERO. Both arms: too coarse 8, too fine 4, duplicate 0, correct 0. That is the finding, not a null result -- the size rule makes concepts smaller, which is what the consumer asked for, and K3 does not measure size. It asks whether a boundary falls where a unit of knowledge begins, and an arithmetic cut does not know where one begins. Blind second rater per arm, n_blind = 6, two separate raters so an arm C rating cannot anchor on an arm B one: 5/6 in each arm, and the two blind raters' own six-document counts are identical to each other. The single disagreement is the same document as the baseline's -- with the roles reversed, and resolved by a specific offset in one direction and a general impression in the other, exactly as the baseline described. The `too coarse` count is still a floor. Reported rather than smoothed: this first rater records 8/4/0/0 on the same arm B proposals the 2026-09-02 baseline scored 7/3/1/1. The proposals did not change; the rater did, and both differences are traced. What did move, and is not K3: max concept body 217 472 -> 19 988, concepts over 100 000 characters 4 -> 0, documents proposing nothing 11/39 -> 6/39, concepts 629 -> 680. Found while measuring, not looked for: Bilag 9.1 -- the largest concept in the bundle and the one the consumer flagged -- is an EXTRACTION failure. 95.1 % of its 217 470 characters are (cid:N) glyph codes and 98 alphabetic words of 4+ letters survive in the whole document. Arm C divides unreadable text into 14 pieces of unreadable text. Its verdict in both arms rests on document identity, not on readable content. The bundle a consumer is running against right now is byte-unchanged: whole tree, 1108 files, sha256 9cd74519... before and after. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
318 lines
16 KiB
Markdown
318 lines
16 KiB
Markdown
# K3 with Arm C beside the baseline, 2026-09-04
|
|
|
|
Two numbers on the same footing, so a threshold can be set afterwards. **No
|
|
threshold is set here**, and none is implied: the K3 method
|
|
(`docs/2026-09-02-k3-k4-k5-metode.md`) declares none, and inventing one inside
|
|
the work that produces a measurement is fitting the bar to the number.
|
|
|
|
Counts only. The corpus is public procurement material, but nothing here needs
|
|
a document body or a full filename list to be checkable.
|
|
|
|
## Arm C is not defined upstream of this document
|
|
|
|
`docs/2026-09-02-k3-k4-k5-metode.md` contains **zero** occurrences of the word
|
|
"arm" (`grep -c -i "arm"` -> `0`). Neither Arm A nor Arm B nor Arm C is defined
|
|
there. Where the three names actually occur:
|
|
|
|
| arm | where it is named | what it says |
|
|
|-----|-------------------|--------------|
|
|
| A | `docs/2026-08-29-konverteringsarmen-arm-a.md:1` | "Conversion arm (arm A): pandoc vs markitdown vs docling" |
|
|
| B | `tests/test_segmented_inbox.py:509`, a code comment | "arm B cannot execute without this" |
|
|
| C | `docs/2026-09-03-k2-bundle-rebuild.md:171` | "Reported, not fixed: Arm C is its own decision." |
|
|
|
|
So Arm C had no definition to conform to. **The definition measured here is
|
|
this document's own** and is marked as such everywhere it appears, including in
|
|
the tool's `--help`:
|
|
|
|
> **Arm C** = Arm B's mechanical rules, plus one deterministic rule that cuts
|
|
> any proposed span longer than a declared cap at the nearest paragraph
|
|
> boundary at or before it, the whole document counting as one span when the
|
|
> rules find no boundary at all.
|
|
|
|
One rule and not two, deliberately. The two failure modes
|
|
`docs/2026-09-03-k2-bundle-rebuild.md` measured -- a PDF with no outline
|
|
(Bilag 9.1, 217 472 characters) and a PDF whose headings are its table of
|
|
contents so the trailing segment absorbs the body (Bilag 3.1, Bilag 1) -- are
|
|
the same failure of size, and a second rule aimed at each would confound which
|
|
one moved the number.
|
|
|
|
**What Arm C deliberately does not change:** the region before the first
|
|
candidate is still covered by no segment. That is a real coverage defect -- the
|
|
baseline's blind rater named it -- and fixing it here would have put two
|
|
changes behind one measurement.
|
|
|
|
### The cap, declared before any Arm C proposal was judged
|
|
|
|
`max_segment_chars = 20000`, fixed from Arm B's own output and not from a K3
|
|
outcome:
|
|
|
|
- Arm B's segment-body sizes over the whole K2 bundle, `n = 629` concepts:
|
|
p50 441, p75 1 215, p90 2 972, p95 6 099, mean 2 698, max 217 472.
|
|
- 20 000 is ~3.3x that p95, so what Arm B already produces is left alone:
|
|
measured **15 of 629** concepts (2.4 %) exceed it.
|
|
- At the corpus's measured ~2.20 characters per token, 20 000 characters is
|
|
~9 100 tokens -- an order of magnitude below the 100 000-token line that
|
|
motivated the rebuild.
|
|
|
|
**No sensitivity sweep was run.** Sweeping the cap and keeping the value that
|
|
produced the best K3 number would fit the parameter to the verdict.
|
|
|
|
## The standard profile did not move
|
|
|
|
`--max-segment-chars` defaults to `0`, which is off. A test writes the artifact
|
|
with and without the flag at `0` and compares bytes.
|
|
|
|
The bundle a consumer is running against was hashed before the work started and
|
|
again after the Arm C bundle was built, whole tree, 1108 files:
|
|
|
|
```
|
|
find K2-bundle-20260903 -type f | sort | xargs shasum -a 256 | shasum -a 256
|
|
9cd745194346cda0c70eab9c7136fa44506203bbe85bc17d7eff2766c6e9b4d1 (before)
|
|
9cd745194346cda0c70eab9c7136fa44506203bbe85bc17d7eff2766c6e9b4d1 (after)
|
|
```
|
|
|
|
Arm C was built to its own output: `K2-bundle-armc-20260904/`, plans in
|
|
`K2-plans-armc-20260904/`.
|
|
|
|
## K3, the two numbers side by side
|
|
|
|
Same 12 documents, same canonical hash order, same four categories, same
|
|
tie-break (coarse before fine before duplicate). First rater
|
|
`claude-opus-5/okf-session-89`, labels written to file before any blind rating
|
|
was read.
|
|
|
|
| category | arm B (baseline) | arm C |
|
|
|------------|------------------|-------|
|
|
| too coarse | 8 | 8 |
|
|
| too fine | 4 | 4 |
|
|
| duplicate | 0 | 0 |
|
|
| correct | 0 | 0 |
|
|
|
|
Both sum to `n = 12`. No replacement was needed; the reconstructed sample is
|
|
the baseline's own -- a known-positive check, **4 of the 12 have an empty
|
|
Arm B proposal**, which is what `docs/2026-09-02-k3-k4-k5-baseline.md` reported.
|
|
|
|
**Arm C changed the proposal on 6 of the 12 documents and moved the category
|
|
counts by zero.** That is the finding, not a null result: the size rule makes
|
|
concepts smaller, which is what a consumer asked for, and K3 does not measure
|
|
size. K3 asks whether a boundary falls where a unit of knowledge begins, and an
|
|
arithmetic cut does not know where one begins.
|
|
|
|
### This first rater does not reproduce the 2026-09-02 baseline row
|
|
|
|
The 2026-09-02 baseline recorded 7 / 3 / 1 / 1 on the same twelve Arm B
|
|
proposals. This session's first rater records **8 / 4 / 0 / 0**. The proposals
|
|
did not change; the rater did. Two of the differences are traceable:
|
|
|
|
- The baseline's single `correct` was contested by its own blind rater, who
|
|
named a chapter absorbed into the preceding segment and an introduction
|
|
covered by no segment. That document is `Bilag 3.8 - Overvannsutredning`, and
|
|
this rater checked at that resolution: its chapter 2 (`Planlagt situasjon`,
|
|
offset 6325) lies wholly inside the span 4064-6886 of the segment opened by
|
|
section 1.3. Rated **too coarse**.
|
|
- The baseline's single `duplicate` is not reproduced. Where a table-of-contents
|
|
line and a body heading produce two segments with the same title, this rater
|
|
read the two as different content -- a contents listing is not the section it
|
|
lists -- so `too fine` rather than `duplicate`.
|
|
|
|
The baseline said its `too coarse` count was **a floor rather than an
|
|
estimate**. This re-rating is consistent with that and does not overturn it:
|
|
same-family raters, small `n`, and a difference in reading rather than in
|
|
evidence.
|
|
|
|
## Blind second rater, per arm
|
|
|
|
`n_blind = 6` per arm: positions 0, 2, 4, 6, 8, 10 of the sample's canonical
|
|
hash order. Two separate raters, one per arm, each in its own context, each
|
|
given only the proposals, the source evidence, the four category definitions and
|
|
the tie-break -- and neither given the other arm, so an arm C rating cannot
|
|
anchor on an arm B one.
|
|
|
|
| arm | agreement | the one disagreement |
|
|
|-----|-----------|----------------------|
|
|
| B (baseline) | **5/6** | position 6, `Bilag 3.8 - Overvannsutredning` |
|
|
| C | **5/6** | position 6, the same document, the same proposal |
|
|
|
|
The two arms agree with their blind raters at the same rate, and the blind
|
|
raters' own six-document counts are identical to each other: 4 too coarse,
|
|
1 too fine, 1 correct, in **both** arms. Two rater instances that never saw
|
|
each other's arm reached the same distribution -- which is the same headline as
|
|
the twelve-document counts, reached independently.
|
|
|
|
**The disagreement is the same document as the baseline's, with the roles
|
|
reversed.** On 2026-09-02 the first rater called `Bilag 3.8` correct and the
|
|
blind rater called it too coarse. Here the first rater calls it too coarse and
|
|
both blind raters call it correct, on the grounds that "the six segments track
|
|
the document's own numbered subsections (1.1-1.3, 3.1-3.3), each opening
|
|
exactly at its heading."
|
|
|
|
That is true and it is not the whole document. The first rater's evidence is
|
|
narrower and checkable: the document's chapter 2, `Planlagt situasjon`, opens at
|
|
offset 6325, and the segment opened by section 1.3 spans 4064-6886 -- so
|
|
chapter 2 lies wholly inside it and has no segment of its own. Both arms
|
|
propose this identical segmentation, because the document is under the cap and
|
|
Arm C left it untouched.
|
|
|
|
**The asymmetry is the finding, not the ratio.** In both the baseline and this
|
|
run, the disagreement was resolved by a specific offset in one direction and by
|
|
a general impression in the other, and the specific direction was always
|
|
`too coarse`. That is what the baseline meant by calling its `too coarse` count
|
|
a floor. It is still a floor.
|
|
|
|
**No verdict is revised.** A first rater who edits a label after reading the
|
|
second rater's is not being second-rated at all.
|
|
|
|
**Cohen's kappa is deliberately not reported**, for the reason the method gives:
|
|
at four categories and `n_blind = 6` a chance-corrected statistic would look
|
|
more rigorous than percent agreement while being less informative.
|
|
|
|
**The independence caveat stands and is not softened.** All raters here are
|
|
instances of the same model family, so agreement overstates independence,
|
|
probably substantially.
|
|
|
|
## What did move, with denominators
|
|
|
|
Nothing in this section is K3. It is reported because it is what the consumer's
|
|
finding was actually about.
|
|
|
|
| figure | arm B | arm C |
|
|
|--------|-------|-------|
|
|
| documents with something to propose | 28/39 | 33/39 |
|
|
| documents proposing nothing | 11/39 | 6/39 |
|
|
| proposed entries | 618 | 674 |
|
|
| concepts in the bundle | 629 | 680 |
|
|
| `index.md` files | 478 | 483 |
|
|
| concepts carrying `adjudication` | 618/629 | 674/680 |
|
|
| concept body characters, median | 441 | 510 |
|
|
| concept body characters, max | **217 472** | **19 988** |
|
|
| concepts over 100 000 characters | 4 | **0** |
|
|
| concepts over 20 000 characters | 15 | **0** |
|
|
| wall time, whole run | 784.29 s | 820.55 s |
|
|
|
|
Door-level counts are unchanged, as they must be -- Arm C touches segmentation,
|
|
not extraction: `N = 43`, merged 39/43, coded rejections 4/43
|
|
(`extractor_unknown` 3, `extractor_empty_pdf` 1), run exited `0`.
|
|
|
|
The 6 documents that still propose nothing under Arm C are the ones already
|
|
under the cap. Arm C fires on size; where size is not the problem it has nothing
|
|
to say, and a one-entry plan would only dress a single concept in a plan file.
|
|
|
|
### The three documents the order named
|
|
|
|
Concept bodies in the two bundles, not plan spans:
|
|
|
|
| document | arm B concepts | arm B largest | arm C concepts | arm C largest |
|
|
|----------|----------------|---------------|----------------|---------------|
|
|
| Bilag 3.1 | 34 | 180 604 | 43 | 19 946 |
|
|
| Bilag 1 | 18 | 142 667 | 27 | 19 920 |
|
|
| Bilag 9.1 | 1 | 217 472 | 14 | 19 988 |
|
|
|
|
## A finding this measurement did not go looking for
|
|
|
|
**Bilag 9.1 -- the largest concept in the bundle, and the one the consumer
|
|
flagged -- is an extraction failure, not a segmentation failure.** Measured on
|
|
its extracted text: **95.1 %** of the 217 470 characters are `(cid:N)` glyph
|
|
codes (27 978 of them), and **98** alphabetic words of four or more letters
|
|
survive in the whole document. The PDF's fonts carry no usable ToUnicode
|
|
mapping, so the text this repository persisted is very largely undecodable.
|
|
|
|
This bounds what any arm can claim about that document. Its category in both
|
|
arms rests on document identity -- an agreement that is transferred, plus
|
|
attachments -- and not on readable content, so it contributes one count to each
|
|
arm and no evidence that discriminates between them. Arm C divides unreadable
|
|
text into 14 pieces of unreadable text.
|
|
|
|
Reported, not fixed. A CID-mapped PDF is an extraction question, and the
|
|
extraction warning this library already emits ("figures are not represented")
|
|
does not cover it: this document's *prose* did not survive either.
|
|
|
|
## What this does not measure
|
|
|
|
- **No threshold**, on K3 or anything else. Two numbers, so the operator can set
|
|
one.
|
|
- **K4 and K5 are untouched.** No adjudication timing was re-run and no SPEC
|
|
§ 5.1 provenance was re-counted; the baseline's figures stand.
|
|
- **Arm C's bundle was not re-measured against the consumption contract**, and
|
|
its rebuild-equals-incremental property was not re-run. Both are properties of
|
|
the harness, unchanged by this flag.
|
|
- **`pptx`, `odt`, `rtf` still have denominator 0** in this corpus. Unmeasured,
|
|
not passing.
|
|
- The cap was **not swept**. One value, declared first, measured once.
|
|
|
|
## Reproducing
|
|
|
|
```
|
|
PLANS=~/corpora/okf-telling-20260829/K2-plans-armc-20260904; mkdir -p "$PLANS"
|
|
i=0
|
|
for f in ~/corpora/okf-telling-20260829/K2/trinn1/*; do
|
|
i=$((i+1)); b=$(basename "$f")
|
|
.venv/bin/python tools/okf_propose_segments.py "$f" \
|
|
--out "$PLANS/$(printf '%02d' $i).json" \
|
|
--path-prefix "${b%.*}" --proposed-at 2026-09-04T00:00:00Z \
|
|
--max-segment-chars 20000
|
|
done
|
|
.venv/bin/python tools/okf_corpus_run.py \
|
|
--corpus ~/corpora/okf-telling-20260829/K2/trinn1 \
|
|
--report ~/corpora/okf-telling-20260829/K2-bundle-armc-20260904-report.md \
|
|
--bundle ~/corpora/okf-telling-20260829/K2-bundle-armc-20260904 \
|
|
--ingested-at 2026-09-04T00:00:00Z --plans-dir "$PLANS" \
|
|
--bundle-id k2-trinn1-armc-20260904 --okf-version 0.2
|
|
```
|
|
|
|
Converter as the harness resolved it: the vendored `pypandoc` binary, version
|
|
**3.9** -- not the host's 3.10.2.
|
|
|
|
## Appendix: the twelve raw verdicts, both arms
|
|
|
|
Blind-subset positions are marked `*`; those six are the ones with a second
|
|
rater. Documents are named by their short corpus label.
|
|
|
|
| pos | document | arm B | arm C | arm B blind | arm C blind |
|
|
|-----|----------|-------|-------|-------------|-------------|
|
|
| 0 * | Bilag 9.1 (Avtale som tiltransporteres) | too coarse | too coarse | too coarse | too coarse |
|
|
| 1 | Bilag 3.2.2 (RIG-R02 geoteknisk) | too coarse | too coarse | - | - |
|
|
| 2 * | Bilag 1.1 (Generelle tekniske krav) | too coarse | too coarse | too coarse | too coarse |
|
|
| 3 | Bilag 7 (Prisskjema, `xlsx`) | too coarse | too coarse | - | - |
|
|
| 4 * | Vedlegg 5 (Begrunnelse for krav) | too coarse | too coarse | too coarse | too coarse |
|
|
| 5 | Vedlegg 3 (Erfaringsoversikt) | too fine | too fine | - | - |
|
|
| 6 * | Bilag 3.8 (Overvannsutredning) | too coarse | too coarse | **correct** | **correct** |
|
|
| 7 | Bilag 1.3 (BIM-manual) | too fine | too fine | - | - |
|
|
| 8 * | Bilag 3.4 (Premissdokument bygningsfysikk) | too coarse | too coarse | too coarse | too coarse |
|
|
| 9 | Bilag 5 (SHA-plan) | too coarse | too coarse | - | - |
|
|
| 10 * | Vedlegg 1 (Soknadsbrev) | too fine | too fine | too fine | too fine |
|
|
| 11 | Dokument for avtaleinngaelse | too fine | too fine | - | - |
|
|
|
|
The six documents whose arm B and arm C proposals are **byte-identical** are
|
|
positions 5, 6, 7, 9, 10 and 11: each is under the cap, so Arm C left it
|
|
untouched and the two verdicts are the same judgement of the same artifact, not
|
|
two judgements that happened to agree. The six Arm C proposals that are
|
|
genuinely new are positions 0, 1, 2, 3, 4 and 8 -- and **none of them changed
|
|
category**.
|
|
|
|
The first rater's evidence, per position, in one line each:
|
|
|
|
- 0 -- 14 size-cut parts of a document whose text is 95.1 % undecodable; see
|
|
the finding above. Arm B emitted it as one 217 470-character concept.
|
|
- 1 -- entry 20 fuses section 5.2, chapter 6 and the appendices (22 281
|
|
characters); Arm C shortens that entry to 17 756 and adds a 4 525-character
|
|
part, and the fusion is still there.
|
|
- 2 -- nine numbered chapters, listed in the document's own contents, in one
|
|
concept; Arm C cuts at a page footer at ~19 164, fusing roughly six chapters
|
|
then three.
|
|
- 3 -- one entry over `F.1 Prissammenstilling`, the maintenance-agreement table,
|
|
`F.2 Regningsarbeider` and the options table; Arm C's seven parts align with
|
|
none of those four, and its first entry is a 34-character sliver.
|
|
- 4 -- background, the quoted regulation and the assessment in one concept;
|
|
Arm C's cut separates the appendix table but leaves the three fused.
|
|
- 5 -- three reference forms shredded into 21 entries.
|
|
- 6 -- chapter 2 absorbed into the span of section 1.3; see the blind-rater
|
|
disagreement above.
|
|
- 7 -- nine spurious segments cut out of the table of contents, above 36 body
|
|
segments that do track the document.
|
|
- 8 -- 24 pages in one concept; Arm C's three parts break a sentence across
|
|
parts 2 and 3.
|
|
- 9 -- entry 5 fuses chapters 2, 3, 4, 5, 6 and the appendix (8 853 characters),
|
|
and entry 1 is a fragment of the table of contents.
|
|
- 10 -- the checklist table cut into 13 fixed-size slices.
|
|
- 11 -- the agreement's own head (offsets 0-793) covered by no segment, and the
|
|
signature table emitted as two fragments.
|