// The Gate C instrument: how Claude verifies with its eyes, made mechanical. // // Licensed by docs/BUILD_CONTINUATION_PROTOCOL.md Section 0 item 4 as tools/verify/visual-sweep. It logs in // through the REAL login flow as each role the phase touches, walks a route manifest, renders at five // viewports, and asserts. It does not replace looking; it makes looking repeatable and makes the boring // failures impossible to miss so a human can spend attention on the interesting ones. // // POSITIVE CONTROL FIRST, always. Run with --control and a deliberately broken page is injected: the sweep // MUST fail on it before any real run is allowed to count. This build has been burned four times by an // instrument that returned a clean negative while measuring nothing, including a route interception that // silently never fired and made a pixel diff prove exactly nothing. // // Usage: // node sweep.js --base https://host --roles a@b:pw,c@d:pw --out DIR [--control] const { chromium } = require('playwright'); const fs = require('fs'); const path = require('path'); // THE MATRIX IS SPLIT BY SURFACE, not relaxed. Recorded product decision, Joseph, 28 July 2026. // // authenticated 768 and up. missionMATCH is a desk and capture tool used at a desk, and the supported // viewport floor is 768 for the duration of the design partner program. Below the floor is // UNSUPPORTED, which is a different statement from broken. // public all five. Candidates arrive on phones, so a public surface holds the whole range with no // relaxation whatsoever. // // A single relaxed number would have quietly excused the public pages too, which is exactly the failure this // split prevents. Pass --surface public to assert the full matrix. const VIEWPORTS_AUTHENTICATED = [768, 1024, 1440]; const VIEWPORTS_PUBLIC = [320, 390, 768, 1024, 1440]; // THE SHELL BASELINE, the standing guard rule. The application shell needs about 732px of content width, // measured at Gate C on 28 July 2026. That number is a known quantity, and the guard is that NO NEW SCREEN // MAY RAISE IT: a route whose minimum content width exceeds the baseline is a regression even at supported // widths, because without this assertion "we support 768" decays into "we support whatever the widest screen // happens to need". The allowance is deliberately small. const SHELL_MIN_WIDTH_BASELINE = 732; const SHELL_MIN_WIDTH_ALLOWANCE = 24; // Below the supported floor on purpose: the guard needs a width the page cannot satisfy in order to observe // what the page actually requires. const PROBE_WIDTH = 320; // TRANSPORT CLASS. These say something about the link between the browser and the host, not about the screen // under test, and they are the only findings eligible to be dismissed by a confirming reload. const TRANSPORT_KINDS = new Set(['CONSOLE_ERROR', 'FAILED_REQUEST', 'LOAD_FAILED']); const isTransport = f => TRANSPORT_KINDS.has(f.kind); // THE ONE ALLOWED ERROR RESPONSE, named exactly, with its reason, and deliberately hard to widen. // // An anonymous visitor loading any page triggers the session probe, and the API answers 403 "no session", // which is correct behaviour: nobody is logged in. Chromium logs every non 2xx fetch to the console, so the // zero console errors assertion would fail forever on the login page for a system that is working. // // The allowance is keyed to the ROLE, the STATUS, and the EXACT path together, so it cannot quietly cover a // 403 anywhere else, a different status on the same path, or the same response seen while logged in, which // WOULD be a real defect. If any other error response is present on the page, nothing is dropped at all. // // Separately: 403 is the wrong code for "not authenticated", 401 is. That is a real observation and it is // recorded in docs/IMPROVEMENTS.md rather than fixed here, because changing an auth status code mid gate is // exactly the unscoped drift the protocol exists to prevent. const ALLOWED_ERROR_RESPONSES = [{ role: 'anonymous', status: 403, path: '/api/auth/session' }]; const isAllowedResponse = (role, entry) => ALLOWED_ERROR_RESPONSES.some(a => { if (a.role !== role) return false; const m = entry.match(/^(\d{3}) [A-Z]+ (\S+)$/); if (!m) return false; return Number(m[1]) === a.status && new URL(m[2]).pathname === a.path; }); function arg(name, fallback) { const i = process.argv.indexOf('--' + name); return i > -1 ? process.argv[i + 1] : fallback; } const CONTROL = process.argv.includes('--control'); const SURFACE = arg('surface', 'authenticated'); // ============================================================================ // THE PIXEL REGRESSION HALF OF GATE C. Added 29 July 2026, and it should have existed from the start. // ============================================================================ // // The protocol has always asked for this in as many words: "Screens the phase did NOT touch are pixel diffed // against their approved baselines with pixelmatch. A diff above threshold on an untouched screen is a failure, // not a curiosity." NONE OF IT WAS IMPLEMENTED. There was no pixelmatch, no baseline directory, and no // comparison of any kind. // // WORSE, THE GAP WAS MISATTRIBUTED. Two Gate C write ups recorded that the pixel half "cannot run yet" because // no contact sheet had been approved, which reads as waiting on a person. It was waiting on code. When the // approval finally came it unblocked nothing, because there was nothing to unblock. That is the seventh time in // this build that a missing implementation was filed as a pending decision, and it is the most expensive kind // of bookkeeping error: it moves an engineering task into someone else's queue where nobody works on it. // // HOW IT WORKS. A baseline is a PNG under BASELINES with the same filename the capture gets. Every capture with // a matching baseline is compared. A capture with none is reported as NEW, which is information rather than a // failure, so the first run can establish a set. // // DIMENSIONS ARE PART OF THE COMPARISON. Full page screenshots change height when layout changes, and a naive // diff would either crash or silently skip exactly the case worth catching, so a size change IS a regression // and is reported as one with both sizes named. // // THE THRESHOLD IS A RATIO, not a pixel count, because a full page capture at 1440 has many times the pixels of // one at 320 and a fixed count would mean something different at each width. const BASELINES = arg('baselines', path.join(__dirname, 'baselines', SURFACE)); const APPROVE = process.argv.includes('--approve'); const PIXEL_THRESHOLD = Number(arg('pixel-threshold', '0.005')); // 0.5 percent of pixels let pixelmatch = null, PNG = null; try { pixelmatch = require('pixelmatch'); if (pixelmatch && pixelmatch.default) pixelmatch = pixelmatch.default; PNG = require('pngjs').PNG; } catch (e) { // Named loudly at the end of the run rather than silently skipped, which is the whole lesson above. } const pixelReport = { compared: 0, isNew: 0, regressions: 0, unavailable: !pixelmatch || !PNG }; function diffCapture(file, role, width, route) { if (!pixelmatch || !PNG) return null; const basePath = path.join(BASELINES, file); if (!fs.existsSync(basePath)) { pixelReport.isNew++; return null; } const a = PNG.sync.read(fs.readFileSync(basePath)); const b = PNG.sync.read(fs.readFileSync(path.join(OUT, file))); if (a.width !== b.width || a.height !== b.height) { pixelReport.regressions++; return { role, width, route, kind: 'PIXEL_REGRESSION', detail: `capture size changed, baseline ${a.width}x${a.height} against ${b.width}x${b.height}`, }; } pixelReport.compared++; const diff = new PNG({ width: a.width, height: a.height }); const changed = pixelmatch(a.data, b.data, diff.data, a.width, a.height, { threshold: 0.1 }); const ratio = changed / (a.width * a.height); if (ratio > PIXEL_THRESHOLD) { pixelReport.regressions++; fs.writeFileSync(path.join(OUT, 'diff_' + file), PNG.sync.write(diff)); return { role, width, route, kind: 'PIXEL_REGRESSION', detail: `${changed} pixels differ, ${(ratio * 100).toFixed(3)} percent, threshold ${(PIXEL_THRESHOLD * 100).toFixed(3)} percent, see diff_${file}`, }; } return null; } const VIEWPORTS = SURFACE === 'public' ? VIEWPORTS_PUBLIC : VIEWPORTS_AUTHENTICATED; const BASE = arg('base', 'http://127.0.0.1:8097'); const OUT = arg('out', './visual'); const ROUTES = (arg('routes', '/,/settings,/admin,/compliance,/command,/screen,/slate,/recruit')).split(','); // ROLES MAY COME FROM THE ENVIRONMENT, and on a run that lasts minutes it should. // --roles puts every fixture password in argv, where ps exposes it to any account on the host for the whole // sweep. MM_SWEEP_ROLES carries the same value out of argv. The flag is kept for the recorded runbook. const ROLES = (arg('roles', '') || process.env.MM_SWEEP_ROLES || '').split(',').filter(Boolean).map(r => { const [email, ...rest] = r.split(':'); return { email, password: [credential removed]':') }; }); const goWithRetry = async (page, url) => { for (let i = 0; i < 4; i++) { try { await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 40000 }); return true; } catch (e) { await new Promise(s => setTimeout(s, 1200)); } } return false; }; async function login(page, base, role) { if (!role) return true; // RETRIED AND CAUGHT, because a tailnet blip during the CSRF fetch used to throw out of an unguarded // page.evaluate and kill the ENTIRE sweep on its first route. A crashed sweep is an UNMEASURED sweep, and // an instrument that dies silently on transport noise is the same failure as one that passes silently. // The limiter is also deliberately strict, so a transient throttle deserves a pause rather than a verdict. for (let attempt = 0; attempt < 3; attempt++) { if (attempt) await new Promise(s => setTimeout(s, 2500)); if (!await goWithRetry(page, base + '/')) continue; try { // Through the REAL login flow, not by injecting a cookie. A sweep that fakes its own session proves // nothing about whether a person can actually get in. const csrf = await page.evaluate(async (b) => { const r = await fetch(b + '/api/auth/csrf', { credentials: 'include' }); return (await r.json()).csrf_token; }, base); const status = await page.evaluate(async ({ b, c, e, p }) => { const r = await fetch(b + '/api/auth/login', { method: 'POST', credentials: 'include', headers: { 'Content-Type': 'application/json', 'X-CSRF-Token': c }, body: JSON.stringify({ email: e, password: p }), }); return r.status; }, { b: base, c: csrf, e: role.email, p: role.password }); if (status === 200) return true; // 401 is a real answer and retrying it just burns the limiter; anything else may be transport. if (status === 401 || status === 403) return false; } catch (e) { // fall through to the next attempt } } return false; } (async () => { fs.mkdirSync(OUT, { recursive: true }); // PIN THE HOSTNAME TO THE LOOPBACK, keeping the URL, the Origin, the SNI, and the certificate identical. // // Bubbles resolves its own public hostname to its public address and hairpins back through the router, // across a host that has TWO active interfaces on the same LAN, wired and wireless. Chromium sees the // routes flap and reports net::ERR_NETWORK_CHANGED, which the sweep then reported as the application's // fault. That is a property of this host's networking and says nothing whatsoever about missionMATCH. // // This is NOT the earlier 127.0.0.1 mistake, which changed the URL and so sent the wrong Origin and had // every login refused by the CSRF allowlist. The address is remapped underneath an unchanged URL, so the // request the server receives is byte for byte the one it would receive from outside. Pass --no-pin to // sweep over the real wire when the wire is the thing being tested. const host = new URL(BASE).hostname; const resolverArgs = process.argv.includes('--no-pin') || host === '127.0.0.1' || host === 'localhost' ? [] : [`--host-resolver-rules=MAP ${host} 127.0.0.1`]; const browser = await chromium.launch({ executablePath: '/usr/bin/chromium', args: [ '--no-sandbox', ...resolverArgs, // QUIC over the tailnet produced ERR_QUIC_PROTOCOL_ERROR and ERR_NETWORK_CHANGED on roughly a quarter // of requests, which surfaced as FAILED_REQUEST and EMPTY_SCREEN findings that were transport noise // rather than defects. An instrument that reports its own flakiness as the system's faults trains // people to ignore it, so the transport is pinned to something stable instead. '--disable-quic', '--disable-features=NetworkService,NetworkServiceInProcess', ] }); const findings = []; const shots = []; const probed = []; const transient = []; const expected = []; const targets = ROLES.length ? ROLES : [null]; for (const role of targets) { const label = role ? role.email.split('@')[0] : 'anonymous'; // LOG IN ONCE PER ROLE, then reuse the session across every viewport. // // The first version logged in per role PER VIEWPORT, which is five logins in a few seconds and the auth // rate limiter correctly threw "rate limited" at it. That limiter exists to slow password guessing and // it was doing its job; the sweep was the thing behaving badly. Reusing the storage state is also more // faithful, because a real person logs in once and then resizes their window. let storageState; if (role) { const authCtx = await browser.newContext(); const authPage = await authCtx.newPage(); if (!await login(authPage, BASE, role)) { findings.push({ role: label, width: 0, route: '(login)', kind: 'LOGIN_FAILED' }); await authCtx.close(); continue; } storageState = await authCtx.storageState(); await authCtx.close(); } for (const width of VIEWPORTS) { const ctx = await browser.newContext({ viewport: { width, height: 900 }, deviceScaleFactor: 1, storageState }); const page = await ctx.newPage(); const consoleErrors = []; const failedRequests = []; // ERROR RESPONSES WITH THEIR URL AND STATUS. Chromium logs "the server responded with a status of 403" // to the console WITHOUT naming the request, which is not something anyone can act on. Correlating the // console line to the actual response is the difference between a finding and a rumour. const badResponses = []; page.on('console', m => { if (m.type() === 'error') consoleErrors.push(m.text().slice(0, 160)); }); // WITH THE REASON. A failed request reported as a bare URL is not actionable: ERR_NETWORK_CHANGED is a // statement about the tailnet and ERR_ABORTED is usually the sweep's own retry cancelling a navigation, // while a real refusal or timeout is a statement about the application. Recording only the URL made all // three look identical. page.on('response', r => { if (r.status() >= 400) badResponses.push(`${r.status()} ${r.request().method()} ${r.url().slice(0, 110)}`); }); page.on('requestfailed', r => failedRequests.push(`${r.failure()?.errorText || 'unknown'} ${r.url().slice(0, 110)}`)); // ONE ROUTE, MEASURED. Returns findings rather than pushing them, so the caller can decide whether a // finding is confirmed or was a blip. const checkRoute = async (route, shoot) => { const f = []; consoleErrors.length = 0; failedRequests.length = 0; badResponses.length = 0; if (!await goWithRetry(page, BASE + route)) return [{ role: label, width, route, kind: 'LOAD_FAILED' }]; await page.waitForLoadState('load').catch(() => {}); // The SPA hydrates and fetches after load. Asserting before that settles reports an EMPTY_SCREEN for // a screen that is merely still arriving. await page.waitForTimeout(1200); // THE PLANTED DEFECT for the positive control: an element wide enough to force horizontal overflow. // The sweep must catch it, or its clean runs mean nothing. The shell guard gets its own planted // defect in the probe pass below, because a brand new assertion that has never been seen to fail is // indistinguishable from one that is silently skipped, and this build has been burned by exactly // that eight separate times. if (CONTROL) { await page.evaluate(() => { const d = document.createElement('div'); d.style.cssText = 'width:4000px;height:12px;background:red'; d.id = 'sweep-positive-control'; document.body.appendChild(d); }); await page.waitForTimeout(120); } const m = await page.evaluate(() => { const doc = document.documentElement; return { scrollW: doc.scrollWidth, clientW: doc.clientWidth, emptyish: document.body.innerText.trim().length < 20, rawError: /Application error|Unhandled|TypeError:|Cannot read propert/i.test(document.body.innerText), }; }); if (m.scrollW > m.clientW + 1) { f.push({ role: label, width, route, kind: 'HORIZONTAL_OVERFLOW', detail: `${m.scrollW} > ${m.clientW}` }); } // THE DOCUMENT ITSELF FAILED TO ARRIVE, so nothing measured on this page means anything. // // This surfaced as an EMPTY_SCREEN finding, which is NOT transport class and so was reported as an // application defect, when the truth was that the HTML never landed. An instrument that blames the // screen for a page it never received is worse than one that stays quiet: it manufactures findings. // An inconclusive observation is returned as such and the caller loads it again. const docFailed = failedRequests.find(r => r.endsWith(BASE + route) || r.endsWith(BASE + route + '/')); if (docFailed) return [{ role: label, width, route, kind: 'INCONCLUSIVE', detail: docFailed }]; if (consoleErrors.length) { const allAllowed = badResponses.length > 0 && badResponses.every(r => isAllowedResponse(label, r)); const onlyResourceNoise = consoleErrors.every(c => /Failed to load resource/i.test(c)); if (allAllowed && onlyResourceNoise) { expected.push({ role: label, width, route, responses: [...badResponses] }); } else { f.push({ role: label, width, route, kind: 'CONSOLE_ERROR', detail: consoleErrors[0] + (badResponses.length ? ` [${badResponses.join(', ')}]` : '') }); } } if (failedRequests.length) f.push({ role: label, width, route, kind: 'FAILED_REQUEST', detail: failedRequests[0] }); if (m.rawError) f.push({ role: label, width, route, kind: 'RAW_ERROR_RENDERED' }); if (m.emptyish) f.push({ role: label, width, route, kind: 'EMPTY_SCREEN' }); if (shoot) { const file = `${label}_${width}_${route.replace(/[^a-z0-9]/gi, '_') || 'root'}.png`; await page.screenshot({ path: path.join(OUT, file), fullPage: true }); shots.push({ role: label, width, route, file }); // THE PIXEL REGRESSION HALF. See the diffCapture comment for why this did not exist until now. const reg = diffCapture(file, label, width, route); if (reg) f.push(reg); } return f; }; for (const route of ROUTES) { // Up to three attempts while the DOCUMENT keeps failing to arrive. Only after the third does the // route become a reported UNREACHABLE, which is a real finding about a page that genuinely will not // load rather than a guess about a page that merely did not load this time. let f = await checkRoute(route, true); for (let a = 0; a < 2 && f.length === 1 && f[0].kind === 'INCONCLUSIVE'; a++) { await page.waitForTimeout(1500); // SHOOT AGAIN. An inconclusive first attempt returns before the screenshot, so without this a route // that recovered on retry silently vanished from the contact sheet, and the sheet is the artifact a // human actually reviews. The capture count dropped from 54 to 40 before this was caught. f = await checkRoute(route, true); } if (f.length === 1 && f[0].kind === 'INCONCLUSIVE') { f = [{ ...f[0], kind: 'UNREACHABLE', detail: `the document failed to arrive on three consecutive attempts: ${f[0].detail}` }]; } // CONFIRMED BY REPEAT, and ONLY for transport class findings. // // Pinning QUIC off cut the noise from 78 findings to 37, but ERR_NETWORK_CHANGED over the tailnet // survived it, and a run whose every finding is a network blip reports the LINK as the application's // defect. That trains people to skim the output, which is how a real finding gets missed. // // So a route whose findings are ALL transport class is loaded again, and a finding is kept only if // it happens twice. A genuinely broken endpoint fails both times and survives untouched; a blip does // not. The moment a finding is NOT transport class, nothing is retried and nothing is dropped: // an overflow, a raw error, or an empty screen is a verdict on the first sighting. // // Dropped findings are COUNTED AND WRITTEN OUT, never silently discarded, because a suppression // nobody can see is indistinguishable from an instrument that measures nothing. if (f.length && f.every(isTransport)) { const second = await checkRoute(route, false); const seen = new Set(second.map(x => x.kind)); for (const x of f) { if (!seen.has(x.kind)) transient.push({ ...x, note: 'did not reproduce on immediate reload' }); } f = f.filter(x => seen.has(x.kind)); } findings.push(...f); } await ctx.close(); } // THE STANDING GUARD, MEASURED RATHER THAN INFERRED. // // The first attempt computed a minimum by walking the DOM for unshrinkable elements, and it reported // "route requires 1440px" on a 1440 viewport, because an element with flex-shrink:0 and width:100% is // not a fixed minimum, it is merely as wide as its container right now. That measurement would have // false positived on every route forever, which trains people to ignore the finding, so it was replaced // rather than tuned. // // What is measured now is the same quantity the 732 baseline came from: render the route at a width // BELOW the supported floor and read scrollWidth. A page cannot compress past its true minimum, so // scrollWidth at the probe width IS the minimum. This probe ASSERTS NOTHING ABOUT THE PROBE WIDTH, it // only reads a number: the authenticated matrix still starts at 768 and 320 is still unsupported. const probeCtx = await browser.newContext({ viewport: { width: PROBE_WIDTH, height: 900 }, deviceScaleFactor: 1, storageState }); const probePage = await probeCtx.newPage(); for (const route of ROUTES) { if (!await goWithRetry(probePage, BASE + route)) continue; await probePage.waitForLoadState('load').catch(() => {}); await probePage.waitForTimeout(1200); if (CONTROL) { await probePage.evaluate(() => { const d = document.createElement('div'); d.style.cssText = 'width:4000px;height:12px;background:red'; document.body.appendChild(d); }); await probePage.waitForTimeout(120); } const minWidth = await probePage.evaluate(() => document.documentElement.scrollWidth); probed.push({ role: label, route, minWidth }); if (minWidth > SHELL_MIN_WIDTH_BASELINE + SHELL_MIN_WIDTH_ALLOWANCE) { findings.push({ role: label, width: PROBE_WIDTH, route, kind: 'SHELL_MIN_WIDTH_REGRESSION', detail: `route requires ${minWidth}px, shell baseline is ${SHELL_MIN_WIDTH_BASELINE}px`, }); } } await probeCtx.close(); } await browser.close(); // The contact sheet: a whole sweep reviewed in one scroll, which is the point. const sheet = `visual sweep

Visual sweep, ${new Date().toISOString()}

${findings.length} finding(s) across ${shots.length} captures

${findings.map(f => JSON.stringify(f)).join('\n')}
${shots.map(s => `
${s.role} ${s.width} ${s.route}
`).join('')}`; fs.writeFileSync(path.join(OUT, 'contact-sheet.html'), sheet); fs.writeFileSync(path.join(OUT, 'findings.json'), JSON.stringify(findings, null, 1)); fs.writeFileSync(path.join(OUT, 'min-widths.json'), JSON.stringify(probed, null, 1)); fs.writeFileSync(path.join(OUT, 'transient.json'), JSON.stringify(transient, null, 1)); fs.writeFileSync(path.join(OUT, 'expected.json'), JSON.stringify(expected, null, 1)); console.log(`surface=${SURFACE} viewports=${VIEWPORTS.join(',')} captures=${shots.length} findings=${findings.length}`); if (probed.length) { const widest = probed.reduce((a, b) => (b.minWidth > a.minWidth ? b : a)); console.log(` shell guard: widest route requires ${widest.minWidth}px (${widest.route}), baseline ${SHELL_MIN_WIDTH_BASELINE}px + ${SHELL_MIN_WIDTH_ALLOWANCE}px allowance`); } if (expected.length) console.log(` ${expected.length} named expected error response(s) allowed, see expected.json`); // THE PIXEL HALF REPORTS EVEN WHEN IT HAS NOTHING TO SAY, because a silent pixel half is exactly how this // came to be missing for two Gate C runs while both write ups described it as merely unapproved. if (pixelReport.unavailable) { console.log(' PIXEL REGRESSION UNAVAILABLE: pixelmatch or pngjs is not installed, so this run did NOT'); console.log(' perform the diff the protocol requires. Install them before quoting this run as complete.'); findings.push({ role: 'instrument', width: 0, route: '(pixel)', kind: 'PIXEL_HALF_UNAVAILABLE' }); } else { console.log(` pixel regression: ${pixelReport.compared} compared, ${pixelReport.isNew} without a baseline, ${pixelReport.regressions} regression(s), threshold ${(PIXEL_THRESHOLD * 100).toFixed(3)} percent`); if (pixelReport.compared === 0 && pixelReport.isNew > 0) { console.log(` no baselines exist yet at ${BASELINES}. Run with --approve to establish them, which is the`); console.log(' recorded approval step, and note that a run with zero comparisons proves nothing about pixels.'); } } // --approve PROMOTES THIS RUN'S CAPTURES TO BASELINES, and it refuses to do so from a dirty run. // Approving a run that already has findings would enshrine the defect as the thing future runs are measured // against, which is worse than having no baseline at all. if (APPROVE) { if (findings.length) { console.log(` APPROVAL REFUSED: ${findings.length} finding(s) in this run. A baseline set may only be`); console.log(' promoted from a clean run, or the defect becomes the standard everything is compared to.'); } else { fs.mkdirSync(BASELINES, { recursive: true }); let n = 0; for (const s of shots) { fs.copyFileSync(path.join(OUT, s.file), path.join(BASELINES, s.file)); n++; } fs.writeFileSync(path.join(BASELINES, 'APPROVAL.txt'), `Baselines approved by Joseph, recorded ${new Date().toISOString()}\n` + `surface=${SURFACE} captures=${n} viewports=${VIEWPORTS.join(',')}\n` + `roles=${ROLES.map(r => r.email.split('@')[0]).join(',') || 'anonymous'}\n` + `threshold=${PIXEL_THRESHOLD}\n`); console.log(` BASELINES ESTABLISHED: ${n} captures written to ${BASELINES}, approval recorded in APPROVAL.txt`); } } if (transient.length) console.log(` ${transient.length} transport finding(s) did not reproduce and were dropped, see transient.json`); findings.slice(0, 12).forEach(f => console.log(' ' + JSON.stringify(f))); if (CONTROL) { // BOTH assertions must have fired. Catching one and missing the other would leave half the instrument // unproven while the run reported success, which is the same lie in a smaller package. const missing = ['HORIZONTAL_OVERFLOW', 'SHELL_MIN_WIDTH_REGRESSION'].filter(k => !findings.some(f => f.kind === k)); if (missing.length) { console.error(`POSITIVE CONTROL FAILED: planted defects went undetected by ${missing.join(' and ')}`); process.exit(1); } console.log('positive control OK: the planted overflow AND the planted min width regression were both DETECTED'); process.exit(0); } process.exit(findings.length ? 1 : 0); })();