@evomap/evolver-core 2.0.0-beta.1 → 2.0.0-beta.11
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 -0
- package/dist/algo/candidateAssembly.js +23 -14
- package/dist/algo/capabilityCandidates.d.ts +2 -0
- package/dist/algo/capabilityCandidates.js +5 -0
- package/dist/algo/conversationSniffer.d.ts +18 -0
- package/dist/algo/conversationSniffer.js +149 -0
- package/dist/algo/cycleEngine.d.ts +11 -0
- package/dist/algo/cycleEngine.js +14 -6
- package/dist/algo/cycleFailureClassifier.d.ts +1 -1
- package/dist/algo/cycleFailureClassifier.js +13 -5
- package/dist/algo/geneIntake.d.ts +14 -4
- package/dist/algo/geneIntake.js +37 -9
- package/dist/algo/geneSelection.d.ts +18 -1
- package/dist/algo/geneSelection.js +42 -18
- package/dist/algo/index.d.ts +2 -0
- package/dist/algo/index.js +2 -0
- package/dist/algo/memoryGraph.d.ts +62 -0
- package/dist/algo/memoryGraph.js +86 -0
- package/dist/algo/orchestrator.d.ts +3 -0
- package/dist/algo/orchestrator.js +14 -2
- package/dist/assetstore/assetSidecarRecords.d.ts +28 -0
- package/dist/assetstore/assetSidecarRecords.js +376 -0
- package/dist/assetstore/assetSidecarRecovery.d.ts +48 -0
- package/dist/assetstore/assetSidecarRecovery.js +288 -0
- package/dist/assetstore/assetStoreHealth.d.ts +82 -0
- package/dist/assetstore/assetStoreHealth.js +308 -0
- package/dist/assetstore/assetStoreLayout.d.ts +2 -0
- package/dist/assetstore/assetStoreLayout.js +6 -0
- package/dist/assetstore/assetStoreStorage.d.ts +42 -0
- package/dist/assetstore/assetStoreStorage.js +327 -0
- package/dist/assetstore/assetSyncLedger.d.ts +118 -0
- package/dist/assetstore/assetSyncLedger.js +745 -0
- package/dist/assetstore/index.d.ts +5 -1
- package/dist/assetstore/index.js +5 -1
- package/dist/assetstore/localJsonl.d.ts +12 -3
- package/dist/assetstore/localJsonl.js +131 -39
- package/dist/assetstore/pendingSignals.js +3 -1
- package/dist/assetstore/provenance.d.ts +39 -4
- package/dist/assetstore/provenance.js +134 -55
- package/dist/assetstore/provider.d.ts +40 -0
- package/dist/assetstore/provider.js +63 -5
- package/dist/assetstore/reviewFilter.js +5 -2
- package/dist/assetstore/reviewLedger.d.ts +14 -2
- package/dist/assetstore/reviewLedger.js +78 -43
- package/dist/assetstore/seedGenes.d.ts +3 -0
- package/dist/assetstore/seedGenes.js +134 -0
- package/dist/benchmark/antiGeneBenchmark.d.ts +2 -0
- package/dist/benchmark/antiGeneBenchmark.js +11 -1
- package/dist/benchmark/antiGeneImpact.d.ts +16 -0
- package/dist/benchmark/antiGeneImpact.js +34 -0
- package/dist/benchmark/antiGeneRollout.d.ts +2 -0
- package/dist/benchmark/antiGeneRollout.js +13 -1
- package/dist/benchmark/index.d.ts +2 -1
- package/dist/benchmark/index.js +2 -1
- package/dist/benchmark/triggerShift.d.ts +62 -0
- package/dist/benchmark/triggerShift.js +106 -0
- package/dist/events/eventArchive.d.ts +65 -0
- package/dist/events/eventArchive.js +343 -0
- package/dist/events/eventStore.js +2 -12
- package/dist/events/ingest.d.ts +1 -1
- package/dist/events/ingest.js +9 -0
- package/dist/events/paths.d.ts +10 -10
- package/dist/events/paths.js +20 -20
- package/dist/events/public.d.ts +3 -1
- package/dist/events/public.js +2 -1
- package/dist/events/retention.d.ts +24 -1
- package/dist/events/retention.js +133 -37
- package/dist/exec/autoExec.d.ts +6 -1
- package/dist/exec/autoExec.js +34 -0
- package/dist/exec/autonomousCycle.d.ts +2 -0
- package/dist/exec/autonomousCycle.js +5 -0
- package/dist/exec/claudeBridge.d.ts +21 -3
- package/dist/exec/claudeBridge.js +413 -26
- package/dist/exec/openPrRegistry.d.ts +8 -2
- package/dist/exec/openPrRegistry.js +32 -22
- package/dist/exec/prompt.js +9 -0
- package/dist/exec/runnerRegistry.d.ts +90 -18
- package/dist/exec/runnerRegistry.js +603 -42
- package/dist/exec/selfPrObfuscation.d.ts +2 -1
- package/dist/exec/selfPrObfuscation.js +19 -6
- package/dist/hub/agentDirectory.d.ts +90 -0
- package/dist/hub/agentDirectory.js +104 -0
- package/dist/hub/bindings.js +23 -3
- package/dist/hub/capability.d.ts +14 -2
- package/dist/hub/fake.d.ts +4 -2
- package/dist/hub/fake.js +3 -2
- package/dist/hub/index.d.ts +1 -0
- package/dist/hub/index.js +1 -0
- package/dist/hub/sanitize.js +3 -2
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/issueReporter/index.d.ts +156 -0
- package/dist/issueReporter/index.js +1688 -0
- package/dist/mailbox/catalog.js +3 -0
- package/dist/mailbox/ipcServer.js +2 -2
- package/dist/mailbox/store.d.ts +14 -0
- package/dist/mailbox/store.js +44 -2
- package/dist/material/consumer.js +9 -6
- package/dist/material/index.d.ts +1 -0
- package/dist/material/index.js +1 -0
- package/dist/material/materialArchive.d.ts +81 -0
- package/dist/material/materialArchive.js +466 -0
- package/dist/material/materialStore.d.ts +1 -0
- package/dist/material/materialStore.js +6 -13
- package/dist/ops/savingsCore.js +1 -2
- package/dist/ops/selfUpdate.d.ts +10 -1
- package/dist/ops/selfUpdate.js +64 -15
- package/dist/personality/schema.d.ts +12 -12
- package/dist/schema/common.d.ts +1 -1
- package/dist/schema/common.js +1 -1
- package/dist/schema/material.d.ts +5 -5
- package/dist/strategy/constraintAblation.d.ts +64 -0
- package/dist/strategy/constraintAblation.js +3074 -0
- package/dist/strategy/index.d.ts +2 -1
- package/dist/strategy/index.js +2 -1
- package/dist/trace/trajectoryExport.js +2 -2
- package/dist/util/fetchPort.d.ts +1 -0
- package/dist/util/fetchPort.js +11 -0
- package/dist/util/fileLock.d.ts +24 -5
- package/dist/util/fileLock.js +288 -72
- package/dist/util/index.d.ts +1 -0
- package/dist/util/index.js +1 -0
- package/dist/wire/geneHints.d.ts +42 -1
- package/dist/wire/geneHints.js +52 -1
- package/dist/wire/index.d.ts +14 -2
- package/dist/wire/index.js +1 -1
- package/dist/workflow/dsl.d.ts +24 -3
- package/dist/workflow/dsl.js +4 -0
- package/dist/workflow/engine.d.ts +5 -1
- package/dist/workflow/engine.js +3 -0
- package/dist/workflow/index.d.ts +3 -1
- package/dist/workflow/index.js +3 -1
- package/dist/workflow/runtime.d.ts +110 -0
- package/dist/workflow/runtime.js +1298 -0
- package/dist/workflow/stateStore.d.ts +172 -0
- package/dist/workflow/stateStore.js +1044 -0
- package/package.json +6 -1
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import { closeSync, existsSync, fsyncSync, mkdirSync, openSync, readFileSync, readdirSync, renameSync, rmSync, writeSync, } from 'node:fs';
|
|
2
|
+
import { basename, dirname, extname, join } from 'node:path';
|
|
3
|
+
import { acquireLock, releaseLock } from '../util/fileLock.js';
|
|
4
|
+
import { rootEvent } from './eventSchema.js';
|
|
5
|
+
export const ROOT_EVENT_ARCHIVE_DEFAULT_KEEP_EVENTS = 10_000;
|
|
6
|
+
const SEGMENT_PATTERN = /^root-events-(\d{16})-(\d{16})\.jsonl$/;
|
|
7
|
+
export class InvalidRootEventLogError extends Error {
|
|
8
|
+
line;
|
|
9
|
+
code = 'ROOT_EVENT_ARCHIVE_INVALID_LOG';
|
|
10
|
+
constructor(line, reason) {
|
|
11
|
+
super(`root event archive refused invalid active log at line ${line}: ${reason}`);
|
|
12
|
+
this.line = line;
|
|
13
|
+
this.name = 'InvalidRootEventLogError';
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
export class ArchiveSegmentConflictError extends Error {
|
|
17
|
+
archiveId;
|
|
18
|
+
code = 'ROOT_EVENT_ARCHIVE_SEGMENT_CONFLICT';
|
|
19
|
+
constructor(archiveId) {
|
|
20
|
+
super(`root event archive segment ${archiveId} already exists with different content`);
|
|
21
|
+
this.archiveId = archiveId;
|
|
22
|
+
this.name = 'ArchiveSegmentConflictError';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
export class InvalidRootEventArchiveError extends Error {
|
|
26
|
+
segment;
|
|
27
|
+
line;
|
|
28
|
+
code = 'ROOT_EVENT_ARCHIVE_INVALID_ARCHIVE';
|
|
29
|
+
constructor(segment, line) {
|
|
30
|
+
super(`root event archive segment ${segment} is invalid at line ${line}`);
|
|
31
|
+
this.segment = segment;
|
|
32
|
+
this.line = line;
|
|
33
|
+
this.name = 'InvalidRootEventArchiveError';
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
export class RootEventHistoryGapError extends Error {
|
|
37
|
+
expectedSeq;
|
|
38
|
+
actualSeq;
|
|
39
|
+
code = 'ROOT_EVENT_HISTORY_GAP';
|
|
40
|
+
constructor(expectedSeq, actualSeq) {
|
|
41
|
+
super(`root event history expected seq ${expectedSeq} but found ${actualSeq}`);
|
|
42
|
+
this.expectedSeq = expectedSeq;
|
|
43
|
+
this.actualSeq = actualSeq;
|
|
44
|
+
this.name = 'RootEventHistoryGapError';
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
export function rootEventArchiveDir(path) {
|
|
48
|
+
const ext = extname(path);
|
|
49
|
+
const stem = ext.length > 0 ? basename(path, ext) : basename(path);
|
|
50
|
+
return join(dirname(path), `${stem}.archive`);
|
|
51
|
+
}
|
|
52
|
+
export function rootEventArchiveSegmentName(firstSeq, lastSeq) {
|
|
53
|
+
return `root-events-${String(firstSeq).padStart(16, '0')}-${String(lastSeq).padStart(16, '0')}.jsonl`;
|
|
54
|
+
}
|
|
55
|
+
export function planRootEventArchive(opts) {
|
|
56
|
+
const keepEvents = normalizeKeepEvents(opts.keepEvents);
|
|
57
|
+
const active = readActiveStrict(opts.path);
|
|
58
|
+
const wouldArchive = Math.max(0, active.length - keepEvents);
|
|
59
|
+
const prefix = active.slice(0, wouldArchive);
|
|
60
|
+
readValidatedArchive(opts.path, active);
|
|
61
|
+
const firstSeq = prefix[0]?.event.seq ?? null;
|
|
62
|
+
const lastSeq = prefix[prefix.length - 1]?.event.seq ?? null;
|
|
63
|
+
return {
|
|
64
|
+
mode: 'preview',
|
|
65
|
+
activeRecords: active.length,
|
|
66
|
+
keepEvents,
|
|
67
|
+
wouldArchive,
|
|
68
|
+
retainedRecords: active.length - wouldArchive,
|
|
69
|
+
firstSeq,
|
|
70
|
+
lastSeq,
|
|
71
|
+
archiveId: firstSeq === null || lastSeq === null ? null : `${firstSeq}-${lastSeq}`,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
export function archiveRootEvents(opts) {
|
|
75
|
+
const keepEvents = normalizeKeepEvents(opts.keepEvents);
|
|
76
|
+
const lockPath = `${opts.path}.lock`;
|
|
77
|
+
mkdirSync(dirname(opts.path), { recursive: true });
|
|
78
|
+
acquireLock(lockPath);
|
|
79
|
+
try {
|
|
80
|
+
const active = readActiveStrict(opts.path);
|
|
81
|
+
const archivedRecords = Math.max(0, active.length - keepEvents);
|
|
82
|
+
const prefix = active.slice(0, archivedRecords);
|
|
83
|
+
const tail = active.slice(archivedRecords);
|
|
84
|
+
const firstSeq = prefix[0]?.event.seq ?? null;
|
|
85
|
+
const lastSeq = prefix[prefix.length - 1]?.event.seq ?? null;
|
|
86
|
+
const archiveId = firstSeq === null || lastSeq === null ? null : `${firstSeq}-${lastSeq}`;
|
|
87
|
+
let reusedSegment = false;
|
|
88
|
+
const archivedBySeq = readValidatedArchive(opts.path, active);
|
|
89
|
+
if (archiveId !== null && firstSeq !== null && lastSeq !== null) {
|
|
90
|
+
const archiveDir = rootEventArchiveDir(opts.path);
|
|
91
|
+
const missing = [];
|
|
92
|
+
for (const line of prefix) {
|
|
93
|
+
const archived = archivedBySeq.get(line.event.seq);
|
|
94
|
+
if (archived === undefined) {
|
|
95
|
+
missing.push(line);
|
|
96
|
+
continue;
|
|
97
|
+
}
|
|
98
|
+
if (JSON.stringify(archived) !== JSON.stringify(line.event)) {
|
|
99
|
+
throw new ArchiveSegmentConflictError(String(line.event.seq));
|
|
100
|
+
}
|
|
101
|
+
reusedSegment = true;
|
|
102
|
+
}
|
|
103
|
+
for (const segment of contiguousGroups(missing)) {
|
|
104
|
+
const missingFirstSeq = segment[0].event.seq;
|
|
105
|
+
const missingLastSeq = segment[segment.length - 1].event.seq;
|
|
106
|
+
const archiveBytes = serializeLines(segment);
|
|
107
|
+
mkdirSync(archiveDir, { recursive: true });
|
|
108
|
+
const segmentPath = join(archiveDir, rootEventArchiveSegmentName(missingFirstSeq, missingLastSeq));
|
|
109
|
+
if (existsSync(segmentPath))
|
|
110
|
+
throw new ArchiveSegmentConflictError(`${missingFirstSeq}-${missingLastSeq}`);
|
|
111
|
+
durableReplace(`${segmentPath}.tmp`, segmentPath, archiveBytes);
|
|
112
|
+
fsyncDirectoryBestEffort(archiveDir);
|
|
113
|
+
}
|
|
114
|
+
durableReplace(`${opts.path}.archive.tmp`, opts.path, serializeLines(tail));
|
|
115
|
+
fsyncDirectoryBestEffort(dirname(opts.path));
|
|
116
|
+
}
|
|
117
|
+
return {
|
|
118
|
+
mode: 'write',
|
|
119
|
+
activeRecordsBefore: active.length,
|
|
120
|
+
keepEvents,
|
|
121
|
+
archivedRecords,
|
|
122
|
+
retainedRecords: tail.length,
|
|
123
|
+
firstSeq,
|
|
124
|
+
lastSeq,
|
|
125
|
+
archiveId,
|
|
126
|
+
reusedSegment,
|
|
127
|
+
};
|
|
128
|
+
}
|
|
129
|
+
finally {
|
|
130
|
+
releaseLock(lockPath);
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
export function readRootEventHistory(path, archiveDir = rootEventArchiveDir(path)) {
|
|
134
|
+
const bySeq = new Map();
|
|
135
|
+
for (const file of archiveSegmentFiles(archiveDir)) {
|
|
136
|
+
for (const event of readEventsLenient(join(archiveDir, file))) {
|
|
137
|
+
// Archive segments are immutable: the first segment in canonical order owns a seq. A later conflicting
|
|
138
|
+
// segment cannot silently replace it during operational reads. Strict validation still reports the
|
|
139
|
+
// conflict and blocks archive writes.
|
|
140
|
+
if (!bySeq.has(event.seq))
|
|
141
|
+
bySeq.set(event.seq, event);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// Preserve the pre-archive fail-soft behavior for routine commands. The active log is the current writer
|
|
145
|
+
// source, so it deterministically wins an active/archive conflict without crashing status/report readers.
|
|
146
|
+
for (const event of readEventsLenient(path))
|
|
147
|
+
bySeq.set(event.seq, event);
|
|
148
|
+
return [...bySeq.values()].sort((a, b) => a.seq - b.seq);
|
|
149
|
+
}
|
|
150
|
+
export function validateRootEventHistory(path) {
|
|
151
|
+
const active = readActiveStrict(path);
|
|
152
|
+
readValidatedArchive(path, active);
|
|
153
|
+
}
|
|
154
|
+
export function inspectRootEventArchive(path) {
|
|
155
|
+
const archiveDir = rootEventArchiveDir(path);
|
|
156
|
+
const files = archiveSegmentFiles(archiveDir);
|
|
157
|
+
let bytes = 0;
|
|
158
|
+
let records = 0;
|
|
159
|
+
let invalidLines = 0;
|
|
160
|
+
let firstSeq = null;
|
|
161
|
+
let lastSeq = null;
|
|
162
|
+
for (const file of files) {
|
|
163
|
+
const raw = readFileSync(join(archiveDir, file), 'utf8');
|
|
164
|
+
bytes += Buffer.byteLength(raw, 'utf8');
|
|
165
|
+
for (const line of raw.split('\n')) {
|
|
166
|
+
if (line.length === 0)
|
|
167
|
+
continue;
|
|
168
|
+
try {
|
|
169
|
+
const event = rootEvent.parse(JSON.parse(line));
|
|
170
|
+
firstSeq ??= event.seq;
|
|
171
|
+
lastSeq = event.seq;
|
|
172
|
+
records += 1;
|
|
173
|
+
}
|
|
174
|
+
catch {
|
|
175
|
+
invalidLines += 1;
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
return {
|
|
180
|
+
exists: files.length > 0,
|
|
181
|
+
segments: files.length,
|
|
182
|
+
bytes,
|
|
183
|
+
records,
|
|
184
|
+
invalidLines,
|
|
185
|
+
firstSeq,
|
|
186
|
+
lastSeq,
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
function readActiveStrict(path) {
|
|
190
|
+
if (!existsSync(path))
|
|
191
|
+
return [];
|
|
192
|
+
const out = [];
|
|
193
|
+
const lines = readFileSync(path, 'utf8').split('\n');
|
|
194
|
+
let previousSeq = null;
|
|
195
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
196
|
+
const raw = lines[index];
|
|
197
|
+
if (raw.length === 0)
|
|
198
|
+
continue;
|
|
199
|
+
let event;
|
|
200
|
+
try {
|
|
201
|
+
event = rootEvent.parse(JSON.parse(raw));
|
|
202
|
+
}
|
|
203
|
+
catch {
|
|
204
|
+
throw new InvalidRootEventLogError(index + 1, 'invalid json or event schema');
|
|
205
|
+
}
|
|
206
|
+
if (previousSeq !== null && event.seq !== previousSeq + 1) {
|
|
207
|
+
throw new InvalidRootEventLogError(index + 1, 'seq must be contiguous and strictly increasing');
|
|
208
|
+
}
|
|
209
|
+
previousSeq = event.seq;
|
|
210
|
+
out.push({ event, raw });
|
|
211
|
+
}
|
|
212
|
+
return out;
|
|
213
|
+
}
|
|
214
|
+
function readEventsLenient(path) {
|
|
215
|
+
if (!existsSync(path))
|
|
216
|
+
return [];
|
|
217
|
+
const out = [];
|
|
218
|
+
for (const line of readFileSync(path, 'utf8').split('\n')) {
|
|
219
|
+
if (line.length === 0)
|
|
220
|
+
continue;
|
|
221
|
+
try {
|
|
222
|
+
out.push(rootEvent.parse(JSON.parse(line)));
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
// Active reads retain the existing crash-tail behavior. Strict archive writes refuse these lines.
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return out;
|
|
229
|
+
}
|
|
230
|
+
function archiveSegmentFiles(archiveDir) {
|
|
231
|
+
if (!existsSync(archiveDir))
|
|
232
|
+
return [];
|
|
233
|
+
return readdirSync(archiveDir).filter((entry) => SEGMENT_PATTERN.test(entry)).sort();
|
|
234
|
+
}
|
|
235
|
+
function readArchivedEventsStrict(archiveDir) {
|
|
236
|
+
const out = new Map();
|
|
237
|
+
for (const file of archiveSegmentFiles(archiveDir)) {
|
|
238
|
+
const lines = readFileSync(join(archiveDir, file), 'utf8').split('\n');
|
|
239
|
+
let previousSeq = null;
|
|
240
|
+
for (let index = 0; index < lines.length; index += 1) {
|
|
241
|
+
const line = lines[index];
|
|
242
|
+
if (line.length === 0)
|
|
243
|
+
continue;
|
|
244
|
+
let event;
|
|
245
|
+
try {
|
|
246
|
+
event = rootEvent.parse(JSON.parse(line));
|
|
247
|
+
}
|
|
248
|
+
catch {
|
|
249
|
+
throw new InvalidRootEventArchiveError(file, index + 1);
|
|
250
|
+
}
|
|
251
|
+
if (previousSeq !== null && event.seq !== previousSeq + 1) {
|
|
252
|
+
throw new InvalidRootEventArchiveError(file, index + 1);
|
|
253
|
+
}
|
|
254
|
+
previousSeq = event.seq;
|
|
255
|
+
const current = out.get(event.seq);
|
|
256
|
+
if (current !== undefined && JSON.stringify(current) !== JSON.stringify(event)) {
|
|
257
|
+
throw new ArchiveSegmentConflictError(String(event.seq));
|
|
258
|
+
}
|
|
259
|
+
out.set(event.seq, event);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
return out;
|
|
263
|
+
}
|
|
264
|
+
function readValidatedArchive(path, active) {
|
|
265
|
+
const archived = readArchivedEventsStrict(rootEventArchiveDir(path));
|
|
266
|
+
for (const line of active) {
|
|
267
|
+
const existing = archived.get(line.event.seq);
|
|
268
|
+
if (existing !== undefined && JSON.stringify(existing) !== JSON.stringify(line.event)) {
|
|
269
|
+
throw new ArchiveSegmentConflictError(String(line.event.seq));
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
assertContinuousHistory(archived, active);
|
|
273
|
+
return archived;
|
|
274
|
+
}
|
|
275
|
+
function assertContinuousHistory(archived, active) {
|
|
276
|
+
const seqs = new Set(archived.keys());
|
|
277
|
+
for (const line of active)
|
|
278
|
+
seqs.add(line.event.seq);
|
|
279
|
+
const ordered = [...seqs].sort((left, right) => left - right);
|
|
280
|
+
if (ordered.length === 0)
|
|
281
|
+
return;
|
|
282
|
+
let expected = 1;
|
|
283
|
+
for (const actual of ordered) {
|
|
284
|
+
if (actual !== expected)
|
|
285
|
+
throw new RootEventHistoryGapError(expected, actual);
|
|
286
|
+
expected += 1;
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
function contiguousGroups(lines) {
|
|
290
|
+
const groups = [];
|
|
291
|
+
for (const line of lines) {
|
|
292
|
+
const current = groups[groups.length - 1];
|
|
293
|
+
const previous = current?.[current.length - 1];
|
|
294
|
+
if (current === undefined || previous === undefined || line.event.seq !== previous.event.seq + 1) {
|
|
295
|
+
groups.push([line]);
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
current.push(line);
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return groups;
|
|
302
|
+
}
|
|
303
|
+
function serializeLines(lines) {
|
|
304
|
+
return lines.length === 0 ? '' : `${lines.map((line) => line.raw).join('\n')}\n`;
|
|
305
|
+
}
|
|
306
|
+
function durableReplace(tmpPath, finalPath, contents) {
|
|
307
|
+
let fd = null;
|
|
308
|
+
try {
|
|
309
|
+
fd = openSync(tmpPath, 'w', 0o600);
|
|
310
|
+
writeSync(fd, contents, undefined, 'utf8');
|
|
311
|
+
fsyncSync(fd);
|
|
312
|
+
closeSync(fd);
|
|
313
|
+
fd = null;
|
|
314
|
+
renameSync(tmpPath, finalPath);
|
|
315
|
+
}
|
|
316
|
+
catch (error) {
|
|
317
|
+
if (fd !== null)
|
|
318
|
+
closeSync(fd);
|
|
319
|
+
rmSync(tmpPath, { force: true });
|
|
320
|
+
throw error;
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
function fsyncDirectoryBestEffort(path) {
|
|
324
|
+
let fd = null;
|
|
325
|
+
try {
|
|
326
|
+
fd = openSync(path, 'r');
|
|
327
|
+
fsyncSync(fd);
|
|
328
|
+
}
|
|
329
|
+
catch {
|
|
330
|
+
// Windows and some filesystems do not support fsync on directories.
|
|
331
|
+
}
|
|
332
|
+
finally {
|
|
333
|
+
if (fd !== null)
|
|
334
|
+
closeSync(fd);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
function normalizeKeepEvents(value) {
|
|
338
|
+
if (value === undefined)
|
|
339
|
+
return ROOT_EVENT_ARCHIVE_DEFAULT_KEEP_EVENTS;
|
|
340
|
+
if (!Number.isFinite(value) || value < 1)
|
|
341
|
+
throw new RangeError('keepEvents must be a positive integer');
|
|
342
|
+
return Math.floor(value);
|
|
343
|
+
}
|
|
@@ -2,6 +2,7 @@ import { openSync, writeSync, fsyncSync, closeSync, statSync, readSync, mkdirSyn
|
|
|
2
2
|
import { dirname } from 'node:path';
|
|
3
3
|
import { monotonicFactory } from 'ulid';
|
|
4
4
|
import { acquireLock, releaseLock } from '../util/fileLock.js';
|
|
5
|
+
import { readRootEventHistory } from './eventArchive.js';
|
|
5
6
|
// Monotonic ULIDs: plain ulid() randomizes the low 80 bits, so two ids minted in the SAME millisecond can sort
|
|
6
7
|
// out of order — the event log wants time-sortable eventIds (and a flaky CI test proved it). The monotonic
|
|
7
8
|
// factory increments within a millisecond, guaranteeing each successive eventId is strictly greater.
|
|
@@ -73,18 +74,7 @@ export class EventStore {
|
|
|
73
74
|
}
|
|
74
75
|
/** 读全部事件 (跳过尾部半行/损坏行). */
|
|
75
76
|
readAll() {
|
|
76
|
-
|
|
77
|
-
return [];
|
|
78
|
-
const out = [];
|
|
79
|
-
for (const l of readFileSync(this.path, 'utf8').split('\n')) {
|
|
80
|
-
if (!l)
|
|
81
|
-
continue;
|
|
82
|
-
try {
|
|
83
|
-
out.push(rootEvent.parse(JSON.parse(l)));
|
|
84
|
-
}
|
|
85
|
-
catch { /* 崩溃半行: 跳过 */ }
|
|
86
|
-
}
|
|
87
|
-
return out;
|
|
77
|
+
return readRootEventHistory(this.path);
|
|
88
78
|
}
|
|
89
79
|
*iterate(fromSeq = 0) {
|
|
90
80
|
for (const e of this.readAll())
|
package/dist/events/ingest.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { EventStore, type EventStoreOptions } from './eventStore.js';
|
|
|
2
2
|
import type { RawEvent, RootEvent } from './eventSchema.js';
|
|
3
3
|
import type { EventSink } from './sink.js';
|
|
4
4
|
/** 已知事件类型 (军杰 §9; 可 registerEventType 扩展). */
|
|
5
|
-
export declare const EVENT_TYPES: readonly ["cycle.started", "cycle.signals_collected", "cycle.solidified", "cycle.failed", "cycle.aborted", "cycle.heartbeat", "cycle.consumed", "decision.gene_selected", "decision.triggered", "decision.suppressed", "personality.selected", "personality.risk_gated", "personality.mutated", "personality.stats_updated", "personality.pivoted", "signals.extracted", "mutation.built", "capsule.produced", "evolution_event.projected", "observer.quarantined", "observer.dead_letter", "actor.human.nudge", "actor.human.intervene", "actor.human.teach", "actor.human.observe", "actor.human.review.approve", "actor.human.review.reject", "gene.distilled", "gene.distill_shadowed", "anti_gene.distilled", "anti_gene.distill_shadowed", "anti_gene.benchmark_result", "anti_gene.rollout_result", "reflection.recorded", "material.batch_ready", "value.reuse_hit", "value.inject", "value.reuse_outcome", "value.recall"];
|
|
5
|
+
export declare const EVENT_TYPES: readonly ["cycle.started", "cycle.signals_collected", "cycle.solidified", "cycle.failed", "cycle.aborted", "cycle.heartbeat", "cycle.consumed", "decision.gene_selected", "decision.triggered", "decision.suppressed", "personality.selected", "personality.risk_gated", "personality.mutated", "personality.stats_updated", "personality.pivoted", "signals.extracted", "mutation.built", "capsule.produced", "evolution_event.projected", "observer.quarantined", "observer.dead_letter", "actor.human.nudge", "actor.human.intervene", "actor.human.teach", "actor.human.observe", "actor.human.review.approve", "actor.human.review.reject", "actor.human.trust.promote", "actor.human.trust.revoke", "actor.human.sidecar.recover", "gene.distilled", "gene.distill_shadowed", "anti_gene.distilled", "anti_gene.distill_shadowed", "anti_gene.benchmark_result", "anti_gene.rollout_result", "reflection.recorded", "material.batch_ready", "value.reuse_hit", "value.inject", "value.reuse_outcome", "value.recall"];
|
|
6
6
|
export type EventType = (typeof EVENT_TYPES)[number];
|
|
7
7
|
export declare function registerEventType(t: string): void;
|
|
8
8
|
export declare function isKnownEventType(t: string): boolean;
|
package/dist/events/ingest.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import { dirname, join } from 'node:path';
|
|
1
2
|
import { EventStore } from './eventStore.js';
|
|
3
|
+
import { createIssueDraftForEventBestEffort } from '../issueReporter/index.js';
|
|
2
4
|
/** 已知事件类型 (军杰 §9; 可 registerEventType 扩展). */
|
|
3
5
|
export const EVENT_TYPES = [
|
|
4
6
|
'cycle.started', 'cycle.signals_collected', 'cycle.solidified', 'cycle.failed',
|
|
@@ -10,6 +12,8 @@ export const EVENT_TYPES = [
|
|
|
10
12
|
'observer.quarantined', 'observer.dead_letter',
|
|
11
13
|
'actor.human.nudge', 'actor.human.intervene', 'actor.human.teach', 'actor.human.observe',
|
|
12
14
|
'actor.human.review.approve', 'actor.human.review.reject',
|
|
15
|
+
'actor.human.trust.promote', 'actor.human.trust.revoke',
|
|
16
|
+
'actor.human.sidecar.recover',
|
|
13
17
|
'gene.distilled', 'gene.distill_shadowed',
|
|
14
18
|
'anti_gene.distilled', 'anti_gene.distill_shadowed',
|
|
15
19
|
'anti_gene.benchmark_result', 'anti_gene.rollout_result',
|
|
@@ -49,6 +53,11 @@ export class Ingestor {
|
|
|
49
53
|
if (raw.actor?.kind === 'human' && !raw.actor.id)
|
|
50
54
|
throw new IngestValidationError('actor.kind=human 必带 actor.id (审计, 军杰 §9.7)');
|
|
51
55
|
const evt = await this.store.append(raw);
|
|
56
|
+
createIssueDraftForEventBestEffort(evt, {
|
|
57
|
+
rootDir: join(dirname(this.store.path), 'issue-reporter'),
|
|
58
|
+
workspaceScope: process.cwd(),
|
|
59
|
+
env: process.env,
|
|
60
|
+
});
|
|
52
61
|
this.sink?.dispatch(evt);
|
|
53
62
|
return evt;
|
|
54
63
|
}
|
package/dist/events/paths.d.ts
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
/** ~/.evomap, 可 EVOLVER_HOME/EVOMAP_HOME 覆盖. */
|
|
2
|
-
export declare function evomapHome(): string;
|
|
3
|
-
export declare function rootEventsPath(): string;
|
|
4
|
-
export declare function mvDir(): string;
|
|
2
|
+
export declare function evomapHome(env?: Readonly<Record<string, string | undefined>>): string;
|
|
3
|
+
export declare function rootEventsPath(env?: Readonly<Record<string, string | undefined>>): string;
|
|
4
|
+
export declare function mvDir(env?: Readonly<Record<string, string | undefined>>): string;
|
|
5
5
|
/** 可进化人格模型持久化文件 (五维向量 + 各键统计 + 变更历史). v1 personality_state.json 的 v2 落点. */
|
|
6
|
-
export declare function personalityStatePath(): string;
|
|
7
|
-
export declare function assetsDir(): string;
|
|
6
|
+
export declare function personalityStatePath(env?: Readonly<Record<string, string | undefined>>): string;
|
|
7
|
+
export declare function assetsDir(env?: Readonly<Record<string, string | undefined>>): string;
|
|
8
8
|
/** M1 raw-material substrate (append-only jsonl consumed by the cycle). */
|
|
9
|
-
export declare function materialDir(): string;
|
|
9
|
+
export declare function materialDir(env?: Readonly<Record<string, string | undefined>>): string;
|
|
10
10
|
/** MaterialStore backing file. */
|
|
11
|
-
export declare function materialStorePath(): string;
|
|
11
|
+
export declare function materialStorePath(env?: Readonly<Record<string, string | undefined>>): string;
|
|
12
12
|
/** Per-source watermark cursor used to make re-ingest idempotent (file-level dedup). */
|
|
13
|
-
export declare function materialWatermarkPath(): string;
|
|
13
|
+
export declare function materialWatermarkPath(env?: Readonly<Record<string, string | undefined>>): string;
|
|
14
14
|
/** Proxy LLM-trace day-files dir (`llm-trace-YYYYMMDD.jsonl`), the route-savings source for the value ledger.
|
|
15
15
|
* Mirrors the proxy's EVOLVER_LLM_TRACE_DIR default so the outreach layer reads what the proxy wrote. */
|
|
16
|
-
export declare function tracesDir(): string;
|
|
16
|
+
export declare function tracesDir(env?: Readonly<Record<string, string | undefined>>): string;
|
|
17
17
|
/** Hub-asset audit trail (`asset_call_log.jsonl`): one JSONL line per hub-asset interaction (search hit/miss,
|
|
18
18
|
* reuse/reference, publish, review). Written best-effort by AssetCallLog; the desktop's RecallHistory / 召回历程
|
|
19
19
|
* reads it. Defaults to the evomap home root, beside assets/ + evolution/.
|
|
20
20
|
* NOTE(reuse/#234): confirm this matches where the proxy/RecallHistory reads — best-effort append, so a path
|
|
21
21
|
* mismatch degrades the audit line, never the reuse write itself. */
|
|
22
|
-
export declare function assetCallLogPath(): string;
|
|
22
|
+
export declare function assetCallLogPath(env?: Readonly<Record<string, string | undefined>>): string;
|
package/dist/events/paths.js
CHANGED
|
@@ -1,44 +1,44 @@
|
|
|
1
1
|
import { homedir } from 'node:os';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
/** ~/.evomap, 可 EVOLVER_HOME/EVOMAP_HOME 覆盖. */
|
|
4
|
-
export function evomapHome() {
|
|
5
|
-
return
|
|
4
|
+
export function evomapHome(env = process.env) {
|
|
5
|
+
return env['EVOLVER_HOME'] ?? env['EVOMAP_HOME'] ?? join(homedir(), '.evomap');
|
|
6
6
|
}
|
|
7
|
-
export function rootEventsPath() {
|
|
8
|
-
return join(evomapHome(), 'evolution', 'root_events.jsonl');
|
|
7
|
+
export function rootEventsPath(env = process.env) {
|
|
8
|
+
return join(evomapHome(env), 'evolution', 'root_events.jsonl');
|
|
9
9
|
}
|
|
10
|
-
export function mvDir() {
|
|
11
|
-
return join(evomapHome(), 'evolution', 'mv');
|
|
10
|
+
export function mvDir(env = process.env) {
|
|
11
|
+
return join(evomapHome(env), 'evolution', 'mv');
|
|
12
12
|
}
|
|
13
13
|
/** 可进化人格模型持久化文件 (五维向量 + 各键统计 + 变更历史). v1 personality_state.json 的 v2 落点. */
|
|
14
|
-
export function personalityStatePath() {
|
|
15
|
-
return join(evomapHome(), 'evolution', 'personality_state.json');
|
|
14
|
+
export function personalityStatePath(env = process.env) {
|
|
15
|
+
return join(evomapHome(env), 'evolution', 'personality_state.json');
|
|
16
16
|
}
|
|
17
|
-
export function assetsDir() {
|
|
18
|
-
return join(evomapHome(), 'assets');
|
|
17
|
+
export function assetsDir(env = process.env) {
|
|
18
|
+
return join(evomapHome(env), 'assets');
|
|
19
19
|
}
|
|
20
20
|
/** M1 raw-material substrate (append-only jsonl consumed by the cycle). */
|
|
21
|
-
export function materialDir() {
|
|
22
|
-
return join(evomapHome(), 'evolution', 'material');
|
|
21
|
+
export function materialDir(env = process.env) {
|
|
22
|
+
return join(evomapHome(env), 'evolution', 'material');
|
|
23
23
|
}
|
|
24
24
|
/** MaterialStore backing file. */
|
|
25
|
-
export function materialStorePath() {
|
|
26
|
-
return join(materialDir(), 'material.jsonl');
|
|
25
|
+
export function materialStorePath(env = process.env) {
|
|
26
|
+
return join(materialDir(env), 'material.jsonl');
|
|
27
27
|
}
|
|
28
28
|
/** Per-source watermark cursor used to make re-ingest idempotent (file-level dedup). */
|
|
29
|
-
export function materialWatermarkPath() {
|
|
30
|
-
return join(materialDir(), 'watermark.json');
|
|
29
|
+
export function materialWatermarkPath(env = process.env) {
|
|
30
|
+
return join(materialDir(env), 'watermark.json');
|
|
31
31
|
}
|
|
32
32
|
/** Proxy LLM-trace day-files dir (`llm-trace-YYYYMMDD.jsonl`), the route-savings source for the value ledger.
|
|
33
33
|
* Mirrors the proxy's EVOLVER_LLM_TRACE_DIR default so the outreach layer reads what the proxy wrote. */
|
|
34
|
-
export function tracesDir() {
|
|
35
|
-
return
|
|
34
|
+
export function tracesDir(env = process.env) {
|
|
35
|
+
return env['EVOLVER_LLM_TRACE_DIR'] ?? join(evomapHome(env), 'proxy', 'traces');
|
|
36
36
|
}
|
|
37
37
|
/** Hub-asset audit trail (`asset_call_log.jsonl`): one JSONL line per hub-asset interaction (search hit/miss,
|
|
38
38
|
* reuse/reference, publish, review). Written best-effort by AssetCallLog; the desktop's RecallHistory / 召回历程
|
|
39
39
|
* reads it. Defaults to the evomap home root, beside assets/ + evolution/.
|
|
40
40
|
* NOTE(reuse/#234): confirm this matches where the proxy/RecallHistory reads — best-effort append, so a path
|
|
41
41
|
* mismatch degrades the audit line, never the reuse write itself. */
|
|
42
|
-
export function assetCallLogPath() {
|
|
43
|
-
return join(evomapHome(), 'asset_call_log.jsonl');
|
|
42
|
+
export function assetCallLogPath(env = process.env) {
|
|
43
|
+
return join(evomapHome(env), 'asset_call_log.jsonl');
|
|
44
44
|
}
|
package/dist/events/public.d.ts
CHANGED
|
@@ -5,10 +5,12 @@ export type { Projector } from './replayer.js';
|
|
|
5
5
|
export { eventCountsProjector, DEFAULT_PROJECTORS } from './projectors.js';
|
|
6
6
|
export type { EventCountsMV } from './projectors.js';
|
|
7
7
|
export { LineTooLargeError, MAX_LINE_BYTES } from './eventStore.js';
|
|
8
|
+
export { ArchiveSegmentConflictError, InvalidRootEventArchiveError, InvalidRootEventLogError, RootEventHistoryGapError, archiveRootEvents, inspectRootEventArchive, planRootEventArchive, readRootEventHistory, rootEventArchiveDir, rootEventArchiveSegmentName, validateRootEventHistory, ROOT_EVENT_ARCHIVE_DEFAULT_KEEP_EVENTS, } from './eventArchive.js';
|
|
9
|
+
export type { RootEventArchiveOptions, RootEventArchivePlan, RootEventArchiveResult, RootEventArchiveStats, } from './eventArchive.js';
|
|
8
10
|
export { rootEventsPath, evomapHome, mvDir, personalityStatePath, assetsDir, materialDir, materialStorePath, materialWatermarkPath, tracesDir, assetCallLogPath } from './paths.js';
|
|
9
11
|
export { EVENT_SCHEMA_VERSION } from './eventSchema.js';
|
|
10
12
|
export type { RootEvent, RawEvent, HumanNarrative, Actor, Replayability } from './eventSchema.js';
|
|
11
13
|
export { readEvents, statusReport, listCycles, showCycle, listTriggers, dailySummary, buildNarrativeSnapshot, NARRATIVE_DEFAULT_LIMIT, NARRATIVE_MAX_LIMIT, } from './reports.js';
|
|
12
|
-
export { buildRetentionReport, defaultMaterialCursorPath, RETENTION_DEFAULT_MAX_MATERIAL_BYTES, RETENTION_DEFAULT_MAX_MATERIAL_RECORDS, RETENTION_DEFAULT_MAX_ROOT_BYTES, RETENTION_DEFAULT_MAX_ROOT_EVENTS, RETENTION_DEFAULT_ROOT_TAIL_EVENTS, RETENTION_DEFAULT_WATCH_RATIO, } from './retention.js';
|
|
14
|
+
export { buildRetentionReport, defaultMaterialCursorPath, defaultMaterialCursorPaths, RETENTION_DEFAULT_MAX_MATERIAL_BYTES, RETENTION_DEFAULT_MAX_MATERIAL_RECORDS, RETENTION_DEFAULT_MAX_ROOT_BYTES, RETENTION_DEFAULT_MAX_ROOT_EVENTS, RETENTION_DEFAULT_ROOT_TAIL_EVENTS, RETENTION_DEFAULT_WATCH_RATIO, } from './retention.js';
|
|
13
15
|
export type { ReportEvent, StatusReport, CycleSummary, CycleTimeline, TriggerRow, DailySummary, NarrativeEntry, NarrativeOutcome, NarrativeSnapshot, NarrativeSnapshotOptions, } from './reports.js';
|
|
14
16
|
export type { MaterialRetentionSnapshot, RetentionReport, RetentionReportOptions, RetentionState, RetentionThresholds, RootRetentionSnapshot, } from './retention.js';
|
package/dist/events/public.js
CHANGED
|
@@ -2,7 +2,8 @@ export { Ingestor, EVENT_TYPES, registerEventType, isKnownEventType, IngestValid
|
|
|
2
2
|
export { Replayer } from './replayer.js';
|
|
3
3
|
export { eventCountsProjector, DEFAULT_PROJECTORS } from './projectors.js';
|
|
4
4
|
export { LineTooLargeError, MAX_LINE_BYTES } from './eventStore.js';
|
|
5
|
+
export { ArchiveSegmentConflictError, InvalidRootEventArchiveError, InvalidRootEventLogError, RootEventHistoryGapError, archiveRootEvents, inspectRootEventArchive, planRootEventArchive, readRootEventHistory, rootEventArchiveDir, rootEventArchiveSegmentName, validateRootEventHistory, ROOT_EVENT_ARCHIVE_DEFAULT_KEEP_EVENTS, } from './eventArchive.js';
|
|
5
6
|
export { rootEventsPath, evomapHome, mvDir, personalityStatePath, assetsDir, materialDir, materialStorePath, materialWatermarkPath, tracesDir, assetCallLogPath } from './paths.js';
|
|
6
7
|
export { EVENT_SCHEMA_VERSION } from './eventSchema.js';
|
|
7
8
|
export { readEvents, statusReport, listCycles, showCycle, listTriggers, dailySummary, buildNarrativeSnapshot, NARRATIVE_DEFAULT_LIMIT, NARRATIVE_MAX_LIMIT, } from './reports.js';
|
|
8
|
-
export { buildRetentionReport, defaultMaterialCursorPath, RETENTION_DEFAULT_MAX_MATERIAL_BYTES, RETENTION_DEFAULT_MAX_MATERIAL_RECORDS, RETENTION_DEFAULT_MAX_ROOT_BYTES, RETENTION_DEFAULT_MAX_ROOT_EVENTS, RETENTION_DEFAULT_ROOT_TAIL_EVENTS, RETENTION_DEFAULT_WATCH_RATIO, } from './retention.js';
|
|
9
|
+
export { buildRetentionReport, defaultMaterialCursorPath, defaultMaterialCursorPaths, RETENTION_DEFAULT_MAX_MATERIAL_BYTES, RETENTION_DEFAULT_MAX_MATERIAL_RECORDS, RETENTION_DEFAULT_MAX_ROOT_BYTES, RETENTION_DEFAULT_MAX_ROOT_EVENTS, RETENTION_DEFAULT_ROOT_TAIL_EVENTS, RETENTION_DEFAULT_WATCH_RATIO, } from './retention.js';
|
|
@@ -4,7 +4,7 @@ export declare const RETENTION_DEFAULT_MAX_ROOT_BYTES: number;
|
|
|
4
4
|
export declare const RETENTION_DEFAULT_MAX_MATERIAL_RECORDS = 10000;
|
|
5
5
|
export declare const RETENTION_DEFAULT_MAX_MATERIAL_BYTES: number;
|
|
6
6
|
export declare const RETENTION_DEFAULT_WATCH_RATIO = 0.8;
|
|
7
|
-
export declare const RETENTION_DEFAULT_ROOT_TAIL_EVENTS
|
|
7
|
+
export declare const RETENTION_DEFAULT_ROOT_TAIL_EVENTS = 10000;
|
|
8
8
|
export interface RetentionThresholds {
|
|
9
9
|
maxRecords: number;
|
|
10
10
|
maxBytes: number;
|
|
@@ -22,6 +22,17 @@ export interface RootRetentionSnapshot {
|
|
|
22
22
|
lastSeq: number | null;
|
|
23
23
|
firstTs: string | null;
|
|
24
24
|
lastTs: string | null;
|
|
25
|
+
archiveSegments: number;
|
|
26
|
+
archiveRecords: number;
|
|
27
|
+
archiveBytes: number;
|
|
28
|
+
archiveInvalidLines: number;
|
|
29
|
+
historyRecords: number;
|
|
30
|
+
historyBytes: number;
|
|
31
|
+
historyConflicts: number;
|
|
32
|
+
historyGaps: number;
|
|
33
|
+
historyIntegrityErrors: number;
|
|
34
|
+
archiveRotationSupported: true;
|
|
35
|
+
archiveRotationSafe: boolean;
|
|
25
36
|
protectTailEvents: number;
|
|
26
37
|
destructivePruneSafe: false;
|
|
27
38
|
reason: string;
|
|
@@ -36,12 +47,22 @@ export interface MaterialRetentionSnapshot {
|
|
|
36
47
|
thresholds: RetentionThresholds;
|
|
37
48
|
firstCapturedAt: string | null;
|
|
38
49
|
lastCapturedAt: string | null;
|
|
50
|
+
archiveSegments: number;
|
|
51
|
+
archiveRecords: number;
|
|
52
|
+
archiveBytes: number;
|
|
53
|
+
archiveInvalidLines: number;
|
|
54
|
+
historyRecords: number;
|
|
55
|
+
historyBytes: number;
|
|
56
|
+
cursorCount: number;
|
|
57
|
+
minCursor: number;
|
|
39
58
|
cursorValid: boolean;
|
|
40
59
|
cursorInRange: boolean;
|
|
41
60
|
cursor: number;
|
|
42
61
|
effectiveCursor: number;
|
|
43
62
|
consumedPrefix: number;
|
|
44
63
|
pending: number;
|
|
64
|
+
archiveRotationSupported: true;
|
|
65
|
+
archiveRotationSafe: boolean;
|
|
45
66
|
destructivePruneSafe: false;
|
|
46
67
|
reason: string;
|
|
47
68
|
}
|
|
@@ -58,6 +79,7 @@ export interface RetentionReportOptions {
|
|
|
58
79
|
rootEventsPath?: string;
|
|
59
80
|
materialStorePath?: string;
|
|
60
81
|
materialCursorPath?: string;
|
|
82
|
+
materialCursorPaths?: readonly string[];
|
|
61
83
|
now?: () => number;
|
|
62
84
|
maxRootEvents?: number;
|
|
63
85
|
maxRootBytes?: number;
|
|
@@ -67,4 +89,5 @@ export interface RetentionReportOptions {
|
|
|
67
89
|
protectRootTailEvents?: number;
|
|
68
90
|
}
|
|
69
91
|
export declare function defaultMaterialCursorPath(path?: string): string;
|
|
92
|
+
export declare function defaultMaterialCursorPaths(path?: string): string[];
|
|
70
93
|
export declare function buildRetentionReport(opts?: RetentionReportOptions): RetentionReport;
|