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

@ -247,6 +247,26 @@ and fixtures, never code.
constant rather than the clock, because a wall-clock default takes
rebuild-equals-incremental away from anyone who omits them. Arm C and
Arm D are off and not exposed here.
- Consume a bundle: `python3 tools/okf_consume.py <bundle> --question "<q>"
[--k N] [--limit N] [--out PATH] [--ref IDENTITY]` — the **pre-pass**
`docs/consumption-contract.md` § 1 defines, and the only reading direction
this library has. It lives in `tools/` for the reason
`okf_contract_check.py` states for itself: outside `src/`, so no consumer's
install surface changes because it exists. Its entry point is
`build_payload(...)` with the CLI a thin `main()`, so lifting it into `src/`
the day a consumer asks for a wheel-installed command is a move, not a
rewrite. Deterministic and offline by construction: no model call, no socket,
no clock, stdlib plus this package only. It **walks the index tree, never a
directory** — § 9.2 forbids enumerating one unless the named profile says the
index is derived, and measured, `entries_match_directory` is `True` for
`STRICT_V1` alone; the walk loses nothing (629 = 629 on the K2 bundle,
controlled in a test against the very method § 9.2 forbids). `--ref` is an
**assertion**, never an override: the emitted identity is always the computed
one, because § 3.3 exists to stop a payload being labelled with an identity
its bytes do not have. Three exit codes: 0 written, 1 refused, 2 did not run.
The first instantiated consumption skill is `skills/okf-consume/`; the
measurement behind it, including the control that FAILED, is
`docs/2026-09-07-okf-konsumskill-maaling.md`.
## Workflow