@fgv/ts-agent-memory 5.1.0-47 → 5.1.0-49
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/packlets/ingest/orchestrator.js +11 -1
- package/dist/packlets/ingest/orchestrator.js.map +1 -1
- package/dist/packlets/observe/memoryObservationStore.js +6 -0
- package/dist/packlets/observe/memoryObservationStore.js.map +1 -1
- package/dist/packlets/observe/observer.js.map +1 -1
- package/dist/packlets/retrieve/linkTraversalRetriever.js +1 -1
- package/dist/packlets/retrieve/linkTraversalRetriever.js.map +1 -1
- package/dist/packlets/retrieve/recencyRetriever.js +1 -1
- package/dist/packlets/retrieve/recencyRetriever.js.map +1 -1
- package/dist/packlets/retrieve/retriever.js +11 -5
- package/dist/packlets/retrieve/retriever.js.map +1 -1
- package/dist/packlets/retrieve/structuredFilterRetriever.js +27 -5
- package/dist/packlets/retrieve/structuredFilterRetriever.js.map +1 -1
- package/dist/packlets/retrieve/tagRetriever.js +1 -1
- package/dist/packlets/retrieve/tagRetriever.js.map +1 -1
- package/dist/packlets/retrieve/temporalRetrievers.js +1 -1
- package/dist/packlets/retrieve/temporalRetrievers.js.map +1 -1
- package/dist/packlets/store/fileTreeMemoryStore.js +152 -132
- package/dist/packlets/store/fileTreeMemoryStore.js.map +1 -1
- package/dist/packlets/store/vectorMaintenance.js +251 -0
- package/dist/packlets/store/vectorMaintenance.js.map +1 -0
- package/dist/packlets/types/envelope.js.map +1 -1
- package/dist/packlets/vector/inMemoryCosineIndex.js +81 -18
- package/dist/packlets/vector/inMemoryCosineIndex.js.map +1 -1
- package/dist/packlets/vector/inMemoryFragmentCosineIndex.js +7 -0
- package/dist/packlets/vector/inMemoryFragmentCosineIndex.js.map +1 -1
- package/dist/packlets/vector/vectorIndex.js.map +1 -1
- package/dist/ts-agent-memory.d.ts +431 -79
- package/lib/packlets/ingest/orchestrator.d.ts.map +1 -1
- package/lib/packlets/ingest/orchestrator.js +11 -1
- package/lib/packlets/ingest/orchestrator.js.map +1 -1
- package/lib/packlets/observe/memoryObservationStore.d.ts.map +1 -1
- package/lib/packlets/observe/memoryObservationStore.js +6 -0
- package/lib/packlets/observe/memoryObservationStore.js.map +1 -1
- package/lib/packlets/observe/observer.d.ts +61 -0
- package/lib/packlets/observe/observer.d.ts.map +1 -1
- package/lib/packlets/observe/observer.js.map +1 -1
- package/lib/packlets/retrieve/linkTraversalRetriever.d.ts +1 -1
- package/lib/packlets/retrieve/linkTraversalRetriever.js +1 -1
- package/lib/packlets/retrieve/linkTraversalRetriever.js.map +1 -1
- package/lib/packlets/retrieve/recencyRetriever.d.ts +1 -1
- package/lib/packlets/retrieve/recencyRetriever.js +1 -1
- package/lib/packlets/retrieve/recencyRetriever.js.map +1 -1
- package/lib/packlets/retrieve/retriever.d.ts +26 -7
- package/lib/packlets/retrieve/retriever.d.ts.map +1 -1
- package/lib/packlets/retrieve/retriever.js +11 -5
- package/lib/packlets/retrieve/retriever.js.map +1 -1
- package/lib/packlets/retrieve/structuredFilterRetriever.d.ts +26 -4
- package/lib/packlets/retrieve/structuredFilterRetriever.d.ts.map +1 -1
- package/lib/packlets/retrieve/structuredFilterRetriever.js +27 -5
- package/lib/packlets/retrieve/structuredFilterRetriever.js.map +1 -1
- package/lib/packlets/retrieve/tagRetriever.d.ts +1 -1
- package/lib/packlets/retrieve/tagRetriever.js +1 -1
- package/lib/packlets/retrieve/tagRetriever.js.map +1 -1
- package/lib/packlets/retrieve/temporalRetrievers.js +1 -1
- package/lib/packlets/retrieve/temporalRetrievers.js.map +1 -1
- package/lib/packlets/store/fileTreeMemoryStore.d.ts +135 -59
- package/lib/packlets/store/fileTreeMemoryStore.d.ts.map +1 -1
- package/lib/packlets/store/fileTreeMemoryStore.js +151 -131
- package/lib/packlets/store/fileTreeMemoryStore.js.map +1 -1
- package/lib/packlets/store/vectorMaintenance.d.ts +149 -0
- package/lib/packlets/store/vectorMaintenance.d.ts.map +1 -0
- package/lib/packlets/store/vectorMaintenance.js +255 -0
- package/lib/packlets/store/vectorMaintenance.js.map +1 -0
- package/lib/packlets/types/envelope.d.ts +11 -0
- package/lib/packlets/types/envelope.d.ts.map +1 -1
- package/lib/packlets/types/envelope.js.map +1 -1
- package/lib/packlets/vector/inMemoryCosineIndex.d.ts +30 -7
- package/lib/packlets/vector/inMemoryCosineIndex.d.ts.map +1 -1
- package/lib/packlets/vector/inMemoryCosineIndex.js +80 -17
- package/lib/packlets/vector/inMemoryCosineIndex.js.map +1 -1
- package/lib/packlets/vector/inMemoryFragmentCosineIndex.d.ts +7 -0
- package/lib/packlets/vector/inMemoryFragmentCosineIndex.d.ts.map +1 -1
- package/lib/packlets/vector/inMemoryFragmentCosineIndex.js +7 -0
- package/lib/packlets/vector/inMemoryFragmentCosineIndex.js.map +1 -1
- package/lib/packlets/vector/vectorIndex.d.ts +129 -1
- package/lib/packlets/vector/vectorIndex.d.ts.map +1 -1
- package/lib/packlets/vector/vectorIndex.js.map +1 -1
- package/package.json +17 -7
- package/.rush/temp/5667e36f1c0cc503a5c20a3ebff76e7b9a702d41.tar.log +0 -468
- package/.rush/temp/chunked-rush-logs/ts-agent-memory.build.chunks.jsonl +0 -9
- package/.rush/temp/operation/build/all.log +0 -9
- package/.rush/temp/operation/build/log-chunks.jsonl +0 -9
- package/.rush/temp/operation/build/state.json +0 -3
- package/.rush/temp/shrinkwrap-deps.json +0 -689
- package/config/api-extractor.json +0 -343
- package/config/jest.config.json +0 -14
- package/config/rig.json +0 -4
- package/dist/test/unit/converters/antagonistRoundTrip.test.js +0 -95
- package/dist/test/unit/converters/antagonistRoundTrip.test.js.map +0 -1
- package/dist/test/unit/converters/bodyConverterRegistry.test.js +0 -72
- package/dist/test/unit/converters/bodyConverterRegistry.test.js.map +0 -1
- package/dist/test/unit/converters/envelopeConverter.test.js +0 -313
- package/dist/test/unit/converters/envelopeConverter.test.js.map +0 -1
- package/dist/test/unit/index/memoryIndex.test.js +0 -214
- package/dist/test/unit/index/memoryIndex.test.js.map +0 -1
- package/dist/test/unit/ingest/antagonistCycleAndParity.test.js +0 -277
- package/dist/test/unit/ingest/antagonistCycleAndParity.test.js.map +0 -1
- package/dist/test/unit/ingest/cycleGuard.test.js +0 -81
- package/dist/test/unit/ingest/cycleGuard.test.js.map +0 -1
- package/dist/test/unit/ingest/dedupScope.test.js +0 -434
- package/dist/test/unit/ingest/dedupScope.test.js.map +0 -1
- package/dist/test/unit/ingest/orchestrator.test.js +0 -1058
- package/dist/test/unit/ingest/orchestrator.test.js.map +0 -1
- package/dist/test/unit/observe/memoryObservationStore.test.js +0 -118
- package/dist/test/unit/observe/memoryObservationStore.test.js.map +0 -1
- package/dist/test/unit/retrieve/fragmentSemanticRetriever.test.js +0 -116
- package/dist/test/unit/retrieve/fragmentSemanticRetriever.test.js.map +0 -1
- package/dist/test/unit/retrieve/linkTraversalRetriever.test.js +0 -257
- package/dist/test/unit/retrieve/linkTraversalRetriever.test.js.map +0 -1
- package/dist/test/unit/retrieve/retrievers.test.js +0 -768
- package/dist/test/unit/retrieve/retrievers.test.js.map +0 -1
- package/dist/test/unit/retrieve/temporalRetrievers.test.js +0 -182
- package/dist/test/unit/retrieve/temporalRetrievers.test.js.map +0 -1
- package/dist/test/unit/store/antagonistTemporalBoundary.test.js +0 -120
- package/dist/test/unit/store/antagonistTemporalBoundary.test.js.map +0 -1
- package/dist/test/unit/store/embedOnWrite.test.js +0 -317
- package/dist/test/unit/store/embedOnWrite.test.js.map +0 -1
- package/dist/test/unit/store/fileTreeMemoryStore.test.js +0 -778
- package/dist/test/unit/store/fileTreeMemoryStore.test.js.map +0 -1
- package/dist/test/unit/store/fragmentEmbedOnWrite.test.js +0 -255
- package/dist/test/unit/store/fragmentEmbedOnWrite.test.js.map +0 -1
- package/dist/test/unit/store/indexInjection.test.js +0 -432
- package/dist/test/unit/store/indexInjection.test.js.map +0 -1
- package/dist/test/unit/store/lenientOpen.test.js +0 -248
- package/dist/test/unit/store/lenientOpen.test.js.map +0 -1
- package/dist/test/unit/store/listScoped.test.js +0 -109
- package/dist/test/unit/store/listScoped.test.js.map +0 -1
- package/dist/test/unit/store/observations.test.js +0 -239
- package/dist/test/unit/store/observations.test.js.map +0 -1
- package/dist/test/unit/store/rankAxis.test.js +0 -254
- package/dist/test/unit/store/rankAxis.test.js.map +0 -1
- package/dist/test/unit/store/scopeEncoding.test.js +0 -24
- package/dist/test/unit/store/scopeEncoding.test.js.map +0 -1
- package/dist/test/unit/store/temporalStore.test.js +0 -398
- package/dist/test/unit/store/temporalStore.test.js.map +0 -1
- package/dist/test/unit/tools/memoryTools.test.js +0 -842
- package/dist/test/unit/tools/memoryTools.test.js.map +0 -1
- package/dist/test/unit/types/identityCodec.test.js +0 -187
- package/dist/test/unit/types/identityCodec.test.js.map +0 -1
- package/dist/test/unit/types/ids.test.js +0 -84
- package/dist/test/unit/types/ids.test.js.map +0 -1
- package/dist/test/unit/types/temporalCodec.test.js +0 -203
- package/dist/test/unit/types/temporalCodec.test.js.map +0 -1
- package/dist/test/unit/types/temporalPolicy.test.js +0 -83
- package/dist/test/unit/types/temporalPolicy.test.js.map +0 -1
- package/dist/test/unit/types/writePolicy.test.js +0 -331
- package/dist/test/unit/types/writePolicy.test.js.map +0 -1
- package/dist/test/unit/vector/fragmentConverters.test.js +0 -58
- package/dist/test/unit/vector/fragmentConverters.test.js.map +0 -1
- package/dist/test/unit/vector/inMemoryCosineIndex.test.js +0 -252
- package/dist/test/unit/vector/inMemoryCosineIndex.test.js.map +0 -1
- package/dist/test/unit/vector/inMemoryFragmentCosineIndex.test.js +0 -362
- package/dist/test/unit/vector/inMemoryFragmentCosineIndex.test.js.map +0 -1
- package/dist/test/unit/vector/vectorIndex.test.js +0 -51
- package/dist/test/unit/vector/vectorIndex.test.js.map +0 -1
- package/eslint.config.js +0 -15
- package/etc/ts-agent-memory.api.md +0 -940
- package/lib/test/unit/converters/antagonistRoundTrip.test.d.ts +0 -10
- package/lib/test/unit/converters/antagonistRoundTrip.test.d.ts.map +0 -1
- package/lib/test/unit/converters/antagonistRoundTrip.test.js +0 -97
- package/lib/test/unit/converters/antagonistRoundTrip.test.js.map +0 -1
- package/lib/test/unit/converters/bodyConverterRegistry.test.d.ts +0 -2
- package/lib/test/unit/converters/bodyConverterRegistry.test.d.ts.map +0 -1
- package/lib/test/unit/converters/bodyConverterRegistry.test.js +0 -74
- package/lib/test/unit/converters/bodyConverterRegistry.test.js.map +0 -1
- package/lib/test/unit/converters/envelopeConverter.test.d.ts +0 -2
- package/lib/test/unit/converters/envelopeConverter.test.d.ts.map +0 -1
- package/lib/test/unit/converters/envelopeConverter.test.js +0 -315
- package/lib/test/unit/converters/envelopeConverter.test.js.map +0 -1
- package/lib/test/unit/index/memoryIndex.test.d.ts +0 -2
- package/lib/test/unit/index/memoryIndex.test.d.ts.map +0 -1
- package/lib/test/unit/index/memoryIndex.test.js +0 -216
- package/lib/test/unit/index/memoryIndex.test.js.map +0 -1
- package/lib/test/unit/ingest/antagonistCycleAndParity.test.d.ts +0 -9
- package/lib/test/unit/ingest/antagonistCycleAndParity.test.d.ts.map +0 -1
- package/lib/test/unit/ingest/antagonistCycleAndParity.test.js +0 -279
- package/lib/test/unit/ingest/antagonistCycleAndParity.test.js.map +0 -1
- package/lib/test/unit/ingest/cycleGuard.test.d.ts +0 -2
- package/lib/test/unit/ingest/cycleGuard.test.d.ts.map +0 -1
- package/lib/test/unit/ingest/cycleGuard.test.js +0 -83
- package/lib/test/unit/ingest/cycleGuard.test.js.map +0 -1
- package/lib/test/unit/ingest/dedupScope.test.d.ts +0 -2
- package/lib/test/unit/ingest/dedupScope.test.d.ts.map +0 -1
- package/lib/test/unit/ingest/dedupScope.test.js +0 -436
- package/lib/test/unit/ingest/dedupScope.test.js.map +0 -1
- package/lib/test/unit/ingest/orchestrator.test.d.ts +0 -2
- package/lib/test/unit/ingest/orchestrator.test.d.ts.map +0 -1
- package/lib/test/unit/ingest/orchestrator.test.js +0 -1060
- package/lib/test/unit/ingest/orchestrator.test.js.map +0 -1
- package/lib/test/unit/observe/memoryObservationStore.test.d.ts +0 -2
- package/lib/test/unit/observe/memoryObservationStore.test.d.ts.map +0 -1
- package/lib/test/unit/observe/memoryObservationStore.test.js +0 -120
- package/lib/test/unit/observe/memoryObservationStore.test.js.map +0 -1
- package/lib/test/unit/retrieve/fragmentSemanticRetriever.test.d.ts +0 -2
- package/lib/test/unit/retrieve/fragmentSemanticRetriever.test.d.ts.map +0 -1
- package/lib/test/unit/retrieve/fragmentSemanticRetriever.test.js +0 -118
- package/lib/test/unit/retrieve/fragmentSemanticRetriever.test.js.map +0 -1
- package/lib/test/unit/retrieve/linkTraversalRetriever.test.d.ts +0 -2
- package/lib/test/unit/retrieve/linkTraversalRetriever.test.d.ts.map +0 -1
- package/lib/test/unit/retrieve/linkTraversalRetriever.test.js +0 -259
- package/lib/test/unit/retrieve/linkTraversalRetriever.test.js.map +0 -1
- package/lib/test/unit/retrieve/retrievers.test.d.ts +0 -2
- package/lib/test/unit/retrieve/retrievers.test.d.ts.map +0 -1
- package/lib/test/unit/retrieve/retrievers.test.js +0 -770
- package/lib/test/unit/retrieve/retrievers.test.js.map +0 -1
- package/lib/test/unit/retrieve/temporalRetrievers.test.d.ts +0 -2
- package/lib/test/unit/retrieve/temporalRetrievers.test.d.ts.map +0 -1
- package/lib/test/unit/retrieve/temporalRetrievers.test.js +0 -184
- package/lib/test/unit/retrieve/temporalRetrievers.test.js.map +0 -1
- package/lib/test/unit/store/antagonistTemporalBoundary.test.d.ts +0 -9
- package/lib/test/unit/store/antagonistTemporalBoundary.test.d.ts.map +0 -1
- package/lib/test/unit/store/antagonistTemporalBoundary.test.js +0 -122
- package/lib/test/unit/store/antagonistTemporalBoundary.test.js.map +0 -1
- package/lib/test/unit/store/embedOnWrite.test.d.ts +0 -2
- package/lib/test/unit/store/embedOnWrite.test.d.ts.map +0 -1
- package/lib/test/unit/store/embedOnWrite.test.js +0 -319
- package/lib/test/unit/store/embedOnWrite.test.js.map +0 -1
- package/lib/test/unit/store/fileTreeMemoryStore.test.d.ts +0 -2
- package/lib/test/unit/store/fileTreeMemoryStore.test.d.ts.map +0 -1
- package/lib/test/unit/store/fileTreeMemoryStore.test.js +0 -780
- package/lib/test/unit/store/fileTreeMemoryStore.test.js.map +0 -1
- package/lib/test/unit/store/fragmentEmbedOnWrite.test.d.ts +0 -2
- package/lib/test/unit/store/fragmentEmbedOnWrite.test.d.ts.map +0 -1
- package/lib/test/unit/store/fragmentEmbedOnWrite.test.js +0 -257
- package/lib/test/unit/store/fragmentEmbedOnWrite.test.js.map +0 -1
- package/lib/test/unit/store/indexInjection.test.d.ts +0 -2
- package/lib/test/unit/store/indexInjection.test.d.ts.map +0 -1
- package/lib/test/unit/store/indexInjection.test.js +0 -434
- package/lib/test/unit/store/indexInjection.test.js.map +0 -1
- package/lib/test/unit/store/lenientOpen.test.d.ts +0 -2
- package/lib/test/unit/store/lenientOpen.test.d.ts.map +0 -1
- package/lib/test/unit/store/lenientOpen.test.js +0 -250
- package/lib/test/unit/store/lenientOpen.test.js.map +0 -1
- package/lib/test/unit/store/listScoped.test.d.ts +0 -2
- package/lib/test/unit/store/listScoped.test.d.ts.map +0 -1
- package/lib/test/unit/store/listScoped.test.js +0 -111
- package/lib/test/unit/store/listScoped.test.js.map +0 -1
- package/lib/test/unit/store/observations.test.d.ts +0 -2
- package/lib/test/unit/store/observations.test.d.ts.map +0 -1
- package/lib/test/unit/store/observations.test.js +0 -241
- package/lib/test/unit/store/observations.test.js.map +0 -1
- package/lib/test/unit/store/rankAxis.test.d.ts +0 -2
- package/lib/test/unit/store/rankAxis.test.d.ts.map +0 -1
- package/lib/test/unit/store/rankAxis.test.js +0 -256
- package/lib/test/unit/store/rankAxis.test.js.map +0 -1
- package/lib/test/unit/store/scopeEncoding.test.d.ts +0 -2
- package/lib/test/unit/store/scopeEncoding.test.d.ts.map +0 -1
- package/lib/test/unit/store/scopeEncoding.test.js +0 -26
- package/lib/test/unit/store/scopeEncoding.test.js.map +0 -1
- package/lib/test/unit/store/temporalStore.test.d.ts +0 -2
- package/lib/test/unit/store/temporalStore.test.d.ts.map +0 -1
- package/lib/test/unit/store/temporalStore.test.js +0 -400
- package/lib/test/unit/store/temporalStore.test.js.map +0 -1
- package/lib/test/unit/tools/memoryTools.test.d.ts +0 -2
- package/lib/test/unit/tools/memoryTools.test.d.ts.map +0 -1
- package/lib/test/unit/tools/memoryTools.test.js +0 -844
- package/lib/test/unit/tools/memoryTools.test.js.map +0 -1
- package/lib/test/unit/types/identityCodec.test.d.ts +0 -2
- package/lib/test/unit/types/identityCodec.test.d.ts.map +0 -1
- package/lib/test/unit/types/identityCodec.test.js +0 -189
- package/lib/test/unit/types/identityCodec.test.js.map +0 -1
- package/lib/test/unit/types/ids.test.d.ts +0 -2
- package/lib/test/unit/types/ids.test.d.ts.map +0 -1
- package/lib/test/unit/types/ids.test.js +0 -86
- package/lib/test/unit/types/ids.test.js.map +0 -1
- package/lib/test/unit/types/temporalCodec.test.d.ts +0 -2
- package/lib/test/unit/types/temporalCodec.test.d.ts.map +0 -1
- package/lib/test/unit/types/temporalCodec.test.js +0 -205
- package/lib/test/unit/types/temporalCodec.test.js.map +0 -1
- package/lib/test/unit/types/temporalPolicy.test.d.ts +0 -2
- package/lib/test/unit/types/temporalPolicy.test.d.ts.map +0 -1
- package/lib/test/unit/types/temporalPolicy.test.js +0 -85
- package/lib/test/unit/types/temporalPolicy.test.js.map +0 -1
- package/lib/test/unit/types/writePolicy.test.d.ts +0 -2
- package/lib/test/unit/types/writePolicy.test.d.ts.map +0 -1
- package/lib/test/unit/types/writePolicy.test.js +0 -333
- package/lib/test/unit/types/writePolicy.test.js.map +0 -1
- package/lib/test/unit/vector/fragmentConverters.test.d.ts +0 -2
- package/lib/test/unit/vector/fragmentConverters.test.d.ts.map +0 -1
- package/lib/test/unit/vector/fragmentConverters.test.js +0 -60
- package/lib/test/unit/vector/fragmentConverters.test.js.map +0 -1
- package/lib/test/unit/vector/inMemoryCosineIndex.test.d.ts +0 -2
- package/lib/test/unit/vector/inMemoryCosineIndex.test.d.ts.map +0 -1
- package/lib/test/unit/vector/inMemoryCosineIndex.test.js +0 -254
- package/lib/test/unit/vector/inMemoryCosineIndex.test.js.map +0 -1
- package/lib/test/unit/vector/inMemoryFragmentCosineIndex.test.d.ts +0 -2
- package/lib/test/unit/vector/inMemoryFragmentCosineIndex.test.d.ts.map +0 -1
- package/lib/test/unit/vector/inMemoryFragmentCosineIndex.test.js +0 -364
- package/lib/test/unit/vector/inMemoryFragmentCosineIndex.test.js.map +0 -1
- package/lib/test/unit/vector/vectorIndex.test.d.ts +0 -2
- package/lib/test/unit/vector/vectorIndex.test.d.ts.map +0 -1
- package/lib/test/unit/vector/vectorIndex.test.js +0 -53
- package/lib/test/unit/vector/vectorIndex.test.js.map +0 -1
- package/rush-logs/ts-agent-memory.build.cache.log +0 -3
- package/rush-logs/ts-agent-memory.build.log +0 -9
- package/src/index.ts +0 -14
- package/src/packlets/converters/bodyConverterRegistry.ts +0 -105
- package/src/packlets/converters/envelopeConverter.ts +0 -233
- package/src/packlets/converters/index.ts +0 -7
- package/src/packlets/index/index.ts +0 -6
- package/src/packlets/index/memoryIndex.ts +0 -332
- package/src/packlets/ingest/cycleGuard.ts +0 -153
- package/src/packlets/ingest/hostStages.ts +0 -111
- package/src/packlets/ingest/index.ts +0 -9
- package/src/packlets/ingest/model.ts +0 -195
- package/src/packlets/ingest/orchestrator.ts +0 -968
- package/src/packlets/observe/index.ts +0 -7
- package/src/packlets/observe/memoryObservationStore.ts +0 -153
- package/src/packlets/observe/observer.ts +0 -119
- package/src/packlets/retrieve/fragmentSemanticRetriever.ts +0 -138
- package/src/packlets/retrieve/hybridRetriever.ts +0 -194
- package/src/packlets/retrieve/index.ts +0 -14
- package/src/packlets/retrieve/linkTraversalRetriever.ts +0 -158
- package/src/packlets/retrieve/recencyRetriever.ts +0 -54
- package/src/packlets/retrieve/retriever.ts +0 -291
- package/src/packlets/retrieve/semanticRetriever.ts +0 -152
- package/src/packlets/retrieve/structuredFilterRetriever.ts +0 -58
- package/src/packlets/retrieve/tagRetriever.ts +0 -58
- package/src/packlets/retrieve/temporalRetrievers.ts +0 -210
- package/src/packlets/store/fileTreeMemoryStore.ts +0 -1872
- package/src/packlets/store/index.ts +0 -7
- package/src/packlets/store/scopeEncoding.ts +0 -36
- package/src/packlets/tools/index.ts +0 -6
- package/src/packlets/tools/memoryTools.ts +0 -706
- package/src/packlets/types/envelope.ts +0 -196
- package/src/packlets/types/filenameSafety.ts +0 -57
- package/src/packlets/types/identityCodec.ts +0 -447
- package/src/packlets/types/ids.ts +0 -124
- package/src/packlets/types/index.ts +0 -11
- package/src/packlets/types/temporal.ts +0 -96
- package/src/packlets/types/writePolicy.ts +0 -612
- package/src/packlets/vector/fragmentConverters.ts +0 -55
- package/src/packlets/vector/inMemoryCosineIndex.ts +0 -196
- package/src/packlets/vector/inMemoryFragmentCosineIndex.ts +0 -289
- package/src/packlets/vector/index.ts +0 -9
- package/src/packlets/vector/vectorIndex.ts +0 -273
- package/src/test/unit/converters/antagonistRoundTrip.test.ts +0 -110
- package/src/test/unit/converters/bodyConverterRegistry.test.ts +0 -89
- package/src/test/unit/converters/envelopeConverter.test.ts +0 -418
- package/src/test/unit/index/memoryIndex.test.ts +0 -272
- package/src/test/unit/ingest/antagonistCycleAndParity.test.ts +0 -367
- package/src/test/unit/ingest/cycleGuard.test.ts +0 -110
- package/src/test/unit/ingest/dedupScope.test.ts +0 -542
- package/src/test/unit/ingest/orchestrator.test.ts +0 -1355
- package/src/test/unit/observe/memoryObservationStore.test.ts +0 -158
- package/src/test/unit/retrieve/fragmentSemanticRetriever.test.ts +0 -163
- package/src/test/unit/retrieve/linkTraversalRetriever.test.ts +0 -329
- package/src/test/unit/retrieve/retrievers.test.ts +0 -1018
- package/src/test/unit/retrieve/temporalRetrievers.test.ts +0 -226
- package/src/test/unit/store/antagonistTemporalBoundary.test.ts +0 -158
- package/src/test/unit/store/embedOnWrite.test.ts +0 -418
- package/src/test/unit/store/fileTreeMemoryStore.test.ts +0 -1041
- package/src/test/unit/store/fragmentEmbedOnWrite.test.ts +0 -349
- package/src/test/unit/store/indexInjection.test.ts +0 -550
- package/src/test/unit/store/lenientOpen.test.ts +0 -292
- package/src/test/unit/store/listScoped.test.ts +0 -138
- package/src/test/unit/store/observations.test.ts +0 -290
- package/src/test/unit/store/rankAxis.test.ts +0 -349
- package/src/test/unit/store/scopeEncoding.test.ts +0 -37
- package/src/test/unit/store/temporalStore.test.ts +0 -469
- package/src/test/unit/tools/memoryTools.test.ts +0 -1121
- package/src/test/unit/types/identityCodec.test.ts +0 -266
- package/src/test/unit/types/ids.test.ts +0 -94
- package/src/test/unit/types/temporalCodec.test.ts +0 -259
- package/src/test/unit/types/temporalPolicy.test.ts +0 -124
- package/src/test/unit/types/writePolicy.test.ts +0 -446
- package/src/test/unit/vector/fragmentConverters.test.ts +0 -80
- package/src/test/unit/vector/inMemoryCosineIndex.test.ts +0 -318
- package/src/test/unit/vector/inMemoryFragmentCosineIndex.test.ts +0 -477
- package/src/test/unit/vector/vectorIndex.test.ts +0 -64
- package/temp/build/lint/_eslint-5eVG3S6w.json +0 -306
- package/temp/build/typescript/ts_8nwakTlr.json +0 -1
- package/temp/ts-agent-memory.api.json +0 -21030
- package/temp/ts-agent-memory.api.md +0 -940
- package/tsconfig.json +0 -8
|
@@ -1,203 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2026 Erik Fortune
|
|
3
|
-
* SPDX-License-Identifier: MIT
|
|
4
|
-
*/
|
|
5
|
-
import '@fgv/ts-utils-jest';
|
|
6
|
-
import { KnowledgeIdentityCodec, TemporalIdentityCodec, isTemporalIdentityCodec, isTemporalRecord, isVersionCurrent, isVersionValidAt, selectCurrentVersion, selectVersionAsOf } from '../../../packlets/types';
|
|
7
|
-
import { envelopeConverter } from '../../../packlets/converters';
|
|
8
|
-
const codec = TemporalIdentityCodec.create('facts').orThrow();
|
|
9
|
-
describe('TemporalIdentityCodec', () => {
|
|
10
|
-
describe('create', () => {
|
|
11
|
-
test('rejects a non-portable base scope', () => {
|
|
12
|
-
expect(TemporalIdentityCodec.create('has/slash')).toFailWith(/baseScope/i);
|
|
13
|
-
});
|
|
14
|
-
});
|
|
15
|
-
describe('encode', () => {
|
|
16
|
-
test('maps an entityId to the entity subtree, versioned', () => {
|
|
17
|
-
expect(codec.encode('fact-1')).toSucceedWith({
|
|
18
|
-
scope: 'facts/entities/fact-1',
|
|
19
|
-
idStem: 'fact-1',
|
|
20
|
-
isVersioned: true
|
|
21
|
-
});
|
|
22
|
-
});
|
|
23
|
-
test('rejects a non-portable entityId', () => {
|
|
24
|
-
expect(codec.encode('bad/id')).toFailWith(/entityId/i);
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
describe('encodeVersion', () => {
|
|
28
|
-
test('forms the <entityId>-v<seq> stem', () => {
|
|
29
|
-
expect(codec.encodeVersion('fact-1', 7)).toSucceedWith('fact-1-v7');
|
|
30
|
-
});
|
|
31
|
-
test('rejects a negative or non-integer seq', () => {
|
|
32
|
-
expect(codec.encodeVersion('fact-1', -1)).toFailWith(/non-negative integer/i);
|
|
33
|
-
expect(codec.encodeVersion('fact-1', 1.5)).toFailWith(/non-negative integer/i);
|
|
34
|
-
});
|
|
35
|
-
test('rejects a non-portable entityId', () => {
|
|
36
|
-
expect(codec.encodeVersion('bad/id', 1)).toFailWith(/entityId/i);
|
|
37
|
-
});
|
|
38
|
-
});
|
|
39
|
-
describe('decode / decodeVersion', () => {
|
|
40
|
-
test('recovers the entityId and seq from a (scope, version stem)', () => {
|
|
41
|
-
expect(codec.decodeVersion('facts/entities/fact-1', 'fact-1-v3')).toSucceedWith({
|
|
42
|
-
entityId: 'fact-1',
|
|
43
|
-
seq: 3
|
|
44
|
-
});
|
|
45
|
-
expect(codec.decode('facts/entities/fact-1', 'fact-1-v3')).toSucceedWith('fact-1');
|
|
46
|
-
});
|
|
47
|
-
test('disambiguates an entityId that itself ends in -v<digits> via the scope', () => {
|
|
48
|
-
// The subtree scope is authoritative for the entityId, so a stem whose
|
|
49
|
-
// entityId is `rev-v2` parses correctly.
|
|
50
|
-
expect(codec.decodeVersion('facts/entities/rev-v2', 'rev-v2-v5')).toSucceedWith({
|
|
51
|
-
entityId: 'rev-v2',
|
|
52
|
-
seq: 5
|
|
53
|
-
});
|
|
54
|
-
});
|
|
55
|
-
test('rejects a scope that is not <base>/entities/<entityId>', () => {
|
|
56
|
-
expect(codec.decodeVersion('facts/fact-1', 'fact-1-v0')).toFailWith(/must be 'facts\/entities\/<entityId>'/i);
|
|
57
|
-
expect(codec.decodeVersion('other/entities/fact-1', 'fact-1-v0')).toFailWith(/must be 'facts\/entities\/<entityId>'/i);
|
|
58
|
-
});
|
|
59
|
-
test('rejects a non-portable entityId embedded in the scope', () => {
|
|
60
|
-
expect(codec.decodeVersion('facts/entities/ ', ' -v0')).toFailWith(/entityId/i);
|
|
61
|
-
});
|
|
62
|
-
test('rejects a stem that does not carry the entity prefix', () => {
|
|
63
|
-
expect(codec.decodeVersion('facts/entities/fact-1', 'other-v0')).toFailWith(/must begin with 'fact-1-v'/i);
|
|
64
|
-
});
|
|
65
|
-
test('rejects a stem with a non-integer version suffix', () => {
|
|
66
|
-
expect(codec.decodeVersion('facts/entities/fact-1', 'fact-1-vX')).toFailWith(/non-integer version suffix/i);
|
|
67
|
-
});
|
|
68
|
-
test('rejects a version suffix outside the safe integer range (corruption/tamper guard)', () => {
|
|
69
|
-
// A very long digit run passes the regex but overflows Number.MAX_SAFE_INTEGER;
|
|
70
|
-
// parseInt would silently lose precision, so decode must fail rather than corrupt seq.
|
|
71
|
-
expect(codec.decodeVersion('facts/entities/fact-1', 'fact-1-v99999999999999999999')).toFailWith(/outside the safe integer range/i);
|
|
72
|
-
});
|
|
73
|
-
});
|
|
74
|
-
describe('verifyRoundTrip', () => {
|
|
75
|
-
test('succeeds for a well-formed (scope, version stem)', () => {
|
|
76
|
-
expect(codec.verifyRoundTrip('facts/entities/fact-1', 'fact-1-v9')).toSucceedWith(true);
|
|
77
|
-
});
|
|
78
|
-
test('fails when the stem cannot be decoded', () => {
|
|
79
|
-
expect(codec.verifyRoundTrip('facts/entities/fact-1', 'fact-1-vZ')).toFailWith(/non-integer version suffix/i);
|
|
80
|
-
});
|
|
81
|
-
test('fails on a non-canonical (zero-padded) seq stem', () => {
|
|
82
|
-
// `-v007` decodes to seq 7 but re-encodes to `-v7`, so it is not canonical.
|
|
83
|
-
expect(codec.verifyRoundTrip('facts/entities/fact-1', 'fact-1-v007')).toFailWith(/round-trip mismatch/i);
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
});
|
|
87
|
-
describe('isTemporalIdentityCodec', () => {
|
|
88
|
-
test('is true for a temporal codec', () => {
|
|
89
|
-
expect(isTemporalIdentityCodec(codec)).toBe(true);
|
|
90
|
-
});
|
|
91
|
-
test('is false for a flat codec', () => {
|
|
92
|
-
const flat = new KnowledgeIdentityCodec();
|
|
93
|
-
expect(isTemporalIdentityCodec(flat)).toBe(false);
|
|
94
|
-
});
|
|
95
|
-
});
|
|
96
|
-
/** Build a temporal version record for the selection-helper tests. */
|
|
97
|
-
// eslint-disable-next-line @rushstack/no-new-null -- invalid_at null is the meaningful still-valid sentinel
|
|
98
|
-
function versionRecord(seq, validAt, invalidAt) {
|
|
99
|
-
const temporal = { valid_at: validAt };
|
|
100
|
-
if (invalidAt !== undefined) {
|
|
101
|
-
temporal.invalid_at = invalidAt;
|
|
102
|
-
}
|
|
103
|
-
return {
|
|
104
|
-
envelope: envelopeConverter
|
|
105
|
-
.convert({
|
|
106
|
-
id: `fact-1-v${seq}`,
|
|
107
|
-
entityId: 'fact-1',
|
|
108
|
-
kind: 'fact',
|
|
109
|
-
tags: [],
|
|
110
|
-
links: [],
|
|
111
|
-
created: validAt,
|
|
112
|
-
updated: validAt,
|
|
113
|
-
seq,
|
|
114
|
-
contentHash: `h${seq}`,
|
|
115
|
-
provenance: { source: 'agent' },
|
|
116
|
-
temporal
|
|
117
|
-
})
|
|
118
|
-
.orThrow(),
|
|
119
|
-
body: `body v${seq}`
|
|
120
|
-
};
|
|
121
|
-
}
|
|
122
|
-
describe('temporal selection helpers', () => {
|
|
123
|
-
const v1 = versionRecord(1, 100, 200);
|
|
124
|
-
const v2 = versionRecord(2, 200);
|
|
125
|
-
const atemporal = {
|
|
126
|
-
envelope: envelopeConverter
|
|
127
|
-
.convert({
|
|
128
|
-
id: 'doc',
|
|
129
|
-
entityId: 'doc',
|
|
130
|
-
kind: 'knowledge',
|
|
131
|
-
tags: [],
|
|
132
|
-
links: [],
|
|
133
|
-
created: 0,
|
|
134
|
-
updated: 0,
|
|
135
|
-
seq: 0,
|
|
136
|
-
contentHash: 'h',
|
|
137
|
-
provenance: { source: 'agent' }
|
|
138
|
-
})
|
|
139
|
-
.orThrow(),
|
|
140
|
-
body: 'flat'
|
|
141
|
-
};
|
|
142
|
-
test('isTemporalRecord keys off the temporal block', () => {
|
|
143
|
-
expect(isTemporalRecord(v1)).toBe(true);
|
|
144
|
-
expect(isTemporalRecord(atemporal)).toBe(false);
|
|
145
|
-
});
|
|
146
|
-
test('isVersionCurrent is true only for a null/absent invalid_at', () => {
|
|
147
|
-
expect(isVersionCurrent(v1)).toBe(false);
|
|
148
|
-
expect(isVersionCurrent(v2)).toBe(true);
|
|
149
|
-
expect(isVersionCurrent(versionRecord(3, 300, null))).toBe(true);
|
|
150
|
-
expect(isVersionCurrent(atemporal)).toBe(false);
|
|
151
|
-
});
|
|
152
|
-
test('isVersionValidAt bounds by valid_at and invalid_at', () => {
|
|
153
|
-
expect(isVersionValidAt(v1, 50)).toBe(false); // before valid_at
|
|
154
|
-
expect(isVersionValidAt(v1, 150)).toBe(true); // within [100, 200)
|
|
155
|
-
expect(isVersionValidAt(v1, 200)).toBe(false); // at invalid_at (exclusive)
|
|
156
|
-
expect(isVersionValidAt(v2, 500)).toBe(true); // still valid
|
|
157
|
-
expect(isVersionValidAt(atemporal, 500)).toBe(false);
|
|
158
|
-
});
|
|
159
|
-
test('isVersionValidAt defaults valid_at to created when absent', () => {
|
|
160
|
-
const noValidAt = {
|
|
161
|
-
envelope: envelopeConverter
|
|
162
|
-
.convert({
|
|
163
|
-
id: 'fact-1-v4',
|
|
164
|
-
entityId: 'fact-1',
|
|
165
|
-
kind: 'fact',
|
|
166
|
-
tags: [],
|
|
167
|
-
links: [],
|
|
168
|
-
created: 400,
|
|
169
|
-
updated: 400,
|
|
170
|
-
seq: 4,
|
|
171
|
-
contentHash: 'h4',
|
|
172
|
-
provenance: { source: 'agent' },
|
|
173
|
-
temporal: {}
|
|
174
|
-
})
|
|
175
|
-
.orThrow(),
|
|
176
|
-
body: 'v4'
|
|
177
|
-
};
|
|
178
|
-
expect(isVersionValidAt(noValidAt, 399)).toBe(false);
|
|
179
|
-
expect(isVersionValidAt(noValidAt, 400)).toBe(true);
|
|
180
|
-
});
|
|
181
|
-
test('selectCurrentVersion returns the highest-seq current version', () => {
|
|
182
|
-
var _a;
|
|
183
|
-
expect((_a = selectCurrentVersion([v1, v2])) === null || _a === void 0 ? void 0 : _a.envelope.id).toBe('fact-1-v2');
|
|
184
|
-
// A fully-invalidated entity has no current version.
|
|
185
|
-
expect(selectCurrentVersion([v1])).toBeUndefined();
|
|
186
|
-
expect(selectCurrentVersion([])).toBeUndefined();
|
|
187
|
-
});
|
|
188
|
-
test('selectCurrentVersion is order-independent (highest seq wins on an unsorted input)', () => {
|
|
189
|
-
var _a, _b;
|
|
190
|
-
const v3 = versionRecord(3, 300);
|
|
191
|
-
// Descending input: the first candidate is already the max, so a later
|
|
192
|
-
// candidate must NOT displace it.
|
|
193
|
-
expect((_a = selectCurrentVersion([v3, v2])) === null || _a === void 0 ? void 0 : _a.envelope.id).toBe('fact-1-v3');
|
|
194
|
-
expect((_b = selectCurrentVersion([v2, v3])) === null || _b === void 0 ? void 0 : _b.envelope.id).toBe('fact-1-v3');
|
|
195
|
-
});
|
|
196
|
-
test('selectVersionAsOf returns the highest-seq version valid at the instant', () => {
|
|
197
|
-
var _a, _b;
|
|
198
|
-
expect((_a = selectVersionAsOf([v1, v2], 150)) === null || _a === void 0 ? void 0 : _a.envelope.id).toBe('fact-1-v1');
|
|
199
|
-
expect((_b = selectVersionAsOf([v1, v2], 250)) === null || _b === void 0 ? void 0 : _b.envelope.id).toBe('fact-1-v2');
|
|
200
|
-
expect(selectVersionAsOf([v1, v2], 50)).toBeUndefined();
|
|
201
|
-
});
|
|
202
|
-
});
|
|
203
|
-
//# sourceMappingURL=temporalCodec.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"temporalCodec.test.js","sourceRoot":"","sources":["../../../../src/test/unit/types/temporalCodec.test.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2026 Erik Fortune\n * SPDX-License-Identifier: MIT\n */\n\nimport '@fgv/ts-utils-jest';\nimport {\n EntityId,\n IIdentityCodec,\n IMemoryRecord,\n KnowledgeIdentityCodec,\n MemoryScopeKey,\n TemporalIdentityCodec,\n isTemporalIdentityCodec,\n isTemporalRecord,\n isVersionCurrent,\n isVersionValidAt,\n selectCurrentVersion,\n selectVersionAsOf\n} from '../../../packlets/types';\nimport { envelopeConverter } from '../../../packlets/converters';\n\nconst codec: TemporalIdentityCodec = TemporalIdentityCodec.create('facts').orThrow();\n\ndescribe('TemporalIdentityCodec', () => {\n describe('create', () => {\n test('rejects a non-portable base scope', () => {\n expect(TemporalIdentityCodec.create('has/slash')).toFailWith(/baseScope/i);\n });\n });\n\n describe('encode', () => {\n test('maps an entityId to the entity subtree, versioned', () => {\n expect(codec.encode('fact-1' as EntityId)).toSucceedWith({\n scope: 'facts/entities/fact-1' as MemoryScopeKey,\n idStem: 'fact-1',\n isVersioned: true\n });\n });\n\n test('rejects a non-portable entityId', () => {\n expect(codec.encode('bad/id' as EntityId)).toFailWith(/entityId/i);\n });\n });\n\n describe('encodeVersion', () => {\n test('forms the <entityId>-v<seq> stem', () => {\n expect(codec.encodeVersion('fact-1' as EntityId, 7)).toSucceedWith('fact-1-v7');\n });\n\n test('rejects a negative or non-integer seq', () => {\n expect(codec.encodeVersion('fact-1' as EntityId, -1)).toFailWith(/non-negative integer/i);\n expect(codec.encodeVersion('fact-1' as EntityId, 1.5)).toFailWith(/non-negative integer/i);\n });\n\n test('rejects a non-portable entityId', () => {\n expect(codec.encodeVersion('bad/id' as EntityId, 1)).toFailWith(/entityId/i);\n });\n });\n\n describe('decode / decodeVersion', () => {\n test('recovers the entityId and seq from a (scope, version stem)', () => {\n expect(codec.decodeVersion('facts/entities/fact-1' as MemoryScopeKey, 'fact-1-v3')).toSucceedWith({\n entityId: 'fact-1' as EntityId,\n seq: 3\n });\n expect(codec.decode('facts/entities/fact-1' as MemoryScopeKey, 'fact-1-v3')).toSucceedWith(\n 'fact-1' as EntityId\n );\n });\n\n test('disambiguates an entityId that itself ends in -v<digits> via the scope', () => {\n // The subtree scope is authoritative for the entityId, so a stem whose\n // entityId is `rev-v2` parses correctly.\n expect(codec.decodeVersion('facts/entities/rev-v2' as MemoryScopeKey, 'rev-v2-v5')).toSucceedWith({\n entityId: 'rev-v2' as EntityId,\n seq: 5\n });\n });\n\n test('rejects a scope that is not <base>/entities/<entityId>', () => {\n expect(codec.decodeVersion('facts/fact-1' as MemoryScopeKey, 'fact-1-v0')).toFailWith(\n /must be 'facts\\/entities\\/<entityId>'/i\n );\n expect(codec.decodeVersion('other/entities/fact-1' as MemoryScopeKey, 'fact-1-v0')).toFailWith(\n /must be 'facts\\/entities\\/<entityId>'/i\n );\n });\n\n test('rejects a non-portable entityId embedded in the scope', () => {\n expect(codec.decodeVersion('facts/entities/ ' as MemoryScopeKey, ' -v0')).toFailWith(/entityId/i);\n });\n\n test('rejects a stem that does not carry the entity prefix', () => {\n expect(codec.decodeVersion('facts/entities/fact-1' as MemoryScopeKey, 'other-v0')).toFailWith(\n /must begin with 'fact-1-v'/i\n );\n });\n\n test('rejects a stem with a non-integer version suffix', () => {\n expect(codec.decodeVersion('facts/entities/fact-1' as MemoryScopeKey, 'fact-1-vX')).toFailWith(\n /non-integer version suffix/i\n );\n });\n\n test('rejects a version suffix outside the safe integer range (corruption/tamper guard)', () => {\n // A very long digit run passes the regex but overflows Number.MAX_SAFE_INTEGER;\n // parseInt would silently lose precision, so decode must fail rather than corrupt seq.\n expect(\n codec.decodeVersion('facts/entities/fact-1' as MemoryScopeKey, 'fact-1-v99999999999999999999')\n ).toFailWith(/outside the safe integer range/i);\n });\n });\n\n describe('verifyRoundTrip', () => {\n test('succeeds for a well-formed (scope, version stem)', () => {\n expect(codec.verifyRoundTrip('facts/entities/fact-1' as MemoryScopeKey, 'fact-1-v9')).toSucceedWith(\n true\n );\n });\n\n test('fails when the stem cannot be decoded', () => {\n expect(codec.verifyRoundTrip('facts/entities/fact-1' as MemoryScopeKey, 'fact-1-vZ')).toFailWith(\n /non-integer version suffix/i\n );\n });\n\n test('fails on a non-canonical (zero-padded) seq stem', () => {\n // `-v007` decodes to seq 7 but re-encodes to `-v7`, so it is not canonical.\n expect(codec.verifyRoundTrip('facts/entities/fact-1' as MemoryScopeKey, 'fact-1-v007')).toFailWith(\n /round-trip mismatch/i\n );\n });\n });\n});\n\ndescribe('isTemporalIdentityCodec', () => {\n test('is true for a temporal codec', () => {\n expect(isTemporalIdentityCodec(codec)).toBe(true);\n });\n\n test('is false for a flat codec', () => {\n const flat: IIdentityCodec = new KnowledgeIdentityCodec();\n expect(isTemporalIdentityCodec(flat)).toBe(false);\n });\n});\n\n/** Build a temporal version record for the selection-helper tests. */\n// eslint-disable-next-line @rushstack/no-new-null -- invalid_at null is the meaningful still-valid sentinel\nfunction versionRecord(seq: number, validAt: number, invalidAt?: number | null): IMemoryRecord<unknown> {\n const temporal: Record<string, unknown> = { valid_at: validAt };\n if (invalidAt !== undefined) {\n temporal.invalid_at = invalidAt;\n }\n return {\n envelope: envelopeConverter\n .convert({\n id: `fact-1-v${seq}`,\n entityId: 'fact-1',\n kind: 'fact',\n tags: [],\n links: [],\n created: validAt,\n updated: validAt,\n seq,\n contentHash: `h${seq}`,\n provenance: { source: 'agent' },\n temporal\n })\n .orThrow(),\n body: `body v${seq}`\n };\n}\n\ndescribe('temporal selection helpers', () => {\n const v1 = versionRecord(1, 100, 200);\n const v2 = versionRecord(2, 200);\n const atemporal: IMemoryRecord<unknown> = {\n envelope: envelopeConverter\n .convert({\n id: 'doc',\n entityId: 'doc',\n kind: 'knowledge',\n tags: [],\n links: [],\n created: 0,\n updated: 0,\n seq: 0,\n contentHash: 'h',\n provenance: { source: 'agent' }\n })\n .orThrow(),\n body: 'flat'\n };\n\n test('isTemporalRecord keys off the temporal block', () => {\n expect(isTemporalRecord(v1)).toBe(true);\n expect(isTemporalRecord(atemporal)).toBe(false);\n });\n\n test('isVersionCurrent is true only for a null/absent invalid_at', () => {\n expect(isVersionCurrent(v1)).toBe(false);\n expect(isVersionCurrent(v2)).toBe(true);\n expect(isVersionCurrent(versionRecord(3, 300, null))).toBe(true);\n expect(isVersionCurrent(atemporal)).toBe(false);\n });\n\n test('isVersionValidAt bounds by valid_at and invalid_at', () => {\n expect(isVersionValidAt(v1, 50)).toBe(false); // before valid_at\n expect(isVersionValidAt(v1, 150)).toBe(true); // within [100, 200)\n expect(isVersionValidAt(v1, 200)).toBe(false); // at invalid_at (exclusive)\n expect(isVersionValidAt(v2, 500)).toBe(true); // still valid\n expect(isVersionValidAt(atemporal, 500)).toBe(false);\n });\n\n test('isVersionValidAt defaults valid_at to created when absent', () => {\n const noValidAt: IMemoryRecord<unknown> = {\n envelope: envelopeConverter\n .convert({\n id: 'fact-1-v4',\n entityId: 'fact-1',\n kind: 'fact',\n tags: [],\n links: [],\n created: 400,\n updated: 400,\n seq: 4,\n contentHash: 'h4',\n provenance: { source: 'agent' },\n temporal: {}\n })\n .orThrow(),\n body: 'v4'\n };\n expect(isVersionValidAt(noValidAt, 399)).toBe(false);\n expect(isVersionValidAt(noValidAt, 400)).toBe(true);\n });\n\n test('selectCurrentVersion returns the highest-seq current version', () => {\n expect(selectCurrentVersion([v1, v2])?.envelope.id).toBe('fact-1-v2');\n // A fully-invalidated entity has no current version.\n expect(selectCurrentVersion([v1])).toBeUndefined();\n expect(selectCurrentVersion([])).toBeUndefined();\n });\n\n test('selectCurrentVersion is order-independent (highest seq wins on an unsorted input)', () => {\n const v3 = versionRecord(3, 300);\n // Descending input: the first candidate is already the max, so a later\n // candidate must NOT displace it.\n expect(selectCurrentVersion([v3, v2])?.envelope.id).toBe('fact-1-v3');\n expect(selectCurrentVersion([v2, v3])?.envelope.id).toBe('fact-1-v3');\n });\n\n test('selectVersionAsOf returns the highest-seq version valid at the instant', () => {\n expect(selectVersionAsOf([v1, v2], 150)?.envelope.id).toBe('fact-1-v1');\n expect(selectVersionAsOf([v1, v2], 250)?.envelope.id).toBe('fact-1-v2');\n expect(selectVersionAsOf([v1, v2], 50)).toBeUndefined();\n });\n});\n"]}
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Copyright (c) 2026 Erik Fortune
|
|
3
|
-
* SPDX-License-Identifier: MIT
|
|
4
|
-
*/
|
|
5
|
-
import '@fgv/ts-utils-jest';
|
|
6
|
-
import { TemporalVersionedPolicy } from '../../../packlets/types';
|
|
7
|
-
function makeRecord(overrides, body) {
|
|
8
|
-
const envelope = Object.assign({ id: 'fact-1-v1', entityId: 'fact-1', kind: 'fact', tags: ['sky'], links: [], created: 1000, updated: 1000, seq: 1, contentHash: 'hash-1', provenance: { source: 'agent' }, temporal: { valid_at: 1000 } }, overrides);
|
|
9
|
-
return { envelope, body: body !== null && body !== void 0 ? body : 'the sky is blue' };
|
|
10
|
-
}
|
|
11
|
-
describe('TemporalVersionedPolicy', () => {
|
|
12
|
-
let policy;
|
|
13
|
-
beforeEach(() => {
|
|
14
|
-
policy = TemporalVersionedPolicy.create().orThrow();
|
|
15
|
-
});
|
|
16
|
-
test('exposes the temporal mutable surface and entity dedup', () => {
|
|
17
|
-
expect(policy.mutableFields).toEqual(['body', 'tags', 'links', 'provenance', 'embeddingRef']);
|
|
18
|
-
expect(policy.dedupScope).toBe('entity');
|
|
19
|
-
});
|
|
20
|
-
describe('admit', () => {
|
|
21
|
-
test("always accepts (invalidate-don't-delete: never culls)", () => {
|
|
22
|
-
expect(policy.admit(makeRecord(), [])).toSucceedWith({ decision: 'accept' });
|
|
23
|
-
expect(policy.admit(makeRecord(), [makeRecord(), makeRecord()])).toSucceedWith({
|
|
24
|
-
decision: 'accept'
|
|
25
|
-
});
|
|
26
|
-
});
|
|
27
|
-
});
|
|
28
|
-
describe('applyUpdate (forms the new version content)', () => {
|
|
29
|
-
test('replaces a string body wholesale', () => {
|
|
30
|
-
const existing = makeRecord(undefined, 'the sky is blue');
|
|
31
|
-
expect(policy.applyUpdate(existing, { body: 'the sky is grey' })).toSucceedAndSatisfy((updated) => {
|
|
32
|
-
expect(updated.body).toBe('the sky is grey');
|
|
33
|
-
});
|
|
34
|
-
});
|
|
35
|
-
test('merges tags / provenance and preserves untouched envelope metadata', () => {
|
|
36
|
-
const existing = makeRecord({ provenance: { source: 'agent', by: 'curator' } });
|
|
37
|
-
expect(policy.applyUpdate(existing, { tags: ['sky', 'weather'], provenance: { model: 'gpt' } })).toSucceedAndSatisfy((updated) => {
|
|
38
|
-
expect(updated.envelope.tags).toEqual(['sky', 'weather']);
|
|
39
|
-
expect(updated.envelope.provenance).toEqual({ source: 'agent', by: 'curator', model: 'gpt' });
|
|
40
|
-
// Identity/transaction-time fields are carried verbatim (the store restamps them).
|
|
41
|
-
expect(updated.envelope.entityId).toBe('fact-1');
|
|
42
|
-
});
|
|
43
|
-
});
|
|
44
|
-
test('rejects a patch that deletes a required field', () => {
|
|
45
|
-
expect(policy.applyUpdate(makeRecord(), { body: null })).toFailWith(/may not delete required field/i);
|
|
46
|
-
});
|
|
47
|
-
test('restores embeddingRef as absent when a null patch drops it (hash-stable)', () => {
|
|
48
|
-
const existing = makeRecord({ embeddingRef: 'vec-1' });
|
|
49
|
-
expect(policy.applyUpdate(existing, { embeddingRef: null })).toSucceedAndSatisfy((updated) => {
|
|
50
|
-
expect(updated.envelope.embeddingRef).toBeUndefined();
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
test('carries an untouched embeddingRef through a body-only patch', () => {
|
|
54
|
-
const existing = makeRecord({ embeddingRef: 'vec-1' }, 'the sky is blue');
|
|
55
|
-
expect(policy.applyUpdate(existing, { body: 'the sky is grey' })).toSucceedAndSatisfy((updated) => {
|
|
56
|
-
expect(updated.body).toBe('the sky is grey');
|
|
57
|
-
expect(updated.envelope.embeddingRef).toBe('vec-1');
|
|
58
|
-
});
|
|
59
|
-
});
|
|
60
|
-
/**
|
|
61
|
-
* Mirrors the `provenance merge contract (README-pinned)` block in
|
|
62
|
-
* `writePolicy.test.ts`. The package README states that the provenance
|
|
63
|
-
* guarantees hold for BOTH pinned-surface policies, so both must be pinned
|
|
64
|
-
* here — otherwise the README claims more than the tests establish.
|
|
65
|
-
*/
|
|
66
|
-
describe('provenance merge contract (README-pinned)', () => {
|
|
67
|
-
function provenanceRecord() {
|
|
68
|
-
return makeRecord({
|
|
69
|
-
provenance: { source: 'agent', confidence: 0.9, note: 'stale' }
|
|
70
|
-
});
|
|
71
|
-
}
|
|
72
|
-
test('an explicit null on a sub-key clears that key and preserves its siblings', () => {
|
|
73
|
-
expect(policy.applyUpdate(provenanceRecord(), { provenance: { note: null } })).toSucceedAndSatisfy((updated) => {
|
|
74
|
-
expect(updated.envelope.provenance).toEqual({ source: 'agent', confidence: 0.9 });
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
test('a whole-block null is rejected loudly rather than silently accepted', () => {
|
|
78
|
-
expect(policy.applyUpdate(provenanceRecord(), { provenance: null })).toFailWith(/may not delete required field\(s\): provenance/i);
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
});
|
|
82
|
-
});
|
|
83
|
-
//# sourceMappingURL=temporalPolicy.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"temporalPolicy.test.js","sourceRoot":"","sources":["../../../../src/test/unit/types/temporalPolicy.test.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright (c) 2026 Erik Fortune\n * SPDX-License-Identifier: MIT\n */\n\nimport '@fgv/ts-utils-jest';\nimport {\n EntityId,\n IMemoryEnvelope,\n IMemoryRecord,\n IProvenance,\n Kind,\n MemoryId,\n Tag,\n TemporalVersionedPolicy\n} from '../../../packlets/types';\n\nfunction makeRecord(overrides?: Partial<IMemoryEnvelope>, body?: unknown): IMemoryRecord<unknown> {\n const envelope: IMemoryEnvelope = {\n id: 'fact-1-v1' as MemoryId,\n entityId: 'fact-1' as EntityId,\n kind: 'fact' as Kind,\n tags: ['sky'] as Tag[],\n links: [],\n created: 1000,\n updated: 1000,\n seq: 1,\n contentHash: 'hash-1',\n provenance: { source: 'agent' } as IProvenance,\n temporal: { valid_at: 1000 },\n ...overrides\n };\n return { envelope, body: body ?? 'the sky is blue' };\n}\n\ndescribe('TemporalVersionedPolicy', () => {\n let policy: TemporalVersionedPolicy;\n\n beforeEach(() => {\n policy = TemporalVersionedPolicy.create().orThrow();\n });\n\n test('exposes the temporal mutable surface and entity dedup', () => {\n expect(policy.mutableFields).toEqual(['body', 'tags', 'links', 'provenance', 'embeddingRef']);\n expect(policy.dedupScope).toBe('entity');\n });\n\n describe('admit', () => {\n test(\"always accepts (invalidate-don't-delete: never culls)\", () => {\n expect(policy.admit(makeRecord(), [])).toSucceedWith({ decision: 'accept' });\n expect(policy.admit(makeRecord(), [makeRecord(), makeRecord()])).toSucceedWith({\n decision: 'accept'\n });\n });\n });\n\n describe('applyUpdate (forms the new version content)', () => {\n test('replaces a string body wholesale', () => {\n const existing = makeRecord(undefined, 'the sky is blue');\n expect(policy.applyUpdate(existing, { body: 'the sky is grey' })).toSucceedAndSatisfy((updated) => {\n expect(updated.body).toBe('the sky is grey');\n });\n });\n\n test('merges tags / provenance and preserves untouched envelope metadata', () => {\n const existing = makeRecord({ provenance: { source: 'agent', by: 'curator' } as IProvenance });\n expect(\n policy.applyUpdate(existing, { tags: ['sky', 'weather'], provenance: { model: 'gpt' } })\n ).toSucceedAndSatisfy((updated) => {\n expect(updated.envelope.tags).toEqual(['sky', 'weather']);\n expect(updated.envelope.provenance).toEqual({ source: 'agent', by: 'curator', model: 'gpt' });\n // Identity/transaction-time fields are carried verbatim (the store restamps them).\n expect(updated.envelope.entityId).toBe('fact-1');\n });\n });\n\n test('rejects a patch that deletes a required field', () => {\n expect(policy.applyUpdate(makeRecord(), { body: null })).toFailWith(/may not delete required field/i);\n });\n\n test('restores embeddingRef as absent when a null patch drops it (hash-stable)', () => {\n const existing = makeRecord({ embeddingRef: 'vec-1' });\n expect(policy.applyUpdate(existing, { embeddingRef: null })).toSucceedAndSatisfy((updated) => {\n expect(updated.envelope.embeddingRef).toBeUndefined();\n });\n });\n\n test('carries an untouched embeddingRef through a body-only patch', () => {\n const existing = makeRecord({ embeddingRef: 'vec-1' }, 'the sky is blue');\n expect(policy.applyUpdate(existing, { body: 'the sky is grey' })).toSucceedAndSatisfy((updated) => {\n expect(updated.body).toBe('the sky is grey');\n expect(updated.envelope.embeddingRef).toBe('vec-1');\n });\n });\n\n /**\n * Mirrors the `provenance merge contract (README-pinned)` block in\n * `writePolicy.test.ts`. The package README states that the provenance\n * guarantees hold for BOTH pinned-surface policies, so both must be pinned\n * here — otherwise the README claims more than the tests establish.\n */\n describe('provenance merge contract (README-pinned)', () => {\n function provenanceRecord(): IMemoryRecord<unknown> {\n return makeRecord({\n provenance: { source: 'agent', confidence: 0.9, note: 'stale' } as IProvenance\n });\n }\n\n test('an explicit null on a sub-key clears that key and preserves its siblings', () => {\n expect(policy.applyUpdate(provenanceRecord(), { provenance: { note: null } })).toSucceedAndSatisfy(\n (updated) => {\n expect(updated.envelope.provenance).toEqual({ source: 'agent', confidence: 0.9 });\n }\n );\n });\n\n test('a whole-block null is rejected loudly rather than silently accepted', () => {\n expect(policy.applyUpdate(provenanceRecord(), { provenance: null })).toFailWith(\n /may not delete required field\\(s\\): provenance/i\n );\n });\n });\n });\n});\n"]}
|