refactor(sse): extract combo dispatch prelude into combo/dispatchPrelude.ts - #8582
Merged
diegosouzapw merged 5 commits intoJul 27, 2026
Conversation
This was referenced Jul 25, 2026
Closed
MumuTW
force-pushed
the
refactor/combo-dispatch-prelude
branch
from
July 26, 2026 10:16
197f678 to
f851731
Compare
…ude.ts Pure move, no behaviour change. First of ~7 PRs decomposing the combo.ts god-file (diegosouzapw#3501). handleComboChat evaluates a series of dispatch branches before it ever reaches target resolution or the sequential attempt loop. None of them iterate targets in priority order or need the failover/retry/credential gate machinery that follows, so they move to a leaf: - context-cache pin routing (Fix diegosouzapw#679), including the pinIsDurablyUnhealthy / isPinnedModelDurablyUnhealthy health gate - fusion panel dispatch + the diegosouzapw#6455 misconfiguration warn - pipeline chaining - nested combo-ref execute-mode runtime-unit dispatch Only the chaos and round-robin hand-offs stay inline (11 and 13 lines); extracting those would be pure indirection. open-sse/services/combo.ts 3642 -> 3341 (-301) open-sse/services/combo/dispatchPrelude.ts: 619 (under the 800 cap) Each helper keeps the fall-through protocol the inline blocks had: return a Response to OWN the request, return null to fall through. A flipped null/Response would silently bypass the whole combo strategy, so the new tests pin both directions for every branch. combo.ts re-exports pinIsDurablyUnhealthy so combo-pin-health-gate.test.ts keeps resolving. The leaf takes handleComboChat as a `runCombo` parameter instead of importing it, so combo/ keeps zero back-edges into combo.ts. Complexity-neutral: the first cut added +3 violations (two max-lines-per-function, one complexity) inside the new leaf, so evaluatePinnedResponse, orderRuntimeUnits, recordRuntimeUnitStickySuccess and buildBaseOptions were split out. check:complexity now measures 2169 and check:cognitive-complexity 956 — identical to the pristine base.
…n testing An adversarial mutation audit of the suite added in the previous commit found it guarded the fall-through protocol well but asserted almost nothing about what the helpers do once they OWN the request. 5 of 12 seeded mutations survived. Worst case: deleting the pinned-model dispatch call outright left all 12 tests green. Three holes, now closed (8 tests -> 20): Hole A — the honored-pin path had zero coverage. Both existing pin tests DROP the pin, so the dispatch, the 200-but-empty quality gate, the [408, 429, 500, 502, 503, 504] failover list and the catch(pinErr) branch were unguarded — exactly the logic the 2026-06-21 / 2026-06-22 incident comments call load-bearing. Adds five tests over a seeded healthy provider connection so the pin is actually honored. Hole B — orderRuntimeUnits was only ever driven with `priority`, which is a no-op through it. Four of five strategy branches could be deleted with nothing failing. Adds round-robin rotation and weighted sticky ordering tests. Hole C — recordRuntimeUnitStickySuccess never did anything under test: both its guards need weighted/round-robin, so an early return changed nothing. Covered by the new sticky-batch test. Verified by re-running the mutations rather than assuming: all 7 that previously survived (delete-pin-dispatch, serve-despite-failed-quality, never-fail-over-on-transient, rr-counter-not-advanced, rotation-removed, weighted-sticky-skipped, sticky-recording-no-op) are now killed. The first sticky-batch test I wrote was itself vacuous — asserting "same unit twice" holds equally when the recording helper is stubbed out, since nothing advances the counter either. It now asserts the batch runs out and rotation resumes on the third dispatch, which is what actually distinguishes the two. Also restores API_KEY_SECRET in test.after; it was set at module load and never put back, inconsistent with the DATA_DIR handling beside it.
The combo sub-check of check:known-symbols asserts every canonical routing
strategy has a real dispatch branch. It scanned a hardcoded file list and
matched only `strategy === "..."`, so the prelude extraction tripped it twice:
[combo] 2 estratégia(s) canônica(s) sem branch de despacho em combo.ts:
✗ fusion
✗ pipeline
Both branches are still wired — they just moved to combo/dispatchPrelude.ts and
took the early-return guard form `if (strategy !== "fusion") return null;` that
extracting a branch into a `tryXDispatch()` leaf naturally produces.
Two changes, both extending existing precedent (the list already carries the
Block J leaves for the same reason):
- register combo/dispatchPrelude.ts in comboDispatchFiles
- widen the extractor to `strategy [!=]== "..."` so the inverted guard counts
Loose `==`/`!=` stay rejected, and no `handledNotCanonical` fallout: the gate
now reports 20 canonical strategies, all 20 via despacho.
check:mutation-test-coverage --strict failed once the known-symbols fix let
Fast Quality Gates advance to it:
✗ 2 covering unit test(s) across 2 module(s) are missing from
stryker.conf.json tap.testFiles
open-sse/services/combo/comboStructure.ts
open-sse/services/combo/rrState.ts
The new tests/unit/combo-dispatch-prelude.test.ts exercises both modules, and
both are already in stryker's mutate list, so without the registration its
mutant kills would not have counted toward the nightly mutation gate.
Note (unchanged, still out of scope): combo/dispatchPrelude.ts itself is not in
stryker's `mutate` list. Adding it would widen the nightly mutation surface,
which is a separate call from fixing this drift.
MumuTW
force-pushed
the
refactor/combo-dispatch-prelude
branch
from
July 27, 2026 04:40
f851731 to
afef8bf
Compare
diegosouzapw
added a commit
to MumuTW/OmniRoute
that referenced
this pull request
Jul 27, 2026
check-known-symbols.ts: the combo dispatch file list gained combo/dispatchPrelude.ts on the release side (diegosouzapw#8582, same extraction series) while this branch adds combo/targetResolution.ts. Both entries are needed — each extraction moved a set of `strategy === "..."` dispatch checks out of combo.ts, and the gate reads all of them to derive the handled-strategy set. Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
diegosouzapw
added a commit
that referenced
this pull request
Jul 27, 2026
…ution.ts (#8592) * refactor(sse): extract combo dispatch prelude into combo/dispatchPrelude.ts Pure move, no behaviour change. First of ~7 PRs decomposing the combo.ts god-file (#3501). handleComboChat evaluates a series of dispatch branches before it ever reaches target resolution or the sequential attempt loop. None of them iterate targets in priority order or need the failover/retry/credential gate machinery that follows, so they move to a leaf: - context-cache pin routing (Fix #679), including the pinIsDurablyUnhealthy / isPinnedModelDurablyUnhealthy health gate - fusion panel dispatch + the #6455 misconfiguration warn - pipeline chaining - nested combo-ref execute-mode runtime-unit dispatch Only the chaos and round-robin hand-offs stay inline (11 and 13 lines); extracting those would be pure indirection. open-sse/services/combo.ts 3642 -> 3341 (-301) open-sse/services/combo/dispatchPrelude.ts: 619 (under the 800 cap) Each helper keeps the fall-through protocol the inline blocks had: return a Response to OWN the request, return null to fall through. A flipped null/Response would silently bypass the whole combo strategy, so the new tests pin both directions for every branch. combo.ts re-exports pinIsDurablyUnhealthy so combo-pin-health-gate.test.ts keeps resolving. The leaf takes handleComboChat as a `runCombo` parameter instead of importing it, so combo/ keeps zero back-edges into combo.ts. Complexity-neutral: the first cut added +3 violations (two max-lines-per-function, one complexity) inside the new leaf, so evaluatePinnedResponse, orderRuntimeUnits, recordRuntimeUnitStickySuccess and buildBaseOptions were split out. check:complexity now measures 2169 and check:cognitive-complexity 956 — identical to the pristine base. * test(sse): close the dispatch-prelude coverage holes found by mutation testing An adversarial mutation audit of the suite added in the previous commit found it guarded the fall-through protocol well but asserted almost nothing about what the helpers do once they OWN the request. 5 of 12 seeded mutations survived. Worst case: deleting the pinned-model dispatch call outright left all 12 tests green. Three holes, now closed (8 tests -> 20): Hole A — the honored-pin path had zero coverage. Both existing pin tests DROP the pin, so the dispatch, the 200-but-empty quality gate, the [408, 429, 500, 502, 503, 504] failover list and the catch(pinErr) branch were unguarded — exactly the logic the 2026-06-21 / 2026-06-22 incident comments call load-bearing. Adds five tests over a seeded healthy provider connection so the pin is actually honored. Hole B — orderRuntimeUnits was only ever driven with `priority`, which is a no-op through it. Four of five strategy branches could be deleted with nothing failing. Adds round-robin rotation and weighted sticky ordering tests. Hole C — recordRuntimeUnitStickySuccess never did anything under test: both its guards need weighted/round-robin, so an early return changed nothing. Covered by the new sticky-batch test. Verified by re-running the mutations rather than assuming: all 7 that previously survived (delete-pin-dispatch, serve-despite-failed-quality, never-fail-over-on-transient, rr-counter-not-advanced, rotation-removed, weighted-sticky-skipped, sticky-recording-no-op) are now killed. The first sticky-batch test I wrote was itself vacuous — asserting "same unit twice" holds equally when the recording helper is stubbed out, since nothing advances the counter either. It now asserts the batch runs out and rotation resumes on the third dispatch, which is what actually distinguishes the two. Also restores API_KEY_SECRET in test.after; it was set at module load and never put back, inconsistent with the DATA_DIR handling beside it. * fix(ci): teach known-symbols gate the relocated fusion/pipeline dispatch The combo sub-check of check:known-symbols asserts every canonical routing strategy has a real dispatch branch. It scanned a hardcoded file list and matched only `strategy === "..."`, so the prelude extraction tripped it twice: [combo] 2 estratégia(s) canônica(s) sem branch de despacho em combo.ts: ✗ fusion ✗ pipeline Both branches are still wired — they just moved to combo/dispatchPrelude.ts and took the early-return guard form `if (strategy !== "fusion") return null;` that extracting a branch into a `tryXDispatch()` leaf naturally produces. Two changes, both extending existing precedent (the list already carries the Block J leaves for the same reason): - register combo/dispatchPrelude.ts in comboDispatchFiles - widen the extractor to `strategy [!=]== "..."` so the inverted guard counts Loose `==`/`!=` stay rejected, and no `handledNotCanonical` fallout: the gate now reports 20 canonical strategies, all 20 via despacho. * chore(ci): register combo-dispatch-prelude test in stryker tap.testFiles check:mutation-test-coverage --strict failed once the known-symbols fix let Fast Quality Gates advance to it: ✗ 2 covering unit test(s) across 2 module(s) are missing from stryker.conf.json tap.testFiles open-sse/services/combo/comboStructure.ts open-sse/services/combo/rrState.ts The new tests/unit/combo-dispatch-prelude.test.ts exercises both modules, and both are already in stryker's mutate list, so without the registration its mutant kills would not have counted toward the nightly mutation gate. Note (unchanged, still out of scope): combo/dispatchPrelude.ts itself is not in stryker's `mutate` list. Adding it would widen the nightly mutation surface, which is a separate call from fixing this drift. * docs(changelog): add fragment for #8582 combo dispatch prelude * refactor(sse): extract combo target resolution into combo/targetResolution.ts Pure move, no behaviour change. Lifts the target-resolution stage of handleComboChat — everything between the dispatch prelude and the attempt loop — into a new leaf, open-sse/services/combo/targetResolution.ts. Moved verbatim: provider-wildcard expansion, weighted step-group resolution + sticky-weighted eligibility, request-tag routing, the known-context-overflow early return, the smart/pipeline-enabled auto dispatch, auto-strategy ordering, per-strategy ordering, cache-strategy affinity, session stickiness, eval scores, request-compatibility + context-requirement filters, task-aware reordering, prompt-cache affinity, and the priority-strategy pre-screen. The three early exits become an { earlyResponse } result so the host decides to return them (same pattern as resolveAutoStrategyOrder). The values the attempt loop still reads — orderedTargets, stickyWeightedLimit, getWeightedStepKeyForTarget, the session-stickiness result and preScreenMap — are returned instead of closed over. Loop config (maxRetries, retryDelayMs, fallbackDelayMs, maxSetRetries, setRetryDelayMs) stays in combo.ts. buildAutoCandidates is dependency-injected because it lives in combo.ts, so the leaf keeps zero back-edges into its host. combo.ts 3640 -> 3321 lines; new leaf 484 lines (under the 800 cap). Part of the #3501 god-file decomposition campaign. * refactor(sse): split targetResolution into stage helpers, ratchet combo.ts file-size baseline Follow-up to the target-resolution extraction: the moved region landed as one 311-line function, which converted inline code inside the (already-violating) handleComboChat into a NEW separately-counted violating function — check:complexity 2169 -> 2171 and check:cognitive-complexity 956 -> 957. Split resolveComboTargetPipeline along its natural stage boundaries into 14 helpers (wildcard expansion, weighted eviction/eligibility/sticky-key/selection, step-key mapper, context-overflow response, pool-size log, smart-pipeline dispatch and its fall-through logger, strategy ordering, continuity filters, task-aware ordering, prompt-cache enablement/first-target protection/affinity stage). Each stage takes the previous stage's output and returns the next; still a pure move. The leaf now contributes ZERO complexity, max-lines-per-function and cognitive-complexity violations. Both ratchets are back at base 4053e23 values: check:complexity 2169, check:cognitive-complexity 956. (Both still print RED against their frozen ceilings 2130/951 — pre-existing base-red per #8580.) Also ratchets ONLY the open-sse/services/combo.ts entry in config/quality/file-size-baseline.json from 3642 to 3322, with a justification note in the file's existing style. No sweep of unrelated entries. * chore: stack targetResolution on dispatchPrelude tip, rebank + skills Rebased onto refactor/combo-dispatch-prelude. Keep both leaves in check-known-symbols. Regenerate file-size baseline; sync agent skills. * fix(sse): restore #8494 capability fail-closed after targetResolution extract Stacking targetResolution onto the dispatchPrelude tip dropped the #8488/#8494 compatFilterFailOpen wiring: hard capability filters emptied the pool into a generic 404 no_executable_targets, and fail-open never re-admitted the pool. Restore describeCapabilityFilterExhaustion earlyResponse in applyContinuityFilters and the matching round-robin path, then rebank the file-size baseline for tip growth the incomplete prior rebank missed. * fix(sse): realign model-lockout cooldown options with the post-#8254 type This branch predates #8254, which renamed the recordModelLockoutFailure option `exactCooldownVerified` -> `exactCooldownIsUpstreamReset` and changed combo.ts's predicate from `lockoutHintVerified` (#8393's `lockoutHintMs > 0`) to `lockoutHintMs > mlSettings.baseCooldownMs`. Rebasing onto the current tip brought the renamed type without updating these two call sites, so typecheck:core failed with TS2353 at both. Restores the base expression verbatim rather than re-wiring `lockoutHintVerified` under the new name. The base predicate is the correct one: selectLockoutCooldownMs returns the parsed hint ONLY when `lockoutHintMs > baseCooldownMs`, and otherwise returns 0 or a synthetic baseCooldownMs — so `lockoutHintMs > 0` would mark a synthetic cooldown as an upstream reset and let it bypass the #7940 maxCooldownMs cap, which is the bug #8254 fixed. --------- Co-authored-by: MumuTW <johnsxn.us@gmail.com> Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com> Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
Merged
HouMinXi
pushed a commit
to HouMinXi/OmniRoute
that referenced
this pull request
Aug 2, 2026
…ude.ts (diegosouzapw#8582) * refactor(sse): extract combo dispatch prelude into combo/dispatchPrelude.ts Pure move, no behaviour change. First of ~7 PRs decomposing the combo.ts god-file (diegosouzapw#3501). handleComboChat evaluates a series of dispatch branches before it ever reaches target resolution or the sequential attempt loop. None of them iterate targets in priority order or need the failover/retry/credential gate machinery that follows, so they move to a leaf: - context-cache pin routing (Fix diegosouzapw#679), including the pinIsDurablyUnhealthy / isPinnedModelDurablyUnhealthy health gate - fusion panel dispatch + the diegosouzapw#6455 misconfiguration warn - pipeline chaining - nested combo-ref execute-mode runtime-unit dispatch Only the chaos and round-robin hand-offs stay inline (11 and 13 lines); extracting those would be pure indirection. open-sse/services/combo.ts 3642 -> 3341 (-301) open-sse/services/combo/dispatchPrelude.ts: 619 (under the 800 cap) Each helper keeps the fall-through protocol the inline blocks had: return a Response to OWN the request, return null to fall through. A flipped null/Response would silently bypass the whole combo strategy, so the new tests pin both directions for every branch. combo.ts re-exports pinIsDurablyUnhealthy so combo-pin-health-gate.test.ts keeps resolving. The leaf takes handleComboChat as a `runCombo` parameter instead of importing it, so combo/ keeps zero back-edges into combo.ts. Complexity-neutral: the first cut added +3 violations (two max-lines-per-function, one complexity) inside the new leaf, so evaluatePinnedResponse, orderRuntimeUnits, recordRuntimeUnitStickySuccess and buildBaseOptions were split out. check:complexity now measures 2169 and check:cognitive-complexity 956 — identical to the pristine base. * test(sse): close the dispatch-prelude coverage holes found by mutation testing An adversarial mutation audit of the suite added in the previous commit found it guarded the fall-through protocol well but asserted almost nothing about what the helpers do once they OWN the request. 5 of 12 seeded mutations survived. Worst case: deleting the pinned-model dispatch call outright left all 12 tests green. Three holes, now closed (8 tests -> 20): Hole A — the honored-pin path had zero coverage. Both existing pin tests DROP the pin, so the dispatch, the 200-but-empty quality gate, the [408, 429, 500, 502, 503, 504] failover list and the catch(pinErr) branch were unguarded — exactly the logic the 2026-06-21 / 2026-06-22 incident comments call load-bearing. Adds five tests over a seeded healthy provider connection so the pin is actually honored. Hole B — orderRuntimeUnits was only ever driven with `priority`, which is a no-op through it. Four of five strategy branches could be deleted with nothing failing. Adds round-robin rotation and weighted sticky ordering tests. Hole C — recordRuntimeUnitStickySuccess never did anything under test: both its guards need weighted/round-robin, so an early return changed nothing. Covered by the new sticky-batch test. Verified by re-running the mutations rather than assuming: all 7 that previously survived (delete-pin-dispatch, serve-despite-failed-quality, never-fail-over-on-transient, rr-counter-not-advanced, rotation-removed, weighted-sticky-skipped, sticky-recording-no-op) are now killed. The first sticky-batch test I wrote was itself vacuous — asserting "same unit twice" holds equally when the recording helper is stubbed out, since nothing advances the counter either. It now asserts the batch runs out and rotation resumes on the third dispatch, which is what actually distinguishes the two. Also restores API_KEY_SECRET in test.after; it was set at module load and never put back, inconsistent with the DATA_DIR handling beside it. * fix(ci): teach known-symbols gate the relocated fusion/pipeline dispatch The combo sub-check of check:known-symbols asserts every canonical routing strategy has a real dispatch branch. It scanned a hardcoded file list and matched only `strategy === "..."`, so the prelude extraction tripped it twice: [combo] 2 estratégia(s) canônica(s) sem branch de despacho em combo.ts: ✗ fusion ✗ pipeline Both branches are still wired — they just moved to combo/dispatchPrelude.ts and took the early-return guard form `if (strategy !== "fusion") return null;` that extracting a branch into a `tryXDispatch()` leaf naturally produces. Two changes, both extending existing precedent (the list already carries the Block J leaves for the same reason): - register combo/dispatchPrelude.ts in comboDispatchFiles - widen the extractor to `strategy [!=]== "..."` so the inverted guard counts Loose `==`/`!=` stay rejected, and no `handledNotCanonical` fallout: the gate now reports 20 canonical strategies, all 20 via despacho. * chore(ci): register combo-dispatch-prelude test in stryker tap.testFiles check:mutation-test-coverage --strict failed once the known-symbols fix let Fast Quality Gates advance to it: ✗ 2 covering unit test(s) across 2 module(s) are missing from stryker.conf.json tap.testFiles open-sse/services/combo/comboStructure.ts open-sse/services/combo/rrState.ts The new tests/unit/combo-dispatch-prelude.test.ts exercises both modules, and both are already in stryker's mutate list, so without the registration its mutant kills would not have counted toward the nightly mutation gate. Note (unchanged, still out of scope): combo/dispatchPrelude.ts itself is not in stryker's `mutate` list. Adding it would widen the nightly mutation surface, which is a separate call from fixing this drift. * docs(changelog): add fragment for diegosouzapw#8582 combo dispatch prelude
HouMinXi
pushed a commit
to HouMinXi/OmniRoute
that referenced
this pull request
Aug 2, 2026
…ution.ts (diegosouzapw#8592) * refactor(sse): extract combo dispatch prelude into combo/dispatchPrelude.ts Pure move, no behaviour change. First of ~7 PRs decomposing the combo.ts god-file (diegosouzapw#3501). handleComboChat evaluates a series of dispatch branches before it ever reaches target resolution or the sequential attempt loop. None of them iterate targets in priority order or need the failover/retry/credential gate machinery that follows, so they move to a leaf: - context-cache pin routing (Fix diegosouzapw#679), including the pinIsDurablyUnhealthy / isPinnedModelDurablyUnhealthy health gate - fusion panel dispatch + the diegosouzapw#6455 misconfiguration warn - pipeline chaining - nested combo-ref execute-mode runtime-unit dispatch Only the chaos and round-robin hand-offs stay inline (11 and 13 lines); extracting those would be pure indirection. open-sse/services/combo.ts 3642 -> 3341 (-301) open-sse/services/combo/dispatchPrelude.ts: 619 (under the 800 cap) Each helper keeps the fall-through protocol the inline blocks had: return a Response to OWN the request, return null to fall through. A flipped null/Response would silently bypass the whole combo strategy, so the new tests pin both directions for every branch. combo.ts re-exports pinIsDurablyUnhealthy so combo-pin-health-gate.test.ts keeps resolving. The leaf takes handleComboChat as a `runCombo` parameter instead of importing it, so combo/ keeps zero back-edges into combo.ts. Complexity-neutral: the first cut added +3 violations (two max-lines-per-function, one complexity) inside the new leaf, so evaluatePinnedResponse, orderRuntimeUnits, recordRuntimeUnitStickySuccess and buildBaseOptions were split out. check:complexity now measures 2169 and check:cognitive-complexity 956 — identical to the pristine base. * test(sse): close the dispatch-prelude coverage holes found by mutation testing An adversarial mutation audit of the suite added in the previous commit found it guarded the fall-through protocol well but asserted almost nothing about what the helpers do once they OWN the request. 5 of 12 seeded mutations survived. Worst case: deleting the pinned-model dispatch call outright left all 12 tests green. Three holes, now closed (8 tests -> 20): Hole A — the honored-pin path had zero coverage. Both existing pin tests DROP the pin, so the dispatch, the 200-but-empty quality gate, the [408, 429, 500, 502, 503, 504] failover list and the catch(pinErr) branch were unguarded — exactly the logic the 2026-06-21 / 2026-06-22 incident comments call load-bearing. Adds five tests over a seeded healthy provider connection so the pin is actually honored. Hole B — orderRuntimeUnits was only ever driven with `priority`, which is a no-op through it. Four of five strategy branches could be deleted with nothing failing. Adds round-robin rotation and weighted sticky ordering tests. Hole C — recordRuntimeUnitStickySuccess never did anything under test: both its guards need weighted/round-robin, so an early return changed nothing. Covered by the new sticky-batch test. Verified by re-running the mutations rather than assuming: all 7 that previously survived (delete-pin-dispatch, serve-despite-failed-quality, never-fail-over-on-transient, rr-counter-not-advanced, rotation-removed, weighted-sticky-skipped, sticky-recording-no-op) are now killed. The first sticky-batch test I wrote was itself vacuous — asserting "same unit twice" holds equally when the recording helper is stubbed out, since nothing advances the counter either. It now asserts the batch runs out and rotation resumes on the third dispatch, which is what actually distinguishes the two. Also restores API_KEY_SECRET in test.after; it was set at module load and never put back, inconsistent with the DATA_DIR handling beside it. * fix(ci): teach known-symbols gate the relocated fusion/pipeline dispatch The combo sub-check of check:known-symbols asserts every canonical routing strategy has a real dispatch branch. It scanned a hardcoded file list and matched only `strategy === "..."`, so the prelude extraction tripped it twice: [combo] 2 estratégia(s) canônica(s) sem branch de despacho em combo.ts: ✗ fusion ✗ pipeline Both branches are still wired — they just moved to combo/dispatchPrelude.ts and took the early-return guard form `if (strategy !== "fusion") return null;` that extracting a branch into a `tryXDispatch()` leaf naturally produces. Two changes, both extending existing precedent (the list already carries the Block J leaves for the same reason): - register combo/dispatchPrelude.ts in comboDispatchFiles - widen the extractor to `strategy [!=]== "..."` so the inverted guard counts Loose `==`/`!=` stay rejected, and no `handledNotCanonical` fallout: the gate now reports 20 canonical strategies, all 20 via despacho. * chore(ci): register combo-dispatch-prelude test in stryker tap.testFiles check:mutation-test-coverage --strict failed once the known-symbols fix let Fast Quality Gates advance to it: ✗ 2 covering unit test(s) across 2 module(s) are missing from stryker.conf.json tap.testFiles open-sse/services/combo/comboStructure.ts open-sse/services/combo/rrState.ts The new tests/unit/combo-dispatch-prelude.test.ts exercises both modules, and both are already in stryker's mutate list, so without the registration its mutant kills would not have counted toward the nightly mutation gate. Note (unchanged, still out of scope): combo/dispatchPrelude.ts itself is not in stryker's `mutate` list. Adding it would widen the nightly mutation surface, which is a separate call from fixing this drift. * docs(changelog): add fragment for diegosouzapw#8582 combo dispatch prelude * refactor(sse): extract combo target resolution into combo/targetResolution.ts Pure move, no behaviour change. Lifts the target-resolution stage of handleComboChat — everything between the dispatch prelude and the attempt loop — into a new leaf, open-sse/services/combo/targetResolution.ts. Moved verbatim: provider-wildcard expansion, weighted step-group resolution + sticky-weighted eligibility, request-tag routing, the known-context-overflow early return, the smart/pipeline-enabled auto dispatch, auto-strategy ordering, per-strategy ordering, cache-strategy affinity, session stickiness, eval scores, request-compatibility + context-requirement filters, task-aware reordering, prompt-cache affinity, and the priority-strategy pre-screen. The three early exits become an { earlyResponse } result so the host decides to return them (same pattern as resolveAutoStrategyOrder). The values the attempt loop still reads — orderedTargets, stickyWeightedLimit, getWeightedStepKeyForTarget, the session-stickiness result and preScreenMap — are returned instead of closed over. Loop config (maxRetries, retryDelayMs, fallbackDelayMs, maxSetRetries, setRetryDelayMs) stays in combo.ts. buildAutoCandidates is dependency-injected because it lives in combo.ts, so the leaf keeps zero back-edges into its host. combo.ts 3640 -> 3321 lines; new leaf 484 lines (under the 800 cap). Part of the diegosouzapw#3501 god-file decomposition campaign. * refactor(sse): split targetResolution into stage helpers, ratchet combo.ts file-size baseline Follow-up to the target-resolution extraction: the moved region landed as one 311-line function, which converted inline code inside the (already-violating) handleComboChat into a NEW separately-counted violating function — check:complexity 2169 -> 2171 and check:cognitive-complexity 956 -> 957. Split resolveComboTargetPipeline along its natural stage boundaries into 14 helpers (wildcard expansion, weighted eviction/eligibility/sticky-key/selection, step-key mapper, context-overflow response, pool-size log, smart-pipeline dispatch and its fall-through logger, strategy ordering, continuity filters, task-aware ordering, prompt-cache enablement/first-target protection/affinity stage). Each stage takes the previous stage's output and returns the next; still a pure move. The leaf now contributes ZERO complexity, max-lines-per-function and cognitive-complexity violations. Both ratchets are back at base d408a20 values: check:complexity 2169, check:cognitive-complexity 956. (Both still print RED against their frozen ceilings 2130/951 — pre-existing base-red per diegosouzapw#8580.) Also ratchets ONLY the open-sse/services/combo.ts entry in config/quality/file-size-baseline.json from 3642 to 3322, with a justification note in the file's existing style. No sweep of unrelated entries. * chore: stack targetResolution on dispatchPrelude tip, rebank + skills Rebased onto refactor/combo-dispatch-prelude. Keep both leaves in check-known-symbols. Regenerate file-size baseline; sync agent skills. * fix(sse): restore diegosouzapw#8494 capability fail-closed after targetResolution extract Stacking targetResolution onto the dispatchPrelude tip dropped the diegosouzapw#8488/diegosouzapw#8494 compatFilterFailOpen wiring: hard capability filters emptied the pool into a generic 404 no_executable_targets, and fail-open never re-admitted the pool. Restore describeCapabilityFilterExhaustion earlyResponse in applyContinuityFilters and the matching round-robin path, then rebank the file-size baseline for tip growth the incomplete prior rebank missed. * fix(sse): realign model-lockout cooldown options with the post-diegosouzapw#8254 type This branch predates diegosouzapw#8254, which renamed the recordModelLockoutFailure option `exactCooldownVerified` -> `exactCooldownIsUpstreamReset` and changed combo.ts's predicate from `lockoutHintVerified` (diegosouzapw#8393's `lockoutHintMs > 0`) to `lockoutHintMs > mlSettings.baseCooldownMs`. Rebasing onto the current tip brought the renamed type without updating these two call sites, so typecheck:core failed with TS2353 at both. Restores the base expression verbatim rather than re-wiring `lockoutHintVerified` under the new name. The base predicate is the correct one: selectLockoutCooldownMs returns the parsed hint ONLY when `lockoutHintMs > baseCooldownMs`, and otherwise returns 0 or a synthetic baseCooldownMs — so `lockoutHintMs > 0` would mark a synthetic cooldown as an upstream reset and let it bypass the diegosouzapw#7940 maxCooldownMs cap, which is the bug diegosouzapw#8254 fixed. --------- Co-authored-by: MumuTW <johnsxn.us@gmail.com> Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com> Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
…ude.ts (diegosouzapw#8582) * refactor(sse): extract combo dispatch prelude into combo/dispatchPrelude.ts Pure move, no behaviour change. First of ~7 PRs decomposing the combo.ts god-file (diegosouzapw#3501). handleComboChat evaluates a series of dispatch branches before it ever reaches target resolution or the sequential attempt loop. None of them iterate targets in priority order or need the failover/retry/credential gate machinery that follows, so they move to a leaf: - context-cache pin routing (Fix diegosouzapw#679), including the pinIsDurablyUnhealthy / isPinnedModelDurablyUnhealthy health gate - fusion panel dispatch + the diegosouzapw#6455 misconfiguration warn - pipeline chaining - nested combo-ref execute-mode runtime-unit dispatch Only the chaos and round-robin hand-offs stay inline (11 and 13 lines); extracting those would be pure indirection. open-sse/services/combo.ts 3642 -> 3341 (-301) open-sse/services/combo/dispatchPrelude.ts: 619 (under the 800 cap) Each helper keeps the fall-through protocol the inline blocks had: return a Response to OWN the request, return null to fall through. A flipped null/Response would silently bypass the whole combo strategy, so the new tests pin both directions for every branch. combo.ts re-exports pinIsDurablyUnhealthy so combo-pin-health-gate.test.ts keeps resolving. The leaf takes handleComboChat as a `runCombo` parameter instead of importing it, so combo/ keeps zero back-edges into combo.ts. Complexity-neutral: the first cut added +3 violations (two max-lines-per-function, one complexity) inside the new leaf, so evaluatePinnedResponse, orderRuntimeUnits, recordRuntimeUnitStickySuccess and buildBaseOptions were split out. check:complexity now measures 2169 and check:cognitive-complexity 956 — identical to the pristine base. * test(sse): close the dispatch-prelude coverage holes found by mutation testing An adversarial mutation audit of the suite added in the previous commit found it guarded the fall-through protocol well but asserted almost nothing about what the helpers do once they OWN the request. 5 of 12 seeded mutations survived. Worst case: deleting the pinned-model dispatch call outright left all 12 tests green. Three holes, now closed (8 tests -> 20): Hole A — the honored-pin path had zero coverage. Both existing pin tests DROP the pin, so the dispatch, the 200-but-empty quality gate, the [408, 429, 500, 502, 503, 504] failover list and the catch(pinErr) branch were unguarded — exactly the logic the 2026-06-21 / 2026-06-22 incident comments call load-bearing. Adds five tests over a seeded healthy provider connection so the pin is actually honored. Hole B — orderRuntimeUnits was only ever driven with `priority`, which is a no-op through it. Four of five strategy branches could be deleted with nothing failing. Adds round-robin rotation and weighted sticky ordering tests. Hole C — recordRuntimeUnitStickySuccess never did anything under test: both its guards need weighted/round-robin, so an early return changed nothing. Covered by the new sticky-batch test. Verified by re-running the mutations rather than assuming: all 7 that previously survived (delete-pin-dispatch, serve-despite-failed-quality, never-fail-over-on-transient, rr-counter-not-advanced, rotation-removed, weighted-sticky-skipped, sticky-recording-no-op) are now killed. The first sticky-batch test I wrote was itself vacuous — asserting "same unit twice" holds equally when the recording helper is stubbed out, since nothing advances the counter either. It now asserts the batch runs out and rotation resumes on the third dispatch, which is what actually distinguishes the two. Also restores API_KEY_SECRET in test.after; it was set at module load and never put back, inconsistent with the DATA_DIR handling beside it. * fix(ci): teach known-symbols gate the relocated fusion/pipeline dispatch The combo sub-check of check:known-symbols asserts every canonical routing strategy has a real dispatch branch. It scanned a hardcoded file list and matched only `strategy === "..."`, so the prelude extraction tripped it twice: [combo] 2 estratégia(s) canônica(s) sem branch de despacho em combo.ts: ✗ fusion ✗ pipeline Both branches are still wired — they just moved to combo/dispatchPrelude.ts and took the early-return guard form `if (strategy !== "fusion") return null;` that extracting a branch into a `tryXDispatch()` leaf naturally produces. Two changes, both extending existing precedent (the list already carries the Block J leaves for the same reason): - register combo/dispatchPrelude.ts in comboDispatchFiles - widen the extractor to `strategy [!=]== "..."` so the inverted guard counts Loose `==`/`!=` stay rejected, and no `handledNotCanonical` fallout: the gate now reports 20 canonical strategies, all 20 via despacho. * chore(ci): register combo-dispatch-prelude test in stryker tap.testFiles check:mutation-test-coverage --strict failed once the known-symbols fix let Fast Quality Gates advance to it: ✗ 2 covering unit test(s) across 2 module(s) are missing from stryker.conf.json tap.testFiles open-sse/services/combo/comboStructure.ts open-sse/services/combo/rrState.ts The new tests/unit/combo-dispatch-prelude.test.ts exercises both modules, and both are already in stryker's mutate list, so without the registration its mutant kills would not have counted toward the nightly mutation gate. Note (unchanged, still out of scope): combo/dispatchPrelude.ts itself is not in stryker's `mutate` list. Adding it would widen the nightly mutation surface, which is a separate call from fixing this drift. * docs(changelog): add fragment for diegosouzapw#8582 combo dispatch prelude
muhamadgalihsaputra
pushed a commit
to niyatna/NiyatnaRoute
that referenced
this pull request
Sep 27, 2026
…ution.ts (diegosouzapw#8592) * refactor(sse): extract combo dispatch prelude into combo/dispatchPrelude.ts Pure move, no behaviour change. First of ~7 PRs decomposing the combo.ts god-file (diegosouzapw#3501). handleComboChat evaluates a series of dispatch branches before it ever reaches target resolution or the sequential attempt loop. None of them iterate targets in priority order or need the failover/retry/credential gate machinery that follows, so they move to a leaf: - context-cache pin routing (Fix diegosouzapw#679), including the pinIsDurablyUnhealthy / isPinnedModelDurablyUnhealthy health gate - fusion panel dispatch + the diegosouzapw#6455 misconfiguration warn - pipeline chaining - nested combo-ref execute-mode runtime-unit dispatch Only the chaos and round-robin hand-offs stay inline (11 and 13 lines); extracting those would be pure indirection. open-sse/services/combo.ts 3642 -> 3341 (-301) open-sse/services/combo/dispatchPrelude.ts: 619 (under the 800 cap) Each helper keeps the fall-through protocol the inline blocks had: return a Response to OWN the request, return null to fall through. A flipped null/Response would silently bypass the whole combo strategy, so the new tests pin both directions for every branch. combo.ts re-exports pinIsDurablyUnhealthy so combo-pin-health-gate.test.ts keeps resolving. The leaf takes handleComboChat as a `runCombo` parameter instead of importing it, so combo/ keeps zero back-edges into combo.ts. Complexity-neutral: the first cut added +3 violations (two max-lines-per-function, one complexity) inside the new leaf, so evaluatePinnedResponse, orderRuntimeUnits, recordRuntimeUnitStickySuccess and buildBaseOptions were split out. check:complexity now measures 2169 and check:cognitive-complexity 956 — identical to the pristine base. * test(sse): close the dispatch-prelude coverage holes found by mutation testing An adversarial mutation audit of the suite added in the previous commit found it guarded the fall-through protocol well but asserted almost nothing about what the helpers do once they OWN the request. 5 of 12 seeded mutations survived. Worst case: deleting the pinned-model dispatch call outright left all 12 tests green. Three holes, now closed (8 tests -> 20): Hole A — the honored-pin path had zero coverage. Both existing pin tests DROP the pin, so the dispatch, the 200-but-empty quality gate, the [408, 429, 500, 502, 503, 504] failover list and the catch(pinErr) branch were unguarded — exactly the logic the 2026-06-21 / 2026-06-22 incident comments call load-bearing. Adds five tests over a seeded healthy provider connection so the pin is actually honored. Hole B — orderRuntimeUnits was only ever driven with `priority`, which is a no-op through it. Four of five strategy branches could be deleted with nothing failing. Adds round-robin rotation and weighted sticky ordering tests. Hole C — recordRuntimeUnitStickySuccess never did anything under test: both its guards need weighted/round-robin, so an early return changed nothing. Covered by the new sticky-batch test. Verified by re-running the mutations rather than assuming: all 7 that previously survived (delete-pin-dispatch, serve-despite-failed-quality, never-fail-over-on-transient, rr-counter-not-advanced, rotation-removed, weighted-sticky-skipped, sticky-recording-no-op) are now killed. The first sticky-batch test I wrote was itself vacuous — asserting "same unit twice" holds equally when the recording helper is stubbed out, since nothing advances the counter either. It now asserts the batch runs out and rotation resumes on the third dispatch, which is what actually distinguishes the two. Also restores API_KEY_SECRET in test.after; it was set at module load and never put back, inconsistent with the DATA_DIR handling beside it. * fix(ci): teach known-symbols gate the relocated fusion/pipeline dispatch The combo sub-check of check:known-symbols asserts every canonical routing strategy has a real dispatch branch. It scanned a hardcoded file list and matched only `strategy === "..."`, so the prelude extraction tripped it twice: [combo] 2 estratégia(s) canônica(s) sem branch de despacho em combo.ts: ✗ fusion ✗ pipeline Both branches are still wired — they just moved to combo/dispatchPrelude.ts and took the early-return guard form `if (strategy !== "fusion") return null;` that extracting a branch into a `tryXDispatch()` leaf naturally produces. Two changes, both extending existing precedent (the list already carries the Block J leaves for the same reason): - register combo/dispatchPrelude.ts in comboDispatchFiles - widen the extractor to `strategy [!=]== "..."` so the inverted guard counts Loose `==`/`!=` stay rejected, and no `handledNotCanonical` fallout: the gate now reports 20 canonical strategies, all 20 via despacho. * chore(ci): register combo-dispatch-prelude test in stryker tap.testFiles check:mutation-test-coverage --strict failed once the known-symbols fix let Fast Quality Gates advance to it: ✗ 2 covering unit test(s) across 2 module(s) are missing from stryker.conf.json tap.testFiles open-sse/services/combo/comboStructure.ts open-sse/services/combo/rrState.ts The new tests/unit/combo-dispatch-prelude.test.ts exercises both modules, and both are already in stryker's mutate list, so without the registration its mutant kills would not have counted toward the nightly mutation gate. Note (unchanged, still out of scope): combo/dispatchPrelude.ts itself is not in stryker's `mutate` list. Adding it would widen the nightly mutation surface, which is a separate call from fixing this drift. * docs(changelog): add fragment for diegosouzapw#8582 combo dispatch prelude * refactor(sse): extract combo target resolution into combo/targetResolution.ts Pure move, no behaviour change. Lifts the target-resolution stage of handleComboChat — everything between the dispatch prelude and the attempt loop — into a new leaf, open-sse/services/combo/targetResolution.ts. Moved verbatim: provider-wildcard expansion, weighted step-group resolution + sticky-weighted eligibility, request-tag routing, the known-context-overflow early return, the smart/pipeline-enabled auto dispatch, auto-strategy ordering, per-strategy ordering, cache-strategy affinity, session stickiness, eval scores, request-compatibility + context-requirement filters, task-aware reordering, prompt-cache affinity, and the priority-strategy pre-screen. The three early exits become an { earlyResponse } result so the host decides to return them (same pattern as resolveAutoStrategyOrder). The values the attempt loop still reads — orderedTargets, stickyWeightedLimit, getWeightedStepKeyForTarget, the session-stickiness result and preScreenMap — are returned instead of closed over. Loop config (maxRetries, retryDelayMs, fallbackDelayMs, maxSetRetries, setRetryDelayMs) stays in combo.ts. buildAutoCandidates is dependency-injected because it lives in combo.ts, so the leaf keeps zero back-edges into its host. combo.ts 3640 -> 3321 lines; new leaf 484 lines (under the 800 cap). Part of the diegosouzapw#3501 god-file decomposition campaign. * refactor(sse): split targetResolution into stage helpers, ratchet combo.ts file-size baseline Follow-up to the target-resolution extraction: the moved region landed as one 311-line function, which converted inline code inside the (already-violating) handleComboChat into a NEW separately-counted violating function — check:complexity 2169 -> 2171 and check:cognitive-complexity 956 -> 957. Split resolveComboTargetPipeline along its natural stage boundaries into 14 helpers (wildcard expansion, weighted eviction/eligibility/sticky-key/selection, step-key mapper, context-overflow response, pool-size log, smart-pipeline dispatch and its fall-through logger, strategy ordering, continuity filters, task-aware ordering, prompt-cache enablement/first-target protection/affinity stage). Each stage takes the previous stage's output and returns the next; still a pure move. The leaf now contributes ZERO complexity, max-lines-per-function and cognitive-complexity violations. Both ratchets are back at base 54b4bf1 values: check:complexity 2169, check:cognitive-complexity 956. (Both still print RED against their frozen ceilings 2130/951 — pre-existing base-red per diegosouzapw#8580.) Also ratchets ONLY the open-sse/services/combo.ts entry in config/quality/file-size-baseline.json from 3642 to 3322, with a justification note in the file's existing style. No sweep of unrelated entries. * chore: stack targetResolution on dispatchPrelude tip, rebank + skills Rebased onto refactor/combo-dispatch-prelude. Keep both leaves in check-known-symbols. Regenerate file-size baseline; sync agent skills. * fix(sse): restore diegosouzapw#8494 capability fail-closed after targetResolution extract Stacking targetResolution onto the dispatchPrelude tip dropped the diegosouzapw#8488/diegosouzapw#8494 compatFilterFailOpen wiring: hard capability filters emptied the pool into a generic 404 no_executable_targets, and fail-open never re-admitted the pool. Restore describeCapabilityFilterExhaustion earlyResponse in applyContinuityFilters and the matching round-robin path, then rebank the file-size baseline for tip growth the incomplete prior rebank missed. * fix(sse): realign model-lockout cooldown options with the post-diegosouzapw#8254 type This branch predates diegosouzapw#8254, which renamed the recordModelLockoutFailure option `exactCooldownVerified` -> `exactCooldownIsUpstreamReset` and changed combo.ts's predicate from `lockoutHintVerified` (diegosouzapw#8393's `lockoutHintMs > 0`) to `lockoutHintMs > mlSettings.baseCooldownMs`. Rebasing onto the current tip brought the renamed type without updating these two call sites, so typecheck:core failed with TS2353 at both. Restores the base expression verbatim rather than re-wiring `lockoutHintVerified` under the new name. The base predicate is the correct one: selectLockoutCooldownMs returns the parsed hint ONLY when `lockoutHintMs > baseCooldownMs`, and otherwise returns 0 or a synthetic baseCooldownMs — so `lockoutHintMs > 0` would mark a synthetic cooldown as an upstream reset and let it bypass the diegosouzapw#7940 maxCooldownMs cap, which is the bug diegosouzapw#8254 fixed. --------- Co-authored-by: MumuTW <johnsxn.us@gmail.com> Co-authored-by: diegosouzapw <diegosouzapw@users.noreply.github.com> Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Pure move, no behaviour change. PR 1 of ~7 decomposing the
combo.tsgod-file (#3501).What moved
handleComboChatevaluates a series of dispatch branches before it reaches target resolution or the sequential attempt loop. None of them iterate targets in priority order, and none need the failover/retry/credential-gate machinery that follows — they either short-circuit to one model, fan out and synthesize, thread output → input, or dispatch pre-resolved runtime units. They now live in a leaf:pinIsDurablyUnhealthy/isPinnedModelDurablyUnhealthyhealth gatetryPinnedModelDispatchtryFusionDispatchtryPipelineDispatchtryRuntimeUnitDispatchOnly the chaos and round-robin hand-offs stay inline (11 and 13 lines) — extracting those would be pure indirection.
Why it is safe
Every helper keeps the fall-through protocol the inline blocks had: return a
Responseto OWN the request, returnnullto fall through to the next branch and ultimately to the normal combo machinery. A flippednull/Responsewould silently bypass the whole combo strategy, so the new tests pin both directions for every branch.Quirks were preserved deliberately, not cleaned up. In particular the pinned-model branch still emits its
dropping pin, using strategywarn on the path where the pin was honored but its response was rejected — that reads slightly off, but it is existing behaviour and this PR is not the place to change it.combo.tsre-exportspinIsDurablyUnhealthysotests/unit/combo-pin-health-gate.test.tskeeps resolving unchanged. The leaf takeshandleComboChatas arunComboparameter rather than importing it, socombo/keeps zero back-edges intocombo.ts.Complexity is neutral
The first cut added +3 violations inside the new leaf (two
max-lines-per-function, onecomplexity) — the same trap thephaseComboSetupextraction hit. Split outevaluatePinnedResponse,orderRuntimeUnits,recordRuntimeUnitStickySuccessandbuildBaseOptionsto bring it back to zero:4053e2314check:complexitycheck:cognitive-complexityBoth gates still report red against their frozen ceilings (2130 / 951) — that is the pre-existing base-red measured and documented in #8580, not this PR. Deliberately not rebaselining them here; that belongs to #8580.
Verification
Branched off
4053e2314rather than therelease/v3.8.49tip, since the tip is base-red.npm run typecheck:corenpm run lintnpm run check:cyclesopen-sse/servicesnode scripts/check/check-file-size.mjstests/unit/combo-dispatch-prelude.test.tstests/unit/*combo*npm run test:unitThe 5
test:unitfailures are inmodel-test-route.test.ts,ops-scripts.test.ts,services/ServiceSupervisor.test.tsandshared/machineId.test.ts(2). A further cascade of subtests inantigravity-oauth-postexchange-nonblocking.test.tsanddb-usageanalytics-split.test.tsreportscancelledByParentand lands in the 34 cancelled, not the 5 failed. None of these six files contains a single reference tocombo, and none is touched by this diff (git diff --name-only 4053e2314=combo.ts, the two new files, and the baseline). Theantigravity-oauth-postexchange-nonblockingfailures were independently reproduced on a pristine detached worktree at4053e2314, confirming they predate this branch.One earlier run of the combo batch showed an
ENOTEMPTYfailure in8332-combo-vision-fallback.test.ts— afs.rmSyncrace in itstest.afterhook when sibling files run concurrently, not an assertion. It passes in isolation and two full re-runs of the batch were clean.Tests
New
tests/unit/combo-dispatch-prelude.test.ts(20 tests) imports the leaf directly and asserts each helper's fall-through contract. It includes a positive control — execute mode + a simple strategy really does reachexecuteRuntimeUnitComboand recurse into the referenced combo — so thenullassertions cannot pass vacuously on a malformed combo-ref fixture. (They did, briefly: the first draft used{ comboRef: "leaf" }instead of{ kind: "combo-ref", comboName: "leaf" }.)On cycles — correcting my own claim
I originally cited
npm run check:cyclesas evidence that this refactor introduces no cycle. That was misleading. The gate's default roots aresrc/shared/components,src/lib/db,src/lib/compliance,open-sse/translator,open-sse/mcp-server—open-sse/servicesis not among them, so a green run says nothing about this directory. An adversarial reviewer caught this.Running it explicitly scoped, and comparing against a pristine detached worktree at the base commit:
4053e2314check-cycles open-sse/servicescombo.ts)dispatchPrelude.ts)So
open-sse/servicescarries a large pre-existing cyclic cluster that already includedcombo.ts, and the new leaf joins it — 8 of its imports (fusion.ts,pipeline.ts,combo/runtimeUnits.ts,combo/fusionPanel.ts,combo/comboStructure.ts,combo/rrState.ts,combo/validateQuality.ts,combo/comboPredicates.ts) are already members.What this does not mean is a new back-edge. No file under
combo/importscombo.ts— the leaf takeshandleComboChatby injection as arunComboparameter, and a grep for imports ofcombo.tsacrosscombo/*.tsreturns zero. No previously-acyclic pair became cyclic; one node joined a cluster that was already cyclic. Untangling that cluster is out of scope here and belongs with #3501's later phases.Mutation audit
The first version of the test file was put through an adversarial mutation audit. It guarded the fall-through protocol well, but 5 of 12 seeded mutations survived — it asserted almost nothing about what the helpers do once they OWN the request. The worst case: deleting the pinned-model dispatch call outright left all 12 tests green.
Three holes, closed in
0e5fa1f81(8 tests -> 20):[408, 429, 500, 502, 503, 504]failover list and thecatch (pinErr)branch were unguarded — precisely the logic the 2026-06-21 / 2026-06-22 incident comments call load-bearing. Five new tests run against a seeded healthy provider connection so the pin is genuinely honored.orderRuntimeUnitswas only ever driven withpriority, which is a no-op through it — four of its five strategy branches could be deleted with nothing failing. Added round-robin rotation and weighted sticky-ordering tests.recordRuntimeUnitStickySuccessnever did anything under test (both guards need weighted/round-robin), so an earlyreturnchanged nothing.Re-measured rather than assumed — all seven previously-surviving mutations are now killed:
rrCountersWorth recording: the first sticky-batch test I wrote was itself vacuous — "same unit served twice" holds equally when the recording helper is stubbed out, because then nothing advances the counter either. It now asserts the batch runs out and rotation resumes on the third dispatch, which is what actually separates the two cases.
Also restores
API_KEY_SECRETintest.after(it was set at module load and never put back, inconsistent with theDATA_DIRhandling on the line above).Note for follow-up:
dispatchPrelude.tsis not instryker.conf.json'smutatelist, so the nightly mutation gate would not have caught any of this. Out of scope here.CI gate fix (
check:known-symbols)First CI run failed
Fast Quality Gates:Real, and caused by this PR — though no dispatch was lost. The gate's combo sub-check
scans a hardcoded file list and matches only
strategy === "...", so it missed thebranches twice over: they moved to
combo/dispatchPrelude.ts, and extracting a branchinto a
tryXDispatch()leaf turns the condition into the early-return guardif (strategy !== "fusion") return null;.Two changes to
scripts/check/check-known-symbols.ts, both extending precedent alreadyin the file (the list carries the Block J leaves for the same reason):
combo/dispatchPrelude.tsincomboDispatchFilesstrategy [!=]== "..."so the inverted guard countsThe alternative — contorting the leaf back into a positive
===shape to satisfy aregex — would have re-introduced the nesting the extraction removed. Loose
==/!=stay rejected; two new tests in
tests/unit/check-known-symbols.test.tspin both thenew form and that rejection (35 → 37 tests, all green). Gate now reports 20 canonical
strategies, all 20 via despacho.
Base-red: the
Unit Tests fast-path (2/4)jobAlso red, and not this PR. Two tests in
tests/unit/serial/combo-quota-share-cooldown-wait-timing.test.ts:Reproduced byte-identical on a pristine detached worktree at the base
4053e2314—same two tests, same expected/actual pairs. Pre-existing.
Baseline
Ratcheted only the
combo.tsfrozen entry, 3642 → 3341, with a justification note.check:file-size --updatewould have swept 74 other files plus 17 test files — unrelated drift already present on the base — so that was reverted and left for the release captain's rebaseline.Stacking
Touches a region of
combo.tsdisjoint from the other in-flight branches (#8553fix/7847-combo-attempt-body-cow,refactor/combo-error-classifiers,chore/combo-predicates-extract) and from PR 2 of this campaign (refactor/combo-target-resolution), so the hunks should merge in any order.