Overview
The asset store manages all evolution artifacts: Genes, Capsules, EvolutionEvents, candidates, and failed capsules. It provides read/write functions with atomic operations and schema validation.
Location: src/gep/assetStore.js
Core Functions
loadGenes()
Load all genes from storage.
Location: src/gep/assetStore.js:87
Array of Gene objects (deduplicated by ID)
Storage Format:
- JSON:
assets/gep/genes.json (structured gene list)
- JSONL:
assets/gep/genes.jsonl (append-only, takes precedence)
Example:
const { loadGenes } = require('./gep/assetStore');
const genes = loadGenes();
console.log('Loaded genes:', genes.length);
// Output: Loaded genes: 12
loadCapsules()
Load all capsules from storage.
Location: src/gep/assetStore.js:114
Array of Capsule objects (deduplicated by ID)
Storage Format:
- JSON:
assets/gep/capsules.json (legacy)
- JSONL:
assets/gep/capsules.jsonl (append-only, preferred)
readAllEvents()
Read all evolution events.
Location: src/gep/assetStore.js:150
Array of EvolutionEvent objects
Storage Format: assets/gep/events.jsonl (append-only)
getLastEventId()
Get the ID of the most recent event.
Location: src/gep/assetStore.js:138
function getLastEventId()
Last event ID (e.g., evt_1678901234567)
appendEventJsonl()
Append a new event to the event log.
Location: src/gep/assetStore.js:161
function appendEventJsonl(eventObj)
EvolutionEvent object to append
Example:
const { appendEventJsonl } = require('./gep/assetStore');
const event = {
type: 'EvolutionEvent',
schema_version: 3,
id: 'evt_' + Date.now(),
intent: 'repair',
signals: ['log_error'],
genes_used: ['gene_gep_repair'],
outcome: { status: 'success', score: 0.85 },
// ...
};
appendEventJsonl(event);
appendCandidateJsonl()
Append a capability candidate.
Location: src/gep/assetStore.js:166
function appendCandidateJsonl(candidateObj)
Candidate object (Gene or Capsule)
readRecentCandidates()
Read recent candidates from the log.
Location: src/gep/assetStore.js:176
function readRecentCandidates(limit = 20)
Maximum number of candidates to return
Array of candidate objects (most recent first)
upsertGene()
Create or update a gene.
Location: src/gep/assetStore.js:208
function upsertGene(geneObj)
Gene object to create/update
Atomic Write: Uses temporary file + rename for crash safety.
Example:
const { upsertGene, computeAssetId } = require('./gep/assetStore');
const gene = {
type: 'Gene',
schema_version: 3,
id: 'gene_custom_repair',
category: 'repair',
signals_match: ['custom_error'],
preconditions: ['signals contains custom_error'],
strategy: ['Analyze custom error', 'Apply targeted fix'],
constraints: { max_files: 5, forbidden_paths: ['.git'] },
validation: ['node scripts/validate.js'],
};
gene.asset_id = computeAssetId(gene);
upsertGene(gene);
upsertCapsule()
Create or update a capsule.
Location: src/gep/assetStore.js:225
function upsertCapsule(capsuleObj)
Capsule object to create/update
appendFailedCapsule()
Record a failed capsule for learning.
Location: src/gep/assetStore.js:240
function appendFailedCapsule(capsuleObj)
Automatic Trimming:
Location: src/gep/assetStore.js:235
const FAILED_CAPSULES_MAX = 200;
const FAILED_CAPSULES_TRIM_TO = 100;
if (list.length > FAILED_CAPSULES_MAX) {
list = list.slice(list.length - FAILED_CAPSULES_TRIM_TO);
}
readRecentFailedCapsules()
Read recent failed capsules.
Location: src/gep/assetStore.js:252
function readRecentFailedCapsules(limit = 50)
Maximum number of failed capsules to return
Array of failed Capsule objects (most recent first)
ensureAssetFiles()
Ensure all expected asset files exist.
Location: src/gep/assetStore.js:266
function ensureAssetFiles()
Purpose: Create empty files for optional append-only stores so external tools (grep, cat) never fail with “No such file or directory”.
Created Files:
assets/gep/genes.json
assets/gep/capsules.json
assets/gep/genes.jsonl
assets/gep/events.jsonl
assets/gep/candidates.jsonl
assets/gep/failed_capsules.json
Schema Validation
Location: src/gep/assetStore.js:201
function ensureSchemaFields(obj) {
if (!obj || typeof obj !== 'object') return obj;
if (!obj.schema_version) obj.schema_version = SCHEMA_VERSION;
if (!obj.asset_id) {
try {
obj.asset_id = computeAssetId(obj);
} catch (e) {}
}
return obj;
}
All write functions automatically call ensureSchemaFields() before persisting.
Default Genes
Location: src/gep/assetStore.js:37
function getDefaultGenes() {
return {
version: 1,
genes: [
{
type: 'Gene',
id: 'gene_gep_repair_from_errors',
category: 'repair',
signals_match: ['error', 'exception', 'failed', 'unstable'],
preconditions: ['signals contains error-related indicators'],
strategy: [
'Extract structured signals from logs',
'Select existing Gene by signals match',
'Estimate blast radius before editing',
'Apply smallest reversible patch',
'Validate using declared validation steps',
'Solidify: append EvolutionEvent, update Gene/Capsule store',
],
constraints: {
max_files: 12,
forbidden_paths: ['.git', 'node_modules'],
},
validation: [
buildValidationCmd(['src/evolve', 'src/gep/solidify']),
buildValidationCmd(['src/gep/selector', 'src/gep/memoryGraph']),
],
},
// ...
],
};
}
Validation Command Builder
Location: src/gep/assetStore.js:29
function buildValidationCmd(relModules) {
const paths = relModules.map(m => `./${m}`);
return `node scripts/validate-modules.js ${paths.join(' ')}`;
}
Purpose: Build validation commands using repo-root-relative paths (works correctly when executed with cwd=repoRoot).
File Paths
Location: src/gep/assetStore.js:79
function genesPath() {
return path.join(getGepAssetsDir(), 'genes.json');
}
function capsulesPath() {
return path.join(getGepAssetsDir(), 'capsules.json');
}
function capsulesJsonlPath() {
return path.join(getGepAssetsDir(), 'capsules.jsonl');
}
function eventsPath() {
return path.join(getGepAssetsDir(), 'events.jsonl');
}
function candidatesPath() {
return path.join(getGepAssetsDir(), 'candidates.jsonl');
}
function externalCandidatesPath() {
return path.join(getGepAssetsDir(), 'external_candidates.jsonl');
}
function failedCapsulesPath() {
return path.join(getGepAssetsDir(), 'failed_capsules.json');
}
Complete Example
const assetStore = require('./gep/assetStore');
const { computeAssetId, SCHEMA_VERSION } = require('./gep/contentHash');
// Ensure asset files exist
assetStore.ensureAssetFiles();
// Load genes and capsules
const genes = assetStore.loadGenes();
const capsules = assetStore.loadCapsules();
console.log('Loaded:', genes.length, 'genes,', capsules.length, 'capsules');
// Create a new gene
const newGene = {
type: 'Gene',
schema_version: SCHEMA_VERSION,
id: 'gene_custom_' + Date.now(),
category: 'optimize',
signals_match: ['perf_bottleneck'],
strategy: ['Profile performance', 'Apply optimization'],
constraints: { max_files: 8 },
validation: ['node scripts/validate.js'],
};
newGene.asset_id = computeAssetId(newGene);
assetStore.upsertGene(newGene);
// Append an event
const event = {
type: 'EvolutionEvent',
schema_version: SCHEMA_VERSION,
id: 'evt_' + Date.now(),
intent: 'optimize',
signals: ['perf_bottleneck'],
genes_used: [newGene.id],
outcome: { status: 'success', score: 0.75 },
blast_radius: { files: 3, lines: 45 },
};
event.asset_id = computeAssetId(event);
assetStore.appendEventJsonl(event);
// Read recent events
const recentEvents = assetStore.readAllEvents().slice(-10);
console.log('Recent events:', recentEvents.length);
// Get last event ID
const lastId = assetStore.getLastEventId();
console.log('Last event ID:', lastId);