Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 28 additions & 0 deletions .trinity/seals/queen_QueenKeyFailover.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"built_by": "t27c-bootstrap@0.5.2+e1b4c32a0",
"closure": [],
"config": "gen=c,rust,verilog,zig;tests=zig",
"gen_hash_c": "sha256:5f77faa623af9084319268ddafac1350f178856731433e7102f0bf744eb13a26",
"gen_hash_rust": "sha256:6e01af71b3e0a39b2e9f4cd08f62b8f15214a63d6b86cd3a50cf85981adc7fb0",
"gen_hash_verilog": "sha256:e4ab6f3d2b3359c5d14d12f24e3a3e9b1db0a2a4e7c3b48b2bad8c0a989f330e",
"gen_hash_zig": "sha256:c3b7830aa44fdb41e3eb33cb2a3fb7ad70b8b80e914e36b8eeb16fbf5f134a27",
"module": "QueenKeyFailover",
"ring": 12,
"seal_schema": 2,
"sealed_at": "2026-10-17T15:49:19Z",
"sealed_by": "t27c-bootstrap@0.5.2",
"spec_hash": "sha256:822367357fc6b487c1c7fb7ac8369165e6a7e6636fd9b0dcafec29e9a6274301",
"spec_path": "specs/queen/key_failover.t27",
"tests": {
"failed": 0,
"failing": [],
"forced": false,
"passed": 9,
"total": 9,
"vacuous": 0
},
"toolchain": {
"test_runner": "sha256:1982ae948e24d00c5d221ccec12dfce1eb01204b53e37b0f857f93b16d64629d",
"zig": "0.16.0"
}
}
14 changes: 14 additions & 0 deletions docs/now/2026-10-17-key-failover.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# NOW -- key_failover.t27: a bee whose key is refused moves to another key, then another pool (2026-10-17)

## specs/queen/key_failover.t27 (Closes #9993, part of #9976)

- Measured in the Railway logs, 2026-10-17 13:00-15:18Z: 17 of 93 bee turns on trios-bee-runner-2 ended after 0 steps.
- At least 22 of them were z.ai 429 code 1305 (temporary overload), 16 in one minute at 14:08.
- The cause: a bee is pinned to one key at dispatch, the SDK retries that key three times, and 33 other keys in two pools stand by.
- `error_kind()` classifies a refusal as transient, quota, auth or a bad request. The z.ai code wins over the HTTP status.
- `cooldown_seconds()` rests a transiently refused key for 15 s, doubled per strike, at most 240 s. A quota or auth refusal closes the key for 30 min.
- `next_free()` picks the next free key and never the one that just failed. `pool_overloaded()` moves to the next pool once 3 distinct keys said 1305.
- `step()` bounds a turn at 8 attempts. `charges_issue()` charges only a bad request, so an overloaded provider never retires the issue.
- Railway lab, `t27c test-report`: 9 tests, 112 runtime asserts, 0 FAIL, 0 vacuous, 4 invariants.
- `tri mutate spec`: 92 of 93 mutants killed and 0 survived. The one hang is a mutant's own endless loop (`k = k`).
- Wiring into trios goes through `t27b ts` (#9994), not hand-written TypeScript.
Loading
Loading