Skip to content

Commit 4086122

Browse files
committed
Capture resolved CLI model and route slug through SLUG_MODEL
Adds RunConfig.resolvedModel, populated from the CLI's `system_init` event, so runs remain comparable across alias bumps even when the user selected an alias like `haiku`. Adds SLUG_MODEL alongside JUDGE_MODEL and switches slug.ts to use it, so the slug generator can move independently from the judge — slugs fall back gracefully and don't anchor historical comparisons.
1 parent 002666d commit 4086122

5 files changed

Lines changed: 20 additions & 1 deletion

File tree

src/server/runner.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,10 @@ export class Runner extends EventEmitter {
382382
},
383383
);
384384

385+
if (typeof raw.model === 'string' && raw.model.length > 0) {
386+
this.input.initialConfig.resolvedModel = raw.model;
387+
}
388+
385389
const memoryPaths = raw.memory_paths as Record<string, unknown> | undefined;
386390
const auto = memoryPaths?.auto;
387391
if (typeof auto !== 'string' || auto.length === 0) return;

src/server/slug.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { spawn } from 'node:child_process';
33
import { pathExists } from './fsUtil.js';
44
import { join } from 'node:path';
55
import { readdir } from 'node:fs/promises';
6+
import { SLUG_MODEL } from '@shared/constants.js';
67
import { log } from './log.js';
78

89
const MAX_SLUG_LENGTH = 32;
@@ -129,7 +130,7 @@ async function tryHaikuSlug(content: string, claudeBin: string): Promise<string
129130
'-p',
130131
prompt,
131132
'--model',
132-
'haiku',
133+
SLUG_MODEL,
133134
'--output-format',
134135
'json',
135136
'--tools',

src/shared/constants.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,12 @@ export const PROJECT_MARKERS = [
2626
// when a new Haiku ships and rebaselining is acceptable.
2727
export const JUDGE_MODEL = 'claude-haiku-4-5';
2828

29+
// Model used to auto-generate run-folder slugs from variant content. Kept
30+
// separate from JUDGE_MODEL so the slug generator can move independently —
31+
// slugs are non-critical (they fall back gracefully) and don't anchor any
32+
// historical comparison the way judge scores do.
33+
export const SLUG_MODEL = 'claude-haiku-4-5';
34+
2935
// Judge input budgets (plan § Judge flow step 2).
3036
export const JUDGE_PROMPT_CAP_BYTES = 4 * 1024;
3137
export const JUDGE_VARIANT_CAP_BYTES = 8 * 1024;

src/shared/schemas/run.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ export const RunConfigSchema = z.object({
2626
promptSha256: z.string(),
2727
prompt: z.string(),
2828
model: ModelIdSchema,
29+
// Concrete model identifier the CLI reports in its `system_init` event.
30+
// `model` above is what the user selected (often an alias like `haiku`);
31+
// this captures what actually ran, so reruns across an alias bump remain
32+
// comparable. Optional/nullable for back-compat with pre-existing configs.
33+
resolvedModel: z.string().nullable().optional(),
2934
mode: ModeSchema,
3035
status: RunStatusSchema,
3136
startedAt: z.string(),

test/runner.smoke.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,9 @@ await scenario('init.json: persisted with the system init payload', async () =>
485485
if (typeof init.session_id !== 'string' || !init.session_id.startsWith('fake-')) {
486486
throw new Error(`init.json session_id unexpected: ${init.session_id}`);
487487
}
488+
if (final.resolvedModel !== 'haiku') {
489+
throw new Error(`expected resolvedModel='haiku', got ${final.resolvedModel}`);
490+
}
488491
});
489492
});
490493

0 commit comments

Comments
 (0)