Reserve provider requests inside the durable worker envelope
Some checks failed
Governed runtime contract / contract (push) Failing after 31s

Assistant: codex
Assistant-Model: gpt-5.6-luna
Assistant-Session: 01a07ff8-19d0-7820-b4d0-1353833cb7fc
This commit is contained in:
tegwick 2026-09-09 21:50:12 +02:00
parent 4ae245a88f
commit c30806b968
13 changed files with 1114 additions and 12 deletions

View file

@ -10,6 +10,7 @@ from pathlib import Path
root = Path("/work")
settings = json.loads((root / "case.json").read_text())
seen = []
guard_attempts = []
class Handler(http.server.BaseHTTPRequestHandler):
@ -47,7 +48,7 @@ class Handler(http.server.BaseHTTPRequestHandler):
self.wfile.write(b'{"input_tokens":100}')
return
message_number = sum("count_tokens" not in request["path"] for request in seen)
if settings["case"] == "tools" and message_number == 1:
if settings["case"] in ("tools", "guarded-tools") and message_number == 1:
blocks = [
{
"type": "tool_use",
@ -83,7 +84,9 @@ class Handler(http.server.BaseHTTPRequestHandler):
blocks = [{"type": "text", "text": "fixture complete"}]
stop = "end_turn"
usage = {
"input_tokens": 60000 if settings["case"] == "overrun" else 100,
"input_tokens": 60000
if settings["case"] in ("overrun", "guarded-overrun")
else 100,
"output_tokens": 0,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0,
@ -155,6 +158,104 @@ class Handler(http.server.BaseHTTPRequestHandler):
server = http.server.ThreadingHTTPServer(("127.0.0.1", 0), Handler)
threading.Thread(target=server.serve_forever, daemon=True).start()
gate = meter = None
route_token = "fixture-no-provider-secret"
base_url = "http://127.0.0.1:" + str(server.server_port)
if settings["case"].startswith("guarded-"):
from datetime import UTC, datetime, timedelta
from types import SimpleNamespace
from llm_connect.messages_gate import MessagesPolicy, MessagesServer, RequestRefused
from rein_aharness.request_admission import RequestLedger
from rein_aharness.spend_admission import SpendLedger, SpendPolicy
class ObservedPolicy(MessagesPolicy):
def validate(self, data, betas):
row = {
"fields": sorted(data),
"betas": betas,
"context_management": data.get("context_management"),
"thinking": data.get("thinking"),
"output_config": data.get("output_config"),
}
guard_attempts.append(row)
try:
value = super().validate(data, betas)
row["liability_microusd"] = value
return value
except RequestRefused as exc:
row["refusal"] = str(exc)
raise
# Synthetic accepted bounds ONLY, never a live price/FX/authority packet.
policy = ObservedPolicy(
"fixture:no-live-tariff",
"claude-sonnet-4-6",
200000,
32000,
3,
15,
allowed_betas=(
"claude-code-20250219",
"interleaved-thinking-2025-05-14",
"thinking-token-count-2026-05-13",
"context-management-2025-06-27",
"prompt-caching-scope-2026-01-05",
"effort-2025-11-24",
),
)
cap = "0.01" if settings["case"] == "guarded-overrun" else "5"
private = root / "private"
private.mkdir(mode=0o700)
now = datetime.now(UTC)
expiry = (now + timedelta(minutes=5)).isoformat()
parent_policy = SpendPolicy(
"1",
"fixture",
"fixture:no-live-authority",
(now - timedelta(minutes=1)).isoformat(),
expiry,
"UTC",
"fixture-worker",
"fixture-definition",
"/work/target",
"fixture",
"harness.fixture@1.0.0",
"a" * 64,
"b" * 64,
"fixture-grant",
cap,
cap,
4,
"1",
cap,
cap,
cap,
)
parent = SpendLedger(private / "spend.sqlite3", parent_policy)
parent.initialize()
meter = RequestLedger(parent)
meter.initialize()
parent.reserve(
SimpleNamespace(
id="fixture-run",
activity_definition_id="fixture-definition",
idempotency_key="fixture",
attempt=1,
)
)
route_token = meter.bind_route(
"fixture-run", policy.sha256, lease_id="fixture-lease", expires_at=expiry
)
gate = MessagesServer(
policy,
meter,
provider_key="fixture-owner-only-key",
upstream_url=base_url,
allow_test_http=True,
)
gate.start()
base_url = "http://127.0.0.1:" + str(gate.port)
(root / "target" / ".claude").mkdir(parents=True)
(root / "target" / ".claude" / "settings.json").write_text(
json.dumps(
@ -181,8 +282,8 @@ threading.Thread(target=server.serve_forever, daemon=True).start()
subprocess.run(["git", "init", "-q", str(root / "target")], check=True)
env = dict(
os.environ,
ANTHROPIC_BASE_URL="http://127.0.0.1:" + str(server.server_port),
ANTHROPIC_API_KEY="fixture-no-provider-secret",
ANTHROPIC_BASE_URL=base_url,
ANTHROPIC_API_KEY=route_token,
CLAUDE_CONFIG_DIR="/work/config",
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC="1",
DISABLE_AUTOUPDATER="1",
@ -222,7 +323,11 @@ try:
if (root / "target" / "result.txt").exists()
else None,
"network_namespace": os.readlink("/proc/self/ns/net"),
"guard_attempts": guard_attempts,
"request_reservations": meter.status() if meter else [],
}
print(json.dumps(output))
finally:
if gate:
gate.stop()
server.shutdown()

View file

@ -21,7 +21,9 @@ pytestmark = pytest.mark.skipif(
)
@pytest.mark.parametrize("case", ["overrun", "tools"])
@pytest.mark.parametrize(
"case", ["overrun", "tools", "guarded-overrun", "guarded-tools"]
)
def test_installed_cli_boundary(tmp_path, case):
binary = Path(
os.environ.get("REIN_CLAUDE_PROOF_BINARY") or shutil.which("claude") or ""
@ -31,7 +33,7 @@ def test_installed_cli_boundary(tmp_path, case):
"revalidate the fixture for this binary version before claiming the pinned proof"
)
adapter = AgenticClaudeCodeAdapter(workdir=tmp_path, model="claude-sonnet-4-6")
cap = 0.01 if case == "overrun" else 1
cap = 0.01 if case in ("overrun", "guarded-overrun") else 1
argv = adapter._build_command(
RunConfig(model_params={"max_budget_usd": cap, "max_turns": 4})
)
@ -45,6 +47,23 @@ def test_installed_cli_boundary(tmp_path, case):
shutil.copyfile(
Path(__file__).with_name("native_cli_fixture.py"), tmp_path / "fixture.py"
)
if case.startswith("guarded-"):
import llm_connect.messages_gate
import rein_aharness.request_admission
import rein_aharness.spend_admission
for package, modules in {
"llm_connect": [llm_connect.messages_gate],
"rein_aharness": [
rein_aharness.request_admission,
rein_aharness.spend_admission,
],
}.items():
target = tmp_path / package
target.mkdir()
(target / "__init__.py").write_text("")
for module in modules:
shutil.copyfile(module.__file__, target / Path(module.__file__).name)
command = [
"bwrap",
"--unshare-all",
@ -93,7 +112,9 @@ def test_installed_cli_boundary(tmp_path, case):
"/usr/bin/python3",
"/work/fixture.py",
]
proc = subprocess.run(command, capture_output=True, text=True, timeout=55, check=False)
proc = subprocess.run(
command, capture_output=True, text=True, timeout=55, check=False
)
assert proc.returncode == 0, proc.stderr[-1000:]
result = json.loads(proc.stdout)
assert result["network_namespace"] != os.readlink("/proc/self/ns/net")
@ -111,7 +132,20 @@ def test_installed_cli_boundary(tmp_path, case):
assert request["model"] == "claude-sonnet-4-6"
assert not request["ambient_context_loaded"]
terminal = result["terminal"]
if case == "overrun":
if case.startswith("guarded-"):
assert all("refusal" not in row for row in result["guard_attempts"]), (
json.dumps(result["guard_attempts"])
)
if case == "guarded-overrun":
assert result["guard_attempts"], result
assert all(
row.get("liability_microusd") == 1_080_000
for row in result["guard_attempts"]
), result
assert not requests and not result["request_reservations"]
assert result["returncode"] != 0 and terminal["is_error"]
assert terminal["total_cost_usd"] == 0
elif case == "overrun":
assert len(requests) == 1
assert proc.returncode == 0 and result["returncode"] == 1
assert terminal["subtype"] == "error_max_budget_usd"
@ -129,6 +163,15 @@ def test_installed_cli_boundary(tmp_path, case):
assert result["created_file"] == "fixture-created\n"
usage, cost = terminal_accounting(terminal, max_budget_usd=cap, max_turns=4)
assert usage["total_tokens"] > 0 and cost > 0
if case == "guarded-tools":
assert len(result["request_reservations"]) == 2
assert all(
row["state"] == "charged" for row in result["request_reservations"]
)
assert (
sum(row["liability_microusd"] for row in result["request_reservations"])
== 2_160_000
)
if output_dir := os.environ.get("REIN_CLAUDE_PROOF_OUTPUT"):
target = Path(output_dir)
target.mkdir(parents=True, exist_ok=True)

View file

@ -0,0 +1,313 @@
"""Real SQLite/HTTP, deterministic provider; no paid calls or credentials."""
import http.client
import http.server
import json
import threading
from concurrent.futures import ThreadPoolExecutor
from datetime import UTC, datetime, timedelta
import pytest
from llm_connect.messages_gate import MessagesPolicy, MessagesServer
from rein_aharness.request_admission import RequestLedger
from rein_aharness.spend_admission import SpendAdmissionError, SpendLedger
from test_spend_admission import ledger as ledger # shared private ledger fixture
from test_spend_admission import run, success
@pytest.fixture
def meter(ledger):
child = RequestLedger(ledger)
child.initialize()
ledger.reserve(run())
return child
@pytest.fixture
def policy():
return MessagesPolicy(
"fixture:not-live-tariff", "fixture-model", 1000, 1000, 1000, 1000
)
def route(meter, policy, **kwargs):
return meter.bind_route(
run().id,
policy.sha256,
lease_id="fixture-lease",
expires_at=(datetime.now(UTC) + timedelta(seconds=60)).isoformat(),
**kwargs,
)
def test_parent_capacity_no_refund_replay_and_reopen(meter, policy):
token = route(meter, policy)
receipt = meter.reserve_request(token, policy.sha256, 2_000_000)
with pytest.raises(SpendAdmissionError, match="unresolved"):
RequestLedger(meter.parent).reserve_request(token, policy.sha256, 1)
meter.complete_request(receipt, 10)
with pytest.raises(SpendAdmissionError, match="replay"):
meter.complete_request(receipt, 10)
second = meter.reserve_request(token, policy.sha256, 2_000_000)
meter.complete_request(second, 0)
with pytest.raises(SpendAdmissionError, match="capacity"):
meter.reserve_request(token, policy.sha256, 2_000_000)
assert sum(row["liability_microusd"] for row in meter.status()) == 4_000_000
assert meter.parent.status()["reservations"][0]["liability"] == 5_000_000
serialized = json.dumps(meter.status())
assert token not in serialized and "private prompt" not in serialized
def test_concurrent_admission_only_one_pending(meter, policy):
token = route(meter, policy)
def reserve(_):
try:
RequestLedger(
SpendLedger(meter.parent.path, meter.parent.policy)
).reserve_request(token, policy.sha256, 1_000_000)
return True
except SpendAdmissionError:
return False
with ThreadPoolExecutor(max_workers=8) as pool:
assert sum(pool.map(reserve, range(8))) == 1
assert len(meter.status()) == 1
def test_unknown_holds_parent_even_after_success_and_operator_closes(meter, policy):
token = route(meter, policy)
meter.reserve_request(token, policy.sha256, 100)
assert not meter.parent.observe(run().id, success(meter.parent, run()))
with pytest.raises(SpendAdmissionError, match="revoked"):
meter.reserve_request(token, policy.sha256, 100)
assert meter.parent.status()["reservations"][0]["state"] == "held"
meter.parent.reconcile(
run().id, cost_usd="1", receipt="audit:provider-stopped-final"
)
assert meter.status()[0]["state"] == "charged"
with pytest.raises(SpendAdmissionError):
meter.bind_route(
run().id,
policy.sha256,
lease_id="replacement",
expires_at="2098-01-01T00:00:00Z",
)
def test_unknown_terminal_revokes_and_known_overrun_freezes(meter, policy):
token = route(meter, policy)
receipt = meter.reserve_request(token, policy.sha256, 100)
with pytest.raises(SpendAdmissionError, match="breached"):
meter.complete_request(receipt, 6_000_000)
assert meter.parent.status()["breached"]
assert meter.parent.status()["reservations"][0]["liability"] == 6_000_000
assert not meter.parent.observe(run().id, {"evidence": {}})
assert not meter.request_active(receipt)
with pytest.raises(SpendAdmissionError):
meter.reserve_request(token, policy.sha256, 1)
def test_wrong_token_policy_expired_lease_and_revocation(meter, policy):
now = datetime.now(UTC)
token = meter.bind_route(
run().id,
policy.sha256,
lease_id="fixture",
expires_at=(now + timedelta(seconds=1)).isoformat(),
now=now,
)
for credential, digest in [("a" * 43, policy.sha256), (token, "b" * 64)]:
with pytest.raises(SpendAdmissionError):
meter.reserve_request(credential, digest, 1, now=now)
receipt = meter.reserve_request(token, policy.sha256, 1, now=now)
assert not meter.request_active(receipt, now=now + timedelta(seconds=2))
meter.revoke_route(run().id)
assert not meter.request_active(receipt, now=now + timedelta(seconds=2))
def stream_bytes(*, truncated=False, output=10):
events = [
{
"type": "message_start",
"message": {
"model": "fixture-model",
"usage": {
"input_tokens": 10,
"output_tokens": 0,
"cache_creation_input_tokens": 20,
"cache_read_input_tokens": 30,
},
},
},
{
"type": "message_delta",
"delta": {"stop_reason": "end_turn"},
"usage": {"output_tokens": output},
},
{"type": "message_stop"},
]
if truncated:
events.pop()
return "".join(
"event: " + e["type"] + "\ndata: " + json.dumps(e) + "\n\n" for e in events
).encode()
@pytest.fixture
def fake_provider():
seen = []
mode = {"status": 200, "truncated": False, "output": 10}
class Handler(http.server.BaseHTTPRequestHandler):
def log_message(self, *args):
pass
def do_POST(self):
body = self.rfile.read(int(self.headers["Content-Length"]))
seen.append(
{
"key": self.headers.get("x-api-key"),
"path": self.path,
"body": json.loads(body),
"authorization": self.headers.get("Authorization"),
}
)
response = stream_bytes(truncated=mode["truncated"], output=mode["output"])
self.send_response(mode["status"])
self.send_header("Content-Type", "text/event-stream")
self.send_header("Content-Length", str(len(response)))
self.end_headers()
if wait := mode.get("wait"):
mode["entered"].set()
wait.wait(5)
self.wfile.write(response)
server = http.server.ThreadingHTTPServer(("127.0.0.1", 0), Handler)
threading.Thread(target=server.serve_forever, daemon=True).start()
yield server, seen, mode
server.shutdown()
server.server_close()
@pytest.fixture
def gateway(meter, policy, fake_provider):
provider, seen, mode = fake_provider
token = route(meter, policy)
server = MessagesServer(
policy,
meter,
provider_key="dummy-owner-key",
upstream_url=f"http://127.0.0.1:{provider.server_port}",
allow_test_http=True,
)
server.start()
yield server, token, seen, mode
server.stop()
def request(gateway, **changes):
server, token, _, _ = gateway
body = {
"model": "fixture-model",
"max_tokens": 1000,
"stream": True,
"messages": [{"role": "user", "content": "private fixture prompt"}],
}
body.update(changes)
connection = http.client.HTTPConnection("127.0.0.1", server.port, timeout=5)
connection.request(
"POST",
"/v1/messages?beta=true",
json.dumps(body),
{"Content-Type": "application/json", "x-api-key": token},
)
response = connection.getresponse()
result = response.status, response.read()
connection.close()
return result
def test_transport_reserves_before_forward_and_preserves_parent(gateway, meter):
for _ in range(2):
assert request(gateway)[0] == 200
assert request(gateway)[0] == 400
assert len(gateway[2]) == 2
assert all(
r["key"] == "dummy-owner-key" and not r["authorization"] for r in gateway[2]
)
assert all(r["observed_microusd"] == 70000 for r in meter.status())
assert sum(r["liability_microusd"] for r in meter.status()) == 4_000_000
assert meter.parent.observe(run().id, success(meter.parent, run()))
assert request(gateway)[0] == 400 and len(gateway[2]) == 2
@pytest.mark.parametrize(
"changes",
[
{"max_tokens": True},
{"max_tokens": 1001},
{"max_tokens": 0},
{"max_tokens": 1.5},
{"model": "other-model"},
{"stream": False},
{"service_tier": "auto"},
{"tools": [{"type": "web_search_20250305", "name": "web_search"}]},
{
"messages": [
{
"role": "user",
"content": [
{
"type": "image",
"source": {"type": "url", "url": "https://example.com"},
}
],
}
]
},
{"context_management": {}},
{"cache_control": {"type": "unknown"}},
],
)
def test_unsupported_requests_never_forward(gateway, meter, changes):
assert request(gateway, **changes)[0] == 400
assert gateway[2] == [] and meter.status() == []
@pytest.mark.parametrize("failure", ["truncated", "429", "overrun"])
def test_uncertain_or_overrun_response_prevents_retry(gateway, meter, failure):
if failure == "truncated":
gateway[3]["truncated"] = True
if failure == "429":
gateway[3]["status"] = 429
if failure == "overrun":
gateway[3]["output"] = 6000
request(gateway)
assert request(gateway)[0] == 400
assert len(gateway[2]) == 1
assert meter.status()[0]["state"] == "held"
assert not meter.parent.observe(run().id, success(meter.parent, run()))
def test_inflight_lease_loss_holds_and_denies_concurrent_forward(gateway, meter):
gateway[3].update(wait=threading.Event(), entered=threading.Event())
with ThreadPoolExecutor() as pool:
first = pool.submit(request, gateway)
assert gateway[3]["entered"].wait(3)
assert request(gateway)[0] == 400
meter.revoke_route(run().id)
gateway[3]["wait"].set()
first.result(5)
assert len(gateway[2]) == 1 and meter.status()[0]["state"] == "held"
def test_missing_request_schema_never_recreates_parent(ledger, policy):
ledger.reserve(run())
meter = RequestLedger(ledger)
with pytest.raises(SpendAdmissionError):
route(meter, policy)
with pytest.raises(SpendAdmissionError, match="before dispatch"):
meter.initialize()
assert ledger.status()["reservations"][0]["state"] == "held"