@remnic/core 9.3.689 → 9.3.691
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 +7 -6
- package/dist/access-boundary.js +19 -18
- package/dist/access-cli.js +111 -47
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +6 -5
- package/dist/access-http.js +25 -24
- package/dist/access-mcp.d.ts +13 -5
- package/dist/access-mcp.js +22 -21
- package/dist/access-operations.d.ts +13 -7
- package/dist/access-operations.js +23 -20
- package/dist/access-schema.js +3 -3
- package/dist/{access-service-DmCHJ4cH.d.ts → access-service-CKnFdxH-.d.ts} +63 -3
- package/dist/access-service.d.ts +6 -5
- package/dist/access-service.js +18 -17
- package/dist/access-surface-catalog.d.ts +6 -5
- package/dist/access-surface-catalog.js +2 -0
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +1 -1
- package/dist/adapters/index.js +4 -4
- package/dist/adapters/registry.js +2 -2
- package/dist/{auto-sync-NUQWSFQD.js → auto-sync-RWXT6P5M.js} +5 -5
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +5 -4
- package/dist/briefing.d.ts +2 -1
- package/dist/briefing.js +6 -5
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer.d.ts +2 -1
- package/dist/calibration.d.ts +1 -1
- package/dist/calibration.js +2 -2
- package/dist/capabilities.d.ts +1 -1
- package/dist/{catalog-COqWZlZ6.d.ts → catalog-BEWLjdOr.d.ts} +2 -2
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +9 -8
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/{chunk-GTDH3IUH.js → chunk-2D27ODNX.js} +2 -2
- package/dist/{chunk-3K37VPM3.js → chunk-3BRA3N5A.js} +2 -2
- package/dist/{chunk-4FE2K57M.js → chunk-3VVH6ZQW.js} +2 -2
- package/dist/{chunk-FIVDN2SM.js → chunk-4RGWCRIJ.js} +4 -4
- package/dist/{chunk-AGJH5ISO.js → chunk-5KBNNUXS.js} +2 -2
- package/dist/{chunk-OV4D5T7V.js → chunk-66HROLW5.js} +2 -2
- package/dist/{chunk-Z2M6YTAJ.js → chunk-7UVDIWLL.js} +34 -5
- package/dist/chunk-7UVDIWLL.js.map +1 -0
- package/dist/{chunk-QANVLERJ.js → chunk-ADUAF5EV.js} +2 -2
- package/dist/{chunk-LLONI6PY.js → chunk-AFWEUTMS.js} +2 -2
- package/dist/{chunk-W63OY3J7.js → chunk-D3DNGQNQ.js} +3 -3
- package/dist/{chunk-T422SYM6.js → chunk-DCWIQFNA.js} +5 -5
- package/dist/{chunk-NGFEWFNK.js → chunk-DQHZA7Y3.js} +1 -1
- package/dist/chunk-DQHZA7Y3.js.map +1 -0
- package/dist/{chunk-OBXTMFZQ.js → chunk-ECZPWSB5.js} +2 -2
- package/dist/{chunk-BFVPIKDY.js → chunk-GCOSQBQ2.js} +3 -3
- package/dist/{chunk-SAEZIIID.js → chunk-IPJD7WJH.js} +2 -2
- package/dist/{chunk-KQAFEZQX.js → chunk-IPLYGWQF.js} +5 -5
- package/dist/{chunk-MDYG7VI7.js → chunk-IREVVFTM.js} +10 -1
- package/dist/{chunk-MDYG7VI7.js.map → chunk-IREVVFTM.js.map} +1 -1
- package/dist/{chunk-RKNJBZ55.js → chunk-JBPKEARU.js} +4 -4
- package/dist/{chunk-RHXFYIHA.js → chunk-K7I24ZO2.js} +42 -27
- package/dist/chunk-K7I24ZO2.js.map +1 -0
- package/dist/{chunk-XU7363OX.js → chunk-KO6OL4I7.js} +617 -23
- package/dist/chunk-KO6OL4I7.js.map +1 -0
- package/dist/{chunk-UTYBJR7M.js → chunk-MCV2DD6F.js} +2 -2
- package/dist/{chunk-3FC6LW6T.js → chunk-MRFVMSTR.js} +2 -2
- package/dist/{chunk-WDXCNJSF.js → chunk-MXZWKOOR.js} +2 -2
- package/dist/{chunk-QSQW54U5.js → chunk-NCRDCTEJ.js} +33 -10
- package/dist/chunk-NCRDCTEJ.js.map +1 -0
- package/dist/{chunk-6O6A6YUO.js → chunk-NUZ3N445.js} +7 -7
- package/dist/{chunk-UHUZXWDX.js → chunk-OOO7ZKOD.js} +16 -5
- package/dist/chunk-OOO7ZKOD.js.map +1 -0
- package/dist/{chunk-GS55WYRL.js → chunk-QFG23CRE.js} +2 -2
- package/dist/{chunk-UDJLF3BO.js → chunk-QLRYXOAD.js} +2 -2
- package/dist/chunk-QNG35H27.js +2190 -0
- package/dist/chunk-QNG35H27.js.map +1 -0
- package/dist/{chunk-A4HH2EWA.js → chunk-QVG4LAQO.js} +2 -2
- package/dist/{chunk-4N3TFFPH.js → chunk-SAC5V6JT.js} +2 -2
- package/dist/chunk-SVOZFLIQ.js +16 -0
- package/dist/chunk-SVOZFLIQ.js.map +1 -0
- package/dist/{chunk-JZBFL7RI.js → chunk-TJ5IIQIR.js} +468 -2265
- package/dist/chunk-TJ5IIQIR.js.map +1 -0
- package/dist/{chunk-UXLZOVCN.js → chunk-TSGREOYY.js} +38 -6
- package/dist/chunk-TSGREOYY.js.map +1 -0
- package/dist/{chunk-B4XVLHJA.js → chunk-U2OBZSGG.js} +2 -2
- package/dist/{chunk-STOEE37X.js → chunk-UOCLRM74.js} +2 -2
- package/dist/{chunk-A7UZR6RA.js → chunk-UTUYAPLY.js} +14 -1
- package/dist/chunk-UTUYAPLY.js.map +1 -0
- package/dist/{chunk-JPETDXED.js → chunk-UUMYB3FR.js} +2 -2
- package/dist/{chunk-BLIWOONZ.js → chunk-VFVG4NS2.js} +33 -20
- package/dist/chunk-VFVG4NS2.js.map +1 -0
- package/dist/{chunk-OWFY6NGQ.js → chunk-VH2DHBHG.js} +2 -2
- package/dist/chunk-VH2DHBHG.js.map +1 -0
- package/dist/{chunk-WIHPNY65.js → chunk-W4ELOUNX.js} +2 -2
- package/dist/{chunk-VX6OBUDW.js → chunk-WIKNVFBS.js} +2 -2
- package/dist/{chunk-2SNKUSQC.js → chunk-X5J3JZR3.js} +4 -4
- package/dist/{chunk-PH3HOKYW.js → chunk-ZLXGFAML.js} +2 -2
- package/dist/{cli-D8nZ2MPH.d.ts → cli-CrSW_KRq.d.ts} +3 -3
- package/dist/cli.d.ts +7 -6
- package/dist/cli.js +40 -38
- package/dist/compounding/engine.d.ts +2 -1
- package/dist/compounding/engine.js +6 -5
- 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/config.js +1 -1
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +6 -5
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +6 -5
- package/dist/consolidation-provenance-check.d.ts +2 -1
- package/dist/consolidation-undo.d.ts +2 -1
- package/dist/contradiction/index.d.ts +2 -1
- package/dist/contradiction/index.js +4 -4
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/backend.js +2 -2
- 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/enrichment/index.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +2 -1
- package/dist/entity-retrieval.js +6 -5
- package/dist/entity-schema.d.ts +1 -1
- package/dist/event-time.d.ts +35 -0
- package/dist/event-time.js +325 -0
- package/dist/event-time.js.map +1 -0
- package/dist/explicit-capture.d.ts +5 -4
- 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-judge.js +3 -3
- package/dist/extraction.d.ts +1 -1
- package/dist/extraction.js +3 -3
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/fallback-llm.js +2 -2
- package/dist/identity-continuity.d.ts +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/index.d.ts +10 -9
- package/dist/index.js +78 -75
- package/dist/index.js.map +1 -1
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/engine.js +2 -2
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/index.js +2 -2
- 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/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +6 -5
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +6 -5
- package/dist/maintenance/rebuild-memory-projection.js +7 -6
- package/dist/mcp-memory-inspector-app.d.ts +6 -5
- 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 +2 -1
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +3 -2
- package/dist/namespaces/migrate.js +11 -10
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/search.js +4 -4
- package/dist/namespaces/storage.d.ts +3 -2
- package/dist/namespaces/storage.js +6 -5
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +2 -1
- package/dist/operator-toolkit.js +15 -13
- package/dist/{orchestrator-CA6ouzBn.d.ts → orchestrator-DvswGK76.d.ts} +147 -3
- package/dist/orchestrator.d.ts +5 -4
- package/dist/orchestrator.js +37 -35
- 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-explain-renderer.js +3 -3
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-planner-llm.js +2 -2
- 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-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +1 -1
- package/dist/recall-xray.js +2 -2
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/resume-bundles.js +2 -2
- 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/schemas.d.ts +10 -10
- package/dist/search/embed-helper.d.ts +1 -1
- 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-CWch5uM7.d.ts → semantic-consolidation-D5U0Mrdb.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +7 -6
- package/dist/semantic-rule-promotion.js +6 -5
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +6 -5
- 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 +6 -28
- package/dist/storage.js +8 -6
- package/dist/structured-attributes.d.ts +29 -0
- package/dist/structured-attributes.js +8 -0
- package/dist/structured-attributes.js.map +1 -0
- 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 +2 -1
- package/dist/temporal-supersession.js +2 -2
- package/dist/temporal-validity.d.ts +22 -2
- package/dist/temporal-validity.js +3 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +2 -1
- package/dist/tier-routing.d.ts +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transfer/autodetect.js +1 -1
- package/dist/transfer/backup.js +1 -1
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/{types-Dm5xxVrr.d.ts → types-2NoBoRBM.d.ts} +38 -0
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/verified-recall.js +6 -5
- package/package.json +2 -2
- package/src/access-boundary.ts +2 -1
- package/src/access-cli.test.ts +40 -0
- package/src/access-cli.ts +90 -2
- package/src/access-http.ts +35 -6
- package/src/access-mcp.ts +34 -0
- package/src/access-operations.ts +45 -0
- package/src/access-service.ts +60 -0
- package/src/access-surface-catalog.test.ts +1 -1
- package/src/access-surface-catalog.ts +2 -0
- package/src/bitemporal-frontmatter.test.ts +177 -0
- package/src/cli.ts +18 -0
- package/src/coding/architecture-card.test.ts +544 -0
- package/src/coding/architecture-card.ts +687 -0
- package/src/coding/architecture-surfaces.test.ts +579 -0
- package/src/coding/architecture-surfaces.ts +457 -0
- package/src/config.ts +13 -0
- package/src/event-time.test.ts +514 -0
- package/src/event-time.ts +548 -0
- package/src/maintenance/namespace-maintenance-fanout.test.ts +595 -0
- package/src/maintenance/namespace-maintenance-fanout.ts +318 -0
- package/src/maintenance/namespace-planner.ts +74 -16
- package/src/operator-toolkit.ts +25 -0
- package/src/orchestrator.ts +171 -1
- package/src/storage.ts +40 -20
- package/src/structured-attributes.ts +39 -0
- package/src/temporal-validity.ts +34 -0
- package/src/types.ts +38 -0
- package/dist/chunk-A7UZR6RA.js.map +0 -1
- package/dist/chunk-BLIWOONZ.js.map +0 -1
- package/dist/chunk-JZBFL7RI.js.map +0 -1
- package/dist/chunk-NGFEWFNK.js.map +0 -1
- package/dist/chunk-OWFY6NGQ.js.map +0 -1
- package/dist/chunk-QSQW54U5.js.map +0 -1
- package/dist/chunk-RHXFYIHA.js.map +0 -1
- package/dist/chunk-UHUZXWDX.js.map +0 -1
- package/dist/chunk-UXLZOVCN.js.map +0 -1
- package/dist/chunk-XU7363OX.js.map +0 -1
- package/dist/chunk-Z2M6YTAJ.js.map +0 -1
- /package/dist/{auto-sync-NUQWSFQD.js.map → auto-sync-RWXT6P5M.js.map} +0 -0
- /package/dist/{chunk-GTDH3IUH.js.map → chunk-2D27ODNX.js.map} +0 -0
- /package/dist/{chunk-3K37VPM3.js.map → chunk-3BRA3N5A.js.map} +0 -0
- /package/dist/{chunk-4FE2K57M.js.map → chunk-3VVH6ZQW.js.map} +0 -0
- /package/dist/{chunk-FIVDN2SM.js.map → chunk-4RGWCRIJ.js.map} +0 -0
- /package/dist/{chunk-AGJH5ISO.js.map → chunk-5KBNNUXS.js.map} +0 -0
- /package/dist/{chunk-OV4D5T7V.js.map → chunk-66HROLW5.js.map} +0 -0
- /package/dist/{chunk-QANVLERJ.js.map → chunk-ADUAF5EV.js.map} +0 -0
- /package/dist/{chunk-LLONI6PY.js.map → chunk-AFWEUTMS.js.map} +0 -0
- /package/dist/{chunk-W63OY3J7.js.map → chunk-D3DNGQNQ.js.map} +0 -0
- /package/dist/{chunk-T422SYM6.js.map → chunk-DCWIQFNA.js.map} +0 -0
- /package/dist/{chunk-OBXTMFZQ.js.map → chunk-ECZPWSB5.js.map} +0 -0
- /package/dist/{chunk-BFVPIKDY.js.map → chunk-GCOSQBQ2.js.map} +0 -0
- /package/dist/{chunk-SAEZIIID.js.map → chunk-IPJD7WJH.js.map} +0 -0
- /package/dist/{chunk-KQAFEZQX.js.map → chunk-IPLYGWQF.js.map} +0 -0
- /package/dist/{chunk-RKNJBZ55.js.map → chunk-JBPKEARU.js.map} +0 -0
- /package/dist/{chunk-UTYBJR7M.js.map → chunk-MCV2DD6F.js.map} +0 -0
- /package/dist/{chunk-3FC6LW6T.js.map → chunk-MRFVMSTR.js.map} +0 -0
- /package/dist/{chunk-WDXCNJSF.js.map → chunk-MXZWKOOR.js.map} +0 -0
- /package/dist/{chunk-6O6A6YUO.js.map → chunk-NUZ3N445.js.map} +0 -0
- /package/dist/{chunk-GS55WYRL.js.map → chunk-QFG23CRE.js.map} +0 -0
- /package/dist/{chunk-UDJLF3BO.js.map → chunk-QLRYXOAD.js.map} +0 -0
- /package/dist/{chunk-A4HH2EWA.js.map → chunk-QVG4LAQO.js.map} +0 -0
- /package/dist/{chunk-4N3TFFPH.js.map → chunk-SAC5V6JT.js.map} +0 -0
- /package/dist/{chunk-B4XVLHJA.js.map → chunk-U2OBZSGG.js.map} +0 -0
- /package/dist/{chunk-STOEE37X.js.map → chunk-UOCLRM74.js.map} +0 -0
- /package/dist/{chunk-JPETDXED.js.map → chunk-UUMYB3FR.js.map} +0 -0
- /package/dist/{chunk-WIHPNY65.js.map → chunk-W4ELOUNX.js.map} +0 -0
- /package/dist/{chunk-VX6OBUDW.js.map → chunk-WIKNVFBS.js.map} +0 -0
- /package/dist/{chunk-2SNKUSQC.js.map → chunk-X5J3JZR3.js.map} +0 -0
- /package/dist/{chunk-PH3HOKYW.js.map → chunk-ZLXGFAML.js.map} +0 -0
package/src/storage.ts
CHANGED
|
@@ -321,6 +321,22 @@ function serializeFrontmatter(fm: MemoryFrontmatter): string {
|
|
|
321
321
|
// memories round-trip unchanged; readers default `valid_at` to `created`.
|
|
322
322
|
if (fm.valid_at) lines.push(`validAt: ${fm.valid_at}`);
|
|
323
323
|
if (fm.invalid_at) lines.push(`invalidAt: ${fm.invalid_at}`);
|
|
324
|
+
// Issue #1578 — bi-temporal ingestion provenance. Validate on write so a
|
|
325
|
+
// corrupt `observedAt` (non-ISO / overflowed) cannot leak onto disk; reads
|
|
326
|
+
// are permissive, mirroring the `valid_at` precedent. `eventTimeSource` is
|
|
327
|
+
// a closed enum — reject anything outside it rather than persisting garbage.
|
|
328
|
+
if (fm.observedAt) {
|
|
329
|
+
const validated = normalizeMemoryWriteTimestamp("observedAt", fm.observedAt);
|
|
330
|
+
if (validated) lines.push(`observedAt: ${validated}`);
|
|
331
|
+
}
|
|
332
|
+
if (fm.eventTimeSource) {
|
|
333
|
+
if (fm.eventTimeSource !== "extracted" && fm.eventTimeSource !== "assumed") {
|
|
334
|
+
throw new Error(
|
|
335
|
+
`serializeFrontmatter: invalid eventTimeSource ${JSON.stringify(fm.eventTimeSource)} — expected "extracted" | "assumed"`,
|
|
336
|
+
);
|
|
337
|
+
}
|
|
338
|
+
lines.push(`eventTimeSource: ${fm.eventTimeSource}`);
|
|
339
|
+
}
|
|
324
340
|
if (fm.forgottenAt) lines.push(`forgottenAt: ${fm.forgottenAt}`);
|
|
325
341
|
if (fm.forgottenReason) lines.push(`forgottenReason: ${JSON.stringify(fm.forgottenReason)}`);
|
|
326
342
|
// Lifecycle policy fields
|
|
@@ -808,6 +824,12 @@ function parseFrontmatter(
|
|
|
808
824
|
// Issue #680 — explicit fact lifecycle round-trip.
|
|
809
825
|
valid_at: fm.validAt || undefined,
|
|
810
826
|
invalid_at: fm.invalidAt || undefined,
|
|
827
|
+
// Issue #1578 — bi-temporal ingestion provenance round-trip.
|
|
828
|
+
observedAt: fm.observedAt || undefined,
|
|
829
|
+
eventTimeSource:
|
|
830
|
+
fm.eventTimeSource === "extracted" || fm.eventTimeSource === "assumed"
|
|
831
|
+
? fm.eventTimeSource
|
|
832
|
+
: undefined,
|
|
811
833
|
forgottenAt: fm.forgottenAt || undefined,
|
|
812
834
|
forgottenReason: parseFrontmatterStringValue(fm.forgottenReason),
|
|
813
835
|
lifecycleState: (fm.lifecycleState as LifecycleState) || undefined,
|
|
@@ -1175,26 +1197,12 @@ export class ContentHashIndex {
|
|
|
1175
1197
|
* normalizeAttributePairs({ foo: "bar", BAZ: "qux" })
|
|
1176
1198
|
* // → "baz: qux; foo: bar"
|
|
1177
1199
|
*/
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
* library-supplied content.
|
|
1185
|
-
*/
|
|
1186
|
-
export function stripAttributesSuffix(content: string): string {
|
|
1187
|
-
const trimmed = content.trimEnd();
|
|
1188
|
-
if (!trimmed.endsWith("]")) return content.trim();
|
|
1189
|
-
const marker = "\n[Attributes: ";
|
|
1190
|
-
const markerIndex = trimmed.lastIndexOf(marker);
|
|
1191
|
-
if (markerIndex === -1) return content.trim();
|
|
1192
|
-
// The block must be the FINAL line and contain no "]" before the
|
|
1193
|
-
// closing bracket (mirrors the shape normalizeAttributePairs emits).
|
|
1194
|
-
const inner = trimmed.slice(markerIndex + marker.length, -1);
|
|
1195
|
-
if (inner.includes("]") || inner.includes("\n")) return content.trim();
|
|
1196
|
-
return trimmed.slice(0, markerIndex).trim();
|
|
1197
|
-
}
|
|
1200
|
+
// `stripAttributesSuffix` now lives in ./structured-attributes.ts (shared with
|
|
1201
|
+
// the coding surfaces + wearable service). Imported here so internal callers
|
|
1202
|
+
// (snapshotBeforeWrite, snapshotForProvenance) resolve, and re-exported to
|
|
1203
|
+
// keep the public storage API stable for existing callers (wearables, dist).
|
|
1204
|
+
import { stripAttributesSuffix } from "./structured-attributes.js";
|
|
1205
|
+
export { stripAttributesSuffix };
|
|
1198
1206
|
|
|
1199
1207
|
export function normalizeAttributePairs(pairs: Record<string, string>): string {
|
|
1200
1208
|
return Object.entries(pairs)
|
|
@@ -3347,6 +3355,12 @@ export class StorageManager {
|
|
|
3347
3355
|
memoryKind?: MemoryFrontmatter["memoryKind"];
|
|
3348
3356
|
expiresAt?: string;
|
|
3349
3357
|
validAt?: string;
|
|
3358
|
+
// Issue #1578 — bi-temporal ingestion provenance. `observedAt` is the
|
|
3359
|
+
// ingestion time (when Remnic learned the fact); `eventTimeSource`
|
|
3360
|
+
// records whether `validAt` was resolved from an extracted expression
|
|
3361
|
+
// or assumed from the ingestion anchor. Both validate on serialize.
|
|
3362
|
+
observedAt?: string;
|
|
3363
|
+
eventTimeSource?: "extracted" | "assumed";
|
|
3350
3364
|
structuredAttributes?: Record<string, string>;
|
|
3351
3365
|
/**
|
|
3352
3366
|
* When provided, this string is used as the source for the fact-content
|
|
@@ -3379,6 +3393,10 @@ export class StorageManager {
|
|
|
3379
3393
|
const conf = options.confidence ?? 0.8;
|
|
3380
3394
|
const tier = confidenceTier(conf);
|
|
3381
3395
|
const validAt = normalizeMemoryWriteTimestamp("validAt", options.validAt);
|
|
3396
|
+
const observedAt = normalizeMemoryWriteTimestamp(
|
|
3397
|
+
"observedAt",
|
|
3398
|
+
options.observedAt,
|
|
3399
|
+
);
|
|
3382
3400
|
|
|
3383
3401
|
// Auto-set TTL for speculative memories
|
|
3384
3402
|
let expiresAt: string | undefined;
|
|
@@ -3412,6 +3430,8 @@ export class StorageManager {
|
|
|
3412
3430
|
sourceTurnId: options.sourceTurnId,
|
|
3413
3431
|
memoryKind: options.memoryKind,
|
|
3414
3432
|
valid_at: validAt,
|
|
3433
|
+
observedAt,
|
|
3434
|
+
eventTimeSource: options.eventTimeSource,
|
|
3415
3435
|
structuredAttributes: options.structuredAttributes,
|
|
3416
3436
|
};
|
|
3417
3437
|
if (options.status !== undefined) {
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared helpers for the `\n[Attributes: …]` enrichment suffix that
|
|
3
|
+
* `writeMemory` appends to a stored body when `structuredAttributes` are
|
|
4
|
+
* present.
|
|
5
|
+
*
|
|
6
|
+
* Extracted here (out of `storage.ts`) so every reader — the storage
|
|
7
|
+
* manager, the wearable service, and the coding surfaces — strips the suffix
|
|
8
|
+
* with ONE definition. Previously `coding/architecture-surfaces.ts` carried a
|
|
9
|
+
* weaker local copy that only checked the trailing `]`, which could truncate
|
|
10
|
+
* card markdown that legitimately ends in a `[Attributes: …]` line (cursor
|
|
11
|
+
* review: duplicate attribute suffix stripper).
|
|
12
|
+
*
|
|
13
|
+
* String operations, not regex — CodeQL `js/polynomial-redos` flags
|
|
14
|
+
* suffix-anchored patterns over library-supplied content.
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Remove the `[Attributes: …]` suffix `writeMemory` appends to the stored
|
|
19
|
+
* body when structuredAttributes are present, yielding the raw fact/card text
|
|
20
|
+
* for content comparison or client display. Inverse companion of
|
|
21
|
+
* `normalizeAttributePairs` enrichment in `storage.ts`.
|
|
22
|
+
*
|
|
23
|
+
* Returns the stripped (trimmed) body when the marker opens the final
|
|
24
|
+
* non-empty line and its inner payload contains no premature `]` or newline
|
|
25
|
+
* (mirrors the exact shape `normalizeAttributePairs` emits). Otherwise
|
|
26
|
+
* returns the trimmed input unchanged — never truncates legitimate content.
|
|
27
|
+
*/
|
|
28
|
+
export function stripAttributesSuffix(content: string): string {
|
|
29
|
+
const trimmed = content.trimEnd();
|
|
30
|
+
if (!trimmed.endsWith("]")) return content.trim();
|
|
31
|
+
const marker = "\n[Attributes: ";
|
|
32
|
+
const markerIndex = trimmed.lastIndexOf(marker);
|
|
33
|
+
if (markerIndex === -1) return content.trim();
|
|
34
|
+
// The block must be the FINAL line and contain no "]" before the
|
|
35
|
+
// closing bracket (mirrors the shape normalizeAttributePairs emits).
|
|
36
|
+
const inner = trimmed.slice(markerIndex + marker.length, -1);
|
|
37
|
+
if (inner.includes("]") || inner.includes("\n")) return content.trim();
|
|
38
|
+
return trimmed.slice(0, markerIndex).trim();
|
|
39
|
+
}
|
package/src/temporal-validity.ts
CHANGED
|
@@ -101,6 +101,40 @@ export function isValidAsOf(
|
|
|
101
101
|
return invalidAtMs > asOfMs;
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
/**
|
|
105
|
+
* Bi-temporal injection filter (issue #1578).
|
|
106
|
+
*
|
|
107
|
+
* Returns `true` when the fact's event-time interval has already ended before
|
|
108
|
+
* `nowMs` — i.e. it is no longer *true in the world* and should leave the
|
|
109
|
+
* default injection candidate set (it remains findable by explicit search
|
|
110
|
+
* and `as_of` queries, mirroring the lifecycle-filter escape-hatch principle
|
|
111
|
+
* in AGENTS.md §16). Gated by `temporalBiTemporal`; the escape hatch
|
|
112
|
+
* `temporalExpiredInInjection` re-admits expired facts when a deployment
|
|
113
|
+
* prefers the older always-inject behavior.
|
|
114
|
+
*
|
|
115
|
+
* Semantics: a fact is expired-now when `invalid_at` is present and
|
|
116
|
+
* `invalid_at <= nowMs` (the exclusive upper bound has passed). Absent
|
|
117
|
+
* `invalid_at` means "still valid" — never expired. This is the
|
|
118
|
+
* status-orthogonal complement of `isValidAsOf` for the wall-clock instant:
|
|
119
|
+
* an `active` memory can be validity-expired, and a `superseded` one can
|
|
120
|
+
* still be validity-valid within its historical window (issue pitfall: the
|
|
121
|
+
* filter is status-orthogonal).
|
|
122
|
+
*/
|
|
123
|
+
export function isValidityExpiredNow(
|
|
124
|
+
fm: Pick<MemoryFrontmatter, "invalid_at">,
|
|
125
|
+
nowMs: number,
|
|
126
|
+
): boolean {
|
|
127
|
+
if (!Number.isFinite(nowMs)) return false;
|
|
128
|
+
const invalidAt = fm.invalid_at?.trim();
|
|
129
|
+
if (!invalidAt || invalidAt.length === 0) return false;
|
|
130
|
+
const invalidAtMs = Date.parse(invalidAt);
|
|
131
|
+
// Unparseable invalid_at — conservatively keep the fact (do not filter on
|
|
132
|
+
// corrupt data; the as_of path already handles malformed bounds).
|
|
133
|
+
if (!Number.isFinite(invalidAtMs)) return false;
|
|
134
|
+
// Half-open interval end has passed: [valid_at, invalid_at) ended.
|
|
135
|
+
return invalidAtMs <= nowMs;
|
|
136
|
+
}
|
|
137
|
+
|
|
104
138
|
/**
|
|
105
139
|
* Parse and validate an `as_of` value supplied at an input boundary
|
|
106
140
|
* (CLI flag, HTTP query param, MCP field). Returns parsed milliseconds
|
package/src/types.ts
CHANGED
|
@@ -788,6 +788,25 @@ export interface PluginConfig {
|
|
|
788
788
|
* filtered out.
|
|
789
789
|
*/
|
|
790
790
|
temporalSupersessionIncludeInRecall: boolean;
|
|
791
|
+
/**
|
|
792
|
+
* Bi-temporal validity master gate (issue #1578). When `false` (default),
|
|
793
|
+
* the recall validity-injection filter and `asOf` semantics behave
|
|
794
|
+
* byte-identically to pre-#1578.
|
|
795
|
+
*
|
|
796
|
+
* Turn on to exclude validity-expired facts from default injection
|
|
797
|
+
* candidates (they remain findable by explicit search and `as_of`
|
|
798
|
+
* queries). Storage round-trips `observedAt`/`eventTimeSource`; the
|
|
799
|
+
* extraction prompt → `resolveEventTime` write-time wiring lands in a
|
|
800
|
+
* follow-on PR, so new extractions are not yet event-time-resolved.
|
|
801
|
+
*/
|
|
802
|
+
temporalBiTemporal: boolean;
|
|
803
|
+
/**
|
|
804
|
+
* Escape hatch for the bi-temporal injection filter (issue #1578). When
|
|
805
|
+
* `true`, facts whose `[valid_at, invalid_at)` interval ended before now
|
|
806
|
+
* are kept in injection candidates even with `temporalBiTemporal` on — some
|
|
807
|
+
* deployments prefer the older (always-inject) behavior. Default `false`.
|
|
808
|
+
*/
|
|
809
|
+
temporalExpiredInInjection: boolean;
|
|
791
810
|
// Direct-answer retrieval tier (issue #518)
|
|
792
811
|
/**
|
|
793
812
|
* When true, recall checks whether a single validated memory in a
|
|
@@ -2423,6 +2442,25 @@ export interface MemoryFrontmatter {
|
|
|
2423
2442
|
* point in time.
|
|
2424
2443
|
*/
|
|
2425
2444
|
invalid_at?: string;
|
|
2445
|
+
/**
|
|
2446
|
+
* Ingestion time (issue #1578) — when Remnic *learned* this fact.
|
|
2447
|
+
* Distinct from `created` (file creation) and `valid_at` (event-time
|
|
2448
|
+
* start). Aligns with the source turn timestamp (#1575
|
|
2449
|
+
* `sources[].observedAt`). When `eventTimeSource === "assumed"`,
|
|
2450
|
+
* `valid_at` is copied from this value.
|
|
2451
|
+
*/
|
|
2452
|
+
observedAt?: string;
|
|
2453
|
+
/**
|
|
2454
|
+
* Provenance of the event-time interval (issue #1578).
|
|
2455
|
+
* - `"extracted"` — a per-fact `eventTime` expression was resolved
|
|
2456
|
+
* against the source turn's timestamp and produced `valid_at` /
|
|
2457
|
+
* `invalid_at`.
|
|
2458
|
+
* - `"assumed"` — no resolvable expression; `valid_at` was copied from
|
|
2459
|
+
* `observedAt` (the ingestion anchor).
|
|
2460
|
+
* Absent on memories written before #1578; readers treat absent as
|
|
2461
|
+
* `"assumed"` for display purposes.
|
|
2462
|
+
*/
|
|
2463
|
+
eventTimeSource?: "extracted" | "assumed";
|
|
2426
2464
|
/**
|
|
2427
2465
|
* Timestamp when the operator explicitly forgot this memory
|
|
2428
2466
|
* (issue #686 PR 4/6). Set by `remnic forget <id>`. Memories with
|