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
This commit is contained in:
Garry Tan authored and GitHub committed 2026-09-29 06:07:35 -07:00
1 parent 65bfb0ce49
commit dcaea52800
333 files changed
+41755 -7357

No files matched your search

+70
View File
@@ -0,0 +1,70 @@
import * as path from 'node:path';
export interface DocsCompletion {
schema_version: 1;
audit_id: string;
status: 'updated' | 'current' | 'blocked';
files_updated: string[];
files_reviewed: string[];
documentation_section: string;
blockers: string[];
decisions: string[];
}
const keys = ['schema_version', 'audit_id', 'status', 'files_updated', 'files_reviewed', 'documentation_section', 'blockers', 'decisions'];
export function parseDocsCompletion(output: string, auditId: string): DocsCompletion {
const result = JSON.parse(output.trimEnd().split('\n').at(-1)!);
if (!result || Array.isArray(result) || typeof result !== 'object' ||
Object.keys(result).sort().join() !== [...keys].sort().join()) throw new Error('completion fields');
if (result.schema_version !== 1 || result.audit_id !== auditId) throw new Error('completion identity');
if (!['updated', 'current', 'blocked'].includes(result.status)) throw new Error('completion status');
for (const field of ['files_updated', 'files_reviewed', 'blockers', 'decisions']) {
if (!Array.isArray(result[field]) || result[field].some((v: unknown) => typeof v !== 'string' || !v.trim())) {
throw new Error(`completion ${field}`);
}
}
if (typeof result.documentation_section !== 'string' || !result.documentation_section.trim()) throw new Error('completion markdown');
for (const field of ['files_updated', 'files_reviewed']) {
const paths: string[] = result[field];
if (new Set(paths).size !== paths.length || paths.some(p => path.posix.isAbsolute(p) || p.includes('\\') ||
p.split('/').some(part => !part || part === '.' || part === '..') || /[*?\[\]]/.test(p))) throw new Error('completion paths');
}
if (result.status === 'blocked' ? result.blockers.length === 0 : result.blockers.length !== 0) throw new Error('completion blockers');
if (result.status === 'current' && result.files_updated.length !== 0 ||
result.status === 'updated' && result.files_updated.length === 0) throw new Error('completion edits');
return result;
}
export function vetDocsCompletion(result: DocsCompletion, evidence: {
settled: boolean;
markerSeen: boolean;
headUnchanged: boolean;
indexUnchanged: boolean;
candidateUnchanged: boolean;
readOnly: boolean;
changedPaths: string[];
allowedDocs: string[];
}): void {
if (!evidence.settled || !evidence.markerSeen) throw new Error('unsettled or unmarked child');
if (!evidence.headUnchanged || !evidence.indexUnchanged) throw new Error('Git ownership violation');
if (!evidence.candidateUnchanged) throw new Error('stale candidate');
if (evidence.readOnly && evidence.changedPaths.length) throw new Error('read-only mutation');
if ([...evidence.changedPaths].sort().join('\0') !== [...result.files_updated].sort().join('\0')) throw new Error('unreported edits');
const forbidden = /(?:^|\/)(?:VERSION|CHANGELOG(?:\.[^/]*)?|TODOS(?:\.[^/]*)?|package(?:-lock)?\.json|[^/]*lock[^/]*|manifest\.json)$/i;
if (evidence.changedPaths.some(p => forbidden.test(p) || !evidence.allowedDocs.includes(p))) throw new Error('non-doc mutation');
}
export function extractDocsDispatch(section: string): string {
const begin = section.indexOf('**Subagent prompt:**');
const end = section.indexOf('**Parent processing:**');
if (begin < 0 || end <= begin) throw new Error('documentation dispatch markers moved');
return section.slice(begin + '**Subagent prompt:**'.length, end)
.split('\n').map(line => line.replace(/^> ?/, '')).join('\n').trim();
}
export function docsDispatchIndex(calls: Array<{ tool: string; input: unknown }>): number {
return calls.findIndex(call => ['Agent', 'Task'].includes(call.tool) &&
/document-release\/SKILL\.md|executing the \/document-release workflow/i.test(JSON.stringify(call.input)) &&
!/Parent processing:|## Step 19: Create PR\/MR/.test(JSON.stringify(call.input)));
}