@evomap/evolver-core 2.0.0-beta.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.
- package/dist/algo/antiDistill.d.ts +35 -0
- package/dist/algo/antiDistill.js +167 -0
- package/dist/algo/bans.d.ts +6 -0
- package/dist/algo/bans.js +33 -0
- package/dist/algo/candidateAssembly.d.ts +65 -0
- package/dist/algo/candidateAssembly.js +196 -0
- package/dist/algo/capabilityCandidates.d.ts +38 -0
- package/dist/algo/capabilityCandidates.js +131 -0
- package/dist/algo/confidence.d.ts +106 -0
- package/dist/algo/confidence.js +196 -0
- package/dist/algo/cycleEngine.d.ts +143 -0
- package/dist/algo/cycleEngine.js +417 -0
- package/dist/algo/cycleFailureClassifier.d.ts +52 -0
- package/dist/algo/cycleFailureClassifier.js +104 -0
- package/dist/algo/epigenetics.d.ts +14 -0
- package/dist/algo/epigenetics.js +41 -0
- package/dist/algo/evolutionEvent.d.ts +23 -0
- package/dist/algo/evolutionEvent.js +24 -0
- package/dist/algo/exploration.d.ts +34 -0
- package/dist/algo/exploration.js +55 -0
- package/dist/algo/geneHealth.d.ts +24 -0
- package/dist/algo/geneHealth.js +16 -0
- package/dist/algo/geneIntake.d.ts +37 -0
- package/dist/algo/geneIntake.js +100 -0
- package/dist/algo/genePromotion.d.ts +48 -0
- package/dist/algo/genePromotion.js +53 -0
- package/dist/algo/geneSelection.d.ts +128 -0
- package/dist/algo/geneSelection.js +222 -0
- package/dist/algo/index.d.ts +18 -0
- package/dist/algo/index.js +18 -0
- package/dist/algo/mutation.d.ts +12 -0
- package/dist/algo/mutation.js +22 -0
- package/dist/algo/orchestrator.d.ts +65 -0
- package/dist/algo/orchestrator.js +63 -0
- package/dist/algo/solidify.d.ts +43 -0
- package/dist/algo/solidify.js +63 -0
- package/dist/algo/strategyPresets.d.ts +32 -0
- package/dist/algo/strategyPresets.js +61 -0
- package/dist/assetstore/index.d.ts +8 -0
- package/dist/assetstore/index.js +8 -0
- package/dist/assetstore/learningHistory.d.ts +25 -0
- package/dist/assetstore/learningHistory.js +38 -0
- package/dist/assetstore/localJsonl.d.ts +34 -0
- package/dist/assetstore/localJsonl.js +182 -0
- package/dist/assetstore/pendingSignals.d.ts +22 -0
- package/dist/assetstore/pendingSignals.js +171 -0
- package/dist/assetstore/provenance.d.ts +39 -0
- package/dist/assetstore/provenance.js +109 -0
- package/dist/assetstore/provider.d.ts +48 -0
- package/dist/assetstore/provider.js +36 -0
- package/dist/assetstore/remoteStub.d.ts +32 -0
- package/dist/assetstore/remoteStub.js +36 -0
- package/dist/assetstore/reviewFilter.d.ts +20 -0
- package/dist/assetstore/reviewFilter.js +44 -0
- package/dist/assetstore/reviewLedger.d.ts +55 -0
- package/dist/assetstore/reviewLedger.js +121 -0
- package/dist/benchmark/antiGeneBenchmark.d.ts +79 -0
- package/dist/benchmark/antiGeneBenchmark.js +241 -0
- package/dist/benchmark/antiGeneRollout.d.ts +80 -0
- package/dist/benchmark/antiGeneRollout.js +256 -0
- package/dist/benchmark/benchmark.d.ts +32 -0
- package/dist/benchmark/benchmark.js +26 -0
- package/dist/benchmark/evolutionThesisSolver.d.ts +25 -0
- package/dist/benchmark/evolutionThesisSolver.js +41 -0
- package/dist/benchmark/index.d.ts +5 -0
- package/dist/benchmark/index.js +5 -0
- package/dist/benchmark/thesis.d.ts +85 -0
- package/dist/benchmark/thesis.js +150 -0
- package/dist/bootstrap/envFingerprint.d.ts +45 -0
- package/dist/bootstrap/envFingerprint.js +72 -0
- package/dist/bootstrap/index.d.ts +2 -0
- package/dist/bootstrap/index.js +2 -0
- package/dist/bootstrap/selfEvolve.d.ts +36 -0
- package/dist/bootstrap/selfEvolve.js +26 -0
- package/dist/cycle/cycleTimeline.d.ts +35 -0
- package/dist/cycle/cycleTimeline.js +74 -0
- package/dist/cycle/index.d.ts +2 -0
- package/dist/cycle/index.js +2 -0
- package/dist/cycle/stateMachine.d.ts +6 -0
- package/dist/cycle/stateMachine.js +25 -0
- package/dist/daemon/cycleContext.d.ts +12 -0
- package/dist/daemon/cycleContext.js +13 -0
- package/dist/daemon/drain.d.ts +11 -0
- package/dist/daemon/drain.js +16 -0
- package/dist/daemon/guards.d.ts +87 -0
- package/dist/daemon/guards.js +142 -0
- package/dist/daemon/idempotency.d.ts +11 -0
- package/dist/daemon/idempotency.js +36 -0
- package/dist/daemon/idleScheduler.d.ts +55 -0
- package/dist/daemon/idleScheduler.js +181 -0
- package/dist/daemon/index.d.ts +8 -0
- package/dist/daemon/index.js +8 -0
- package/dist/daemon/stepRunner.d.ts +12 -0
- package/dist/daemon/stepRunner.js +31 -0
- package/dist/daemon/unhandledRejectionWindow.d.ts +21 -0
- package/dist/daemon/unhandledRejectionWindow.js +52 -0
- package/dist/daemon/watchdog.d.ts +11 -0
- package/dist/daemon/watchdog.js +14 -0
- package/dist/events/eventSchema.d.ts +132 -0
- package/dist/events/eventSchema.js +30 -0
- package/dist/events/eventStore.d.ts +32 -0
- package/dist/events/eventStore.js +137 -0
- package/dist/events/ingest.d.ts +34 -0
- package/dist/events/ingest.js +61 -0
- package/dist/events/paths.d.ts +22 -0
- package/dist/events/paths.js +44 -0
- package/dist/events/projectors.d.ts +9 -0
- package/dist/events/projectors.js +11 -0
- package/dist/events/public.d.ts +14 -0
- package/dist/events/public.js +8 -0
- package/dist/events/replayer.d.ts +26 -0
- package/dist/events/replayer.js +67 -0
- package/dist/events/reports.d.ts +90 -0
- package/dist/events/reports.js +244 -0
- package/dist/events/retention.d.ts +70 -0
- package/dist/events/retention.js +177 -0
- package/dist/events/sink.d.ts +5 -0
- package/dist/events/sink.js +1 -0
- package/dist/exec/autoExec.d.ts +137 -0
- package/dist/exec/autoExec.js +221 -0
- package/dist/exec/autonomousCycle.d.ts +48 -0
- package/dist/exec/autonomousCycle.js +78 -0
- package/dist/exec/claudeBridge.d.ts +112 -0
- package/dist/exec/claudeBridge.js +219 -0
- package/dist/exec/index.d.ts +9 -0
- package/dist/exec/index.js +11 -0
- package/dist/exec/openPrRegistry.d.ts +60 -0
- package/dist/exec/openPrRegistry.js +130 -0
- package/dist/exec/policy/blastRadius.d.ts +31 -0
- package/dist/exec/policy/blastRadius.js +67 -0
- package/dist/exec/policy/constraints.d.ts +26 -0
- package/dist/exec/policy/constraints.js +62 -0
- package/dist/exec/policy/destructive.d.ts +45 -0
- package/dist/exec/policy/destructive.js +108 -0
- package/dist/exec/policy/failureMode.d.ts +33 -0
- package/dist/exec/policy/failureMode.js +49 -0
- package/dist/exec/policy/index.d.ts +24 -0
- package/dist/exec/policy/index.js +30 -0
- package/dist/exec/policy/protectedPaths.d.ts +17 -0
- package/dist/exec/policy/protectedPaths.js +65 -0
- package/dist/exec/policyCheck.d.ts +2 -0
- package/dist/exec/policyCheck.js +7 -0
- package/dist/exec/prompt.d.ts +34 -0
- package/dist/exec/prompt.js +108 -0
- package/dist/exec/proofOfWork.d.ts +9 -0
- package/dist/exec/proofOfWork.js +11 -0
- package/dist/exec/runnerRegistry.d.ts +123 -0
- package/dist/exec/runnerRegistry.js +237 -0
- package/dist/exec/selfPr.d.ts +83 -0
- package/dist/exec/selfPr.js +104 -0
- package/dist/exec/selfPrObfuscation.d.ts +21 -0
- package/dist/exec/selfPrObfuscation.js +85 -0
- package/dist/hooks/hooks.d.ts +117 -0
- package/dist/hooks/hooks.js +89 -0
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.js +1 -0
- package/dist/hub/assetCallLog.d.ts +43 -0
- package/dist/hub/assetCallLog.js +72 -0
- package/dist/hub/bindings.d.ts +28 -0
- package/dist/hub/bindings.js +90 -0
- package/dist/hub/capability.d.ts +278 -0
- package/dist/hub/capability.js +1 -0
- package/dist/hub/conversationDistiller.d.ts +88 -0
- package/dist/hub/conversationDistiller.js +264 -0
- package/dist/hub/fake.d.ts +45 -0
- package/dist/hub/fake.js +69 -0
- package/dist/hub/hubReview.d.ts +91 -0
- package/dist/hub/hubReview.js +106 -0
- package/dist/hub/index.d.ts +10 -0
- package/dist/hub/index.js +10 -0
- package/dist/hub/ingest.d.ts +15 -0
- package/dist/hub/ingest.js +15 -0
- package/dist/hub/questionGenerator.d.ts +59 -0
- package/dist/hub/questionGenerator.js +406 -0
- package/dist/hub/reuseDecision.d.ts +87 -0
- package/dist/hub/reuseDecision.js +127 -0
- package/dist/hub/sanitize.d.ts +52 -0
- package/dist/hub/sanitize.js +321 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +27 -0
- package/dist/mailbox/catalog.d.ts +17 -0
- package/dist/mailbox/catalog.js +53 -0
- package/dist/mailbox/daemon.d.ts +48 -0
- package/dist/mailbox/daemon.js +61 -0
- package/dist/mailbox/dispatch.d.ts +46 -0
- package/dist/mailbox/dispatch.js +62 -0
- package/dist/mailbox/envelope.d.ts +43 -0
- package/dist/mailbox/envelope.js +52 -0
- package/dist/mailbox/index.d.ts +8 -0
- package/dist/mailbox/index.js +8 -0
- package/dist/mailbox/ipcServer.d.ts +46 -0
- package/dist/mailbox/ipcServer.js +168 -0
- package/dist/mailbox/requestReply.d.ts +40 -0
- package/dist/mailbox/requestReply.js +77 -0
- package/dist/mailbox/store.d.ts +74 -0
- package/dist/mailbox/store.js +308 -0
- package/dist/mailbox/wake.d.ts +45 -0
- package/dist/mailbox/wake.js +60 -0
- package/dist/material/boundary.d.ts +7 -0
- package/dist/material/boundary.js +14 -0
- package/dist/material/consumer.d.ts +21 -0
- package/dist/material/consumer.js +52 -0
- package/dist/material/emit.d.ts +55 -0
- package/dist/material/emit.js +52 -0
- package/dist/material/factory.d.ts +27 -0
- package/dist/material/factory.js +25 -0
- package/dist/material/index.d.ts +8 -0
- package/dist/material/index.js +8 -0
- package/dist/material/materialStore.d.ts +24 -0
- package/dist/material/materialStore.js +76 -0
- package/dist/material/sampling.d.ts +21 -0
- package/dist/material/sampling.js +39 -0
- package/dist/material/sources.d.ts +25 -0
- package/dist/material/sources.js +33 -0
- package/dist/material/watermark.d.ts +21 -0
- package/dist/material/watermark.js +76 -0
- package/dist/observers/cursorRewriteObserver.d.ts +46 -0
- package/dist/observers/cursorRewriteObserver.js +103 -0
- package/dist/observers/distillObserver.d.ts +31 -0
- package/dist/observers/distillObserver.js +93 -0
- package/dist/observers/index.d.ts +5 -0
- package/dist/observers/index.js +5 -0
- package/dist/observers/observerBus.d.ts +44 -0
- package/dist/observers/observerBus.js +73 -0
- package/dist/observers/reflectionObserver.d.ts +31 -0
- package/dist/observers/reflectionObserver.js +124 -0
- package/dist/observers/valueDigestObserver.d.ts +50 -0
- package/dist/observers/valueDigestObserver.js +70 -0
- package/dist/ops/cleanup.d.ts +23 -0
- package/dist/ops/cleanup.js +68 -0
- package/dist/ops/health.d.ts +37 -0
- package/dist/ops/health.js +96 -0
- package/dist/ops/index.d.ts +7 -0
- package/dist/ops/index.js +7 -0
- package/dist/ops/recall.d.ts +65 -0
- package/dist/ops/recall.js +152 -0
- package/dist/ops/reuseOutcomes.d.ts +68 -0
- package/dist/ops/reuseOutcomes.js +126 -0
- package/dist/ops/savingsCore.d.ts +47 -0
- package/dist/ops/savingsCore.js +112 -0
- package/dist/ops/selfUpdate.d.ts +106 -0
- package/dist/ops/selfUpdate.js +294 -0
- package/dist/ops/valueLedger.d.ts +205 -0
- package/dist/ops/valueLedger.js +238 -0
- package/dist/ops/valueOutreach.d.ts +70 -0
- package/dist/ops/valueOutreach.js +244 -0
- package/dist/personality/drift.d.ts +45 -0
- package/dist/personality/drift.js +106 -0
- package/dist/personality/events.d.ts +25 -0
- package/dist/personality/events.js +37 -0
- package/dist/personality/evolveOps.d.ts +20 -0
- package/dist/personality/evolveOps.js +93 -0
- package/dist/personality/index.d.ts +11 -0
- package/dist/personality/index.js +11 -0
- package/dist/personality/mutate.d.ts +21 -0
- package/dist/personality/mutate.js +39 -0
- package/dist/personality/pivot.d.ts +23 -0
- package/dist/personality/pivot.js +22 -0
- package/dist/personality/prompt.d.ts +6 -0
- package/dist/personality/prompt.js +62 -0
- package/dist/personality/riskGate.d.ts +42 -0
- package/dist/personality/riskGate.js +80 -0
- package/dist/personality/schema.d.ts +255 -0
- package/dist/personality/schema.js +119 -0
- package/dist/personality/select.d.ts +46 -0
- package/dist/personality/select.js +71 -0
- package/dist/personality/stats.d.ts +46 -0
- package/dist/personality/stats.js +82 -0
- package/dist/personality/store.d.ts +35 -0
- package/dist/personality/store.js +92 -0
- package/dist/schema/common.d.ts +28 -0
- package/dist/schema/common.js +17 -0
- package/dist/schema/index.d.ts +5 -0
- package/dist/schema/index.js +5 -0
- package/dist/schema/material.d.ts +201 -0
- package/dist/schema/material.js +50 -0
- package/dist/schema/problem.d.ts +160 -0
- package/dist/schema/problem.js +45 -0
- package/dist/schema/proofOfWork.d.ts +97 -0
- package/dist/schema/proofOfWork.js +9 -0
- package/dist/schema/signal.d.ts +41 -0
- package/dist/schema/signal.js +19 -0
- package/dist/shadow/index.d.ts +6 -0
- package/dist/shadow/index.js +6 -0
- package/dist/shadow/jsonlSink.d.ts +17 -0
- package/dist/shadow/jsonlSink.js +27 -0
- package/dist/shadow/redact.d.ts +11 -0
- package/dist/shadow/redact.js +18 -0
- package/dist/shadow/shadowHub.d.ts +12 -0
- package/dist/shadow/shadowHub.js +42 -0
- package/dist/shadow/shadowMailbox.d.ts +17 -0
- package/dist/shadow/shadowMailbox.js +25 -0
- package/dist/shadow/shadowStore.d.ts +18 -0
- package/dist/shadow/shadowStore.js +55 -0
- package/dist/shadow/sink.d.ts +37 -0
- package/dist/shadow/sink.js +18 -0
- package/dist/signals/cycleHistoryFromEvents.d.ts +11 -0
- package/dist/signals/cycleHistoryFromEvents.js +96 -0
- package/dist/signals/expand.d.ts +34 -0
- package/dist/signals/expand.js +125 -0
- package/dist/signals/extractor.d.ts +25 -0
- package/dist/signals/extractor.js +57 -0
- package/dist/signals/index.d.ts +6 -0
- package/dist/signals/index.js +6 -0
- package/dist/signals/metaSignals.d.ts +57 -0
- package/dist/signals/metaSignals.js +158 -0
- package/dist/signals/signalGate.d.ts +15 -0
- package/dist/signals/signalGate.js +40 -0
- package/dist/signals/traceSignals.d.ts +44 -0
- package/dist/signals/traceSignals.js +123 -0
- package/dist/signatures/classifier.d.ts +16 -0
- package/dist/signatures/classifier.js +29 -0
- package/dist/signatures/index.d.ts +2 -0
- package/dist/signatures/index.js +2 -0
- package/dist/signatures/signatures.d.ts +22 -0
- package/dist/signatures/signatures.js +42 -0
- package/dist/strategy/experiment.d.ts +48 -0
- package/dist/strategy/experiment.js +63 -0
- package/dist/strategy/index.d.ts +2 -0
- package/dist/strategy/index.js +2 -0
- package/dist/strategy/strategyPoint.d.ts +30 -0
- package/dist/strategy/strategyPoint.js +23 -0
- package/dist/trace/index.d.ts +2 -0
- package/dist/trace/index.js +2 -0
- package/dist/trace/trajectory.d.ts +82 -0
- package/dist/trace/trajectory.js +117 -0
- package/dist/trace/trajectoryExport.d.ts +237 -0
- package/dist/trace/trajectoryExport.js +1818 -0
- package/dist/trigger/budget.d.ts +16 -0
- package/dist/trigger/budget.js +20 -0
- package/dist/trigger/engine.d.ts +12 -0
- package/dist/trigger/engine.js +23 -0
- package/dist/trigger/index.d.ts +6 -0
- package/dist/trigger/index.js +6 -0
- package/dist/trigger/problemBuilder.d.ts +24 -0
- package/dist/trigger/problemBuilder.js +32 -0
- package/dist/trigger/trigger.d.ts +22 -0
- package/dist/trigger/trigger.js +27 -0
- package/dist/trigger/valueModel.d.ts +26 -0
- package/dist/trigger/valueModel.js +25 -0
- package/dist/trigger/wfq.d.ts +13 -0
- package/dist/trigger/wfq.js +25 -0
- package/dist/util/fileLock.d.ts +24 -0
- package/dist/util/fileLock.js +227 -0
- package/dist/util/index.d.ts +2 -0
- package/dist/util/index.js +2 -0
- package/dist/util/version.d.ts +12 -0
- package/dist/util/version.js +51 -0
- package/dist/verify/index.d.ts +4 -0
- package/dist/verify/index.js +4 -0
- package/dist/verify/rollback.d.ts +22 -0
- package/dist/verify/rollback.js +33 -0
- package/dist/verify/sandboxRunner.d.ts +39 -0
- package/dist/verify/sandboxRunner.js +116 -0
- package/dist/verify/sandboxedValidation.d.ts +35 -0
- package/dist/verify/sandboxedValidation.js +56 -0
- package/dist/verify/validation.d.ts +41 -0
- package/dist/verify/validation.js +85 -0
- package/dist/wire/canonicalize.golden.d.ts +23 -0
- package/dist/wire/canonicalize.golden.js +46 -0
- package/dist/wire/geneHints.d.ts +64 -0
- package/dist/wire/geneHints.js +100 -0
- package/dist/wire/index.d.ts +91 -0
- package/dist/wire/index.js +3 -0
- package/dist/wire/schemaGate.d.ts +11 -0
- package/dist/wire/schemaGate.js +49 -0
- package/dist/workflow/dsl.d.ts +54 -0
- package/dist/workflow/dsl.js +15 -0
- package/dist/workflow/engine.d.ts +30 -0
- package/dist/workflow/engine.js +94 -0
- package/dist/workflow/index.d.ts +2 -0
- package/dist/workflow/index.js +2 -0
- package/package.json +29 -0
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import type { AssetStoreProvider } from '../assetstore/provider.js';
|
|
2
|
+
import { ReviewLedger } from '../assetstore/reviewLedger.js';
|
|
3
|
+
import type { ReportEvent } from '../events/reports.js';
|
|
4
|
+
import { type CycleInput } from '../algo/cycleEngine.js';
|
|
5
|
+
import type { GepCategory } from '../wire/index.js';
|
|
6
|
+
export type AntiGeneRolloutArm = 'baseline' | 'antiGene';
|
|
7
|
+
export type AntiGeneRolloutVerdict = 'anti_gene_better' | 'no_clear_improvement' | 'anti_gene_worse' | 'insufficient_samples';
|
|
8
|
+
export interface AntiGeneRolloutTask {
|
|
9
|
+
id: string;
|
|
10
|
+
signals: string[];
|
|
11
|
+
target?: string;
|
|
12
|
+
expectedEffect?: string;
|
|
13
|
+
category?: GepCategory;
|
|
14
|
+
summary?: string;
|
|
15
|
+
confidence?: number;
|
|
16
|
+
expectedAntiWarnings?: string[];
|
|
17
|
+
}
|
|
18
|
+
export interface AntiGeneRolloutSuite {
|
|
19
|
+
name: string;
|
|
20
|
+
validation?: string[];
|
|
21
|
+
tasks: AntiGeneRolloutTask[];
|
|
22
|
+
}
|
|
23
|
+
export interface AntiGeneRolloutArmMetrics {
|
|
24
|
+
arm: AntiGeneRolloutArm;
|
|
25
|
+
n: number;
|
|
26
|
+
failures: number;
|
|
27
|
+
failureRate: number;
|
|
28
|
+
repeatedFailures: number;
|
|
29
|
+
overblocked: number;
|
|
30
|
+
observedWarnings: number;
|
|
31
|
+
}
|
|
32
|
+
export interface AntiGeneRolloutRunResult {
|
|
33
|
+
status: 'success' | 'failed';
|
|
34
|
+
score: number;
|
|
35
|
+
repeatedFailure: boolean;
|
|
36
|
+
overblocked: boolean;
|
|
37
|
+
observedAntiWarnings: string[];
|
|
38
|
+
missingExpectedWarnings: string[];
|
|
39
|
+
selectedGeneId?: string | null;
|
|
40
|
+
}
|
|
41
|
+
export interface AntiGeneRolloutTaskResult {
|
|
42
|
+
taskId: string;
|
|
43
|
+
baseline: AntiGeneRolloutRunResult;
|
|
44
|
+
antiGene: AntiGeneRolloutRunResult;
|
|
45
|
+
}
|
|
46
|
+
export interface AntiGeneRolloutReport {
|
|
47
|
+
suite: string;
|
|
48
|
+
tasks: number;
|
|
49
|
+
baseline: AntiGeneRolloutArmMetrics;
|
|
50
|
+
antiGene: AntiGeneRolloutArmMetrics;
|
|
51
|
+
missingExpectedWarnings: number;
|
|
52
|
+
overblocked: number;
|
|
53
|
+
failureDelta: number;
|
|
54
|
+
verdict: AntiGeneRolloutVerdict;
|
|
55
|
+
taskResults: AntiGeneRolloutTaskResult[];
|
|
56
|
+
taskResultsTruncated?: number;
|
|
57
|
+
}
|
|
58
|
+
export interface AntiGeneRolloutExecuteContext {
|
|
59
|
+
arm: AntiGeneRolloutArm;
|
|
60
|
+
task: AntiGeneRolloutTask;
|
|
61
|
+
store: AssetStoreProvider;
|
|
62
|
+
review: ReviewLedger;
|
|
63
|
+
armDir: string;
|
|
64
|
+
}
|
|
65
|
+
export type AntiGeneRolloutExecuteFactory = (context: AntiGeneRolloutExecuteContext) => CycleInput['execute'];
|
|
66
|
+
export interface AntiGeneRolloutDeps {
|
|
67
|
+
store: AssetStoreProvider;
|
|
68
|
+
review?: ReviewLedger;
|
|
69
|
+
makeExecute: AntiGeneRolloutExecuteFactory;
|
|
70
|
+
}
|
|
71
|
+
export interface AntiGeneRolloutOptions {
|
|
72
|
+
minSamples?: number;
|
|
73
|
+
minFailureDelta?: number;
|
|
74
|
+
now?: () => number;
|
|
75
|
+
eventsPath?: string;
|
|
76
|
+
}
|
|
77
|
+
export declare function runAntiGeneRollout(suite: AntiGeneRolloutSuite, deps: AntiGeneRolloutDeps, options?: AntiGeneRolloutOptions): Promise<AntiGeneRolloutReport>;
|
|
78
|
+
export declare function writeAntiGeneRolloutResult(report: AntiGeneRolloutReport, eventsPath: string, now?: () => number): Promise<void>;
|
|
79
|
+
export declare function antiGeneRolloutReportsFromEvents(events: readonly ReportEvent[]): AntiGeneRolloutReport[];
|
|
80
|
+
export declare function latestAntiGeneRolloutReport(events: readonly ReportEvent[]): AntiGeneRolloutReport | null;
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
import { mkdtempSync, rmSync } from 'node:fs';
|
|
2
|
+
import { tmpdir } from 'node:os';
|
|
3
|
+
import { join } from 'node:path';
|
|
4
|
+
import { LocalJsonlProvider } from '../assetstore/localJsonl.js';
|
|
5
|
+
import { ReviewLedger } from '../assetstore/reviewLedger.js';
|
|
6
|
+
import { Ingestor } from '../events/ingest.js';
|
|
7
|
+
import { LineTooLargeError } from '../events/eventStore.js';
|
|
8
|
+
import { CycleEngine } from '../algo/cycleEngine.js';
|
|
9
|
+
import { runEvolutionCycle } from '../algo/orchestrator.js';
|
|
10
|
+
import { makeGeneSelectionPoint } from '../algo/geneSelection.js';
|
|
11
|
+
const ALL_ASSETS_LIMIT = Number.MAX_SAFE_INTEGER;
|
|
12
|
+
const ASSET_KINDS = ['Gene', 'Capsule', 'EvolutionEvent', 'AntiGene'];
|
|
13
|
+
function buildProblem(task, now) {
|
|
14
|
+
return {
|
|
15
|
+
id: task.id,
|
|
16
|
+
signature: `anti-gene-rollout:${task.id}`,
|
|
17
|
+
signatureV: 1,
|
|
18
|
+
firstSeenAt: new Date(now - 1000).toISOString(),
|
|
19
|
+
lastSeenAt: new Date(now).toISOString(),
|
|
20
|
+
occurrences: 3,
|
|
21
|
+
linkedSignals: task.signals,
|
|
22
|
+
resolvedBy: null,
|
|
23
|
+
status: 'open',
|
|
24
|
+
value: { severity: 1, reach: 1, strategicFit: 1, novelty: 0, costEst: 0 },
|
|
25
|
+
consecutiveFailures: 0,
|
|
26
|
+
cooldownUntil: null,
|
|
27
|
+
extensions: {},
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
async function copyAssets(source, dest, includeApprovedAntiGenes, sourceReview) {
|
|
31
|
+
for (const kind of ASSET_KINDS) {
|
|
32
|
+
for (const asset of await source.list(kind, ALL_ASSETS_LIMIT)) {
|
|
33
|
+
if (kind === 'AntiGene') {
|
|
34
|
+
if (!includeApprovedAntiGenes)
|
|
35
|
+
continue;
|
|
36
|
+
if (sourceReview.get(String(asset.asset_id))?.state !== 'approved')
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
await dest.put(asset);
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function copyReview(source, dest) {
|
|
44
|
+
for (const record of source.records()) {
|
|
45
|
+
dest.mark({
|
|
46
|
+
assetId: record.assetId,
|
|
47
|
+
state: record.state,
|
|
48
|
+
...(record.by ? { by: record.by } : {}),
|
|
49
|
+
...(record.reason ? { reason: record.reason } : {}),
|
|
50
|
+
at: record.at,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
function defaultReviewForStore(store, now) {
|
|
55
|
+
const baseDir = store.baseDir;
|
|
56
|
+
return typeof baseDir === 'string' ? new ReviewLedger(baseDir, now) : null;
|
|
57
|
+
}
|
|
58
|
+
function observedWarningIds(decision) {
|
|
59
|
+
if (!decision || typeof decision !== 'object')
|
|
60
|
+
return [];
|
|
61
|
+
const warnings = decision.antiWarnings;
|
|
62
|
+
if (!Array.isArray(warnings))
|
|
63
|
+
return [];
|
|
64
|
+
return warnings
|
|
65
|
+
.map((warning) => {
|
|
66
|
+
if (!warning || typeof warning !== 'object' || Array.isArray(warning))
|
|
67
|
+
return '';
|
|
68
|
+
const row = warning;
|
|
69
|
+
return String(row.antiGeneId ?? row.assetId ?? '');
|
|
70
|
+
})
|
|
71
|
+
.filter(Boolean);
|
|
72
|
+
}
|
|
73
|
+
function missingExpected(expected, observed) {
|
|
74
|
+
const seen = new Set(observed);
|
|
75
|
+
return (expected ?? []).filter((id) => !seen.has(id));
|
|
76
|
+
}
|
|
77
|
+
function statusFromResult(result) {
|
|
78
|
+
return result.finalStage === 'solidified' ? 'success' : 'failed';
|
|
79
|
+
}
|
|
80
|
+
function scoreFromResult(result, status) {
|
|
81
|
+
const score = result.capsule?.outcome?.score;
|
|
82
|
+
return typeof score === 'number' && Number.isFinite(score) ? score : status === 'success' ? 0.9 : 0.2;
|
|
83
|
+
}
|
|
84
|
+
async function runOneArm(arm, task, source, sourceReview, makeExecute, rootDir, now) {
|
|
85
|
+
const armDir = join(rootDir, arm, task.id);
|
|
86
|
+
const store = new LocalJsonlProvider(join(armDir, 'assets'));
|
|
87
|
+
const review = new ReviewLedger(join(armDir, 'assets'), now);
|
|
88
|
+
await copyAssets(source, store, arm === 'antiGene', sourceReview);
|
|
89
|
+
copyReview(sourceReview, review);
|
|
90
|
+
const eventPath = join(armDir, 'events.jsonl');
|
|
91
|
+
const engine = new CycleEngine({
|
|
92
|
+
ingestor: new Ingestor({ path: eventPath, now }),
|
|
93
|
+
selection: makeGeneSelectionPoint(),
|
|
94
|
+
store,
|
|
95
|
+
now,
|
|
96
|
+
});
|
|
97
|
+
const opts = {
|
|
98
|
+
cycleId: `${arm}-${task.id}`,
|
|
99
|
+
problem: buildProblem(task, now()),
|
|
100
|
+
signals: task.signals,
|
|
101
|
+
category: task.category ?? 'repair',
|
|
102
|
+
target: task.target ?? 't.ts',
|
|
103
|
+
expectedEffect: task.expectedEffect ?? `anti-gene rollout ${task.id}`,
|
|
104
|
+
summary: task.summary ?? `anti-gene rollout ${task.id}`,
|
|
105
|
+
confidence: task.confidence ?? 0.9,
|
|
106
|
+
execute: makeExecute({ arm, task, store, review, armDir }),
|
|
107
|
+
review,
|
|
108
|
+
consumePendingSignals: false,
|
|
109
|
+
};
|
|
110
|
+
const result = await runEvolutionCycle(engine, store, opts);
|
|
111
|
+
const status = statusFromResult(result);
|
|
112
|
+
const observed = observedWarningIds(result.decision);
|
|
113
|
+
return {
|
|
114
|
+
status,
|
|
115
|
+
score: scoreFromResult(result, status),
|
|
116
|
+
repeatedFailure: status === 'failed' && (task.expectedAntiWarnings?.length ?? 0) > 0,
|
|
117
|
+
overblocked: false,
|
|
118
|
+
observedAntiWarnings: observed,
|
|
119
|
+
missingExpectedWarnings: arm === 'antiGene' ? missingExpected(task.expectedAntiWarnings, observed) : [],
|
|
120
|
+
selectedGeneId: result.decision?.selectedGeneId ?? null,
|
|
121
|
+
};
|
|
122
|
+
}
|
|
123
|
+
function armMetrics(arm, results) {
|
|
124
|
+
const n = results.length;
|
|
125
|
+
const failures = results.filter((r) => r.status === 'failed').length;
|
|
126
|
+
return {
|
|
127
|
+
arm,
|
|
128
|
+
n,
|
|
129
|
+
failures,
|
|
130
|
+
failureRate: n > 0 ? failures / n : 0,
|
|
131
|
+
repeatedFailures: results.filter((r) => r.repeatedFailure).length,
|
|
132
|
+
overblocked: results.filter((r) => r.overblocked).length,
|
|
133
|
+
observedWarnings: results.reduce((sum, r) => sum + r.observedAntiWarnings.length, 0),
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
function verdict(report, minSamples, minFailureDelta) {
|
|
137
|
+
if (report.baseline.n < minSamples || report.antiGene.n < minSamples)
|
|
138
|
+
return 'insufficient_samples';
|
|
139
|
+
if (report.failureDelta >= minFailureDelta && report.antiGene.observedWarnings > 0 && report.missingExpectedWarnings === 0)
|
|
140
|
+
return 'anti_gene_better';
|
|
141
|
+
if (report.failureDelta < -minFailureDelta || (minFailureDelta === 0 && report.failureDelta < 0))
|
|
142
|
+
return 'anti_gene_worse';
|
|
143
|
+
return 'no_clear_improvement';
|
|
144
|
+
}
|
|
145
|
+
function normalizeTaskResults(taskResults) {
|
|
146
|
+
return taskResults.map((task) => {
|
|
147
|
+
const overblocked = task.baseline.status === 'success' && task.antiGene.status === 'failed';
|
|
148
|
+
return {
|
|
149
|
+
taskId: task.taskId,
|
|
150
|
+
baseline: { ...task.baseline, overblocked: false },
|
|
151
|
+
antiGene: { ...task.antiGene, overblocked, repeatedFailure: overblocked ? false : task.antiGene.repeatedFailure },
|
|
152
|
+
};
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
function buildReport(suite, rawTaskResults, minSamples, minFailureDelta) {
|
|
156
|
+
const taskResults = normalizeTaskResults(rawTaskResults);
|
|
157
|
+
const baseline = armMetrics('baseline', taskResults.map((r) => r.baseline));
|
|
158
|
+
const antiGene = armMetrics('antiGene', taskResults.map((r) => r.antiGene));
|
|
159
|
+
const partial = {
|
|
160
|
+
suite: suite.name,
|
|
161
|
+
tasks: suite.tasks.length,
|
|
162
|
+
baseline,
|
|
163
|
+
antiGene,
|
|
164
|
+
missingExpectedWarnings: taskResults.reduce((sum, r) => sum + r.antiGene.missingExpectedWarnings.length, 0),
|
|
165
|
+
overblocked: antiGene.overblocked,
|
|
166
|
+
failureDelta: baseline.failureRate - antiGene.failureRate,
|
|
167
|
+
taskResults,
|
|
168
|
+
};
|
|
169
|
+
return { ...partial, verdict: verdict(partial, minSamples, minFailureDelta) };
|
|
170
|
+
}
|
|
171
|
+
export async function runAntiGeneRollout(suite, deps, options = {}) {
|
|
172
|
+
const now = options.now ?? Date.now;
|
|
173
|
+
const sourceReview = deps.review ?? defaultReviewForStore(deps.store, now);
|
|
174
|
+
if (!sourceReview)
|
|
175
|
+
throw new Error('AntiGene rollout requires a ReviewLedger or a LocalJsonlProvider-backed store so review state can be copied');
|
|
176
|
+
const minSamples = options.minSamples ?? 30;
|
|
177
|
+
const minFailureDelta = options.minFailureDelta ?? 0.05;
|
|
178
|
+
const rootDir = mkdtempSync(join(tmpdir(), 'anti-gene-rollout-'));
|
|
179
|
+
try {
|
|
180
|
+
const taskResults = [];
|
|
181
|
+
for (const task of suite.tasks) {
|
|
182
|
+
taskResults.push({
|
|
183
|
+
taskId: task.id,
|
|
184
|
+
baseline: await runOneArm('baseline', task, deps.store, sourceReview, deps.makeExecute, rootDir, now),
|
|
185
|
+
antiGene: await runOneArm('antiGene', task, deps.store, sourceReview, deps.makeExecute, rootDir, now),
|
|
186
|
+
});
|
|
187
|
+
}
|
|
188
|
+
const report = buildReport(suite, taskResults, minSamples, minFailureDelta);
|
|
189
|
+
if (options.eventsPath)
|
|
190
|
+
await writeAntiGeneRolloutResult(report, options.eventsPath, now);
|
|
191
|
+
return report;
|
|
192
|
+
}
|
|
193
|
+
finally {
|
|
194
|
+
rmSync(rootDir, { recursive: true, force: true });
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
export async function writeAntiGeneRolloutResult(report, eventsPath, now = Date.now) {
|
|
198
|
+
const ingestor = new Ingestor({ path: eventsPath, now });
|
|
199
|
+
try {
|
|
200
|
+
await ingestReportPayload(ingestor, report);
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
if (!(error instanceof LineTooLargeError))
|
|
204
|
+
throw error;
|
|
205
|
+
await ingestReportPayload(ingestor, compactReportPayload(report, 5));
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
async function ingestReportPayload(ingestor, payload) {
|
|
209
|
+
await ingestor.ingest({
|
|
210
|
+
type: 'anti_gene.rollout_result',
|
|
211
|
+
human: { title: `anti-gene rollout ${payload.suite}` },
|
|
212
|
+
payload: payload,
|
|
213
|
+
actor: { kind: 'machine', id: 'anti-gene-rollout' },
|
|
214
|
+
});
|
|
215
|
+
}
|
|
216
|
+
function compactWarnings(items) {
|
|
217
|
+
return items.slice(0, 3);
|
|
218
|
+
}
|
|
219
|
+
function compactRunResult(result) {
|
|
220
|
+
return {
|
|
221
|
+
...result,
|
|
222
|
+
observedAntiWarnings: compactWarnings(result.observedAntiWarnings),
|
|
223
|
+
missingExpectedWarnings: compactWarnings(result.missingExpectedWarnings),
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
function compactReportPayload(report, maxTasks) {
|
|
227
|
+
return {
|
|
228
|
+
...report,
|
|
229
|
+
taskResults: report.taskResults.slice(0, maxTasks).map((task) => ({
|
|
230
|
+
taskId: task.taskId,
|
|
231
|
+
baseline: compactRunResult(task.baseline),
|
|
232
|
+
antiGene: compactRunResult(task.antiGene),
|
|
233
|
+
})),
|
|
234
|
+
taskResultsTruncated: Math.max(0, report.taskResults.length - maxTasks),
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
function isReportPayload(value) {
|
|
238
|
+
return !!value && typeof value === 'object'
|
|
239
|
+
&& typeof value.suite === 'string'
|
|
240
|
+
&& typeof value.tasks === 'number'
|
|
241
|
+
&& typeof value.verdict === 'string';
|
|
242
|
+
}
|
|
243
|
+
export function antiGeneRolloutReportsFromEvents(events) {
|
|
244
|
+
const out = [];
|
|
245
|
+
for (const event of events) {
|
|
246
|
+
if (event.type !== 'anti_gene.rollout_result')
|
|
247
|
+
continue;
|
|
248
|
+
if (isReportPayload(event.payload))
|
|
249
|
+
out.push(event.payload);
|
|
250
|
+
}
|
|
251
|
+
return out;
|
|
252
|
+
}
|
|
253
|
+
export function latestAntiGeneRolloutReport(events) {
|
|
254
|
+
const reports = antiGeneRolloutReportsFromEvents(events);
|
|
255
|
+
return reports[reports.length - 1] ?? null;
|
|
256
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { Strategy } from '../strategy/strategyPoint.js';
|
|
2
|
+
import { computeFitness, type FitnessSample, type FitnessScore, type FitnessWeights } from '../strategy/experiment.js';
|
|
3
|
+
export interface BenchmarkCase<I> {
|
|
4
|
+
id: string;
|
|
5
|
+
input: I;
|
|
6
|
+
}
|
|
7
|
+
export interface BenchmarkSuite<I, O> {
|
|
8
|
+
name: string;
|
|
9
|
+
cases: ReadonlyArray<BenchmarkCase<I>>;
|
|
10
|
+
/** 评分: 给定 case 输入与策略输出, 产 fitness 样本(resolved/reuse/cost). */
|
|
11
|
+
score: (input: I, output: O, caseId: string) => FitnessSample;
|
|
12
|
+
}
|
|
13
|
+
export interface BenchmarkRunResult {
|
|
14
|
+
strategy: string;
|
|
15
|
+
version: string;
|
|
16
|
+
fitness: FitnessScore;
|
|
17
|
+
}
|
|
18
|
+
export interface BenchmarkReport {
|
|
19
|
+
suite: string;
|
|
20
|
+
results: BenchmarkRunResult[];
|
|
21
|
+
winner: string;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Benchmark 框架(M4-BM, D9). 对比进化算法各策略在同一题集上的 fitness, 排名选优.
|
|
25
|
+
* EverOS/SkillOpt 作**对照基线**(原创为主, 非复刻); 算法自进化时拿它当锚.
|
|
26
|
+
*/
|
|
27
|
+
export declare function runBenchmark<I, O>(suite: BenchmarkSuite<I, O>, strategies: ReadonlyArray<Strategy<I, O>>, weights?: FitnessWeights): Promise<BenchmarkReport>;
|
|
28
|
+
/** EverOS 风格对照: 倾向复用既有 skill(reuse-first). 仅作比较锚, 非复刻. */
|
|
29
|
+
export declare function everosControl<I, O>(run: (input: I) => O): Strategy<I, O>;
|
|
30
|
+
/** SkillOpt 风格对照: 倾向优化单一最优 skill. 仅作比较锚, 非复刻. */
|
|
31
|
+
export declare function skillOptControl<I, O>(run: (input: I) => O): Strategy<I, O>;
|
|
32
|
+
export { computeFitness };
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { offlineReplay, computeFitness, DEFAULT_WEIGHTS } from '../strategy/experiment.js';
|
|
2
|
+
/**
|
|
3
|
+
* Benchmark 框架(M4-BM, D9). 对比进化算法各策略在同一题集上的 fitness, 排名选优.
|
|
4
|
+
* EverOS/SkillOpt 作**对照基线**(原创为主, 非复刻); 算法自进化时拿它当锚.
|
|
5
|
+
*/
|
|
6
|
+
export async function runBenchmark(suite, strategies, weights = DEFAULT_WEIGHTS) {
|
|
7
|
+
const inputs = suite.cases.map((c) => c.input);
|
|
8
|
+
const ctxOf = (i) => ({ now: 0, cycleId: `bm-${suite.cases[i]?.id ?? i}` });
|
|
9
|
+
const results = [];
|
|
10
|
+
for (const s of strategies) {
|
|
11
|
+
const fitness = await offlineReplay(s, inputs, (input, output) => suite.score(input, output, ''), ctxOf, weights);
|
|
12
|
+
results.push({ strategy: s.name, version: s.version, fitness });
|
|
13
|
+
}
|
|
14
|
+
results.sort((a, b) => b.fitness.score - a.fitness.score);
|
|
15
|
+
return { suite: suite.name, results, winner: results[0]?.strategy ?? '' };
|
|
16
|
+
}
|
|
17
|
+
/* ── 对照基线(标注为 control, 不是真实现, D9) ── */
|
|
18
|
+
/** EverOS 风格对照: 倾向复用既有 skill(reuse-first). 仅作比较锚, 非复刻. */
|
|
19
|
+
export function everosControl(run) {
|
|
20
|
+
return { name: 'everos-control', version: 'baseline', run: (input) => run(input) };
|
|
21
|
+
}
|
|
22
|
+
/** SkillOpt 风格对照: 倾向优化单一最优 skill. 仅作比较锚, 非复刻. */
|
|
23
|
+
export function skillOptControl(run) {
|
|
24
|
+
return { name: 'skillopt-control', version: 'baseline', run: (input) => run(input) };
|
|
25
|
+
}
|
|
26
|
+
export { computeFitness };
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { AssetStoreProvider } from '../assetstore/provider.js';
|
|
2
|
+
import { type CycleInput, type CycleResult } from '../algo/cycleEngine.js';
|
|
3
|
+
import { type RunCycleOptions } from '../algo/orchestrator.js';
|
|
4
|
+
import type { ThesisArm, ThesisSolver, ThesisTask } from './thesis.js';
|
|
5
|
+
export interface EvolutionThesisDeps<I> {
|
|
6
|
+
/** evolver arm store: the learned-gene pool (assembleCandidates pulls candidates from here). */
|
|
7
|
+
pool: AssetStoreProvider;
|
|
8
|
+
/** baseline arm store: no relevant genes, so the cycle innovates (no reuse). */
|
|
9
|
+
baseline: AssetStoreProvider;
|
|
10
|
+
/** Agent work; a deterministic fake in tests, makeSafeExecute(...) in prod. */
|
|
11
|
+
execute: CycleInput['execute'];
|
|
12
|
+
/** Map a thesis task to the cycle inputs (problem / signals / category / target / ...). */
|
|
13
|
+
toCycleOpts: (task: ThesisTask<I>) => Omit<RunCycleOptions, 'cycleId' | 'execute'>;
|
|
14
|
+
now?: () => number;
|
|
15
|
+
/** Event-log path per run (default: a fresh temp file per run). */
|
|
16
|
+
eventsPath?: (arm: ThesisArm, taskId: string) => string;
|
|
17
|
+
/** Normalized cost from the cycle result (default 1). */
|
|
18
|
+
cost?: (r: CycleResult) => number;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Build a ThesisSolver that drives the real CycleEngine + orchestrator. Feed the resulting solver to
|
|
22
|
+
* runThesis(). In production: pool = the gene pool, baseline = a fresh empty store, execute =
|
|
23
|
+
* makeSafeExecute(repo, store, safety, { validate }) so `passed` reflects an objective validation.
|
|
24
|
+
*/
|
|
25
|
+
export declare function makeEvolutionThesisSolver<I>(deps: EvolutionThesisDeps<I>): ThesisSolver<I>;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
// Wire the honest thesis A/B harness to the REAL evolution loop. The evolver arm runs runEvolutionCycle
|
|
2
|
+
// against the learned-gene pool (so selection can reuse a gene); the baseline arm runs against an empty
|
|
3
|
+
// store (so it always innovates). Both use the same injected `execute` (a fake in tests; makeSafeExecute
|
|
4
|
+
// in prod) and the same task. Objective outcome = the cycle reached 'solidified' (success, as decided by
|
|
5
|
+
// the execute/validation hook); reuse = a gene was selected. Nothing about reuse feeds the pass/fail.
|
|
6
|
+
import { mkdtempSync } from 'node:fs';
|
|
7
|
+
import { tmpdir } from 'node:os';
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
import { Ingestor } from '../events/ingest.js';
|
|
10
|
+
import { CycleEngine } from '../algo/cycleEngine.js';
|
|
11
|
+
import { runEvolutionCycle } from '../algo/orchestrator.js';
|
|
12
|
+
import { makeGeneSelectionPoint } from '../algo/geneSelection.js';
|
|
13
|
+
/**
|
|
14
|
+
* Build a ThesisSolver that drives the real CycleEngine + orchestrator. Feed the resulting solver to
|
|
15
|
+
* runThesis(). In production: pool = the gene pool, baseline = a fresh empty store, execute =
|
|
16
|
+
* makeSafeExecute(repo, store, safety, { validate }) so `passed` reflects an objective validation.
|
|
17
|
+
*/
|
|
18
|
+
export function makeEvolutionThesisSolver(deps) {
|
|
19
|
+
const now = deps.now ?? (() => Date.now());
|
|
20
|
+
const eventsPath = deps.eventsPath
|
|
21
|
+
?? ((arm, taskId) => join(mkdtempSync(join(tmpdir(), 'thesis-')), `${arm}-${taskId}.jsonl`));
|
|
22
|
+
return async (task, arm) => {
|
|
23
|
+
const store = arm === 'evolver' ? deps.pool : deps.baseline;
|
|
24
|
+
const engine = new CycleEngine({
|
|
25
|
+
ingestor: new Ingestor({ path: eventsPath(arm, task.id), now }),
|
|
26
|
+
selection: makeGeneSelectionPoint(),
|
|
27
|
+
store,
|
|
28
|
+
now,
|
|
29
|
+
});
|
|
30
|
+
const r = await runEvolutionCycle(engine, store, {
|
|
31
|
+
cycleId: `${arm}-${task.id}`,
|
|
32
|
+
...deps.toCycleOpts(task),
|
|
33
|
+
execute: deps.execute,
|
|
34
|
+
});
|
|
35
|
+
return {
|
|
36
|
+
passed: r.finalStage === 'solidified', // success is decided by the execute/validation hook, not self-report
|
|
37
|
+
reusedGene: !!r.decision?.selectedGeneId,
|
|
38
|
+
cost: deps.cost ? deps.cost(r) : 1,
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
export type ThesisArm = 'baseline' | 'evolver';
|
|
2
|
+
export interface ThesisTask<I> {
|
|
3
|
+
id: string;
|
|
4
|
+
input: I;
|
|
5
|
+
}
|
|
6
|
+
/** One task's objective result for one arm. */
|
|
7
|
+
export interface ThesisOutcome {
|
|
8
|
+
/** Objectively solved (e.g. the validation hook passed). Decided by a verifier, not the agent. */
|
|
9
|
+
passed: boolean;
|
|
10
|
+
/** Normalized cost (tokens/time/etc.; caller defines the unit). */
|
|
11
|
+
cost: number;
|
|
12
|
+
/** Whether a prior gene was reused this run (descriptive only — never counted toward the verdict). */
|
|
13
|
+
reusedGene: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Solver seam: the real agent plugs in here (arm='evolver' runs with the learned-gene pool, 'baseline'
|
|
17
|
+
* runs without it). Tests inject a deterministic fake, so the harness is never bound to a live LLM.
|
|
18
|
+
*/
|
|
19
|
+
export type ThesisSolver<I> = (task: ThesisTask<I>, arm: ThesisArm) => Promise<ThesisOutcome> | ThesisOutcome;
|
|
20
|
+
export interface ArmReport {
|
|
21
|
+
arm: ThesisArm;
|
|
22
|
+
n: number;
|
|
23
|
+
/** Tasks the arm objectively passed — the numerator behind passRate, kept so the verdict can run a real
|
|
24
|
+
* two-proportion test (rates alone lose the counts the test needs). */
|
|
25
|
+
passes: number;
|
|
26
|
+
passRate: number;
|
|
27
|
+
avgCost: number;
|
|
28
|
+
/** Descriptive only, does not affect the verdict. baseline is ~0 (no gene pool). */
|
|
29
|
+
reuseRate: number;
|
|
30
|
+
}
|
|
31
|
+
export type ThesisVerdict = 'evolver_better' | 'no_significant_diff' | 'evolver_worse' | 'insufficient_samples';
|
|
32
|
+
export interface ThesisReport {
|
|
33
|
+
suite: string;
|
|
34
|
+
baseline: ArmReport;
|
|
35
|
+
evolver: ArmReport;
|
|
36
|
+
/** evolver.passRate - baseline.passRate. The practical-significance input to the verdict. */
|
|
37
|
+
passRateDelta: number;
|
|
38
|
+
/** evolver.avgCost - baseline.avgCost. */
|
|
39
|
+
costDelta: number;
|
|
40
|
+
/** Two-proportion z statistic for (evolver − baseline) pass rates (pooled-variance test). 0 when undefined. */
|
|
41
|
+
z: number;
|
|
42
|
+
/** Two-sided p-value for `z` (normal approximation). 1 when the test is undefined (zero variance). */
|
|
43
|
+
pValue: number;
|
|
44
|
+
/** Whether the pass-rate difference is statistically significant at `alpha` (pValue <= alpha). A REQUIREMENT
|
|
45
|
+
* for an evolver_better/worse verdict — a practical delta alone (>= minPassRateDelta) is no longer enough,
|
|
46
|
+
* because at small n a 5pt delta is well inside sampling noise (the headline thesis number must be defensible). */
|
|
47
|
+
significant: boolean;
|
|
48
|
+
/** (1 − alpha) Wald confidence interval for passRateDelta. When it straddles 0 the difference is not significant. */
|
|
49
|
+
ciLow: number;
|
|
50
|
+
ciHigh: number;
|
|
51
|
+
/** Achieved power to detect an effect of size minPassRateDelta at the OBSERVED baseline rate and this n (alpha
|
|
52
|
+
* two-sided). The number a bare `no_significant_diff` hides: a LOW power means the null is underpowered (the
|
|
53
|
+
* experiment couldn't have seen the minimum interesting effect), not that there is no effect. 0 when undefined. */
|
|
54
|
+
power: number;
|
|
55
|
+
/** Per-arm sample size needed to reach `targetPower` for a minPassRateDelta effect at the observed baseline rate.
|
|
56
|
+
* Actionable "run ~N tasks/arm" guidance; Infinity when minPassRateDelta is 0 (no effect size to power for). */
|
|
57
|
+
requiredN: number;
|
|
58
|
+
verdict: ThesisVerdict;
|
|
59
|
+
}
|
|
60
|
+
export interface ThesisOptions {
|
|
61
|
+
/** Min absolute passRate gain to call evolver better/worse (default 0.05) — the PRACTICAL bar. */
|
|
62
|
+
minPassRateDelta?: number;
|
|
63
|
+
/** Significance level for the two-proportion test (default 0.05) — the STATISTICAL bar. The verdict needs both. */
|
|
64
|
+
alpha?: number;
|
|
65
|
+
/** Min samples per arm before drawing a verdict (default 30); below it => insufficient_samples. */
|
|
66
|
+
minSamples?: number;
|
|
67
|
+
/** Target power for the requiredN guidance + the underpowered read of a null (default 0.8). */
|
|
68
|
+
targetPower?: number;
|
|
69
|
+
/**
|
|
70
|
+
* Interleave arms per task: run baseline then evolver on each task before moving to the next,
|
|
71
|
+
* instead of all-baseline first then all-evolver. Prevents API rate limits from hitting the
|
|
72
|
+
* second arm disproportionately (the serial default runs baseline entirely first, so evolver
|
|
73
|
+
* faces the tail-end of a rate-limit window).
|
|
74
|
+
*/
|
|
75
|
+
interleave?: boolean;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Run both arms over the same task suite and compare. A verdict of evolver_better/worse requires BOTH a practical
|
|
79
|
+
* delta (|passRateDelta| >= minPassRateDelta) AND statistical significance (two-proportion test p <= alpha);
|
|
80
|
+
* otherwise no_significant_diff. reuseRate and costDelta are reported, never scored.
|
|
81
|
+
*/
|
|
82
|
+
export declare function runThesis<I>(suite: {
|
|
83
|
+
name: string;
|
|
84
|
+
tasks: readonly ThesisTask<I>[];
|
|
85
|
+
}, solver: ThesisSolver<I>, opts?: ThesisOptions): Promise<ThesisReport>;
|