test: derive paid touchfiles from each eval's static closure (E)

touchfiles.test.ts now checks, per key, that the paid file's static
test/helpers and test/fixtures closure (plus fixture paths it names in string
literals) is covered, and names the file, path, chain and key to fix when it is
not. Free *.test.ts files are no longer touchfiles, so editing a free replay
test stops selecting paid evals: 950 entries removed, 653 real closure paths
added. The hand-copied inventories go: periodic-fixture-selection,
fake-impeccable-touchfiles and 45 per-file selection examples. Selection for
the sample edits (plan-eng-review template, claude-pty-runner,
plan-count-fixture, gstack-config) loses no case under either profile.
CONTRIBUTING documents the rule and its lower bound.
This commit is contained in:
garrytan committed 2026-09-29 07:00:28 +00:00
1 parent 689ef3094b
commit 7cbb5e04e4
53 files changed
+627 -1873

No files matched your search

-9
View File
@@ -6,8 +6,6 @@ import { spawnSync } from 'node:child_process';
import { createAutoplanArtifactRecorder, recordAutoplanArtifact, readPendingAutoplanArtifact,
autoplanArtifactRecorderStatus, autoplanArtifactApprovalBoundary } from './helpers/autoplan-artifact-recorder';
import type { NativePublicToolEvent } from './helpers/plan-count-transcript';
import { E2E_TOUCHFILES, selectTests } from './helpers/touchfiles';
// Synthetic hook envelopes and owned temp paths. The live pending hook envelope
// was unpublished; these controls do not reconstruct it or provide paid coverage.
function fixture(approveEdits=false) {
@@ -164,13 +162,6 @@ describe('owned Autoplan pending artifact metadata recorder',()=>{
expect(f.status()).toEqual({status:'invalid',reason:'stdin_timeout'});
}finally{clearTimeout(timer);child.stdin.end();if(child.exitCode===null){child.kill('SIGKILL');await child.exited}f.dispose()}
},7000);
test('recorder disposal removes owned state and shared recorder inputs select both paid owners',()=>{
const f=fixture();f.write(f.event());f.dispose();expect(fs.existsSync(f.recorder.file)).toBe(false);
for(const file of ['test/helpers/autoplan-artifact-recorder.ts','test/autoplan-artifact-recorder.test.ts'])
expect(selectTests([file],E2E_TOUCHFILES,[]).selected.sort()).toEqual([]);
for(const file of ['test/autoplan-pending-artifact.test.ts','test/fixtures/autoplan-pending-artifact-ae.json'])
expect(selectTests([file],E2E_TOUCHFILES,[]).selected).toEqual([]);
});
});
// Real hook subprocesses and the public JSONL reader; no synthetic phase success
-6
View File
@@ -1,6 +0,0 @@
import {test,expect,afterEach} from 'bun:test';
import {E2E_TOUCHFILES} from './helpers/touchfiles-data';
const cleanup:Array<()=>void>=[];afterEach(()=>{for(const f of cleanup.splice(0))f()});
test('new regression files register only the actual Autoplan owner',()=>{
for(const p of ['test/autoplan-clipped-suffix-aq.test.ts','test/fixtures/autoplan-clipped-suffix-aq.json'])expect(Object.entries(E2E_TOUCHFILES).filter(([,files])=>files.includes(p)).map(([owner])=>owner)).toEqual([]);
});
-4
View File
@@ -4,7 +4,6 @@ import fixture from './fixtures/autoplan-edit-digests-al.json';
import {createAutoplanArtifactRecorder,recordAutoplanArtifact,readPendingAutoplanArtifact,autoplanArtifactRecorderStatus} from './helpers/autoplan-artifact-recorder';
import {createAutoplanEditDigest,validAutoplanEditDigest} from './helpers/autoplan-artifact-digest';
import type {NativePublicToolEvent} from './helpers/plan-count-transcript';
import {E2E_TOUCHFILES,selectTests} from './helpers/touchfiles';
const cleanups:Array<()=>void>=[];afterEach(()=>{for(const cleanup of cleanups.splice(0))cleanup()});
function replay(record=true) {
const root=fs.mkdtempSync(path.join(os.tmpdir(),'ap-digest-')),cwd=path.join(root,path.basename(fixture.cwd)),ownedStateRoot=path.join(root,'home','.gstack'),config=path.join(root,'config');
@@ -37,9 +36,6 @@ test('unavailable or oversized before/request data yields no new digest authorit
const link=path.join(r.root,'linked');fs.symlinkSync(r.file,link);expect(createAutoplanEditDigest(link,r.event.tool_input.old_string,r.event.tool_input.new_string)).toBeUndefined();
fs.writeFileSync(r.file,'x'.repeat(1024*1024+1));expect(createAutoplanEditDigest(r.file,'x','new')).toBeUndefined();fs.unlinkSync(r.file);expect(createAutoplanEditDigest(r.file,'old','new')).toBeUndefined();
});
test('Eng and Autoplan share the digest helper and regression evidence',()=>{
for(const file of ['test/helpers/autoplan-artifact-digest.ts','test/autoplan-edit-digests-al.test.ts','test/fixtures/autoplan-edit-digests-al.json'])expect(selectTests([file],E2E_TOUCHFILES,[]).selected.sort()).toEqual([]);
});
test('identical pending hook replay cannot refresh digest or timestamp',()=>{
const r=replay(),before=fs.readFileSync(r.recorder.file,'utf8');recordAutoplanArtifact(JSON.stringify(r.event),r.recorder.file,r.context.cwd,r.config,r.context.ownedStateRoot);expect(fs.readFileSync(r.recorder.file,'utf8')).toBe(before);
});
-8
View File
@@ -5,7 +5,6 @@ import * as path from 'node:path';
import { spawnSync } from 'node:child_process';
import { createPendingQuestionRecorder, readPendingQuestion, recordPendingQuestion } from './helpers/plan-count-pending-question';
import { readPlanCountTranscript } from './helpers/plan-count-transcript';
import { E2E_TOUCHFILES, selectTests } from './helpers/touchfiles';
import captured from './fixtures/autoplan-routing-manual-skills-ac.json';
// Exact retained public question; hook envelopes and owned temp paths are
@@ -208,13 +207,6 @@ describe('opt-in pending native AskUserQuestion capture', () => {
}
} finally { f.dispose(); }
});
test('the helper and new free test select only the two opted-in workflows', () => {
for (const file of ['test/helpers/plan-count-pending-question.ts', 'test/autoplan-pending-question.test.ts']) {
expect(selectTests([file], E2E_TOUCHFILES, []).selected.sort()).toEqual(['plan-ceo-mode-routing']);
}
});
test('a hook whose input never ends closes within its own bound and remains silent', async () => {
const f = fixture();
const hook = f.recorder.hooks.PreToolUse[0]!.hooks[0]!;
-8
View File
@@ -5,7 +5,6 @@ import * as path from 'node:path';
import { pathToFileURL } from 'node:url';
import { autoplanPhaseCompletions } from './helpers/autoplan-phase-observer';
import type { PlanCountTranscript } from './helpers/plan-count-transcript';
import { E2E_TOUCHFILES, selectTests } from './helpers/touchfiles';
import fixture_autoplan_phase_dash_ao from './fixtures/autoplan-phase-dash-ao.json';
import actual_autoplan_with_result_au from './fixtures/autoplan-with-result-au.json';
@@ -204,13 +203,6 @@ describe('native autoplan phase observation', () => {
.toEqual([{ phase: 3, ts: START + 1 }, { phase: 1, ts: START + 2 }]);
expect(autoplanPhaseCompletions(transcript([1, 'Phase 2 skipped — no UI scope.']), START)).toEqual([]);
});
test('phase observer changes select the autoplan eval', () => {
for (const file of ['test/helpers/autoplan-phase-observer.ts', 'test/autoplan-phase-observer.test.ts']) {
expect(selectTests([file], E2E_TOUCHFILES).selected).toEqual([]);
}
});
test.skipIf(process.platform === 'win32')('ANSI-rendered completions use native evidence while displayed Read/source markers do not', async () => {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'autoplan-phase-replay-'));
const fake = path.join(dir, 'fake-claude');
-16
View File
@@ -5,8 +5,6 @@ import path from 'node:path';
import {readPlanCountTranscript,type NativePublicToolEvent} from './helpers/plan-count-transcript';
import {autoplanPhaseCompletions} from './helpers/autoplan-phase-observer';
import fixture from './fixtures/autoplan-public-narration-ad.json';
import {E2E_TOUCHFILES,selectTests} from './helpers/touchfiles';
const at=Date.parse(fixture.provenance.timestamp);
function read(blocks: unknown[]= [fixture.block],delta: any={},complete=true) {
const dir=fs.mkdtempSync(path.join(os.tmpdir(),'public-narration-')),cwd=path.join(dir,'repo');
@@ -124,17 +122,3 @@ test('phase ordering and duplicate collapse use native time rather than polling
{sessionId:'parent',timestamp:new Date(at+30).toISOString(),text:'Phase 1 is done.'}]};
expect(autoplanPhaseCompletions(t,at)).toEqual([{phase:1,ts:at+10},{phase:2,ts:at+20}]);
});
test('public narration changes select every existing shared native-reader consumer',()=>{
const expected=[
'auto-decide-preserved',
'plan-ceo-mode-routing','plan-ceo-split-overflow',
'plan-design-review-plan-mode','plan-design-with-ui-scope',
'plan-eng-multi-finding-batching',
'plan-eng-review-plan-mode',
].sort();
const reader=selectTests(['test/helpers/plan-count-transcript.ts'],E2E_TOUCHFILES).selected.sort();
expect(reader).toEqual(expected);
for(const file of ['test/autoplan-public-narration.test.ts','test/fixtures/autoplan-public-narration-ad.json'])
expect(selectTests([file],E2E_TOUCHFILES).selected.sort()).toEqual(reader);
});
-1
View File
@@ -193,7 +193,6 @@ describe('autoplan reads installed host methodology', () => {
test('the new discovery contract selects the affected live autoplan workflows', () => {
for (const name of ['autoplan-dual-voice', 'carve-section-loading']) {
expect(E2E_TOUCHFILES[name]).toContain('test/autoplan-review-discovery.test.ts');
expect(E2E_TOUCHFILES[name]).toContain('scripts/resolvers/composition.ts');
}
});
-1
View File
@@ -503,7 +503,6 @@ describe('installed snapshot helper in fresh shells', () => {
test('all affected live workflow selectors include the executable continuity contract', () => {
for (const name of ['autoplan-dual-voice', 'carve-section-loading']) {
expect(E2E_TOUCHFILES[name]).toContain('bin/gstack-autoplan-snapshot.ts');
expect(E2E_TOUCHFILES[name]).toContain('test/autoplan-snapshot.test.ts');
}
});
});
-7
View File
@@ -1,7 +1,6 @@
import { describe, expect, test } from 'bun:test';
import { hasNativePostAnswerCeoPosture, nextCeoPostureContinuation } from './helpers/ceo-mode-option';
import type { PlanCountTranscript } from './helpers/plan-count-transcript';
import { E2E_TOUCHFILES, selectTests } from './helpers/touchfiles';
import captured from './fixtures/ceo-barless-submit-ac.json';
const selectedAt = Date.parse(captured.provenance.modeRequestAt);
@@ -118,10 +117,4 @@ describe('bounded CEO barless packet submission', () => {
text: 'HOLD SCOPE: keep the saved-view feature fixed and make its failure handling rigorous.' });
expect(hasNativePostAnswerCeoPosture(p.t, 'HOLD SCOPE', /hold\s*scope/i, selectedAt)).toBe(true);
});
test('the free test and fixture select only the mode-routing workflow', () => {
for (const file of ['test/ceo-barless-submit.test.ts', 'test/fixtures/ceo-barless-submit-ac.json']) {
expect(selectTests([file], E2E_TOUCHFILES, []).selected).toEqual(['plan-ceo-mode-routing']);
}
});
});
-7
View File
@@ -5,7 +5,6 @@ import * as path from 'node:path';
import { findCeoModeOption, hasNativePostAnswerCeoPosture } from './helpers/ceo-mode-option';
import { parseNumberedOptions } from './helpers/claude-pty-runner';
import { readPlanCountTranscript, type NativePublicToolEvent } from './helpers/plan-count-transcript';
import { E2E_TOUCHFILES, selectTests } from './helpers/touchfiles';
import captured from './fixtures/ceo-expansion-auq-ac.json';
const posture = /\b(expansion|10x|delight|dream|cathedral|opt[\s-]?in)\b/i;
@@ -118,10 +117,4 @@ describe('CEO expansion posture in a completed native decision brief', () => {
(records: Records) => { records[6]!.message.content[0]!.is_error = true; },
]) expect(matches(replay(change))).toBe(false);
});
test('the new free test and captured fixture select the paid mode-routing case', () => {
for (const file of ['test/ceo-expansion-auq.test.ts', 'test/fixtures/ceo-expansion-auq-ac.json']) {
expect(selectTests([file], E2E_TOUCHFILES, []).selected).toEqual(['plan-ceo-mode-routing']);
}
});
});
-10
View File
@@ -1,7 +1,6 @@
import { describe, expect, test } from 'bun:test';
import { findCeoModeOption, hasPostAnswerCeoPosture, hasNativePostAnswerCeoPosture, nativeCeoModeAnswer, nextCeoModeNavigation, nextCeoPostureContinuation } from './helpers/ceo-mode-option';
import { parseNumberedOptions, stripAnsi, planCountQuestionInput, nativePlanCallFingerprint } from './helpers/claude-pty-runner';
import { E2E_TOUCHFILES, selectTests } from './helpers/touchfiles';
import type { PlanCountTranscript } from './helpers/plan-count-transcript';
import * as fs from 'node:fs';
import * as os from 'node:os';
@@ -90,15 +89,6 @@ describe('CEO mode option matching', () => {
{ index: 2, label: 'Choose a plan │ SCOPE EXPANSION' },
], 'HOLD SCOPE')).toBeNull();
});
test('the shared parser selects all callers while mode-specific regressions stay scoped', () => {
expect(selectTests(['test/helpers/ceo-mode-option.ts'], E2E_TOUCHFILES).selected)
.toEqual(['plan-ceo-mode-routing', 'plan-ceo-split-overflow']);
expect(selectTests(['test/ceo-mode-option.test.ts'], E2E_TOUCHFILES).selected)
.toEqual(['plan-ceo-mode-routing', 'plan-ceo-split-overflow']);
expect(selectTests(['test/pty-option-selection.test.ts'], E2E_TOUCHFILES).selected)
.toEqual(['plan-ceo-mode-routing']);
});
});
describe('CEO mode navigation replay', () => {
-4
View File
@@ -4,7 +4,6 @@ import os from 'node:os';
import path from 'node:path';
import {spawnSync} from 'node:child_process';
import {getQuestion} from '../scripts/question-registry';
import {E2E_TOUCHFILES} from './helpers/touchfiles-data';
import {CARVE_GUARDS} from './helpers/carve-guards';
const root=path.resolve(import.meta.dir,'..');
const temp=fs.mkdtempSync(path.join(os.tmpdir(),'gstack-ceo-mode-preference-'));
@@ -126,9 +125,6 @@ test('only an explicit user selection or enabled successful mode check bypasses
expect(document).toContain('Note: options differ in kind, not coverage — no completeness score.');
}
});
test('the new render/runtime regression belongs to the existing auto-decide owner',()=>{
expect(Object.entries(E2E_TOUCHFILES).filter(([,v])=>v.includes('test/ceo-mode-preference-al.test.ts')).map(([k])=>k)).toEqual(['auto-decide-preserved']);
});
test('rendered mode contract stays within the existing canonical skeleton cap',()=>{
// --out-dir changes section-link roots only. Undo that output-location
// substitution before measuring the same canonical bytes as parity-suite.
-4
View File
@@ -7,7 +7,6 @@ import { execFileSync } from 'node:child_process';
import { nextCeoModeNavigation } from './helpers/ceo-mode-option';
import { planCountQuestionInput } from './helpers/claude-pty-runner';
import type { NativePlanQuestionCall } from './helpers/plan-count-transcript';
import { E2E_TOUCHFILES, selectTests } from './helpers/touchfiles';
import priorCalls from './fixtures/ceo-mode-prerequisite-o-calls.json';
import directProceedCall from './fixtures/ceo-mode-prerequisite-q-call.json';
import fullAd from './fixtures/ceo-mode-full-ad.json';
@@ -88,9 +87,6 @@ describe('CEO mode prerequisite navigation', () => {
const modes='☐ Review mode\nWhich mode?\n❯ 1. SELECTIVE EXPANSION\n 2. HOLD SCOPE\n 3. SCOPE EXPANSION\n 4. SCOPE REDUCTION';
for(const [mode,index] of [['HOLD SCOPE',2],['SCOPE EXPANSION',3]] as const){const a=nextCeoModeNavigation(modes,mode,new Set());expect(a.kind).toBe('mode');if(a.kind==='mode')expect(a.index).toBe(index);}
});
test('fixture and free regression select only the mode-routing eval', () => {
for(const file of ['test/ceo-mode-prerequisite.test.ts','test/fixtures/ceo-mode-prerequisite-o-calls.json','test/fixtures/ceo-mode-prerequisite-q-call.json'])expect(selectTests([file],E2E_TOUCHFILES).selected).toEqual(['plan-ceo-mode-routing']);
});
});
for(const fixtureIndex of [1,2,3,4])test.skipIf(process.platform==='win32')(`fake native PTY skips prerequisite ${fixtureIndex} and confirms target posture`,async()=>{
const dir=fs.mkdtempSync(path.join(os.tmpdir(),'ceo-mode-prerequisite-')),fake=path.join(dir,'fake-claude'),events=path.join(dir,'events.jsonl'),worker=path.join(dir,'worker.ts');
-26
View File
@@ -1,26 +0,0 @@
import { describe, expect, test } from 'bun:test';
import { E2E_TIERS, E2E_TOUCHFILES, GLOBAL_TOUCHFILES, selectTests } from './helpers/touchfiles';
function selectedBy(file: string) {
return selectTests([file], E2E_TOUCHFILES, GLOBAL_TOUCHFILES).selected;
}
describe('Codex eval selection', () => {
test('recording-helper changes select every recorded Codex case in the periodic tier', () => {
const selected = selectedBy('test/helpers/codex-eval.ts');
expect(selected.sort()).toEqual([
'codex-discover-skill',
'codex-review-findings',
'codex-sol-scope-termination',
].sort());
expect(selected.every((id) => E2E_TIERS[id] === 'periodic')).toBe(true);
});
test('Sol fixture generation changes select its periodic case', () => {
for (const file of ['test/helpers/sol-skill-fixture.ts', 'test/sol-skill-fixture.test.ts']) {
expect(selectedBy(file)).toEqual(['codex-sol-scope-termination']);
}
expect(E2E_TIERS['codex-sol-scope-termination']).toBe('periodic');
});
});
+5 -3
View File
@@ -253,12 +253,14 @@ describe('cookie workflow judge input', () => {
});
test('each owned dependency selects this judge in the fast PR profile', () => {
for (const file of ['setup-browser-cookies/SKILL.md.tmpl', 'setup-browser-cookies/SKILL.md', 'BROWSER.md', 'test/helpers/cookie-workflow-judge-input.ts', 'test/cookie-workflow-judge-input.test.ts', 'test/helpers/cookie-workflow-manual-review.ts', 'test/cookie-workflow-manual-review.test.ts', 'test/helpers/manual-judge-review-fixture.ts', '.github/cookie-workflow-manual-review.json']) {
for (const file of ['setup-browser-cookies/SKILL.md.tmpl', 'setup-browser-cookies/SKILL.md', 'BROWSER.md', 'test/helpers/cookie-workflow-judge-input.ts', 'test/helpers/cookie-workflow-manual-review.ts', 'test/helpers/manual-judge-review-fixture.ts', '.github/cookie-workflow-manual-review.json']) {
const selectedJudges = selectTests([file], LLM_JUDGE_TOUCHFILES).selected;
expect(selectedJudges).toEqual([NAME]);
// Helpers the judge file imports select every judge that file registers (derived closure).
const exact = !file.startsWith('test/helpers/') || file === 'test/helpers/manual-judge-review-fixture.ts';
if (exact) expect(selectedJudges).toEqual([NAME]); else expect(selectedJudges).toContain(NAME);
const selectedE2E = selectTests([file], E2E_TOUCHFILES).selected;
const profile = selectPrProfile({ changedFiles: [file], selectedJudges, selectedE2E });
expect(profile.judges).toEqual([NAME]);
if (exact) expect(profile.judges).toEqual([NAME]); else expect(profile.judges).toContain(NAME);
expect(profile.deferredPromptFiles).toEqual([]);
expect(profile.missingCoverage).toEqual([]);
expect(profile.needsFullValidation).toBe(false);
-8
View File
@@ -4,8 +4,6 @@ import fixture from './fixtures/coverage-audit-ae.json';
import ciDiagrams from './fixtures/coverage-audit-ci-diagrams.json';
import { coverageAuditVerdict } from './helpers/coverage-audit-evidence';
import { recordE2E } from './helpers/e2e-helpers';
import { E2E_TOUCHFILES, LLM_JUDGE_TOUCHFILES, GLOBAL_TOUCHFILES } from './helpers/touchfiles';
import { selectTests } from './helpers/test-selection';
import fixture_coverage_audit_af from './fixtures/coverage-audit-af.json';
import { posix } from 'node:path';
import { win32 } from 'node:path';
@@ -450,12 +448,6 @@ Guard clauses tested: 0 / 4
expect(entries).toHaveLength(1);expect(entries[0].passed).toBe(valid);expect(entries[0].error).toBe(valid?undefined:v.failures.join('; '));
}
});
test('coverage evidence files select their exact registered consumers',()=>{
for(const file of ['test/helpers/coverage-audit-evidence.ts','test/coverage-audit-evidence.test.ts','test/fixtures/coverage-audit-ae.json','test/fixtures/coverage-audit-ci-diagrams.json']){
expect(selectTests([file],E2E_TOUCHFILES,GLOBAL_TOUCHFILES).selected.sort()).toEqual(file === 'test/helpers/coverage-audit-evidence.ts' || file === 'test/coverage-audit-evidence.test.ts' ? ['plan-eng-coverage-audit','review-coverage-audit','ship-coverage-audit'] : ['plan-eng-coverage-audit','review-coverage-audit']);
expect(selectTests([file],LLM_JUDGE_TOUCHFILES,GLOBAL_TOUCHFILES).selected).toEqual([]);
}
});
});
describe('coverage-audit-af', () => {
-8
View File
@@ -1,8 +1,6 @@
import { expect, test } from 'bun:test';
import { readFileSync } from 'node:fs';
import { extractDesignResearchContract } from './helpers/skill-fixture';
import { E2E_TOUCHFILES, selectTests } from './helpers/touchfiles';
const source = readFileSync(new URL('../design-consultation/SKILL.md', import.meta.url), 'utf8');
test('research-only fixture supplies actual readiness and egress dependencies without expanding scope', () => {
@@ -23,9 +21,3 @@ test.each(['## BROWSER SETUP', '### Rules for driving a real browser', '## Web r
'## Phase 2: Research', '**Step 1: Identify', '**Step 2: Visual research', '_aside_exec()'])('missing %s fails closed before a paid run', marker => {
expect(() => extractDesignResearchContract(source.replace(marker, 'REMOVED'))).toThrow();
});
test('research fixture changes select their actual live consumer', () => {
for (const file of ['test/helpers/skill-fixture.ts', 'test/design-research-fixture.test.ts']) {
expect(selectTests([file], E2E_TOUCHFILES, []).selected).toContain('design-consultation-research');
}
});
@@ -27,8 +27,7 @@ test('DX artifact calibrations keep four acknowledged choices and vary only comp
test('the separate DX calibration has a canonical periodic selector and all direct fixture inputs', () => {
expect(E2E_TIERS[ID]).toBe('periodic');
for (const file of [`test/skill-e2e-${ID}.test.ts`, 'test/fixtures/devex-peer-comparison-classification.ts',
'test/devex-peer-comparison-calibration.test.ts']) {
for (const file of [`test/skill-e2e-${ID}.test.ts`, 'test/fixtures/devex-peer-comparison-classification.ts']) {
expect(fs.existsSync(path.join(ROOT, file))).toBe(true);
expect(selectTests([file], E2E_TOUCHFILES, []).selected).toEqual([ID]);
}
-13
View File
@@ -6,7 +6,6 @@ import {HOST_PATHS, type TemplateContext} from '../scripts/resolvers/types';
import {generatePreamble} from '../scripts/resolvers/preamble';
import {generateAskUserFormat} from '../scripts/resolvers/preamble/generate-ask-user-format';
import {generateGBrainContextLoad} from '../scripts/resolvers/gbrain';
import {E2E_TOUCHFILES, LLM_JUDGE_TOUCHFILES, selectTests} from './helpers/touchfiles';
import {readWorkflowJudgeInput} from './helpers/workflow-judge-input';
const template = fs.readFileSync(path.join(import.meta.dir, '../plan-eng-review/SKILL.md.tmpl'), 'utf8');
@@ -108,18 +107,6 @@ test('Eng alone defers canonical question rules until scope and keeps one counte
}
}
});
test('the regression selects the same paid owners as the Eng template', () => {
for (const map of [E2E_TOUCHFILES, LLM_JUDGE_TOUCHFILES]) {
expect(selectTests(['test/eng-scope-entry-ap.test.ts'], map, []).selected)
.toEqual(selectTests(['plan-eng-review/SKILL.md.tmpl'], map, []).selected);
for (const paths of Object.values(map)) for (let i = 0; i < paths.length; i++) {
expect(Object.hasOwn(paths, i)).toBe(true);
expect(typeof paths[i]).toBe('string');
}
}
});
test('the full evaluated bundle routes startup into ordered preparation before scope analysis', () => {
const input = readWorkflowJudgeInput({root:path.join(import.meta.dir, '..'), skillPath:'plan-eng-review/SKILL.md',
startMarker:'# Plan Review Mode', endMarker:null});
-10
View File
@@ -8,8 +8,6 @@ import { fakePlanSeedPrelude } from './helpers/fake-plan-seed';
import fixture from './fixtures/eng-seeded-completion-ai.json';
import { classifyVisible, extractPlanFilePath } from './helpers/claude-pty-runner';
import * as predicates from './helpers/claude-pty-runner';
import { selectTests, E2E_TOUCHFILES } from './helpers/touchfiles';
const gate = '─────\nClaude has written up a plan and is ready to execute. Would you like to proceed?\n❯ 1. Yes, and use auto mode\n2. Yes, manually approve edits\n3. Tell Claude what to change';
const compactGate = 'Exit plan mode?\nClaude wants to exit plan mode\n❯ 1. Yes, and switch to default (ask each time) for this session\n2. No';
const question = 'Which runner should the plan use?\nA) Use the built-in runner\nB) Build a custom runner\nRecommendation: A because it avoids duplicate scheduling logic.\nReply with A or B.';
@@ -181,11 +179,3 @@ test('rejected completion does not erase a genuine earlier question or change un
const unseeded = await mockedObservation([gate.replace('❯ ', '')], 'waiting', false);
expect(unseeded.obs.outcome).toBe('plan_ready'); expect(unseeded.judged).toBe(0);
});
test('completion evidence dependencies select exactly the seeded observation owners', () => {
const owners = ['plan-ceo-review-plan-mode', 'plan-eng-review-plan-mode', 'plan-design-review-plan-mode',
'plan-devex-review-plan-mode', 'plan-mode-no-op', 'auto-decide-preserved'].sort();
for (const file of ['test/eng-seeded-completion-ai.test.ts', 'test/fixtures/eng-seeded-completion-ai.json']) {
expect(selectTests([file], E2E_TOUCHFILES).selected.sort()).toEqual(owners);
}
});
-36
View File
@@ -1,36 +0,0 @@
import { describe, expect, test } from 'bun:test';
import { E2E_TOUCHFILES, E2E_TIERS, GLOBAL_TOUCHFILES, LLM_JUDGE_TOUCHFILES } from './helpers/touchfiles-data';
import { selectTests } from './helpers/test-selection';
describe('fake impeccable engine selection', () => {
const helper = 'test/helpers/fake-impeccable.ts';
const consumers = [
'design-html-slop-gate',
'design-review-detector-shim',
'design-review-detector-shim-dom',
'design-review-plugin-handoff',
'review-design-lite',
];
test('a helper-only edit selects every paid consumer without global expansion', () => {
const result = selectTests([helper], E2E_TOUCHFILES);
expect(result.selected.slice().sort()).toEqual(consumers);
expect(result.reason).toBe('diff');
expect(result.skipped).toContain('design-consultation-core');
expect(GLOBAL_TOUCHFILES).not.toContain(helper);
expect(selectTests([helper], LLM_JUDGE_TOUCHFILES).selected).toEqual([]);
});
test('the fake executable and captured output retain the same consumers and tiers', () => {
for (const changed of ['test/fixtures/fake-impeccable.ts', 'test/fixtures/impeccable-detect-sample.json']) {
expect(selectTests([changed], E2E_TOUCHFILES).selected.slice().sort()).toEqual(consumers);
}
expect(consumers.map(name => [name, E2E_TIERS[name]])).toEqual([
['design-html-slop-gate', 'periodic'],
['design-review-detector-shim', 'gate'],
['design-review-detector-shim-dom', 'gate'],
['design-review-plugin-handoff', 'gate'],
['review-design-lite', 'periodic'],
]);
});
});
-93
View File
@@ -1,93 +0,0 @@
{
"cwd": "/tmp/gstack-paid-shard-MPtf0T/tmp/gstack-autoplan-chain-LukJXD",
"config": "/tmp/gstack-paid-shard-MPtf0T/tmp/gstack-hermetic-3587976-PXLrEr/with-skills/.claude",
"stateRoot": "/tmp/gstack-paid-shard-MPtf0T/tmp/gstack-hermetic-3587976-PXLrEr/skill-home-cMZrbW/.gstack",
"hook": {
"version": 1,
"cwd": "/tmp/gstack-paid-shard-MPtf0T/tmp/gstack-autoplan-chain-LukJXD",
"config": "/tmp/gstack-paid-shard-MPtf0T/tmp/gstack-hermetic-3587976-PXLrEr/with-skills/.claude",
"stateRoot": "/tmp/gstack-paid-shard-MPtf0T/tmp/gstack-hermetic-3587976-PXLrEr/skill-home-cMZrbW/.gstack",
"seenIds": [
"toolu_019ngUUTCGyDufyLQaN9Tvgm"
],
"pending": {
"source": "pre_tool_use",
"sessionId": "037c9f5e-7035-45e2-935d-0b950c435930",
"toolUseId": "toolu_019ngUUTCGyDufyLQaN9Tvgm",
"tool": "Edit",
"file": "/tmp/gstack-paid-shard-MPtf0T/tmp/gstack-hermetic-3587976-PXLrEr/skill-home-cMZrbW/.gstack/projects/gstack-autoplan-chain-LukJXD/ceo-plans/2026-09-10-user-dashboard.md",
"timestamp": "2026-09-10T14:35:35.363Z",
"transcriptPath": "/tmp/gstack-paid-shard-MPtf0T/tmp/gstack-hermetic-3587976-PXLrEr/with-skills/.claude/projects/-tmp-gstack-paid-shard-MPtf0T-tmp-gstack-autoplan-chain-LukJXD/037c9f5e-7035-45e2-935d-0b950c435930.jsonl",
"editDigest": {
"version": 1,
"beforeSHA256": "6771404ca60011824af336f0a7011e3aba465b8728c011eef935a4b847e72bdd",
"requestSHA256": "7ea64ad22d29d9c779b6e945119ea238e2f40862a368ca518100626a1e7978de",
"oldLineHashes": [
"95b34a72ab3b36711dc4f7cffc93cfe9e4ac45adaff3cbe06170576bb2b7787d"
],
"newLineHashes": [
"b69061a320491c4d23ea3b0e11040b1edfdf54c90d67287236c5b49695b74a6d",
"f01cbe18eb0051492cb3e8740542a491038881c5f23dac05003dfa84a4a59087",
"2a23528279bef0c9dcde730b41c9cb25768c8d6de1d40195181e48efa8e6a295",
"8110f2d8d27cb7e397562be0be38bc995e33cdf5d570d3d18aae23fe83db5116",
"4fef7666a0b82562e292a3d53f26f0721c09a74ceb0a30a970351f213468b07e",
"2bbfa283b38391e7d66c205292efb1e8565120fa337a098863f4758576fe1239",
"be4ed8d0778c7ba2036e19657ac496f2b24ee5d3ceb4d1240c3f7993567f4f89",
"861a718d78d38dd744ab59540c3139c5283d0e67a3deed5b41138f9581084d34",
"418ec10dc288464be75940c80f56faa734f5380ed8c2a957dcc52ed75f60f942",
"a59e48fe92bfcea3ec1cad39996f1a01039861faaa75daa251be8d64b102abdc",
"c701beb15c91ba566b32cd004f4ba46eb8f317061549c0f699041c151065a387",
"44aa4bd0d2a4cc4cbce51a9ea6bc485d5fb2cfbebfc01a1fe275d8e165f51c92",
"e8fd6eaf078d6ccc6028e6213e12acfa82511902136e4aec48e1398990582884",
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"cfc849f68e95805d8b84b46121a94a5ee70daf8fe374e20224d88a4290553089",
"1e619e0fe087d96a85514e4f9f741b2aae28e3c65a73f3833b6c1869e282ed5b",
"0ef460f920e57467c135c9b9605f343e189fc4397565d14b12d0fc9ff5f31e4f",
"d9134cd12c765f0e72b00438c6f70fa3af52d4a4602dfb27c8ae4fe29a7ee4cc",
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"95b34a72ab3b36711dc4f7cffc93cfe9e4ac45adaff3cbe06170576bb2b7787d"
]
}
},
"sessionId": "037c9f5e-7035-45e2-935d-0b950c435930"
},
"before": "---\nstatus: ACTIVE\n---\n# CEO Plan: User Dashboard Page\nGenerated by /plan-ceo-review (via /autoplan) on 2026-09-10\nBranch: main | Mode: SELECTIVE EXPANSION\nRepo: gstack-autoplan-chain-LukJXD (local, no remote)\n\n## Problem and goal\n\nMembers of the existing single-role workspace visit three separate pages after login to resume work, check alerts, and inspect recent changes. One team walkthrough measured a median of 75 seconds to find the next item. The dashboard at `/dashboard` is meant to cut the median login-to-first-completed-task time from ~75 s to 45 s (a 40 % reduction), with completed-task rate and permission-error rate as guardrails.\n\n**Primary ship metric:** median login-to-first-completed-task time, treatment vs control. **Ship threshold:** ≥ 40 % reduction (equivalent to 75 → 45 s) sustained over the ≥ 2-week measurement window with no guardrail regression. **Diagnostic split (not a ship gate):** login→first-action-start (the leg the dashboard moves) and action-start→completion (unchanged by this plan), both derivable from the existing login / action start / action completion events, so the read-out attributes the delta correctly. The production baseline for all three is computed from existing events before the cohort opens; the 75 s walkthrough figure is not load-bearing.\n\n**Experiment design.** Assignment is a deterministic hash of member id, fixed for the experiment's duration. Default split 10 % treatment / 90 % control. Minimum sample: ≥ 300 logins per arm within the window; if the workspace's active-member count makes that unreachable at 10 % (record the count at approval), switch to a 50/50 split, and if still unreachable, fall back to a before/after comparison over the same window and say so in the read-out. `/dashboard` is flag-gated (below), so control members cannot reach it and contaminate the read-out.\n\n## Vision\n\n### 10x Check\nThe dashboard becomes the member's assistant rather than a summary page: a ranked \"next item\" (\"You have 2 items due today\"), alerts grouped by source, small tasks completed inline, live updates as teammates act, and a home that other features publish panels into. Concrete shape: ranking service over the action registry, a panel registry, a push channel. Human ~4-6 weeks / CC ~2-3 days. Out of this plan's blast radius; the personalisation plan owns it. This plan lays the seam (per-panel envelopes + a shared panel shell) without building the platform.\n\n### Platonic Ideal\nSkipped (SELECTIVE EXPANSION).\n\n## Baseline held (plan scope)\n- `/dashboard` page with Quick actions, Notifications, Recent activity panels; Tailwind, mobile-first (sm/md/lg).\n- Loading skeleton, empty, error, success per panel; hover and focus-visible on every control.\n- \"Mark all as read\" confirmation modal on the existing dialog primitive.\n- Toast feedback for actions.\n- `GET /api/dashboard` aggregate over existing PostgreSQL tables; no schema change.\n- Out of scope by the user: dark mode, personalisation.\n\n## Implementation approach chosen\nApproach A: aggregate endpoint composed server-side from the existing list methods and action registry, returning per-panel result envelopes so one failing panel never sinks the page. Alternatives: B client-side composition of three existing endpoints (7/10, close second, surfaced as taste decision T1); C smart post-login redirect + shell badge (4/10 against the stated goal, rejected).\n\n**If the Final Gate selects B instead of A:** the \"Endpoint\", \"Response shape\", and \"Retry\" paragraphs below are replaced by three per-panel fetch hooks wrapping the existing list endpoints and a small eligibility endpoint over the registry; each hook produces the same `Envelope<T>` client-side, so panel states, empty CTAs, mark-all-read, latest-wins, redirect precedence, caching headers, toast, accessibility, analytics, and rollout are unchanged. Composer tests become hook tests. **If the gate selects dashboard-local for T3:** the toast code moves under `src/components/dashboard/` with the same API and the same live-region rule; nothing else changes.\n\n## Verified preconditions (confirm before implementation; each has a fallback)\n- **Bulk-read API accepts a snapshot time.** The plan's contracts section states it \"marks only notifications at or before the supplied snapshot time\". Confirm the parameter name and type. If it turns out not to exist, mark-all-read cannot be made safe against later arrivals and the modal flow is **blocked** until the API gains the parameter (this becomes the same API work E8 needs; raise at the gate, do not ship a clock-unsafe version).\n- **Bulk-read API returns the affected count.** Confirm; otherwise the success toast reads \"Marked all as read\" without a number.\n- **Feature-flag system supports stable per-member assignment** (hash of member id). Confirm; otherwise implement the hash in the redirect module and store only the flag's on/off and percentage in the flag sLine truncated
"viewport": " +t. \n 139 +- **Snapshot consistency.** Notifications rows, `unreadTotal`, and `now()` come from a single statement (CTE) so t\n +hey share one READ COMMITTED snapshot. Query budget via `SET LOCAL statement_timeout = '2s'` inside that statement\n +'s transaction (or the driver's per-query timeout option); the \"timed-out query releases its connection\" test asse\n +rts on pool metrics, not on the promise alone. \n 140 +- **Route gating in a client-rendered app.** The page route performs a client-side redirect to the current landing\n + after the flag lookup (no server 302 unless the app already server-renders routes); `GET /api/dashboard` returnin\n +g 404 for flag-off members is the authoritative gate. \n 141 +- **Forcing panel states in tests.** Playwright uses `page.route()` interception on `/api/dashboard` and the bulk-\n +read route to inject 503 / per-panel `ok:false` / empty payloads; no test-only headers in production builds. \n 142 +- **Identifiers.** The create action is `actionId = 'create_item'` (from the registry's stable ids); `fetchedAt` i\n +s ISO 8601 UTC with milliseconds; the 44 px target rule applies to every interactive control inside the panels (ac\n +tions, Retry, See all, Mark all as read). \n 143 + \n 144 +## Reviewer Concerns (unresolved after 3 iterations) \n 145 +- **Snapshot window (r3 #5).** A notification inserted in a transaction whose `now()` predates `fetchedAt` but whi\n +ch commits after the dashboard read has `created_at <= fetchedAt`, is invisible to the list, and is still marked r\n +ead. Accepted and documented: the window is the duration of an in-flight insert transaction (milliseconds), the ex\n +isting bulk-read contract is clock-based, and changing it to id-based is the E8-adjacent API work already deferred\n +. Record as a known limitation in the JSDoc on the mark-all-read handler. \n 146 +- **Provisional approach vs open taste items (r2 #4, r3 #6).** The reviewer wants T1/T3 closed or A/E7 marked prov\n +isional. They are provisional by design: /autoplan surfaces taste decisions at one Final Gate and the fallback par\n +agraphs define what changes. Not a contradiction to resolve in this document. \n 147 +- **Population size (r3 #14).** The single-workspace population may be too small for the default design; the fallb\n +acks exist, and the member count is now recorded before R1 starts. \n 148 + \n 149 ## Taste decisions carried to the Final Gate\n 150 - T1 aggregate endpoint (A) vs client-side composition (B) — open; the B fallback paragraph above states exactly w\n hat changes.\n 151 - T2 confirmation modal for Mark all as read — recorded decision, surfaced for information: the independent review\n er preferred direct action + undo, but undo (E8) needs a new mutation API and is deferred, so the modal stays unle\n ss E8 is pulled into scope.\n╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌\n Do you want to make this edit to 2026-09-10-user-dashboard.md?\n ❯ 1. Yes\n 2. Yes, and switch to accept edits (auto-approve file edits and common file commands) for this session (shift+tab)\n 3. No\n\n Esc to cancel · Tab to amend\n",
"request": {
"old_string": "## Taste decisions carried to the Final Gate",
"new_string": "## Iteration-3 amendments (override earlier wording where they conflict)\n- **Guardrail bounds.** Completed-task rate in treatment must not be lower than control by more than 2 percentage points; permission-error rate must not be higher than control by more than 1 percentage point, both over the same window.\n- **Control-arm assignment recorded.** Emit `dashboard_assignment{cohort, hashVersion}` on the existing login event for every member (both arms); record the hash salt/version at approval. `dashboard_viewed` remains treatment-only.\n- **Ship-rule estimator.** Unit of analysis is the member (first login-to-first-completed-task per member per day, then per-member median). Estimator: bootstrap 95 % CI on the difference of medians; ship when the CI lower bound shows ≥ 40 % reduction. \"≥ 300 logins per arm\" becomes \"≥ 300 member-days per arm\".\n- **Record the active-member count before starting R1**, not after; choose the split then.\n- **Whole-response failures on the GET.** 503 `DashboardUnavailable` or a network/parse failure → all three panels ERROR with one shared page-level Retry; 404 (assignment flipped off mid-session) → client redirects to the current landing; 401 → login. Envelope codes remain per-panel only.\n- **Panel state model.** `{ status: LOADING | EMPTY | ERROR | SUCCESS, refreshing: boolean }`. `status` derives only from the last settled envelope; `refreshing` is set at request start when the panel already has a settled status other than LOADING, and cleared on settle. EMPTY panels refresh with their empty copy still rendered. The Mark-all-read trigger stays rendered but disabled while `refreshing`; it is rendered only when `status === SUCCESS && unreadTotal > 0`.\n- **CSRF vs membership 403.** Retry-once applies only when the existing client's typed error indicates a CSRF failure (its existing discriminator, body code or header); a membership 403 shows the access message with no retry.\n- **Preconditions heading** is to be read as \"Preconditions to verify before implementation\". The bulk-read semantic requirement is: it marks read only notifications with `created_at <= snapshot` by the DB clock and is idempotent.\n- **Snapshot consistency.** Notifications rows, `unreadTotal`, and `now()` come from a single statement (CTE) so they share one READ COMMITTED snapshot. Query budget via `SET LOCAL statement_timeout = '2s'` inside that statement's transaction (or the driver's per-query timeout option); the \"timed-out query releases its connection\" test asserts on pool metrics, not on the promise alone.\n- **Route gating in a client-rendered app.** The page route performs a client-side redirect to the current landing after the flag lookup (no server 302 unless the app already server-renders routes); `GET /api/dashboard` returning 404 for flag-off members is the authoritative gate.\n- **Forcing panel states in tests.** Playwright uses `page.route()` interception on `/api/dashboard` and the bulk-read route to inject 503 / per-panel `ok:false` / empty payloads; no test-only headers in production builds.\n- **Identifiers.** The create action is `actionId = 'create_item'` (from the registry's stable ids); `fetchedAt` is ISO 8601 UTC with milliseconds; the 44 px target rule applies to every interactive control inside the panels (actions, Retry, See all, Mark all as read).\n\n## Reviewer Concerns (unresolved after 3 iterations)\n- **Snapshot window (r3 #5).** A notification inserted in a transaction whose `now()` predates `fetchedAt` but which commits after the dashboard read has `created_at <= fetchedAt`, is invisible to the list, and is still marked read. Accepted and documented: the window is the duration of an in-flight insert transaction (milliseconds), the existing bulk-read contract is clock-based, and changing it to id-based is the E8-adjacent API work already deferred. Record as a known limitation in the JSDoc on the mark-all-read handler.\n- **Provisional approach vs open taste items (r2 #4, r3 #6).** The reviewer wants T1/T3 closed or A/E7 marked provisional. They are provisional by design: /autoplan surfaces taste decisions at one Final Gate and the fallback paragraphs define what changes. Not a contradiction to resolve in this document.\n- **Population size (r3 #14).** The single-workspace population may be too small for the default design; the fallbacks exist, and the member count is now recorded before R1 starts.\n\n## Taste decisions carried to the Final Gate"
},
"publicTools": [
{
"sessionId": "037c9f5e-7035-45e2-935d-0b950c435930",
"timestamp": "2026-09-10T14:32:00.204Z",
"toolUseId": "toolu_01A78r3KVhp1i9RAkz57ECSC",
"kind": "use",
"name": "Write",
"input": {
"file_path": "/tmp/gstack-paid-shard-MPtf0T/tmp/gstack-hermetic-3587976-PXLrEr/skill-home-cMZrbW/.gstack/projects/gstack-autoplan-chain-LukJXD/ceo-plans/2026-09-10-user-dashboard.md",
"content": "---\nstatus: ACTIVE\n---\n# CEO Plan: User Dashboard Page\nGenerated by /plan-ceo-review (via /autoplan) on 2026-09-10\nBranch: main | Mode: SELECTIVE EXPANSION\nRepo: gstack-autoplan-chain-LukJXD (local, no remote)\n\n## Problem and goal\n\nMembers of the existing single-role workspace visit three separate pages after login to resume work, check alerts, and inspect recent changes. One team walkthrough measured a median of 75 seconds to find the next item. The dashboard at `/dashboard` is meant to cut the median login-to-first-completed-task time from ~75 s to 45 s (a 40 % reduction), with completed-task rate and permission-error rate as guardrails.\n\n**Primary ship metric:** median login-to-first-completed-task time, treatment vs control. **Ship threshold:** ≥ 40 % reduction (equivalent to 75 → 45 s) sustained over the ≥ 2-week measurement window with no guardrail regression. **Diagnostic split (not a ship gate):** login→first-action-start (the leg the dashboard moves) and action-start→completion (unchanged by this plan), both derivable from the existing login / action start / action completion events, so the read-out attributes the delta correctly. The production baseline for all three is computed from existing events before the cohort opens; the 75 s walkthrough figure is not load-bearing.\n\n**Experiment design.** Assignment is a deterministic hash of member id, fixed for the experiment's duration. Default split 10 % treatment / 90 % control. Minimum sample: ≥ 300 logins per arm within the window; if the workspace's active-member count makes that unreachable at 10 % (record the count at approval), switch to a 50/50 split, and if still unreachable, fall back to a before/after comparison over the same window and say so in the read-out. `/dashboard` is flag-gated (below), so control members cannot reach it and contaminate the read-out.\n\n## Vision\n\n### 10x Check\nThe dashboard becomes the member's assistant rather than a summary page: a ranked \"next item\" (\"You have 2 items due today\"), alerts grouped by source, small tasks completed inline, live updates as teammates act, and a home that other features publish panels into. Concrete shape: ranking service over the action registry, a panel registry, a push channel. Human ~4-6 weeks / CC ~2-3 days. Out of this plan's blast radius; the personalisation plan owns it. This plan lays the seam (per-panel envelopes + a shared panel shell) without building the platform.\n\n### Platonic Ideal\nSkipped (SELECTIVE EXPANSION).\n\n## Baseline held (plan scope)\n- `/dashboard` page with Quick actions, Notifications, Recent activity panels; Tailwind, mobile-first (sm/md/lg).\n- Loading skeleton, empty, error, success per panel; hover and focus-visible on every control.\n- \"Mark all as read\" confirmation modal on the existing dialog primitive.\n- Toast feedback for actions.\n- `GET /api/dashboard` aggregate over existing PostgreSQL tables; no schema change.\n- Out of scope by the user: dark mode, personalisation.\n\n## Implementation approach chosen\nApproach A: aggregate endpoint composed server-side from the existing list methods and action registry, returning per-panel result envelopes so one failing panel never sinks the page. Alternatives: B client-side composition of three existing endpoints (7/10, close second, surfaced as taste decision T1); C smart post-login redirect + shell badge (4/10 against the stated goal, rejected).\n\n**If the Final Gate selects B instead of A:** the \"Endpoint\", \"Response shape\", and \"Retry\" paragraphs below are replaced by three per-panel fetch hooks wrapping the existing list endpoints and a small eligibility endpoint over the registry; each hook produces the same `Envelope<T>` client-side, so panel states, empty CTAs, mark-all-read, latest-wins, redirect precedence, caching headers, toast, accessibility, analytics, and rollout are unchanged. Composer tests become hook tests. **If the gate selects dashboard-local for T3:** the toast code moves under `src/components/dashboard/` with the same API and the same live-region rule; nothing else changes.\n\n## Verified preconditions (confirm before implementation; each has a fallback)\n- **Bulk-read API accepts a snapshot time.** The plan's contracts section states it \"marks only notifications at or before the supplied snapshot time\". Confirm the parameter name and type. If it turns out not to exist, mark-all-read cannot be made safe against later arrivals and the modal flow is **blocked** until the API gains the parameter (this becomes the same API work E8 needs; raise at the gate, do not ship a clock-unsafe version).\n- **Bulk-read API returns the affected count.** Confirm; otherwise the success toast reads \"Marked all as read\" without a number.\n- **Feature-flag system supports stable per-member assignment** (hash of member id). Confirm; otherwise implement the hash in the redirect module and store only the flag's on/off and percentage in theLine truncated
},
"messageId": "msg_011CeuvH91RGhGXA5XHMPN7J",
"requestId": "req_011CeuvH6MgNDWkEkYtuWxs9"
},
{
"sessionId": "037c9f5e-7035-45e2-935d-0b950c435930",
"timestamp": "2026-09-10T14:32:00.969Z",
"toolUseId": "toolu_01A78r3KVhp1i9RAkz57ECSC",
"kind": "result",
"content": "The file /tmp/gstack-paid-shard-MPtf0T/tmp/gstack-hermetic-3587976-PXLrEr/skill-home-cMZrbW/.gstack/projects/gstack-autoplan-chain-LukJXD/ceo-plans/2026-09-10-user-dashboard.md has been updated successfully. (file state is current in your context — no need to Read it back)",
"isError": false
}
],
"provenance": {
"status": "Exact original request reconstruction independently equals original requestSHA; no new digest existed in the paid attempt.",
"requestSHA256": "7ea64ad22d29d9c779b6e945119ea238e2f40862a368ca518100626a1e7978de",
"beforeSHA256": "6771404ca60011824af336f0a7011e3aba465b8728c011eef935a4b847e72bdd",
"paneSHA256": "c5662a9c0d67ba04de8720c25d51378b4662266273cb186f48f7c3109abd2ee2",
"sourceProof": "ap-cropped-addition-plan-v1/proof.json",
"reconstruction": "ap-cropped-addition-request-reconstruction-plan-v1.json",
"publicTools": "Exact acknowledged same-file predecessor pair from full94 public events.",
"actualCoverage": "operator-cancelled-incomplete; no phase credit"
}
}
+71
View File
@@ -0,0 +1,71 @@
/**
* Derived touchfile rule: a paid test depends on every `test/helpers` and
* `test/fixtures` file it reaches through static imports, plus every such path
* named in a string literal inside that closure (fixtures read through `fs`).
* The result is a lower bound: a computed fixture path is declared by adding it
* to the key by hand.
*/
import * as fs from 'fs';
import * as path from 'path';
import { matchGlob } from './test-selection';
export interface ClosureEntry {
/** Repo-relative dependency path. */
file: string;
/** How the paid test reached it: the import chain, ending in `"literal"` for string references. */
chain: string[];
}
const LITERAL = /test\/(?:helpers|fixtures)\/[A-Za-z0-9_.\-/]+[A-Za-z0-9_]/g;
const scanner = new Bun.Transpiler({ loader: 'tsx' });
function resolveImport(root: string, from: string, specifier: string): string | null {
if (!specifier.startsWith('.')) return null;
const base = path.resolve(path.dirname(path.join(root, from)), specifier);
for (const candidate of [base, `${base}.ts`, base.replace(/\.js$/, '.ts'), path.join(base, 'index.ts')]) {
if (fs.existsSync(candidate) && fs.statSync(candidate).isFile()) return path.relative(root, candidate).split(path.sep).join('/');
}
return null;
}
/** Selection itself is diffed by map (diffTouchfileMaps), and test files are never dependencies. */
const SELECTION_MODULES = new Set(['test/helpers/touchfiles-data.ts', 'test/helpers/touchfiles.ts', 'test/helpers/test-selection.ts']);
const inScope = (file: string) => (file.startsWith('test/helpers/') || file.startsWith('test/fixtures/')) &&
!file.endsWith('.test.ts') && !SELECTION_MODULES.has(file);
/**
* Static test/helpers + test/fixtures closure of one paid test file, with literal fixture paths.
* Traversal stops at `boundary` files (the global touchfiles): an edit there already selects every test.
*/
export function paidTestClosure(root: string, testFile: string, boundary: ReadonlySet<string> = new Set()): ClosureEntry[] {
const seen = new Map<string, string[]>();
const queue: Array<{ file: string; chain: string[] }> = [{ file: testFile, chain: [testFile] }];
while (queue.length) {
const { file, chain } = queue.shift()!;
if (!/\.(ts|tsx|js|mjs)$/.test(file) || boundary.has(file)) continue;
const source = fs.readFileSync(path.join(root, file), 'utf8');
let imports: Array<{ path: string }> = [];
try { imports = scanner.scanImports(source); } catch { imports = []; }
for (const { path: specifier } of imports) {
const target = resolveImport(root, file, specifier);
if (!target || !inScope(target) || seen.has(target)) continue;
seen.set(target, [...chain, target]);
queue.push({ file: target, chain: [...chain, target] });
}
for (const match of source.match(LITERAL) ?? []) {
const absolute = path.join(root, match);
if (!inScope(match) || !fs.existsSync(absolute)) continue;
const literal = fs.statSync(absolute).isDirectory() ? `${match.replace(/\/$/, '')}/**` : match;
if (seen.has(literal)) continue;
seen.set(literal, [...chain, `"${match}"`]);
if (!literal.endsWith('/**')) queue.push({ file: literal, chain: [...chain, `"${match}"`] });
}
}
return [...seen].map(([file, chain]) => ({ file, chain }));
}
/** True when a dependency is selected by the key's own list or the global list. */
export function isCovered(file: string, patterns: readonly string[], globals: readonly string[]): boolean {
const probe = file.endsWith('/**') ? `${file.slice(0, -3)}/probe` : file;
return [...patterns, ...globals].some(pattern => pattern === file || matchGlob(probe, pattern));
}
File diff suppressed because it is too large. Load diff
-7
View File
@@ -8,17 +8,10 @@ import { getHermeticDirs, hermeticSkillsConfigDir } from './helpers/hermetic-env
import { refreshHermeticSkillRuntime, questionCompanionReadSettings, hermeticSkillRuntime } from './helpers/hermetic-skill-runtime';
import { pathToFileURL } from 'node:url';
import { createHash } from 'node:crypto';
import { E2E_TOUCHFILES, selectTests } from './helpers/touchfiles';
const ROOT = path.resolve(import.meta.dir, '..');
const digest = (file: string) => createHash('sha256').update(fs.readFileSync(file)).digest('hex');
describe('hermetic seeded PTY runtime', () => {
test('runtime helper and regression select every PTY consumer', () => {
const consumers = Object.entries(E2E_TOUCHFILES).filter(([, files]) => files.includes('test/helpers/claude-pty-runner.ts')).map(([name]) => name).sort();
expect(consumers.length).toBeGreaterThanOrEqual(15);
for (const file of ['test/helpers/hermetic-skill-runtime.ts', 'test/hermetic-skill-runtime.test.ts'])
expect(selectTests([file], E2E_TOUCHFILES).selected.sort()).toEqual(consumers);
});
test.skipIf(process.platform === 'win32')('uses current lazy files and tools with scoped access, preserving auth, caches, and explicit overrides', async () => {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'gstack-runtime-probe-'));
const operatorHome = path.join(dir, 'operator-home');
-10
View File
@@ -5,7 +5,6 @@ import * as path from 'node:path';
import { findNativeAutoDecision } from './helpers/native-auto-decide';
import { classifyVisible } from './helpers/claude-pty-runner';
import { readPlanCountTranscript, type NativePublicToolEvent } from './helpers/plan-count-transcript';
import { E2E_TOUCHFILES, selectTests } from './helpers/touchfiles';
import capture_auto_decide_current_declaration from './fixtures/auto-decide-current-declaration-6aef.json';
import capture_auto_decide_explanatory_mode from './fixtures/auto-decide-explanatory-mode-043a.json';
import captured749_auto_decide_explanatory_mode from './fixtures/auto-decide-explanatory-mode-749df.json';
@@ -109,15 +108,6 @@ test('the native reader cannot promote foreign cwd, child, user or tool-result t
}
}finally{fs.rmSync(dir,{recursive:true,force:true});}
});
test('new native annotation dependencies retain all existing observation caller owners',()=>{
const expected=['plan-ceo-review-plan-mode','plan-eng-review-plan-mode','plan-design-review-plan-mode','plan-devex-review-plan-mode','plan-mode-no-op','office-hours-auto-mode','auto-decide-preserved'];
for(const file of ['test/helpers/native-auto-decide.ts','test/native-auto-decide.test.ts','test/native-auto-decide-pty.test.ts','test/fixtures/native-auto-decide-ag.json']){
const owners=Object.entries(E2E_TOUCHFILES).filter(([,paths])=>paths.includes(file)).map(([name])=>name);expect(owners).toEqual(expected);
expect(selectTests([file],E2E_TOUCHFILES).selected).toContain('auto-decide-preserved');
}
});
describe('auto-decide-current-declaration', () => {
const capture = capture_auto_decide_current_declaration;
const clone = () => structuredClone(capture.retry) as any;
+1 -9
View File
@@ -4,7 +4,7 @@ import * as fs from 'node:fs';
import * as path from 'node:path';
import * as os from 'node:os';
import { validateOfficeHoursCompletion, validateOfficeHoursReviewerHandoffs, validateOfficeHoursReviewArtifacts, validateOfficeHoursReviewPreservation, validateOfficeHoursSpecSummary, type OfficeHoursCompletionEvidence } from './helpers/office-hours-completion';
import { E2E_TOUCHFILES, E2E_TIERS } from './helpers/touchfiles-data';
import { E2E_TOUCHFILES } from './helpers/touchfiles-data';
import { selectTests } from './helpers/test-selection';
const designPath = '/tmp/office-hours-fixture/docs/designs/roster-check.md';
@@ -697,14 +697,6 @@ describe('office-hours completion eval selection', () => {
expect(selected).toContain('office-hours-section-loading');
expect(selected).not.toContain('carve-section-loading');
});
test('completion helper changes select its gate and dedicated periodic workflow', () => {
const { selected } = selectTests(['test/helpers/office-hours-completion.ts'], E2E_TOUCHFILES);
expect(selected).toEqual(['office-hours-spec-review', 'office-hours-section-loading']);
expect(selected.filter(name => E2E_TIERS[name] === 'periodic')).toEqual(['office-hours-section-loading']);
expect(E2E_TIERS['office-hours-spec-review']).toBe('gate');
expect(E2E_TOUCHFILES['office-hours-section-loading']).toContain('test/skill-e2e-office-hours-section-loading.test.ts');
});
});
describe('office-hours spec-review summary completion', () => {
-6
View File
@@ -2,8 +2,6 @@ import { expect, test } from 'bun:test';
import * as fs from 'node:fs';
import * as path from 'node:path';
import { CAPTURE_MS, CAPTURE_LONG_MS } from './helpers/eval-budgets';
import { E2E_TOUCHFILES } from './helpers/touchfiles';
const source = fs.readFileSync(path.join(import.meta.dir, 'skill-e2e-office-hours-phase4.test.ts'), 'utf8');
const question = (word = 'architectural', options = 'A) Put retrieval on the server\nB) Put retrieval on the client') =>
`Where should retrieval live?\nThis ${word} choice decides which component owns the retrieval algorithm and the cross-host API contract.\n${options}\nRecommendation: A because all hosts need a consistent algorithm with one owner.\n`;
@@ -98,7 +96,3 @@ test('Phase4 caller fixture retains fork validation under either path convention
expect(rejected.thrown).toBeDefined(); expect(rejected.judged).toBe(0); expect(rejected.rows[0].passed).toBe(false);
}
});
test('Phase4 caller controls select only the existing Phase4 paid owner', () => {
expect(Object.entries(E2E_TOUCHFILES).filter(([,paths])=>paths.includes('test/office-hours-phase4-caller.test.ts')).map(([name])=>name)).toEqual(['office-hours-phase4-fork']);
});
-5
View File
@@ -2,7 +2,6 @@ import { expect, test } from 'bun:test';
import * as fs from 'node:fs';
import * as path from 'node:path';
import { CAPTURE_MS, CAPTURE_LONG_MS } from './helpers/eval-budgets';
import { E2E_TOUCHFILES } from './helpers/touchfiles';
import { OFFICE_HOURS_BUN_GRACE_MS, runRecordedOfficeHoursAttempt } from './helpers/office-hours-attempt';
const source = fs.readFileSync(path.join(import.meta.dir, 'skill-e2e-office-hours.test.ts'), 'utf8');
@@ -114,7 +113,3 @@ test('posture consecutive failed and passing callbacks retain separate final ver
expect(x.records[0].judge_scores).toEqual({ axis_a: 4, axis_b: 3 }); expect(x.records[1].judge_scores).toEqual({ axis_a: 4, axis_b: 4 });
}
});
test('posture recorder controls select exactly the two existing paid owners', () => {
expect(Object.entries(E2E_TOUCHFILES).filter(([, paths]) => paths.includes('test/office-posture-recording.test.ts')).map(([name]) => name)).toEqual([...owners]);
});
-7
View File
@@ -6,7 +6,6 @@ import { spawnSync } from 'node:child_process';
import { createPendingQuestionRecorder, recordPendingQuestion, readPendingQuestion,
pendingQuestionRecorderStatus } from './helpers/plan-count-pending-question';
import { readPlanCountTranscript } from './helpers/plan-count-transcript';
import { E2E_TOUCHFILES, selectTests } from './helpers/touchfiles';
import captured from './fixtures/pending-question-completion-ad.json';
// Public question/result contents are retained; hook envelopes, paths and live
@@ -186,10 +185,4 @@ describe('scoped pending question completion payloads', () => {
expect(f.status()).toEqual({status:'idle'});expect(f.read()).toBeUndefined();
} finally {f.dispose();}
});
test('the completion regression and fixture select exactly the two opted-in paid workflows', () => {
for(const file of ['test/pending-question-completion.test.ts','test/fixtures/pending-question-completion-ad.json']) {
expect(selectTests([file],E2E_TOUCHFILES,[]).selected.sort()).toEqual(['plan-ceo-mode-routing']);
}
});
});
-708
View File
@@ -1,708 +0,0 @@
import { describe, expect, test } from 'bun:test';
import { E2E_TIERS, E2E_TOUCHFILES, LLM_JUDGE_TOUCHFILES, selectTests } from './helpers/touchfiles';
import { OVERLAY_FIXTURES } from './fixtures/overlay-nudges';
describe('periodic fixture dependencies select their behavioral cases', () => {
const cases: Array<[string, string[]]> = [
['test/ceo-expansion-pacing-native.test.ts', ['plan-ceo-mode-routing']],
['test/fixtures/ceo-expansion-pacing-fb10.json', ['plan-ceo-mode-routing']],
['test/helpers/ceo-hold-posture-review.ts', ['plan-ceo-mode-routing']],
['test/ceo-hold-posture-review.test.ts', ['plan-ceo-mode-routing']],
['test/fixtures/ceo-hold-proof-fb10.json', ['plan-ceo-mode-routing']],
['test/eng-resolution-block-position.test.ts', ['plan-eng-multi-finding-batching']],
['test/fixtures/eng-a689-retry-public.json', ['plan-eng-multi-finding-batching']],
['test/fixtures/auto-decide-mode-selector-749df.json', ['auto-decide-preserved']],
['test/fixtures/eng-batching-prefixed-ledger-f359.json', ['plan-eng-multi-finding-batching']],
['test/fixtures/ceo-hold-preservation-f359.json', ['plan-ceo-mode-routing']],
['test/fixtures/auto-decide-completed-mode-f359.json', ['auto-decide-preserved']],
['test/review-count-markdown.test.ts', ['plan-eng-multi-finding-batching']],
['test/fixtures/review-count-markdown-6f.json', ['plan-eng-multi-finding-batching']],
['test/fixtures/eng-batching-expanded-ledger-6714.json', ['plan-eng-multi-finding-batching']],
['test/fixtures/eng-native-review-identities-6714.json', ['plan-eng-multi-finding-batching']],
['test/autoplan-dual-voice-fixture.test.ts', ['autoplan-dual-voice']],
['test/helpers/autoplan-dual-voice-evidence.ts', ['autoplan-dual-voice']],
['test/autoplan-dual-voice-evidence.test.ts', ['autoplan-dual-voice']],
['test/fixtures/autoplan-dual-false-positive-6bd.json', ['autoplan-dual-voice']],
['test/helpers/autoplan-method-read-audit.ts', ['autoplan-dual-voice']],
['test/fixtures/autoplan-method-read-aa-events.json', ['autoplan-dual-voice']],
['test/helpers/outside-voice-evidence.ts', ['autoplan-dual-voice', 'outside-plan-disabled-no-fallback',
'outside-voice-claude-code-to-codex', 'outside-voice-codex-to-claude-code']],
['test/fixtures/outside-async-task-m-events.json', ['autoplan-dual-voice',
'outside-voice-claude-code-to-codex', 'outside-voice-codex-to-claude-code']],
['test/autoplan-phase-handoff.test.ts', ['carve-section-loading', 'autoplan-dual-voice']],
['test/autoplan-amend-input.test.ts', ['carve-section-loading', 'autoplan-dual-voice']],
['test/fixtures/autoplan-amend-input-77.json', ['carve-section-loading', 'autoplan-dual-voice']],
['test/fixtures/autoplan-phase-handoff-6714.json', ['carve-section-loading', 'autoplan-dual-voice']],
['test/eng-finding-retry-budget.test.ts', ['plan-ceo-split-overflow', 'plan-eng-multi-finding-batching']],
['test/fixtures/ceo-expansion-pacing-77.json', ['plan-ceo-mode-routing']],
['test/fixtures/disabled-retained-record.json', ['outside-plan-disabled-no-fallback']],
['test/fixtures/ceo-expansion-posture-kind-dacc.json', ['plan-ceo-mode-routing']],
['test/fixtures/ceo-expansion-pause-6714.json', ['plan-ceo-mode-routing']],
['test/fixtures/ceo-expansion-complete-inventory-6f.json', ['plan-ceo-mode-routing']],
['test/ceo-mode-pending-submit.test.ts', ['plan-ceo-mode-routing']],
['test/fixtures/ceo-mode-pending-submit.json', ['plan-ceo-mode-routing']],
['test/fixtures/ceo-fill-lifetime.json', ['plan-ceo-section-loading']],
['test/eng-batching-native-replay.test.ts', ['plan-eng-multi-finding-batching']],
['test/fixtures/eng-batching-native-8525.json', ['plan-eng-multi-finding-batching']],
['test/eng-batching-saved-ledger.test.ts', ['plan-eng-multi-finding-batching']],
['test/fixtures/eng-batching-saved-ledger-dacc.json', ['plan-eng-multi-finding-batching']],
['test/plan-design-sdk-fixture.test.ts', ['plan-design-review-plan-mode']],
['test/setup-gbrain-remote-caller.test.ts', ['setup-gbrain-remote']],
['test/skill-fixture.test.ts', ['journey-ideation', 'journey-plan-eng', 'journey-debug', 'journey-qa', 'journey-code-review', 'journey-ship', 'journey-docs', 'journey-retro', 'journey-design-system', 'journey-visual-qa', 'journey-negatives']],
['test/office-hours-writeback-env.test.ts', ['office-hours-brain-writeback']],
['test/helpers/setup-gbrain-sandbox.ts', ['setup-gbrain-bad-token', 'setup-gbrain-path4-local-pglite', 'setup-gbrain-remote']],
['test/helpers/setup-gbrain-fixture-command.ts', ['setup-gbrain-bad-token', 'setup-gbrain-path4-local-pglite']],
['test/gstack-paths.test.ts', ['carve-section-loading', 'design-html-slop-gate']],
['test/gstack-brain-context-load.test.ts', ['plan-ceo-section-loading']],
['test/fixtures/eng-file-permission-repaint.json', ['plan-eng-multi-finding-batching']],
['test/helpers/carve-section-case.ts', ['carve-section-loading']],
['test/helpers/carve-plan-fixture.ts', ['carve-section-loading']],
['test/carve-plan-fixture.test.ts', ['carve-section-loading']],
['test/fixtures/carve-existing-repository/src/repository.ts', ['carve-section-loading']],
['test/fixtures/carve-existing-repository/README.md', ['carve-section-loading']],
['test/fixtures/carve-existing-repository/example.ts', ['carve-section-loading']],
['test/codex-carve-fixture.test.ts', ['carve-section-loading']],
['test/design-html-section-completion.test.ts', ['carve-section-loading']],
['test/fixtures/design-html-section-complete.md', ['carve-section-loading']],
['test/plan-design-floor-fixture.test.ts', ['plan-design-finding-floor']],
['test/helpers/hermetic-env.test.ts', ['plan-ceo-split-overflow']],
['test/helpers/ceo-split-question-policy.ts', ['plan-ceo-split-overflow']],
['test/ceo-split-question-policy.test.ts', ['plan-ceo-split-overflow']],
['test/ceo-split-collection.test.ts', ['plan-ceo-split-overflow']],
['test/fixtures/ceo-split-collection-0bcd.json', ['plan-ceo-split-overflow']],
['test/fixtures/ceo-split-actor-6aef.json', ['plan-ceo-split-overflow']],
['test/helpers/ceo-mode-option.ts', ['plan-ceo-mode-routing', 'plan-ceo-split-overflow']],
['docs/askuserquestion-split.md', ['plan-ceo-split-overflow', 'plan-decision-classification', 'plan-devex-peer-comparison-classification']],
['test/resolver-ask-user-format.test.ts', ['plan-ceo-split-overflow']],
['test/section-capture-native-tools.test.ts', ['ship-section-loading', 'plan-ceo-section-loading', 'office-hours-section-loading', 'carve-section-loading']],
...['test/fixtures/webfetch-permission.json', 'test/plan-skill-webfetch-permission.test.ts'].map((file): [string, string[]] => [file,
[
'plan-eng-multi-finding-batching', 'plan-ceo-split-overflow'],
]),
['test/helpers/plan-mode-evidence.ts', ['plan-design-review-plan-mode', 'plan-eng-review-plan-mode']],
['test/plan-mode-evidence.test.ts', ['plan-design-review-plan-mode', 'plan-eng-review-plan-mode']],
...['overlay-measurement', 'overlay-workspace', 'overlay-attempt', 'overlay-case', 'overlay-case-policy', 'overlay-lifecycle'].map((helper): [string, string[]] => [
`test/helpers/${helper}.ts`, OVERLAY_FIXTURES.map(fixture => `overlay-harness-${fixture.id}`),
]),
];
for (const file of ['test/overlay-sdk-cancel-eof.test.ts', 'test/overlay-recording-order.test.ts', 'test/paid-overlay-scheduling.test.ts', 'test/fixtures/overlay-admission-child.ts']) {
cases.push([file, OVERLAY_FIXTURES.map(fixture => `overlay-harness-${fixture.id}`)]);
}
for (const fixture of OVERLAY_FIXTURES) {
cases.push([`test/skill-e2e-overlay-harness-${fixture.id}.test.ts`, [`overlay-harness-${fixture.id}`]]);
}
test('SDK runner changes retain the native gate and existing periodic consumers', () => {
const periodic = ['setup-gbrain-remote', 'setup-gbrain-bad-token',
'setup-gbrain-path4-local-pglite', ...OVERLAY_FIXTURES.map(fixture => `overlay-harness-${fixture.id}`)];
const result = selectTests(['test/agent-sdk-runner.test.ts'], E2E_TOUCHFILES);
expect(result.reason).toBe('diff');
expect(result.selected.sort()).toEqual(['auq-format-gate', ...periodic].sort());
expect(E2E_TIERS['auq-format-gate']).toBe('gate');
for (const id of periodic) expect(E2E_TIERS[id]).toBe('periodic');
});
test('test/review-army-budget.test.ts', () => {
const periodic = ['review-army-red-team', 'review-army-consensus'];
const result = selectTests(['test/review-army-budget.test.ts'], E2E_TOUCHFILES);
expect(result.reason).toBe('diff');
expect(result.selected.sort()).toEqual(['review-army-perf-n-plus-one', ...periodic].sort());
expect(E2E_TIERS['review-army-perf-n-plus-one']).toBe('gate');
for (const id of periodic) expect(E2E_TIERS[id]).toBe('periodic');
});
for (const [file, expected] of cases) {
test(file, () => {
const result = selectTests([file], E2E_TOUCHFILES);
expect(result.reason).toBe('diff');
expect(result.selected.sort()).toEqual([...expected].sort());
for (const id of expected) expect(E2E_TIERS[id]).toBe('periodic');
});
}
});
test('Eng section local review helpers select their carve evaluation', () => {
for (const file of ['bin/gstack-review-log', 'bin/gstack-review-read', 'lib/review-evidence.ts',
'bin/gstack-slug', 'bin/gstack-wtree', 'bin/gstack-config', 'bin/gstack-brain-enqueue']) {
const result = selectTests([file], E2E_TOUCHFILES);
expect(result.reason).toBe('diff');
expect(result.selected).toContain('carve-section-loading');
}
expect(E2E_TIERS['carve-section-loading']).toBe('periodic');
});
test('offering source lookup dependencies select all four gate audits', () => {
const expected = ['codex-offered-office-hours', 'codex-offered-ceo-review',
'codex-offered-design-review', 'codex-offered-eng-review'].sort();
for (const file of ['test/helpers/codex-offering-fixture.ts', 'test/codex-offering-fixture.test.ts',
'test/fixtures/codex-offering-cdd-public.json', 'test/fixtures/codex-offering-timeout-public.json', 'test/helpers/workflow-judge-input.ts',
'test/workflow-judge-input.test.ts', 'test/helpers/workflow-excerpt.ts']) {
const result = selectTests([file], E2E_TOUCHFILES);
expect(result.reason).toBe('diff');
const consumers = file === 'test/helpers/workflow-excerpt.ts'
? [...expected, 'ship-managed-hook-refresh', 'ship-unmanaged-hook-consent', 'ship-local-hook-preservation'].sort()
: expected;
expect(result.selected.sort()).toEqual(consumers);
for (const id of consumers) expect(E2E_TIERS[id]).toBe('gate');
}
for (const file of ['test/helpers/codex-offering-fixture.ts', 'test/codex-offering-fixture.test.ts',
'test/fixtures/codex-offering-cdd-public.json', 'test/fixtures/codex-offering-timeout-public.json']) {
expect(selectTests([file], LLM_JUDGE_TOUCHFILES).selected).toEqual([]);
}
});
test('shared attempt regressions select periodic callers and the gate report case', () => {
const periodic = ['plan-design-review-plan-mode', 'office-hours-forcing-energy', 'office-hours-builder-wildness', 'office-hours-brain-writeback', 'plan-ceo-review-format-mode', 'plan-ceo-review-format-approach', 'plan-eng-review-format-coverage', 'plan-eng-review-format-kind', 'plan-ceo-review-prosons-cadence', 'plan-review-prosons-format', 'plan-review-prosons-hardstop-neg', 'plan-review-prosons-neutral-neg', 'setup-gbrain-bad-token', 'setup-gbrain-path4-local-pglite', 'setup-gbrain-remote', 'review-army-red-team'];
const result = selectTests(['test/office-hours-attempt.test.ts'], E2E_TOUCHFILES);
expect(result.reason).toBe('diff');
expect(result.selected.sort()).toEqual([...periodic, 'plan-review-report'].sort());
for (const id of periodic) expect(E2E_TIERS[id]).toBe('periodic');
expect(E2E_TIERS['plan-review-report']).toBe('gate');
});
test('native fixture dependencies include the migrated auto-decision and seeded CEO smoke callers', () => {
const expected = [
'auto-decide-preserved',
'plan-ceo-finding-floor', 'plan-ceo-mode-routing', 'plan-ceo-review-plan-mode', 'plan-ceo-split-overflow',
'plan-design-finding-floor', 'plan-design-with-ui-scope',
'plan-devex-finding-floor',
'plan-eng-finding-floor', 'plan-eng-multi-finding-batching',
];
for (const file of ['test/helpers/plan-count-fixture.ts', 'test/plan-count-fixture.test.ts']) {
const result = selectTests([file], E2E_TOUCHFILES);
expect(result.reason).toBe('diff');
expect(result.selected.sort()).toEqual(expected);
expect(selectTests([file], LLM_JUDGE_TOUCHFILES).selected).toEqual([]);
}
expect(E2E_TIERS['auto-decide-preserved']).toBe('periodic');
expect(E2E_TIERS['plan-ceo-review-plan-mode']).toBe('gate');
});
test('shared native input dependencies select every PTY consumer without changing tiers', () => {
const expected = selectTests(['test/helpers/claude-pty-runner.ts'], E2E_TOUCHFILES).selected.sort();
expect(expected).toHaveLength(15);
expect(expected.filter(id => E2E_TIERS[id] === 'gate')).toHaveLength(7);
expect(expected.filter(id => E2E_TIERS[id] === 'periodic')).toHaveLength(8);
for (const file of ['test/plan-count-design-ui-recovery.test.ts', 'test/fixtures/design-ui-boxed-question.json', 'test/pty-workspace-trust.test.ts', 'test/fixtures/pty-companion-cli.ts',
'test/helpers/plan-skill-questions.ts', 'test/plan-skill-questions.test.ts', 'test/fixtures/design-tasks-bash-permission.json', 'test/fixtures/eng-auq-validation-error.json',
'test/helpers/plan-skill-question-events.ts', 'test/plan-skill-question-events.test.ts',
'test/helpers/plan-skill-question-hook-scope.ts', 'test/helpers/skill-census.ts', 'test/plan-skill-question-hook-scope.test.ts']) {
const result = selectTests([file], E2E_TOUCHFILES);
expect(result.reason).toBe('diff');
expect(result.selected.sort()).toEqual(expected);
}
});
test('seed submission dependencies select every seeded caller with its existing tier', () => {
const expected = ['auto-decide-preserved', 'plan-ceo-review-plan-mode',
'plan-design-review-plan-mode', 'plan-devex-review-plan-mode', 'plan-eng-review-plan-mode', 'plan-mode-no-op'];
for (const file of ['test/helpers/fake-plan-seed.ts', 'test/helpers/plan-seed-submission.ts', 'test/plan-seed-submission.test.ts', 'test/fixtures/plan-seed-cli.ts']) {
const result = selectTests([file], E2E_TOUCHFILES);
expect(result.reason).toBe('diff');
expect(result.selected.sort()).toEqual(expected);
}
expect(expected.map(id => E2E_TIERS[id])).toEqual(['periodic', 'gate', 'periodic', 'gate', 'periodic', 'gate']);
});
test('task emission source selects CEO completion consumers', () => {
const selected = selectTests(['scripts/resolvers/tasks-section.ts'], E2E_TOUCHFILES);
expect(selected.reason).toBe('diff');
for (const id of [
'plan-ceo-finding-floor', 'plan-ceo-split-overflow',
'plan-ceo-section-loading', 'plan-ceo-review-plan-mode',
]) expect(selected.selected).toContain(id);
expect(selectTests(['scripts/resolvers/tasks-section.ts'], LLM_JUDGE_TOUCHFILES).selected).toEqual([]);
});
test('review report resolver selects every periodic completion consumer', () => {
const required = [
'plan-ceo-split-overflow',
'carve-section-loading', 'plan-ceo-section-loading', 'plan-eng-multi-finding-batching',
];
const result = selectTests(['scripts/resolvers/review.ts'], E2E_TOUCHFILES);
expect(result.reason).toBe('diff');
for (const id of required) {
expect(result.selected).toContain(id);
expect(E2E_TIERS[id]).toBe('periodic');
}
});
test('shared plan question source selects every generated review consumer', () => {
const source = 'scripts/resolvers/preamble/generate-ask-user-format.ts';
const renders = ['plan-ceo-review', 'plan-eng-review', 'plan-design-review', 'plan-devex-review']
.map(skill => `${skill}/SKILL.md`);
for (const map of [E2E_TOUCHFILES, LLM_JUDGE_TOUCHFILES]) {
const expected = selectTests(renders, map);
const actual = selectTests([source], map);
expect(expected.reason).toBe('diff');
expect(actual.reason).toBe('diff');
expect(expected.selected.length).toBeGreaterThan(0);
expect(expected.selected.filter(id => !actual.selected.includes(id))).toEqual([]);
}
});
test('Eng approval-rule source and free contract controls select every declared Eng consumer', () => {
const expected = [
'plan-eng-review',
'plan-eng-review-artifact',
'plan-review-report',
'plan-eng-review-plan-mode',
'plan-mode-no-op',
'carve-section-loading',
'plan-eng-finding-floor',
'plan-eng-multi-finding-batching',
'plan-eng-review-format-coverage',
'plan-eng-review-format-kind',
'plan-ceo-review-prosons-cadence',
'plan-review-prosons-format',
'codex-offered-eng-review',
'plan-eng-coverage-audit',
'autoplan-dual-voice'
];
for (const file of ['plan-eng-review/sections/review-sections.md.tmpl', 'scripts/resolvers/review.ts', 'test/plan-review-cases.test.ts']) {
const result = selectTests([file], E2E_TOUCHFILES);
expect(result.reason).toBe('diff');
for (const id of expected) expect(result.selected, `${file}: ${id}`).toContain(id);
expect(selectTests([file], LLM_JUDGE_TOUCHFILES).selected).toContain('plan-eng-review/SKILL.md sections');
}
});
// This actor is used by the bounded native Design UI case, not the optional
// outside-review evaluations. Its captured inputs must select that same case.
test('Design native-only actor capture selects its gate case', () => {
const result = selectTests(['test/fixtures/design-outside-voices-question.json'], E2E_TOUCHFILES);
expect(result.reason).toBe('diff');
expect(result.selected).toEqual(['plan-design-with-ui-scope']);
expect(E2E_TIERS['plan-design-with-ui-scope']).toBe('gate');
});
test('native compact-boundary ancestry selects every consuming callback', () => {
const expected = [
'plan-ceo-mode-routing',
'plan-eng-multi-finding-batching', 'plan-ceo-split-overflow',
'plan-design-with-ui-scope', 'plan-design-review-plan-mode', 'plan-eng-review-plan-mode',
'auto-decide-preserved', ].sort();
for (const file of ['test/helpers/plan-count-transcript.ts', 'test/plan-count-session-cwd.test.ts']) {
const selected = selectTests([file], E2E_TOUCHFILES);
expect(selected.reason).toBe('diff');
expect(selected.selected.sort()).toEqual(expected);
expect(selectTests([file], LLM_JUDGE_TOUCHFILES).selected).toEqual([]);
}
});
test('same-plan expansion disposition replay selects the existing mode helper consumers', () => {
for (const dependency of ['test/ceo-mode-expansion-disposition.test.ts', 'test/fixtures/ceo-expansion-disposition-77.json']) {
expect([...selectTests([dependency], E2E_TOUCHFILES).selected].sort()).toEqual(['plan-ceo-mode-routing']);
expect(selectTests([dependency], LLM_JUDGE_TOUCHFILES).selected).toEqual([]);
}
});
test('structured auto-decision evidence selects every native observer', () => {
const expected = ['auto-decide-preserved', 'plan-ceo-review-plan-mode',
'plan-design-review-plan-mode', 'plan-devex-review-plan-mode', 'plan-eng-review-plan-mode', 'plan-mode-no-op'];
for (const file of ['test/fixtures/auto-decide-structured-77.json',
'test/helpers/auto-decision-state.ts', 'test/fixtures/auto-decide-state-cab3.json']) {
expect([...selectTests([file], E2E_TOUCHFILES).selected].sort()).toEqual(expected);
expect(selectTests([file], LLM_JUDGE_TOUCHFILES).selected).toEqual([]);
}
for (const file of ['bin/gstack-question-log', 'bin/gstack-question-preference']) {
const producers = selectTests([file], E2E_TOUCHFILES).selected;
for (const id of expected) expect(producers).toContain(id);
}
});
test('explanatory native mode evidence selects all observers with their existing tiers', () => {
const expected = ['auto-decide-preserved', 'office-hours-auto-mode',
'plan-ceo-review-plan-mode', 'plan-design-review-plan-mode', 'plan-devex-review-plan-mode',
'plan-eng-review-plan-mode', 'plan-mode-no-op'];
for (const file of ['test/helpers/native-auto-decide.ts', 'test/native-auto-decide.test.ts',
'test/fixtures/auto-decide-current-declaration-6aef.json', 'test/native-auto-decide.test.ts',
'test/fixtures/auto-decide-explanatory-mode-043a.json', 'test/fixtures/auto-decide-explanatory-mode-749df.json']) {
expect([...selectTests([file], E2E_TOUCHFILES).selected].sort()).toEqual(expected);
expect(selectTests([file], LLM_JUDGE_TOUCHFILES).selected).toEqual([]);
}
expect(expected.map(id => E2E_TIERS[id])).toEqual([
'periodic', 'gate', 'gate', 'periodic', 'gate', 'periodic', 'gate',
]);
});
// The workflow judge includes all carved sections, including those outside the
// entrypoint marker window (readWorkflowJudgeInput).
test('CEO carved sections select the judge that consumes their complete content', () => {
for (const file of [
'plan-ceo-review/sections/review-sections.md.tmpl',
'plan-ceo-review/sections/review-sections.md',
]) {
expect(selectTests([file], LLM_JUDGE_TOUCHFILES).selected)
.toEqual(['plan-ceo-review/SKILL.md modes']);
}
});
test('file supervision regression selects all affected callers with their existing tiers', () => {
const gate = [
'codex-offered-ceo-review', 'codex-offered-design-review', 'codex-offered-eng-review',
'codex-offered-office-hours', 'office-hours-spec-review', 'plan-ceo-finding-floor',
'plan-ceo-review-benefits', 'plan-devex-finding-floor', 'plan-mode-no-op', 'plan-review-report',
];
const periodic = [
'auto-decide-preserved', 'plan-ceo-mode-routing',
'plan-ceo-review', 'plan-ceo-review-expansion-energy', 'plan-ceo-review-format-approach',
'plan-ceo-review-format-mode', 'plan-ceo-review-prosons-cadence', 'plan-ceo-review-selective',
'plan-design-finding-floor', 'plan-eng-finding-floor', 'plan-eng-review', 'plan-eng-review-artifact',
'plan-eng-review-format-coverage', 'plan-eng-review-format-kind', 'plan-eng-review-plan-mode',
'plan-review-prosons-format', 'plan-review-prosons-hardstop-neg', 'plan-review-prosons-neutral-neg',
];
const changed = ['test/paid-retry-supervision.test.ts'];
const result = selectTests(changed, E2E_TOUCHFILES);
expect(result.reason).toBe('diff');
expect(result.selected.sort()).toEqual([...gate, ...periodic].sort());
for (const id of gate) expect(E2E_TIERS[id]).toBe('gate');
for (const id of periodic) expect(E2E_TIERS[id]).toBe('periodic');
expect(selectTests(changed, LLM_JUDGE_TOUCHFILES).selected).toEqual([]);
});
test('floor permissions and large-report fixtures select their actual consumers', () => {
const floors = ['plan-ceo-finding-floor', 'plan-eng-finding-floor', 'plan-design-finding-floor', 'plan-devex-finding-floor'];
for (const file of ['test/plan-floor-permission.test.ts', 'test/fixtures/plan-floor-permission-fb10.json'])
expect(selectTests([file], E2E_TOUCHFILES).selected.sort()).toEqual([...floors].sort());
const filePermissionConsumers = selectTests(['test/helpers/plan-count-file-permission.ts'], E2E_TOUCHFILES).selected;
expect(filePermissionConsumers.sort()).toEqual([...floors,
'plan-eng-multi-finding-batching', 'plan-ceo-split-overflow'].sort());
expect(selectTests(['test/fixtures/ceo-report-permission-fb10.json'], E2E_TOUCHFILES).selected.sort())
.toEqual(filePermissionConsumers);
expect(E2E_TIERS['plan-ceo-finding-floor']).toBe('gate');
expect(E2E_TIERS['plan-devex-finding-floor']).toBe('gate');
expect(E2E_TIERS['plan-eng-finding-floor']).toBe('periodic');
expect(E2E_TIERS['plan-design-finding-floor']).toBe('periodic');
});
// These existing permission checks now also serve gate floor actors.
for (const file of ['test/plan-count-cropped-wrap.test.ts', 'test/fixtures/plan-count-cropped-wrap-6714.json']) {
test(file, () => {
const gate = ['plan-ceo-finding-floor', 'plan-devex-finding-floor'];
const periodic = [
'plan-eng-multi-finding-batching', 'plan-ceo-split-overflow',
'plan-eng-finding-floor', 'plan-design-finding-floor'];
const result = selectTests([file], E2E_TOUCHFILES);
expect(result.reason).toBe('diff');
expect(result.selected.sort()).toEqual([...gate, ...periodic].sort());
for (const id of gate) expect(E2E_TIERS[id]).toBe('gate');
for (const id of periodic) expect(E2E_TIERS[id]).toBe('periodic');
});
}
// Shared harness repairs must select every existing consumer, including gate floors.
const nativeRepairDependencies = [
{
"name": "AUTO mode declarations",
"files": [
"test/native-auto-decide.test.ts",
"test/fixtures/auto-decide-recommendation-361c.json",
"test/native-auto-decide.test.ts",
"test/fixtures/auto-decide-target-361c.json"
],
"owners": [
"plan-ceo-review-plan-mode",
"plan-eng-review-plan-mode",
"plan-design-review-plan-mode",
"plan-devex-review-plan-mode",
"plan-mode-no-op",
"office-hours-auto-mode",
"auto-decide-preserved",
]
},
{
"name": "owned cropped Create previews",
"files": [
"test/plan-create-permission.test.ts",
"test/fixtures/plan-create-permission-361c.json"
],
"owners": [
"plan-eng-finding-floor",
"plan-ceo-finding-floor",
"plan-design-finding-floor",
"plan-devex-finding-floor",
"plan-eng-multi-finding-batching",
"plan-ceo-split-overflow"
]
},
{
"name": "split native question and report permission",
"files": [
"test/fixtures/ceo-split-padding-361c-public.json",
"test/fixtures/ceo-split-edit-permission-361c-public.json"
],
"owners": [
"plan-ceo-split-overflow"
]
},
{
"name": "finding-qualified floors",
"files": [
"test/helpers/plan-floor-review.ts",
"test/plan-floor-review.test.ts",
"test/fixtures/plan-floor-routing-361c.json"
],
"owners": [
"plan-ceo-finding-floor",
"plan-eng-finding-floor",
"plan-design-finding-floor",
"plan-devex-finding-floor"
]
},
{
"name": "complete long native Edit panes",
"files": [
"test/plan-count-long-edit.test.ts",
"test/fixtures/plan-count-long-edit-0bcd.json"
],
"owners": [
"plan-eng-finding-floor",
"plan-ceo-finding-floor",
"plan-design-finding-floor",
"plan-devex-finding-floor",
"plan-eng-multi-finding-batching",
"plan-ceo-split-overflow"
]
},
{
"name": "native border on truncated questions",
"files": [
"test/plan-count-truncated-border.test.ts",
"test/fixtures/eng-d2-truncated-border-0bcd.json"
],
"owners": [
"plan-ceo-review-plan-mode",
"plan-eng-review-plan-mode",
"plan-design-review-plan-mode",
"plan-devex-review-plan-mode",
"plan-mode-no-op",
"office-hours-auto-mode",
"auto-decide-preserved",
"plan-ceo-mode-routing",
"plan-design-with-ui-scope",
"plan-eng-finding-floor",
"plan-ceo-finding-floor",
"plan-design-finding-floor",
"plan-devex-finding-floor",
"plan-eng-multi-finding-batching",
"plan-ceo-split-overflow"
]
}
];
for (const group of nativeRepairDependencies) {
test(`native repair dependencies: ${group.name}`, () => {
for (const file of group.files) {
const selected = selectTests([file], E2E_TOUCHFILES);
expect(selected.reason).toBe('diff');
expect(selected.selected.sort()).toEqual([...group.owners].sort());
expect(selectTests([file], LLM_JUDGE_TOUCHFILES).selected).toEqual([]);
}
});
}
test('native repair dependencies preserve every original tier', () => {
expect(E2E_TIERS).toMatchObject({
"plan-ceo-review-plan-mode": "gate",
"plan-eng-review-plan-mode": "periodic",
"plan-design-review-plan-mode": "periodic",
"plan-devex-review-plan-mode": "gate",
"plan-mode-no-op": "gate",
"office-hours-auto-mode": "gate",
"auto-decide-preserved": "periodic",
"plan-eng-finding-floor": "periodic",
"plan-ceo-finding-floor": "gate",
"plan-design-finding-floor": "periodic",
"plan-devex-finding-floor": "gate",
"plan-eng-multi-finding-batching": "periodic",
"plan-ceo-split-overflow": "periodic",
"plan-ceo-mode-routing": "periodic",
"plan-devex-peer-comparison-classification": "periodic",
"plan-decision-classification": "periodic"
});
});
// These dependency edges do not create new paid identities. Reuse of unchanged
// model inputs is qualified separately before a paid run.
test('promoted public transcript decoder keeps its actual callers selected', () => {
const expected = [
'plan-eng-review-plan-mode',
'plan-design-review-plan-mode',
'auto-decide-preserved',
'plan-ceo-mode-routing',
'plan-design-with-ui-scope',
'plan-eng-multi-finding-batching',
'plan-ceo-split-overflow',
'plan-ceo-finding-floor',
'plan-eng-finding-floor',
'plan-design-finding-floor',
'plan-devex-finding-floor',
];
expect(selectTests(['lib/claude-public-transcript.ts'], E2E_TOUCHFILES).selected.sort())
.toEqual(expected.sort());
expect(selectTests(['lib/claude-public-transcript.ts'], LLM_JUDGE_TOUCHFILES).selected).toEqual([]);
});
test('combined Create captures select the existing owned file-permission consumers', () => {
const expected = [
'plan-eng-finding-floor',
'plan-ceo-finding-floor',
'plan-design-finding-floor',
'plan-devex-finding-floor',
'plan-eng-multi-finding-batching',
'plan-ceo-split-overflow',
];
for (const file of ['test/plan-create-combined-permission.test.ts',
'test/fixtures/plan-create-combined-permission-70b.json']) {
expect(selectTests([file], E2E_TOUCHFILES).selected.sort()).toEqual([...expected].sort());
expect(selectTests([file], LLM_JUDGE_TOUCHFILES).selected).toEqual([]);
}
});
test('floor quotation evidence selects four assessors and product-type evidence selects only DX', () => {
const floors = [
'plan-ceo-finding-floor',
'plan-eng-finding-floor',
'plan-design-finding-floor',
'plan-devex-finding-floor',
];
expect(selectTests(['test/fixtures/plan-floor-quote-70b.json'], E2E_TOUCHFILES).selected.sort())
.toEqual([...floors].sort());
expect(selectTests(['test/fixtures/plan-floor-product-type-70b.json'], E2E_TOUCHFILES).selected)
.toEqual(['plan-devex-finding-floor']);
for (const file of ['test/plan-floor-review.test.ts', 'test/plan-floor-permission.test.ts'])
expect(selectTests([file], E2E_TOUCHFILES).selected.sort()).toEqual([...floors].sort());
for (const file of ['test/fixtures/plan-floor-quote-70b.json', 'test/fixtures/plan-floor-product-type-70b.json'])
expect(selectTests([file], LLM_JUDGE_TOUCHFILES).selected).toEqual([]);
expect(E2E_TIERS['plan-ceo-finding-floor']).toBe('gate');
expect(E2E_TIERS['plan-devex-finding-floor']).toBe('gate');
expect(E2E_TIERS['plan-design-finding-floor']).toBe('periodic');
expect(E2E_TIERS['plan-eng-finding-floor']).toBe('periodic');
});
test('DX custom setup transport selects its existing floor case without quality resampling', () => {
for (const file of ['test/plan-floor-dx-actor.test.ts', 'test/fixtures/plan-floor-dx-custom-491.json']) {
expect(selectTests([file], E2E_TOUCHFILES).selected).toEqual(['plan-devex-finding-floor']);
expect(selectTests([file], LLM_JUDGE_TOUCHFILES).selected).toEqual([]);
}
});
test('numbered native-menu captures select the existing parser consumers', () => {
const expected = Object.entries(E2E_TOUCHFILES)
.filter(([, files]) => files.includes('test/plan-skill-questions.test.ts'))
.map(([id]) => id).sort();
expect(expected).toHaveLength(15);
for (const file of ['test/pty-numbered-option-indent-native.test.ts',
'test/fixtures/ceo-split-e5-numbered-description-491.json']) {
expect(selectTests([file], E2E_TOUCHFILES).selected.sort()).toEqual(expected);
expect(selectTests([file], LLM_JUDGE_TOUCHFILES).selected).toEqual([]);
}
});
test('pending native Write captures select the existing owned-permission consumers', () => {
const expected = Object.entries(E2E_TOUCHFILES)
.filter(([, files]) => files.includes('test/plan-create-combined-permission.test.ts'))
.map(([id]) => id).sort();
expect(expected).toHaveLength(6);
for (const file of ['test/plan-create-prepublication.test.ts',
'test/fixtures/plan-create-prepublication-491.json']) {
expect(selectTests([file], E2E_TOUCHFILES).selected.sort()).toEqual(expected);
expect(selectTests([file], LLM_JUDGE_TOUCHFILES).selected).toEqual([]);
}
});
test('stderr lifecycle regression selects runtime consumers without a quality-map edge', () => {
const expected = [
'browse-basic', 'browse-snapshot', 'aside-browse-basic', 'aside-browse-flow', 'aside-qa-quick',
'aside-scrape-json', 'aside-canary-quick', 'hermetic-canary', 'hermetic-sentinel', 'first-task-scaffold',
'skillmd-setup-discovery', 'skillmd-no-local-binary', 'skillmd-outside-git', 'session-awareness', 'operational-learning',
'qa-quick', 'qa-b6-static', 'qa-b7-spa', 'qa-b8-checkout', 'qa-only-no-fix',
'qa-fix-loop', 'qa-bootstrap', 'review-sql-injection', 'review-enum-completeness', 'review-base-branch',
'review-design-lite', 'review-army-migration-safety', 'review-army-perf-n-plus-one', 'review-army-delivery-audit', 'review-army-quality-score',
'review-army-json-findings', 'review-army-red-team', 'review-army-simplification', 'review-army-simplification-precision', 'review-army-consensus',
'office-hours-spec-review', 'office-hours-forcing-energy', 'office-hours-builder-wildness', 'plan-ceo-review', 'plan-ceo-review-selective',
'plan-ceo-review-benefits', 'plan-ceo-review-expansion-energy', 'plan-eng-review', 'plan-eng-review-artifact', 'plan-review-report',
'plan-design-review-plan-mode', 'office-hours-phase4-fork', 'auq-format-gate', 'tpa-present', 'tpa-absent-linux',
'tpa-broken', 'tpa-absent-darwin', 'tpa-apple-ban', 'ship-section-loading', 'plan-ceo-section-loading',
'carve-section-loading', 'setup-gbrain-remote', 'setup-gbrain-bad-token', 'setup-gbrain-path4-local-pglite', 'plan-ceo-review-format-mode',
'plan-ceo-review-format-approach', 'plan-eng-review-format-coverage', 'plan-eng-review-format-kind', 'plan-ceo-review-prosons-cadence', 'plan-review-prosons-format',
'plan-review-prosons-hardstop-neg', 'plan-review-prosons-neutral-neg', 'plan-tune-inspect', 'codex-offered-office-hours', 'codex-offered-ceo-review',
'codex-offered-design-review', 'codex-offered-eng-review', 'ship-base-branch', 'ship-local-workflow', 'review-dashboard-via',
'retro', 'retro-base-branch', 'cso-full-audit', 'cso-diff-mode', 'cso-infra-scope',
'learnings-show', 'timeline-event-flow', 'context-recovery-artifacts', 'context-save-writes-file', 'context-restore-loads-latest',
'context-save-routing', 'context-save-then-restore-roundtrip', 'context-restore-fragment-match', 'context-restore-empty-state', 'context-restore-list-delegates',
'context-restore-legacy-compat', 'context-save-list-current-branch', 'context-save-list-all-branches', 'document-release', 'codex-review',
'outside-voice-codex-to-claude-code', 'outside-voice-claude-code-to-codex', 'outside-plan-disabled-no-fallback', 'ship-coverage-audit', 'review-coverage-audit',
'plan-eng-coverage-audit', 'ship-triage', 'ship-docsync', 'docsync-spawned', 'design-consultation-core',
'design-consultation-existing', 'design-consultation-research', 'design-consultation-preview', 'plan-design-review-no-ui-scope', 'design-review-fix',
'design-review-detector-shim', 'design-review-detector-shim-dom', 'design-review-plugin-handoff', 'design-html-slop-gate', 'diagram-triplet', 'diagram-authoring-quality',
'gstack-upgrade-happy-path', 'land-and-deploy-workflow', 'land-and-deploy-first-run', 'land-and-deploy-review-gate', 'canary-workflow',
'benchmark-workflow', 'setup-deploy-workflow', 'autoplan-dual-voice', 'scrape-match-path', 'scrape-prototype-path',
'skillify-happy-path', 'skillify-provenance-refusal', 'skillify-approval-reject', 'journey-ideation', 'journey-plan-eng',
'journey-debug', 'journey-qa', 'journey-code-review', 'journey-ship', 'journey-docs',
'journey-retro', 'journey-design-system', 'journey-visual-qa', 'journey-negatives',
'office-hours-brain-writeback', 'arm-benchmark-native-overbuild', 'arm-benchmark-crud-endpoint', 'arm-benchmark-bugfix-decoys', 'office-hours-section-loading',
];
const file = 'test/session-runner-stream-lifecycle.test.ts';
expect(selectTests([file], E2E_TOUCHFILES).selected.sort()).toEqual(expected.sort());
expect(selectTests([file], LLM_JUDGE_TOUCHFILES).selected).toEqual([]);
});
test('collection completion lifecycle selects the existing native counter consumers', () => {
const selected = selectTests(['test/plan-count-collection-completion.test.ts'], E2E_TOUCHFILES);
expect(selected.reason).toBe('diff');
expect(selected.selected.length).toBeGreaterThan(0);
expect(selected.selected.sort()).toEqual(
selectTests(['test/plan-count-timeout.test.ts'], E2E_TOUCHFILES).selected.sort());
expect(selectTests(['test/plan-count-collection-completion.test.ts'], LLM_JUDGE_TOUCHFILES).selected).toEqual([]);
});
for (const file of ['test/plan-count-cross-cwd-ancestry.test.ts', 'test/fixtures/plan-count-cross-cwd-ancestry-0bcd.json']) {
test(`${file} selects native cwd continuation consumers`, () => {
const selected = selectTests([file], E2E_TOUCHFILES);
expect(selected.reason).toBe('diff');
expect(selected.selected.sort()).toEqual([
'auto-decide-preserved', 'plan-ceo-mode-routing', 'plan-ceo-split-overflow',
'plan-design-review-plan-mode', 'plan-design-with-ui-scope',
'plan-eng-multi-finding-batching',
'plan-eng-review-plan-mode',
].sort());
expect(selectTests([file], LLM_JUDGE_TOUCHFILES).selected).toEqual([]);
});
}
test('native clipped regressions retain the existing parser and owned-permission selection', () => {
for (const [dependency, count, files] of [
['test/helpers/claude-pty-runner.ts', 15, [
'test/plan-count-clipped-elision.test.ts', 'test/fixtures/eng-d1-clipped-elision-1579.json', 'test/fixtures/eng-d2-planning-prelude-4d.json',
]],
['test/helpers/plan-count-file-permission.ts', 6, [
'test/plan-edit-cropped-permission.test.ts', 'test/fixtures/plan-edit-cropped-permission-1579.json',
]],
] as const) {
const expected = selectTests([dependency], E2E_TOUCHFILES).selected.sort();
expect(expected).toHaveLength(count);
for (const file of files) {
expect(selectTests([file], E2E_TOUCHFILES).selected.sort()).toEqual(expected);
expect(selectTests([file], LLM_JUDGE_TOUCHFILES).selected).toEqual([]);
}
}
});
-8
View File
@@ -20,9 +20,6 @@ import os_ceo_handoff_y from 'node:os';
import path_ceo_handoff_y from 'node:path';
import fixture_ceo_handoff_y from './fixtures/ceo-handoff-y-call.json';
import captured_dx_manual_handoff_ao from './fixtures/dx-manual-handoff-ao.json';
import { E2E_TOUCHFILES } from './helpers/touchfiles-data';
import { LLM_JUDGE_TOUCHFILES } from './helpers/touchfiles-data';
import { GLOBAL_TOUCHFILES } from './helpers/touchfiles-data';
import fixture_plan_count_dx_handoff_o from './fixtures/devex-handoff-o-call.json';
import actual_eng_next_handoff_ah from './fixtures/eng-next-handoff-ah.json';
import { isCurrentPlanApprovalScreen } from './helpers/plan-count-pending-exit';
@@ -1148,11 +1145,6 @@ function change(call:NativePlanQuestionCall,from:string,to:string){
const selected=call.answers![q.question];q.question=q.question.replace(from,to);call.answers={[q.question]:selected!};
}
describe('AO completed manual DX handoff preserves report freshness',()=>{
test('shared completion callers register the regression with dense literal paths',()=>{
const arrays=[...Object.values(E2E_TOUCHFILES),...Object.values(LLM_JUDGE_TOUCHFILES),GLOBAL_TOUCHFILES];
expect(arrays).toHaveLength(216);
for(const values of arrays)for(let i=0;i<values.length;i++)expect(typeof values[i]).toBe('string');
});
test('exact owned report precedes navigation only, with the current Exit gate recognized',()=>{
expect(captured.calls).toHaveLength(2);expect(captured.events).toHaveLength(4);
expect(Date.parse(captured.calls[0]!.answeredAt!)).toBeLessThan(captured.provenance.reportMtimeMs);
+1 -14
View File
@@ -219,11 +219,6 @@ import capturedAh_plan_count_permission_ac from './fixtures/plan-count-permissio
import { currentFilePermissionBinding } from './helpers/plan-count-file-permission';
import exact_plan_count_quoted_frame_ak from './fixtures/plan-count-quoted-frame-ak.json';
import owned_plan_count_quoted_frame_ak from './fixtures/plan-count-owned-permission-v.json';
test('AD v2 cropped target fixture selects all existing file-permission consumers',()=>{
expect(selectTests(['test/fixtures/plan-count-permission-target-ad-v2.json'],E2E_TOUCHFILES,[]).selected)
.toEqual(selectTests(['test/plan-count-file-permission.test.ts'],E2E_TOUCHFILES,[]).selected);
});
describe('batching-permission-at', () => {
const fs = fs_batching_permission_at;
const os = os_batching_permission_at;
@@ -723,13 +718,7 @@ for (const c of cases) {
}
});
}
test('AD crop fixture selects the exact existing permission regression callers', () => {
expect(selectTests(['test/fixtures/plan-count-permission-ad.json'], E2E_TOUCHFILES).selected.sort()).toEqual(
selectTests(['test/fixtures/plan-count-permission-ac.json'], E2E_TOUCHFILES).selected.sort());
});
test('AE crop admits one native divider only and preserves its exact existing caller selection', () => {
test('AE crop admits one native divider only', () => {
const c = cases.find(item => item.p.pid === capturedAe.pid)!;
const firstLine = c.screen.slice(0, c.screen.indexOf('\n') + 1);
for (const screen of [firstLine + c.screen, 'unrelated prose\n' + c.screen,
@@ -738,8 +727,6 @@ test('AE crop admits one native divider only and preserves its exact existing ca
expect(adEpoch(c, screen)).toBeNull();
expect(createPlanCountPermissionGuard()(screen, '', adEpoch(c, screen))).not.toBe('grant');
}
expect(selectTests(['test/fixtures/plan-count-permission-ae.json'], E2E_TOUCHFILES).selected.sort()).toEqual(
selectTests(['test/fixtures/plan-count-permission-ad.json'], E2E_TOUCHFILES).selected.sort());
});
test('AH wrapped crop admits four or five spaces with the same owned native epoch', () => {
-7
View File
@@ -2,16 +2,9 @@ import {expect,test} from 'bun:test';
import {planFloorDXPane,planFloorDXReplyInput,matchesNativePlanQuestion,type PlanFloorDXReply} from './helpers/claude-pty-runner';
import captured from './fixtures/plan-floor-dx-custom-491.json';
import editorHints from './fixtures/plan-floor-dx-editor-hint.json';
import {E2E_TOUCHFILES,selectTests} from './helpers/touchfiles';
const call=captured.call;
const state=(stage:PlanFloorDXReply['stage']='focus'):PlanFloorDXReply=>({call:structuredClone(call),
pane:planFloorDXPane(captured.questionViewport,call)!,reply:captured.reply,stage});
test('editor-hint capture changes select the live DX finding-floor probe',()=>{
expect(selectTests(['test/fixtures/plan-floor-dx-editor-hint.json'],E2E_TOUCHFILES,[]).selected)
.toContain('plan-devex-finding-floor');
});
test('generic matcher authenticates the crop while DX custom replies still require the complete pane',()=>{
expect(matchesNativePlanQuestion(captured.originalViewport,call)).toBe(true);
expect(planFloorDXPane(captured.originalViewport,call)).toBeNull();
-9
View File
@@ -5,8 +5,6 @@ import * as path from 'node:path';
import { pathToFileURL } from 'node:url';
import { readPlanFloorTarget } from './helpers/plan-floor-target';
import { createFakeBunCli } from './helpers/fake-bun-cli';
import { selectTests, E2E_TOUCHFILES } from './helpers/touchfiles';
const ROOT = path.resolve(import.meta.dir, '..');
const SID = '11111111-2222-3333-4444-555555555555';
const START = Date.parse('2026-09-10T04:46:45Z');
@@ -80,13 +78,6 @@ test('changed or linked plan, invalid clock, linked journal and oversized source
fs.unlinkSync(f.journal); fs.renameSync(real, f.journal); fs.truncateSync(f.journal, 32 * 1024 * 1024 + 1); expect(f.check().status).toBe('error');
} finally { f.cleanup(); }
});
test('new delivery helper and controls select all four existing floor owners', () => {
for (const file of ['test/helpers/plan-floor-target.ts', 'test/plan-floor-target.test.ts']) {
expect(selectTests([file], E2E_TOUCHFILES).selected.sort()).toEqual(['plan-ceo-finding-floor', 'plan-design-finding-floor', 'plan-devex-finding-floor', 'plan-eng-finding-floor']);
}
});
test('compiled fake CLI preserves Claude arguments and stdin without a shebang launcher', async () => {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'native-floor-cli-'));
try {
-31
View File
@@ -5,38 +5,7 @@ import * as path from 'node:path';
import { planDecisionCalibrations } from './fixtures/plan-decision-classification';
import { buildPlanReviewDecisionPrompt } from './helpers/plan-review-decisions';
import { ENG_BATCHING_FINDINGS } from './helpers/plan-review-cases';
import { E2E_TOUCHFILES, E2E_TIERS, selectTests } from './helpers/touchfiles';
const ROOT = path.resolve(import.meta.dir, '..');
const IDS = ['plan-eng-multi-finding-batching', 'plan-ceo-split-overflow', 'plan-decision-classification'].sort();
test('semantic helper changes also select the separate DX analysis calibration', () => {
for (const file of ['test/helpers/plan-review-decisions.ts', 'test/plan-review-decisions.test.ts',
'test/helpers/plan-review-cases.ts', 'test/plan-review-cases.test.ts',
'test/skill-e2e-plan-decision-classification.test.ts', 'test/fixtures/plan-decision-classification.ts', 'test/plan-review-calibration.test.ts']) {
const shared = ['test/helpers/plan-review-decisions.ts', 'test/plan-review-decisions.test.ts',
'test/helpers/plan-review-cases.ts', 'test/plan-review-cases.test.ts'].includes(file);
const expected = shared ? [...IDS, 'plan-devex-peer-comparison-classification'] : [...IDS];
if (file === 'test/helpers/plan-review-decisions.ts' || file === 'test/plan-review-decisions.test.ts')
expected.push('plan-ceo-mode-routing');
// The UI gate now uses the shared picker for acknowledged native questions.
if (file === 'test/helpers/plan-review-cases.ts') expected.push('plan-design-with-ui-scope');
// plan-review-cases.test.ts also verifies the Eng template/renderer gate.
// Its direct behavioral consumers extend the unchanged helper-only set.
if (file === 'test/plan-review-cases.test.ts') expected.push(
'plan-eng-review', 'plan-eng-review-artifact', 'plan-review-report',
'plan-eng-review-plan-mode', 'plan-mode-no-op',
'carve-section-loading', 'plan-eng-finding-floor',
'plan-eng-review-format-coverage', 'plan-eng-review-format-kind',
'plan-ceo-review-prosons-cadence', 'plan-review-prosons-format',
'codex-offered-eng-review', 'plan-eng-coverage-audit', 'autoplan-dual-voice',
);
expect(selectTests([file], E2E_TOUCHFILES, []).selected.sort()).toEqual(
expected.sort());
}
for (const id of IDS) expect(E2E_TIERS[id]).toBe('periodic');
});
test('calibration briefs preserve source-required structure and actual choices without phase/qid reliance', () => {
const format = fs.readFileSync(path.join(ROOT, 'scripts/resolvers/preamble/generate-ask-user-format.ts'), 'utf8');
const split = fs.readFileSync(path.join(ROOT, 'docs/askuserquestion-split.md'), 'utf8');
-32
View File
@@ -10,7 +10,6 @@ import { fakePlanSeedPrelude } from './helpers/fake-plan-seed';
import { nativeSeededPlanSelection } from './helpers/plan-scope-selection';
import { isScopeGateQuestionVisible } from './helpers/claude-pty-runner';
import { readPlanCountTranscript, type NativePublicToolEvent, type PlanCountTranscript } from './helpers/plan-count-transcript';
import { selectTests, E2E_TOUCHFILES } from './helpers/touchfiles';
import captured_design_scope_announcement_ao from './fixtures/design-scope-announcement-ao.json';
import fixture_design_scope_declaration_ak from './fixtures/design-scope-declaration-ak.json';
import fs_design_scope_entry_aq from 'node:fs';
@@ -163,14 +162,6 @@ test('design scope question still requires the actual branch option', () => {
expect(isScopeGateQuestionVisible('What should I design-review?')).toBe(false);
expect(isScopeGateQuestionVisible('I should design-review the current branch diff.')).toBe(false);
});
test('seeded plan selection dependencies select the existing design and Eng mode checks', () => {
for (const file of ['test/helpers/plan-scope-selection.ts', 'test/plan-scope-selection.test.ts']) {
const selection = selectTests([file], E2E_TOUCHFILES);
expect(selection.selected).toContain('plan-design-review-plan-mode'); expect(selection.selected).toContain('plan-eng-review-plan-mode');
}
});
test('real PTY observation binds its explicit session and retains public diagnostics before cleanup', async () => {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'scope-pty-'));
const cli = createFakeBunCli(path.join(dir, 'fake-claude'), fakePlanSeedPrelude() + `
@@ -274,13 +265,6 @@ test('AG completed selection still requires this parent and a successful prior s
expect(verdict(fixture(text), { ...opts, sessionId: '' })).toBe(false);
expect(verdict(fixture(text), { ...opts, seed: opts.seed + '\n# Another plan' })).toBe(false);
});
test('AG actual scope fixture has exactly the existing two plan-mode owners', () => {
const selected = selectTests(['test/fixtures/design-plan-scope-ag.json'], E2E_TOUCHFILES).selected;
expect([...selected].sort()).toEqual(['plan-design-review-plan-mode', 'plan-eng-review-plan-mode']);
});
test('AG audit continuation cannot withdraw or relabel the current selection', () => {
const text = `I've selected reviewing the pasted "Marketing landing page" draft plan since we're in plan mode.`;
for (const tail of [
@@ -400,12 +384,6 @@ test('later current corrections defeat the draft selection while quoted history
expect(awCheck(p), text).toBe(true);
}
});
test('the AW public fixture selects the existing scope helper owners without a new paid test', () => {
expect(selectTests(['test/fixtures/plan-scope-target-aw.json'], E2E_TOUCHFILES, []).selected)
.toEqual(selectTests(['test/helpers/plan-scope-selection.ts'], E2E_TOUCHFILES, []).selected);
});
// Exact public AZ intros; identities and timestamps use the existing synthetic fixture.
const spokenEngIntros = [
"I'll run the eng review skill against your draft plan.",
@@ -863,16 +841,6 @@ test('a later explicit reselection follows the existing currentness rule', () =>
const p = input(), m = declaration(p); p.transcript.assistantMessages.push({ ...m, timestamp: new Date(Date.parse(m.timestamp) + 1000).toISOString(), text: 'This selection is withdrawn.' }); expect(verdict(p)).toBe(false);
p.transcript.assistantMessages.push({ ...m, timestamp: new Date(Date.parse(m.timestamp) + 2000).toISOString() }); expect(verdict(p)).toBe(true);
});
for (const owner of [
'plan-ceo-review-plan-mode', 'plan-eng-review-plan-mode',
'plan-design-review-plan-mode', 'plan-devex-review-plan-mode', 'plan-mode-no-op',
]) test(`scope dependency registration is dense for ${owner}`, () => {
const paths = E2E_TOUCHFILES[owner]!;
for (let index = 0; index < paths.length; index++) {
expect(Object.hasOwn(paths, index)).toBe(true);
expect(typeof paths[index]).toBe('string');
}
});
});
describe('plan-scope-recovery-av', () => {
-8
View File
@@ -8,8 +8,6 @@ import { setupQuestionEventSource, readPermissionRequestEvents } from './helpers
import retainedQuestionValidation from './fixtures/eng-auq-validation-error.json';
import retainedBashDirectory from './fixtures/bash-directory-permission.json';
import retainedDesignTasksPermission from './fixtures/design-tasks-bash-permission.json';
import { E2E_TOUCHFILES, selectTests } from './helpers/touchfiles';
const sessionId = '00000000-0000-4000-8000-000000000001';
const question: NativeQuestion = { question: 'D1 — Which approach?\nMake it reliable. Enforce the delivery policy.', header: 'Approach', multiSelect: false,
options: ['Extend dispatcher', 'Queue fanout', 'Minimal patch', 'Hold scope'].map(label => ({ label, description: label })) };
@@ -1858,12 +1856,6 @@ function bashHooks() {
return { source, input, response, emit, post, read };
}
test('captured directory Bash permission fixture selects every existing permission-helper consumer', () => {
const selected = selectTests(['test/fixtures/bash-directory-permission.json'], E2E_TOUCHFILES);
expect(selected.reason).toBe('diff');
expect(selected.selected.sort()).toEqual(selectTests(['test/helpers/plan-skill-questions.ts'], E2E_TOUCHFILES).selected.sort());
});
test('captured directory Bash card requires its exact owned request and permits only one grant', () => {
const { input, card, nativeId } = retainedBashDirectory;
const s = bashHooks(); s.emit('PreToolUse', nativeId, input);
-7
View File
@@ -4,14 +4,7 @@ import * as fs from 'node:fs';
import * as os from 'node:os';
import * as path from 'node:path';
import { spawnSync } from 'node:child_process';
import { E2E_TOUCHFILES, selectTests } from './helpers/touchfiles';
const ROOT = path.resolve(import.meta.dir, '..');
test('QA fixture regressions select only the QA fix loop', () => {
expect(selectTests(['test/qa-fix-loop-fixture.test.ts'], E2E_TOUCHFILES).selected).toEqual(['qa-fix-loop']);
});
test.each(['success', 'bash-edit', 'max-turns', 'no-edit', 'no-commit', 'runner', 'retry', 'directory', 'recording', 'late-timeout'])
('QA attempt recording and fixture ownership: %s', scenario => {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'qa-fix-body-'));
-7
View File
@@ -3,14 +3,7 @@ import * as fs from 'node:fs';
import * as os from 'node:os';
import * as path from 'node:path';
import {spawnSync} from 'node:child_process';
import {E2E_TOUCHFILES, selectTests} from './helpers/touchfiles';
const ROOT = path.resolve(import.meta.dir, '..');
test('QA-only capability regressions select the no-fix case', () => {
expect(selectTests(['test/qa-only-capability.test.ts'], E2E_TOUCHFILES).selected).toEqual(['qa-only-no-fix']);
});
test.each(['success', 'omitted-tools', 'report-edit', 'source-edit', 'source-write'])
('QA-only registered capability and no-fix contract: %s', scenario => {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'qa-tools-'));
-6
View File
@@ -3,8 +3,6 @@ import * as fs from 'node:fs';
import * as path from 'node:path';
import { JUDGE_MS, CAPTURE_MS } from './helpers/eval-budgets';
import { SESSION_DRAIN_GRACE_MS } from './helpers/session-runner';
import { E2E_TOUCHFILES } from './helpers/touchfiles';
const source=fs.readFileSync(path.join(import.meta.dir,'skill-e2e-review-army.test.ts'),'utf8');
async function exercise(scenarios: Array<'success'|'timeout'|'wrong-report'|'browse-error'>, fixturePath = path) {
const setups:any[]=[],done:any[]=[],callbacks:any[]=[],rows:any[]=[],calls:any[]=[];
@@ -61,7 +59,3 @@ test('Consensus caller fixture preserves success and semantic failure under eith
expect(x.rows.map(r=>r.passed)).toEqual([true,false]);
}
});
test('Consensus lifecycle controls select the existing consensus owner only',()=>{
expect(Object.entries(E2E_TOUCHFILES).filter(([,paths])=>paths.includes('test/review-consensus-lifecycle.test.ts')).map(([name])=>name)).toEqual(['review-army-consensus']);
});
@@ -103,7 +103,6 @@ test('scoring and section dependencies are explicit while existing clean and pas
test('new regression and changed preamble sources select all Design and Eng owners', () => {
for (const map of [E2E_TOUCHFILES, LLM_JUDGE_TOUCHFILES]) {
const affected = selectTests(['plan-design-review/SKILL.md.tmpl', 'plan-eng-review/SKILL.md.tmpl'], map, []).selected;
expect(selectTests(['test/review-entry-and-design-clarity-au.test.ts'], map, []).selected).toEqual(affected);
for (const source of ['scripts/resolvers/preamble/generate-preamble-bash.ts', 'scripts/resolvers/preamble/generate-completion-status.ts']) {
const selected = selectTests([source], map, []).selected;
for (const owner of affected) expect(selected).toContain(owner);
-6
View File
@@ -3,8 +3,6 @@ import * as fs from 'node:fs';
import * as path from 'node:path';
import { JUDGE_MS, CAPTURE_MS } from './helpers/eval-budgets';
import { SESSION_DRAIN_GRACE_MS } from './helpers/session-runner';
import { E2E_TOUCHFILES } from './helpers/touchfiles';
const source=fs.readFileSync(path.join(import.meta.dir,'skill-e2e-review.test.ts'),'utf8');
async function exercise(scenarios: Array<'success'|'timeout'|'wrong-report'|'browse-error'>) {
const setups:any[]=[],done:any[]=[],callbacks:any[]=[],rows:any[]=[],calls:any[]=[];
@@ -52,7 +50,3 @@ test('Enum semantic failure records false exactly once after the existing assert
test('Enum verdict retains the existing browser-error guard',async()=>{
const x=await exercise(['browse-error']);expect(x.rows).toHaveLength(1);expect(x.rows[0].passed).toBe(false);
});
test('Enum lifecycle controls select the existing enum owner only',()=>{
expect(Object.entries(E2E_TOUCHFILES).filter(([,paths])=>paths.includes('test/review-enum-lifecycle.test.ts')).map(([name])=>name)).toEqual(['review-enum-completeness']);
});
-8
View File
@@ -4,8 +4,6 @@ import * as fs from 'node:fs';
import * as os from 'node:os';
import * as path from 'node:path';
import { buildPaidShardArgs, retriesForFiles, resolvePaidShardTimeoutMs } from '../scripts/test-paid-shards';
import { E2E_TOUCHFILES, selectTests } from './helpers/touchfiles';
const ROOT = path.resolve(import.meta.dir, '..');
const PAID_FILE = 'test/skill-e2e-review.test.ts';
const CASES = [
@@ -13,12 +11,6 @@ const CASES = [
['review-enum-completeness', 300, 15],
['review-design-lite', 400, 35],
] as const;
test('review finalization regressions select all three owning cases', () => {
expect(selectTests(['test/review-finalization-budget.test.ts'], E2E_TOUCHFILES).selected?.sort())
.toEqual(CASES.map(([id]) => id).sort());
});
for (const [id, workMs, maxTurns] of CASES) {
test.each(['recover', 'both-timeout'])(`${id} records late results before retry or finalization: %s`, scenario => {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'review-finalization-'));
-9
View File
@@ -3,16 +3,7 @@ import * as fs from 'node:fs';
import * as os from 'node:os';
import * as path from 'node:path';
import {spawnSync} from 'node:child_process';
import {E2E_TOUCHFILES, selectTests} from './helpers/touchfiles';
const ROOT = path.resolve(import.meta.dir, '..');
test('N+1 native dispatch regressions select their paid case', () => {
for (const file of ['test/review-n-plus-one-contract.test.ts', 'test/fixtures/review-n-plus-one-dispatch.json']) {
expect(selectTests([file], E2E_TOUCHFILES).selected).toEqual(['review-army-perf-n-plus-one']);
}
});
test.each(['complete-control', 'captured-omission', 'claimed-only', 'background', 'missing-report', 'unrelated-report', 'captured-timeout'])
('N+1 registered completion contract: %s', scenario => {
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'n1-contract-'));
-9
View File
@@ -10,8 +10,6 @@ import { runRecordedOfficeHoursAttempt, OFFICE_HOURS_BUN_GRACE_MS } from './help
import { buildHermeticEnv } from './helpers/hermetic-env';
import { CAPTURE_MS } from './helpers/eval-budgets';
import { redactFindingSpans } from '../lib/redact-engine';
import { E2E_TOUCHFILES } from './helpers/touchfiles-data';
// Assemble synthetic credentials at runtime, as in gate-secret-scan.test.ts.
const CREDENTIAL = ['ghp_', 'aB3dE5fG7hI9jK1lM3nO5pQ7rS9tU1vW3xY5'].join('');
const source = fs.readFileSync(path.join(import.meta.dir, 'skill-e2e-setup-gbrain-path4-local-pglite.test.ts'), 'utf8');
@@ -133,13 +131,6 @@ test('Path4 public diagnostics exclude private fields and redact output, tools a
expect(serialized).not.toContain('apiKeySource');
expect(row.transcript).toHaveLength(3);
});
test('Path4 caller controls select only their registered paid owner', () => {
const owners = Object.entries(E2E_TOUCHFILES).filter(([, paths]) => paths.includes('test/setup-gbrain-path4-caller.test.ts')).map(([name]) => name);
expect(owners).toEqual(['setup-gbrain-path4-local-pglite']);
});
test('Path4 redacted credential URLs cannot erase success or mask a failed assertion', async () => {
// Text redaction can consume JSON punctuation after an unspaced URL host.
// These synthetic credentials exercise the real redactor and actual callback.
+1 -25
View File
@@ -79,17 +79,6 @@ describe('shared-code legacy interactive actor', () => {
await expect(callback('AskUserQuestion', { questions: [{ question: 'Decision', options: [option] }] }))
.rejects.toThrow('No unambiguous no-change option');
});
test('both native index-flag captures select every owning interactive lifecycle case', () => {
for (const fixture of ['test/fixtures/shared-libs-index-flags-skip-question.json',
'test/fixtures/shared-libs-index-flags-no-change-description.json']) {
expect(selectTests([fixture], E2E_TOUCHFILES, GLOBAL_TOUCHFILES).selected.sort()).toEqual([
'shared-libs-review-index-flags', 'shared-libs-review-lifecycle', 'shared-libs-review-path-eligibility',
'shared-libs-review-prior-coverage', 'shared-libs-review-revalidation',
]);
}
});
for (const [choose, labels] of [['approve', ['Fix it', 'Apply remedy', 'Approve', 'Extract helper', 'Reuse library', 'Choice (recommended)']],
['skip', ['Skip', 'Keep current', 'Decline', 'Do not change', 'Leave as-is']]] as const) {
test.each(labels)(`${choose} supports the declared choice: %s`, async label => {
@@ -159,13 +148,6 @@ describe('shared-code legacy interactive actor', () => {
expect(input).toEqual(original);
}
});
test('the captured native no-change questions select every owning interactive lifecycle case', () => {
expect(selectTests(['test/fixtures/shared-libs-index-flags-native-questions.json'], E2E_TOUCHFILES, GLOBAL_TOUCHFILES).selected.sort())
.toEqual(['shared-libs-review-index-flags', 'shared-libs-review-lifecycle', 'shared-libs-review-path-eligibility',
'shared-libs-review-prior-coverage', 'shared-libs-review-revalidation']);
});
test('the registered callback acknowledges the complete first-attempt native skip despite descriptive reuse', async () => {
const native = JSON.parse(fs.readFileSync(path.join(import.meta.dir, 'fixtures/shared-libs-index-flags-native-questions.json'), 'utf8'));
const { sourceRun, attempt, input } = native.regressions[0];
@@ -789,19 +771,13 @@ const interactive = [
'shared-libs-plan-callers', 'shared-libs-review-index-flags', 'shared-libs-review-lifecycle',
'shared-libs-review-path-eligibility', 'shared-libs-review-prior-coverage', 'shared-libs-review-revalidation',
];
const judged = ['shared-libs-opportunity-judgment', 'shared-libs-plan-callers', 'shared-libs-pr-coverage'];
const allShared = Object.keys(E2E_TOUCHFILES).filter(name => name.startsWith('shared-libs-')).sort();
const selected = (dependency: string) => selectTests([dependency], E2E_TOUCHFILES, GLOBAL_TOUCHFILES)
.selected.filter(name => name.startsWith('shared-libs-')).sort();
describe('shared-code paid dependency selection', () => {
test('SDK and judge changes select the actual affected owners', () => {
expect(selected('test/helpers/agent-sdk-runner.ts')).toEqual(interactive);
expect(selected('test/helpers/llm-judge.ts')).toEqual(judged);
});
test('generation, gating, fixture validation and host support keep their coverage owners', () => {
for (const dependency of ['scripts/gen-skill-docs.ts', 'test/helpers/e2e-gate.ts', 'test/shared-libs-fixture.test.ts']) {
for (const dependency of ['scripts/gen-skill-docs.ts', 'test/helpers/e2e-gate.ts']) {
expect(selected(dependency)).toEqual(allShared);
}
expect(selected('lib/claude-bin.ts')).toEqual(allShared.filter(name => name !== 'shared-libs-codex-read-only'));
-9
View File
@@ -3,8 +3,6 @@ import * as fs from 'node:fs';
import * as os from 'node:os';
import * as path from 'node:path';
import native from './fixtures/shared-libs-resolved-reads-public.json';
import { E2E_TOUCHFILES, GLOBAL_TOUCHFILES, selectTests } from './helpers/touchfiles';
const source = fs.readFileSync(path.join(import.meta.dir, 'skill-e2e-shared-libs-paths.test.ts'), 'utf8');
const detectorStart = source.indexOf('function sourceReadTrace(');
const callbackStart = source.indexOf('async function exerciseEligibility(');
@@ -122,13 +120,6 @@ test.each(['Read', 'Bash'])('direct alias reads retain the existing %s contract'
const result = { toolCalls: [{ tool, input: tool === 'Read' ? { file_path: aliases[0] } : { command: `cat ${aliases[0]}` } }] };
expect(detect(result, f, aliases)).toContain(aliases[0]);
});
test.each(['test/shared-libs-source-reads.test.ts', 'test/fixtures/shared-libs-resolved-reads-public.json'])('%s selects every owning path callback without a global fallback', file => {
expect(selectTests([file], E2E_TOUCHFILES, GLOBAL_TOUCHFILES).selected.sort()).toEqual([
'shared-libs-review-index-flags', 'shared-libs-review-path-eligibility', 'shared-libs-review-prior-coverage',
]);
});
test.each([false, true])('the actual eligibility callback consumes the read detector result (missing output=%s)', async missingOutput => {
const f = fixture();
const result: any = capture();
-5
View File
@@ -3,7 +3,6 @@ import fs from 'node:fs';
import path from 'node:path';
import * as evidence from './helpers/coverage-audit-evidence';
import { JUDGE_MS, CAPTURE_MS } from './helpers/eval-budgets';
import { E2E_TOUCHFILES } from './helpers/touchfiles-data';
import fixture from './fixtures/ship-coverage-audit-af.json';
import { randomUUID } from 'node:crypto';
import { validateCoverageAudit } from './helpers/coverage-audit';
@@ -93,10 +92,6 @@ test('AF ship actual read helper accepts only literal owned delivery before read
for(const row of fixture.rows.slice(0,2))expect((evidence as any).coverageAuditReadEvidence(row.result.transcript,{cwd:row.cwd,source:{path:row.cwd+'/src/billing.ts',content:fixture.files.source},tests:{path:row.cwd+'/test/billing.test.ts',content:fixture.files.tests}})).toEqual({sourceRead:true,testsRead:true});
});
test('AF ship controls and fixture select the one existing owner',()=>{
for(const name of ['test/ship-coverage-audit-af.test.ts','test/fixtures/ship-coverage-audit-af.json'])expect(Object.entries(E2E_TOUCHFILES).filter(([,files])=>files.includes(name)).map(([owner])=>owner)).toEqual(['ship-coverage-audit']);
});
function commandReads(command:string) {
const row=fixture.rows[0]!;const session=row.sessionId;
const transcript=[{type:'system',subtype:'init',session_id:session,cwd:row.cwd},
-7
View File
@@ -26,7 +26,6 @@ import { generateThirdPartyActions } from "../scripts/resolvers/third-party-acti
import { generateAsideSetup } from "../scripts/resolvers/aside";
import { HOST_PATHS } from "../scripts/resolvers/types";
import { asideDriveOptions } from './helpers/third-party-actions';
import { E2E_TOUCHFILES, selectTests } from './helpers/touchfiles';
import recoveryFixture from './fixtures/third-party-actions-recovery-public.json';
const ROOT = path.resolve(import.meta.dir, "..");
@@ -41,12 +40,6 @@ const ctx = {
const section = generateThirdPartyActions(ctx);
describe('consent offer extraction', () => {
test('helper changes select the consent gate evals', () => {
expect(selectTests(['test/helpers/third-party-actions.ts'], E2E_TOUCHFILES, []).selected.sort()).toEqual([
'tpa-absent-darwin', 'tpa-absent-linux', 'tpa-apple-ban', 'tpa-broken', 'tpa-present',
]);
});
test('an unavailable-option explanation is not an offer', () => {
expect(asideDriveOptions(`B) I drive it in gstack's own visible browser
C) Manual instructions
+51 -65
View File
@@ -18,6 +18,7 @@ import {
GLOBAL_TOUCHFILES,
} from './helpers/touchfiles';
import { paidTestClosure, isCovered } from './helpers/touchfile-closure';
import { readWorkflowExcerpt } from './helpers/workflow-excerpt';
import { sharedLibsPlanExcerpt } from './helpers/shared-libs-plan-excerpt';
@@ -115,7 +116,7 @@ describe('selectTests', () => {
},
);
test.each(['lib/cso/cli.ts', 'lib/cso/state.ts', 'test/cso-cli.test.ts', 'test/cso-snapshot-state.test.ts'])(
test.each(['lib/cso/cli.ts', 'lib/cso/state.ts'])(
'CSO runtime and report regressions select all three audit cases: %s', (file) => {
const result = selectTests([file], E2E_TOUCHFILES);
expect(result.reason).toBe('diff');
@@ -135,14 +136,6 @@ describe('selectTests', () => {
},
);
test.each(['test/helpers/coverage-audit.ts', 'test/coverage-audit.test.ts'])(
'coverage-audit validation changes select all three gate cases: %s', (file) => {
const result = selectTests([file], E2E_TOUCHFILES);
expect(result.selected.sort()).toEqual(['plan-eng-coverage-audit', 'review-coverage-audit', 'ship-coverage-audit']);
expect(result.selected.every(id => E2E_TIERS[id] === 'gate')).toBe(true);
},
);
test('testing resolver source selects the same E2E consumers as its generated content', () => {
const consumers = [
['plan-eng-review/sections/review-sections.md', 'TEST_COVERAGE_AUDIT_PLAN'],
@@ -243,33 +236,6 @@ describe('selectTests', () => {
expect(result.selected).toContain('plan-design-review/SKILL.md passes');
});
test('the shared recording lifecycle selects every bounded attempt', () => {
const result = selectTests(['test/helpers/office-hours-attempt.ts'], E2E_TOUCHFILES);
const expected = {
'office-hours-forcing-energy': 'periodic',
'office-hours-builder-wildness': 'periodic',
'office-hours-brain-writeback': 'periodic',
'plan-design-review-plan-mode': 'periodic',
'plan-ceo-review-format-mode': 'periodic',
'plan-ceo-review-format-approach': 'periodic',
'plan-eng-review-format-coverage': 'periodic',
'plan-eng-review-format-kind': 'periodic',
'plan-ceo-review-prosons-cadence': 'periodic',
'plan-review-prosons-format': 'periodic',
'plan-review-prosons-hardstop-neg': 'periodic',
'plan-review-prosons-neutral-neg': 'periodic',
'setup-gbrain-bad-token': 'periodic',
'setup-gbrain-path4-local-pglite': 'periodic',
'setup-gbrain-remote': 'periodic',
'review-army-red-team': 'periodic',
'review-coverage-audit': 'gate',
'plan-eng-coverage-audit': 'gate',
'ship-coverage-audit': 'gate',
'plan-review-report': 'gate',
};
expect(result.selected.sort()).toEqual(Object.keys(expected).sort());
for (const [id, tier] of Object.entries(expected)) expect(E2E_TIERS[id]).toBe(tier);
});
test('browse/src change selects browse and qa tests', () => {
const result = selectTests(['browse/src/commands.ts'], E2E_TOUCHFILES);
@@ -299,33 +265,14 @@ describe('selectTests', () => {
test('mode-question capture dependencies select its native gate', () => {
for (const file of [
'test/auq-mode-capture.test.ts', 'test/skill-ceo-section-ordering.test.ts',
'test/helpers/agent-sdk-runner.ts', 'test/helpers/auq-native-capture.ts',
'test/helpers/hermetic-env.ts', 'test/helpers/eval-store.ts',
'lib/claude-bin.ts', 'test/workflow-excerpt.test.ts',
'lib/claude-bin.ts',
]) {
expect(selectTests([file], E2E_TOUCHFILES).selected).toContain('auq-format-gate');
}
});
test('shared-code evidence regressions select their consuming evaluations', () => {
expect(selectTests(['test/fixtures/shared-libs-readonly-substitution-ci16358.json'], E2E_TOUCHFILES).selected.sort())
.toEqual(['shared-libs-codex-read-only', 'shared-libs-opportunity-judgment', 'shared-libs-pr-coverage',
'shared-libs-read-only', 'shared-libs-unsupported-git'].sort());
for (const file of ['test/helpers/shared-libs-review-start-evidence.ts', 'test/shared-libs-review-start-evidence.test.ts',
'test/fixtures/shared-libs-review-start-public.json',
'test/fixtures/shared-libs-revalidation-max-turns-public.json']) {
expect(selectTests([file], E2E_TOUCHFILES).selected).toEqual(['shared-libs-review-revalidation']);
}
const pathCases = ['shared-libs-review-path-eligibility', 'shared-libs-review-index-flags',
'shared-libs-review-prior-coverage'];
expect(selectTests(['test/shared-libs-revalidation-prompt.test.ts'], E2E_TOUCHFILES).selected.sort())
.toEqual([...pathCases, 'shared-libs-review-revalidation'].sort());
expect(selectTests(['test/fixtures/shared-libs-index-flags-skip-question.json'], E2E_TOUCHFILES).selected.sort())
.toEqual([...pathCases, 'shared-libs-review-revalidation', 'shared-libs-review-lifecycle'].sort());
expect(selectTests(['test/fixtures/shared-libs-paths-max-turns-public.json'], E2E_TOUCHFILES).selected)
.toEqual(['shared-libs-review-index-flags']);
});
test('skill-specific change selects only that skill and related tests', () => {
const result = selectTests(['plan-ceo-review/SKILL.md'], E2E_TOUCHFILES);
@@ -376,7 +323,6 @@ describe('selectTests', () => {
test.each([
'test/helpers/hermetic-skill-runtime.ts',
'test/hermetic-skill-runtime.test.ts',
'lib/fs-atomic.ts',
])('live runtime dependency selects PTY consumers: %s', (file) => {
const result = selectTests([file], E2E_TOUCHFILES);
@@ -385,13 +331,6 @@ describe('selectTests', () => {
expect(result.selected).not.toContain('retro');
});
test('session tool isolation regression selects its capture workflows', () => {
const result = selectTests(['test/session-runner-tools.test.ts'], E2E_TOUCHFILES);
expect(result.selected.sort()).toEqual([
'auq-format-gate', 'carve-section-loading', 'plan-ceo-section-loading', 'plan-design-review-plan-mode', 'ship-section-loading',
]);
expect(result.reason).toBe('diff');
});
test('gen-skill-docs.ts is a scoped touchfile, not global', () => {
const result = selectTests(['scripts/gen-skill-docs.ts'], E2E_TOUCHFILES);
@@ -408,7 +347,7 @@ describe('selectTests', () => {
expect(result.selected).not.toContain('cso-full-audit');
});
test.each(['test/helpers/ceo-finding-fixture.ts', 'test/ceo-finding-fixture.test.ts', 'test/ceo-mode-routing-fixture.test.ts'])('mode input dependency selects its periodic eval: %s', file => {
test.each(['test/helpers/ceo-finding-fixture.ts'])('mode input dependency selects its periodic eval: %s', file => {
const result = selectTests([file], E2E_TOUCHFILES);
expect(result.selected).toContain('plan-ceo-mode-routing');
expect(result.reason).toBe('diff');
@@ -731,3 +670,50 @@ describe('reverse invariant — keys must name living paid tests', () => {
expect(stale.map(([k]) => k), 'exception points at a deleted file — remove the entry').toEqual([]);
});
});
describe('derived touchfile closure', () => {
const { isPaidTestFile } = require('./helpers/paid-test-set') as typeof import('./helpers/paid-test-set');
const paid = fs.readdirSync(path.join(ROOT, 'test')).map(name => `test/${name}`).filter(isPaidTestFile).sort();
const source = Object.fromEntries(paid.map(file => [file, fs.readFileSync(path.join(ROOT, file), 'utf8')]));
const quotes = (file: string, key: string) =>
source[file]!.includes(`'${key}'`) || source[file]!.includes(`"${key}"`) || source[file]!.includes('`' + key + '`');
/** A key belongs to the paid files in its own list, else to the paid files that quote it. */
const owners = (key: string, deps: readonly string[]) => {
const listed = deps.filter(dep => paid.includes(dep));
return listed.length ? listed : paid.filter(file => quotes(file, key));
};
const maps = [['E2E_TOUCHFILES', E2E_TOUCHFILES], ['LLM_JUDGE_TOUCHFILES', LLM_JUDGE_TOUCHFILES]] as const;
/** Paid files no key selects; they run only by tier or census. */
const KEYLESS_PAID: Record<string, string> = {
'test/codex-e2e-recommendation-substance.test.ts': 'census-only Codex case; PERIODIC_CI_EXCLUDE (no codex CLI in CI)',
'test/skill-e2e-auq-consistency.test.ts': 'periodic tier gate only (describeE2ETier), never diff-selected',
'test/skill-e2e-auq-verbose-vs-carved-ab.test.ts': 'periodic tier gate only (describeE2ETier), never diff-selected',
};
test('no free test file is a touchfile', () => {
const listed = maps.flatMap(([name, map]) => Object.entries(map).flatMap(([key, deps]) =>
deps.filter(dep => dep.endsWith('.test.ts') && !isPaidTestFile(dep)).map(dep => `${name}['${key}']: ${dep}`)));
expect(listed, 'Editing a free test must not select paid evals; remove these entries').toEqual([]);
});
test('every key covers the static helper/fixture closure and literal fixture paths of its paid files', () => {
const boundary = new Set(GLOBAL_TOUCHFILES);
const failures: string[] = [];
for (const [name, map] of maps) for (const [key, deps] of Object.entries(map)) {
for (const owner of owners(key, deps)) for (const entry of paidTestClosure(ROOT, owner, boundary)) {
if (isCovered(entry.file, deps, GLOBAL_TOUCHFILES)) continue;
failures.push(`paid test ${owner} depends on ${entry.file}\n via ${entry.chain.join(' -> ')}\n` +
` add '${entry.file}' to ${name}['${key}']`);
}
}
expect(failures.length, failures.length ? `${failures.join('\n')}\n` +
'Verify with: bun run scripts/test-paid-shards.ts --tier gate --profile pr --list\n' +
'See CONTRIBUTING.md#paid-test-touchfiles. This rule is a lower bound: fixture paths built at runtime ' +
'are not visible to it, so declare them in the key by hand.' : '').toBe(0);
});
test('keyless paid files are exactly the declared exemptions', () => {
const keyed = (file: string) => maps.some(([, map]) => Object.entries(map).some(([key, deps]) => deps.includes(file) || quotes(file, key)));
expect(paid.filter(file => !keyed(file))).toEqual(Object.keys(KEYLESS_PAID).sort());
});
});
-8
View File
@@ -1,6 +1,5 @@
import { describe, expect, test } from 'bun:test';
import { ENG_REVIEW_EXCERPT, readWorkflowExcerpt } from './helpers/workflow-excerpt';
import { LLM_JUDGE_TOUCHFILES, selectTests } from './helpers/touchfiles';
import { mkdtempSync, readFileSync, rmSync, writeFileSync } from 'fs';
import { tmpdir } from 'os';
import { join } from 'path';
@@ -54,13 +53,6 @@ function expectOutsideReviewControlFlow(text: string, promptHeading: string): vo
}
describe('workflow judge excerpts', () => {
test('helper changes select all dependent workflow judges', () => {
const selected = selectTests(['test/helpers/workflow-excerpt.ts'], LLM_JUDGE_TOUCHFILES, []).selected;
expect(selected).toHaveLength(14);
expect(selected).toContain('ship/SKILL.md workflow');
expect(selected).toContain('plan-design-review/SKILL.md passes');
});
test('expands ship sections in execution order, not alphabetical order', () => {
const text = readWorkflowExcerpt('ship/SKILL.md', '# Ship:', '## Important Rules');
const headings = ['## Step 3:', '## Step 4:', '## Step 7:', '## Step 8:', '## Step 9:', '## Step 10:', '## Step 11:', '## Step 12:', '## Step 13:', '## Step 14:'];