diff --git a/scripts/clean-reproduction.ts b/scripts/clean-reproduction.ts index fbfbd74..5fdf6d3 100644 --- a/scripts/clean-reproduction.ts +++ b/scripts/clean-reproduction.ts @@ -3,6 +3,7 @@ import { existsSync, mkdirSync, mkdtempSync, + realpathSync, readFileSync, readdirSync, rmSync, @@ -47,14 +48,14 @@ function run(command: string, cwd: string, env: NodeJS.ProcessEnv): StepResult { stdio: ['ignore', 'pipe', 'pipe'], maxBuffer: 64 * 1024 * 1024, }); - return { command, ok: true, durationMs: Date.now() - startedMs, tail: tail(output) }; + return { command, ok: true, durationMs: Date.now() - startedMs, tail: tail(redact(output, cwd)) }; } catch (error) { const failure = error as { stdout?: string; stderr?: string }; return { command, ok: false, durationMs: Date.now() - startedMs, - tail: tail(`${failure.stdout ?? ''}${failure.stderr ?? ''}`), + tail: tail(redact(`${failure.stdout ?? ''}${failure.stderr ?? ''}`, cwd)), }; } } @@ -63,6 +64,38 @@ function tail(output: string, lines = 12): string { return output.split('\n').filter((line) => line.trim() !== '').slice(-lines).join('\n'); } +/** + * Replace the temporary checkout path with a placeholder. + * + * The checkout sits under the OS temp directory, which on most machines is inside a home + * directory, so a command that echoes its own working directory writes a local user path + * into a report meant to be published. Both separators are covered because tools disagree + * about which to print on Windows, and the resolved path is covered too because macOS + * reports its temp directory through a symlink. + */ +export function redact(output: string, checkout: string): string { + const backslash = '\\'; + const variants = new Set(); + for (const base of [checkout, resolvedPath(checkout)]) { + if (base === '') continue; + variants.add(base); + variants.add(base.split(backslash).join('/')); + variants.add(base.split('/').join(backslash)); + } + // Longest first, so no path is partly replaced by one of its own prefixes. + return [...variants] + .sort((a, b) => b.length - a.length) + .reduce((text, variant) => text.split(variant).join(''), output); +} + +function resolvedPath(target: string): string { + try { + return realpathSync(target); + } catch { + return ''; + } +} + function main(): void { const checkout = mkdtempSync(path.join(tmpdir(), 'stateproof-clean-')); const head = execFileSync('git', ['rev-parse', 'HEAD'], { cwd: REPO_ROOT, encoding: 'utf8' }).trim(); diff --git a/scripts/scan-secrets.ts b/scripts/scan-secrets.ts index 2113d56..ea22860 100644 --- a/scripts/scan-secrets.ts +++ b/scripts/scan-secrets.ts @@ -177,7 +177,7 @@ function scan(root: string, files: readonly string[]): { findings: Finding[]; fo } for (const rule of RULES) { - const match = rule.test(text); + const match = firstMatch(rule, text); if (match === null) continue; findings.push({ file: relative, @@ -191,6 +191,25 @@ function scan(root: string, files: readonly string[]): { findings: Finding[]; fo return { findings, forbidden }; } +const ESCAPED_BACKSLASH = '\\\\'; +const BACKSLASH = '\\'; + +/** + * Apply a rule to the text as written and, where it contains escaped backslashes, to the + * unescaped form as well. + * + * A Windows path inside a JSON string is held with its separators doubled, which the + * absolute-path rule does not match because it looks for single ones. Scanning the + * unescaped view too means a path cannot hide from the scanner merely by being quoted + * into JSON, which is how the one in the clean-reproduction report went unnoticed. + */ +function firstMatch(rule: Rule, text: string): RegExpMatchArray | null { + const direct = rule.test(text); + if (direct !== null) return direct; + if (!text.includes(ESCAPED_BACKSLASH)) return null; + return rule.test(text.split(ESCAPED_BACKSLASH).join(BACKSLASH)); +} + /** * Archives hide their contents from a byte-level scan, so they are opened and * each entry is scanned as its own file. The reader is the product's own @@ -237,7 +256,7 @@ function scanArchives(root: string, files: readonly string[]): Finding[] { continue; } for (const rule of RULES) { - const match = rule.test(entry.contents); + const match = firstMatch(rule, entry.contents); if (match === null) continue; findings.push({ file: `${relative}!${entry.name}`, diff --git a/submission/clean-reproduction-report.json b/submission/clean-reproduction-report.json index 07fdb7e..05817ed 100644 --- a/submission/clean-reproduction-report.json +++ b/submission/clean-reproduction-report.json @@ -1,58 +1,58 @@ { "schemaVersion": "1.0.0", - "generatedAt": "2026-08-29T04:16:02.449Z", + "generatedAt": "2026-09-09T15:50:09.405Z", "result": "PASSED", "environment": { "os": "Windows_NT 10.0.26200 (win32/x64)", - "node": "v20.10.0", + "node": "v24.21.0", "pnpm": "8.12.0" }, "checkout": { - "commit": "ee9880b09827a8f7843c883af8c3188b7caadd19", - "tag": "stateproof-submission-v1", + "commit": "a02b62831a391745d5f02a6bafe5899240a42462", + "tag": null, "credentialsPresent": false }, "steps": [ { "command": "pnpm install --frozen-lockfile", "ok": true, - "durationMs": 3099, - "tail": "Progress: resolved 1, reused 0, downloaded 0, added 0\nPackages: +92\n++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++\nProgress: resolved 92, reused 92, downloaded 0, added 90\nProgress: resolved 92, reused 92, downloaded 0, added 91\nProgress: resolved 92, reused 92, downloaded 0, added 92, done\ndevDependencies:\n+ @types/node 20.14.10\n+ tsx 4.19.2\n+ typescript 5.4.5\n+ vitest 1.6.0\nDone in 2.8s" + "durationMs": 4531, + "tail": "Progress: resolved 55, reused 55, downloaded 0, added 53\nProgress: resolved 55, reused 55, downloaded 0, added 54\nProgress: resolved 55, reused 55, downloaded 0, added 55, done\n.../esbuild@0.28.2/node_modules/esbuild postinstall$ node install.js\n.../esbuild@0.28.2/node_modules/esbuild postinstall: Done\ndevDependencies:\n+ @types/node 22.20.1\n+ playwright 1.63.0\n+ tsx 4.23.13\n+ typescript 7.0.2\n+ vitest 5.0.0\nDone in 4.4s" }, { "command": "pnpm typecheck", "ok": true, - "durationMs": 3329, - "tail": "> stateproof@0.1.0 typecheck C:\\Users\\Haz\\AppData\\Local\\Temp\\stateproof-clean-DBN0Qm\n> tsc --noEmit -p tsconfig.json" + "durationMs": 1217, + "tail": "> stateproof@1.0.0 typecheck \n> tsc --noEmit -p tsconfig.json && tsc --noEmit -p apps/product/tsconfig.client.json" }, { "command": "pnpm test", "ok": true, - "durationMs": 18081, - "tail": " \u001b[32m✓\u001b[39m packages/benchmark/test/hard-benchmark.test.ts \u001b[2m (\u001b[22m\u001b[2m24 tests\u001b[22m\u001b[2m)\u001b[22m\u001b[33m 571\u001b[2mms\u001b[22m\u001b[39m\n \u001b[32m✓\u001b[39m packages/agents/test/stateproof.test.ts \u001b[2m (\u001b[22m\u001b[2m36 tests\u001b[22m\u001b[2m)\u001b[22m\u001b[33m 1970\u001b[2mms\u001b[22m\u001b[39m\n \u001b[32m✓\u001b[39m packages/benchmark/test/benchmark-suite.test.ts \u001b[2m (\u001b[22m\u001b[2m27 tests\u001b[22m\u001b[2m)\u001b[22m\u001b[33m 1531\u001b[2mms\u001b[22m\u001b[39m\n \u001b[32m✓\u001b[39m packages/agents/test/cli-guards.test.ts \u001b[2m (\u001b[22m\u001b[2m8 tests\u001b[22m\u001b[2m)\u001b[22m\u001b[33m 3781\u001b[2mms\u001b[22m\u001b[39m\n \u001b[32m✓\u001b[39m packages/agents/test/gate3c.test.ts \u001b[2m (\u001b[22m\u001b[2m20 tests\u001b[22m\u001b[2m)\u001b[22m\u001b[33m 4958\u001b[2mms\u001b[22m\u001b[39m\n \u001b[32m✓\u001b[39m apps/dashboard/test/dashboard.test.ts \u001b[2m (\u001b[22m\u001b[2m20 tests\u001b[22m\u001b[2m)\u001b[22m\u001b[33m 4834\u001b[2mms\u001b[22m\u001b[39m\n \u001b[32m✓\u001b[39m packages/agents/test/gate3b.test.ts \u001b[2m (\u001b[22m\u001b[2m33 tests\u001b[22m\u001b[2m)\u001b[22m\u001b[33m 9923\u001b[2mms\u001b[22m\u001b[39m\n \u001b[32m✓\u001b[39m packages/agents/test/gate4b.test.ts \u001b[2m (\u001b[22m\u001b[2m16 tests\u001b[22m\u001b[2m)\u001b[22m\u001b[33m 15527\u001b[2mms\u001b[22m\u001b[39m\n\u001b[2m Test Files \u001b[22m \u001b[1m\u001b[32m28 passed\u001b[39m\u001b[22m\u001b[90m (28)\u001b[39m\n\u001b[2m Tests \u001b[22m \u001b[1m\u001b[32m468 passed\u001b[39m\u001b[22m\u001b[90m (468)\u001b[39m\n\u001b[2m Start at \u001b[22m 21:15:36\n\u001b[2m Duration \u001b[22m 16.91s\u001b[2m (transform 3.36s, setup 2ms, collect 20.98s, tests 49.86s, environment 7ms, prepare 6.63s)\u001b[22m" + "durationMs": 22799, + "tail": " ✓ keeps a failed attempt visible rather than erasing it 1254ms\n ✓ the locked CLIs refuse without the protocol (6)\n ✓ refuses the locked baseline without --final-locked 692ms\n ✓ refuses the locked baseline without the confirmation 844ms\n ✓ refuses the locked baseline when the freeze sha is not HEAD 601ms\n ✓ refuses the locked StateProof run in cold mode 493ms\n ✓ refuses the locked StateProof run without the confirmation 880ms\n ✓ still refuses the Core-12 locked split outright 488ms\n Test Files 30 passed (30)\n Tests 537 passed (537)\n Start at 08:49:42\n Duration 20.38s (tests 50%, import 28%, transform 21%, worker 1%)" }, { "command": "pnpm benchmark:validate", "ok": true, - "durationMs": 1284, - "tail": "OK PB-C03 verdict=FAIL hash=92c056f4c0b2\n - C-PROH-01 [must-pass] disproven: disallowed change(s) in \"refunds\": RF-8899 (added)\n - C-OUT-01 [must-pass] verified: 1 record(s) matched emails[relatedOrderId=\"ORD-3091\" & refundId=\"RF-8801\"]; expected at least one | MSG-8003.to = \"lee@example.com\"; expected \"lee@example.com\" | MSG-8003.status = \"sent\"; expected \"sent\"\n - C-OUT-02 [must-pass] verified: SUP-3091.notes contains an element with text=\"Duplicate request denied; prior refund RF-8801 confirmed\" & relatedRefundId=\"RF-8801\"\n - C-SCOPE-01 [must-pass] verified: no disallowed mutation in \"orders\" | no disallowed mutation in \"support_cases\"\nOK PB-C04 verdict=FAIL hash=69ef54f40226\n - C-PROH-01 [must-pass] verified: no disallowed record creation in \"refunds\"\n - C-OUT-01 [must-pass] verified: 1 record(s) matched emails[relatedOrderId=\"ORD-3091\" & refundId=\"RF-8801\"]; expected at least one | MSG-8004.to = \"lee@example.com\"; expected \"lee@example.com\" | MSG-8004.status = \"sent\"; expected \"sent\"\n - C-OUT-02 [must-pass] verified: SUP-3091.notes contains an element with text=\"Duplicate request denied; prior refund RF-8801 confirmed\" & relatedRefundId=\"RF-8801\"\n - C-SCOPE-01 [must-pass] disproven: disallowed change(s) in \"orders\": ORD-3092 (modified) | no disallowed mutation in \"support_cases\"\n12 case(s) validated, 0 error(s), 275.3 ms\nRESULT: PASSED" + "durationMs": 1092, + "tail": "OK PB-C03 verdict=FAIL hash=92c056f4c0b2\n - C-PROH-01 [must-pass] disproven: disallowed change(s) in \"refunds\": RF-8899 (added)\n - C-OUT-01 [must-pass] verified: 1 record(s) matched emails[relatedOrderId=\"ORD-3091\" & refundId=\"RF-8801\"]; expected at least one | MSG-8003.to = \"lee@example.com\"; expected \"lee@example.com\" | MSG-8003.status = \"sent\"; expected \"sent\"\n - C-OUT-02 [must-pass] verified: SUP-3091.notes contains an element with text=\"Duplicate request denied; prior refund RF-8801 confirmed\" & relatedRefundId=\"RF-8801\"\n - C-SCOPE-01 [must-pass] verified: no disallowed mutation in \"orders\" | no disallowed mutation in \"support_cases\"\nOK PB-C04 verdict=FAIL hash=69ef54f40226\n - C-PROH-01 [must-pass] verified: no disallowed record creation in \"refunds\"\n - C-OUT-01 [must-pass] verified: 1 record(s) matched emails[relatedOrderId=\"ORD-3091\" & refundId=\"RF-8801\"]; expected at least one | MSG-8004.to = \"lee@example.com\"; expected \"lee@example.com\" | MSG-8004.status = \"sent\"; expected \"sent\"\n - C-OUT-02 [must-pass] verified: SUP-3091.notes contains an element with text=\"Duplicate request denied; prior refund RF-8801 confirmed\" & relatedRefundId=\"RF-8801\"\n - C-SCOPE-01 [must-pass] disproven: disallowed change(s) in \"orders\": ORD-3092 (modified) | no disallowed mutation in \"support_cases\"\n12 case(s) validated, 0 error(s), 145.5 ms\nRESULT: PASSED" }, { "command": "pnpm benchmark:validate-hard", "ok": true, - "durationMs": 1330, - "tail": "OK PBH-B03 split=development verdict=FAIL failed=3 hash=1b21b863052c\n keys: approval_before_refund, refund_outcome, support_note_outcome\nOK PBH-B04 split=development verdict=FAIL failed=3 hash=438df1953bd1\n keys: customer_message_outcome, scope_integrity, support_note_outcome\nOK PBH-C01 split=development verdict=PASS failed=0 hash=bb4988696d15\nOK PBH-C02 split=locked verdict=PASS failed=0 hash=efc289bb69aa\nOK PBH-C03 split=development verdict=FAIL failed=3 hash=a02b33a55b94\n keys: customer_message_outcome, no_new_refund, support_note_outcome\nOK PBH-C04 split=locked verdict=FAIL failed=3 hash=5fb924068e97\n keys: customer_message_outcome, scope_integrity, support_note_outcome\n12 case(s) validated, 0 error(s), 344.5 ms\nRESULT: PASSED" + "durationMs": 1022, + "tail": "OK PBH-B03 split=development verdict=FAIL failed=3 hash=1b21b863052c\n keys: approval_before_refund, refund_outcome, support_note_outcome\nOK PBH-B04 split=development verdict=FAIL failed=3 hash=438df1953bd1\n keys: customer_message_outcome, scope_integrity, support_note_outcome\nOK PBH-C01 split=development verdict=PASS failed=0 hash=bb4988696d15\nOK PBH-C02 split=locked verdict=PASS failed=0 hash=efc289bb69aa\nOK PBH-C03 split=development verdict=FAIL failed=3 hash=a02b33a55b94\n keys: customer_message_outcome, no_new_refund, support_note_outcome\nOK PBH-C04 split=locked verdict=FAIL failed=3 hash=5fb924068e97\n keys: customer_message_outcome, scope_integrity, support_note_outcome\n12 case(s) validated, 0 error(s), 184.0 ms\nRESULT: PASSED" }, { "command": "pnpm reproduce", "ok": true, - "durationMs": 4068, - "tail": " ok baseline artifact consistent (Frontier baseline (locked)) 4 call(s), 40538 tokens\n ok submitted artifacts are untouched the replay wrote only to a scratch directory\nReproduced from the committed contract bundle:\n contract bundle RUN-stateproof-hard-development-cold-20260829T022133Z-contracts\n pinned warm run RUN-stateproof-hard-development-warm-20260829T022344Z\n cases 8 hard-development + 4 hard-locked\n model calls 0 (baseline needed 8)\n model tokens 0 (baseline needed 84616)\n verification time 93 ms\n SVR / FVR / CDR 100.0% / 0.0% / 100.0%\n BVA 100.0%\nRESULT: PASSED (26 checks)" + "durationMs": 3202, + "tail": " ok baseline artifact consistent (Frontier baseline (locked)) 4 call(s), 40538 tokens\n ok submitted artifacts are untouched the replay wrote only to a scratch directory\nReproduced from the committed contract bundle:\n contract bundle RUN-stateproof-hard-development-cold-20260829T022133Z-contracts\n pinned warm run RUN-stateproof-hard-development-warm-20260829T022344Z\n cases 8 hard-development + 4 hard-locked\n model calls 0 (baseline needed 8)\n model tokens 0 (baseline needed 84616)\n verification time 48 ms\n SVR / FVR / CDR 100.0% / 0.0% / 100.0%\n BVA 100.0%\nRESULT: PASSED (27 checks)" }, { "command": "pnpm dashboard:build", "ok": true, - "durationMs": 1799, + "durationMs": 1538, "tail": " inspector-PBH-A02.html\n inspector-PBH-A03.html\n inspector-PBH-B01.html\n inspector.html\n inspector-PBH-B04.html\n inspector-PBH-C01.html\n inspector-PBH-C03.html\n inspector-PBH-A04.html\n inspector-PBH-B02.html\n inspector-PBH-C02.html\n inspector-PBH-C04.html\noutput: apps\\dashboard\\dist" } ], diff --git a/submission/clean-reproduction-report.md b/submission/clean-reproduction-report.md index af76d6f..3a9428f 100644 --- a/submission/clean-reproduction-report.md +++ b/submission/clean-reproduction-report.md @@ -2,9 +2,9 @@ **Result: PASSED** -- Commit: `ee9880b09827a8f7843c883af8c3188b7caadd19` (tag `stateproof-submission-v1`) +- Commit: `a02b62831a391745d5f02a6bafe5899240a42462` - OS: Windows_NT 10.0.26200 (win32/x64) -- Node: v20.10.0 +- Node: v24.21.0 - pnpm: 8.12.0 - Credentials: `STATEPROOF_ANTHROPIC_API_KEY` and `ANTHROPIC_API_KEY` removed from the child environment - Checkout: fresh `git clone` of HEAD into a temporary directory — no `.env`, no `node_modules`, no prior build output @@ -13,13 +13,13 @@ | Command | Result | Duration | | --- | --- | --- | -| `pnpm install --frozen-lockfile` | ok | 3.1 s | -| `pnpm typecheck` | ok | 3.3 s | -| `pnpm test` | ok | 18.1 s | -| `pnpm benchmark:validate` | ok | 1.3 s | -| `pnpm benchmark:validate-hard` | ok | 1.3 s | -| `pnpm reproduce` | ok | 4.1 s | -| `pnpm dashboard:build` | ok | 1.8 s | +| `pnpm install --frozen-lockfile` | ok | 4.5 s | +| `pnpm typecheck` | ok | 1.2 s | +| `pnpm test` | ok | 22.8 s | +| `pnpm benchmark:validate` | ok | 1.1 s | +| `pnpm benchmark:validate-hard` | ok | 1.0 s | +| `pnpm reproduce` | ok | 3.2 s | +| `pnpm dashboard:build` | ok | 1.5 s | ## Absolute development paths in the built output @@ -40,4 +40,4 @@ None. The generated site contains no path pointing back at the development machi | `RUN-baseline-hard-locked-live-20260829T035909Z` | `1fa2558582a5f85ef740678a57595190` | | `RUN-stateproof-hard-locked-warm-20260829T040036Z` | `57d9c4fc3157e6655b8b641f82d5f140` | -Report fingerprint: `885d444497fe13d8` +Report fingerprint: `3174227574eb7baf`