test(qa-observer): fix mode treats atomic temps of authorized src/test writes as transient

CI webhook-fix failed with 'Could not watch test/worker.regression-1.test.ts.tmp...':
Claude Code's Write renamed its temp before the per-file watch was added. The
functional eval now tells the observer its mode, and a temp whose target that
mode may write is observed through its directory watch. Report-only mode and
undeclared paths keep failing closed.
This commit is contained in:
garrytan committed 2026-09-30 19:49:54 +00:00
1 parent b541f28ddb
commit 00dacee8bd
3 files changed
+16 -5

No files matched your search

+1 -1
View File
@@ -103,7 +103,7 @@ export async function runQAFunctionalCase(entry: { id: string; family: QAFamily;
fixtureGit(fixture.root, ['commit', '-m', 'Bind current QA instructions to fixture']);
fixture.revision = fixtureGit(fixture.root, ['rev-parse', 'HEAD']);
if (fixtureGit(fixture.root, ['status', '--porcelain'])) throw new Error('QA fixture must start clean');
observer = await observeQAWrites(fixture.root, { evidenceProducer: true });
observer = await observeQAWrites(fixture.root, { evidenceProducer: true, atomicWriteMode: entry.mode });
await runRecordedOfficeHoursAttempt({
collector, name: entry.id, suite: 'Functional QA native E2E',
model: process.env.EVALS_MODEL ?? resolveEvalModel('capture'),
+4 -2
View File
@@ -72,7 +72,7 @@ export interface QAWriteObservation {
limits: string[];
}
export async function observeQAWrites(root: string, options: { reportDirectory?: string; evidenceProducer?: boolean; atomicTargets?: string[] } = {}) {
export async function observeQAWrites(root: string, options: { reportDirectory?: string; evidenceProducer?: boolean; atomicTargets?: string[]; atomicWriteMode?: QAMode } = {}) {
if (process.platform !== 'linux') throw new Error('QA write observer unavailable: Linux inotify required');
if (fs.realpathSync(root) !== root) throw new Error('Observer root must be canonical');
let reportDirectory: string | undefined;
@@ -83,7 +83,9 @@ export async function observeQAWrites(root: string, options: { reportDirectory?:
}
const transientFile = (relative: string) => qaWriteAllowed(relative, 'qa-only')
|| (reportDirectory !== undefined && relative.startsWith(reportDirectory + path.sep))
|| (options.atomicTargets ?? []).some(target => relative.startsWith(target + '.tmp.') && /^\.tmp\.[1-9]\d*\.[0-9a-f]{12}$/.test(relative.slice(target.length)));
|| (options.atomicTargets ?? []).some(target => relative.startsWith(target + '.tmp.') && /^\.tmp\.[1-9]\d*\.[0-9a-f]{12}$/.test(relative.slice(target.length)))
|| (options.atomicWriteMode !== undefined && /\.tmp\.[1-9]\d*\.[0-9a-f]{12}$/.test(relative)
&& qaWriteAllowed(relative.replace(/\.tmp\.[1-9]\d*\.[0-9a-f]{12}$/, ''), options.atomicWriteMode));
const before = qaTreeSnapshot(root);
const { dlopen, FFIType, ptr } = await import('bun:ffi');
const libc = dlopen('libc.so.6', {