Skip to content

Commit 504021a

Browse files
committed
fix: report conditional partition disjointness
1 parent 8894880 commit 504021a

2 files changed

Lines changed: 40 additions & 9 deletions

File tree

src/jacobian/finite_partition.py

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -375,6 +375,15 @@ def invoke(self, request: CapabilityRequest) -> CapabilityResult:
375375
and not duplicate_case_ids
376376
and (not require_disjoint or not overlaps)
377377
)
378+
verified_replay_basis = (
379+
"authorized checker replayed equality-based coverage and required "
380+
"disjointness within the caller-supplied universe"
381+
if require_disjoint
382+
else (
383+
"authorized checker replayed equality-based coverage within the "
384+
"caller-supplied universe; disjointness was not required"
385+
)
386+
)
378387
return CapabilityResult(
379388
capability_id=self.descriptor.capability_id,
380389
capability_version=self.descriptor.version,
@@ -414,9 +423,8 @@ def invoke(self, request: CapabilityRequest) -> CapabilityResult:
414423
else CapabilityCompletenessStatus.PARTIAL
415424
),
416425
basis=(
417-
"authorized checker replayed equality-based coverage and "
418-
"disjointness within the caller-supplied universe; it did not "
419-
"check external-domain completeness or member/case semantics"
426+
f"{verified_replay_basis}; it did not check external-domain "
427+
"completeness or member/case semantics"
420428
if verified
421429
else "generator-side membership accounting; not independently checked"
422430
),
@@ -443,9 +451,8 @@ def invoke(self, request: CapabilityRequest) -> CapabilityResult:
443451
assurance=CapabilityAssurance(
444452
level=assurance_level,
445453
basis=(
446-
"operator-authorized checker accepted equality-based coverage and "
447-
"disjointness within the caller-supplied universe; external-domain "
448-
"completeness and member/case semantics were not checked"
454+
f"{verified_replay_basis}; external-domain completeness and "
455+
"member/case semantics were not checked"
449456
if verified
450457
else "partition was proposed and inspected by its generator only"
451458
),
@@ -475,7 +482,7 @@ def _verify(
475482
scope_digest=scope.manifest.object_digest,
476483
)
477484
payload: dict[str, Any] = {
478-
"replay": "exact finite membership",
485+
"replay": "equality-based finite coverage and conditional disjointness",
479486
"relation_id": "case.relation.partitions",
480487
"obligation_uri": claim_uri,
481488
}

tests/composition/runtime/test_finite_partition_capability.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,12 @@
1111
from jacobian.contracts.results import Arithmetic, Conclusion, Coverage, Method
1212

1313

14-
def _request(mode: CapabilityMode, *, missing_last: bool = False) -> CapabilityRequest:
14+
def _request(
15+
mode: CapabilityMode,
16+
*,
17+
missing_last: bool = False,
18+
require_disjoint: bool = True,
19+
) -> CapabilityRequest:
1520
return CapabilityRequest(
1621
capability_id="case.partition.finite",
1722
mode=mode,
@@ -24,7 +29,7 @@ def _request(mode: CapabilityMode, *, missing_last: bool = False) -> CapabilityR
2429
"members": ["1", "3"] if missing_last else ["1", "3", "5"],
2530
},
2631
],
27-
"require_disjoint": True,
32+
"require_disjoint": require_disjoint,
2833
},
2934
)
3035

@@ -78,6 +83,25 @@ def test_finite_partition_contract_and_result_preserve_semantic_boundary(
7883
assert "member/case semantics" in result.completeness.basis
7984

8085

86+
def test_finite_partition_reports_conditional_disjointness_scope(
87+
authorized_complete_runtime,
88+
) -> None:
89+
runtime = authorized_complete_runtime
90+
request = _request(CapabilityMode.VERIFY, require_disjoint=False)
91+
request.input["cases"][1]["members"].append("0")
92+
93+
result = runtime.core.capabilities.invoke(request)
94+
95+
assert result.assurance.level is CapabilityAssuranceLevel.VERIFIED
96+
assert result.output["overlaps"] == ["0"]
97+
assert "disjointness was not required" in result.assurance.basis
98+
assert "disjointness was not required" in result.completeness.basis
99+
certificate = runtime.core.store.get(result.output["certificate_uri"])
100+
assert certificate.payload["payload"]["replay"] == (
101+
"equality-based finite coverage and conditional disjointness"
102+
)
103+
104+
81105
def test_finite_partition_verify_fails_closed_on_incomplete_cases(
82106
authorized_complete_runtime,
83107
) -> None:

0 commit comments

Comments
 (0)