Report and enforce concept-declaration coverage (T03)
validation-coverage gains a concept_declaration block: declared, defined in prose, undeclared, ratio, silent artifacts, and the extraction limit stated in words. The ratio sits slightly above one because seed-concept lists and YAML payload concepts are declared but not extractable, and saying so in the report is better than a number that looks complete. Two checks carry different weights. concept_declaration_missing is an error: an artifact that defines concepts and declares none, with the kernel map exempt by name because it assigns concepts rather than defining them. Zero today, so a new artifact added without declarations fails. concept_defined_without_owner is a warning over concepts no artifact declares; a name another artifact owns is an import rather than a gap, which keeps the warning from firing 57 times and training reviewers to ignore it. Three warnings today and each is real: the Organization Model defines eleven concepts nobody owns, CARING four including Effective Access and Declared Access, and the Capability Model two. They are carried as T07 rather than declared in passing, because declaring without a boundary review is the mistake this workplan exists to fix. make check passes with 53 tests, clean validation and three warnings. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 3588@bnt-lap001 Assistant-Session: 24b80f66-e5a7-4e61-99fe-2d422e6d17da
This commit is contained in:
parent
772422553f
commit
a28526e540
4 changed files with 140 additions and 3 deletions
|
|
@ -16,7 +16,13 @@ from info_tech_canon.maintenance import (
|
|||
export_emission_bundle,
|
||||
source_evidence,
|
||||
)
|
||||
from info_tech_canon.service import DEFAULT_INFOSPACE_ROOT, load_context, validate_canon
|
||||
from info_tech_canon.contracts import coverage
|
||||
from info_tech_canon.service import (
|
||||
DEFAULT_INFOSPACE_ROOT,
|
||||
concept_declaration_checks,
|
||||
load_context,
|
||||
validate_canon,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
|
|
@ -152,3 +158,33 @@ def test_concept_coverage_cli_reports_one_artifact(capsys):
|
|||
payload = json.loads(capsys.readouterr().out)
|
||||
assert payload["ok"] is True
|
||||
assert [item["artifact"] for item in payload["artifacts"]] == ["model/identity"]
|
||||
|
||||
|
||||
def test_declaration_checks_warn_on_unowned_and_error_on_silence(tmp_path):
|
||||
context = load_context()
|
||||
ownership = concept_ownership(context)
|
||||
result = concept_declaration_checks(context, ownership)
|
||||
|
||||
assert not result["errors"]
|
||||
warned = {item["artifact_id"] for item in result["warnings"]}
|
||||
assert "model/organization" in warned
|
||||
assert all(item["code"] == "concept_defined_without_owner" for item in result["warnings"])
|
||||
|
||||
|
||||
def test_declaration_error_fires_when_an_artifact_declares_nothing(corpus):
|
||||
target = corpus / "models/security/InfoTechCanonSecurityModel.md"
|
||||
text = target.read_text(encoding="utf-8")
|
||||
target.write_text(text.split("---\n", 2)[2], encoding="utf-8")
|
||||
|
||||
context = load_context(corpus)
|
||||
result = concept_declaration_checks(context, concept_ownership(context))
|
||||
|
||||
assert [item["artifact_id"] for item in result["errors"]] == ["model/security"]
|
||||
|
||||
|
||||
def test_validation_coverage_reports_the_declaration_ratio():
|
||||
report = coverage(load_context())["concept_declaration"]
|
||||
|
||||
assert report["silent_artifacts"] == ["kernel/itc-kernel-map"]
|
||||
assert report["undeclared"] < report["declared"]
|
||||
assert report["limit"]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue