| 1 |
The base install talks to nothing. No model provider, database driver or HTTP client. |
| 2 |
One Fact class for edges and properties. |
| 3 |
Spans are character offsets, not quoted strings. A span either resolves to its text or it does not, and checking is free. |
| 4 |
Everything is frozen. Stages return new objects. |
| 5 |
Stages are Protocols, not base classes. Write one method to supply your own stage. |
| 6 |
Snippets are data, rendered two ways. One object gives the prompt's prose and the output schema. |
| 7 |
Two model adapters, not one, and not a hundred. A standard-library OpenAI-compatible client, and litellm behind [llm]. |
| 7a |
Model roles are part of the configuration. Grounding defaults to a smaller model than extraction. |
| 7b |
A registry, so an internal gateway is not a fork. |
| 8 |
Ontology inference is a bootstrap, not a mode. An inferred ontology is reviewed and frozen before use. |
| 9 |
The Initiator and Retriever are optional. |
| 10 |
Trust tiers are an enum with weights, not a free float. Four named tiers with fixed weights. |
| 11 |
Fact.signature excludes reconcilable qualifiers. |
| 12 |
Verification is one script. scripts/verify.sh is what CI and contributors run. |
| 13 |
The board is linked to the repo, not auto-populated. New issues are added to the account-owned board by hand. |
| 14 |
Polarity is a field, and it is part of the signature. A denial and its assertion never merge. |
| 15 |
The ontology says which qualifiers bear identity; the fact carries the answer. Qualifier(identity=True) puts a key in Fact.signature. |
| 16 |
Resolution proposes links; it never replaces nodes. SAME_AS, SIMILAR and DIFFERENT links; nodes are never merged. |
| 17 |
Two clocks: valid time on the fact, transaction time on the evidence. |
| 18 |
An entity records how its key was decided. Entity.resolution says whether the caller, an external id or a linker decided. |
| 19 |
The chunk is the unit of the pipeline, and the router sees chunks. |
| 20 |
Thirteen Protocols, each with a pass-through default. |
| 21 |
A stage the platform also does is warned about, never forbidden. |
| 22 |
The package is openodke; the tool and its data keep odke. |
| 23 |
Evidence cites the claim-bearing clause, and carries the mention beside it. |
| 25 |
A span says who chose it. Evidence.span_origin is cited, located or context. |
| 27 |
A prompt is a registered, versioned object. Every prompt is id@version, locked by its hash. |
| 28 |
An inverse comes from the schema, is marked, and is never grounded twice. |
| 29 |
A comparison has three verdicts, and inconclusive is not a pass. Better, worse or inconclusive with its detection limit; the CI gate fails worse. |
| 30 |
A cached answer is keyed on everything that changes it, and costs 0.0. The response cache's key, what it never stores, and why a hit costs 0.0. |
| 31 |
The store is looked up, never loaded, and a lookup never changes it. A proof re-keys the incoming facts onto the stored entity as stored; anything weaker is a link. |
| 32 |
A budget stop keeps what the run has. A call past the budget is refused before it is made; the run keeps what it has, writes, and exits 3. |
| 33 |
A support list names each source, and Neo4j keeps it as parallel lists. Fact.supported_by names each independent source; support is its length. |
| 34 |
The pair judge asks in both orders, and only where the rules leave a pair open. A model asked about pairs scored just below the SIMILAR bar, twice; same only if both orders say so, and same is a link, never a merge. |
| 35 |
A write merges with the store, in the corroborator, before the score. A restated fact gains the batch's sources, not a second edge. |
| 36 |
Without gold, the judge is corrected, the strict number stands, and pooled recall overstates. PPI corrects a judge by labels; adjudication sits beside the strict precision; relative recall prints its caveat. |
| 37 |
A source that changes is retracted, and a fact left with none is retired, not deleted. odke reconcile --delete and odke validate --update; Fact.retired_at keeps the fact. |
| 38 |
A miss goes where its evidence first points, and a fix is priced by arithmetic. Ten cause buckets in three tiers; each fix's expected gain exact or at the run's own rate, kept beside what was measured. |
| 39 |
The fact-equivalence judge reads only the pre-filter's pairs, in both orders, and its score sits beside the strict one. A near miss asked in both orders; the lenient score never replaces the strict one. |
| 40 |
A run writes its manifest after the sinks, and a replay refuses what changed. The config resolved and hashed without secrets, the models asked and served, the inputs by hash; --from-manifest runs it again or not at all. |
| 41 |
An event holds ids and numbers, never text, and a span goes where the application sends it. One shape for every JSON event; a job's counts are its report's; [otel] is the API alone. |
| 42 |
A fact names the ontology that last checked it, as a stamp and not a field. odke.ontology and odke.schema_slice, by fingerprint; found through an index; odke ontology diff --store. |
| 43 |
A batch's own look-alikes are one entity unless something keeps them apart. Within a batch, look-alikes that no id, number, legal form, context or judge keeps apart are re-keyed onto one entity; the store is still only linked. Off by default until the judge's calibration or the audit labels say otherwise. |
| 44 |
A tenant is a prefix on the key and a salt on the signature, not a second key property. <tenant>/<key> and a signature hashed with the tenant: two tenants' identical facts are two, and one constraint per type serves them all. |
| 45 |
A large run is micro-batches, and the store joins them. batch_size reads, runs and writes a slice at a time; a fact two slices state is merged by the store, not in memory. |
| 46 |
Corroboration is scored on the graph, by support, with checked alignments as sources. T-REx's two checked aligners give the sources; precision is factual and closed-world; on keeps the edges two or more sources back. |
| 48 |
The public API is a pinned list, and an old name warns until the next major. What semver covers, a deprecated name warns through 1.x and goes in 2.0.0, provisional APIs may change in a minor; the 1.0 review. |
| 50 |
Six rules are tests over the whole codebase, and every pull request carries its evidence. R1–R6 in tests/rules/, each over every entry point of its kind; a break waits as a strict xfail its fix removes; every pull request carries verify.sh and recordings on base and head. |
| 51 |
Two writers merge through a version on each fact, compared when it is set. odke.version, a token each write renews, locked then compared on write; a moved fact is read again, merged and scored again in the same write; the reconciler locks first. |
| 52 |
A reader keeps what it knows of a newer minor, and refuses what its own version never had. A triples row or eval report of a later 1.x is read for the fields this version knows, at every level; in its own version or an older one, an unknown field is refused; the manifest keeps what it knows of any. |
| 53 |
A store never bootstrapped refuses the merge, and names the bootstrap. The store merge's read refuses a store with no bootstrap, or no index for a declared predicate; an undeclared one warns; a write that reads nothing is unchanged. |
| 54 |
Below its bar, a judge still runs, and nothing is dropped on its word. Below its calibration bar, or with no card, the grounder's refusals are marked for review and the pair judge's decisions go to review; at or above it they act. An option given wins; one switch, DEFAULT_POLICY, reads card since the first cards (25 Oct 2026): every grounder and pair-judge card is below its bar. |
| 55 |
The site is built by Zensical, in its own look, and is published as Markdown too. Zensical replaces MkDocs and Material for MkDocs (end of life May 2027) and reads mkdocs.yml; the look is docs/assets/openodke.css; each page is also published as .md, with /llms.txt, and a "Copy page" menu. |