Skip to content
← Documentation

docs/falsification-layer.md


The falsification layer

The mission this subsystem serves: Cognithamus is not a system that draws pictures of repositories. It is a system that takes a claim about a codebase and provides the strongest available mechanism to prove, disprove, weaken, qualify, or expose the limits of that claim. The layer that does this is src/lib/inquiry/, and this document records what was built, what was decided, what was refused, and what is deliberately deferred.

Repository → Acquisition → World → inquire(claim, world, registry) → Inquiry

The epistemic object

An Inquiry is one claim, evaluated against one World, taken apart:

part what it is its law
claim the proposition, worded by the instrument that evaluated it the evaluated wording is part of the output, so the record cannot test one thing and report another
evidence measured statements, each with a bearing every statement carries ≥ 1 citation, and every citation resolves
assumptions declared premises each states what would falsify it
refusals what this World cannot answer each states the measurement that would resolve it
defeaters the claim's declared failure conditions each reports untested, tested-and-absent, or triggered
arithmetic the counts travels with the verdict so the derivation is checkable by eye
standing the verdict a closed classification, derived by a published rule
nextMeasurements what to measure next derived from refusals and untested defeaters, never invented

A Citation is not prose. It is a typed pointer — a stored measurement, a stored link, one side of the placed/unplaced/unobserved partition, the observation window, the origin revision — and resolves() verifies it against the World. After a falsifier answers, the engine audits the finding: a citation that does not resolve, or that falls outside the instrument's declared read scope, is a thrown FalsifierViolation, not a degraded answer. An instrument cannot invent evidence, cannot cite what it did not declare, and cannot drop a failure condition it promised to watch.

What was refused, and why

A confidence number. Nothing in this system measures the probability that a claim is true, so a scalar confidence would be decorative intelligence inside the layer built to forbid it. The reader gets the confidence's anatomy instead — counts, assumptions, refusals, and which failure conditions were actually looked for — classified by standingOf, whose rule is published in the model and re-derived independently in the falsification register's harness.

Advocates. buildRegistry refuses any instrument that declares no defeaters. An evaluator that cannot say what would refute its own claims is an advocate, and advocacy is not measurement. This is the registration-time twin of registerConnector refusing a connector that would drift the ontology.

Unavailability as refutation. When coupling was never read (a window with no usable commits), a hub claim is refused, never refuted — and when coupling was read and found empty, that is a measured zero, which does refute. The distinction is quality.ts's Availability three-state carried into epistemics, and it is a registered law (inquiry-absence-never-zero, survived 100,000/100,000).

The growth mechanism

The layer is a contract, not a checklist. A falsifier declares its family (open — structural, historical, ownership, dependency, security, …), the one claim kind it evaluates, the evidence it reads (enforced by a scoped view that throws on undeclared access), and its defeaters. Anything satisfying the contract joins the registry; nothing in the engine knows any falsifier by name. New measurement capabilities expand the falsification universe by widening what views can expose and what instruments can therefore declare — never by redesign.

Three instruments ship, chosen because every measurement they consume already exists in acquired Worlds:

  • coupling-hub (structural) — is this file a co-change hub?
  • partition-coverage (structural) — does the World cover the repository?
  • sole-authorship (ownership) — was every measured file touched by one author?

What running it against reality found

The first execution against site-world.json — this repository, measured at bcea73f — falsified the first instrument. src/app/robots.ts cleared the partner-count bar (27 partners, median 10) on links that each rest on exactly one shared commit: a bulk change, not co-evolution. The declared assumption ("accidental co-commits weaken it") predicted exactly this failure, so it was promoted from assumption to a second declared defeater, and the misclassified hub became a REFUTED standing with the tension visible — supporting evidence, contradicting evidence, and the triggered condition all on the record. tests/inquiry.test.ts pins the case. That sequence — instrument, deployment, refutation, strengthened instrument, pinned regression — is the layer working on itself, and it is the intended loop for every future instrument.

The same run also produced, about this repository: sole authorship ESTABLISHED (210/210 files, defeater tested and absent); coverage CONTESTED (202 placed against 117 unobserved paths, with the resolving measurement named from the measured extension counts: .md (100), .png (7), .json (5)).

Its own laws, measured

Three laws of the layer are entries in the falsification register (src/lib/ledger/falsification.ts), attacked with randomized Worlds on every gate run and recorded at the deep rung:

  • inquiry-standing-lawful — the verdict matches its published table. 100,000/100,000.
  • inquiry-citations-resolve — every produced inquiry is internally honest. 100,000/100,000.
  • inquiry-absence-never-zero — unread evidence never reads as a zero. 100,000/100,000.

The substrate audit (2026-08-24)

The layer was frozen and audited as core substrate before any expansion. Each property is pinned in tests/substrate-audit.test.ts; findings that changed code are listed with what they changed.

1. Renders can consume an Inquiry without interpretation logic. Verified mechanically: an Inquiry survives JSON round-trip identically (no functions, no clocks, no undefined), every value a renderer would switch on is from a closed union, and every cited subject id joins back to the World the render already consumes. The one dependency found and accepted: citations carry ids (identity) while statements carry labels (prose), so a render pairs the Inquiry with its World for display — the same World, no second authority, no inference. The canonical text projection (scripts/inquire.mts) does exactly this join and nothing else.

2. The World is the only evidence authority. An allowlist boundary test: inquiry/ imports only itself and the world layer's pure modules (types, quality, fold), and its source — comments included — contains no filesystem, subprocess, database, environment, network, clock, or randomness reference. Widening the allowlist is a deliberate audit event, not a refactor.

3. Registration is additive. The engine and model name no instrument and no claim kind (asserted as text), and the audit registers a fourth probe instrument beside the shipped three with zero engine change — an executable proof, run on every gate.

4. The canonical artifact. docs/public/canonical-inquiries.json holds one real epistemic object per standing — established (sole authorship), contested (coverage), refuted (robots.ts as hub), undetermined (a claim kind no instrument evaluates yet: the registry-boundary object) — all evaluated against this repository's measured World. A drift guard re-evaluates and compares on every run; regeneration is node --import tsx scripts/gen-canonical.mts, and a diff in that file is an epistemic change to be reviewed as one.

5. Citation traceability. Engine-enforced and double-booked in the audit: every citation resolves, every contradiction carries grounds. One documented shape: a measured absence (zero coupling across a usable window) has no stored row to cite, so it cites the observation window — the record that the system looked. Positive counter-evidence always cites its rows.

6. Refusal quality. Mechanical bar on every refusal in the scenario matrix: the question is a question, the grounds are stated, the resolving measurement is named, is distinct from both, and appears in nextMeasurements. Finding fixed during the audit: a claim about a measured-but-unplaced subject used to get the same refusal as an unknown path; it now carries the World's recorded basis ("never changed in the same commit as another source file") and a matching resolution.

Instrument finding. Extending mutation testing to this layer exposed that the mutation harness's failure detector was environment-blind: node's test reporter defaults to TAP when not attached to a TTY, and the matcher reads the spec reporter's lines. The harness's own instrument control caught it — it planted a failure, saw nothing, and refused to report, exactly as designed. The reporter is now pinned (--test-reporter=spec). Three inquiry mutations joined the harness: disabling citation resolution, admitting advocates, and ignoring triggered defeaters. Measured on 2026-08-24: all 37 mutations CAUGHT, each by exactly its intended invariant — the three inquiry defects included — under the harness's exact blast-radius rule.

Resolved after the freeze lifted (2026-08-24). The audit's recorded question — should a hub claim about a subject unplaced because it never co-changed be refuted rather than refused when the window was usable? — resolved to refutation. The reasoning: a placed file with zero partners in a usable window is refuted; the unplaced file's recorded basis states the same measured zero, and one measured fact must not earn two standings depending on placement. The boundaries hold: budget-refused subjects (which did co-change; their degree is simply not embedded) remain refusals, and an unusable window remains a refusal — inquiry-absence-never-zero still governs. The canonical undetermined example moved to the registry-boundary object, which downstream consumers will meet anyway.

Deferred, and recorded as such

Per the anti-drift protocol, the following directly serve the mission but are not built yet, and nothing else should be built before them:

  1. Rendering the epistemic object through the Reality Engine — claims as structures, evidence as connections, uncertainty as measurable space, contradictions as tension, missing information as unexplored regions. The truth model now exists so the render can emerge from it; the render itself is Phase 4 and must not precede more instruments only if those instruments strengthen falsification. Today's render is scripts/inquire.mts, a deliberately generic text projection of Inquiry.
  2. Historical and dependency families — falsifiers over window series (drift: does structure survive a different observation window?) and over import graphs when that measurement lands.
  3. Inquiries as evidence — recording an inquiry's outcome so a later inquiry can cite it (Action → New Evidence in the loop). Requires an identity and persistence decision that deserves its own document.
  4. Falsifier generation — deriving candidate defeaters from a claim automatically. Not before the manual contract has more mileage.