Ratified by Joshua Shay 2026-07-26. All nine rules are implemented and merged to
main @ 803703fc: R5-R7 (#120), R9 (#117), R1-R4/R8 (#125). The status line names
the enforcement pins so the record points at what holds it up.
Also discharges a staleness the ratification would otherwise have blessed. §4.1's
heading — "No curriculum band can earn a SERVE license under the current
architecture" — is NO LONGER TRUE of the running system, and it was falsified by
this ADR's own R5: the finding rested on "the premise cap holds a family to <=16
chains", and query-scoped compilation removed that cap. Post-R5, four bands would
earn SERVE the moment a ledger is sealed. Leaving that heading unqualified in an
Accepted ADR is precisely the ADR-0256 shape — a governance record asserting
something false about live code.
The §4.1 CONCLUSION survives, for a different and stronger reason, and the note
says so: reliability is commitment precision and a correct UNKNOWN is a
commitment, so a band clears theta_SERVE on non-commitments alone
(conservative_floor(660,660)=0.990046). Licensable evidence is 99.0-99.98%
non-entailed; max entailed volume in any band is 9. So §4.1's "≥97.6%
non-entailed" arithmetic was directionally right and its CAUSE was wrong — it is
not the premise cap that makes a curriculum license dishonest, it is the absence
of a mix rule. The binding constraint is now the outcome-mix ruling (§5, still
open), and nothing is licensed while it is unmade: the ledger is absent and
`core proposal-queue reseal` refuses to grant a license without
--allow-new-licenses.
[Verification]: in-worktree on canonical CPython 3.12.13 with `uv sync --locked`:
smoke 621 (unchanged), and 335 passed across test_adr_status_governance.py /
test_adr_index.py / test_volume_honesty.py. Status parses as "Accepted …" under
the governance regex and the banned `ratify-on-merge` predicate is absent. No
flag moved; no code changed.
450 lines
25 KiB
Markdown
450 lines
25 KiB
Markdown
# ADR-0264 — Negative curriculum, premise scope, and what a curriculum band can earn
|
||
|
||
- **Status:** Accepted — ratified by Joshua Shay 2026-07-26. All nine rules
|
||
(R1–R9) are implemented and merged to `main` @ `803703fc`. This ADR changes no
|
||
flag and no default; it fixed a schema shape and a compilation rule, and it
|
||
recorded a blocking finding about ADR-0262 §5.1. **§4.1 is self-superseded by
|
||
this ADR's own R5** — see the note there before citing it.
|
||
- **Date:** 2026-07-25 · **Ratified:** 2026-07-26
|
||
- **Implemented by:** R5–R7 #120 · R9 #117 · R1–R4/R8 #125. Enforcement pins:
|
||
`tests/test_curriculum_polarity.py` (R1–R4, R8),
|
||
`tests/test_volume_honesty.py` (R9),
|
||
`tests/test_curriculum_serve.py` (R6/R7),
|
||
`tests/test_curriculum_practice.py` (R9 at the producer).
|
||
- **Arc:** curriculum-license-loop Phase A
|
||
(`docs/plans/curriculum-license-loop-2026-07-25.md` §4)
|
||
- **Governs:** the `polarity` field of `teaching/domain_chains/*.jsonl`,
|
||
`teaching/curriculum_premises.py` (`CurriculumChain.sentence`,
|
||
`compile_premises`, `load_curriculum` admission),
|
||
`chat/curriculum_surface.py::decide_curriculum_question`,
|
||
`evals/curriculum_serve/oracle.py`, and
|
||
`teaching/ratification.py::validate_admissible`.
|
||
- **Amends:** ADR-0262 §5.1 (its conclusion, not its decision) and §6's
|
||
premise-set-scaling scope-out. Builds on ADR-0261 §5.1 (refuse, don't drop)
|
||
and ADR-0260 (the verb-predicate band that decides these arguments).
|
||
|
||
## 1. Context
|
||
|
||
The plan of record asked Phase A one question: how does an explicitly-taught
|
||
negative coexist with the open-world reading, where an absent edge must stay
|
||
UNKNOWN and never become "no"? Answering it required reading the compilation
|
||
path end to end, and that read produced three facts that were not known when the
|
||
plan was written. Two of them change what the arc must do next.
|
||
|
||
Everything below was verified by running the real path in-tree, not by reading
|
||
docstrings. Reproduction is in §6.
|
||
|
||
**Fact 1 — the row field `polarity` is silently ignored, and a negative row
|
||
serves a confident wrong "Yes."** `load_curriculum` reads
|
||
`review_status`, `domain`, `subject`, `object`, the two `*_pack_id` fields and
|
||
`connective`. Nothing else. `CurriculumChain.sentence` is unconditionally
|
||
`f"{subject} {connective} {obj}"`. So a row added today with
|
||
`"polarity": "negative"` compiles to the *affirmative* sentence, and the question
|
||
it was authored to refute comes back `entailed`:
|
||
|
||
```
|
||
+1 negative row (acceleration requires charge, polarity=negative)
|
||
Does acceleration require charge? -> verdict='entailed'
|
||
```
|
||
|
||
The user-visible surface for that verdict is *"Yes — my physics curriculum
|
||
teaches that acceleration requires charge, directly, among the 10 modal
|
||
relations it states."* The curriculum said the opposite.
|
||
|
||
This is not caught by any gate. `evals/curriculum_serve/oracle.py` is
|
||
independent in code but reads the same rows, and it ignores `polarity` for the
|
||
same reason. Gold and the serving path agree on the wrong answer, so the lane
|
||
stays green and `wrong=0` holds. This is the exact failure class Phase A exists
|
||
to prevent, and it is now demonstrated rather than hypothesised.
|
||
|
||
**Fact 2 — `operator_family` is not the band axis; the connective is.** The plan
|
||
of record and the division-of-work both state that bands key on
|
||
`(domain, operator_family)` and warn against a `modal_negative` family. The
|
||
warning points at a real hazard but names the wrong field. `load_curriculum`
|
||
never reads the row's `operator_family`; `CONNECTIVE_FAMILY[connective]` is the
|
||
sole family authority, deliberately and as documented in
|
||
`teaching/curriculum_premises.py`. Two rows in the corpus already declare a
|
||
family their connective contradicts (`physics-causal-008` and one
|
||
`systems_software` row, both `requires`/`causal`) and are correctly read as
|
||
modal. `physics · modal` therefore holds **9** chains, not 8 — which is where
|
||
the plan's `n=9` came from.
|
||
|
||
The hazard restated correctly: the connective fixes both the band **and the
|
||
propositional atom**. A negative expressed as a *new connective* (`precludes`,
|
||
`does_not_require`) mints a different atom from the positive question it was
|
||
meant to refute, so the ROBDD returns UNKNOWN instead of REFUTED — silently, at
|
||
every such row.
|
||
|
||
**Fact 3 — the premise cap makes ADR-0262 §5.1's own prescribed remedy destroy
|
||
the capability it was meant to build.** `compile_premises` emits *every* chain in
|
||
the family as a premise sentence, and `read_verb_argument` refuses beyond
|
||
`MAX_PREMISE_SENTENCES = 16`. Measured end to end:
|
||
|
||
```
|
||
physics modal chains = 9 (cap = 16)
|
||
+7 rows -> 16 premises: taught positive = 'entailed' negative pair = 'entailed'
|
||
+8 rows -> 17 premises: taught positive = 'declined' negative pair = 'declined'
|
||
reason='compiled_premises_unreadable'
|
||
```
|
||
|
||
At row 17 the band stops answering *anything* — including
|
||
`conservation requires symmetry`, which works today. ADR-0262 §5.1 prescribes
|
||
authoring **≈219 relations per subject × family** to reach a balanced band.
|
||
ADR-0262 §6 scopes premise-set scaling out, on the reasoning that "no current
|
||
family exceeds 9" and the fix can wait until one does. Those two sections are in
|
||
contradiction: §5.1's remedy triggers §6's deferred fix at row 17 and then
|
||
collapses the band for the remaining 202 rows. The scope-out silently blocks the
|
||
plan it shares an ADR with.
|
||
|
||
## 2. Decision
|
||
|
||
**R1 — Polarity is a row-level `polarity` field.** Values `"affirmative"` and
|
||
`"negative"`; **absent means affirmative**, so all 88 existing rows are
|
||
unchanged and no migration is required.
|
||
|
||
It is *not* an `intent` value. `intent` already carries an orthogonal
|
||
teaching-intent axis with five values in use
|
||
(`cause`/`verification`/`procedure`/`comparison`/`correction`); overloading it
|
||
would conflate two independent axes in one column and make each unreadable from
|
||
the other. It is *not* a new `operator_family` value and *not* a new
|
||
`connective` — see R3.
|
||
|
||
**R2 — A negative row compiles to the sentential-not form.**
|
||
|
||
```
|
||
affirmative: f"{subject} {connective} {obj}"
|
||
negative: f"it is not the case that {subject} {connective} {obj}"
|
||
```
|
||
|
||
The `("it","is","not","the","case","that")` prefix is an existing shape in
|
||
`generate/proof_chain/english.py` and `member.py`, already read by the verb
|
||
band. It is chosen over `"{subject} does not {connective} {obj}"` for one
|
||
reason: the `does not` shape wants the base form of the verb (`require`, not
|
||
`requires`), which would require a de-inflection table — a new inverse of
|
||
`_VERB_IRREGULAR_3SG` — to be invented and maintained. The band happens to read
|
||
`"does not requires"` too, but that is ungrammatical English written into a
|
||
reasoning trace, and depending on it would be depending on an accident.
|
||
|
||
Verified: all three shapes reach `REFUTED` with correct atom identity
|
||
(premises `('a0','a1','~(a2)')` against query `'a2'`).
|
||
|
||
**R3 — A negative row MUST reuse the affirmative connective.** Atom identity is
|
||
`(subject, normalized-verb, object)`. `REFUTED` is `(⋀P) → ¬Q` being a tautology,
|
||
which requires the negated premise and the query to be *the same atom*. A new
|
||
connective mints a new atom and yields UNKNOWN. `validate_admissible` must reject
|
||
a negative row whose connective is absent from `CONNECTIVE_FAMILY`.
|
||
|
||
**R4 — Contradiction is rejected at ratification, not discovered at serve
|
||
time.** A negative row for a `(domain, subject, connective, object)` that already
|
||
holds an affirmative row — or the reverse — is inadmissible.
|
||
`teaching/ratification.py::validate_admissible` rejects it. Without this guard
|
||
the compiled premise set is inconsistent, `evaluate_entailment_with_trace`
|
||
returns `REFUSED`/`INCONSISTENT_PREMISES`, and the surface says *"The curriculum
|
||
I have for that is inconsistent"* — an honest answer to a problem that should
|
||
never have been ratified. Fail at authoring, where a human is present.
|
||
|
||
**R5 — Premise compilation is query-scoped, and the scope must be a superset of
|
||
the query-atom rows.** The soundness condition is exact:
|
||
|
||
> For a corpus of atomic rows, every compiled premise mints one independent
|
||
> propositional atom. A scope that contains every row whose atom is the query's
|
||
> atom decides the query identically to the full family, because no other atom
|
||
> appears in the query formula and independent atoms cannot constrain it.
|
||
|
||
Two consequences worth stating separately, because ADR-0262 §6 conflates them:
|
||
|
||
- **Sound** (narrowing cannot invent an entailment) is the weaker property §6
|
||
argues for. It is true but insufficient — a narrowing can be sound while
|
||
silently *losing* true entailments, which is coverage loss in exactly the
|
||
class of case the license counts, and is the shape ADR-0261 §5.1 was written
|
||
about.
|
||
- **Verdict-identical** is the property R5 requires, and it holds only for a
|
||
scope that is a superset of the query-atom rows.
|
||
|
||
The default scope is **term incidence**: rows whose subject or object is one of
|
||
the query's two terms. This is bounded by vocabulary degree rather than corpus
|
||
size, keeps real neighbouring premises in the argument, and is a superset of the
|
||
query-atom rows. If term incidence would still exceed the band's cap, narrow to
|
||
the query-atom rows — never an arbitrary truncation. The reader is never asked to
|
||
refuse for size.
|
||
|
||
> **Precision fix, 2026-07-26.** "Verdict-identical" is exact for every scope the
|
||
> full family could be *read* at, and that is where the 8,520-question / zero-
|
||
> mismatch evidence in §6 was gathered. It is **not** exact for the over-cap
|
||
> branch: there the full family exceeds `MAX_PREMISE_SENTENCES`, so full-family
|
||
> compilation would refuse `compiled_premises_unreadable` and answer nothing.
|
||
> Narrowing there is verdict-**improving**, not identical — which is the entire
|
||
> point of the unblock. The precise claim is therefore: **identical wherever the
|
||
> full family was readable, improving where it was not.** Read literally, the
|
||
> unqualified phrasing would lead a reader to expect a 17-chain family to keep
|
||
> declining, which is backwards.
|
||
|
||
**R6 — An empty scope is UNKNOWN; only an empty family is a refusal.** Today
|
||
`compile_premises` returning nothing means "this family has no ratified chains"
|
||
and correctly refuses `empty_curriculum`. Under R5 it will much more often mean
|
||
"no ratified chain mentions this query", which is UNKNOWN — the open-world
|
||
reading. These two must be distinguished at the call site, or 8,463 of the 8,520
|
||
questions measured in §6 flip from `unknown` to `declined`.
|
||
|
||
**R7 — `premise_count` continues to report family size.** It is user-visible
|
||
(*"It states 9 modal relations, and none of them decides this one"*). Under R5
|
||
the compiled scope is usually 0 or 1, and reporting that number would understate
|
||
the curriculum to the user. Report family size in the surface; carry the
|
||
compiled-scope size as a separate field for the lane and the audit ledger, and
|
||
disclose the narrowing there. This also keeps ADR-0262 §7's existing assertions
|
||
stable.
|
||
|
||
**R8 — The oracle learns polarity independently.** `evals/curriculum_serve/oracle.py`
|
||
reads `polarity` with its own default rule and its own restated vocabulary, sharing
|
||
no helper with `teaching/curriculum_premises.py`. Its code-level independence is
|
||
the entire evidentiary value of the lane; a shared polarity helper would make the
|
||
two agree by construction, which is what Fact 1 shows is indistinguishable from
|
||
being right. Additionally: **negative edges are excluded from the BFS adjacency**.
|
||
A negative edge is not a traversable path, and including it would inflate the
|
||
reachability depths the lane asserts against.
|
||
|
||
**R9 — Committed volume must be DISTINCT evidence, and a band that cannot reach
|
||
the threshold must say so before anyone authors for it.**
|
||
|
||
`conservative_floor` is a one-sided Wilson lower bound, and Wilson assumes
|
||
**independent trials**. CORE's pipeline is deterministic, so replaying an
|
||
identical case is not a second trial — it is the same trial with a guaranteed
|
||
outcome. A ledger's `committed` count is therefore an upper bound on its
|
||
evidence, and the defensible figure is its distinct-decision count. A producer
|
||
must commit at most one case per distinct decision, where the decision key for
|
||
this path is the query atom `(domain, subject, connective, object)` — spelling
|
||
variants of one question are one case, because R2/R3 normalize them to one atom.
|
||
|
||
Additionally the producer reports, per band, the maximum honest committed volume
|
||
(§4.2) and the maximum entailed share the ratified corpus can support, and a band
|
||
whose ceiling is below the licensing threshold is reported **structurally unable
|
||
to earn SERVE** rather than left for authoring effort to discover.
|
||
|
||
> **Amended 2026-07-25, Phase B.** This rule was written as a precaution for a
|
||
> producer that does not exist yet. Measuring the producers that *do* exist found
|
||
> it already violated: **21 of the 25 ratified `deduction_serve` bands do not
|
||
> clear θ_SERVE=0.99 on distinct evidence**, three of them inflating 28 distinct
|
||
> cases into 720 committed, under a flag ratified ON. The `estimation` producer
|
||
> (ADR-0175) is clean at 660 distinct per class, so this is a regression from an
|
||
> established standard rather than an architectural gap. Measured, pinned in both
|
||
> directions by `tests/test_volume_honesty.py`, and **not repaired** — the ledger
|
||
> is SHA-sealed and ratified, so re-sealing it is Shay's decision. Full audit:
|
||
> `docs/research/distinct-evidence-audit-2026-07-25.md`.
|
||
>
|
||
> Outcome *mix* is deliberately excluded from the pin. `ClassTally` has no verdict
|
||
> axis, so mix can only be enforced at the producer; the deduction producer
|
||
> already balances 240/240/240 by construction; and whether each verdict class
|
||
> needs its own 657 is an open ruling that would retroactively fail all 25 bands
|
||
> (smallest per-band verdict-class count is 120). Recorded for Shay with numbers,
|
||
> not decided.
|
||
|
||
## 3. Why this is sound
|
||
|
||
R5 is the only rule that changes an existing answer, so it is the only one that
|
||
needs evidence rather than argument. Both candidate scopes were compared against
|
||
full-family compilation over every routable question in all four served domains
|
||
(philosophy_theology sampled to its first 40 lemmas to stay tractable):
|
||
|
||
```
|
||
questions compared : 8520
|
||
term-incidence mismatches : 0
|
||
query-atom mismatches : 0 (over non-empty scopes)
|
||
query-atom EMPTY scopes : 8463 <- R6 governs these
|
||
max premises, full-family : 9
|
||
max premises, term-incidence : 8
|
||
```
|
||
|
||
Zero verdict changes. The physics lane's `entailed 14 / unknown 12 / declined 6`
|
||
gold is preserved exactly: taught edges keep a non-empty query-atom scope and
|
||
stay `entailed`; untaught pairs get an empty scope and stay `unknown` under R6;
|
||
pre-band refusals are untouched.
|
||
|
||
R1–R4 and R8 add a verdict (`REFUTED`) that the decision path already maps and
|
||
already has a surface template for. They do not change any existing answer,
|
||
because absent `polarity` means affirmative.
|
||
|
||
## 4. Findings
|
||
|
||
### 4.1 No curriculum band can earn a SERVE license under the current architecture
|
||
|
||
> **SELF-SUPERSEDED by this ADR's own R5, discharged 2026-07-26. The heading is no
|
||
> longer true of the running system.** Read the finding below as a statement about
|
||
> the **pre-R5** architecture; it was accurate then and it is why R5 exists.
|
||
>
|
||
> §4.1's reasoning rests on "the premise cap holds a family to ≤16 chains". R5
|
||
> removed that: compilation is query-scoped, so a family of any size answers. With
|
||
> the cap gone, **four bands would earn SERVE the moment a ledger is sealed** —
|
||
> `physics·causal`, `systems_software·causal`, and
|
||
> `philosophy_theology·{modal,contrast}` — measured in
|
||
> `docs/research/curriculum-practice-producer-2026-07-26.md` §1.
|
||
>
|
||
> But the conclusion "the binding constraint is not curriculum volume" **survives,
|
||
> for a different and stronger reason.** Reliability is commitment precision and a
|
||
> correct UNKNOWN is a commitment, so a band clears θ_SERVE **on non-commitments
|
||
> alone**: `conservative_floor(660,660) = 0.990046`. The licensable evidence is
|
||
> 99.0–99.98% non-entailed, and max entailed volume in any band is **9**. So §4.1's
|
||
> "≥97.6% non-entailed" arithmetic was directionally right and its cause was wrong
|
||
> — it is not the premise cap that makes a curriculum license dishonest, it is the
|
||
> absence of a mix rule. That also means the plan's Phase-1 exit criterion ("a
|
||
> real, still-unearned ledger") is unreachable: a committed ledger is necessarily
|
||
> an earning one.
|
||
>
|
||
> **The binding constraint is now the outcome-mix ruling** (§5, recorded as open
|
||
> and still open). `chat/data/curriculum_serve_ledger.json` is deliberately absent
|
||
> and `core proposal-queue reseal` refuses to grant a license without
|
||
> `--allow-new-licenses`, so nothing is licensed while that ruling is unmade.
|
||
|
||
This follows from two facts already in the repository, and it does not depend on
|
||
any rule in §2.
|
||
|
||
- A taught edge makes exactly one question come back `entailed`, so the entailed
|
||
cases available to a band equal the number of ratified chains in its family.
|
||
- The premise cap holds a family to **≤16 chains** — beyond that the band
|
||
answers nothing at all (Fact 3).
|
||
|
||
So a band has at most 16 entailed cases available, against a licensing threshold
|
||
of **n ≥ 657 committed**. Reaching 657 therefore requires a ledger that is at
|
||
least `1 − 16/657` = **97.6% non-entailed**. ADR-0262 §5.1 already rules that
|
||
unacceptable. Its ⅓-entailed target caps committed volume at `3 × 16 = 48`, and
|
||
*any* mix floor above 2.44% blocks a license outright.
|
||
|
||
The conclusion inverts §5.1's: the binding constraint is **not** curriculum
|
||
volume, and not "a curriculum-authoring and ratification task — Shay's call, not
|
||
an engineering one." Authoring is blocked by an engineering prerequisite. R5 is
|
||
that prerequisite: query-scoped compilation removes the 16-chain ceiling, at
|
||
which point §5.1's ≈219-relation prescription becomes achievable and its
|
||
arithmetic becomes correct again.
|
||
|
||
### 4.2 Seven of eleven bands cannot reach the threshold even with unlimited authoring
|
||
|
||
> **CORRECTED 2026-07-26, after Phase C measured this against the wired code.**
|
||
> The original heading said *eight* of eleven and the table below understated
|
||
> every ceiling. Both errors have one cause: I sized bands from **per-term
|
||
> exclusivity** (a lemma taught by only one subject), while `resolve_domain`'s
|
||
> actual predicate is **per-pair** — a question routes iff exactly one served
|
||
> subject holds *both* terms. A lemma taught in two subjects can still appear in
|
||
> a pair only one of them holds both halves of, so per-term exclusivity is a
|
||
> strictly tighter bound.
|
||
>
|
||
> | band | stated below | measured | change |
|
||
> |---|---:|---:|---|
|
||
> | `curriculum_systems_software_causal` | 630 | **720** | **impossible → reachable** |
|
||
> | `curriculum_philosophy_theology_modal` | 44,104 | 45,300 | — |
|
||
> | `curriculum_philosophy_theology_contrast` | 22,052 | 22,650 | — |
|
||
> | `curriculum_mathematics_logic_modal` | 420 | 480 | — |
|
||
> | `curriculum_mathematics_logic_{sequence,contrast,evidential}` | 210 | 240 | — |
|
||
> | `curriculum_systems_software_modal` | 420 | 480 | — |
|
||
> | `curriculum_systems_software_sequence` | 210 | 240 | — |
|
||
> | `curriculum_physics_{causal,modal}` | 720 / 480 | 720 / 480 | — |
|
||
>
|
||
> So **four** bands can reach 657, not three, and **seven** cannot, not eight.
|
||
> Every conclusion that depends on this survives: `physics · modal` at 480 is
|
||
> still impossible at any authoring volume, and `philosophy_theology · modal` is
|
||
> still the defensible target by two orders of magnitude. The numbers are now
|
||
> pinned as *measured* values in
|
||
> `tests/test_curriculum_practice.py::BAND_ATOM_SPACE`, so this class of error
|
||
> cannot recur silently. See
|
||
> `docs/research/curriculum-practice-producer-2026-07-26.md` §2.
|
||
>
|
||
> The original text is preserved below unedited.
|
||
|
||
Volume is bounded by *taught vocabulary*, not by corpus size, because a question
|
||
must have both terms in exactly one served subject's vocabulary to route at all
|
||
(`ambiguous_reading` otherwise). Measured routable question spaces:
|
||
|
||
| domain | \|V\| | exclusive lemmas | routable ordered pairs |
|
||
|---|---|---|---|
|
||
| physics | 16 | 16 | 240 |
|
||
| mathematics_logic | 16 | 15 | 210 |
|
||
| systems_software | 16 | 15 | 210 |
|
||
| philosophy_theology | 151 | 149 | 22,052 |
|
||
|
||
`max_honest_n = routable_pairs × |connectives(family)|`, one committed case per
|
||
distinct question:
|
||
|
||
| band | chains | max honest n | vs 657 |
|
||
|---|---|---|---|
|
||
| curriculum_physics_causal | 7 | 720 | reachable |
|
||
| **curriculum_physics_modal** | **9** | **480** | **impossible** |
|
||
| curriculum_mathematics_logic_modal | 4 | 420 | impossible |
|
||
| curriculum_mathematics_logic_contrast | 8 | 210 | impossible |
|
||
| curriculum_mathematics_logic_evidential | 8 | 210 | impossible |
|
||
| curriculum_mathematics_logic_sequence | 4 | 210 | impossible |
|
||
| curriculum_systems_software_causal | 7 | 630 | impossible |
|
||
| curriculum_systems_software_modal | 6 | 420 | impossible |
|
||
| curriculum_systems_software_sequence | 3 | 210 | impossible |
|
||
| curriculum_philosophy_theology_contrast | 8 | 22,052 | reachable |
|
||
| curriculum_philosophy_theology_modal | 8 | 44,104 | reachable |
|
||
|
||
**The plan of record's first content target is one of the impossible ones.**
|
||
`physics · modal` was chosen for having the most chains (9, "closest of eleven
|
||
bands"). Chain count is not the constraint; vocabulary is. Its ceiling is 480 —
|
||
below the threshold with every possible question counted, and that ceiling cannot
|
||
be raised by authoring chains, only by growing `en_physics_v1`.
|
||
|
||
`physics · causal` is nominally reachable at 720 but would need 657 of its 720
|
||
questions — 91% of the entire space — leaving no held-out room at all.
|
||
|
||
**The defensible first target is `philosophy_theology · modal`:** 44,104 honest
|
||
ceiling (67× the threshold), 8 chains already ratified, and the same 8-chain
|
||
starting point as the physics band. This reverses a decision in the plan of
|
||
record, on a measurement.
|
||
|
||
### 4.3 The two unbuilt segments are still unbuilt, and are still not the blocker
|
||
|
||
Phases C and D stand as written — `evals/curriculum_serve/practice/` and the
|
||
`reseal` verb do not exist, and `chat/data/curriculum_serve_ledger.json` has no
|
||
writer. That finding survives. What changes is its priority: building the
|
||
producer before R5 lands would produce a correct instrument reporting that every
|
||
band is at its ceiling.
|
||
|
||
## 5. What this ADR does not decide
|
||
|
||
- **The bound in R9.** The specific de-duplication tuple and mix floor are
|
||
Phase B's deliverable. R9 fixes only that a bound must exist and be reported.
|
||
- **Raising `MAX_PREMISE_SENTENCES`.** Rejected as an approach, not deferred: it
|
||
is a shared honesty cap that the 25 deduction bands also decide under, raising
|
||
it would move hash-pinned lanes, and a 219-premise argument is not honest at
|
||
any cap. R5 makes the cap irrelevant to curriculum instead.
|
||
- **Composition across curriculum edges.** Still scoped out per ADR-0262 §3.3.
|
||
R8's exclusion of negative edges from BFS is a reachability-reporting rule, not
|
||
a licence to chain.
|
||
- **Negated questions.** The grammar stays `Does <term> <relation> <term>?`,
|
||
three tokens. Polarity lives in the curriculum, never in the question. "Does X
|
||
not require Y?" is four tokens and refuses typed, as it does today.
|
||
- **Growing `en_physics_v1`.** §4.2 says physics bands need vocabulary, not
|
||
chains. Whether to grow the pack is a separate ratified decision.
|
||
- **Any flag.** `curriculum_serving_enabled` stays False.
|
||
|
||
## 6. Verification
|
||
|
||
All four probes are in
|
||
`docs/research/curriculum-premise-scope-2026-07-25.md`, each runnable against a
|
||
clean tree; the corpus-mutating one restores the file and asserts byte-identity.
|
||
|
||
1. **Negation reaches REFUTED** — three shapes, atom identity checked.
|
||
2. **Cap collapse** — real negative rows appended to
|
||
`physics_chains_v1.jsonl`; band answers at 16 premises, declines at 17,
|
||
including the previously-working taught positive. Also demonstrates Fact 1:
|
||
at +1 row the negative pair answers `entailed`.
|
||
3. **Scope equivalence** — 8,520 routable questions, 0 mismatches for both
|
||
candidate scopes, 8,463 empty query-atom scopes.
|
||
4. **Band ceilings** — the §4.2 table, derived from `CONNECTIVE_FAMILY` and the
|
||
loaded vocabularies rather than restated.
|
||
|
||
No production code changed in this ADR; §2's rules are implemented by Phase C
|
||
against Phase B's tests.
|
||
|
||
## 7. Consequences for the plan of record
|
||
|
||
1. **New phase, before content: implement R5–R7.** Nothing else in the arc can
|
||
earn anything until the 16-chain ceiling is gone. Loud failure mode (the lane
|
||
pins every physics verdict), so it is a Sonnet unit once the assertion set
|
||
here is fixed — which it now is.
|
||
2. **Phase F retargets to `philosophy_theology · modal`** per §4.2, and its
|
||
volume target is recomputed against that band's ceiling.
|
||
3. **Phase B additionally specifies R9's ceiling report**, so no future arc
|
||
spends authoring effort on a structurally impossible band.
|
||
4. **ADR-0262 §5.1's conclusion is amended** by §4.1 — the constraint is
|
||
engineering-then-content, not content alone. §5.1's *criterion* is upheld and
|
||
promoted to a measured precondition.
|