feat(consume): instantiate the K2 consumption skill, and document the pre-pass

Step 12's README section is brought forward to here because the docs gate is
right: a feat commit that ships a new command needs the command documented.
CLAUDE.md's Commands section gains the pre-pass beside `okf build`. Nothing
else moves.

Contract check against a real payload from the 629-concept bundle:

  $ .venv/bin/python tools/okf_consume.py <K2-bundle> \
      --question 'Hvordan skal prisene fylles ut?' --out /tmp/k2.json
  $ .venv/bin/python tools/okf_contract_check.py \
      --skill skills/okf-consume/SKILL.md --payload /tmp/k2.json
  conformant: 14 rules over 8 excerpts and 621 withheld entries, 0 findings
  exit=0

And the two negative controls, because a green checker proves little on its
own -- measured, it returns 0 findings on an empty payload paired with the
unfilled template:

  broken denominator identity -> NOT conformant, 2 findings, exit=1
  missing payload file        -> exit=2

Placeholder scan, known-positive first: the DOTALL scan reports 20 occurrences
on the template and 0 on this copy. The shipped example payload is generated
from the in-repo golden bundle, not from the corpus, and a test regenerates it
byte for byte. No K2 concept path or document title reaches any tracked file
here, checked with a pattern shown able to find against the bundle's own index.

Suite run after git add: 1224 passed, mypy --strict clean on 26 files,
ruff clean.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kjell Tore Guttormsen 2026-09-07 09:30:32 +02:00
commit 51735fa7a8
6 changed files with 489 additions and 0 deletions

View file

@ -102,6 +102,51 @@ reproduces the new one byte for byte. The command's own byte-identity test
compares it against the two scripts at the current commit, where the two agree
over the whole tree.
## Consume
The other direction: a bundle plus one question in, one bounded, contract-shaped
payload out.
```
python3 tools/okf_consume.py ./bundle --question "your question" --out payload.json
```
`tools/okf_consume.py` is the **pre-pass** `docs/consumption-contract.md` § 1
defines — the deterministic program that reads the bundle, ranks its concepts,
cuts them to a bounded set and emits one payload. It decides nothing about the
question; the skill that reads the payload does the judgement. It calls no
model, opens no socket, imports nothing outside the standard library and this
package, and takes no clock: the same bundle bytes and the same
`(question, k, limit)` produce byte-identical output.
It emits the § 8 shape — `contract`, `bundle` (`bundle_id` plus a
`sha256-tree:` content identity), `budget` (unit, instrument, limit, spent and a
validated known-positive), `denominators`, `excerpts` and `withheld` — and every
withheld concept names the rule that dropped it, from a closed set of six.
`considered == withheld + delivered` closes by construction, and the payload is
refused rather than reported when it does not.
Three exit codes, not two: **0** a payload was written, **1** the run happened
and refused (the budget admitted none of the concepts that answered the
question, or an asserted `--ref` contradicted the bytes), **2** the run did not
happen. Collapsing 2 into 1 would report an unread bundle as a failed cut.
`--ref` is an **assertion**, never an override — the identity is always computed
from the bytes, because labelling a payload with an identity its bytes do not
have is the one thing § 3.3 exists to prevent.
Check any payload against the skill that will read it:
```
python3 tools/okf_contract_check.py --skill skills/okf-consume/SKILL.md --payload payload.json
```
`skills/okf-consume/` is the first instantiated consumption skill: a filled copy
of `skills/okf-consume-template/` naming this pre-pass, with every per-corpus
hole replaced by a measured value. Measured 2026-09-07 on a 629-concept bundle,
hit@8 was **5 of 6** questions at rank 1 against a chance baseline of **1.35 of
6** — with one control that failed, and both are in
`docs/2026-09-07-okf-konsumskill-maaling.md` with the honesty limits stated.
## Implemented scope (v1)
The library provides three entry points for getting content into an OKF