You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
release(0.12.2): fresh execution_id per /check + chain-mode /gate cache
Bug-fix release layered on top of 0.12.1. No wire-format change;
both fixes are client-side only.
* BUG #4 -- check_workflow_budget() now sends a fresh uuidv7 as the
"execution_id" field on every /check call instead of reusing
workflow_id. The server's gate_reserve_v3 overwrites the field on
response anyway, but a client-side placeholder that collides
across calls confuses the v3 reservation binding on /track when
Transport.track_single() reaches the backend and the field is
stale -- exact symptom is 503 RESERVATION_NOT_FOUND per
CLAUDE.md section 29.
* BUG #5 -- new nullrun.runtime._GATE_CACHE (5s TTL, keyed on
(workflow_id, chain_id, model)) collapses consecutive /gate
calls from inside `with chain(...)` to a single roundtrip,
avoiding 100 /gate calls per 100-step agent loop. Single-shot
(Hard mode) callers MUST bypass the cache -- Hard mode's binary
allow -> block semantics would let a stale "allow" leak a
budget-exhausted call through. Opt-out via
NULLRUN_GATE_CACHE_DISABLE=1 for callers that want the legacy
always-roundtrip behaviour (used by live smoke tests per
docs/runbooks/budget-blue-green-smoke.sh).
Tests: 158 new lines in tests/test_v3_wire_contract.py covering
per-call execution_id uniqueness, uuidv7 format validation, and
the new cache data-structure invariants + opt-out cases.
Bumps __version__ + pyproject.toml to 0.12.2.
Bug-fix release. Two related correctness fixes layered on top of 0.12.1; no wire-format change.
14
+
15
+
### Fixed
16
+
17
+
-**BUG #4 — `/check` execution_id**: `check_workflow_budget()` now sends a fresh `uuidv7` as the `execution_id` field on every call, instead of reusing `workflow_id`. The backend's `gate_reserve_v3` overwrites the field with its own server-minted value on the response, but the previous behaviour could confuse the v3 reservation binding on `/track` when `track_single()` reached the backend — the same root cause as the four gaps 0.12.1 closed, from the client-side placeholder angle. (CLAUDE.md §29 §24 ownership.)
18
+
-**BUG #5 — chain-mode gate thrash**: new `nullrun.runtime._GATE_CACHE` (5s TTL, keyed on `(workflow_id, chain_id, model)`) collapses consecutive `/gate` calls from inside `with chain(...)` to a single roundtrip, avoiding 100 /gate calls per 100-step agent loop. Single-shot (Hard mode) callers bypass the cache — the gate legitimately flips allow→block between consecutive calls there, and a stale "allow" would leak a budget-exhausted call through. Opt-out via `NULLRUN_GATE_CACHE_DISABLE=1` for callers that want the legacy always-roundtrip behaviour (e.g. live smoke tests per `docs/runbooks/budget-blue-green-smoke.sh`).
19
+
20
+
### Added
21
+
22
+
- 158 lines of contract tests in `tests/test_v3_wire_contract.py`: `TestGateExecutionId` (per-call uniqueness + uuidv7 format validation) and `TestGateCache` (5 cache invariant + opt-out cases).
23
+
24
+
### Changed
25
+
26
+
-`__version__` bumped from 0.12.1 to 0.12.2.
27
+
28
+
11
29
## [0.12.1] - 2026-07-04
12
30
13
31
Bug-fix release. The v0.12.0 changelog claimed the SDK propagates the server-minted `execution_id` from /check to /track but the wiring was never shipped — the SDK still sent client-supplied ids on /track/batch and ignored `reservation_id` on /check responses (audit fix per memory `sdk-v3-migration-gaps`).
0 commit comments