mirror of
https://github.com/garrytan/gstack.git
synced 2026-11-03 15:27:56 +01:00
ship-policy: merge trains carry up to 5 READY PRs (train.max_size 3 -> 5)
Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
1 parent
2d1b55d762
commit
45618dfaad
4 files changed
+12
-7
No files matched your search
@@ -13,7 +13,7 @@
|
||||
"stamp_sensitive_gates": ["tests"],
|
||||
"pr_count": { "default_pr_count": 1, "split_requires_owner": true },
|
||||
"maintainers": ["garrytan"],
|
||||
"train": { "gate_workflow": "evals.yml", "free_workflow": "free-tests.yml", "full_gate_check": "gstack/full-gate", "record_artifact": "gstack-train-record", "max_size": 3, "fill_hours": 1, "screen_selection": "gstack-paid", "trial_reservation_usd": 1.5 },
|
||||
"train": { "gate_workflow": "evals.yml", "free_workflow": "free-tests.yml", "full_gate_check": "gstack/full-gate", "record_artifact": "gstack-train-record", "max_size": 5, "fill_hours": 1, "screen_selection": "gstack-paid", "trial_reservation_usd": 1.5 },
|
||||
"changelog_fragments": { "dir": "changelog.d", "required_checks": ["free-tests", "windows-free-tests", "Check VERSION is not stale vs queue", "quality", "check-freshness", "actionlint"] },
|
||||
"min_gstack_version": "1.91.340.0"
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
**A merge train now carries up to five READY PRs instead of three.** That means fewer full gates for the same number of PRs. A short train still leaves one hour after its oldest READY.
|
||||
|
||||
### Changed
|
||||
- `.gstack/ship-policy.json`: `train.max_size` goes from 3 to 5 (Garry, 2026-10-31). `fill_hours` stays at 1. `test/gstack-ship-policy.test.ts` pins the new value. Four READY PRs wait for the hour, and the fifth fills the train. The example block in docs/ship-policy.md, which shows gstack's own policy, now reads 5.
|
||||
+1
-1
@@ -351,7 +351,7 @@ warning on stderr). A block for gstack itself would read:
|
||||
"train": {
|
||||
"gate_workflow": "evals.yml", "free_workflow": "free-tests.yml",
|
||||
"full_gate_check": "gstack/full-gate", "record_artifact": "gstack-train-record",
|
||||
"max_size": 3, "fill_hours": 1, "screen_selection": "gstack-paid",
|
||||
"max_size": 5, "fill_hours": 1, "screen_selection": "gstack-paid",
|
||||
"trial_reservation_usd": 1.5
|
||||
},
|
||||
"min_gstack_version": "<the version that introduced train>"
|
||||
|
||||
@@ -162,16 +162,17 @@ describe("gstack's own .gstack/ship-policy.json", () => {
|
||||
expect(raw.changelog_fragments.required_checks.filter((n: string) => !jobs.has(n))).toEqual([]);
|
||||
});
|
||||
|
||||
// Value: protects=the fill rule the coordinator relies on: a train dispatches at 3 READY PRs or one hour after the first READY, whichever comes first
|
||||
// (2026-10-26: 5 PRs / 3 hours left READY PRs waiting most of a day); fails_when=the live block drifts back to a larger or slower fill; why_new=the values were unpinned; seam=the policy file; no_claim=fillDue's arithmetic (ship-queue-train-logic)
|
||||
test('fills a train at 3 READY PRs or one hour after the first READY, whichever comes first', () => {
|
||||
// Value: protects=the fill rule the coordinator relies on: a train dispatches at 5 READY PRs or one hour after the first READY, whichever comes first
|
||||
// (2026-10-26: 5 PRs / 3 hours left READY PRs waiting most of a day, so the fill went to 3 PRs / 1 hour; 2026-10-31: Garry's B1 raised the size back to 5, keeping the 1-hour fill); fails_when=the live block drifts back to a larger or slower fill; why_new=the values were unpinned; seam=the policy file; no_claim=fillDue's arithmetic (ship-queue-train-logic)
|
||||
test('fills a train at 5 READY PRs or one hour after the first READY, whichever comes first', () => {
|
||||
const raw = JSON.parse(fs.readFileSync(path.join(import.meta.dir, '..', '.gstack', 'ship-policy.json'), 'utf8'));
|
||||
expect([raw.train.max_size, raw.train.fill_hours]).toEqual([3, 1]);
|
||||
expect([raw.train.max_size, raw.train.fill_hours]).toEqual([5, 1]);
|
||||
const first = '2026-10-26T09:00:00.000Z';
|
||||
const slots = (n: number) => Array.from({ length: n }, (_, i) => ({ pr: i + 1, ready_at: new Date(Date.parse(first) + i * 60_000).toISOString() })) as any;
|
||||
expect(fillDue(slots(2), raw.train, '2026-10-26T09:59:00Z', false)).toBe('2026-10-26T10:00:00.000Z');
|
||||
expect(fillDue(slots(2), raw.train, '2026-10-26T10:00:00Z', false)).toBeNull();
|
||||
expect(fillDue(slots(3), raw.train, '2026-10-26T09:05:00Z', false)).toBeNull();
|
||||
expect(fillDue(slots(4), raw.train, '2026-10-26T09:05:00Z', false)).toBe('2026-10-26T10:00:00.000Z');
|
||||
expect(fillDue(slots(5), raw.train, '2026-10-26T09:05:00Z', false)).toBeNull();
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
Reference in new issue
Block a user