refactor(cdsl_engine): sink atomic runtime capability flags into schema contracts

Phase 4 of the decoupling refactor (behavior-preserving):
- profile_schema.json: every operation contract now carries
  runtime_capability {body_mutating, requires_active_body,
  replayable, requires_selector, open_profile_ok} (single source of truth)
- operation_contracts.py: validates and forwards the flags
- capabilities.py: the five data-classification frozensets are now
  derived from the schema at import time; dispatch-logic sets
  (_HOLE_ATOMICS, _PATTERN_ATOMICS, extent constants) stay in code
- test_profile_schema.py: completeness + structural invariants test

Equivalence proven by flag counts (27/13/25/6/2) matching the previous
hand-written sets and by the unchanged test-baseline failure set.
This commit is contained in:
2026-09-09 13:41:38 +08:00
parent 5ffb106f36
commit beac59fc8b
4 changed files with 101 additions and 66 deletions
@@ -31,6 +31,7 @@ def materialized_feature_contracts(profile: dict[str, Any]) -> dict[str, dict[st
params_schema = raw.get("author_params_schema")
injected_paths = raw.get("server_injected_paths")
selector_policy = raw.get("selector_policy")
runtime_capability = raw.get("runtime_capability")
if (
not isinstance(shape, dict)
or not isinstance(params_schema, dict)
@@ -38,6 +39,13 @@ def materialized_feature_contracts(profile: dict[str, Any]) -> dict[str, dict[st
or not isinstance(selector_policy, dict)
):
raise ValueError(f"operation contract is incomplete for {atomic_id}")
if not isinstance(runtime_capability, dict) or not all(
isinstance(runtime_capability.get(flag), bool)
for flag in (
"body_mutating", "requires_active_body", "replayable", "requires_selector", "open_profile_ok",
)
):
raise ValueError(f"operation runtime_capability is invalid for {atomic_id}")
properties = params_schema.get("properties")
required = params_schema.get("required")
if not isinstance(properties, dict) or not isinstance(required, list):
@@ -59,5 +67,6 @@ def materialized_feature_contracts(profile: dict[str, Any]) -> dict[str, dict[st
"requires_sketch": shape.get("sketch") == "required",
"selector_slot": selector_policy.get("slot"),
"selector_token_kind": selector_policy.get("token_kind"),
"runtime_capability": dict(runtime_capability),
}
return derived