Preserve fractional approval expiry through atomic consumption
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a140c4-354a-7823-8f0d-8f717397f786
This commit is contained in:
parent
3485415b82
commit
d40e842052
6 changed files with 271 additions and 6 deletions
|
|
@ -103,11 +103,11 @@ def utc_now(clock: Callable[[], datetime] | None = None) -> datetime:
|
|||
now = datetime.now(timezone.utc)
|
||||
if now.tzinfo is None:
|
||||
now = now.replace(tzinfo=timezone.utc)
|
||||
return now.astimezone(timezone.utc).replace(microsecond=0)
|
||||
return now.astimezone(timezone.utc)
|
||||
|
||||
|
||||
def iso(ts: datetime) -> str:
|
||||
return ts.astimezone(timezone.utc).replace(microsecond=0).isoformat()
|
||||
return ts.astimezone(timezone.utc).isoformat()
|
||||
|
||||
|
||||
def parse_iso(value: str) -> datetime:
|
||||
|
|
@ -768,7 +768,6 @@ class Engine:
|
|||
):
|
||||
raise Unprocessable("decision_id must be a non-empty string")
|
||||
conn = self._conn()
|
||||
now = iso(self.now())
|
||||
idempotent = False
|
||||
try:
|
||||
conn.execute("BEGIN IMMEDIATE")
|
||||
|
|
@ -794,7 +793,11 @@ class Engine:
|
|||
if row["status"] != "approved":
|
||||
conn.rollback()
|
||||
raise Conflict(f"cannot consume from status {row['status']}")
|
||||
if self.now() < parse_iso(row["not_before"]) or self.now() >= parse_iso(row["expires_at"]):
|
||||
# Lock acquisition can wait past a validity boundary. One post-lock
|
||||
# instant is authoritative for both the check and its durable proof.
|
||||
consumed_at = self.now()
|
||||
now = iso(consumed_at)
|
||||
if consumed_at < parse_iso(row["not_before"]) or consumed_at >= parse_iso(row["expires_at"]):
|
||||
conn.rollback()
|
||||
raise Conflict("cannot consume outside validity window")
|
||||
if row["human_control"]:
|
||||
|
|
@ -819,6 +822,7 @@ class Engine:
|
|||
"use",
|
||||
approval_id,
|
||||
actor=row["actor"],
|
||||
observed_at=consumed_at,
|
||||
extra={
|
||||
"binding_digest": row["binding_digest"],
|
||||
"binding": json.loads(row["binding_json"]),
|
||||
|
|
@ -911,13 +915,14 @@ class Engine:
|
|||
*,
|
||||
actor: str | None,
|
||||
extra: dict[str, Any] | None = None,
|
||||
observed_at: datetime | None = None,
|
||||
) -> str:
|
||||
if self.fail_outbox:
|
||||
raise StoreUnavailable("outbox insert failed")
|
||||
if event_class not in EVENT_CLASSES:
|
||||
raise Unprocessable(f"unknown event class {event_class}")
|
||||
event_id = str(uuid4())
|
||||
created = iso(self.now())
|
||||
created = iso(observed_at if observed_at is not None else self.now())
|
||||
resource = f"approval:{approval_id}" if approval_id else "approval-engine:heartbeat"
|
||||
details = {"class": event_class, **(extra or {})}
|
||||
if approval_id:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue