feat(authorization-obligations): run the checker in MAP with config and manifest counters

Task 3.1. The obligations proposer runs after variant search in standard and
deep scans, reads the declared policy from the target, and never writes it.
Its findings are appended after every other finding and never enter the sandbox
candidate set. The manifest block carries the sibling sets, the under-populated
count, the operations examined, the findings by label, the policy version, the
stage degradations, and the sibling sets themselves.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
Claude-Session: https://claude.ai/code/session_01T7XD7x5KonMdmGRkp63EQG
This commit is contained in:
Marius Ciepluch
2026-09-06 07:24:13 +02:00
co-authored by Claude Opus 5
parent 2249de8d2e
commit e13a397942
3 changed files with 245 additions and 2 deletions
+19
View File
@@ -135,6 +135,14 @@ class VariantsConfig:
max_mechanisms: int = 500
@dataclass(frozen=True)
class ObligationsConfig:
# authorization-obligations: the obligation checker in MAP (standard/deep only).
enabled: bool = True
min_siblings: int = 3
policy_path: str = ".openultrasast/obligations.toml"
@dataclass(frozen=True)
class ResolvedConfig:
models: ModelConfig = ModelConfig()
@@ -151,6 +159,7 @@ class ResolvedConfig:
complexity: ComplexityConfig = ComplexityConfig()
regress: RegressConfig = RegressConfig()
variants: VariantsConfig = VariantsConfig()
obligations: ObligationsConfig = ObligationsConfig()
runs_dir: str = ".openultrasast/runs"
@@ -176,6 +185,7 @@ def load_config(config_path: Path | None = None) -> ResolvedConfig:
complexity=_load_complexity(data.get("complexity", {})),
regress=_load_regress(data.get("regress", {})),
variants=_load_variants(data.get("variants", {})),
obligations=_load_obligations(data.get("obligations", {})),
runs_dir=os.environ.get("OPENULTRASAST_RUNS_DIR", ".openultrasast/runs"),
)
@@ -345,3 +355,12 @@ def _load_variants(value: object) -> VariantsConfig:
enabled=bool(data.get("enabled", True)),
max_mechanisms=_int_value(data.get("max_mechanisms"), 500),
)
def _load_obligations(value: object) -> ObligationsConfig:
data = _section(value)
return ObligationsConfig(
enabled=bool(data.get("enabled", True)),
min_siblings=_int_value(data.get("min_siblings"), 3),
policy_path=str(data.get("policy_path", ".openultrasast/obligations.toml")),
)