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
|
|
@ -122,6 +122,35 @@ def validate_provision(provision: dict, canon: dict) -> None:
|
|||
if row.get("supply") and row["supply"] not in {"internal", "external"}:
|
||||
raise ValueError(f"supply must be internal or external, got {row['supply']!r}")
|
||||
|
||||
validate_uses_provisions(provision, canon)
|
||||
|
||||
|
||||
def validate_uses_provisions(provision: dict, canon: dict) -> None:
|
||||
"""CAP-R11: relying on another provision is a relationship, not consumption.
|
||||
|
||||
A `depends_on` entry MUST correspond to a `depends_on` declared between the
|
||||
two capabilities in the catalog, so the provision graph stays checkable
|
||||
against the capability graph rather than free-form.
|
||||
"""
|
||||
capability = canon["capabilities"][provision["capability"]]
|
||||
for entry in provision.get("uses_provisions") or []:
|
||||
target = entry["capability"]
|
||||
if target not in canon["capabilities"]:
|
||||
raise ValueError(f"unknown capability {target} in uses_provisions")
|
||||
relation = entry["relation"]
|
||||
if relation not in {"depends_on", "may_use"}:
|
||||
raise ValueError(f"relation must be depends_on or may_use, got {relation!r}")
|
||||
if not entry.get("provider"):
|
||||
raise ValueError(f"uses_provisions entry for {target} must name a provider")
|
||||
declared = set(capability.get(relation) or [])
|
||||
if relation == "depends_on" and target not in declared:
|
||||
raise ValueError(
|
||||
f"{provision['capability']} does not declare depends_on {target} in the catalog"
|
||||
)
|
||||
if relation == "may_use" and target not in declared:
|
||||
# SHOULD, not MUST — surfaced rather than fatal.
|
||||
entry.setdefault("_note", f"catalog does not declare may_use {target}")
|
||||
|
||||
|
||||
def evidence_coverage(provision: dict, canon: dict) -> dict:
|
||||
"""Which of the capability's declared evidence hooks this provision satisfies."""
|
||||
|
|
@ -185,6 +214,10 @@ def review(record: dict, canon: dict) -> dict:
|
|||
"maturity": provision["maturity"],
|
||||
"evidence": evidence_coverage(provision, canon),
|
||||
"consumption": consumption_profile(provision),
|
||||
"uses_provisions": [
|
||||
{"capability": u["capability"], "relation": u["relation"], "provider": u["provider"]}
|
||||
for u in provision.get("uses_provisions") or []
|
||||
],
|
||||
}
|
||||
for provision in record.get("provisions") or []
|
||||
],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue