Files
gstack/test/helpers/qa-checkpoint-evidence.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

223 lines
14 KiB
TypeScript

import * as fs from 'node:fs';
import * as path from 'node:path';
import { isDeepStrictEqual } from 'node:util';
import { qaEvidenceCommand, qaEvidenceHash, qaNativeCapture, qaProducerReceipt, type QaEvidenceContext } from './qa-evidence-producer';
const checkpointName = /^exploration-\d{3}\.json$/;
const object = (value: unknown): value is Record<string, any> => value !== null && typeof value === 'object' && !Array.isArray(value);
function safeRoot(root: string): void {
if (!path.isAbsolute(root) || path.resolve(root) !== root || root === path.parse(root).root
|| !fs.lstatSync(root).isDirectory() || fs.realpathSync(root) !== root) throw new Error('Unsafe checkpoint report root');
}
export function readQACheckpointFiles(reportRoot: string): Record<string, string> {
safeRoot(reportRoot);
const files: Record<string, string> = {};
for (const name of fs.readdirSync(reportRoot).filter(name => checkpointName.test(name)).sort()) {
const target = path.join(reportRoot, name);
const stat = fs.lstatSync(target);
if (!stat.isFile() || stat.nlink !== 1) throw new Error(`Unsafe checkpoint file: ${name}`);
const fd = fs.openSync(target, fs.constants.O_RDONLY | fs.constants.O_NOFOLLOW);
try {
const opened = fs.fstatSync(fd);
if (!opened.isFile() || opened.nlink !== 1 || opened.dev !== stat.dev || opened.ino !== stat.ino) throw new Error(`Changed checkpoint file: ${name}`);
files[name] = fs.readFileSync(fd, 'utf8');
} finally { fs.closeSync(fd); }
}
return files;
}
type Probe = { command: string; observed: unknown };
type Call = { id: string; parent: string | null; name: string; input: Record<string, any>; start: number; end: number; output: string; failed: boolean; file?: { path: string; content: string } };
export function nativeCalls(transcript: unknown[], failures: string[]): Call[] {
const calls = new Map<string, Call>();
for (const [index, raw] of transcript.entries()) {
if (!object(raw)) { failures.push('Malformed native event'); continue; }
if (!['assistant', 'user'].includes(raw.type)) continue;
const parent = raw.parent_tool_use_id ?? null;
if (parent !== null && typeof parent !== 'string') { failures.push('Malformed native parent scope'); continue; }
if (!Array.isArray(raw.message?.content)) {
if (raw.message?.content != null && typeof raw.message.content !== 'string') failures.push('Malformed native message content');
continue;
}
for (const block of raw.message.content) {
if (!object(block)) { failures.push('Malformed native content block'); continue; }
if (raw.type === 'assistant' && block.type === 'tool_use') {
const key = JSON.stringify([parent, block.id]);
if (typeof block.id !== 'string' || !block.id || calls.has(key) || typeof block.name !== 'string' || !object(block.input)) {
failures.push('Missing or duplicate native tool identity');
continue;
}
calls.set(key, { id: block.id, parent, name: block.name, input: block.input, start: index, end: -1, output: '', failed: false });
} else if (raw.type === 'user' && block.type === 'tool_result') {
const call = calls.get(JSON.stringify([parent, block.tool_use_id]));
if (!call || call.end !== -1) { failures.push('Orphaned or duplicate native result'); continue; }
call.end = index;
call.failed = block.is_error === true || call.name === 'Bash' && raw.tool_use_result?.interrupted === true;
if (typeof block.content === 'string') call.output = block.content;
else if (Array.isArray(block.content) && block.content.every(part => object(part) && part.type === 'text' && typeof part.text === 'string')) {
call.output = block.content.map(part => part.text).join('\n');
} else { call.failed = true; failures.push('Unsupported native result content'); }
const file = raw.tool_use_result?.type === 'text' ? raw.tool_use_result.file : undefined;
if (call.name === 'Read' && !call.failed && object(file) && typeof call.input.file_path === 'string' && file.filePath === call.input.file_path && typeof file.content === 'string'
&& file.startLine === 1 && file.numLines === file.content.split('\n').length && file.totalLines === file.numLines
&& call.output === file.content.split('\n').map((line: string, index: number) => `${index + 1}\t${line}`).join('\n')) {
call.file = { path: file.filePath, content: file.content };
}
}
}
}
for (const call of calls.values()) {
if (call.end < 0) failures.push('Missing native tool completion');
}
return [...calls.values()];
}
function nativeJSON(output: string): unknown[] {
try { return [JSON.parse(output)]; } catch {}
return output.split('\n').flatMap(line => {
try { const value = JSON.parse(line); return object(value) || Array.isArray(value) ? [value] : []; } catch { return []; }
});
}
export function validateQACheckpoints(input: {
transcript: unknown[];
reportRoot: string;
probes: Probe[];
requiredProbes: Probe[];
additionalTargets?: Array<{ command: string; output: string }>;
files: Record<string, string>;
reportMarkdown: string;
producer?: QaEvidenceContext;
}): string[] {
const failures: string[] = [];
let disk: Record<string, string>;
try { disk = readQACheckpointFiles(input.reportRoot); }
catch { return ['Unsafe or missing checkpoint report root/artifact']; }
if (!isDeepStrictEqual(disk, input.files)) failures.push('Checkpoint files differ from actual disk artifacts');
const calls = nativeCalls(input.transcript, failures);
const bound: Array<{ probe: Probe; call: Call }> = [];
for (const probe of input.probes) {
const matches = calls.filter(call => {
if (call.name !== 'Bash' || call.input.command !== probe.command || call.end <= call.start) return false;
const capture = qaNativeCapture(call, input.producer);
const produced = qaEvidenceCommand(call.input.command, input.producer) || /^bun \S*\/gstack-qa-evidence(?:\s|['"]\s)/.test(call.input.command)
|| call.output.split('\n').some(line => line.startsWith('QA_EVIDENCE '));
return produced ? !!capture && isDeepStrictEqual(capture.captured.observed, probe.observed) : isDeepStrictEqual(nativeJSON(call.output), [probe.observed]);
});
if (matches.length !== 1 || bound.some(row => row.call === matches[0])) failures.push(`Unbound or ambiguous native probe: ${probe.command}`);
else bound.push({ probe, call: matches[0] });
}
bound.sort((a, b) => a.call.start - b.call.start);
const notes: Array<{ name: string; call: Call; value: Record<string, any>; intent?: Call }> = [];
const written = new Set<string>();
for (const call of calls) {
const producerCommand = call.name === 'Bash' ? qaEvidenceCommand(call.input.command, input.producer) : undefined;
let attempted = call.input.file_path;
let content = call.input.content;
let intent: Call | undefined;
if (producerCommand?.action === 'checkpoint') {
const producer = qaProducerReceipt(call, input.producer);
const name = `exploration-${producerCommand.id}.json`;
const writes = producerCommand.intent ? [call] : calls.filter(write => write.name === 'Write' && !write.failed && write.parent === call.parent
&& write.end > write.start && write.end < call.start && write.input.file_path === producerCommand.source
&& typeof write.input.content === 'string' && qaEvidenceHash(write.input.content) === producer?.receipt.intentSha256);
if (!producer || writes.length !== 1 || typeof disk[name] !== 'string' || qaEvidenceHash(disk[name]) !== producer.receipt.sha256) {
failures.push(`Checkpoint lacks completed native producer and intent: ${name}`);
continue;
}
intent = writes[0];
let decision: any;
let published: any;
const intentText = producerCommand.intent ? JSON.stringify(producerCommand.intent) : intent.input.content;
try { decision = JSON.parse(intentText); } catch {}
try { published = JSON.parse(disk[name]); } catch {}
const captures = bound.filter(row => row.call.parent === call.parent && row.call.end < intent!.start
&& row.probe.command === decision?.observationCommand).map(row => ({ row, producer: qaNativeCapture(row.call, input.producer) }))
.filter(row => row.producer?.command.id === producer.receipt.capture && row.producer.receipt.sha256 === producer.receipt.captureSha256);
const capture = captures.length === 1 ? captures[0] : undefined;
const read = capture && (capture.producer!.command.publicOutput || calls.some(read => read.name === 'Read' && !read.failed && read.parent === call.parent
&& read.start > capture.row.call.end && read.end > read.start && read.end < intent!.start
&& read.file?.path === path.join(input.reportRoot, `.qa-evidence/${producer.receipt.capture}/observation.json`)
&& read.file.content === capture.producer!.captured.observationText));
if (!capture || !read || !object(decision) || decision.capture !== producer.receipt.capture
|| qaEvidenceHash(intentText) !== producer.receipt.intentSha256
|| !isDeepStrictEqual(Object.keys(decision).sort(), ['capture', 'hypothesis', 'nextCommand', 'observationCommand'])
|| !isDeepStrictEqual(published, { observationCommand: decision.observationCommand, observed: capture.row.probe.observed, hypothesis: decision.hypothesis, nextCommand: decision.nextCommand })
|| producerCommand.source && calls.some(change => ['Write', 'Edit'].includes(change.name) && change.input.file_path === producerCommand.source
&& change.start > intent!.end && change.start < call.end)) {
failures.push(`Checkpoint intent lacks its completed observation read: ${name}`);
continue;
}
attempted = path.join(input.reportRoot, name);
content = disk[name];
}
if (call.name === 'Bash' && producerCommand?.action !== 'checkpoint' && typeof call.input.command === 'string' && /exploration-\d+\.json/.test(call.input.command)) {
failures.push('Unsupported checkpoint Bash interaction');
}
if (typeof attempted !== 'string' || !path.basename(attempted).startsWith('exploration-')) continue;
if (call.name === 'Read') continue;
const name = path.basename(attempted);
if ((call.name !== 'Write' && !intent) || !checkpointName.test(name) || attempted !== path.join(input.reportRoot, name)) {
failures.push(`Unsupported checkpoint write/path: ${attempted}`);
continue;
}
if (written.has(name)) failures.push(`Reused or overwritten checkpoint: ${name}`);
written.add(name);
if (call.failed || call.end <= call.start) { failures.push(`Checkpoint Write did not complete successfully: ${name}`); continue; }
if (typeof content !== 'string' || !Object.hasOwn(disk, name) || disk[name] !== content) {
failures.push(`Checkpoint artifact differs from captured Write: ${name}`);
continue;
}
const destinations = [...input.reportMarkdown.matchAll(/\[[^\]\n]*\]\(([^\s)]+)(?:\s+"[^"]*")?\)/g)].map(match => match[1]);
if (!destinations.some(destination => destination === name || destination === `./${name}` || destination === path.join(input.reportRoot, name))) {
failures.push(`Report does not link checkpoint: ${name}`);
}
let value: unknown;
try { value = JSON.parse(content); } catch {}
if (!object(value) || !isDeepStrictEqual(Object.keys(value).sort(), ['hypothesis', 'nextCommand', 'observationCommand', 'observed'])
|| typeof value.hypothesis !== 'string' || value.hypothesis.trim().length <= 20
|| !/[a-z]{3}/i.test(value.hypothesis) || typeof value.observationCommand !== 'string' || typeof value.nextCommand !== 'string') {
failures.push(`Invalid checkpoint schema: ${name}`);
continue;
}
notes.push({ name, call, value, ...(intent ? { intent } : {}) });
}
for (const name of Object.keys(disk)) if (!written.has(name)) failures.push(`Checkpoint has no public Write: ${name}`);
const additional: Array<{ command: string; call: Call }> = [];
for (const target of input.additionalTargets ?? []) {
if (!notes.some(note => note.value.nextCommand === target.command)) continue;
const matches = calls.filter(call => call.name === 'Bash' && call.input.command === target.command
&& call.end > call.start && call.output === target.output);
if (matches.length !== 1 || bound.some(row => row.call === matches[0]) || additional.some(row => row.call === matches[0])) {
failures.push(`Unbound or ambiguous additional checkpoint target: ${target.command}`);
} else additional.push({ command: target.command, call: matches[0] });
}
const owners = new Map<Call, typeof notes>();
for (const target of [...bound.map(row => ({ command: row.probe.command, call: row.call })), ...additional]) {
const previous = bound.filter(row => row.call.parent === target.call.parent && row.call.start < target.call.start).at(-1);
owners.set(target.call, notes.filter(note => previous && note.call.parent === target.call.parent
&& note.call.start > previous.call.end && note.call.end < target.call.start
&& (!note.intent || note.intent.start > previous.call.end)
&& note.value.observationCommand === previous.probe.command && isDeepStrictEqual(note.value.observed, previous.probe.observed)
&& note.value.nextCommand === target.command
&& !calls.some(call => call.name === 'Bash' && call.parent === target.call.parent && call.input.command === target.command
&& call.start >= note.call.start && call.start < target.call.start)));
}
const targets = new Set<Call>();
for (const required of input.requiredProbes) {
const matches = bound.filter(row => row.probe.command === required.command && isDeepStrictEqual(row.probe.observed, required.observed));
if (matches.length !== 1 || targets.has(matches[0].call)) { failures.push(`Unbound or reused checkpoint target: ${required.command}`); continue; }
const target = matches[0];
targets.add(target.call);
if (owners.get(target.call)?.length !== 1) failures.push(`Missing unique completed checkpoint before probe: ${required.command}`);
}
for (const note of notes) {
const matches = [...owners.values()].filter(candidates => candidates.includes(note));
if (matches.length !== 1 || matches[0].length !== 1) failures.push(`Unrelated, reused or retrospective checkpoint: ${note.name}`);
}
return failures.map(failure => `QA checkpoint: ${failure}`);
}