@remnic/core 9.3.700 → 9.3.702
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/access-boundary.d.ts +7 -7
- package/dist/access-boundary.js +17 -14
- package/dist/access-cli.js +40 -37
- package/dist/access-cli.js.map +1 -1
- package/dist/access-http.d.ts +7 -7
- package/dist/access-http.js +20 -17
- package/dist/access-mcp.d.ts +7 -7
- package/dist/access-mcp.js +19 -16
- package/dist/access-operations.d.ts +7 -7
- package/dist/access-operations.js +18 -15
- package/dist/{access-service-Cte3ol0W.d.ts → access-service-COCzhgEL.d.ts} +397 -19
- package/dist/access-service.d.ts +6 -6
- package/dist/access-service.js +16 -13
- package/dist/access-surface-catalog.d.ts +7 -7
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-memory-bridge.js +2 -2
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +7 -6
- package/dist/active-recall.js.map +1 -1
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +5 -5
- package/dist/briefing.d.ts +1 -1
- package/dist/briefing.js +8 -7
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer.d.ts +1 -1
- package/dist/calibration.d.ts +1 -1
- package/dist/capabilities.d.ts +1 -1
- package/dist/{catalog-DN1PzThs.d.ts → catalog-DxCzhjE6.d.ts} +28 -54
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +9 -8
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/{chunk-XJNBEDFE.js → chunk-3FAMU5TX.js} +31 -74
- package/dist/chunk-3FAMU5TX.js.map +1 -0
- package/dist/{chunk-PCZR32VL.js → chunk-3JJWNZTT.js} +2 -2
- package/dist/{chunk-YXLT4EMM.js → chunk-4463LUIE.js} +12 -2
- package/dist/chunk-4463LUIE.js.map +1 -0
- package/dist/{chunk-R5DB26G6.js → chunk-4SBW47WK.js} +9 -23
- package/dist/chunk-4SBW47WK.js.map +1 -0
- package/dist/{chunk-CCOXIDRM.js → chunk-5VXVXJH6.js} +149 -6
- package/dist/{chunk-CCOXIDRM.js.map → chunk-5VXVXJH6.js.map} +1 -1
- package/dist/{chunk-PQG4T5V3.js → chunk-64XXOQRW.js} +49 -45
- package/dist/chunk-64XXOQRW.js.map +1 -0
- package/dist/{chunk-YXIFA36P.js → chunk-6TAETM63.js} +2 -2
- package/dist/{chunk-6JDGADXK.js → chunk-6VVP6NK7.js} +2 -2
- package/dist/{chunk-FN2SM5SN.js → chunk-ABCGDW3A.js} +75 -12
- package/dist/chunk-ABCGDW3A.js.map +1 -0
- package/dist/{chunk-CHM274U6.js → chunk-AMNLZ6SF.js} +2 -2
- package/dist/{chunk-JX3YZVII.js → chunk-CZJ6QSKG.js} +3 -3
- package/dist/{chunk-GYVVQYA3.js → chunk-EOOVJK2U.js} +3 -3
- package/dist/{chunk-JKW5XSWC.js → chunk-EYJD6KIO.js} +2 -2
- package/dist/{chunk-XY4WJTEX.js → chunk-EZR35XHX.js} +2 -2
- package/dist/{chunk-UU6MVCJ6.js → chunk-FIOYURII.js} +32 -25
- package/dist/chunk-FIOYURII.js.map +1 -0
- package/dist/{chunk-2NWHLAXX.js → chunk-FVI5B7DE.js} +2 -2
- package/dist/{chunk-X74FJSW7.js → chunk-GFIARMA7.js} +16 -8
- package/dist/chunk-GFIARMA7.js.map +1 -0
- package/dist/{chunk-PONNZ54D.js → chunk-GY3SKOS4.js} +4 -4
- package/dist/{chunk-U33LWTQQ.js → chunk-HV57RHMD.js} +4 -4
- package/dist/{chunk-RC3CNIPK.js → chunk-IO5NQEGZ.js} +2 -2
- package/dist/{chunk-IKNQAGBV.js → chunk-IX3UQT4H.js} +1 -1
- package/dist/{chunk-IKNQAGBV.js.map → chunk-IX3UQT4H.js.map} +1 -1
- package/dist/{chunk-HDLC75NX.js → chunk-IX72AAMZ.js} +2 -2
- package/dist/{chunk-DR2JTSLZ.js → chunk-JMA4RYRN.js} +62 -163
- package/dist/chunk-JMA4RYRN.js.map +1 -0
- package/dist/{chunk-G5PKTQ5J.js → chunk-JTKFZMZ7.js} +2 -2
- package/dist/{chunk-YMTGXDN6.js → chunk-KC6TCAWV.js} +5 -5
- package/dist/{chunk-ROZJACKP.js → chunk-KKK7YTYN.js} +4 -1
- package/dist/chunk-KKK7YTYN.js.map +1 -0
- package/dist/{chunk-EC2AYKRX.js → chunk-L6W77GWW.js} +10 -24
- package/dist/chunk-L6W77GWW.js.map +1 -0
- package/dist/{chunk-ED35D32I.js → chunk-LQ4J7ELC.js} +2 -2
- package/dist/{chunk-YPR7DOPD.js → chunk-LTJAMRGI.js} +4 -4
- package/dist/{chunk-YPR7DOPD.js.map → chunk-LTJAMRGI.js.map} +1 -1
- package/dist/chunk-LUPVCGYK.js +63 -0
- package/dist/chunk-LUPVCGYK.js.map +1 -0
- package/dist/{chunk-RJ2THZ4H.js → chunk-MBUM2Y3L.js} +2 -2
- package/dist/{chunk-T5QAZIBO.js → chunk-MOXFPLD6.js} +3 -3
- package/dist/{chunk-O54DY26V.js → chunk-MXEWQKM7.js} +2 -2
- package/dist/{chunk-33L6XHU2.js → chunk-NUIJEGVD.js} +6 -6
- package/dist/{chunk-3E5WRQNQ.js → chunk-OXEAMU42.js} +529 -9
- package/dist/chunk-OXEAMU42.js.map +1 -0
- package/dist/{chunk-EOBJRBLC.js → chunk-QGJAGC2J.js} +2 -2
- package/dist/{chunk-SMIVW7XC.js → chunk-QIMFOCSH.js} +2 -2
- package/dist/{chunk-IJEZMWKA.js → chunk-SFOAQQDJ.js} +3 -3
- package/dist/{chunk-HRUULBBV.js → chunk-SHRRWOVY.js} +81 -4
- package/dist/chunk-SHRRWOVY.js.map +1 -0
- package/dist/{chunk-NINRTFSV.js → chunk-SINGJCUR.js} +5 -5
- package/dist/{chunk-ZPQVJEVQ.js → chunk-SK2CR6MW.js} +146 -2
- package/dist/chunk-SK2CR6MW.js.map +1 -0
- package/dist/{chunk-SEWF2O74.js → chunk-TGAHHCB6.js} +2 -2
- package/dist/{chunk-D75JXBV4.js → chunk-WN4GHSDH.js} +2 -2
- package/dist/{chunk-K4DWSPMW.js → chunk-WRGPE6AW.js} +2 -2
- package/dist/{chunk-GA5A6MJH.js → chunk-XGMCUY5P.js} +62 -116
- package/dist/chunk-XGMCUY5P.js.map +1 -0
- package/dist/{chunk-SDPDU2PM.js → chunk-YTMDF6S7.js} +2 -2
- package/dist/{chunk-ZDK2IW5F.js → chunk-Z7XEIAV4.js} +2 -2
- package/dist/{chunk-NHBEO3F3.js → chunk-ZCEI242W.js} +24 -24
- package/dist/{cli--yVN9yEV.d.ts → cli-BM4xQPp4.d.ts} +3 -3
- package/dist/cli.d.ts +7 -7
- package/dist/cli.js +35 -34
- package/dist/compounding/engine.d.ts +1 -1
- package/dist/compounding/engine.js +8 -7
- package/dist/compounding/preference-consolidator.d.ts +1 -1
- package/dist/compression-optimizer.d.ts +1 -1
- package/dist/config.d.ts +1 -1
- package/dist/config.js +4 -2
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +8 -7
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +9 -8
- package/dist/consolidation-provenance-check.d.ts +1 -1
- package/dist/consolidation-undo.d.ts +1 -1
- package/dist/contradiction/index.d.ts +2 -2
- package/dist/conversation-index/backend.d.ts +1 -1
- package/dist/conversation-index/chunker.d.ts +1 -1
- package/dist/conversation-index/faiss-adapter.d.ts +1 -1
- package/dist/conversation-index/indexer.d.ts +1 -1
- package/dist/conversation-index/search.d.ts +1 -1
- package/dist/day-summary.d.ts +1 -1
- package/dist/delinearize.d.ts +1 -1
- package/dist/direct-answer-wiring.d.ts +1 -1
- package/dist/direct-answer.d.ts +1 -1
- package/dist/embedding-fallback.d.ts +1 -1
- package/dist/enrichment/index.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +1 -1
- package/dist/entity-retrieval.js +8 -7
- package/dist/entity-schema.d.ts +1 -1
- package/dist/event-order-recall.js +2 -1
- package/dist/explicit-capture.d.ts +5 -5
- package/dist/explicit-capture.js +2 -2
- package/dist/explicit-cue-recall.js +2 -1
- package/dist/extraction-faithfulness.d.ts +1 -1
- package/dist/extraction-judge-telemetry.d.ts +1 -1
- package/dist/extraction-judge-training.d.ts +1 -1
- package/dist/extraction-judge.d.ts +1 -1
- package/dist/extraction.d.ts +14 -1
- package/dist/extraction.js +5 -3
- package/dist/fallback-llm.d.ts +1 -1
- package/dist/{forget-BEXG5PQC.js → forget-6SOIPUMQ.js} +3 -3
- package/dist/identity-continuity.d.ts +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/index.d.ts +123 -123
- package/dist/index.js +57 -56
- package/dist/index.js.map +1 -1
- package/dist/intent.d.ts +1 -1
- package/dist/lcm/engine.d.ts +1 -1
- package/dist/lcm/index.d.ts +1 -1
- package/dist/lcm/tools.d.ts +1 -1
- package/dist/lifecycle.d.ts +1 -1
- package/dist/live-connectors-runner.d.ts +1 -1
- package/dist/local-llm.d.ts +1 -1
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +8 -7
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +8 -7
- package/dist/maintenance/rebuild-memory-projection.js +9 -8
- package/dist/mcp-memory-inspector-app.d.ts +7 -7
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-lifecycle-ledger-utils.d.ts +1 -1
- package/dist/memory-projection-store.d.ts +1 -1
- package/dist/memory-provenance.d.ts +1 -1
- package/dist/memory-worth-outcomes.d.ts +1 -1
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +2 -2
- package/dist/namespaces/migrate.js +9 -8
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +1 -1
- package/dist/namespaces/storage.d.ts +14 -3
- package/dist/namespaces/storage.js +8 -7
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +1 -1
- package/dist/operator-toolkit.js +14 -13
- package/dist/orchestration/maintenance.d.ts +2 -2
- package/dist/orchestration/maintenance.js +10 -9
- package/dist/{orchestrator-CJI4xdqV.d.ts → orchestrator-C9CDWAm6.d.ts} +4 -4
- package/dist/orchestrator.d.ts +5 -5
- package/dist/orchestrator.js +33 -31
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/provenance.d.ts +36 -2
- package/dist/provenance.js +5 -1
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +1 -1
- package/dist/recall-disclosure-escalation.d.ts +1 -1
- package/dist/recall-explain-renderer.d.ts +1 -1
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-pipeline-stages.d.ts +15 -0
- package/dist/recall-pipeline-stages.js +3 -56
- package/dist/recall-pipeline-stages.js.map +1 -1
- package/dist/recall-planner-llm.d.ts +1 -1
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-xray-cli.d.ts +1 -1
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.d.ts +1 -1
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.d.ts +1 -1
- package/dist/recall-xray.js +2 -2
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/response-guidance-recall.js +2 -1
- package/dist/resume-bundles.js +7 -5
- package/dist/retrieval-agents.d.ts +1 -1
- package/dist/retrieval-tiers.d.ts +1 -1
- package/dist/routing/engine.d.ts +1 -1
- package/dist/routing/store.d.ts +1 -1
- package/dist/schemas.d.ts +19 -0
- package/dist/schemas.js +1 -1
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/index.d.ts +1 -1
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/port.d.ts +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/{semantic-DJR8_DMQ.d.ts → semantic-SLAa_prH.d.ts} +1 -1
- package/dist/{semantic-consolidation-BtUfv-AL.d.ts → semantic-consolidation-DgFXyALl.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +9 -8
- package/dist/semantic-rule-promotion.js +8 -7
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +8 -7
- package/dist/session-observer-bands.d.ts +1 -1
- package/dist/session-observer-state.d.ts +1 -1
- package/dist/shared-context/manager.d.ts +1 -1
- package/dist/signal.d.ts +1 -1
- package/dist/storage.d.ts +13 -1
- package/dist/storage.js +7 -6
- package/dist/summarizer.d.ts +1 -1
- package/dist/summarizer.js +3 -2
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/summary-snapshot.js +2 -1
- package/dist/targeted-fact-recall.js +2 -1
- package/dist/temporal-supersession.d.ts +1 -1
- package/dist/temporal-validity.d.ts +1 -1
- package/dist/threading.d.ts +1 -1
- package/dist/tier-migration.d.ts +1 -1
- package/dist/tier-routing.d.ts +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transcript.js +2 -2
- package/dist/{types-PuiPZ9iE.d.ts → types-MWKPZnM0.d.ts} +25 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/utils/serialize-mutations.js +1 -1
- package/dist/verified-recall.js +8 -7
- package/package.json +2 -2
- package/src/access-http.ts +162 -0
- package/src/access-service.ts +215 -0
- package/src/admin/admin-surfaces.test.ts +458 -0
- package/src/admin/admin-surfaces.ts +819 -0
- package/src/event-order-recall.test.ts +53 -0
- package/src/event-order-recall.ts +61 -37
- package/src/explicit-cue-recall.ts +21 -1
- package/src/extraction.ts +91 -6
- package/src/namespaces/catalog.test.ts +222 -14
- package/src/namespaces/catalog.ts +54 -187
- package/src/namespaces/storage.ts +87 -80
- package/src/orchestrator.ts +46 -5
- package/src/provenance-extraction.test.ts +838 -0
- package/src/provenance.ts +413 -0
- package/src/recall-pipeline-parity.test.ts +288 -0
- package/src/recall-pipeline-stages.test.ts +43 -0
- package/src/recall-pipeline-stages.ts +22 -0
- package/src/response-guidance-recall.ts +32 -36
- package/src/schemas.ts +7 -0
- package/src/storage.ts +23 -0
- package/src/summary-snapshot.test.ts +63 -1
- package/src/summary-snapshot.ts +61 -80
- package/src/targeted-fact-recall.ts +25 -32
- package/src/types.ts +24 -0
- package/src/utils/serialize-mutations.ts +10 -6
- package/dist/chunk-3E5WRQNQ.js.map +0 -1
- package/dist/chunk-DR2JTSLZ.js.map +0 -1
- package/dist/chunk-EC2AYKRX.js.map +0 -1
- package/dist/chunk-FN2SM5SN.js.map +0 -1
- package/dist/chunk-GA5A6MJH.js.map +0 -1
- package/dist/chunk-HRUULBBV.js.map +0 -1
- package/dist/chunk-PQG4T5V3.js.map +0 -1
- package/dist/chunk-R5DB26G6.js.map +0 -1
- package/dist/chunk-ROZJACKP.js.map +0 -1
- package/dist/chunk-UU6MVCJ6.js.map +0 -1
- package/dist/chunk-X74FJSW7.js.map +0 -1
- package/dist/chunk-XJNBEDFE.js.map +0 -1
- package/dist/chunk-YXLT4EMM.js.map +0 -1
- package/dist/chunk-ZPQVJEVQ.js.map +0 -1
- /package/dist/{chunk-PCZR32VL.js.map → chunk-3JJWNZTT.js.map} +0 -0
- /package/dist/{chunk-YXIFA36P.js.map → chunk-6TAETM63.js.map} +0 -0
- /package/dist/{chunk-6JDGADXK.js.map → chunk-6VVP6NK7.js.map} +0 -0
- /package/dist/{chunk-CHM274U6.js.map → chunk-AMNLZ6SF.js.map} +0 -0
- /package/dist/{chunk-JX3YZVII.js.map → chunk-CZJ6QSKG.js.map} +0 -0
- /package/dist/{chunk-GYVVQYA3.js.map → chunk-EOOVJK2U.js.map} +0 -0
- /package/dist/{chunk-JKW5XSWC.js.map → chunk-EYJD6KIO.js.map} +0 -0
- /package/dist/{chunk-XY4WJTEX.js.map → chunk-EZR35XHX.js.map} +0 -0
- /package/dist/{chunk-2NWHLAXX.js.map → chunk-FVI5B7DE.js.map} +0 -0
- /package/dist/{chunk-PONNZ54D.js.map → chunk-GY3SKOS4.js.map} +0 -0
- /package/dist/{chunk-U33LWTQQ.js.map → chunk-HV57RHMD.js.map} +0 -0
- /package/dist/{chunk-RC3CNIPK.js.map → chunk-IO5NQEGZ.js.map} +0 -0
- /package/dist/{chunk-HDLC75NX.js.map → chunk-IX72AAMZ.js.map} +0 -0
- /package/dist/{chunk-G5PKTQ5J.js.map → chunk-JTKFZMZ7.js.map} +0 -0
- /package/dist/{chunk-YMTGXDN6.js.map → chunk-KC6TCAWV.js.map} +0 -0
- /package/dist/{chunk-ED35D32I.js.map → chunk-LQ4J7ELC.js.map} +0 -0
- /package/dist/{chunk-RJ2THZ4H.js.map → chunk-MBUM2Y3L.js.map} +0 -0
- /package/dist/{chunk-T5QAZIBO.js.map → chunk-MOXFPLD6.js.map} +0 -0
- /package/dist/{chunk-O54DY26V.js.map → chunk-MXEWQKM7.js.map} +0 -0
- /package/dist/{chunk-33L6XHU2.js.map → chunk-NUIJEGVD.js.map} +0 -0
- /package/dist/{chunk-EOBJRBLC.js.map → chunk-QGJAGC2J.js.map} +0 -0
- /package/dist/{chunk-SMIVW7XC.js.map → chunk-QIMFOCSH.js.map} +0 -0
- /package/dist/{chunk-IJEZMWKA.js.map → chunk-SFOAQQDJ.js.map} +0 -0
- /package/dist/{chunk-NINRTFSV.js.map → chunk-SINGJCUR.js.map} +0 -0
- /package/dist/{chunk-SEWF2O74.js.map → chunk-TGAHHCB6.js.map} +0 -0
- /package/dist/{chunk-D75JXBV4.js.map → chunk-WN4GHSDH.js.map} +0 -0
- /package/dist/{chunk-K4DWSPMW.js.map → chunk-WRGPE6AW.js.map} +0 -0
- /package/dist/{chunk-SDPDU2PM.js.map → chunk-YTMDF6S7.js.map} +0 -0
- /package/dist/{chunk-ZDK2IW5F.js.map → chunk-Z7XEIAV4.js.map} +0 -0
- /package/dist/{chunk-NHBEO3F3.js.map → chunk-ZCEI242W.js.map} +0 -0
- /package/dist/{forget-BEXG5PQC.js.map → forget-6SOIPUMQ.js.map} +0 -0
package/src/summary-snapshot.ts
CHANGED
|
@@ -1,18 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
mkdir,
|
|
3
|
-
open,
|
|
4
|
-
readFile,
|
|
5
|
-
stat,
|
|
6
|
-
unlink,
|
|
7
|
-
utimes,
|
|
8
|
-
writeFile,
|
|
9
|
-
} from "node:fs/promises";
|
|
1
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
10
2
|
import path from "node:path";
|
|
11
3
|
import { z } from "zod";
|
|
12
4
|
import {
|
|
13
5
|
encodeStoragePathSegment,
|
|
14
6
|
resolvePathInsideStorageRoot,
|
|
15
7
|
} from "./storage-paths.js";
|
|
8
|
+
import {
|
|
9
|
+
serializeMutations,
|
|
10
|
+
withHeldFileLock,
|
|
11
|
+
} from "./utils/serialize-mutations.js";
|
|
16
12
|
import type { HourlySummary } from "./types.js";
|
|
17
13
|
|
|
18
14
|
const summarySnapshotSchemaVersion = 1;
|
|
@@ -34,7 +30,9 @@ const SummarySnapshotSchema = z.object({
|
|
|
34
30
|
|
|
35
31
|
type SummarySnapshot = z.infer<typeof SummarySnapshotSchema>;
|
|
36
32
|
|
|
37
|
-
|
|
33
|
+
// Lock timings for the cross-process summary-snapshot file lock. These are
|
|
34
|
+
// passed straight through to the shared `withHeldFileLock` utility (issue
|
|
35
|
+
// #1524 adoption); the previous bespoke lock used the same numbers.
|
|
38
36
|
const summarySnapshotLockTimeoutMs = 5_000;
|
|
39
37
|
const summarySnapshotLockStaleMs = 30_000;
|
|
40
38
|
const summarySnapshotLockHeartbeatMs = Math.max(
|
|
@@ -137,31 +135,65 @@ export async function writeSummarySnapshot(
|
|
|
137
135
|
await writeFile(filePath, JSON.stringify(payload, null, 2), "utf-8");
|
|
138
136
|
}
|
|
139
137
|
|
|
138
|
+
// ── Concurrency primitives (issue #1524 adoption) ─────────────────────────
|
|
139
|
+
//
|
|
140
|
+
// Summary-snapshot upserts were previously guarded by TWO bespoke serializers:
|
|
141
|
+
// 1. an in-process `summarySnapshotUpserts` map keyed by sessionKey that
|
|
142
|
+
// chained each upsert off the prior one's release (mirroring
|
|
143
|
+
// `serializeMutations`), and
|
|
144
|
+
// 2. an on-disk `withExclusiveSummarySnapshotFileLock` that re-implemented
|
|
145
|
+
// `open(path, "wx")` acquire, mtime heartbeat, stale-break, and
|
|
146
|
+
// ownership-checked release.
|
|
147
|
+
// Both now delegate to the shared utility so there is ONE home for each
|
|
148
|
+
// primitive (`serializeMutations` for in-process, `withHeldFileLock` for
|
|
149
|
+
// cross-process). The behavior contract is preserved:
|
|
150
|
+
// - in-process upserts for the SAME sessionKey are strictly serialized
|
|
151
|
+
// (read-merge-write cannot interleave);
|
|
152
|
+
// - a cross-process holder blocks up to `summarySnapshotLockTimeoutMs`, then
|
|
153
|
+
// the upsert FAILS (a snapshot is advisory; we never race a read-merge-write
|
|
154
|
+
// unlocked). To preserve this strictness on top of a best-effort utility,
|
|
155
|
+
// the work callback throws when `acquired === false`.
|
|
156
|
+
|
|
140
157
|
async function withSummarySnapshotLock<T>(
|
|
141
158
|
memoryDir: string,
|
|
142
159
|
sessionKey: string,
|
|
143
160
|
work: () => Promise<T>,
|
|
144
161
|
): Promise<T> {
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
try {
|
|
155
|
-
return await withExclusiveSummarySnapshotFileLock(
|
|
162
|
+
// In-process serialization (one upsert per sessionKey at a time). The
|
|
163
|
+
// serializer recovers from rejection, so a failed upsert never poisons the
|
|
164
|
+
// next one — matching the previous chain's `.then(noop, noop)` recovery.
|
|
165
|
+
return serializeMutations(`summary-snapshot:${sessionKey}`, () =>
|
|
166
|
+
// Cross-process mutex via the shared utility. The lock path, stale
|
|
167
|
+
// threshold, bounded wait, and heartbeat cadence all flow through; the
|
|
168
|
+
// utility's replacement-safe stale break (NG7Bg) and ownership-checked
|
|
169
|
+
// release are stronger than the bare `unlink` this module used before.
|
|
170
|
+
withHeldFileLock(
|
|
156
171
|
summarySnapshotLockPath(memoryDir, sessionKey),
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
172
|
+
{
|
|
173
|
+
staleMs: summarySnapshotLockStaleMs,
|
|
174
|
+
maxWaitMs: summarySnapshotLockTimeoutMs,
|
|
175
|
+
heartbeatMs: summarySnapshotLockHeartbeatMs,
|
|
176
|
+
},
|
|
177
|
+
async (acquired) => {
|
|
178
|
+
// Strict-fail when the lock could not be acquired: the upsert is a
|
|
179
|
+
// read-merge-write, so a best-effort unlocked run would clobber a
|
|
180
|
+
// concurrent writer. The utility's `acquired === false` covers BOTH a
|
|
181
|
+
// genuine contention timeout AND a filesystem acquire failure (lock-dir
|
|
182
|
+
// mkdir/open/permission errors — the advisory lock is best-effort, so
|
|
183
|
+
// the util degrades rather than throwing). The bespoke lock this
|
|
184
|
+
// replaced propagated fs errors verbatim and reserved the timeout
|
|
185
|
+
// message for contention; we no longer claim "timed out" for an fs
|
|
186
|
+
// failure (cursor Low 25143f4f) — the message names both causes so
|
|
187
|
+
// upstream fail-open (runHourly) is unchanged but debugging is honest.
|
|
188
|
+
if (!acquired) {
|
|
189
|
+
throw new Error(
|
|
190
|
+
"could not acquire summary snapshot lock (contention timeout or filesystem error)",
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
return work();
|
|
194
|
+
},
|
|
195
|
+
),
|
|
196
|
+
);
|
|
165
197
|
}
|
|
166
198
|
|
|
167
199
|
export async function upsertSummarySnapshot(
|
|
@@ -185,54 +217,3 @@ export async function upsertSummarySnapshot(
|
|
|
185
217
|
await writeSummarySnapshot(memoryDir, summary.sessionKey, next);
|
|
186
218
|
});
|
|
187
219
|
}
|
|
188
|
-
|
|
189
|
-
async function withExclusiveSummarySnapshotFileLock<T>(
|
|
190
|
-
lockPath: string,
|
|
191
|
-
callback: () => Promise<T>,
|
|
192
|
-
): Promise<T> {
|
|
193
|
-
await mkdir(path.dirname(lockPath), { recursive: true });
|
|
194
|
-
const startedAt = Date.now();
|
|
195
|
-
|
|
196
|
-
while (true) {
|
|
197
|
-
try {
|
|
198
|
-
const handle = await open(lockPath, "wx");
|
|
199
|
-
let heartbeat: NodeJS.Timeout | null = null;
|
|
200
|
-
if (summarySnapshotLockHeartbeatMs > 0) {
|
|
201
|
-
heartbeat = setInterval(() => {
|
|
202
|
-
void utimes(lockPath, new Date(), new Date()).catch(() => undefined);
|
|
203
|
-
}, summarySnapshotLockHeartbeatMs);
|
|
204
|
-
heartbeat.unref?.();
|
|
205
|
-
}
|
|
206
|
-
try {
|
|
207
|
-
return await callback();
|
|
208
|
-
} finally {
|
|
209
|
-
if (heartbeat) clearInterval(heartbeat);
|
|
210
|
-
await handle.close().catch(() => undefined);
|
|
211
|
-
await unlink(lockPath).catch(() => undefined);
|
|
212
|
-
}
|
|
213
|
-
} catch (error) {
|
|
214
|
-
if (!isAlreadyExistsError(error)) throw error;
|
|
215
|
-
try {
|
|
216
|
-
const lockStat = await stat(lockPath);
|
|
217
|
-
if (Date.now() - lockStat.mtimeMs > summarySnapshotLockStaleMs) {
|
|
218
|
-
await unlink(lockPath).catch(() => undefined);
|
|
219
|
-
continue;
|
|
220
|
-
}
|
|
221
|
-
} catch {
|
|
222
|
-
continue;
|
|
223
|
-
}
|
|
224
|
-
if (Date.now() - startedAt > summarySnapshotLockTimeoutMs) {
|
|
225
|
-
throw new Error("timed out acquiring summary snapshot lock");
|
|
226
|
-
}
|
|
227
|
-
await sleep(10);
|
|
228
|
-
}
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
function isAlreadyExistsError(error: unknown): boolean {
|
|
233
|
-
return typeof error === "object" && error !== null && "code" in error && error.code === "EEXIST";
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
function sleep(ms: number): Promise<void> {
|
|
237
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
238
|
-
}
|
|
@@ -9,6 +9,11 @@ import {
|
|
|
9
9
|
resolveLcmReadSessionIds,
|
|
10
10
|
} from "./lcm-fallback-read.js";
|
|
11
11
|
|
|
12
|
+
import {
|
|
13
|
+
unifiedDedupeAndRank,
|
|
14
|
+
type RankedEvidenceItem,
|
|
15
|
+
} from "./recall-pipeline-stages.js";
|
|
16
|
+
|
|
12
17
|
export interface TargetedFactRecallOptions {
|
|
13
18
|
engine: ExplicitCueRecallEngine | null | undefined;
|
|
14
19
|
sessionId?: string;
|
|
@@ -27,10 +32,6 @@ export interface TargetedFactRecallOptions {
|
|
|
27
32
|
title?: string;
|
|
28
33
|
}
|
|
29
34
|
|
|
30
|
-
interface RankedEvidenceItem extends EvidencePackItem {
|
|
31
|
-
rank: number;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
35
|
const DEFAULT_MAX_SEARCH_RESULTS = 48;
|
|
35
36
|
const DEFAULT_SCAN_WINDOW_TURNS = 8;
|
|
36
37
|
const DEFAULT_SCAN_WINDOW_TOKENS = 12_000;
|
|
@@ -210,38 +211,30 @@ async function collectTargetedFactScanItems(
|
|
|
210
211
|
return items;
|
|
211
212
|
}
|
|
212
213
|
|
|
214
|
+
/**
|
|
215
|
+
* Issue #1539 PR3: targeted-fact now routes dedup/score/threshold/sort through
|
|
216
|
+
* the unified spine (`unifiedDedupeAndRank`). The divergence that lived inline
|
|
217
|
+
* here — append-normalized-numeric-cues content transform, relevance scoring on
|
|
218
|
+
* ORIGINAL content, default DESC turn-index ordering with -1 sentinel for
|
|
219
|
+
* missing turns — is now declared config on the spine. The score and
|
|
220
|
+
* appendNormalizedNumericCues helpers stay in this module because they are
|
|
221
|
+
* genuinely per-tier policy; only the duplicated dedup/sort/threshold machinery
|
|
222
|
+
* moved out.
|
|
223
|
+
*
|
|
224
|
+
* Behavior is byte-for-byte identical to the inline implementation it replaces
|
|
225
|
+
* (the spine was extracted to match it exactly; see recall-pipeline-stages.ts).
|
|
226
|
+
* The targeted-fact-recall.test.ts suite (42 cases, incl. the search/scan
|
|
227
|
+
* ordering and summary insertion tests) is the characterization.
|
|
228
|
+
*/
|
|
213
229
|
function rankAndDedupeTargetedFactItems(
|
|
214
230
|
items: EvidencePackItem[],
|
|
215
231
|
query: string,
|
|
216
232
|
): RankedEvidenceItem[] {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
const id = item.id ?? (
|
|
223
|
-
item.sessionId && typeof item.turnIndex === "number"
|
|
224
|
-
? `${item.sessionId}:${item.turnIndex}`
|
|
225
|
-
: undefined
|
|
226
|
-
);
|
|
227
|
-
if (id && seenIds.has(id)) continue;
|
|
228
|
-
const contentKey = item.content.toLowerCase().replace(/\s+/g, " ").trim();
|
|
229
|
-
if (seenContent.has(contentKey)) continue;
|
|
230
|
-
if (id) seenIds.add(id);
|
|
231
|
-
seenContent.add(contentKey);
|
|
232
|
-
ranked.push({
|
|
233
|
-
...item,
|
|
234
|
-
content: appendNormalizedNumericCues(item.content),
|
|
235
|
-
rank: scoreTargetedFactEvidence(item, query),
|
|
236
|
-
});
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
return ranked.sort((left, right) => {
|
|
240
|
-
if (right.rank !== left.rank) return right.rank - left.rank;
|
|
241
|
-
const leftTurn = typeof left.turnIndex === "number" ? left.turnIndex : -1;
|
|
242
|
-
const rightTurn = typeof right.turnIndex === "number" ? right.turnIndex : -1;
|
|
243
|
-
if (rightTurn !== leftTurn) return rightTurn - leftTurn;
|
|
244
|
-
return (right.score ?? 0) - (left.score ?? 0);
|
|
233
|
+
return unifiedDedupeAndRank(items, {
|
|
234
|
+
query,
|
|
235
|
+
intents: [],
|
|
236
|
+
scoreEvidence: (item, q) => scoreTargetedFactEvidence(item, q),
|
|
237
|
+
transformContent: (content) => appendNormalizedNumericCues(content),
|
|
245
238
|
});
|
|
246
239
|
}
|
|
247
240
|
|
package/src/types.ts
CHANGED
|
@@ -2852,6 +2852,30 @@ export interface ExtractedFact {
|
|
|
2852
2852
|
* "no verified span" and skip gracefully.
|
|
2853
2853
|
*/
|
|
2854
2854
|
sources?: ProvenanceSource[];
|
|
2855
|
+
/**
|
|
2856
|
+
* Coarse provenance strength tag (issue #1575 PR 2). Set by the extraction
|
|
2857
|
+
* validator: "verified" when the quote was located in source turns,
|
|
2858
|
+
* "unverified" when the quote survived but no offsets were recoverable.
|
|
2859
|
+
* Absent when `provenance.enabled` is false or no quote was provided —
|
|
2860
|
+
* readers treat absent as "none" (rule 34 spirit).
|
|
2861
|
+
*/
|
|
2862
|
+
provenance?: "verified" | "unverified" | "none";
|
|
2863
|
+
/**
|
|
2864
|
+
* Transient LLM-provided supporting quote (issue #1575 PR 2). Consumed by
|
|
2865
|
+
* the post-parse validator to build `sources`, then stripped before the
|
|
2866
|
+
* fact reaches persistence. NEVER included in content-hash dedup (rule 23 /
|
|
2867
|
+
* checklist §13). Absent on facts that have already passed the validator.
|
|
2868
|
+
*/
|
|
2869
|
+
quote?: string;
|
|
2870
|
+
/**
|
|
2871
|
+
* Transient requireSpans signal (issue #1575 PR 2). Set by the provenance
|
|
2872
|
+
* validator (`ProvenanceBuildResult.requireSpansPending`) when
|
|
2873
|
+
* `provenance.requireSpans` is enabled and the quote could not be located
|
|
2874
|
+
* in any source turn. Read by the persist path to route the fact to
|
|
2875
|
+
* `pending_review` instead of `active`. Stripped before persistence —
|
|
2876
|
+
* it never reaches frontmatter (chatgpt-codex-connector thread 4xB).
|
|
2877
|
+
*/
|
|
2878
|
+
requireSpansPending?: boolean;
|
|
2855
2879
|
promptedByQuestion?: string;
|
|
2856
2880
|
/**
|
|
2857
2881
|
* Whether this fact is project-scoped or globally applicable.
|
|
@@ -670,10 +670,14 @@ async function lockHeldBySelf(held: HeldLock): Promise<boolean> {
|
|
|
670
670
|
}
|
|
671
671
|
|
|
672
672
|
function sleep(ms: number): Promise<void> {
|
|
673
|
-
|
|
674
|
-
//
|
|
675
|
-
//
|
|
676
|
-
//
|
|
677
|
-
|
|
678
|
-
|
|
673
|
+
// Manual deferred instead of Promise.withResolvers (ES2024) — plugin-openclaw's
|
|
674
|
+
// standalone tsconfig targets ES2022 lib and this module is reachable from its
|
|
675
|
+
// type graph, so withResolvers would TS2550 there (same fix as
|
|
676
|
+
// extraction-faithfulness.ts:467).
|
|
677
|
+
return new Promise<void>((resolve) => {
|
|
678
|
+
// NOT unref'd: this polls inside an awaited acquire loop, so the caller's
|
|
679
|
+
// await chain keeps the loop alive; unref would let Node exit mid-poll when
|
|
680
|
+
// nothing else is pending (the heartbeat interval IS unref'd separately).
|
|
681
|
+
setTimeout(resolve, ms);
|
|
682
|
+
});
|
|
679
683
|
}
|