fix: bind performance evidence to production resources

This commit is contained in:
2026-09-02 08:53:00 +03:00
parent 5b7e47c2a2
commit e3ac3a4db4
23 changed files with 642 additions and 60 deletions

View File

@@ -2,10 +2,13 @@
import { readFile } from 'node:fs/promises';
import { aggregateFiveDriveTraces } from './lib/performance-aggregation.mjs';
const paths = process.argv.slice(2);
const args = process.argv.slice(2);
if (args[0] !== '--trust-policy' || typeof args[1] !== 'string') throw new Error('Pass --trust-policy followed by an explicit trusted public-key policy.');
const policy = JSON.parse(await readFile(args[1], 'utf8'));
const paths = args.slice(2);
if (paths.length !== 5) throw new Error('Pass exactly five explicit drive-trace.v1 JSON paths.');
const runs = [];
for (const path of paths) runs.push(JSON.parse(await readFile(path, 'utf8')));
const aggregate = aggregateFiveDriveTraces(runs);
const aggregate = aggregateFiveDriveTraces(runs, policy);
process.stdout.write(`${JSON.stringify(aggregate, null, 2)}\n`);
if (!aggregate.passes) process.exitCode = 1;

View File

@@ -10,10 +10,13 @@ import {
classifyArtifact,
evaluateBudgetTotals,
evaluateMediaAssetBudget,
evaluateRuntimeBudgetEvidence,
validateRuntimeBudgetTraceReport,
} from './lib/bundle-budgets.mjs';
const root = resolve(process.argv[2] ?? 'dist');
const runtimeTraceIndex = process.argv.indexOf('--runtime-trace');
const runtimeTracePath = runtimeTraceIndex === -1 ? null : process.argv[runtimeTraceIndex + 1];
if (runtimeTraceIndex !== -1 && runtimeTracePath === undefined) throw new Error('--runtime-trace requires one explicit drive-trace JSON path.');
if (!(await stat(root)).isDirectory()) throw new Error('Bundle budget target must be a directory.');
const listFiles = async (directory) => {
@@ -38,7 +41,6 @@ const readJson = async (path, label) => {
const manifest = await readJson(resolve('content/public/asset-manifest.json'), 'Public asset manifest');
const content = await readJson(resolve('content/public/portfolio-content.json'), 'Portfolio content');
const runtimeEvidence = await readJson(resolve('config/performance-budget-evidence.json'), 'Runtime budget evidence');
if (!Array.isArray(manifest?.assets)) throw new Error('Public asset manifest is invalid.');
const assetClassById = new Map();
@@ -118,13 +120,17 @@ const entrySource = await readFile(resolve(root, entry.path), 'utf8');
if (!/import\([^)]*environment-/u.test(entrySource)) throw new Error('The live scene is not separated behind a dynamic import.');
if (/WebGLRenderer|WebGLProgram|ShaderMaterial/u.test(entrySource)) throw new Error('Three.js/live-scene code leaked into the reduced-motion initial chunk.');
const runtime = evaluateRuntimeBudgetEvidence(runtimeEvidence);
const violations = [...evaluateBudgetTotals(totals).violations, ...mediaViolations, ...runtime.violations];
let runtime = null;
if (runtimeTracePath !== null) {
const trace = await readJson(resolve(runtimeTracePath), 'Runtime drive trace');
runtime = validateRuntimeBudgetTraceReport(trace);
}
const violations = [...evaluateBudgetTotals(totals).violations, ...mediaViolations, ...(runtime?.violations ?? [])];
const report = {
schema: 'portfolio-bundle-budget/v1',
compression: 'brotli-quality-11-or-raw-already-compressed',
totals,
runtime: { peakRequests: runtimeEvidence.peakRequests, tiers: runtime.tiers },
runtime: runtime === null ? { status: 'pending-production-path-trace' } : { status: 'verified-production-path-trace', tier: runtime.tier },
records: records.sort((left, right) => left.path.localeCompare(right.path)),
violations,
};

View File

@@ -13,3 +13,15 @@ export function evaluateRuntimeBudgetEvidence(evidence: Readonly<Record<string,
tiers: Array<{ tier: string; textureBytes: number; geometryBytes: number; renderTargetBytes: number; runtimeAllowanceBytes: number; totalBytes: number }>;
violations: Array<{ budget: string; actual: number; threshold: number; id?: string }>;
};
export function evaluateRuntimeTraceBudgetEvidence(evidence: Readonly<Record<string, unknown>>): {
tier: { tier: string; textureBytes: number; geometryBytes: number; renderTargetBytes: number; runtimeAllowanceBytes: number; totalBytes: number };
violations: Array<{ budget: string; actual: number; threshold: number; id?: string }>;
};
export function validateRuntimeBudgetTraceReport(report: Readonly<Record<string, unknown>>): {
tier: { tier: string; textureBytes: number; geometryBytes: number; renderTargetBytes: number; runtimeAllowanceBytes: number; totalBytes: number };
violations: Array<{ budget: string; actual: number; threshold: number; id?: string }>;
};
export function calculatePeakRequestConcurrency(entries: readonly Readonly<Record<string, unknown>>[]): {
imageScene: number;
video: number;
};

View File

@@ -133,3 +133,85 @@ export const evaluateRuntimeBudgetEvidence = (evidence) => {
});
return { tiers, violations };
};
export const evaluateRuntimeTraceBudgetEvidence = (evidence) => {
if (evidence?.schema !== 'portfolio-runtime-trace-evidence/v1' || evidence.allocation === null || typeof evidence.allocation !== 'object') {
throw new Error('Runtime trace evidence must use portfolio-runtime-trace-evidence/v1.');
}
const evaluated = evaluateRuntimeBudgetEvidence({
schema: 'portfolio-runtime-budget-evidence/v1',
peakRequests: evidence.peakRequests,
tiers: [
evidence.allocation,
evidence.allocation.tier === 'low'
? { tier: 'high', textures: [], geometryBytes: 0, renderTargets: [] }
: { tier: 'low', textures: [], geometryBytes: 0, renderTargets: [] },
],
});
const tier = evaluated.tiers.find((item) => item.tier === evidence.allocation.tier);
if (tier === undefined) throw new Error('Runtime trace tier could not be evaluated.');
return {
tier,
violations: evaluated.violations,
};
};
export const validateRuntimeBudgetTraceReport = (report) => {
if (report?.schema !== 'runtime-budget-trace.v1'
|| report.evidenceKind !== 'authenticated-test-build-production-path'
|| report.gatingReferenceResult !== false) {
throw new Error('Runtime budget verification requires an authenticated production-path capture.');
}
const expectedProfile = report.tier === 'high' ? 'desktop-high' : report.tier === 'low' ? 'mobile-low' : null;
if (expectedProfile === null || report.profile !== expectedProfile) {
throw new Error('Runtime budget capture profile and tier disagree.');
}
const viewport = report.observed?.viewport;
const devicePixelRatio = report.observed?.devicePixelRatio;
const rendererPixelRatio = report.observed?.rendererPixelRatio;
const expectedRendererPixelRatio = report.tier === 'high' ? 1.5 : 1.25;
if (!finitePositiveInteger(viewport?.width) || !finitePositiveInteger(viewport?.height)
|| !(Number.isFinite(devicePixelRatio) && devicePixelRatio >= expectedRendererPixelRatio)
|| rendererPixelRatio !== expectedRendererPixelRatio) {
throw new Error('Runtime budget capture did not exercise the named tier DPR cap.');
}
const evidence = report.runtimeBudgetEvidence;
if (evidence?.allocation?.tier !== report.tier || !Array.isArray(evidence.allocation.renderTargets)) {
throw new Error('Runtime budget capture allocation and tier disagree.');
}
const framebuffers = evidence.allocation.renderTargets.filter((target) => target?.id === 'default-framebuffer');
const expectedWidth = Math.round(viewport.width * rendererPixelRatio);
const expectedHeight = Math.round(viewport.height * rendererPixelRatio);
if (framebuffers.length !== 1 || framebuffers[0].width !== expectedWidth || framebuffers[0].height !== expectedHeight) {
throw new Error('Runtime budget capture framebuffer dimensions do not match the observed viewport and DPR cap.');
}
return evaluateRuntimeTraceBudgetEvidence(evidence);
};
const requestClass = (entry) => {
if (entry.initiatorType === 'video' || /\.(?:mp4|webm)(?:[?#]|$)/iu.test(entry.name)) return 'video';
if (entry.initiatorType === 'img' || /\/assets\/(?:environment-|high-tier-)/u.test(entry.name)) return 'imageScene';
return null;
};
export const calculatePeakRequestConcurrency = (entries) => {
if (!Array.isArray(entries)) throw new Error('Resource timing entries are required.');
const peaks = { imageScene: 0, video: 0 };
for (const kind of ['imageScene', 'video']) {
const events = [];
for (const entry of entries) {
if (requestClass(entry) !== kind) continue;
if (!Number.isFinite(entry.startTime) || !Number.isFinite(entry.responseEnd) || entry.responseEnd < entry.startTime) {
throw new Error('Tracked resource timing is incomplete.');
}
events.push({ at: entry.startTime, delta: 1 }, { at: entry.responseEnd, delta: -1 });
}
events.sort((left, right) => left.at - right.at || left.delta - right.delta);
let active = 0;
for (const event of events) {
active += event.delta;
peaks[kind] = Math.max(peaks[kind], active);
}
}
return peaks;
};

View File

@@ -1,4 +1,4 @@
export function aggregateFiveDriveTraces(runs: readonly unknown[]): {
export function aggregateFiveDriveTraces(runs: readonly unknown[], trustPolicy: Readonly<Record<string, unknown>>): {
schema: 'drive-trace-aggregation/v1';
profile: string;
runCount: 5;

View File

@@ -1,11 +1,14 @@
import { verifySignedReferenceRun } from './reference-evidence.mjs';
const median = (values) => {
if (values.length === 0) throw new Error('At least one value is required.');
const sorted = [...values].sort((left, right) => left - right);
return sorted[Math.floor(sorted.length / 2)];
};
export const aggregateFiveDriveTraces = (runs) => {
export const aggregateFiveDriveTraces = (runs, trustPolicy) => {
if (!Array.isArray(runs) || runs.length !== 5) throw new Error('Exactly five drive-trace.v1 runs are required.');
for (const run of runs) verifySignedReferenceRun(run, trustPolicy);
const profile = runs[0]?.profile;
if (typeof profile !== 'string' || runs.some((run) => run?.schema !== 'drive-trace.v1' || run.profile !== profile)) {
throw new Error('All runs must use one drive-trace.v1 profile.');

View File

@@ -0,0 +1,10 @@
import type { KeyLike } from 'node:crypto';
export function signReferenceCandidate(
candidate: Readonly<Record<string, unknown>>,
signer: { keyId: string; privateKey: KeyLike },
): Record<string, unknown>;
export function verifySignedReferenceRun(
run: Readonly<Record<string, unknown>>,
policy: { schema: string; keyId: string; publicKeyPem: string },
): Record<string, unknown>;

View File

@@ -0,0 +1,82 @@
import { createHash, createPublicKey, sign, verify } from 'node:crypto';
const domain = Buffer.from('portfolio-drive-trace-result/v1\0', 'utf8');
const canonicalize = (value) => {
if (value === null || typeof value === 'boolean' || typeof value === 'string') return JSON.stringify(value);
if (typeof value === 'number') {
if (!Number.isFinite(value)) throw new Error('Reference evidence cannot contain non-finite numbers.');
return JSON.stringify(value);
}
if (Array.isArray(value)) return `[${value.map(canonicalize).join(',')}]`;
if (typeof value === 'object') {
const entries = Object.entries(value).sort(([left], [right]) => left.localeCompare(right, 'en-US'));
if (entries.some(([, item]) => item === undefined)) throw new Error('Reference evidence cannot contain undefined values.');
return `{${entries.map(([key, item]) => `${JSON.stringify(key)}:${canonicalize(item)}`).join(',')}}`;
}
throw new Error('Reference evidence contains an unsupported value.');
};
const signingPayload = (run) => {
if (run === null || typeof run !== 'object' || Array.isArray(run)) throw new Error('Reference result must be an object.');
const { referenceProof: _proof, ...payload } = run;
return payload;
};
const encodedPayload = (payload) => Buffer.concat([domain, Buffer.from(canonicalize(payload), 'utf8')]);
export const signReferenceCandidate = (candidate, signer) => {
if (candidate?.schema !== 'drive-trace.v1' || candidate.evidenceKind !== 'validated-reference-candidate-unsigned'
|| candidate.gatingReferenceResult !== false || candidate.referenceCandidateValidated !== true
|| candidate.referenceBudgetsPass !== true || candidate.validReferenceCadence !== true
|| !Object.values(candidate.budgetResults ?? {}).every((value) => value === true)) {
throw new Error('Only a fully validated unsigned reference candidate can be signed.');
}
if (typeof signer?.keyId !== 'string' || !/^[a-z0-9][a-z0-9-]{2,79}$/u.test(signer.keyId) || signer.privateKey === undefined) {
throw new Error('An external Ed25519 signing identity is required.');
}
const payload = {
...candidate,
evidenceKind: 'signed-physical-reference',
gatingReferenceResult: true,
};
const bytes = encodedPayload(payload);
const resultDigest = createHash('sha256').update(bytes).digest('hex');
const signature = sign(null, bytes, signer.privateKey).toString('base64url');
return {
...payload,
referenceProof: {
schema: 'portfolio-reference-result-proof/v1',
algorithm: 'Ed25519',
encoding: 'base64url-nopad',
keyId: signer.keyId,
resultDigest,
signature,
},
};
};
export const verifySignedReferenceRun = (run, policy) => {
if (policy?.schema !== 'portfolio-reference-trust-policy/v1'
|| typeof policy.keyId !== 'string' || typeof policy.publicKeyPem !== 'string') {
throw new Error('An explicit trusted reference public-key policy is required.');
}
const proof = run?.referenceProof;
if (run?.schema !== 'drive-trace.v1' || run.evidenceKind !== 'signed-physical-reference'
|| run.gatingReferenceResult !== true || proof?.schema !== 'portfolio-reference-result-proof/v1'
|| proof.algorithm !== 'Ed25519' || proof.encoding !== 'base64url-nopad' || proof.keyId !== policy.keyId
|| !/^[a-f0-9]{64}$/u.test(proof.resultDigest ?? '') || !/^[A-Za-z0-9_-]+$/u.test(proof.signature ?? '')) {
throw new Error('Reference result signature metadata is invalid.');
}
const payload = signingPayload(run);
const bytes = encodedPayload(payload);
const digest = createHash('sha256').update(bytes).digest('hex');
if (digest !== proof.resultDigest) throw new Error('Reference result digest mismatch.');
let publicKey;
try { publicKey = createPublicKey(policy.publicKeyPem); } catch { throw new Error('Trusted reference public key is invalid.'); }
if (publicKey.asymmetricKeyType !== 'ed25519'
|| !verify(null, bytes, publicKey, Buffer.from(proof.signature, 'base64url'))) {
throw new Error('Reference result signature is not trusted.');
}
return payload;
};

View File

@@ -0,0 +1,18 @@
#!/usr/bin/env node
import { createPrivateKey } from 'node:crypto';
import { readFile, writeFile } from 'node:fs/promises';
import { signReferenceCandidate } from './lib/reference-evidence.mjs';
const args = process.argv.slice(2);
if (args.length !== 6 || args[0] !== '--key-id' || args[2] !== '--private-key') {
throw new Error('Usage: sign-drive-trace --key-id ID --private-key PRIVATE_PEM INPUT_JSON OUTPUT_JSON');
}
const [, keyId, , privateKeyPath, inputPath, outputPath] = args;
const [candidate, privateKeyPem] = await Promise.all([
readFile(inputPath, 'utf8').then(JSON.parse),
readFile(privateKeyPath, 'utf8'),
]);
const privateKey = createPrivateKey(privateKeyPem);
if (privateKey.asymmetricKeyType !== 'ed25519') throw new Error('Reference results require an external Ed25519 private key.');
const signed = signReferenceCandidate(candidate, { keyId, privateKey });
await writeFile(outputPath, `${JSON.stringify(signed, null, 2)}\n`, { encoding: 'utf8', flag: 'wx', mode: 0o600 });