diff --git a/docs/sprints/2026-07-23.md b/docs/sprints/2026-07-23.md index 7065311a..6c234291 100644 --- a/docs/sprints/2026-07-23.md +++ b/docs/sprints/2026-07-23.md @@ -156,12 +156,34 @@ every flat alias still pointed at npm, so a Kotlin run's auto-gate would have ru own class, and routing dead-ends carry `gate="stage"` while every other path carries its real gate, so `"$gate:$signature"` can't collapse them. Locked in with a regression test rather than a rewrite. -**Goal 3 remaining:** #299 + #300 (provider-death path). #308 partly pre-empted by `ac460156` — a shell -timeout is now recoverable and coaches `nohup &` detach, so there is no background-process registry to -build unless a real gate needs one. +- **#299 ✅** (commit `c5289420`). `route()` now splits the two cases the old code conflated: a + capability **nobody was ever configured with** still fails fast, but a capability that *is* + configured whose candidates are all currently unhealthy gets a bounded wait (3 × 2s, each round + re-checking `refreshedHealth` rather than the TTL cache) before `NoEligibleProvider`. A crash-plus- + restart no longer collapses a retryable failure into a session kill. +- **#300 ✅** (commit `bf362527`). Made health *gating* instead of reactive: new + `InferenceRouter.reportFailure(providerId, reason)` (default no-op) writes `Unavailable` straight + into the health cache, bypassing `healthCheck()`/TTL, and `SessionOrchestrator.kt:454` calls it from + the inference catch when `isConnectionLevelFailure(e)`. The next `route()` sees the drop + immediately instead of ~18s later. Recovery needs no extra path — TTL expiry or #299's bounded-wait + re-check picks the provider back up. -**Goal 2 remaining:** #261 (impl decomposition), plus status calls on #260 and #305 — both have landed -commits (`516af1ca`; `5df35879`/`8806de16`/`12775d56`/`f5aaa255`) but neither ticket is closed. +**Goal 3 remaining:** none. #308 partly pre-empted by `ac460156` — a shell timeout is now recoverable +and coaches `nohup &` detach, so there is no background-process registry to build unless a real gate +needs one. + +**Goal 2 status calls — 2026-07-27.** +- **#260 ✅** (commit `516af1ca`). Both halves are in the prompts: `discovery.md` requires inspecting + the whole decision surface and batching *all* operator-only questions after inspection (no + stop-at-first-uncertainty), and `analyst_freestyle.md` makes the `dod` artifact the handoff contract + — atomic, yes/no-checkable criteria, plus one criterion carrying the named task into the impl plan + and one per material failure path. #3 (architect re-plans on better input) fell out for free. +- **#305 stays open.** Store 1 (Observations) shipped (`5df35879` et al) and is real, but Stores 2 + (fix lifecycle) and 3 (plan-shapes + discovery warm-start read path) are unbuilt — and Store 3 is + exactly what Goal 2's exit criterion ("discovery carries accreted knowledge from a prior run") + names. Not closable; carries past this sprint. +- **#261 blocked by #267, correctly.** Its own body defers it until the simpler pipeline is proven on + a clean end-to-end run — which is the #267 acceptance run. Do #267 first. ---