@remnic/core 9.3.734 → 9.3.736
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/access-boundary.d.ts +8 -6
- package/dist/access-boundary.js +9 -9
- package/dist/access-cli.js +24 -24
- package/dist/access-http.d.ts +8 -6
- package/dist/access-http.js +14 -14
- package/dist/access-mcp.d.ts +8 -6
- package/dist/access-mcp.js +13 -13
- package/dist/access-operations-batch.js +11 -11
- package/dist/access-operations.d.ts +8 -6
- package/dist/access-operations.js +12 -12
- package/dist/{access-service-rjFfmfKB.d.ts → access-service-CdC0q4pr.d.ts} +3 -3
- package/dist/access-service.d.ts +8 -6
- package/dist/access-service.js +8 -8
- package/dist/access-surface-catalog.d.ts +8 -6
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-memory-bridge.js +3 -3
- package/dist/active-recall.d.ts +1 -1
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +7 -5
- package/dist/briefing.d.ts +1 -1
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer.d.ts +1 -1
- package/dist/calibration.d.ts +1 -1
- package/dist/capabilities.d.ts +101 -2
- package/dist/capabilities.js +13 -3
- package/dist/{catalog-DHYXzM4-.d.ts → catalog-D2NLDg4S.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/{chunk-IWMGBNXY.js → chunk-2T2N7ISV.js} +3 -3
- package/dist/{chunk-K7PAILHO.js → chunk-5BOQNB2K.js} +3 -3
- package/dist/{chunk-Q5LGXWNG.js → chunk-AAIHDIMD.js} +6 -6
- package/dist/{chunk-WHQ2JB35.js → chunk-AB2E5DCN.js} +2 -2
- package/dist/{chunk-Z7J3OAPR.js → chunk-AE2HPUP7.js} +726 -645
- package/dist/chunk-AE2HPUP7.js.map +1 -0
- package/dist/{chunk-FAGERSH2.js → chunk-AE7NTZ75.js} +3 -3
- package/dist/{chunk-V5OVSGB6.js → chunk-AESC5OQJ.js} +2 -2
- package/dist/{chunk-7FPJFCXL.js → chunk-BXPG5AVX.js} +4 -4
- package/dist/{chunk-UH3NYOHN.js → chunk-CHJIWG2H.js} +2 -2
- package/dist/{chunk-IDIXGGDN.js → chunk-E4LYJ7PY.js} +6 -6
- package/dist/{chunk-WTTVFSCO.js → chunk-FF36YNKY.js} +3 -3
- package/dist/{chunk-TJSQHO4Q.js → chunk-FLPKEMSO.js} +2 -2
- package/dist/{chunk-UF3N7IRP.js → chunk-G54IDCD3.js} +45 -41
- package/dist/chunk-G54IDCD3.js.map +1 -0
- package/dist/{chunk-UK6U5C3N.js → chunk-GB2FZOWB.js} +3 -3
- package/dist/{chunk-5OYHJIJN.js → chunk-GYICIICQ.js} +3 -3
- package/dist/{chunk-PEF2XOIV.js → chunk-HFXZIF3V.js} +3 -3
- package/dist/{chunk-PKO5NJ65.js → chunk-HLPYL6LC.js} +27 -24
- package/dist/chunk-HLPYL6LC.js.map +1 -0
- package/dist/{chunk-ET5HXSQL.js → chunk-IPI45Q4S.js} +2 -2
- package/dist/{chunk-2L5RTVMO.js → chunk-IX4L7E5G.js} +2 -2
- package/dist/{chunk-SYX73XD7.js → chunk-IXGXALRV.js} +10 -7
- package/dist/chunk-IXGXALRV.js.map +1 -0
- package/dist/{chunk-SHJGBAIW.js → chunk-JWDE7OVJ.js} +44 -2
- package/dist/{chunk-SHJGBAIW.js.map → chunk-JWDE7OVJ.js.map} +1 -1
- package/dist/{chunk-IZLTOS5L.js → chunk-K3Y2SJTN.js} +4 -4
- package/dist/{chunk-CILX2XW7.js → chunk-NDKW67ER.js} +2 -2
- package/dist/{chunk-54RCE5Z3.js → chunk-NNJKEAP2.js} +2 -2
- package/dist/{chunk-LV32K4OP.js → chunk-OYHYBHHI.js} +2 -2
- package/dist/{chunk-5DIKZKOD.js → chunk-P6VLG7KE.js} +2 -2
- package/dist/{chunk-T7CGPTFU.js → chunk-QNTLWH3T.js} +3 -3
- package/dist/{chunk-6U7TES2M.js → chunk-UO6MPN77.js} +13 -12
- package/dist/chunk-UO6MPN77.js.map +1 -0
- package/dist/{chunk-NDYQIN6C.js → chunk-VOEVVIP3.js} +3 -3
- package/dist/{chunk-3QETM5NG.js → chunk-ZBZ4XULO.js} +3 -3
- package/dist/{cli-XVpmSoQs.d.ts → cli-BHy6Bo6u.d.ts} +3 -3
- package/dist/cli.d.ts +9 -7
- package/dist/cli.js +20 -20
- package/dist/compounding/engine.d.ts +1 -1
- package/dist/compounding/engine.js +2 -2
- package/dist/compounding/preference-consolidator.d.ts +1 -1
- package/dist/compression-optimizer.d.ts +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/consolidation-provenance-check.d.ts +1 -1
- package/dist/consolidation-undo.d.ts +1 -1
- package/dist/contradiction/index.d.ts +1 -1
- package/dist/contradiction/index.js +2 -2
- package/dist/{contradiction-scan-OUHMCUBT.js → contradiction-scan-2B4AE4TI.js} +3 -3
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/chunker.d.ts +1 -1
- package/dist/conversation-index/faiss-adapter.d.ts +1 -1
- package/dist/conversation-index/indexer.d.ts +1 -1
- package/dist/conversation-index/search.d.ts +1 -1
- package/dist/day-summary.d.ts +1 -1
- package/dist/delinearize.d.ts +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer.d.ts +1 -1
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/embedding-fallback.js +2 -2
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +1 -1
- package/dist/entity-retrieval.js +2 -2
- package/dist/entity-schema.d.ts +1 -1
- package/dist/explicit-capture.d.ts +7 -5
- package/dist/explicit-capture.js +2 -2
- package/dist/extraction-faithfulness.d.ts +1 -1
- package/dist/extraction-judge-telemetry.d.ts +1 -1
- package/dist/extraction-judge-training.d.ts +1 -1
- package/dist/extraction-judge.d.ts +1 -1
- package/dist/extraction.d.ts +1 -1
- package/dist/extraction.js +3 -3
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/{first-start-migration-W4U6XDKI.js → first-start-migration-2RQYDIZ7.js} +6 -5
- package/dist/first-start-migration-2RQYDIZ7.js.map +1 -0
- package/dist/graph-dashboard-diff.d.ts +1 -1
- package/dist/graph-dashboard-key.d.ts +1 -1
- package/dist/graph-dashboard-parser.d.ts +1 -1
- package/dist/graph-edge-reinforcement.d.ts +1 -1
- package/dist/graph-snapshot.d.ts +1 -1
- package/dist/graph.d.ts +1 -1
- package/dist/identity-continuity.d.ts +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/index.d.ts +9 -9
- package/dist/index.js +30 -30
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +1 -1
- package/dist/local-llm.js +2 -2
- package/dist/local-model-endpoint.d.ts +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/mcp-memory-inspector-app.d.ts +8 -6
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-worth-outcomes.d.ts +1 -1
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +2 -2
- package/dist/namespaces/migrate.js +6 -6
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/principal.js +2 -2
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/search.js +4 -4
- package/dist/namespaces/storage.d.ts +2 -2
- package/dist/namespaces/storage.js +2 -2
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +1 -1
- package/dist/operator-toolkit.js +11 -11
- package/dist/orchestration/compression-guideline-coordinator.d.ts +1 -1
- package/dist/orchestration/compression-guideline-coordinator.js +2 -1
- package/dist/orchestration/maintenance.d.ts +2 -2
- package/dist/orchestration/maintenance.js +6 -6
- package/dist/{orchestrator-BXi-gadS.d.ts → orchestrator-C-xp_rtZ.d.ts} +141 -18
- package/dist/orchestrator.d.ts +7 -5
- package/dist/orchestrator.js +19 -21
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/provenance.d.ts +1 -1
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +1 -1
- package/dist/recall-disclosure-escalation.d.ts +1 -1
- package/dist/recall-explain-renderer.d.ts +1 -1
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-xray-cli.d.ts +1 -1
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray.d.ts +1 -1
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/retrieval-agents.d.ts +1 -1
- package/dist/retrieval-tiers.d.ts +1 -1
- package/dist/routing/engine.d.ts +1 -1
- package/dist/routing/store.d.ts +1 -1
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/embed-helper.js +2 -2
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/factory.js +3 -3
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +3 -3
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/{semantic-consolidation-DeL5grLx.d.ts → semantic-consolidation-COdwU-me.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/session-observer-bands.d.ts +1 -1
- package/dist/session-observer-state.d.ts +1 -1
- package/dist/shared-context/manager.d.ts +1 -1
- package/dist/signal.d.ts +1 -1
- package/dist/storage.d.ts +1 -1
- package/dist/summarizer.d.ts +1 -1
- package/dist/summarizer.js +3 -3
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/temporal-supersession.d.ts +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +1 -1
- package/dist/tier-routing.d.ts +1 -1
- package/dist/{tier-stats-LSM35HZY.js → tier-stats-KPDIISG7.js} +6 -5
- package/dist/tier-stats-KPDIISG7.js.map +1 -0
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-CpFz51Pv.d.ts → types-w3Y232yi.d.ts} +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/package.json +2 -2
- package/src/access-service.ts +20 -20
- package/src/capabilities.test.ts +197 -0
- package/src/capabilities.ts +206 -0
- package/src/cli/creation-ledger-commands.ts +2 -2
- package/src/cli/research-status-commands.ts +13 -13
- package/src/cli.ts +17 -17
- package/src/maintenance/first-start-migration.ts +3 -3
- package/src/maintenance/tier-stats.ts +3 -3
- package/src/operator-toolkit.ts +8 -8
- package/src/orchestration/compression-guideline-coordinator.ts +7 -6
- package/src/orchestration/entity-synthesis-coordinator.ts +319 -0
- package/src/orchestration/lifecycle-policy-coordinator.ts +504 -0
- package/src/orchestrator.ts +40 -618
- package/dist/chunk-6U7TES2M.js.map +0 -1
- package/dist/chunk-PKO5NJ65.js.map +0 -1
- package/dist/chunk-SYX73XD7.js.map +0 -1
- package/dist/chunk-UF3N7IRP.js.map +0 -1
- package/dist/chunk-Z7J3OAPR.js.map +0 -1
- package/dist/first-start-migration-W4U6XDKI.js.map +0 -1
- package/dist/tier-stats-LSM35HZY.js.map +0 -1
- /package/dist/{chunk-IWMGBNXY.js.map → chunk-2T2N7ISV.js.map} +0 -0
- /package/dist/{chunk-K7PAILHO.js.map → chunk-5BOQNB2K.js.map} +0 -0
- /package/dist/{chunk-Q5LGXWNG.js.map → chunk-AAIHDIMD.js.map} +0 -0
- /package/dist/{chunk-WHQ2JB35.js.map → chunk-AB2E5DCN.js.map} +0 -0
- /package/dist/{chunk-FAGERSH2.js.map → chunk-AE7NTZ75.js.map} +0 -0
- /package/dist/{chunk-V5OVSGB6.js.map → chunk-AESC5OQJ.js.map} +0 -0
- /package/dist/{chunk-7FPJFCXL.js.map → chunk-BXPG5AVX.js.map} +0 -0
- /package/dist/{chunk-UH3NYOHN.js.map → chunk-CHJIWG2H.js.map} +0 -0
- /package/dist/{chunk-IDIXGGDN.js.map → chunk-E4LYJ7PY.js.map} +0 -0
- /package/dist/{chunk-WTTVFSCO.js.map → chunk-FF36YNKY.js.map} +0 -0
- /package/dist/{chunk-TJSQHO4Q.js.map → chunk-FLPKEMSO.js.map} +0 -0
- /package/dist/{chunk-UK6U5C3N.js.map → chunk-GB2FZOWB.js.map} +0 -0
- /package/dist/{chunk-5OYHJIJN.js.map → chunk-GYICIICQ.js.map} +0 -0
- /package/dist/{chunk-PEF2XOIV.js.map → chunk-HFXZIF3V.js.map} +0 -0
- /package/dist/{chunk-ET5HXSQL.js.map → chunk-IPI45Q4S.js.map} +0 -0
- /package/dist/{chunk-2L5RTVMO.js.map → chunk-IX4L7E5G.js.map} +0 -0
- /package/dist/{chunk-IZLTOS5L.js.map → chunk-K3Y2SJTN.js.map} +0 -0
- /package/dist/{chunk-CILX2XW7.js.map → chunk-NDKW67ER.js.map} +0 -0
- /package/dist/{chunk-54RCE5Z3.js.map → chunk-NNJKEAP2.js.map} +0 -0
- /package/dist/{chunk-LV32K4OP.js.map → chunk-OYHYBHHI.js.map} +0 -0
- /package/dist/{chunk-5DIKZKOD.js.map → chunk-P6VLG7KE.js.map} +0 -0
- /package/dist/{chunk-T7CGPTFU.js.map → chunk-QNTLWH3T.js.map} +0 -0
- /package/dist/{chunk-NDYQIN6C.js.map → chunk-VOEVVIP3.js.map} +0 -0
- /package/dist/{chunk-3QETM5NG.js.map → chunk-ZBZ4XULO.js.map} +0 -0
- /package/dist/{contradiction-scan-OUHMCUBT.js.map → contradiction-scan-2B4AE4TI.js.map} +0 -0
package/src/orchestrator.ts
CHANGED
|
@@ -79,12 +79,9 @@ import {
|
|
|
79
79
|
} from "./search/factory.js";
|
|
80
80
|
import { NoopSearchBackend } from "./search/noop-backend.js";
|
|
81
81
|
import {
|
|
82
|
-
compareEntityTimestamps,
|
|
83
82
|
StorageManager,
|
|
84
83
|
ContentHashIndex,
|
|
85
|
-
fingerprintEntityStructuredFacts,
|
|
86
84
|
normalizeAttributePairs,
|
|
87
|
-
parseEntityFile,
|
|
88
85
|
} from "./storage.js";
|
|
89
86
|
import { sanitizeMemoryContent } from "./sanitize.js";
|
|
90
87
|
import { ThreadingManager } from "./threading.js";
|
|
@@ -102,6 +99,8 @@ import { TierMigrationCoordinator } from "./orchestration/tier-migration-coordin
|
|
|
102
99
|
import { ExtractionQueueCoordinator } from "./orchestration/extraction-queue-coordinator.js";
|
|
103
100
|
import { CompressionGuidelineCoordinator } from "./orchestration/compression-guideline-coordinator.js";
|
|
104
101
|
import { SemanticConsolidationCoordinator } from "./orchestration/semantic-consolidation-coordinator.js";
|
|
102
|
+
import { LifecyclePolicyCoordinator } from "./orchestration/lifecycle-policy-coordinator.js";
|
|
103
|
+
import { EntitySynthesisCoordinator } from "./orchestration/entity-synthesis-coordinator.js";
|
|
105
104
|
import {
|
|
106
105
|
runLiveConnectorsOnce,
|
|
107
106
|
type LiveConnectorsRunSummary,
|
|
@@ -281,7 +280,7 @@ import {
|
|
|
281
280
|
resolveQmdCapabilities,
|
|
282
281
|
resolveIdentityContinuityCapabilities,
|
|
283
282
|
resolveLocalLlmCapabilities,
|
|
284
|
-
} from "./capabilities.js";
|
|
283
|
+
resolveSecurityCapabilities, resolveEvalCapabilities, resolveUtilityLearningCapabilities, resolveObjectiveStateCapabilities, resolveCompressionCapabilities} from "./capabilities.js";
|
|
285
284
|
import { DEFAULT_TAXONOMY } from "./taxonomy/index.js";
|
|
286
285
|
import {
|
|
287
286
|
searchHarmonicRetrieval,
|
|
@@ -450,8 +449,6 @@ import type {
|
|
|
450
449
|
RecallPlanMode,
|
|
451
450
|
RecallSectionConfig,
|
|
452
451
|
RecallTierExplain,
|
|
453
|
-
EntityStructuredSection,
|
|
454
|
-
EntityTimelineEntry,
|
|
455
452
|
} from "./types.js";
|
|
456
453
|
import { disposeDefaultArchiveScoring, getDefaultArchiveScoring, memoryFileToScoreItem } from "./recall/archive-scoring.js";
|
|
457
454
|
|
|
@@ -491,92 +488,6 @@ interface ExtractionRunResult {
|
|
|
491
488
|
postPersistMetadataFailed?: boolean;
|
|
492
489
|
}
|
|
493
490
|
|
|
494
|
-
export function dedupeEntitySynthesisEvidenceEntries(
|
|
495
|
-
entries: EntityTimelineEntry[],
|
|
496
|
-
): EntityTimelineEntry[] {
|
|
497
|
-
const dedupedEvidenceEntries: EntityTimelineEntry[] = [];
|
|
498
|
-
const evidenceByFact = new Map<string, {
|
|
499
|
-
newest: EntityTimelineEntry;
|
|
500
|
-
oldest: EntityTimelineEntry;
|
|
501
|
-
}>();
|
|
502
|
-
|
|
503
|
-
for (const entry of entries) {
|
|
504
|
-
const normalizedFact = entry.text.trim();
|
|
505
|
-
if (!normalizedFact) continue;
|
|
506
|
-
const existing = evidenceByFact.get(normalizedFact);
|
|
507
|
-
if (!existing) {
|
|
508
|
-
evidenceByFact.set(normalizedFact, { newest: entry, oldest: entry });
|
|
509
|
-
continue;
|
|
510
|
-
}
|
|
511
|
-
if (compareEntityTimestamps(entry.timestamp, existing.newest.timestamp) > 0) {
|
|
512
|
-
existing.newest = entry;
|
|
513
|
-
}
|
|
514
|
-
if (compareEntityTimestamps(entry.timestamp, existing.oldest.timestamp) < 0) {
|
|
515
|
-
existing.oldest = entry;
|
|
516
|
-
}
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
for (const { newest, oldest } of evidenceByFact.values()) {
|
|
520
|
-
dedupedEvidenceEntries.push(newest);
|
|
521
|
-
const newestKey = [
|
|
522
|
-
newest.timestamp,
|
|
523
|
-
newest.source ?? "",
|
|
524
|
-
newest.sessionKey ?? "",
|
|
525
|
-
newest.principal ?? "",
|
|
526
|
-
newest.text,
|
|
527
|
-
].join("\u0000");
|
|
528
|
-
const oldestKey = [
|
|
529
|
-
oldest.timestamp,
|
|
530
|
-
oldest.source ?? "",
|
|
531
|
-
oldest.sessionKey ?? "",
|
|
532
|
-
oldest.principal ?? "",
|
|
533
|
-
oldest.text,
|
|
534
|
-
].join("\u0000");
|
|
535
|
-
if (oldestKey !== newestKey) {
|
|
536
|
-
dedupedEvidenceEntries.push(oldest);
|
|
537
|
-
}
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
return dedupedEvidenceEntries;
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
function flattenStructuredSectionEvidence(
|
|
544
|
-
sections: EntityStructuredSection[] | undefined,
|
|
545
|
-
): EntityTimelineEntry[] {
|
|
546
|
-
return (sections ?? []).flatMap((section) =>
|
|
547
|
-
section.facts
|
|
548
|
-
.map((fact) => fact.trim())
|
|
549
|
-
.filter((fact) => fact.length > 0)
|
|
550
|
-
.map((fact) => ({
|
|
551
|
-
timestamp: "",
|
|
552
|
-
text: fact,
|
|
553
|
-
source: `section:${section.title}`,
|
|
554
|
-
})),
|
|
555
|
-
);
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
function fingerprintEntitySynthesisEvidence(entity: {
|
|
559
|
-
timeline: EntityTimelineEntry[];
|
|
560
|
-
structuredSections?: EntityStructuredSection[];
|
|
561
|
-
}): string {
|
|
562
|
-
const fingerprint = createHash("sha256");
|
|
563
|
-
const timelineEntries = entity.timeline
|
|
564
|
-
.map((entry) => [
|
|
565
|
-
entry.timestamp,
|
|
566
|
-
entry.source ?? "",
|
|
567
|
-
entry.sessionKey ?? "",
|
|
568
|
-
entry.principal ?? "",
|
|
569
|
-
entry.text,
|
|
570
|
-
].join("\u0000"))
|
|
571
|
-
.sort();
|
|
572
|
-
const timelineEntrySeparator = String.fromCharCode(1);
|
|
573
|
-
const structuredFactsSeparator = String.fromCharCode(2);
|
|
574
|
-
fingerprint.update(timelineEntries.join(timelineEntrySeparator));
|
|
575
|
-
fingerprint.update(structuredFactsSeparator);
|
|
576
|
-
fingerprint.update(fingerprintEntityStructuredFacts(entity) ?? "");
|
|
577
|
-
return fingerprint.digest("hex");
|
|
578
|
-
}
|
|
579
|
-
|
|
580
491
|
export interface GraphRecallSnapshot {
|
|
581
492
|
recordedAt: string;
|
|
582
493
|
mode: RecallPlanMode | string;
|
|
@@ -1902,6 +1813,8 @@ export class Orchestrator {
|
|
|
1902
1813
|
readonly tierMigrationCoordinator: TierMigrationCoordinator;
|
|
1903
1814
|
readonly compressionGuidelineCoordinator: CompressionGuidelineCoordinator;
|
|
1904
1815
|
readonly semanticConsolidationCoordinator: SemanticConsolidationCoordinator;
|
|
1816
|
+
readonly lifecyclePolicyCoordinator: LifecyclePolicyCoordinator;
|
|
1817
|
+
readonly entitySynthesisCoordinator: EntitySynthesisCoordinator;
|
|
1905
1818
|
/**
|
|
1906
1819
|
* In-memory X-ray snapshot from the most recent `recall()` call that
|
|
1907
1820
|
* was invoked with `xrayCapture: true` (issue #570 PR 1). Scope is
|
|
@@ -3025,6 +2938,12 @@ export class Orchestrator {
|
|
|
3025
2938
|
fastChatCompletion: (messages, options) =>
|
|
3026
2939
|
this.fastChatCompletion(messages, options),
|
|
3027
2940
|
});
|
|
2941
|
+
this.entitySynthesisCoordinator = new EntitySynthesisCoordinator({
|
|
2942
|
+
config,
|
|
2943
|
+
getStorage: (namespace) => this.getStorage(namespace),
|
|
2944
|
+
fastChatCompletion: (messages, options) =>
|
|
2945
|
+
this.fastChatCompletion(messages, options),
|
|
2946
|
+
});
|
|
3028
2947
|
|
|
3029
2948
|
this.sessionObserver = new SessionObserverState({
|
|
3030
2949
|
memoryDir: config.memoryDir,
|
|
@@ -3098,6 +3017,16 @@ export class Orchestrator {
|
|
|
3098
3017
|
config.gatewayConfig,
|
|
3099
3018
|
this.modelRegistry,
|
|
3100
3019
|
);
|
|
3020
|
+
this.lifecyclePolicyCoordinator = new LifecyclePolicyCoordinator({
|
|
3021
|
+
config,
|
|
3022
|
+
getStorage: () => this.storage,
|
|
3023
|
+
extraction: this.extraction,
|
|
3024
|
+
embeddingFallback: this.embeddingFallback,
|
|
3025
|
+
getEffectiveLifecycleThresholds: () => this.effectiveLifecycleThresholds(),
|
|
3026
|
+
removeContentHashForMemory: (targetStorage, memory, context) =>
|
|
3027
|
+
this.removeContentHashForMemory(targetStorage, memory, context),
|
|
3028
|
+
saveContentHashIndexes: () => this.saveContentHashIndexes(),
|
|
3029
|
+
});
|
|
3101
3030
|
this.threading = new ThreadingManager(
|
|
3102
3031
|
path.join(config.memoryDir, "threads"),
|
|
3103
3032
|
config.threadingGapMinutes,
|
|
@@ -3510,8 +3439,8 @@ export class Orchestrator {
|
|
|
3510
3439
|
this.runtimePolicyValues = await this.policyRuntime.loadRuntimeValues();
|
|
3511
3440
|
this.utilityRuntimeValues = await loadUtilityRuntimeValues({
|
|
3512
3441
|
memoryDir: this.config.memoryDir,
|
|
3513
|
-
memoryUtilityLearningEnabled: this.config.
|
|
3514
|
-
promotionByOutcomeEnabled: this.config.
|
|
3442
|
+
memoryUtilityLearningEnabled: resolveUtilityLearningCapabilities(this.config).memoryUtilityLearning,
|
|
3443
|
+
promotionByOutcomeEnabled: resolveUtilityLearningCapabilities(this.config).promotionByOutcome,
|
|
3515
3444
|
});
|
|
3516
3445
|
|
|
3517
3446
|
// Initialize content-hash dedup index
|
|
@@ -4432,150 +4361,10 @@ export class Orchestrator {
|
|
|
4432
4361
|
namespace?: string,
|
|
4433
4362
|
maxEntities: number = 5,
|
|
4434
4363
|
): Promise<number> {
|
|
4435
|
-
|
|
4436
|
-
|
|
4437
|
-
|
|
4438
|
-
|
|
4439
|
-
) return 0;
|
|
4440
|
-
const storage = await this.getStorage(namespace);
|
|
4441
|
-
const queued = await storage.refreshEntitySynthesisQueue();
|
|
4442
|
-
let processed = 0;
|
|
4443
|
-
let attempted = 0;
|
|
4444
|
-
|
|
4445
|
-
for (const entityName of queued) {
|
|
4446
|
-
if (attempted >= maxEntities) break;
|
|
4447
|
-
attempted += 1;
|
|
4448
|
-
try {
|
|
4449
|
-
const raw = await storage.readEntity(entityName);
|
|
4450
|
-
if (!raw) continue;
|
|
4451
|
-
const entity = parseEntityFile(raw, this.config.entitySchemas);
|
|
4452
|
-
const previousSynthesis = entity.synthesis || entity.summary || "";
|
|
4453
|
-
const sortedTimelineEntries = entity.timeline
|
|
4454
|
-
.slice()
|
|
4455
|
-
.sort((left, right) => compareEntityTimestamps(right.timestamp, left.timestamp));
|
|
4456
|
-
const newerTimelineEntries = sortedTimelineEntries.filter(
|
|
4457
|
-
(entry) =>
|
|
4458
|
-
!entity.synthesisUpdatedAt
|
|
4459
|
-
|| compareEntityTimestamps(entry.timestamp, entity.synthesisUpdatedAt) > 0,
|
|
4460
|
-
);
|
|
4461
|
-
const appendedTimelineEntries = entity.synthesisTimelineCount === undefined
|
|
4462
|
-
? []
|
|
4463
|
-
: entity.timeline.slice(Math.max(0, entity.synthesisTimelineCount));
|
|
4464
|
-
const structuredEvidenceEntries = flattenStructuredSectionEvidence(entity.structuredSections);
|
|
4465
|
-
const structuredEvidenceCount = structuredEvidenceEntries.length;
|
|
4466
|
-
const structuredEvidenceDigest = fingerprintEntityStructuredFacts(entity);
|
|
4467
|
-
const structuredEvidenceDrifted = structuredEvidenceDigest !== (entity.synthesisStructuredFactDigest?.trim() || undefined);
|
|
4468
|
-
const appendedStructuredEvidenceEntries = entity.synthesisStructuredFactCount === undefined
|
|
4469
|
-
|| structuredEvidenceDrifted
|
|
4470
|
-
? structuredEvidenceEntries
|
|
4471
|
-
: structuredEvidenceEntries.slice(Math.max(0, entity.synthesisStructuredFactCount));
|
|
4472
|
-
const candidateEvidenceEntries = [
|
|
4473
|
-
...newerTimelineEntries,
|
|
4474
|
-
...appendedTimelineEntries,
|
|
4475
|
-
...appendedStructuredEvidenceEntries,
|
|
4476
|
-
]
|
|
4477
|
-
.slice()
|
|
4478
|
-
.sort((left, right) => compareEntityTimestamps(right.timestamp, left.timestamp));
|
|
4479
|
-
const dedupedEvidenceEntries = dedupeEntitySynthesisEvidenceEntries(
|
|
4480
|
-
candidateEvidenceEntries.length > 0
|
|
4481
|
-
? candidateEvidenceEntries
|
|
4482
|
-
: [...sortedTimelineEntries, ...structuredEvidenceEntries],
|
|
4483
|
-
);
|
|
4484
|
-
const chronologicalEvidenceEntries = dedupedEvidenceEntries
|
|
4485
|
-
.slice()
|
|
4486
|
-
.sort((left, right) => compareEntityTimestamps(left.timestamp, right.timestamp));
|
|
4487
|
-
if (chronologicalEvidenceEntries.length === 0) continue;
|
|
4488
|
-
const latestEvidenceTimestamp = chronologicalEvidenceEntries
|
|
4489
|
-
.slice()
|
|
4490
|
-
.reverse()
|
|
4491
|
-
.map((entry) => entry.timestamp?.trim() || undefined)
|
|
4492
|
-
.find((timestamp) => Boolean(timestamp));
|
|
4493
|
-
const previousSynthesisUpdatedAt = entity.synthesisUpdatedAt?.trim() || undefined;
|
|
4494
|
-
const nextSynthesisUpdatedAt = compareEntityTimestamps(
|
|
4495
|
-
latestEvidenceTimestamp,
|
|
4496
|
-
previousSynthesisUpdatedAt,
|
|
4497
|
-
) >= 0
|
|
4498
|
-
? latestEvidenceTimestamp
|
|
4499
|
-
: previousSynthesisUpdatedAt;
|
|
4500
|
-
const evidenceBatches: typeof chronologicalEvidenceEntries[] = [];
|
|
4501
|
-
for (let index = 0; index < chronologicalEvidenceEntries.length; index += 8) {
|
|
4502
|
-
evidenceBatches.push(chronologicalEvidenceEntries.slice(index, index + 8));
|
|
4503
|
-
}
|
|
4504
|
-
|
|
4505
|
-
let nextSynthesis = previousSynthesis;
|
|
4506
|
-
let batchFailed = false;
|
|
4507
|
-
for (const evidenceEntries of evidenceBatches) {
|
|
4508
|
-
const evidenceText = evidenceEntries
|
|
4509
|
-
.map((entry) => {
|
|
4510
|
-
const sectionTitle = entry.source?.startsWith("section:")
|
|
4511
|
-
? entry.source.slice("section:".length)
|
|
4512
|
-
: "";
|
|
4513
|
-
const metadata = [
|
|
4514
|
-
`timestamp=${entry.timestamp}`,
|
|
4515
|
-
sectionTitle ? `section=${sectionTitle}` : entry.source ? `source=${entry.source}` : "",
|
|
4516
|
-
entry.sessionKey ? `session=${entry.sessionKey}` : "",
|
|
4517
|
-
entry.principal ? `principal=${entry.principal}` : "",
|
|
4518
|
-
]
|
|
4519
|
-
.filter(Boolean)
|
|
4520
|
-
.join(", ");
|
|
4521
|
-
return `- ${metadata}: ${entry.text}`;
|
|
4522
|
-
})
|
|
4523
|
-
.join("\n");
|
|
4524
|
-
const response = await this.fastChatCompletion(
|
|
4525
|
-
[
|
|
4526
|
-
{
|
|
4527
|
-
role: "system",
|
|
4528
|
-
content:
|
|
4529
|
-
"Rewrite the entity synthesis as compact current truth. Preserve uncertainty when evidence conflicts. Return plain text only.",
|
|
4530
|
-
},
|
|
4531
|
-
{
|
|
4532
|
-
role: "user",
|
|
4533
|
-
content: [
|
|
4534
|
-
`Entity: ${entity.name} (${entity.type})`,
|
|
4535
|
-
nextSynthesis ? `Previous synthesis:\n${nextSynthesis}` : "Previous synthesis: none",
|
|
4536
|
-
`New evidence:\n${evidenceText}`,
|
|
4537
|
-
].join("\n\n"),
|
|
4538
|
-
},
|
|
4539
|
-
],
|
|
4540
|
-
{
|
|
4541
|
-
temperature: 0.2,
|
|
4542
|
-
maxTokens: this.config.entitySynthesisMaxTokens,
|
|
4543
|
-
operation: "entity_summary",
|
|
4544
|
-
priority: "background",
|
|
4545
|
-
},
|
|
4546
|
-
);
|
|
4547
|
-
const synthesis = response?.content?.trim().replace(/^["']|["']$/g, "");
|
|
4548
|
-
const maxSynthesisChars = Math.max(2_000, this.config.entitySynthesisMaxTokens * 8);
|
|
4549
|
-
if (!synthesis || synthesis.length < 10 || synthesis.length > maxSynthesisChars) {
|
|
4550
|
-
batchFailed = true;
|
|
4551
|
-
break;
|
|
4552
|
-
}
|
|
4553
|
-
nextSynthesis = synthesis;
|
|
4554
|
-
}
|
|
4555
|
-
if (batchFailed || nextSynthesis.length === 0) continue;
|
|
4556
|
-
const latestRaw = await storage.readEntity(entityName);
|
|
4557
|
-
if (!latestRaw) continue;
|
|
4558
|
-
const latestEntity = parseEntityFile(latestRaw, this.config.entitySchemas);
|
|
4559
|
-
if (
|
|
4560
|
-
fingerprintEntitySynthesisEvidence(latestEntity)
|
|
4561
|
-
!== fingerprintEntitySynthesisEvidence(entity)
|
|
4562
|
-
) {
|
|
4563
|
-
continue;
|
|
4564
|
-
}
|
|
4565
|
-
await storage.updateEntitySynthesis(entityName, nextSynthesis, {
|
|
4566
|
-
entityUpdatedAt: new Date().toISOString(),
|
|
4567
|
-
synthesisStructuredFactDigest: structuredEvidenceDigest,
|
|
4568
|
-
synthesisStructuredFactCount: structuredEvidenceCount,
|
|
4569
|
-
synthesisTimelineCount: entity.timeline.length,
|
|
4570
|
-
updatedAt: nextSynthesisUpdatedAt,
|
|
4571
|
-
});
|
|
4572
|
-
processed += 1;
|
|
4573
|
-
} catch (err) {
|
|
4574
|
-
log.debug(`entity synthesis refresh failed for ${entityName}: ${err}`);
|
|
4575
|
-
}
|
|
4576
|
-
}
|
|
4577
|
-
|
|
4578
|
-
return processed;
|
|
4364
|
+
// Issue #1526: entity synthesis lifecycle moved to EntitySynthesisCoordinator.
|
|
4365
|
+
// Thin delegation keeps all call sites (consolidation pass, access-service)
|
|
4366
|
+
// and tests that exercise the public API working unchanged.
|
|
4367
|
+
return this.entitySynthesisCoordinator.processQueue(namespace, maxEntities);
|
|
4579
4368
|
}
|
|
4580
4369
|
|
|
4581
4370
|
async generateDaySummary(
|
|
@@ -4805,7 +4594,7 @@ export class Orchestrator {
|
|
|
4805
4594
|
action: event.action,
|
|
4806
4595
|
eligibility,
|
|
4807
4596
|
options: {
|
|
4808
|
-
actionsEnabled: this.config.
|
|
4597
|
+
actionsEnabled: resolveCompressionCapabilities(this.config).contextCompressionActions,
|
|
4809
4598
|
maxCompressionTokensPerHour: this.config.maxCompressionTokensPerHour,
|
|
4810
4599
|
},
|
|
4811
4600
|
});
|
|
@@ -8305,11 +8094,11 @@ export class Orchestrator {
|
|
|
8305
8094
|
const objectiveStatePromise = (async (): Promise<string | null> => {
|
|
8306
8095
|
const t0 = Date.now();
|
|
8307
8096
|
if (
|
|
8308
|
-
!this.config.
|
|
8309
|
-
!this.config.
|
|
8097
|
+
!resolveObjectiveStateCapabilities(this.config).objectiveStateMemory ||
|
|
8098
|
+
!resolveObjectiveStateCapabilities(this.config).objectiveStateRecall ||
|
|
8310
8099
|
!this.isRecallSectionEnabled(
|
|
8311
8100
|
"objective-state",
|
|
8312
|
-
this.config.
|
|
8101
|
+
resolveObjectiveStateCapabilities(this.config).objectiveStateRecall === true,
|
|
8313
8102
|
)
|
|
8314
8103
|
) {
|
|
8315
8104
|
recordRecallSectionMetric({
|
|
@@ -8562,11 +8351,11 @@ export class Orchestrator {
|
|
|
8562
8351
|
const trustZonePromise = (async (): Promise<string | null> => {
|
|
8563
8352
|
const t0 = Date.now();
|
|
8564
8353
|
if (
|
|
8565
|
-
!this.config.
|
|
8566
|
-
!this.config.
|
|
8354
|
+
!resolveSecurityCapabilities(this.config).trustZones ||
|
|
8355
|
+
!resolveSecurityCapabilities(this.config).trustZoneRecall ||
|
|
8567
8356
|
!this.isRecallSectionEnabled(
|
|
8568
8357
|
"trust-zones",
|
|
8569
|
-
this.config.
|
|
8358
|
+
resolveSecurityCapabilities(this.config).trustZoneRecall === true,
|
|
8570
8359
|
)
|
|
8571
8360
|
) {
|
|
8572
8361
|
recordRecallSectionMetric({
|
|
@@ -11735,7 +11524,7 @@ export class Orchestrator {
|
|
|
11735
11524
|
if (
|
|
11736
11525
|
this.isRecallSectionEnabled(
|
|
11737
11526
|
"compression-guidelines",
|
|
11738
|
-
this.config.
|
|
11527
|
+
resolveCompressionCapabilities(this.config).compressionGuidelineLearning === true,
|
|
11739
11528
|
)
|
|
11740
11529
|
) {
|
|
11741
11530
|
const compressionGuidelineSection =
|
|
@@ -17017,81 +16806,6 @@ export class Orchestrator {
|
|
|
17017
16806
|
return this.compressionGuidelineCoordinator.buildCompressionGuidelineRecallSection();
|
|
17018
16807
|
}
|
|
17019
16808
|
|
|
17020
|
-
private actionOutcomePriorDelta(event: MemoryActionEvent): number {
|
|
17021
|
-
if (event.outcome === "failed") return -0.3;
|
|
17022
|
-
if (event.policyDecision === "deny") return -0.22;
|
|
17023
|
-
if (event.policyDecision === "defer") return -0.14;
|
|
17024
|
-
if (event.outcome === "skipped") return -0.1;
|
|
17025
|
-
|
|
17026
|
-
if (event.outcome !== "applied") return 0;
|
|
17027
|
-
switch (event.action) {
|
|
17028
|
-
case "store_episode":
|
|
17029
|
-
case "store_note":
|
|
17030
|
-
case "update_note":
|
|
17031
|
-
return 0.08;
|
|
17032
|
-
case "create_artifact":
|
|
17033
|
-
case "summarize_node":
|
|
17034
|
-
case "link_graph":
|
|
17035
|
-
return 0.04;
|
|
17036
|
-
case "discard":
|
|
17037
|
-
return -0.03;
|
|
17038
|
-
default:
|
|
17039
|
-
return 0;
|
|
17040
|
-
}
|
|
17041
|
-
}
|
|
17042
|
-
|
|
17043
|
-
private async buildLifecycleActionPriors(
|
|
17044
|
-
storage: StorageManager = this.storage,
|
|
17045
|
-
): Promise<Map<string, number>> {
|
|
17046
|
-
const events = await storage.readMemoryActionEvents(1200);
|
|
17047
|
-
if (events.length === 0) return new Map<string, number>();
|
|
17048
|
-
|
|
17049
|
-
const nowMs = Date.now();
|
|
17050
|
-
const windowMs = 14 * 24 * 60 * 60 * 1000;
|
|
17051
|
-
const byMemory = new Map<
|
|
17052
|
-
string,
|
|
17053
|
-
Array<{ weightedDelta: number; weight: number }>
|
|
17054
|
-
>();
|
|
17055
|
-
|
|
17056
|
-
for (const event of events) {
|
|
17057
|
-
if (
|
|
17058
|
-
typeof event.memoryId !== "string" ||
|
|
17059
|
-
event.memoryId.trim().length === 0
|
|
17060
|
-
)
|
|
17061
|
-
continue;
|
|
17062
|
-
const ts = Date.parse(event.timestamp);
|
|
17063
|
-
if (!Number.isFinite(ts)) continue;
|
|
17064
|
-
const ageMs = nowMs - ts;
|
|
17065
|
-
if (ageMs < 0 || ageMs > windowMs) continue;
|
|
17066
|
-
|
|
17067
|
-
const delta = this.actionOutcomePriorDelta(event);
|
|
17068
|
-
if (delta === 0) continue;
|
|
17069
|
-
|
|
17070
|
-
const recencyWeight = Math.max(0.2, 1 - ageMs / windowMs);
|
|
17071
|
-
const list = byMemory.get(event.memoryId) ?? [];
|
|
17072
|
-
if (list.length >= 8) list.shift();
|
|
17073
|
-
list.push({
|
|
17074
|
-
weightedDelta: delta * recencyWeight,
|
|
17075
|
-
weight: recencyWeight,
|
|
17076
|
-
});
|
|
17077
|
-
byMemory.set(event.memoryId, list);
|
|
17078
|
-
}
|
|
17079
|
-
|
|
17080
|
-
const out = new Map<string, number>();
|
|
17081
|
-
for (const [memoryId, deltas] of byMemory.entries()) {
|
|
17082
|
-
if (deltas.length === 0) continue;
|
|
17083
|
-
const weightedSum = deltas.reduce(
|
|
17084
|
-
(sum, item) => sum + item.weightedDelta,
|
|
17085
|
-
0,
|
|
17086
|
-
);
|
|
17087
|
-
const weightTotal = deltas.reduce((sum, item) => sum + item.weight, 0);
|
|
17088
|
-
if (weightTotal <= 0) continue;
|
|
17089
|
-
const score = weightedSum / weightTotal;
|
|
17090
|
-
out.set(memoryId, Math.max(-0.25, Math.min(0.15, score)));
|
|
17091
|
-
}
|
|
17092
|
-
return out;
|
|
17093
|
-
}
|
|
17094
|
-
|
|
17095
16809
|
private async recordScheduledDreamsPhaseRun(
|
|
17096
16810
|
phase: "lightSleep" | "rem" | "deepSleep",
|
|
17097
16811
|
itemsProcessed: number,
|
|
@@ -17126,315 +16840,23 @@ export class Orchestrator {
|
|
|
17126
16840
|
allMemories: MemoryFile[],
|
|
17127
16841
|
storage: StorageManager = this.storage,
|
|
17128
16842
|
): Promise<number> {
|
|
17129
|
-
|
|
17130
|
-
const nowIso = now.toISOString();
|
|
17131
|
-
const countsByState: Record<LifecycleState, number> = {
|
|
17132
|
-
candidate: 0,
|
|
17133
|
-
validated: 0,
|
|
17134
|
-
active: 0,
|
|
17135
|
-
stale: 0,
|
|
17136
|
-
archived: 0,
|
|
17137
|
-
};
|
|
17138
|
-
const transitionCounts: Record<string, number> = {};
|
|
17139
|
-
let updatedCount = 0;
|
|
17140
|
-
let disputedCount = 0;
|
|
17141
|
-
let evaluatedCount = 0;
|
|
17142
|
-
const lifecycleCaps = resolveMemoryLifecycleCapabilities(this.config);
|
|
17143
|
-
|
|
17144
|
-
const thresholds = this.effectiveLifecycleThresholds();
|
|
17145
|
-
const policy = {
|
|
17146
|
-
promoteHeatThreshold: thresholds.promoteHeatThreshold,
|
|
17147
|
-
staleDecayThreshold: thresholds.staleDecayThreshold,
|
|
17148
|
-
archiveDecayThreshold: thresholds.archiveDecayThreshold,
|
|
17149
|
-
protectedCategories: this.config.lifecycleProtectedCategories,
|
|
17150
|
-
};
|
|
17151
|
-
const actionPriors = await this.buildLifecycleActionPriors(storage);
|
|
17152
|
-
|
|
17153
|
-
for (const memory of allMemories) {
|
|
17154
|
-
if (
|
|
17155
|
-
memory.frontmatter.status === "superseded" ||
|
|
17156
|
-
memory.frontmatter.status === "forgotten"
|
|
17157
|
-
) {
|
|
17158
|
-
continue;
|
|
17159
|
-
}
|
|
17160
|
-
evaluatedCount += 1;
|
|
17161
|
-
const currentState = resolveLifecycleState(memory.frontmatter);
|
|
17162
|
-
const actionPriorScore = actionPriors.get(memory.frontmatter.id);
|
|
17163
|
-
const signals: LifecycleSignals | undefined =
|
|
17164
|
-
typeof actionPriorScore === "number" &&
|
|
17165
|
-
Number.isFinite(actionPriorScore)
|
|
17166
|
-
? { actionPriorScore }
|
|
17167
|
-
: undefined;
|
|
17168
|
-
const decision = decideLifecycleTransition(memory, policy, now, signals);
|
|
17169
|
-
const nextState: LifecycleState =
|
|
17170
|
-
memory.frontmatter.status === "archived"
|
|
17171
|
-
? "archived"
|
|
17172
|
-
: decision.nextState;
|
|
17173
|
-
|
|
17174
|
-
countsByState[nextState] += 1;
|
|
17175
|
-
if (memory.frontmatter.verificationState === "disputed") {
|
|
17176
|
-
disputedCount += 1;
|
|
17177
|
-
}
|
|
17178
|
-
if (nextState !== currentState) {
|
|
17179
|
-
const key = `${currentState}->${nextState}`;
|
|
17180
|
-
transitionCounts[key] = (transitionCounts[key] ?? 0) + 1;
|
|
17181
|
-
}
|
|
17182
|
-
|
|
17183
|
-
const prevHeat = memory.frontmatter.heatScore;
|
|
17184
|
-
const prevDecay = memory.frontmatter.decayScore;
|
|
17185
|
-
const scoreDelta =
|
|
17186
|
-
Math.abs((prevHeat ?? -1) - decision.heatScore) +
|
|
17187
|
-
Math.abs((prevDecay ?? -1) - decision.decayScore);
|
|
17188
|
-
const shouldPersist =
|
|
17189
|
-
memory.frontmatter.lifecycleState !== nextState ||
|
|
17190
|
-
memory.frontmatter.heatScore === undefined ||
|
|
17191
|
-
memory.frontmatter.decayScore === undefined ||
|
|
17192
|
-
memory.frontmatter.lastValidatedAt === undefined ||
|
|
17193
|
-
scoreDelta >= 0.01;
|
|
17194
|
-
|
|
17195
|
-
if (!shouldPersist) continue;
|
|
17196
|
-
|
|
17197
|
-
const wrote = await storage.writeMemoryFrontmatter(memory, {
|
|
17198
|
-
lifecycleState: nextState,
|
|
17199
|
-
heatScore: decision.heatScore,
|
|
17200
|
-
decayScore: decision.decayScore,
|
|
17201
|
-
lastValidatedAt: nowIso,
|
|
17202
|
-
});
|
|
17203
|
-
if (wrote) updatedCount += 1;
|
|
17204
|
-
}
|
|
17205
|
-
|
|
17206
|
-
// Report how many memories had frontmatter rewritten so callers can record a
|
|
17207
|
-
// catalog write touch for lifecycle-only passes (codex NR-tS).
|
|
17208
|
-
if (!lifecycleCaps.lifecycleMetrics) return updatedCount;
|
|
17209
|
-
|
|
17210
|
-
const total = evaluatedCount;
|
|
17211
|
-
const metrics = {
|
|
17212
|
-
generatedAt: nowIso,
|
|
17213
|
-
memoriesEvaluated: total,
|
|
17214
|
-
memoriesUpdated: updatedCount,
|
|
17215
|
-
countsByLifecycleState: countsByState,
|
|
17216
|
-
transitionCounts,
|
|
17217
|
-
staleRatio: total > 0 ? countsByState.stale / total : 0,
|
|
17218
|
-
disputedRatio: total > 0 ? disputedCount / total : 0,
|
|
17219
|
-
policy: {
|
|
17220
|
-
promoteHeatThreshold: thresholds.promoteHeatThreshold,
|
|
17221
|
-
staleDecayThreshold: thresholds.staleDecayThreshold,
|
|
17222
|
-
archiveDecayThreshold: thresholds.archiveDecayThreshold,
|
|
17223
|
-
protectedCategories: this.config.lifecycleProtectedCategories,
|
|
17224
|
-
},
|
|
17225
|
-
};
|
|
17226
|
-
const metricsPath = path.join(
|
|
17227
|
-
storage.dir,
|
|
17228
|
-
"state",
|
|
17229
|
-
"lifecycle-metrics.json",
|
|
17230
|
-
);
|
|
17231
|
-
await mkdir(path.dirname(metricsPath), { recursive: true });
|
|
17232
|
-
await writeFile(metricsPath, JSON.stringify(metrics, null, 2), "utf-8");
|
|
17233
|
-
return updatedCount;
|
|
16843
|
+
return this.lifecyclePolicyCoordinator.runLifecyclePolicyPass(allMemories, storage);
|
|
17234
16844
|
}
|
|
17235
|
-
|
|
17236
|
-
/**
|
|
17237
|
-
* Archive old, low-importance, rarely-accessed facts (v6.0).
|
|
17238
|
-
* Moves eligible facts from facts/ to archive/YYYY-MM-DD/.
|
|
17239
|
-
* Returns the number of archived facts.
|
|
17240
|
-
*/
|
|
17241
16845
|
private async runFactArchival(
|
|
17242
16846
|
allMemories: import("./types.js").MemoryFile[],
|
|
17243
16847
|
): Promise<number> {
|
|
17244
|
-
|
|
17245
|
-
const ageCutoffMs = this.config.factArchivalAgeDays * 24 * 60 * 60 * 1000;
|
|
17246
|
-
const protectedCategories = new Set(
|
|
17247
|
-
this.config.factArchivalProtectedCategories,
|
|
17248
|
-
);
|
|
17249
|
-
let archivedCount = 0;
|
|
17250
|
-
|
|
17251
|
-
for (const memory of allMemories) {
|
|
17252
|
-
const fm = memory.frontmatter;
|
|
17253
|
-
|
|
17254
|
-
// Skip already-archived or superseded
|
|
17255
|
-
if (fm.status && fm.status !== "active") continue;
|
|
17256
|
-
|
|
17257
|
-
// Skip protected categories
|
|
17258
|
-
if (protectedCategories.has(fm.category)) continue;
|
|
17259
|
-
|
|
17260
|
-
// Skip corrections (always keep)
|
|
17261
|
-
if (fm.category === "correction") continue;
|
|
17262
|
-
|
|
17263
|
-
// Check age requirement
|
|
17264
|
-
const createdMs = new Date(fm.created).getTime();
|
|
17265
|
-
if (now - createdMs < ageCutoffMs) continue;
|
|
17266
|
-
|
|
17267
|
-
// Check importance (only archive low-importance facts)
|
|
17268
|
-
const importanceScore = fm.importance?.score ?? 0.5;
|
|
17269
|
-
if (importanceScore >= this.config.factArchivalMaxImportance) continue;
|
|
17270
|
-
|
|
17271
|
-
// Check access count
|
|
17272
|
-
const accessCount = fm.accessCount ?? 0;
|
|
17273
|
-
if (accessCount > this.config.factArchivalMaxAccessCount) continue;
|
|
17274
|
-
|
|
17275
|
-
// All criteria met — archive
|
|
17276
|
-
const result = await this.storage.archiveMemory(memory);
|
|
17277
|
-
if (result) {
|
|
17278
|
-
// Remove from the same storage-scoped content-hash index since it is
|
|
17279
|
-
// no longer in hot search.
|
|
17280
|
-
await this.removeContentHashForMemory(
|
|
17281
|
-
this.storage,
|
|
17282
|
-
memory,
|
|
17283
|
-
"fact-archival",
|
|
17284
|
-
);
|
|
17285
|
-
await this.embeddingFallback.removeFromIndex(memory.frontmatter.id);
|
|
17286
|
-
if (
|
|
17287
|
-
resolveIndexingCapabilities(this.config).queryAwareIndexing &&
|
|
17288
|
-
memory.path &&
|
|
17289
|
-
memory.frontmatter?.created
|
|
17290
|
-
) {
|
|
17291
|
-
deindexMemory(
|
|
17292
|
-
this.config.memoryDir,
|
|
17293
|
-
memory.path,
|
|
17294
|
-
memory.frontmatter.created,
|
|
17295
|
-
memory.frontmatter.tags ?? [],
|
|
17296
|
-
);
|
|
17297
|
-
}
|
|
17298
|
-
archivedCount++;
|
|
17299
|
-
}
|
|
17300
|
-
}
|
|
17301
|
-
|
|
17302
|
-
// Save hash indexes if we removed any entries.
|
|
17303
|
-
if (archivedCount > 0) {
|
|
17304
|
-
await this.saveContentHashIndexes().catch((err) =>
|
|
17305
|
-
log.warn(`content-hash index save failed during archival: ${err}`),
|
|
17306
|
-
);
|
|
17307
|
-
}
|
|
17308
|
-
|
|
17309
|
-
return archivedCount;
|
|
16848
|
+
return this.lifecyclePolicyCoordinator.runFactArchival(allMemories);
|
|
17310
16849
|
}
|
|
17311
|
-
|
|
17312
|
-
/**
|
|
17313
|
-
* Run memory summarization if memory count exceeds threshold (Phase 4A).
|
|
17314
|
-
*/
|
|
17315
16850
|
private async runSummarization(
|
|
17316
16851
|
allMemories: import("./types.js").MemoryFile[],
|
|
17317
16852
|
): Promise<void> {
|
|
17318
|
-
|
|
17319
|
-
const activeMemories = allMemories.filter(
|
|
17320
|
-
(m) => isActiveMemoryStatus(m.frontmatter.status),
|
|
17321
|
-
);
|
|
17322
|
-
|
|
17323
|
-
if (activeMemories.length < this.config.summarizationTriggerCount) {
|
|
17324
|
-
return;
|
|
17325
|
-
}
|
|
17326
|
-
|
|
17327
|
-
log.info(
|
|
17328
|
-
`memory count (${activeMemories.length}) exceeds threshold (${this.config.summarizationTriggerCount}) — running summarization`,
|
|
17329
|
-
);
|
|
17330
|
-
|
|
17331
|
-
// Sort by creation date, oldest first
|
|
17332
|
-
const sorted = activeMemories.sort(
|
|
17333
|
-
(a, b) =>
|
|
17334
|
-
new Date(a.frontmatter.created).getTime() -
|
|
17335
|
-
new Date(b.frontmatter.created).getTime(),
|
|
17336
|
-
);
|
|
17337
|
-
|
|
17338
|
-
// Keep recent memories, with explicit zero handling so `slice(-0)` does not
|
|
17339
|
-
// accidentally keep every memory out of the summarization candidate set.
|
|
17340
|
-
const recentToKeep = Math.max(0, this.config.summarizationRecentToKeep);
|
|
17341
|
-
const toSummarize = recentToKeep > 0 ? sorted.slice(0, -recentToKeep) : sorted;
|
|
17342
|
-
|
|
17343
|
-
// Filter candidates for summarization
|
|
17344
|
-
const candidates = toSummarize.filter((m) => {
|
|
17345
|
-
// Skip if protected by entity reference
|
|
17346
|
-
if (m.frontmatter.entityRef) return false;
|
|
17347
|
-
|
|
17348
|
-
// Skip if protected by tag
|
|
17349
|
-
const protectedTags = this.config.summarizationProtectedTags;
|
|
17350
|
-
if (m.frontmatter.tags.some((t) => protectedTags.includes(t)))
|
|
17351
|
-
return false;
|
|
17352
|
-
|
|
17353
|
-
// Skip if importance is above threshold
|
|
17354
|
-
const importance = m.frontmatter.importance?.score ?? 0.5;
|
|
17355
|
-
if (importance >= this.config.summarizationImportanceThreshold)
|
|
17356
|
-
return false;
|
|
17357
|
-
|
|
17358
|
-
return true;
|
|
17359
|
-
});
|
|
17360
|
-
|
|
17361
|
-
if (candidates.length < 50) {
|
|
17362
|
-
log.debug(
|
|
17363
|
-
`only ${candidates.length} candidates for summarization — skipping`,
|
|
17364
|
-
);
|
|
17365
|
-
return;
|
|
17366
|
-
}
|
|
17367
|
-
|
|
17368
|
-
// Summarize in batches of 50
|
|
17369
|
-
const batchSize = 50;
|
|
17370
|
-
for (let i = 0; i < candidates.length; i += batchSize) {
|
|
17371
|
-
const batch = candidates.slice(i, i + batchSize);
|
|
17372
|
-
const batchData = batch.map((m) => ({
|
|
17373
|
-
id: m.frontmatter.id,
|
|
17374
|
-
content: m.content,
|
|
17375
|
-
category: m.frontmatter.category,
|
|
17376
|
-
created: m.frontmatter.created,
|
|
17377
|
-
}));
|
|
17378
|
-
|
|
17379
|
-
const result = await this.extraction.summarizeMemories(batchData);
|
|
17380
|
-
if (!result) continue;
|
|
17381
|
-
|
|
17382
|
-
// Create summary
|
|
17383
|
-
const summary: MemorySummary = {
|
|
17384
|
-
id: `summary-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
|
|
17385
|
-
createdAt: new Date().toISOString(),
|
|
17386
|
-
timeRangeStart: batch[0].frontmatter.created,
|
|
17387
|
-
timeRangeEnd: batch[batch.length - 1].frontmatter.created,
|
|
17388
|
-
summaryText: result.summaryText,
|
|
17389
|
-
keyFacts: result.keyFacts,
|
|
17390
|
-
keyEntities: result.keyEntities,
|
|
17391
|
-
sourceEpisodeIds: batch.map((m) => m.frontmatter.id),
|
|
17392
|
-
};
|
|
17393
|
-
|
|
17394
|
-
await this.storage.writeSummary(summary);
|
|
17395
|
-
|
|
17396
|
-
// Archive source memories
|
|
17397
|
-
const archived = await this.storage.archiveMemories(
|
|
17398
|
-
batch.map((m) => m.frontmatter.id),
|
|
17399
|
-
summary.id,
|
|
17400
|
-
);
|
|
17401
|
-
|
|
17402
|
-
// Catalog write touch (issue #1499 sweep): summarization writes a durable
|
|
17403
|
-
// summary and then rewrites source-memory archive status, bypassing the
|
|
17404
|
-
// extraction write path. Record the touch after both mutations complete so
|
|
17405
|
-
// `lastWriteAt` covers the final archived-state write.
|
|
17406
|
-
// #1522: catalog touch handled at the storage chokepoint.
|
|
17407
|
-
|
|
17408
|
-
log.info(
|
|
17409
|
-
`created summary ${summary.id} from ${batch.length} memories, archived ${archived}`,
|
|
17410
|
-
);
|
|
17411
|
-
}
|
|
16853
|
+
return this.lifecyclePolicyCoordinator.runSummarization(allMemories);
|
|
17412
16854
|
}
|
|
17413
|
-
|
|
17414
|
-
/**
|
|
17415
|
-
* Run topic extraction on all memories (Phase 4B).
|
|
17416
|
-
*/
|
|
17417
16855
|
private async runTopicExtraction(
|
|
17418
16856
|
allMemories: import("./types.js").MemoryFile[],
|
|
17419
16857
|
): Promise<void> {
|
|
17420
|
-
|
|
17421
|
-
const activeMemories = allMemories.filter(
|
|
17422
|
-
(m) => isActiveMemoryStatus(m.frontmatter.status),
|
|
17423
|
-
);
|
|
17424
|
-
|
|
17425
|
-
if (activeMemories.length === 0) return;
|
|
17426
|
-
|
|
17427
|
-
const topics = extractTopics(
|
|
17428
|
-
activeMemories,
|
|
17429
|
-
this.config.topicExtractionTopN,
|
|
17430
|
-
);
|
|
17431
|
-
await this.storage.saveTopics(topics);
|
|
17432
|
-
|
|
17433
|
-
log.debug(
|
|
17434
|
-
`extracted ${topics.length} topics from ${activeMemories.length} memories`,
|
|
17435
|
-
);
|
|
16858
|
+
return this.lifecyclePolicyCoordinator.runTopicExtraction(allMemories);
|
|
17436
16859
|
}
|
|
17437
|
-
|
|
17438
16860
|
/** Threshold (bytes) at which IDENTITY.md reflections get auto-consolidated */
|
|
17439
16861
|
private static readonly IDENTITY_CONSOLIDATE_THRESHOLD = 8_000;
|
|
17440
16862
|
|
|
@@ -17888,7 +17310,7 @@ export class Orchestrator {
|
|
|
17888
17310
|
private queueEvalShadowRecall(
|
|
17889
17311
|
record: Omit<EvalShadowRecallRecord, "schemaVersion">,
|
|
17890
17312
|
): void {
|
|
17891
|
-
if (!this.config.
|
|
17313
|
+
if (!resolveEvalCapabilities(this.config).evalHarness || !resolveEvalCapabilities(this.config).evalShadowMode)
|
|
17892
17314
|
return;
|
|
17893
17315
|
this.evalShadowWriteChain = this.evalShadowWriteChain
|
|
17894
17316
|
.catch(() => undefined)
|