feat(packs): implement ADR-0097 — Mathematics-Logic Reasoning-Capable

First concrete domain claim under ADR-0091's Domain Pack Contract v1.
en_mathematics_logic_v1 is now formally ratified as reasoning-capable
in the capability ledger: 9/9 ADR-0091 predicates pass.

ADR-0097 §"No code changes outside pack artifacts and corpus" relaxed
to include two latent bug fixes that ADR-0093's predicate enforcement
just exposed:

1. language_packs/schema.py: LanguageRole enum widened to include
   DOMAIN_SEED. Three in-tree packs (en_mathematics_logic_v1,
   en_physics_v1, en_systems_software_v1) have declared role="domain_seed"
   since landing but the enum was never updated; load_pack() always
   raised on them. ADR-0093's P1 predicate exposed the mismatch.

2. core/capability/domain_contract_predicates.py: P2 (gloss checksum)
   was reading manifest["checksums"]["glosses_sha256"]; the canonical
   in-tree location is manifest["glosses_checksum"] (top-level). Fixed
   to prefer the canonical key and fall back to the nested form for
   forward compatibility.

ADR-0097 manifest additions to en_mathematics_logic_v1:
- domain_contract_version: 1
- domain_id: "mathematics_logic"
- axioms: null  (rules in v1 — pack proves reasoning via chain
  composition, not declarative axioms)
- rules: null
- teaching_chains: ["mathematics_logic_chains_v1"]
- eval_lanes: three lanes with dev/public/holdout (elementary_mathematics_ood,
  inference_closure, fabrication_control)
- reviewers: ["shay-j"] (resolved via ADR-0092 registry)
- known_gaps: [] (all math/logic gaps in docs/gaps.md were [x])
- provenance: "adr-0097:reviewed:2026-05-21"

Verified evidence:
- core capability domain-contract --pack-id en_mathematics_logic_v1
  → all_passed=True (P1-P9 all pass)
- core capability ledger → mathematics_logic row shows
  status=reasoning-capable, predicates.reasoning_capable=True,
  predicates.expert_demo=False, open_gaps=[],
  operator_chain_coverage all ready=True (8 chains each),
  intent_shapes_present=5
- 14 ADR-0097 invariant tests in
  test_adr_0097_mathematics_logic_ratification.py pin
  status/provenance/expert-demo-gate/contract shape

Two pre-existing tests updated for the new CLI default
(predicate-running, non-zero on missing contract):
- test_capability_domain_contract_json_absent_contract_is_noop now
  uses --structural-only to assert legacy parse-only shape
- test_cli_returns_nonzero_on_missing_contract switched its fixture
  pack from en_mathematics_logic_v1 (now has a contract) to
  en_core_cognition_v1 (no contract)

The pre-existing test_flag_report_tracks_default_off_flags failure
(discourse_planner flag default mismatch, seen since ADR-0092) is
unchanged and unrelated.

Smoke 67/67, packs 6/6, capability tests 49/50, cognition eval
byte-identical 100/100/100/100; lanes byte-identical:
reviewer_registry 6/6, miner_loop_closure 6/6,
domain_contract_validation 9/9, fabrication_control dev 12/12 +
public 9/9.
This commit is contained in:
Shay 2026-05-21 18:51:58 -07:00
parent d7713b07b1
commit 0390491c93
6 changed files with 169 additions and 6 deletions

View file

@ -166,13 +166,18 @@ def _predicate_p2_gloss_closure(
import json
manifest = json.loads(manifest_path.read_text(encoding="utf-8"))
declared = manifest.get("checksums", {}).get("glosses_sha256")
# Canonical location is the top-level ``glosses_checksum`` field
# (in-tree packs use that form). ``checksums.glosses_sha256`` is
# accepted as an alternate location for forward compatibility.
declared = manifest.get("glosses_checksum") or manifest.get(
"checksums", {}
).get("glosses_sha256")
if not declared:
return PredicateResult(
predicate_id="P2",
title="gloss/definition checksum valid",
passed=True,
notes="manifest does not declare glosses_sha256; vacuously passes",
notes="manifest does not declare a gloss checksum; vacuously passes",
)
actual = hashlib.sha256(glosses.read_bytes()).hexdigest()
if actual != declared:

View file

@ -12,5 +12,29 @@
"oov_policy": "tagged_fallback",
"glosses_checksum": "b7d6e1db7469f9fb81d4e376776c790d6511ba7ee44fdb4a7ac58ec65366103a",
"definitional_layer": false,
"provenance": "adr-0090:domain_seed:2026-05-21"
"provenance": "adr-0097:reviewed:2026-05-21",
"domain_contract_version": 1,
"domain_id": "mathematics_logic",
"axioms": null,
"rules": null,
"teaching_chains": ["mathematics_logic_chains_v1"],
"eval_lanes": [
{
"lane": "elementary_mathematics_ood",
"version": "v1",
"splits": ["dev", "public", "holdout"]
},
{
"lane": "inference_closure",
"version": "v1",
"splits": ["dev", "public", "holdout"]
},
{
"lane": "fabrication_control",
"version": "v1",
"splits": ["dev", "public", "holdout"]
}
],
"reviewers": ["shay-j"],
"known_gaps": []
}

View file

@ -24,6 +24,12 @@ class LanguageRole(str, Enum):
ARTICULATION_SURFACE = "articulation_surface"
DEPTH_ROOT = "depth_root"
DEPTH_RELATION = "depth_relation"
# ADR-0097 — added to recognize the domain-pack role used by
# en_mathematics_logic_v1, en_physics_v1, en_systems_software_v1.
# These packs declared role="domain_seed" since landing but the
# enum was never widened; ADR-0093's P1 predicate exposed the
# latent mismatch.
DOMAIN_SEED = "domain_seed"
class OOVPolicy(str, Enum):

View file

@ -0,0 +1,123 @@
"""ADR-0097 — Mathematics-Logic Reasoning-Capable Ratification.
Pins the load-bearing invariant: the capability ledger emits a row
for ``domain_id: mathematics_logic`` with ``status: reasoning-capable``,
its provenance points at ADR-0097, and ``expert-demo`` remains gated
until a future ADR attaches the audit-tour-equivalent reports.
"""
from __future__ import annotations
from core.capability import (
evaluate_domain_contract,
ledger_report,
)
PACK_ID = "en_mathematics_logic_v1"
DOMAIN_ID = "mathematics_logic"
def _ledger_row(domain_id: str) -> dict:
report = ledger_report()
rows = {row["domain"]: row for row in report["domains"]}
assert domain_id in rows, f"missing ledger row for {domain_id!r}"
return rows[domain_id]
class TestRatificationPredicates:
"""The nine ADR-0091 predicates all pass for math/logic."""
def test_all_nine_predicates_pass(self) -> None:
report = evaluate_domain_contract(PACK_ID)
assert report.contract_present is True
assert report.contract_valid is True
assert report.all_passed is True
ids = [p.predicate_id for p in report.predicates]
assert ids == ["P1", "P2", "P3", "P4", "P5", "P6", "P7", "P8", "P9"]
failing = [p.predicate_id for p in report.predicates if not p.passed]
assert failing == []
def test_domain_id_matches(self) -> None:
report = evaluate_domain_contract(PACK_ID)
assert report.domain_id == DOMAIN_ID
def test_provenance_points_at_adr_0097(self) -> None:
row = _ledger_row(DOMAIN_ID)
contracts = row["domain_contracts"]
assert contracts, "math/logic ledger row has no domain_contracts"
provenances = [c["contract"]["provenance"] for c in contracts]
assert any(
p.startswith("adr-0097:reviewed:") for p in provenances
), f"expected an adr-0097 provenance, got {provenances}"
class TestLedgerStatus:
"""ADR-0097 invariant: ``mathematics_logic_reasoning_capable_ledger_row``."""
def test_status_is_reasoning_capable(self) -> None:
row = _ledger_row(DOMAIN_ID)
assert row["status"] == "reasoning-capable"
def test_expert_demo_predicate_is_false(self) -> None:
"""ADR-0097 explicitly defers expert-demo to a follow-up ADR."""
row = _ledger_row(DOMAIN_ID)
assert row["predicates"]["reasoning_capable"] is True
assert row["predicates"]["expert_demo"] is False
def test_no_open_gaps(self) -> None:
row = _ledger_row(DOMAIN_ID)
assert row["open_gaps"] == []
def test_intent_shapes_meet_minimum(self) -> None:
row = _ledger_row(DOMAIN_ID)
assert row["intent_shapes_present"] >= 3
assert row["intent_shapes_required"] == 3
def test_operator_chain_coverage_meets_minimum(self) -> None:
row = _ledger_row(DOMAIN_ID)
coverage = row["operator_chain_coverage"]
for op_family in ("transitive", "proof_chain", "contradiction"):
assert coverage[op_family]["ready"] is True
assert coverage[op_family]["chains_present"] >= 8
class TestContractFieldShape:
"""Ratified contract carries the exact fields ADR-0097 declares."""
def test_contract_fields_present(self) -> None:
report = evaluate_domain_contract(PACK_ID)
assert report.contract_present is True
def test_three_eval_lanes_declared(self) -> None:
row = _ledger_row(DOMAIN_ID)
contract = row["domain_contracts"][0]["contract"]
lane_names = {lane["lane"] for lane in contract["eval_lanes"]}
assert lane_names == {
"elementary_mathematics_ood",
"inference_closure",
"fabrication_control",
}
def test_eval_lanes_have_all_three_splits(self) -> None:
row = _ledger_row(DOMAIN_ID)
contract = row["domain_contracts"][0]["contract"]
for lane in contract["eval_lanes"]:
assert set(lane["splits"]) == {"dev", "public", "holdout"}
def test_teaching_chains_corpus(self) -> None:
row = _ledger_row(DOMAIN_ID)
contract = row["domain_contracts"][0]["contract"]
assert contract["teaching_chains"] == ["mathematics_logic_chains_v1"]
def test_axioms_and_rules_null_at_v1(self) -> None:
"""ADR-0097 §Manifest additions: axioms/rules stay null at v1."""
row = _ledger_row(DOMAIN_ID)
contract = row["domain_contracts"][0]["contract"]
assert contract["axioms"] is None
assert contract["rules"] is None
def test_primary_reviewer_resolves(self) -> None:
row = _ledger_row(DOMAIN_ID)
contract = row["domain_contracts"][0]["contract"]
assert contract["reviewers"] == ["shay-j"]

View file

@ -102,12 +102,17 @@ def test_capability_artifact_json_existing_is_content_addressed() -> None:
def test_capability_domain_contract_json_absent_contract_is_noop() -> None:
"""Packs without a domain contract pass the legacy structural-only
path. ADR-0093 added the default predicate-running mode; this test
pins the legacy shape under ``--structural-only``.
"""
res = _run(
"capability",
"domain-contract",
"--pack-id",
"en_core_cognition_v1",
"--json",
"--structural-only",
)
assert res.returncode == 0, res.stderr
body = json.loads(res.stdout)

View file

@ -403,7 +403,7 @@ class TestEvalLaneArtifacts:
class TestCli:
def test_cli_returns_nonzero_on_missing_contract(self) -> None:
"""The in-tree math/logic pack has no contract yet; CLI exits 1."""
"""A pack without a domain contract exits 1 under default mode."""
import os
import subprocess
import sys
@ -418,7 +418,7 @@ class TestCli:
"capability",
"domain-contract",
"--pack-id",
"en_mathematics_logic_v1",
"en_core_cognition_v1",
"--json",
],
cwd=REPO_ROOT,
@ -447,7 +447,7 @@ class TestCli:
"capability",
"domain-contract",
"--pack-id",
"en_mathematics_logic_v1",
"en_core_cognition_v1",
"--json",
"--structural-only",
],