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:
tegwick 2026-09-28 12:40:07 +02:00
parent 9383b94019
commit 36303d25a3
7 changed files with 281 additions and 20 deletions

View file

@ -348,10 +348,17 @@ def build_report(
rare_load_bearing: set[str],
attributive: set[str],
fail_on_should: bool = False,
schema_only: bool = False,
) -> dict[str, Any]:
inventory_supplied = bool(load_bearing or rare_load_bearing or attributive)
if schema_only and (inventory_supplied or fail_on_should):
raise ValueError("schema-only validation cannot include profile options")
if any(not name.strip() for name in load_bearing | rare_load_bearing | attributive):
raise ValueError("inventory event classes must not be blank")
findings = _schema_findings(contract_schema, declaration)
contract_valid = not findings
if contract_valid:
profile_assessed = contract_valid and inventory_supplied and not schema_only
if profile_assessed:
findings.extend(
evaluate_profile(
declaration,
@ -362,17 +369,37 @@ def build_report(
)
must_count = sum(item.level == "MUST" for item in findings)
should_count = sum(item.level == "SHOULD" for item in findings)
assessment_scope = "supplied-inventory" if inventory_supplied else "inventory-missing"
if schema_only:
assessment_scope = "schema-only"
return {
"profile": PROFILE_ID,
"contract_schema": contract_schema_path,
"declaration": declaration_path,
"contract_valid": contract_valid,
"conformant": must_count == 0 and (not fail_on_should or should_count == 0),
"profile_assessed": profile_assessed,
"assessment_scope": assessment_scope,
"inventory": {
"load_bearing": sorted(load_bearing),
"rare_load_bearing": sorted(rare_load_bearing),
"attributive": sorted(attributive),
},
"conformant": (
must_count == 0 and (not fail_on_should or should_count == 0)
if profile_assessed
else None
),
"summary": {"must": must_count, "should": should_count},
"findings": [asdict(item) for item in findings],
}
def _event_class(value: str) -> str:
if not value.strip():
raise argparse.ArgumentTypeError("event class must not be blank")
return value
def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Validate an imported emission-cadence declaration against the NetKingdom profile."
@ -380,16 +407,40 @@ def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
parser.add_argument("declaration", type=Path)
parser.add_argument("--contract-schema", required=True, type=Path)
parser.add_argument(
"--load-bearing", action="append", default=[], metavar="EVENT_CLASS"
"--schema-only",
action="store_true",
help="Validate only the supplied JSON Schema; do not assess security-profile conformance.",
)
parser.add_argument(
"--rare-load-bearing", action="append", default=[], metavar="EVENT_CLASS"
"--load-bearing",
action="append",
default=[],
type=_event_class,
metavar="EVENT_CLASS",
)
parser.add_argument(
"--attributive", action="append", default=[], metavar="EVENT_CLASS"
"--rare-load-bearing",
action="append",
default=[],
type=_event_class,
metavar="EVENT_CLASS",
)
parser.add_argument(
"--attributive",
action="append",
default=[],
type=_event_class,
metavar="EVENT_CLASS",
)
parser.add_argument("--fail-on-should", action="store_true")
return parser.parse_args(argv)
args = parser.parse_args(argv)
if args.schema_only and (
args.load_bearing or args.rare_load_bearing or args.attributive or args.fail_on_should
):
parser.error(
"--schema-only cannot be combined with profile inventory or --fail-on-should"
)
return args
def main(argv: list[str] | None = None) -> int:
@ -409,8 +460,15 @@ def main(argv: list[str] | None = None) -> int:
rare_load_bearing=set(args.rare_load_bearing),
attributive=set(args.attributive),
fail_on_should=args.fail_on_should,
schema_only=args.schema_only,
)
print(json.dumps(report, indent=2, sort_keys=True))
if not report["contract_valid"]:
return 1
if args.schema_only:
return 0
if not report["profile_assessed"]:
return 2
return 0 if report["conformant"] else 1