feat: adopt canon 0.4.0-0.6.0 — EvidenceBasis is canon, uses_provisions is canon
Both demands were accepted. Adopting what landed. EVIDENCE BASIS IS NOW ITC-GOV CANON (0.4.0) tools/basis.py reads infospace/models/governance/evidence-basis.yaml instead of defining its own vocabulary — same discipline we already applied to the capability catalog. Two semantic changes came back that we did not have: - estimated and assumed are peers in tier "judgement". We had them separately ranked, which asserted a difference the canon does not. - derived belongs to no tier at all; asking for its tier before resolving it is now an error rather than a silent rank. Tier membership is read from tiers[].members, not bases[].tier: the latter labels invoiced/measured/quoted all as "evidenced" while the tier list splits them across "observed" and "quoted". tiers[] is authoritative; reported upstream. USES_PROVISIONS IS NOW CANON (0.5.0, CAP-R11) Dropped the proposed_extensions marker. Renamed relation "uses" to "may_use" per their migration note. tools/capability.py now enforces CAP-R11: relation must be depends_on or may_use, a provider must be named, and a depends_on entry MUST be declared between those capabilities in the catalog. data.backup gained catalog may_use: security.secrets from our restatement, so our entry now checks out. Also in 0.4.0: §10.3 changed so a joinable consumer record counts as promotion proof, met by our restatement; ITC-CAP is now 0.4.0 / canon 0.6.0, status draft. Record and tests updated to those versions. 196 tests pass. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
b8081f6c2d
commit
7a196b6265
6 changed files with 292 additions and 131 deletions
|
|
@ -29,8 +29,10 @@ class CanonBindingTest(unittest.TestCase):
|
|||
self.canon = canon()
|
||||
|
||||
def test_catalog_is_the_version_we_restated_against(self):
|
||||
self.assertEqual("0.2.0", self.canon["version"])
|
||||
self.assertEqual("0.3.0", self.canon["canon_version"])
|
||||
self.assertEqual("0.4.0", self.canon["version"])
|
||||
self.assertEqual("0.6.0", self.canon["canon_version"])
|
||||
self.assertEqual(self.canon["version"], RECORD["canon"]["model_version"])
|
||||
self.assertEqual(self.canon["canon_version"], RECORD["canon"]["canon_version"])
|
||||
|
||||
def test_human_effort_and_intelligence_classes_exist_with_native_units(self):
|
||||
classes = self.canon["resource_classes"]
|
||||
|
|
@ -133,6 +135,34 @@ class ProvisionTest(unittest.TestCase):
|
|||
self.assertFalse(coverage["complete"])
|
||||
self.assertIn("object_integrity_tests", coverage["missing"])
|
||||
|
||||
def test_using_another_capability_is_a_relation_not_a_p_row(self):
|
||||
"""CAP-R11. The credential-custody P row was the wrong kind."""
|
||||
backup = self.provisions["data.backup"]
|
||||
classes = {r["class"] for r in backup["consumes"]}
|
||||
self.assertNotIn("P", classes)
|
||||
relations = {u["capability"]: u["relation"] for u in backup["uses_provisions"]}
|
||||
self.assertEqual("may_use", relations["security.secrets"])
|
||||
self.assertEqual("depends_on", relations["data.object"])
|
||||
|
||||
def test_depends_on_must_be_declared_between_the_capabilities(self):
|
||||
backup = self.provisions["data.backup"]
|
||||
entry = next(u for u in backup["uses_provisions"] if u["capability"] == "security.secrets")
|
||||
entry["relation"] = "depends_on"
|
||||
with self.assertRaisesRegex(ValueError, "does not declare depends_on"):
|
||||
validate_provision(backup, self.canon)
|
||||
|
||||
def test_relation_outside_the_canon_vocabulary_is_rejected(self):
|
||||
backup = self.provisions["data.backup"]
|
||||
backup["uses_provisions"][0]["relation"] = "uses"
|
||||
with self.assertRaisesRegex(ValueError, "depends_on or may_use"):
|
||||
validate_provision(backup, self.canon)
|
||||
|
||||
def test_a_used_provision_must_name_its_provider(self):
|
||||
backup = self.provisions["data.backup"]
|
||||
backup["uses_provisions"][0]["provider"] = ""
|
||||
with self.assertRaisesRegex(ValueError, "must name a provider"):
|
||||
validate_provision(backup, self.canon)
|
||||
|
||||
def test_effort_and_tokens_are_recorded_in_native_units(self):
|
||||
rows = {r["class"]: r for r in self.provisions["data.object"]["consumes"]}
|
||||
self.assertEqual("hour", rows["H"]["quantity"]["unit"])
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue