"""Characterization test for the Environmental Knowledge Program definition (data, not code). Pins the LAW-FIRST contract: the domain is ordered Corpus(B1) -> Capabilities(B2) -> Transition(B3), not the reverse; ownership is assigned per stage; B3 (ISO 14001 -> corpus) is blocked until both sides exist. If a future edit reverses the order or drops an owner, this test fails. """ from __future__ import annotations import os import yaml _PROG = os.path.join(os.path.dirname(__file__), "..", "knowledge", "programs", "environmental.yaml") def _program(): with open(_PROG, encoding="utf-8") as f: return yaml.safe_load(f) def test_blueprint_is_the_reusable_production_line(): p = _program() assert p["blueprint"] == ["corpus", "obligations", "capabilities", "transition_patterns", "playbooks", "reference_scenarios", "completeness"] def test_stages_are_law_first_in_order(): stages = _program()["stages"] assert [s["id"] for s in stages] == ["B1", "B2", "B3"] # corpus -> capabilities -> transition assert "Corpus" in stages[0]["name"] and "Transition" in stages[2]["name"] def test_ownership_assigned_per_stage(): by = {s["id"]: s for s in _program()["stages"]} assert "Legal Knowledge" in by["B1"]["owner"] # corpus + obligations assert "Compliance Execution" in by["B2"]["owner"] # capability model assert "Reasoning" in by["B3"]["owner"] # transition patterns def test_transition_is_blocked_until_both_sides_known(): b3 = {s["id"]: s for s in _program()["stages"]}["B3"] assert b3["status"] == "blocked" assert b3["depends_on"] == ["B1", "B2"] # built LAST (law-first) def test_b1_covers_the_six_environmental_areas(): b1 = {s["id"]: s for s in _program()["stages"]}["B1"] assert set(b1["areas"]) == {"water", "chemicals", "emissions", "energy", "waste", "product_responsibility"} def test_program_is_a_domain_not_an_iso_project(): p = _program() assert "Umweltanforderungen" in p["customer_question"] # starts from the law, not ISO 14001 assert "ISO 14001 ist KEIN Umweltrecht" in p["principle"]