const assert = require('node:assert/strict'); const crypto = require('node:crypto'); const fs = require('node:fs'); const path = require('node:path'); const root = path.resolve(__dirname, '..'); const read = relative => fs.readFileSync(path.join(root, relative), 'utf8'); const hash = relative => crypto.createHash('sha256').update(fs.readFileSync(path.join(root, relative))).digest('hex'); const packageJson = JSON.parse(read('package.json')); const baseline = JSON.parse(read('verification/approved-r4.json')); const html = read('dist/index.html'); const css = read('dist/styles.css'); const app = read('dist/app.js'); assert.equal(packageJson.private, true, 'the app must remain a private deployable package'); assert.equal(packageJson.dependencies, undefined, 'runtime must remain dependency-free'); assert.equal(packageJson.devDependencies, undefined, 'local verification must not require npm installation'); for (const script of ['dev', 'start', 'test', 'test:static', 'test:e2e', 'verify']) { assert.equal(typeof packageJson.scripts[script], 'string', `missing npm script: ${script}`); } const actualHashes = {}; for (const [relative, expected] of Object.entries(baseline.files)) { actualHashes[relative] = hash(relative); assert.equal(actualHashes[relative], expected, `${relative} diverged from the declared production baseline`); } assert.match(html, /^/i); assert.match(html, //); assert.match(html, /본문으로 건너뛰기<\/a>/); assert.match(html, /id="announcer"[^>]*aria-live="polite"/); assert.match(html, /