Et linjenummer inn i et ANNET repos fil raatner paa deres neste redigering, og denne fila skal kunne leses utenfra. Samme regel som STATE-pekere: paragraf- anker, verifisert med en grep som faktisk treffer. Co-Authored-By: Claude <claude-opus-5>
6.5 KiB
OKF consumption contracts
This file is the source. Three facts below span a producer (
llm-ingestion-okf) and this consumer, so neither side can hold the other to them from inside its own plan file. Docstrings, tests and the invariant ledger inCLAUDE.mdpoint here; they do not restate the rule. A second copy of a contract is the drift this repository has a rule against.The producer's half is recorded in that repository's
docs/plan/office-intake.md§§ 4–5 anddocs/consumption-contract.md. Ratified at programme level 2026-09-02. Written in English because the counterparty half is, and a contract split across two languages is a contract nobody reads whole.Every number below comes from a command, and each command is written next to its number.
§ 1. The falsification threshold — present and not unverified
A falsification verdict may rest on a concept only when both hold:
evidence_for(path).state == "present" AND tier != "unverified"
Everything else is reported and explicitly discounted, never silently excluded. The report
carries the triple (state, reason, items_seen): a concept that was dropped and a concept that was
read-and-discounted are different facts, and only the second is honest about what was actually read.
The threshold is expressed in exactly one place — okf.admits_falsification(evidence) -> bool.
A threshold spelled inline at each caller is a threshold nobody can find, and a second copy is free
to drift from the first.
author, usage_count and last_modified are deliberately NOT required, and the denominator is
written down rather than implied. SPEC § 5.1 names six keys on a sources entry — resource,
id, title, author, usage_count, last_modified — and the producer writes two of them:
# Grep-able anchor, never a line number — a line anchor into another repository's file rots
# on that repository's next edit, and this one has to survive being read from outside.
grep -A11 'Each `sources` entry:' ~/repos/_okf-canonical/SPEC.md # the six entry keys
grep -rh '^sources:' ~/repos/llm-ingestion-okf/examples/
# -> sources: [{ id: golden-v0-2-sales, resource: fixture }]
# (1 of the 26 markdown files under examples/ carries the key at all)
Measured 2026-09-02 against producer 62b6192. 2 of 6, not 2 of 5 — an earlier draft of this
contract carried the smaller denominator, which would have understated how much of § 5.1 the
producer leaves unwritten. Requiring the three credibility signals would make the threshold
unreachable in practice while looking strict on paper: the worst of both. The threshold names only
what is actually written.
usage_window is a sibling of sources, not an entry key, and is outside the six.
§ 2. The adjudication state — absence is unknown, never absent
A concept carries its adjudication state in the frontmatter key adjudication, whose value set
is closed: proposed or adjudicated.
| Observation | State |
|---|---|
adjudication: proposed |
proposed |
adjudication: adjudicated |
adjudicated |
| the key is not present | unknown |
| any other value | refused by name — never mapped into the vocabulary |
The third row is the whole contract. A concept that does not carry the key means we did not
learn whether this was adjudicated (an older bundle), and collapsing that into absent — it was
not adjudicated — is a verdict on missing evidence presented as evidence of absence. It is the same
defect as collapsing unreadable into absent one layer up, and the same defect the ungiven-verdict
work removed from RunResult.verdict.
The fourth row is validation, never repair: an out-of-vocabulary value is an error, not an
extension point, and mapping it to unknown would silently invent the very state this contract
exists to keep honest.
Honesty limit, stated: this consumer's fixtures are hand-written to the contract above, not
produced by llm-ingestion-okf. Integration against the producer's own golden is later work and is
not claimed here.
§ 3. Identity across bundles — the pair (bundle_id, concept_id)
A concept ID is bundle-local and stable. Identity across bundles is the pair
(bundle_id, concept_id) — never the concept ID alone.
bundle_id resolves in a fixed order, and the resolved value carries which source answered:
| Order | Source | origin |
|---|---|---|
| 1 | the concept's own frontmatter | declared-concept |
| 2 | the bundle root's index.md |
declared-index |
| 3 | neither declared it — the mount basename is used | mount-derived |
Three origins, not a boolean. A caller that cannot tell "the concept said so" from "we fell back twice" has been handed a stamp it cannot audit.
A base with no readable index.md is not "undeclared". The existing navigation fail-fast
propagates unchanged; reading an unreadable base as "no declaration" is the tolerant-read defect
that widens an answer instead of refusing it. Only a base whose index is readable and declares
nothing falls through to the next row.
Measured today: every base resolves mount-derived. No shipped index.md declares the key:
find shared -name index.md | wc -l # -> 7
grep -l 'bundle_id' $(find shared -name index.md) | wc -l # -> 0
So this contract changes which sources are consulted, not what happens when none of them declares anything — which is why adopting it moves no existing call site.
There is no cross-bundle link form. A consumer holding several bundles partitions per bundle; the producer emits no syntax for pointing from inside one bundle into another, and adding one is out of scope until a consumer states the need.
§ 4. What these three do not settle
- The wire form of
sourcesis the producer's to fix. Flow-sequence-of-mappings is the normative emission form; block form remains conformant OKF but outside the accepted subset. A known defect stands on the producer side:llm-ingestion-guard1.2.0 rejects a flow sequence of mappings forsources. That is a known producer-side gate defect, not a consumer error, and this consumer does not wait on it. - The trust tiers themselves (§ 5.3 of the SPEC) are inferred, never stored — no credibility score is written by either side.
- Nothing here wires a library primitive into a run's stdout. The reader reads; the caller decides. Both halves of that split predate these contracts and are unchanged by them.