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
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ Format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).

## [Unreleased]

### Changed
- fix(quorum): **the stall timer no longer uses byte count as evidence of liveness (STALL-TIMEOUT-03).** `<500 bytes → apply a tighter kill window` was a proxy for "this slot is hung", and a live multi-model quorum falsified it the hard way — by killing three of its own five voters mid-answer. `claude-1` (idle 90s → 90s window), `copilot-1` (idle 30s → 30s), and `claude-z-ai` (90s) were all producing correct output when the timer fired; their partial answers were recoverable from `unavail_message`. `codex-1` and `antigravity-1` survived not because they were faster but because they **stream**, so every chunk rearmed the timer. The discriminator was never byte count. Worse, deriving the window from `idle_timeout_ms` (the #385 fix) made that field do double duty as "how long may this model think before output" — and for most slots the configured value (30s/90s) is far *smaller* than real think time, while the caller had budgeted 300s. There are now two windows, one per failure mode: **before the first byte**, `ttfb_timeout_ms` (default 30s) — zero output is the only honest evidence of a hang, so fast-fail belongs there; **after the first byte**, the inter-chunk ceiling — `inter_chunk_ceiling_ms` if the slot declares one, else the caller's idle budget. `stall_timeout_ms` is kept as a legacy alias for the ceiling, since the values already in that field were measured against post-preamble silence, so no config surface is added. Live-verified: `claude-1` answers in 134s where it previously died at 90s. Measuring also corrected an assumption — the `claude` CLI **buffers** (zero bytes until well past 30s) rather than emitting a preamble like the z-ai/minimax/kimi routes, which is why TTFB is per-slot configurable and why the claude-family slots carry `ttfb_timeout_ms: 150000`. Ratified by quorum (3/3 unanimous, Round 1: codex-1, antigravity-1, claude-minimax) over the alternative of keeping #386 as shipped; debate at `.planning/quorum/debates/2026-08-07-stall-timer-design-decision-a-vs-b.md`.


## [0.44.3] - 2026-08-07 — Quorum stall-window derivation, no shipped user config, and migration/portability guards

Expand Down
Loading
Loading