Documentation Index
Fetch the complete documentation index at: https://mintlify.com/EvoMap/evolver/llms.txt
Use this file to discover all available pages before exploring further.
Overview
Evolver executes validation commands specified in Gene definitions to verify evolution correctness. To prevent arbitrary command execution, all validation commands are gated by safety checks.
Location: src/gep/solidify.js:569-601
Safety Checks
1. Prefix Whitelist
Only commands starting with node, npm, or npx are allowed:
const VALIDATION_ALLOWED_PREFIXES = ['node ', 'npm ', 'npx '];
if (!VALIDATION_ALLOWED_PREFIXES.some(p => c.startsWith(p))) return false;
Rejected:
bash script.sh # ❌ Not in whitelist
python test.py # ❌ Not in whitelist
sh -c "npm test" # ❌ Not in whitelist
Allowed:
node test.js # ✅
npm test # ✅
npx jest # ✅
2. No Command Substitution
Backticks and $(...) are rejected anywhere in the command string:
if (/`|\$\(/.test(c)) return false;
Rejected:
node -e "$(cat /etc/passwd)" # ❌ Command substitution
npm run `malicious` # ❌ Backticks
node test.js --arg=$(whoami) # ❌ Command substitution
3. No Shell Operators
After stripping quoted content, ;, &, |, >, < are rejected:
const stripped = c.replace(/"[^"]*"/g, '').replace(/'[^']*'/g, '');
if (/[;&|><]/.test(stripped)) return false;
Rejected:
npm test && rm -rf / # ❌ Contains &&
node test.js | grep error # ❌ Contains |
node test.js > /tmp/out.txt # ❌ Contains >
npm test; echo "done" # ❌ Contains ;
Allowed (operators inside quotes):
node -e 'console.log("a && b")' # ✅ && is quoted
npm test -- --grep "a|b" # ✅ | is quoted
4. No Eval Patterns
Direct node -e / node --eval is blocked to prevent arbitrary code execution:
if (/^node\s+(-e|--eval|--print|-p)\b/.test(c)) return false;
Rejected:
node -e "process.exit(1)" # ❌ Eval pattern
node --eval "require('fs')" # ❌ Eval pattern
node -p "1+1" # ❌ Print pattern
5. Timeout
Each validation command is limited to 180 seconds (3 minutes):
const r = tryRunCmd(c, { cwd: repoRoot, timeoutMs: 180000 });
Location: src/gep/solidify.js:596
6. Scoped Execution
Commands run with cwd set to the repository root, preventing path traversal:
function runValidations(gene, opts = {}) {
const repoRoot = opts.repoRoot || getRepoRoot();
// ...
const r = tryRunCmd(c, { cwd: repoRoot, timeoutMs });
}
Location: src/gep/solidify.js:583-601
Implementation
isValidationCommandAllowed
// src/gep/solidify.js:569-581
const VALIDATION_ALLOWED_PREFIXES = ['node ', 'npm ', 'npx '];
function isValidationCommandAllowed(cmd) {
const c = String(cmd || '').trim();
if (!c) return false;
// 1. Prefix whitelist
if (!VALIDATION_ALLOWED_PREFIXES.some(p => c.startsWith(p))) return false;
// 2. No command substitution
if (/`|\$\(/.test(c)) return false;
// 3. No shell operators (after stripping quotes)
const stripped = c.replace(/"[^"]*"/g, '').replace(/'[^']*'/g, '');
if (/[;&|><]/.test(stripped)) return false;
// 4. Block eval-like patterns
if (/^node\s+(-e|--eval|--print|-p)\b/.test(c)) return false;
return true;
}
runValidations
// src/gep/solidify.js:583-601
function runValidations(gene, opts = {}) {
const repoRoot = opts.repoRoot || getRepoRoot();
const timeoutMs = Number.isFinite(Number(opts.timeoutMs)) ? Number(opts.timeoutMs) : 180000;
const validation = Array.isArray(gene && gene.validation) ? gene.validation : [];
const results = [];
const startedAt = Date.now();
for (const cmd of validation) {
const c = String(cmd || '').trim();
if (!c) continue;
// Safety check
if (!isValidationCommandAllowed(c)) {
results.push({
cmd: c,
ok: false,
out: '',
err: 'BLOCKED: validation command rejected by safety check (allowed prefixes: node/npm/npx; shell operators prohibited)'
});
return { ok: false, results, startedAt, finishedAt: Date.now() };
}
// Execute
const r = tryRunCmd(c, { cwd: repoRoot, timeoutMs });
results.push({ cmd: c, ok: r.ok, out: String(r.out || ''), err: String(r.err || '') });
// Fail fast
if (!r.ok) return { ok: false, results, startedAt, finishedAt: Date.now() };
}
return { ok: true, results, startedAt, finishedAt: Date.now() };
}
Gene Validation Examples
Safe Gene
{
"type": "Gene",
"id": "gene_safe_validation",
"category": "repair",
"validation": [
"node scripts/validate-modules.js ./src",
"npm test",
"npx eslint src/"
]
}
Unsafe Gene (Rejected)
{
"type": "Gene",
"id": "gene_unsafe_validation",
"category": "repair",
"validation": [
"bash scripts/deploy.sh", // ❌ Not node/npm/npx
"npm test && rm -rf /" // ❌ Shell operator &&
]
}
Result: Solidify fails with violation:
constraint: validation_failed: bash scripts/deploy.sh => BLOCKED: validation command rejected by safety check
When promoting external Genes via scripts/a2a_promote.js, all validation commands are audited before promotion:
// Pseudo-code from a2a_promote.js
for (const cmd of gene.validation) {
if (!isValidationCommandAllowed(cmd)) {
console.error(`Unsafe validation command: ${cmd}`);
process.exit(1);
}
}
Location: README.md:214-216
Bypass Attempts
Attempt 1: Shell Escape via Arguments
node test.js "--arg='; rm -rf /'"
Blocked: The ; is outside quotes after stripping, detected by step 3.
Attempt 2: Pipe via Unquoted Args
node test.js | grep error
Blocked: | detected by step 3.
Attempt 3: Command Substitution in Args
node test.js --file=$(cat /etc/passwd)
Blocked: $( detected by step 2.
Attempt 4: Eval Injection
node -e "require('child_process').execSync('rm -rf /')"
Blocked: node -e detected by step 4.
Custom Validation Scripts
If you need custom validation logic, wrap it in a Node.js script:
Bad (Shell Script)
# scripts/custom-check.sh
#!/bin/bash
if [ -f "required.txt" ]; then
echo "OK"
else
exit 1
fi
Gene:
{
"validation": [
"bash scripts/custom-check.sh" // ❌ Rejected
]
}
Good (Node.js Script)
// scripts/custom-check.js
const fs = require('fs');
if (!fs.existsSync('required.txt')) {
console.error('Missing required.txt');
process.exit(1);
}
console.log('OK');
Gene:
{
"validation": [
"node scripts/custom-check.js" // ✅ Allowed
]
}
Validation Report
Validation results are recorded in a machine-readable ValidationReport:
{
"type": "ValidationReport",
"id": "vr_1234567890",
"gene_id": "gene_repair_001",
"commands": [
"npm test",
"node scripts/validate.js"
],
"results": [
{ "cmd": "npm test", "ok": true, "duration_ms": 3200 },
{ "cmd": "node scripts/validate.js", "ok": true, "duration_ms": 450 }
],
"env_fingerprint": { "platform": "linux", "node_version": "v18.16.0" },
"started_at": "2024-01-15T10:30:00.000Z",
"finished_at": "2024-01-15T10:30:03.650Z"
}
Location: src/gep/solidify.js:1133-1140
Timeout Handling
If a validation command exceeds 180 seconds, it is killed:
tryRunCmd(cmd, { cwd: repoRoot, timeoutMs: 180000 });
Result:
{
"cmd": "npm run slow-test",
"ok": false,
"err": "Command timed out after 180000ms"
}
Best Practices
-
Use npm scripts: Define complex validation in
package.json scripts:
{
"scripts": {
"validate": "eslint src/ && jest --coverage"
}
}
Then:
{ "validation": ["npm run validate"] }
-
Keep validations fast: Target < 60 seconds for responsiveness
-
Fail fast: If a critical check fails early, don’t waste time on subsequent checks
-
No side effects: Validation commands should be read-only (no writes, no deployments)
-
Explicit exit codes: Ensure scripts exit with code 0 (success) or non-zero (failure)
Troubleshooting
Validation command blocked
Symptom: Solidify fails with “BLOCKED: validation command rejected by safety check”.
Cause: Command contains shell operators or non-whitelisted prefix.
Solution: Rewrite command using Node.js:
# Before (blocked)
bash scripts/check.sh && npm test
# After (allowed)
node scripts/check.js
npm test
Validation timeout
Symptom: Validation hangs for 3 minutes then fails.
Cause: Command is too slow or stuck.
Solution: Optimize or split into smaller checks:
# Slow
npm run full-integration-test # Takes 5 minutes
# Fast
npm run unit-test # Takes 30 seconds
Symptom: a2a_promote.js rejects gene with unsafe validation command.
Cause: Gene contains shell scripts or dangerous commands.
Solution: Contact asset author to fix validation commands, or fork and fix locally.