Merge origin/main (v1.64.1.0) into garrytan/time-attack-fork-review

The code-smell wave refactored the tunnel start into the staged
startTunnel helper; the merge adopts that structure and threads this
branch's truthful consent strings through its consent parameter (the
receipt now names the isPairAgentEnabled gate at both call sites). The
eng-review PTY warmup takes both improvements: main's resolveClaudeBinary
fallback and this branch's resolveEvalModel kind. Resolver imports
union; carve budgets take the larger of both waves' measured values
(parity suite green on the merged tree); conflicted generated SKILL.md
files regenerated from resolved sources. VERSION stays 1.65.0.0 over
main's 1.64.1.0; CHANGELOG stacks 1.65.0.0 > 1.64.1.0 > 1.64.0.0.
This commit is contained in:
Garry Tan
2026-08-15 10:01:18 -07:00
187 changed files with 2744 additions and 22778 deletions
+8
View File
@@ -22,6 +22,14 @@ import { execSync } from 'child_process';
export interface SkillBaselineEntry {
skill: string;
/**
* SKILL.md file bytes as captured. NOTE for rebaselines: the parity harness
* compares UNION bytes (skeleton + sections/*.md) against this field, so a
* committed baseline fixture must have carved skills' entries normalized to
* union size (skeleton + sum of sections/*.md) or every carved skill reads
* as 1.2-1.4x over on day one. The v1.57.7.0 and v1.64.1.0 fixtures are
* union-normalized.
*/
skillMdBytes: number;
skillMdLines: number;
estTokens: number; // ~4 chars/token heuristic
+7 -1
View File
@@ -154,6 +154,7 @@ export const CARVE_GUARDS: Record<string, CarveGuard> = {
},
behavioral: 'external',
externalTest: 'test/skill-e2e-plan-ceo-review-section-loading.test.ts',
// v1.65 merge: provisional larger-of-both-waves budget; re-measured below.
// Fork port wave 2 (#703): the repo-doc-preference block in the design
// check grew every plan-review skeleton ~0.7KB. Measured values noted.
maxSkeletonBytes: 92_500, // v1.64+v1.65 merge: both waves' preamble growth; measured 92,004
@@ -177,6 +178,7 @@ export const CARVE_GUARDS: Record<string, CarveGuard> = {
behavioral: 'plan',
// v1.2.0 activation lift (shared first-run-guidance preamble) + #2077 ask-first scope gate.
// +~1 KB: plan-mode auto-select-B scope-gate exceptions (2026-08).
// v1.65 merge: provisional larger-of-both-waves budget; re-measured below.
// Fork port wave 2 (#703): the repo-doc-preference block in the design
// check grew every plan-review skeleton ~0.7KB. Measured values noted.
maxSkeletonBytes: 70_000, // measured 68,780
@@ -257,6 +259,7 @@ export const CARVE_GUARDS: Record<string, CarveGuard> = {
behavioral: 'prompt',
// v1.2.0 activation lift: first-run-guidance section in the shared preamble,
// plus the P1 office-hours closing handoff (AUQ that launches the next skill).
// v1.65 merge: provisional larger-of-both-waves budget; re-measured below.
// Fork port wave 2: the third-party web-actions contract sits inline
// (judgment must be visible before the workflow directs the user to a
// vendor site), plus the #703 dual-write + repo-doc-preference block and
@@ -310,7 +313,10 @@ export const CARVE_GUARDS: Record<string, CarveGuard> = {
// +Conductor AUQ-default-prose rule + one-way/continuation safety in the
// always-loaded AskUserQuestion Format section.
// v1.2.0 activation lift: first-run-guidance section in the shared preamble.
maxSkeletonBytes: 69_800, // v1.64+v1.65 merge; measured 69,476
// v1.65 merge: provisional larger-of-both-waves budget; re-measured below.
// v1.64.1.0: shared-preamble prose from the two parallel v1.64 waves lands
// the skeleton at 69,022 B; +~1 KB headroom.
maxSkeletonBytes: 70_000,
minUnionBytes: 72_000,
mustContain: ['Typography', 'Color', 'Aesthetic Direction'],
// Cross-cutting preamble growth (v1.57.2.0 AUQ-failure prose fallback ~2KB +
+4 -1
View File
@@ -455,8 +455,11 @@ ${tail}
};
try {
// Use the same binary resolution as every PTY launch in this file —
// judgePtyState previously hardcoded bare 'claude' three definitions
// below resolveClaudeBinary(), breaking under hermetic PATHs.
const result = nodeSpawnSync(
'claude',
resolveClaudeBinary() ?? 'claude',
['-p', '--model', resolveEvalModel('warmup'), '--max-turns', '1'],
{
input: prompt,
+51
View File
@@ -0,0 +1,51 @@
/**
* Whole-file E2E tier gate — the single definition of the
* `EVALS=1 && EVALS_TIER === '<tier>'` predicate that tier-gated paid test
* files used to copy-paste (~36 local copies before consolidation).
*
* This module MUST stay side-effect-free. It is imported at module scope by
* every tier-gated test file, including files the sharded paid runner
* (scripts/test-paid-shards.ts) spawns one-process-each — unlike
* test/helpers/e2e-helpers.ts, whose EVALS=1 module-scope work includes a
* ~30s `claude -p` connectivity ping, diff-based selection, and ~/.gstack
* pre-seeding. The only import allowed here is `bun:test`.
* test/helpers/e2e-gate.unit.test.ts enforces this with a source scan.
*
* Env is read at CALL time (the importing test file's module top-level), not
* captured at this module's load time, so the gate behaves identically under
* single-process `bun test` globs and the sharded runner's per-shard env.
*
* Static-grep consumers that must recognize the call shape
* `describeE2ETier('<tier>')` / `e2eTierEnabled('<tier>')` alongside the raw
* `EVALS_TIER === '<tier>'` predicate:
* - test/e2e-tier-alignment.test.ts (HELPER_GATE_RE) — tier-alignment invariant
* - scripts/test-paid-shards.ts classifyPaidTestFile — pre-spawn tier exclusion
*/
import { describe } from 'bun:test';
export type E2ETier = 'gate' | 'periodic';
/**
* True when this process should run whole-file-gated paid tests of `tier`:
* EVALS=1 AND EVALS_TIER exactly equals the tier.
*
* Deliberate consequence: EVALS=1 with EVALS_TIER unset is false for BOTH
* tiers. Tierless runs (`test:evals` / `eval:bg` / `eval:bg:all`) skip every
* tier-gated file and rely on diff-based per-test selection instead — that is
* the long-standing behavior of the copy-pasted predicates, pinned by
* test/helpers/e2e-gate.unit.test.ts.
*/
export function e2eTierEnabled(tier: E2ETier): boolean {
return !!process.env.EVALS && process.env.EVALS_TIER === tier;
}
/**
* `describe` when `e2eTierEnabled(tier)`, else `describe.skip`.
*
* Usage (module top-level of a tier-gated test file):
* const describeE2E = describeE2ETier('periodic');
*/
export function describeE2ETier(tier: E2ETier): typeof describe | typeof describe.skip {
return e2eTierEnabled(tier) ? describe : describe.skip;
}
+103
View File
@@ -0,0 +1,103 @@
/**
* Pins the consolidated E2E tier gate (test/helpers/e2e-gate.ts).
*
* Two invariants:
* 1. The env matrix — including the tierless-run trap: EVALS=1 with
* EVALS_TIER unset must SKIP both tiers (that is how `test:evals` /
* `eval:bg:all` have always treated whole-file tier gates; per-test
* diff selection covers those runs instead).
* 2. Module purity — e2e-gate.ts is imported at module scope by every
* tier-gated paid test file, one-process-each under the sharded
* runner. Its only import must be `bun:test` and it must contain no
* spawn/network/fs machinery (the reason it cannot live in
* e2e-helpers.ts, whose EVALS=1 module scope runs a ~30s claude ping).
*/
import { describe, test, expect, beforeEach, afterEach } from 'bun:test';
import * as fs from 'fs';
import * as path from 'path';
import { describeE2ETier, e2eTierEnabled } from './e2e-gate';
const SAVED_EVALS = process.env.EVALS;
const SAVED_TIER = process.env.EVALS_TIER;
function restoreEnv() {
if (SAVED_EVALS === undefined) delete process.env.EVALS;
else process.env.EVALS = SAVED_EVALS;
if (SAVED_TIER === undefined) delete process.env.EVALS_TIER;
else process.env.EVALS_TIER = SAVED_TIER;
}
describe('e2e-gate: env matrix (read at call time)', () => {
beforeEach(() => {
delete process.env.EVALS;
delete process.env.EVALS_TIER;
});
afterEach(restoreEnv);
test('EVALS unset → skip, even when EVALS_TIER matches', () => {
process.env.EVALS_TIER = 'gate';
expect(e2eTierEnabled('gate')).toBe(false);
expect(describeE2ETier('gate')).toBe(describe.skip);
expect(describeE2ETier('periodic')).toBe(describe.skip);
});
test('EVALS=1 + matching tier → run', () => {
process.env.EVALS = '1';
process.env.EVALS_TIER = 'gate';
expect(e2eTierEnabled('gate')).toBe(true);
expect(describeE2ETier('gate')).toBe(describe);
process.env.EVALS_TIER = 'periodic';
expect(e2eTierEnabled('periodic')).toBe(true);
expect(describeE2ETier('periodic')).toBe(describe);
});
test('EVALS=1 + other tier → skip', () => {
process.env.EVALS = '1';
process.env.EVALS_TIER = 'periodic';
expect(e2eTierEnabled('gate')).toBe(false);
expect(describeE2ETier('gate')).toBe(describe.skip);
process.env.EVALS_TIER = 'gate';
expect(e2eTierEnabled('periodic')).toBe(false);
expect(describeE2ETier('periodic')).toBe(describe.skip);
});
test('EVALS=1 + EVALS_TIER unset → skip both tiers (the tierless test:evals / eval:bg:all trap)', () => {
process.env.EVALS = '1';
expect(e2eTierEnabled('gate')).toBe(false);
expect(e2eTierEnabled('periodic')).toBe(false);
expect(describeE2ETier('gate')).toBe(describe.skip);
expect(describeE2ETier('periodic')).toBe(describe.skip);
});
});
describe('e2e-gate: module purity (side-effect-free import)', () => {
const source = fs.readFileSync(path.join(import.meta.dir, 'e2e-gate.ts'), 'utf-8');
test('the only import specifier is bun:test', () => {
const specifiers = [...source.matchAll(/from\s+['"]([^'"]+)['"]/g)].map((m) => m[1]);
expect(specifiers.length).toBeGreaterThan(0);
expect(specifiers.filter((s) => s !== 'bun:test')).toEqual([]);
// No dynamic escape hatches either.
expect(source).not.toMatch(/\brequire\s*\(/);
expect(source).not.toMatch(/\bimport\s*\(/);
});
test('no spawn / network / fs machinery in the module body', () => {
// Strip comments so prose explaining WHY the module must stay pure
// (which legitimately names spawnSync etc.) doesn't trip the scan.
const code = source
.replace(/\/\*[\s\S]*?\*\//g, '')
.replace(/\/\/[^\n]*/g, '');
for (const banned of [
'spawnSync', 'spawn(', 'execSync', 'child_process',
'Bun.spawn', 'Bun.file', 'Bun.write',
'fetch(', 'WebSocket', 'XMLHttpRequest',
'readFileSync', 'writeFileSync', 'mkdirSync', 'node:fs', "from 'fs'",
]) {
expect(code.includes(banned), `e2e-gate.ts must not contain "${banned}"`).toBe(false);
}
});
});
+33 -18
View File
@@ -32,26 +32,36 @@ export const evalsEnabled = !!process.env.EVALS;
// --- Diff-based test selection ---
// When EVALS_ALL is not set, only run tests whose touchfiles were modified.
// Set EVALS_ALL=1 to force all tests. Set EVALS_BASE to override base branch.
export let selectedTests: string[] | null = null; // null = run all
if (evalsEnabled && !process.env.EVALS_ALL) {
/**
* Compute the diff-based selection for a touchfiles table. Returns null for
* "run all" (EVALS off, EVALS_ALL=1, or no diff vs the base branch — e.g. on
* main). Shared by this module (E2E_TOUCHFILES) and skill-llm-eval.test.ts
* (LLM_JUDGE_TOUCHFILES) so the selection logic exists exactly once.
*/
export function computeDiffSelection(
touchfiles: Record<string, string[]>,
label: string,
): string[] | null {
if (!evalsEnabled || process.env.EVALS_ALL) return null;
const baseBranch = process.env.EVALS_BASE
|| detectBaseBranch(ROOT)
|| 'main';
const changedFiles = getChangedFiles(baseBranch, ROOT);
// If changedFiles is empty (e.g., on main branch), run all
if (changedFiles.length === 0) return null;
if (changedFiles.length > 0) {
const selection = selectTests(changedFiles, E2E_TOUCHFILES, GLOBAL_TOUCHFILES);
selectedTests = selection.selected;
process.stderr.write(`\nE2E selection (${selection.reason}): ${selection.selected.length}/${Object.keys(E2E_TOUCHFILES).length} tests\n`);
if (selection.skipped.length > 0) {
process.stderr.write(` Skipped: ${selection.skipped.join(', ')}\n`);
}
process.stderr.write('\n');
const selection = selectTests(changedFiles, touchfiles, GLOBAL_TOUCHFILES);
process.stderr.write(`\n${label} selection (${selection.reason}): ${selection.selected.length}/${Object.keys(touchfiles).length} tests\n`);
if (selection.skipped.length > 0) {
process.stderr.write(` Skipped: ${selection.skipped.join(', ')}\n`);
}
// If changedFiles is empty (e.g., on main branch), selectedTests stays null → run all
process.stderr.write('\n');
return selection.selected;
}
export let selectedTests: string[] | null = computeDiffSelection(E2E_TOUCHFILES, 'E2E'); // null = run all
// EVALS_TIER: filter tests by tier after diff-based selection.
// 'gate' = gate tests only (CI default — blocks merge)
// 'periodic' = periodic tests only (weekly cron / manual)
@@ -72,9 +82,14 @@ if (evalsEnabled && process.env.EVALS_TIER) {
export const describeE2E = evalsEnabled ? describe : describe.skip;
/** Wrap a describe block to skip entirely if none of its tests are selected. */
export function describeIfSelected(name: string, testNames: string[], fn: () => void) {
const anySelected = selectedTests === null || testNames.some(t => selectedTests!.includes(t));
/**
* Wrap a describe block to skip entirely if none of its tests are selected.
* `selected` defaults to this module's E2E selection (diff + EVALS_TIER);
* pass an explicit selection (e.g. computeDiffSelection over
* LLM_JUDGE_TOUCHFILES) to reuse the gating against a different table.
*/
export function describeIfSelected(name: string, testNames: string[], fn: () => void, selected: string[] | null = selectedTests) {
const anySelected = selected === null || testNames.some(t => selected.includes(t));
(anySelected ? describeE2E : describe.skip)(name, fn);
}
@@ -272,14 +287,14 @@ if (evalsEnabled) {
}
/** Skip an individual test if not selected (for multi-test describe blocks). */
export function testIfSelected(testName: string, fn: () => Promise<void>, timeout: number) {
const shouldRun = selectedTests === null || selectedTests.includes(testName);
export function testIfSelected(testName: string, fn: () => Promise<void>, timeout: number, selected: string[] | null = selectedTests) {
const shouldRun = selected === null || selected.includes(testName);
(shouldRun ? test : test.skip)(testName, fn, timeout);
}
/** Concurrent version — runs in parallel with other concurrent tests within the same describe block. */
export function testConcurrentIfSelected(testName: string, fn: () => Promise<void>, timeout: number) {
const shouldRun = selectedTests === null || selectedTests.includes(testName);
export function testConcurrentIfSelected(testName: string, fn: () => Promise<void>, timeout: number, selected: string[] | null = selectedTests) {
const shouldRun = selected === null || selected.includes(testName);
(shouldRun ? test.concurrent : test.skip)(testName, fn, timeout);
}
-13
View File
@@ -295,7 +295,6 @@ export const E2E_TOUCHFILES: Record<string, string[]> = {
// Plan completion audit + verification
'ship-plan-completion': ['ship/**', 'scripts/gen-skill-docs.ts'],
'ship-plan-verification': ['ship/**', 'qa-only/**', 'scripts/gen-skill-docs.ts'],
'ship-idempotency': ['ship/**', 'scripts/resolvers/utility.ts'],
'review-plan-completion': ['review/**', 'scripts/gen-skill-docs.ts'],
// Design
@@ -327,11 +326,6 @@ export const E2E_TOUCHFILES: Record<string, string[]> = {
'benchmark-workflow': ['benchmark/**', 'browse/src/**'],
'setup-deploy-workflow': ['setup-deploy/**', 'scripts/gen-skill-docs.ts'],
// Sidebar agent
'sidebar-navigate': ['browse/src/server.ts', 'browse/src/sidebar-agent.ts', 'browse/src/sidebar-utils.ts', 'extension/**'],
'sidebar-url-accuracy': ['browse/src/server.ts', 'browse/src/sidebar-agent.ts', 'browse/src/sidebar-utils.ts', 'extension/background.js'],
'sidebar-css-interaction': ['browse/src/server.ts', 'browse/src/sidebar-agent.ts', 'browse/src/write-commands.ts', 'browse/src/read-commands.ts', 'browse/src/cdp-inspector.ts', 'extension/**'],
// Autoplan
'autoplan-core': ['autoplan/**', 'plan-ceo-review/**', 'plan-eng-review/**', 'plan-design-review/**'],
'autoplan-dual-voice': ['autoplan/**', 'codex/**', 'bin/gstack-codex-probe', 'scripts/resolvers/review.ts', 'scripts/resolvers/design.ts'],
@@ -657,7 +651,6 @@ export const E2E_TIERS: Record<string, 'gate' | 'periodic'> = {
'ship-triage': 'gate',
'ship-plan-completion': 'gate',
'ship-plan-verification': 'gate',
'ship-idempotency': 'periodic',
// Retro — gate for cheap branch detection, periodic for full Opus retro
'retro': 'periodic',
@@ -711,11 +704,6 @@ export const E2E_TIERS: Record<string, 'gate' | 'periodic'> = {
'benchmark-workflow': 'gate',
'setup-deploy-workflow': 'gate',
// Sidebar agent
'sidebar-navigate': 'periodic',
'sidebar-url-accuracy': 'periodic',
'sidebar-css-interaction': 'periodic',
// Autoplan — periodic (not yet implemented)
'autoplan-core': 'periodic',
'autoplan-dual-voice': 'periodic',
@@ -785,7 +773,6 @@ export const LLM_JUDGE_TOUCHFILES: Record<string, string[]> = {
'plan-eng-review/SKILL.md sections': ['plan-eng-review/SKILL.md', 'plan-eng-review/SKILL.md.tmpl'],
// /spec authored-spec quality (paid LLM-judge — periodic-tier).
'spec authored quality': ['spec/SKILL.md', 'spec/SKILL.md.tmpl', 'test/fixtures/spec/**'],
'plan-design-review/SKILL.md passes': ['plan-design-review/SKILL.md', 'plan-design-review/SKILL.md.tmpl'],
// Design skills