diff --git a/.kiro/specs/detection-core/tasks.md b/.kiro/specs/detection-core/tasks.md index f2b4efd..36703a6 100644 --- a/.kiro/specs/detection-core/tasks.md +++ b/.kiro/specs/detection-core/tasks.md @@ -18,7 +18,7 @@ - Existing target facts may be schema-migrated without expanding vocabulary or behavior. - [ ] 1. Establish migration-safe foundations -- [ ] 1.1 Freeze historical v1 artifacts and the reviewed migration inventory +- [x] 1.1 Freeze historical v1 artifacts and the reviewed migration inventory - Pin representative v1 trace and report bytes and hashes as immutable regression fixtures. - Provide an independent schema-routed read-only decoder that validates committed v1 artifacts without importing the compatibility namespace, constructing v2 determinate outcomes, or exposing a writer or converter. - Freeze the reviewed initial set of v1 readers and writers with stable entry identities, paths, symbols or capabilities, owner boundaries, and open migration status. diff --git a/src/openultrasast/core/legacy.py b/src/openultrasast/core/legacy.py new file mode 100644 index 0000000..0473788 --- /dev/null +++ b/src/openultrasast/core/legacy.py @@ -0,0 +1,328 @@ +"""Read-only validation for committed detection-core v1 artifacts. + +The v1 schemas are selected by the caller because historical artifacts do not +self-identify. This module deliberately exposes no writer or v2 conversion. +""" + +from __future__ import annotations + +import json +import math +from dataclasses import dataclass +from pathlib import Path + +from openultrasast.core.canonical import bytes_digest + +LEGACY_TRACE_SCHEMA = "trace-v1" +LEGACY_REPORT_SCHEMA = "admission-report-v1" + +_TRACE_FIELDS = frozenset( + { + "authority", + "completeness_reasons", + "digests", + "entry", + "guards", + "hops", + "judgment", + "operation_kind", + "resource", + "witnesses", + } +) +_REPORT_FIELDS = frozenset( + { + "coverage", + "criteria_pre_registered", + "decision", + "failed_gates", + "families", + "fix_recall", + "flagged_ordinary_per_100", + "indeterminate_rate", + "instrument_failures", + "manifest", + "pair_correctness", + "pairs", + "precision", + "runtime", + "verified_location_recall", + } +) +_RATE_FIELDS = frozenset({"count", "n", "rate", "wilson95"}) +_CRITERIA_FIELDS = frozenset( + { + "max_flagged_ordinary_per_100", + "max_indeterminate_rate", + "min_fix_recall", + "min_pair_correctness", + "min_precision", + "min_verified_location_recall", + } +) +_MANIFEST_FIELDS = frozenset( + { + "acquisition_record_digest", + "analyzer_revision", + "configuration_digest", + "fact_set_digest", + "population_digest", + "population_role", + } +) + + +class LegacyArtifactError(ValueError): + """Historical bytes do not satisfy the explicitly selected v1 schema.""" + + +def _reject_duplicate_fields(pairs: list[tuple[str, object]]) -> dict[str, object]: + value: dict[str, object] = {} + for key, item in pairs: + if key in value: + raise LegacyArtifactError(f"duplicate legacy artifact field: {key}") + value[key] = item + return value + + +def _decode_json(content: bytes) -> object: + try: + return json.loads(content, object_pairs_hook=_reject_duplicate_fields) + except (UnicodeDecodeError, json.JSONDecodeError) as exc: + raise LegacyArtifactError("legacy artifact must be valid UTF-8 JSON") from exc + + +@dataclass(frozen=True) +class LegacyArtifact: + """Validated historical bytes, retained without normalization or rewriting.""" + + schema_version: str + content: bytes + content_digest: str + byte_length: int + + @property + def payload(self) -> dict[str, object]: + """Return a fresh inspection copy of the validated JSON object.""" + value = _decode_json(self.content) + if not isinstance(value, dict): # Kept defensive; construction validates this. + raise LegacyArtifactError("legacy artifact must contain a JSON object") + return {str(key): item for key, item in value.items()} + + +def _object(value: object, fields: frozenset[str], name: str) -> dict[str, object]: + if not isinstance(value, dict) or not all(isinstance(key, str) for key in value): + raise LegacyArtifactError(f"{name} must be an object") + actual = set(value) + if actual != fields: + missing = sorted(fields - actual) + unknown = sorted(actual - fields) + raise LegacyArtifactError(f"{name} has missing fields {missing} and unknown fields {unknown}") + return {str(key): item for key, item in value.items()} + + +def _text(value: object, name: str) -> str: + if not isinstance(value, str) or not value: + raise LegacyArtifactError(f"{name} must be nonempty text") + return value + + +def _text_list(value: object, name: str) -> list[str]: + if not isinstance(value, list) or not all(isinstance(item, str) and item for item in value): + raise LegacyArtifactError(f"{name} must be a list of nonempty text") + return value + + +def _integer(value: object, name: str) -> int: + if isinstance(value, bool) or not isinstance(value, int) or value < 0: + raise LegacyArtifactError(f"{name} must be a non-negative integer") + return value + + +def _number(value: object, name: str) -> float: + if isinstance(value, bool) or not isinstance(value, (int, float)) or not math.isfinite(value) or value < 0: + raise LegacyArtifactError(f"{name} must be a finite non-negative number") + return float(value) + + +def _nullable_number(value: object, name: str) -> float | None: + if value is None: + return None + return _number(value, name) + + +def _objects(value: object, name: str) -> list[object]: + if not isinstance(value, list): + raise LegacyArtifactError(f"{name} must be a list") + return value + + +def _validate_trace(value: object) -> None: + trace = _object(value, _TRACE_FIELDS, "trace-v1") + for name in ("entry", "operation_kind", "resource", "authority"): + _text(trace[name], name) + if trace["judgment"] not in {"unguarded", "discharged", "indeterminate"}: + raise LegacyArtifactError("judgment is not a recognized v1 value") + _text_list(trace["completeness_reasons"], "completeness_reasons") + _validate_hops(trace["hops"]) + _validate_witnesses(trace["witnesses"]) + _validate_guards(trace["guards"]) + digests = trace["digests"] + if not isinstance(digests, dict) or not all( + isinstance(key, str) and key and isinstance(item, str) and item for key, item in digests.items() + ): + raise LegacyArtifactError("digests must map nonempty text to nonempty text") + + +def _validate_hops(value: object) -> None: + for index, item in enumerate(_objects(value, "hops")): + hop = _object(item, frozenset({"call_line", "complete", "function"}), f"hops[{index}]") + _text(hop["function"], f"hops[{index}].function") + _integer(hop["call_line"], f"hops[{index}].call_line") + if not isinstance(hop["complete"], bool): + raise LegacyArtifactError(f"hops[{index}].complete must be boolean") + + +def _validate_witnesses(value: object) -> None: + fields = frozenset({"kind", "provenance", "relation"}) + for index, item in enumerate(_objects(value, "witnesses")): + witness = _object(item, fields, f"witnesses[{index}]") + for name in fields: + _text(witness[name], f"witnesses[{index}].{name}") + + +def _validate_guards(value: object) -> None: + fields = frozenset({"kind", "effect"}) + for index, item in enumerate(_objects(value, "guards")): + guard = _object(item, fields, f"guards[{index}]") + for name in fields: + _text(guard[name], f"guards[{index}].{name}") + + +def _validate_report(value: object) -> None: + report = _object(value, _REPORT_FIELDS, "admission-report-v1") + if _number(report["coverage"], "coverage") > 1: + raise LegacyArtifactError("coverage must be between zero and one") + if report["decision"] not in {"GO", "NO-GO"}: + raise LegacyArtifactError("decision is not a recognized v1 value") + failed_gates = _text_list(report["failed_gates"], "failed_gates") + if (report["decision"] == "GO") != (not failed_gates): + raise LegacyArtifactError("decision and failed_gates are inconsistent") + _text_list(report["families"], "families") + _integer(report["instrument_failures"], "instrument_failures") + _validate_criteria(report["criteria_pre_registered"]) + _validate_manifest(report["manifest"]) + pairs = _validate_pairs(report["pairs"]) + rates: dict[str, tuple[int, int]] = {} + for name in ( + "fix_recall", + "flagged_ordinary_per_100", + "indeterminate_rate", + "pair_correctness", + "precision", + "verified_location_recall", + ): + rates[name] = _validate_rate(report[name], name) + if pairs != rates["pair_correctness"]: + raise LegacyArtifactError("pairs must agree with pair_correctness") + runtime_n = _validate_runtime(report["runtime"]) + if runtime_n != pairs[1] or runtime_n != rates["fix_recall"][1]: + raise LegacyArtifactError("runtime.n must agree with the evaluated pair denominator") + + +def _validate_criteria(value: object) -> None: + criteria = _object(value, _CRITERIA_FIELDS, "criteria_pre_registered") + for name, item in criteria.items(): + _number(item, f"criteria_pre_registered.{name}") + + +def _validate_manifest(value: object) -> None: + manifest = _object(value, _MANIFEST_FIELDS, "manifest") + for name, item in manifest.items(): + _text(item, f"manifest.{name}") + + +def _validate_pairs(value: object) -> tuple[int, int]: + pairs = _object(value, frozenset({"correct", "n"}), "pairs") + correct = _integer(pairs["correct"], "pairs.correct") + total = _integer(pairs["n"], "pairs.n") + if correct > total: + raise LegacyArtifactError("pairs.correct must not exceed pairs.n") + return correct, total + + +def _validate_runtime(value: object) -> int: + runtime = _object(value, frozenset({"max_seconds", "mean_seconds", "n"}), "runtime") + maximum = _number(runtime["max_seconds"], "runtime.max_seconds") + mean = _number(runtime["mean_seconds"], "runtime.mean_seconds") + if maximum < mean: + raise LegacyArtifactError("runtime.max_seconds must not be below runtime.mean_seconds") + return _integer(runtime["n"], "runtime.n") + + +def _validate_rate(value: object, name: str) -> tuple[int, int]: + rate = _object(value, _RATE_FIELDS, name) + count = _integer(rate["count"], f"{name}.count") + total = _integer(rate["n"], f"{name}.n") + if count > total: + raise LegacyArtifactError(f"{name}.count must not exceed {name}.n") + actual = _nullable_number(rate["rate"], f"{name}.rate") + interval = rate["wilson95"] + if not isinstance(interval, list) or len(interval) != 2: + raise LegacyArtifactError(f"{name}.wilson95 must contain two bounds") + bounds = tuple(_nullable_number(bound, f"{name}.wilson95[{index}]") for index, bound in enumerate(interval)) + if total == 0: + if actual is not None or bounds != (None, None): + raise LegacyArtifactError(f"{name} must use null rate and interval when n is zero") + return count, total + if actual is None or any(bound is None for bound in bounds): + raise LegacyArtifactError(f"{name} must use non-null rate and interval when n is positive") + lower, upper = bounds + assert lower is not None and upper is not None + scale = 100.0 if name == "flagged_ordinary_per_100" else 1.0 + expected = count / total * scale + if not math.isclose(actual, expected, rel_tol=1e-12, abs_tol=1e-12): + raise LegacyArtifactError(f"{name}.rate must be derived from count and n") + if not 0 <= lower <= upper <= scale: + raise LegacyArtifactError(f"{name}.wilson95 bounds are invalid") + return count, total + + +def decode_legacy_artifact(content: bytes, *, schema_version: str) -> LegacyArtifact: + """Validate exact historical bytes through one explicit v1 schema route.""" + if schema_version not in {LEGACY_TRACE_SCHEMA, LEGACY_REPORT_SCHEMA}: + raise LegacyArtifactError(f"unknown legacy schema: {schema_version!r}") + if type(content) is not bytes: + raise LegacyArtifactError("legacy artifact content must be exact bytes") + if not content: + raise LegacyArtifactError("legacy artifact content must be nonempty") + value = _decode_json(content) + if isinstance(value, dict) and "schema_version" in value: + raise LegacyArtifactError("legacy artifact schema is ambiguous; use the explicit route only") + validator = _validate_trace if schema_version == LEGACY_TRACE_SCHEMA else _validate_report + validator(value) + return LegacyArtifact( + schema_version=schema_version, + content=content, + content_digest=bytes_digest(content), + byte_length=len(content), + ) + + +def read_legacy_artifact(path: str | Path, *, schema_version: str) -> LegacyArtifact: + """Read nonzero historical bytes and validate them without any write path.""" + try: + content = Path(path).read_bytes() + except OSError as exc: + raise LegacyArtifactError(f"legacy artifact is not readable: {path}") from exc + return decode_legacy_artifact(content, schema_version=schema_version) + + +__all__ = [ + "LEGACY_REPORT_SCHEMA", + "LEGACY_TRACE_SCHEMA", + "LegacyArtifact", + "LegacyArtifactError", + "decode_legacy_artifact", + "read_legacy_artifact", +] diff --git a/tests/core_migration_audit.py b/tests/core_migration_audit.py new file mode 100644 index 0000000..8457f3f --- /dev/null +++ b/tests/core_migration_audit.py @@ -0,0 +1,187 @@ +"""Independent syntax-only audit of explicit detection-core v1 readers.""" + +from __future__ import annotations + +import ast +import subprocess +from dataclasses import dataclass +from pathlib import Path + +REPO = Path(__file__).resolve().parents[1] +_EXCLUDED_PREFIXES = ("benchmarks/fixtures/", "benchmarks/pairs/", "tests/fixtures/") +_LEGACY_IMPORTS: dict[str, frozenset[str] | None] = { + "openultrasast.core": frozenset( + { + "AdmissionManifest", + "AdmissionManifestError", + "BoundedSilence", + "Budget", + "Complexity", + "Coverage", + "FactPack", + "Guard", + "Hop", + "InstrumentFailure", + "Judgment", + "ProbeResult", + "ProvenClaim", + "PushRequest", + "PushVerdict", + "TraceRecord", + "Witness", + "admit_fact_pack", + "as_clean", + "check_reads", + "consume_verdict", + "validate_admission_manifest", + } + ), + "openultrasast.core._legacy_factpack": None, + "openultrasast.core.admission": frozenset( + { + "AdmissionManifest", + "AdmissionManifestError", + "REPORT_SCHEMA_KEYS", + "validate_admission_manifest", + "validate_report_schema", + } + ), + "openultrasast.core.budget": frozenset({"Budget", "Complexity"}), + "openultrasast.core.consumer": None, + "openultrasast.core.coverage": frozenset({"Coverage", "InstrumentFailure", "ResolutionOutcome", "check_reads"}), + "openultrasast.core.factpack": frozenset({"FactPackError", "admit_fact_pack", "admit_pack_file", "load_pack_file", "verify_fact_pack"}), + "openultrasast.core.probes": frozenset( + { + "FittedComponentBlocked", + "LegacyProbeResult", + "ShortcutDetected", + "assert_no_shortcut", + "require_admission_evidence", + "reversed_pair_probe", + } + ), + "openultrasast.core.provenance": frozenset({"ProvenanceMismatch", "stamp", "verify_stamp"}), + "openultrasast.core.trace": None, + "openultrasast.core.verdict": None, +} +_TOP_LEVEL_COMPATIBILITY = _LEGACY_IMPORTS["openultrasast.core"] or frozenset() + + +class LegacyReaderAuditError(ValueError): + """The explicit-reader audit could not read or parse its declared scope.""" + + +@dataclass(frozen=True) +class ReaderAuditReport: + files_read: int + bytes_read: int + capabilities: tuple[tuple[str, str], ...] + + +def tracked_python() -> tuple[Path, ...]: + completed = subprocess.run(["git", "ls-files", "*.py"], cwd=REPO, check=True, capture_output=True, text=True) + return tuple( + REPO / relative + for relative in completed.stdout.splitlines() + if relative.endswith(".py") and not relative.startswith(_EXCLUDED_PREFIXES) + ) + + +def _dotted(node: ast.AST) -> str: + if isinstance(node, ast.Name): + return node.id + if isinstance(node, ast.Attribute): + prefix = _dotted(node.value) + return f"{prefix}.{node.attr}" if prefix else "" + return "" + + +def _explicit_imports(tree: ast.Module) -> set[str]: + anchors = set() + for node in ast.walk(tree): + if isinstance(node, ast.ImportFrom) and node.module in _LEGACY_IMPORTS: + allowed = _LEGACY_IMPORTS[node.module] + anchors.update(f"import_from:{node.module}:{alias.name}" for alias in node.names if allowed is None or alias.name in allowed) + elif isinstance(node, ast.Import): + anchors.update( + f"import:{alias.name}" for alias in node.names if alias.name in _LEGACY_IMPORTS and _LEGACY_IMPORTS[alias.name] is None + ) + return anchors + + +def _direct_submodule_bindings(tree: ast.Module) -> dict[str, str]: + bindings = {} + for node in ast.walk(tree): + if isinstance(node, ast.Import): + for alias in node.names: + if alias.name in _LEGACY_IMPORTS and alias.name != "openultrasast.core": + bindings[alias.asname or alias.name] = alias.name + elif isinstance(node, ast.ImportFrom) and node.module == "openultrasast.core": + for alias in node.names: + module = f"openultrasast.core.{alias.name}" + if module in _LEGACY_IMPORTS: + bindings[alias.asname or alias.name] = module + return bindings + + +def _module_attribute_reads(tree: ast.Module) -> set[str]: + bindings = _direct_submodule_bindings(tree) + reads = set() + for node in ast.walk(tree): + if not isinstance(node, ast.Attribute): + continue + module = bindings.get(_dotted(node.value)) + if module is None: + continue + allowed = _LEGACY_IMPORTS[module] + if allowed is None or node.attr in allowed: + reads.add(f"module_attr:{module}:{node.attr}") + return reads + + +def _top_level_aliases(tree: ast.Module) -> set[str]: + aliases = set() + for node in ast.walk(tree): + if isinstance(node, ast.Import): + aliases.update(alias.asname for alias in node.names if alias.name == "openultrasast.core" and alias.asname) + elif isinstance(node, ast.ImportFrom) and node.module == "openultrasast": + aliases.update(alias.asname or alias.name for alias in node.names if alias.name == "core") + return aliases + + +def _top_level_reads(tree: ast.Module) -> set[str]: + aliases = _top_level_aliases(tree) + reads = set() + for node in ast.walk(tree): + if not isinstance(node, ast.Attribute) or node.attr not in _TOP_LEVEL_COMPATIBILITY: + continue + base = _dotted(node.value) + if base in aliases or base == "openultrasast.core": + reads.add(f"top_level:{node.attr}") + return reads + + +def audit_legacy_readers(paths: tuple[Path, ...]) -> ReaderAuditReport: + capabilities = set() + files_read = 0 + bytes_read = 0 + for path in paths: + relative = path.relative_to(REPO).as_posix() + try: + content = path.read_bytes() + except OSError as exc: + raise LegacyReaderAuditError(f"reader audit input is not readable: {relative}") from exc + if not content: + raise LegacyReaderAuditError(f"reader audit input must contain nonzero bytes: {relative}") + try: + tree = ast.parse(content, filename=relative) + except (SyntaxError, UnicodeDecodeError) as exc: + raise LegacyReaderAuditError(f"reader audit input is not parseable: {relative}") from exc + files_read += 1 + bytes_read += len(content) + anchors = _explicit_imports(tree) | _module_attribute_reads(tree) | _top_level_reads(tree) + capabilities.update((relative, anchor) for anchor in anchors) + return ReaderAuditReport(files_read, bytes_read, tuple(sorted(capabilities))) + + +__all__ = ["LegacyReaderAuditError", "ReaderAuditReport", "audit_legacy_readers", "tracked_python"] diff --git a/tests/core_migration_inventory.py b/tests/core_migration_inventory.py new file mode 100644 index 0000000..cf13ed9 --- /dev/null +++ b/tests/core_migration_inventory.py @@ -0,0 +1,368 @@ +"""Validation primitives for the frozen detection-core v1 migration worklist.""" + +from __future__ import annotations + +import ast +import hashlib +import json +from dataclasses import dataclass +from enum import Enum +from pathlib import Path + +from openultrasast.core.legacy import LegacyArtifact, decode_legacy_artifact + +REPO = Path(__file__).resolve().parents[1] +INVENTORY_SCHEMA = "openultrasast.detection-core.legacy-migration.v1" +_ENTRY_FIELDS = frozenset( + { + "artifact_family", + "capability_anchors", + "dependency_kind", + "disposition", + "entry_id", + "owner_boundary", + "path", + "symbol", + } +) +_ARTIFACT_FIELDS = frozenset({"byte_length", "path", "schema_version", "sha256"}) +_INVENTORY_FIELDS = frozenset({"entries", "historical_artifacts", "schema_version"}) +_OWNER_BOUNDARIES = frozenset( + {"authorization-adapter", "benchmark", "core", "hunt", "operational-tooling", "push", "repository-tooling", "tests"} +) + + +class LegacyInventoryError(ValueError): + """The frozen migration worklist or one of its targets is invalid.""" + + +class MigrationDisposition(Enum): + OPEN = "open" + V2_MIGRATED = "v2_migrated" + RETIRED = "retired" + + +class DependencyKind(Enum): + READER = "reader" + WRITER = "writer" + + +@dataclass(frozen=True) +class HistoricalArtifactRecord: + path: str + schema_version: str + sha256: str + byte_length: int + + +@dataclass(frozen=True) +class LegacyInventoryEntry: + entry_id: str + path: str + symbol: str + dependency_kind: DependencyKind + artifact_family: str + capability_anchors: tuple[str, ...] + owner_boundary: str + disposition: MigrationDisposition + + +@dataclass(frozen=True) +class LegacyMigrationInventory: + schema_version: str + historical_artifacts: tuple[HistoricalArtifactRecord, ...] + entries: tuple[LegacyInventoryEntry, ...] + + +def _object(value: object, fields: frozenset[str], name: str) -> dict[str, object]: + if not isinstance(value, dict) or not all(isinstance(key, str) for key in value): + raise LegacyInventoryError(f"{name} must be an object") + actual = set(value) + if actual != fields: + raise LegacyInventoryError(f"{name} fields differ: missing={sorted(fields - actual)}, unknown={sorted(actual - fields)}") + return value + + +def _text(value: object, name: str) -> str: + if not isinstance(value, str) or not value: + raise LegacyInventoryError(f"{name} must be nonempty text") + return value + + +def _sha256(value: object, name: str) -> str: + text = _text(value, name) + if len(text) != 64 or any(character not in "0123456789abcdef" for character in text): + raise LegacyInventoryError(f"{name} must be a lowercase SHA-256 digest") + return text + + +def _relative_path(value: object, name: str) -> str: + text = _text(value, name) + path = Path(text) + if path.is_absolute() or ".." in path.parts or path.as_posix() != text: + raise LegacyInventoryError(f"{name} must be a normalized repository-relative path") + return text + + +def _parse_artifact(value: object, index: int) -> HistoricalArtifactRecord: + item = _object(value, _ARTIFACT_FIELDS, f"historical_artifacts[{index}]") + length = item["byte_length"] + if isinstance(length, bool) or not isinstance(length, int) or length <= 0: + raise LegacyInventoryError(f"historical_artifacts[{index}].byte_length must be positive") + return HistoricalArtifactRecord( + path=_relative_path(item["path"], f"historical_artifacts[{index}].path"), + schema_version=_text(item["schema_version"], f"historical_artifacts[{index}].schema_version"), + sha256=_sha256(item["sha256"], f"historical_artifacts[{index}].sha256"), + byte_length=length, + ) + + +def _enum(enum_type: type[Enum], value: object, name: str) -> Enum: + text = _text(value, name) + try: + return enum_type(text) + except ValueError as exc: + raise LegacyInventoryError(f"{name} has unknown value {text!r}") from exc + + +def _parse_entry(value: object, index: int) -> LegacyInventoryEntry: + item = _object(value, _ENTRY_FIELDS, f"entries[{index}]") + owner = _text(item["owner_boundary"], f"entries[{index}].owner_boundary") + if owner not in _OWNER_BOUNDARIES: + raise LegacyInventoryError(f"entries[{index}].owner_boundary is unknown") + raw_anchors = item["capability_anchors"] + if not isinstance(raw_anchors, list) or not raw_anchors: + raise LegacyInventoryError(f"entries[{index}].capability_anchors must be a nonempty list") + anchors = tuple(_text(anchor, f"entries[{index}].capability_anchors") for anchor in raw_anchors) + if len(set(anchors)) != len(anchors): + raise LegacyInventoryError(f"entries[{index}].capability_anchors contains duplicates") + entry = LegacyInventoryEntry( + entry_id=_sha256(item["entry_id"], f"entries[{index}].entry_id"), + path=_relative_path(item["path"], f"entries[{index}].path"), + symbol=_text(item["symbol"], f"entries[{index}].symbol"), + dependency_kind=_enum(DependencyKind, item["dependency_kind"], f"entries[{index}].dependency_kind"), # type: ignore[arg-type] + artifact_family=_text(item["artifact_family"], f"entries[{index}].artifact_family"), + capability_anchors=anchors, + owner_boundary=owner, + disposition=_enum(MigrationDisposition, item["disposition"], f"entries[{index}].disposition"), # type: ignore[arg-type] + ) + if entry.entry_id != entry_identity(entry): + raise LegacyInventoryError(f"entries[{index}].entry_id does not match immutable identity fields") + return entry + + +def entry_identity(entry: LegacyInventoryEntry) -> str: + """Derive the stable identity without the mutable migration disposition.""" + value = { + "artifact_family": entry.artifact_family, + "capability_anchors": entry.capability_anchors, + "dependency_kind": entry.dependency_kind.value, + "owner_boundary": entry.owner_boundary, + "path": entry.path, + "symbol": entry.symbol, + } + canonical = json.dumps(value, sort_keys=True, separators=(",", ":")).encode() + return hashlib.sha256(canonical).hexdigest() + + +def _decode_inventory(content: bytes) -> LegacyMigrationInventory: + try: + value = json.loads(content) + except (UnicodeDecodeError, json.JSONDecodeError) as exc: + raise LegacyInventoryError("migration inventory must be valid UTF-8 JSON") from exc + root = _object(value, _INVENTORY_FIELDS, "migration inventory") + if root["schema_version"] != INVENTORY_SCHEMA: + raise LegacyInventoryError("migration inventory schema_version is unknown") + raw_artifacts = root["historical_artifacts"] + raw_entries = root["entries"] + if not isinstance(raw_artifacts, list) or not isinstance(raw_entries, list) or not raw_entries: + raise LegacyInventoryError("migration inventory requires artifact and nonempty entry lists") + artifacts = tuple(_parse_artifact(item, index) for index, item in enumerate(raw_artifacts)) + entries = tuple(_parse_entry(item, index) for index, item in enumerate(raw_entries)) + if len({entry.entry_id for entry in entries}) != len(entries): + raise LegacyInventoryError("migration inventory contains duplicate identities") + return LegacyMigrationInventory(INVENTORY_SCHEMA, artifacts, entries) + + +def load_migration_inventory(path: str | Path) -> LegacyMigrationInventory: + """Read the nonzero reviewed worklist without discovering new entries.""" + try: + content = Path(path).read_bytes() + except OSError as exc: + raise LegacyInventoryError(f"migration inventory is not readable: {path}") from exc + if not content: + raise LegacyInventoryError("migration inventory must contain nonzero bytes") + return _decode_inventory(content) + + +def _defined_symbols(tree: ast.Module) -> set[str]: + symbols = {""} + + def visit(nodes: list[ast.stmt], parents: tuple[str, ...] = ()) -> None: + for node in nodes: + if isinstance(node, (ast.ClassDef, ast.FunctionDef, ast.AsyncFunctionDef)): + current = (*parents, node.name) + symbols.add(".".join(current)) + visit(node.body, current) + + visit(tree.body) + return symbols + + +def _call_leaf(node: ast.Call) -> str: + if isinstance(node.func, ast.Name): + return node.func.id + if isinstance(node.func, ast.Attribute): + return node.func.attr + return "" + + +def _dotted(node: ast.AST) -> str: + if isinstance(node, ast.Name): + return node.id + if isinstance(node, ast.Attribute): + prefix = _dotted(node.value) + return f"{prefix}.{node.attr}" if prefix else "" + return "" + + +def _top_level_reads(tree: ast.Module) -> set[str]: + aliases = set() + for node in ast.walk(tree): + if isinstance(node, ast.Import): + aliases.update(alias.asname for alias in node.names if alias.name == "openultrasast.core" and alias.asname) + elif isinstance(node, ast.ImportFrom) and node.module == "openultrasast": + aliases.update(alias.asname or alias.name for alias in node.names if alias.name == "core") + return { + node.attr for node in ast.walk(tree) if isinstance(node, ast.Attribute) and _dotted(node.value) in aliases | {"openultrasast.core"} + } + + +def _direct_core_module_bindings(tree: ast.Module) -> dict[str, str]: + bindings = {} + for node in ast.walk(tree): + if isinstance(node, ast.Import): + for alias in node.names: + if alias.name.startswith("openultrasast.core."): + bindings[alias.asname or alias.name] = alias.name + elif isinstance(node, ast.ImportFrom) and node.module == "openultrasast.core": + for alias in node.names: + bindings[alias.asname or alias.name] = f"openultrasast.core.{alias.name}" + return bindings + + +def _direct_module_attributes(tree: ast.Module) -> set[str]: + bindings = _direct_core_module_bindings(tree) + return { + f"{module}:{node.attr}" + for node in ast.walk(tree) + if isinstance(node, ast.Attribute) and (module := bindings.get(_dotted(node.value))) is not None + } + + +def _capability_index(tree: ast.Module) -> dict[str, set[str]]: + imported = { + f"{node.module}:{alias.name}" + for node in ast.walk(tree) + if isinstance(node, ast.ImportFrom) and node.module is not None + for alias in node.names + } + modules = {alias.name for node in ast.walk(tree) if isinstance(node, ast.Import) for alias in node.names} + constants = {node.value for node in ast.walk(tree) if isinstance(node, ast.Constant) and isinstance(node.value, str)} + names = {node.id for node in ast.walk(tree) if isinstance(node, ast.Name)} + names.update(node.attr for node in ast.walk(tree) if isinstance(node, ast.Attribute)) + return { + "call": {_call_leaf(node) for node in ast.walk(tree) if isinstance(node, ast.Call)}, + "constant": constants, + "definition": _defined_symbols(tree), + "import": modules, + "import_from": imported, + "module_attr": _direct_module_attributes(tree), + "name": names, + "top_level": _top_level_reads(tree), + } + + +def _missing_anchors(entry: LegacyInventoryEntry, tree: ast.Module) -> tuple[str, ...]: + index = _capability_index(tree) + missing = [] + for anchor in entry.capability_anchors: + kind, separator, value = anchor.partition(":") + if not separator or kind not in index or value not in index[kind]: + missing.append(anchor) + return tuple(missing) + + +def validate_inventory_sources(inventory: LegacyMigrationInventory, *, root: Path) -> None: + """Prove every registered migration target is readable, nonzero, and present.""" + for entry in inventory.entries: + path = root / entry.path + try: + content = path.read_bytes() + except OSError as exc: + raise LegacyInventoryError(f"inventory source is not readable: {entry.path}") from exc + if not content: + raise LegacyInventoryError(f"inventory source must contain nonzero bytes: {entry.path}") + try: + tree = ast.parse(content, filename=entry.path) + except (SyntaxError, UnicodeDecodeError) as exc: + raise LegacyInventoryError(f"inventory source is not parseable: {entry.path}") from exc + if entry.symbol not in _defined_symbols(tree): + raise LegacyInventoryError(f"inventory target is absent: {entry.path}:{entry.symbol}") + missing = _missing_anchors(entry, tree) + if missing: + raise LegacyInventoryError(f"inventory capability is absent: {entry.path}:{missing}") + + +def validate_historical_artifacts(inventory: LegacyMigrationInventory, *, root: Path) -> tuple[LegacyArtifact, ...]: + """Re-open and validate every byte-frozen v1 artifact from its exact manifest.""" + artifacts = [] + for record in inventory.historical_artifacts: + try: + content = (root / record.path).read_bytes() + except OSError as exc: + raise LegacyInventoryError(f"historical artifact is not readable: {record.path}") from exc + if len(content) != record.byte_length: + raise LegacyInventoryError(f"historical artifact length changed: {record.path}") + if hashlib.sha256(content).hexdigest() != record.sha256: + raise LegacyInventoryError(f"historical artifact digest changed: {record.path}") + artifact = decode_legacy_artifact(content, schema_version=record.schema_version) + artifacts.append(artifact) + return tuple(artifacts) + + +def validate_inventory_transition(frozen: LegacyMigrationInventory, candidate: LegacyMigrationInventory) -> None: + """Allow only disposition closure while retaining the frozen worklist identity.""" + frozen_ids = tuple(entry.entry_id for entry in frozen.entries) + candidate_ids = tuple(entry.entry_id for entry in candidate.entries) + if frozen.schema_version != candidate.schema_version or frozen_ids != candidate_ids: + raise LegacyInventoryError("migration inventory identities changed") + if frozen.historical_artifacts != candidate.historical_artifacts: + raise LegacyInventoryError("historical artifact identities changed") + for before, after in zip(frozen.entries, candidate.entries, strict=True): + if not isinstance(before.disposition, MigrationDisposition) or not isinstance(after.disposition, MigrationDisposition): + raise LegacyInventoryError("migration inventory disposition is outside the closed domain") + if not isinstance(before.dependency_kind, DependencyKind) or not isinstance(after.dependency_kind, DependencyKind): + raise LegacyInventoryError("migration inventory dependency kind is outside the closed domain") + if entry_identity(after) != after.entry_id or entry_identity(before) != entry_identity(after): + raise LegacyInventoryError("migration inventory identities changed") + if before.disposition is MigrationDisposition.OPEN: + continue + if after.disposition is not before.disposition: + raise LegacyInventoryError(f"terminal migration entry reopened or changed: {before.entry_id}") + + +__all__ = [ + "REPO", + "DependencyKind", + "HistoricalArtifactRecord", + "LegacyInventoryEntry", + "LegacyInventoryError", + "LegacyMigrationInventory", + "MigrationDisposition", + "entry_identity", + "load_migration_inventory", + "validate_historical_artifacts", + "validate_inventory_sources", + "validate_inventory_transition", +] diff --git a/tests/fixtures/detection_core/v1/migration_inventory.json b/tests/fixtures/detection_core/v1/migration_inventory.json new file mode 100644 index 0000000..f773dc1 --- /dev/null +++ b/tests/fixtures/detection_core/v1/migration_inventory.json @@ -0,0 +1,2675 @@ +{ + "entries": [ + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.trace:Guard" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "86a1113a0052c928c53719ff8ee4b110aa4bdd1a8d20ff9ab7492227e346e872", + "owner_boundary": "authorization-adapter", + "path": "src/openultrasast/semantic/obligations/core_adapter.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.trace:Hop" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "91f404b327f8ed526ebbd1370e6f8b065af6238e3815ece46ac1de3c35845113", + "owner_boundary": "authorization-adapter", + "path": "src/openultrasast/semantic/obligations/core_adapter.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.trace:TraceRecord" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "85631fe892d3ae9307ea2f93de6c0e280d2d8e0054fefffaa9b6edca330247a2", + "owner_boundary": "authorization-adapter", + "path": "src/openultrasast/semantic/obligations/core_adapter.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.trace:Witness" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "1c8eeb5e2b6949fb391f16030e1f9aafd676fc854761a7cd1fbf574341c90ef8", + "owner_boundary": "authorization-adapter", + "path": "src/openultrasast/semantic/obligations/core_adapter.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.verdict:Judgment" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "f8a5c42661f6a79b0abbe668e8993fd0ec26d1c9dad5df4e141472e6de62f586", + "owner_boundary": "authorization-adapter", + "path": "src/openultrasast/semantic/obligations/core_adapter.py", + "symbol": "" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:to_legacy_trace_record", + "name:TraceRecord" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "eb963401f43fca11e38c50e5e064f58b33233b9564a3a85e5b629a6fb2820d7d", + "owner_boundary": "authorization-adapter", + "path": "src/openultrasast/semantic/obligations/core_adapter.py", + "symbol": "to_legacy_trace_record" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:main", + "constant:done", + "call:dumps", + "call:write_text" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "40465a45eb2ef682fecad973566a0bd94956bfb804d1fc6ea1d43075533232b1", + "owner_boundary": "benchmark", + "path": "benchmarks/learn/engine_task_entry.py", + "symbol": "main" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "constant:family", + "constant:id", + "constant:instrument", + "constant:instrument_failures", + "constant:precision", + "constant:push", + "call:dumps", + "call:write_text" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "f0fd6f3806e7f50b826c6b3fad99d50c4ac02aeedb5cc3afca6c140f3bebbcf7", + "owner_boundary": "benchmark", + "path": "benchmarks/measurements/2026-10-14-access-control-hunt/analyse.py", + "symbol": "" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:main", + "call:dumps", + "call:write_text" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "fd21a8b7f0759a69e9f51ad3d2bae51e435ebb88cabea3bc44b8fec534fae32f", + "owner_boundary": "benchmark", + "path": "benchmarks/measurements/2026-10-14-access-control-hunt/analyse.py", + "symbol": "main" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:main", + "constant:id", + "constant:status", + "call:canonical" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "61d6e4cf01bb735ec13ea6dcd9aeb3e804abaccd26e0c7ad18819f2b28a7db0c", + "owner_boundary": "benchmark", + "path": "benchmarks/unseen/calibrate.py", + "symbol": "main" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:run_replays", + "constant:change", + "constant:input_digest", + "constant:item_id" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "c01d686518e8c0d17fa60092007604923b133200328a975bbf39e4727d75d900", + "owner_boundary": "benchmark", + "path": "benchmarks/unseen/replay.py", + "symbol": "run_replays" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:main", + "call:dumps", + "call:write_text" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "039988ff20d8f58a169cc7cd183e25a88b2bb2638fa969becb3553d8d7bc927b", + "owner_boundary": "benchmark", + "path": "benchmarks/unseen/score.py", + "symbol": "main" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:_resume_or_prove", + "constant:id", + "constant:input_digest", + "call:_write_json" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "fe616a80de18d275283ad26ccd9027c4fbf151c017d02c14205e9cfc374a8b53", + "owner_boundary": "benchmark", + "path": "benchmarks/valid/admission_run.py", + "symbol": "_resume_or_prove" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:assemble_admission_report", + "constant:id", + "constant:status", + "name:admission_report" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "41eade0e409ea4726173e851fcad5c9c81076bd7e094fc4c2ad830ac40f958b4", + "owner_boundary": "benchmark", + "path": "benchmarks/valid/admission_run.py", + "symbol": "assemble_admission_report" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.coverage:InstrumentFailure" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "ae8dd5862ff8cb6fb4cdfb83f99eb0ac881fed4dd6d0e01d19f7e4bad25f1a36", + "owner_boundary": "benchmark", + "path": "benchmarks/valid/arm_regression.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.coverage:check_reads" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "f3ba25f48c0da317242323061f27a45213a459b93a12aeeb16389bd0f3e5525f", + "owner_boundary": "benchmark", + "path": "benchmarks/valid/arm_regression.py", + "symbol": "" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:run_arm", + "constant:id", + "constant:input_digest", + "call:_write_json" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "b2bee4333d7374d21d2f4d0a8cdf49bb7c2f398daba5f63d7c3c2f7349f9be72", + "owner_boundary": "benchmark", + "path": "benchmarks/valid/arm_regression.py", + "symbol": "run_arm" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:run_development", + "constant:id", + "call:dumps", + "call:write_text", + "name:DevelopmentRecord" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "2acb6086c4eba2ee4a6bd6f6bacc86219207dd71548586c7966bb38153de9150", + "owner_boundary": "benchmark", + "path": "benchmarks/valid/development_runner.py", + "symbol": "run_development" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:combine", + "constant:missing", + "constant:push", + "constant:status", + "call:_write_json" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "c4fe7770e44fb6c37a97cc2b5c686927d116522cdd62229fe7203aa58405477b", + "owner_boundary": "benchmark", + "path": "benchmarks/valid/hunter_arm.py", + "symbol": "combine" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:run", + "constant:change", + "constant:done", + "constant:id", + "constant:input_digest", + "constant:item_id", + "constant:status", + "call:_write_json", + "call:canonical" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "880bbb68575bcb453127df5930a3d73d5dc67b478096bc504fafa878d91e534c", + "owner_boundary": "benchmark", + "path": "benchmarks/valid/hunter_arm.py", + "symbol": "run" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:_judge_input", + "constant:missing", + "constant:operation", + "constant:trace", + "call:dumps" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "6a96286909032b9997570a1f42afd97ffb92258a7d6ad0ebd077f4cdcb65adef", + "owner_boundary": "benchmark", + "path": "benchmarks/valid/judge_pass.py", + "symbol": "_judge_input" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:run", + "constant:id", + "constant:status", + "call:dumps", + "call:write", + "call:write_text" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "dea8fd3d112e1cbb4abb54b5d0e77e83c0a6e1e75e5ba2171dbd6f7ba436b75b", + "owner_boundary": "benchmark", + "path": "benchmarks/valid/judge_pass.py", + "symbol": "run" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:summarize", + "constant:status", + "call:dumps", + "call:write_text" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "8bf0cd9c6a28264ad9ff1492f203d384b33432ddf0d9027381497cc8352de48c", + "owner_boundary": "benchmark", + "path": "benchmarks/valid/judge_pass.py", + "symbol": "summarize" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:main", + "call:dumps", + "call:write_text" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "c9906d437a27969e465c4d3139b1e865de0ac82761d0a980cf41efce20a0c178", + "owner_boundary": "benchmark", + "path": "benchmarks/valid/metrics.py", + "symbol": "main" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.admission:AdmissionManifest" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "ce683bd3299f95f9972af9e760939fc0c465a4ce0f682a0eb6e1de3e29538522", + "owner_boundary": "benchmark", + "path": "benchmarks/valid/prover_admission.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.admission:AdmissionManifestError" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "f206dbf8024c582e401dc14fe1dd336f0d7abfac016f6ab0c3e3980236eb6b2c", + "owner_boundary": "benchmark", + "path": "benchmarks/valid/prover_admission.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.admission:REPORT_SCHEMA_KEYS" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "b7de07df33d29a2cba9543b53505f9789d7b51b4890797964b571c20f69fa26d", + "owner_boundary": "benchmark", + "path": "benchmarks/valid/prover_admission.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.admission:validate_admission_manifest" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "cb86f9a346e08246f627daa0ad1ba71b4e203d467dd08c983772b73d0926a429", + "owner_boundary": "benchmark", + "path": "benchmarks/valid/prover_admission.py", + "symbol": "" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:run", + "constant:change", + "constant:done", + "constant:id", + "constant:input_digest", + "constant:item_id", + "constant:status", + "call:_write_json", + "call:canonical" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "bfeaa25d41ff876c1211b69f0bc497e246cabb4bcdd0569f27ae2ae15e84d3f5", + "owner_boundary": "benchmark", + "path": "benchmarks/valid/prover_arm.py", + "symbol": "run" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:summarize", + "constant:coverage", + "constant:id", + "constant:instrument", + "constant:status", + "call:_write_json" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "c3e95086ce661de7f589d787c324b4dd08977481fb427452837e8482d24210bf", + "owner_boundary": "benchmark", + "path": "benchmarks/valid/prover_arm.py", + "symbol": "summarize" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:run", + "constant:change", + "constant:done", + "constant:id", + "constant:input_digest", + "constant:item_id", + "constant:status", + "call:_write_json", + "call:canonical" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "8db722b97cb4411fd2a12391f23d5b79b46832fcd7d62d08905aa667871c6c6a", + "owner_boundary": "benchmark", + "path": "benchmarks/valid/semgrep_arm.py", + "symbol": "run" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core._legacy_factpack:LegacyFactPack" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "887c9abe9a6d827c39655c6835fb0c2471be035914e2bbff888a4cd54635b8e0", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.admission:AdmissionManifest" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "e0e6b7628e807268977f50b44957d7077e7b96b1694d830000428f9e04d4dba6", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.admission:AdmissionManifestError" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "72504f565d0aed596df0aec44a85a52f817cc6c8e9d8b24c1a571fb913b7d32f", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.admission:REPORT_SCHEMA_KEYS" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "d9388f59242df66bd22089fabf63e9c10a47074ba309428af73989bb63e8f2b3", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.admission:validate_admission_manifest" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "c286592508bf696ef3a3cf0fb9a04a20a7cefc83595903ec55e8a9eb64d6d0d7", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.admission:validate_report_schema" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "28f1843913be0fb2d25047f07ee6ccad67dcedcdbc13f3be739de6b61506242a", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.budget:Budget" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "978b22af2773bfd5fb0a0ef8f3c6954e7ab4e80415c8e8d1493f1c1316919359", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.budget:Complexity" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "45d0fda44ab94264d9f9d483441104572d4e9cb6fa2fc4ac6648b59191053b57", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.consumer:PushRequest" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "48c7c5f8d20c5ce91d5b67662c0bbff9a73b36dc74dbd982a97622428f732510", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.consumer:PushVerdict" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "7dcc39a3e0a9b228323e9e7dd951aaa834d33da52324ea9b54b87862df13c782", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.consumer:consume_verdict" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "60206eae898dc5a886421040733f505fb2b0018a16ac33be1a5bf4b1ec63f1bf", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.coverage:Coverage" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "37109a1ec553a8ec4932ed4bc0b5f607eaec49d063aa92019bea4d0e6c9cd5f6", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.coverage:InstrumentFailure" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "2c82b2ea7ac674100c40524440c01b330024d6470e066f7d0b7a1141cd469fdb", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.coverage:ResolutionOutcome" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "ec9e6071b66da9950df479222966229e5fab6a745654a7c72cab409bc19b9d7d", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.coverage:check_reads" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "1ab736e2ba9cf9f48459dd62a6b22360777285391af1b4ade671dfdf6e5131d0", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.factpack:FactPackError" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "aef399565171f4f7e3959a31ccca7b7cfa1920c280fa01c0824db1c1304a7f79", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.factpack:admit_fact_pack" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "bdac5e64e2cc371c1900cfe8ff33f9f4850e9eada8ed4081447d2853b2ba87da", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.factpack:verify_fact_pack" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "4c298d5a77c421030968e6f01520b6e1a7f508168a60323894aad90771622a6f", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.probes:FittedComponentBlocked" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "6d29462362d8f48ec83f231d73cab7a28b8fabf24a4804115085b0c5459a88a2", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.probes:LegacyProbeResult" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "6625181ec5682cee60e7e2e8a893fba8e6d36d0182a168729cfc8938020bf4a7", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.probes:ShortcutDetected" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "0d4d0d81c8fe5208557ee28ed51b5cdd9b4adb2ecf2a8ea12fa08d1a950283d9", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.probes:assert_no_shortcut" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "a2106653f09d94c14df246b6b395515ce9e4dc4a6bc02af40171b971ff0b6420", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.probes:require_admission_evidence" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "042cbbbf7b724c8f994b36f483e184ecaf3f78ddc9987dab748bcdaf5f700312", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.probes:reversed_pair_probe" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "b5e912ad36e56bec3cebb76a899c9f0b7982178ce698745c029af6e407ba3737", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.provenance:ProvenanceMismatch" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "0d5669f0f82f3263a32bf3e8e347664126a5c2b72b70547521c6d066216ac1d3", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.provenance:stamp" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "44c243eef2fce80567e6f9256cec2e2b79dbda92c7f94ef51d30b95e109e0cd4", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.provenance:verify_stamp" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "57f5d7e641cbf32f3367f58c6fc73cb62034f6ca50e054158565c51b24a0722e", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.trace:Guard" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "638e07ce04752e53a7434016121432ec164c37c9943846e8e0779a7431d08212", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.trace:Hop" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "765cf64f7365d72bda21ef05ad428a1789f121c94616d65fb5b4f76c22c621c2", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.trace:TraceRecord" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "7d41be20de3aaf488561f679af8e61a1ffb555df853ba2b1471ad9c9b48ba46b", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.trace:Witness" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "7b7061e378b95b5b4226c9e07dc89209b2d53a7eb53ae712d593615776049eb7", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.verdict:BoundedSilence" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "03fef27c448f9cc21b3730510d3541b7026a71278e780e0eee6d465688b505f6", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.verdict:Judgment" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "5fd498e0cde62f31d61d94ba241ac19ae09035a499e25a2cd085d565517dad72", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.verdict:ProvenClaim" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "11a794312a50f82e36447aaca87713bd8767274056a671c531cfe27dcc8834dc", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.verdict:as_clean" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "db3c78ea4b76f06b44199a1bb8c3ce27530fd4661633fb289c2294661d553afc", + "owner_boundary": "core", + "path": "src/openultrasast/core/__init__.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "definition:LegacyFactPack" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "4bd20ab1f41b5bee116cfc4b750053153e43c2e6a69d937d37edcf9b9d2c839b", + "owner_boundary": "core", + "path": "src/openultrasast/core/_legacy_factpack.py", + "symbol": "LegacyFactPack" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "definition:admit_fact_pack", + "name:FactPackError", + "name:LegacyFactPack" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "c6ed5d745593aa2a7f067999ce36c147870bc603b0d69a5e9a8525dba01981a3", + "owner_boundary": "core", + "path": "src/openultrasast/core/_legacy_factpack.py", + "symbol": "admit_fact_pack" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "definition:admit_pack_file", + "name:FactPackError", + "name:LegacyFactPack" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "5ccaabc6c41d9dd9b43c51a72e25f62861a32b31da613eeb294f9bf73c5910b3", + "owner_boundary": "core", + "path": "src/openultrasast/core/_legacy_factpack.py", + "symbol": "admit_pack_file" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "definition:load_pack_file", + "constant:facts", + "constant:family", + "name:FactPackError", + "name:LegacyFactPack", + "name:admit_fact_pack" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "c3283d2128b5a9ad17e3986b6901e14436c93b7e7c00f09d3e9818b21259311d", + "owner_boundary": "core", + "path": "src/openultrasast/core/_legacy_factpack.py", + "symbol": "load_pack_file" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.trace:TraceRecord" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "54b51010027a01bbef01c27d0f9b55b45f0d72ed28c16c32e0fdb54e0dced22d", + "owner_boundary": "core", + "path": "src/openultrasast/core/consumer.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.verdict:BoundedSilence" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "430da53a431e51206c676a01fd194d8da88ef82d486adcaf9639799099183cae", + "owner_boundary": "core", + "path": "src/openultrasast/core/consumer.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.verdict:ProvenClaim" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "b0604196a9601049d109926643fa4896f146c591a475711fd97b0fa72b74d559", + "owner_boundary": "core", + "path": "src/openultrasast/core/consumer.py", + "symbol": "" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:consume_verdict", + "name:TraceRecord" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "c22607252467344d5c4aa26dafaf02052c00d36df41f7e700f72383c6b2182a6", + "owner_boundary": "core", + "path": "src/openultrasast/core/consumer.py", + "symbol": "consume_verdict" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core._legacy_factpack:FactPackError" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "9eb4cba855044fe025daa7a523458c4fba0b12758ca604c894849f824f55ccb4", + "owner_boundary": "core", + "path": "src/openultrasast/core/factpack.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core._legacy_factpack:admit_fact_pack" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "1b90ea5474dff89121dc1317a86892bb0d68f2c64117923c5979cf4bb0cd8b76", + "owner_boundary": "core", + "path": "src/openultrasast/core/factpack.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core._legacy_factpack:admit_pack_file" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "005f1fee3a1a659a65a45d8134bc71f061e314bdc28ba95516e870997c2648cd", + "owner_boundary": "core", + "path": "src/openultrasast/core/factpack.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core._legacy_factpack:load_pack_file" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "4c846ba1d97e5a5b4bbf8f1e99e10c40da10906ca93d68596cb987738438582a", + "owner_boundary": "core", + "path": "src/openultrasast/core/factpack.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core._legacy_factpack:verify_fact_pack" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "23e6ccf25c185ca231d73ab02570b14a9cddae27f7506e95d517e241bb693ae4", + "owner_boundary": "core", + "path": "src/openultrasast/core/factpack.py", + "symbol": "" + }, + { + "artifact_family": "v1-probe", + "capability_anchors": [ + "definition:reversed_pair_probe", + "name:LegacyProbeResult" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "c8aaf430009a592a8ed4361f38023d5faa12a6da6186fc0dcea9c7c522da85ad", + "owner_boundary": "core", + "path": "src/openultrasast/core/probes.py", + "symbol": "reversed_pair_probe" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.verdict:Judgment" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "2b27d3181fcacfd832ee3c3dea4f3b52a5d73d76dc478620d1e726ce9454b394", + "owner_boundary": "core", + "path": "src/openultrasast/core/trace.py", + "symbol": "" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:TraceRecord.canonical", + "call:record" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "36e5d60b410bf7f9c676a5da9e95718cab95dadfbf61cda0d0e2f24b56cf3c92", + "owner_boundary": "core", + "path": "src/openultrasast/core/trace.py", + "symbol": "TraceRecord.canonical" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.coverage:Coverage" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "9f2097b8a673c3079a8a61cc28e9099c671e48e6c29a3e95a9e3aac3d53ccb00", + "owner_boundary": "hunt", + "path": "src/openultrasast/hunt/prover.py", + "symbol": "" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:prove_change", + "call:record", + "name:ProverResult", + "name:build_trace" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "a5be0d8793d0048de9444366db2fd389640e99c04a9e8ef450453644c004ffa0", + "owner_boundary": "hunt", + "path": "src/openultrasast/hunt/prover.py", + "symbol": "prove_change" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:pilot_gain", + "constant:id", + "constant:push", + "call:dumps", + "call:write_text" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "0d2cdb31783316d18cb28e987029ac7ad1e86e1e54a568df0cfbd8e138af34ac", + "owner_boundary": "hunt", + "path": "src/openultrasast/hunt/report.py", + "symbol": "pilot_gain" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:run", + "constant:change", + "constant:done", + "constant:id", + "constant:input_digest", + "constant:item_id", + "call:_write_json", + "call:write", + "name:RunArtifact" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "5852ea0d3160cc0969ab05c1c2b11047bd5915e6164fe43d13744c053716d768", + "owner_boundary": "hunt", + "path": "src/openultrasast/hunt/runner.py", + "symbol": "run" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:main", + "call:dumps" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "f002a8d514f64f221e15484b4bfb89775c154e90720030530fcf3e1d9a1e23e4", + "owner_boundary": "operational-tooling", + "path": "ops/smoke_admission.py", + "symbol": "main" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:main", + "constant:facts", + "call:dumps" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "896a61db1ce207ddc6a5a99432de6ae6f1a2889f450c384a25b0478ee61123c4", + "owner_boundary": "operational-tooling", + "path": "ops/smoke_report.py", + "symbol": "main" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:_analyze", + "constant:facts", + "constant:status" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "2e59a0d8bf2764879f78c5f85841ef496c53f2a89bd1eba7248cbf9020828c58", + "owner_boundary": "push", + "path": "src/openultrasast/push/runner.py", + "symbol": "_analyze" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:push", + "constant:facts", + "constant:witnesses" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "577f8955e147afee6590d0e5735df7a963d29ca90ed508a46323d1a0a71f62e0", + "owner_boundary": "push", + "path": "src/openultrasast/push/runner.py", + "symbol": "push" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_budget_gate_returns_no_go", + "name:admission_report" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "a8685de9229906307386c537ff096b385bff727e270744ccc3dd02978a7d5b2a", + "owner_boundary": "tests", + "path": "tests/test_admission_scoring.py", + "symbol": "test_budget_gate_returns_no_go" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_development_population_is_refused", + "name:admission_report" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "6192b0591a4086c0c818f1f9090744eae1d6dcd57d388e7263d8e1fee7f31700", + "owner_boundary": "tests", + "path": "tests/test_admission_scoring.py", + "symbol": "test_development_population_is_refused" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_fixed_side_regression_counts_pair_incorrect", + "constant:fix_recall", + "constant:pair_correctness", + "name:admission_report" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "62958d0f3ce864676a71b63ac8ad460acac24b7e4a74c423307847ba723c6b55", + "owner_boundary": "tests", + "path": "tests/test_admission_scoring.py", + "symbol": "test_fixed_side_regression_counts_pair_incorrect" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_flagged_ordinary_per_100_and_precision", + "constant:precision", + "name:admission_report" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "dff4c6a9d8351492fc104cff2b77f6655a368c306436bc626b40a9ca00efea7b", + "owner_boundary": "tests", + "path": "tests/test_admission_scoring.py", + "symbol": "test_flagged_ordinary_per_100_and_precision" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_indeterminate_vulnerable_side_is_never_clean", + "constant:fix_recall", + "name:admission_report" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "6ee17dd07b6cb3dac0e7fa0199be6823fb36a85ea42c6fd199c72ca9d0f33d50", + "owner_boundary": "tests", + "path": "tests/test_admission_scoring.py", + "symbol": "test_indeterminate_vulnerable_side_is_never_clean" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_instrument_gate_returns_no_go", + "constant:instrument", + "name:admission_report" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "339a9f2db2ad5cc25aeb67f8a1e8eb7bdaa7d82d676854f4ebcca7094c577d38", + "owner_boundary": "tests", + "path": "tests/test_admission_scoring.py", + "symbol": "test_instrument_gate_returns_no_go" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_invalid_judgment_is_refused", + "constant:judgment", + "name:admission_report" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "c750e9f857db29f5af4190d10ae12ea58667c9d830e6622d2939bb3741b44797", + "owner_boundary": "tests", + "path": "tests/test_admission_scoring.py", + "symbol": "test_invalid_judgment_is_refused" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_mislabeled_negative_is_refused", + "name:admission_report" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "2950179a754e2a7d1c6f14babe89e988e248d6ed906c12aed627a44f72ea5e63", + "owner_boundary": "tests", + "path": "tests/test_admission_scoring.py", + "symbol": "test_mislabeled_negative_is_refused" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_pre_registered_criterion_failure_returns_no_go", + "name:admission_report" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "8dbe137ba370dda9b64c3b1d515f85ef394842f646b45830c9654c85f84ab5f6", + "owner_boundary": "tests", + "path": "tests/test_admission_scoring.py", + "symbol": "test_pre_registered_criterion_failure_returns_no_go" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_report_carries_provenance_without_labels", + "call:dumps", + "name:admission_report" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "6a0cad50d7cacf249013efa131534342b42ea8926e8a854c13989238be75e0ba", + "owner_boundary": "tests", + "path": "tests/test_admission_scoring.py", + "symbol": "test_report_carries_provenance_without_labels" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_report_is_deterministic", + "call:dumps", + "name:admission_report" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "30352a898da4651340068aba6ac03dc3239b4dd1cbee0eb01284eec8e2a3ef99", + "owner_boundary": "tests", + "path": "tests/test_admission_scoring.py", + "symbol": "test_report_is_deterministic" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_verified_location_recall_keeps_sample_count", + "name:admission_report" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "e7dd8917446e73e989177e1d403e8dd27393746bc884b906343884bbdf2749a3", + "owner_boundary": "tests", + "path": "tests/test_admission_scoring.py", + "symbol": "test_verified_location_recall_keeps_sample_count" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_vulnerable_only_pair_scores_correct", + "constant:fix_recall", + "constant:pair_correctness", + "name:admission_report" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "8b97cc498fdd6a4411cb6c22ec6fa592c72dd63e80853e6e3757323016635fa3", + "owner_boundary": "tests", + "path": "tests/test_admission_scoring.py", + "symbol": "test_vulnerable_only_pair_scores_correct" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_summarize_arm_publishes_budget_result_and_masks_repositories", + "constant:fact_set_digest", + "constant:id", + "constant:instrument", + "constant:judgment", + "constant:stage_funnel", + "constant:status", + "call:dumps" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "6fe48be48004f15cf1157b77a2ca88c7a0fb2f6bb649c71aa656f3a62c17c53b", + "owner_boundary": "tests", + "path": "tests/test_arm_regression.py", + "symbol": "test_summarize_arm_publishes_budget_result_and_masks_repositories" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_summarize_arm_refuses_zero_byte_summary", + "constant:id", + "constant:instrument", + "constant:judgment", + "constant:stage_funnel", + "constant:status", + "call:dumps", + "call:write_text" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "d81da9903d045cbad92e06b1f36bd12becec9f9b88e09697689c5a69ab7a04f4", + "owner_boundary": "tests", + "path": "tests/test_arm_regression.py", + "symbol": "test_summarize_arm_refuses_zero_byte_summary" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.admission:AdmissionManifest" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "546a3f2d3921f64728fa02c888eee3feefaeafaa1ea1a146c75fc13da32351dc", + "owner_boundary": "tests", + "path": "tests/test_core_admission.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.admission:AdmissionManifestError" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "16b2351051af0b44f4e14e19e40c1ecb54bbcd384de099a2770c82d387d4e651", + "owner_boundary": "tests", + "path": "tests/test_core_admission.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.admission:REPORT_SCHEMA_KEYS" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "1c4b767a6d878b987583f4f56da1850ce82414079a0e1ca68367d7e6a4101874", + "owner_boundary": "tests", + "path": "tests/test_core_admission.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.admission:validate_admission_manifest" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "e3cb066f71af808d9445bd9df27a2483efa64a1637ec6519099035eda85f1dfc", + "owner_boundary": "tests", + "path": "tests/test_core_admission.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.budget:Budget" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "c974daa201ee1477870220cc125647f780483ecbb73f368cd118e620f93271e4", + "owner_boundary": "tests", + "path": "tests/test_core_budget.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.budget:Complexity" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "97e4d250409b8d1644847e7c83660e8e20139612e80c0193f340d046d1d7aa6c", + "owner_boundary": "tests", + "path": "tests/test_core_budget.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "module_attr:openultrasast.core.budget:Budget" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "038a226ebcc1eca0a32cd8b898ffe9ce83adb5df15d18d79a3c43483ad1aca24", + "owner_boundary": "tests", + "path": "tests/test_core_budget_v2.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "module_attr:openultrasast.core.budget:Complexity" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "b25954ccaf660d5bd49452865c401b865840cf7ea3200b6ab326b03dd4e2ddef", + "owner_boundary": "tests", + "path": "tests/test_core_budget_v2.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import:openultrasast.core.verdict" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "358c892356e82903ac96a6ab5283df55d9f47187c103ebce68fb851de72abd2f", + "owner_boundary": "tests", + "path": "tests/test_core_contract.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "module_attr:openultrasast.core.verdict:__all__" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "02e8dd66f7e81267b27d2ea5397fcfd84dbd4a60ffd0a82afcc22c408ee48c6e", + "owner_boundary": "tests", + "path": "tests/test_core_contract.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.coverage:Coverage" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "acee736c3f54c1f7c8f01a274168634c68ecd74d21bf2957558cf0023070173c", + "owner_boundary": "tests", + "path": "tests/test_core_contract.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.coverage:InstrumentFailure" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "effcf6b958937e3a81e9c03ec9e7c0e85dfc488b408bf863a1c1eb4d2af78466", + "owner_boundary": "tests", + "path": "tests/test_core_contract.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.coverage:check_reads" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "7b30c9525f9f720376fcd522fe2ccacb0dd23c31dd202de870757ea7a6aa7937", + "owner_boundary": "tests", + "path": "tests/test_core_contract.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.provenance:ProvenanceMismatch" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "2a76d3269b716199320b8289664176e215efb33a63525a79409eaa741acb2622", + "owner_boundary": "tests", + "path": "tests/test_core_contract.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.provenance:stamp" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "1ef7ad00714c9f91cb3ce4213e9333b2b854f82701e1a222655cb8d16c3b5ac4", + "owner_boundary": "tests", + "path": "tests/test_core_contract.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.provenance:verify_stamp" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "d5a9dd284be54015e2db8fb5404a1aa5874f9144d4757e31aced9e70e112b08b", + "owner_boundary": "tests", + "path": "tests/test_core_contract.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.trace:Guard" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "25930bdec32b86e9095600cc021c457211329e633ceb0b832a743d45a934c77a", + "owner_boundary": "tests", + "path": "tests/test_core_contract.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.trace:Hop" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "4ef60d902d422c1e8294790073f87297bf0e0bb590e50096d401bb62e1bd1176", + "owner_boundary": "tests", + "path": "tests/test_core_contract.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.trace:TraceRecord" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "f8d6537243fdda7764595bab88a1ee254a9608093cce3f0505b3b99f99ef8781", + "owner_boundary": "tests", + "path": "tests/test_core_contract.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.trace:Witness" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "5af8f27b2897bf64b00c806ec42461e2fcfb3c528dafd8d6eba85fcb6b38cbee", + "owner_boundary": "tests", + "path": "tests/test_core_contract.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.verdict:BoundedSilence" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "2033f744b853b1d6423966cfc9d810fd93f653f3ba397beb7edc6b5ddbe42232", + "owner_boundary": "tests", + "path": "tests/test_core_contract.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.verdict:Judgment" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "91b37247c77ca3da8ac78deaa4ee61624cd4e2b4613807b4a127c0963f07c007", + "owner_boundary": "tests", + "path": "tests/test_core_contract.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.verdict:ProvenClaim" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "efb1105356223fea3d5311879e28576c1aa2c6dd6ade5120854ee377fb9d818a", + "owner_boundary": "tests", + "path": "tests/test_core_contract.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.verdict:as_clean" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "24d652011571ceedc00e0fb49502bde6dafe8f480defef5ae8d0462d9bb2d901", + "owner_boundary": "tests", + "path": "tests/test_core_contract.py", + "symbol": "" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:_trace", + "name:TraceRecord" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "e046ed22bba9f748b48be4ac797979dab494cb81b702c1554056569f2ec3bfbe", + "owner_boundary": "tests", + "path": "tests/test_core_contract.py", + "symbol": "_trace" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_trace_record_pins_schema_fields", + "constant:authority", + "constant:guards", + "constant:judgment", + "constant:operation_kind", + "constant:resource", + "constant:witnesses", + "call:record" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "1cad39c718f515373ab0c2f304d6272608ddd396f38cbf9c26c595ebac333516", + "owner_boundary": "tests", + "path": "tests/test_core_contract.py", + "symbol": "test_trace_record_pins_schema_fields" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_trace_serializes_byte_identical_on_repeat", + "call:canonical" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "deaea9e5222f22e6eb2a651b90b235b3bb768092c2109ff89514e98dbbbc1a0d", + "owner_boundary": "tests", + "path": "tests/test_core_contract.py", + "symbol": "test_trace_serializes_byte_identical_on_repeat" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.coverage:InstrumentFailure" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "fc94bf747979b7e84d153e9b35502cfdbfd3d23b605328ad7d198c32059bbda6", + "owner_boundary": "tests", + "path": "tests/test_core_coverage_v2.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.consumer:PushRequest" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "992991e421ad3e70f5c62f65cdb70f12cf655a786ade1efb56b1703a5ec940fc", + "owner_boundary": "tests", + "path": "tests/test_core_factpack_consumer.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.consumer:consume_verdict" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "f1a6a81676cc8c785bc5793a618638643374680e22e2097ab1c2bbc1dc81dde3", + "owner_boundary": "tests", + "path": "tests/test_core_factpack_consumer.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.factpack:FactPackError" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "a5e43c42451b19f43c67eb26c5788da657bc4ee61aa24103b3654b3b0cf8e40a", + "owner_boundary": "tests", + "path": "tests/test_core_factpack_consumer.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.factpack:admit_fact_pack" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "0f715b2bf7e3462b13d07f035b3a3a8e2e86d8a183aa4acd8662331b31907b83", + "owner_boundary": "tests", + "path": "tests/test_core_factpack_consumer.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.factpack:verify_fact_pack" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "63f827ed52c4e703af23212d34ee619b871c2d9285e82ad1ef1c760b49e96c2a", + "owner_boundary": "tests", + "path": "tests/test_core_factpack_consumer.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.trace:TraceRecord" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "a9a1d1e2367fbbc265a2881aaae827a2c85eb1580e1b3382622e0baaa40b8a8a", + "owner_boundary": "tests", + "path": "tests/test_core_factpack_consumer.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.verdict:BoundedSilence" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "eb84a659da8017aca4b38485e4af746b9bc21643ffb9d6443a4409e2521fc85b", + "owner_boundary": "tests", + "path": "tests/test_core_factpack_consumer.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.verdict:Judgment" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "bdde92b920dcbaa6f5ca92990b87e0314cb2341c1ae63c2f9559ad09feb1272d", + "owner_boundary": "tests", + "path": "tests/test_core_factpack_consumer.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.verdict:ProvenClaim" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "7707603bc7ab3de03007e458484515aa7a2a4595b6dafe4da7b44b492eea39e8", + "owner_boundary": "tests", + "path": "tests/test_core_factpack_consumer.py", + "symbol": "" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:_record", + "name:TraceRecord" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "e8758b18d7936afad4fa7446a3e266d825a9a27692f825cf40a293580a2e0dda", + "owner_boundary": "tests", + "path": "tests/test_core_factpack_consumer.py", + "symbol": "_record" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.factpack:FactPackError" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "a98bc3e050a545541ff3cd18b6952e91ecaa9dd7654da604b87c1f1e34dbc470", + "owner_boundary": "tests", + "path": "tests/test_core_factpack_file.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.factpack:admit_pack_file" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "0b8a72c93433962641ffca7f4c6a0c3b97c9a6a8603d9727e8cc7dc97f127e82", + "owner_boundary": "tests", + "path": "tests/test_core_factpack_file.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.factpack:verify_fact_pack" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "f2eec239c6466fd7155a3e4cafceb2226c135ba9a286b4a77531ffe7930a9d8e", + "owner_boundary": "tests", + "path": "tests/test_core_factpack_file.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.trace:TraceRecord" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "43370cf42c55b92b78ee6c6889d403576114b6afbe60377101c5c57697a34034", + "owner_boundary": "tests", + "path": "tests/test_core_native.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.verdict:Judgment" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "26b6da04c995ce3372c89f8f96511a6f13ebcafff73cc575818d79815619f38b", + "owner_boundary": "tests", + "path": "tests/test_core_native.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "module_attr:openultrasast.core.probes:FittedComponentBlocked" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "37aa4e298728c683fd973c1f059962c4815a3810df5927279708fec770887152", + "owner_boundary": "tests", + "path": "tests/test_core_probes.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "module_attr:openultrasast.core.probes:LegacyProbeResult" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "137a37a282eb9cf14e962a2ce5240d067502afc2c312c012df04d4450b14745c", + "owner_boundary": "tests", + "path": "tests/test_core_probes.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "module_attr:openultrasast.core.probes:ShortcutDetected" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "39581bbb92ab239269bd338ff8ac52baf6b1d7cef88f597dc0d5e83e14761919", + "owner_boundary": "tests", + "path": "tests/test_core_probes.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "module_attr:openultrasast.core.probes:assert_no_shortcut" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "fab878643f2e0ada88b9efaea759e316a781bf6a23bdf2d95c0000b9b456ae13", + "owner_boundary": "tests", + "path": "tests/test_core_probes.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "module_attr:openultrasast.core.probes:require_admission_evidence" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "286b22760f38c55a1ddf41ffe4fbf0bfd0d7e128f6443ce3f3c8fae59d0eb4b2", + "owner_boundary": "tests", + "path": "tests/test_core_probes.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "module_attr:openultrasast.core.probes:reversed_pair_probe" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "a7ddae538a396120da01cb9855654804dbc1f1ad5999552778dd4e3b1a36232e", + "owner_boundary": "tests", + "path": "tests/test_core_probes.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "top_level:ProbeResult" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "b5a93b96a87310face9feb530c7520b3a9f56009b1736f35f136c8a4a6c3673f", + "owner_boundary": "tests", + "path": "tests/test_core_probes.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.admission:AdmissionManifestError" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "0ba8cb1e2916dbda5829c753935e09fb10d3efbc9fae01295139ea65d895e53e", + "owner_boundary": "tests", + "path": "tests/test_core_validation.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.admission:validate_report_schema" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "90f7a839a71d4c1c3669c219c28fcc2b3816b963cdea25a634a7042c2ede8269", + "owner_boundary": "tests", + "path": "tests/test_core_validation.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.consumer:PushRequest" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "656a3a0e7175e98589c9094feb261569259f5aefda343c4e4daa00fc5480056a", + "owner_boundary": "tests", + "path": "tests/test_core_validation.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.consumer:consume_verdict" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "4471330d8ecd10925858eb9978a8c5f39073b1fa8384c4262b73644f6a4b3b4a", + "owner_boundary": "tests", + "path": "tests/test_core_validation.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.verdict:Judgment" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "681864c66348a52dfee3631bf59307652fadc2e4d259c48b6bc81853ee1df567", + "owner_boundary": "tests", + "path": "tests/test_core_validation.py", + "symbol": "" + }, + { + "artifact_family": "v1-contract", + "capability_anchors": [ + "import_from:openultrasast.core.verdict:ProvenClaim" + ], + "dependency_kind": "reader", + "disposition": "open", + "entry_id": "1ab2115d0c47e65acdef399d3927077fd33fce08171ee955ef3e167e79db17f3", + "owner_boundary": "tests", + "path": "tests/test_core_validation.py", + "symbol": "" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_run_development_is_deterministic_across_runs._normalized", + "name:DevelopmentRecord" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "3de95f829f742fcfcb71ad8b06b4376c58940750ad4e7dd26739f0c3285b9655", + "owner_boundary": "tests", + "path": "tests/test_development_runner.py", + "symbol": "test_run_development_is_deterministic_across_runs._normalized" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:_record", + "constant:judgment", + "name:DevelopmentRecord" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "2d764d7a5c78c7822e22c2abbe9f9baf67a3fdbaac4d1c36fcf3c307539d819f", + "owner_boundary": "tests", + "path": "tests/test_four_arm.py", + "symbol": "_record" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:write_records", + "constant:done", + "constant:id", + "constant:input_digest", + "constant:push", + "constant:status", + "call:dumps", + "call:write_text" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "4ceb5c63f47c07603a61ee972d29e8528639820b4c1969233ca74efea9c98403", + "owner_boundary": "tests", + "path": "tests/test_hunt_ablation.py", + "symbol": "write_records" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:artifact", + "name:RunArtifact" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "75f2086747bc1c6b7cb19cbffe6dcc6bdd55fd844df9220eb9e427c8d996a57c", + "owner_boundary": "tests", + "path": "tests/test_hunt_artifact.py", + "symbol": "artifact" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_artifact_round_trip_and_tamper", + "constant:id", + "call:dumps", + "call:write", + "call:write_text", + "name:RunArtifact" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "439a94cbe5033a44ecbcfe195346a6ba9eb87482235816135a6a7106b6a28c88", + "owner_boundary": "tests", + "path": "tests/test_hunt_artifact.py", + "symbol": "test_artifact_round_trip_and_tamper" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_ledger_and_budget_prevent_artifact", + "call:write" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "7a430458372aeed7e32e2982bc2378dbcb714ac0f6c6c169085b7f1881d85f9d", + "owner_boundary": "tests", + "path": "tests/test_hunt_artifact.py", + "symbol": "test_ledger_and_budget_prevent_artifact" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:record_run", + "constant:change", + "constant:done", + "constant:id", + "constant:item_id", + "constant:push" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "89586e24c4493834ac1a787ac54fc820faf039b85a4ef780512d699fed9813c9", + "owner_boundary": "tests", + "path": "tests/test_hunt_contamination.py", + "symbol": "record_run" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_combine_preserves_a_and_scores_b", + "constant:change", + "constant:done", + "constant:family", + "constant:id", + "constant:input_digest", + "constant:instrument", + "constant:item_id", + "constant:missing", + "constant:push", + "constant:status", + "call:dumps", + "call:write_text" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "9532b0212b14cac8e4b4d29e5ff3173b82f8368399e635b27c491045c678fee0", + "owner_boundary": "tests", + "path": "tests/test_hunter_arm.py", + "symbol": "test_combine_preserves_a_and_scores_b" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_resume_skips_done_without_client_or_checkout", + "constant:change", + "constant:done", + "constant:id", + "constant:input_digest", + "constant:item_id", + "constant:status", + "call:dumps", + "call:write_text" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "38b18d685e2da74ef99890c992b609a4135e2bbb2322a6e773f4a4ef9c73d66d", + "owner_boundary": "tests", + "path": "tests/test_hunter_arm.py", + "symbol": "test_resume_skips_done_without_client_or_checkout" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_build_trace_carries_abstract_state_as_an_opt_in_argument", + "constant:judgment", + "call:record", + "name:build_trace" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "2d37be8ae21946fbed17ad5e5fa68d8bf486a657299e442ad35dd69503912365", + "owner_boundary": "tests", + "path": "tests/test_obligation_judgment.py", + "symbol": "test_build_trace_carries_abstract_state_as_an_opt_in_argument" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_call_text_fallback_balances_nested_arguments", + "name:build_trace" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "6d3caa2638285c1d8ff40194de536f63942229b3e0dab2feba1bb1d8676407b2", + "owner_boundary": "tests", + "path": "tests/test_obligation_trace.py", + "symbol": "test_call_text_fallback_balances_nested_arguments" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_control_components_include_branch_guard_without_discharge", + "call:record", + "name:build_trace" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "eb6ec4bfc9ffd463a40083808655d7ad74ad76e75f3fdd55388e18493eaf4d18", + "owner_boundary": "tests", + "path": "tests/test_obligation_trace.py", + "symbol": "test_control_components_include_branch_guard_without_discharge" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_deterministic_text_and_canonical_json", + "constant:operation", + "call:dumps", + "call:record" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "66ac06dda8fa6a57a8a8a66a7066b7a89759fb0b4de1aed639df60728002bf1c", + "owner_boundary": "tests", + "path": "tests/test_obligation_trace.py", + "symbol": "test_deterministic_text_and_canonical_json" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_guards_after_follow_return_order", + "name:build_trace" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "182178303988df577e5caa1c8c19779567f1adbcea4a599730b1dead164dad85", + "owner_boundary": "tests", + "path": "tests/test_obligation_trace.py", + "symbol": "test_guards_after_follow_return_order" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_handler_operation_arguments_are_parameter_origins", + "name:build_trace" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "cf678e5453ab4feab1394e0d1ef2a5911d35007c86cde2e3e602eb39c44449fb", + "owner_boundary": "tests", + "path": "tests/test_obligation_trace.py", + "symbol": "test_handler_operation_arguments_are_parameter_origins" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_order_dominance_trace_names_relation_and_effect", + "call:record" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "278e7328ffc7bb24d51e3144b31a481b60eb5d75c3b22b1657f66d3d21dfadb4", + "owner_boundary": "tests", + "path": "tests/test_obligation_trace.py", + "symbol": "test_order_dominance_trace_names_relation_and_effect" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_recent_bind_sources_and_unknown_composites", + "name:build_trace" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "af1802204a0b13b0abe152869e26bab08bb087673a37f2be8360e87c79d27f96", + "owner_boundary": "tests", + "path": "tests/test_obligation_trace.py", + "symbol": "test_recent_bind_sources_and_unknown_composites" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_request_alias_and_member_access_across_methods", + "name:build_trace" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "e27cd988eff513f84e1f3ae7f5f7933bda6b4a440873d41600ab9f95fc4f4a01", + "owner_boundary": "tests", + "path": "tests/test_obligation_trace.py", + "symbol": "test_request_alias_and_member_access_across_methods" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_source_name_suffix_is_unknown", + "name:build_trace" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "583551a4944cd94d2bd7c11f624d9d1401d911b134837fa8a1d6220a7782a9e3", + "owner_boundary": "tests", + "path": "tests/test_obligation_trace.py", + "symbol": "test_source_name_suffix_is_unknown" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:trace", + "name:build_trace" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "4066abfdd6f8e4e1cd54040b1edf76aa55fb73f2141b0002926c159c81401b7a", + "owner_boundary": "tests", + "path": "tests/test_obligation_trace.py", + "symbol": "trace" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_equivalent_origins_admit_same_claim_and_only_block_when_enabled" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "d27a3d4a2b74dfb2733180b5630a47bc526e882aec481fbdccb17fea1dccf5e0", + "owner_boundary": "tests", + "path": "tests/test_push_admission.py", + "symbol": "test_equivalent_origins_admit_same_claim_and_only_block_when_enabled" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_no_default_eligibility_and_unsupported_origin_is_a_coverage_gap" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "6053d34069919993420bf59d10d1fb78e61b47728d72a750d7f21a3c25343453", + "owner_boundary": "tests", + "path": "tests/test_push_admission.py", + "symbol": "test_no_default_eligibility_and_unsupported_origin_is_a_coverage_gap" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_unchanged_on_one_base_does_not_suppress_new_on_another" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "dc6ca292792d0d1c04ba2a12effad4bb0491bf18d0a421e5dbeb76386f15f546", + "owner_boundary": "tests", + "path": "tests/test_push_admission.py", + "symbol": "test_unchanged_on_one_base_does_not_suppress_new_on_another" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_unknown_novelty_is_coverage_but_unchanged_debt_is_not" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "ee04a2981458e29ebd221ab61ed44c1df7e2af88803b1dc7a2bce63b9c895f39", + "owner_boundary": "tests", + "path": "tests/test_push_admission.py", + "symbol": "test_unknown_novelty_is_coverage_but_unchanged_debt_is_not" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:report_with", + "constant:facts" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "2d20c6424ba6c7a5388fe4da3981541ea87e7d96826be20748a9bc88b6a295e9", + "owner_boundary": "tests", + "path": "tests/test_push_report.py", + "symbol": "report_with" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:_record", + "constant:instrument", + "constant:judgment", + "name:DevelopmentRecord" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "9b39705e258c05855051dc4e84cbc999f68cb27f8584dc8d2f64ec22a93f5945", + "owner_boundary": "tests", + "path": "tests/test_runner_gates.py", + "symbol": "_record" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_instrument_failure_record_is_not_covered", + "constant:change", + "constant:done", + "constant:id", + "constant:input_digest", + "constant:instrument", + "constant:item_id", + "constant:push", + "constant:status", + "call:_write_json" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "ed6e50427d3a43f6d6beaa12d9fc23520235edc7e91da2be21d5edd0b000d052", + "owner_boundary": "tests", + "path": "tests/test_semgrep_arm.py", + "symbol": "test_instrument_failure_record_is_not_covered" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_record_shape_is_accepted_by_the_scorer", + "constant:change", + "constant:coverage", + "constant:done", + "constant:family", + "constant:id", + "constant:input_digest", + "constant:instrument", + "constant:item_id", + "constant:push", + "constant:status", + "call:_write_json", + "call:dumps" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "97b5d8f82de0c3f37aaf6875a46ea6f093872f2e0c15aac372d1843841f06005", + "owner_boundary": "tests", + "path": "tests/test_semgrep_arm.py", + "symbol": "test_record_shape_is_accepted_by_the_scorer" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_calibration_median_bootstrap_and_privacy", + "constant:missing", + "constant:push", + "call:dumps" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "aaf79a319db89e70aaa3dcba02f0aeefd47327f39b60f93cc4e37db31c2c5ce7", + "owner_boundary": "tests", + "path": "tests/test_unseen_calibrate.py", + "symbol": "test_calibration_median_bootstrap_and_privacy" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_engine_proof_counts_differences_without_names", + "constant:done", + "constant:instrument", + "constant:status", + "call:dumps", + "call:write_text" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "72e697a76fb7262182faed2cc5f7a5b0f7dac0a16f9841d511a72d0823bef1c1", + "owner_boundary": "tests", + "path": "tests/test_unseen_proof.py", + "symbol": "test_engine_proof_counts_differences_without_names" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_replay_proof", + "constant:findings", + "constant:input_digest", + "constant:instrument", + "constant:push", + "constant:status", + "call:dumps", + "call:write_text" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "b513894d07db26320eeb40c40d2841b640a02c5187ef6c302ba7cc5abd02901f", + "owner_boundary": "tests", + "path": "tests/test_unseen_proof.py", + "symbol": "test_replay_proof" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_frozen_toml_slice_and_scoring_join", + "constant:change", + "constant:input_digest", + "constant:instrument", + "constant:item_id", + "call:canonical", + "call:dumps", + "call:write_text" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "73c2eaab431b3c48e1c6664039f67b27b251dd64aecc39e86c8dd84854925a30", + "owner_boundary": "tests", + "path": "tests/test_unseen_replay.py", + "symbol": "test_frozen_toml_slice_and_scoring_join" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_catch_and_all_stream_false_alarm", + "constant:findings", + "constant:push", + "call:record" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "8901c60311b597627ecf1d1b0746a53cd07f16b4e51ab757146c9b1a5aa13319", + "owner_boundary": "tests", + "path": "tests/test_unseen_score.py", + "symbol": "test_catch_and_all_stream_false_alarm" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_coverage_and_failure_denominator", + "constant:instrument", + "constant:push", + "constant:status", + "call:record" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "91cc457f9b62e6e5cfa3891b68e1ed0da51917b60717c8f07b125b13a28a2046", + "owner_boundary": "tests", + "path": "tests/test_unseen_score.py", + "symbol": "test_coverage_and_failure_denominator" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_gate", + "constant:findings", + "call:record" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "c63d79f8f137667740e157f1d1b45229430d5c35a8f2a287f85e4cbb81178e72", + "owner_boundary": "tests", + "path": "tests/test_unseen_score.py", + "symbol": "test_gate" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_location_rules", + "call:record" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "b8bafdb6150fcd09f1a98b167cc90c8638376e83ea8d367ab6e287ebd531e05f", + "owner_boundary": "tests", + "path": "tests/test_unseen_score.py", + "symbol": "test_location_rules" + }, + { + "artifact_family": "v1-artifact", + "capability_anchors": [ + "definition:test_real_artifact_coverage_and_location_binding", + "constant:findings", + "constant:push", + "call:record" + ], + "dependency_kind": "writer", + "disposition": "open", + "entry_id": "de9fe8d13ae069dd101e9e76cd5a1a63b95cf7a39ce2da49b52ef7f57dca9aef", + "owner_boundary": "tests", + "path": "tests/test_unseen_score.py", + "symbol": "test_real_artifact_coverage_and_location_binding" + } + ], + "historical_artifacts": [ + { + "byte_length": 401, + "path": "tests/fixtures/detection_core/v1/trace.json", + "schema_version": "trace-v1", + "sha256": "93c58ba7c51f11a3173c939e9dcc1eac33334c05a1e066bcc1e4879c4c8de8f0" + }, + { + "byte_length": 1902, + "path": "tests/fixtures/detection_core/v1/report.json", + "schema_version": "admission-report-v1", + "sha256": "e07f10c838b3161040edf05965d1cd1e861023dce36f74f7367dc030b883bcca" + } + ], + "schema_version": "openultrasast.detection-core.legacy-migration.v1" +} diff --git a/tests/fixtures/detection_core/v1/report.json b/tests/fixtures/detection_core/v1/report.json new file mode 100644 index 0000000..360a83a --- /dev/null +++ b/tests/fixtures/detection_core/v1/report.json @@ -0,0 +1,91 @@ +{ + "coverage": 0.3333333333333333, + "criteria_pre_registered": { + "max_flagged_ordinary_per_100": 10.0, + "max_indeterminate_rate": 0.5, + "min_fix_recall": 0.5, + "min_pair_correctness": 0.5, + "min_precision": 0.25, + "min_verified_location_recall": 0.5 + }, + "decision": "NO-GO", + "failed_gates": [ + "min_fix_recall: 0.0 < 0.5", + "min_pair_correctness: 0.0 < 0.5", + "min_precision: 0.0 < 0.25", + "min_verified_location_recall: not measured (n=0) vs 0.5" + ], + "families": [], + "fix_recall": { + "count": 0, + "n": 12, + "rate": 0.0, + "wilson95": [ + 0, + 0.2425007574992425 + ] + }, + "flagged_ordinary_per_100": { + "count": 2, + "n": 240, + "rate": 0.8333333333333334, + "wilson95": [ + 0.2288235363161974, + 2.9870346273441455 + ] + }, + "indeterminate_rate": { + "count": 3, + "n": 264, + "rate": 0.011363636363636364, + "wilson95": [ + 0.003871976570054633, + 0.03287212890123884 + ] + }, + "instrument_failures": 0, + "manifest": { + "acquisition_record_digest": "none", + "analyzer_revision": "d063167b28ed7db2335737fdb0dae0555225ea85", + "configuration_digest": "095b5a4905ad", + "fact_set_digest": "3eb5bf699434", + "population_digest": "c866c0e812c0b54476c7168fdb0e4a20652de0d30485270afecbe51e5c35e424", + "population_role": "admission" + }, + "pair_correctness": { + "count": 0, + "n": 12, + "rate": 0.0, + "wilson95": [ + 0, + 0.2425007574992425 + ] + }, + "pairs": { + "correct": 0, + "n": 12 + }, + "precision": { + "count": 0, + "n": 14, + "rate": 0.0, + "wilson95": [ + 0, + 0.21531701192718142 + ] + }, + "runtime": { + "max_seconds": 7.112766742007807, + "mean_seconds": 2.8931797610857757, + "n": 12 + }, + "verified_location_recall": { + "count": 0, + "n": 0, + "rate": null, + "wilson95": [ + null, + null + ] + } +} diff --git a/tests/fixtures/detection_core/v1/trace.json b/tests/fixtures/detection_core/v1/trace.json new file mode 100644 index 0000000..f39cf67 --- /dev/null +++ b/tests/fixtures/detection_core/v1/trace.json @@ -0,0 +1 @@ +{"authority":"admin","completeness_reasons":[],"digests":{"input":"abc123"},"entry":"src/app.py::handler","guards":[{"effect":"branches","kind":"permission_check"}],"hops":[{"call_line":10,"complete":true,"function":"handler"}],"judgment":"unguarded","operation_kind":"protected_read","resource":"credentials","witnesses":[{"kind":"guard","provenance":"fact:checkPermission","relation":"all_paths"}]} diff --git a/tests/test_core_migration.py b/tests/test_core_migration.py new file mode 100644 index 0000000..3266363 --- /dev/null +++ b/tests/test_core_migration.py @@ -0,0 +1,143 @@ +"""Read-only historical validation for the detection-core v1 migration.""" + +from __future__ import annotations + +import ast +import hashlib +import json +from collections.abc import Callable +from pathlib import Path + +import pytest + +from openultrasast.core.legacy import ( + LEGACY_REPORT_SCHEMA, + LEGACY_TRACE_SCHEMA, + LegacyArtifactError, + decode_legacy_artifact, + read_legacy_artifact, +) + +REPO = Path(__file__).resolve().parents[1] +FIXTURES = REPO / "tests/fixtures/detection_core/v1" +TRACE_SHA256 = "93c58ba7c51f11a3173c939e9dcc1eac33334c05a1e066bcc1e4879c4c8de8f0" +REPORT_SHA256 = "e07f10c838b3161040edf05965d1cd1e861023dce36f74f7367dc030b883bcca" + + +@pytest.mark.parametrize( + ("name", "digest", "length"), + (("trace.json", TRACE_SHA256, 401), ("report.json", REPORT_SHA256, 1902)), +) +def test_v1_fixtures_are_nonzero_and_byte_exact(name: str, digest: str, length: int) -> None: + content = (FIXTURES / name).read_bytes() + + assert len(content) == length, "the historical instrument must read the expected nonzero bytes" + assert hashlib.sha256(content).hexdigest() == digest + + +def test_legacy_reader_routes_explicit_trace_and_report_schemas() -> None: + trace = read_legacy_artifact(FIXTURES / "trace.json", schema_version=LEGACY_TRACE_SCHEMA) + report = read_legacy_artifact(FIXTURES / "report.json", schema_version=LEGACY_REPORT_SCHEMA) + + assert trace.schema_version == "trace-v1" and trace.byte_length == 401 + assert trace.payload["judgment"] == "unguarded" + assert report.schema_version == "admission-report-v1" and report.byte_length == 1902 + assert report.payload["decision"] == "NO-GO" + assert trace.content == (FIXTURES / "trace.json").read_bytes() + assert report.content == (FIXTURES / "report.json").read_bytes() + + +def test_legacy_reader_exposes_no_writer_converter_or_baseline_comparison() -> None: + from openultrasast.core.evidence import EvidenceRecord + + artifact = read_legacy_artifact(FIXTURES / "trace.json", schema_version=LEGACY_TRACE_SCHEMA) + + assert not isinstance(artifact, EvidenceRecord) + for prohibited in ("write", "to_v2", "decision", "baseline_identity", "compare_identity"): + assert not hasattr(artifact, prohibited) + with pytest.raises(AttributeError): + artifact.content = b"replacement" # type: ignore[misc] + changed = artifact.payload + changed["judgment"] = "discharged" + assert artifact.payload["judgment"] == "unguarded" + + +@pytest.mark.parametrize("schema", ("", "trace-v2", "admission-report-v2", "unknown")) +def test_legacy_reader_refuses_unknown_or_v2_schema_routes(schema: str) -> None: + content = (FIXTURES / "trace.json").read_bytes() + + with pytest.raises(LegacyArtifactError, match="schema"): + decode_legacy_artifact(content, schema_version=schema) + + +def test_legacy_reader_refuses_cross_routed_or_embedded_schema_identity() -> None: + with pytest.raises(LegacyArtifactError): + decode_legacy_artifact((FIXTURES / "trace.json").read_bytes(), schema_version=LEGACY_REPORT_SCHEMA) + with pytest.raises(LegacyArtifactError): + decode_legacy_artifact((FIXTURES / "report.json").read_bytes(), schema_version=LEGACY_TRACE_SCHEMA) + embedded = {**json.loads((FIXTURES / "trace.json").read_bytes()), "schema_version": LEGACY_TRACE_SCHEMA} + with pytest.raises(LegacyArtifactError, match="ambiguous"): + decode_legacy_artifact(json.dumps(embedded).encode(), schema_version=LEGACY_TRACE_SCHEMA) + + +def test_legacy_reader_refuses_duplicate_json_fields_and_bytes_subclasses() -> None: + duplicated = b'{"entry":"shadow",' + (FIXTURES / "trace.json").read_bytes()[1:] + with pytest.raises(LegacyArtifactError, match="duplicate"): + decode_legacy_artifact(duplicated, schema_version=LEGACY_TRACE_SCHEMA) + + class HostileBytes(bytes): + def __len__(self) -> int: + raise AssertionError("subclass methods must not be observed") + + with pytest.raises(LegacyArtifactError, match="exact bytes"): + decode_legacy_artifact(HostileBytes((FIXTURES / "trace.json").read_bytes()), schema_version=LEGACY_TRACE_SCHEMA) + + +@pytest.mark.parametrize( + ("fixture", "schema", "mutation"), + ( + ("trace.json", "trace-v1", lambda value: {**value, "unknown": True}), + ("trace.json", "trace-v1", lambda value: {**value, "judgment": "clean"}), + ("report.json", "admission-report-v1", lambda value: {**value, "decision": "MAYBE"}), + ("report.json", "admission-report-v1", lambda value: {key: item for key, item in value.items() if key != "manifest"}), + ), +) +def test_legacy_reader_refuses_open_or_invalid_historical_shapes( + fixture: str, + schema: str, + mutation: Callable[[dict[str, object]], dict[str, object]], +) -> None: + value = json.loads((FIXTURES / fixture).read_bytes()) + + with pytest.raises(LegacyArtifactError): + decode_legacy_artifact(json.dumps(mutation(value)).encode(), schema_version=schema) + + +def test_legacy_reader_refuses_empty_or_unreadable_input(tmp_path: Path) -> None: + empty = tmp_path / "empty.json" + empty.write_bytes(b"") + + with pytest.raises(LegacyArtifactError, match="nonempty"): + read_legacy_artifact(empty, schema_version=LEGACY_TRACE_SCHEMA) + with pytest.raises(LegacyArtifactError, match="readable"): + read_legacy_artifact(tmp_path / "missing.json", schema_version=LEGACY_TRACE_SCHEMA) + + +def test_legacy_decoder_has_no_compatibility_or_v2_domain_dependency() -> None: + path = REPO / "src/openultrasast/core/legacy.py" + content = path.read_bytes() + assert content, "the import-boundary instrument must read nonzero decoder bytes" + tree = ast.parse(content, filename=str(path.relative_to(REPO))) + modules = {node.module for node in ast.walk(tree) if isinstance(node, ast.ImportFrom) and node.module is not None} | { + alias.name for node in ast.walk(tree) if isinstance(node, ast.Import) for alias in node.names + } + + assert "openultrasast.core.legacy_v1" not in modules + assert "openultrasast.core.evidence" not in modules + assert modules & {"openultrasast.core.canonical"} == {"openultrasast.core.canonical"} + + +def test_legacy_reader_is_not_reexported_from_the_public_core_api() -> None: + import openultrasast.core as core + + assert not ({"LegacyArtifact", "decode_legacy_artifact", "read_legacy_artifact"} & set(core.__all__)) diff --git a/tests/test_core_migration_provenance.py b/tests/test_core_migration_provenance.py new file mode 100644 index 0000000..d48277b --- /dev/null +++ b/tests/test_core_migration_provenance.py @@ -0,0 +1,293 @@ +"""Immutable worklist tests for the detection-core v1 migration.""" + +from __future__ import annotations + +import json +from dataclasses import replace +from pathlib import Path + +import core_migration_audit +import pytest +from core_migration_audit import audit_legacy_readers, tracked_python +from core_migration_inventory import ( + REPO, + LegacyInventoryError, + MigrationDisposition, + entry_identity, + load_migration_inventory, + validate_historical_artifacts, + validate_inventory_sources, + validate_inventory_transition, +) + +INVENTORY = REPO / "tests/fixtures/detection_core/v1/migration_inventory.json" + + +@pytest.mark.parametrize( + ("source", "expected"), + ( + ( + "import openultrasast.core.probes as legacy_probes\nresult = legacy_probes.LegacyProbeResult\n", + "module_attr:openultrasast.core.probes:LegacyProbeResult", + ), + ( + "from openultrasast.core import budget as legacy_budget\nresult = legacy_budget.Budget\n", + "module_attr:openultrasast.core.budget:Budget", + ), + ), +) +def test_reader_audit_covers_direct_legacy_submodule_bindings( + tmp_path: Path, monkeypatch: pytest.MonkeyPatch, source: str, expected: str +) -> None: + monkeypatch.setattr(core_migration_audit, "REPO", tmp_path) + path = tmp_path / "reader.py" + path.write_text(source, encoding="utf-8") + + report = audit_legacy_readers((path,)) + + assert report.files_read == 1 and report.bytes_read == len(source.encode()) + assert report.capabilities == (("reader.py", expected),) + + +def test_reader_audit_covers_real_direct_legacy_submodule_reads() -> None: + expected = { + ("tests/test_core_budget_v2.py", "module_attr:openultrasast.core.budget:Budget"), + ("tests/test_core_budget_v2.py", "module_attr:openultrasast.core.budget:Complexity"), + ("tests/test_core_probes.py", "module_attr:openultrasast.core.probes:FittedComponentBlocked"), + ("tests/test_core_probes.py", "module_attr:openultrasast.core.probes:LegacyProbeResult"), + ("tests/test_core_probes.py", "module_attr:openultrasast.core.probes:ShortcutDetected"), + ("tests/test_core_probes.py", "module_attr:openultrasast.core.probes:assert_no_shortcut"), + ("tests/test_core_probes.py", "module_attr:openultrasast.core.probes:require_admission_evidence"), + ("tests/test_core_probes.py", "module_attr:openultrasast.core.probes:reversed_pair_probe"), + ("tests/test_core_contract.py", "module_attr:openultrasast.core.verdict:__all__"), + } + paths = tuple(REPO / path for path in sorted({path for path, _ in expected})) + + report = audit_legacy_readers(paths) + + assert report.files_read == 3 and report.bytes_read > 0 + assert expected <= set(report.capabilities) + + +def test_frozen_inventory_resolves_nonzero_sources_and_targets() -> None: + content = INVENTORY.read_bytes() + assert content, "the inventory instrument must read nonzero bytes" + + inventory = load_migration_inventory(INVENTORY) + + assert inventory.entries + assert all(entry.disposition is MigrationDisposition.OPEN for entry in inventory.entries) + assert all(entry.entry_id == entry_identity(entry) for entry in inventory.entries) + validate_inventory_sources(inventory, root=REPO) + + +def test_inventory_covers_known_live_legacy_boundaries() -> None: + inventory = load_migration_inventory(INVENTORY) + registered_readers = {entry.path for entry in inventory.entries if entry.dependency_kind.value == "reader"} + registered_writers = {entry.path for entry in inventory.entries if entry.dependency_kind.value == "writer"} + + assert registered_readers == { + "benchmarks/valid/arm_regression.py", + "benchmarks/valid/prover_admission.py", + "src/openultrasast/core/__init__.py", + "src/openultrasast/core/consumer.py", + "src/openultrasast/core/factpack.py", + "src/openultrasast/core/trace.py", + "src/openultrasast/hunt/prover.py", + "src/openultrasast/semantic/obligations/core_adapter.py", + "tests/test_core_admission.py", + "tests/test_core_budget.py", + "tests/test_core_budget_v2.py", + "tests/test_core_contract.py", + "tests/test_core_coverage_v2.py", + "tests/test_core_factpack_consumer.py", + "tests/test_core_factpack_file.py", + "tests/test_core_native.py", + "tests/test_core_probes.py", + "tests/test_core_validation.py", + } + assert registered_writers == { + "benchmarks/learn/engine_task_entry.py", + "benchmarks/measurements/2026-10-14-access-control-hunt/analyse.py", + "benchmarks/unseen/calibrate.py", + "benchmarks/unseen/replay.py", + "benchmarks/unseen/score.py", + "benchmarks/valid/admission_run.py", + "benchmarks/valid/arm_regression.py", + "benchmarks/valid/development_runner.py", + "benchmarks/valid/hunter_arm.py", + "benchmarks/valid/judge_pass.py", + "benchmarks/valid/metrics.py", + "benchmarks/valid/prover_arm.py", + "benchmarks/valid/semgrep_arm.py", + "ops/smoke_admission.py", + "ops/smoke_report.py", + "src/openultrasast/core/_legacy_factpack.py", + "src/openultrasast/core/consumer.py", + "src/openultrasast/core/probes.py", + "src/openultrasast/core/trace.py", + "src/openultrasast/hunt/prover.py", + "src/openultrasast/hunt/report.py", + "src/openultrasast/hunt/runner.py", + "src/openultrasast/push/runner.py", + "src/openultrasast/semantic/obligations/core_adapter.py", + "tests/test_admission_scoring.py", + "tests/test_arm_regression.py", + "tests/test_core_contract.py", + "tests/test_core_factpack_consumer.py", + "tests/test_development_runner.py", + "tests/test_four_arm.py", + "tests/test_hunt_ablation.py", + "tests/test_hunt_artifact.py", + "tests/test_hunt_contamination.py", + "tests/test_hunter_arm.py", + "tests/test_obligation_judgment.py", + "tests/test_obligation_trace.py", + "tests/test_push_admission.py", + "tests/test_push_report.py", + "tests/test_runner_gates.py", + "tests/test_semgrep_arm.py", + "tests/test_unseen_calibrate.py", + "tests/test_unseen_proof.py", + "tests/test_unseen_replay.py", + "tests/test_unseen_score.py", + } + + +def test_inventory_registers_the_active_legacy_probe_writer() -> None: + inventory = load_migration_inventory(INVENTORY) + + assert any( + entry.path == "src/openultrasast/core/probes.py" + and entry.symbol == "reversed_pair_probe" + and entry.dependency_kind.value == "writer" + for entry in inventory.entries + ) + + +def test_independent_reader_audit_matches_split_inventory_capabilities() -> None: + report = audit_legacy_readers(tracked_python()) + inventory = load_migration_inventory(INVENTORY) + reader_entries = tuple(entry for entry in inventory.entries if entry.dependency_kind.value == "reader") + registered = {(entry.path, anchor) for entry in reader_entries for anchor in entry.capability_anchors} + + assert report.files_read > 0 and report.bytes_read > 0 + assert ("tests/test_core_probes.py", "top_level:ProbeResult") in report.capabilities + assert all(len(entry.capability_anchors) == 1 for entry in reader_entries) + assert registered == set(report.capabilities) + + +def test_inventory_targets_require_exact_capability_anchors(tmp_path: Path) -> None: + frozen = load_migration_inventory(INVENTORY) + entry = frozen.entries[0] + assert entry.capability_anchors + substituted = tmp_path / entry.path + substituted.parent.mkdir(parents=True) + substituted.write_text("def unrelated():\n return True\n", encoding="utf-8") + + with pytest.raises(LegacyInventoryError, match="capability"): + validate_inventory_sources(replace(frozen, entries=(entry,)), root=tmp_path) + + +def test_historical_artifact_manifest_pins_exact_nonzero_bytes() -> None: + inventory = load_migration_inventory(INVENTORY) + + artifacts = validate_historical_artifacts(inventory, root=REPO) + + assert {artifact.schema_version for artifact in artifacts} == {"trace-v1", "admission-report-v1"} + assert all(artifact.byte_length > 0 for artifact in artifacts) + + +@pytest.mark.parametrize("terminal", (MigrationDisposition.V2_MIGRATED, MigrationDisposition.RETIRED)) +def test_inventory_entries_close_monotonically_without_identity_changes(terminal: MigrationDisposition) -> None: + frozen = load_migration_inventory(INVENTORY) + changed_entry = replace(frozen.entries[0], disposition=terminal) + candidate = replace(frozen, entries=(changed_entry, *frozen.entries[1:])) + + validate_inventory_transition(frozen, candidate) + + with pytest.raises(LegacyInventoryError, match="terminal"): + validate_inventory_transition(candidate, frozen) + + +def test_inventory_transition_refuses_runtime_invalid_disposition() -> None: + frozen = load_migration_inventory(INVENTORY) + invalid = replace(frozen.entries[0], disposition="closed") # type: ignore[arg-type] + candidate = replace(frozen, entries=(invalid, *frozen.entries[1:])) + + with pytest.raises(LegacyInventoryError, match="disposition"): + validate_inventory_transition(frozen, candidate) + + +@pytest.mark.parametrize("mutation", ("add", "delete", "rekey")) +def test_inventory_refuses_additions_deletions_and_rekeying(mutation: str) -> None: + frozen = load_migration_inventory(INVENTORY) + if mutation == "add": + added = replace( + frozen.entries[0], + entry_id="f" * 64, + path="src/openultrasast/core/canonical.py", + symbol="", + ) + candidate = replace(frozen, entries=(*frozen.entries, added)) + elif mutation == "delete": + candidate = replace(frozen, entries=frozen.entries[1:]) + else: + changed = replace(frozen.entries[0], symbol="different_target") + changed = replace(changed, entry_id=entry_identity(changed)) + candidate = replace(frozen, entries=(changed, *frozen.entries[1:])) + + with pytest.raises(LegacyInventoryError, match="identities"): + validate_inventory_transition(frozen, candidate) + + +@pytest.mark.parametrize( + ("field", "value", "message"), + (("schema_version", "v2", "schema"), ("disposition", "closed", "disposition")), +) +def test_inventory_refuses_schema_and_status_mutations(tmp_path: Path, field: str, value: str, message: str) -> None: + document = json.loads(INVENTORY.read_bytes()) + if field == "schema_version": + document[field] = value + else: + document["entries"][0][field] = value + changed = tmp_path / "migration_inventory.json" + changed.write_text(json.dumps(document), encoding="utf-8") + + with pytest.raises(LegacyInventoryError, match=message): + load_migration_inventory(changed) + + +def test_inventory_refuses_unreadable_zero_and_unknown_targets(tmp_path: Path) -> None: + frozen = load_migration_inventory(INVENTORY) + original = frozen.entries[0] + + missing = replace(original, path="missing.py", symbol="") + missing = replace(missing, entry_id=entry_identity(missing)) + with pytest.raises(LegacyInventoryError, match="readable"): + validate_inventory_sources(replace(frozen, entries=(missing,)), root=tmp_path) + + empty_path = tmp_path / "empty.py" + empty_path.write_bytes(b"") + empty = replace(original, path="empty.py", symbol="") + empty = replace(empty, entry_id=entry_identity(empty)) + with pytest.raises(LegacyInventoryError, match="nonzero"): + validate_inventory_sources(replace(frozen, entries=(empty,)), root=tmp_path) + + source_path = tmp_path / "source.py" + source_path.write_text("def present():\n return True\n", encoding="utf-8") + unknown = replace(original, path="source.py", symbol="absent") + unknown = replace(unknown, entry_id=entry_identity(unknown)) + with pytest.raises(LegacyInventoryError, match="target"): + validate_inventory_sources(replace(frozen, entries=(unknown,)), root=tmp_path) + + +def test_inventory_refuses_changed_artifact_bytes(tmp_path: Path) -> None: + frozen = load_migration_inventory(INVENTORY) + artifact = frozen.historical_artifacts[0] + target = tmp_path / artifact.path + target.parent.mkdir(parents=True) + target.write_bytes(b"{}\n") + + with pytest.raises(LegacyInventoryError, match="digest|length"): + validate_historical_artifacts(replace(frozen, historical_artifacts=(artifact,)), root=tmp_path)