mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-09 22:48:57 +02:00
Second overlapping-wave merge; resolutions compose intent: - TEST_ROOTS: ours is the superset (main also wired ios-qa/daemon/test; ours additionally has ios-qa/scripts + browser-skills). package.json 'test' keeps routing through the canonical strict runner. - gbrainAvailable: main fixed the same load-flake with a strictly better mechanism (memoized stat-based PATH scan, no subprocess at all) — theirs supersedes this branch's memoized-exec probe. Main also made the query timeout env-overridable (GSTACK_BRAIN_TIMEOUT_MS). - Model defaults: adopted main's lib/eval-model.ts abstraction (one resolution point, env-overridable per kind) and applied decision D1a inside it: capture defaults to Sonnet (Opus opt-in via explicit arg or GSTACK_EVAL_MODEL_CAPTURE); test pins updated to follow. - Parent watchdog: main's rewrite (named parameterized tick, driven deterministically by its test via __testInternals__, plus handoff suppression semantics from session persistence) supersedes this branch's env-tunable interval; adopted their server + test wholesale. - windows-free-tests: ours (curated bun run test:windows) — main's hand-list grew by one more file, which the curated runner subsumes automatically; that drift is the reason for D11. - context-skills 0-for-26 fix: both waves made the IDENTICAL fix; kept this branch's comment (carries the receipts). - .gitignore: main's superset (also ignores Package.resolved — their never-commit call; untracked the copy this branch had committed). Verified: 239-test merge battery green, watchdog 8/8, eval-model 5/5, actionlint clean, eval:select works. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
26 lines
1.3 KiB
TypeScript
26 lines
1.3 KiB
TypeScript
/** OV11: the host-neutral eval-model resolver's contract. */
|
|
import { describe, test, expect } from "bun:test";
|
|
import { resolveEvalModel } from "../lib/eval-model";
|
|
|
|
describe("resolveEvalModel", () => {
|
|
test("explicit argument wins over everything", () => {
|
|
expect(resolveEvalModel("capture", "my-model", { GSTACK_EVAL_MODEL: "x" } as never)).toBe("my-model");
|
|
});
|
|
test("per-kind env beats the global env", () => {
|
|
expect(resolveEvalModel("warmup", null, { GSTACK_EVAL_MODEL_WARMUP: "w", GSTACK_EVAL_MODEL: "g" } as never)).toBe("w");
|
|
});
|
|
test("global env beats the default", () => {
|
|
expect(resolveEvalModel("distill", null, { GSTACK_EVAL_MODEL: "g" } as never)).toBe("g");
|
|
});
|
|
test("defaults per kind", () => {
|
|
// capture defaults to Sonnet per D1a (2026-08 review): Opus is opt-in via
|
|
// explicit arg or GSTACK_EVAL_MODEL_CAPTURE.
|
|
expect(resolveEvalModel("capture", null, {} as never)).toBe("claude-sonnet-4-6");
|
|
expect(resolveEvalModel("warmup", null, {} as never)).toBe("claude-haiku-4-5");
|
|
expect(resolveEvalModel("distill", null, {} as never)).toBe("claude-haiku-4-5-20251001");
|
|
});
|
|
test("unknown kind throws instead of silently defaulting", () => {
|
|
expect(() => resolveEvalModel("banana" as never, null, {} as never)).toThrow();
|
|
});
|
|
});
|