From 5e8d7ae9aee128a648be2b0a652f9a301e776ebe Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Fri, 21 Aug 2026 17:22:17 -0700 Subject: [PATCH] FN-9190: Add invalid concurrency resolver regression coverage Cover invalid persisted maxConcurrent values across both public resolver entry points. - Add a shared matrix for zero, negative, non-finite, missing, and wrong-type values. - Verify effective ceilings remain finite and positive after fallback resolution. - Preserve binding and disabled worktree-limit behavior for every invalid value. Files changed: .../concurrency-capacity-resolver.test.ts | 68 +++++++++++++++++++++- 1 file changed, 66 insertions(+), 2 deletions(-) Fusion-Task-Id: FN-9190 Fusion-Task-Lineage: aeb0daad-8f03-4835-a218-f45448c66c33 Co-authored-by: Fusion (runfusion.ai) --- .../concurrency-capacity-resolver.test.ts | 68 ++++++++++++++++++- 1 file changed, 66 insertions(+), 2 deletions(-) diff --git a/packages/core/src/__tests__/concurrency-capacity-resolver.test.ts b/packages/core/src/__tests__/concurrency-capacity-resolver.test.ts index 8eb6ff2371..9d3116fc0f 100644 --- a/packages/core/src/__tests__/concurrency-capacity-resolver.test.ts +++ b/packages/core/src/__tests__/concurrency-capacity-resolver.test.ts @@ -7,6 +7,26 @@ import { resolveMaxConcurrentSetting, } from "../workflows/workflow-capacity.js"; +/* +FNXC:CapacityModel 2026-08-22-00:09: +FN-9189's surface audit requires invalid persisted maxConcurrent values to resolve identically through both exported entry points. Production callers use the effective ceiling, so this shared matrix protects it from leaking an invalid scalar after the fallback resolver sanitizes it. +*/ +const INVALID_MAX_CONCURRENT_CASES = [ + ["zero", 0], + ["negative", -3], + ["NaN", Number.NaN], + ["Infinity", Infinity], + ["-Infinity", -Infinity], + ["numeric string", "2"], + ["null", null], + ["undefined", undefined], + ["missing key", {}], +] as const; + +function invalidMaxConcurrentSettings(value: unknown) { + return (value !== null && typeof value === "object" ? value : { maxConcurrent: value }) as never; +} + describe("resolveEffectiveConcurrency", () => { it("uses shipped defaults for absent values", () => { expect(resolveEffectiveConcurrency(undefined)).toEqual({ @@ -17,8 +37,52 @@ describe("resolveEffectiveConcurrency", () => { }); }); - it.each([0, -3, Number.NaN, Infinity, "2", null])("rejects invalid maxConcurrent %j", (maxConcurrent) => { - expect(resolveMaxConcurrentSetting({ maxConcurrent } as never)).toBe(DEFAULT_PROJECT_SETTINGS.maxConcurrent); + it.each(INVALID_MAX_CONCURRENT_CASES)("falls back for invalid maxConcurrent: %s", (_label, value) => { + expect(resolveMaxConcurrentSetting(invalidMaxConcurrentSettings(value))).toBe(DEFAULT_PROJECT_SETTINGS.maxConcurrent); + }); + + it.each(INVALID_MAX_CONCURRENT_CASES)("returns a finite default effective ceiling for invalid maxConcurrent: %s", (_label, value) => { + const resolved = resolveEffectiveConcurrency(invalidMaxConcurrentSettings(value)); + + expect(resolved).toEqual({ + maxConcurrent: DEFAULT_PROJECT_SETTINGS.maxConcurrent, + worktreeLimit: DEFAULT_PROJECT_SETTINGS.maxWorktrees, + effectiveLimit: DEFAULT_PROJECT_SETTINGS.maxConcurrent, + bindingKnob: "maxConcurrent", + }); + expect(Number.isFinite(resolved.maxConcurrent)).toBe(true); + expect(resolved.maxConcurrent).toBeGreaterThan(0); + expect(Number.isFinite(resolved.effectiveLimit)).toBe(true); + expect(resolved.effectiveLimit).toBeGreaterThan(0); + }); + + it.each(INVALID_MAX_CONCURRENT_CASES)("keeps a binding worktree ceiling for invalid maxConcurrent: %s", (_label, value) => { + const resolved = resolveEffectiveConcurrency({ + ...invalidMaxConcurrentSettings(value), + maxWorktrees: 1, + worktreeLimitEnabled: true, + }); + + expect(resolved).toEqual({ + maxConcurrent: DEFAULT_PROJECT_SETTINGS.maxConcurrent, + worktreeLimit: 1, + effectiveLimit: 1, + bindingKnob: "maxWorktrees", + }); + }); + + it.each(INVALID_MAX_CONCURRENT_CASES)("removes the worktree ceiling when disabled for invalid maxConcurrent: %s", (_label, value) => { + const resolved = resolveEffectiveConcurrency({ + ...invalidMaxConcurrentSettings(value), + worktreeLimitEnabled: false, + }); + + expect(resolved).toEqual({ + maxConcurrent: DEFAULT_PROJECT_SETTINGS.maxConcurrent, + worktreeLimit: null, + effectiveLimit: DEFAULT_PROJECT_SETTINGS.maxConcurrent, + bindingKnob: "maxConcurrent", + }); }); it("honors configured values and names a binding worktree limit", () => {