@humanbased/crosscheck 1.2.0-beta.79 → 1.2.0-beta.81

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.md +51 -5
  2. package/crosscheck.config.example.yml +39 -8
  3. package/dist/__tests__/board.test.js +11 -0
  4. package/dist/__tests__/board.test.js.map +1 -1
  5. package/dist/__tests__/onboard-preservation.test.js +54 -3
  6. package/dist/__tests__/onboard-preservation.test.js.map +1 -1
  7. package/dist/__tests__/repository-guidance.test.js +1 -1
  8. package/dist/__tests__/repository-guidance.test.js.map +1 -1
  9. package/dist/__tests__/review-models.test.js +5 -2
  10. package/dist/__tests__/review-models.test.js.map +1 -1
  11. package/dist/__tests__/review-strategy.test.d.ts +2 -0
  12. package/dist/__tests__/review-strategy.test.d.ts.map +1 -0
  13. package/dist/__tests__/review-strategy.test.js +397 -0
  14. package/dist/__tests__/review-strategy.test.js.map +1 -0
  15. package/dist/commands/onboard.d.ts +25 -3
  16. package/dist/commands/onboard.d.ts.map +1 -1
  17. package/dist/commands/onboard.js +151 -46
  18. package/dist/commands/onboard.js.map +1 -1
  19. package/dist/commands/run.d.ts.map +1 -1
  20. package/dist/commands/run.js +22 -4
  21. package/dist/commands/run.js.map +1 -1
  22. package/dist/commands/watch.d.ts.map +1 -1
  23. package/dist/commands/watch.js +38 -6
  24. package/dist/commands/watch.js.map +1 -1
  25. package/dist/config/review-model-tiers.json +3 -3
  26. package/dist/config/review-strategy.json +204 -0
  27. package/dist/config/schema.d.ts +7 -5
  28. package/dist/config/schema.d.ts.map +1 -1
  29. package/dist/config/schema.js +29 -7
  30. package/dist/config/schema.js.map +1 -1
  31. package/dist/github/client.d.ts +16 -1
  32. package/dist/github/client.d.ts.map +1 -1
  33. package/dist/github/client.js +32 -1
  34. package/dist/github/client.js.map +1 -1
  35. package/dist/github/webhook.d.ts +4 -0
  36. package/dist/github/webhook.d.ts.map +1 -1
  37. package/dist/github/webhook.js.map +1 -1
  38. package/dist/lib/annotation.d.ts +7 -0
  39. package/dist/lib/annotation.d.ts.map +1 -1
  40. package/dist/lib/annotation.js +11 -1
  41. package/dist/lib/annotation.js.map +1 -1
  42. package/dist/lib/board.d.ts +3 -0
  43. package/dist/lib/board.d.ts.map +1 -1
  44. package/dist/lib/board.js +4 -2
  45. package/dist/lib/board.js.map +1 -1
  46. package/dist/lib/comment-bodies.d.ts +2 -0
  47. package/dist/lib/comment-bodies.d.ts.map +1 -1
  48. package/dist/lib/comment-bodies.js +5 -1
  49. package/dist/lib/comment-bodies.js.map +1 -1
  50. package/dist/lib/review-models.d.ts +15 -2
  51. package/dist/lib/review-models.d.ts.map +1 -1
  52. package/dist/lib/review-models.js +19 -6
  53. package/dist/lib/review-models.js.map +1 -1
  54. package/dist/lib/review-strategy.d.ts +92 -0
  55. package/dist/lib/review-strategy.d.ts.map +1 -0
  56. package/dist/lib/review-strategy.js +282 -0
  57. package/dist/lib/review-strategy.js.map +1 -0
  58. package/dist/lib/runner.d.ts +80 -0
  59. package/dist/lib/runner.d.ts.map +1 -1
  60. package/dist/lib/runner.js +289 -17
  61. package/dist/lib/runner.js.map +1 -1
  62. package/docs/dynamic-thoroughness.md +738 -0
  63. package/get-started.md +68 -7
  64. package/package.json +4 -3
@@ -0,0 +1,397 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { resolveReviewStrategy, detectDomain, escalate, clampEffort, effortLevelsFor, isModelBanned, strategyModelFor, strategyVersion, ladderLimits, } from '../lib/review-strategy.js';
3
+ import { resolveClaudeModel, resolveCodexModel, effectiveTier } from '../lib/review-models.js';
4
+ import { ConfigSchema, CLAUDE_EFFORT_LEVELS, CODEX_EFFORT_LEVELS } from '../config/schema.js';
5
+ import { buildReviewCommentBody } from '../github/client.js';
6
+ import { parseAnnotation } from '../lib/annotation.js';
7
+ import { filterStepsByTypes } from '../lib/repo-workflow.js';
8
+ import { strategyDeterminedModel, strategyVendor, resolveRoundExecution } from '../lib/runner.js';
9
+ import { claudeEffort } from '../reviewers/claude.js';
10
+ import { codexReasoningEffort } from '../reviewers/codex.js';
11
+ import { tierTimeoutMs } from '../reviewers/tier-timeouts.js';
12
+ const pr = (files, over = {}) => resolveReviewStrategy({ files, additions: 100, deletions: 50, ...over });
13
+ describe('PR classification', () => {
14
+ it('skips a lockfile-only PR entirely', () => {
15
+ const r = pr(['package-lock.json', 'pnpm-lock.yaml']);
16
+ expect(r.classId).toBe('generated');
17
+ expect(r.tier).toBeNull();
18
+ expect(r.steps).toEqual([]);
19
+ });
20
+ it('promotes a security path to thorough', () => {
21
+ const r = pr(['src/auth/session.ts']);
22
+ expect(r.classId).toBe('risky');
23
+ expect(r.tier).toBe('thorough');
24
+ expect(r.steps).toEqual(['review', 'fix', 'recheck']);
25
+ });
26
+ it('promotes on a risk:T3 label even with innocuous paths', () => {
27
+ const r = pr(['src/widget.ts'], { labels: ['risk:T3'] });
28
+ expect(r.classId).toBe('risky');
29
+ expect(r.tier).toBe('thorough');
30
+ });
31
+ it('promotes a hotfix targeting the default branch', () => {
32
+ const r = pr(['src/widget.ts'], { title: 'hotfix(api): patch', baseRef: 'main', defaultBranch: 'main' });
33
+ expect(r.classId).toBe('risky');
34
+ });
35
+ it('does not promote a hotfix targeting a non-default branch', () => {
36
+ const r = pr(['src/widget.ts'], { title: 'hotfix(api): patch', baseRef: 'staging', defaultBranch: 'main' });
37
+ expect(r.classId).not.toBe('risky');
38
+ });
39
+ // Ordering regression: `risky` must sit above every cheapening rule, or a
40
+ // deletion of auth code falls through to `fast`.
41
+ it('classifies a deletion of auth code as risky, not deletion-only', () => {
42
+ const r = pr(['src/auth/legacy-session.ts'], { additions: 0, deletions: 400 });
43
+ expect(r.classId).toBe('risky');
44
+ expect(r.tier).toBe('thorough');
45
+ });
46
+ it('classifies a two-file migration as risky, not trivial', () => {
47
+ const r = pr(['db/migrations/20260101_add.sql', 'src/x.ts'], { additions: 10, deletions: 2 });
48
+ expect(r.classId).toBe('risky');
49
+ });
50
+ // Regression: `additions_max` alone matched a +2/-2 typo fix, because a small
51
+ // edit also has near-zero additions. Deletion-only needs a floor on deletions.
52
+ it('classifies a small edit as trivial, not deletion-only', () => {
53
+ const r = pr(['src/widget.ts'], { additions: 2, deletions: 2 });
54
+ expect(r.classId).toBe('trivial');
55
+ expect(r.steps).toContain('fix');
56
+ });
57
+ it('classifies a pure deletion as deletion-only with no fix loop', () => {
58
+ const r = pr(['src/widget.ts', 'src/helper.ts'], { additions: 0, deletions: 300 });
59
+ expect(r.classId).toBe('deletion_only');
60
+ expect(r.tier).toBe('fast');
61
+ expect(r.steps).toEqual(['review']);
62
+ });
63
+ it('gives a docs PR review with no fix or recheck', () => {
64
+ const r = pr(['docs/design.md', 'docs/adr/0001.md', 'src/x.ts']);
65
+ expect(r.classId).toBe('docs');
66
+ expect(r.steps).toEqual(['review']);
67
+ });
68
+ it('classifies a test-only PR as fast', () => {
69
+ const r = pr(['src/__tests__/a.test.ts', 'src/__tests__/b.spec.ts']);
70
+ expect(r.classId).toBe('test_only');
71
+ expect(r.tier).toBe('fast');
72
+ });
73
+ it('classifies a small source change as trivial', () => {
74
+ const r = pr(['src/widget.ts'], { additions: 20, deletions: 10 });
75
+ expect(r.classId).toBe('trivial');
76
+ expect(r.tier).toBe('fast');
77
+ });
78
+ it('falls through to standard for an ordinary change', () => {
79
+ const r = pr(['src/a.ts', 'src/b.ts', 'src/c.ts', 'src/d.ts'], { additions: 400, deletions: 200 });
80
+ expect(r.classId).toBe('standard');
81
+ expect(r.tier).toBe('balanced');
82
+ });
83
+ it('falls through to standard when no files can be listed', () => {
84
+ expect(pr([]).classId).toBe('standard');
85
+ });
86
+ it('carries a citable reason and the strategy version on every class', () => {
87
+ const r = pr(['src/auth/x.ts']);
88
+ expect(r.reason.length).toBeGreaterThan(10);
89
+ expect(r.version).toBe(strategyVersion());
90
+ });
91
+ });
92
+ describe('domain detection', () => {
93
+ it('detects a frontend-dominant PR', () => {
94
+ expect(detectDomain(['a.tsx', 'b.scss', 'c.ts'])).toBe('frontend');
95
+ });
96
+ it('detects a backend-dominant PR', () => {
97
+ expect(detectDomain(['a.py', 'b.go', 'c.tsx'])).toBe('backend');
98
+ });
99
+ // Backend is the conservative default: its preference list is `measured`
100
+ // while the frontend list is still a hypothesis.
101
+ it('falls back to backend on a tie or when neither is present', () => {
102
+ expect(detectDomain(['a.tsx', 'b.py'])).toBe('backend');
103
+ expect(detectDomain(['README.md'])).toBe('backend');
104
+ expect(detectDomain([])).toBe('backend');
105
+ });
106
+ });
107
+ describe('escalation ladder', () => {
108
+ it('leaves round 1 at the class tier', () => {
109
+ expect(escalate({ tier: 'balanced', effort: 'medium' }, 1, 'claude-sonnet-5'))
110
+ .toEqual({ tier: 'balanced', effort: 'medium' });
111
+ });
112
+ it('raises effort at round 2 and again at round 3, holding the model', () => {
113
+ expect(escalate({ tier: 'balanced', effort: 'medium' }, 2, 'claude-sonnet-5'))
114
+ .toEqual({ tier: 'balanced', effort: 'high' });
115
+ expect(escalate({ tier: 'balanced', effort: 'medium' }, 3, 'claude-sonnet-5'))
116
+ .toEqual({ tier: 'balanced', effort: 'xhigh' });
117
+ });
118
+ it('never weakens the model across rounds', () => {
119
+ const out = escalate({ tier: 'thorough', effort: 'high' }, 3, 'claude-opus-5');
120
+ expect(out.tier).toBe('thorough');
121
+ });
122
+ // The OpenCode case: most open-weight models expose no effort ladder, so the
123
+ // effort step has to degrade to a model step or escalation silently no-ops.
124
+ it('promotes a tier when the model has no effort control', () => {
125
+ expect(effortLevelsFor('claude-haiku-4-5-20251001')).toEqual([]);
126
+ expect(escalate({ tier: 'fast', effort: null }, 2, 'claude-haiku-4-5-20251001'))
127
+ .toEqual({ tier: 'balanced', effort: null });
128
+ });
129
+ it('caps tier promotion at thorough', () => {
130
+ expect(escalate({ tier: 'thorough', effort: null }, 3, 'claude-haiku-4-5-20251001').tier)
131
+ .toBe('thorough');
132
+ });
133
+ });
134
+ describe('effort clamping', () => {
135
+ it('passes through a supported level', () => {
136
+ expect(clampEffort('claude-opus-5', 'xhigh')).toBe('xhigh');
137
+ });
138
+ it('returns null for a model with no effort parameter', () => {
139
+ expect(clampEffort('claude-haiku-4-5-20251001', 'high')).toBeNull();
140
+ });
141
+ it('snaps down to the nearest supported level', () => {
142
+ // deepseek exposes none/high/max — xhigh must snap down to high, not fail.
143
+ expect(clampEffort('deepseek-v4-pro', 'xhigh')).toBe('high');
144
+ });
145
+ });
146
+ describe('banned models', () => {
147
+ it('bans claude-fable-5 from review', () => {
148
+ expect(isModelBanned('claude-fable-5')).toBe(true);
149
+ expect(isModelBanned('claude-opus-5')).toBe(false);
150
+ });
151
+ it('never routes a banned model from any vendor tier', () => {
152
+ for (const vendor of ['claude', 'codex', 'opencode']) {
153
+ for (const tier of ['fast', 'balanced', 'thorough']) {
154
+ const model = strategyModelFor(vendor, tier);
155
+ expect(model).toBeTruthy();
156
+ expect(isModelBanned(model)).toBe(false);
157
+ }
158
+ }
159
+ });
160
+ });
161
+ describe('model resolution honours the strategy', () => {
162
+ const quality = (over = {}) => ({ tier: 'balanced', mode: 'smart', focus: [], ...over });
163
+ it('uses the strategy tier in smart mode', () => {
164
+ expect(resolveClaudeModel(quality(), undefined, { tier: 'thorough' })).toBe('claude-opus-5');
165
+ expect(resolveClaudeModel(quality(), undefined, { tier: 'fast' })).toBe('claude-haiku-4-5-20251001');
166
+ });
167
+ it('ignores the strategy tier in fixed mode', () => {
168
+ expect(resolveClaudeModel(quality({ mode: 'fixed' }), undefined, { tier: 'thorough' }))
169
+ .toBe('claude-sonnet-5');
170
+ });
171
+ it('falls back to the configured tier when no strategy resolved', () => {
172
+ expect(effectiveTier(quality(), null)).toBe('balanced');
173
+ expect(effectiveTier(quality(), { tier: null })).toBe('balanced');
174
+ });
175
+ it('routes thorough to opus-5, not the legacy opus-4-8', () => {
176
+ expect(resolveClaudeModel(quality(), undefined, { tier: 'thorough' })).toBe('claude-opus-5');
177
+ });
178
+ // Regression: the old `auth !== 'api-key' → 'default'` guard discarded a
179
+ // configured model, sending 81% of observed reviews out unpinned.
180
+ it('honours a configured codex model under subscription auth', () => {
181
+ const vendor = { enabled: true, model: 'gpt-5.6-sol', auth: 'subscription', effort: 'medium', timeout_sec: null, quality: 'medium' };
182
+ expect(resolveCodexModel(quality(), vendor)).toBe('gpt-5.6-sol');
183
+ });
184
+ it('drives the codex tier model from the strategy under api-key auth', () => {
185
+ const vendor = { enabled: true, model: null, auth: 'api-key', effort: 'medium', timeout_sec: null, quality: 'medium' };
186
+ expect(resolveCodexModel(quality(), vendor, { tier: 'thorough' })).toBe('gpt-5.6-sol');
187
+ expect(resolveCodexModel(quality(), vendor, { tier: 'fast' })).toBe('gpt-5.6-luna');
188
+ });
189
+ it('keeps the CLI default under subscription auth with nothing configured', () => {
190
+ // The built-in tier mapping stays api-key-only on purpose: the gpt-5.6-*
191
+ // IDs require codex >= 0.147.0 and would 400 on an older CLI, so a
192
+ // subscription user with no model configured keeps the CLI's own default.
193
+ const vendor = { enabled: true, model: null, auth: 'subscription', effort: 'medium', timeout_sec: null, quality: 'medium' };
194
+ expect(resolveCodexModel(quality(), vendor, { tier: 'thorough' })).toBe('default');
195
+ });
196
+ it('drives model_tiers selection from the strategy under subscription auth', () => {
197
+ const vendor = { enabled: true, model: null, auth: 'subscription', effort: 'medium', timeout_sec: null, quality: 'medium', model_tiers: { thorough: 'gpt-5.6-sol' } };
198
+ expect(resolveCodexModel(quality(), vendor, { tier: 'thorough' })).toBe('gpt-5.6-sol');
199
+ expect(resolveCodexModel(quality(), vendor, { tier: 'fast' })).toBe('default');
200
+ });
201
+ });
202
+ describe('ladder limits', () => {
203
+ it('bounds rounds, blocking findings, and wall clock', () => {
204
+ const l = ladderLimits();
205
+ expect(l.maxRounds).toBe(3);
206
+ expect(l.maxBlocking).toBe(5);
207
+ expect(l.maxWallClockMin).toBeGreaterThan(0);
208
+ });
209
+ });
210
+ describe('strategy citation on the PR', () => {
211
+ it('stamps version, class, and tier into the annotation', () => {
212
+ const body = buildReviewCommentBody({
213
+ body: 'findings', reviewer: 'claude', origin: 'codex', verdict: 'BLOCK',
214
+ model: 'claude-opus-5', stepType: 'review', round: 1, sha: 'abc1234',
215
+ strategy: { version: '1.0.0', classId: 'risky', tier: 'thorough', reason: 'touches a security path' },
216
+ });
217
+ expect(body).toContain('strategy=1.0.0');
218
+ expect(body).toContain('class=risky');
219
+ expect(body).toContain('tier=thorough');
220
+ // Additive fields must not disturb the stable prefix other parsers read.
221
+ expect(body).toMatch(/<!-- crosscheck: origin=codex reviewer=claude model=claude-opus-5 type=review round=1 verdict=BLOCK service=crosscheck/);
222
+ });
223
+ it('quotes the matched class reason so the routing decision is auditable', () => {
224
+ const body = buildReviewCommentBody({
225
+ body: 'findings', reviewer: 'claude', verdict: 'APPROVE', model: 'claude-opus-5',
226
+ strategy: { version: '1.0.0', classId: 'risky', tier: 'thorough', reason: 'touches a security path' },
227
+ });
228
+ expect(body).toContain('thorough tier · touches a security path · strategy v1.0.0');
229
+ });
230
+ it('omits every strategy field under fixed mode', () => {
231
+ const body = buildReviewCommentBody({
232
+ body: 'findings', reviewer: 'claude', verdict: 'APPROVE', model: 'claude-sonnet-5',
233
+ });
234
+ expect(body).not.toContain('strategy=');
235
+ expect(body).not.toContain('class=');
236
+ });
237
+ });
238
+ describe('smart mode is the default', () => {
239
+ // Regression: this default was silently lost in a squash merge, leaving every
240
+ // config on `mode: undefined` while the docs advertised smart as the default.
241
+ it('defaults quality.mode to smart on an empty config', () => {
242
+ const quality = ConfigSchema.parse({}).quality;
243
+ expect(quality.mode).toBe('smart');
244
+ expect(quality.tier).toBe('balanced');
245
+ });
246
+ it('lets an explicit fixed opt out', () => {
247
+ expect(ConfigSchema.parse({ quality: { mode: 'fixed' } }).quality.mode).toBe('fixed');
248
+ });
249
+ });
250
+ describe('citation only asserts what actually ran', () => {
251
+ const strat = { version: '1.0.0', classId: 'risky', tier: 'thorough', reason: 'security path' };
252
+ // An explicit vendors.*.model outranks the tier map, so on a pinned config the
253
+ // strategy's tier is not what ran. Citing it would assert a routing decision
254
+ // that never happened — the property this feature exists to provide.
255
+ it('withholds the citation when a pinned vendor model overrode the tier', () => {
256
+ expect(strategyDeterminedModel({ model: 'gpt-5.6-terra' }, strat)).toBe(false);
257
+ expect(strategyDeterminedModel({ model: null }, strat)).toBe(true);
258
+ });
259
+ it('withholds the citation under fixed mode', () => {
260
+ expect(strategyDeterminedModel({ model: null }, null)).toBe(false);
261
+ });
262
+ });
263
+ describe('strategy applies effort, not just tier', () => {
264
+ // Regression: effort was resolved and logged but never sent, so the run line
265
+ // named a level the CLI was never given.
266
+ it('folds the class effort into the vendor config', () => {
267
+ const vendor = { effort: 'medium' };
268
+ const out = strategyVendor(vendor, { effort: 'high' }, CLAUDE_EFFORT_LEVELS);
269
+ expect(out.effort).toBe('high');
270
+ });
271
+ it('leaves the vendor untouched when the class sets no effort', () => {
272
+ const vendor = { effort: 'medium' };
273
+ expect(strategyVendor(vendor, null, CLAUDE_EFFORT_LEVELS).effort).toBe('medium');
274
+ expect(strategyVendor(vendor, { effort: null }, CLAUDE_EFFORT_LEVELS).effort).toBe('medium');
275
+ });
276
+ });
277
+ describe('effort stays inside the vocabulary each vendor CLI accepts', () => {
278
+ const roundStrategy = (round, model) => {
279
+ const e = escalate({ tier: 'balanced', effort: 'medium' }, round, model);
280
+ return { version: '1.0.0', classId: 'standard', reason: 'r', steps: [], domain: 'backend', ...e };
281
+ };
282
+ // Regression: round 3 asks for `xhigh`, which review-strategy.json lists as a
283
+ // capability of claude-opus-5 — but vendors.claude.effort has no such level,
284
+ // so claudeEffort() mapped the unknown value to `medium`. Round 3 then ran
285
+ // WEAKER than round 2's `high`, inverting the ladder's one invariant.
286
+ it('never sends claude a later round weaker than the round before', () => {
287
+ const r2 = strategyVendor({ effort: 'medium' }, roundStrategy(2, 'claude-opus-5'), CLAUDE_EFFORT_LEVELS);
288
+ const r3 = strategyVendor({ effort: 'medium' }, roundStrategy(3, 'claude-opus-5'), CLAUDE_EFFORT_LEVELS);
289
+ expect(claudeEffort(r2.effort)).toBe('high');
290
+ expect(claudeEffort(r3.effort)).toBe('high');
291
+ });
292
+ // Codex does expose xhigh, so clamping must not flatten it to claude's ceiling.
293
+ it('passes xhigh through to codex, which accepts it', () => {
294
+ const r3 = strategyVendor({ effort: 'medium' }, roundStrategy(3, 'gpt-5.6-sol'), CODEX_EFFORT_LEVELS);
295
+ expect(codexReasoningEffort(r3.effort ?? '')).toBe('xhigh');
296
+ });
297
+ });
298
+ describe('one round, one set of tier and effort decisions', () => {
299
+ const config = (over = {}) => ConfigSchema.parse({ quality: { tier: 'balanced', mode: 'smart' }, ...over });
300
+ const risky = { version: '1.0.0', classId: 'risky', reason: 'security path', tier: 'thorough', effort: 'high', steps: ['review', 'fix', 'recheck'], domain: 'backend' };
301
+ it('applies the class tier to the whole round, not just the review', () => {
302
+ const exec = resolveRoundExecution(config(), risky, 1);
303
+ expect(exec.quality.tier).toBe('thorough');
304
+ // The fix step reads its model AND its subprocess budget from this config;
305
+ // a thorough model on the balanced 600s cap is cut off mid-fix.
306
+ expect(tierTimeoutMs(exec.roundConfig.quality.tier)).toBe(tierTimeoutMs('thorough'));
307
+ expect(exec.roundConfig.vendors.claude.effort).toBe('high');
308
+ });
309
+ // Regression: the review step ran the escalated round strategy while the fix
310
+ // step re-folded the base class, so a promoted round fixed at the old tier.
311
+ it('carries an escalated round into the config the fix step runs under', () => {
312
+ const noEffortLadder = { ...risky, tier: 'fast', effort: null };
313
+ const exec = resolveRoundExecution(config(), noEffortLadder, 2);
314
+ expect(exec.escalated).toBe(true);
315
+ expect(exec.quality.tier).toBe(exec.roundConfig.quality.tier);
316
+ expect(exec.strategy?.tier).toBe(exec.quality.tier);
317
+ });
318
+ it('leaves the config untouched under fixed mode', () => {
319
+ const cfg = config({ quality: { tier: 'fast', mode: 'fixed' } });
320
+ const exec = resolveRoundExecution(cfg, null, 3);
321
+ expect(exec.quality.tier).toBe('fast');
322
+ expect(exec.roundConfig).toBe(cfg);
323
+ expect(exec.escalated).toBe(false);
324
+ });
325
+ });
326
+ describe('annotation round-trips the citation', () => {
327
+ it('parses strategy, class, and tier back out', () => {
328
+ const body = buildReviewCommentBody({
329
+ body: 'findings', reviewer: 'claude', origin: 'codex', verdict: 'BLOCK',
330
+ model: 'claude-opus-5', stepType: 'review', round: 1,
331
+ strategy: { version: '1.0.0', classId: 'risky', tier: 'thorough', reason: 'security path' },
332
+ });
333
+ const parsed = parseAnnotation(body);
334
+ expect(parsed?.strategy).toBe('1.0.0');
335
+ expect(parsed?.class).toBe('risky');
336
+ expect(parsed?.tier).toBe('thorough');
337
+ });
338
+ });
339
+ describe('class step sets narrow the pipeline', () => {
340
+ const full = [
341
+ { name: 'conflict-resolve', type: 'conflict-resolve' },
342
+ { name: 'review', type: 'review' },
343
+ { name: 'fix', type: 'fix' },
344
+ { name: 'recheck', type: 'recheck' },
345
+ ];
346
+ it('narrows a docs PR to review, dropping fix and recheck', () => {
347
+ const kept = filterStepsByTypes(full, ['review']);
348
+ expect(kept.map(s => s.type)).toEqual(['review']);
349
+ });
350
+ it('keeps conflict-resolve only when the depth permits code modification', () => {
351
+ // review-only must not touch the code, so conflict-resolve goes too.
352
+ expect(filterStepsByTypes(full, ['review']).map(s => s.type)).not.toContain('conflict-resolve');
353
+ expect(filterStepsByTypes(full, ['review', 'fix']).map(s => s.type)).toContain('conflict-resolve');
354
+ });
355
+ // The class narrows; it never widens. A repo pinned to review-only stays
356
+ // review-only however permissive the matched class is.
357
+ it('cannot add a step the configured pipeline does not have', () => {
358
+ const reviewOnly = [{ name: 'review', type: 'review' }];
359
+ const kept = filterStepsByTypes(reviewOnly, ['review', 'fix', 'recheck']);
360
+ expect(kept.map(s => s.type)).toEqual(['review']);
361
+ });
362
+ });
363
+ describe('rounds escalate on measured non-convergence', () => {
364
+ it('holds the class tier on round 1 and escalates after', () => {
365
+ const base = { tier: 'balanced', effort: 'medium' };
366
+ expect(escalate(base, 1, 'claude-sonnet-5')).toEqual({ tier: 'balanced', effort: 'medium' });
367
+ expect(escalate(base, 2, 'claude-sonnet-5').effort).toBe('high');
368
+ expect(escalate(base, 3, 'claude-sonnet-5').effort).toBe('xhigh');
369
+ });
370
+ it('promotes the tier instead when the model has no effort ladder', () => {
371
+ expect(escalate({ tier: 'fast', effort: null }, 2, 'claude-haiku-4-5-20251001'))
372
+ .toEqual({ tier: 'balanced', effort: null });
373
+ });
374
+ });
375
+ describe('codex under subscription auth', () => {
376
+ const codex = (over = {}) => ({ enabled: true, model: null, auth: 'subscription', effort: 'medium', quality: 'medium', timeout_sec: null, ...over });
377
+ const q = (tier) => ({ tier, mode: 'smart', focus: [] });
378
+ // Without model_tiers every tier collapses to the CLI's own default, so the
379
+ // strategy's tier had no effect and must not be cited.
380
+ it('collapses every tier to default with no model_tiers', () => {
381
+ for (const tier of ['fast', 'balanced', 'thorough']) {
382
+ expect(resolveCodexModel(q(tier), codex())).toBe('default');
383
+ }
384
+ });
385
+ it('withholds the citation when the resolved model is default', () => {
386
+ const strat = { version: '1.0.0', classId: 'risky', tier: 'thorough' };
387
+ expect(strategyDeterminedModel({ model: null }, strat, 'default')).toBe(false);
388
+ expect(strategyDeterminedModel({ model: null }, strat, 'gpt-5.6-sol')).toBe(true);
389
+ });
390
+ // What onboard writes under smart, so tiers actually differ.
391
+ it('varies by tier once model_tiers is written', () => {
392
+ const v = codex({ model_tiers: { fast: 'gpt-5.6-luna', balanced: 'gpt-5.6-terra', thorough: 'gpt-5.6-sol' } });
393
+ expect(resolveCodexModel(q('fast'), v)).toBe('gpt-5.6-luna');
394
+ expect(resolveCodexModel(q('thorough'), v)).toBe('gpt-5.6-sol');
395
+ });
396
+ });
397
+ //# sourceMappingURL=review-strategy.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-strategy.test.js","sourceRoot":"","sources":["../../src/__tests__/review-strategy.test.ts"],"names":[],"mappings":"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"}
@@ -13,7 +13,7 @@ type VendorModeConfig = {
13
13
  };
14
14
  declare const QUALITY_TIERS: {
15
15
  readonly fast: {
16
- readonly description: "quick scan, top issues only (~10s, lowest cost)";
16
+ readonly description: "quick scan, top issues only (~$0.24 per review)";
17
17
  readonly claude: {
18
18
  readonly model: "haiku";
19
19
  readonly effort: "low";
@@ -24,7 +24,7 @@ declare const QUALITY_TIERS: {
24
24
  };
25
25
  };
26
26
  readonly balanced: {
27
- readonly description: "full review, all issues with explanations (~30s)";
27
+ readonly description: "full review, all issues with explanations (~$0.72 per review)";
28
28
  readonly claude: {
29
29
  readonly model: "sonnet";
30
30
  readonly effort: "medium";
@@ -35,7 +35,7 @@ declare const QUALITY_TIERS: {
35
35
  };
36
36
  };
37
37
  readonly thorough: {
38
- readonly description: "deep multi-pass, security + architecture (~60s+, higher cost)";
38
+ readonly description: "deep multi-pass, security + architecture (~$1.20 per review)";
39
39
  readonly claude: {
40
40
  readonly model: "opus";
41
41
  readonly effort: "max";
@@ -47,6 +47,27 @@ declare const QUALITY_TIERS: {
47
47
  };
48
48
  };
49
49
  type QualityTier = keyof typeof QUALITY_TIERS;
50
+ export interface ThoroughnessChoice {
51
+ /** Fixed tier, and the fallback used under smart mode when a PR's files can't be read. */
52
+ tier: QualityTier;
53
+ mode: 'smart' | 'fixed';
54
+ }
55
+ /**
56
+ * What a re-run of onboard proposes, from the `quality` block as it is WRITTEN.
57
+ *
58
+ * Both fields must come from the raw yaml, never the parsed config: the schema
59
+ * defaults `mode` to smart and `tier` to balanced, so a parsed value can never
60
+ * distinguish "the user chose this" from "this config predates the field".
61
+ * Reading the parsed tier made every existing config look hand-set, so any
62
+ * re-onboard — silently, under `--yes` — opted the user out of the new default.
63
+ *
64
+ * A config that named a tier before smart existed keeps it, on the reasoning
65
+ * that it was a deliberate choice; one that never mentioned quality does not.
66
+ */
67
+ export declare function thoroughnessDefaults(rawQuality: {
68
+ tier?: string;
69
+ mode?: string;
70
+ }): ThoroughnessChoice;
50
71
  export declare function detectCurrentPreset(workflowDir?: string): WorkflowPreset;
51
72
  export declare function detectConflictResolveEnabled(workflowDir?: string): boolean;
52
73
  export interface LinearDecision {
@@ -66,6 +87,7 @@ export interface OnboardDecisions {
66
87
  vendorConfig: VendorModeConfig;
67
88
  authorVendor: 'claude' | 'codex' | 'both';
68
89
  qualityTier: QualityTier;
90
+ qualityMode: 'smart' | 'fixed';
69
91
  enabledSkills: string[];
70
92
  pipelinePreset: WorkflowPreset;
71
93
  maxRounds?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"onboard.d.ts","sourceRoot":"","sources":["../../src/commands/onboard.ts"],"names":[],"mappings":"AA0BA,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAQD,KAAK,cAAc,GAAG,aAAa,GAAG,YAAY,GAAG,oBAAoB,CAAA;AAEzE,KAAK,gBAAgB,GAAG;IACtB,IAAI,EAAE,cAAc,GAAG,eAAe,CAAA;IACtC,aAAa,EAAE,OAAO,CAAA;IACtB,YAAY,EAAE,OAAO,CAAA;CACtB,CAAA;AAID,QAAA,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgBT,CAAA;AAEV,KAAK,WAAW,GAAG,MAAM,OAAO,aAAa,CAAA;AAkM7C,wBAAgB,mBAAmB,CAAC,WAAW,GAAE,MAAuC,GAAG,cAAc,CAgBxG;AAED,wBAAgB,4BAA4B,CAAC,WAAW,GAAE,MAAuC,GAAG,OAAO,CAO1G;AA4ED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,KAAK,GAAG,SAAS,GAAG,oBAAoB,CAAA;IAC9C,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAQD,wBAAsB,YAAY,CAChC,OAAO,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,SAAS,EAC9E,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC,cAAc,CAAC,CAkBzB;AAkED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,UAAU,GAAG,MAAM,CAAA;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,YAAY,EAAE,gBAAgB,CAAA;IAC9B,YAAY,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAA;IACzC,WAAW,EAAE,WAAW,CAAA;IACxB,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,cAAc,EAAE,cAAc,CAAA;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,eAAe,EAAE,OAAO,CAAA;IACxB,aAAa,EAAE,eAAe,GAAG,MAAM,CAAA;IACvC,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,KAAK,GAAG,OAAO,CAAA;IAC9B,MAAM,CAAC,EAAE,cAAc,CAAA;CACxB;AAwDD,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,gBAAgB,EAC3B,WAAW,SAAiC,GAC3C,IAAI,CA4LN;AAED,wBAAsB,UAAU,CAAC,IAAI,GAAE,WAAgB,iBA6ZtD"}
1
+ {"version":3,"file":"onboard.d.ts","sourceRoot":"","sources":["../../src/commands/onboard.ts"],"names":[],"mappings":"AA0BA,MAAM,WAAW,WAAW;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,IAAI,CAAC,EAAE,OAAO,CAAA;IACd,WAAW,CAAC,EAAE,OAAO,CAAA;CACtB;AAQD,KAAK,cAAc,GAAG,aAAa,GAAG,YAAY,GAAG,oBAAoB,CAAA;AAEzE,KAAK,gBAAgB,GAAG;IACtB,IAAI,EAAE,cAAc,GAAG,eAAe,CAAA;IACtC,aAAa,EAAE,OAAO,CAAA;IACtB,YAAY,EAAE,OAAO,CAAA;CACtB,CAAA;AAQD,QAAA,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgBT,CAAA;AAEV,KAAK,WAAW,GAAG,MAAM,OAAO,aAAa,CAAA;AA4J7C,MAAM,WAAW,kBAAkB;IACjC,0FAA0F;IAC1F,IAAI,EAAE,WAAW,CAAA;IACjB,IAAI,EAAE,OAAO,GAAG,OAAO,CAAA;CACxB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,oBAAoB,CAAC,UAAU,EAAE;IAAE,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,kBAAkB,CAOrG;AA0DD,wBAAgB,mBAAmB,CAAC,WAAW,GAAE,MAAuC,GAAG,cAAc,CAgBxG;AAED,wBAAgB,4BAA4B,CAAC,WAAW,GAAE,MAAuC,GAAG,OAAO,CAO1G;AA4ED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,KAAK,GAAG,SAAS,GAAG,oBAAoB,CAAA;IAC9C,QAAQ,EAAE,MAAM,EAAE,CAAA;CACnB;AAQD,wBAAsB,YAAY,CAChC,OAAO,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,EAAE,CAAA;CAAE,GAAG,SAAS,EAC9E,IAAI,EAAE,WAAW,GAChB,OAAO,CAAC,cAAc,CAAC,CAkBzB;AAkED,MAAM,WAAW,gBAAgB;IAC/B,UAAU,EAAE,UAAU,GAAG,MAAM,CAAA;IAC/B,KAAK,EAAE,MAAM,CAAA;IACb,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,YAAY,EAAE,MAAM,EAAE,CAAA;IACtB,YAAY,EAAE,gBAAgB,CAAA;IAC9B,YAAY,EAAE,QAAQ,GAAG,OAAO,GAAG,MAAM,CAAA;IACzC,WAAW,EAAE,WAAW,CAAA;IACxB,WAAW,EAAE,OAAO,GAAG,OAAO,CAAA;IAC9B,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,cAAc,EAAE,cAAc,CAAA;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,eAAe,EAAE,OAAO,CAAA;IACxB,aAAa,EAAE,eAAe,GAAG,MAAM,CAAA;IACvC,WAAW,EAAE,MAAM,CAAA;IACnB,aAAa,EAAE,KAAK,GAAG,OAAO,CAAA;IAC9B,MAAM,CAAC,EAAE,cAAc,CAAA;CACxB;AAwDD,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,gBAAgB,EAC3B,WAAW,SAAiC,GAC3C,IAAI,CA2NN;AAED,wBAAsB,UAAU,CAAC,IAAI,GAAE,WAAgB,iBAictD"}