Files
gstack/test/outside-voice-preflight.test.ts
T
Garry Tan dcaea52800 v1.91.7.0 feat: add functional QA and pre-publication docs checks (#2983)
* feat: add surface-aware exploratory QA and ship documentation gates

* test: preserve delegated QA setup authority after main integration

* fix(qa): clarify exploration order and preserve report artifacts

* test(qa): follow the shared setup reference directly

* refactor(ship): make verification and recovery routes explicit

* test(ship): align evidence and review guards with explicit routes

* fix(workflows): clarify ship recovery and functional QA evidence

* fix(workflows): clarify approval recovery and full QA coverage

* refactor(workflows): order review transactions and clarify ship state

* fix(ship): clarify final verification and fail closed at publication

* fix(evals): attribute native atomic documentation writes

* fix(ship): clarify recovery and documentation lifecycle guidance

* fix(test): preserve observed native placeholder styling in CI

* fix(codex): report watchdog timeouts without a process-exit race

* Checkpoint functional QA implementation and workflow validation repairs

* Fix documentation and shared-review fixture contracts

* docs: clarify judge reuse and evaluation supervision

* test: align review evidence and selected case contracts

* test: verify append-only documentation checkpoints and recovery

* fix: qualify QA workflows and CI validation repairs

* fix: launch shared-libs fixture scripts on Windows

* fix: qualify QA deadlines, fixture isolation, and shard cleanup

* fix: preserve qualified QA and cancellation repairs

* fix: enforce functional fixture authority and share strict event decoding

* fix: retain free-test evidence and explain recovery

* fix: reject malformed native evidence after decoder consolidation

* test: use reliable capture for telemetry privacy filters

* test: refresh measured quick coverage and document validation costs

* Fix native fixture receipts and preserve VM validation evidence

* Align negative judge controls with upstream clarity policy

* Fix report-only QA preparation and public evidence handling

* Clarify QA-only preparation and current-report preservation

* Stream Ship quality judgments with an explicit 64k response contract

* Validate compact judge reasoning locally with supported wire schema

* Align functional QA fixture instructions with evidence acceptance

* Bind native browser diagnostics to execution evidence and align review verdicts

* Preserve native diagnostic line boundaries

* Serialize functional QA evidence from native captures

* Keep large QA evidence fixture payload out of Windows argv
2026-09-29 06:07:35 -07:00

239 lines
15 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/** Execute each outside-review fence with no state from a previous shell. */
import { afterAll, describe, expect, test } from 'bun:test';
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 { outsideVoiceCommand, outsideVoicePreflight, outsideVoiceInvocation } from '../scripts/resolvers/outside-voice';
import { generateAdversarialStep, generateCodexDocReview, generateCodexPlanReview } from '../scripts/resolvers/review';
import { validateOutsideReview } from '../lib/outside-review-result';
import { HOST_PATHS, type TemplateContext } from '../scripts/resolvers/types';
import { ALL_HOST_CONFIGS } from '../hosts';
const ROOT = path.resolve(import.meta.dir, '..');
const TEMP = fs.mkdtempSync(path.join(os.tmpdir(), 'gstack-outside-preflight-'));
afterAll(() => fs.rmSync(TEMP, { recursive: true, force: true }));
test('adversarial outside failures retain the required native pass without duplicate dispatch', () => {
for (const host of ALL_HOST_CONFIGS) {
for (const skillName of ['ship', 'review']) {
const ctx: TemplateContext = { host: host.name, skillName, tmplPath: `${skillName}/SKILL.md.tmpl`, paths: HOST_PATHS[host.name] };
const preflight = outsideVoicePreflight(ctx, { disabledBehavior: 'codex-only' });
expect(preflight).toMatch(/(?:do not dispatch a duplicate|without duplicating it)/);
expect(preflight).not.toMatch(/fall(?:ing)? back to (?:a|the) .*subagent/i);
const output = generateAdversarialStep(ctx);
expect(output).toContain('adversarial subagent (always runs)');
expect(output).toContain('For non-ready modes, retain the native pass above; do not dispatch it again.');
expect(output.match(/Retain the required native pass without duplicating it; it cannot complete outside coverage\./g)).toHaveLength(2);
expect(output).not.toContain("Use the caller's fallback");
expect(output).toContain('Only this optional outside adversarial pass is non-blocking');
expect(output).toContain('GATE: MISSING COVERAGE');
expect(outsideVoiceInvocation(ctx)).toContain("Use the caller's fallback; missing coverage is never clean/PASS.");
const disabled = outsideVoicePreflight(ctx, { disabledBehavior: 'skip-all' });
expect(disabled).toMatch(/(?:do NOT fall back|Disabled ends this entire extra review step)/);
}
}
});
test('ship design availability is an existing automatic choice, not a new opt-in', () => {
for (const host of ALL_HOST_CONFIGS) {
const ctx: TemplateContext = { host: host.name, skillName: 'ship', tmplPath: 'ship/SKILL.md.tmpl', paths: HOST_PATHS[host.name] };
const output = outsideVoicePreflight(ctx, { disabledBehavior: 'opt-in' });
expect(output).toContain('Ship attempts this optional design check automatically when frontend review applies');
expect(output).toContain('No additional opt-in is needed');
expect(output).toContain('Step 11 keeps its separate outside-review switch');
expect(output).toContain('`CODEX_MODE` reports provider availability, not user consent');
expect(output).not.toContain('Honor this caller’s existing opt-in/skip choice');
expect(output).not.toContain('This caller has its own opt-in/skip control');
const other = outsideVoicePreflight({ ...ctx, skillName: 'review' }, { disabledBehavior: 'opt-in' });
expect(other).toContain('Honor this caller’s existing opt-in/skip choice');
expect(other).not.toContain('No additional opt-in is needed');
expect(other).toContain('_OUTSIDE_CFG=enabled # This caller has its own opt-in/skip control.');
expect(output.match(/```bash\n([\s\S]*?)\n```/)![1]).toBe(other.match(/```bash\n([\s\S]*?)\n```/)![1].replace(
'_OUTSIDE_CFG=enabled # This caller has its own opt-in/skip control.', '_OUTSIDE_CFG=enabled'));
}
});
test('CEO and Eng describe the actual disabled route and completion validator', () => {
for (const host of ALL_HOST_CONFIGS) {
for (const skillName of ['plan-ceo-review', 'plan-eng-review']) {
const ctx: TemplateContext = { host: host.name, skillName, tmplPath: `${skillName}/SKILL.md.tmpl`, paths: HOST_PATHS[host.name] };
const output = generateCodexPlanReview(ctx);
expect(output).not.toContain('Skip this section entirely');
if (skillName === 'plan-ceo-review') {
expect(output.replace(/\s+/g, ' ')).toContain('If preflight selected `disabled`, use the guarded record below');
expect(output).toContain('"outside_status":"disabled"');
} else expect(output).toContain('persist `outside_status: disabled` with the guarded');
const prompt = output.slice(output.indexOf('"IMPORTANT:'), output.indexOf('\n<plan content>"'));
expect(prompt).toContain('End with Recommendation: <action> because <specific reason>');
expect(prompt).toContain('If there are no findings, say so and explain why');
const invocation = outsideVoiceInvocation(ctx);
expect(invocation).toContain('missing Recommendation: <action> because <reason> markers');
expect(invocation).not.toContain('score/severity/completion');
if (skillName === 'plan-eng-review') {
const routing = output.slice(output.indexOf('**Outcome routing:**'), output.indexOf('**Disabled is a terminal branch'));
expect(routing).toMatch(/\| Disabled \|[^\n]*No prompt, outside process or native replacement\./);
expect(routing).toMatch(/\| Other preflight mode, including harness mismatch \|[^\n]*Native fallback\./);
expect(routing).toMatch(/\| Outside execution or output validation fails \|[^\n]*finish termination, then use Native fallback\./);
expect(routing).toMatch(/\| Native fallback unavailable or fails \|[^\n]*No clean-review credit\./);
const fallback = output.slice(output.indexOf('**Native fallback'), output.indexOf('Dispatch via the Agent tool'));
expect(fallback.replace(/\s+/g, ' ')).toContain('Immediately before dispatch, check the preflight result again: disabled means no replacement');
const bounded = output.slice(output.indexOf('**Bounded outside-voice wait'), output.indexOf('**Cross-model tension:**'));
expect(bounded).toContain('A native result never supplies outside coverage.');
expect(output).toContain('A completed native fallback uses SOURCE=in-host, OUTSIDE_STATUS=unavailable, and STATUS=clean or issues_found from its findings');
expect(output).toContain('"unavailable" if neither reviewer completed');
expect(output).toContain('Never count missing coverage as a clean review');
expect(output).toContain("These findings are the reviewer's, even if later resolved by the parent");
// Compact prose must retain the actual wrong-harness execution guard.
expect(invocation).toContain('exit 78');
expect(invocation.indexOf('exit 78')).toBeLessThan(invocation.indexOf('_OUTSIDE_TMP=$(mktemp'));
} else {
const prose = output.replace(/\s+/g, ' ');
expect(prose).toContain('Other preflight failures retain their printed diagnosis, including harness mismatch');
const fallback = prose.slice(prose.indexOf('**Native fallback —'), prose.indexOf('Dispatch via the Agent tool'));
expect(fallback).toContain('Immediately before dispatch, recheck whether reviews are enabled');
expect(fallback).toContain('`CODEX_MODE: disabled`, return to **Record the disabled outcome** without dispatching');
expect(prose).toContain('Its opening harness guard rechecks the fresh shell: exit 78 uses the same Native fallback below, never a replacement provider');
expect(prose).toContain('A native result never supplies outside coverage.');
expect(invocation).toContain('exit 78');
expect(invocation.indexOf('exit 78')).toBeLessThan(invocation.indexOf('_OUTSIDE_TMP=$(mktemp'));
}
}
}
expect(validateOutsideReview('Recommendation: proceed because no findings remain.', 'review').completed).toBe(true);
expect(validateOutsideReview('SCORE: 10\nAMBIGUITIES: NONE', 'review').completed).toBe(false);
expect(validateOutsideReview('Recommendation: proceed', 'review').completed).toBe(false);
});
describe('own-harness review fallback instructions', () => {
for (const host of ALL_HOST_CONFIGS) {
for (const [name, render] of [['plan', generateCodexPlanReview], ['documentation', generateCodexDocReview]] as const) {
test(`${host.name}: ${name} fallback names only the mode its preflight emits`, () => {
const ctx: TemplateContext = { host: host.name, skillName: 'review', tmplPath: 'review/SKILL.md.tmpl', paths: HOST_PATHS[host.name] };
const text = render(ctx);
const mode = host.name === 'codex' ? 'under_current_harness' : 'under_codex';
const preflight = text.match(/```bash\n([\s\S]*?)\n```/)![1];
expect(preflight).toContain(mode);
expect([...new Set(text.match(/under_codex|under_current_harness/g))]).toEqual([mode]);
expect(text.includes("retain the section's native pass if defined")).toBe(false);
const fallback = text.slice(text.indexOf('**Native fallback'), text.indexOf('Dispatch via the Agent tool'));
const ownHarnessBranch = `On \`CODEX_MODE: ${mode}\``;
expect(text.split(ownHarnessBranch)).toHaveLength(2);
expect(fallback).toContain(ownHarnessBranch);
expect(fallback).toContain('`outside_status: unavailable`');
expect(fallback).toContain('run no outside CLI');
expect(fallback).toContain('use the native subagent below');
expect(fallback).toContain('A native result never supplies outside coverage.');
expect(fallback).toContain('The disabled branch never reaches this fallback.');
expect(fallback).toContain('`CODEX_MODE: disabled`, finish this section with `outside_status: disabled`;');
});
}
}
});
function fixture() {
const dir = fs.mkdtempSync(path.join(TEMP, 'case-'));
const repo = path.join(dir, "repo ' $(touch NEVER)");
const home = path.join(dir, 'home');
fs.mkdirSync(repo);
fs.mkdirSync(home);
const git = spawnSync('git', ['init', '-q'], { cwd: repo, encoding: 'utf8' });
if (git.status !== 0) throw new Error(git.stderr);
const capture = path.join(dir, 'capture.json');
const fake = path.join(dir, 'fake-claude.ts');
fs.writeFileSync(fake, `const prompt=await Bun.stdin.text(); await Bun.write(process.env.FIXTURE_CAPTURE!,JSON.stringify({prompt,args:process.argv.slice(2)})); console.log(JSON.stringify({result:'Recommendation: ship because the isolated fixture completed its review.'}));`);
const env = { ...process.env, HOME: home, CODEX_HOME: '', GSTACK_HOME: path.join(home, '.gstack'),
GSTACK_ROOT: '', GSTACK_BIN: '', GSTACK_ACTIVE_HOST: 'codex', CODEX_THREAD_ID: 'fixture', CODEX_SANDBOX: '', CLAUDECODE: '',
GSTACK_CLAUDE_BIN: process.execPath, GSTACK_CLAUDE_BIN_ARGS: JSON.stringify([fake]), FIXTURE_CAPTURE: capture };
const install = (destination: string) => {
fs.mkdirSync(path.dirname(destination), { recursive: true });
fs.symlinkSync(ROOT, destination, 'dir');
return destination;
};
const local = path.join(repo, '.agents/skills/gstack');
const global = path.join(home, '.codex/skills/gstack');
const ctx: TemplateContext = { host: 'codex', model: 'gpt', skillName: 'review', tmplPath: 'review/SKILL.md.tmpl', paths: HOST_PATHS.codex };
const run = (command: string, overrides: NodeJS.ProcessEnv = {}) => spawnSync('bash', ['-c', command], {
cwd: repo, env: { ...env, ...overrides }, encoding: 'utf8', timeout: 10_000,
});
const preflight = (overrides: NodeJS.ProcessEnv = {}) => {
const rendered = outsideVoicePreflight(ctx, { disabledBehavior: 'opt-in' });
const command = rendered.match(/```bash\n([\s\S]*?)\n```/)![1];
return run(`${command}\nprintf 'RESOLVED_ROOT: %s\\n' "$GSTACK_ROOT"`, overrides);
};
return { repo, home, env, local, global, ctx, capture, install, run, preflight };
}
describe('outside reviewer runtime discovery in fresh shells', () => {
test('a repo-local installation resolves before any preamble exports exist', () => {
const f = fixture();
f.install(f.local);
f.install(f.global);
const result = f.preflight();
expect(result.status).toBe(0);
expect(result.stdout).toContain('CODEX_MODE: ready');
expect(result.stdout).toContain(`RESOLVED_ROOT: ${f.local}`);
expect(result.stderr).toBe('');
// The availability probe resolves a CLI; it must not dispatch a review.
expect(fs.existsSync(f.capture)).toBe(false);
});
test('global installation and CODEX_HOME both work without a local installation', () => {
const f = fixture();
f.install(f.global);
expect(f.preflight().stdout).toContain(`RESOLVED_ROOT: ${f.global}`);
const codexHome = path.join(f.home, 'custom codex');
const custom = f.install(path.join(codexHome, 'skills/gstack'));
const result = f.preflight({ CODEX_HOME: codexHome });
expect(result.stdout).toContain('CODEX_MODE: ready');
expect(result.stdout).toContain(`RESOLVED_ROOT: ${custom}`);
});
test('valid explicit runtime roots take priority and stale roots fall back locally', () => {
const f = fixture();
f.install(f.local);
const explicit = f.install(path.join(f.home, 'explicit runtime'));
expect(f.preflight({ GSTACK_ROOT: explicit }).stdout).toContain(`RESOLVED_ROOT: ${explicit}`);
expect(f.preflight({ GSTACK_BIN: path.join(explicit, 'bin') }).stdout).toContain(`RESOLVED_ROOT: ${explicit}`);
const result = f.preflight({ GSTACK_ROOT: '/missing/gstack', GSTACK_BIN: '/missing/gstack/bin' });
expect(result.stdout).toContain('CODEX_MODE: ready');
expect(result.stdout).toContain(`RESOLVED_ROOT: ${f.local}`);
});
test('missing CLI reports not_installed rather than an import-path failure', () => {
const f = fixture();
f.install(f.local);
const result = f.preflight({ GSTACK_CLAUDE_BIN: 'missing-gstack-claude-fixture-command' });
expect(result.stdout).toContain('CODEX_MODE: not_installed');
expect(result.stderr).toBe('');
expect(fs.existsSync(f.capture)).toBe(false);
});
test('master switch is read from the discovered runtime before outside dispatch', () => {
const f = fixture();
f.install(f.local);
const config = spawnSync(path.join(ROOT, 'bin/gstack-config'), ['set', 'codex_reviews', 'disabled'], {
cwd: f.repo, env: f.env, encoding: 'utf8', timeout: 5000,
});
expect(config.status).toBe(0);
const command = outsideVoicePreflight(f.ctx, { disabledBehavior: 'codex-only' }).match(/```bash\n([\s\S]*?)\n```/)![1];
const result = f.run(command);
expect(result.stdout).toContain('CODEX_MODE: disabled');
expect(fs.existsSync(f.capture)).toBe(false);
});
test('invocation independently discovers runtime and sends the literal prompt', () => {
const f = fixture();
f.install(f.local);
const prompt = path.join(f.repo, "prompt ' literal.txt");
fs.writeFileSync(prompt, 'Review literal $(touch NEVER) and `touch NEVER` text.');
const command = outsideVoiceCommand(f.ctx, { promptFile: prompt, timeoutMs: 3000 });
const result = f.run(command);
expect(result.status).toBe(0);
expect(result.stdout).toContain('OUTSIDE_STATUS: completed provider=claude-code host=codex');
expect(JSON.parse(fs.readFileSync(f.capture, 'utf8')).prompt).toBe(fs.readFileSync(prompt, 'utf8'));
expect(fs.existsSync(path.join(f.repo, 'NEVER'))).toBe(false);
});
});