Merge origin/main (934221b) into #3379 for train slot; stamp v1.91.196.0

Co-authored-by: capy-ai[bot] <230910855+capy-ai[bot]@users.noreply.github.com>
This commit is contained in:
garrytanandcapy-ai[bot] committed 2026-10-25 05:31:32 +00:00
commit 4e9f52f29b
76 files changed
+2418 -297

No files matched your search

+1
View File
@@ -138,6 +138,7 @@ export const FREE_FIXTURES: Readonly<Record<string, readonly string[]>> = {
'test/fixtures/investigate-owned-question-39195396438.json': ['test/workflow-boundaries-fixture.test.ts'],
'test/fixtures/judge-calibration/**': ['scripts/judge-calibration.ts', 'test/judge-calibration.test.ts'],
'test/fixtures/judge-panel-replay-2026-10-05.json': ['test/judge-panel-median.test.ts'],
'test/fixtures/merge-train-3345/**': ['test/changelog-merge-damage.test.ts', 'test/compare-pr-version.test.ts'],
'test/fixtures/module-size-ratchet.json': ['test/helpers/module-size.ts', 'test/module-size-ratchet.test.ts'],
'test/fixtures/module-size/**': ['test/helpers/module-size.ts', 'test/module-size-ratchet.test.ts'],
'test/fixtures/multi-agent-wave/**': ['test/headless-artifacts.test.ts', 'test/helpers/autoplan-run-fixture.ts', 'test/plan-reality.test.ts'],
+2 -2
View File
@@ -68,8 +68,8 @@ export const SAFETY_RULES: readonly SafetyRule[] = [
evalId: 'safety-ios-demo-ui-only',
source: 'ios-qa/SKILL.md.tmpl',
section: '## Demo mode',
match: /demo mode overrides/i,
sha256: '8d42208c888d76af49ebe6e4d58e85537c979f53ecb32fff7e85e95e6859182a',
match: /drive every action through visible UI/i,
sha256: '0ba3230bff9de32f03719daec35c6cef762e15c550264fcffd342dde52291e21',
},
];
+15 -4
View File
@@ -9,6 +9,7 @@
* artifact downloads and check-run reads. Every call is logged, so tests can
* prove what was (and was not) dispatched.
*/
import { spawnSync } from 'node:child_process';
import { createHash } from 'node:crypto';
import * as fs from 'node:fs';
import * as path from 'node:path';
@@ -58,7 +59,7 @@ export function repoKey(fx: TrainFixture): string {
}
/** A same-repo PR: a branch from origin/main touching `file`, published as refs/pull/<n>/head (and /merge), known to the gh shim. */
export function openPr(fx: TrainFixture, pr: string, opts: { file?: string; text?: string; changelog?: boolean; cross?: boolean; from?: string } = {}): string {
export function openPr(fx: TrainFixture, pr: string, opts: { file?: string; text?: string; changelog?: boolean | ((text: string) => string); cross?: boolean; from?: string } = {}): string {
const { repo } = fx;
repo.git('checkout', '-q', opts.from ?? 'origin/main', '-B', `pr-${pr}`);
const file = opts.file ?? `pr-${pr}.txt`;
@@ -66,7 +67,7 @@ export function openPr(fx: TrainFixture, pr: string, opts: { file?: string; text
fs.writeFileSync(path.join(repo.work, file), opts.text ?? `change from #${pr}\n`);
if (opts.changelog !== false) {
const cl = fs.readFileSync(path.join(repo.work, 'CHANGELOG.md'), 'utf8');
fs.writeFileSync(path.join(repo.work, 'CHANGELOG.md'), cl.replace('# Changelog\n', `# Changelog\n\n## [Unreleased]\n\n- #${pr} change\n`));
fs.writeFileSync(path.join(repo.work, 'CHANGELOG.md'), typeof opts.changelog === 'function' ? opts.changelog(cl) : cl.replace('# Changelog\n', `# Changelog\n\n## [Unreleased]\n\n- #${pr} change\n`));
}
repo.git('add', '-A');
repo.git('commit', '-q', '-m', `feat #${pr}`);
@@ -76,9 +77,19 @@ export function openPr(fx: TrainFixture, pr: string, opts: { file?: string; text
return head;
}
/** The repo key of a GitHub-form origin URL: sha256 of the URL with .git and trailing slashes dropped. */
export const urlKey = (url: string) => createHash('sha256').update(url.replace(/\.git$/, '').replace(/\/+$/, '')).digest('hex').slice(0, 16);
/** Point the fixture clone's origin at a GitHub-form URL that git rewrites to the local bare origin (url.insteadOf). */
export function githubOrigin(fx: TrainFixture, url: string, cwd = fx.repo.work): void {
const git = (...args: string[]) => spawnSync('git', args, { cwd, encoding: 'utf8', timeout: 30_000, env: { ...process.env, ...fx.repo.env } });
git('config', `url.${fx.repo.origin}.insteadOf`, url);
git('remote', 'set-url', 'origin', url);
}
/** A READY receipt as `ready --screen|--no-screen` writes it (the lane side is tested separately). */
export function readyReceipt(fx: TrainFixture, pr: string, head: string, opts: { screen?: boolean; at?: string } = {}): void {
const key = repoKey(fx);
export function readyReceipt(fx: TrainFixture, pr: string, head: string, opts: { screen?: boolean; at?: string; key?: string } = {}): void {
const key = opts.key ?? repoKey(fx);
const file = path.join(fx.state, 'ship-queue', 'ready', key, `${pr}-${head}.json`);
fs.mkdirSync(path.dirname(file), { recursive: true });
const at = opts.at ?? '2026-10-18T08:00:00.000Z';