Require explicit cadence profile assessment and correct contract pins
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a0e77d-47a4-7771-8e34-7339c7fac0e4
This commit is contained in:
parent
9383b94019
commit
36303d25a3
7 changed files with 281 additions and 20 deletions
|
|
@ -2,6 +2,7 @@ from __future__ import annotations
|
|||
|
||||
import copy
|
||||
import importlib.util
|
||||
import json
|
||||
import pathlib
|
||||
import sys
|
||||
|
||||
|
|
@ -92,14 +93,86 @@ def test_valid_rare_load_bearing_requires_both_positive_controls() -> None:
|
|||
result = report(declaration(rare_entry()), rare={"audit.deny"})
|
||||
|
||||
assert result["contract_valid"] is True
|
||||
assert result["profile_assessed"] is True
|
||||
assert result["inventory"]["rare_load_bearing"] == ["audit.deny"]
|
||||
assert result["conformant"] is True
|
||||
assert result["findings"] == []
|
||||
|
||||
|
||||
def test_omitted_inventory_does_not_claim_profile_conformance() -> None:
|
||||
item = rare_entry()
|
||||
del item["heartbeat"]
|
||||
result = report(declaration(item))
|
||||
|
||||
assert result["contract_valid"] is True
|
||||
assert result["profile_assessed"] is False
|
||||
assert result["conformant"] is None
|
||||
assert result["assessment_scope"] == "inventory-missing"
|
||||
assert result["findings"] == [] # Rarity is never inferred from the entry.
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"options,valid,exit_code,scope",
|
||||
[
|
||||
([], True, 2, "inventory-missing"),
|
||||
(["--schema-only"], True, 0, "schema-only"),
|
||||
(["--schema-only"], False, 1, "schema-only"),
|
||||
([], False, 1, "inventory-missing"),
|
||||
],
|
||||
)
|
||||
def test_cli_unassessed_results(tmp_path, capsys, options, valid, exit_code, scope):
|
||||
schema = tmp_path / "schema.yaml"
|
||||
document = tmp_path / "declaration.yaml"
|
||||
schema.write_text(yaml.safe_dump(CONTRACT_SCHEMA))
|
||||
item = rare_entry()
|
||||
del item["heartbeat"]
|
||||
document.write_text(yaml.safe_dump(declaration(item) if valid else {}))
|
||||
|
||||
assert (
|
||||
profile.main([str(document), "--contract-schema", str(schema), *options])
|
||||
== exit_code
|
||||
)
|
||||
result = json.loads(capsys.readouterr().out)
|
||||
assert result["contract_valid"] is valid
|
||||
assert result["profile_assessed"] is False
|
||||
assert result["conformant"] is None
|
||||
assert result["assessment_scope"] == scope
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"options",
|
||||
[
|
||||
["--load-bearing", "audit.deny"],
|
||||
["--rare-load-bearing", "audit.deny"],
|
||||
["--attributive", "audit.allow"],
|
||||
["--fail-on-should"],
|
||||
],
|
||||
)
|
||||
def test_schema_only_refuses_profile_options(options):
|
||||
with pytest.raises(SystemExit) as exc:
|
||||
profile.parse_args(
|
||||
["source.yaml", "--contract-schema", "schema.yaml", "--schema-only", *options]
|
||||
)
|
||||
assert exc.value.code == 2
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"option", ["--load-bearing", "--rare-load-bearing", "--attributive"]
|
||||
)
|
||||
def test_blank_class_is_not_an_inventory(option):
|
||||
with pytest.raises(SystemExit) as exc:
|
||||
profile.parse_args(
|
||||
["source.yaml", "--contract-schema", "schema.yaml", option, " "]
|
||||
)
|
||||
assert exc.value.code == 2
|
||||
|
||||
|
||||
def test_contract_validation_runs_before_profile() -> None:
|
||||
result = report({"source": "example"}, rare={"audit.deny"})
|
||||
|
||||
assert result["contract_valid"] is False
|
||||
assert result["profile_assessed"] is False
|
||||
assert result["conformant"] is None
|
||||
assert codes(result) == {"contract-validation-failed"}
|
||||
assert "load-bearing-cadence-missing" not in codes(result)
|
||||
|
||||
|
|
@ -254,8 +327,6 @@ def test_duplicate_source_ids_fail_even_with_distinct_event_classes(upstream_sch
|
|||
def test_should_policy_and_cli(tmp_path, capsys):
|
||||
schema = tmp_path / "schema.json"
|
||||
document = tmp_path / "declaration.yaml"
|
||||
import json
|
||||
|
||||
schema.write_text(json.dumps(CONTRACT_SCHEMA))
|
||||
document.write_text(json.dumps(declaration()))
|
||||
args = [
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue