Phase A of the curriculum-license-loop arc. Design only; no production code,
no flag, no default changed.
Rules R1-R9: polarity is a row-level field (absent => affirmative), negatives
compile to the sentential-not form and MUST reuse the affirmative connective
(atom identity), contradiction is rejected at ratification, premise
compilation becomes query-scoped, an empty scope is UNKNOWN, premise_count
keeps reporting family size, the oracle learns polarity independently, and a
band's honest ceiling must be reported before anyone authors for it.
Three findings, each measured in-tree and each reversing something:
1. `polarity` is read by nothing. A row authored to refute a question today
serves a confident wrong "Yes" -- and the independent oracle ignores the
field for the same reason, so gold agrees and wrong=0 stays green. This is
the silent-failure class Phase A existed to prevent, now demonstrated.
2. The 16-premise honesty cap holds a family to <=16 chains; at 17 the band
declines everything, including the taught positive that works today. So
ADR-0262 §5.1's own remedy (author ~219 relations) destroys the capability
at row 17, tripping the fix §6 deferred as a future contingency. Jointly:
a band has <=16 entailed cases against a 657-committed threshold, so no
curriculum band can earn SERVE until scoping lands. The blocker is
engineering, not content -- inverting the conclusion two arcs closed on.
3. Honest volume is bounded by taught vocabulary, not corpus size. 8 of 11
bands cannot reach 657 at all, including the plan's chosen first target
physics·modal (ceiling 480, counting every possible question). Retargets
Phase F to philosophy_theology·modal (ceiling 44,104, same 8-chain start).
R5 is the only rule that could change an existing answer, so it is the only
one carrying evidence: 8,520 routable questions, 0 verdict mismatches for both
candidate scopes. Verdict-identity holds for any scope that is a superset of
the query-atom rows, since each premise mints one independent atom. That is
stronger than ADR-0262 §6's soundness argument, and it is why this narrowing
is not the ADR-0261 §5.1 premise-dropping failure.
ADR-0262 §5.1/§5.2/§6 carry forward-pointers; original text preserved.
[Verification]: uv sync --locked on canonical CPython 3.12.13; in-worktree
`core test --suite smoke -q` 556 passed (555 baseline + 1: the derived
ratify-on-merge pin picked up ADR-0264 and discharged it), `--suite
deductive -q` 285 passed. Four probes reproducible from
docs/research/curriculum-premise-scope-2026-07-25.md; the corpus-mutating one
restores the file and asserts byte-identity.
Nine ADRs (0254, 0256-0263) were merged into main and left stamped Proposed.
Two carried an explicit ratify-on-merge predicate their own merge had already
discharged, and ADR-0256 governs deduction_serving_enabled, which was ratified
True on 2026-07-24 and is serving live traffic. So the governance record
asserted "not yet decided" about a decision already in force.
That is the asymmetry the assessment arc (#113) found one file over in
workbench/api.py: the honest path degrades, the stale record lies. An unwritten
ADR is a visible gap; a Proposed one that is actually in force is a false
statement.
Each stamp records the ACTUAL ratifying act -- "Accepted, ratified by Joshua
Shay via <merge> (<sha>, <date>)" -- derived from the commit that added the file
and verified an ancestor of main, not assumed. Merge authority is Shay's alone
(AGENTS.md: no merge automation), so the merge IS the ratifying act.
No ADR content changed. No flag changed. ADR-0262's stamp says so explicitly:
accepting it does NOT enable curriculum_serving_enabled, which stays False
pending ratified volume -- eleven bands re-measured today, still 24x-73x short.
tests/test_adr_status_governance.py pins two independent invariants in the
smoke (pre-push) suite:
1. A default-ON flag is not governed by a Proposed ADR. The flag -> ADR mapping
is DERIVED by walking core/config.py for `<name>: bool = True` and reading
ADR refs from the preceding comment block -- not a hand-written table, which
would be the same second-copy-of-a-closed-set defect ADR-0256's arc fixed.
2. A ratify-on-merge predicate cannot coexist with Proposed. Self-discharging:
the file being on main IS the merge having happened.
Plus a vacuity guard, because a derivation that parses zero flags would make
every other assertion pass on an empty set.
Registered two orphans found in passing: test_adr_index.py (5) and
test_ratification_ceremony.py (14) landed in #113 in NO curated suite, so 19
tests -- including the one mechanism that can move curriculum volume -- ran
only under `full`, which gates nothing. Fifth instance of this shape.
Deliberately NOT fixed, recorded in the research doc: the 312-file corpus has
27 unparseable status lines and draft/ratified/active variants. A closed-vocab
assertion would fail on ~35 pre-existing files and get muted, and a muted gate
reads as coverage.
[Verification]: smoke 555 passed in 137.73s (236 baseline + 314 + 5, +1.2s);
governance pin 314 passed in 1.18s standalone and MUTATION-CHECKED -- reverting
ADR-0256 to Proposed fails both invariants independently (2 failed/312 passed);
orphans 19 passed; ruff clean. Canonical Python 3.12.13, uv sync --locked.
The curriculum composer committed on question SHAPE — any `Does …?` text —
and then, being fail-closed, always returned a surface. With the flag on,
"Does the build pass?" would have been taken away from the rest of dispatch
and answered "I haven't been taught the or pass"; "Does anyone know the
time?" likewise. Found by checking the flag's readiness before recommending
ratification; never live, since the flag is default-off.
The asymmetry is the lesson: the deduction composer may commit on shape
because a sentence-initial "therefore" IS a signal of intent — text shaped
that way is an argument. `Does …?` is one of the most common ways to open
any English question and signals nothing. A fail-closed composer is only as
safe as its commit gate is narrow.
The gate is now `is_curriculum_question`: claim the turn only when the
question parses to three tokens AND its terms are vocabulary a served
subject actually teaches. Everything past the gate stays fail-closed —
including `ambiguous_reading` (both terms taught, two subjects claim them)
and `out_of_curriculum` (terms taught, relation unknown), which are real
curriculum questions with honest answers. The DECIDER is unchanged, so the
lane still records untaught-vocabulary probes as declined: the curriculum
path declines them AND does not speak for them.
[Verification]: tests/test_curriculum_serve.py 28 passed (+8: five ordinary
`Does …?` questions pass through untouched, three routable ones still
answered); core test --suite deductive 268 passed; curriculum lane 32/32
wrong=0 with its pinned report SHA unchanged.
Phase 2 of the generalization arc, implementing the plan's §4
curriculum-entailment gold contract. "Does force cause acceleration?" is
answered from the ratified physics chain corpus and nothing else; "Does
gravity cause acceleration?" is declined because gravity is in no pack
CORE has been taught; "Does force cause motion?" is unsettled even though
the curriculum contains both links, because nothing ratified says
causation composes.
Path (flag-gated, default off): closed question grammar -> subject routing
by ratified vocabulary -> family-scoped premise compilation from reviewed,
pack-resident chains -> the SAME argument bands (ADR-0260/0261) -> the
ROBDD engine. Zero subject-specific decision code: physics differs from
philosophy only in which rows load.
Epistemology enforced mechanically, not by convention:
- gold is a function of (curriculum, question); cases pin chain ids and
the runner FAILS a case whose pinned chain is absent or unratified;
- untaught => UNKNOWN, never "no" (open-world; silence is not denial);
- an independent oracle (own loader, ratification predicate, family table,
agreement rules, verdict rule) re-derives every gold — it disagreed once,
on "entropy reveals energy" vs "entropy causes energy", and the ORACLE
was the side that was wrong;
- anti-recall probes are a lane GUARD: a split without >=3 true-but-untaught
probes refuses to run.
Findings recorded rather than worked around (ADR-0262 §5):
- every curriculum band is UNEARNED and every answer is hedged. A band needs
n>=657 with a real outcome mix; physics teaches 7 causal + 9 modal
relations, so at most 16 questions in the subject can ever be ENTAILED.
A balanced band needs ~219 taught relations per subject×family — a ~25x
gap that only ratified curriculum content closes. Phase 2's blocker is
curriculum volume, not machinery.
- REFUTED is unreachable from present corpora (every chain is positive).
- there is NO biology domain-chain corpus; the biology OOD lane measures
fluency, not truth. The four subjects with ratified chains and mounted
packs are physics, mathematics_logic, systems_software,
philosophy_theology — the composer serves all four.
[Verification]: curriculum lane 32/32 wrong=0 with 5 anti-recall probes and
all three contract guards passing; tests/test_curriculum_serve.py 20 passed;
core test --suite deductive 252 passed; lane pinned as curriculum_serve_v1.