@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,24 @@
|
|
|
1
|
+
import { ulid as makeUlid } from 'ulid';
|
|
2
|
+
import { computeAssetId, SCHEMA_VERSION } from '../wire/index.js';
|
|
3
|
+
/**
|
|
4
|
+
* EvolutionEvent = 世代记录(outcome 真值在此, 硬化 A4). 单向引 Capsule(capsule_id);
|
|
5
|
+
* 写入序列: capsule asset_id 先算 → 填 capsule_id → 再算 event asset_id.
|
|
6
|
+
*/
|
|
7
|
+
export function buildEvolutionEvent(input) {
|
|
8
|
+
const base = {
|
|
9
|
+
type: 'EvolutionEvent',
|
|
10
|
+
schema_version: SCHEMA_VERSION,
|
|
11
|
+
id: makeUlid(),
|
|
12
|
+
parent: input.parent ?? null,
|
|
13
|
+
intent: input.intent,
|
|
14
|
+
signals: [...input.signals],
|
|
15
|
+
genes_used: [...input.genesUsed],
|
|
16
|
+
mutation_id: input.mutationId,
|
|
17
|
+
blast_radius: input.blastRadius,
|
|
18
|
+
outcome: input.outcome,
|
|
19
|
+
capsule_id: input.capsuleId,
|
|
20
|
+
source_type: input.sourceType,
|
|
21
|
+
};
|
|
22
|
+
const asset_id = computeAssetId(base);
|
|
23
|
+
return { ...base, asset_id };
|
|
24
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export type PlateauSeverity = 'suggested' | 'required';
|
|
2
|
+
export interface PlateauState {
|
|
3
|
+
active: boolean;
|
|
4
|
+
severity: PlateauSeverity;
|
|
5
|
+
count: number;
|
|
6
|
+
}
|
|
7
|
+
/** Exploration control fed into selection. Absent → pure deterministic top-score selection. */
|
|
8
|
+
export interface ExplorationInput {
|
|
9
|
+
/** Force drift on even without a plateau (e.g. an explicit explore policy). */
|
|
10
|
+
driftEnabled?: boolean;
|
|
11
|
+
/** Plateau detected upstream; an active plateau forces drift intensity up. */
|
|
12
|
+
plateau?: PlateauState;
|
|
13
|
+
/** Total attempts across the candidate pool (drives the maturity decay of the drift offset). */
|
|
14
|
+
totalAttempts?: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Adaptive drift intensity (ported v1): 1/sqrt(Ne) + an offset that decays from 0.3 → 0.02 as the pool
|
|
18
|
+
* matures (totalAttempts approaches Ne * 10). Tiny pools (Ne <= 1) get a fixed high 0.7 to force exploration.
|
|
19
|
+
*/
|
|
20
|
+
export declare function computeDriftIntensity(ne: number, totalAttempts?: number): number;
|
|
21
|
+
/** Detect a plateau from recent cycle outcomes: count the trailing run of consecutive non-success. */
|
|
22
|
+
export declare function detectPlateau(recentOutcomes: readonly ('success' | 'failed')[]): PlateauState;
|
|
23
|
+
export interface DriftDecision {
|
|
24
|
+
driftMode: 'deterministic' | 'drift' | 'plateau_drift';
|
|
25
|
+
index: number;
|
|
26
|
+
intensity: number;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Pick which ranked candidate to take among `eligibleCount` above-floor candidates.
|
|
30
|
+
* No exploration → deterministic top (index 0). With exploration → compute intensity (an active plateau
|
|
31
|
+
* forces it to 0.7/1.0); with probability = intensity, pick a random candidate from the top-N (N grows
|
|
32
|
+
* with intensity). rng() is called at most twice; pass a seeded rng for deterministic tests.
|
|
33
|
+
*/
|
|
34
|
+
export declare function driftSelect(eligibleCount: number, exp: ExplorationInput | undefined, rng: () => number): DriftDecision;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
// Exploration layer (ported from v1 src/gep/selector.js): adaptive drift intensity + plateau override
|
|
2
|
+
// to escape local optima. v2 selection is deterministic by default (always the top score); drift stays
|
|
3
|
+
// OFF unless the caller passes SelectionInput.exploration (typically when a plateau is detected upstream).
|
|
4
|
+
// When active, the strategy occasionally picks from the top-N candidates instead of the single top —
|
|
5
|
+
// random exploration to break a stuck pool. Randomness is injected (ctx.rng) for deterministic tests.
|
|
6
|
+
const MATURITY_ATTEMPTS_PER_GENE = 10;
|
|
7
|
+
const DRIFT_OFFSET_MAX = 0.3;
|
|
8
|
+
const DRIFT_OFFSET_MIN = 0.02;
|
|
9
|
+
const PLATEAU_SUGGEST = 5;
|
|
10
|
+
const PLATEAU_FORCE = 10;
|
|
11
|
+
/**
|
|
12
|
+
* Adaptive drift intensity (ported v1): 1/sqrt(Ne) + an offset that decays from 0.3 → 0.02 as the pool
|
|
13
|
+
* matures (totalAttempts approaches Ne * 10). Tiny pools (Ne <= 1) get a fixed high 0.7 to force exploration.
|
|
14
|
+
*/
|
|
15
|
+
export function computeDriftIntensity(ne, totalAttempts = 0) {
|
|
16
|
+
if (!Number.isFinite(ne) || ne <= 1)
|
|
17
|
+
return 0.7;
|
|
18
|
+
const maturityThreshold = ne * MATURITY_ATTEMPTS_PER_GENE;
|
|
19
|
+
const maturity = maturityThreshold > 0 ? Math.min(1, totalAttempts / maturityThreshold) : 0;
|
|
20
|
+
const offset = DRIFT_OFFSET_MAX - (DRIFT_OFFSET_MAX - DRIFT_OFFSET_MIN) * maturity;
|
|
21
|
+
return Math.min(1, 1 / Math.sqrt(ne) + offset);
|
|
22
|
+
}
|
|
23
|
+
/** Detect a plateau from recent cycle outcomes: count the trailing run of consecutive non-success. */
|
|
24
|
+
export function detectPlateau(recentOutcomes) {
|
|
25
|
+
let count = 0;
|
|
26
|
+
for (let i = recentOutcomes.length - 1; i >= 0; i--) {
|
|
27
|
+
if (recentOutcomes[i] === 'success')
|
|
28
|
+
break;
|
|
29
|
+
count++;
|
|
30
|
+
}
|
|
31
|
+
if (count >= PLATEAU_FORCE)
|
|
32
|
+
return { active: true, severity: 'required', count };
|
|
33
|
+
if (count >= PLATEAU_SUGGEST)
|
|
34
|
+
return { active: true, severity: 'suggested', count };
|
|
35
|
+
return { active: false, severity: 'suggested', count };
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Pick which ranked candidate to take among `eligibleCount` above-floor candidates.
|
|
39
|
+
* No exploration → deterministic top (index 0). With exploration → compute intensity (an active plateau
|
|
40
|
+
* forces it to 0.7/1.0); with probability = intensity, pick a random candidate from the top-N (N grows
|
|
41
|
+
* with intensity). rng() is called at most twice; pass a seeded rng for deterministic tests.
|
|
42
|
+
*/
|
|
43
|
+
export function driftSelect(eligibleCount, exp, rng) {
|
|
44
|
+
if (!exp || (!exp.driftEnabled && !exp.plateau?.active) || eligibleCount <= 1) {
|
|
45
|
+
return { driftMode: 'deterministic', index: 0, intensity: 0 };
|
|
46
|
+
}
|
|
47
|
+
let intensity = computeDriftIntensity(eligibleCount, exp.totalAttempts ?? 0);
|
|
48
|
+
if (exp.plateau?.active)
|
|
49
|
+
intensity = Math.max(intensity, exp.plateau.severity === 'required' ? 1.0 : 0.7);
|
|
50
|
+
if (rng() >= intensity)
|
|
51
|
+
return { driftMode: 'deterministic', index: 0, intensity };
|
|
52
|
+
const topN = Math.min(eligibleCount, Math.max(2, Math.ceil(eligibleCount * intensity)));
|
|
53
|
+
const index = Math.min(topN - 1, Math.max(0, Math.floor(rng() * topN)));
|
|
54
|
+
return { driftMode: exp.plateau?.active ? 'plateau_drift' : 'drift', index, intensity };
|
|
55
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { GeneLearningView } from '../assetstore/learningHistory.js';
|
|
2
|
+
/** 统一 gene 健康分(算法草案§7 自然选择反馈). 并 learning_history/epigenetic/anti_patterns. */
|
|
3
|
+
export interface GeneHealth {
|
|
4
|
+
geneId: string;
|
|
5
|
+
successRate: number;
|
|
6
|
+
reuseCount: number;
|
|
7
|
+
antiPatternPenalty: number;
|
|
8
|
+
score: number;
|
|
9
|
+
}
|
|
10
|
+
export interface GeneHealthWeights {
|
|
11
|
+
successRate: number;
|
|
12
|
+
reuse: number;
|
|
13
|
+
antiPattern: number;
|
|
14
|
+
}
|
|
15
|
+
export declare const HEALTH_WEIGHTS_VERSION = "gh-1";
|
|
16
|
+
export declare const DEFAULT_HEALTH_WEIGHTS: GeneHealthWeights;
|
|
17
|
+
/**
|
|
18
|
+
* gene 健康分 = w1·successRate + w2·reuse归一 − w3·antiPattern密度.
|
|
19
|
+
* 输入 = M3-6 聚合视图(不内联 learning_history) + anti_patterns 数 + 复用计数.
|
|
20
|
+
*/
|
|
21
|
+
export declare function geneHealthScore(view: GeneLearningView, opts?: {
|
|
22
|
+
reuseCount?: number;
|
|
23
|
+
antiPatternCount?: number;
|
|
24
|
+
}, w?: GeneHealthWeights): GeneHealth;
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export const HEALTH_WEIGHTS_VERSION = 'gh-1';
|
|
2
|
+
export const DEFAULT_HEALTH_WEIGHTS = { successRate: 0.6, reuse: 0.3, antiPattern: 0.4 };
|
|
3
|
+
/** reuseCount 归一(对数压缩, 复用越多分越高但边际递减). */
|
|
4
|
+
function reuseScore(count) {
|
|
5
|
+
return count <= 0 ? 0 : Math.min(1, Math.log10(count + 1) / 2); // 100 次≈封顶
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* gene 健康分 = w1·successRate + w2·reuse归一 − w3·antiPattern密度.
|
|
9
|
+
* 输入 = M3-6 聚合视图(不内联 learning_history) + anti_patterns 数 + 复用计数.
|
|
10
|
+
*/
|
|
11
|
+
export function geneHealthScore(view, opts = {}, w = DEFAULT_HEALTH_WEIGHTS) {
|
|
12
|
+
const reuseCount = opts.reuseCount ?? view.total;
|
|
13
|
+
const antiPatternPenalty = Math.min(1, (opts.antiPatternCount ?? 0) / 5); // 5+ anti-pattern 封顶惩罚
|
|
14
|
+
const score = w.successRate * view.successRate + w.reuse * reuseScore(reuseCount) - w.antiPattern * antiPatternPenalty;
|
|
15
|
+
return { geneId: view.geneId, successRate: view.successRate, reuseCount, antiPatternPenalty, score };
|
|
16
|
+
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type Gene } from '../wire/index.js';
|
|
2
|
+
/**
|
|
3
|
+
* True when a gene id is a distilled (skill-derived) gene. Single source of truth for the prefix check — also
|
|
4
|
+
* consumed by candidate assembly / selection to recognise the broadly-applicable distilled genes that may be
|
|
5
|
+
* reused as a last-resort fallback when no gene matches the live signals (ported from v1 #97).
|
|
6
|
+
*/
|
|
7
|
+
export declare function isDistilledGeneId(id: string | undefined | null): boolean;
|
|
8
|
+
export interface GeneCandidate {
|
|
9
|
+
id?: string;
|
|
10
|
+
category?: string;
|
|
11
|
+
signals_match?: readonly string[];
|
|
12
|
+
strategy?: readonly string[];
|
|
13
|
+
summary?: string;
|
|
14
|
+
preconditions?: readonly string[];
|
|
15
|
+
constraints?: {
|
|
16
|
+
max_files?: number;
|
|
17
|
+
forbidden_paths?: readonly string[];
|
|
18
|
+
};
|
|
19
|
+
validation?: readonly string[];
|
|
20
|
+
routing_hint?: unknown;
|
|
21
|
+
tool_policy?: unknown;
|
|
22
|
+
}
|
|
23
|
+
/** Minimal shape of an existing gene needed for dedup. */
|
|
24
|
+
export interface ExistingGeneRef {
|
|
25
|
+
id?: string;
|
|
26
|
+
signals_match?: readonly string[];
|
|
27
|
+
}
|
|
28
|
+
export interface GeneIntakeResult {
|
|
29
|
+
ok: boolean;
|
|
30
|
+
gene?: Gene;
|
|
31
|
+
errors: string[];
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Validate + normalize a distilled/proposed gene for pool insertion. On success returns the canonical Gene
|
|
35
|
+
* (defaults filled, asset_id computed); otherwise the structural / dedup / schema errors.
|
|
36
|
+
*/
|
|
37
|
+
export declare function intakeGene(candidate: GeneCandidate, existing?: readonly ExistingGeneRef[]): GeneIntakeResult;
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
// Gene intake — the structural part of skill distillation (ported from v1 src/gep/skillDistiller.js).
|
|
2
|
+
// v2's solidify produces Capsules but never Genes, so the reusable gene pool is otherwise static (only
|
|
3
|
+
// seeded/imported). This is the safe INTAKE gate for a distilled/proposed gene before it joins the pool:
|
|
4
|
+
// normalize defaults, validate structure + the gep-sdk schema, recompute asset_id, and reject a gene whose
|
|
5
|
+
// signals fully overlap an existing one (dedup, so the pool does not grow redundant). The gene's CONTENT
|
|
6
|
+
// is generated upstream (the agent runtime / a distillation prompt — generative, out of core scope); this
|
|
7
|
+
// slice is the structural gate. Pairs with capabilityCandidates (which proposes what to distill).
|
|
8
|
+
import { computeAssetId, validateWire, SCHEMA_VERSION, normalizeRoutingHint, normalizeToolPolicy, stripGeneHints, } from '../wire/index.js';
|
|
9
|
+
const VALID_CATEGORIES = ['repair', 'optimize', 'innovate', 'explore'];
|
|
10
|
+
const DEFAULT_FORBIDDEN_PATHS = ['.git', 'node_modules'];
|
|
11
|
+
const DEFAULT_MAX_FILES = 12;
|
|
12
|
+
/** Id prefix every distilled (skill-derived) gene carries. Recognised via {@link isDistilledGeneId}. */
|
|
13
|
+
const DISTILLED_ID_PREFIX = 'gene_distilled_';
|
|
14
|
+
/**
|
|
15
|
+
* True when a gene id is a distilled (skill-derived) gene. Single source of truth for the prefix check — also
|
|
16
|
+
* consumed by candidate assembly / selection to recognise the broadly-applicable distilled genes that may be
|
|
17
|
+
* reused as a last-resort fallback when no gene matches the live signals (ported from v1 #97).
|
|
18
|
+
*/
|
|
19
|
+
export function isDistilledGeneId(id) {
|
|
20
|
+
return typeof id === 'string' && id.startsWith(DISTILLED_ID_PREFIX);
|
|
21
|
+
}
|
|
22
|
+
function fnv1a(s) {
|
|
23
|
+
let h = 2166136261;
|
|
24
|
+
for (let i = 0; i < s.length; i++) {
|
|
25
|
+
h ^= s.charCodeAt(i);
|
|
26
|
+
h = Math.imul(h, 16777619);
|
|
27
|
+
}
|
|
28
|
+
return (h >>> 0).toString(16).padStart(8, '0');
|
|
29
|
+
}
|
|
30
|
+
const clean = (xs) => (xs ?? []).map((s) => String(s).trim()).filter((s) => s.length > 0);
|
|
31
|
+
/** Returns the id of an existing gene whose signals are a superset of `signals` (i.e. the candidate is redundant), else null. */
|
|
32
|
+
function fullyOverlaps(signals, existing) {
|
|
33
|
+
const newSet = signals.map((s) => s.toLowerCase());
|
|
34
|
+
for (const eg of existing) {
|
|
35
|
+
const egSet = new Set((eg.signals_match ?? []).map((s) => String(s).toLowerCase()));
|
|
36
|
+
if (egSet.size === 0)
|
|
37
|
+
continue;
|
|
38
|
+
if (newSet.every((s) => egSet.has(s)))
|
|
39
|
+
return eg.id ?? '?';
|
|
40
|
+
}
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Validate + normalize a distilled/proposed gene for pool insertion. On success returns the canonical Gene
|
|
45
|
+
* (defaults filled, asset_id computed); otherwise the structural / dedup / schema errors.
|
|
46
|
+
*/
|
|
47
|
+
export function intakeGene(candidate, existing = []) {
|
|
48
|
+
const errors = [];
|
|
49
|
+
const signals = clean(candidate.signals_match);
|
|
50
|
+
const strategy = clean(candidate.strategy);
|
|
51
|
+
if (signals.length === 0)
|
|
52
|
+
errors.push('signals_match is empty');
|
|
53
|
+
if (strategy.length === 0)
|
|
54
|
+
errors.push('strategy is empty');
|
|
55
|
+
if (signals.length > 0) {
|
|
56
|
+
const dup = fullyOverlaps(signals, existing);
|
|
57
|
+
if (dup)
|
|
58
|
+
errors.push(`signals_match fully overlaps existing gene: ${dup}`);
|
|
59
|
+
}
|
|
60
|
+
if (errors.length > 0)
|
|
61
|
+
return { ok: false, errors };
|
|
62
|
+
const category = VALID_CATEGORIES.includes(candidate.category) ? candidate.category : 'optimize';
|
|
63
|
+
const id = candidate.id && candidate.id.startsWith(DISTILLED_ID_PREFIX) ? candidate.id : `${DISTILLED_ID_PREFIX}${fnv1a(signals.join('|'))}`;
|
|
64
|
+
// v2-delta EvoX hints (v1 PR #93): normalized so a candidate carrying them lands canonical, dropped to
|
|
65
|
+
// absent when malformed/empty. The router / tool-gate reads absent === "no opinion".
|
|
66
|
+
const routingHint = normalizeRoutingHint(candidate.routing_hint);
|
|
67
|
+
const toolPolicy = normalizeToolPolicy(candidate.tool_policy);
|
|
68
|
+
const gene = {
|
|
69
|
+
type: 'Gene',
|
|
70
|
+
schema_version: SCHEMA_VERSION,
|
|
71
|
+
id,
|
|
72
|
+
category,
|
|
73
|
+
signals_match: signals,
|
|
74
|
+
strategy,
|
|
75
|
+
constraints: {
|
|
76
|
+
max_files: candidate.constraints?.max_files ?? DEFAULT_MAX_FILES,
|
|
77
|
+
forbidden_paths: [...(candidate.constraints?.forbidden_paths ?? DEFAULT_FORBIDDEN_PATHS)],
|
|
78
|
+
},
|
|
79
|
+
validation: candidate.validation ? [...candidate.validation] : [],
|
|
80
|
+
summary: candidate.summary ?? `Strategy for: ${signals.slice(0, 3).join(', ')}`,
|
|
81
|
+
...(candidate.preconditions ? { preconditions: [...candidate.preconditions] } : {}),
|
|
82
|
+
...(routingHint ? { routing_hint: routingHint } : {}),
|
|
83
|
+
...(toolPolicy ? { tool_policy: toolPolicy } : {}),
|
|
84
|
+
asset_id: '',
|
|
85
|
+
};
|
|
86
|
+
// asset_id folds in the hints (intake's own canonical shape — gep-sdk canonicalize hashes every own key).
|
|
87
|
+
// NB: this is NOT byte-equal to what v1's createGene would hash for the same logical gene — v1 always emits
|
|
88
|
+
// routing_hint/tool_policy:null plus empty epigenetic_marks/learning_history/anti_patterns/preconditions that
|
|
89
|
+
// v2 intake omits, so the canonical shapes differ. Self-consistent here; not a cross-impl parity guarantee.
|
|
90
|
+
gene.asset_id = computeAssetId(gene) ?? '';
|
|
91
|
+
// Structural gate validates the gep-sdk-known CORE. routing_hint / tool_policy are v2-delta (pending a
|
|
92
|
+
// gene-schema bump), so strip them before the check — else additionalProperties:false rejects the gene at
|
|
93
|
+
// intake. The full hinted gene stays schema-invalid until the SDK catches up — surfaced by the advisory
|
|
94
|
+
// validateWire preview (evolver_gep_build) and enforced by the hub on receipt, NOT by a local egress gate
|
|
95
|
+
// (the publish/egress path is sanitize-only). Same v2-delta contract Capsule's proof_of_work had pre-1.11.0.
|
|
96
|
+
const v = validateWire(stripGeneHints(gene));
|
|
97
|
+
if (!v.ok)
|
|
98
|
+
return { ok: false, errors: v.errors };
|
|
99
|
+
return { ok: true, gene, errors: [] };
|
|
100
|
+
}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { AssetStoreProvider } from '../assetstore/provider.js';
|
|
2
|
+
import type { ReviewLedger } from '../assetstore/reviewLedger.js';
|
|
3
|
+
export interface AutoPromoteOptions {
|
|
4
|
+
/** Min real (value-producing) successes — with ZERO failures — before a quarantined draft is auto-approved. */
|
|
5
|
+
minSuccess?: number;
|
|
6
|
+
/** Who/why stamp for the audited approval. Defaults to the auto-promoter. */
|
|
7
|
+
by?: string;
|
|
8
|
+
}
|
|
9
|
+
/** The default proven-success bar. Symmetric to reuse-report's prune threshold (a few clean signals, not one). */
|
|
10
|
+
export declare const DEFAULT_PROMOTE_MIN_SUCCESS = 3;
|
|
11
|
+
/**
|
|
12
|
+
* The single promote predicate: a quarantined gene auto-promotes iff it has ZERO failures AND at least minSuccess
|
|
13
|
+
* real (value-producing) successes. Inert (zero-work) successes are excluded by aggregateLearningHistory, so they
|
|
14
|
+
* never count here. Every surface that judges promote-eligibility (auto-promote, reuse-report --promote, the
|
|
15
|
+
* review listing) MUST route through this so they cannot diverge — e.g. a gene the review view labels "healthy"
|
|
16
|
+
* by success-rate but that still has a failure must read as NOT promotable here.
|
|
17
|
+
*/
|
|
18
|
+
export declare function probationWouldPromote(view: {
|
|
19
|
+
success: number;
|
|
20
|
+
failed: number;
|
|
21
|
+
}, minSuccess?: number): boolean;
|
|
22
|
+
/** A quarantined gene's evidence so far, measured against the promote threshold. Read-only: this is what the
|
|
23
|
+
* daemon's auto-promote tick decides on, surfaced so an operator can SEE the probation pool before flipping
|
|
24
|
+
* EVOLVER_GENE_PROBATION on. `wouldPromote` is the exact predicate autoPromoteProbationGenes acts on. */
|
|
25
|
+
export interface ProbationStatus {
|
|
26
|
+
assetId: string;
|
|
27
|
+
geneId: string;
|
|
28
|
+
success: number;
|
|
29
|
+
failed: number;
|
|
30
|
+
inert: number;
|
|
31
|
+
total: number;
|
|
32
|
+
/** The bar this status was scored against (echoes the option for display). */
|
|
33
|
+
minSuccess: number;
|
|
34
|
+
/** True iff this gene would be auto-approved right now (0 failures AND success >= minSuccess). */
|
|
35
|
+
wouldPromote: boolean;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Read-only scan of the review ledger: for every QUARANTINED gene, derive its learning evidence and whether it
|
|
39
|
+
* meets the promote bar right now. The single source of truth for the promote predicate — autoPromoteProbationGenes
|
|
40
|
+
* acts on exactly this, and reuse-report --promote displays it. Never mutates the ledger.
|
|
41
|
+
*/
|
|
42
|
+
export declare function scanProbationGenes(store: AssetStoreProvider, review: ReviewLedger, opts?: Pick<AutoPromoteOptions, 'minSuccess'>): Promise<ProbationStatus[]>;
|
|
43
|
+
/**
|
|
44
|
+
* Scan the review ledger for quarantined genes and auto-approve those whose cycle outcomes prove their value
|
|
45
|
+
* (>= minSuccess real successes AND 0 failures). Returns the asset_ids promoted. Never promotes a gene with any
|
|
46
|
+
* failure, nor one whose only "successes" were inert. Idempotent: an already-approved/rejected gene is skipped.
|
|
47
|
+
*/
|
|
48
|
+
export declare function autoPromoteProbationGenes(store: AssetStoreProvider, review: ReviewLedger, opts?: AutoPromoteOptions): Promise<string[]>;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { aggregateLearningHistory } from '../assetstore/learningHistory.js';
|
|
2
|
+
/** The default proven-success bar. Symmetric to reuse-report's prune threshold (a few clean signals, not one). */
|
|
3
|
+
export const DEFAULT_PROMOTE_MIN_SUCCESS = 3;
|
|
4
|
+
/**
|
|
5
|
+
* The single promote predicate: a quarantined gene auto-promotes iff it has ZERO failures AND at least minSuccess
|
|
6
|
+
* real (value-producing) successes. Inert (zero-work) successes are excluded by aggregateLearningHistory, so they
|
|
7
|
+
* never count here. Every surface that judges promote-eligibility (auto-promote, reuse-report --promote, the
|
|
8
|
+
* review listing) MUST route through this so they cannot diverge — e.g. a gene the review view labels "healthy"
|
|
9
|
+
* by success-rate but that still has a failure must read as NOT promotable here.
|
|
10
|
+
*/
|
|
11
|
+
export function probationWouldPromote(view, minSuccess = DEFAULT_PROMOTE_MIN_SUCCESS) {
|
|
12
|
+
return view.failed === 0 && view.success >= minSuccess;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Read-only scan of the review ledger: for every QUARANTINED gene, derive its learning evidence and whether it
|
|
16
|
+
* meets the promote bar right now. The single source of truth for the promote predicate — autoPromoteProbationGenes
|
|
17
|
+
* acts on exactly this, and reuse-report --promote displays it. Never mutates the ledger.
|
|
18
|
+
*/
|
|
19
|
+
export async function scanProbationGenes(store, review, opts = {}) {
|
|
20
|
+
const minSuccess = opts.minSuccess ?? DEFAULT_PROMOTE_MIN_SUCCESS;
|
|
21
|
+
const out = [];
|
|
22
|
+
for (const rec of review.records()) {
|
|
23
|
+
if (rec.state !== 'quarantined')
|
|
24
|
+
continue; // only probation drafts; human approve/reject is left alone
|
|
25
|
+
const gene = await store.get(rec.assetId);
|
|
26
|
+
if (!gene || gene.type !== 'Gene')
|
|
27
|
+
continue;
|
|
28
|
+
const geneId = typeof gene['id'] === 'string' ? String(gene['id']) : rec.assetId;
|
|
29
|
+
const view = await aggregateLearningHistory(store, geneId);
|
|
30
|
+
out.push({
|
|
31
|
+
assetId: rec.assetId, geneId,
|
|
32
|
+
success: view.success, failed: view.failed, inert: view.inert ?? 0, total: view.total,
|
|
33
|
+
minSuccess, wouldPromote: probationWouldPromote(view, minSuccess),
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
return out;
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Scan the review ledger for quarantined genes and auto-approve those whose cycle outcomes prove their value
|
|
40
|
+
* (>= minSuccess real successes AND 0 failures). Returns the asset_ids promoted. Never promotes a gene with any
|
|
41
|
+
* failure, nor one whose only "successes" were inert. Idempotent: an already-approved/rejected gene is skipped.
|
|
42
|
+
*/
|
|
43
|
+
export async function autoPromoteProbationGenes(store, review, opts = {}) {
|
|
44
|
+
const by = opts.by ?? 'auto-promote';
|
|
45
|
+
const promoted = [];
|
|
46
|
+
for (const s of await scanProbationGenes(store, review, opts)) {
|
|
47
|
+
if (!s.wouldPromote)
|
|
48
|
+
continue;
|
|
49
|
+
review.approve(s.assetId, by, `evidence: ${s.success}/${s.total} success, 0 fail (auto-promote #306)`);
|
|
50
|
+
promoted.push(s.assetId);
|
|
51
|
+
}
|
|
52
|
+
return promoted;
|
|
53
|
+
}
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import type { Strategy } from '../strategy/strategyPoint.js';
|
|
2
|
+
import { StrategyPoint } from '../strategy/strategyPoint.js';
|
|
3
|
+
import { type GeneHealth } from './geneHealth.js';
|
|
4
|
+
import type { GeneLearningView } from '../assetstore/learningHistory.js';
|
|
5
|
+
import type { AssetRecord } from '../assetstore/provider.js';
|
|
6
|
+
import { type ExplorationInput } from './exploration.js';
|
|
7
|
+
/** 一个候选 gene 的选择期素材. */
|
|
8
|
+
export interface GeneCandidateInput {
|
|
9
|
+
geneId: string;
|
|
10
|
+
/**
|
|
11
|
+
* Content asset_id (sha256:…) of this candidate, when distinct from the logical geneId. Optional. Lets the
|
|
12
|
+
* cross-runtime reuse map (#268, keyed by reuse-event assetId) match a candidate by EITHER id — local genes
|
|
13
|
+
* supply it from their record; an injected hub candidate can carry it so it is matched on the same footing.
|
|
14
|
+
*/
|
|
15
|
+
assetId?: string;
|
|
16
|
+
signalsMatch: readonly string[];
|
|
17
|
+
view: GeneLearningView;
|
|
18
|
+
reuseCount?: number;
|
|
19
|
+
antiPatternCount?: number;
|
|
20
|
+
/** Optional gene category/summary for semantic tag expansion (signal-expansion recall, ported from v1). */
|
|
21
|
+
category?: string;
|
|
22
|
+
summary?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Full hub-fetched Gene payload, when an adapter injects a transient reuse candidate. Selection never reads this;
|
|
25
|
+
* autoexec uses it to land the asset through the provenance/review gates before the candidate can be executed.
|
|
26
|
+
*/
|
|
27
|
+
hubAsset?: AssetRecord;
|
|
28
|
+
/** Epigenetic penalty for the current environment class (subtracted from score; computed upstream, ported from v1). */
|
|
29
|
+
epigeneticPenalty?: number;
|
|
30
|
+
/**
|
|
31
|
+
* Preferred-gene confidence in [0,1] for the current signal fingerprint (added to score; positive cross-cycle
|
|
32
|
+
* learning, computed upstream from the confidence sidecar, ported from v1). A gene that keeps succeeding under
|
|
33
|
+
* the same signals is nudged up. This is a SOFT re-ordering factor only: it is applied to the same candidate
|
|
34
|
+
* set the hard gates already produced, so a high confidence can never resurrect a gene that was excluded.
|
|
35
|
+
*/
|
|
36
|
+
confidence?: number;
|
|
37
|
+
/**
|
|
38
|
+
* Cross-runtime reuse sentiment in [-1, 1] for this gene (#268 phase 1): the net of self-reported reuse
|
|
39
|
+
* SUCCESSes vs negatives (failed/mismatched/stale/unsafe), computed upstream from reuse-outcome events
|
|
40
|
+
* (reuseAdjustFromSummary). A SOFT, bounded re-order factor — added with a small weight and clamped — so this
|
|
41
|
+
* weak, self-reported signal can nudge near-ties (and down-rank a gene foreign agents keep finding unhelpful)
|
|
42
|
+
* yet can NEVER override the hard gates (trust/review/ban run in assembly, before scoring). Absent → 0 → no
|
|
43
|
+
* effect, so the factor is dormant until a caller injects the signal (default-off).
|
|
44
|
+
*/
|
|
45
|
+
reuseAdjust?: number;
|
|
46
|
+
}
|
|
47
|
+
export interface SelectionInput {
|
|
48
|
+
signals: readonly string[];
|
|
49
|
+
candidates: readonly GeneCandidateInput[];
|
|
50
|
+
/** 低于此分则不选(→ 走 innovate 新基因), 默认 0. */
|
|
51
|
+
floor?: number;
|
|
52
|
+
/**
|
|
53
|
+
* Explicit gene requested by GEP / an external runtime. This is a hard selection only within the already
|
|
54
|
+
* assembled candidate/fallback pools: it cannot resurrect a gene filtered by trust/review/ban upstream, and it is
|
|
55
|
+
* refused here when the entry is epigenetically suppressed for the current environment. Accepts either logical
|
|
56
|
+
* geneId or content assetId.
|
|
57
|
+
*/
|
|
58
|
+
forcedGeneId?: string;
|
|
59
|
+
/** Exploration control (drift / plateau override). Absent → deterministic top-score selection (ported from v1). */
|
|
60
|
+
exploration?: ExplorationInput;
|
|
61
|
+
/**
|
|
62
|
+
* Distilled-gene fallback pool (ported from v1 #97): broadly-applicable distilled genes that do NOT match the
|
|
63
|
+
* live signals, supplied by the assembly layer (already trust/review/ban-filtered) so they never compete in the
|
|
64
|
+
* normal scored set. Used ONLY as a last resort when no candidate clears the floor: instead of falling straight
|
|
65
|
+
* through to a blind innovate, selection reuses a known distilled strategy. Epigenetically-suppressed entries
|
|
66
|
+
* (epigeneticPenalty > 0) are skipped — v2's event-log-derived epigeneticPenalty is the analog of v1's asset-mark
|
|
67
|
+
* hard suppression (a related band, not the identical predicate).
|
|
68
|
+
*/
|
|
69
|
+
distilledFallback?: readonly GeneCandidateInput[];
|
|
70
|
+
/**
|
|
71
|
+
* Non-executable negative memory matched for the current signals. These warnings are carried into the decision
|
|
72
|
+
* for prompt rendering only; they never enter scoring, fallback, or forced selection.
|
|
73
|
+
*/
|
|
74
|
+
antiWarnings?: readonly AntiWarning[];
|
|
75
|
+
}
|
|
76
|
+
export interface ScoredCandidate {
|
|
77
|
+
geneId: string;
|
|
78
|
+
assetId?: string;
|
|
79
|
+
score: number;
|
|
80
|
+
reasons: string[];
|
|
81
|
+
health?: GeneHealth;
|
|
82
|
+
}
|
|
83
|
+
export interface AntiWarning {
|
|
84
|
+
antiGeneId: string;
|
|
85
|
+
assetId?: string;
|
|
86
|
+
trigger: readonly string[];
|
|
87
|
+
avoid: readonly string[];
|
|
88
|
+
summary?: string;
|
|
89
|
+
severity?: 'low' | 'medium' | 'high';
|
|
90
|
+
rationale?: string;
|
|
91
|
+
}
|
|
92
|
+
/** 可解释的选择决策(禁黑盒, 军杰§9.4): 带 candidates/scores/reasons/weightsVersion. */
|
|
93
|
+
export interface GeneDecision {
|
|
94
|
+
selectedGeneId: string | null;
|
|
95
|
+
/** Content asset_id for the selected candidate when known. Preserves exact forced-by-asset execution semantics. */
|
|
96
|
+
selectedAssetId?: string;
|
|
97
|
+
candidates: ScoredCandidate[];
|
|
98
|
+
/** Advisory-only AntiGene guardrails; never selected, executed, or attributed as used genes. */
|
|
99
|
+
antiWarnings?: AntiWarning[];
|
|
100
|
+
weightsVersion: string;
|
|
101
|
+
strategyName: string;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Weight of the preferred-gene confidence factor (fourth factor, positive cross-cycle learning). Kept small so
|
|
105
|
+
* it only re-orders near-ties between already-eligible candidates rather than overriding health / signal match.
|
|
106
|
+
*/
|
|
107
|
+
export declare const CONFIDENCE_WEIGHT = 0.15;
|
|
108
|
+
/**
|
|
109
|
+
* Weight of the cross-runtime reuse-sentiment factor (#268 phase 1). Deliberately SMALLER than CONFIDENCE_WEIGHT:
|
|
110
|
+
* a self-reported reuse outcome is weaker evidence than the confidence sidecar (which is built from verified cycle
|
|
111
|
+
* history), so it only re-orders near-ties. Clamped to a [-1,1] sentiment, so its contribution is bounded to
|
|
112
|
+
* ±REUSE_WEIGHT and can never dominate health/signal-match.
|
|
113
|
+
*/
|
|
114
|
+
export declare const REUSE_WEIGHT = 0.1;
|
|
115
|
+
/**
|
|
116
|
+
* Version of the full engine-health weight vector (health 0.6 + signal-match 0.4 − epigenetic penalty
|
|
117
|
+
* + CONFIDENCE_WEIGHT × confidence + REUSE_WEIGHT × reuse-sentiment). Bumped whenever a factor is added so golden
|
|
118
|
+
* weight snapshots track the change. Composed from the health-weights version so a change to either layer shows.
|
|
119
|
+
*/
|
|
120
|
+
export declare const SELECTION_WEIGHTS_VERSION = "sel-3(gh-1,conf=0.15,reuse=0.1)";
|
|
121
|
+
/** 实现1: engine 健康分主导(health 0.6 + 信号匹配 0.4). */
|
|
122
|
+
export declare const engineHealthSelection: Strategy<SelectionInput, GeneDecision>;
|
|
123
|
+
/** 实现2: 纯信号匹配采样(忽略 health, 对照基线 — 经验主义要可对比). */
|
|
124
|
+
export declare const signalMatchSelection: Strategy<SelectionInput, GeneDecision>;
|
|
125
|
+
/** 实现3: agent 主导(注入决策回调; engine 只给候选+分, agent 拍板, D26 agent 一等公民). */
|
|
126
|
+
export declare function agentLedSelection(pick: (scored: ScoredCandidate[], input: SelectionInput) => string | null): Strategy<SelectionInput, GeneDecision>;
|
|
127
|
+
/** 选 gene StrategyPoint: 默认 engine-health, 备选 signal-match(+ 可注册 agent-led). */
|
|
128
|
+
export declare function makeGeneSelectionPoint(): StrategyPoint<SelectionInput, GeneDecision>;
|