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
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue