@evo-dev/core 0.0.1-alpha.19 → 0.0.1-alpha.20
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 +59 -8
- package/dist/index.js +803 -230
- package/package.json +1 -1
- package/src/evolution/evidence/session-memory/retention.ts +359 -78
- package/src/evolution/evidence/session-memory/segment.ts +15 -1
- package/src/evolution/evidence/session-memory/storage.ts +37 -6
- package/src/evolution/evidence/session-memory/types.ts +5 -2
- package/src/evolution/evidence/session-memory/updater.ts +23 -15
- package/src/evolution/knowledge/changes.ts +6 -0
- package/src/evolution/knowledge/freshness.ts +17 -57
- package/src/evolution/knowledge/index.ts +204 -12
- package/src/evolution/knowledge/support.ts +135 -0
- package/src/hooks/index.ts +124 -20
package/dist/config/index.js
CHANGED
|
@@ -709,6 +709,40 @@ async function ensureOkfKnowledgeBase(homeDir) {
|
|
|
709
709
|
}
|
|
710
710
|
await rebuildOkfKnowledgeIndexes({ homeDir });
|
|
711
711
|
}
|
|
712
|
+
function normalizeKnowledgeSupportRef(value, path) {
|
|
713
|
+
const input = assertRecordValue(value, path);
|
|
714
|
+
const kind = readRequiredString(input.kind, `${path}.kind`);
|
|
715
|
+
if (kind !== "user-declaration" && kind !== "repo-policy" && kind !== "state-observation" && kind !== "verified-outcome" && kind !== "semantic-inference") {
|
|
716
|
+
throw new Error(`${path}.kind is invalid.`);
|
|
717
|
+
}
|
|
718
|
+
const observedAt = readRequiredString(input.observedAt, `${path}.observedAt`);
|
|
719
|
+
if (!Number.isFinite(Date.parse(observedAt)))
|
|
720
|
+
throw new Error(`${path}.observedAt is invalid.`);
|
|
721
|
+
const subjectFingerprint = input.subjectFingerprint === null ? null : sanitizeOkfText(readRequiredString(input.subjectFingerprint, `${path}.subjectFingerprint`));
|
|
722
|
+
return {
|
|
723
|
+
id: sanitizeOkfText(readRequiredString(input.id, `${path}.id`)),
|
|
724
|
+
kind,
|
|
725
|
+
sourceRefId: sanitizeOkfText(readRequiredString(input.sourceRefId, `${path}.sourceRefId`)),
|
|
726
|
+
subjectFingerprint,
|
|
727
|
+
observedAt: new Date(observedAt).toISOString()
|
|
728
|
+
};
|
|
729
|
+
}
|
|
730
|
+
function assertRecordValue(value, path) {
|
|
731
|
+
if (!isRecord(value))
|
|
732
|
+
throw new Error(`${path} must be an object.`);
|
|
733
|
+
return value;
|
|
734
|
+
}
|
|
735
|
+
function readRequiredString(value, path) {
|
|
736
|
+
if (!isNonEmptyString2(value))
|
|
737
|
+
throw new Error(`${path} must be a non-empty string.`);
|
|
738
|
+
return value;
|
|
739
|
+
}
|
|
740
|
+
function isRecord(value) {
|
|
741
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
742
|
+
}
|
|
743
|
+
function isNonEmptyString2(value) {
|
|
744
|
+
return typeof value === "string" && value.trim() !== "";
|
|
745
|
+
}
|
|
712
746
|
async function rebuildOkfKnowledgeIndexes(input) {
|
|
713
747
|
const paths2 = resolveOkfKnowledgePaths(input.homeDir);
|
|
714
748
|
await mkdir(paths2.indexesDir, { recursive: true });
|
|
@@ -887,6 +921,7 @@ function parseOkfConceptFile(okfDir, filePath, content) {
|
|
|
887
921
|
lifecycle: lifecycleParsed.lifecycle,
|
|
888
922
|
lifecyclePersisted: lifecycleParsed.persisted,
|
|
889
923
|
verificationSnapshot: parseOkfVerificationSnapshot(frontmatter),
|
|
924
|
+
supportRef: parseOkfKnowledgeSupportRef(frontmatter),
|
|
890
925
|
title,
|
|
891
926
|
description,
|
|
892
927
|
tags,
|
|
@@ -897,6 +932,22 @@ function parseOkfConceptFile(okfDir, filePath, content) {
|
|
|
897
932
|
body: parsed.body
|
|
898
933
|
};
|
|
899
934
|
}
|
|
935
|
+
function parseOkfKnowledgeSupportRef(frontmatter) {
|
|
936
|
+
const block = extractNestedYamlBlock(frontmatter, "evodev", "supportRef");
|
|
937
|
+
if (block === null)
|
|
938
|
+
return null;
|
|
939
|
+
try {
|
|
940
|
+
return normalizeKnowledgeSupportRef({
|
|
941
|
+
id: readIndentedYamlScalar(block, "id"),
|
|
942
|
+
kind: readIndentedYamlScalar(block, "kind"),
|
|
943
|
+
sourceRefId: readIndentedYamlScalar(block, "sourceRefId"),
|
|
944
|
+
subjectFingerprint: readNullableLifecycleString(readIndentedYamlScalar(block, "subjectFingerprint")),
|
|
945
|
+
observedAt: readIndentedYamlScalar(block, "observedAt")
|
|
946
|
+
}, "evodev.supportRef");
|
|
947
|
+
} catch {
|
|
948
|
+
return null;
|
|
949
|
+
}
|
|
950
|
+
}
|
|
900
951
|
function parseOkfVerificationSnapshot(frontmatter) {
|
|
901
952
|
const block = extractNestedYamlBlock(frontmatter, "evodev", "verificationSnapshot");
|
|
902
953
|
if (block === null)
|
|
@@ -1386,9 +1437,9 @@ function parseHookSettings(value) {
|
|
|
1386
1437
|
const defaults = createDefaultHookSettings();
|
|
1387
1438
|
if (value === undefined || value === null)
|
|
1388
1439
|
return defaults;
|
|
1389
|
-
if (!
|
|
1440
|
+
if (!isRecord2(value))
|
|
1390
1441
|
throw new Error("Invalid hooks settings; expected object.");
|
|
1391
|
-
const observability =
|
|
1442
|
+
const observability = isRecord2(value.observability) ? value.observability : undefined;
|
|
1392
1443
|
optionalBoolean2(observability?.metadataOnly, defaults.observability.metadataOnly, "hooks.observability.metadataOnly");
|
|
1393
1444
|
optionalBoolean2(observability?.rawPayloadStorage, defaults.observability.rawPayloadStorage, "hooks.observability.rawPayloadStorage");
|
|
1394
1445
|
return {
|
|
@@ -1409,9 +1460,9 @@ function parseHookSettings(value) {
|
|
|
1409
1460
|
};
|
|
1410
1461
|
}
|
|
1411
1462
|
function parseHookTargetSettings(value, defaults, target) {
|
|
1412
|
-
const targets =
|
|
1413
|
-
const targetSettings =
|
|
1414
|
-
const events =
|
|
1463
|
+
const targets = isRecord2(value) ? value : {};
|
|
1464
|
+
const targetSettings = isRecord2(targets[target]) ? targets[target] : {};
|
|
1465
|
+
const events = isRecord2(targetSettings.events) ? targetSettings.events : {};
|
|
1415
1466
|
const parsedEvents = { ...defaults.events };
|
|
1416
1467
|
for (const eventType of CANONICAL_HOOK_EVENT_TYPES) {
|
|
1417
1468
|
parsedEvents[eventType] = optionalBoolean2(events[eventType], defaults.events[eventType], `hooks.targets.${target}.events.${eventType}`);
|
|
@@ -1428,7 +1479,7 @@ function optionalBoolean2(value, fallback, path) {
|
|
|
1428
1479
|
throw new Error(`Invalid ${path}; expected boolean.`);
|
|
1429
1480
|
return value;
|
|
1430
1481
|
}
|
|
1431
|
-
function
|
|
1482
|
+
function isRecord2(value) {
|
|
1432
1483
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
1433
1484
|
}
|
|
1434
1485
|
|
|
@@ -1974,7 +2025,7 @@ async function writeIndexIfMissingOrMigrate(filePath, kind, defaults) {
|
|
|
1974
2025
|
} catch (error) {
|
|
1975
2026
|
throw new EvoDevConfigError(`Invalid bootstrap index JSON (${describeFileError(error)})`, filePath);
|
|
1976
2027
|
}
|
|
1977
|
-
if (!
|
|
2028
|
+
if (!isRecord3(existing) || existing.kind !== kind)
|
|
1978
2029
|
return;
|
|
1979
2030
|
const migrated = { ...defaults, ...existing };
|
|
1980
2031
|
if (Object.keys(defaults).every((key) => (key in existing)))
|
|
@@ -2007,7 +2058,7 @@ function describeFileError(error) {
|
|
|
2007
2058
|
function isNodeError(error) {
|
|
2008
2059
|
return error instanceof Error && "code" in error;
|
|
2009
2060
|
}
|
|
2010
|
-
function
|
|
2061
|
+
function isRecord3(value) {
|
|
2011
2062
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
2012
2063
|
}
|
|
2013
2064
|
export {
|