Hi Iman, Thanks — I added the ordering you suggested and made it deterministic.
The new critical trace is: authorize(target=v7, compliance=v4) final read: target=v7, compliance=v4 -> PASS compliance -> v5 target remains v7 commit with target If-Match(v7) -> succeeds So the executor's final re-read is fresh and correct at the moment it occurs, but the prerequisite can still be revoked before the target mutation commits. The result is: the final prerequisite read passes; the target precondition still passes; the prerequisite is false at commit time; the target mutation still occurs. That confirms the distinction you pointed out: fresh observation != commit-time guarantee I also kept the control and falsification cases: target changes before commit -> If-Match blocks; external prerequisite changes before final check -> full application re-check blocks; external prerequisite changes after final check -> target mutation still commits unless there is some stronger coordination/commitment mechanism. So the remaining property now looks less like a read/freshness problem and more like a commitment problem: If authorization depends on state maintained by multiple independently changing authorities, what mechanism binds those authorities' preconditions to the actual side-effecting commit? My current interpretation is that a strong guarantee requires either: one transactional authority controlling the relevant state and mutation; or a reservation/commitment protocol that every participating authority actually honors. Otherwise the system can only make a weaker claim about what was observed before execution. I agree that the wire representation of the precondition set and the commitment semantics should be treated as separate questions. I have the runnable probe ready. It now includes T1-T7, with the new post-final-read revocation case as T7b. Probe SHA-256: c6d854c9608c99970e0e1aff26201ea746bb770736f57428fa669b2ecee6741d I can put it in a public GitHub commit next if that is the most useful form for comparison. Thanks, Valentyn On Sun, Sep 13, 2026, 21:02 Iman Schrock <[email protected]> wrote: > Hi Valentyn, > > Thanks for running the variants. Keeping the target at v7 while > compliance changes isolates the separate dependency. > > > [VR] An application-specific re-check of compliance=v4 at the effect > boundary closes the case > > [IS] There is one more ordering worth adding: the executor performs > its final compliance check at v4, compliance changes to v5, then the > target mutation commits. A plain re-query can still lose that race. > > For a commit-time guarantee, the mechanism needs to say how compliance > changes are ordered against the mutation. That could be one > transactional authority, or a reservation that the participating > providers actually honor. A freshness bound on an observation doesn't > provide that guarantee. If an authority won't participate, the profile > should state the weaker guarantee rather than report the conjunction > as commit-safe. > > One WebDAV detail also matters for the comparison: RFC 4918 section > 10.4.3 uses AND within a List, but OR across Lists and tagged-list > productions. Multiple tagged resources don't automatically express > your required conjunction: > https://www.rfc-editor.org/rfc/rfc4918.html#section-10.4.3 > > I don't have a generic cross-provider mechanism in the sources we've > discussed that establishes your full commit-time property. I'd keep > the wire representation and the commitment rules as separate > questions, then test both orderings against each proposed > implementation. > > Could you share the runnable case and its commit? That would give us a > common test to compare, including what happens when a prerequisite is > revoked after the final read. > > Best, > Iman >
c6d854c9608c99970e0e1aff26201ea746bb770736f57428fa669b2ecee6741d ietf_commit_boundary_probe.py
from __future__ import annotations
from dataclasses import dataclass
from typing import Dict, Tuple
@dataclass
class Resource:
version: int
value: int = 0
@dataclass(frozen=True)
class Approval:
target_version: int
external_versions: Dict[str, int]
action: str = "increment"
amount: int = 1
class World:
def __init__(self) -> None:
self.resources = {
"target": Resource(7, 0),
"budget": Resource(12, 100),
"compliance": Resource(4, 1),
}
def snapshot(self) -> Dict[str, int]:
return {name: r.version for name, r in self.resources.items()}
def mutate_version(self, name: str) -> None:
self.resources[name].version += 1
def execute_if_match_only(self, approval: Approval) -> Tuple[bool, str]:
if self.resources["target"].version != approval.target_version:
return False, "target_precondition_failed"
self.resources["target"].value += approval.amount
self.resources["target"].version += 1
return True, "committed"
def final_read_then_commit(
self,
approval: Approval,
*,
revoke_after_final_read: bool,
) -> Dict[str, object]:
target_ok = self.resources["target"].version == approval.target_version
external_ok = all(
self.resources[name].version == expected
for name, expected in approval.external_versions.items()
)
if not (target_ok and external_ok):
return {
"final_read_passed": False,
"commit": (False, "final_read_failed"),
"effect": self.resources["target"].value,
}
if revoke_after_final_read:
self.mutate_version("compliance")
result = self.execute_if_match_only(approval)
return {
"final_read_passed": True,
"compliance_still_matches_at_commit":
self.resources["compliance"].version
== approval.external_versions["compliance"],
"commit": result,
"effect": self.resources["target"].value,
}
def authorize(world: World) -> Approval:
s = world.snapshot()
return Approval(
target_version=s["target"],
external_versions={
"budget": s["budget"],
"compliance": s["compliance"],
},
)
def verifier_passes(world: World, approval: Approval) -> bool:
return (
world.resources["target"].version == approval.target_version
and all(
world.resources[name].version == expected
for name, expected in approval.external_versions.items()
)
)
def run_matrix() -> Dict[str, object]:
out: Dict[str, object] = {}
w = World()
a = authorize(w)
out["T1_control"] = {
"verifier": verifier_passes(w, a),
"result": w.execute_if_match_only(a),
"effect": w.resources["target"].value,
}
w = World()
a = authorize(w)
assert verifier_passes(w, a)
w.mutate_version("target")
out["T2_target_race_if_match"] = {
"result": w.execute_if_match_only(a),
"effect": w.resources["target"].value,
}
w = World()
a = authorize(w)
assert verifier_passes(w, a)
w.mutate_version("budget")
out["T3_external_race_if_match_only"] = {
"target_version_still_matches":
w.resources["target"].version == a.target_version,
"budget_version_matches":
w.resources["budget"].version == a.external_versions["budget"],
"result": w.execute_if_match_only(a),
"effect": w.resources["target"].value,
}
w = World()
a = authorize(w)
assert verifier_passes(w, a)
w.mutate_version("budget")
all_ok = (
w.resources["target"].version == a.target_version
and all(
w.resources[name].version == expected
for name, expected in a.external_versions.items()
)
)
out["T4_external_race_full_recheck"] = {
"full_recheck_passed": all_ok,
"effect": w.resources["target"].value,
}
w = World()
a = authorize(w)
before = verifier_passes(w, a)
w.mutate_version("target")
out["T5_verifier_to_commit_target_race"] = {
"verifier_before_race": before,
"result": w.execute_if_match_only(a),
"effect": w.resources["target"].value,
}
w = World()
a = authorize(w)
before = verifier_passes(w, a)
w.mutate_version("compliance")
out["T6_verifier_to_commit_external_race"] = {
"verifier_before_race": before,
"target_version_still_matches":
w.resources["target"].version == a.target_version,
"result_if_match_only": w.execute_if_match_only(a),
"effect": w.resources["target"].value,
}
w = World()
a = authorize(w)
out["T7a_final_read_no_race"] = w.final_read_then_commit(
a, revoke_after_final_read=False
)
w = World()
a = authorize(w)
out["T7b_revoked_after_final_read"] = w.final_read_then_commit(
a, revoke_after_final_read=True
)
return out
def self_test(results: Dict[str, object]) -> None:
assert results["T1_control"]["result"][0] is True
assert results["T2_target_race_if_match"]["result"][0] is False
assert results["T3_external_race_if_match_only"]["target_version_still_matches"] is True
assert results["T3_external_race_if_match_only"]["budget_version_matches"] is False
assert results["T3_external_race_if_match_only"]["result"][0] is True
assert results["T4_external_race_full_recheck"]["full_recheck_passed"] is False
assert results["T5_verifier_to_commit_target_race"]["verifier_before_race"] is True
assert results["T5_verifier_to_commit_target_race"]["result"][0] is False
assert results["T6_verifier_to_commit_external_race"]["verifier_before_race"] is True
assert results["T6_verifier_to_commit_external_race"]["target_version_still_matches"] is True
assert results["T6_verifier_to_commit_external_race"]["result_if_match_only"][0] is True
assert results["T7a_final_read_no_race"]["final_read_passed"] is True
assert results["T7a_final_read_no_race"]["commit"][0] is True
assert results["T7b_revoked_after_final_read"]["final_read_passed"] is True
assert results["T7b_revoked_after_final_read"]["compliance_still_matches_at_commit"] is False
assert results["T7b_revoked_after_final_read"]["commit"][0] is True
assert results["T7b_revoked_after_final_read"]["effect"] == 1
if __name__ == "__main__":
import json
results = run_matrix()
self_test(results)
print(json.dumps(results, indent=2))
# IETF Commit-Boundary Probe v0.2 This probe tests whether an authorization whose validity depends on independently changing prerequisite state remains safe at the actual mutation boundary. ## Key traces - T2: target representation changes -> target If-Match blocks. - T3: external prerequisite changes while target remains unchanged -> target If-Match alone still commits. - T5: verifier passes, target changes before commit -> mutation-boundary If-Match blocks. - T6: verifier passes, external prerequisite changes before commit -> If-Match alone still commits. - T7a: final prerequisite read passes and nothing changes -> commit succeeds. - T7b: final prerequisite read passes, prerequisite is revoked, then target mutation commits -> commit still succeeds. T7b demonstrates that a final re-read is not itself a commit-time guarantee across independently changing authorities. ## Interpretation This does not by itself prove a standards gap. It does show that: 1. freshness of an observation is weaker than commitment; 2. target-resource conditional mutation does not automatically bind independent prerequisite state; 3. an application can only claim a stronger commit-time guarantee if all required authorities participate in a common transactional/reservation/commit protocol, or if the profile explicitly defines a weaker guarantee. The remaining interoperability question is whether an existing standard defines a generic cross-provider mechanism for transporting and enforcing that commitment set at the actual side-effect boundary.
results.json
Description: application/json
_______________________________________________ OAuth mailing list -- [email protected] To unsubscribe send an email to [email protected]
