llm-ingestion-okf/skills/okf-consume-template/references
Kjell Tore Guttormsen 17c49fc04b feat(consume): give every excerpt the name and the address an answer must cite
The pre-pass delivered the right concept and the answer could not name it.
Measured by portfolio-optimiser 2026-09-08 over three paid arms: the gold
concept came back at rank 1 of 8 on 3 of 3 bundles, and the model answered
correctly on 1 of 3, because a delivered excerpt carried `concept_id`, body
text and nothing the document is known by. The previous session measured the
same gap from the other side: the provenance it had just written into every
concept did not reach the payload at all.

`excerpt_for` now carries `title` unconditionally, and `req_number`, the SPEC
5.1 address `sources` and each locator key (`source_pages`, `source_sheet`,
`source_rows`, `source_lines`, `source_offset`) when the concept has them. A key
the producer did not write stays absent: an empty value would assert that they
wrote an empty one, which is the contract's 6.4 failure.

`sources` is read in BOTH YAML forms, on a measurement rather than a taste. K2
writes the flow form on 629 of 629 concepts; the largest N-bundle writes the
block form on 270 of 270 and carries no locator key at all, so a flow-only
reader delivers that bundle with no address whatsoever. Reading the block form
is not a licence to write it - the emission rule is untouched, because the
line-oriented parser still cannot round-trip a block list. A `sources` value
this reader cannot decode is named (`sources_unreadable`), never dropped into
the same silence as an absent one.

Contract 8 gains the requirement and the checker gains its code
(`excerpt_unnamed`, 15 rules now, was 14): an excerpt a reader cannot name is
one an answer cannot cite, whatever its rank. `req_number`, `sources` and the
locators are SHOULD, not MUST - they are conditional on the producer, and a
bundle whose concepts carry no identifier cannot deliver one.

K2 controls, same question and same k, before against a frozen copy of the tool
at b6a8c8b: the RANKING does not move - the same 8 concept ids in the same
order, identical `text_sha256`, identical `withheld`, identical denominators
(629 = 621 + 8). The FIELD is what moved: payload 108 877 -> 111 744 B
(+2.63 %), budget spent 18 606 -> 20 907 (+287.6 B per excerpt), excerpt
members 9 -> 15, 83 changed lines. The contract document's own bytes moved with
8, so the budget instrument's known-positive moves with it: 10 349 -> 12 049
measured, 10 060 -> 11 719 raw, delta 289 -> 330.

New fixture `tests/fixtures/consume-provenance`: the two address forms and a
concept carrying neither address nor identifier. Purpose-built, because the two
real bundles are complementary and neither exercises both forms.

Suite 1347 (1339 before), ruff clean, mypy src clean.

Co-Authored-By: Claude <claude-opus-5>
2026-09-08 15:01:41 +02:00
..
example-payload.json feat(consume): give every excerpt the name and the address an answer must cite 2026-09-08 15:01:41 +02:00
README.md feat(skills): a consumption-skill template with no defaults 2026-09-02 16:06:24 +02:00

References for the consumption-skill template

Two files, and they play different roles.

  • example-payload.json — a conformant payload in the shape docs/consumption-contract.md § 8 fixes. It is the known-positive for tools/okf_contract_check.py: the suite checks that this file passes, so a checker that refuses everything cannot be green. Its three excerpts carry one of each adjudication value on purpose, so that the closed set is exercised rather than asserted. The digests are real sha256 digests of the paths beside them, not of any real concept file: the example is a shape, not a bundle.
  • SKILL.md beside this directory — the template a per-corpus skill copies.

Copying the template

  1. Copy skills/okf-consume-template/ to wherever the per-corpus skill lives.
  2. Replace every <PLACEHOLDER>. None has a default; a copy with one left is unfinished, not configured.
  3. Keep every ## heading. The checker reads them by name.
  4. Point --payload at your own pre-pass output, not at this example, and run the checker in the corpus repo's test suite rather than by hand.

The checker checks shape. The division of labour (§ 2) and the prohibitions (§ 9) are properties of a run, and no static check can see them.