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:
parent
d7713b07b1
commit
0390491c93
6 changed files with 169 additions and 6 deletions
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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": []
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
123
tests/test_adr_0097_mathematics_logic_ratification.py
Normal file
123
tests/test_adr_0097_mathematics_logic_ratification.py
Normal 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"]
|
||||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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",
|
||||
],
|
||||
|
|
|
|||
Loading…
Reference in a new issue