@evomap/evolver-core 2.0.0-beta.19 → 2.0.0-beta.22
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/assets/gep/genes.jsonl +5 -5
- package/dist/algo/bans.d.ts +10 -1
- package/dist/algo/bans.js +56 -6
- package/dist/algo/candidateAssembly.d.ts +25 -2
- package/dist/algo/candidateAssembly.js +143 -20
- package/dist/algo/capabilityCandidates.js +10 -0
- package/dist/algo/cycleEngine.d.ts +40 -5
- package/dist/algo/cycleEngine.js +277 -37
- package/dist/algo/evolutionEvent.d.ts +26 -0
- package/dist/algo/evolutionEvent.js +32 -0
- package/dist/algo/exploration.d.ts +7 -0
- package/dist/algo/exploration.js +16 -3
- package/dist/algo/geneHealth.d.ts +34 -1
- package/dist/algo/geneHealth.js +42 -0
- package/dist/algo/geneIntake.d.ts +46 -1
- package/dist/algo/geneIntake.js +121 -10
- package/dist/algo/geneSelection.d.ts +115 -6
- package/dist/algo/geneSelection.js +459 -32
- package/dist/algo/index.d.ts +4 -1
- package/dist/algo/index.js +4 -1
- package/dist/algo/kautoProjection.d.ts +41 -0
- package/dist/algo/kautoProjection.js +95 -0
- package/dist/algo/kautoValidator.d.ts +68 -0
- package/dist/algo/kautoValidator.js +256 -0
- package/dist/algo/orchestrator.d.ts +14 -1
- package/dist/algo/orchestrator.js +9 -2
- package/dist/algo/solidify.d.ts +11 -2
- package/dist/algo/solidify.js +37 -7
- package/dist/algo/ucb1.d.ts +53 -0
- package/dist/algo/ucb1.js +156 -0
- package/dist/assetrepair/hubRejection.d.ts +12 -0
- package/dist/assetrepair/hubRejection.js +109 -0
- package/dist/assetrepair/index.d.ts +2 -0
- package/dist/assetrepair/index.js +2 -0
- package/dist/assetrepair/repair.d.ts +33 -0
- package/dist/assetrepair/repair.js +155 -0
- package/dist/assetstore/assetSidecarRecords.js +5 -1
- package/dist/assetstore/assetStoreHealth.d.ts +2 -3
- package/dist/assetstore/assetStoreHealth.js +4 -10
- package/dist/assetstore/foreignJsonlSource.d.ts +48 -0
- package/dist/assetstore/foreignJsonlSource.js +150 -0
- package/dist/assetstore/index.d.ts +3 -0
- package/dist/assetstore/index.js +3 -0
- package/dist/assetstore/learningHistory.js +3 -3
- package/dist/assetstore/localAssetStoreSnapshot.d.ts +51 -0
- package/dist/assetstore/localAssetStoreSnapshot.js +329 -0
- package/dist/assetstore/localJsonl.d.ts +8 -0
- package/dist/assetstore/localJsonl.js +128 -3
- package/dist/assetstore/provenance.d.ts +38 -3
- package/dist/assetstore/provenance.js +103 -45
- package/dist/assetstore/provider.d.ts +4 -0
- package/dist/assetstore/reviewFilter.d.ts +19 -1
- package/dist/assetstore/reviewFilter.js +36 -0
- package/dist/assetstore/unionReadStore.d.ts +25 -0
- package/dist/assetstore/unionReadStore.js +119 -0
- package/dist/benchmark/antiGeneBenchmark.d.ts +2 -0
- package/dist/benchmark/antiGeneBenchmark.js +4 -3
- package/dist/benchmark/antiGeneRollout.d.ts +2 -0
- package/dist/benchmark/antiGeneRollout.js +4 -3
- package/dist/benchmark/index.d.ts +2 -1
- package/dist/benchmark/index.js +2 -1
- package/dist/benchmark/selectionFlatAbstention.d.ts +152 -0
- package/dist/benchmark/selectionFlatAbstention.js +481 -0
- package/dist/bootstrap/envFingerprint.d.ts +9 -0
- package/dist/bootstrap/envFingerprint.js +5 -0
- package/dist/bootstrap/index.d.ts +2 -1
- package/dist/bootstrap/index.js +2 -1
- package/dist/bootstrap/lifecycleBootstrap.d.ts +111 -0
- package/dist/bootstrap/lifecycleBootstrap.js +433 -0
- package/dist/bootstrap/v1EnvCompat.d.ts +3 -0
- package/dist/bootstrap/v1EnvCompat.js +48 -1
- package/dist/events/eventArchive.d.ts +2 -0
- package/dist/events/eventArchive.js +13 -3
- package/dist/events/eventSchema.d.ts +7 -7
- package/dist/events/eventStore.d.ts +2 -0
- package/dist/events/eventStore.js +5 -1
- package/dist/events/ingest.d.ts +2 -1
- package/dist/events/ingest.js +6 -0
- package/dist/exec/autoExec.d.ts +30 -3
- package/dist/exec/autoExec.js +294 -29
- package/dist/exec/autonomousCycle.d.ts +7 -0
- package/dist/exec/autonomousCycle.js +2 -0
- package/dist/exec/claudeBridge.d.ts +28 -6
- package/dist/exec/claudeBridge.js +411 -258
- package/dist/exec/executionBinding.d.ts +414 -0
- package/dist/exec/executionBinding.js +588 -0
- package/dist/exec/index.d.ts +1 -0
- package/dist/exec/index.js +1 -0
- package/dist/exec/proofOfWork.d.ts +1 -1
- package/dist/exec/proofOfWork.js +2 -2
- package/dist/exec/runnerRegistry.d.ts +5 -0
- package/dist/exec/runnerRegistry.js +54 -14
- package/dist/hub/capability.d.ts +40 -1
- package/dist/hub/conversationDistiller.d.ts +19 -0
- package/dist/hub/conversationDistiller.js +115 -37
- package/dist/hub/fake.d.ts +1 -0
- package/dist/hub/fake.js +1 -0
- package/dist/hub/index.d.ts +1 -0
- package/dist/hub/index.js +1 -0
- package/dist/hub/recipeCompose.d.ts +27 -0
- package/dist/hub/recipeCompose.js +90 -0
- package/dist/hub/sanitize.js +119 -5
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/mailbox/ipcServer.d.ts +2 -0
- package/dist/mailbox/ipcServer.js +20 -0
- package/dist/mailbox/store.d.ts +52 -2
- package/dist/mailbox/store.js +546 -81
- package/dist/modelCompatibility.d.ts +164 -0
- package/dist/modelCompatibility.js +309 -0
- package/dist/observers/valueDigestObserver.d.ts +9 -0
- package/dist/observers/valueDigestObserver.js +35 -2
- package/dist/ops/cleanup.js +1 -1
- package/dist/ops/evolutionGraphProjection.d.ts +20 -0
- package/dist/ops/evolutionGraphProjection.js +315 -0
- package/dist/ops/index.d.ts +2 -1
- package/dist/ops/index.js +2 -1
- package/dist/ops/selfUpdate.d.ts +8 -0
- package/dist/ops/selfUpdate.js +24 -8
- package/dist/ops/valueOutreach.d.ts +3 -1
- package/dist/ops/valueOutreach.js +5 -1
- package/dist/personality/schema.d.ts +18 -18
- package/dist/schema/evolutionGraph.d.ts +784 -0
- package/dist/schema/evolutionGraph.js +187 -0
- package/dist/schema/index.d.ts +1 -0
- package/dist/schema/index.js +1 -0
- package/dist/schema/proofOfWork.d.ts +125 -6
- package/dist/schema/proofOfWork.js +102 -4
- package/dist/shadow/shadowHub.js +1 -0
- package/dist/signals/expand.d.ts +15 -1
- package/dist/signals/expand.js +148 -0
- package/dist/signals/index.d.ts +3 -1
- package/dist/signals/index.js +3 -1
- package/dist/signals/scopeVocabulary.d.ts +75 -0
- package/dist/signals/scopeVocabulary.js +91 -0
- package/dist/signals/taskDomain.d.ts +22 -0
- package/dist/signals/taskDomain.js +43 -0
- package/dist/trace/learningTrace.d.ts +7 -0
- package/dist/trace/learningTrace.js +22 -0
- package/dist/trace/trajectory.d.ts +8 -0
- package/dist/trace/trajectory.js +14 -2
- package/dist/util/fileLock.d.ts +92 -5
- package/dist/util/fileLock.js +809 -70
- package/dist/util/index.d.ts +2 -1
- package/dist/util/index.js +1 -1
- package/dist/verify/index.d.ts +2 -1
- package/dist/verify/index.js +1 -1
- package/dist/verify/sandboxRunner.d.ts +2 -0
- package/dist/verify/sandboxRunner.js +154 -10
- package/dist/verify/sandboxedValidation.d.ts +7 -2
- package/dist/verify/sandboxedValidation.js +102 -24
- package/dist/verify/validation.d.ts +24 -3
- package/dist/verify/validation.js +141 -24
- package/dist/wire/geneHints.d.ts +88 -16
- package/dist/wire/geneHints.js +124 -15
- package/dist/wire/index.d.ts +8 -3
- package/dist/wire/index.js +2 -2
- package/dist/wire/schemaGate.d.ts +21 -0
- package/dist/wire/schemaGate.js +119 -10
- package/package.json +5 -4
|
@@ -0,0 +1,481 @@
|
|
|
1
|
+
import { createHash, randomUUID } from 'node:crypto';
|
|
2
|
+
import { assessSelectionGuard, engineHealthSelection, } from '../algo/geneSelection.js';
|
|
3
|
+
export const SELECTION_FLAT_ABSTENTION_BENCHMARK_VERSION = 'global-flat-abstention-paired-v1';
|
|
4
|
+
const FULL_COMMIT_RE = /^[0-9a-f]{40}$/;
|
|
5
|
+
const SHA256_RE = /^sha256:[0-9a-f]{64}$/;
|
|
6
|
+
const SAFE_METADATA_RE = /^[A-Za-z0-9][A-Za-z0-9._-]{0,127}$/;
|
|
7
|
+
const CI95_ALPHA = 0.05;
|
|
8
|
+
function actionForDecision(decision) {
|
|
9
|
+
if (!decision.selectedGeneId)
|
|
10
|
+
return { kind: 'innovate' };
|
|
11
|
+
return {
|
|
12
|
+
kind: 'reuse',
|
|
13
|
+
geneId: decision.selectedGeneId,
|
|
14
|
+
...(decision.selectedAssetId ? { assetId: decision.selectedAssetId } : {}),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function actionsEqual(left, right) {
|
|
18
|
+
return left.kind === right.kind
|
|
19
|
+
&& (left.kind === 'innovate' || (right.kind === 'reuse'
|
|
20
|
+
&& left.geneId === right.geneId
|
|
21
|
+
&& left.assetId === right.assetId));
|
|
22
|
+
}
|
|
23
|
+
/** Compare production with a benchmark-only global flat-positive abstention counterfactual. */
|
|
24
|
+
export function compareOutsidePlateauFlatSelection(input) {
|
|
25
|
+
const currentDecision = engineHealthSelection.run({ ...input, selectionGuard: 'enforce' }, { now: 0, cycleId: 'benchmark-global-flat-abstention', rng: () => 0.5 });
|
|
26
|
+
const currentAction = actionForDecision(currentDecision);
|
|
27
|
+
const floor = input.floor ?? 0;
|
|
28
|
+
const eligible = currentDecision.candidates.filter((candidate) => candidate.score > floor);
|
|
29
|
+
const flatPoolAssessment = assessSelectionGuard(eligible, true);
|
|
30
|
+
const targeted = input.exploration?.plateau?.active !== true
|
|
31
|
+
&& input.exploration?.driftEnabled !== true
|
|
32
|
+
&& !input.forcedGeneId?.trim()
|
|
33
|
+
&& currentAction.kind === 'reuse'
|
|
34
|
+
&& currentDecision.selectionGuard?.status === 'allowed'
|
|
35
|
+
&& flatPoolAssessment.reason === 'plateau_flat_match';
|
|
36
|
+
return {
|
|
37
|
+
targeted,
|
|
38
|
+
...(targeted ? { targetReason: 'outside_plateau_flat_positive' } : {}),
|
|
39
|
+
currentDecision,
|
|
40
|
+
currentAction,
|
|
41
|
+
globalFlatAbstainAction: targeted ? { kind: 'innovate' } : currentAction,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
function assertSafeMetadata(value, field) {
|
|
45
|
+
if (typeof value !== 'string' || !SAFE_METADATA_RE.test(value)) {
|
|
46
|
+
throw new Error(`${field} must be a non-sensitive ASCII slug`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
function validateExpectedAction(action, field) {
|
|
50
|
+
if (action?.kind === 'innovate')
|
|
51
|
+
return;
|
|
52
|
+
if (action?.kind !== 'reuse' || typeof action.geneId !== 'string' || action.geneId.trim().length === 0) {
|
|
53
|
+
throw new Error(`${field} must be a valid selection action`);
|
|
54
|
+
}
|
|
55
|
+
if (action.assetId !== undefined && (typeof action.assetId !== 'string' || action.assetId.trim().length === 0)) {
|
|
56
|
+
throw new Error(`${field}.assetId must be non-empty when present`);
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
function sha256(value) {
|
|
60
|
+
return `sha256:${createHash('sha256').update(value).digest('hex')}`;
|
|
61
|
+
}
|
|
62
|
+
function encodeOwnProperties(value, context) {
|
|
63
|
+
if (Object.getOwnPropertySymbols(value).length > 0) {
|
|
64
|
+
throw new Error('task snapshot contains symbol keys');
|
|
65
|
+
}
|
|
66
|
+
const descriptors = Object.getOwnPropertyDescriptors(value);
|
|
67
|
+
return Object.getOwnPropertyNames(value).map((key) => {
|
|
68
|
+
const descriptor = descriptors[key];
|
|
69
|
+
if (descriptor.get || descriptor.set)
|
|
70
|
+
throw new Error('task snapshot contains accessor properties');
|
|
71
|
+
return `${JSON.stringify(key)}:${canonicalSnapshotValue(descriptor.value, context)}`;
|
|
72
|
+
}).join(',');
|
|
73
|
+
}
|
|
74
|
+
function canonicalSnapshotValue(value, context = { seen: new Map(), nextId: 0 }) {
|
|
75
|
+
if (value === null)
|
|
76
|
+
return 'null';
|
|
77
|
+
if (value === undefined)
|
|
78
|
+
return 'undefined';
|
|
79
|
+
if (typeof value === 'string')
|
|
80
|
+
return `string:${JSON.stringify(value)}`;
|
|
81
|
+
if (typeof value === 'boolean')
|
|
82
|
+
return value ? 'boolean:true' : 'boolean:false';
|
|
83
|
+
if (typeof value === 'number') {
|
|
84
|
+
if (!Number.isFinite(value))
|
|
85
|
+
throw new Error('task snapshot contains a non-finite number');
|
|
86
|
+
return `number:${Object.is(value, -0) ? '-0' : String(value)}`;
|
|
87
|
+
}
|
|
88
|
+
if (typeof value === 'bigint')
|
|
89
|
+
return `bigint:${value.toString()}`;
|
|
90
|
+
if (typeof value !== 'object') {
|
|
91
|
+
throw new Error(`task snapshot contains unsupported ${typeof value} data`);
|
|
92
|
+
}
|
|
93
|
+
const previousId = context.seen.get(value);
|
|
94
|
+
if (previousId !== undefined)
|
|
95
|
+
return `reference:${previousId}`;
|
|
96
|
+
const id = context.nextId;
|
|
97
|
+
context.nextId += 1;
|
|
98
|
+
context.seen.set(value, id);
|
|
99
|
+
if (Array.isArray(value)) {
|
|
100
|
+
return `array#${id}:{${encodeOwnProperties(value, context)}}`;
|
|
101
|
+
}
|
|
102
|
+
if (value instanceof Date) {
|
|
103
|
+
if (Number.isNaN(value.getTime()))
|
|
104
|
+
throw new Error('task snapshot contains an invalid date');
|
|
105
|
+
return `date#${id}:${value.toISOString()}:{${encodeOwnProperties(value, context)}}`;
|
|
106
|
+
}
|
|
107
|
+
if (value instanceof Map) {
|
|
108
|
+
const entries = [...value.entries()].map(([key, item]) => (`${canonicalSnapshotValue(key, context)}=>${canonicalSnapshotValue(item, context)}`));
|
|
109
|
+
return `map#${id}:[${entries.join(',')}]:{${encodeOwnProperties(value, context)}}`;
|
|
110
|
+
}
|
|
111
|
+
if (value instanceof Set) {
|
|
112
|
+
const entries = [...value].map((item) => canonicalSnapshotValue(item, context));
|
|
113
|
+
return `set#${id}:[${entries.join(',')}]:{${encodeOwnProperties(value, context)}}`;
|
|
114
|
+
}
|
|
115
|
+
if (ArrayBuffer.isView(value)) {
|
|
116
|
+
if (typeof SharedArrayBuffer !== 'undefined' && value.buffer instanceof SharedArrayBuffer) {
|
|
117
|
+
throw new Error('task snapshot must not contain SharedArrayBuffer-backed views');
|
|
118
|
+
}
|
|
119
|
+
return `view#${id}:${value.constructor.name}:${value.byteOffset}:${value.byteLength}:${canonicalSnapshotValue(value.buffer, context)}:{${encodeOwnProperties(value, context)}}`;
|
|
120
|
+
}
|
|
121
|
+
if (typeof SharedArrayBuffer !== 'undefined' && value instanceof SharedArrayBuffer) {
|
|
122
|
+
throw new Error('task snapshot must not contain SharedArrayBuffer');
|
|
123
|
+
}
|
|
124
|
+
if (value instanceof ArrayBuffer) {
|
|
125
|
+
return `array-buffer#${id}:${Buffer.from(value).toString('hex')}:{${encodeOwnProperties(value, context)}}`;
|
|
126
|
+
}
|
|
127
|
+
const prototype = Object.getPrototypeOf(value);
|
|
128
|
+
if (prototype !== Object.prototype && prototype !== null) {
|
|
129
|
+
throw new Error('task snapshot contains unsupported non-plain object data');
|
|
130
|
+
}
|
|
131
|
+
return `object#${id}:{${encodeOwnProperties(value, context)}}`;
|
|
132
|
+
}
|
|
133
|
+
function cloneStructured(value, errorMessage) {
|
|
134
|
+
try {
|
|
135
|
+
return structuredClone(value);
|
|
136
|
+
}
|
|
137
|
+
catch {
|
|
138
|
+
throw new Error(errorMessage);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/** Compute the digest that the cohort manifest must pre-register for this exact task snapshot. */
|
|
142
|
+
export function computeSelectionFlatTaskFingerprint(task) {
|
|
143
|
+
const snapshot = cloneStructured(task, 'task snapshot must be structured-cloneable for fingerprinting');
|
|
144
|
+
return sha256(canonicalSnapshotValue([
|
|
145
|
+
SELECTION_FLAT_ABSTENTION_BENCHMARK_VERSION,
|
|
146
|
+
snapshot.id,
|
|
147
|
+
snapshot.workspaceSnapshotDigest,
|
|
148
|
+
snapshot.split,
|
|
149
|
+
snapshot.stratum,
|
|
150
|
+
snapshot.payload,
|
|
151
|
+
snapshot.selection,
|
|
152
|
+
snapshot.expectation,
|
|
153
|
+
]));
|
|
154
|
+
}
|
|
155
|
+
function isolationKey(datasetDigest, executionNonce, fingerprint, arm) {
|
|
156
|
+
return sha256(`${datasetDigest}\0${executionNonce}\0${fingerprint}\0${arm}`);
|
|
157
|
+
}
|
|
158
|
+
function validateSuite(suite) {
|
|
159
|
+
assertSafeMetadata(suite.name, 'suite.name');
|
|
160
|
+
assertSafeMetadata(suite.cohort.id, 'cohort.id');
|
|
161
|
+
assertSafeMetadata(suite.cohort.version, 'cohort.version');
|
|
162
|
+
assertSafeMetadata(suite.cohort.verifier.id, 'cohort.verifier.id');
|
|
163
|
+
assertSafeMetadata(suite.cohort.verifier.version, 'cohort.verifier.version');
|
|
164
|
+
if (typeof suite.cohort.sourceCommit !== 'string'
|
|
165
|
+
|| !FULL_COMMIT_RE.test(suite.cohort.sourceCommit)) {
|
|
166
|
+
throw new Error('cohort.sourceCommit must be a full lowercase 40-hex commit');
|
|
167
|
+
}
|
|
168
|
+
if (suite.cohort.taskFingerprints.length !== suite.tasks.length) {
|
|
169
|
+
throw new Error('pre-registered cohort does not match the benchmark tasks');
|
|
170
|
+
}
|
|
171
|
+
const ids = new Set();
|
|
172
|
+
const fingerprints = new Set();
|
|
173
|
+
for (const [index, task] of suite.tasks.entries()) {
|
|
174
|
+
assertSafeMetadata(task.id, `tasks[${index}].id`);
|
|
175
|
+
assertSafeMetadata(task.stratum, `tasks[${index}].stratum`);
|
|
176
|
+
if (task.split !== 'calibration' && task.split !== 'holdout') {
|
|
177
|
+
throw new Error(`invalid split for task ${task.id}`);
|
|
178
|
+
}
|
|
179
|
+
if (typeof task.workspaceSnapshotDigest !== 'string'
|
|
180
|
+
|| !SHA256_RE.test(task.workspaceSnapshotDigest)) {
|
|
181
|
+
throw new Error(`invalid workspace snapshot digest for task ${task.id}`);
|
|
182
|
+
}
|
|
183
|
+
if (task.expectation?.role !== 'target' && task.expectation?.role !== 'control') {
|
|
184
|
+
throw new Error(`invalid expected role for task ${task.id}`);
|
|
185
|
+
}
|
|
186
|
+
validateExpectedAction(task.expectation.currentAction, `task ${task.id} current expectation`);
|
|
187
|
+
validateExpectedAction(task.expectation.globalFlatAbstainAction, `task ${task.id} global expectation`);
|
|
188
|
+
if (ids.has(task.id))
|
|
189
|
+
throw new Error(`duplicate task id: ${task.id}`);
|
|
190
|
+
if (fingerprints.has(task.taskFingerprint)) {
|
|
191
|
+
throw new Error(`duplicate task fingerprint: ${task.taskFingerprint}`);
|
|
192
|
+
}
|
|
193
|
+
if (typeof task.taskFingerprint !== 'string' || !SHA256_RE.test(task.taskFingerprint)) {
|
|
194
|
+
throw new Error(`invalid task fingerprint for ${task.id}`);
|
|
195
|
+
}
|
|
196
|
+
if (computeSelectionFlatTaskFingerprint(task) !== task.taskFingerprint) {
|
|
197
|
+
throw new Error(`task content fingerprint mismatch for ${task.id}`);
|
|
198
|
+
}
|
|
199
|
+
if (suite.cohort.taskFingerprints[index] !== task.taskFingerprint) {
|
|
200
|
+
throw new Error(`pre-registered cohort order mismatch at task ${task.id}`);
|
|
201
|
+
}
|
|
202
|
+
ids.add(task.id);
|
|
203
|
+
fingerprints.add(task.taskFingerprint);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
function cleanOutcome(taskId, expectedVerifier, outcome) {
|
|
207
|
+
const passed = outcome?.passed;
|
|
208
|
+
const producedValue = outcome?.producedValue;
|
|
209
|
+
const unsafe = outcome?.unsafe;
|
|
210
|
+
const cost = outcome?.cost;
|
|
211
|
+
const verifier = outcome?.verifier;
|
|
212
|
+
const verifierId = verifier?.id;
|
|
213
|
+
const verifierVersion = verifier?.version;
|
|
214
|
+
const proofSha256 = verifier?.proofSha256;
|
|
215
|
+
if (typeof passed !== 'boolean'
|
|
216
|
+
|| typeof producedValue !== 'boolean'
|
|
217
|
+
|| typeof unsafe !== 'boolean') {
|
|
218
|
+
throw new Error(`verifier returned invalid boolean fields for task ${taskId}`);
|
|
219
|
+
}
|
|
220
|
+
if (!Number.isFinite(cost) || cost < 0) {
|
|
221
|
+
throw new Error(`verifier returned invalid cost for task ${taskId}`);
|
|
222
|
+
}
|
|
223
|
+
if (verifierId !== expectedVerifier.id || verifierVersion !== expectedVerifier.version) {
|
|
224
|
+
throw new Error(`verifier identity mismatch for task ${taskId}`);
|
|
225
|
+
}
|
|
226
|
+
if (typeof proofSha256 !== 'string' || !SHA256_RE.test(proofSha256)) {
|
|
227
|
+
throw new Error(`verifier returned invalid proof digest for task ${taskId}`);
|
|
228
|
+
}
|
|
229
|
+
// Rebuild the object so adapter-only logs or payloads cannot leak into the persisted report.
|
|
230
|
+
return {
|
|
231
|
+
passed,
|
|
232
|
+
producedValue,
|
|
233
|
+
unsafe,
|
|
234
|
+
cost,
|
|
235
|
+
verifier: {
|
|
236
|
+
id: verifierId,
|
|
237
|
+
version: verifierVersion,
|
|
238
|
+
proofSha256,
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
function logAdd(left, right) {
|
|
243
|
+
if (left === Number.NEGATIVE_INFINITY)
|
|
244
|
+
return right;
|
|
245
|
+
if (right === Number.NEGATIVE_INFINITY)
|
|
246
|
+
return left;
|
|
247
|
+
const high = Math.max(left, right);
|
|
248
|
+
return high + Math.log(Math.exp(left - high) + Math.exp(right - high));
|
|
249
|
+
}
|
|
250
|
+
/** Exact two-sided McNemar p-value over the discordant pairs. */
|
|
251
|
+
export function exactMcNemarTwoSided(globalOnlyPass, currentOnlyPass) {
|
|
252
|
+
if (!Number.isSafeInteger(globalOnlyPass) || globalOnlyPass < 0
|
|
253
|
+
|| !Number.isSafeInteger(currentOnlyPass) || currentOnlyPass < 0) {
|
|
254
|
+
throw new Error('McNemar counts must be non-negative safe integers');
|
|
255
|
+
}
|
|
256
|
+
const discordant = globalOnlyPass + currentOnlyPass;
|
|
257
|
+
if (!Number.isSafeInteger(discordant)) {
|
|
258
|
+
throw new Error('McNemar discordant total must be a safe integer');
|
|
259
|
+
}
|
|
260
|
+
if (discordant === 0)
|
|
261
|
+
return 1;
|
|
262
|
+
const tail = Math.min(globalOnlyPass, currentOnlyPass);
|
|
263
|
+
let logProbability = -discordant * Math.log(2);
|
|
264
|
+
let logCumulative = logProbability;
|
|
265
|
+
for (let k = 1; k <= tail; k += 1) {
|
|
266
|
+
logProbability += Math.log(discordant - k + 1) - Math.log(k);
|
|
267
|
+
logCumulative = logAdd(logCumulative, logProbability);
|
|
268
|
+
}
|
|
269
|
+
return Math.min(1, 2 * Math.exp(logCumulative));
|
|
270
|
+
}
|
|
271
|
+
/** Distribution-free Hoeffding 95% CI for the mean paired success difference (global minus current). */
|
|
272
|
+
export function pairedRiskDifference95(pairs) {
|
|
273
|
+
if (pairs.length === 0)
|
|
274
|
+
return { difference: 0, ci95Low: -1, ci95High: 1 };
|
|
275
|
+
const differences = pairs.map((pair) => Number(pair.globalFlatAbstainPassed) - Number(pair.currentPassed));
|
|
276
|
+
const difference = differences.reduce((sum, value) => sum + value, 0) / differences.length;
|
|
277
|
+
// Each paired difference lies in [-1, 1], so Hoeffding remains valid at small n and at all-win boundaries.
|
|
278
|
+
const margin = Math.sqrt((2 * Math.log(2 / CI95_ALPHA)) / differences.length);
|
|
279
|
+
return {
|
|
280
|
+
difference,
|
|
281
|
+
ci95Low: Math.max(-1, difference - margin),
|
|
282
|
+
ci95High: Math.min(1, difference + margin),
|
|
283
|
+
};
|
|
284
|
+
}
|
|
285
|
+
function rate(count, total) {
|
|
286
|
+
return total === 0 ? 0 : count / total;
|
|
287
|
+
}
|
|
288
|
+
function average(values) {
|
|
289
|
+
return values.length === 0 ? 0 : values.reduce((sum, value) => sum + value, 0) / values.length;
|
|
290
|
+
}
|
|
291
|
+
function summarizeRows(rows) {
|
|
292
|
+
const n = rows.length;
|
|
293
|
+
let bothPass = 0;
|
|
294
|
+
let bothFail = 0;
|
|
295
|
+
let globalOnlyPass = 0;
|
|
296
|
+
let currentOnlyPass = 0;
|
|
297
|
+
for (const row of rows) {
|
|
298
|
+
const currentPassed = row.current.outcome.passed;
|
|
299
|
+
const globalPassed = row.globalFlatAbstain.outcome.passed;
|
|
300
|
+
if (currentPassed && globalPassed)
|
|
301
|
+
bothPass += 1;
|
|
302
|
+
else if (!currentPassed && !globalPassed)
|
|
303
|
+
bothFail += 1;
|
|
304
|
+
else if (globalPassed)
|
|
305
|
+
globalOnlyPass += 1;
|
|
306
|
+
else
|
|
307
|
+
currentOnlyPass += 1;
|
|
308
|
+
}
|
|
309
|
+
const currentPasses = bothPass + currentOnlyPass;
|
|
310
|
+
const globalFlatAbstainPasses = bothPass + globalOnlyPass;
|
|
311
|
+
const currentUnsafeRate = rate(rows.filter((row) => row.current.outcome.unsafe).length, n);
|
|
312
|
+
const globalUnsafeRate = rate(rows.filter((row) => row.globalFlatAbstain.outcome.unsafe).length, n);
|
|
313
|
+
const currentAverageCost = average(rows.map((row) => row.current.outcome.cost));
|
|
314
|
+
const globalAverageCost = average(rows.map((row) => row.globalFlatAbstain.outcome.cost));
|
|
315
|
+
const risk = pairedRiskDifference95(rows.map((row) => ({
|
|
316
|
+
currentPassed: row.current.outcome.passed,
|
|
317
|
+
globalFlatAbstainPassed: row.globalFlatAbstain.outcome.passed,
|
|
318
|
+
})));
|
|
319
|
+
return {
|
|
320
|
+
n,
|
|
321
|
+
currentPasses,
|
|
322
|
+
globalFlatAbstainPasses,
|
|
323
|
+
bothPass,
|
|
324
|
+
bothFail,
|
|
325
|
+
globalOnlyPass,
|
|
326
|
+
currentOnlyPass,
|
|
327
|
+
currentPassRate: rate(currentPasses, n),
|
|
328
|
+
globalFlatAbstainPassRate: rate(globalFlatAbstainPasses, n),
|
|
329
|
+
pairedRiskDifference: risk.difference,
|
|
330
|
+
ci95Low: risk.ci95Low,
|
|
331
|
+
ci95High: risk.ci95High,
|
|
332
|
+
mcnemarPValue: exactMcNemarTwoSided(globalOnlyPass, currentOnlyPass),
|
|
333
|
+
currentProducedValueRate: rate(rows.filter((row) => row.current.outcome.producedValue).length, n),
|
|
334
|
+
globalFlatAbstainProducedValueRate: rate(rows.filter((row) => row.globalFlatAbstain.outcome.producedValue).length, n),
|
|
335
|
+
currentUnsafeRate,
|
|
336
|
+
globalFlatAbstainUnsafeRate: globalUnsafeRate,
|
|
337
|
+
unsafeRateDelta: globalUnsafeRate - currentUnsafeRate,
|
|
338
|
+
currentAverageCost,
|
|
339
|
+
globalFlatAbstainAverageCost: globalAverageCost,
|
|
340
|
+
averageCostDelta: globalAverageCost - currentAverageCost,
|
|
341
|
+
currentInnovateRate: rate(rows.filter((row) => row.current.action === 'innovate').length, n),
|
|
342
|
+
globalFlatAbstainInnovateRate: rate(rows.filter((row) => row.globalFlatAbstain.action === 'innovate').length, n),
|
|
343
|
+
};
|
|
344
|
+
}
|
|
345
|
+
function cloneTaskForArm(task) {
|
|
346
|
+
return cloneStructured(task, `task ${task.id} must be structured-cloneable for isolated arm execution`);
|
|
347
|
+
}
|
|
348
|
+
function cloneSuiteSnapshot(suite) {
|
|
349
|
+
return cloneStructured(suite, 'benchmark suite must be structured-cloneable before validation');
|
|
350
|
+
}
|
|
351
|
+
function cloneAction(action) {
|
|
352
|
+
return action.kind === 'innovate'
|
|
353
|
+
? { kind: 'innovate' }
|
|
354
|
+
: {
|
|
355
|
+
kind: 'reuse',
|
|
356
|
+
geneId: action.geneId,
|
|
357
|
+
...(action.assetId ? { assetId: action.assetId } : {}),
|
|
358
|
+
};
|
|
359
|
+
}
|
|
360
|
+
function benchmarkDatasetDigest(suite, comparisons) {
|
|
361
|
+
const material = [
|
|
362
|
+
SELECTION_FLAT_ABSTENTION_BENCHMARK_VERSION,
|
|
363
|
+
suite.name,
|
|
364
|
+
suite.cohort.id,
|
|
365
|
+
suite.cohort.version,
|
|
366
|
+
suite.cohort.sourceCommit,
|
|
367
|
+
suite.cohort.verifier.id,
|
|
368
|
+
suite.cohort.verifier.version,
|
|
369
|
+
suite.tasks.map((task, index) => [
|
|
370
|
+
index,
|
|
371
|
+
task.taskFingerprint,
|
|
372
|
+
task.split,
|
|
373
|
+
task.stratum,
|
|
374
|
+
comparisons[index]?.targeted === true,
|
|
375
|
+
comparisons[index]?.currentAction.kind,
|
|
376
|
+
comparisons[index]?.globalFlatAbstainAction.kind,
|
|
377
|
+
]),
|
|
378
|
+
];
|
|
379
|
+
return sha256(JSON.stringify(material));
|
|
380
|
+
}
|
|
381
|
+
function validatePreRegisteredExpectation(task, comparison) {
|
|
382
|
+
const actualRole = comparison.targeted ? 'target' : 'control';
|
|
383
|
+
if (task.expectation.role !== actualRole) {
|
|
384
|
+
throw new Error(`pre-registered role mismatch for task ${task.id}`);
|
|
385
|
+
}
|
|
386
|
+
if (!actionsEqual(task.expectation.currentAction, comparison.currentAction)) {
|
|
387
|
+
throw new Error(`pre-registered current action mismatch for task ${task.id}`);
|
|
388
|
+
}
|
|
389
|
+
if (!actionsEqual(task.expectation.globalFlatAbstainAction, comparison.globalFlatAbstainAction)) {
|
|
390
|
+
throw new Error(`pre-registered global action mismatch for task ${task.id}`);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
function rowsByStratum(rows) {
|
|
394
|
+
const result = Object.create(null);
|
|
395
|
+
const strata = [...new Set(rows.map((row) => row.stratum))].sort();
|
|
396
|
+
for (const stratum of strata) {
|
|
397
|
+
result[stratum] = summarizeRows(rows.filter((row) => row.stratum === stratum));
|
|
398
|
+
}
|
|
399
|
+
return result;
|
|
400
|
+
}
|
|
401
|
+
/**
|
|
402
|
+
* Run a pre-registered, full-information paired benchmark. Controls are classification checks only and are never
|
|
403
|
+
* executed. Target tasks run both arms on separately cloned inputs and caller-owned isolated workspaces.
|
|
404
|
+
*/
|
|
405
|
+
export async function runSelectionFlatAbstentionBenchmark(suite, verifier) {
|
|
406
|
+
const snapshot = cloneSuiteSnapshot(suite);
|
|
407
|
+
validateSuite(snapshot);
|
|
408
|
+
const comparisons = snapshot.tasks.map((task) => compareOutsidePlateauFlatSelection(task.selection));
|
|
409
|
+
snapshot.tasks.forEach((task, index) => {
|
|
410
|
+
validatePreRegisteredExpectation(task, comparisons[index]);
|
|
411
|
+
});
|
|
412
|
+
const datasetDigest = benchmarkDatasetDigest(snapshot, comparisons);
|
|
413
|
+
const executionNonce = randomUUID();
|
|
414
|
+
const rows = [];
|
|
415
|
+
let targetIndex = 0;
|
|
416
|
+
for (const [taskIndex, task] of snapshot.tasks.entries()) {
|
|
417
|
+
const comparison = comparisons[taskIndex];
|
|
418
|
+
if (!comparison.targeted) {
|
|
419
|
+
if (!actionsEqual(comparison.currentAction, comparison.globalFlatAbstainAction)) {
|
|
420
|
+
throw new Error(`control action divergence for task ${task.id}`);
|
|
421
|
+
}
|
|
422
|
+
continue;
|
|
423
|
+
}
|
|
424
|
+
const armOrder = targetIndex % 2 === 0
|
|
425
|
+
? ['current', 'global-flat-abstain']
|
|
426
|
+
: ['global-flat-abstain', 'current'];
|
|
427
|
+
targetIndex += 1;
|
|
428
|
+
const outcomes = new Map();
|
|
429
|
+
for (const [order, arm] of armOrder.entries()) {
|
|
430
|
+
const action = arm === 'current'
|
|
431
|
+
? comparison.currentAction
|
|
432
|
+
: comparison.globalFlatAbstainAction;
|
|
433
|
+
const rawOutcome = await verifier({
|
|
434
|
+
task: cloneTaskForArm(task),
|
|
435
|
+
arm,
|
|
436
|
+
action: cloneAction(action),
|
|
437
|
+
isolationKey: isolationKey(datasetDigest, executionNonce, task.taskFingerprint, arm),
|
|
438
|
+
order: order,
|
|
439
|
+
});
|
|
440
|
+
outcomes.set(arm, cleanOutcome(task.id, snapshot.cohort.verifier, rawOutcome));
|
|
441
|
+
}
|
|
442
|
+
rows.push({
|
|
443
|
+
taskFingerprint: task.taskFingerprint,
|
|
444
|
+
split: task.split,
|
|
445
|
+
stratum: task.stratum,
|
|
446
|
+
armOrder,
|
|
447
|
+
current: {
|
|
448
|
+
action: comparison.currentAction.kind,
|
|
449
|
+
outcome: outcomes.get('current'),
|
|
450
|
+
},
|
|
451
|
+
globalFlatAbstain: {
|
|
452
|
+
action: comparison.globalFlatAbstainAction.kind,
|
|
453
|
+
outcome: outcomes.get('global-flat-abstain'),
|
|
454
|
+
},
|
|
455
|
+
});
|
|
456
|
+
}
|
|
457
|
+
return {
|
|
458
|
+
benchmarkVersion: SELECTION_FLAT_ABSTENTION_BENCHMARK_VERSION,
|
|
459
|
+
statisticalMethods: {
|
|
460
|
+
mcnemar: 'exact-two-sided-binomial',
|
|
461
|
+
riskDifferenceCi: 'paired-hoeffding-95',
|
|
462
|
+
},
|
|
463
|
+
suite: snapshot.name,
|
|
464
|
+
cohort: {
|
|
465
|
+
id: snapshot.cohort.id,
|
|
466
|
+
version: snapshot.cohort.version,
|
|
467
|
+
sourceCommit: snapshot.cohort.sourceCommit,
|
|
468
|
+
verifier: { ...snapshot.cohort.verifier },
|
|
469
|
+
registeredTasks: snapshot.cohort.taskFingerprints.length,
|
|
470
|
+
},
|
|
471
|
+
datasetDigest,
|
|
472
|
+
targetTasks: rows.length,
|
|
473
|
+
controlTasks: snapshot.tasks.length - rows.length,
|
|
474
|
+
controlDivergences: 0,
|
|
475
|
+
rows,
|
|
476
|
+
overall: summarizeRows(rows),
|
|
477
|
+
calibration: summarizeRows(rows.filter((row) => row.split === 'calibration')),
|
|
478
|
+
holdout: summarizeRows(rows.filter((row) => row.split === 'holdout')),
|
|
479
|
+
strata: rowsByStratum(rows),
|
|
480
|
+
};
|
|
481
|
+
}
|
|
@@ -15,6 +15,12 @@ export interface EnvFingerprint {
|
|
|
15
15
|
* as its own field (e.g. so the Hub can index assets by model / feed the by-model leaderboard).
|
|
16
16
|
*/
|
|
17
17
|
model: string;
|
|
18
|
+
/**
|
|
19
|
+
* Reported Evolver client version for Hub anti-abuse trust (#555). The owning runtime resolves this from its
|
|
20
|
+
* own package/build metadata and supplies it explicitly, so a host application's npm environment cannot be
|
|
21
|
+
* mistaken for the Evolver version. Optional so older callers keep working.
|
|
22
|
+
*/
|
|
23
|
+
evolver_version?: string;
|
|
18
24
|
}
|
|
19
25
|
export interface EnvCaptureDeps {
|
|
20
26
|
platform?: string;
|
|
@@ -24,7 +30,10 @@ export interface EnvCaptureDeps {
|
|
|
24
30
|
hostname?: string;
|
|
25
31
|
env?: Record<string, string | undefined>;
|
|
26
32
|
isContainer?: () => boolean;
|
|
33
|
+
/** Explicit Evolver version for fingerprint (Refs #555). */
|
|
34
|
+
evolverVersion?: string;
|
|
27
35
|
}
|
|
36
|
+
export declare function normalizeEvolverVersion(value: string | undefined): string | undefined;
|
|
28
37
|
/**
|
|
29
38
|
* Resolve the underlying LLM model name powering this evolver node (ported from v1 PR #174). Until now the
|
|
30
39
|
* only source was the explicit EVOLVER_MODEL_NAME, so nodes that never set it published assets with no model
|
|
@@ -6,6 +6,9 @@ import { hostname as osHostname, release as osRelease } from 'node:os';
|
|
|
6
6
|
import { existsSync } from 'node:fs';
|
|
7
7
|
import { createHash } from 'node:crypto';
|
|
8
8
|
const sha12 = (s) => createHash('sha256').update(s).digest('hex').slice(0, 12);
|
|
9
|
+
export function normalizeEvolverVersion(value) {
|
|
10
|
+
return value?.trim().slice(0, 64) || undefined;
|
|
11
|
+
}
|
|
9
12
|
/** Heuristic container detection (Docker / Kubernetes). */
|
|
10
13
|
function detectContainer(env) {
|
|
11
14
|
if (env['KUBERNETES_SERVICE_HOST'])
|
|
@@ -50,6 +53,7 @@ export function detectModelName(env = (typeof process !== 'undefined' ? process.
|
|
|
50
53
|
export function captureEnvFingerprint(deps = {}) {
|
|
51
54
|
const env = deps.env ?? (typeof process !== 'undefined' ? process.env : {});
|
|
52
55
|
const region = (env['EVOLVER_REGION'] ?? '').trim().toLowerCase().slice(0, 5) || undefined;
|
|
56
|
+
const evolverVersion = normalizeEvolverVersion(deps.evolverVersion);
|
|
53
57
|
return {
|
|
54
58
|
device: sha12(deps.hostname ?? osHostname()),
|
|
55
59
|
node_version: deps.nodeVersion ?? process.version,
|
|
@@ -59,6 +63,7 @@ export function captureEnvFingerprint(deps = {}) {
|
|
|
59
63
|
...(region ? { region } : {}),
|
|
60
64
|
container: deps.isContainer ? deps.isContainer() : detectContainer(env),
|
|
61
65
|
model: detectModelName(env),
|
|
66
|
+
...(evolverVersion ? { evolver_version: evolverVersion } : {}),
|
|
62
67
|
};
|
|
63
68
|
}
|
|
64
69
|
/**
|
package/dist/bootstrap/index.js
CHANGED
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
import { type FileLockProcessStartIdentity } from '../util/fileLock.js';
|
|
2
|
+
export declare const LIFECYCLE_BOOTSTRAP_MARKER_SCHEMA = "evolver.lifecycle-bootstrap.v1";
|
|
3
|
+
export declare const LIFECYCLE_BOOTSTRAP_LEGACY_BINDING = "legacy-v907";
|
|
4
|
+
export declare const LIFECYCLE_BOOTSTRAP_LEGACY_ENV_FILE_STATE_ROOT_PROOF = "legacy-v907-env-file";
|
|
5
|
+
export declare const LIFECYCLE_BOOTSTRAP_DEADLINE_ENV = "EVOLVER_INTERNAL_BOOTSTRAP_DEADLINE_MS";
|
|
6
|
+
export declare const LIFECYCLE_BOOTSTRAP_TRANSACTION_ENV = "EVOLVER_INTERNAL_BOOTSTRAP_TRANSACTION_ID";
|
|
7
|
+
export declare const LIFECYCLE_BOOTSTRAP_SUCCESS_FILE = "bootstrap.json";
|
|
8
|
+
export declare const LIFECYCLE_BOOTSTRAP_JOURNAL_FILE = "bootstrap-transaction.json";
|
|
9
|
+
export declare const LIFECYCLE_BOOTSTRAP_OWNER_LOCK_FILE = "bootstrap-owner.lock";
|
|
10
|
+
export declare const LIFECYCLE_BOOTSTRAP_READINESS_FILE = "bootstrap-readiness.json";
|
|
11
|
+
export declare const LIFECYCLE_BOOTSTRAP_READINESS_LOCK_FILE = "bootstrap-readiness.lock";
|
|
12
|
+
export declare const LIFECYCLE_BOOTSTRAP_READINESS_SCHEMA = "evolver.lifecycle-bootstrap-readiness.v1";
|
|
13
|
+
export declare const LIFECYCLE_BOOTSTRAP_MANUAL_TRANSITION_FILE = "bootstrap-manual-transition.json";
|
|
14
|
+
export declare const LIFECYCLE_BOOTSTRAP_MANUAL_TRANSITION_SCHEMA = "evolver.lifecycle-bootstrap-manual-transition.v1";
|
|
15
|
+
export declare const MAX_LIFECYCLE_BOOTSTRAP_MANUAL_TRANSITION_BYTES: number;
|
|
16
|
+
export declare const LIFECYCLE_BOOTSTRAP_REGISTRATION_INTENT_FILE = "bootstrap-registration.intent.json";
|
|
17
|
+
export declare const LIFECYCLE_BOOTSTRAP_REGISTRATION_INTENT_TERMINAL_FILE = "bootstrap-registration.intent.terminal";
|
|
18
|
+
export declare const LIFECYCLE_BOOTSTRAP_REGISTRATION_INTENT_CLEARING_FILE = "bootstrap-registration.intent.clearing";
|
|
19
|
+
export declare const LIFECYCLE_BOOTSTRAP_REGISTRATION_INTENT_SCHEMA = "evolver.bootstrap-registration-intent.v1";
|
|
20
|
+
export declare const LIFECYCLE_BOOTSTRAP_REGISTRATION_TOKEN_ENV = "EVOLVER_INTERNAL_BOOTSTRAP_REGISTRATION_TOKEN";
|
|
21
|
+
export declare const MAX_LIFECYCLE_BOOTSTRAP_REGISTRATION_INTENT_BYTES: number;
|
|
22
|
+
export type LifecycleBootstrapTarget = 'launchd' | 'systemd' | 'windows';
|
|
23
|
+
export type LifecycleBootstrapManagerBindingKind = 'transaction' | typeof LIFECYCLE_BOOTSTRAP_LEGACY_BINDING;
|
|
24
|
+
export interface LifecycleBootstrapLegacyStateRootProof {
|
|
25
|
+
kind: typeof LIFECYCLE_BOOTSTRAP_LEGACY_ENV_FILE_STATE_ROOT_PROOF;
|
|
26
|
+
envFilePath: string;
|
|
27
|
+
stateDir: string;
|
|
28
|
+
}
|
|
29
|
+
export interface LifecycleBootstrapMarker {
|
|
30
|
+
schema: typeof LIFECYCLE_BOOTSTRAP_MARKER_SCHEMA;
|
|
31
|
+
transactionId: string;
|
|
32
|
+
bootstrappedAt: string;
|
|
33
|
+
target: LifecycleBootstrapTarget;
|
|
34
|
+
service: string;
|
|
35
|
+
files: string[];
|
|
36
|
+
managerArtifactPath: string;
|
|
37
|
+
managerBindingKind?: LifecycleBootstrapManagerBindingKind;
|
|
38
|
+
artifacts: Array<{
|
|
39
|
+
path: string;
|
|
40
|
+
size: number;
|
|
41
|
+
sha256: string;
|
|
42
|
+
device?: string;
|
|
43
|
+
inode?: string;
|
|
44
|
+
}>;
|
|
45
|
+
/** Exact legacy companion artifacts retained on disk but never owned by proxy rollback. */
|
|
46
|
+
preservedArtifacts?: Array<{
|
|
47
|
+
path: string;
|
|
48
|
+
size: number;
|
|
49
|
+
sha256: string;
|
|
50
|
+
device?: string;
|
|
51
|
+
inode?: string;
|
|
52
|
+
}>;
|
|
53
|
+
/** Exact env-file attestation required by unpinned #907 launchers. */
|
|
54
|
+
legacyStateRootProof?: LifecycleBootstrapLegacyStateRootProof;
|
|
55
|
+
}
|
|
56
|
+
/** Exact success marker emitted by the pre-transaction first-run bootstrap merged in #907. */
|
|
57
|
+
export interface LegacyLifecycleBootstrapMarker {
|
|
58
|
+
bootstrappedAt: string;
|
|
59
|
+
target: LifecycleBootstrapTarget;
|
|
60
|
+
service: string;
|
|
61
|
+
files: string[];
|
|
62
|
+
}
|
|
63
|
+
export interface LifecycleBootstrapReadiness {
|
|
64
|
+
schema: typeof LIFECYCLE_BOOTSTRAP_READINESS_SCHEMA;
|
|
65
|
+
transactionId: string;
|
|
66
|
+
pid: number;
|
|
67
|
+
pidProcessStartIdentity: FileLockProcessStartIdentity;
|
|
68
|
+
supervisorPid: number;
|
|
69
|
+
supervisorProcessStartIdentity: FileLockProcessStartIdentity;
|
|
70
|
+
startedAt: string;
|
|
71
|
+
ipcUrl: string;
|
|
72
|
+
}
|
|
73
|
+
export interface LifecycleBootstrapManualTransition {
|
|
74
|
+
schema: typeof LIFECYCLE_BOOTSTRAP_MANUAL_TRANSITION_SCHEMA;
|
|
75
|
+
transitionId: string;
|
|
76
|
+
removedTransactionId: string;
|
|
77
|
+
target: LifecycleBootstrapTarget;
|
|
78
|
+
service: string;
|
|
79
|
+
createdAt: string;
|
|
80
|
+
}
|
|
81
|
+
export interface LifecycleBootstrapRegistrationIntentOwner {
|
|
82
|
+
pid: number;
|
|
83
|
+
token: string;
|
|
84
|
+
processStartIdentity: FileLockProcessStartIdentity;
|
|
85
|
+
}
|
|
86
|
+
interface LifecycleBootstrapRegistrationIntentBase {
|
|
87
|
+
schema: typeof LIFECYCLE_BOOTSTRAP_REGISTRATION_INTENT_SCHEMA;
|
|
88
|
+
owner: LifecycleBootstrapRegistrationIntentOwner;
|
|
89
|
+
createdAt: string;
|
|
90
|
+
}
|
|
91
|
+
export type LifecycleBootstrapRegistrationTerminalOutcome = 'committed' | 'rolled_back' | 'no_child' | 'cancelled';
|
|
92
|
+
export type LifecycleBootstrapRegistrationIntent = (LifecycleBootstrapRegistrationIntentBase & {
|
|
93
|
+
state: 'registering';
|
|
94
|
+
}) | (LifecycleBootstrapRegistrationIntentBase & {
|
|
95
|
+
state: 'terminal';
|
|
96
|
+
outcome: LifecycleBootstrapRegistrationTerminalOutcome;
|
|
97
|
+
terminalAt: string;
|
|
98
|
+
transactionId?: string;
|
|
99
|
+
});
|
|
100
|
+
export declare function parseLifecycleBootstrapRegistrationToken(value: unknown): string | undefined;
|
|
101
|
+
export declare function parseLifecycleBootstrapManualTransition(value: unknown): LifecycleBootstrapManualTransition | undefined;
|
|
102
|
+
export declare function parseLifecycleBootstrapManualTransitionJson(raw: string): LifecycleBootstrapManualTransition | undefined;
|
|
103
|
+
export declare function parseLifecycleBootstrapRegistrationIntent(value: unknown): LifecycleBootstrapRegistrationIntent | undefined;
|
|
104
|
+
export declare function parseLifecycleBootstrapRegistrationIntentJson(raw: string): LifecycleBootstrapRegistrationIntent | undefined;
|
|
105
|
+
export declare function parseLifecycleBootstrapMarker(value: unknown): LifecycleBootstrapMarker | undefined;
|
|
106
|
+
export declare function parseLegacyLifecycleBootstrapMarker(value: unknown): LegacyLifecycleBootstrapMarker | undefined;
|
|
107
|
+
export declare function parseLegacyLifecycleBootstrapMarkerJson(raw: string): LegacyLifecycleBootstrapMarker | undefined;
|
|
108
|
+
export declare function parseLifecycleBootstrapMarkerJson(raw: string): LifecycleBootstrapMarker | undefined;
|
|
109
|
+
export declare function parseLifecycleBootstrapReadiness(value: unknown): LifecycleBootstrapReadiness | undefined;
|
|
110
|
+
export declare function parseLifecycleBootstrapReadinessJson(raw: string): LifecycleBootstrapReadiness | undefined;
|
|
111
|
+
export {};
|