69 lines
2.3 KiB
JavaScript
69 lines
2.3 KiB
JavaScript
// Environment fingerprint capture for GEP assets.
|
|
// Records the runtime environment so that cross-environment diffusion
|
|
// success rates (GDI) can be measured scientifically.
|
|
|
|
const os = require('os');
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
const crypto = require('crypto');
|
|
const { getRepoRoot } = require('./paths');
|
|
const { getDeviceId, isContainer } = require('./deviceId');
|
|
|
|
// Capture a structured environment fingerprint.
|
|
// This is embedded into Capsules, EvolutionEvents, and ValidationReports.
|
|
function captureEnvFingerprint() {
|
|
const repoRoot = getRepoRoot();
|
|
let pkgVersion = null;
|
|
let pkgName = null;
|
|
try {
|
|
const raw = fs.readFileSync(path.join(repoRoot, 'package.json'), 'utf8');
|
|
const pkg = JSON.parse(raw);
|
|
pkgVersion = pkg && pkg.version ? String(pkg.version) : null;
|
|
pkgName = pkg && pkg.name ? String(pkg.name) : null;
|
|
} catch (e) {}
|
|
|
|
const region = (process.env.EVOLVER_REGION || '').trim().toLowerCase().slice(0, 5) || undefined;
|
|
|
|
return {
|
|
device_id: getDeviceId(),
|
|
node_version: process.version,
|
|
platform: process.platform,
|
|
arch: process.arch,
|
|
os_release: os.release(),
|
|
hostname: crypto.createHash('sha256').update(os.hostname()).digest('hex').slice(0, 12),
|
|
evolver_version: pkgVersion,
|
|
client: pkgName || 'evolver',
|
|
client_version: pkgVersion,
|
|
region: region,
|
|
cwd: crypto.createHash('sha256').update(process.cwd()).digest('hex').slice(0, 12),
|
|
container: isContainer(),
|
|
};
|
|
}
|
|
|
|
// Compute a short fingerprint key for comparison and grouping.
|
|
// Two nodes with the same key are considered "same environment class".
|
|
function envFingerprintKey(fp) {
|
|
if (!fp || typeof fp !== 'object') return 'unknown';
|
|
const parts = [
|
|
fp.device_id || '',
|
|
fp.node_version || '',
|
|
fp.platform || '',
|
|
fp.arch || '',
|
|
fp.hostname || '',
|
|
fp.client || fp.evolver_version || '',
|
|
fp.client_version || fp.evolver_version || '',
|
|
].join('|');
|
|
return crypto.createHash('sha256').update(parts, 'utf8').digest('hex').slice(0, 16);
|
|
}
|
|
|
|
// Check if two fingerprints are from the same environment class.
|
|
function isSameEnvClass(fpA, fpB) {
|
|
return envFingerprintKey(fpA) === envFingerprintKey(fpB);
|
|
}
|
|
|
|
module.exports = {
|
|
captureEnvFingerprint,
|
|
envFingerprintKey,
|
|
isSameEnvClass,
|
|
};
|