@astragenie/astramemory-local 0.7.2
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/CHANGELOG.md +341 -0
- package/README.md +419 -0
- package/dist/backup/retention.d.ts +15 -0
- package/dist/backup/retention.js +62 -0
- package/dist/backup/retention.js.map +1 -0
- package/dist/backup/snapshot.d.ts +21 -0
- package/dist/backup/snapshot.js +55 -0
- package/dist/backup/snapshot.js.map +1 -0
- package/dist/backup/verify.d.ts +23 -0
- package/dist/backup/verify.js +77 -0
- package/dist/backup/verify.js.map +1 -0
- package/dist/budget/tracker.d.ts +58 -0
- package/dist/budget/tracker.js +102 -0
- package/dist/budget/tracker.js.map +1 -0
- package/dist/capture/codex.d.ts +63 -0
- package/dist/capture/codex.js +0 -0
- package/dist/capture/codex.js.map +1 -0
- package/dist/cli/backup.d.ts +1 -0
- package/dist/cli/backup.js +112 -0
- package/dist/cli/backup.js.map +1 -0
- package/dist/cli/budget.d.ts +7 -0
- package/dist/cli/budget.js +44 -0
- package/dist/cli/budget.js.map +1 -0
- package/dist/cli/capture.d.ts +10 -0
- package/dist/cli/capture.js +113 -0
- package/dist/cli/capture.js.map +1 -0
- package/dist/cli/consolidate.d.ts +16 -0
- package/dist/cli/consolidate.js +146 -0
- package/dist/cli/consolidate.js.map +1 -0
- package/dist/cli/doctor.d.ts +1 -0
- package/dist/cli/doctor.js +54 -0
- package/dist/cli/doctor.js.map +1 -0
- package/dist/cli/entity-backfill.d.ts +10 -0
- package/dist/cli/entity-backfill.js +46 -0
- package/dist/cli/entity-backfill.js.map +1 -0
- package/dist/cli/hook-install.d.ts +45 -0
- package/dist/cli/hook-install.js +77 -0
- package/dist/cli/hook-install.js.map +1 -0
- package/dist/cli/index.d.ts +2 -0
- package/dist/cli/index.js +312 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init.d.ts +16 -0
- package/dist/cli/init.js +431 -0
- package/dist/cli/init.js.map +1 -0
- package/dist/cli/mcp-stdio.d.ts +18 -0
- package/dist/cli/mcp-stdio.js +67 -0
- package/dist/cli/mcp-stdio.js.map +1 -0
- package/dist/cli/memory.d.ts +15 -0
- package/dist/cli/memory.js +52 -0
- package/dist/cli/memory.js.map +1 -0
- package/dist/cli/open-runtime-db.d.ts +15 -0
- package/dist/cli/open-runtime-db.js +37 -0
- package/dist/cli/open-runtime-db.js.map +1 -0
- package/dist/cli/pair.d.ts +29 -0
- package/dist/cli/pair.js +64 -0
- package/dist/cli/pair.js.map +1 -0
- package/dist/cli/providers.d.ts +10 -0
- package/dist/cli/providers.js +97 -0
- package/dist/cli/providers.js.map +1 -0
- package/dist/cli/queue-purge.d.ts +5 -0
- package/dist/cli/queue-purge.js +92 -0
- package/dist/cli/queue-purge.js.map +1 -0
- package/dist/cli/queue.d.ts +29 -0
- package/dist/cli/queue.js +73 -0
- package/dist/cli/queue.js.map +1 -0
- package/dist/cli/rebuild.d.ts +15 -0
- package/dist/cli/rebuild.js +70 -0
- package/dist/cli/rebuild.js.map +1 -0
- package/dist/cli/reembed-dim.d.ts +21 -0
- package/dist/cli/reembed-dim.js +199 -0
- package/dist/cli/reembed-dim.js.map +1 -0
- package/dist/cli/reinstall.d.ts +1 -0
- package/dist/cli/reinstall.js +205 -0
- package/dist/cli/reinstall.js.map +1 -0
- package/dist/cli/restore.d.ts +1 -0
- package/dist/cli/restore.js +167 -0
- package/dist/cli/restore.js.map +1 -0
- package/dist/cli/retag.d.ts +14 -0
- package/dist/cli/retag.js +62 -0
- package/dist/cli/retag.js.map +1 -0
- package/dist/cli/search.d.ts +66 -0
- package/dist/cli/search.js +174 -0
- package/dist/cli/search.js.map +1 -0
- package/dist/cli/serve.d.ts +9 -0
- package/dist/cli/serve.js +364 -0
- package/dist/cli/serve.js.map +1 -0
- package/dist/cli/service.d.ts +1 -0
- package/dist/cli/service.js +121 -0
- package/dist/cli/service.js.map +1 -0
- package/dist/cli/sync.d.ts +15 -0
- package/dist/cli/sync.js +61 -0
- package/dist/cli/sync.js.map +1 -0
- package/dist/cli/token.d.ts +24 -0
- package/dist/cli/token.js +77 -0
- package/dist/cli/token.js.map +1 -0
- package/dist/cli/wait-health.d.ts +4 -0
- package/dist/cli/wait-health.js +23 -0
- package/dist/cli/wait-health.js.map +1 -0
- package/dist/config/config.d.ts +127 -0
- package/dist/config/config.js +38 -0
- package/dist/config/config.js.map +1 -0
- package/dist/config/datadir.d.ts +30 -0
- package/dist/config/datadir.js +65 -0
- package/dist/config/datadir.js.map +1 -0
- package/dist/config/loader.d.ts +23 -0
- package/dist/config/loader.js +102 -0
- package/dist/config/loader.js.map +1 -0
- package/dist/config/migrate-dirs.d.ts +36 -0
- package/dist/config/migrate-dirs.js +132 -0
- package/dist/config/migrate-dirs.js.map +1 -0
- package/dist/config/persist-envs.d.ts +23 -0
- package/dist/config/persist-envs.js +119 -0
- package/dist/config/persist-envs.js.map +1 -0
- package/dist/config/resolve-runtime.d.ts +19 -0
- package/dist/config/resolve-runtime.js +53 -0
- package/dist/config/resolve-runtime.js.map +1 -0
- package/dist/config/secrets.d.ts +28 -0
- package/dist/config/secrets.js +38 -0
- package/dist/config/secrets.js.map +1 -0
- package/dist/config/sync-settings.d.ts +16 -0
- package/dist/config/sync-settings.js +34 -0
- package/dist/config/sync-settings.js.map +1 -0
- package/dist/config/writer.d.ts +19 -0
- package/dist/config/writer.js +121 -0
- package/dist/config/writer.js.map +1 -0
- package/dist/consolidate/consolidate.d.ts +80 -0
- package/dist/consolidate/consolidate.js +0 -0
- package/dist/consolidate/consolidate.js.map +1 -0
- package/dist/consolidate/proposals.d.ts +35 -0
- package/dist/consolidate/proposals.js +66 -0
- package/dist/consolidate/proposals.js.map +1 -0
- package/dist/contracts/atom-wire.d.ts +48 -0
- package/dist/contracts/atom-wire.js +55 -0
- package/dist/contracts/atom-wire.js.map +1 -0
- package/dist/contracts/embed.d.ts +41 -0
- package/dist/contracts/embed.js +20 -0
- package/dist/contracts/embed.js.map +1 -0
- package/dist/contracts/index.d.ts +5 -0
- package/dist/contracts/index.js +6 -0
- package/dist/contracts/index.js.map +1 -0
- package/dist/contracts/job.d.ts +113 -0
- package/dist/contracts/job.js +32 -0
- package/dist/contracts/job.js.map +1 -0
- package/dist/contracts/llm.d.ts +30 -0
- package/dist/contracts/llm.js +2 -0
- package/dist/contracts/llm.js.map +1 -0
- package/dist/contracts/memory.d.ts +47 -0
- package/dist/contracts/memory.js +5 -0
- package/dist/contracts/memory.js.map +1 -0
- package/dist/contracts/vector.d.ts +29 -0
- package/dist/contracts/vector.js +2 -0
- package/dist/contracts/vector.js.map +1 -0
- package/dist/distill/flatten-turns.d.ts +1 -0
- package/dist/distill/flatten-turns.js +50 -0
- package/dist/distill/flatten-turns.js.map +1 -0
- package/dist/distill/pipeline.d.ts +45 -0
- package/dist/distill/pipeline.js +113 -0
- package/dist/distill/pipeline.js.map +1 -0
- package/dist/distill/prompts/extract.d.ts +122 -0
- package/dist/distill/prompts/extract.js +67 -0
- package/dist/distill/prompts/extract.js.map +1 -0
- package/dist/distill/stages/01-cleanup.d.ts +9 -0
- package/dist/distill/stages/01-cleanup.js +67 -0
- package/dist/distill/stages/01-cleanup.js.map +1 -0
- package/dist/distill/stages/02-normalize.d.ts +9 -0
- package/dist/distill/stages/02-normalize.js +76 -0
- package/dist/distill/stages/02-normalize.js.map +1 -0
- package/dist/distill/stages/03-chunk.d.ts +22 -0
- package/dist/distill/stages/03-chunk.js +138 -0
- package/dist/distill/stages/03-chunk.js.map +1 -0
- package/dist/distill/stages/04-compact.d.ts +28 -0
- package/dist/distill/stages/04-compact.js +69 -0
- package/dist/distill/stages/04-compact.js.map +1 -0
- package/dist/distill/stages/05-extract.d.ts +35 -0
- package/dist/distill/stages/05-extract.js +101 -0
- package/dist/distill/stages/05-extract.js.map +1 -0
- package/dist/distill/stages/06-reduce.d.ts +16 -0
- package/dist/distill/stages/06-reduce.js +30 -0
- package/dist/distill/stages/06-reduce.js.map +1 -0
- package/dist/distill/stages/07-memory-normalize.d.ts +27 -0
- package/dist/distill/stages/07-memory-normalize.js +65 -0
- package/dist/distill/stages/07-memory-normalize.js.map +1 -0
- package/dist/distill/stages/08-embed-index.d.ts +31 -0
- package/dist/distill/stages/08-embed-index.js +82 -0
- package/dist/distill/stages/08-embed-index.js.map +1 -0
- package/dist/doctor/checks.d.ts +77 -0
- package/dist/doctor/checks.js +626 -0
- package/dist/doctor/checks.js.map +1 -0
- package/dist/doctor/hardening-checks.d.ts +9 -0
- package/dist/doctor/hardening-checks.js +182 -0
- package/dist/doctor/hardening-checks.js.map +1 -0
- package/dist/doctor/probes/embed-probe.d.ts +19 -0
- package/dist/doctor/probes/embed-probe.js +47 -0
- package/dist/doctor/probes/embed-probe.js.map +1 -0
- package/dist/doctor/probes/llm-chat-probe.d.ts +11 -0
- package/dist/doctor/probes/llm-chat-probe.js +41 -0
- package/dist/doctor/probes/llm-chat-probe.js.map +1 -0
- package/dist/doctor/probes/plugin-coexistence.d.ts +14 -0
- package/dist/doctor/probes/plugin-coexistence.js +60 -0
- package/dist/doctor/probes/plugin-coexistence.js.map +1 -0
- package/dist/doctor/runner.d.ts +17 -0
- package/dist/doctor/runner.js +53 -0
- package/dist/doctor/runner.js.map +1 -0
- package/dist/doctor/types.d.ts +12 -0
- package/dist/doctor/types.js +2 -0
- package/dist/doctor/types.js.map +1 -0
- package/dist/entity/backfill.d.ts +30 -0
- package/dist/entity/backfill.js +55 -0
- package/dist/entity/backfill.js.map +1 -0
- package/dist/entity/extract-entities.d.ts +27 -0
- package/dist/entity/extract-entities.js +86 -0
- package/dist/entity/extract-entities.js.map +1 -0
- package/dist/entity/normalize.d.ts +17 -0
- package/dist/entity/normalize.js +20 -0
- package/dist/entity/normalize.js.map +1 -0
- package/dist/eval/harness.d.ts +96 -0
- package/dist/eval/harness.js +119 -0
- package/dist/eval/harness.js.map +1 -0
- package/dist/eval/metrics.d.ts +23 -0
- package/dist/eval/metrics.js +44 -0
- package/dist/eval/metrics.js.map +1 -0
- package/dist/log/correlation.d.ts +24 -0
- package/dist/log/correlation.js +33 -0
- package/dist/log/correlation.js.map +1 -0
- package/dist/log/logger.d.ts +38 -0
- package/dist/log/logger.js +129 -0
- package/dist/log/logger.js.map +1 -0
- package/dist/log/scrub.d.ts +33 -0
- package/dist/log/scrub.js +91 -0
- package/dist/log/scrub.js.map +1 -0
- package/dist/mcp/server.d.ts +36 -0
- package/dist/mcp/server.js +553 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/memory-tool/adapter.d.ts +73 -0
- package/dist/memory-tool/adapter.js +269 -0
- package/dist/memory-tool/adapter.js.map +1 -0
- package/dist/pipeline/errors.d.ts +21 -0
- package/dist/pipeline/errors.js +34 -0
- package/dist/pipeline/errors.js.map +1 -0
- package/dist/pipeline/failure-classifier.d.ts +13 -0
- package/dist/pipeline/failure-classifier.js +72 -0
- package/dist/pipeline/failure-classifier.js.map +1 -0
- package/dist/pipeline/handler-ctx-ext.d.ts +23 -0
- package/dist/pipeline/handler-ctx-ext.js +19 -0
- package/dist/pipeline/handler-ctx-ext.js.map +1 -0
- package/dist/pipeline/handler.d.ts +20 -0
- package/dist/pipeline/handler.js +2 -0
- package/dist/pipeline/handler.js.map +1 -0
- package/dist/pipeline/handlers/cleanup.d.ts +14 -0
- package/dist/pipeline/handlers/cleanup.js +47 -0
- package/dist/pipeline/handlers/cleanup.js.map +1 -0
- package/dist/pipeline/handlers/consolidate.d.ts +8 -0
- package/dist/pipeline/handlers/consolidate.js +23 -0
- package/dist/pipeline/handlers/consolidate.js.map +1 -0
- package/dist/pipeline/handlers/distill-events.d.ts +15 -0
- package/dist/pipeline/handlers/distill-events.js +134 -0
- package/dist/pipeline/handlers/distill-events.js.map +1 -0
- package/dist/pipeline/handlers/distill.d.ts +17 -0
- package/dist/pipeline/handlers/distill.js +110 -0
- package/dist/pipeline/handlers/distill.js.map +1 -0
- package/dist/pipeline/handlers/reembed.d.ts +10 -0
- package/dist/pipeline/handlers/reembed.js +34 -0
- package/dist/pipeline/handlers/reembed.js.map +1 -0
- package/dist/pipeline/job-repo.d.ts +86 -0
- package/dist/pipeline/job-repo.js +168 -0
- package/dist/pipeline/job-repo.js.map +1 -0
- package/dist/pipeline/mock-providers.d.ts +49 -0
- package/dist/pipeline/mock-providers.js +175 -0
- package/dist/pipeline/mock-providers.js.map +1 -0
- package/dist/pipeline/registry.d.ts +15 -0
- package/dist/pipeline/registry.js +20 -0
- package/dist/pipeline/registry.js.map +1 -0
- package/dist/pipeline/worker.d.ts +41 -0
- package/dist/pipeline/worker.js +167 -0
- package/dist/pipeline/worker.js.map +1 -0
- package/dist/providers/embed/azure-openai.d.ts +25 -0
- package/dist/providers/embed/azure-openai.js +138 -0
- package/dist/providers/embed/azure-openai.js.map +1 -0
- package/dist/providers/embed/ollama.d.ts +17 -0
- package/dist/providers/embed/ollama.js +106 -0
- package/dist/providers/embed/ollama.js.map +1 -0
- package/dist/providers/index.d.ts +19 -0
- package/dist/providers/index.js +72 -0
- package/dist/providers/index.js.map +1 -0
- package/dist/providers/llm/azure-openai.d.ts +20 -0
- package/dist/providers/llm/azure-openai.js +135 -0
- package/dist/providers/llm/azure-openai.js.map +1 -0
- package/dist/providers/llm/ollama.d.ts +13 -0
- package/dist/providers/llm/ollama.js +113 -0
- package/dist/providers/llm/ollama.js.map +1 -0
- package/dist/providers/llm/pricing.d.ts +21 -0
- package/dist/providers/llm/pricing.js +22 -0
- package/dist/providers/llm/pricing.js.map +1 -0
- package/dist/recall/pack.d.ts +32 -0
- package/dist/recall/pack.js +90 -0
- package/dist/recall/pack.js.map +1 -0
- package/dist/recall/policy.d.ts +39 -0
- package/dist/recall/policy.js +96 -0
- package/dist/recall/policy.js.map +1 -0
- package/dist/redact/detectors.d.ts +20 -0
- package/dist/redact/detectors.js +85 -0
- package/dist/redact/detectors.js.map +1 -0
- package/dist/redact/entropy.d.ts +24 -0
- package/dist/redact/entropy.js +77 -0
- package/dist/redact/entropy.js.map +1 -0
- package/dist/redact/index.d.ts +47 -0
- package/dist/redact/index.js +165 -0
- package/dist/redact/index.js.map +1 -0
- package/dist/search/fuse.d.ts +108 -0
- package/dist/search/fuse.js +135 -0
- package/dist/search/fuse.js.map +1 -0
- package/dist/search/query.d.ts +28 -0
- package/dist/search/query.js +70 -0
- package/dist/search/query.js.map +1 -0
- package/dist/search/search.d.ts +164 -0
- package/dist/search/search.js +310 -0
- package/dist/search/search.js.map +1 -0
- package/dist/server/app.d.ts +17 -0
- package/dist/server/app.js +133 -0
- package/dist/server/app.js.map +1 -0
- package/dist/server/health-state.d.ts +29 -0
- package/dist/server/health-state.js +28 -0
- package/dist/server/health-state.js.map +1 -0
- package/dist/server/lib/network.d.ts +12 -0
- package/dist/server/lib/network.js +16 -0
- package/dist/server/lib/network.js.map +1 -0
- package/dist/server/lib/score-contract.d.ts +36 -0
- package/dist/server/lib/score-contract.js +54 -0
- package/dist/server/lib/score-contract.js.map +1 -0
- package/dist/server/lib/stable-stringify.d.ts +10 -0
- package/dist/server/lib/stable-stringify.js +27 -0
- package/dist/server/lib/stable-stringify.js.map +1 -0
- package/dist/server/lib/wire-meta.d.ts +7 -0
- package/dist/server/lib/wire-meta.js +29 -0
- package/dist/server/lib/wire-meta.js.map +1 -0
- package/dist/server/queries/dashboard.d.ts +142 -0
- package/dist/server/queries/dashboard.js +166 -0
- package/dist/server/queries/dashboard.js.map +1 -0
- package/dist/server/routes/consolidation.d.ts +14 -0
- package/dist/server/routes/consolidation.js +67 -0
- package/dist/server/routes/consolidation.js.map +1 -0
- package/dist/server/routes/dashboard-api-html.d.ts +15 -0
- package/dist/server/routes/dashboard-api-html.js +144 -0
- package/dist/server/routes/dashboard-api-html.js.map +1 -0
- package/dist/server/routes/dashboard-consolidation-html.d.ts +26 -0
- package/dist/server/routes/dashboard-consolidation-html.js +202 -0
- package/dist/server/routes/dashboard-consolidation-html.js.map +1 -0
- package/dist/server/routes/dashboard-html.d.ts +15 -0
- package/dist/server/routes/dashboard-html.js +365 -0
- package/dist/server/routes/dashboard-html.js.map +1 -0
- package/dist/server/routes/dashboard-jobs-html.d.ts +18 -0
- package/dist/server/routes/dashboard-jobs-html.js +186 -0
- package/dist/server/routes/dashboard-jobs-html.js.map +1 -0
- package/dist/server/routes/dashboard-search-html.d.ts +18 -0
- package/dist/server/routes/dashboard-search-html.js +189 -0
- package/dist/server/routes/dashboard-search-html.js.map +1 -0
- package/dist/server/routes/dashboard.d.ts +19 -0
- package/dist/server/routes/dashboard.js +68 -0
- package/dist/server/routes/dashboard.js.map +1 -0
- package/dist/server/routes/digest.d.ts +9 -0
- package/dist/server/routes/digest.js +37 -0
- package/dist/server/routes/digest.js.map +1 -0
- package/dist/server/routes/entities.d.ts +12 -0
- package/dist/server/routes/entities.js +46 -0
- package/dist/server/routes/entities.js.map +1 -0
- package/dist/server/routes/health.d.ts +14 -0
- package/dist/server/routes/health.js +100 -0
- package/dist/server/routes/health.js.map +1 -0
- package/dist/server/routes/ingest.d.ts +209 -0
- package/dist/server/routes/ingest.js +454 -0
- package/dist/server/routes/ingest.js.map +1 -0
- package/dist/server/routes/lifecycle.d.ts +21 -0
- package/dist/server/routes/lifecycle.js +132 -0
- package/dist/server/routes/lifecycle.js.map +1 -0
- package/dist/server/routes/mcp.d.ts +15 -0
- package/dist/server/routes/mcp.js +36 -0
- package/dist/server/routes/mcp.js.map +1 -0
- package/dist/server/routes/memory-tool.d.ts +14 -0
- package/dist/server/routes/memory-tool.js +28 -0
- package/dist/server/routes/memory-tool.js.map +1 -0
- package/dist/server/routes/memory.d.ts +7 -0
- package/dist/server/routes/memory.js +19 -0
- package/dist/server/routes/memory.js.map +1 -0
- package/dist/server/routes/recall.d.ts +15 -0
- package/dist/server/routes/recall.js +74 -0
- package/dist/server/routes/recall.js.map +1 -0
- package/dist/server/routes/search.d.ts +12 -0
- package/dist/server/routes/search.js +203 -0
- package/dist/server/routes/search.js.map +1 -0
- package/dist/server/routes/version.d.ts +2 -0
- package/dist/server/routes/version.js +11 -0
- package/dist/server/routes/version.js.map +1 -0
- package/dist/server/routes/why.d.ts +9 -0
- package/dist/server/routes/why.js +38 -0
- package/dist/server/routes/why.js.map +1 -0
- package/dist/service/index.d.ts +10 -0
- package/dist/service/index.js +25 -0
- package/dist/service/index.js.map +1 -0
- package/dist/service/install-flow.d.ts +18 -0
- package/dist/service/install-flow.js +47 -0
- package/dist/service/install-flow.js.map +1 -0
- package/dist/service/instance-lock.d.ts +26 -0
- package/dist/service/instance-lock.js +150 -0
- package/dist/service/instance-lock.js.map +1 -0
- package/dist/service/launchd.d.ts +11 -0
- package/dist/service/launchd.js +196 -0
- package/dist/service/launchd.js.map +1 -0
- package/dist/service/schtasks.d.ts +31 -0
- package/dist/service/schtasks.js +274 -0
- package/dist/service/schtasks.js.map +1 -0
- package/dist/service/shim.d.ts +21 -0
- package/dist/service/shim.js +80 -0
- package/dist/service/shim.js.map +1 -0
- package/dist/service/systemd.d.ts +11 -0
- package/dist/service/systemd.js +150 -0
- package/dist/service/systemd.js.map +1 -0
- package/dist/service/task-xml.d.ts +36 -0
- package/dist/service/task-xml.js +91 -0
- package/dist/service/task-xml.js.map +1 -0
- package/dist/service/types.d.ts +47 -0
- package/dist/service/types.js +2 -0
- package/dist/service/types.js.map +1 -0
- package/dist/storage/archival.d.ts +29 -0
- package/dist/storage/archival.js +47 -0
- package/dist/storage/archival.js.map +1 -0
- package/dist/storage/bearer-keystore.d.ts +34 -0
- package/dist/storage/bearer-keystore.js +75 -0
- package/dist/storage/bearer-keystore.js.map +1 -0
- package/dist/storage/db.d.ts +37 -0
- package/dist/storage/db.js +92 -0
- package/dist/storage/db.js.map +1 -0
- package/dist/storage/entities.d.ts +71 -0
- package/dist/storage/entities.js +141 -0
- package/dist/storage/entities.js.map +1 -0
- package/dist/storage/ingest-idempotency.d.ts +26 -0
- package/dist/storage/ingest-idempotency.js +29 -0
- package/dist/storage/ingest-idempotency.js.map +1 -0
- package/dist/storage/keystore.d.ts +64 -0
- package/dist/storage/keystore.js +194 -0
- package/dist/storage/keystore.js.map +1 -0
- package/dist/storage/memories.d.ts +51 -0
- package/dist/storage/memories.js +67 -0
- package/dist/storage/memories.js.map +1 -0
- package/dist/storage/memory-events.d.ts +145 -0
- package/dist/storage/memory-events.js +287 -0
- package/dist/storage/memory-events.js.map +1 -0
- package/dist/storage/migrate-encrypt.d.ts +16 -0
- package/dist/storage/migrate-encrypt.js +121 -0
- package/dist/storage/migrate-encrypt.js.map +1 -0
- package/dist/storage/migrate.d.ts +27 -0
- package/dist/storage/migrate.js +105 -0
- package/dist/storage/migrate.js.map +1 -0
- package/dist/storage/redaction-log.d.ts +18 -0
- package/dist/storage/redaction-log.js +27 -0
- package/dist/storage/redaction-log.js.map +1 -0
- package/dist/storage/usefulness.d.ts +115 -0
- package/dist/storage/usefulness.js +203 -0
- package/dist/storage/usefulness.js.map +1 -0
- package/dist/sync/conflict-resolve.d.ts +26 -0
- package/dist/sync/conflict-resolve.js +139 -0
- package/dist/sync/conflict-resolve.js.map +1 -0
- package/dist/sync/puller.d.ts +115 -0
- package/dist/sync/puller.js +173 -0
- package/dist/sync/puller.js.map +1 -0
- package/dist/sync/shipper.d.ts +112 -0
- package/dist/sync/shipper.js +189 -0
- package/dist/sync/shipper.js.map +1 -0
- package/dist/tag-hygiene/backfill.d.ts +50 -0
- package/dist/tag-hygiene/backfill.js +117 -0
- package/dist/tag-hygiene/backfill.js.map +1 -0
- package/dist/tag-hygiene/derive-repo.d.ts +9 -0
- package/dist/tag-hygiene/derive-repo.js +19 -0
- package/dist/tag-hygiene/derive-repo.js.map +1 -0
- package/dist/tag-hygiene/tier2-infer.d.ts +28 -0
- package/dist/tag-hygiene/tier2-infer.js +72 -0
- package/dist/tag-hygiene/tier2-infer.js.map +1 -0
- package/dist/vector/sqlite-vec.d.ts +16 -0
- package/dist/vector/sqlite-vec.js +49 -0
- package/dist/vector/sqlite-vec.js.map +1 -0
- package/migrations/001-init.sql +117 -0
- package/migrations/002-wire-v1.sql +16 -0
- package/migrations/003-expand-memory-types.sql +81 -0
- package/migrations/004-provenance.sql +4 -0
- package/migrations/005-security.sql +12 -0
- package/migrations/006-atom-v3.sql +28 -0
- package/migrations/007-memory-events.sql +30 -0
- package/migrations/008-consolidation.sql +31 -0
- package/migrations/009-tag-hygiene.sql +13 -0
- package/migrations/010-sync-pull.sql +53 -0
- package/migrations/011-embed-dim-migration.sql +28 -0
- package/migrations/012-entities.sql +36 -0
- package/migrations/013-archival.sql +50 -0
- package/package.json +50 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { DB } from './db.js';
|
|
2
|
+
import type { Memory, MemoryScope, MemoryType } from '../contracts/index.js';
|
|
3
|
+
import type { MemoryEventRepo } from './memory-events.js';
|
|
4
|
+
export interface InsertInput {
|
|
5
|
+
type: MemoryType;
|
|
6
|
+
text: string;
|
|
7
|
+
normalized_text: string;
|
|
8
|
+
repo: string | null;
|
|
9
|
+
project: string | null;
|
|
10
|
+
branch: string | null;
|
|
11
|
+
agent: string | null;
|
|
12
|
+
session_id: string | null;
|
|
13
|
+
hash: string;
|
|
14
|
+
source_hash: string | null;
|
|
15
|
+
importance?: number;
|
|
16
|
+
confidence?: number;
|
|
17
|
+
embedding_provider?: string | null;
|
|
18
|
+
embedding_model?: string | null;
|
|
19
|
+
embedding_dim?: number | null;
|
|
20
|
+
evidence?: string | null;
|
|
21
|
+
/** ADR-009 scope. Defaults to 'personal'. */
|
|
22
|
+
scope?: MemoryScope;
|
|
23
|
+
}
|
|
24
|
+
export interface FtsHit {
|
|
25
|
+
id: string;
|
|
26
|
+
text: string;
|
|
27
|
+
type: MemoryType;
|
|
28
|
+
bm25: number;
|
|
29
|
+
}
|
|
30
|
+
export declare class MemoryRepo {
|
|
31
|
+
private db;
|
|
32
|
+
constructor(db: DB);
|
|
33
|
+
insert(input: InsertInput): string;
|
|
34
|
+
/**
|
|
35
|
+
* Insert + append a 'create' memory_event (ADR-002) in the SAME
|
|
36
|
+
* transaction. Dedup-aware like insert(): if a memory with this hash
|
|
37
|
+
* already exists, no row is inserted and no event is appended — matches
|
|
38
|
+
* insert()'s existing dedup semantics, so a re-ingest never fabricates a
|
|
39
|
+
* duplicate create event for an atom that already has one.
|
|
40
|
+
*/
|
|
41
|
+
insertWithCreateEvent(input: InsertInput, events: MemoryEventRepo): {
|
|
42
|
+
id: string;
|
|
43
|
+
created: boolean;
|
|
44
|
+
};
|
|
45
|
+
/** Raw insert — no dedup check (caller has already decided to insert). */
|
|
46
|
+
private insertRow;
|
|
47
|
+
get(id: string): Memory | null;
|
|
48
|
+
/** Parse the JSON-stored derived_from column into a string[] | null. */
|
|
49
|
+
private static hydrate;
|
|
50
|
+
searchFts(query: string, limit: number): FtsHit[];
|
|
51
|
+
}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
export class MemoryRepo {
|
|
3
|
+
db;
|
|
4
|
+
constructor(db) {
|
|
5
|
+
this.db = db;
|
|
6
|
+
}
|
|
7
|
+
insert(input) {
|
|
8
|
+
const existing = this.db.prepare('SELECT id FROM memories WHERE hash = ?').get(input.hash);
|
|
9
|
+
if (existing)
|
|
10
|
+
return existing.id;
|
|
11
|
+
return this.insertRow(input);
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Insert + append a 'create' memory_event (ADR-002) in the SAME
|
|
15
|
+
* transaction. Dedup-aware like insert(): if a memory with this hash
|
|
16
|
+
* already exists, no row is inserted and no event is appended — matches
|
|
17
|
+
* insert()'s existing dedup semantics, so a re-ingest never fabricates a
|
|
18
|
+
* duplicate create event for an atom that already has one.
|
|
19
|
+
*/
|
|
20
|
+
insertWithCreateEvent(input, events) {
|
|
21
|
+
const tx = this.db.transaction(() => {
|
|
22
|
+
const existing = this.db.prepare('SELECT id FROM memories WHERE hash = ?').get(input.hash);
|
|
23
|
+
if (existing)
|
|
24
|
+
return { id: existing.id, created: false };
|
|
25
|
+
const id = this.insertRow(input);
|
|
26
|
+
events.append({ event_type: 'create', atom_id: id, content_hash: input.hash });
|
|
27
|
+
return { id, created: true };
|
|
28
|
+
});
|
|
29
|
+
return tx();
|
|
30
|
+
}
|
|
31
|
+
/** Raw insert — no dedup check (caller has already decided to insert). */
|
|
32
|
+
insertRow(input) {
|
|
33
|
+
const id = randomUUID();
|
|
34
|
+
const now = Date.now();
|
|
35
|
+
this.db.prepare(`
|
|
36
|
+
INSERT INTO memories
|
|
37
|
+
(id, type, text, normalized_text, repo, project, branch, agent, session_id,
|
|
38
|
+
importance, confidence, hash, embedding_provider, embedding_model, embedding_dim,
|
|
39
|
+
created_at, updated_at, source_hash, evidence, valid_from, scope)
|
|
40
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
|
41
|
+
`).run(id, input.type, input.text, input.normalized_text, input.repo, input.project, input.branch, input.agent, input.session_id, input.importance ?? 0.5, input.confidence ?? 0.5, input.hash, input.embedding_provider ?? null, input.embedding_model ?? null, input.embedding_dim ?? null, now, now, input.source_hash, input.evidence ?? null, now, input.scope ?? 'personal');
|
|
42
|
+
return id;
|
|
43
|
+
}
|
|
44
|
+
get(id) {
|
|
45
|
+
const row = this.db.prepare('SELECT * FROM memories WHERE id = ?').get(id);
|
|
46
|
+
return row ? MemoryRepo.hydrate(row) : null;
|
|
47
|
+
}
|
|
48
|
+
/** Parse the JSON-stored derived_from column into a string[] | null. */
|
|
49
|
+
static hydrate(row) {
|
|
50
|
+
return {
|
|
51
|
+
...row,
|
|
52
|
+
derived_from: row.derived_from ? JSON.parse(row.derived_from) : null,
|
|
53
|
+
archived: row.archived === 1,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
searchFts(query, limit) {
|
|
57
|
+
const rows = this.db.prepare(`
|
|
58
|
+
SELECT m.id, m.text, m.type, bm25(memories_fts) AS bm25
|
|
59
|
+
FROM memories_fts
|
|
60
|
+
JOIN memories m ON m.rowid = memories_fts.rowid
|
|
61
|
+
WHERE memories_fts MATCH ?
|
|
62
|
+
ORDER BY bm25 LIMIT ?
|
|
63
|
+
`).all(query, limit);
|
|
64
|
+
return rows;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=memories.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memories.js","sourceRoot":"","sources":["../../src/storage/memories.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memory_events append-only log + lifecycle operations (ADR-002 decision
|
|
3
|
+
* point 1, migration 007). The log is the source of truth for state
|
|
4
|
+
* *changes*; the materialized `memories` row is updated in the SAME
|
|
5
|
+
* transaction as the event append (log + tables in one file, not full event
|
|
6
|
+
* sourcing — no view rebuilding, no projection framework).
|
|
7
|
+
*/
|
|
8
|
+
import type { DB } from './db.js';
|
|
9
|
+
import type { MemoryScope } from '../contracts/index.js';
|
|
10
|
+
export type MemoryEventType = 'create' | 'invalidate' | 'supersede' | 'promote_scope' | 'erase_request' | 'usefulness' | 'archive' | 'restore';
|
|
11
|
+
export interface MemoryEvent {
|
|
12
|
+
seq: number;
|
|
13
|
+
event_id: string;
|
|
14
|
+
event_type: MemoryEventType;
|
|
15
|
+
atom_id: string;
|
|
16
|
+
payload_json: string | null;
|
|
17
|
+
content_hash: string | null;
|
|
18
|
+
created_at: number;
|
|
19
|
+
synced_at: number | null;
|
|
20
|
+
}
|
|
21
|
+
export interface AppendEventInput {
|
|
22
|
+
event_type: MemoryEventType;
|
|
23
|
+
atom_id: string;
|
|
24
|
+
/** JSON-serialized on write; use listForAtom + JSON.parse to read back. */
|
|
25
|
+
payload?: unknown;
|
|
26
|
+
content_hash?: string | null;
|
|
27
|
+
created_at?: number;
|
|
28
|
+
/**
|
|
29
|
+
* Globally-unique event identity (ADR-011). Local single-device writers
|
|
30
|
+
* never pass this — it is always freshly generated (node:crypto
|
|
31
|
+
* randomUUID()). Only the pull-ingest path (src/sync/puller.ts) writes
|
|
32
|
+
* remote-originated events with their OWN pre-existing event_id, and it
|
|
33
|
+
* does so via a raw dedup-insert, not through this method — append() is
|
|
34
|
+
* exclusively the local-origin path.
|
|
35
|
+
*/
|
|
36
|
+
event_id?: string;
|
|
37
|
+
}
|
|
38
|
+
/** Memory not found for the requested lifecycle op — maps to HTTP 404. */
|
|
39
|
+
export declare class MemoryNotFoundError extends Error {
|
|
40
|
+
readonly atomId: string;
|
|
41
|
+
constructor(atomId: string);
|
|
42
|
+
}
|
|
43
|
+
/** State conflict (e.g. already invalidated) — maps to HTTP 409. */
|
|
44
|
+
export declare class MemoryConflictError extends Error {
|
|
45
|
+
constructor(message: string);
|
|
46
|
+
}
|
|
47
|
+
/** Invalid scope transition (e.g. downward promotion) — maps to HTTP 400. */
|
|
48
|
+
export declare class InvalidScopeTransitionError extends Error {
|
|
49
|
+
constructor(message: string);
|
|
50
|
+
}
|
|
51
|
+
export declare class MemoryEventRepo {
|
|
52
|
+
private db;
|
|
53
|
+
constructor(db: DB);
|
|
54
|
+
/** Low-level append. Caller owns the transaction boundary. */
|
|
55
|
+
append(event: AppendEventInput): number;
|
|
56
|
+
/** Full event log for one atom, ordered by seq (append order). */
|
|
57
|
+
listForAtom(atomId: string): MemoryEvent[];
|
|
58
|
+
/**
|
|
59
|
+
* Invalidate a memory: sets valid_to = now, appends an 'invalidate' event,
|
|
60
|
+
* both in one transaction. Idempotent-safe: throws MemoryConflictError if
|
|
61
|
+
* the memory is already invalid rather than silently double-invalidating.
|
|
62
|
+
*/
|
|
63
|
+
invalidate(atomId: string, reason?: string): void;
|
|
64
|
+
/**
|
|
65
|
+
* Supersede oldId with newId: sets old.valid_to = now AND
|
|
66
|
+
* old.superseded_by = newId, appends a 'supersede' event on oldId — all in
|
|
67
|
+
* one transaction. Validates both ids exist; oldId must currently be valid
|
|
68
|
+
* (not already invalidated/superseded); newId must be valid (valid_to null).
|
|
69
|
+
*
|
|
70
|
+
* FEAT-401 fix: also co-issues newId.valid_from = the SAME `now` used for
|
|
71
|
+
* old.valid_to. Without this, newId keeps the valid_from it was stamped
|
|
72
|
+
* with at insert() time (which normally predates the supersede() call by
|
|
73
|
+
* however long the caller took to decide to supersede), producing an
|
|
74
|
+
* overlap window [newId.valid_from, oldId.valid_to) where an as_of query
|
|
75
|
+
* would match BOTH generations — a bitemporal-window leak. Co-issuing the
|
|
76
|
+
* boundary keeps the two windows contiguous and non-overlapping
|
|
77
|
+
* (old.valid_to === new.valid_from), matching the half-open-interval
|
|
78
|
+
* model as_of resolution assumes (ADR-001, FEAT-401 AC-1/AC-5): the
|
|
79
|
+
* successor becomes "the believed value" exactly as of the supersede
|
|
80
|
+
* instant, not as of whenever it happened to be inserted.
|
|
81
|
+
*
|
|
82
|
+
* FEAT-402 AC-3: also deletes oldId's memory_entities links in the same
|
|
83
|
+
* transaction. The memories row itself is NOT deleted (bitemporal history
|
|
84
|
+
* is kept for as_of queries), so this can't rely on the erase() path's
|
|
85
|
+
* ON DELETE CASCADE — it's explicit here instead. A superseded memory's
|
|
86
|
+
* facts should stop counting as current evidence for an entity even
|
|
87
|
+
* though the row survives for audit.
|
|
88
|
+
*/
|
|
89
|
+
supersede(oldId: string, newId: string): void;
|
|
90
|
+
/**
|
|
91
|
+
* Archive a memory (FEAT-404 TTL/archival tiers): sets valid_to = now +
|
|
92
|
+
* archived = 1 + archived_at = now, appends an 'archive' event — all in
|
|
93
|
+
* one transaction. Reuses the exact non-destructive valid_to bookkeeping
|
|
94
|
+
* invalidate()/supersede() already use (row survives, restorable via
|
|
95
|
+
* restore()) — the only difference is *why* the row stopped being
|
|
96
|
+
* current, which is why this is a distinct event type rather than a
|
|
97
|
+
* relabeled invalidate().
|
|
98
|
+
*
|
|
99
|
+
* Deliberately does NOT append a 'memory_corrected' usefulness signal the
|
|
100
|
+
* way invalidate()/supersede() do: staleness-triggered archival is
|
|
101
|
+
* routine housekeeping driven by low usefulness, not a correction of a
|
|
102
|
+
* wrong/superseded fact — appending one would create a feedback loop
|
|
103
|
+
* that further penalizes an atom the policy might restore later.
|
|
104
|
+
*
|
|
105
|
+
* Throws MemoryConflictError if the memory is already invalid (including
|
|
106
|
+
* already archived) rather than silently double-archiving.
|
|
107
|
+
*/
|
|
108
|
+
archive(atomId: string, reason?: string): void;
|
|
109
|
+
/**
|
|
110
|
+
* Restore a previously-archived memory (FEAT-404 AC-4): clears valid_to
|
|
111
|
+
* and archived/archived_at, appends a 'restore' event — all in one
|
|
112
|
+
* transaction. The memory immediately re-qualifies for every
|
|
113
|
+
* `valid_to IS NULL` candidate filter (search.ts, recall/pack.ts), so it
|
|
114
|
+
* reappears in search with no further wiring needed.
|
|
115
|
+
*
|
|
116
|
+
* Throws MemoryNotFoundError if the id doesn't exist, MemoryConflictError
|
|
117
|
+
* if it isn't currently archived (e.g. it was invalidated/superseded
|
|
118
|
+
* through a different path, or was never archived).
|
|
119
|
+
*/
|
|
120
|
+
restore(atomId: string): void;
|
|
121
|
+
/**
|
|
122
|
+
* Promote a memory's scope: personal -> team -> org (ADR-009). Only
|
|
123
|
+
* upward promotions are allowed; same-scope or downward requests throw
|
|
124
|
+
* InvalidScopeTransitionError. State update + event append in one
|
|
125
|
+
* transaction.
|
|
126
|
+
*/
|
|
127
|
+
promoteScope(atomId: string, toScope: MemoryScope): void;
|
|
128
|
+
/**
|
|
129
|
+
* Erase a memory (erasure v1, ADR-006 W5): HARD-deletes the memories row
|
|
130
|
+
* (FTS cleans up via the AFTER DELETE trigger) and its vector index row,
|
|
131
|
+
* and appends an 'erase_request' event — the event IS the tombstone:
|
|
132
|
+
* - payload.scope lets the sync shipper (ADR-009) ship the tombstone to
|
|
133
|
+
* the cloud even though the memories row is gone,
|
|
134
|
+
* - content_hash = the memory's hash powers the replay filter (stage 8
|
|
135
|
+
* refuses to resurrect an erased memory on re-distillation).
|
|
136
|
+
* Erasure always wins over retention/replay — the text is unrecoverable
|
|
137
|
+
* locally after this call.
|
|
138
|
+
*/
|
|
139
|
+
erase(atomId: string, reason?: string): void;
|
|
140
|
+
/**
|
|
141
|
+
* Replay filter (erasure v1): true when a memory with this content hash
|
|
142
|
+
* has been erased — re-distillation must not resurrect it.
|
|
143
|
+
*/
|
|
144
|
+
isErasedHash(contentHash: string): boolean;
|
|
145
|
+
}
|
|
@@ -0,0 +1,287 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* memory_events append-only log + lifecycle operations (ADR-002 decision
|
|
3
|
+
* point 1, migration 007). The log is the source of truth for state
|
|
4
|
+
* *changes*; the materialized `memories` row is updated in the SAME
|
|
5
|
+
* transaction as the event append (log + tables in one file, not full event
|
|
6
|
+
* sourcing — no view rebuilding, no projection framework).
|
|
7
|
+
*/
|
|
8
|
+
import { randomUUID } from 'node:crypto';
|
|
9
|
+
/** Memory not found for the requested lifecycle op — maps to HTTP 404. */
|
|
10
|
+
export class MemoryNotFoundError extends Error {
|
|
11
|
+
atomId;
|
|
12
|
+
constructor(atomId) {
|
|
13
|
+
super(`memory not found: ${atomId}`);
|
|
14
|
+
this.atomId = atomId;
|
|
15
|
+
this.name = 'MemoryNotFoundError';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
/** State conflict (e.g. already invalidated) — maps to HTTP 409. */
|
|
19
|
+
export class MemoryConflictError extends Error {
|
|
20
|
+
constructor(message) {
|
|
21
|
+
super(message);
|
|
22
|
+
this.name = 'MemoryConflictError';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
/** Invalid scope transition (e.g. downward promotion) — maps to HTTP 400. */
|
|
26
|
+
export class InvalidScopeTransitionError extends Error {
|
|
27
|
+
constructor(message) {
|
|
28
|
+
super(message);
|
|
29
|
+
this.name = 'InvalidScopeTransitionError';
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
// ADR-009: scope only ever moves upward — personal -> team -> org.
|
|
33
|
+
const SCOPE_RANK = { personal: 0, team: 1, org: 2 };
|
|
34
|
+
export class MemoryEventRepo {
|
|
35
|
+
db;
|
|
36
|
+
constructor(db) {
|
|
37
|
+
this.db = db;
|
|
38
|
+
}
|
|
39
|
+
/** Low-level append. Caller owns the transaction boundary. */
|
|
40
|
+
append(event) {
|
|
41
|
+
const createdAt = event.created_at ?? Date.now();
|
|
42
|
+
const payloadJson = event.payload !== undefined ? JSON.stringify(event.payload) : null;
|
|
43
|
+
const eventId = event.event_id ?? randomUUID();
|
|
44
|
+
const result = this.db
|
|
45
|
+
.prepare(`
|
|
46
|
+
INSERT INTO memory_events (event_id, event_type, atom_id, payload_json, content_hash, created_at)
|
|
47
|
+
VALUES (?, ?, ?, ?, ?, ?)
|
|
48
|
+
`)
|
|
49
|
+
.run(eventId, event.event_type, event.atom_id, payloadJson, event.content_hash ?? null, createdAt);
|
|
50
|
+
return Number(result.lastInsertRowid);
|
|
51
|
+
}
|
|
52
|
+
/** Full event log for one atom, ordered by seq (append order). */
|
|
53
|
+
listForAtom(atomId) {
|
|
54
|
+
return this.db
|
|
55
|
+
.prepare('SELECT * FROM memory_events WHERE atom_id = ? ORDER BY seq ASC')
|
|
56
|
+
.all(atomId);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Invalidate a memory: sets valid_to = now, appends an 'invalidate' event,
|
|
60
|
+
* both in one transaction. Idempotent-safe: throws MemoryConflictError if
|
|
61
|
+
* the memory is already invalid rather than silently double-invalidating.
|
|
62
|
+
*/
|
|
63
|
+
invalidate(atomId, reason) {
|
|
64
|
+
const tx = this.db.transaction(() => {
|
|
65
|
+
const row = this.db
|
|
66
|
+
.prepare('SELECT id, valid_to FROM memories WHERE id = ?')
|
|
67
|
+
.get(atomId);
|
|
68
|
+
if (!row)
|
|
69
|
+
throw new MemoryNotFoundError(atomId);
|
|
70
|
+
if (row.valid_to !== null) {
|
|
71
|
+
throw new MemoryConflictError(`memory ${atomId} is already invalid`);
|
|
72
|
+
}
|
|
73
|
+
const now = Date.now();
|
|
74
|
+
this.db.prepare('UPDATE memories SET valid_to = ?, updated_at = ? WHERE id = ?').run(now, now, atomId);
|
|
75
|
+
this.append({ event_type: 'invalidate', atom_id: atomId, payload: { reason: reason ?? null }, created_at: now });
|
|
76
|
+
// ADR-010: negative usefulness signal — same tx as the state change.
|
|
77
|
+
// Payload shape documented in src/storage/usefulness.ts (memory_corrected family).
|
|
78
|
+
this.append({
|
|
79
|
+
event_type: 'usefulness',
|
|
80
|
+
atom_id: atomId,
|
|
81
|
+
payload: { family: 'memory_corrected', action: 'invalidated' },
|
|
82
|
+
created_at: now,
|
|
83
|
+
});
|
|
84
|
+
});
|
|
85
|
+
tx();
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Supersede oldId with newId: sets old.valid_to = now AND
|
|
89
|
+
* old.superseded_by = newId, appends a 'supersede' event on oldId — all in
|
|
90
|
+
* one transaction. Validates both ids exist; oldId must currently be valid
|
|
91
|
+
* (not already invalidated/superseded); newId must be valid (valid_to null).
|
|
92
|
+
*
|
|
93
|
+
* FEAT-401 fix: also co-issues newId.valid_from = the SAME `now` used for
|
|
94
|
+
* old.valid_to. Without this, newId keeps the valid_from it was stamped
|
|
95
|
+
* with at insert() time (which normally predates the supersede() call by
|
|
96
|
+
* however long the caller took to decide to supersede), producing an
|
|
97
|
+
* overlap window [newId.valid_from, oldId.valid_to) where an as_of query
|
|
98
|
+
* would match BOTH generations — a bitemporal-window leak. Co-issuing the
|
|
99
|
+
* boundary keeps the two windows contiguous and non-overlapping
|
|
100
|
+
* (old.valid_to === new.valid_from), matching the half-open-interval
|
|
101
|
+
* model as_of resolution assumes (ADR-001, FEAT-401 AC-1/AC-5): the
|
|
102
|
+
* successor becomes "the believed value" exactly as of the supersede
|
|
103
|
+
* instant, not as of whenever it happened to be inserted.
|
|
104
|
+
*
|
|
105
|
+
* FEAT-402 AC-3: also deletes oldId's memory_entities links in the same
|
|
106
|
+
* transaction. The memories row itself is NOT deleted (bitemporal history
|
|
107
|
+
* is kept for as_of queries), so this can't rely on the erase() path's
|
|
108
|
+
* ON DELETE CASCADE — it's explicit here instead. A superseded memory's
|
|
109
|
+
* facts should stop counting as current evidence for an entity even
|
|
110
|
+
* though the row survives for audit.
|
|
111
|
+
*/
|
|
112
|
+
supersede(oldId, newId) {
|
|
113
|
+
const tx = this.db.transaction(() => {
|
|
114
|
+
const oldRow = this.db
|
|
115
|
+
.prepare('SELECT id, valid_to FROM memories WHERE id = ?')
|
|
116
|
+
.get(oldId);
|
|
117
|
+
if (!oldRow)
|
|
118
|
+
throw new MemoryNotFoundError(oldId);
|
|
119
|
+
const newRow = this.db
|
|
120
|
+
.prepare('SELECT id, valid_to FROM memories WHERE id = ?')
|
|
121
|
+
.get(newId);
|
|
122
|
+
if (!newRow)
|
|
123
|
+
throw new MemoryNotFoundError(newId);
|
|
124
|
+
if (oldRow.valid_to !== null) {
|
|
125
|
+
throw new MemoryConflictError(`memory ${oldId} is already invalid`);
|
|
126
|
+
}
|
|
127
|
+
if (newRow.valid_to !== null) {
|
|
128
|
+
throw new MemoryConflictError(`memory ${newId} must be valid to supersede with — it is already invalid`);
|
|
129
|
+
}
|
|
130
|
+
const now = Date.now();
|
|
131
|
+
this.db
|
|
132
|
+
.prepare('UPDATE memories SET valid_to = ?, superseded_by = ?, updated_at = ? WHERE id = ?')
|
|
133
|
+
.run(now, newId, now, oldId);
|
|
134
|
+
this.db
|
|
135
|
+
.prepare('UPDATE memories SET valid_from = ?, updated_at = ? WHERE id = ?')
|
|
136
|
+
.run(now, now, newId);
|
|
137
|
+
// FEAT-402 AC-3: zero orphan links — the superseded memory no longer
|
|
138
|
+
// contributes to "everything about entity X".
|
|
139
|
+
this.db.prepare('DELETE FROM memory_entities WHERE memory_id = ?').run(oldId);
|
|
140
|
+
this.append({ event_type: 'supersede', atom_id: oldId, payload: { superseded_by: newId }, created_at: now });
|
|
141
|
+
// ADR-010: negative usefulness signal — same tx as the state change.
|
|
142
|
+
// Payload shape documented in src/storage/usefulness.ts (memory_corrected family).
|
|
143
|
+
this.append({
|
|
144
|
+
event_type: 'usefulness',
|
|
145
|
+
atom_id: oldId,
|
|
146
|
+
payload: { family: 'memory_corrected', action: 'superseded' },
|
|
147
|
+
created_at: now,
|
|
148
|
+
});
|
|
149
|
+
});
|
|
150
|
+
tx();
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Archive a memory (FEAT-404 TTL/archival tiers): sets valid_to = now +
|
|
154
|
+
* archived = 1 + archived_at = now, appends an 'archive' event — all in
|
|
155
|
+
* one transaction. Reuses the exact non-destructive valid_to bookkeeping
|
|
156
|
+
* invalidate()/supersede() already use (row survives, restorable via
|
|
157
|
+
* restore()) — the only difference is *why* the row stopped being
|
|
158
|
+
* current, which is why this is a distinct event type rather than a
|
|
159
|
+
* relabeled invalidate().
|
|
160
|
+
*
|
|
161
|
+
* Deliberately does NOT append a 'memory_corrected' usefulness signal the
|
|
162
|
+
* way invalidate()/supersede() do: staleness-triggered archival is
|
|
163
|
+
* routine housekeeping driven by low usefulness, not a correction of a
|
|
164
|
+
* wrong/superseded fact — appending one would create a feedback loop
|
|
165
|
+
* that further penalizes an atom the policy might restore later.
|
|
166
|
+
*
|
|
167
|
+
* Throws MemoryConflictError if the memory is already invalid (including
|
|
168
|
+
* already archived) rather than silently double-archiving.
|
|
169
|
+
*/
|
|
170
|
+
archive(atomId, reason) {
|
|
171
|
+
const tx = this.db.transaction(() => {
|
|
172
|
+
const row = this.db
|
|
173
|
+
.prepare('SELECT id, valid_to, archived FROM memories WHERE id = ?')
|
|
174
|
+
.get(atomId);
|
|
175
|
+
if (!row)
|
|
176
|
+
throw new MemoryNotFoundError(atomId);
|
|
177
|
+
if (row.valid_to !== null) {
|
|
178
|
+
throw new MemoryConflictError(`memory ${atomId} is already invalid — cannot archive`);
|
|
179
|
+
}
|
|
180
|
+
const now = Date.now();
|
|
181
|
+
this.db
|
|
182
|
+
.prepare('UPDATE memories SET valid_to = ?, archived = 1, archived_at = ?, updated_at = ? WHERE id = ?')
|
|
183
|
+
.run(now, now, now, atomId);
|
|
184
|
+
this.append({ event_type: 'archive', atom_id: atomId, payload: { reason: reason ?? null }, created_at: now });
|
|
185
|
+
});
|
|
186
|
+
tx();
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Restore a previously-archived memory (FEAT-404 AC-4): clears valid_to
|
|
190
|
+
* and archived/archived_at, appends a 'restore' event — all in one
|
|
191
|
+
* transaction. The memory immediately re-qualifies for every
|
|
192
|
+
* `valid_to IS NULL` candidate filter (search.ts, recall/pack.ts), so it
|
|
193
|
+
* reappears in search with no further wiring needed.
|
|
194
|
+
*
|
|
195
|
+
* Throws MemoryNotFoundError if the id doesn't exist, MemoryConflictError
|
|
196
|
+
* if it isn't currently archived (e.g. it was invalidated/superseded
|
|
197
|
+
* through a different path, or was never archived).
|
|
198
|
+
*/
|
|
199
|
+
restore(atomId) {
|
|
200
|
+
const tx = this.db.transaction(() => {
|
|
201
|
+
const row = this.db
|
|
202
|
+
.prepare('SELECT id, valid_to, archived FROM memories WHERE id = ?')
|
|
203
|
+
.get(atomId);
|
|
204
|
+
if (!row)
|
|
205
|
+
throw new MemoryNotFoundError(atomId);
|
|
206
|
+
if (row.archived !== 1) {
|
|
207
|
+
throw new MemoryConflictError(`memory ${atomId} is not archived`);
|
|
208
|
+
}
|
|
209
|
+
const now = Date.now();
|
|
210
|
+
this.db
|
|
211
|
+
.prepare('UPDATE memories SET valid_to = NULL, archived = 0, archived_at = NULL, updated_at = ? WHERE id = ?')
|
|
212
|
+
.run(now, atomId);
|
|
213
|
+
this.append({ event_type: 'restore', atom_id: atomId, created_at: now });
|
|
214
|
+
});
|
|
215
|
+
tx();
|
|
216
|
+
}
|
|
217
|
+
/**
|
|
218
|
+
* Promote a memory's scope: personal -> team -> org (ADR-009). Only
|
|
219
|
+
* upward promotions are allowed; same-scope or downward requests throw
|
|
220
|
+
* InvalidScopeTransitionError. State update + event append in one
|
|
221
|
+
* transaction.
|
|
222
|
+
*/
|
|
223
|
+
promoteScope(atomId, toScope) {
|
|
224
|
+
const tx = this.db.transaction(() => {
|
|
225
|
+
const row = this.db
|
|
226
|
+
.prepare('SELECT id, scope FROM memories WHERE id = ?')
|
|
227
|
+
.get(atomId);
|
|
228
|
+
if (!row)
|
|
229
|
+
throw new MemoryNotFoundError(atomId);
|
|
230
|
+
if (SCOPE_RANK[toScope] <= SCOPE_RANK[row.scope]) {
|
|
231
|
+
throw new InvalidScopeTransitionError(`cannot promote memory ${atomId} from '${row.scope}' to '${toScope}' — only upward promotions allowed (personal -> team -> org)`);
|
|
232
|
+
}
|
|
233
|
+
const now = Date.now();
|
|
234
|
+
this.db.prepare('UPDATE memories SET scope = ?, updated_at = ? WHERE id = ?').run(toScope, now, atomId);
|
|
235
|
+
this.append({
|
|
236
|
+
event_type: 'promote_scope',
|
|
237
|
+
atom_id: atomId,
|
|
238
|
+
payload: { from: row.scope, to: toScope },
|
|
239
|
+
created_at: now,
|
|
240
|
+
});
|
|
241
|
+
});
|
|
242
|
+
tx();
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Erase a memory (erasure v1, ADR-006 W5): HARD-deletes the memories row
|
|
246
|
+
* (FTS cleans up via the AFTER DELETE trigger) and its vector index row,
|
|
247
|
+
* and appends an 'erase_request' event — the event IS the tombstone:
|
|
248
|
+
* - payload.scope lets the sync shipper (ADR-009) ship the tombstone to
|
|
249
|
+
* the cloud even though the memories row is gone,
|
|
250
|
+
* - content_hash = the memory's hash powers the replay filter (stage 8
|
|
251
|
+
* refuses to resurrect an erased memory on re-distillation).
|
|
252
|
+
* Erasure always wins over retention/replay — the text is unrecoverable
|
|
253
|
+
* locally after this call.
|
|
254
|
+
*/
|
|
255
|
+
erase(atomId, reason) {
|
|
256
|
+
const tx = this.db.transaction(() => {
|
|
257
|
+
const row = this.db
|
|
258
|
+
.prepare('SELECT id, rowid, scope, hash FROM memories WHERE id = ?')
|
|
259
|
+
.get(atomId);
|
|
260
|
+
if (!row)
|
|
261
|
+
throw new MemoryNotFoundError(atomId);
|
|
262
|
+
const now = Date.now();
|
|
263
|
+
// Tombstone first (same tx): the event survives the row.
|
|
264
|
+
this.append({
|
|
265
|
+
event_type: 'erase_request',
|
|
266
|
+
atom_id: atomId,
|
|
267
|
+
payload: { scope: row.scope, reason: reason ?? null },
|
|
268
|
+
content_hash: row.hash,
|
|
269
|
+
created_at: now,
|
|
270
|
+
});
|
|
271
|
+
this.db.prepare('DELETE FROM memories_vec WHERE rowid = ?').run(BigInt(row.rowid));
|
|
272
|
+
this.db.prepare('DELETE FROM memories WHERE id = ?').run(atomId); // FTS trigger fires
|
|
273
|
+
});
|
|
274
|
+
tx();
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Replay filter (erasure v1): true when a memory with this content hash
|
|
278
|
+
* has been erased — re-distillation must not resurrect it.
|
|
279
|
+
*/
|
|
280
|
+
isErasedHash(contentHash) {
|
|
281
|
+
const row = this.db
|
|
282
|
+
.prepare(`SELECT 1 AS x FROM memory_events WHERE event_type = 'erase_request' AND content_hash = ? LIMIT 1`)
|
|
283
|
+
.get(contentHash);
|
|
284
|
+
return row !== undefined;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
//# sourceMappingURL=memory-events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-events.js","sourceRoot":"","sources":["../../src/storage/memory-events.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export type EncryptMigrationResult = 'migrated' | 'already-encrypted' | 'missing';
|
|
2
|
+
/** Exported for key-aware CLI opens (open-runtime-db.ts): a plaintext file
|
|
3
|
+
* must be opened WITHOUT a key — PRAGMA key on plaintext reads as garbage. */
|
|
4
|
+
export declare function isPlaintextSqlite(dbPath: string): boolean;
|
|
5
|
+
/**
|
|
6
|
+
* Detects a plaintext DB at `dbPath` and migrates it to encrypted form with
|
|
7
|
+
* `key`. Returns:
|
|
8
|
+
* - 'missing' — no file at dbPath (fresh install; openDb() with
|
|
9
|
+
* a key will create an encrypted file directly).
|
|
10
|
+
* - 'already-encrypted' — file exists and is not plaintext (already
|
|
11
|
+
* migrated, or created encrypted from the start).
|
|
12
|
+
* - 'migrated' — a plaintext DB was found and successfully
|
|
13
|
+
* converted; `<dbPath>.pre-encryption.bak` now
|
|
14
|
+
* holds the pre-migration plaintext copy.
|
|
15
|
+
*/
|
|
16
|
+
export declare function encryptIfPlaintext(dbPath: string, key: string): EncryptMigrationResult;
|