repro-surgeon 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +15 -0
- package/CODE_OF_CONDUCT.md +7 -0
- package/CONTRIBUTING.md +31 -0
- package/LICENSE +21 -0
- package/README.md +159 -0
- package/SECURITY.md +15 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.js +165 -0
- package/dist/cli.js.map +1 -0
- package/dist/config.d.ts +3 -0
- package/dist/config.js +177 -0
- package/dist/config.js.map +1 -0
- package/dist/dependencies.d.ts +37 -0
- package/dist/dependencies.js +237 -0
- package/dist/dependencies.js.map +1 -0
- package/dist/engine.d.ts +25 -0
- package/dist/engine.js +327 -0
- package/dist/engine.js.map +1 -0
- package/dist/export.d.ts +7 -0
- package/dist/export.js +520 -0
- package/dist/export.js.map +1 -0
- package/dist/graph.d.ts +3 -0
- package/dist/graph.js +247 -0
- package/dist/graph.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +7 -0
- package/dist/index.js.map +1 -0
- package/dist/oracle.d.ts +2 -0
- package/dist/oracle.js +81 -0
- package/dist/oracle.js.map +1 -0
- package/dist/protection.d.ts +2 -0
- package/dist/protection.js +6 -0
- package/dist/protection.js.map +1 -0
- package/dist/report.d.ts +5 -0
- package/dist/report.js +539 -0
- package/dist/report.js.map +1 -0
- package/dist/runner.d.ts +3 -0
- package/dist/runner.js +195 -0
- package/dist/runner.js.map +1 -0
- package/dist/snapshot.d.ts +11 -0
- package/dist/snapshot.js +220 -0
- package/dist/snapshot.js.map +1 -0
- package/dist/state.d.ts +9 -0
- package/dist/state.js +143 -0
- package/dist/state.js.map +1 -0
- package/dist/transforms.d.ts +3 -0
- package/dist/transforms.js +188 -0
- package/dist/transforms.js.map +1 -0
- package/dist/types.d.ts +207 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/docs/architecture.md +91 -0
- package/docs/assets/report.png +0 -0
- package/docs/configuration.md +73 -0
- package/docs/evidence/dependency-removal.json +109 -0
- package/docs/evidence/next-frameworks.json +271 -0
- package/docs/evidence/next-pages.json +152 -0
- package/docs/evidence/rounding.json +46 -0
- package/docs/report-surface.md +22 -0
- package/docs/troubleshooting.md +47 -0
- package/docs/validation.md +103 -0
- package/examples/next-container/README.md +7 -0
- package/examples/next-container/app/about/page.jsx +1 -0
- package/examples/next-container/app/case.css +5 -0
- package/examples/next-container/app/layout.jsx +3 -0
- package/examples/next-container/app/page.jsx +4 -0
- package/examples/next-container/lib/catalog.js +2 -0
- package/examples/next-container/next.config.mjs +1 -0
- package/examples/next-container/package-lock.json +952 -0
- package/examples/next-container/package.json +13 -0
- package/examples/next-container/repro-surgeon.json +37 -0
- package/examples/next-css-bom/README.md +7 -0
- package/examples/next-css-bom/app/about/page.jsx +1 -0
- package/examples/next-css-bom/app/case.css +3 -0
- package/examples/next-css-bom/app/layout.jsx +3 -0
- package/examples/next-css-bom/app/page.jsx +4 -0
- package/examples/next-css-bom/lib/catalog.js +2 -0
- package/examples/next-css-bom/next.config.mjs +1 -0
- package/examples/next-css-bom/package-lock.json +952 -0
- package/examples/next-css-bom/package.json +13 -0
- package/examples/next-css-bom/repro-surgeon.json +36 -0
- package/examples/next-pages/README.md +14 -0
- package/examples/next-pages/lib/unused-catalog.js +5 -0
- package/examples/next-pages/next.config.mjs +1 -0
- package/examples/next-pages/package-lock.json +952 -0
- package/examples/next-pages/package.json +11 -0
- package/examples/next-pages/pages/health.jsx +3 -0
- package/examples/next-pages/pages/index.jsx +9 -0
- package/examples/next-pages/repro-surgeon.json +18 -0
- package/examples/next-root-param/README.md +7 -0
- package/examples/next-root-param/app/[lang-country]/about/page.jsx +1 -0
- package/examples/next-root-param/app/[lang-country]/layout.tsx +4 -0
- package/examples/next-root-param/app/[lang-country]/page.tsx +3 -0
- package/examples/next-root-param/lib/catalog.js +2 -0
- package/examples/next-root-param/next-env.d.ts +2 -0
- package/examples/next-root-param/next.config.mjs +1 -0
- package/examples/next-root-param/package-lock.json +1016 -0
- package/examples/next-root-param/package.json +19 -0
- package/examples/next-root-param/repro-surgeon.json +37 -0
- package/examples/next-root-param/tsconfig.json +35 -0
- package/examples/rounding/README.md +16 -0
- package/examples/rounding/check.mjs +6 -0
- package/examples/rounding/config/store.json +7 -0
- package/examples/rounding/fixtures/invoice.json +11 -0
- package/examples/rounding/package-lock.json +7 -0
- package/examples/rounding/package.json +7 -0
- package/examples/rounding/repro-surgeon.json +12 -0
- package/examples/rounding/src/catalog.mjs +9 -0
- package/examples/rounding/src/shipping.mjs +7 -0
- package/examples/rounding/src/totals.mjs +11 -0
- package/package.json +29 -0
package/dist/export.js
ADDED
|
@@ -0,0 +1,520 @@
|
|
|
1
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
2
|
+
import { lstat, mkdir, readFile, readdir, rename, rm } from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import ts from 'typescript';
|
|
6
|
+
import { parseConfig } from "./config.js";
|
|
7
|
+
import { assertTemporaryDirectoryOutsideSource, createIsolatedDirectory, WorkspaceManager } from "./dependencies.js";
|
|
8
|
+
import { evaluateOracle } from "./oracle.js";
|
|
9
|
+
import { runCommand } from "./runner.js";
|
|
10
|
+
import { assertDisjointPaths, hashValue, safeRelativePath, snapshotHash, writeSnapshot } from "./snapshot.js";
|
|
11
|
+
import { acquireRunLock, loadCheckpoint, saveCheckpoint } from "./state.js";
|
|
12
|
+
const MANIFEST_PATH = '.repro/manifest.json';
|
|
13
|
+
const GENERATED_DIRECTORIES = new Set([
|
|
14
|
+
'.git',
|
|
15
|
+
'node_modules',
|
|
16
|
+
'.next',
|
|
17
|
+
'.nuxt',
|
|
18
|
+
'.turbo',
|
|
19
|
+
'.cache',
|
|
20
|
+
'.vercel',
|
|
21
|
+
'dist',
|
|
22
|
+
'out',
|
|
23
|
+
'build',
|
|
24
|
+
'coverage',
|
|
25
|
+
]);
|
|
26
|
+
function fileHash(content) {
|
|
27
|
+
return createHash('sha256').update(content).digest('hex');
|
|
28
|
+
}
|
|
29
|
+
function manifestFiles(snapshot) {
|
|
30
|
+
return [...snapshot]
|
|
31
|
+
.sort(([left], [right]) => left.localeCompare(right, 'en'))
|
|
32
|
+
.map(([name, entry]) => ({
|
|
33
|
+
path: name,
|
|
34
|
+
mode: entry.mode & 0o777,
|
|
35
|
+
bytes: entry.content.length,
|
|
36
|
+
sha256: fileHash(entry.content),
|
|
37
|
+
}));
|
|
38
|
+
}
|
|
39
|
+
function validateRow(value, section) {
|
|
40
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value)) {
|
|
41
|
+
throw new Error(`Invalid ${section} manifest entry.`);
|
|
42
|
+
}
|
|
43
|
+
const row = value;
|
|
44
|
+
const keys = Object.keys(row).sort();
|
|
45
|
+
if (keys.join(',') !== 'bytes,mode,path,sha256')
|
|
46
|
+
throw new Error(`Invalid ${section} manifest fields.`);
|
|
47
|
+
if (typeof row.path !== 'string')
|
|
48
|
+
throw new Error(`Invalid ${section} manifest path.`);
|
|
49
|
+
safeRelativePath(row.path);
|
|
50
|
+
if (!Number.isInteger(row.mode) || row.mode < 0 || row.mode > 0o777) {
|
|
51
|
+
throw new Error(`Invalid ${section} manifest mode for ${row.path}.`);
|
|
52
|
+
}
|
|
53
|
+
if (!Number.isSafeInteger(row.bytes) || row.bytes < 0) {
|
|
54
|
+
throw new Error(`Invalid ${section} manifest byte count for ${row.path}.`);
|
|
55
|
+
}
|
|
56
|
+
if (typeof row.sha256 !== 'string' || !/^[a-f0-9]{64}$/.test(row.sha256)) {
|
|
57
|
+
throw new Error(`Invalid ${section} manifest checksum for ${row.path}.`);
|
|
58
|
+
}
|
|
59
|
+
return row;
|
|
60
|
+
}
|
|
61
|
+
function parseManifest(value) {
|
|
62
|
+
if (value === null || typeof value !== 'object' || Array.isArray(value))
|
|
63
|
+
throw new Error('Invalid export manifest.');
|
|
64
|
+
const manifest = value;
|
|
65
|
+
const keys = Object.keys(manifest).sort();
|
|
66
|
+
if (keys.join(',') !== 'createdAt,files,format,generated,runId,sourceHash,version')
|
|
67
|
+
throw new Error('Invalid export manifest fields.');
|
|
68
|
+
if (manifest.version !== 1 || manifest.format !== 'repro-surgeon-export-v1')
|
|
69
|
+
throw new Error('Unsupported export manifest.');
|
|
70
|
+
if (typeof manifest.runId !== 'string' || manifest.runId.length === 0)
|
|
71
|
+
throw new Error('Invalid export manifest run identifier.');
|
|
72
|
+
if (typeof manifest.createdAt !== 'string' || Number.isNaN(Date.parse(manifest.createdAt)))
|
|
73
|
+
throw new Error('Invalid export manifest timestamp.');
|
|
74
|
+
if (typeof manifest.sourceHash !== 'string' || !/^[a-f0-9]{64}$/.test(manifest.sourceHash))
|
|
75
|
+
throw new Error('Invalid export source hash.');
|
|
76
|
+
if (!Array.isArray(manifest.files) || !Array.isArray(manifest.generated))
|
|
77
|
+
throw new Error('Invalid export manifest file lists.');
|
|
78
|
+
const files = manifest.files.map((row) => validateRow(row, 'source'));
|
|
79
|
+
const generated = manifest.generated.map((row) => validateRow(row, 'generated'));
|
|
80
|
+
const seen = new Set();
|
|
81
|
+
for (const row of files) {
|
|
82
|
+
if (row.path.startsWith('.repro/'))
|
|
83
|
+
throw new Error('Source manifest may not own reserved .repro metadata.');
|
|
84
|
+
if (seen.has(row.path))
|
|
85
|
+
throw new Error(`Duplicate export manifest path: ${row.path}`);
|
|
86
|
+
seen.add(row.path);
|
|
87
|
+
}
|
|
88
|
+
for (const row of generated) {
|
|
89
|
+
if (!row.path.startsWith('.repro/') || row.path === MANIFEST_PATH)
|
|
90
|
+
throw new Error('Generated manifest paths must be reserved .repro files.');
|
|
91
|
+
if (seen.has(row.path))
|
|
92
|
+
throw new Error(`Duplicate export manifest path: ${row.path}`);
|
|
93
|
+
seen.add(row.path);
|
|
94
|
+
}
|
|
95
|
+
return { version: 1, format: 'repro-surgeon-export-v1', runId: manifest.runId, createdAt: manifest.createdAt, sourceHash: manifest.sourceHash, files, generated };
|
|
96
|
+
}
|
|
97
|
+
async function walkFiles(root, relative = '') {
|
|
98
|
+
const directory = path.join(root, relative);
|
|
99
|
+
const entries = await readdir(directory, { withFileTypes: true });
|
|
100
|
+
const files = [];
|
|
101
|
+
for (const entry of entries) {
|
|
102
|
+
const name = relative ? `${relative}/${entry.name}` : entry.name;
|
|
103
|
+
safeRelativePath(name);
|
|
104
|
+
const full = path.join(root, name);
|
|
105
|
+
const info = await lstat(full);
|
|
106
|
+
if (info.isSymbolicLink())
|
|
107
|
+
throw new Error(`Export contains a symbolic link: ${name}`);
|
|
108
|
+
if (info.isDirectory()) {
|
|
109
|
+
if (relative === '' && GENERATED_DIRECTORIES.has(entry.name))
|
|
110
|
+
continue;
|
|
111
|
+
files.push(...await walkFiles(root, name));
|
|
112
|
+
}
|
|
113
|
+
else if (info.isFile())
|
|
114
|
+
files.push(name);
|
|
115
|
+
else
|
|
116
|
+
throw new Error(`Export contains a non-regular file: ${name}`);
|
|
117
|
+
}
|
|
118
|
+
return files;
|
|
119
|
+
}
|
|
120
|
+
async function readValidatedExport(root) {
|
|
121
|
+
const rootInfo = await lstat(root);
|
|
122
|
+
if (rootInfo.isSymbolicLink() || !rootInfo.isDirectory())
|
|
123
|
+
throw new Error('Export root must be a real directory.');
|
|
124
|
+
let manifest;
|
|
125
|
+
let manifestContent;
|
|
126
|
+
try {
|
|
127
|
+
manifestContent = await readFile(path.join(root, MANIFEST_PATH));
|
|
128
|
+
manifest = parseManifest(JSON.parse(manifestContent.toString('utf8')));
|
|
129
|
+
}
|
|
130
|
+
catch (error) {
|
|
131
|
+
throw new Error(`Export manifest is missing, invalid, or unrelated: ${error instanceof Error ? error.message : String(error)}`);
|
|
132
|
+
}
|
|
133
|
+
const expected = new Map();
|
|
134
|
+
for (const row of [...manifest.files, ...manifest.generated])
|
|
135
|
+
expected.set(row.path, row);
|
|
136
|
+
const actual = await walkFiles(root);
|
|
137
|
+
for (const name of actual) {
|
|
138
|
+
if (name !== MANIFEST_PATH && !expected.has(name))
|
|
139
|
+
throw new Error(`Export has an extra unlisted source file: ${name}`);
|
|
140
|
+
}
|
|
141
|
+
if (!actual.includes(MANIFEST_PATH))
|
|
142
|
+
throw new Error('Export manifest is missing.');
|
|
143
|
+
const snapshot = new Map();
|
|
144
|
+
for (const [name, row] of expected) {
|
|
145
|
+
let info;
|
|
146
|
+
let content;
|
|
147
|
+
try {
|
|
148
|
+
info = await lstat(path.join(root, name));
|
|
149
|
+
content = await readFile(path.join(root, name));
|
|
150
|
+
}
|
|
151
|
+
catch {
|
|
152
|
+
throw new Error(`Export source is missing: ${name}`);
|
|
153
|
+
}
|
|
154
|
+
if (!info.isFile() || info.isSymbolicLink())
|
|
155
|
+
throw new Error(`Export source is not a regular file: ${name}`);
|
|
156
|
+
if ((info.mode & 0o777) !== row.mode || content.length !== row.bytes || fileHash(content) !== row.sha256) {
|
|
157
|
+
throw new Error(`Export source changed after creation: ${name}`);
|
|
158
|
+
}
|
|
159
|
+
snapshot.set(name, { content, mode: row.mode });
|
|
160
|
+
}
|
|
161
|
+
snapshot.set(MANIFEST_PATH, { content: manifestContent, mode: (await lstat(path.join(root, MANIFEST_PATH))).mode & 0o777 });
|
|
162
|
+
const sourceSnapshot = new Map(manifest.files.map((row) => [row.path, snapshot.get(row.path)]));
|
|
163
|
+
if (snapshotHash(sourceSnapshot) !== manifest.sourceHash)
|
|
164
|
+
throw new Error('Export source checksum differs from its manifest.');
|
|
165
|
+
const config = parseConfig(JSON.parse(snapshot.get('.repro/config.json')?.content.toString('utf8') ?? 'null'));
|
|
166
|
+
return { manifest, config, snapshot };
|
|
167
|
+
}
|
|
168
|
+
async function runtimeModule(name) {
|
|
169
|
+
const directory = path.dirname(fileURLToPath(import.meta.url));
|
|
170
|
+
try {
|
|
171
|
+
return (await readFile(path.join(directory, `${name}.js`), 'utf8')).replace(/\n?\/\/# sourceMappingURL=.*$/u, '');
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
if (error.code !== 'ENOENT')
|
|
175
|
+
throw error;
|
|
176
|
+
}
|
|
177
|
+
const source = await readFile(path.join(directory, `${name}.ts`), 'utf8');
|
|
178
|
+
return ts.transpileModule(source, {
|
|
179
|
+
compilerOptions: { module: ts.ModuleKind.ESNext, target: ts.ScriptTarget.ES2023, verbatimModuleSyntax: true },
|
|
180
|
+
fileName: `${name}.ts`,
|
|
181
|
+
}).outputText;
|
|
182
|
+
}
|
|
183
|
+
function readme(config) {
|
|
184
|
+
return `# ${config.name}\n\nThis directory is a reduced reproduction. Review its source before sharing it.\n\n## Verify\n\n1. Use Node.js 22.18 or newer and npm 10 or newer.\n2. Run \`node .repro/verify.mjs\`.\n\nThe verifier checks every exported source file, copies the export to an isolated temporary directory, installs its locked dependencies there, and runs this argv command without a shell:\n\n\`\`\`json\n${JSON.stringify(config.command, null, 2)}\n\`\`\`\n\nThe original command is expected to exit with code ${config.oracle.exitCode}. The verifier exits successfully only when that failure also contains every required fragment and no forbidden fragment. This establishes the configured observation, not semantic root-cause identity or global minimality.\n`;
|
|
185
|
+
}
|
|
186
|
+
const STANDALONE_VERIFIER = String.raw `#!/usr/bin/env node
|
|
187
|
+
import { createHash } from 'node:crypto';
|
|
188
|
+
import { chmod, lstat, mkdir, mkdtemp, readFile, readdir, realpath, rm, writeFile } from 'node:fs/promises';
|
|
189
|
+
import { tmpdir } from 'node:os';
|
|
190
|
+
import path from 'node:path';
|
|
191
|
+
import { fileURLToPath, pathToFileURL } from 'node:url';
|
|
192
|
+
|
|
193
|
+
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
|
|
194
|
+
const ignored = new Set(['.git','node_modules','.next','.nuxt','.turbo','.cache','.vercel','dist','out','build','coverage']);
|
|
195
|
+
const cancellation = new AbortController();
|
|
196
|
+
let interruptionExitCode = 0;
|
|
197
|
+
const interrupt = code => {
|
|
198
|
+
interruptionExitCode ||= code;
|
|
199
|
+
cancellation.abort();
|
|
200
|
+
};
|
|
201
|
+
const interruptSignal = () => interrupt(130);
|
|
202
|
+
const terminateSignal = () => interrupt(143);
|
|
203
|
+
process.once('SIGINT', interruptSignal);
|
|
204
|
+
process.once('SIGTERM', terminateSignal);
|
|
205
|
+
const safe = value => {
|
|
206
|
+
if (!value || value.includes('\0') || value.includes('\\') || path.posix.isAbsolute(value) || /^[A-Za-z]:/.test(value) || value.split('/').some(part => !part || part === '.' || part === '..')) throw new Error('Unsafe manifest path');
|
|
207
|
+
};
|
|
208
|
+
const sha = value => createHash('sha256').update(value).digest('hex');
|
|
209
|
+
const walk = async (base, relative = '') => {
|
|
210
|
+
const result = [];
|
|
211
|
+
for (const entry of await readdir(path.join(base, relative), { withFileTypes: true })) {
|
|
212
|
+
const name = relative ? relative + '/' + entry.name : entry.name;
|
|
213
|
+
safe(name);
|
|
214
|
+
const info = await lstat(path.join(base, name));
|
|
215
|
+
if (info.isSymbolicLink()) throw new Error('Symbolic link in export: ' + name);
|
|
216
|
+
if (info.isDirectory()) {
|
|
217
|
+
if (relative === '' && ignored.has(entry.name)) continue;
|
|
218
|
+
result.push(...await walk(base, name));
|
|
219
|
+
} else if (info.isFile()) result.push(name);
|
|
220
|
+
else throw new Error('Non-regular file in export: ' + name);
|
|
221
|
+
}
|
|
222
|
+
return result;
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
const validateFiles = async (base, manifest, expected, manifestContent) => {
|
|
226
|
+
const currentManifest = await readFile(path.join(base, '.repro/manifest.json'));
|
|
227
|
+
if (!currentManifest.equals(manifestContent)) throw new Error('Export manifest changed');
|
|
228
|
+
for (const name of await walk(base)) if (name !== '.repro/manifest.json' && !expected.has(name)) throw new Error('Extra unlisted source file: ' + name);
|
|
229
|
+
const contents = new Map();
|
|
230
|
+
const source = [];
|
|
231
|
+
for (const [name, row] of expected) {
|
|
232
|
+
const info = await lstat(path.join(base, name));
|
|
233
|
+
const content = await readFile(path.join(base, name));
|
|
234
|
+
if (!info.isFile() || info.isSymbolicLink() || (info.mode & 511) !== row.mode || content.length !== row.bytes || sha(content) !== row.sha256) throw new Error('Export source changed: ' + name);
|
|
235
|
+
contents.set(name, content);
|
|
236
|
+
if (!name.startsWith('.repro/')) source.push([name, row, content]);
|
|
237
|
+
}
|
|
238
|
+
const combined = createHash('sha256');
|
|
239
|
+
for (const [name, row, content] of source.sort((a, b) => a[0].localeCompare(b[0], 'en'))) {
|
|
240
|
+
combined.update(JSON.stringify([name, row.mode, content.length]) + '\n');
|
|
241
|
+
combined.update(content);
|
|
242
|
+
}
|
|
243
|
+
if (combined.digest('hex') !== manifest.sourceHash) throw new Error('Export source checksum changed');
|
|
244
|
+
return contents;
|
|
245
|
+
};
|
|
246
|
+
|
|
247
|
+
const writeExportFile = async (base, name, content, mode) => {
|
|
248
|
+
const destination = path.join(base, name);
|
|
249
|
+
await mkdir(path.dirname(destination), { recursive: true, mode: 448 });
|
|
250
|
+
await writeFile(destination, content, { mode });
|
|
251
|
+
await chmod(destination, mode);
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
const isWithin = (parent, candidate) => {
|
|
255
|
+
const relative = path.relative(parent, candidate);
|
|
256
|
+
return relative === '' || (relative !== '..' && !relative.startsWith('..' + path.sep) && !path.isAbsolute(relative));
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
const assertIsolatedAncestors = async workspace => {
|
|
260
|
+
let current = path.dirname(await realpath(workspace));
|
|
261
|
+
for (;;) {
|
|
262
|
+
try {
|
|
263
|
+
await lstat(path.join(current, 'node_modules'));
|
|
264
|
+
throw new Error('Temporary verification directory has an ancestor node_modules: ' + current);
|
|
265
|
+
} catch (error) {
|
|
266
|
+
if (!error || error.code !== 'ENOENT') throw error;
|
|
267
|
+
}
|
|
268
|
+
const parent = path.dirname(current);
|
|
269
|
+
if (parent === current) return;
|
|
270
|
+
current = parent;
|
|
271
|
+
}
|
|
272
|
+
};
|
|
273
|
+
|
|
274
|
+
try {
|
|
275
|
+
const manifestContent = await readFile(path.join(root, '.repro/manifest.json'));
|
|
276
|
+
const manifest = JSON.parse(manifestContent.toString('utf8'));
|
|
277
|
+
if (manifest.version !== 1 || manifest.format !== 'repro-surgeon-export-v1' || !Array.isArray(manifest.files) || !Array.isArray(manifest.generated)) throw new Error('Invalid export manifest');
|
|
278
|
+
const expected = new Map();
|
|
279
|
+
for (const [section, rows] of [['source', manifest.files], ['generated', manifest.generated]]) {
|
|
280
|
+
for (const row of rows) {
|
|
281
|
+
if (!row || typeof row.path !== 'string' || !Number.isInteger(row.mode) || row.mode < 0 || row.mode > 511 || !Number.isSafeInteger(row.bytes) || row.bytes < 0 || typeof row.sha256 !== 'string' || !/^[a-f0-9]{64}$/.test(row.sha256)) throw new Error('Invalid ' + section + ' manifest entry');
|
|
282
|
+
safe(row.path);
|
|
283
|
+
if (section === 'source' ? row.path.startsWith('.repro/') : !row.path.startsWith('.repro/') || row.path === '.repro/manifest.json') throw new Error('Invalid reserved manifest path');
|
|
284
|
+
if (expected.has(row.path)) throw new Error('Duplicate manifest path: ' + row.path);
|
|
285
|
+
expected.set(row.path, row);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
const contents = await validateFiles(root, manifest, expected, manifestContent);
|
|
289
|
+
const config = JSON.parse(contents.get('.repro/config.json').toString('utf8'));
|
|
290
|
+
if (!Array.isArray(config.command) || config.command.length === 0 || !config.oracle || !Array.isArray(config.oracle.allOf) || !Array.isArray(config.oracle.noneOf)) throw new Error('Invalid verifier configuration');
|
|
291
|
+
const canonicalRoot = await realpath(root);
|
|
292
|
+
const temporaryBase = await realpath(tmpdir());
|
|
293
|
+
if (isWithin(canonicalRoot, temporaryBase)) throw new Error('The temporary directory is inside the exported source. Choose a TMPDIR outside the export directory and retry.');
|
|
294
|
+
const temporary = await realpath(await mkdtemp(path.join(temporaryBase, 'repro-verifier-')));
|
|
295
|
+
try {
|
|
296
|
+
const workspace = path.join(temporary, 'work');
|
|
297
|
+
await mkdir(workspace, { mode: 448 });
|
|
298
|
+
await assertIsolatedAncestors(workspace);
|
|
299
|
+
for (const [name, row] of expected) await writeExportFile(workspace, name, contents.get(name), row.mode);
|
|
300
|
+
await writeExportFile(workspace, '.repro/manifest.json', manifestContent, 420);
|
|
301
|
+
const home = path.join(temporary, 'home');
|
|
302
|
+
await mkdir(home, { mode: 448 });
|
|
303
|
+
await writeFile(path.join(home, 'npmrc'), '');
|
|
304
|
+
await writeFile(path.join(home, 'global-npmrc'), '');
|
|
305
|
+
const runtimeUrl = pathToFileURL(path.join(workspace, '.repro/runtime/runner.mjs')).href;
|
|
306
|
+
const oracleUrl = pathToFileURL(path.join(workspace, '.repro/runtime/oracle.mjs')).href;
|
|
307
|
+
const { runCommand, cleanEnvironment } = await import(runtimeUrl);
|
|
308
|
+
const { evaluateOracle } = await import(oracleUrl);
|
|
309
|
+
const environment = cleanEnvironment(home, config.execution.env);
|
|
310
|
+
environment.NPM_CONFIG_USERCONFIG = path.join(home, 'npmrc');
|
|
311
|
+
environment.NPM_CONFIG_GLOBALCONFIG = path.join(home, 'global-npmrc');
|
|
312
|
+
environment.NPM_CONFIG_CACHE = path.join(temporary, 'npm-cache');
|
|
313
|
+
environment.NEXT_TELEMETRY_DISABLED = '1';
|
|
314
|
+
environment.NO_COLOR = '1';
|
|
315
|
+
environment.CI = '1';
|
|
316
|
+
const install = ['npm', 'ci', '--no-audit', '--no-fund'];
|
|
317
|
+
if (!config.execution.allowInstallScripts) install.push('--ignore-scripts');
|
|
318
|
+
const installed = await runCommand(install, { cwd: workspace, timeoutMs: config.execution.installTimeoutMs, maxOutputBytes: config.execution.maxOutputBytes, env: environment, signal: cancellation.signal });
|
|
319
|
+
if (installed.exitCode !== 0 || installed.error || installed.timedOut || installed.aborted || installed.signal || installed.outputLimitExceeded) throw new Error('Dependency installation failed in isolated verification workspace');
|
|
320
|
+
await validateFiles(workspace, manifest, expected, manifestContent);
|
|
321
|
+
const execution = await runCommand(config.command, { cwd: workspace, timeoutMs: config.execution.timeoutMs, maxOutputBytes: config.execution.maxOutputBytes, env: environment, signal: cancellation.signal });
|
|
322
|
+
const observation = evaluateOracle(execution, config.oracle);
|
|
323
|
+
if (observation.status !== 'reproduced') throw new Error('Configured failure was not reproduced: ' + observation.reason);
|
|
324
|
+
process.stdout.write('Configured failure reproduced.\n');
|
|
325
|
+
} finally {
|
|
326
|
+
await rm(temporary, { recursive: true, force: true });
|
|
327
|
+
}
|
|
328
|
+
} catch (error) {
|
|
329
|
+
process.stderr.write((error instanceof Error ? error.message : String(error)) + '\n');
|
|
330
|
+
process.exitCode = interruptionExitCode || 1;
|
|
331
|
+
} finally {
|
|
332
|
+
process.removeListener('SIGINT', interruptSignal);
|
|
333
|
+
process.removeListener('SIGTERM', terminateSignal);
|
|
334
|
+
if (interruptionExitCode !== 0) process.exitCode = interruptionExitCode;
|
|
335
|
+
}
|
|
336
|
+
`;
|
|
337
|
+
async function generatedSnapshot(state) {
|
|
338
|
+
return new Map([
|
|
339
|
+
['.repro/LICENSE', { content: await readFile(new URL('../LICENSE', import.meta.url)), mode: 0o644 }],
|
|
340
|
+
['.repro/README.md', { content: Buffer.from(readme(state.config)), mode: 0o644 }],
|
|
341
|
+
['.repro/config.json', { content: Buffer.from(JSON.stringify(state.config, null, 2) + '\n'), mode: 0o644 }],
|
|
342
|
+
['.repro/verify.mjs', { content: Buffer.from(STANDALONE_VERIFIER), mode: 0o755 }],
|
|
343
|
+
['.repro/runtime/runner.mjs', { content: Buffer.from(await runtimeModule('runner')), mode: 0o644 }],
|
|
344
|
+
['.repro/runtime/oracle.mjs', { content: Buffer.from(await runtimeModule('oracle')), mode: 0o644 }],
|
|
345
|
+
]);
|
|
346
|
+
}
|
|
347
|
+
async function writeExport(root, state, snapshot) {
|
|
348
|
+
await writeSnapshot(snapshot, root);
|
|
349
|
+
const generated = await generatedSnapshot(state);
|
|
350
|
+
await writeSnapshot(generated, root);
|
|
351
|
+
const manifest = {
|
|
352
|
+
version: 1,
|
|
353
|
+
format: 'repro-surgeon-export-v1',
|
|
354
|
+
runId: state.id,
|
|
355
|
+
createdAt: new Date().toISOString(),
|
|
356
|
+
sourceHash: snapshotHash(snapshot),
|
|
357
|
+
files: manifestFiles(snapshot),
|
|
358
|
+
generated: manifestFiles(generated),
|
|
359
|
+
};
|
|
360
|
+
await writeSnapshot(new Map([[MANIFEST_PATH, { content: Buffer.from(JSON.stringify(manifest, null, 2) + '\n'), mode: 0o644 }]]), root);
|
|
361
|
+
}
|
|
362
|
+
async function destinationState(destination, runId) {
|
|
363
|
+
try {
|
|
364
|
+
const info = await lstat(destination);
|
|
365
|
+
if (info.isSymbolicLink() || !info.isDirectory())
|
|
366
|
+
throw new Error('Existing export destination is not a real directory.');
|
|
367
|
+
}
|
|
368
|
+
catch (error) {
|
|
369
|
+
if (error.code === 'ENOENT')
|
|
370
|
+
return 'missing';
|
|
371
|
+
throw error;
|
|
372
|
+
}
|
|
373
|
+
if ((await readdir(destination)).length === 0)
|
|
374
|
+
return 'empty';
|
|
375
|
+
const existing = await readValidatedExport(destination);
|
|
376
|
+
if (existing.manifest.runId !== runId)
|
|
377
|
+
throw new Error('Existing export belongs to an unrelated run; refusing to replace it.');
|
|
378
|
+
return 'replaceable';
|
|
379
|
+
}
|
|
380
|
+
async function installExport(stage, destination, current) {
|
|
381
|
+
if (current === 'missing') {
|
|
382
|
+
await rename(stage, destination);
|
|
383
|
+
return;
|
|
384
|
+
}
|
|
385
|
+
if (current === 'empty') {
|
|
386
|
+
await rm(destination, { recursive: true });
|
|
387
|
+
await rename(stage, destination);
|
|
388
|
+
return;
|
|
389
|
+
}
|
|
390
|
+
const backup = `${destination}.previous-${randomUUID()}`;
|
|
391
|
+
await rename(destination, backup);
|
|
392
|
+
try {
|
|
393
|
+
await rename(stage, destination);
|
|
394
|
+
await rm(backup, { recursive: true, force: true });
|
|
395
|
+
}
|
|
396
|
+
catch (error) {
|
|
397
|
+
try {
|
|
398
|
+
await rename(backup, destination);
|
|
399
|
+
}
|
|
400
|
+
catch { /* Preserve the original error. */ }
|
|
401
|
+
throw error;
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
function assertCurrentCheckpoint(state, snapshot, current) {
|
|
405
|
+
const suppliedSnapshotHash = snapshotHash(snapshot);
|
|
406
|
+
if (state.id !== current.state.id
|
|
407
|
+
|| state.configHash !== current.state.configHash
|
|
408
|
+
|| state.bestHash !== current.state.bestHash
|
|
409
|
+
|| state.status !== current.state.status
|
|
410
|
+
|| suppliedSnapshotHash !== current.state.bestHash
|
|
411
|
+
|| hashValue(state.config) !== hashValue(current.state.config)
|
|
412
|
+
|| hashValue(state) !== hashValue(current.state)) {
|
|
413
|
+
throw new Error('Export request is stale and no longer agrees with the current accepted checkpoint. Reload or resume the run before exporting.');
|
|
414
|
+
}
|
|
415
|
+
if (snapshotHash(current.snapshot) !== suppliedSnapshotHash) {
|
|
416
|
+
throw new Error('Export snapshot no longer agrees with the current accepted checkpoint. Reload or resume the run before exporting.');
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
export async function verifyReproduction(exportRoot, options) {
|
|
420
|
+
let exportHash = '';
|
|
421
|
+
let runs = 0;
|
|
422
|
+
let validationRoot;
|
|
423
|
+
let manager;
|
|
424
|
+
let result;
|
|
425
|
+
try {
|
|
426
|
+
const absoluteExportRoot = path.resolve(exportRoot);
|
|
427
|
+
await assertTemporaryDirectoryOutsideSource(absoluteExportRoot);
|
|
428
|
+
const { config, snapshot } = await readValidatedExport(absoluteExportRoot);
|
|
429
|
+
exportHash = snapshotHash(snapshot);
|
|
430
|
+
validationRoot = await createIsolatedDirectory('repro-surgeon-verification-state-');
|
|
431
|
+
manager = new WorkspaceManager(validationRoot, config, options?.signal);
|
|
432
|
+
for (let run = 0; run < config.runs.final; run++) {
|
|
433
|
+
const cwd = await manager.prepare(snapshot);
|
|
434
|
+
await readValidatedExport(cwd);
|
|
435
|
+
const execution = await runCommand(config.command, {
|
|
436
|
+
cwd,
|
|
437
|
+
timeoutMs: config.execution.timeoutMs,
|
|
438
|
+
maxOutputBytes: config.execution.maxOutputBytes,
|
|
439
|
+
env: await manager.environment(),
|
|
440
|
+
...(options?.signal ? { signal: options.signal } : {}),
|
|
441
|
+
});
|
|
442
|
+
runs++;
|
|
443
|
+
const observation = evaluateOracle(execution, config.oracle);
|
|
444
|
+
if (observation.status !== 'reproduced') {
|
|
445
|
+
result = { status: 'failed', runs, reason: `Fresh verification failed: ${observation.reason}`, snapshotHash: exportHash, environment: 'fresh-directory' };
|
|
446
|
+
break;
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
result ??= { status: 'verified', runs, reason: `The exported source reproduced in ${runs} fresh-directory runs.`, snapshotHash: exportHash, environment: 'fresh-directory' };
|
|
450
|
+
}
|
|
451
|
+
catch (error) {
|
|
452
|
+
result = { status: 'failed', runs, reason: error instanceof Error ? error.message : String(error), snapshotHash: exportHash, environment: 'fresh-directory' };
|
|
453
|
+
}
|
|
454
|
+
finally {
|
|
455
|
+
const cleanupErrors = [];
|
|
456
|
+
try {
|
|
457
|
+
await manager?.dispose();
|
|
458
|
+
}
|
|
459
|
+
catch (error) {
|
|
460
|
+
cleanupErrors.push(error instanceof Error ? error.message : String(error));
|
|
461
|
+
}
|
|
462
|
+
if (validationRoot !== undefined) {
|
|
463
|
+
try {
|
|
464
|
+
await rm(validationRoot, { recursive: true, force: true });
|
|
465
|
+
}
|
|
466
|
+
catch (error) {
|
|
467
|
+
cleanupErrors.push(error instanceof Error ? error.message : String(error));
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
if (cleanupErrors.length > 0) {
|
|
471
|
+
result = { status: 'failed', runs, reason: `Fresh verification cleanup failed: ${cleanupErrors.join('; ')}`, snapshotHash: exportHash, environment: 'fresh-directory' };
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
return result ?? { status: 'failed', runs, reason: 'Fresh verification did not produce a result.', snapshotHash: exportHash, environment: 'fresh-directory' };
|
|
475
|
+
}
|
|
476
|
+
export async function exportReproduction(runRoot, state, snapshot, options) {
|
|
477
|
+
if (snapshotHash(snapshot) !== state.bestHash)
|
|
478
|
+
throw new Error('Export snapshot differs from the accepted state.');
|
|
479
|
+
const absoluteRunRoot = path.resolve(runRoot);
|
|
480
|
+
const destination = path.join(absoluteRunRoot, 'repro');
|
|
481
|
+
await assertDisjointPaths(state.sourceRoot, destination);
|
|
482
|
+
const release = await acquireRunLock(absoluteRunRoot);
|
|
483
|
+
try {
|
|
484
|
+
assertCurrentCheckpoint(state, snapshot, await loadCheckpoint(absoluteRunRoot));
|
|
485
|
+
await assertTemporaryDirectoryOutsideSource(state.sourceRoot);
|
|
486
|
+
const current = await destinationState(destination, state.id);
|
|
487
|
+
const stage = path.join(absoluteRunRoot, `.repro-stage-${randomUUID()}`);
|
|
488
|
+
state.status = 'verifying';
|
|
489
|
+
state.verification = { status: 'pending', runs: 0, reason: 'Writing and checking the independent export.', snapshotHash: '', environment: 'fresh-directory' };
|
|
490
|
+
state.updatedAt = new Date().toISOString();
|
|
491
|
+
await saveCheckpoint(absoluteRunRoot, state, snapshot);
|
|
492
|
+
try {
|
|
493
|
+
await mkdir(stage, { mode: 0o700 });
|
|
494
|
+
await writeExport(stage, state, snapshot);
|
|
495
|
+
const staged = await readValidatedExport(stage);
|
|
496
|
+
if (staged.manifest.runId !== state.id)
|
|
497
|
+
throw new Error('Staged export ownership could not be verified.');
|
|
498
|
+
await installExport(stage, destination, current);
|
|
499
|
+
}
|
|
500
|
+
finally {
|
|
501
|
+
await rm(stage, { recursive: true, force: true });
|
|
502
|
+
}
|
|
503
|
+
state.verification = await verifyReproduction(destination, options);
|
|
504
|
+
state.updatedAt = new Date().toISOString();
|
|
505
|
+
if (state.verification.status === 'verified') {
|
|
506
|
+
state.status = 'complete';
|
|
507
|
+
state.stopReason ||= 'Independent export verified';
|
|
508
|
+
}
|
|
509
|
+
else {
|
|
510
|
+
state.status = 'failed';
|
|
511
|
+
state.stopReason ||= `Export verification failed: ${state.verification.reason}`;
|
|
512
|
+
}
|
|
513
|
+
await saveCheckpoint(absoluteRunRoot, state, snapshot);
|
|
514
|
+
return state;
|
|
515
|
+
}
|
|
516
|
+
finally {
|
|
517
|
+
await release();
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
//# sourceMappingURL=export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"export.js","sourceRoot":"","sources":["../src/export.ts"],"names":[],"mappings":"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"}
|
package/dist/graph.d.ts
ADDED