From f7eb79f9ad0f64bc92ffbf6cf991393fe42a2509 Mon Sep 17 00:00:00 2001 From: garrytan Date: Sat, 31 Oct 2026 18:53:06 +0000 Subject: [PATCH] shard-jobs tests: non-hex plan id fixture; harness-version: shard-jobs FREE_ONLY entry is non-behavioral Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com> --- scripts/harness-version.json | 2 +- test/shard-jobs.test.ts | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/scripts/harness-version.json b/scripts/harness-version.json index 420cf7e06..4ad1edd24 100644 --- a/scripts/harness-version.json +++ b/scripts/harness-version.json @@ -17,7 +17,7 @@ "scripts/lib/published-text.ts": {"blob":"3f2e4d616b5dd0204035710c66b64d49055c5714","since":6}, "scripts/lib/shard-engine.ts": {"blob":"dc714d7d897aed185c0ec3d2c92ad22d954039e5","since":6,"nonBehavioral":"createShardSandbox drops the Capy launch markers (GSTACK_SESSION_KIND, GSTACK_CAPY, GSTACK_EPHEMERAL, GSTACK_INSTALL_VERDICT) from shard environments; CI never sets them, so no case's input or verdict changes there, and on a Capy machine fixtures now see the session kind they set themselves instead of the installer's"}, "scripts/test-paid-shards.ts": {"blob":"5439d0a8f6e1569fa7c924af20d67c30c81d5d30","since":6,"nonBehavioral":"credential rejections are classed infra instead of assertion: no case's pass or fail changes; only failed trials whose provider rejected the run's key move class, so no rerun spends on a rejected key"}, - "scripts/test-pr-profile.ts": {"blob":"911e393d0c36c050c3a68db5a81ef21701bfd5ae","since":6,"nonBehavioral":"selection only: fragment exemption narrowed to .md files directly in the fragments dir; changed-file lists include a rename's old path; no case prompt, fixture, judge or verdict logic changes (GST-400)"}, + "scripts/test-pr-profile.ts": {"blob":"594f9764f98add6e5e215b3a2d5f5067eb5c9e0f","since":6,"nonBehavioral":"FREE_ONLY_PR_FILES gains scripts/lib/shard-jobs.ts, a free-runner module; it changes which PR paths select paid cases, never how a case runs or is judged"}, "scripts/test-strict-output.ts": {"blob":"01185d20dc9761b04b9b2f751ec98664fe0eaf93","since":6}, "test/helpers/agent-sdk-runner.ts": {"blob":"210bba92d241a90df578b2c7fc943ac5755d0025","since":6}, "test/helpers/auq-substance-panel.ts": {"blob":"4881260ef793668e4963a062db6d06a5e1f7a40f","since":6}, diff --git a/test/shard-jobs.test.ts b/test/shard-jobs.test.ts index 34121e316..fe033a8af 100644 --- a/test/shard-jobs.test.ts +++ b/test/shard-jobs.test.ts @@ -55,7 +55,7 @@ function harness(shardFiles: string[], respond: (files: string[]) => FreeShardOu phaseGuard: (guarded, shards) => { guards.push({ files: guarded, shards }); return { verify: () => homeChange }; }, log: () => {}, }; - const plan = { version: 1 as const, revision: 'revision-a', id: '0123456789abcdef', shards: [{ shard: 1, files: shardFiles, predictedMs: 0 }] }; + const plan = { version: 1 as const, revision: 'revision-a', id: 'plan-id-for-tests', shards: [{ shard: 1, files: shardFiles, predictedMs: 0 }] }; const shard = plan.shards[0]; const run = (jobs: number) => runCiShard({ plan, shard, revision: 'revision-a', jobs, wallTimeoutMs: 360_000, verbose: false, context }, deps); return { calls, retries, guards, deps, plan, shard, run, setHomeChange: (value: string) => { homeChange = value; }, cancel: () => { terminate = true; } }; @@ -118,9 +118,9 @@ describe('sub-shard assignment', () => { test('disjoint, identity-bound, covering the shard once, with exclusive files in one trailing serial sub-shard', () => { const shardFiles = [...files, EXCLUSIVE]; - const assignments = assignSubShards('0123456789abcdef', { shard: 4, files: shardFiles }, 3, file => file in TREE_MUTATING, pack); + const assignments = assignSubShards('plan-id-for-tests', { shard: 4, files: shardFiles }, 3, file => file in TREE_MUTATING, pack); expect(assignments.map(entry => [entry.id, entry.phase, entry.files.length])).toEqual([ - ['0123456789ab:4.1', 'parallel', 3], ['0123456789ab:4.2', 'parallel', 2], ['0123456789ab:4.3', 'parallel', 2], ['0123456789ab:4.4', 'serial', 1], + ['plan-id-for-:4.1', 'parallel', 3], ['plan-id-for-:4.2', 'parallel', 2], ['plan-id-for-:4.3', 'parallel', 2], ['plan-id-for-:4.4', 'serial', 1], ]); expect(assignments.at(-1)!.files).toEqual([EXCLUSIVE]); expect(assignments.flatMap(entry => entry.files).sort()).toEqual([...shardFiles].sort()); @@ -194,7 +194,7 @@ describe('k > 1: merge, rejection and one retry pass per CI shard', () => { expect(result.outcome.unattributedFailures).toBeGreaterThan(0); expect(eligibleFreeRetryFiles([result.outcome])).toBeNull(); expect(exitCode).toBe(1); - expect(errors.mock.calls.map(call => String(call[0])).some(line => line.startsWith('[test:free] FREE_SUBSHARD_REJECTED: CI shard 1: 0123456789ab:1.'))).toBe(true); + expect(errors.mock.calls.map(call => String(call[0])).some(line => line.startsWith('[test:free] FREE_SUBSHARD_REJECTED: CI shard 1: plan-id-for-:1.'))).toBe(true); } } finally { errors.mockRestore(); } }); @@ -253,7 +253,7 @@ describe('k > 1: merge, rejection and one retry pass per CI shard', () => { expect(result.outcome.status).toBe('timed-out'); expect(exitCode).toBe(1); const text = errors.mock.calls.map(call => String(call[0])).join('\n'); - expect(text).toContain('FREE_SUBSHARD_TIMEOUT: CI shard 1 sub-shard 0123456789ab:1.1 (3 files)'); + expect(text).toContain('FREE_SUBSHARD_TIMEOUT: CI shard 1 sub-shard plan-id-for-:1.1 (3 files)'); expect(text).toContain('hit its 360s wall at --jobs 3 on runner-7 (linux, 8 CPUs), run 123/attempt 2.'); expect(text).toContain(`in flight: ${files[3]}`); expect(text).toContain(`printf '%s\\n' '${files[3]}' > files.txt && GSTACK_FREE_JOBS=1 bun run scripts/test-free-shards.ts --files-from files.txt`);