search-with-proof group 4 + image: board, spend reservation, coordinator, search-task image

Board as immutable versioned blobs (coordinator sole writer); budget reserve/settle
before model calls; per-task and run caps; coordinator loop over an injected
executor; batch.py accepts a fixed allow-list of search variables; XSS browser
oracle; ousast-search-task image (Python, Node/TypeScript, PHP, Java 17, sqlite,
bwrap, chromium) built by CI. 103 tests on the host.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Marius Ciepluch
2026-10-05 14:26:43 +02:00
co-authored by Claude Opus 5.5
parent 6394ee473d
commit 4b38239f68
17 changed files with 1120 additions and 20 deletions
+67 -1
View File
@@ -10,6 +10,7 @@ failure is `AccountError` (the task is `failed` and the run starts nothing furth
from __future__ import annotations
from collections.abc import Mapping
from decimal import Decimal
from typing import Any, Protocol
from ..model.endpoint import Prices
@@ -251,5 +252,70 @@ class MeteredEmbeddingClient:
__all__ = [
"AccountError", "BudgetExhausted", "EmbeddingClient", "MeteredClient", "MeteredEmbeddingClient", "UnmeteredUsage", "cost_of",
"is_account_error", "prices_from",
"is_account_error", "prices_from", "SpendBudget", "SpendReservation",
] # fmt: skip
class SpendBudget:
"""Thread-safe pre-call admission. Share one instance across concurrent callers.
A caller must supply a genuine upper bound, including all tool-loop calls.
Reservations remain charged until settled or explicitly released on failure.
Existing MeteredClient callers retain their historical post-call metering.
"""
def __init__(self, cap: float, *, spent: float = 0.0) -> None:
from threading import Lock
self._lock = Lock()
self._cap = self._amount(cap)
self._spent = self._amount(spent)
if self._spent > self._cap:
raise ValueError("spend exceeds cap")
self._reserved = Decimal(0)
@staticmethod
def _amount(value: float) -> Decimal:
amount = Decimal(str(value))
if not amount.is_finite() or amount < 0:
raise ValueError("cost must be finite and nonnegative")
return amount
@property
def spent(self) -> float:
with self._lock:
return float(self._spent)
@property
def reserved(self) -> float:
with self._lock:
return float(self._reserved)
def reserve(self, max_cost: float) -> SpendReservation:
amount = self._amount(max_cost)
with self._lock:
if self._spent + self._reserved + amount > self._cap:
raise BudgetExhausted("spend reservation exceeds cap", usd=float(self._spent), calls=0)
self._reserved += amount
return SpendReservation(self, amount)
class SpendReservation:
def __init__(self, budget: SpendBudget, amount: Decimal) -> None:
self._budget, self._amount, self._active = budget, amount, True
def settle(self, actual: float) -> None:
amount = self._budget._amount(actual)
with self._budget._lock:
if not self._active:
raise ValueError("reservation already closed")
if amount > self._amount:
# Retain the reservation: a broken upper bound must fail closed.
raise ValueError("actual cost exceeds reservation")
self._budget._reserved -= self._amount
self._budget._spent += amount
self._active = False
def release(self) -> None:
self.settle(0)