fix: close performance evidence and budget gates
This commit is contained in:
102
tests/performance/reference-run.ts
Normal file
102
tests/performance/reference-run.ts
Normal file
@@ -0,0 +1,102 @@
|
||||
import { createHash } from 'node:crypto';
|
||||
import { readFile } from 'node:fs/promises';
|
||||
|
||||
export type ReferenceProfile = 'desktop-high' | 'mobile-low';
|
||||
|
||||
export interface AuthenticatedReferenceRun {
|
||||
profile: ReferenceProfile;
|
||||
runId: string;
|
||||
runIndex: number;
|
||||
attestationDigest: string;
|
||||
browserVersion: string;
|
||||
viewport: { width: number; height: number };
|
||||
}
|
||||
|
||||
interface AuthenticationInput {
|
||||
referenceMode: boolean;
|
||||
expectedProfile: ReferenceProfile;
|
||||
attestationBytes: Uint8Array;
|
||||
expectedDigest: string;
|
||||
}
|
||||
|
||||
interface ObservedEnvironment {
|
||||
viewport: { width: number; height: number };
|
||||
visible: boolean;
|
||||
reducedMotion: 'no-preference' | 'reduce';
|
||||
saveData: boolean;
|
||||
pageZoom: number;
|
||||
browserName: string;
|
||||
browserVersion: string;
|
||||
startedFromAboutBlank: boolean;
|
||||
}
|
||||
|
||||
const exactKeys = (value: unknown, keys: readonly string[], label: string): Record<string, unknown> => {
|
||||
if (value === null || typeof value !== 'object' || Array.isArray(value)) throw new Error(`${label} is invalid.`);
|
||||
const actual = Object.keys(value).sort();
|
||||
const expected = [...keys].sort();
|
||||
if (JSON.stringify(actual) !== JSON.stringify(expected)) throw new Error(`${label} fields are invalid.`);
|
||||
return value as Record<string, unknown>;
|
||||
};
|
||||
|
||||
const pinned = {
|
||||
'desktop-high': { viewport: { width: 1_440, height: 900 }, cpu: 'Apple M1', gpu: 'Apple M1 integrated GPU', ramGb: 8, downstreamKbps: 10_000, upstreamKbps: 10_000, roundTripLatencyMs: 40 },
|
||||
'mobile-low': { viewport: { width: 390, height: 844 }, cpu: 'Google Tensor', gpu: 'Mali-G78 MP20', ramGb: 8, downstreamKbps: 1_600, upstreamKbps: 750, roundTripLatencyMs: 150 },
|
||||
} as const;
|
||||
|
||||
export const authenticateReferenceRun = (input: AuthenticationInput): AuthenticatedReferenceRun => {
|
||||
if (!input.referenceMode) throw new Error('Authenticated reference mode is required.');
|
||||
if (!/^[a-f0-9]{64}$/u.test(input.expectedDigest)) throw new Error('Reference attestation digest is invalid.');
|
||||
const actualDigest = createHash('sha256').update(input.attestationBytes).digest('hex');
|
||||
if (actualDigest !== input.expectedDigest) throw new Error('Reference attestation digest mismatch.');
|
||||
let decoded: unknown;
|
||||
try { decoded = JSON.parse(Buffer.from(input.attestationBytes).toString('utf8')); } catch { throw new Error('Reference attestation JSON is invalid.'); }
|
||||
const root = exactKeys(decoded, ['schema', 'profile', 'runId', 'runIndex', 'capturedAt', 'device', 'browser', 'osVersion', 'display', 'viewport', 'network', 'assertions'], 'Reference attestation');
|
||||
if (root.schema !== 'portfolio-reference-run-attestation/v1' || root.profile !== input.expectedProfile
|
||||
|| typeof root.runId !== 'string' || !/^[a-z0-9][a-z0-9-]{2,79}$/u.test(root.runId)
|
||||
|| !Number.isInteger(root.runIndex) || Number(root.runIndex) < 1 || Number(root.runIndex) > 5
|
||||
|| typeof root.capturedAt !== 'string' || !/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/u.test(root.capturedAt)
|
||||
|| !Number.isFinite(Date.parse(root.capturedAt))
|
||||
|| typeof root.osVersion !== 'string' || root.osVersion.length < 2) throw new Error('Reference run metadata is invalid.');
|
||||
const profile = pinned[input.expectedProfile];
|
||||
const device = exactKeys(root.device, ['model', 'cpu', 'gpu', 'ramGb'], 'Reference device');
|
||||
if (typeof device.model !== 'string' || device.model.length < 2 || device.cpu !== profile.cpu || device.gpu !== profile.gpu || device.ramGb !== profile.ramGb) throw new Error('Reference device does not match the pinned class.');
|
||||
const browser = exactKeys(root.browser, ['name', 'version', 'driverVersion'], 'Reference browser');
|
||||
if (browser.name !== 'Chromium' || typeof browser.version !== 'string' || !/^\d+(?:\.\d+){1,3}$/u.test(browser.version)
|
||||
|| typeof browser.driverVersion !== 'string' || browser.driverVersion.length < 2) throw new Error('Reference browser metadata is invalid.');
|
||||
const display = exactKeys(root.display, ['refreshHz'], 'Reference display');
|
||||
if (display.refreshHz !== 60) throw new Error('Reference display must be fixed at 60 Hz.');
|
||||
const viewport = exactKeys(root.viewport, ['width', 'height'], 'Reference viewport');
|
||||
if (viewport.width !== profile.viewport.width || viewport.height !== profile.viewport.height) throw new Error('Reference viewport does not match the pinned profile.');
|
||||
const network = exactKeys(root.network, ['downstreamKbps', 'upstreamKbps', 'roundTripLatencyMs'], 'Reference network');
|
||||
if (network.downstreamKbps !== profile.downstreamKbps || network.upstreamKbps !== profile.upstreamKbps || network.roundTripLatencyMs !== profile.roundTripLatencyMs) throw new Error('Reference network does not match the pinned profile.');
|
||||
const assertions = exactKeys(root.assertions, ['batteryPercent', 'powerSaving', 'coolStart', 'noOtherForegroundApplications', 'cpuEmulation', 'pageZoom', 'reducedMotion', 'saveData', 'audioState', 'freshBrowserProfile', 'startedFromAboutBlank', 'storageCleared', 'physicalReferenceDevice'], 'Reference assertions');
|
||||
const storage = exactKeys(assertions.storageCleared, ['serviceWorkers', 'cacheStorage', 'httpCache', 'cookies', 'localStorage', 'sessionStorage', 'indexedDb', 'preferences'], 'Reference storage assertions');
|
||||
if (typeof assertions.batteryPercent !== 'number' || assertions.batteryPercent <= 50 || assertions.batteryPercent > 100
|
||||
|| assertions.powerSaving !== false || assertions.coolStart !== true || assertions.noOtherForegroundApplications !== true
|
||||
|| assertions.cpuEmulation !== false || assertions.pageZoom !== 1 || assertions.reducedMotion !== 'no-preference'
|
||||
|| assertions.saveData !== false || assertions.audioState !== 'idle' || assertions.freshBrowserProfile !== true
|
||||
|| assertions.startedFromAboutBlank !== true || assertions.physicalReferenceDevice !== true
|
||||
|| Object.values(storage).some((value) => value !== true)) throw new Error('Reference environment assertions are not all satisfied.');
|
||||
return {
|
||||
profile: input.expectedProfile,
|
||||
runId: root.runId,
|
||||
runIndex: Number(root.runIndex),
|
||||
attestationDigest: actualDigest,
|
||||
browserVersion: browser.version,
|
||||
viewport: profile.viewport,
|
||||
};
|
||||
};
|
||||
|
||||
export const loadAuthenticatedReferenceRun = async (profile: ReferenceProfile): Promise<AuthenticatedReferenceRun | null> => {
|
||||
if (process.env.PORTFOLIO_REFERENCE_LAB !== '1') return null;
|
||||
const path = process.env.PORTFOLIO_REFERENCE_ATTESTATION_PATH;
|
||||
const digest = process.env.PORTFOLIO_REFERENCE_ATTESTATION_SHA256;
|
||||
if (path === undefined || digest === undefined) throw new Error('Reference mode requires an attestation path and SHA-256 digest.');
|
||||
return authenticateReferenceRun({ referenceMode: true, expectedProfile: profile, attestationBytes: await readFile(path), expectedDigest: digest });
|
||||
};
|
||||
|
||||
export const validateObservedReferenceEnvironment = (reference: AuthenticatedReferenceRun, observed: ObservedEnvironment): void => {
|
||||
if (observed.viewport.width !== reference.viewport.width || observed.viewport.height !== reference.viewport.height) throw new Error('Observed viewport does not match the attestation.');
|
||||
if (!observed.visible || observed.reducedMotion !== 'no-preference' || observed.saveData || observed.pageZoom !== 1 || !observed.startedFromAboutBlank) throw new Error('Observed reference environment assertions failed.');
|
||||
if (observed.browserName !== 'Chromium' || observed.browserVersion !== reference.browserVersion) throw new Error('Observed browser does not match the attestation.');
|
||||
};
|
||||
Reference in New Issue
Block a user