mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-07 17:28:23 +01:00
feat(ship-budget): a light diff keeps its segment instead of delegating it (GSTA-167)
check --runtime-lines <n> continues at the Step 7 and 12 boundaries when the diff has at most 50 runtime lines and the segment's calibrated calls at this run's per-call charge cost at most 12M: a child's fixed 2-4.5M (gstack-evals #34) saves at most 3/8 of each parent call. Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
cc28dd35c5
commit
dbe700417c
5 files changed
+104
-8
No files matched your search
@@ -0,0 +1,58 @@
|
||||
/**
|
||||
* GSTA-167 PR 4: a small run keeps its segment instead of delegating it. A child
|
||||
* costs a fixed 2-4.5M (boot, install check, verify-handoff, section reads,
|
||||
* reconcile; gstack-evals #34), so a light-depth diff whose segment costs less
|
||||
* than a child can save continues in the parent's context.
|
||||
*/
|
||||
import { afterEach, describe, expect, test } from 'bun:test';
|
||||
import { CHILD_FIXED_COST, keepsSmallRun, loadCalibration, SMALL_RUN_LINES, SMALL_RUN_SEGMENT, smallRunSegment } from '../lib/ship-budget';
|
||||
import { budgetHarness, type Harness } from './helpers/ship-budget-harness';
|
||||
|
||||
const cal = loadCalibration();
|
||||
const harnesses: Harness[] = [];
|
||||
const fresh = () => { const h = budgetHarness(); harnesses.push(h); return h; };
|
||||
afterEach(() => { while (harnesses.length) harnesses.pop()!.cleanup(); });
|
||||
|
||||
describe('small-run rule', () => {
|
||||
// Value: protects=the threshold is the child's fixed cost over the share of a call a fresh child can save, so a segment under it never pays for a child; fails_when=the constants drift apart or the segment ignores this run's own per-call charge;
|
||||
// why_new=no prior test prices a segment from the measured per-call charge; seam=none; no_claim=the #34 measurements themselves
|
||||
test('the segment threshold is derived from the child cost; the segment is its calibrated calls at this run\'s per-call charge', () => {
|
||||
expect(SMALL_RUN_SEGMENT).toBe(12_000_000);
|
||||
expect(SMALL_RUN_SEGMENT * 0.375).toBe(CHILD_FIXED_COST);
|
||||
const calls = ['7', '8', '9', '10', '11', '11.5'].reduce((n, s) => n + (cal.step_calls[s] ?? cal.step_calls.default!), 0);
|
||||
expect(smallRunSegment(cal, '7', '11.5', 200_000)).toBe(calls * 200_000);
|
||||
expect(smallRunSegment(cal, '7', '11.5', null)).toBe(calls * 250_000);
|
||||
});
|
||||
|
||||
// Value: protects=only a light diff with a cheap segment keeps it, and a missing runtime count keeps today's delegation; fails_when=a large diff or a costly context stops delegating, or an unknown diff size is treated as small;
|
||||
// why_new=keepsSmallRun is new; seam=none; no_claim=what the parent does after continuing
|
||||
test('keeps only a light diff whose segment is under the threshold; an unknown runtime count never keeps', () => {
|
||||
expect(keepsSmallRun(cal, { runtimeLines: 0, from: '7', to: '11.5', call: 220_000 })).toContain('SMALL_RUN: runtime_lines=0');
|
||||
expect(keepsSmallRun(cal, { runtimeLines: SMALL_RUN_LINES, from: '12', to: '22', call: 300_000 })).not.toBeNull();
|
||||
expect(keepsSmallRun(cal, { runtimeLines: SMALL_RUN_LINES + 1, from: '7', to: '11.5', call: 220_000 })).toBeNull();
|
||||
expect(keepsSmallRun(cal, { runtimeLines: 0, from: '7', to: '11.5', call: 400_000 })).toBeNull();
|
||||
expect(keepsSmallRun(cal, { runtimeLines: undefined, from: '7', to: '11.5', call: 220_000 })).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
describe('check --runtime-lines', () => {
|
||||
// Value: protects=the registered check command continues a small run at a segment boundary and still delegates a large one; fails_when=check ignores --runtime-lines or applies it to a large diff;
|
||||
// why_new=the delegation tests never pass a diff size; seam=none; no_claim=the handoff itself
|
||||
test('a light diff continues at the 6->7 boundary with a SMALL_RUN line; a large diff and an omitted count still delegate', () => {
|
||||
const h = fresh();
|
||||
const start = (cap: string) => {
|
||||
const r = h.sb(['start', '--record', h.record(`r${cap}.md`), '--token-cap', cap, '--reading', '0']);
|
||||
return h.field(r.out, 'BUDGET_RUN', 'id');
|
||||
};
|
||||
const small = h.sb(['check', '--run', start('80M'), '--step', '6', '--next', '7', '--reading', '1220000', '--prior-reading', '1000000', '--runtime-lines', '0']);
|
||||
expect(small.code).toBe(0);
|
||||
expect(h.field(small.out, 'BUDGET', 'verdict')).toBe('continue');
|
||||
expect(small.out).toContain('SMALL_RUN: runtime_lines=0');
|
||||
expect(small.out).not.toContain('DELEGATE:');
|
||||
const large = h.sb(['check', '--run', start('81M'), '--step', '6', '--next', '7', '--reading', '1220000', '--prior-reading', '1000000', '--runtime-lines', '900']);
|
||||
expect(h.field(large.out, 'BUDGET', 'verdict')).toBe('delegate');
|
||||
const omitted = h.sb(['check', '--run', start('82M'), '--step', '6', '--next', '7', '--reading', '1220000', '--prior-reading', '1000000']);
|
||||
expect(h.field(omitted.out, 'BUDGET', 'verdict')).toBe('delegate');
|
||||
expect(h.sb(['check', '--run', start('83M'), '--step', '6', '--next', '7', '--reading', '5', '--runtime-lines', 'many']).code).toBe(2);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user