Skip to content

Commit 63f5eff

Browse files
authored
feat: bind production delivery to signed permits and receipts (#383)
Terminal-verification v2: separate Ed25519 pre-delivery permit and post-delivery receipt artifacts; exact canonical permit bytes retained before each managed backend edge and acknowledged after the backend call returns; missing or invalid receipts stay pending and refuse all later input delivery; terminal permit chain rebuilt from exact retained bytes; acceptor compares runner, delivery-session, and globally one-use claim identities with independently loaded Cloud state; one deterministic cross-language vector for the Cloud implementation.
1 parent 9806814 commit 63f5eff

9 files changed

Lines changed: 2273 additions & 284 deletions

openadapt_flow/runtime/durable/authority.py

Lines changed: 684 additions & 58 deletions
Large diffs are not rendered by default.

openadapt_flow/runtime/durable/continuation.py

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
from contextvars import ContextVar
1111
from datetime import datetime, timedelta, timezone
1212
from pathlib import Path
13-
from typing import Iterator, Literal, Optional
13+
from typing import Any, Iterator, Literal, Optional
1414

1515
from pydantic import BaseModel, ConfigDict
1616

@@ -274,14 +274,14 @@ def lease(
274274
self.release(token)
275275
return
276276

277-
def before_delivery(self, token: ContinuationToken) -> None:
277+
def before_delivery(self, token: ContinuationToken) -> Any:
278278
"""Linearize Reject against the first resumed delivery boundary."""
279279

280280
manifest = self.store.read_manifest()
281281
if manifest is None:
282282
raise ContinuationBusy("the durable manifest disappeared before delivery")
283283
try:
284-
self.authority.before_delivery(
284+
remote_permit = self.authority.before_delivery(
285285
manifest,
286286
attempt_id=token.attempt_id,
287287
owner_nonce_sha256=self._nonce_digest(token.owner_nonce),
@@ -313,7 +313,7 @@ def before_delivery(self, token: ContinuationToken) -> None:
313313
}
314314
)
315315
)
316-
return
316+
return remote_permit
317317
if record.phase != "validating":
318318
raise ContinuationBusy(
319319
"the continuation attempt is not eligible for delivery"
@@ -327,6 +327,27 @@ def before_delivery(self, token: ContinuationToken) -> None:
327327
}
328328
)
329329
)
330+
return remote_permit
331+
332+
def acknowledge_delivery(
333+
self, token: ContinuationToken, remote_permit: Any
334+
) -> None:
335+
"""Commit the receipt for the exact backend edge that just returned."""
336+
337+
if remote_permit is None:
338+
return
339+
manifest = self.store.read_manifest()
340+
if manifest is None:
341+
raise ContinuationBusy("the durable manifest disappeared after delivery")
342+
try:
343+
self.authority.acknowledge_remote_delivery(
344+
manifest,
345+
remote_permit,
346+
attempt_id=token.attempt_id,
347+
owner_nonce_sha256=self._nonce_digest(token.owner_nonce),
348+
)
349+
except StateDiverged as exc:
350+
raise ContinuationBusy(str(exc)) from exc
330351

331352
def bind_approval(self, token: ContinuationToken, approval: ApprovalRecord) -> None:
332353
"""Bind the exact admitted approval in the external authority."""
@@ -720,9 +741,19 @@ def __init__(
720741
) -> None:
721742
self.coordinator = coordinator
722743
self.token = token
744+
self._pending_remote_permit: Any = None
723745

724746
def before_delivery(self) -> None:
725-
self.coordinator.before_delivery(self.token)
747+
if self._pending_remote_permit is not None:
748+
raise ContinuationBusy(
749+
"a prior production delivery lacks an acknowledgment receipt"
750+
)
751+
self._pending_remote_permit = self.coordinator.before_delivery(self.token)
752+
753+
def acknowledge_delivery(self) -> None:
754+
pending = self._pending_remote_permit
755+
self.coordinator.acknowledge_delivery(self.token, pending)
756+
self._pending_remote_permit = None
726757

727758
def bind_approval(self, approval: ApprovalRecord) -> None:
728759
self.coordinator.bind_approval(self.token, approval)

openadapt_flow/runtime/replayer.py

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,7 @@ def __init__(
581581
self._durable_linear_snapshot: tuple[Any, ...] = ()
582582
self._durable_program_snapshot: tuple[ProgramCheckpoint, ...] = ()
583583
self._durable_pending_snapshot: Optional[Any] = None
584+
self._active_delivery_acknowledgers: tuple[Any, ...] = ()
584585
self._durable_continuation_guard: Optional[Any] = None
585586
# API/tool actuator -- the TOP of the capability ladder (RFC section 4
586587
# `api` tier). When set, a step carrying an `api_binding` has its write
@@ -1183,15 +1184,36 @@ def run(
11831184
):
11841185
from openadapt_flow.runtime.durable.authority import DurableAuthority
11851186

1187+
managed_durable_run = durable_run
1188+
11861189
class _ManagedInitialDeliveryGuard:
1190+
def __init__(self_nonlocal) -> None:
1191+
self_nonlocal.authority = DurableAuthority(
1192+
run_dir, managed_durable_run.store
1193+
)
1194+
self_nonlocal.pending_remote_permit: Any = None
1195+
11871196
def before_delivery(self_nonlocal) -> None:
1188-
assert durable_run is not None
1189-
DurableAuthority(
1190-
run_dir, durable_run.store
1191-
).before_initial_delivery(
1192-
durable_run._manifest # noqa: SLF001 - exact retained manifest
1197+
if self_nonlocal.pending_remote_permit is not None:
1198+
raise RuntimeError(
1199+
"a prior production delivery lacks an acknowledgment receipt"
1200+
)
1201+
self_nonlocal.pending_remote_permit = (
1202+
self_nonlocal.authority.before_initial_delivery(
1203+
managed_durable_run._manifest # noqa: SLF001 - exact retained manifest
1204+
)
11931205
)
11941206

1207+
def acknowledge_delivery(self_nonlocal) -> None:
1208+
pending = self_nonlocal.pending_remote_permit
1209+
if pending is None:
1210+
return
1211+
self_nonlocal.authority.acknowledge_remote_delivery(
1212+
managed_durable_run._manifest, # noqa: SLF001
1213+
pending,
1214+
)
1215+
self_nonlocal.pending_remote_permit = None
1216+
11951217
self._durable_initial_delivery_guard = _ManagedInitialDeliveryGuard()
11961218
(run_dir / "steps").mkdir(parents=True, exist_ok=True)
11971219

@@ -8790,8 +8812,8 @@ def _resolve_drag_end(
87908812
)
87918813
return resolution, region, error
87928814

8793-
@staticmethod
87948815
def _deliver_backend_call(
8816+
self,
87958817
result: StepResult,
87968818
call: Callable[[], _DeliveryResultT],
87978819
) -> _DeliveryResultT:
@@ -8804,6 +8826,8 @@ def _deliver_backend_call(
88048826
"""
88058827

88068828
attempted_before = result.delivery_attempted
8829+
acknowledgers = self._active_delivery_acknowledgers
8830+
self._active_delivery_acknowledgers = ()
88078831
try:
88088832
delivered = call()
88098833
except (FreshActuationRequired, StructuralResolutionRefused):
@@ -8813,6 +8837,8 @@ def _deliver_backend_call(
88138837
result.delivery_attempted = True
88148838
raise
88158839
result.delivery_attempted = True
8840+
for guard in acknowledgers:
8841+
guard.acknowledge_delivery()
88168842
return delivered
88178843

88188844
@staticmethod
@@ -9222,6 +9248,8 @@ def _delivery_authorization_refusal(
92229248
) -> Optional[str]:
92239249
"""Recheck exact authority at the last point before input delivery."""
92249250

9251+
self._active_delivery_acknowledgers = ()
9252+
acknowledgers: list[Any] = []
92259253
refusal = self._managed_dispatch_refusal()
92269254
if refusal is None:
92279255
refusal = self._fresh_actuation_authorization_refusal(
@@ -9231,6 +9259,7 @@ def _delivery_authorization_refusal(
92319259
if refusal is None and initial_guard is not None:
92329260
try:
92339261
initial_guard.before_delivery()
9262+
acknowledgers.append(initial_guard)
92349263
except Exception as exc: # noqa: BLE001 - durable fencing boundary
92359264
refusal = (
92369265
f"managed initial delivery was preempted before delivery: {exc}"
@@ -9239,6 +9268,7 @@ def _delivery_authorization_refusal(
92399268
if refusal is None and self._durable_continuation_guard is not None:
92409269
try:
92419270
self._durable_continuation_guard.before_delivery()
9271+
acknowledgers.append(self._durable_continuation_guard)
92429272
except Exception as exc: # noqa: BLE001 - durable fencing boundary
92439273
refusal = f"durable continuation was preempted before delivery: {exc}"
92449274
result.failure_category = "continuation_preempted"
@@ -9252,6 +9282,8 @@ def _delivery_authorization_refusal(
92529282
if self.governed_authorization is not None
92539283
else "safety_halt"
92549284
)
9285+
else:
9286+
self._active_delivery_acknowledgers = tuple(acknowledgers)
92559287
return refusal
92569288

92579289
def _act(
@@ -10731,6 +10763,9 @@ def _handle_interstitials(
1073110763
# well: every backend input edge must cross the same lease.
1073210764
try:
1073310765
self._durable_continuation_guard.before_delivery()
10766+
self._active_delivery_acknowledgers = (
10767+
self._durable_continuation_guard,
10768+
)
1073410769
except Exception as exc: # noqa: BLE001 - fencing boundary
1073510770
result.failure_category = "continuation_preempted"
1073610771
result.safety_halt = True

0 commit comments

Comments
 (0)