From 85f2b46d1ef98f4368a3a171867696ac83446186 Mon Sep 17 00:00:00 2001 From: Yewlne Date: Fri, 20 Feb 2026 20:12:36 +0800 Subject: [PATCH] fix: hash hostname in fingerprint, use relative validation paths, remove dead code Three independent improvements: 1. Hash hostname before storing in envFingerprint (envFingerprint.js) os.hostname() was stored verbatim in every Capsule and EvolutionEvent, which are published to the public Hub. sanitize.js does not redact hostnames (no matching pattern), so strings like 'john-macbook-pro.local' leaked into the public feed. Replace with a 12-char SHA-256 prefix so the value still uniquely identifies the environment class without revealing the machine name. 2. Remove absolute paths from buildValidationCmd (assetStore.js) The previous implementation resolved modules via path.resolve(__dirname) at call time, embedding the current machine's absolute path (e.g. /Users/xxx/codespace/evolver/src/evolve) into Gene validation commands stored in genes.json. Two consequences: - sanitize.js redacts /Users/... in published capsules, corrupting the stored validation command for any consumer. - Moving the project directory breaks all previously stored Gene validation commands. runValidations() already executes with cwd=repoRoot, so switching to require('./src/evolve') style relative paths is correct and portable. 3. Remove appendCapsule dead code (assetStore.js, solidify.js) appendCapsule was exported and imported by solidify.js but never called (solidify uses upsertCapsule exclusively). It also lacked deduplication, so any accidental call would grow capsules.json unboundedly. Removed the function, its export, and the unused import in solidify.js. Co-Authored-By: Claude Sonnet 4.6 --- src/gep/assetStore.js | 21 +++++---------------- src/gep/envFingerprint.js | 2 +- src/gep/solidify.js | 2 +- 3 files changed, 7 insertions(+), 18 deletions(-) diff --git a/src/gep/assetStore.js b/src/gep/assetStore.js index 9824902a..5a5ec4a7 100644 --- a/src/gep/assetStore.js +++ b/src/gep/assetStore.js @@ -26,14 +26,11 @@ function writeJsonAtomic(filePath, obj) { fs.renameSync(tmp, filePath); } -// Build a robust validation command that works regardless of CWD. -// Resolves module paths relative to the skill root (skills/evolver/). +// Build a validation command using repo-root-relative paths. +// runValidations() executes with cwd=repoRoot, so require('./src/...') +// resolves correctly without embedding machine-specific absolute paths. function buildValidationCmd(relModules) { - const skillRoot = path.resolve(__dirname, '..', '..'); - const checks = relModules.map(m => { - const abs = path.join(skillRoot, m).replace(/\\/g, '/'); - return `require('${abs}')`; - }); + const checks = relModules.map(m => `require('./${m}')`); return `node -e "${checks.join('; ')}; console.log('ok')"`; } @@ -216,14 +213,6 @@ function upsertGene(geneObj) { writeJsonAtomic(genesPath(), { version: current.version || 1, genes }); } -function appendCapsule(capsuleObj) { - ensureSchemaFields(capsuleObj); - const current = readJsonIfExists(capsulesPath(), getDefaultCapsules()); - const capsules = Array.isArray(current.capsules) ? current.capsules : []; - capsules.push(capsuleObj); - writeJsonAtomic(capsulesPath(), { version: current.version || 1, capsules }); -} - function upsertCapsule(capsuleObj) { if (!capsuleObj || capsuleObj.type !== 'Capsule' || !capsuleObj.id) return; ensureSchemaFields(capsuleObj); @@ -263,7 +252,7 @@ module.exports = { loadGenes, loadCapsules, readAllEvents, getLastEventId, appendEventJsonl, appendCandidateJsonl, appendExternalCandidateJsonl, readRecentCandidates, readRecentExternalCandidates, - upsertGene, appendCapsule, upsertCapsule, + upsertGene, upsertCapsule, genesPath, capsulesPath, eventsPath, candidatesPath, externalCandidatesPath, ensureAssetFiles, buildValidationCmd, }; diff --git a/src/gep/envFingerprint.js b/src/gep/envFingerprint.js index 033188c5..55000f01 100644 --- a/src/gep/envFingerprint.js +++ b/src/gep/envFingerprint.js @@ -26,7 +26,7 @@ function captureEnvFingerprint() { platform: process.platform, arch: process.arch, os_release: os.release(), - hostname: os.hostname(), + hostname: crypto.createHash('sha256').update(os.hostname()).digest('hex').slice(0, 12), evolver_version: pkgVersion, cwd: process.cwd(), container: isContainer(), diff --git a/src/gep/solidify.js b/src/gep/solidify.js index aba153fe..b09f65f9 100644 --- a/src/gep/solidify.js +++ b/src/gep/solidify.js @@ -1,7 +1,7 @@ const fs = require('fs'); const path = require('path'); const { execSync } = require('child_process'); -const { loadGenes, upsertGene, appendEventJsonl, appendCapsule, upsertCapsule, getLastEventId } = require('./assetStore'); +const { loadGenes, upsertGene, appendEventJsonl, upsertCapsule, getLastEventId } = require('./assetStore'); const { computeSignalKey, memoryGraphPath } = require('./memoryGraph'); const { computeCapsuleSuccessStreak, isBlastRadiusSafe } = require('./a2a'); const { getRepoRoot, getMemoryDir, getEvolutionDir, getWorkspaceRoot } = require('./paths');