@evomap/evolver 1.92.0 → 1.94.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/CONTRIBUTING.md +12 -0
  2. package/README.ja-JP.md +1 -1
  3. package/README.ko-KR.md +1 -1
  4. package/README.md +17 -9
  5. package/README.zh-CN.md +1 -1
  6. package/SKILL.md +8 -8
  7. package/assets/gep/genes.seed.json +312 -0
  8. package/assets/logo.png +0 -0
  9. package/cli-options.js +73 -0
  10. package/index.js +30 -0
  11. package/package.json +2 -1
  12. package/scripts/harness-governance-check.js +147 -0
  13. package/src/adapters/scripts/_runtimePaths.js +10 -1
  14. package/src/adapters/scripts/evolver-session-end.js +10 -1
  15. package/src/evolve/guards.js +1 -1
  16. package/src/evolve/pipeline/collect.js +1 -1
  17. package/src/evolve/pipeline/dispatch.js +1 -1
  18. package/src/evolve/pipeline/enrich.js +1 -1
  19. package/src/evolve/pipeline/hub.js +1 -1
  20. package/src/evolve/pipeline/select.js +1 -1
  21. package/src/evolve/pipeline/signals.js +1 -1
  22. package/src/evolve/utils.js +1 -1
  23. package/src/evolve.js +1 -1
  24. package/src/experiment/triggerShift.js +132 -0
  25. package/src/gep/a2aProtocol.js +1 -1
  26. package/src/gep/antiAbuseTelemetry.js +1 -1
  27. package/src/gep/assetStore.js +67 -9
  28. package/src/gep/autoDistillConv.js +1 -1
  29. package/src/gep/autoDistillLlm.js +1 -1
  30. package/src/gep/candidateEval.js +1 -1
  31. package/src/gep/candidates.js +1 -1
  32. package/src/gep/contentHash.js +1 -1
  33. package/src/gep/contextRoutingGene.js +1 -0
  34. package/src/gep/conversationDistiller.js +1 -1
  35. package/src/gep/conversationSniffer.js +1 -1
  36. package/src/gep/crypto.js +1 -1
  37. package/src/gep/curriculum.js +1 -1
  38. package/src/gep/deviceId.js +1 -1
  39. package/src/gep/envFingerprint.js +1 -1
  40. package/src/gep/epigenetics.js +1 -1
  41. package/src/gep/execBridge.js +1 -1
  42. package/src/gep/explore.js +1 -1
  43. package/src/gep/feedbackEnvelope.js +1 -0
  44. package/src/gep/hash.js +1 -1
  45. package/src/gep/hubFetch.js +1 -1
  46. package/src/gep/hubReview.js +1 -1
  47. package/src/gep/hubSearch.js +1 -1
  48. package/src/gep/hubVerify.js +1 -1
  49. package/src/gep/learningSignals.js +1 -1
  50. package/src/gep/memoryGraph.js +1 -1
  51. package/src/gep/memoryGraphAdapter.js +1 -1
  52. package/src/gep/mutation.js +1 -1
  53. package/src/gep/narrativeMemory.js +1 -1
  54. package/src/gep/openPRRegistry.js +1 -1
  55. package/src/gep/personality.js +1 -1
  56. package/src/gep/policyCheck.js +1 -1
  57. package/src/gep/prompt.js +1 -1
  58. package/src/gep/recallInject.js +1 -1
  59. package/src/gep/recallVerifier.js +1 -1
  60. package/src/gep/reflection.js +1 -1
  61. package/src/gep/savingsCore.js +1 -1
  62. package/src/gep/selector.js +1 -1
  63. package/src/gep/signals.js +35 -0
  64. package/src/gep/skillDistiller.js +1 -1
  65. package/src/gep/solidify.js +1 -1
  66. package/src/gep/strategy.js +1 -1
  67. package/src/gep/syncAsset.js +1 -1
  68. package/src/gep/tokenSavings.js +1 -1
  69. package/src/gep/trajectoryExport.js +1 -1
  70. package/src/gep/validator/sandboxExecutor.js +28 -1
  71. package/src/gep/workspaceKeychain.js +1 -1
  72. package/src/proxy/extensions/traceControl.js +1 -1
  73. package/src/proxy/index.js +66 -6
  74. package/src/proxy/inject.js +1 -1
  75. package/src/proxy/server/settings.js +6 -0
  76. package/src/proxy/trace/extractor.js +1 -1
  77. package/src/proxy/trace/usage.js +1 -1
  78. package/assets/cover.png +0 -0
@@ -0,0 +1,147 @@
1
+ #!/usr/bin/env node
2
+ 'use strict';
3
+
4
+ const fs = require('fs');
5
+
6
+ const SENSITIVE_PATH_RE = /^(CONTRIBUTING\.md|\.github\/pull_request_template\.md|\.github\/workflows\/test\.yml|scripts\/harness-governance-check\.js|test\/harnessGovernanceCheck\.test\.js|src\/evolve\.js|src\/evolve\/|src\/adapters\/|src\/experiment\/|src\/gep\/|src\/proxy\/(router|trace)\/|src\/proxy\/inject\.js|assets\/gep\/)/;
7
+
8
+ function parseArgs(argv) {
9
+ const out = {};
10
+ for (let i = 2; i < argv.length; i += 1) {
11
+ const arg = argv[i];
12
+ if (arg === '--body') out.bodyFile = argv[++i];
13
+ else if (arg === '--changed') out.changedFile = argv[++i];
14
+ else if (arg === '--event') out.eventFile = argv[++i];
15
+ else if (arg === '--help' || arg === '-h') out.help = true;
16
+ else throw new Error('unknown argument: ' + arg);
17
+ }
18
+ return out;
19
+ }
20
+
21
+ function stripHtmlComments(text) {
22
+ return String(text || '').replace(/<!--[\s\S]*?-->/g, '');
23
+ }
24
+
25
+ function readStdin() {
26
+ try {
27
+ return fs.readFileSync(0, 'utf8');
28
+ } catch (_) {
29
+ return '';
30
+ }
31
+ }
32
+
33
+ function readBody(opts) {
34
+ if (opts.bodyFile) return fs.readFileSync(opts.bodyFile, 'utf8');
35
+ if (opts.eventFile) {
36
+ const event = JSON.parse(fs.readFileSync(opts.eventFile, 'utf8'));
37
+ return String(event && event.pull_request && event.pull_request.body || '');
38
+ }
39
+ if (process.env.PR_BODY_FILE) return fs.readFileSync(process.env.PR_BODY_FILE, 'utf8');
40
+ if (process.env.PR_BODY) return String(process.env.PR_BODY);
41
+ return readStdin();
42
+ }
43
+
44
+ function readChangedFiles(opts) {
45
+ let raw = '';
46
+ if (opts.changedFile) raw = fs.readFileSync(opts.changedFile, 'utf8');
47
+ else if (process.env.PR_CHANGED_FILES_FILE) raw = fs.readFileSync(process.env.PR_CHANGED_FILES_FILE, 'utf8');
48
+ else if (process.env.PR_CHANGED_FILES) raw = String(process.env.PR_CHANGED_FILES);
49
+ return raw.split(/\r?\n/).map(s => s.trim()).filter(Boolean).map(s => s.replace(/\\/g, '/'));
50
+ }
51
+
52
+ function changedFilesTouchGovernanceSurface(files) {
53
+ return files.some(f => SENSITIVE_PATH_RE.test(f));
54
+ }
55
+
56
+ function lineValue(body, label) {
57
+ const escaped = label.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
58
+ const match = body.match(new RegExp('^' + escaped + ':\\s*(.*)$', 'im'));
59
+ return match ? match[1].trim() : null;
60
+ }
61
+
62
+ function isSubstantiveValue(value) {
63
+ if (!value) return false;
64
+ const normalized = value.trim();
65
+ if (!normalized) return false;
66
+ if (/[<>]/.test(normalized)) return false;
67
+ if (/^n\/?a\.?(?:$|[\s:;,.\-–—])/i.test(normalized)) return false;
68
+ return true;
69
+ }
70
+
71
+ function valueMatches(body, label, valuePattern) {
72
+ const value = lineValue(body, label);
73
+ return isSubstantiveValue(value) && valuePattern.test(value);
74
+ }
75
+
76
+ function validateGovernancePacket(body, changedFiles) {
77
+ const stripped = stripHtmlComments(body);
78
+ const errors = [];
79
+ if (!changedFilesTouchGovernanceSurface(changedFiles)) return errors;
80
+
81
+ if (!/^##+\s+Harness\/evaluator governance/im.test(stripped)) {
82
+ errors.push('missing ## Harness/evaluator governance — add the PR-template section from CONTRIBUTING.md');
83
+ }
84
+
85
+ const requiredValues = [
86
+ ['Upstream governance surface', /\S/, 'name the Evolver harness/evaluator surface; template placeholders and bare N/A are not accepted for sensitive diffs'],
87
+ ['Downstream EvoX impact', /\S/, 'state whether EvoX downstream behavior or contracts are affected; template placeholders and bare N/A are not accepted'],
88
+ ['Rollout-local scope', /\S/, 'state the proposal/shadow/cohort boundary before promotion'],
89
+ ['Promotion boundary', /\S/, 'state how rollout becomes default behavior'],
90
+ ['Evaluator mismatch sets', /\S/, 'cover observation/action/repair/verification/evidence/belief deltas or explain why each is not changed'],
91
+ ['Non-regression evidence', /\S/, 'link tests, shadow runs, replay, or doc-only rationale'],
92
+ ['Fix-severity review', /^(low|medium|high|critical)\b/i, 'classify the strongest fix severity'],
93
+ ['Owner approval', /\S/, 'name the owning module/reviewer requirement'],
94
+ ['Security boundary', /\S/, 'state data/tool/host/network/secrets impact'],
95
+ ['Rollback', /\S/, 'state how to disable/revert/quarantine'],
96
+ ['Live promotion', /^no$/i, "state exactly 'Live promotion: no'"],
97
+ ['Autonomous evaluator self-editing', /^no$/i, "state exactly 'Autonomous evaluator self-editing: no'"],
98
+ ];
99
+
100
+ for (const [label, pattern, hint] of requiredValues) {
101
+ if (!valueMatches(stripped, label, pattern)) {
102
+ errors.push('missing ' + label + ' — ' + hint);
103
+ }
104
+ }
105
+ return errors;
106
+ }
107
+
108
+ function main() {
109
+ const opts = parseArgs(process.argv);
110
+ if (opts.help) {
111
+ console.log('usage: node scripts/harness-governance-check.js [--body file | --event file] --changed file');
112
+ return 0;
113
+ }
114
+ const body = readBody(opts);
115
+ const changedFiles = readChangedFiles(opts);
116
+ const errors = validateGovernancePacket(body, changedFiles);
117
+ if (errors.length) {
118
+ console.error('Harness/evaluator governance gate FAILED.');
119
+ for (const err of errors) console.error('- ' + err);
120
+ console.error('Changed sensitive files:');
121
+ for (const f of changedFiles.filter(f => SENSITIVE_PATH_RE.test(f))) console.error('- ' + f);
122
+ return 1;
123
+ }
124
+ if (changedFilesTouchGovernanceSurface(changedFiles)) {
125
+ console.log('Harness/evaluator governance gate: PASSED');
126
+ } else {
127
+ console.log('Harness/evaluator governance gate: not applicable');
128
+ }
129
+ return 0;
130
+ }
131
+
132
+ if (require.main === module) {
133
+ try {
134
+ process.exitCode = main();
135
+ } catch (err) {
136
+ console.error('Harness/evaluator governance gate ERROR: ' + (err && err.message || err));
137
+ process.exitCode = 2;
138
+ }
139
+ }
140
+
141
+ module.exports = {
142
+ changedFilesTouchGovernanceSurface,
143
+ validateGovernancePacket,
144
+ stripHtmlComments,
145
+ isSubstantiveValue,
146
+ SENSITIVE_PATH_RE,
147
+ };
@@ -402,6 +402,15 @@ function findMemoryGraph(evolverRoot) {
402
402
  return path.join(userDir, 'memory_graph.jsonl');
403
403
  }
404
404
 
405
+ function gitExecutable() {
406
+ if (process.platform !== 'win32') {
407
+ const xcodeGit = '/Applications/Xcode.app/Contents/Developer/usr/libexec/git-core/git';
408
+ if (fs.existsSync(xcodeGit)) return xcodeGit;
409
+ if (fs.existsSync('/usr/bin/git')) return '/usr/bin/git';
410
+ }
411
+ return 'git';
412
+ }
413
+
405
414
  // Is `dir` inside a git work tree? Cheap, no-shell `git rev-parse`. Returns
406
415
  // false on any error (git missing, not a repo, timeout) and never throws.
407
416
  // The session-start hook uses this only to decide whether to surface a
@@ -409,7 +418,7 @@ function findMemoryGraph(evolverRoot) {
409
418
  // suppresses the notice rather than breaking anything.
410
419
  function isGitWorkspace(dir) {
411
420
  try {
412
- const res = spawnSync('git', ['rev-parse', '--is-inside-work-tree'], {
421
+ const res = spawnSync(gitExecutable(), ['rev-parse', '--is-inside-work-tree'], {
413
422
  cwd: dir,
414
423
  encoding: 'utf8',
415
424
  timeout: 5000,
@@ -24,12 +24,21 @@ const { findEvolverRoot, findMemoryGraph, resolveProjectDir, resolveWorkspaceId
24
24
  // consistent with the review-time reader in src/evolve/pipeline/collect.js
25
25
  // (Bugbot PR #109 round-1 MEDIUM; reader/writer drift flagged on PR #555).
26
26
 
27
+ function gitExecutable() {
28
+ if (process.platform !== 'win32') {
29
+ const xcodeGit = '/Applications/Xcode.app/Contents/Developer/usr/libexec/git-core/git';
30
+ if (fs.existsSync(xcodeGit)) return xcodeGit;
31
+ if (fs.existsSync('/usr/bin/git')) return '/usr/bin/git';
32
+ }
33
+ return 'git';
34
+ }
35
+
27
36
  function runGit(args, cwd) {
28
37
  // Argv-array form, no shell. Avoids POSIX `2>/dev/null` redirects that
29
38
  // break on Windows cmd.exe (#537). Failures (e.g. no HEAD~1 in a fresh
30
39
  // repo) are surfaced as a non-zero status; callers distinguish them
31
40
  // from successful empty output via the `ok` flag (PR #94 round-6 LOW).
32
- const res = spawnSync('git', args, {
41
+ const res = spawnSync(gitExecutable(), args, {
33
42
  cwd,
34
43
  encoding: 'utf8',
35
44
  timeout: 5000,