@snoai/memory 0.0.0-stage → 1.0.1
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/LICENSE +176 -0
- package/README.md +33 -2
- package/config/b-profile-section-registry.json +118 -0
- package/config/llm/compiled/2026-05-19T230932Z/manifest.json +25 -0
- package/config/llm/compiled/2026-05-19T230932Z/registry-root.json +67 -0
- package/config/llm/compiled/2026-05-19T230932Z/resolved/mem_claw/openai_gpt_5_nano.json +5 -0
- package/config/llm/compiled/2026-05-19T230932Z/resolved/mem_claw/openrouter_auto.json +5 -0
- package/config/llm/compiled/2026-05-19T230932Z/resolved/mem_claw/sno_ai_extract.json +5 -0
- package/config/llm/compiled/2026-05-19T230932Z/source/mem_claw/openai_gpt_5_nano.mda +24 -0
- package/config/llm/compiled/2026-05-19T230932Z/source/mem_claw/openrouter_auto.mda +24 -0
- package/config/llm/compiled/2026-05-19T230932Z/source/mem_claw/sno_ai_extract.mda +24 -0
- package/config/llm/compiled/2026-07-21T001311Z/manifest.json +43 -0
- package/config/llm/compiled/2026-07-21T001311Z/registry-root.json +97 -0
- package/config/llm/compiled/2026-07-21T001311Z/resolved/mem_claw/openai_gpt_5_nano.json +5 -0
- package/config/llm/compiled/2026-07-21T001311Z/resolved/mem_claw/openrouter_auto.json +5 -0
- package/config/llm/compiled/2026-07-21T001311Z/resolved/mem_claw/sno_ai_extract.json +5 -0
- package/config/llm/compiled/2026-07-21T001311Z/resolved/mem_claw/sno_conflict_verdict.json +10 -0
- package/config/llm/compiled/2026-07-21T001311Z/resolved/mem_claw/sno_extract_chat.json +10 -0
- package/config/llm/compiled/2026-07-21T001311Z/resolved/mem_claw/sno_extract_profile.json +10 -0
- package/config/llm/compiled/2026-07-21T001311Z/source/mem_claw/openai_gpt_5_nano.mda +24 -0
- package/config/llm/compiled/2026-07-21T001311Z/source/mem_claw/openrouter_auto.mda +24 -0
- package/config/llm/compiled/2026-07-21T001311Z/source/mem_claw/sno_ai_extract.mda +24 -0
- package/config/llm/compiled/2026-07-21T001311Z/source/mem_claw/sno_conflict_verdict.mda +27 -0
- package/config/llm/compiled/2026-07-21T001311Z/source/mem_claw/sno_extract_chat.mda +27 -0
- package/config/llm/compiled/2026-07-21T001311Z/source/mem_claw/sno_extract_profile.mda +27 -0
- package/config/llm/compiled/2026-08-29T060335Z/manifest.json +43 -0
- package/config/llm/compiled/2026-08-29T060335Z/registry-root.json +97 -0
- package/config/llm/compiled/2026-08-29T060335Z/resolved/mem_claw/openai_gpt_5_nano.json +5 -0
- package/config/llm/compiled/2026-08-29T060335Z/resolved/mem_claw/openrouter_auto.json +5 -0
- package/config/llm/compiled/2026-08-29T060335Z/resolved/mem_claw/sno_ai_extract.json +5 -0
- package/config/llm/compiled/2026-08-29T060335Z/resolved/mem_claw/sno_conflict_verdict.json +10 -0
- package/config/llm/compiled/2026-08-29T060335Z/resolved/mem_claw/sno_extract_chat.json +10 -0
- package/config/llm/compiled/2026-08-29T060335Z/resolved/mem_claw/sno_extract_profile.json +10 -0
- package/config/llm/compiled/2026-08-29T060335Z/source/mem_claw/openai_gpt_5_nano.mda +24 -0
- package/config/llm/compiled/2026-08-29T060335Z/source/mem_claw/openrouter_auto.mda +24 -0
- package/config/llm/compiled/2026-08-29T060335Z/source/mem_claw/sno_ai_extract.mda +24 -0
- package/config/llm/compiled/2026-08-29T060335Z/source/mem_claw/sno_conflict_verdict.mda +27 -0
- package/config/llm/compiled/2026-08-29T060335Z/source/mem_claw/sno_extract_chat.mda +27 -0
- package/config/llm/compiled/2026-08-29T060335Z/source/mem_claw/sno_extract_profile.mda +27 -0
- package/config/llm/compiled/2026-09-04T004828Z/manifest.json +43 -0
- package/config/llm/compiled/2026-09-04T004828Z/registry-root.json +97 -0
- package/config/llm/compiled/2026-09-04T004828Z/resolved/mem_claw/openai_gpt_5_nano.json +5 -0
- package/config/llm/compiled/2026-09-04T004828Z/resolved/mem_claw/openrouter_auto.json +5 -0
- package/config/llm/compiled/2026-09-04T004828Z/resolved/mem_claw/sno_ai_extract.json +5 -0
- package/config/llm/compiled/2026-09-04T004828Z/resolved/mem_claw/sno_conflict_verdict.json +10 -0
- package/config/llm/compiled/2026-09-04T004828Z/resolved/mem_claw/sno_extract_chat.json +10 -0
- package/config/llm/compiled/2026-09-04T004828Z/resolved/mem_claw/sno_extract_profile.json +10 -0
- package/config/llm/compiled/2026-09-04T004828Z/source/mem_claw/openai_gpt_5_nano.mda +24 -0
- package/config/llm/compiled/2026-09-04T004828Z/source/mem_claw/openrouter_auto.mda +24 -0
- package/config/llm/compiled/2026-09-04T004828Z/source/mem_claw/sno_ai_extract.mda +24 -0
- package/config/llm/compiled/2026-09-04T004828Z/source/mem_claw/sno_conflict_verdict.mda +27 -0
- package/config/llm/compiled/2026-09-04T004828Z/source/mem_claw/sno_extract_chat.mda +27 -0
- package/config/llm/compiled/2026-09-04T004828Z/source/mem_claw/sno_extract_profile.mda +27 -0
- package/config/llm/current.json +4 -0
- package/config/llm/source/mem_claw/openai_gpt_5_nano.mda +24 -0
- package/config/llm/source/mem_claw/openrouter_auto.mda +24 -0
- package/config/llm/source/mem_claw/sno_ai_extract.mda +24 -0
- package/config/llm/source/mem_claw/sno_conflict_verdict.mda +27 -0
- package/config/llm/source/mem_claw/sno_extract_chat.mda +27 -0
- package/config/llm/source/mem_claw/sno_extract_profile.mda +27 -0
- package/config/llm.trust.json +37 -0
- package/dist/_types-CUKHSRkS.d.ts +103 -0
- package/dist/access-tracker-BbEvEocb.d.ts +110 -0
- package/dist/adapter-B7Jox9-6.d.ts +69 -0
- package/dist/adapter-XaRHZWZ2.js +333 -0
- package/dist/agent-llm-port-5oXgBpzJ.d.ts +53 -0
- package/dist/all-resources-BQK2ugjB.js +6379 -0
- package/dist/all-resources-Dij6l5h0.d.ts +18 -0
- package/dist/ambient-learning-text-normalizer-CxjATmMp.js +170 -0
- package/dist/ambient-learning-text-normalizer-_fH3LeuK.d.ts +10 -0
- package/dist/atomic-extraction-reply-BJ9XV_9s.js +863 -0
- package/dist/atomic-extraction-skill-CcXmuCqL.js +56 -0
- package/dist/atomic-memory-extraction-C5rmogoY.js +3605 -0
- package/dist/atomic-memory-extraction-d9EG-4ti.d.ts +327 -0
- package/dist/b-profile-section-dictionary-provider-BHkoNqgk.js +1812 -0
- package/dist/b-profile-section-dictionary-provider-BxbksLj3.d.ts +62 -0
- package/dist/best-effort-BPZSzKk0.d.ts +9 -0
- package/dist/calendar-instruction-CzqZbAPG.js +194 -0
- package/dist/capture-policy-detector-CxbHPkMX.d.ts +53 -0
- package/dist/capture-policy-detector-DaMfy9CZ.js +357 -0
- package/dist/classifier-DnbbtwTS.d.ts +272 -0
- package/dist/client.d.ts +34 -0
- package/dist/client.js +306 -0
- package/dist/coding-skin.d.ts +51 -0
- package/dist/coding-skin.js +55 -0
- package/dist/config-CL90qYva.js +2576 -0
- package/dist/connection-3IVXpuPE.d.ts +391 -0
- package/dist/connection-C9YD5sgm.js +297 -0
- package/dist/daily-log-generator-CH_KuWHs.js +469 -0
- package/dist/daily-log-generator-CsQPHl4A.d.ts +73 -0
- package/dist/daily-spend-estimator-DiwzBlo1.d.ts +8 -0
- package/dist/data-bootstrap-Bl3lthzE.d.ts +30 -0
- package/dist/data-bootstrap-P8sie9WA.js +172 -0
- package/dist/data-paths-C7sNdqvP.d.ts +22 -0
- package/dist/derived-suppression-cache-CI0durYx.d.ts +36 -0
- package/dist/diagnostic-encoder.d.ts +6 -0
- package/dist/diagnostic-encoder.js +29 -0
- package/dist/embedding-provider-client-Q_hJonK9.js +294 -0
- package/dist/embedding-provider-client-vynZMuit.d.ts +94 -0
- package/dist/entry-metadata-parser-BIVSMCIk.js +20 -0
- package/dist/error-D-wb-rZw.js +23 -0
- package/dist/error-signals-D8_3vYu4.d.ts +28 -0
- package/dist/error-signals-lMH2uAdV.js +134 -0
- package/dist/errors-CeVRxf9V.d.ts +49 -0
- package/dist/extraction-text-sanitizer-B_AhIecT.d.ts +32 -0
- package/dist/i18n-text-DbD6Qify.d.ts +13 -0
- package/dist/index-0aqS8pVF.d.ts +351 -0
- package/dist/index-BO4RU_mc.d.ts +650 -0
- package/dist/index-DL8AVj0Z.d.ts +571 -0
- package/dist/index.d.ts +65 -0
- package/dist/index.js +1201 -0
- package/dist/intent-analyzer-B5XVrWwe.d.ts +28 -0
- package/dist/internal/config/index.d.ts +2 -0
- package/dist/internal/config/index.js +581 -0
- package/dist/internal/config/plugin-config-schema.d.ts +2 -0
- package/dist/internal/config/plugin-config-schema.js +2 -0
- package/dist/internal/config/product-mode.d.ts +2 -0
- package/dist/internal/config/product-mode.js +36 -0
- package/dist/internal/config/settings.d.ts +2 -0
- package/dist/internal/config/settings.js +265 -0
- package/dist/internal/config/skill-categories.d.ts +4 -0
- package/dist/internal/config/skill-categories.js +68 -0
- package/dist/internal/config/skin-defaults.d.ts +6 -0
- package/dist/internal/config/skin-defaults.js +6 -0
- package/dist/internal/contract/discovery.d.ts +10 -0
- package/dist/internal/contract/discovery.js +53 -0
- package/dist/internal/contract/profile.d.ts +2 -0
- package/dist/internal/contract/profile.js +44 -0
- package/dist/internal/contract/routes.d.ts +2 -0
- package/dist/internal/contract/routes.js +62 -0
- package/dist/internal/engine/bindings/memory-cli-shared.d.ts +47 -0
- package/dist/internal/engine/bindings/memory-cli-shared.js +84 -0
- package/dist/internal/engine/bindings/memory-forget-tool.d.ts +5 -0
- package/dist/internal/engine/bindings/memory-forget-tool.js +66 -0
- package/dist/internal/engine/bindings/memory-list-tool.d.ts +5 -0
- package/dist/internal/engine/bindings/memory-list-tool.js +57 -0
- package/dist/internal/engine/bindings/memory-recall-tool.d.ts +10 -0
- package/dist/internal/engine/bindings/memory-recall-tool.js +283 -0
- package/dist/internal/engine/bindings/memory-reflection-resolve-tool.d.ts +5 -0
- package/dist/internal/engine/bindings/memory-reflection-resolve-tool.js +150 -0
- package/dist/internal/engine/bindings/memory-stats-tool.d.ts +5 -0
- package/dist/internal/engine/bindings/memory-stats-tool.js +43 -0
- package/dist/internal/engine/bindings/memory-store-tool.d.ts +5 -0
- package/dist/internal/engine/bindings/memory-store-tool.js +165 -0
- package/dist/internal/engine/bindings/memory-tool-access.d.ts +16 -0
- package/dist/internal/engine/bindings/memory-tool-access.js +46 -0
- package/dist/internal/engine/bindings/memory-tool-formatting.d.ts +62 -0
- package/dist/internal/engine/bindings/memory-tool-formatting.js +106 -0
- package/dist/internal/engine/bindings/memory-tool-results.d.ts +8 -0
- package/dist/internal/engine/bindings/memory-tool-results.js +41 -0
- package/dist/internal/engine/bindings/memory-tool-schemas.d.ts +109 -0
- package/dist/internal/engine/bindings/memory-tool-schemas.js +75 -0
- package/dist/internal/engine/bindings/memory-update-tool.d.ts +5 -0
- package/dist/internal/engine/bindings/memory-update-tool.js +127 -0
- package/dist/internal/engine/bindings/sno-station-mem-ambient-learning-hook.d.ts +14 -0
- package/dist/internal/engine/bindings/sno-station-mem-ambient-learning-hook.js +248 -0
- package/dist/internal/engine/bindings/sno-station-mem-auto-recall-hook.d.ts +12 -0
- package/dist/internal/engine/bindings/sno-station-mem-auto-recall-hook.js +324 -0
- package/dist/internal/engine/bindings/sno-station-mem-hook-types.d.ts +56 -0
- package/dist/internal/engine/bindings/sno-station-mem-hook-types.js +1 -0
- package/dist/internal/engine/bindings/sno-station-mem-insight-distill-factory.d.ts +14 -0
- package/dist/internal/engine/bindings/sno-station-mem-insight-distill-factory.js +119 -0
- package/dist/internal/engine/bindings/sno-station-mem-message-transcript.d.ts +52 -0
- package/dist/internal/engine/bindings/sno-station-mem-message-transcript.js +145 -0
- package/dist/internal/engine/bindings/sno-station-mem-reset-hook.d.ts +10 -0
- package/dist/internal/engine/bindings/sno-station-mem-reset-hook.js +9 -0
- package/dist/internal/engine/bindings/sno-station-mem-runtime-mode.d.ts +36 -0
- package/dist/internal/engine/bindings/sno-station-mem-runtime-mode.js +104 -0
- package/dist/internal/engine/bindings/sno-station-mem-session-state.d.ts +10 -0
- package/dist/internal/engine/bindings/sno-station-mem-session-state.js +27 -0
- package/dist/internal/engine/eval/trace.d.ts +2 -0
- package/dist/internal/engine/eval/trace.js +151 -0
- package/dist/internal/engine/extraction/ambient-learning-text-normalizer.d.ts +2 -0
- package/dist/internal/engine/extraction/ambient-learning-text-normalizer.js +2 -0
- package/dist/internal/engine/extraction/atomic-memory-extraction.d.ts +2 -0
- package/dist/internal/engine/extraction/atomic-memory-extraction.js +2 -0
- package/dist/internal/engine/extraction/b-profile-section-dictionary-provider.d.ts +2 -0
- package/dist/internal/engine/extraction/b-profile-section-dictionary-provider.js +2 -0
- package/dist/internal/engine/extraction/b-profile-section-rekey.d.ts +49 -0
- package/dist/internal/engine/extraction/b-profile-section-rekey.js +730 -0
- package/dist/internal/engine/extraction/capture-policy-detector.d.ts +2 -0
- package/dist/internal/engine/extraction/capture-policy-detector.js +2 -0
- package/dist/internal/engine/extraction/embedding-provider-client.d.ts +2 -0
- package/dist/internal/engine/extraction/embedding-provider-client.js +2 -0
- package/dist/internal/engine/extraction/extraction-text-sanitizer.d.ts +2 -0
- package/dist/internal/engine/extraction/extraction-text-sanitizer.js +114 -0
- package/dist/internal/engine/extraction/memory-metadata-codec.d.ts +3 -0
- package/dist/internal/engine/extraction/memory-metadata-codec.js +2 -0
- package/dist/internal/engine/extraction/memory-temporality-classifier.d.ts +2 -0
- package/dist/internal/engine/extraction/memory-temporality-classifier.js +2 -0
- package/dist/internal/engine/i18n/all-resources.d.ts +2 -0
- package/dist/internal/engine/i18n/all-resources.js +2 -0
- package/dist/internal/engine/i18n/locales.d.ts +2 -0
- package/dist/internal/engine/i18n/locales.js +19 -0
- package/dist/internal/engine/i18n/res/_types.d.ts +2 -0
- package/dist/internal/engine/i18n/res/_types.js +11 -0
- package/dist/internal/engine/observability/adapter.d.ts +2 -0
- package/dist/internal/engine/observability/adapter.js +2 -0
- package/dist/internal/engine/observability/best-effort.d.ts +2 -0
- package/dist/internal/engine/observability/best-effort.js +41 -0
- package/dist/internal/engine/observability/early-diagnostics.js +2 -0
- package/dist/internal/engine/observability/memory-snapshot.d.ts +2 -0
- package/dist/internal/engine/observability/memory-snapshot.js +44 -0
- package/dist/internal/engine/observability/observable-embedder.d.ts +2 -0
- package/dist/internal/engine/observability/observable-embedder.js +43 -0
- package/dist/internal/engine/observability/observable-llm-client.d.ts +2 -0
- package/dist/internal/engine/observability/observable-llm-client.js +98 -0
- package/dist/internal/engine/observability/observable-memory-store.d.ts +2 -0
- package/dist/internal/engine/observability/observable-memory-store.js +701 -0
- package/dist/internal/engine/observability/observable-retriever.d.ts +2 -0
- package/dist/internal/engine/observability/observable-retriever.js +95 -0
- package/dist/internal/engine/observability/runtime-diagnostics.d.ts +13 -0
- package/dist/internal/engine/observability/runtime-diagnostics.js +96 -0
- package/dist/internal/engine/observability/session-registry.d.ts +2 -0
- package/dist/internal/engine/observability/session-registry.js +58 -0
- package/dist/internal/engine/observability/version-metadata.d.ts +7 -0
- package/dist/internal/engine/observability/version-metadata.js +59 -0
- package/dist/internal/engine/operations/daily-spend-estimator.d.ts +2 -0
- package/dist/internal/engine/operations/daily-spend-estimator.js +97 -0
- package/dist/internal/engine/operations/learning-file-maintenance.d.ts +2 -0
- package/dist/internal/engine/operations/learning-file-maintenance.js +255 -0
- package/dist/internal/engine/operations/memory-tier-promoter.d.ts +2 -0
- package/dist/internal/engine/operations/memory-tier-promoter.js +95 -0
- package/dist/internal/engine/operations/runtime-audit-log.d.ts +3 -0
- package/dist/internal/engine/operations/runtime-audit-log.js +3 -0
- package/dist/internal/engine/provider/canonical-memory-corpus.d.ts +38 -0
- package/dist/internal/engine/provider/canonical-memory-corpus.js +253 -0
- package/dist/internal/engine/provider/provider-registration.d.ts +39 -0
- package/dist/internal/engine/provider/provider-registration.js +2 -0
- package/dist/internal/engine/provider/provider-row-renderer.d.ts +7 -0
- package/dist/internal/engine/provider/provider-row-renderer.js +53 -0
- package/dist/internal/engine/provider/provider-types.d.ts +2 -0
- package/dist/internal/engine/provider/provider-types.js +1 -0
- package/dist/internal/engine/reflection/daily-log-generator.d.ts +2 -0
- package/dist/internal/engine/reflection/daily-log-generator.js +2 -0
- package/dist/internal/engine/reflection/reflection-command-hooks.d.ts +2 -0
- package/dist/internal/engine/reflection/reflection-command-hooks.js +2 -0
- package/dist/internal/engine/reflection/reflection-deps.d.ts +2 -0
- package/dist/internal/engine/reflection/reflection-deps.js +1 -0
- package/dist/internal/engine/reflection/reflection-embedded-generator.d.ts +2 -0
- package/dist/internal/engine/reflection/reflection-embedded-generator.js +2 -0
- package/dist/internal/engine/reflection/reflection-injection-hooks.d.ts +2 -0
- package/dist/internal/engine/reflection/reflection-injection-hooks.js +219 -0
- package/dist/internal/engine/reflection/reflection-lifecycle-hooks.d.ts +2 -0
- package/dist/internal/engine/reflection/reflection-lifecycle-hooks.js +63 -0
- package/dist/internal/engine/reflection/strategy-hook-runner.d.ts +4 -0
- package/dist/internal/engine/reflection/strategy-hook-runner.js +3 -0
- package/dist/internal/engine/rem/classifier.d.ts +2 -0
- package/dist/internal/engine/rem/classifier.js +180 -0
- package/dist/internal/engine/rem/index.d.ts +4 -0
- package/dist/internal/engine/rem/index.js +2551 -0
- package/dist/internal/engine/rem/types.d.ts +2 -0
- package/dist/internal/engine/rem/types.js +40 -0
- package/dist/internal/engine/retrieval/access-tracker.d.ts +2 -0
- package/dist/internal/engine/retrieval/access-tracker.js +314 -0
- package/dist/internal/engine/retrieval/intent-analyzer.d.ts +2 -0
- package/dist/internal/engine/retrieval/intent-analyzer.js +27 -0
- package/dist/internal/engine/retrieval/retrieval-gate.d.ts +2 -0
- package/dist/internal/engine/retrieval/retrieval-gate.js +47 -0
- package/dist/internal/engine/retrieval/retriever.d.ts +2 -0
- package/dist/internal/engine/retrieval/retriever.js +2 -0
- package/dist/internal/engine/security/memory-scope-policy.d.ts +2 -0
- package/dist/internal/engine/security/memory-scope-policy.js +2 -0
- package/dist/internal/engine/security/redact.d.ts +2 -0
- package/dist/internal/engine/security/redact.js +34 -0
- package/dist/internal/engine/security/scopes.d.ts +3 -0
- package/dist/internal/engine/security/scopes.js +3 -0
- package/dist/internal/engine/shared/errors.d.ts +2 -0
- package/dist/internal/engine/shared/errors.js +66 -0
- package/dist/internal/engine/shared/i18n-text.d.ts +2 -0
- package/dist/internal/engine/shared/i18n-text.js +58 -0
- package/dist/internal/engine/shared/iso-date-time.d.ts +16 -0
- package/dist/internal/engine/shared/iso-date-time.js +40 -0
- package/dist/internal/engine/shared/lru.d.ts +2 -0
- package/dist/internal/engine/shared/lru.js +30 -0
- package/dist/internal/engine/shared/memory-kind-policy.d.ts +2 -0
- package/dist/internal/engine/shared/memory-kind-policy.js +64 -0
- package/dist/internal/engine/shared/paths.d.ts +3 -0
- package/dist/internal/engine/shared/paths.js +2 -0
- package/dist/internal/engine/shared/types.d.ts +3 -0
- package/dist/internal/engine/shared/types.js +25 -0
- package/dist/internal/engine/shared/utils.d.ts +2 -0
- package/dist/internal/engine/shared/utils.js +175 -0
- package/dist/internal/engine/telemetry/memory-telemetry-api.d.ts +134 -0
- package/dist/internal/engine/telemetry/memory-telemetry-api.js +730 -0
- package/dist/internal/engine/telemetry/memory-telemetry-observability.d.ts +24 -0
- package/dist/internal/engine/telemetry/memory-telemetry-observability.js +133 -0
- package/dist/internal/engine/telemetry/memory-telemetry-outbox.d.ts +2 -0
- package/dist/internal/engine/telemetry/memory-telemetry-outbox.js +443 -0
- package/dist/internal/engine/telemetry/memory-telemetry-types.d.ts +2 -0
- package/dist/internal/engine/telemetry/memory-telemetry-types.js +21 -0
- package/dist/internal/engine/telemetry/observe-ledger.d.ts +30 -0
- package/dist/internal/engine/telemetry/observe-ledger.js +111 -0
- package/dist/internal/model/agent-llm-port.d.ts +2 -0
- package/dist/internal/model/agent-llm-port.js +1 -0
- package/dist/internal/model/llm-client.d.ts +3 -0
- package/dist/internal/model/llm-client.js +3 -0
- package/dist/internal/model/llm-failure.d.ts +26 -0
- package/dist/internal/model/llm-failure.js +63 -0
- package/dist/internal/model/llm-mode-routing.d.ts +22 -0
- package/dist/internal/model/llm-mode-routing.js +37 -0
- package/dist/internal/store/atomic-memory-cutover-sql.d.ts +13 -0
- package/dist/internal/store/atomic-memory-cutover-sql.js +237 -0
- package/dist/internal/store/connection.d.ts +2 -0
- package/dist/internal/store/connection.js +2 -0
- package/dist/internal/store/data-bootstrap.d.ts +2 -0
- package/dist/internal/store/data-bootstrap.js +2 -0
- package/dist/internal/store/data-paths.d.ts +2 -0
- package/dist/internal/store/data-paths.js +65 -0
- package/dist/internal/store/maintenance.d.ts +75 -0
- package/dist/internal/store/maintenance.js +1401 -0
- package/dist/internal/store/memory-kinds-cutover-migrator.d.ts +28 -0
- package/dist/internal/store/memory-kinds-cutover-migrator.js +415 -0
- package/dist/internal/store/migrations.d.ts +27 -0
- package/dist/internal/store/migrations.js +201 -0
- package/dist/internal/store/sqlite-runtime.d.ts +2 -0
- package/dist/internal/store/sqlite-runtime.js +109 -0
- package/dist/internal/store/store.d.ts +3 -0
- package/dist/internal/store/store.js +2 -0
- package/dist/learning-file-maintenance-9b-Ut6Kv.d.ts +30 -0
- package/dist/llm-client-BSYUAcUb.js +1374 -0
- package/dist/llm-client-DOTSGzhe.d.ts +51 -0
- package/dist/locales-JxGmkG6t.d.ts +7 -0
- package/dist/log-site-catalog.generated-BMKWj-Nx.js +2321 -0
- package/dist/log-site-catalog.json +1 -0
- package/dist/lru-DyoaTyIs.d.ts +14 -0
- package/dist/memdump.d.ts +52 -0
- package/dist/memdump.js +163 -0
- package/dist/memory-entry-projector-DHo8jH10.js +1015 -0
- package/dist/memory-kind-policy-BiuRjSJc.d.ts +23 -0
- package/dist/memory-metadata-codec-DL1sbJiN.js +577 -0
- package/dist/memory-metadata-codec-DUvsYe_X.d.ts +68 -0
- package/dist/memory-runtime-DqUS4cWi.js +19459 -0
- package/dist/memory-scope-policy-1gg5QlWZ.d.ts +67 -0
- package/dist/memory-scope-policy-DICSCURA.js +283 -0
- package/dist/memory-snapshot-CqY1BUUA.d.ts +16 -0
- package/dist/memory-source-order-YMRoeDLd.js +134 -0
- package/dist/memory-store-base-CQ_bHlYA.d.ts +1094 -0
- package/dist/memory-store-shared-DqpWJXZZ.js +158 -0
- package/dist/memory-store-write-validation-B_hDG2zf.js +243 -0
- package/dist/memory-telemetry-incidents-BWA9kcZx.js +8 -0
- package/dist/memory-telemetry-metadata-CA7W8tK6.js +77 -0
- package/dist/memory-telemetry-outbox-ddTdImt7.d.ts +74 -0
- package/dist/memory-telemetry-receipts-MAJecvXQ.d.ts +34 -0
- package/dist/memory-telemetry-receipts-YsxbwOAf.js +91 -0
- package/dist/memory-telemetry-types-CufVmrCs.d.ts +14 -0
- package/dist/memory-temporality-classifier-BUjXG5o7.js +184 -0
- package/dist/memory-temporality-classifier-Brht5jyK.d.ts +43 -0
- package/dist/memory-tier-promoter-CqGxCkue.d.ts +43 -0
- package/dist/memory-tool-dependencies-CatGzI9R.d.ts +14 -0
- package/dist/memory-tool-dependencies-DjUoelnm.js +19 -0
- package/dist/model-call-table-CspopkBg.js +563 -0
- package/dist/model-reply-text-CKopStP2.js +334 -0
- package/dist/observable-embedder-CNNe9gkg.d.ts +17 -0
- package/dist/observable-llm-client-CRuKlefQ.d.ts +21 -0
- package/dist/observable-memory-store-CnGDpOY5.d.ts +73 -0
- package/dist/observable-retriever-Cooc62Qw.d.ts +23 -0
- package/dist/operation-cancellation-CTKWwNHk.js +81 -0
- package/dist/paths-qVF-5uBq.d.ts +1 -0
- package/dist/plugin-config-schema-C0UUbOmG.d.ts +413 -0
- package/dist/plugin-config-schema-YJLyIIcJ.js +361 -0
- package/dist/profile-TWPJ_myr.d.ts +13 -0
- package/dist/profile-section-writer-BhGKPBjw.js +2149 -0
- package/dist/provider-registration-CF1tg8Xy.js +721 -0
- package/dist/provider-runtime-types-DFhtdA6d.d.ts +134 -0
- package/dist/provider-types-CZGm6v88.d.ts +23 -0
- package/dist/redact-BTIZcHQL.d.ts +5 -0
- package/dist/reflection-command-hooks-ClUl-iv6.js +644 -0
- package/dist/reflection-command-hooks-G1-dI2Av.d.ts +32 -0
- package/dist/reflection-deps-Ccm2Jf5W.d.ts +19 -0
- package/dist/reflection-embedded-generator-BRvqV5N-.js +130 -0
- package/dist/reflection-embedded-generator-kfQfKEYV.d.ts +14 -0
- package/dist/reflection-injection-hooks-CS_uhjoD.d.ts +43 -0
- package/dist/reflection-lifecycle-hooks-CRSpUdLi.d.ts +27 -0
- package/dist/relation-dictionary-Cev1kyLe.js +4248 -0
- package/dist/release-download.d.ts +8 -0
- package/dist/release-download.js +32 -0
- package/dist/relevant-memories-context-m8nuFZcM.js +23 -0
- package/dist/rem-batch-executor-Dg2HgROM.js +2 -0
- package/dist/rem-batch-executor-DuC4nYyf.js +31640 -0
- package/dist/rem-consumer-retrieval-CR0dtcHR.js +246 -0
- package/dist/rem-trigger-Hn6od8IV.js +730 -0
- package/dist/resolver-Dy-hnjCR.js +103 -0
- package/dist/results-C3ZLroMb.js +140 -0
- package/dist/retrieval-gate-Bx2Zg7jD.d.ts +31 -0
- package/dist/retriever-Dxss5fRv.d.ts +469 -0
- package/dist/retriever-ZoLvPRHq.js +1757 -0
- package/dist/rolldown-runtime-D7D4PA-g.js +13 -0
- package/dist/routes-DLHT__Ay.js +60 -0
- package/dist/runtime-audit-log-BCeujlEp.js +430 -0
- package/dist/runtime-audit-log-zpQiR9HT.d.ts +149 -0
- package/dist/scopes-CSOn6zdd.js +71 -0
- package/dist/scopes-CtrY-YQ3.d.ts +23 -0
- package/dist/server-CSvxchqg.js +1412 -0
- package/dist/session-registry-DBoE7AvZ.d.ts +14 -0
- package/dist/sidecar/main.d.ts +1 -0
- package/dist/sidecar/main.js +56 -0
- package/dist/signed-registry-constants-Bv0fgZ8Q.d.ts +12 -0
- package/dist/signed-registry-constants-yq3DlG3B.js +82 -0
- package/dist/sno-station-mem-runtime-dependencies-CoWqUMbK.js +30 -0
- package/dist/sno-station-mem-runtime-dependencies-DHESIuPn.d.ts +31 -0
- package/dist/sqlite-runtime-L_ywirTm.d.ts +58 -0
- package/dist/store-C8sUTssE.d.ts +27 -0
- package/dist/store-nPql26YM.js +5830 -0
- package/dist/strategy-hook-runner-Bxy851Xx.d.ts +16 -0
- package/dist/strategy-hook-runner-Djify5Rw.js +110 -0
- package/dist/token-counter-BD1f48Km.js +73 -0
- package/dist/trace-C1JxMfs-.d.ts +86 -0
- package/dist/types-CWdhXLxr.d.ts +477 -0
- package/dist/types-pVomjzqR.d.ts +132 -0
- package/dist/unplaced-candidate-migration-CbQHzcEM.js +940 -0
- package/dist/utils-Ctb9aevJ.d.ts +34 -0
- package/drizzle/0000_initial.sql +10 -0
- package/drizzle/0001_virtual_tables.sql +34 -0
- package/drizzle/0002_add_indexes.sql +11 -0
- package/drizzle/0003_content_hash_lookup_index.sql +2 -0
- package/drizzle/0004_chunk_swap.sql +60 -0
- package/drizzle/0005_drop_legacy_vec_fts.sql +10 -0
- package/drizzle/0006_fts_simple.sql +45 -0
- package/drizzle/0007_restore_simple_fts.sql +40 -0
- package/drizzle/0008_widen_memory_hash_unique_index.sql +4 -0
- package/drizzle/0009_memory_telemetry.sql +109 -0
- package/drizzle/0010_provider_mappings.sql +27 -0
- package/drizzle/0011_db_optimization.sql +82 -0
- package/drizzle/0012_b_profile_lanes.sql +9 -0
- package/drizzle/0013_extraction_timestamps.sql +6 -0
- package/drizzle/0014_extraction_timestamp_source.sql +3 -0
- package/drizzle/0015_task_lifecycle_state.sql +101 -0
- package/drizzle/0016_task_lifecycle_legacy_migration.sql +144 -0
- package/drizzle/0017_unplaced_candidates.sql +15 -0
- package/drizzle/0018_rem_batch_chassis.sql +71 -0
- package/drizzle/0019_profile_recovery_entries.sql +17 -0
- package/drizzle/0020_rem_scan_retry_progress.down.sql +14 -0
- package/drizzle/0020_rem_scan_retry_progress.sql +24 -0
- package/drizzle/0021_rem_two_facet_storage.down.sql +14 -0
- package/drizzle/0021_rem_two_facet_storage.sql +42 -0
- package/drizzle/0022_rem_facet_chunk_versions.down.sql +4 -0
- package/drizzle/0022_rem_facet_chunk_versions.sql +4 -0
- package/drizzle/0023_rem_defect_ledger.sql +40 -0
- package/drizzle/0024_rem_unbuilt_foundations.down.sql +13 -0
- package/drizzle/0024_rem_unbuilt_foundations.sql +65 -0
- package/drizzle/0025_rem_journal_operation_constraint.sql +28 -0
- package/drizzle/0026_rem_journal_detail.sql +1 -0
- package/drizzle/0027_legacy_nodix_namespace.sql +3 -0
- package/drizzle/0028_memory_timezone.sql +23 -0
- package/drizzle/0029_rem_write_hash_symmetry.sql +17 -0
- package/drizzle/0030_atomic_memory_additive.sql +105 -0
- package/drizzle/0031_atomic_extraction_ledger.sql +23 -0
- package/drizzle/0032_atomic_memory_entities.sql +12 -0
- package/drizzle/0033_todo_own_store.sql +99 -0
- package/drizzle/meta/0000_snapshot.json +87 -0
- package/drizzle/meta/_journal.json +244 -0
- package/generated/rem-operations.json +1 -0
- package/package.json +126 -4
- package/scripts/download-simple-tokenizer.mjs +254 -0
- package/settings.default.json +243 -0
- package/skills/extract-atomic-memory/SKILL.md +298 -0
- package/skills/extract-atomic-memory/references/account-for-turns.md +9 -0
- package/skills/extract-atomic-memory/references/calendar-meaning.md +64 -0
- package/skills/extract-atomic-memory/references/capture.md +120 -0
- package/skills/extract-atomic-memory/references/enrichment.md +92 -0
- package/skills/extract-atomic-memory/references/missing-durable-half.md +6 -0
- package/skills/extract-atomic-memory/references/progress-classification.md +21 -0
- package/skills/extract-atomic-memory/references/resolve-subject.md +19 -0
- package/skills/extract-atomic-memory/references/surrounding-context.md +10 -0
- package/skills/extract-atomic-memory/references/user-subject-guard.md +29 -0
- package/skills/judge-group-closure/SKILL.md +25 -0
- package/skills/judge-rem-memory-updates/SKILL.md +56 -0
- package/skills/judge-rem-memory-updates/agents/openai.yaml +4 -0
- package/skills/judge-retired-position/SKILL.md +25 -0
- package/skills/judge-task-lifecycle/SKILL.md +45 -0
- package/skills/key-state-attribute/SKILL.md +16 -0
- package/skills/resolve-entity-identity/SKILL.md +24 -0
- package/skills/resolve-relative-time/SKILL.md +22 -0
- package/sqlite-extensions/LICENSE-simple-tokenizer +28 -0
- package/sqlite-extensions/LICENSE-sqlite-vec +21 -0
- package/sqlite-extensions/linux-arm64/vec0.so +0 -0
- package/sqlite-extensions/linux-x64/vec0.so +0 -0
|
@@ -0,0 +1,730 @@
|
|
|
1
|
+
import { MAX_LIST_LIMIT } from "../../config/index.js";
|
|
2
|
+
import { a as buildInsightMetadata, c as stringifyInsightMetadata, h as deriveFactKey, s as parseInsightMetadata } from "../../../memory-metadata-codec-DL1sbJiN.js";
|
|
3
|
+
import { boundSectionContent, buildIndexedText } from "./extraction-text-sanitizer.js";
|
|
4
|
+
import { i as getActiveSectionRegistry, o as normalizeTopicToSectionName, s as restoreCachedSectionDictionary } from "../../../b-profile-section-dictionary-provider-BHkoNqgk.js";
|
|
5
|
+
import { o as canonicalizeProfileSectionName, r as recordTokenCounter } from "../../../memory-store-write-validation-B_hDG2zf.js";
|
|
6
|
+
import { createLogger } from "@snoai/utils/logger";
|
|
7
|
+
//#region src/engine/extraction/b-profile-section-rekey.ts
|
|
8
|
+
/** @file b-profile-section-rekey.ts
|
|
9
|
+
* @purpose Re-keys fall-through B-profile rows after a section dictionary upgrade.
|
|
10
|
+
* @boundary Deterministic store mutations only; no LLM or network calls.
|
|
11
|
+
*/
|
|
12
|
+
const log = createLogger("sno-station-mem:b-profile-section-rekey");
|
|
13
|
+
const GENERAL_SECTION = "preferences.general";
|
|
14
|
+
const MISSING_TOPIC_FLAG = "profile.preference.missing_topic";
|
|
15
|
+
const B_PROFILE_CANONICAL_FORM_REPAIR_VERSION = 1;
|
|
16
|
+
async function runBProfileSectionRekey(args) {
|
|
17
|
+
const registry = getActiveSectionRegistry();
|
|
18
|
+
let cached;
|
|
19
|
+
try {
|
|
20
|
+
cached = await args.cache.read();
|
|
21
|
+
} catch (error) {
|
|
22
|
+
log.warn("section dictionary cache rejected during re-key; treating it as absent", { error }, {
|
|
23
|
+
event_name: "sno_station_mem.b-profile-section-rekey.section.dictionary.cache.rejected.during.re.key.treating.it.as.absent",
|
|
24
|
+
file: "packages/memory/src/engine/extraction/b-profile-section-rekey.ts",
|
|
25
|
+
function: "runBProfileSectionRekey",
|
|
26
|
+
site_id: "b-profile-section-rekey.runBProfileSectionRekey.b452a7657e"
|
|
27
|
+
});
|
|
28
|
+
cached = void 0;
|
|
29
|
+
}
|
|
30
|
+
const registryRepairPending = cached?.appliedSchemaVersion !== registry.schema_version;
|
|
31
|
+
const canonicalRepairPending = cached?.canonicalFormRepairVersion !== 1;
|
|
32
|
+
if (!registryRepairPending && !canonicalRepairPending) {
|
|
33
|
+
const empty = emptyReport();
|
|
34
|
+
return {
|
|
35
|
+
dryRun: empty,
|
|
36
|
+
applied: empty,
|
|
37
|
+
skippedByVersion: true
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
let dryRun = emptyReport();
|
|
41
|
+
let applied = emptyReport();
|
|
42
|
+
if (canonicalRepairPending) {
|
|
43
|
+
const plan = await buildCanonicalRepairPlan(args.store, args.projectIdFilter);
|
|
44
|
+
log.info("B-profile canonical-form repair dry run", plan.report, {
|
|
45
|
+
event_name: "sno_station_mem.b-profile-section-rekey.b.profile.canonical.form.repair.dry.run",
|
|
46
|
+
file: "packages/memory/src/engine/extraction/b-profile-section-rekey.ts",
|
|
47
|
+
function: "runBProfileSectionRekey",
|
|
48
|
+
site_id: "b-profile-section-rekey.runBProfileSectionRekey.4494531e35"
|
|
49
|
+
});
|
|
50
|
+
assertCanonicalPlanReconciles(plan);
|
|
51
|
+
const canonicalApplied = await applyCanonicalRepairPlan(args.store, plan);
|
|
52
|
+
if (!reportsEqual(plan.report, canonicalApplied)) {
|
|
53
|
+
log.error("B-profile canonical-form repair reconciliation failed", {
|
|
54
|
+
dryRun: plan.report,
|
|
55
|
+
applied: canonicalApplied
|
|
56
|
+
}, {
|
|
57
|
+
event_name: "sno_station_mem.b-profile-section-rekey.b.profile.canonical.form.repair.reconciliation.failed",
|
|
58
|
+
file: "packages/memory/src/engine/extraction/b-profile-section-rekey.ts",
|
|
59
|
+
function: "runBProfileSectionRekey",
|
|
60
|
+
site_id: "b-profile-section-rekey.runBProfileSectionRekey.5276d7dfea"
|
|
61
|
+
});
|
|
62
|
+
throw new Error("B-profile canonical-form repair applied counts diverged from dry run");
|
|
63
|
+
}
|
|
64
|
+
dryRun = combineReports(dryRun, plan.report);
|
|
65
|
+
applied = combineReports(applied, canonicalApplied);
|
|
66
|
+
}
|
|
67
|
+
if (registryRepairPending || canonicalRepairPending) {
|
|
68
|
+
const plan = await buildRekeyPlan(args.store, args.projectIdFilter);
|
|
69
|
+
log.info("B-profile section re-key dry run", plan.report, {
|
|
70
|
+
event_name: "sno_station_mem.b-profile-section-rekey.b.profile.section.re.key.dry.run",
|
|
71
|
+
file: "packages/memory/src/engine/extraction/b-profile-section-rekey.ts",
|
|
72
|
+
function: "runBProfileSectionRekey",
|
|
73
|
+
site_id: "b-profile-section-rekey.runBProfileSectionRekey.1acb6c65f8"
|
|
74
|
+
});
|
|
75
|
+
assertPlanReconciles(plan.report);
|
|
76
|
+
const registryApplied = await applyRekeyPlan(args.store, plan);
|
|
77
|
+
if (!reportsEqual(plan.report, registryApplied)) {
|
|
78
|
+
log.error("B-profile section re-key reconciliation failed", {
|
|
79
|
+
dryRun: plan.report,
|
|
80
|
+
applied: registryApplied
|
|
81
|
+
}, {
|
|
82
|
+
event_name: "sno_station_mem.b-profile-section-rekey.b.profile.section.re.key.reconciliation.failed",
|
|
83
|
+
file: "packages/memory/src/engine/extraction/b-profile-section-rekey.ts",
|
|
84
|
+
function: "runBProfileSectionRekey",
|
|
85
|
+
site_id: "b-profile-section-rekey.runBProfileSectionRekey.d8bb76de51"
|
|
86
|
+
});
|
|
87
|
+
throw new Error("B-profile section re-key applied counts diverged from dry run");
|
|
88
|
+
}
|
|
89
|
+
dryRun = combineReports(dryRun, plan.report);
|
|
90
|
+
applied = combineReports(applied, registryApplied);
|
|
91
|
+
}
|
|
92
|
+
if (args.projectIdFilter === void 0) await args.cache.write({
|
|
93
|
+
activeRegistry: registry,
|
|
94
|
+
...cached?.fetchedForPluginVersion === void 0 ? {} : { fetchedForPluginVersion: cached.fetchedForPluginVersion },
|
|
95
|
+
appliedSchemaVersion: registry.schema_version,
|
|
96
|
+
canonicalFormRepairVersion: 1
|
|
97
|
+
});
|
|
98
|
+
log.info("B-profile section re-key applied", applied, {
|
|
99
|
+
event_name: "sno_station_mem.b-profile-section-rekey.b.profile.section.re.key.applied",
|
|
100
|
+
file: "packages/memory/src/engine/extraction/b-profile-section-rekey.ts",
|
|
101
|
+
function: "runBProfileSectionRekey",
|
|
102
|
+
site_id: "b-profile-section-rekey.runBProfileSectionRekey.ce06a215a3"
|
|
103
|
+
});
|
|
104
|
+
return {
|
|
105
|
+
dryRun,
|
|
106
|
+
applied,
|
|
107
|
+
skippedByVersion: false
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
function scheduleBProfileSectionRekey(args) {
|
|
111
|
+
(async () => {
|
|
112
|
+
await restoreCachedSectionDictionary({
|
|
113
|
+
mode: args.mode,
|
|
114
|
+
cache: args.cache
|
|
115
|
+
});
|
|
116
|
+
await runBProfileSectionRekey({
|
|
117
|
+
store: args.store,
|
|
118
|
+
cache: args.cache
|
|
119
|
+
});
|
|
120
|
+
})().catch((error) => {
|
|
121
|
+
log.error("detached B-profile section re-key failed", { error }, {
|
|
122
|
+
event_name: "sno_station_mem.b-profile-section-rekey.detached.b.profile.section.re.key.failed",
|
|
123
|
+
file: "packages/memory/src/engine/extraction/b-profile-section-rekey.ts",
|
|
124
|
+
function: "<anonymous callback>",
|
|
125
|
+
site_id: "b-profile-section-rekey.<anonymous callback>.9cc8218e54"
|
|
126
|
+
});
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
async function buildCanonicalRepairPlan(store, projectIdFilter) {
|
|
130
|
+
const activeRows = (await listAllProfileRows(store, projectIdFilter)).map((row) => parseRow(row)).filter((row) => row !== void 0).sort(compareRows).filter((row) => row.metadata.invalidated_at === void 0 && isCanonicalRepairEligible(row.metadata));
|
|
131
|
+
const report = emptyReport();
|
|
132
|
+
report.sourceRows = activeRows.length;
|
|
133
|
+
const groups = /* @__PURE__ */ new Map();
|
|
134
|
+
for (const row of activeRows) {
|
|
135
|
+
const sectionName = canonicalRepairTargetSection(row);
|
|
136
|
+
const groupKey = `${row.entry.projectId}\u0000${sectionName}`;
|
|
137
|
+
const group = groups.get(groupKey);
|
|
138
|
+
if (group) group.rows.push(row);
|
|
139
|
+
else groups.set(groupKey, {
|
|
140
|
+
sectionName,
|
|
141
|
+
rows: [row]
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
Object.assign(report, measureSplitGroups(activeRows));
|
|
145
|
+
const actions = [];
|
|
146
|
+
let finalCount = activeRows.length;
|
|
147
|
+
for (const group of groups.values()) {
|
|
148
|
+
const actionRows = group.rows.length === 1 ? group.rows : group.rows.filter((row) => {
|
|
149
|
+
if (canonicalizeProfileSectionName(row.sectionName) === GENERAL_SECTION && group.sectionName !== GENERAL_SECTION && !hasMergeablePreferenceClause(row.metadata.l2_content)) {
|
|
150
|
+
report.unchanged += 1;
|
|
151
|
+
return false;
|
|
152
|
+
}
|
|
153
|
+
return true;
|
|
154
|
+
});
|
|
155
|
+
if (actionRows.length === 1) {
|
|
156
|
+
const source = actionRows[0];
|
|
157
|
+
if (!source) continue;
|
|
158
|
+
if (source.sectionName === group.sectionName) {
|
|
159
|
+
report.unchanged += 1;
|
|
160
|
+
continue;
|
|
161
|
+
}
|
|
162
|
+
actions.push({
|
|
163
|
+
kind: "migrate",
|
|
164
|
+
sources: [source.entry],
|
|
165
|
+
newSection: group.sectionName
|
|
166
|
+
});
|
|
167
|
+
report.migrated += 1;
|
|
168
|
+
report.targetKeys += 1;
|
|
169
|
+
continue;
|
|
170
|
+
}
|
|
171
|
+
if (actionRows.length === 0) continue;
|
|
172
|
+
actions.push({
|
|
173
|
+
kind: "merge",
|
|
174
|
+
sources: actionRows.map((row) => row.entry),
|
|
175
|
+
newSection: group.sectionName
|
|
176
|
+
});
|
|
177
|
+
report.collisions += 1;
|
|
178
|
+
report.merged += 1;
|
|
179
|
+
report.targetKeys += 1;
|
|
180
|
+
finalCount -= actionRows.length - 1;
|
|
181
|
+
}
|
|
182
|
+
report.finalCount = finalCount;
|
|
183
|
+
return {
|
|
184
|
+
report,
|
|
185
|
+
actions,
|
|
186
|
+
projectIdFilter
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
async function applyCanonicalRepairPlan(store, plan) {
|
|
190
|
+
if (plan.actions.length === 0) return plan.report;
|
|
191
|
+
for (const action of plan.actions) {
|
|
192
|
+
const sources = action.sources.map((planned) => {
|
|
193
|
+
const current = store.getById(planned.id);
|
|
194
|
+
if (!current || current.contentHash !== planned.contentHash || current.metadata !== planned.metadata) throw new Error("B-profile canonical-form repair source changed after dry run");
|
|
195
|
+
const metadata = parseInsightMetadata(current.metadata, current);
|
|
196
|
+
if (typeof metadata.section_name !== "string" || metadata.invalidated_at !== void 0 || !isCanonicalRepairEligible(metadata) || canonicalRepairTargetSection({
|
|
197
|
+
metadata,
|
|
198
|
+
sectionName: metadata.section_name
|
|
199
|
+
}) !== action.newSection) throw new Error("B-profile canonical-form repair source no longer matches its plan");
|
|
200
|
+
return current;
|
|
201
|
+
});
|
|
202
|
+
if (action.kind === "migrate") {
|
|
203
|
+
const source = sources[0];
|
|
204
|
+
if (!source) throw new Error("B-profile canonical-form repair migration source missing");
|
|
205
|
+
await rekeyInPlace(store, source, action.newSection, action.newSection !== GENERAL_SECTION);
|
|
206
|
+
} else await mergeCanonicalCollision(store, sources, action.newSection);
|
|
207
|
+
}
|
|
208
|
+
const finalCount = (await listAllProfileRows(store, plan.projectIdFilter)).filter((row) => {
|
|
209
|
+
const parsed = parseRow(row);
|
|
210
|
+
if (!parsed) return false;
|
|
211
|
+
return parsed.metadata.invalidated_at === void 0 && isCanonicalRepairEligible(parsed.metadata);
|
|
212
|
+
}).length;
|
|
213
|
+
return {
|
|
214
|
+
...plan.report,
|
|
215
|
+
finalCount
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
function canonicalRepairTargetSection(row) {
|
|
219
|
+
const canonicalSection = canonicalizeProfileSectionName(row.sectionName);
|
|
220
|
+
if (canonicalSection !== GENERAL_SECTION) return canonicalSection;
|
|
221
|
+
const rawTopicPhrase = row.metadata.rawTopicPhrase;
|
|
222
|
+
if (typeof rawTopicPhrase !== "string" || rawTopicPhrase.trim().length === 0) return canonicalSection;
|
|
223
|
+
return normalizeTopicToSectionName(rawTopicPhrase);
|
|
224
|
+
}
|
|
225
|
+
function isCanonicalRepairEligible(metadata) {
|
|
226
|
+
return metadata.active_task_kind !== "task" && metadata.active_task_kind !== "projection";
|
|
227
|
+
}
|
|
228
|
+
function measureSplitGroups(laneActiveRows) {
|
|
229
|
+
const rawSections = new Set(laneActiveRows.map((row) => row.sectionName));
|
|
230
|
+
const sectionsByForm = /* @__PURE__ */ new Map();
|
|
231
|
+
const sectionsByTopic = /* @__PURE__ */ new Map();
|
|
232
|
+
for (const section of rawSections) {
|
|
233
|
+
const form = normalizeSplitMeasurementKey(section);
|
|
234
|
+
const matchingForms = sectionsByForm.get(form) ?? /* @__PURE__ */ new Set();
|
|
235
|
+
matchingForms.add(section);
|
|
236
|
+
sectionsByForm.set(form, matchingForms);
|
|
237
|
+
const separator = section.indexOf(".");
|
|
238
|
+
if (separator < 0) continue;
|
|
239
|
+
const topic = normalizeSplitMeasurementKey(section.slice(separator + 1));
|
|
240
|
+
const matchingTopics = sectionsByTopic.get(topic) ?? /* @__PURE__ */ new Set();
|
|
241
|
+
matchingTopics.add(section);
|
|
242
|
+
sectionsByTopic.set(topic, matchingTopics);
|
|
243
|
+
}
|
|
244
|
+
const separatorSplitGroups = Array.from(sectionsByForm.values()).filter((sections) => sections.size > 1).length;
|
|
245
|
+
const domainPrefixSplitGroups = Array.from(sectionsByTopic.values()).filter((sections) => {
|
|
246
|
+
return new Set(Array.from(sections, (section) => section.slice(0, section.indexOf(".")))).size > 1;
|
|
247
|
+
}).length;
|
|
248
|
+
const canonicalSections = new Set(laneActiveRows.map((row) => canonicalizeProfileSectionName(row.sectionName)));
|
|
249
|
+
const crossPathPairs = /* @__PURE__ */ new Set();
|
|
250
|
+
for (const row of laneActiveRows) {
|
|
251
|
+
const section = canonicalizeProfileSectionName(row.sectionName);
|
|
252
|
+
if (!section.startsWith("preferences.")) continue;
|
|
253
|
+
const candidates = [section.slice(12), ...typeof row.metadata.rawTopicPhrase === "string" ? [row.metadata.rawTopicPhrase] : []];
|
|
254
|
+
for (const candidate of candidates) {
|
|
255
|
+
const registrySection = normalizeTopicToSectionName(candidate);
|
|
256
|
+
if (registrySection === GENERAL_SECTION || registrySection === section || !canonicalSections.has(registrySection)) continue;
|
|
257
|
+
crossPathPairs.add([section, registrySection].sort().join("\0"));
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
return {
|
|
261
|
+
separatorSplitGroups,
|
|
262
|
+
domainPrefixSplitGroups,
|
|
263
|
+
crossPathSplitGroups: crossPathPairs.size
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
function normalizeSplitMeasurementKey(value) {
|
|
267
|
+
return value.normalize("NFKC").toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
|
|
268
|
+
}
|
|
269
|
+
async function mergeCanonicalCollision(store, sources, newSection) {
|
|
270
|
+
const sourceMetadata = sources.map((source) => parseInsightMetadata(source.metadata, source));
|
|
271
|
+
const targetFactKey = deriveFactKey({
|
|
272
|
+
kind: "profile",
|
|
273
|
+
section_name: newSection
|
|
274
|
+
});
|
|
275
|
+
if (!targetFactKey) throw new Error(`B-profile canonical-form repair target '${newSection}' is invalid`);
|
|
276
|
+
const activeFactGuard = {
|
|
277
|
+
factKey: targetFactKey,
|
|
278
|
+
expectedIds: sources.filter((_, index) => sourceMetadata[index]?.fact_key === targetFactKey).map((source) => source.id)
|
|
279
|
+
};
|
|
280
|
+
const mergedContent = combineUniquePreferenceClauses(...sourceMetadata.map((metadata) => metadata.l2_content));
|
|
281
|
+
const at = Math.max(Date.now(), ...sources.map((source) => source.timestamp));
|
|
282
|
+
const mergedClauseKeys = new Set(splitPreferenceClauses(mergedContent).map(normalizeClause).filter(Boolean));
|
|
283
|
+
let exactTargetIndex = -1;
|
|
284
|
+
let exactAliasTargetIndex = -1;
|
|
285
|
+
for (let index = sourceMetadata.length - 1; index >= 0; index -= 1) {
|
|
286
|
+
const metadata = sourceMetadata[index];
|
|
287
|
+
if (!metadata) continue;
|
|
288
|
+
const targetClauseKeys = new Set(splitPreferenceClauses(metadata.l2_content).map(normalizeClause).filter(Boolean));
|
|
289
|
+
if (!(targetClauseKeys.size === mergedClauseKeys.size && Array.from(targetClauseKeys).every((clause) => mergedClauseKeys.has(clause)))) continue;
|
|
290
|
+
if (metadata.section_name === newSection) {
|
|
291
|
+
exactTargetIndex = index;
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
if (exactAliasTargetIndex < 0) exactAliasTargetIndex = index;
|
|
295
|
+
}
|
|
296
|
+
if (exactTargetIndex < 0) exactTargetIndex = exactAliasTargetIndex;
|
|
297
|
+
if (exactTargetIndex >= 0) {
|
|
298
|
+
const target = sources[exactTargetIndex];
|
|
299
|
+
if (!target) throw new Error("B-profile canonical-form repair exact target disappeared");
|
|
300
|
+
const targetMetadata = sourceMetadata[exactTargetIndex];
|
|
301
|
+
if (!targetMetadata) throw new Error("B-profile canonical-form repair exact target metadata disappeared");
|
|
302
|
+
const finalTargetMetadata = targetMetadata.section_name === newSection ? target.metadata : metadataForSection(target, newSection);
|
|
303
|
+
if ((await store.supersede({
|
|
304
|
+
create: {
|
|
305
|
+
text: target.text,
|
|
306
|
+
category: target.category,
|
|
307
|
+
projectId: target.projectId,
|
|
308
|
+
importance: target.importance,
|
|
309
|
+
timestamp: target.timestamp,
|
|
310
|
+
metadata: finalTargetMetadata,
|
|
311
|
+
trusted: true
|
|
312
|
+
},
|
|
313
|
+
activeFactGuard,
|
|
314
|
+
preserveExisting: {
|
|
315
|
+
id: target.id,
|
|
316
|
+
expectedContentHash: target.contentHash,
|
|
317
|
+
expectedMetadata: target.metadata
|
|
318
|
+
},
|
|
319
|
+
closes: sources.filter((source) => source.id !== target.id).map((source) => ({
|
|
320
|
+
id: source.id,
|
|
321
|
+
expectedContentHash: source.contentHash,
|
|
322
|
+
expectedMetadata: source.metadata,
|
|
323
|
+
buildMetadata: (createdId) => closedMetadata(source, createdId, at, newSection, true)
|
|
324
|
+
}))
|
|
325
|
+
})).id !== target.id) throw new Error("B-profile canonical-form repair exact target was not preserved");
|
|
326
|
+
return;
|
|
327
|
+
}
|
|
328
|
+
const target = sources[0];
|
|
329
|
+
if (!target) throw new Error("B-profile canonical-form repair collision has no rows");
|
|
330
|
+
const targetMetadata = sourceMetadata[0];
|
|
331
|
+
if (!targetMetadata) throw new Error("B-profile canonical-form repair target metadata missing");
|
|
332
|
+
const abstract = firstSentence(mergedContent);
|
|
333
|
+
const boundedContent = boundSectionContent(mergedContent, abstract, await recordTokenCounter(store.embedder));
|
|
334
|
+
const replacementMetadata = buildInsightMetadata({
|
|
335
|
+
text: boundedContent,
|
|
336
|
+
category: "profile",
|
|
337
|
+
timestamp: at
|
|
338
|
+
}, {
|
|
339
|
+
...metadataForMergeProduct(targetMetadata),
|
|
340
|
+
l0_abstract: abstract,
|
|
341
|
+
l1_overview: boundedContent,
|
|
342
|
+
l2_content: boundedContent,
|
|
343
|
+
section_name: newSection,
|
|
344
|
+
supersedes: target.id,
|
|
345
|
+
valid_from: at,
|
|
346
|
+
asserted_at: at
|
|
347
|
+
});
|
|
348
|
+
await store.supersede({
|
|
349
|
+
create: {
|
|
350
|
+
text: buildIndexedText(abstract, boundedContent),
|
|
351
|
+
category: "profile",
|
|
352
|
+
projectId: target.projectId,
|
|
353
|
+
importance: Math.max(...sources.map((source) => source.importance)),
|
|
354
|
+
timestamp: at,
|
|
355
|
+
metadata: stringifyInsightMetadata(replacementMetadata),
|
|
356
|
+
trusted: true
|
|
357
|
+
},
|
|
358
|
+
activeFactGuard,
|
|
359
|
+
closes: sources.map((source) => ({
|
|
360
|
+
id: source.id,
|
|
361
|
+
expectedContentHash: source.contentHash,
|
|
362
|
+
expectedMetadata: source.metadata,
|
|
363
|
+
buildMetadata: (createdId) => closedMetadata(source, createdId, at, newSection, true)
|
|
364
|
+
}))
|
|
365
|
+
});
|
|
366
|
+
}
|
|
367
|
+
async function buildRekeyPlan(store, projectIdFilter) {
|
|
368
|
+
const activeRows = (await listAllProfileRows(store, projectIdFilter)).map((row) => parseRow(row)).filter((row) => row !== void 0).filter((row) => row.metadata.invalidated_at === void 0);
|
|
369
|
+
const sources = activeRows.filter((row) => row.metadata.section_name === GENERAL_SECTION).sort(compareRows).map((row) => row.entry);
|
|
370
|
+
const report = emptyReport();
|
|
371
|
+
report.sourceRows = sources.length;
|
|
372
|
+
const actions = [];
|
|
373
|
+
const plannedTargets = /* @__PURE__ */ new Set();
|
|
374
|
+
const targetKeys = /* @__PURE__ */ new Set();
|
|
375
|
+
for (const source of sources) {
|
|
376
|
+
const metadata = parseInsightMetadata(source.metadata, source);
|
|
377
|
+
const rawTopicPhrase = metadata.rawTopicPhrase;
|
|
378
|
+
if (typeof rawTopicPhrase !== "string" || !rawTopicPhrase.trim()) {
|
|
379
|
+
report.missingRawPhrase += 1;
|
|
380
|
+
continue;
|
|
381
|
+
}
|
|
382
|
+
const newSection = normalizeTopicToSectionName(rawTopicPhrase);
|
|
383
|
+
if (newSection === GENERAL_SECTION || newSection === metadata.section_name) {
|
|
384
|
+
report.unchanged += 1;
|
|
385
|
+
continue;
|
|
386
|
+
}
|
|
387
|
+
const targetFactKey = deriveFactKey({
|
|
388
|
+
kind: "profile",
|
|
389
|
+
section_name: newSection
|
|
390
|
+
});
|
|
391
|
+
if (!targetFactKey) {
|
|
392
|
+
report.rejected += 1;
|
|
393
|
+
continue;
|
|
394
|
+
}
|
|
395
|
+
const planKey = `${source.projectId}\u0000${targetFactKey}`;
|
|
396
|
+
targetKeys.add(planKey);
|
|
397
|
+
const existingTarget = store.getByFactKey(source.projectId, targetFactKey);
|
|
398
|
+
if (existingTarget) try {
|
|
399
|
+
parseInsightMetadata(existingTarget.metadata, existingTarget);
|
|
400
|
+
} catch {
|
|
401
|
+
report.rejected += 1;
|
|
402
|
+
continue;
|
|
403
|
+
}
|
|
404
|
+
const kind = existingTarget || plannedTargets.has(planKey) ? "merge" : "migrate";
|
|
405
|
+
if (kind === "merge" && !hasMergeablePreferenceClause(metadata.l2_content)) {
|
|
406
|
+
report.rejected += 1;
|
|
407
|
+
continue;
|
|
408
|
+
}
|
|
409
|
+
actions.push({
|
|
410
|
+
kind,
|
|
411
|
+
source,
|
|
412
|
+
targetFactKey,
|
|
413
|
+
newSection
|
|
414
|
+
});
|
|
415
|
+
plannedTargets.add(planKey);
|
|
416
|
+
if (kind === "merge") {
|
|
417
|
+
report.collisions += 1;
|
|
418
|
+
report.merged += 1;
|
|
419
|
+
} else report.migrated += 1;
|
|
420
|
+
}
|
|
421
|
+
report.targetKeys = targetKeys.size;
|
|
422
|
+
report.finalCount = activeRows.length - report.merged;
|
|
423
|
+
return {
|
|
424
|
+
report,
|
|
425
|
+
actions,
|
|
426
|
+
projectIdFilter
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
async function applyRekeyPlan(store, plan) {
|
|
430
|
+
if (plan.actions.length === 0) return plan.report;
|
|
431
|
+
let migrated = 0;
|
|
432
|
+
let merged = 0;
|
|
433
|
+
for (const action of plan.actions) {
|
|
434
|
+
const source = store.getById(action.source.id);
|
|
435
|
+
if (!source || source.contentHash !== action.source.contentHash || source.metadata !== action.source.metadata || !sourceStillMatchesPlan(source, action.newSection)) throwReconciliationError("source row changed after dry run", action);
|
|
436
|
+
const target = store.getByFactKey(source.projectId, action.targetFactKey);
|
|
437
|
+
if (action.kind === "migrate") {
|
|
438
|
+
if (target) throwReconciliationError("unexpected target appeared after dry run", action);
|
|
439
|
+
await rekeyInPlace(store, source, action.newSection);
|
|
440
|
+
migrated += 1;
|
|
441
|
+
continue;
|
|
442
|
+
}
|
|
443
|
+
if (!target) throwReconciliationError("expected collision target disappeared", action);
|
|
444
|
+
await mergeCollision(store, source, target, action.newSection);
|
|
445
|
+
merged += 1;
|
|
446
|
+
}
|
|
447
|
+
const finalCount = (await listAllProfileRows(store, plan.projectIdFilter)).filter((row) => {
|
|
448
|
+
return parseRow(row)?.metadata.invalidated_at === void 0;
|
|
449
|
+
}).length;
|
|
450
|
+
return {
|
|
451
|
+
...plan.report,
|
|
452
|
+
migrated,
|
|
453
|
+
merged,
|
|
454
|
+
collisions: merged,
|
|
455
|
+
finalCount
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
async function rekeyInPlace(store, source, newSection, expectTargetAbsent = true) {
|
|
459
|
+
const targetFactKey = deriveFactKey({
|
|
460
|
+
kind: "profile",
|
|
461
|
+
section_name: newSection
|
|
462
|
+
});
|
|
463
|
+
if (!targetFactKey) throw new Error(`B-profile section re-key target '${newSection}' is invalid`);
|
|
464
|
+
if (!await store.update(source.id, {
|
|
465
|
+
writerAuthority: "profile-writer",
|
|
466
|
+
metadata: metadataForSection(source, newSection),
|
|
467
|
+
expectedContentHash: source.contentHash,
|
|
468
|
+
expectedMetadata: source.metadata,
|
|
469
|
+
...expectTargetAbsent ? { expectedAbsentFactKey: targetFactKey } : {}
|
|
470
|
+
})) throw new Error(`B-profile section re-key source '${source.id}' disappeared`);
|
|
471
|
+
}
|
|
472
|
+
function metadataForSection(source, newSection) {
|
|
473
|
+
const nextMetadata = { ...buildInsightMetadata(source, {
|
|
474
|
+
...parseInsightMetadata(source.metadata, source),
|
|
475
|
+
section_name: newSection
|
|
476
|
+
}) };
|
|
477
|
+
delete nextMetadata[MISSING_TOPIC_FLAG];
|
|
478
|
+
return stringifyInsightMetadata(nextMetadata);
|
|
479
|
+
}
|
|
480
|
+
async function mergeCollision(store, source, target, newSection) {
|
|
481
|
+
const sourceMetadata = parseInsightMetadata(source.metadata, source);
|
|
482
|
+
const targetMetadata = parseInsightMetadata(target.metadata, target);
|
|
483
|
+
const sourceContent = sourceMetadata.l2_content;
|
|
484
|
+
const targetContent = targetMetadata.l2_content;
|
|
485
|
+
const normalizedTargetContent = combineUniquePreferenceClauses(targetContent);
|
|
486
|
+
const mergedContent = combineUniquePreferenceClauses(targetContent, sourceContent);
|
|
487
|
+
const at = Math.max(Date.now(), source.timestamp, target.timestamp);
|
|
488
|
+
if (mergedContent === normalizedTargetContent) {
|
|
489
|
+
const targetFactKey = deriveFactKey({
|
|
490
|
+
kind: "profile",
|
|
491
|
+
section_name: newSection
|
|
492
|
+
});
|
|
493
|
+
if (!targetFactKey) throw new Error(`B-profile section re-key target '${newSection}' is invalid`);
|
|
494
|
+
if ((await store.supersede({
|
|
495
|
+
create: {
|
|
496
|
+
text: target.text,
|
|
497
|
+
category: target.category,
|
|
498
|
+
projectId: target.projectId,
|
|
499
|
+
importance: target.importance,
|
|
500
|
+
timestamp: target.timestamp,
|
|
501
|
+
metadata: target.metadata,
|
|
502
|
+
trusted: true
|
|
503
|
+
},
|
|
504
|
+
closes: [closeSource(source, newSection, at)],
|
|
505
|
+
activeFactGuard: {
|
|
506
|
+
factKey: targetFactKey,
|
|
507
|
+
expectedId: target.id
|
|
508
|
+
},
|
|
509
|
+
preserveExisting: {
|
|
510
|
+
id: target.id,
|
|
511
|
+
expectedContentHash: target.contentHash,
|
|
512
|
+
expectedMetadata: target.metadata
|
|
513
|
+
}
|
|
514
|
+
})).id !== target.id) throw new Error("B-profile section re-key exact target was not preserved");
|
|
515
|
+
return;
|
|
516
|
+
}
|
|
517
|
+
const abstract = firstSentence(mergedContent);
|
|
518
|
+
const boundedContent = boundSectionContent(mergedContent, abstract, await recordTokenCounter(store.embedder));
|
|
519
|
+
const replacementMetadata = buildInsightMetadata({
|
|
520
|
+
text: boundedContent,
|
|
521
|
+
category: "profile",
|
|
522
|
+
timestamp: at
|
|
523
|
+
}, {
|
|
524
|
+
...metadataForMergeProduct(targetMetadata),
|
|
525
|
+
l0_abstract: abstract,
|
|
526
|
+
l1_overview: boundedContent,
|
|
527
|
+
l2_content: boundedContent,
|
|
528
|
+
section_name: newSection,
|
|
529
|
+
supersedes: target.id,
|
|
530
|
+
valid_from: at,
|
|
531
|
+
asserted_at: at
|
|
532
|
+
});
|
|
533
|
+
await store.supersede({
|
|
534
|
+
create: {
|
|
535
|
+
text: buildIndexedText(abstract, boundedContent),
|
|
536
|
+
category: "profile",
|
|
537
|
+
projectId: target.projectId,
|
|
538
|
+
importance: Math.max(source.importance, target.importance),
|
|
539
|
+
timestamp: at,
|
|
540
|
+
metadata: stringifyInsightMetadata(replacementMetadata),
|
|
541
|
+
trusted: true
|
|
542
|
+
},
|
|
543
|
+
closes: [closeTarget(target, at), closeSource(source, newSection, at)]
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
function metadataForMergeProduct(metadata) {
|
|
547
|
+
const product = { ...metadata };
|
|
548
|
+
delete product.idempotency_key;
|
|
549
|
+
delete product.merge_lineage;
|
|
550
|
+
delete product.mappedKind;
|
|
551
|
+
if (product.source === "agent_end") for (const key of [
|
|
552
|
+
"source",
|
|
553
|
+
"role",
|
|
554
|
+
"session_key",
|
|
555
|
+
"session_id",
|
|
556
|
+
"chunk_index",
|
|
557
|
+
"chunk_count",
|
|
558
|
+
"chunking_version",
|
|
559
|
+
"content_type"
|
|
560
|
+
]) delete product[key];
|
|
561
|
+
return product;
|
|
562
|
+
}
|
|
563
|
+
function closeSource(source, newSection, at) {
|
|
564
|
+
return {
|
|
565
|
+
id: source.id,
|
|
566
|
+
expectedContentHash: source.contentHash,
|
|
567
|
+
expectedMetadata: source.metadata,
|
|
568
|
+
buildMetadata: (createdId) => closedMetadata(source, createdId, at, newSection, true)
|
|
569
|
+
};
|
|
570
|
+
}
|
|
571
|
+
function closeTarget(target, at) {
|
|
572
|
+
return {
|
|
573
|
+
id: target.id,
|
|
574
|
+
expectedContentHash: target.contentHash,
|
|
575
|
+
expectedMetadata: target.metadata,
|
|
576
|
+
buildMetadata: (createdId) => closedMetadata(target, createdId, at, void 0, false)
|
|
577
|
+
};
|
|
578
|
+
}
|
|
579
|
+
function closedMetadata(row, createdId, at, sectionName, dropMissingTopicFlag) {
|
|
580
|
+
const current = parseInsightMetadata(row.metadata, row);
|
|
581
|
+
const nextMetadata = { ...buildInsightMetadata(row, {
|
|
582
|
+
...current,
|
|
583
|
+
...sectionName ? { section_name: sectionName } : {},
|
|
584
|
+
invalidated_at: current.valid_from === void 0 ? at : Math.max(at, current.valid_from),
|
|
585
|
+
superseded_by: createdId
|
|
586
|
+
}) };
|
|
587
|
+
if (dropMissingTopicFlag) delete nextMetadata[MISSING_TOPIC_FLAG];
|
|
588
|
+
return stringifyInsightMetadata(nextMetadata);
|
|
589
|
+
}
|
|
590
|
+
function parseRow(entry) {
|
|
591
|
+
try {
|
|
592
|
+
const metadata = parseInsightMetadata(entry.metadata, entry);
|
|
593
|
+
if (typeof metadata.section_name !== "string") return void 0;
|
|
594
|
+
return {
|
|
595
|
+
entry,
|
|
596
|
+
metadata,
|
|
597
|
+
sectionName: metadata.section_name
|
|
598
|
+
};
|
|
599
|
+
} catch {
|
|
600
|
+
return;
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
async function listAllProfileRows(store, projectIdFilter) {
|
|
604
|
+
const rows = [];
|
|
605
|
+
for (let offset = 0;; offset += MAX_LIST_LIMIT) {
|
|
606
|
+
const page = await store.list({
|
|
607
|
+
category: "profile",
|
|
608
|
+
limit: MAX_LIST_LIMIT,
|
|
609
|
+
offset,
|
|
610
|
+
...projectIdFilter === void 0 ? {} : { projectIdFilter }
|
|
611
|
+
});
|
|
612
|
+
if (page.length === 0) return rows;
|
|
613
|
+
rows.push(...page);
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
function sourceStillMatchesPlan(source, newSection) {
|
|
617
|
+
const metadata = parseInsightMetadata(source.metadata, source);
|
|
618
|
+
const rawTopicPhrase = metadata.rawTopicPhrase;
|
|
619
|
+
return metadata.invalidated_at === void 0 && metadata.section_name === GENERAL_SECTION && typeof rawTopicPhrase === "string" && normalizeTopicToSectionName(rawTopicPhrase) === newSection;
|
|
620
|
+
}
|
|
621
|
+
function assertPlanReconciles(report) {
|
|
622
|
+
if (report.migrated + report.merged + report.rejected + report.missingRawPhrase + report.unchanged === report.sourceRows) return;
|
|
623
|
+
log.error("B-profile section re-key dry-run counts do not reconcile", report, {
|
|
624
|
+
event_name: "sno_station_mem.b-profile-section-rekey.b.profile.section.re.key.dry.run.counts.do.not.reconcile",
|
|
625
|
+
file: "packages/memory/src/engine/extraction/b-profile-section-rekey.ts",
|
|
626
|
+
function: "assertPlanReconciles",
|
|
627
|
+
site_id: "b-profile-section-rekey.assertPlanReconciles.03748b5c20"
|
|
628
|
+
});
|
|
629
|
+
throw new Error("B-profile section re-key dry-run counts do not reconcile");
|
|
630
|
+
}
|
|
631
|
+
function assertCanonicalPlanReconciles(plan) {
|
|
632
|
+
if (plan.actions.reduce((count, action) => count + action.sources.length, 0) + plan.report.unchanged === plan.report.sourceRows) return;
|
|
633
|
+
log.error("B-profile canonical-form repair dry-run counts do not reconcile", plan.report, {
|
|
634
|
+
event_name: "sno_station_mem.b-profile-section-rekey.b.profile.canonical.form.repair.dry.run.counts.do.not.reconcile",
|
|
635
|
+
file: "packages/memory/src/engine/extraction/b-profile-section-rekey.ts",
|
|
636
|
+
function: "assertCanonicalPlanReconciles",
|
|
637
|
+
site_id: "b-profile-section-rekey.assertCanonicalPlanReconciles.2ad72089d1"
|
|
638
|
+
});
|
|
639
|
+
throw new Error("B-profile canonical-form repair dry-run counts do not reconcile");
|
|
640
|
+
}
|
|
641
|
+
function throwReconciliationError(reason, action) {
|
|
642
|
+
log.error("B-profile section re-key aborted after dry-run divergence", {
|
|
643
|
+
reason_code: reason.replace(/[^a-z0-9]+/gi, "_").toLowerCase(),
|
|
644
|
+
memory_id: action.source.id,
|
|
645
|
+
projectId: action.source.projectId,
|
|
646
|
+
targetFactKey: action.targetFactKey
|
|
647
|
+
}, {
|
|
648
|
+
event_name: "sno_station_mem.b-profile-section-rekey.b.profile.section.re.key.aborted.after.dry.run.divergence",
|
|
649
|
+
file: "packages/memory/src/engine/extraction/b-profile-section-rekey.ts",
|
|
650
|
+
function: "throwReconciliationError",
|
|
651
|
+
site_id: "b-profile-section-rekey.throwReconciliationError.b59b599311"
|
|
652
|
+
});
|
|
653
|
+
throw new Error(`B-profile section re-key aborted: ${reason}`);
|
|
654
|
+
}
|
|
655
|
+
function reportsEqual(left, right) {
|
|
656
|
+
return JSON.stringify(left) === JSON.stringify(right);
|
|
657
|
+
}
|
|
658
|
+
function combineReports(left, right) {
|
|
659
|
+
return {
|
|
660
|
+
sourceRows: Math.max(left.sourceRows, right.sourceRows),
|
|
661
|
+
targetKeys: left.targetKeys + right.targetKeys,
|
|
662
|
+
collisions: left.collisions + right.collisions,
|
|
663
|
+
migrated: left.migrated + right.migrated,
|
|
664
|
+
merged: left.merged + right.merged,
|
|
665
|
+
rejected: left.rejected + right.rejected,
|
|
666
|
+
missingRawPhrase: left.missingRawPhrase + right.missingRawPhrase,
|
|
667
|
+
unchanged: left.unchanged + right.unchanged,
|
|
668
|
+
finalCount: right.finalCount,
|
|
669
|
+
separatorSplitGroups: left.separatorSplitGroups + right.separatorSplitGroups,
|
|
670
|
+
domainPrefixSplitGroups: left.domainPrefixSplitGroups + right.domainPrefixSplitGroups,
|
|
671
|
+
crossPathSplitGroups: left.crossPathSplitGroups + right.crossPathSplitGroups
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
function emptyReport() {
|
|
675
|
+
return {
|
|
676
|
+
sourceRows: 0,
|
|
677
|
+
targetKeys: 0,
|
|
678
|
+
collisions: 0,
|
|
679
|
+
migrated: 0,
|
|
680
|
+
merged: 0,
|
|
681
|
+
rejected: 0,
|
|
682
|
+
missingRawPhrase: 0,
|
|
683
|
+
unchanged: 0,
|
|
684
|
+
finalCount: 0,
|
|
685
|
+
separatorSplitGroups: 0,
|
|
686
|
+
domainPrefixSplitGroups: 0,
|
|
687
|
+
crossPathSplitGroups: 0
|
|
688
|
+
};
|
|
689
|
+
}
|
|
690
|
+
function compareRows(left, right) {
|
|
691
|
+
return left.entry.projectId.localeCompare(right.entry.projectId) || left.entry.timestamp - right.entry.timestamp || left.entry.id.localeCompare(right.entry.id);
|
|
692
|
+
}
|
|
693
|
+
function combineUniquePreferenceClauses(...texts) {
|
|
694
|
+
const seen = /* @__PURE__ */ new Set();
|
|
695
|
+
const clauses = [];
|
|
696
|
+
for (const text of texts) for (const clause of splitPreferenceClauses(text)) {
|
|
697
|
+
const key = normalizeClause(clause);
|
|
698
|
+
if (!key || seen.has(key)) continue;
|
|
699
|
+
seen.add(key);
|
|
700
|
+
clauses.push(clause);
|
|
701
|
+
}
|
|
702
|
+
return clauses.join("\n");
|
|
703
|
+
}
|
|
704
|
+
function hasMergeablePreferenceClause(text) {
|
|
705
|
+
return splitPreferenceClauses(text).some((clause) => normalizeClause(clause).length > 0);
|
|
706
|
+
}
|
|
707
|
+
function splitPreferenceClauses(text) {
|
|
708
|
+
return text.split(/\n+|(?<=[.!?])\s+/).map((item) => item.trim()).filter(Boolean);
|
|
709
|
+
}
|
|
710
|
+
/**
|
|
711
|
+
* Clause identity for dedup and for the exact-match check that decides which row survives a
|
|
712
|
+
* merge. Case, Unicode form and whitespace do not change what a clause says, so they are
|
|
713
|
+
* normalized away — and nothing else is.
|
|
714
|
+
*
|
|
715
|
+
* This used to delete every non-alphanumeric character, which merged clauses stating different
|
|
716
|
+
* facts: "I use C." and "I use C++." both became "i use c", so one of the two preferences was
|
|
717
|
+
* closed as a duplicate of the other and the count check still passed. Every symbol that
|
|
718
|
+
* distinguishes a name — `+`, `#`, `/`, `.` inside a word — is meaning, not formatting.
|
|
719
|
+
* A trailing sentence terminator is not, so the same clause with and without its full stop
|
|
720
|
+
* stays one clause.
|
|
721
|
+
*/
|
|
722
|
+
function normalizeClause(text) {
|
|
723
|
+
const normalized = text.normalize("NFKC").toLowerCase().replace(/\s+/g, " ").trim().replace(/[.!?]+$/u, "").trim();
|
|
724
|
+
return /[\p{L}\p{N}]/u.test(normalized) ? normalized : "";
|
|
725
|
+
}
|
|
726
|
+
function firstSentence(text) {
|
|
727
|
+
return text.split(/(?<=[.!?])\s+/)[0]?.trim() || text;
|
|
728
|
+
}
|
|
729
|
+
//#endregion
|
|
730
|
+
export { B_PROFILE_CANONICAL_FORM_REPAIR_VERSION, applyRekeyPlan, runBProfileSectionRekey, scheduleBProfileSectionRekey };
|