@evomap/evolver-core 2.0.0-beta.0 → 2.0.0-beta.2

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 (75) hide show
  1. package/assets/gep/genes.jsonl +5 -0
  2. package/dist/algo/candidateAssembly.js +17 -11
  3. package/dist/algo/capabilityCandidates.d.ts +2 -0
  4. package/dist/algo/capabilityCandidates.js +5 -0
  5. package/dist/algo/conversationSniffer.d.ts +18 -0
  6. package/dist/algo/conversationSniffer.js +132 -0
  7. package/dist/algo/cycleEngine.js +2 -0
  8. package/dist/algo/cycleFailureClassifier.js +13 -5
  9. package/dist/algo/geneIntake.d.ts +14 -4
  10. package/dist/algo/geneIntake.js +37 -9
  11. package/dist/algo/geneSelection.d.ts +6 -0
  12. package/dist/algo/geneSelection.js +19 -11
  13. package/dist/algo/index.d.ts +1 -0
  14. package/dist/algo/index.js +1 -0
  15. package/dist/assetstore/assetSyncLedger.d.ts +28 -0
  16. package/dist/assetstore/assetSyncLedger.js +86 -0
  17. package/dist/assetstore/index.d.ts +3 -1
  18. package/dist/assetstore/index.js +3 -1
  19. package/dist/assetstore/localJsonl.d.ts +9 -2
  20. package/dist/assetstore/localJsonl.js +75 -23
  21. package/dist/assetstore/pendingSignals.js +3 -1
  22. package/dist/assetstore/provenance.d.ts +7 -2
  23. package/dist/assetstore/provenance.js +85 -25
  24. package/dist/assetstore/reviewFilter.js +2 -1
  25. package/dist/assetstore/reviewLedger.d.ts +6 -0
  26. package/dist/assetstore/reviewLedger.js +9 -0
  27. package/dist/assetstore/seedGenes.d.ts +3 -0
  28. package/dist/assetstore/seedGenes.js +134 -0
  29. package/dist/benchmark/antiGeneBenchmark.d.ts +2 -0
  30. package/dist/benchmark/antiGeneBenchmark.js +11 -1
  31. package/dist/benchmark/antiGeneImpact.d.ts +16 -0
  32. package/dist/benchmark/antiGeneImpact.js +34 -0
  33. package/dist/benchmark/antiGeneRollout.d.ts +2 -0
  34. package/dist/benchmark/antiGeneRollout.js +13 -1
  35. package/dist/events/eventArchive.d.ts +65 -0
  36. package/dist/events/eventArchive.js +343 -0
  37. package/dist/events/eventStore.js +2 -12
  38. package/dist/events/public.d.ts +3 -1
  39. package/dist/events/public.js +2 -1
  40. package/dist/events/retention.d.ts +24 -1
  41. package/dist/events/retention.js +133 -37
  42. package/dist/exec/autoExec.js +3 -0
  43. package/dist/exec/claudeBridge.js +23 -0
  44. package/dist/exec/runnerRegistry.d.ts +8 -6
  45. package/dist/exec/runnerRegistry.js +71 -18
  46. package/dist/exec/selfPrObfuscation.d.ts +2 -1
  47. package/dist/exec/selfPrObfuscation.js +19 -6
  48. package/dist/hub/agentDirectory.d.ts +90 -0
  49. package/dist/hub/agentDirectory.js +104 -0
  50. package/dist/hub/bindings.js +13 -3
  51. package/dist/hub/capability.d.ts +14 -2
  52. package/dist/hub/fake.d.ts +4 -2
  53. package/dist/hub/fake.js +3 -2
  54. package/dist/hub/index.d.ts +1 -0
  55. package/dist/hub/index.js +1 -0
  56. package/dist/mailbox/catalog.js +3 -0
  57. package/dist/mailbox/ipcServer.js +2 -2
  58. package/dist/mailbox/store.d.ts +14 -0
  59. package/dist/mailbox/store.js +58 -6
  60. package/dist/material/consumer.js +9 -6
  61. package/dist/material/index.d.ts +1 -0
  62. package/dist/material/index.js +1 -0
  63. package/dist/material/materialArchive.d.ts +81 -0
  64. package/dist/material/materialArchive.js +466 -0
  65. package/dist/material/materialStore.d.ts +1 -0
  66. package/dist/material/materialStore.js +6 -13
  67. package/dist/schema/common.d.ts +1 -1
  68. package/dist/schema/common.js +1 -1
  69. package/dist/schema/material.d.ts +5 -5
  70. package/dist/trace/trajectoryExport.js +2 -2
  71. package/dist/wire/geneHints.d.ts +42 -1
  72. package/dist/wire/geneHints.js +52 -1
  73. package/dist/wire/index.d.ts +14 -2
  74. package/dist/wire/index.js +1 -1
  75. package/package.json +2 -1
@@ -0,0 +1,134 @@
1
+ import { computeAssetId, SCHEMA_VERSION } from '../wire/index.js';
2
+ const HARNESS_SEED_GENE_DRAFTS = [
3
+ {
4
+ id: 'gene_seed_publish_feishu_doc',
5
+ category: 'innovate',
6
+ signals_match: [
7
+ 'publish_markdown_to_feishu',
8
+ 'create_feishu_doc',
9
+ 'export_report_to_feishu',
10
+ 'publish_results_to_lark_doc',
11
+ 'feishu_doc',
12
+ 'lark_doc',
13
+ ],
14
+ preconditions: [
15
+ 'lark-cli is installed and available on PATH.',
16
+ 'lark-cli auth status reports a ready user or bot identity.',
17
+ ],
18
+ strategy: [
19
+ 'Run lark-cli doctor and require an ok result before publishing.',
20
+ 'Use the Docs v2 API and avoid deprecated Docs v1 flags.',
21
+ 'Write long Markdown content to a temporary file and pass it as an @file input.',
22
+ 'Create or update the document with the intended user or bot identity, then return the document URL.',
23
+ 'Never overwrite local lark-cli credential files while preparing the document.',
24
+ ],
25
+ constraints: { max_files: 2, forbidden_paths: ['.git', 'node_modules', '~/.lark-cli/config.json'] },
26
+ validation: ['node --version'],
27
+ summary: 'Publish Markdown content as a Feishu/Lark document through the official CLI, using file-backed content and Docs v2.',
28
+ },
29
+ {
30
+ id: 'gene_seed_conventional_git_commit',
31
+ category: 'optimize',
32
+ signals_match: [
33
+ 'git_commit',
34
+ 'create_commit',
35
+ 'commit_changes',
36
+ 'conventional_commit',
37
+ 'stage_and_commit',
38
+ 'write_commit_message',
39
+ ],
40
+ preconditions: ['A git repository has staged or unstaged changes that should become one logical commit.'],
41
+ strategy: [
42
+ 'Inspect git status plus the staged or unstaged diff before choosing a commit shape.',
43
+ 'Pick a Conventional Commits type and optional scope from the actual changed files.',
44
+ 'Stage only the intended logical files and never stage credentials or unrelated changes.',
45
+ 'Write a present-tense imperative subject under 72 characters, with body or footer when needed.',
46
+ 'Do not amend, force-push, hard-reset, or bypass hooks without explicit operator approval.',
47
+ ],
48
+ constraints: { max_files: 50, forbidden_paths: ['.git', 'node_modules'] },
49
+ validation: ['node --version'],
50
+ summary: 'Create a focused Conventional Commits-style git commit from the real diff while avoiding secrets and unrelated changes.',
51
+ },
52
+ {
53
+ id: 'gene_seed_poll_bugbot_review',
54
+ category: 'optimize',
55
+ signals_match: [
56
+ 'poll_bugbot',
57
+ 'bugbot_review',
58
+ 'wait_for_ci_review',
59
+ 'pr_review_gate',
60
+ 'cursor_bugbot',
61
+ 'pr_opened',
62
+ ],
63
+ preconditions: ['An open GitHub PR exists and Cursor Bugbot is expected to review it.'],
64
+ strategy: [
65
+ 'Poll the Cursor Bugbot check by name until it reaches a terminal conclusion or the operator timeout is reached.',
66
+ 'Treat SUCCESS as mergeable only when required checks are green and there are no unresolved Bugbot comments.',
67
+ 'Treat NEUTRAL as not passed; fetch and summarize Cursor Bugbot inline comments for the operator.',
68
+ 'On FAILURE or ACTION_REQUIRED, surface the findings and do not merge automatically.',
69
+ 'Only squash-merge when the operator explicitly asked for merge and the review gate is clean.',
70
+ ],
71
+ constraints: { max_files: 1, forbidden_paths: ['.git', 'node_modules'] },
72
+ validation: ['node --version'],
73
+ summary: 'Wait for Cursor Bugbot on a GitHub PR and gate merge decisions on the actual check conclusion and comments.',
74
+ },
75
+ {
76
+ id: 'gene_seed_gateway_timeout_recovery',
77
+ category: 'repair',
78
+ signals_match: [
79
+ 'gateway_timeout',
80
+ 'upstream_timeout',
81
+ 'http_524',
82
+ 'http_504',
83
+ 'request_timed_out',
84
+ 'retry_on_timeout',
85
+ ],
86
+ preconditions: ['A tool call, fetch, subagent request, or long command returned a gateway-class timeout.'],
87
+ strategy: [
88
+ 'Treat gateway timeout as transient or size-driven until one bounded recovery attempt proves otherwise.',
89
+ 'Retry the exact same operation once, then stop retrying the monolithic call.',
90
+ 'If the retry also times out, split the work by file, directory, endpoint, record, section, or time window.',
91
+ 'Run independent slices in parallel when safe and merge the results.',
92
+ 'Apply the same decomposition recursively only to the slice that still times out.',
93
+ ],
94
+ constraints: { max_files: 1, forbidden_paths: ['.git', 'node_modules'] },
95
+ validation: ['node --version'],
96
+ summary: 'Recover from gateway or upstream timeouts by retrying once, then decomposing the work instead of looping the same large call.',
97
+ },
98
+ {
99
+ id: 'gene_seed_github_webhook_listener',
100
+ category: 'innovate',
101
+ signals_match: [
102
+ 'github_webhook_listener',
103
+ 'bugbot_webhook',
104
+ 'passive_pr_notifications',
105
+ 'notify_when_bugbot_finishes',
106
+ 'webhook_tunnel',
107
+ 'github_pr_inbox',
108
+ ],
109
+ preconditions: ['A developer machine can run a local listener and an outbound tunnel for GitHub webhook delivery.'],
110
+ strategy: [
111
+ 'Use an HMAC-validated local listener for GitHub webhook payloads and deduplicate delivery ids.',
112
+ 'Expose the listener through an outbound-only tunnel rather than an inbound public port.',
113
+ 'Write vetted notifications into a local inbox with restrictive permissions; never execute webhook payloads.',
114
+ 'On session start, re-fetch PR state through GitHub before surfacing any inbox item.',
115
+ 'Rotate webhook secrets periodically and immediately after suspected exposure.',
116
+ ],
117
+ constraints: { max_files: 20, forbidden_paths: ['.git', 'node_modules'] },
118
+ validation: ['node --version'],
119
+ summary: 'Deploy a local HMAC-validated GitHub webhook listener that turns PR and Bugbot events into safe operator notifications.',
120
+ },
121
+ ];
122
+ function materializeSeedGene(draft) {
123
+ const gene = {
124
+ type: 'Gene',
125
+ schema_version: SCHEMA_VERSION,
126
+ ...draft,
127
+ asset_id: '',
128
+ };
129
+ return { ...gene, asset_id: computeAssetId(gene) ?? '' };
130
+ }
131
+ export const BUNDLED_HARNESS_SEED_GENES = Object.freeze(HARNESS_SEED_GENE_DRAFTS.map((gene) => Object.freeze(materializeSeedGene(gene))));
132
+ export function bundledHarnessSeedGenesJsonl() {
133
+ return `${BUNDLED_HARNESS_SEED_GENES.map((gene) => JSON.stringify(gene)).join('\n')}\n`;
134
+ }
@@ -2,6 +2,7 @@ import type { AssetStoreProvider } from '../assetstore/provider.js';
2
2
  import { ReviewLedger } from '../assetstore/reviewLedger.js';
3
3
  import type { ReportEvent } from '../events/reports.js';
4
4
  import type { GepCategory } from '../wire/index.js';
5
+ import { type AntiGeneOverblockSummary } from './antiGeneImpact.js';
5
6
  export type AntiGeneBenchmarkArm = 'baseline' | 'antiGene';
6
7
  export type AntiGeneBenchmarkVerdict = 'anti_gene_better' | 'no_clear_improvement' | 'anti_gene_worse' | 'insufficient_samples';
7
8
  export interface AntiGeneBenchmarkOutcomeSpec {
@@ -58,6 +59,7 @@ export interface AntiGeneBenchmarkReport {
58
59
  antiGene: AntiGeneBenchmarkArmMetrics;
59
60
  missingExpectedWarnings: number;
60
61
  overblocked: number;
62
+ overblockedAntiGenes: AntiGeneOverblockSummary[];
61
63
  failureDelta: number;
62
64
  verdict: AntiGeneBenchmarkVerdict;
63
65
  taskResults: AntiGeneBenchmarkTaskResult[];
@@ -8,6 +8,7 @@ import { LineTooLargeError } from '../events/eventStore.js';
8
8
  import { CycleEngine } from '../algo/cycleEngine.js';
9
9
  import { runEvolutionCycle } from '../algo/orchestrator.js';
10
10
  import { makeGeneSelectionPoint } from '../algo/geneSelection.js';
11
+ import { parseOverblockedAntiGenes, summarizeOverblockedAntiGenes } from './antiGeneImpact.js';
11
12
  const ALL_ASSETS_LIMIT = Number.MAX_SAFE_INTEGER;
12
13
  const ASSET_KINDS = ['Gene', 'Capsule', 'EvolutionEvent', 'AntiGene'];
13
14
  function buildProblem(task, now) {
@@ -148,6 +149,7 @@ function buildReport(suite, taskResults, minSamples, minFailureDelta) {
148
149
  antiGene,
149
150
  missingExpectedWarnings: taskResults.reduce((sum, r) => sum + r.antiGene.missingExpectedWarnings.length, 0),
150
151
  overblocked: antiGene.overblocked,
152
+ overblockedAntiGenes: summarizeOverblockedAntiGenes(taskResults),
151
153
  failureDelta: baseline.failureRate - antiGene.failureRate,
152
154
  taskResults,
153
155
  };
@@ -225,13 +227,21 @@ function isReportPayload(value) {
225
227
  && typeof value.tasks === 'number'
226
228
  && typeof value.verdict === 'string';
227
229
  }
230
+ function normalizeReportPayload(value) {
231
+ const parsed = parseOverblockedAntiGenes(value.overblockedAntiGenes);
232
+ const truncated = typeof value.taskResultsTruncated === 'number' && value.taskResultsTruncated > 0;
233
+ return {
234
+ ...value,
235
+ overblockedAntiGenes: parsed ?? (truncated ? [] : summarizeOverblockedAntiGenes(value.taskResults ?? [])),
236
+ };
237
+ }
228
238
  export function antiGeneBenchmarkReportsFromEvents(events) {
229
239
  const out = [];
230
240
  for (const event of events) {
231
241
  if (event.type !== 'anti_gene.benchmark_result')
232
242
  continue;
233
243
  if (isReportPayload(event.payload))
234
- out.push(event.payload);
244
+ out.push(normalizeReportPayload(event.payload));
235
245
  }
236
246
  return out;
237
247
  }
@@ -0,0 +1,16 @@
1
+ export interface AntiGeneOverblockSummary {
2
+ antiGeneId: string;
3
+ count: number;
4
+ taskIds: string[];
5
+ }
6
+ interface AntiGeneImpactRunResult {
7
+ overblocked: boolean;
8
+ observedAntiWarnings: readonly string[];
9
+ }
10
+ interface AntiGeneImpactTaskResult {
11
+ taskId: string;
12
+ antiGene: AntiGeneImpactRunResult;
13
+ }
14
+ export declare function summarizeOverblockedAntiGenes(taskResults: readonly AntiGeneImpactTaskResult[]): AntiGeneOverblockSummary[];
15
+ export declare function parseOverblockedAntiGenes(value: unknown): AntiGeneOverblockSummary[] | null;
16
+ export {};
@@ -0,0 +1,34 @@
1
+ export function summarizeOverblockedAntiGenes(taskResults) {
2
+ const byId = new Map();
3
+ for (const task of taskResults) {
4
+ if (!task.antiGene.overblocked)
5
+ continue;
6
+ for (const antiGeneId of new Set(task.antiGene.observedAntiWarnings)) {
7
+ const row = byId.get(antiGeneId) ?? { count: 0, taskIds: new Set() };
8
+ row.count += 1;
9
+ row.taskIds.add(task.taskId);
10
+ byId.set(antiGeneId, row);
11
+ }
12
+ }
13
+ return [...byId.entries()]
14
+ .map(([antiGeneId, row]) => ({ antiGeneId, count: row.count, taskIds: [...row.taskIds].sort() }))
15
+ .sort((a, b) => b.count - a.count || a.antiGeneId.localeCompare(b.antiGeneId));
16
+ }
17
+ export function parseOverblockedAntiGenes(value) {
18
+ if (!Array.isArray(value))
19
+ return null;
20
+ const out = [];
21
+ for (const item of value) {
22
+ if (!item || typeof item !== 'object' || Array.isArray(item))
23
+ return null;
24
+ const row = item;
25
+ if (typeof row['antiGeneId'] !== 'string')
26
+ return null;
27
+ if (typeof row['count'] !== 'number' || !Number.isFinite(row['count']))
28
+ return null;
29
+ if (!Array.isArray(row['taskIds']) || !row['taskIds'].every((taskId) => typeof taskId === 'string'))
30
+ return null;
31
+ out.push({ antiGeneId: row['antiGeneId'], count: row['count'], taskIds: [...row['taskIds']] });
32
+ }
33
+ return out;
34
+ }
@@ -3,6 +3,7 @@ import { ReviewLedger } from '../assetstore/reviewLedger.js';
3
3
  import type { ReportEvent } from '../events/reports.js';
4
4
  import { type CycleInput } from '../algo/cycleEngine.js';
5
5
  import type { GepCategory } from '../wire/index.js';
6
+ import { type AntiGeneOverblockSummary } from './antiGeneImpact.js';
6
7
  export type AntiGeneRolloutArm = 'baseline' | 'antiGene';
7
8
  export type AntiGeneRolloutVerdict = 'anti_gene_better' | 'no_clear_improvement' | 'anti_gene_worse' | 'insufficient_samples';
8
9
  export interface AntiGeneRolloutTask {
@@ -50,6 +51,7 @@ export interface AntiGeneRolloutReport {
50
51
  antiGene: AntiGeneRolloutArmMetrics;
51
52
  missingExpectedWarnings: number;
52
53
  overblocked: number;
54
+ overblockedAntiGenes: AntiGeneOverblockSummary[];
53
55
  failureDelta: number;
54
56
  verdict: AntiGeneRolloutVerdict;
55
57
  taskResults: AntiGeneRolloutTaskResult[];
@@ -8,6 +8,7 @@ import { LineTooLargeError } from '../events/eventStore.js';
8
8
  import { CycleEngine } from '../algo/cycleEngine.js';
9
9
  import { runEvolutionCycle } from '../algo/orchestrator.js';
10
10
  import { makeGeneSelectionPoint } from '../algo/geneSelection.js';
11
+ import { parseOverblockedAntiGenes, summarizeOverblockedAntiGenes } from './antiGeneImpact.js';
11
12
  const ALL_ASSETS_LIMIT = Number.MAX_SAFE_INTEGER;
12
13
  const ASSET_KINDS = ['Gene', 'Capsule', 'EvolutionEvent', 'AntiGene'];
13
14
  function buildProblem(task, now) {
@@ -163,6 +164,7 @@ function buildReport(suite, rawTaskResults, minSamples, minFailureDelta) {
163
164
  antiGene,
164
165
  missingExpectedWarnings: taskResults.reduce((sum, r) => sum + r.antiGene.missingExpectedWarnings.length, 0),
165
166
  overblocked: antiGene.overblocked,
167
+ overblockedAntiGenes: summarizeOverblockedAntiGenes(taskResults),
166
168
  failureDelta: baseline.failureRate - antiGene.failureRate,
167
169
  taskResults,
168
170
  };
@@ -240,13 +242,23 @@ function isReportPayload(value) {
240
242
  && typeof value.tasks === 'number'
241
243
  && typeof value.verdict === 'string';
242
244
  }
245
+ function normalizeReportPayload(value) {
246
+ const parsed = parseOverblockedAntiGenes(value.overblockedAntiGenes);
247
+ const taskResults = normalizeTaskResults(value.taskResults ?? []);
248
+ const truncated = typeof value.taskResultsTruncated === 'number' && value.taskResultsTruncated > 0;
249
+ return {
250
+ ...value,
251
+ taskResults,
252
+ overblockedAntiGenes: parsed ?? (truncated ? [] : summarizeOverblockedAntiGenes(taskResults)),
253
+ };
254
+ }
243
255
  export function antiGeneRolloutReportsFromEvents(events) {
244
256
  const out = [];
245
257
  for (const event of events) {
246
258
  if (event.type !== 'anti_gene.rollout_result')
247
259
  continue;
248
260
  if (isReportPayload(event.payload))
249
- out.push(event.payload);
261
+ out.push(normalizeReportPayload(event.payload));
250
262
  }
251
263
  return out;
252
264
  }
@@ -0,0 +1,65 @@
1
+ import { type RootEvent } from './eventSchema.js';
2
+ export declare const ROOT_EVENT_ARCHIVE_DEFAULT_KEEP_EVENTS = 10000;
3
+ export declare class InvalidRootEventLogError extends Error {
4
+ readonly line: number;
5
+ readonly code = "ROOT_EVENT_ARCHIVE_INVALID_LOG";
6
+ constructor(line: number, reason: string);
7
+ }
8
+ export declare class ArchiveSegmentConflictError extends Error {
9
+ readonly archiveId: string;
10
+ readonly code = "ROOT_EVENT_ARCHIVE_SEGMENT_CONFLICT";
11
+ constructor(archiveId: string);
12
+ }
13
+ export declare class InvalidRootEventArchiveError extends Error {
14
+ readonly segment: string;
15
+ readonly line: number;
16
+ readonly code = "ROOT_EVENT_ARCHIVE_INVALID_ARCHIVE";
17
+ constructor(segment: string, line: number);
18
+ }
19
+ export declare class RootEventHistoryGapError extends Error {
20
+ readonly expectedSeq: number;
21
+ readonly actualSeq: number;
22
+ readonly code = "ROOT_EVENT_HISTORY_GAP";
23
+ constructor(expectedSeq: number, actualSeq: number);
24
+ }
25
+ export interface RootEventArchiveOptions {
26
+ path: string;
27
+ keepEvents?: number;
28
+ }
29
+ export interface RootEventArchivePlan {
30
+ mode: 'preview';
31
+ activeRecords: number;
32
+ keepEvents: number;
33
+ wouldArchive: number;
34
+ retainedRecords: number;
35
+ firstSeq: number | null;
36
+ lastSeq: number | null;
37
+ archiveId: string | null;
38
+ }
39
+ export interface RootEventArchiveResult {
40
+ mode: 'write';
41
+ activeRecordsBefore: number;
42
+ keepEvents: number;
43
+ archivedRecords: number;
44
+ retainedRecords: number;
45
+ firstSeq: number | null;
46
+ lastSeq: number | null;
47
+ archiveId: string | null;
48
+ reusedSegment: boolean;
49
+ }
50
+ export interface RootEventArchiveStats {
51
+ exists: boolean;
52
+ segments: number;
53
+ bytes: number;
54
+ records: number;
55
+ invalidLines: number;
56
+ firstSeq: number | null;
57
+ lastSeq: number | null;
58
+ }
59
+ export declare function rootEventArchiveDir(path: string): string;
60
+ export declare function rootEventArchiveSegmentName(firstSeq: number, lastSeq: number): string;
61
+ export declare function planRootEventArchive(opts: RootEventArchiveOptions): RootEventArchivePlan;
62
+ export declare function archiveRootEvents(opts: RootEventArchiveOptions): RootEventArchiveResult;
63
+ export declare function readRootEventHistory(path: string, archiveDir?: string): RootEvent[];
64
+ export declare function validateRootEventHistory(path: string): void;
65
+ export declare function inspectRootEventArchive(path: string): RootEventArchiveStats;