@evo-dev/core 0.0.1-alpha.15 → 0.0.1-alpha.17
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/config/index.js +45 -2
- package/dist/index.js +12899 -11408
- package/package.json +1 -1
- package/src/config/settings.ts +45 -7
- package/src/evolution/candidates/index.ts +50 -0
- package/src/evolution/evidence/session-memory/retention.ts +2 -1
- package/src/evolution/knowledge/change-store.ts +558 -0
- package/src/evolution/knowledge/changes.ts +453 -0
- package/src/evolution/knowledge/freshness.ts +109 -0
- package/src/evolution/knowledge/index.ts +471 -55
- package/src/evolution/knowledge/review.ts +446 -0
- package/src/evolution/processor/process.ts +5 -1
- package/src/evolution/schema.ts +29 -1
- package/src/evolution/shared.ts +108 -0
- package/src/index.ts +4 -0
- package/src/team/index.ts +6 -0
package/package.json
CHANGED
package/src/config/settings.ts
CHANGED
|
@@ -15,14 +15,25 @@ export interface PluginSettings {
|
|
|
15
15
|
}
|
|
16
16
|
|
|
17
17
|
export interface MemorySettings {
|
|
18
|
-
|
|
18
|
+
reviewKnowledgeUpdates: boolean;
|
|
19
19
|
runtimeInjection: boolean;
|
|
20
20
|
staleReview: boolean;
|
|
21
21
|
lexicalIndex: boolean;
|
|
22
22
|
sessionMemory: SessionMemoryPolicySnapshot;
|
|
23
23
|
}
|
|
24
24
|
|
|
25
|
+
type LegacyMemorySettingsInput = Partial<MemorySettings> & {
|
|
26
|
+
/**
|
|
27
|
+
* Deprecated compatibility input. This flag was never connected to OKF activation and is
|
|
28
|
+
* intentionally omitted from canonical settings output.
|
|
29
|
+
*/
|
|
30
|
+
autoAccept?: boolean;
|
|
31
|
+
};
|
|
32
|
+
|
|
25
33
|
export interface EvolutionSettings {
|
|
34
|
+
schedule: {
|
|
35
|
+
dailyTime: string;
|
|
36
|
+
};
|
|
26
37
|
automation: {
|
|
27
38
|
knowledge: boolean;
|
|
28
39
|
semanticKnowledge: boolean;
|
|
@@ -70,8 +81,9 @@ export type SettingsInput = Partial<{
|
|
|
70
81
|
doctor: Partial<EvoDevSettings["doctor"]>;
|
|
71
82
|
hooks: unknown;
|
|
72
83
|
teamRuntime: Partial<TeamRuntimeSettings>;
|
|
73
|
-
memory:
|
|
84
|
+
memory: LegacyMemorySettingsInput;
|
|
74
85
|
evolution: Partial<{
|
|
86
|
+
schedule: Partial<EvolutionSettings["schedule"]>;
|
|
75
87
|
automation: Partial<EvolutionSettings["automation"]>;
|
|
76
88
|
}>;
|
|
77
89
|
}>;
|
|
@@ -130,7 +142,7 @@ export function createDefaultTeamRuntimeSettings(): TeamRuntimeSettings {
|
|
|
130
142
|
|
|
131
143
|
export function createDefaultMemorySettings(): MemorySettings {
|
|
132
144
|
return {
|
|
133
|
-
|
|
145
|
+
reviewKnowledgeUpdates: true,
|
|
134
146
|
runtimeInjection: true,
|
|
135
147
|
staleReview: true,
|
|
136
148
|
lexicalIndex: true,
|
|
@@ -140,6 +152,9 @@ export function createDefaultMemorySettings(): MemorySettings {
|
|
|
140
152
|
|
|
141
153
|
export function createDefaultEvolutionSettings(): EvolutionSettings {
|
|
142
154
|
return {
|
|
155
|
+
schedule: {
|
|
156
|
+
dailyTime: "02:00",
|
|
157
|
+
},
|
|
143
158
|
automation: {
|
|
144
159
|
knowledge: true,
|
|
145
160
|
semanticKnowledge: false,
|
|
@@ -195,6 +210,10 @@ export function mergeSettings(
|
|
|
195
210
|
evolution: {
|
|
196
211
|
...defaults.evolution,
|
|
197
212
|
...existing.evolution,
|
|
213
|
+
schedule: {
|
|
214
|
+
...defaults.evolution.schedule,
|
|
215
|
+
...existing.evolution?.schedule,
|
|
216
|
+
},
|
|
198
217
|
automation: {
|
|
199
218
|
...defaults.evolution.automation,
|
|
200
219
|
...existing.evolution?.automation,
|
|
@@ -272,8 +291,15 @@ export function parseSettings(value: unknown): EvoDevSettings {
|
|
|
272
291
|
function parseEvolutionSettings(value: unknown, path: string): EvolutionSettings {
|
|
273
292
|
const input = expectRecord(value, path);
|
|
274
293
|
const defaults = createDefaultEvolutionSettings();
|
|
294
|
+
const schedule = expectRecord(input.schedule ?? defaults.schedule, `${path}.schedule`);
|
|
275
295
|
const automation = expectRecord(input.automation ?? defaults.automation, `${path}.automation`);
|
|
276
296
|
return {
|
|
297
|
+
schedule: {
|
|
298
|
+
dailyTime: parseDailyTime(
|
|
299
|
+
schedule.dailyTime ?? defaults.schedule.dailyTime,
|
|
300
|
+
`${path}.schedule.dailyTime`,
|
|
301
|
+
),
|
|
302
|
+
},
|
|
277
303
|
automation: {
|
|
278
304
|
knowledge:
|
|
279
305
|
automation.knowledge === undefined
|
|
@@ -291,14 +317,26 @@ function parseEvolutionSettings(value: unknown, path: string): EvolutionSettings
|
|
|
291
317
|
};
|
|
292
318
|
}
|
|
293
319
|
|
|
320
|
+
function parseDailyTime(value: unknown, path: string): string {
|
|
321
|
+
const dailyTime = expectString(value, path);
|
|
322
|
+
const match = /^(\d{2}):(\d{2})$/u.exec(dailyTime);
|
|
323
|
+
if (match === null || Number(match[1]) > 23 || Number(match[2]) > 59) {
|
|
324
|
+
throw new EvoDevConfigError(`Invalid ${path}; expected a 24-hour HH:MM time`);
|
|
325
|
+
}
|
|
326
|
+
return dailyTime;
|
|
327
|
+
}
|
|
328
|
+
|
|
294
329
|
function parseMemorySettings(value: unknown, path: string): MemorySettings {
|
|
295
330
|
const input = expectRecord(value, path);
|
|
296
331
|
const defaults = createDefaultMemorySettings();
|
|
332
|
+
if (input.autoAccept !== undefined) {
|
|
333
|
+
expectBoolean(input.autoAccept, `${path}.autoAccept`);
|
|
334
|
+
}
|
|
297
335
|
return {
|
|
298
|
-
|
|
299
|
-
input.
|
|
300
|
-
? defaults.
|
|
301
|
-
: expectBoolean(input.
|
|
336
|
+
reviewKnowledgeUpdates:
|
|
337
|
+
input.reviewKnowledgeUpdates === undefined
|
|
338
|
+
? defaults.reviewKnowledgeUpdates
|
|
339
|
+
: expectBoolean(input.reviewKnowledgeUpdates, `${path}.reviewKnowledgeUpdates`),
|
|
302
340
|
runtimeInjection:
|
|
303
341
|
input.runtimeInjection === undefined
|
|
304
342
|
? defaults.runtimeInjection
|
|
@@ -437,6 +437,56 @@ export async function updateEvolutionRepoProposalReviewState(input: {
|
|
|
437
437
|
);
|
|
438
438
|
}
|
|
439
439
|
|
|
440
|
+
export async function supersedeEvolutionRepoProposal(input: {
|
|
441
|
+
homeDir: string;
|
|
442
|
+
proposalId: string;
|
|
443
|
+
projectKey?: string;
|
|
444
|
+
expectedReviewState?: EvolutionRepoProposal["reviewState"];
|
|
445
|
+
reason: string;
|
|
446
|
+
now?: string | Date;
|
|
447
|
+
}): Promise<{ path: string; record: EvolutionRepoProposal; changed: boolean }> {
|
|
448
|
+
return await withEvolutionReviewDecisionLock(
|
|
449
|
+
{ homeDir: input.homeDir, kind: "repo-proposal", itemId: input.proposalId },
|
|
450
|
+
async () => {
|
|
451
|
+
const record = await readEvolutionRepoProposalById(input);
|
|
452
|
+
const paths = resolveEvolutionPaths({
|
|
453
|
+
homeDir: input.homeDir,
|
|
454
|
+
projectKey: record.projectKey,
|
|
455
|
+
runId: record.provenance.runId,
|
|
456
|
+
});
|
|
457
|
+
const path = join(paths.repoProposalsDir, `${record.id}.json`);
|
|
458
|
+
if (record.reviewState === "superseded") return { path, record, changed: false };
|
|
459
|
+
if (
|
|
460
|
+
input.expectedReviewState !== undefined &&
|
|
461
|
+
record.reviewState !== input.expectedReviewState
|
|
462
|
+
) {
|
|
463
|
+
throw new Error("Repo proposal review state changed before supersession was applied.");
|
|
464
|
+
}
|
|
465
|
+
if (record.reviewState !== "pending" && record.reviewState !== "deferred") {
|
|
466
|
+
throw new Error("Only pending or deferred repo proposals can be superseded.");
|
|
467
|
+
}
|
|
468
|
+
const reason = input.reason.trim();
|
|
469
|
+
if (reason === "" || reason.length > 500) {
|
|
470
|
+
throw new Error("Repo proposal supersession reason must be 1-500 characters.");
|
|
471
|
+
}
|
|
472
|
+
const changedAt = normalizeTimestamp(input.now);
|
|
473
|
+
const next: EvolutionRepoProposal = {
|
|
474
|
+
...record,
|
|
475
|
+
reviewState: "superseded",
|
|
476
|
+
reviewStateChangedAt: changedAt,
|
|
477
|
+
supersession: {
|
|
478
|
+
policy: "session-proposal-v2",
|
|
479
|
+
reason: sanitizeText(reason),
|
|
480
|
+
supersededAt: changedAt,
|
|
481
|
+
},
|
|
482
|
+
};
|
|
483
|
+
validateEvolutionRepoProposal(next);
|
|
484
|
+
await writeRepoProposalAndIndex({ homeDir: input.homeDir, proposal: next, changedAt });
|
|
485
|
+
return { path, record: next, changed: true };
|
|
486
|
+
},
|
|
487
|
+
);
|
|
488
|
+
}
|
|
489
|
+
|
|
440
490
|
export async function updateEvolutionRepoProposalImprovementEval(input: {
|
|
441
491
|
homeDir: string;
|
|
442
492
|
proposalId: string;
|
|
@@ -312,7 +312,8 @@ function hasPendingDerivedReview(
|
|
|
312
312
|
(proposal) =>
|
|
313
313
|
proposal.provenance.runId === runId &&
|
|
314
314
|
proposal.reviewState !== "rejected" &&
|
|
315
|
-
proposal.reviewState !== "applied"
|
|
315
|
+
proposal.reviewState !== "applied" &&
|
|
316
|
+
proposal.reviewState !== "superseded",
|
|
316
317
|
)
|
|
317
318
|
) {
|
|
318
319
|
return true;
|