arborist/docs/warrant-substrate-cookbook.md
russell@unturf.com d8469613ce
test_doc_counts: AUTOCOUNT db-where supports *: glob for corpus-wide claims
The three "92 claim_pack docs" tags were drifting against shard 000.db's
21 rows because the harness only counted one shard, but the doc prose
("#000031 closed at 92") meant the corpus total (21+16+38+17 across
genesis shards 000-003).

Two-line fix path: extend the harness to sum across all ???.db shards
via a `*:` prefix (e.g. `*:documents?source_type=claim_pack`), then
prefix the three drifted tags. Aligns the harness scope with the
semantic scope of the claim instead of forcing the claim to shrink to
one shard.

The `*:` glob:
  - Matches `[0-9][0-9][0-9].db` basenames only (operator sidecars
    qa.db / snapshots.db / selfmodel-chain.db skipped)
  - Skips shards lacking the named table (schema-version tolerance)
  - Returns _DB_MISSING when no genesis shard exists (CI / fresh-
    checkout skip semantic preserved)
  - Returns _TABLE_MISSING when no contributing shard has the table

Documented in ticket-000044 §3.4 + a third example showing the new
syntax. Diagnosis credit to a sub-agent investigation that confirmed
zero eviction/falsification audit events on claim_packs — the data is
intact; the harness was just single-shard.
2026-05-31 11:37:39 -04:00

34 KiB
Raw Permalink Blame History

Warrant substrate cookbook

Architecture reference for the open-licensed textbook substrate that backs every claim-pack record in arborist. Written 2026-05-10 after the day-long push from 18/92 → 92/92 claim-pack warrant-chain coverage. Intended for future blackops shifts so they don't have to re-derive the substrate map from bench journals.

What this cookbook is

When a Q&A answer cites a claim-pack record (axiom or theorem), the runtime walks a chain:

answer cite
    ↓
claim-pack record_root (g4-generated 2025)
    ↓
derivations row (process_id, citation, src_root, proof_blob)
    ↓
surface chunk_root (open-licensed textbook)
    ↓
Merkle inclusion proof → document_root
    ↓
audit_events chain entry (sha256-linked)

The "open-licensed textbook" at the second-to-last step is the substrate. This document maps which substrate covers which pillar, what license + ingest path each uses, and the discipline patterns that keep the chains audit-clean.

Pillar-by-pillar substrate map

Eight pillars in the claim-pack source (#000029);

92

records total. As of 2026-05-10, every record resolves to at least one substrate in ~/.arborist/crawl/textbook_*.db.

Pillar I — Logic (13 records)

Substrate License Source Covers
Russell Introduction to Mathematical Philosophy (1919) PD PG #41654 single-page HTML natural numbers, classes, descriptions, types, propositional functions
Russell Principles of Mathematics (1903) PD content + CC-BY-SA-4.0 typesetting Klement single-page HTML class theory, relations, paradox derivation, magnitudes
De Morgan First Notions of Logic (1839) PD PG #67017 single-page HTML AEIO propositions, syllogism, hypothetical reasoning
Boole Investigation of the Laws of Thought (1854) PD PG #15114 LaTeX-source via textbook_tex propositional Boolean algebra, "elective symbols"
Software Foundations Vol 1 Logical Foundations MIT softwarefoundations.cis.upenn.edu BFS natural deduction (Logic.v): excluded middle, double negation, existential introduction, vacuous quantification
Whitehead-Russell Principia Mathematica Vol 1 (1910, partial) PD PG #78050 single-page HTML preface + intro + chs I-III; theory of types in narrative form

Modern citations (Mendelson, Enderton) are aliased per #000041 to combinations of these substrates depending on the specific axiom.

Pillar II — Set theory (10 records)

Substrate License Source Covers
Cantor Contributions to the Founding of the Theory of Transfinite Numbers (Jourdain 1915) PD Wikisource Article 1 only cardinal arithmetic, equivalence, addition / multiplication / exponentiation, finite cardinals
Russell Principles of Mathematics (1903) PD content + CC-BY-SA-4.0 typesetting Klement HTML Russell's Paradox derivation, class theory
Whitehead-Russell PM Vol 1 (partial) PD PG #78050 type theory narrative

Modern Jech citations alias to these. Note: Cantor's Article 2 (operations on ordered sets) is not transcribed on Wikisource; the Article 1 transcription covers cardinal-arithmetic axioms but not ordinal axioms. PM *24+ formal type theory is not in PG #78050 (only preface + intro + chs I-III), so the Russell's Paradox Resolution record matches via lexical fallback against narrative discussion rather than the actual *24 formalism — honest soft match, not a strict primary binding.

Pillar III — Arithmetic (13 records)

Substrate License Source Covers
Peano Arithmetices Principia, Nova Methodo Exposita (1889) CC-BY-SA-4.0 (Verheyen + Nahas English transl.) mdnahas/Peano_Book GitHub LaTeX via textbook_tex Peano arithmetic axioms (zero, successor, induction)
Dedekind Essays on the Theory of Numbers (Beman 1901) PD PG #21016 LaTeX via textbook_tex Dedekind cuts construction of reals + chains-and-induction definition of natural numbers
Russell Introduction to Mathematical Philosophy (1919) PD PG #41654 HTML natural numbers, definition of number, induction (informal)
Software Foundations Vol 1 Logical Foundations MIT upenn BFS Coq induction proofs, lists, polymorphism

Landau + Gödel citations alias to these. Note: Peano writes symbolically (0 ∈ N); the cascade's parenthetical-phrase variant

  • OR-fallback variant land hits via SF-LF / Russell IMP / Dedekind for axiom records that cite "Axiom of Zero" / "Distinctness of Zero" / "Injectivity of Successor" / etc. (the direct phrase doesn't appear in Peano's text).

Pillar IV — Geometry (18 records)

Substrate License Source Covers
Hilbert Foundations of Geometry (Townsend 1902) PD PG #17384 LaTeX via textbook_tex every Hilbert axiom (incidence, betweenness, congruence, parallels, continuity)

This pillar resolves directly — the Hilbert citation in claim-pack records IS the textbook in shard. 11/18 match unaliased; 7/18 match via term-aliases (#000042) bridging the 1902 Townsend vocabulary vs modern ("connection" vs "incidence", "Group III: Axiom of Parallels" vs "Euclidean Parallel Postulate", "space axiom" vs "Non-Triviality", "first theorem of congruence" vs "Side-Angle-Side"). Pillar IV is the cleanest demonstration that the substrate-binding works end-to-end.

Pillar V — Probability (5 records)

Substrate License Source Covers
Grinstead-Snell Introduction to Probability GFDL-1.3 Dartmouth PDF → pdftotext -layout → localhost-HTML → arborist ingest --source html Kolmogorov axiomatized probability spaces, sample spaces, conditional probability, Bayes, expected value, large numbers
Laplace A Philosophical Essay on Probabilities (Truscott + Emory 1902) PD PG #58881 single-page HTML pre-Kolmogorov narrative treatment: expected value, conditional probability, additivity

Kolmogorov 1933 itself is URAA-blocked in US until 2058 (Kolmogorov d.1987 → life+70). Grinstead-Snell is the closest open-licensed equivalent. The PDF→localhost-HTML pipeline (see Ingest patterns below) was first proven on this textbook.

Pillar VI — Classical mechanics (5 records)

Substrate License Source Covers
Newton Principia (Motte 1729) PD Wikisource HTML BFS depth=3 max=120 from /1729/ root three laws of motion + universal gravitation

Goldstein-Poole-Safko citations alias to Newton. Newton 1729 vocab (Lex Tertia, quantity of motion, every action) differs from modern; 4 term-aliases registered in #000042 for completeness (some lift via cascade, some don't matter — cascade picks other discriminators).

The shard was rebuilt 2026-05-10 — the original crawl_url at /The_Mathematical_Principles_of_Natural_Philosophy (no edition specifier) followed Wikisource sidebar links instead of book content. New manifest entry pins the (1729) edition root + explicit urls for Axioms / Definitions / Rules of Reasoning subpages. Recrawl produced 120 docs / 779 chunks (was 60 / 289 of mostly nav cruft).

Pillar VII — Combinatorics (14 records)

Substrate License Source Covers
Bogart Combinatorics Through Guided Discovery GFDL-1.3 bogart.openmathbooks.org BFS introductory: sum/product, binomial, inclusion-exclusion, pigeonhole
Levin Discrete Mathematics: An Open Introduction (3rd ed) CC-BY-SA-4.0 discrete.openmathbooks.org BFS intermediate: stars-and-bars, hockey-stick, generating functions intro
Keller-Trotter Applied Combinatorics CC-BY-SA-4.0 appliedcombinatorics.org BFS (38-min crawl-delay) advanced: generating functions, partitions, Polya enumeration

Stanley + Brualdi + Knuth combinatorics citations alias to all three substrates per source_ref string (14 unique compound strings each get three substitute rows; pillar VII has 42 alias rows total of the 54 in citation_aliases).

Note: Keller-Trotter has Crawl-Delay: 20 in robots.txt, so a full BFS at depth=2 max=80 takes ~27-38 minutes. Background-task the crawl with a generous timeout.

Pillar IX — Lambda calculus + abstract algebra (14 records)

Substrate License Source Covers
Programming Language Foundations in Agda (PLFA — Wadler/Kokke/Siek) CC-BY-4.0 plfa.github.io BFS untyped + simply-typed lambda calculus, β/α/η reduction, Confluence/Church-Rosser, fixed point
Software Foundations Vol 1 Logical Foundations MIT upenn BFS Coq induction, lambda calculus, Imp.v sequence/conditional/while-loop
Judson Abstract Algebra: Theory and Applications GFDL-1.3 judsonbooks.org PreTeXt BFS groups, rings, fields, Galois theory, Boolean lattices, Cayley + orbit-stabilizer

Barendregt + Dummit-Foote + Böhm-Jacopini citations alias to these. PLFA is the lambda-calculus core; SF-LF doubles as a logic substrate (pillar I) AND a structured-programming substrate (Böhm-Jacopini Imp.v); Judson is the abstract-algebra primary substitute.

Ingest patterns

Five proven patterns. Pick whichever matches your source.

A. HTML single URL (urls in manifest)

For PG eBooks with a single-page HTML edition (Russell IMP, De Morgan, Laplace) or Wikisource transcriptions (Cantor Article 1). Manifest entry:

{"id":"foo","urls":["https://...html"], ...}

Make target: make textbook ID=foo. Calls arborist ingest --source html --urls-from <file>.

B. HTML BFS crawl (crawl_url + crawl_depth + crawl_max)

For multi-chapter HTML books (PreTeXt: Bogart, Levin, KT, Judson; Wikisource book-length texts: Newton, Aristotle Prior/Posterior; LibreTexts: Grinstead-Snell). Manifest entry:

{"id":"foo","crawl_url":"https://...","crawl_depth":2,"crawl_max":80, ...}

Make target: make textbook ID=foo. Calls arborist crawl --seed-url ... --depth ... --max-pages ... --ingest.

Robots.txt crawl-delay is honored. Plan timeouts: appliedcombinatorics 20s × 80 pages = 27-38 min; plfa.github.io ~5 min; opendatastructures ~1 min.

C. LaTeX-source (tex_url)

For PG eBooks with no HTML edition (Hilbert, Boole, Dedekind) or GitHub-hosted LaTeX (Peano). Manifest entry:

{"id":"foo","tex_url":"https://.../foo.tex","license":"PD", ...}

Make target: dedicated per-book like make textbook-hilbert (the generic make textbook route doesn't handle tex_url). Calls arborist ingest --source textbook_tex --url .... Pipeline strips PG-style preamble + tabular/figure envs; substitutes \to → →, \neg → ¬, \forall → ∀.

Limitation: paracol multi-column macros (Peano) leak some residue (gobble 1cm, 0.5cm, paracol3) but substantive prose extracts cleanly. If the source uses heavy custom macros, expect some noise.

D. PDF → localhost-HTML → html-source

For sources that have a PDF but no clean HTML (Grinstead-Snell Dartmouth PDF; Bayes 1763 Royal Society scan; Frege Begriffsschrift Internet Archive). Pattern:

curl -sLo /tmp/foo.pdf https://...
pdftotext -layout /tmp/foo.pdf /tmp/foo.txt
mkdir -p /tmp/serve
{ echo '<html><head><title>...</title></head><body><pre>';
  cat /tmp/foo.txt;
  echo '</pre></body></html>'; } > /tmp/serve/foo.html

cd /tmp/serve && python3 -m http.server 8765 &
SRV_PID=$!
sleep 2
arborist --db ~/.arborist/crawl/textbook_foo.db ingest \
  --source html --url "http://localhost:8765/foo.html"
kill $SRV_PID

Then run the title backfill (see Discipline patterns below).

E. Direct chunk insertion (Python API)

For one-off cases where none of A-D fit. Walk arborist.document.Document + arborist.store.connect to insert manually. Used when wrapping non-standard sources.

Discipline patterns

Title-from-author backfill

Empirical defect: HTML and textbook_tex ingest pipelines take document titles from <title> tags or URLs. Wikisource and Project Gutenberg HTML pages do NOT include author surname in <title>. Resolver's _shard_matches_citation REQUIRES the cited author's surname to appear in the shard's title-haystack; silently fails for alias-resolved chains where the substitute author isn't self-evident in the shard.

Source-side fix shipped (#000031 follow-up B-2, commit 551c969 2026-05-10): the HTML, textbook_tex, and crawler ingest paths now accept an --author flag that augments the title at insert time: arborist ingest --source html --author "Bertrand Russell" → title becomes "Introduction to Mathematical Philosophy | Project Gutenberg, by Bertrand Russell" with no SQL UPDATE required. The relevant Makefile targets (make textbook-*) wire --author for every textbook in the substrate. Use the --author flag for all new ingests.

Legacy fix-up for already-ingested shards that pre-date B-2: SQL UPDATE on documents.title after the fact:

import sqlite3
c = sqlite3.connect(shard_path)
c.execute(
    "UPDATE documents SET title = title || ', by <author surname>' "
    "WHERE title NOT LIKE '%<author surname>%'"
)
c.commit()

For HTML BFS shards with many docs (Judson 39, Bogart 51, Levin 51, KT 79, PLFA 58, SF-LF 33), append-suffix pattern. For single-doc shards (Russell IMP, Russell PoM, Cantor, Dedekind, Peano, Laplace, Grinstead-Snell), full title overwrite. As of 2026-05-10 every shard in ~/.arborist/shards/ already carries the augmented titles — this section is preserved as the runbook for any future re-ingest of a corpus that pre-dates 2026-05-10 source-side wiring.

Audit discipline on aliases

Per #000041 / #000042: every alias row carries decision_by (non-empty, audit-fail-closed) + decision_rationale (free text — caveats, peer-vs-primary distinction, partial-coverage warnings).

CLI refuses to register without --by. Format convention:

arborist alias citation add ORIGINAL \
    --substitute SUB --author AUTHOR --title TITLE \
    --by "fox 2026-05-10" \
    --rationale "honest sentence about WHY this substitute covers the cited axioms"

The rationale is the load-bearing field for an audit reviewer. "Russell IMP covers Mendelson's propositional axioms but not his incompleteness chapters" is honest. "Russell IMP covers Mendelson" is not.

Multi-substitute aliases

When one cited proprietary work is best covered by N peer substrates, register N rows (same original_ref, different substitute_ref). Resolver tries each; first hit wins. Examples: Mendelson → {Russell IMP, De Morgan, Boole, Russell PoM, SF-LF}. Stanley/Brualdi/Knuth (per source_ref) → {Bogart, Levin, KT}.

Cascade tuning (_build_record_query_cascade)

Two helpers added 2026-05-10:

  1. _phrase_from_parenthetical(theorem_name) — extracts discriminator from trailing parenthetical when one exists. "Kolmogorov's First Axiom (Non-Negativity)" → "non negativity". The original _phrase_for_axiom was stripping parentheticals; many substrates used the parenthetical content as the actual term.
  2. Content-tokens OR-join (top 3) — soft fallback after the AND-join (top 5). When AND zeroes out (substrate doesn't have all 5 tokens together), OR-of-3 reliably surfaces matching chunks. The +14 record unlock at 84% → 100%.

Full cascade order, tightest → loosest:

  1. title-phrase
  2. parenthetical-phrase (NEW)
  3. content-tokens AND-join (top 5)
  4. content-tokens OR-join (top 3) (NEW)
  5. legacy single-token / discriminating-token query

Honest tier breakdown

The 92 chains have three quality tiers:

  • Direct primary (~25 records) — citation matches the literal textbook ingested. Hilbert pillar IV (18), Goldstein → Newton (3), Stanley → Bogart for the records Bogart genuinely covers. Chain is "the cited primary IS in the shard."
  • Substrate substitution (~50 records) — citation alias to a peer-level open work that covers overlapping axioms. Audit row carries decision_rationale explaining honesty. Reviewer can re-judge.
  • Soft-fallback match (~17 records) — OR-of-top-3 content tokens surfaced some chunk in the substrate that shares vocabulary. The chunk contains relevant terms; whether it proves the axiom is a separate, weaker claim. Heuristic-grade.

The schema doesn't currently distinguish these tiers. Audit reviewers walk citation_aliases (74 rows live as of 2026-05-10) + read decision_rationale fields to grade each chain. If tier distinction becomes load-bearing, add a tier ∈ {primary, substitute, soft} column to derivations.

Audit-trail integrity

Every alias row + every derivation insertion writes one row in audit_events with event_hash = sha256(prev || canonical(body)). Verify chain integrity:

make chain-check-shards   # 0 per shard = intact

The audit_events chain ensures: if any alias row is later modified or removed, the chain breaks at that point and downstream verification fails. Tampering is detectable.

What this doesn't yet do

The substrate is in place; the render layer doesn't read it. Q&A answers citing claim-pack records still display ANCHOR-WARRANTED on the four-rung ladder. #000031 Phase 3 wires the render layer to consult derivations and promote to EVIDENCE-WARRANTED. ~50-100 LOC in arborist.cli._render_audit_label. Not done.

The process_id on alias-resolved derivations is currently warrant-resolver-v1 (DIRECT) rather than warrant-resolver-v1+alias. The via_alias flag is set only by term-alias query expansion in resolve_chunks, not by citation-alias substitute-Citation injection in warrant_resolve. Audit trail is correct in citation_aliases table itself; just under-attributed in derivation rows. ~15 LOC fix.

Per-record tier classification (primary / substitute / soft) isn't in the schema. Reviewers infer from citation_aliases rows

  • decision_rationale text. Could be promoted to a column if the distinction becomes load-bearing for downstream consumers.

Re-running the substrate build

Most steps are idempotent at the DB layer (content-addressed inserts; same source content → same document_root → no-op). Network refetches happen but inserts dedupe.

# Bulk: all four 2026-05-09 base-knowledge additions
make textbooks-base-knowledge

# Per-book convenience targets
make textbook-bogart           textbook-keller-trotter   textbook-levin
make textbook-aristotle-prior  textbook-aristotle-posterior
make textbook-newton           textbook-morin
make textbook-judson           textbook-cantor           textbook-demorgan
make textbook-russell-imp      textbook-russell-pom
make textbook-laplace          textbook-pm               textbook-grinstead-snell
make textbook-hilbert          textbook-boole            textbook-peano
make textbook-dedekind         textbook-plfa             textbook-sf-lf

# Title-from-author backfill (one-off SQL — see "Discipline" above
# for the per-shard script)

# Run resolver
arborist warrant-resolve --use-aliases --write
# → 92 / 92 (100%) under the 18-substrate + 74-citation-alias
#       + 13-term-alias state (counts as of 2026-05-10)

Adjacent: live-corpus → bench-fixture harvest

The textbook substrate above gives the cookbook a static surface — 18 hand-curated, license-validated, deterministically ingested sources. A parallel pattern landed 2026-05-10 in ff1752c under #000037 → #000025 that does the opposite: grow bench fixtures from live corpus state, not hand-curation. Worth documenting here because the discipline patterns (attribution metadata, determinism via stratification, fail-loud regen) carry across both surfaces.

Pattern

#000037 Phase 1 controller (arborist/substrate/prometheus.py)
  emits FalsificationFixtureProposal records when
  witness_divergence (n_unverified / n_quotes) >= 0.5
    ↓
bench/scripts/harvest_falsification_proposals.py reads qa.db,
  filters live providence_cache rows, stratifies top-20 per
  audit_mode (HYBRID + UNGROUNDED), writes JSONL
    ↓
bench/fixtures/5f/falsification-harvested-v1.jsonl
  (<!--AUTOCOUNT:fixture-rows:bench/fixtures/5f/falsification-harvested-v1.jsonl-->41<!--/AUTOCOUNT--> rows = 1 _meta header + 40 fixtures)
    ↓
tests/test_bench_batteries.py:test_5f_falsification_harvested_pack_*
  exercises every test run; error_detection_rate == 1.0
  by construction (every harvested row IS a falsification)

Three discipline patterns reused from the textbook substrate

  1. Attribution metadata on every derived artifact — same discipline as derivations.proof_blob carrying inclusion proofs back to source chunks. Each harvested fixture row carries _harvest_meta with cache_key, witness_divergence at harvest time, audit_mode_at_harvest, harvested_from, harvest_threshold, and source_ticket: "#000037 §13 step 11". Regeneration provenance auditable.

  2. Determinism via sort-and-cap — same discipline as citation-alias cascade tuning's "top 5 AND-join then top 3 OR-join" structure. The harvester sorts top-by-cache_key per audit_mode bucket + caps at 20 per mode. Same qa.db state → byte-identical fixture file across regenerations.

  3. Pin the metadata contract in teststest_5f_falsification_harvested_pack_runs_clean asserts every row carries the meta. Same shape as the cookbook appendix's discipline pins: a future regeneration that drops attribution fires a test failure, not a silent regression.

Where to use this pattern

Anywhere a controller emits Proposal records that should become real fixtures. The recipe:

  • Define the Proposal dataclass on the controller side (see arborist/substrate/prometheus.py:FalsificationFixtureProposal).
  • Write a harvester script under bench/scripts/ that reads the source state (qa.db, ~/.arborist/shards/*.db), filters + stratifies, and emits a JSONL fixture pack.
  • Pin the metadata contract in tests/test_bench_batteries.py (or the equivalent battery test file).
  • Wire make <battery>-harvest so regen is one command.

The 18-textbook substrate is the static foundation; the harvested-fixture pattern is how that foundation gets exercised against current corpus state on every test run. Both live in this cookbook because the discipline rules — attribution, determinism, fail-loud — are identical.


References

  • #000031 — surface-ingest cited textbooks
  • #000041 — citation-aliases table + 74 live rows
  • #000042 — term-aliases table + 13 live rows (5 arithmetic + 4 classical-physics + 4 geometry)
  • #000038 — Phase 4 content acquisition (still-blocked proprietary candidates: Hilbert-Ackermann 1928, Mendelson, Enderton, Jech, Goldstein, Barendregt, Stanley, Brualdi, Knuth; the substrate substitution pattern is the workaround)
  • #000037 — Prometheus-Σ recursive falsification controller; source of the FalsificationFixtureProposal records the harvest pattern consumes
  • #000025 — 5F battery; sink for the harvested falsification fixtures (§11 Phase 1f)
  • bench/scripts/harvest_falsification_proposals.py — harvester script (266 LOC) reading qa.db + emitting stratified fixtures
  • bench/fixtures/5f/falsification-harvested-v1.jsonl — current harvested pack (regenerate via make bench-5f-harvest)
  • bench/results/full-warrant-resolution-2026-05-10.md — the bench journal that closed 84% → 100%
  • bench/fixtures/textbooks/manifest-v1.jsonl — license-validated manifest of every textbook in the substrate
  • arborist/qa/warrant_resolver.py_build_record_query_cascade + _phrase_for_axiom + _phrase_from_parenthetical + resolve_chunks
  • arborist/qa/aliases.py — citation + term alias schema + CLI add/list/remove

Appendix — test-coverage cross-reference (2026-05-10)

Per-discipline regression-guard test files. Each test file pins contract phrases / numerical invariants so a future PR that silently drops a discipline rule fires a unit-test failure rather than waiting for bench-time STRICT-rate drift to surface it.

Citation-alias / term-alias mechanism (#000041 + #000042)

  • tests/test_aliases.py — 28 tests covering add_citation_alias / add_term_alias audit-fail-closed (empty decision_by raises ValueError), domain isolation (same term different domain stays distinct), lowercase normalization (Term/Term/Geometry → all lowercased on insert), bidirectional lookup_term_aliases, expand_query_with_term_aliases quoted-phrase preservation, fail-closed on unreachable DB, parenthesis-as-token tokenizer contract (OR-expansion round-trip), and list_term_aliases filter-by-domain / term-substring.

Warrant-resolver chain (#000031 Phase 1+2+3)

  • tests/test_warrant_resolver.py — 23 tests covering citation parsing (3 patterns: "Title by Author", multi-author Oxford comma, semicolon-separated multi-cite); cascade builder (5-query variants: title-phrase, parenthetical-phrase, AND-top-5, OR-top-3, legacy); via_citation_alias floor propagation through ResolutionMatch (B-1 attribution fix).
  • tests/test_warrant_chain.py — 9 tests covering warrant_chain_lookup (process_id LIKE filter, missing-table fail-closed, +alias variant matching), has_warrant_chain empty-set short-circuit, verifier suppression of WARRANT_MISSING when chain present, verdict-field warrant_proven_claim_idxs always present (schema guarantee).

Textbook ingest license-discipline gate

  • tests/test_textbooks_manifest.py — 43 tests covering every license token in _ALLOWED_LICENSES (parametrized 12-token sweep), placeholder rows allowed without URLs, disallowed license + emit URLs raises, CLI dispatch, return-code contract (0 ok / 2 missing-arg / 3 license-fail / 4 unknown-id), and the live manifest itself validates clean.

Cascade tuning (#000040 + parenthetical/OR-fallback)

  • tests/test_warrant_resolver.py::_phrase_from_parenthetical — extracts "non negativity" from "Kolmogorov's First Axiom (Non-Negativity)"; the discriminator is INSIDE the parenthetical that earlier resolver versions stripped. Pinned so a future "simplify the cascade" PR can't silently regress.

Substrate-paper-spec'd primitives (#000012 + #000018 + #000034 + #000037)

  • tests/test_anchor_prg.py — 31 tests for φ_PRG HMAC-SHA-512 expansion (#000035 Phase 1). Covers KAT regression, hand-formula (first-block matches direct hmac.new), prefix-extending closure invariant, output-length monotonicity per dim_h.
  • tests/test_phi_alignment_probe.py23 tests (was 14; +9 from a4b3056 2026-05-10 pattern backfill) for φ_linear Hessian-alignment probe (#000034 Phase 1a). Covers KAT regression, hand-formula (uniform baseline), monotonicity in W concentration + dim_h, closure (a_top + a_bot ≡ full-spectrum on dense decomposition), Lanczos eigenvalue ordering invariant.
  • tests/test_t3_bound_calculator.py83 tests (was 51; +2 from 581ad90 2026-05-10 KAT-fixture-gap closure) for the T3 per-window covert-channel bound calculator (#000036 §11); pins the closed-form B1/B2/B3 formulas, monotonicity in each input, recommendation-text mode transitions, and the §11 worked-example bit-for-bit (with doc-calibration update surfaced through the test).
  • tests/test_fork_score.py — 31 tests for v8 ForkScore (#000012 Phase 1a); pins SIGNAL_FLOOR (5pp) + HARD_REGRESSION_FLOOR (5pp), score = sum-of-breakdown closure, security_risk inert under default iota=0 (opt-in), NEG_INF_REGRESSION hard-reject.
  • tests/test_substrate_fork_score.py — 27 tests covering the arborist substrate score CLI surface (renamed from test_v8_fork_score.py in a4058a4 per the 2026-05-10 v-prefix retirement). Adapter tests + 4 in-process CLI tests via build_parser() + 1 real subprocess invocation catching entry-point / sys.argv drift the in-process tests miss.
  • tests/test_weights.py — 16 tests for WeightSet defaults (each weight value pinned to its docstring rationale; PR that flips alpha=1.0→0.5 fires this test), greek-letter and Python-safe key aliases, frozen-dataclass invariant.
  • tests/test_pi_star_protocol_and_registry.py — 21 tests for PiStar Protocol contract + registry mutation discipline (no public unregister; name@version content-pinned).
  • tests/test_prometheus.py — 42 tests for the Prometheus-Σ recursive-falsification controller (#000037 Phase 1, commits f625cac + f9f5ae4). Verifier-style discipline (NOT calculator pattern — it's a state machine, not closed-form math): pins §16.2 named contracts (17), boundary veto-class cases (5), §14 exception-matrix dispatch including row 4 Hermes-saturation guard, §13 step 11 falsification-fixture proposal, §15 weight-tunable entropy + memory gates, ESCALATE > QUARANTINE > REJECT priority ordering.
  • tests/test_prometheus_audit.py — 25 tests for the controller_events sibling table (#000037 Phase 2, commits a786d6d initial + 43380b1 QA-runner wiring + cc72784 controller-events inspector CLI). Pins migration idempotency, no-chain-mutation invariant (advisory writes never enter audit_events.event_hash preimage), (event_kind, body_hash) UNIQUE dedupe contract, query paths for the three event kinds (controller_decision, controller_difficulty, controller_budget_allocation), QA-runner advisory non- blocking on bad verdict, and the arborist controller-events inspector CLI surface (kind / organism-prefix filters, JSON output, graceful skip on non-arborist sqlite files).

Q&A / verifier scaffolding

  • tests/test_qa_progress.py — 31 tests for the Progress emitter (env / TTY / cli-override precedence; truthy/falsy spelling matrix; fail-closed on missing .isatty).
  • tests/test_qa_prompts.py — 20 tests pinning load-bearing system prompts (worked-example presence, two-pointer cap, pointer-mode no-quote-instruction discipline, JSON-mode first-char-{ / last-char-} rule); a silent prompt edit that drops a critical instruction would otherwise surface only as a STRICT-rate drop in bench.

Concept-relations write-side

  • tests/test_concepts_extract.py — 28 tests for synonym / IDF / FTS5-titles extractors (_title_tokens stopword
    • length-floor + dedupe; EXTRACTORS registry contract; link_reciprocity_synonym idempotency + self-overlap exclusion; backfill_documents_fts NULL-title skip).

Unit-test density vs production-code size

domain LOC tested test LOC test/code ratio
aliases.py 512 469 (28 tests) 0.92
warrant_resolver.py ~800 ~430 (combined) 0.54
warrant_chain.py 89 320 (9 tests) 3.6
t3_bound_calculator.py 249 446 (83 tests) 1.79
fork_score.py 386 609 (31 tests) 1.58
weights.py 73 180 (16 tests) 2.5
pi_star/protocol+registry 124 280 (21 tests) 2.3
qa/progress.py 85 226 (31 tests) 2.7
qa/prompts.py 153 207 (20 tests) 1.35
concepts/extract.py 288 278 (28 tests) 0.97
textbooks_manifest.py 236 463 (43 tests) 1.96
substrate/prometheus.py 893 955 (42 tests) 1.07
substrate/prometheus_audit.py 239 595 (25 tests) 2.49

Pattern: small contract-defining modules (weights, prompts, warrant_chain) get 1.4-3.6× test LOC because they're foundation; larger modules (warrant_resolver, aliases) settle around 0.5-1.0× because they're more code-with-tests-per-feature than contract-with-tests-per-rule.

The ratio is a code-review heuristic: a new substrate-paper-spec'd primitive without ≥1× test/code ratio is suspect on landing.

Cross-reference

This appendix is the per-discipline INDEX — start here when auditing "where are the tests for X?". The complementary per-pattern CHECKLIST for new calculator-style code lives at docs/calculator-test-patterns.md: KAT regression, hand-formula, monotonicity, closure, parametrized invalid-input, CLI subprocess, doc parity, module-export shape — with a 9-item checklist for new modules and an explicit "doesn't apply to verifier-style code" caveat. Codified 2026-05-10 from the three-module pattern bench (t3_bound_calculator + phi_alignment_probe + anchor_prg).

When adding a new substrate-paper-spec'd primitive: walk the checklist in calculator-test-patterns.md to design the test file, then add a row here under the matching discipline.