docs(claude): the three claims v1.1 ordre A made false

`CLAUDE.md` is the file every session here reads before it reads code, so a
stale claim in it is not documentation debt -- it is an instruction. Three were
made false by the commits above and are corrected rather than left standing:

- `okf project` "owns NO flag that moves a bundle's bytes" -- it owns exactly
  one now, `--gate`, and the skill directory no longer carries the bundle id.
- `okf skill --generic` as a candidate -- the generic form is the DEFAULT, with
  `--for-bundle` as the opt-in, and the paragraph now carries why the candidate
  won rather than describing a decision that has already been taken.
- `--withheld-titles` as a live flag -- it is retired with the flat list it
  existed to name, and the paragraph carries the measurement that retired it
  plus the shape and the revision bump that replaced it.

No code and no test moves; this is the invariants file catching up with the
tree it describes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-09-21 00:09:05 +02:00
commit 8c1c28a6ac

View file

@ -584,11 +584,18 @@ and fixtures, never code.
- Type check: `mypy --strict src/`
- Folder to questionable bundle in ONE command: `okf project <folder>`
`okf build` with the package default into `<out>/.okf/<id>/` plus `okf skill`
into `<out>/.claude/skills/<id>-consume/`, `<out>` defaulting to cwd and
`<id>` to the folder name reduced to `[a-z0-9-]`. It owns NO flag that moves
a bundle's bytes and a test holds it byte-equal to `okf build`; two build
paths would leave every measurement report pinned to a bundle nobody
produces. **That invariant was FALSE from the day those two
into `<out>/.claude/skills/okf-consume-any/`, `<out>` defaulting to cwd and
`<id>` to the folder name reduced to `[a-z0-9-]`. **Since v1.1 ordre A
(2026-09-21) the skill directory does NOT carry the bundle id**, because the
skill it writes is the GENERIC one: a second bundle in the same project
reuses it instead of installing a second document saying the same thing about
different numbers. It owns exactly ONE flag that moves a bundle's bytes,
`--gate`, added the same day — the gate is a screen about whether a document
may be persisted at all, not a rule about how one is cut, and a command that
could not reach it screened by a default nothing said was a choice. Every
other `okf build` flag stays absent and a test holds the two byte-equal at
the shipped defaults; two build paths would leave every measurement report
pinned to a bundle nobody produces. **That invariant was FALSE from the day those two
flags became defaults until O6 measured it, and the test could not see it:** `cli.build`'s Python SIGNATURE defaulted
`keep_table_heading` and `sheet_section_rows` to `False` while argparse
defaulted both to `True`, and `project.create` calls `build()` as a function,
@ -1496,8 +1503,17 @@ and fixtures, never code.
and 83 is a FLOOR on the ceiling, never the ceiling. **The architecture choice
between the two shapes is the OPERATOR's**; the rows are its input. Report:
`docs/2026-09-20-mcp-to-varianter.md`.
- **`okf card <bundle>` and `okf skill --generic` are the one-to-many skill
candidate.** The card is one bundle's identity, concept count,
- **`okf skill --out <dir>` WRITES THE GENERIC SKILL, and that is the default
since v1.1 ordre A (2026-09-21); `--for-bundle` is the opt-in for the
instantiated form.** The candidate below won, on the cost the per-bundle form
actually carries: its numbers go stale the moment its bundle is rebuilt, one
copy per consuming project, and `okf card` derives the same numbers in under
a second so the generic document neither invents them nor states another
bundle's. The instantiated copy still refuses out loud (`bundle_mismatch`)
rather than answering from stale numbers — safe to keep, not enough to keep
default. Both forms now carry `## Working method` and `## Answer form`,
required by `okf check` and by the contract's SS 2.5/2.6.
- **`okf card <bundle>` and the generic skill are the one-to-many form.** The card is one bundle's identity, concept count,
conditional-field counts and whole-bundle cost as JSON, **DERIVED on every run
and never written into the bundle** -- storing it would move the bytes of all
six `examples/*/expected-bundle` trees (23 files compared byte-for-byte) and
@ -1733,17 +1749,30 @@ and fixtures, never code.
weight's gold from fused rank 18 to 1.
`docs/2026-09-08-rangeringsbom-sammensatte-ord.md` and
`docs/2026-09-10-k3-runde7-forste-spenn-og-rangeringen.md`.
The other three stay off. A FIFTH flag is not a ranking widening and is
listed apart: `--withheld-titles`
gives each `withheld` entry the concept's `title`, so a reader can see WHAT
was withheld without reading the bundle (§ 2.2 forbids going to look). The
code is 11 lines; the bytes are the reason it is off. Measured, it grows an
N500 payload 37.9 % and takes the 629-concept K2 bundle's BOOKKEEPING to
122 704 B — past the 120 000-byte limit itself — which would have made the
breaking point then published in the hand-filled K2 copy of
`skills/okf-consume/SKILL.md` ("~75 KB at 629 concepts … at roughly 8 000
concepts") false on the day it shipped. That copy was replaced by a generated
one 2026-09-11; the measurement of the flag stands.
The other three stay off.
**`--withheld-titles` IS RETIRED (v1.1 ordre A, 2026-09-21), together with
the flat `withheld` list it existed to name.** Measured on a 2313-concept
bundle of one project's own documentation: the list held **2 305 entries =
186 440 B = 65.5 % of the 284 850-byte payload**, and not one of those bytes
counted against the budget the same payload reported (`spent` 45 192) — so a
reader was handed 239 658 bytes the budget line did not know about, to learn
2 305 concept ids with nothing beside them. The flag bought the missing
field and was off because buying it for 2 305 entries cost another 37.9 %.
**`withheld` is now a MAPPING** (`CONTRACT_REVISION` = `okf-consumption/2`,
bumped so a consumer indexing the old key as a list breaks loudly):
`total` (equal to `denominators.withheld`, so SS 5.2's identity closes on the
NUMBERS), `by_rule` (the same total over the closed rule set), `nearest`
(the best-ranked drops BY NAME with title and source document, read off
`ranked` and not off `cut`'s id-sorted output, capped at
`WITHHELD_NEAREST_DEFAULT` = 20) and `complete`. Same question, same bundle,
after: **52 349 B, 18.4 % of the old file**. `--withheld-full` brings the
whole list back and is what an instrument classifying EVERY miss asks for —
the retrieval gate and `okf_consume_measure` both pass it and assert
`complete`. `--withheld-nearest N` sets the cap. Three checker rules moved
with the shape, and one is the interesting case: `parent_unfollowable` used
`excerpts` + `withheld` as the bundle's own denominator, which a truncated
block is not, so that clause runs only where the payload SAYS it is complete
— stated in SS 8.6 rather than left as a silence.
## Workflow