docs(consume): the Claude Code recipe, measured end to end on two bundles
Four questions, two bundles, one run each, in a scratch project outside this repository with a generated skill per bundle. All four passed, and zero numbers or identifiers appeared in any answer that were not in the delivered set or in the payload's own identities (62, 45 and 35 unique numeric tokens checked). The skill triggered WITHOUT being named in the prompt and selected the right one of two installed skills from the question alone, so no special invocation syntax is needed: the generated `description`, which carries the bundle id, the concept count and the ref, is enough to route on. One defect the runs found, and it was in the prose rather than the payload. The citation guidance listed the four locator keys this library writes, so on the 270-concept third-party bundle the model reported "no page locator, the address is at document level" while the excerpt in front of it carried `source_element_id` - that bundle's own locator, correctly delivered by the prefix rule. The guidance now tells the reader to cite whichever `source_*` keys are present. On the re-run the same question returned the element id. Two runs of one question, the second measuring a changed artefact and not retrying the first. One finding that is not a defect in this chain: the first attempt at a known-negative was not one. The bundle covers water and frost protection on 17 of its 270 concepts and the ranker put none of them in the cut. The consumer behaved exactly as the contract asks - refused, named its denominator, reported its own zero as unmeasured because `withheld` entries carry no titles, and did not go around the cut. Recorded as a retrieval miss rather than replaced, and it is the same shape as the open fusion finding. A correction to this session's own measurement is in the record too: a first sweep used `grep -rhoE "^source_[a-z_]+:"`, whose character class excludes digits, and so missed `source_sha256` on 270 of 270 concepts. A pattern that cannot match what it is looking for returns a zero that reads like a fact. README gains "Consume in Claude Code": folder to answer in three commands, every one of them run in this session. A test holds that the recipe invokes only scripts this repository ships, at the paths it names. Suite 1373 (1339 at the session baseline), ruff clean, mypy src clean. No version bump, no tag, no push. Co-Authored-By: Claude <claude-opus-5>
This commit is contained in:
parent
c95d18905a
commit
171798ed32
5 changed files with 477 additions and 15 deletions
61
README.md
61
README.md
|
|
@ -191,6 +191,67 @@ 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.
|
||||
|
||||
## Consume in Claude Code
|
||||
|
||||
A folder of documents to an answer a model can cite, in three commands. Every
|
||||
command below was run end to end on 2026-09-08 against a nine-document folder
|
||||
and a 270-concept third-party bundle; nothing here is untested.
|
||||
|
||||
```sh
|
||||
SRC=/tmp/c1-fresh-src # the folder of documents
|
||||
BUNDLE=/tmp/c1-fresh-bundle # where the OKF bundle goes
|
||||
PROJECT=/tmp/c1-scratch # the project you will ask the question from
|
||||
```
|
||||
|
||||
**1. Build the bundle.**
|
||||
|
||||
```sh
|
||||
okf build "$SRC" --bundle "$BUNDLE" --bundle-id c1-fresh-20260908 --okf-version 0.2 --ingested-at 2026-09-08T00:00:00Z
|
||||
```
|
||||
|
||||
**2. Generate a skill for that bundle**, straight into the project's skill
|
||||
directory. The skill is instantiated for these bytes: its id, ref, concept
|
||||
count, per-field denominators, whole-bundle cost and breaking point are all
|
||||
measured from the bundle, and it ships a reference payload the checker accepts.
|
||||
|
||||
```sh
|
||||
python3 tools/okf_skill.py "$BUNDLE" --out "$PROJECT/.claude/skills/c1-fresh-20260908-consume"
|
||||
```
|
||||
|
||||
Repeat for every bundle you want reachable; each one gets its own skill named
|
||||
after its `bundle_id`, which is what lets a model pick between them. A bundle
|
||||
you only have read access to is fine — the generator only reads it.
|
||||
|
||||
**3. Ask.** From `$PROJECT`, in Claude Code:
|
||||
|
||||
```sh
|
||||
claude -p "Hvordan skal prisene fylles ut?"
|
||||
```
|
||||
|
||||
Measured with two bundles installed side by side: the model selected the right
|
||||
skill from the question alone, ran the pre-pass and the contract check itself,
|
||||
quoted the requirement verbatim, and named the document, the requirement number,
|
||||
the source resource and the locator inside it. Across three questions, **0**
|
||||
numbers or identifiers appeared in an answer that were not in the delivered set
|
||||
or in the payload's own identities. On a question the bundle does not cover it
|
||||
answered `[sourced-not-sufficient]` and reported the denominator rather than
|
||||
inventing an answer.
|
||||
|
||||
The pre-pass and the checker are the same two commands the skill runs for you,
|
||||
if you want to see the payload first:
|
||||
|
||||
```sh
|
||||
python3 tools/okf_consume.py "$BUNDLE" --question "your question" --out /tmp/payload.json
|
||||
python3 tools/okf_contract_check.py --skill "$PROJECT/.claude/skills/c1-fresh-20260908-consume/SKILL.md" --payload /tmp/payload.json
|
||||
```
|
||||
|
||||
The honest limits: this was measured on **four questions** across two bundles,
|
||||
which is a demonstration and not a hit rate. The ranking is lexical, and one of
|
||||
the four found a topic the bundle **does** cover and did not rank it into the
|
||||
cut — the skill then said so with its denominator instead of answering, which is
|
||||
the behaviour the contract asks for, but a miss is still a miss.
|
||||
`docs/2026-09-08-claude-code-skill-vilkaarlig-bundle.md` has the runs.
|
||||
|
||||
## Implemented scope (v1)
|
||||
|
||||
The library provides three entry points for getting content into an OKF
|
||||
|
|
|
|||
372
docs/2026-09-08-claude-code-skill-vilkaarlig-bundle.md
Normal file
372
docs/2026-09-08-claude-code-skill-vilkaarlig-bundle.md
Normal file
|
|
@ -0,0 +1,372 @@
|
|||
# Connecting an arbitrary OKF bundle to Claude Code
|
||||
|
||||
**Date:** 2026-09-08. **Order:** `20260908T124346Z-4668330384` (C1).
|
||||
**Commits:** `17c49fc` (step 0), `c95d189` (the prefix rule and the generator),
|
||||
and the commit this document lands in.
|
||||
**Baseline:** `b6a8c8b`, suite 1339.
|
||||
|
||||
The question this answers is the operator's, in their own words: *"That Claude
|
||||
Code should be able to work with an arbitrary OKF bundle that we give Claude
|
||||
information about is extremely important."* Three things had to hold — build a
|
||||
bundle from a folder, connect it to Claude Code, and ask it a question whose
|
||||
answer is a document or part of one. The first existed. The second existed only
|
||||
as one skill hand-instantiated for one corpus plus a template full of holes,
|
||||
installed nowhere, never run inside Claude Code. The third was therefore not
|
||||
testable at all.
|
||||
|
||||
---
|
||||
|
||||
## 0. What was measured and what was not
|
||||
|
||||
| | measured | not measured |
|
||||
|---|---|---|
|
||||
| the excerpt fields | yes, on three bundles and two fixtures | — |
|
||||
| the `source_*` pass-through rule | yes, on the bundle that broke the allowlist | whether a fourth producer uses a key not starting with `source_` |
|
||||
| the form choice (generator vs generic skill) | yes, including a control that came out against the obvious gate | operator preference; only the mechanics are here |
|
||||
| the generator's refusals | yes, four of them, each with its code | — |
|
||||
| end to end in Claude Code | **four questions, two bundles, one run each** | a hit rate. Four questions is a demonstration |
|
||||
| the ranking | unchanged, byte-for-byte, on the K2 control | — |
|
||||
| cost per answer in tokens | — | no tokenizer on this machine; costs are in `BUDGET_UNIT` bytes |
|
||||
|
||||
---
|
||||
|
||||
## 1. Reproduction, first
|
||||
|
||||
The known-positive, before anything was changed:
|
||||
|
||||
```
|
||||
python3 tools/okf_contract_check.py --skill skills/okf-consume/SKILL.md \
|
||||
--payload <a K2 payload>
|
||||
# conformant: 15 rules over 8 excerpts and 621 withheld entries, 0 findings
|
||||
# exit 0
|
||||
```
|
||||
|
||||
Then a fresh bundle, built the way an operator would build one: nine documents
|
||||
(two spreadsheets, three word-processor files, four PDFs) copied out of the
|
||||
corpus tree into a scratch folder.
|
||||
|
||||
```
|
||||
okf build /tmp/c1-fresh-src --bundle /tmp/c1-fresh-bundle \
|
||||
--bundle-id c1-fresh-20260908 --okf-version 0.2 --ingested-at 2026-09-08T00:00:00Z
|
||||
# merged + coded rejections = 9; N = 9 (substantive 9/9, rejected 0/9)
|
||||
# 5.15 s, 0.572 s per file
|
||||
```
|
||||
|
||||
54 concepts, ref `sha256-tree:7245851d…9685f71`. The index walk reaches 54; a
|
||||
directory walk finds 55, and the one extra is `log.md`, which the walk excludes
|
||||
by name. 54 = 54, controlled.
|
||||
|
||||
One question with a known gold concept:
|
||||
|
||||
```
|
||||
python3 tools/okf_consume.py /tmp/c1-fresh-bundle \
|
||||
--question "Hvordan skal prisene fylles ut?" --out /tmp/c1-fresh-payload.json
|
||||
```
|
||||
|
||||
`considered 54 = withheld 46 + delivered 8`, `spent` 82 030 of 120 000, and the
|
||||
gold concept — the priced spreadsheet — at **rank 1**. That is the position an
|
||||
operator starts from.
|
||||
|
||||
---
|
||||
|
||||
## 2. Step 0: the excerpt carries the key the question is asked ON
|
||||
|
||||
Two independent measurements pointed at the same missing field.
|
||||
`portfolio-optimiser` ran three paid arms: the gold concept was delivered 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 it from the other side: the
|
||||
provenance it had just written into every concept did not reach the payload at
|
||||
all — nine members, not one of them provenance.
|
||||
|
||||
`excerpt_for` now carries `title` unconditionally, and `req_number`, the SPEC
|
||||
§ 5.1 address `sources`, and the locator keys when the producer wrote them. Four
|
||||
design decisions here were made by measurement rather than by taste.
|
||||
|
||||
**(a) `sources` is read in both YAML forms.** The two real bundles disagree
|
||||
completely:
|
||||
|
||||
| | flow `sources: [{...}]` | block `sources:` + indented | a locator key |
|
||||
|---|---|---|---|
|
||||
| the 629-concept procurement bundle | **629 of 629** | 0 | 618 `source_offset`, 586 `source_pages` |
|
||||
| the 270-concept normative bundle | 0 | **270 of 270** | 0 of the five this library writes |
|
||||
|
||||
`parse_frontmatter` skips indented lines on purpose — a nested `title:` arriving
|
||||
later would substitute for the document's — so the block form arrives as `''`,
|
||||
present and unreadable. A flow-only reader delivers the second bundle with **no
|
||||
address at all**. Reading the block form is not a licence to write it; the
|
||||
emission rule is untouched.
|
||||
|
||||
**(b) An undecodable address is named, not dropped.** `sources_unreadable: true`
|
||||
is a third state beside "an address" and "no address". Collapsing it into either
|
||||
reports something nobody measured.
|
||||
|
||||
**(c) An absent key stays absent.** Writing `req_number: ""` would assert that
|
||||
the producer wrote an empty identifier. Contract § 6.4 forbids exactly that
|
||||
inference, from the other direction.
|
||||
|
||||
**(d) The pass-through is a PREFIX, and this one came from a peer's
|
||||
measurement.** The first implementation used the five locator keys this library
|
||||
writes. The PM measured it against the normative bundle and found the excerpt
|
||||
still lost that bundle's locator: 269 of its 274 files carry
|
||||
`source_element_id`, a key that repository chose under this chain's own rule
|
||||
("the key says what it indexes") and that this library never writes. An
|
||||
allowlist is a list of the producers its author thought of. The rule is now
|
||||
every top-level key beginning with `source_`, and a prefix rather than a
|
||||
substring — `resource_owner` contains the literal and is not a locator.
|
||||
|
||||
*A correction to my own measurement, stated because it is the reason the peer
|
||||
had to send it twice:* my first sweep used `grep -rhoE "^source_[a-z_]+:"`,
|
||||
whose character class excludes digits, so it reported `source_element_id` and
|
||||
silently missed `source_sha256` on 270 of 270. The generator's own counting —
|
||||
over parsed frontmatter, not a regex — found both. A pattern that cannot match
|
||||
what it is looking for returns a zero that reads like a fact.
|
||||
|
||||
### The K2 control: the field moved, the ranking did not
|
||||
|
||||
Same bundle, same question, same `k`. The "before" run is a copy of the tool
|
||||
taken from `git archive b6a8c8b`, run with its own `docs/` beside it, so the
|
||||
editable install cannot leak the new code into the baseline.
|
||||
|
||||
| | before (`b6a8c8b`) | after |
|
||||
|---|---|---|
|
||||
| delivered concept ids, in order | 8 | **identical** |
|
||||
| `text_sha256` per excerpt | — | **identical** |
|
||||
| `withheld` list | 621 entries | **identical** |
|
||||
| denominators | 629 = 621 + 8 | **identical** |
|
||||
| payload bytes | 108 877 | 113 143 (+3.92 %) |
|
||||
| `spent` (`BUDGET_UNIT`) | 18 606 | 22 210 (+450.5 B per excerpt) |
|
||||
| excerpt members | 9 | **17** |
|
||||
| changed lines in the whole payload | — | 99 |
|
||||
| payload sha256 | `afb7e811…` | `c94919c4…` |
|
||||
|
||||
**It is the field, not the ranking.** Nothing about which concepts were chosen,
|
||||
or in which order, moved by one byte.
|
||||
|
||||
The contract document's own bytes moved twice while § 8 was being written, so
|
||||
the budget instrument's known-positive moved with them — by design, since a
|
||||
stale known-positive is meant to be a loud failure: 10 349 → 12 049 → **12 563**
|
||||
measured, 10 060 → 11 719 → **12 227** raw, delta 289 → 330 → **336**.
|
||||
|
||||
Contract § 8 gains `title` as a MUST with its own checker code
|
||||
(`excerpt_unnamed`, so the checker now runs **15** rules, was 14), and
|
||||
`req_number`, `sources` and the locators as SHOULD — they are conditional on the
|
||||
producer, and a bundle whose concepts carry no identifier cannot deliver one.
|
||||
|
||||
---
|
||||
|
||||
## 3. The form: a generator per bundle, chosen against a control that failed
|
||||
|
||||
Two candidates. (a) A generator that instantiates the template for one bundle.
|
||||
(b) One generic skill taking the bundle root as a runtime argument.
|
||||
|
||||
**The obvious gate does not work.** The contract checker was asked to tell them
|
||||
apart, and cannot:
|
||||
|
||||
```
|
||||
python3 tools/okf_contract_check.py --skill skills/okf-consume-template/SKILL.md \
|
||||
--payload /tmp/c1-fresh-payload.json
|
||||
# conformant: 15 rules over 8 excerpts and 46 withheld entries, 0 findings — exit 0
|
||||
|
||||
python3 tools/okf_contract_check.py --skill skills/okf-consume/SKILL.md \
|
||||
--payload /tmp/c1-fresh-payload.json
|
||||
# conformant: 15 rules over 8 excerpts and 46 withheld entries, 0 findings — exit 0
|
||||
```
|
||||
|
||||
The **unfilled template** passes against a real payload, and a skill built for a
|
||||
different corpus passes against this one's. So conformance could not decide the
|
||||
form, and any claim that "(b) fails the checker" would have been false. The
|
||||
checker reads section headings, the marking vocabulary and the payload; it does
|
||||
not read whether a number in the prose is true of this bundle.
|
||||
|
||||
**What decides it is what the skill has to state.** § 5's denominators, § 6.4's
|
||||
conditional-field list and § 7.6's breaking point are per-bundle numbers. A
|
||||
generic skill can only leave them as holes — the template's own definition of
|
||||
*unfinished* — or carry another corpus's numbers, which is worse than a gap,
|
||||
because a stated cost that is false for this bundle is a measurement failure.
|
||||
Instantiating is what makes them true.
|
||||
|
||||
Steps from "here is a bundle" to the first correct, marked answer:
|
||||
|
||||
| | (a) generator | (b) generic skill |
|
||||
|---|---|---|
|
||||
| one-time setup | 1 command per bundle | 1 copy, once |
|
||||
| typed at question time | the question | the question **and the bundle path, every time** |
|
||||
| with two bundles installed | the model selects on the skill name — **measured, it did** | nothing selects; the caller must say which |
|
||||
| per-bundle denominators | measured into the file | absent or false |
|
||||
|
||||
(a), and the deciding column is the third: the operator's requirement is
|
||||
"one *or more* bundles", and (b) has no mechanism for the "more".
|
||||
|
||||
`tools/okf_skill.py` therefore instantiates. It measures, per bundle: id, ref,
|
||||
concept count, the conditional-field table with a denominator for every field
|
||||
(the `source_*` rows **discovered** from the bundle rather than listed), the
|
||||
whole-bundle cost by the gate's own instrument, the share one measured answer
|
||||
spent, and the concept count at which the `withheld` bookkeeping alone reaches
|
||||
the limit. It also runs the index-walk-against-directory control **once, at
|
||||
generation time, never on the question path** — § 9.2 binds a consumer reaching
|
||||
for context at query time, and a build-time control is what turns "the walk
|
||||
loses nothing" into a number the skill can quote.
|
||||
|
||||
It lives in `tools/` for the reason `okf_consume.py` states for itself — outside
|
||||
`src/`, so no consumer's install surface changes — and for one more: a
|
||||
wheel-installed `okf skill` would emit a command pointing at
|
||||
`tools/okf_consume.py`, which the wheel does not contain.
|
||||
|
||||
**Red tests first, and every gate the checker lacks is one of them**: no
|
||||
placeholder survives (with the pattern shown able to find, against the template);
|
||||
the skill names its own bundle's id and ref and **not** the other bundle's; its
|
||||
commands are absolute and point at files that exist; it reports a denominator per
|
||||
conditional field; it is byte-deterministic for a given bundle and destination.
|
||||
Four refusals, each with its code: a directory with no index
|
||||
(`bundle_unreadable`), an index with no `bundle_id` (`bundle_id_missing`), a
|
||||
bundle with no concepts (`bundle_empty`), and an occupied target without
|
||||
`--force` (`target_occupied`). No model call, no new dependency.
|
||||
|
||||
---
|
||||
|
||||
## 4. End to end in Claude Code
|
||||
|
||||
Two skills installed side by side in a scratch project outside this repository,
|
||||
one per bundle. Each row is **one run**; none was repeated to get a better one.
|
||||
|
||||
```
|
||||
python3 tools/okf_skill.py <bundle> --out /tmp/c1-scratch/.claude/skills/<id>-consume
|
||||
cd /tmp/c1-scratch && claude -p "<the question>"
|
||||
```
|
||||
|
||||
| # | bundle | question | skill named in the prompt? | result |
|
||||
|---|---|---|---|---|
|
||||
| i | fresh, 54 concepts | "Hvordan skal prisene fylles ut?" | yes | **pass** |
|
||||
| ii | fresh, 54 concepts | a topic measured absent from the bundle | yes | **pass** — refused |
|
||||
| iii | third-party, 270 concepts | "Hva krever Krav 10.2—2 i N500? Gjengi det sentrale vilkåret." | **no** | **pass** |
|
||||
| iv | fresh, 54 concepts | "Hvordan skal prisene fylles ut?" | **no** | **pass** — and selected the right one of two |
|
||||
|
||||
**(i) The known-positive.** Rank 1 of 8 delivered. The answer opened by naming
|
||||
the document and the sheet, and cited the locator the previous session put into
|
||||
the concept: *"kilde `<the spreadsheet>`, ark `Prissammenstilling`, rader 1 til
|
||||
100"*. It marked with all five required literals, reported
|
||||
`considered 54 / withheld 46 / delivered 8`, named `below_k` as the rule that
|
||||
dropped a concept it flagged as possibly relevant, reproduced the budget
|
||||
known-positive (12 563 = 12 563), and ran the contract check itself: 15 rules,
|
||||
0 findings.
|
||||
|
||||
**(ii) The known-negative.** The absence was measured **before** the question was
|
||||
asked, with the query shown able to find first (`pris` matches 15 files;
|
||||
`jernbane|signalanlegg` matches 0 of 54). The answer: *"dokumentene i bundelen
|
||||
stiller ingen krav til jernbanesignalanlegg"*, marked
|
||||
`[sourced-not-sufficient]`, with its own known-positive control for the regex it
|
||||
used to check the delivered texts, and with the 46 withheld concepts named as
|
||||
`[unread]` rather than as absent. It named external standards only under
|
||||
`[unverifiable-from-bundle]`.
|
||||
|
||||
**(iii) The third-party bundle.** Measured on the tree on disk at the time:
|
||||
`vegnormal-n500-2024`, 270 concepts, ref
|
||||
`sha256-tree:673a0c2c…d6b5b3ad` — **not** the V1 tree the order named, because
|
||||
that repository landed a rebuild during the day. The gold concept came back at
|
||||
rank 1, and the answer quoted the requirement verbatim against the concept body,
|
||||
named the title and the `req_number`, the `sources` resource, the concept id and
|
||||
the excerpt digest, and stated `adjudication: unknown` and
|
||||
`trust_tier: unverified` as measured absences at the producer rather than as
|
||||
judgements about the source.
|
||||
|
||||
**One defect this run found, and it was in the prose.** The first (iii) run said
|
||||
*"the producer wrote no page locator (no `source_pages`), so the address is at
|
||||
document level"* — while the excerpt in front of it carried `source_element_id`,
|
||||
that bundle's own locator. The excerpt was right and the **skill's citation
|
||||
guidance was wrong**: it listed the four keys this library writes instead of
|
||||
telling the reader to cite whichever `source_*` keys are present. Fixed in the
|
||||
template and in both instantiated copies; on the re-run the same question
|
||||
returned *"element `id-4ca67e2f-…`"* in the source pointer. That is two runs of
|
||||
one question, and the second is a measurement of a **changed artefact**, not a
|
||||
retry of the first.
|
||||
|
||||
**(iv) The trigger control.** No skill named in the prompt, two skills installed.
|
||||
It selected `c1-fresh-20260908-consume` on the question alone, ran the pre-pass
|
||||
and the checker, and cited `source_sheet` and `source_rows` by name. So no
|
||||
special invocation syntax is needed; the generated `description` — which names
|
||||
the bundle id, the concept count and the ref — is enough to route on.
|
||||
|
||||
### Invented numbers: zero
|
||||
|
||||
Every numeric or identifier-shaped token in each answer was extracted and
|
||||
checked against a denominator stated per run.
|
||||
|
||||
| run | unique numeric/id tokens | not found in the denominator |
|
||||
|---|---|---|
|
||||
| i | 62 | **0** |
|
||||
| ii | 45 | **0** |
|
||||
| iii | 35 | **0** |
|
||||
|
||||
For (iii) the denominator is the delivered payload itself, reproduced exactly —
|
||||
the model's reported `spent` of 11 941 equals the payload rebuilt here. For (i)
|
||||
and (ii) the model composed its own question string, so its payload is not
|
||||
byte-reproducible; the denominator there is the whole bundle text **plus** the
|
||||
payload's own identities (the bundle ref, every concept-file digest, every
|
||||
delivered-text digest) **plus** the figures the skill itself supplies. A first
|
||||
pass that omitted those identities reported eight and nine "missing" tokens,
|
||||
every one of them a fragment of a correctly quoted digest — the wrong
|
||||
denominator, corrected here rather than published.
|
||||
|
||||
---
|
||||
|
||||
## 5. A finding about the ranking, not about the skill
|
||||
|
||||
The first attempt at (ii) asked the normative bundle about water and frost
|
||||
protection in a subsea tunnel. The model answered
|
||||
`[sourced-not-sufficient]`, said the relevant requirements "if they exist, are
|
||||
among these 262 withheld", and refused to go around the cut. Checked
|
||||
afterwards, **the bundle does cover it**: 17 files match `frostsikring`, 10 match
|
||||
"vann- og frostsikring", 13 match `undersjøisk`, and none of them was ranked
|
||||
into the cut.
|
||||
|
||||
So it was never a known-negative — it was a **retrieval miss**, and it is
|
||||
recorded as one rather than quietly replaced. Two things follow, and they point
|
||||
in opposite directions. The consumer behaved exactly as the contract asks: it
|
||||
did not fabricate, it named its denominator, and it reported its own zero as
|
||||
unmeasured because the `withheld` entries carry only ids and rules, no titles.
|
||||
The ranker did not: a compound Norwegian question ("vann- og frostsikring",
|
||||
"undersjøisk") was out-ranked by concepts sharing only "tunnel" and "vann". That
|
||||
belongs with the fusion work already open, and it is the same shape as the
|
||||
`MIN_SHARED_PREFIX` finding.
|
||||
|
||||
A second, smaller observation: `withheld` entries carry `concept_id` and `rule`
|
||||
and no title, so a reader who wants to know *what* was dropped cannot tell
|
||||
without reading the bundle — which § 2.2 forbids. The consumer in run (ii)
|
||||
identified this itself and reported it as unmeasured. Not fixed here; noted.
|
||||
|
||||
---
|
||||
|
||||
## 6. Suite
|
||||
|
||||
| | before (`b6a8c8b`) | after |
|
||||
|---|---|---|
|
||||
| `pytest -q` | 1339 | **1373** |
|
||||
| `ruff check src tests tools` | clean | clean |
|
||||
| `ruff format --check .` | clean | clean |
|
||||
| `mypy src` | 17 files, clean | 17 files, clean |
|
||||
|
||||
No version bump, no tag, no push.
|
||||
|
||||
---
|
||||
|
||||
## 7. Honesty limits
|
||||
|
||||
- **Four questions across two bundles is a demonstration, not a hit rate.** One
|
||||
run each; nothing was repeated to get a better answer. The one repeat is
|
||||
named, and it measures a changed artefact.
|
||||
- The end-to-end runs allowed the model a tool set (`Bash`, `Read`, `Skill`,
|
||||
`Glob`, `Grep`). Without permission to run the pre-pass the skill cannot do
|
||||
its first step, so this is not an optional flag; it is part of what was
|
||||
measured.
|
||||
- **No token figure anywhere.** There is no tokenizer on this machine, so every
|
||||
cost is in `BUDGET_UNIT` bytes. Quoting an o200k number would be repeating a
|
||||
published figure, not measuring one.
|
||||
- The generated skill's prose is thinner than the hand-instantiated copy for the
|
||||
corpus that was measured over days. It states every number it can measure and
|
||||
claims nothing it cannot; a corpus that needs more — an extension marking, a
|
||||
measured cost distribution over many questions — needs a hand-edited copy, and
|
||||
the generator refuses to overwrite one without `--force` for that reason.
|
||||
- A scratch project inherits the machine's global session-start hooks: run (i)
|
||||
ended by reporting an unrelated 17-message coordination inbox. Harmless here,
|
||||
worth knowing before anyone reads a generated answer as self-contained.
|
||||
|
|
@ -55,13 +55,18 @@ excerpt it rests on — `(bundle_id, concept_id)` and the excerpt's `sha256`.
|
|||
|
||||
**Name the document, do not merely point at it.** Each excerpt also carries
|
||||
`title`, and — when the producer wrote them — `req_number`, the § 5.1 address
|
||||
`sources`, and a locator into that address (`source_pages`, `source_sheet` with
|
||||
`source_rows`, or `source_lines`). Quote those values as they stand; they are the
|
||||
difference between "the bundle says X" and "X, from `<title>` `<req_number>`,
|
||||
`<resource>` at `<locator>`". Absent keys are absent because the producer wrote
|
||||
none — never because the source has none, and never something to fill in. An
|
||||
excerpt carrying `sources_unreadable` has an address this reader could not
|
||||
decode: say so rather than reporting no address.
|
||||
`sources`, and **every key whose name begins with `source_`**. That last one is a
|
||||
prefix and not a list: which locator a bundle uses is its producer's choice, so
|
||||
one bundle locates by `source_pages`, another by `source_sheet` plus
|
||||
`source_rows` or by `source_lines`, and another by a key this library never
|
||||
writes, such as `source_element_id`. **Read the excerpt's own keys and cite
|
||||
whichever ones are there** — do not look for a fixed set and report "no locator"
|
||||
when the one present is simply named something else. Quote the values as they
|
||||
stand; they are the difference between "the bundle says X" and "X, from
|
||||
`<title>` `<req_number>`, `<resource>` at `<locator>`". Absent keys are absent
|
||||
because the producer wrote none — never because the source has none, and never
|
||||
something to fill in. An excerpt carrying `sources_unreadable` has an address
|
||||
this reader could not decode: say so rather than reporting no address.
|
||||
|
||||
| Marking | Use when |
|
||||
|---|---|
|
||||
|
|
|
|||
|
|
@ -83,13 +83,18 @@ excerpt it rests on — `(bundle_id, concept_id)` and the excerpt's `sha256`.
|
|||
|
||||
**Name the document, do not merely point at it.** Each excerpt also carries
|
||||
`title`, and — when the producer wrote them — `req_number`, the § 5.1 address
|
||||
`sources`, and a locator into that address (`source_pages`, `source_sheet` with
|
||||
`source_rows`, or `source_lines`). Quote those values as they stand; they are the
|
||||
difference between "the bundle says X" and "X, from `<title>` `<req_number>`,
|
||||
`<resource>` at `<locator>`". Absent keys are absent because the producer wrote
|
||||
none — never because the source has none, and never something to fill in. An
|
||||
excerpt carrying `sources_unreadable` has an address this reader could not
|
||||
decode: say so rather than reporting no address.
|
||||
`sources`, and **every key whose name begins with `source_`**. That last one is a
|
||||
prefix and not a list: which locator a bundle uses is its producer's choice, so
|
||||
one bundle locates by `source_pages`, another by `source_sheet` plus
|
||||
`source_rows` or by `source_lines`, and another by a key this library never
|
||||
writes, such as `source_element_id`. **Read the excerpt's own keys and cite
|
||||
whichever ones are there** — do not look for a fixed set and report "no locator"
|
||||
when the one present is simply named something else. Quote the values as they
|
||||
stand; they are the difference between "the bundle says X" and "X, from
|
||||
`<title>` `<req_number>`, `<resource>` at `<locator>`". Absent keys are absent
|
||||
because the producer wrote none — never because the source has none, and never
|
||||
something to fill in. An excerpt carrying `sources_unreadable` has an address
|
||||
this reader could not decode: say so rather than reporting no address.
|
||||
|
||||
| Marking | Use when |
|
||||
|---|---|
|
||||
|
|
|
|||
|
|
@ -1118,6 +1118,7 @@ def test_no_corpus_document_name_reaches_any_file_this_work_tracks() -> None:
|
|||
PROJECT_ROOT / "docs" / "2026-09-08-prisform-og-loggen-k2.md",
|
||||
PROJECT_ROOT / "docs" / "2026-09-08-kravnummer-tokenisering.md",
|
||||
PROJECT_ROOT / "docs" / "2026-09-08-sjeldenhetsvekt.md",
|
||||
PROJECT_ROOT / "docs" / "2026-09-08-claude-code-skill-vilkaarlig-bundle.md",
|
||||
PROJECT_ROOT / "README.md",
|
||||
PROJECT_ROOT / "CLAUDE.md",
|
||||
]
|
||||
|
|
@ -1128,12 +1129,30 @@ def test_no_corpus_document_name_reaches_any_file_this_work_tracks() -> None:
|
|||
def test_the_readme_consume_section_states_the_rule_count_the_code_emits() -> None:
|
||||
# A published number must have a test that goes red when it goes false.
|
||||
readme = (PROJECT_ROOT / "README.md").read_text(encoding="utf-8")
|
||||
assert readme.count("## Consume") == 1
|
||||
assert readme.count("## Consume\n") == 1
|
||||
assert readme.count("## Consume in Claude Code\n") == 1
|
||||
assert len(okf_consume.WITHHOLDING_RULES) == 6
|
||||
assert "closed set of six" in readme
|
||||
assert "tools/okf_consume.py" in readme
|
||||
|
||||
|
||||
def test_the_readme_recipe_names_only_commands_this_repository_ships() -> None:
|
||||
# Every command in the "Consume in Claude Code" section was run in the
|
||||
# session that wrote it. This test cannot re-run them; what it can hold is
|
||||
# that each script the recipe invokes still exists under the path it names.
|
||||
readme = (PROJECT_ROOT / "README.md").read_text(encoding="utf-8")
|
||||
recipe = readme.split("## Consume in Claude Code", 1)[1].split("\n## ", 1)[0]
|
||||
scripts = set(re.findall(r"python3 (tools/\S+\.py)", recipe))
|
||||
assert scripts == {
|
||||
"tools/okf_skill.py",
|
||||
"tools/okf_consume.py",
|
||||
"tools/okf_contract_check.py",
|
||||
}, scripts
|
||||
for script in scripts:
|
||||
assert (PROJECT_ROOT / script).is_file(), script
|
||||
assert "okf build " in recipe
|
||||
|
||||
|
||||
# --- Step 11: the measurement scorer -----------------------------------------
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue