@remnic/core 9.69.39 → 9.69.40
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-admin-ops-surface.d.ts +16 -14
- package/dist/access-admin-ops-surface.js +37 -37
- package/dist/access-authorization-probe.d.ts +16 -14
- package/dist/access-authorization-probe.js +38 -38
- package/dist/access-boundary.d.ts +16 -14
- package/dist/access-boundary.js +37 -37
- package/dist/access-cli.js +98 -97
- package/dist/access-cli.js.map +1 -1
- package/dist/access-coding-context-resolution.d.ts +1 -1
- package/dist/access-extraction-force-flush.d.ts +16 -14
- package/dist/access-extraction-force-flush.js +37 -37
- package/dist/access-health-types.d.ts +1 -1
- package/dist/access-http-briefing.d.ts +16 -14
- package/dist/access-http-briefing.js +38 -38
- package/dist/access-http-lcm-compaction.d.ts +16 -14
- package/dist/access-http-lifecycle-flush.d.ts +16 -14
- package/dist/access-http-offline-stream.d.ts +16 -14
- package/dist/access-http-query.d.ts +2 -2
- package/dist/access-http-query.js +39 -39
- package/dist/access-http.d.ts +17 -15
- package/dist/access-http.js +53 -53
- package/dist/access-identity-continuity-surface.d.ts +13 -12
- package/dist/access-identity-continuity-surface.js +37 -37
- package/dist/access-lcm-surface.d.ts +16 -14
- package/dist/access-lcm-surface.js +37 -37
- package/dist/access-mcp.d.ts +16 -14
- package/dist/access-mcp.js +45 -45
- package/dist/access-memory-search-fanout.d.ts +2 -2
- package/dist/{access-namespace-preflight-DY4z6L5X.d.ts → access-namespace-preflight-CKBumJ8W.d.ts} +1 -1
- package/dist/access-namespace-preflight.d.ts +3 -3
- package/dist/access-namespace-preflight.js +37 -37
- package/dist/access-observe-transcript.d.ts +13 -12
- package/dist/access-observe-write-category.d.ts +1 -1
- package/dist/access-observe-write-category.js +2 -2
- package/dist/access-observe-write-surface.d.ts +16 -14
- package/dist/access-observe-write-surface.js +37 -37
- package/dist/access-offline-manifest.d.ts +37 -13
- package/dist/access-offline-manifest.js +7 -3
- package/dist/access-operations-batch.js +39 -39
- package/dist/access-operations.d.ts +16 -14
- package/dist/access-operations.js +44 -44
- package/dist/access-recall-concurrency.d.ts +16 -14
- package/dist/access-recall-concurrency.js +37 -37
- package/dist/access-recall-response.d.ts +16 -14
- package/dist/access-recall-response.js +37 -37
- package/dist/access-recall-surface.d.ts +16 -14
- package/dist/access-recall-surface.js +37 -37
- package/dist/access-schema.d.ts +5 -3
- package/dist/access-schema.js +1 -1
- package/dist/{access-service-MY4bsr_Q.d.ts → access-service-DJ3qogNt.d.ts} +8 -8
- package/dist/access-service-helpers.d.ts +16 -14
- package/dist/access-service.d.ts +16 -14
- package/dist/access-service.js +37 -37
- package/dist/access-surface-catalog.d.ts +16 -14
- package/dist/access-surface-catalog.js +39 -39
- package/dist/access-wearables-meetings-surface.d.ts +6 -5
- package/dist/action-confidence.d.ts +1 -1
- package/dist/active-memory-bridge.d.ts +1 -1
- package/dist/active-recall.d.ts +1 -1
- package/dist/active-recall.js +6 -5
- package/dist/active-recall.js.map +1 -1
- package/dist/activity/digest.d.ts +1 -1
- package/dist/ambient-provenance.d.ts +1 -1
- package/dist/artifact-search.d.ts +1 -1
- package/dist/{auto-sync-RP4C6ZPF.js → auto-sync-D6BAPIJV.js} +5 -5
- package/dist/background-generation-config.d.ts +1 -1
- package/dist/background-generation-config.js +3 -1
- package/dist/background-generation.d.ts +1 -1
- package/dist/behavior-learner.d.ts +1 -1
- package/dist/behavior-signals.d.ts +1 -1
- package/dist/bootstrap.d.ts +13 -12
- package/dist/briefing-window.d.ts +2 -2
- package/dist/briefing.d.ts +2 -2
- package/dist/briefing.js +15 -15
- package/dist/buffer-surprise-report.d.ts +1 -1
- package/dist/buffer-turn-helpers.d.ts +1 -1
- package/dist/buffer.d.ts +2 -2
- package/dist/buffer.js +5 -5
- package/dist/bulk-import/index.d.ts +3 -3
- package/dist/calibration.d.ts +3 -2
- package/dist/calibration.js +2 -2
- package/dist/capabilities.d.ts +1 -1
- package/dist/{catalog-CW87xGx8.d.ts → catalog-BHXkBVhg.d.ts} +1 -1
- package/dist/causal-behavior.d.ts +1 -1
- package/dist/causal-consolidation.d.ts +1 -1
- package/dist/causal-consolidation.js +19 -18
- package/dist/causal-consolidation.js.map +1 -1
- package/dist/causal-trajectory-graph.d.ts +1 -1
- package/dist/{chunk-B36GUU6T.js → chunk-23HFXQ5J.js} +36 -3
- package/dist/chunk-23HFXQ5J.js.map +1 -0
- package/dist/{chunk-YFTNZMGR.js → chunk-27NO2KVB.js} +31 -8
- package/dist/chunk-27NO2KVB.js.map +1 -0
- package/dist/{chunk-JTQR6L2N.js → chunk-2SKMZUOW.js} +2 -2
- package/dist/{chunk-GG5FHZJJ.js → chunk-2SNCQHJZ.js} +2 -2
- package/dist/{chunk-O76F5QPP.js → chunk-3QEVOQF5.js} +2 -2
- package/dist/{chunk-3N3PBBEH.js → chunk-3XPN7AVY.js} +2 -2
- package/dist/{chunk-X4TD4O2F.js → chunk-46Z3VGWF.js} +2 -2
- package/dist/{chunk-2ZTDRNCS.js → chunk-4CMXI55L.js} +2 -2
- package/dist/{chunk-FWWWUPOE.js → chunk-5LYSEZOF.js} +18 -9
- package/dist/chunk-5LYSEZOF.js.map +1 -0
- package/dist/{chunk-IQEJIOEU.js → chunk-62HFZNCJ.js} +17 -10
- package/dist/chunk-62HFZNCJ.js.map +1 -0
- package/dist/{chunk-YKREX63Z.js → chunk-6L2II3KS.js} +5 -3
- package/dist/chunk-6L2II3KS.js.map +1 -0
- package/dist/{chunk-MUTVRKKY.js → chunk-7D6SER6A.js} +8 -8
- package/dist/{chunk-WBM2MVBK.js → chunk-7Z54NXVS.js} +2 -2
- package/dist/{chunk-ACY4ZPF7.js → chunk-AEOOGXMQ.js} +10 -5
- package/dist/chunk-AEOOGXMQ.js.map +1 -0
- package/dist/{chunk-UHRZ324M.js → chunk-BGRTZOJB.js} +3 -3
- package/dist/{chunk-ZEGL7YCC.js → chunk-BXIJSPCL.js} +2 -2
- package/dist/{chunk-JKKII6GX.js → chunk-BYQX4IOG.js} +2 -2
- package/dist/{chunk-WIWLX65T.js → chunk-C5R73BON.js} +2 -2
- package/dist/{chunk-BD7JTBYP.js → chunk-D7MAYFQP.js} +2 -2
- package/dist/{chunk-TNZNSMVJ.js → chunk-DAZANIYU.js} +249 -295
- package/dist/chunk-DAZANIYU.js.map +1 -0
- package/dist/{chunk-LMLGBG6H.js → chunk-DFVSJFHK.js} +2 -2
- package/dist/{chunk-3NPNBVFR.js → chunk-ES5BUPYB.js} +2 -2
- package/dist/{chunk-MVAQ2WM3.js → chunk-G2XZFGYN.js} +6 -2
- package/dist/chunk-G2XZFGYN.js.map +1 -0
- package/dist/{chunk-TNSCIPBQ.js → chunk-G6NQ3L4T.js} +2 -2
- package/dist/{chunk-5N4MZLEH.js → chunk-GO5LOHCD.js} +2 -2
- package/dist/{chunk-AECJY3GJ.js → chunk-GSSDHAYH.js} +2 -2
- package/dist/{chunk-TSP5WH72.js → chunk-HJUP3K6L.js} +2 -2
- package/dist/{chunk-AAZEKXUP.js → chunk-ICNJ6J46.js} +2 -2
- package/dist/{chunk-6EHM2AV7.js → chunk-IMBQFHRV.js} +2 -2
- package/dist/{chunk-4RZLTZVM.js → chunk-IOPIGX7Y.js} +1 -1
- package/dist/{chunk-EYKIDK33.js → chunk-IS2IDFJP.js} +13 -13
- package/dist/{chunk-VJIE4D2I.js → chunk-J4WGTN2N.js} +2 -2
- package/dist/{chunk-NXGSONWM.js → chunk-J7FVMLBR.js} +2 -2
- package/dist/{chunk-VSL63CFJ.js → chunk-JAJIMTFB.js} +6 -6
- package/dist/{chunk-4JVQRFZD.js → chunk-JOP7W24J.js} +9 -9
- package/dist/{chunk-YUW66UAH.js → chunk-JUDT33RX.js} +2 -2
- package/dist/{chunk-QHT7MOUF.js → chunk-K4A6UVPB.js} +22 -11
- package/dist/chunk-K4A6UVPB.js.map +1 -0
- package/dist/{chunk-D545Z7UH.js → chunk-K4JKAXMO.js} +2 -2
- package/dist/{chunk-BV4ZKIZH.js → chunk-K75A5XWU.js} +3 -2
- package/dist/{chunk-3CBI2ZSA.js → chunk-KG2OOAFF.js} +20 -12
- package/dist/chunk-KG2OOAFF.js.map +1 -0
- package/dist/{chunk-M6HBPLBA.js → chunk-KOTG3RXE.js} +2 -2
- package/dist/{chunk-CWTCMZGE.js → chunk-KTOXQMW3.js} +119 -3
- package/dist/chunk-KTOXQMW3.js.map +1 -0
- package/dist/{chunk-OB3XMWX5.js → chunk-KVO2BTA4.js} +2 -2
- package/dist/{chunk-GI4ZBWPQ.js → chunk-KY236SP5.js} +3 -3
- package/dist/{chunk-4BCHFSC7.js → chunk-LFVZD5EC.js} +3 -3
- package/dist/{chunk-O4M4BDIJ.js → chunk-LKFVVN7R.js} +2 -2
- package/dist/{chunk-IYKZJVL5.js → chunk-MDIEES23.js} +1 -1
- package/dist/chunk-MDIEES23.js.map +1 -0
- package/dist/{chunk-4RX5O34R.js → chunk-MJC7UKH7.js} +2 -2
- package/dist/{chunk-CZTPU65V.js → chunk-MVG3KXON.js} +63 -16
- package/dist/chunk-MVG3KXON.js.map +1 -0
- package/dist/{chunk-YDVAM7S4.js → chunk-NETQXOPY.js} +2 -2
- package/dist/chunk-NETQXOPY.js.map +1 -0
- package/dist/{chunk-UZZ7SQT3.js → chunk-NVVZPBKI.js} +2 -2
- package/dist/{chunk-BLDBT6HZ.js → chunk-PJRKLB4Z.js} +18 -2
- package/dist/chunk-PJRKLB4Z.js.map +1 -0
- package/dist/{chunk-VBSNUH4J.js → chunk-PKUJNICO.js} +2 -2
- package/dist/{chunk-OPBFP4TF.js → chunk-QE6YVNP5.js} +7 -7
- package/dist/{chunk-WKDFJXW5.js → chunk-QM2SPLKQ.js} +1 -1
- package/dist/chunk-QM2SPLKQ.js.map +1 -0
- package/dist/{chunk-ENBPQEVU.js → chunk-QPVNK2VE.js} +2 -2
- package/dist/{chunk-RLJHJQUY.js → chunk-QS5Q5RBV.js} +2 -2
- package/dist/{chunk-3EKVN2OP.js → chunk-RDLPFM7I.js} +2 -2
- package/dist/{chunk-F4EHXVP7.js → chunk-RJQAP333.js} +2 -2
- package/dist/{chunk-QTQ6XKGT.js → chunk-RLU2Y5GV.js} +4 -4
- package/dist/chunk-RLU2Y5GV.js.map +1 -0
- package/dist/{chunk-5SPCMAUC.js → chunk-ROEFLU37.js} +4 -4
- package/dist/{chunk-UZEHHXYC.js → chunk-SFHLQPBF.js} +22 -22
- package/dist/chunk-SK7D34OL.js +68 -0
- package/dist/chunk-SK7D34OL.js.map +1 -0
- package/dist/{chunk-ZBW7A667.js → chunk-SUEOG2S4.js} +2 -2
- package/dist/{chunk-Q7CLGFA7.js → chunk-TEMKBSV6.js} +2 -2
- package/dist/{chunk-LQNRVPTV.js → chunk-THTF2W7M.js} +151 -118
- package/dist/chunk-THTF2W7M.js.map +1 -0
- package/dist/{chunk-GMIQV6DD.js → chunk-TO36VPZI.js} +2 -2
- package/dist/{chunk-6YAIN5XJ.js → chunk-TZ44E732.js} +44 -6
- package/dist/chunk-TZ44E732.js.map +1 -0
- package/dist/{chunk-JXN77SGO.js → chunk-U2VDCFXW.js} +1 -1
- package/dist/chunk-U2VDCFXW.js.map +1 -0
- package/dist/{chunk-LPYYY4AP.js → chunk-UZ6JYPJ6.js} +500 -218
- package/dist/chunk-UZ6JYPJ6.js.map +1 -0
- package/dist/{chunk-FXHOZGSE.js → chunk-V2ZA4YWE.js} +2 -2
- package/dist/{chunk-XH3HGI2N.js → chunk-VHKXRYQN.js} +2 -2
- package/dist/{chunk-GAS7KYC7.js → chunk-VKWFNPBH.js} +2 -2
- package/dist/{chunk-6H2G7RFT.js → chunk-VNQRRUNS.js} +11 -10
- package/dist/chunk-VNQRRUNS.js.map +1 -0
- package/dist/{chunk-IL6ODG6M.js → chunk-VQWBUPSJ.js} +2 -2
- package/dist/{chunk-5YCNDC3C.js → chunk-VQYWKCDR.js} +2 -2
- package/dist/{chunk-54NX5EG4.js → chunk-W23JARAQ.js} +2 -2
- package/dist/{chunk-YQNNHLCG.js → chunk-WPGR3RW4.js} +2 -2
- package/dist/{chunk-FNHLI2RE.js → chunk-WZYHPAG5.js} +3 -3
- package/dist/{chunk-5HYUUFMQ.js → chunk-XCPNH2MG.js} +259 -10
- package/dist/chunk-XCPNH2MG.js.map +1 -0
- package/dist/{chunk-TA4C3XB7.js → chunk-XM46Y66S.js} +2 -2
- package/dist/{chunk-PCOVEDPK.js → chunk-YRIFXXMI.js} +3 -3
- package/dist/{chunk-TRLOFIQC.js → chunk-YTK5MVNF.js} +2 -2
- package/dist/{chunk-Q432REND.js → chunk-YTZN2UZO.js} +2 -2
- package/dist/{chunk-6AGWBKQU.js → chunk-Z4GUX2M6.js} +2 -2
- package/dist/{chunk-AENM6GKU.js → chunk-ZAEPD4C2.js} +2 -2
- package/dist/{chunk-KQW3YGEN.js → chunk-ZRMMXWYI.js} +2 -2
- package/dist/{chunk-P4ZAEYKG.js → chunk-ZX3AYNNV.js} +6 -3
- package/dist/chunk-ZX3AYNNV.js.map +1 -0
- package/dist/{chunk-MCRVQ5YQ.js → chunk-ZZCR2QYL.js} +2 -2
- package/dist/{cli-DGq0MNpO.d.ts → cli-BWri5-am.d.ts} +5 -5
- package/dist/cli.d.ts +18 -16
- package/dist/cli.js +75 -74
- package/dist/coding/export-okf-codegraph.d.ts +1 -1
- package/dist/coding/export-okf-codegraph.js +14 -14
- package/dist/coding/pre-action-gate.d.ts +1 -1
- package/dist/compounding/engine.d.ts +2 -2
- package/dist/compounding/engine.js +15 -15
- 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 +6 -5
- package/dist/connectors/codex-materialize-runner.d.ts +1 -1
- package/dist/connectors/codex-materialize-runner.js +15 -15
- package/dist/connectors/codex-materialize.d.ts +1 -1
- package/dist/connectors/index.d.ts +1 -1
- package/dist/connectors/index.js +15 -15
- package/dist/consolidation-provenance-check.d.ts +2 -2
- package/dist/consolidation-undo.d.ts +2 -2
- package/dist/contradiction/index.d.ts +6 -5
- package/dist/converge-config.d.ts +1 -1
- package/dist/convergence-refresh.d.ts +2 -2
- package/dist/convergence-refresh.js +17 -17
- 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/corpus-watermark.d.ts +1 -1
- package/dist/corpus-watermark.js +17 -17
- package/dist/cross-lingual-recall.d.ts +1 -1
- package/dist/day-summary.d.ts +1 -1
- package/dist/deep-recall-http-glue.d.ts +16 -14
- package/dist/deep-recall-http-glue.js +2 -2
- package/dist/deep-recall-mcp-tools.d.ts +16 -14
- package/dist/deep-recall-policy-llm.d.ts +4 -3
- package/dist/deep-recall-policy-llm.js +3 -3
- package/dist/deep-recall-seeds.d.ts +1 -1
- package/dist/delinearize.d.ts +1 -1
- package/dist/dependency-propagation-config.d.ts +1 -1
- package/dist/{dependency-propagation-delivery-Cq1ekOwV.d.ts → dependency-propagation-delivery-ueZlKTQB.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-origin-fields.d.ts +1 -1
- package/dist/entity-retrieval.d.ts +2 -2
- package/dist/entity-retrieval.js +15 -15
- package/dist/entity-schema.d.ts +1 -1
- package/dist/episodic-context.d.ts +1 -1
- package/dist/eval-trajectory-contracts.d.ts +1 -1
- package/dist/eval-trajectory-store.d.ts +1 -1
- package/dist/eval-trajectory.d.ts +1 -1
- package/dist/explicit-capture.d.ts +13 -12
- package/dist/external-wiki-access.d.ts +16 -14
- package/dist/external-wiki-access.js +38 -38
- package/dist/external-wiki-collection-registration.d.ts +1 -1
- package/dist/external-wiki-collection.d.ts +1 -1
- package/dist/external-wiki-mcp-tools.d.ts +16 -14
- package/dist/extraction-error-classification.d.ts +14 -3
- package/dist/extraction-error-classification.js +5 -3
- package/dist/extraction-faithfulness.d.ts +4 -3
- package/dist/extraction-faithfulness.js +3 -3
- package/dist/extraction-judge-telemetry.d.ts +4 -3
- package/dist/extraction-judge-training.d.ts +4 -3
- package/dist/extraction-judge.d.ts +4 -3
- package/dist/extraction-judge.js +3 -3
- package/dist/extraction-liveness.d.ts +1 -1
- package/dist/extraction-normalization.d.ts +1 -1
- package/dist/extraction-prompt.d.ts +1 -1
- package/dist/extraction-source-grounding-rules.d.ts +1 -1
- package/dist/extraction-source-grounding.d.ts +1 -1
- package/dist/extraction-span-config.d.ts +1 -1
- package/dist/extraction-span-materialize.d.ts +1 -1
- package/dist/extraction.d.ts +4 -4
- package/dist/extraction.js +25 -23
- package/dist/fallback-llm-codex-subscription.d.ts +52 -7
- package/dist/fallback-llm-codex-subscription.js +17 -1
- package/dist/fallback-llm.d.ts +25 -28
- package/dist/fallback-llm.js +4 -3
- package/dist/{generic-recall-paths-BcySh_f9.d.ts → generic-recall-paths-CpyVmA88.d.ts} +1 -1
- package/dist/graph-append-error.d.ts +1 -1
- package/dist/graph-dashboard-diff.d.ts +1 -1
- package/dist/graph-dashboard-key.d.ts +1 -1
- package/dist/graph-dashboard-parser.d.ts +1 -1
- package/dist/graph-edge-reinforcement.d.ts +1 -1
- package/dist/graph-jsonl.d.ts +1 -1
- package/dist/graph-path-reconstruction.d.ts +1 -1
- package/dist/graph-path-scoring.d.ts +1 -1
- package/dist/graph-snapshot.d.ts +1 -1
- package/dist/graph.d.ts +1 -1
- package/dist/harmonic-retrieval.js +1 -1
- package/dist/importance.d.ts +1 -1
- package/dist/importers/index.d.ts +1 -1
- package/dist/importers/test-utils.d.ts +1 -1
- package/dist/in-flight-reads.d.ts +1 -1
- package/dist/{index-DWOb4wz9.d.ts → index-BvUA4S7M.d.ts} +3 -3
- package/dist/index.d.ts +79 -39
- package/dist/index.js +119 -103
- 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/index.js +3 -3
- 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-BsJGulur.d.ts +247 -0
- package/dist/local-llm-config.d.ts +4 -1
- package/dist/local-llm-config.js +4 -2
- package/dist/local-llm-helpers.d.ts +18 -69
- package/dist/local-llm-helpers.js +1 -1
- package/dist/local-llm.d.ts +3 -170
- package/dist/local-llm.js +2 -2
- package/dist/local-model-endpoint.d.ts +1 -1
- package/dist/location/index.d.ts +3 -3
- package/dist/location/index.js +17 -17
- package/dist/maintenance/memory-governance.d.ts +1 -1
- package/dist/maintenance/memory-governance.js +15 -15
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +15 -15
- package/dist/maintenance/rebuild-memory-projection.d.ts +2 -2
- package/dist/maintenance/rebuild-memory-projection.js +16 -16
- package/dist/{maintenance-CW9wCzMP.d.ts → maintenance-CYubtIRr.d.ts} +9 -3
- package/dist/mcp-memory-inspector-app.d.ts +16 -14
- package/dist/memory-action-policy.d.ts +1 -1
- package/dist/memory-cache.d.ts +1 -1
- package/dist/memory-controller.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-snapshot.d.ts +1 -1
- package/dist/memory-subject-cli.d.ts +16 -14
- package/dist/memory-subject.d.ts +16 -14
- package/dist/memory-worth-outcomes.d.ts +2 -2
- package/dist/models-json.d.ts +1 -1
- package/dist/namespaces/migrate.d.ts +3 -3
- package/dist/namespaces/migrate.js +16 -16
- package/dist/namespaces/principal.d.ts +1 -1
- package/dist/namespaces/search.d.ts +12 -1
- package/dist/namespaces/search.js +9 -9
- package/dist/namespaces/storage.d.ts +3 -3
- package/dist/namespaces/storage.js +15 -15
- package/dist/native-knowledge.d.ts +1 -1
- package/dist/offline-sync-impression-drain.d.ts +1 -1
- package/dist/operator-doctor-corpus.d.ts +1 -1
- package/dist/operator-doctor-corpus.js +18 -18
- package/dist/operator-doctor-replica.d.ts +1 -1
- package/dist/operator-toolkit.d.ts +3 -3
- package/dist/operator-toolkit.js +29 -28
- package/dist/orchestration/compression-guideline-coordinator.d.ts +2 -2
- package/dist/orchestration/maintenance.d.ts +4 -4
- package/dist/orchestration/maintenance.js +26 -26
- package/dist/{orchestrator-ComHLm49.d.ts → orchestrator-BWDRJ_0d.d.ts} +24 -11
- package/dist/orchestrator.d.ts +13 -12
- package/dist/orchestrator.js +101 -98
- package/dist/patterns-cli.d.ts +1 -1
- package/dist/{pipeline-CiYcqqhl.d.ts → pipeline-7JMn2yMH.d.ts} +1 -1
- package/dist/policy-runtime.d.ts +1 -1
- package/dist/proactive-contention.d.ts +2 -2
- package/dist/provenance.d.ts +1 -1
- package/dist/{public-http-CuK4_Cb1.d.ts → public-http-CJWs3mo9.d.ts} +1 -1
- package/dist/{qmd-qXD4vatU.d.ts → qmd-CxCH9G9m.d.ts} +2 -2
- package/dist/qmd-preflight.d.ts +2 -2
- package/dist/qmd-recall-cache.d.ts +1 -1
- package/dist/qmd.d.ts +2 -2
- package/dist/qmd.js +2 -2
- package/dist/recall-concurrency-config.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-memory-map.d.ts +1 -1
- package/dist/recall-navigate-access.d.ts +1 -1
- package/dist/recall-navigate-access.js +2 -2
- package/dist/recall-navigate-disclosure.d.ts +1 -1
- package/dist/recall-navigate-disclosure.js +1 -1
- package/dist/recall-navigate.d.ts +1 -1
- package/dist/recall-navigate.js +2 -2
- package/dist/recall-planner-llm.d.ts +3 -2
- package/dist/recall-planner-llm.js +4 -3
- package/dist/recall-planner-llm.js.map +1 -1
- package/dist/recall-state-view-admission.d.ts +13 -3
- package/dist/recall-state-view-admission.js +8 -8
- package/dist/recall-state-view-anchors.d.ts +1 -1
- package/dist/recall-state-view-anchors.js +2 -2
- package/dist/recall-state-view-inject.js +2 -2
- package/dist/recall-state-view-render.js +2 -2
- package/dist/recall-state-view-widen.js +2 -2
- package/dist/recall-state-view-wire.js +3 -3
- package/dist/recall-state-view.d.ts +1 -0
- package/dist/recall-state-view.js +1 -1
- package/dist/recall-state.d.ts +1 -1
- package/dist/recall-tag-filter.d.ts +1 -1
- package/dist/recall-timings.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/reconcile/cursor.d.ts +1 -1
- package/dist/reconcile/manifest.d.ts +1 -1
- package/dist/reconcile/plan.d.ts +1 -1
- package/dist/replay/normalizers/chatgpt.d.ts +1 -1
- package/dist/replay/normalizers/claude.d.ts +1 -1
- package/dist/replay/normalizers/openclaw.d.ts +1 -1
- package/dist/replay/normalizers/shared.d.ts +1 -1
- package/dist/replay/runner.d.ts +1 -1
- package/dist/replay/types.d.ts +1 -1
- package/dist/replica-divergence.d.ts +1 -1
- package/dist/replica-peers-config.d.ts +1 -1
- package/dist/resolve-auth-token.d.ts +1 -1
- package/dist/resume-bundles.js +7 -6
- package/dist/retrieval-agents.d.ts +2 -2
- 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/salvage-envelope.d.ts +1 -1
- package/dist/{scope-profiles-BT9rqC3w.d.ts → scope-profiles-BGAUqhBR.d.ts} +1 -1
- package/dist/search/embed-helper.d.ts +1 -1
- package/dist/search/factory.d.ts +1 -1
- package/dist/search/factory.js +8 -8
- package/dist/search/index.d.ts +1 -1
- package/dist/search/index.js +10 -10
- package/dist/search/lancedb-backend.d.ts +1 -1
- package/dist/search/lancedb-backend.js +2 -2
- package/dist/search/meilisearch-backend.d.ts +1 -1
- package/dist/search/meilisearch-backend.js +2 -2
- package/dist/search/noop-backend.d.ts +1 -1
- package/dist/search/orama-backend.d.ts +1 -1
- package/dist/search/orama-backend.js +2 -2
- package/dist/search/port.d.ts +2 -2
- package/dist/search/port.js +1 -1
- package/dist/search/remote-backend.d.ts +1 -1
- package/dist/search/remote-backend.js +2 -2
- package/dist/{semantic-consolidation-CmZi7thY.d.ts → semantic-consolidation-CCeRD9pV.d.ts} +1 -1
- package/dist/semantic-consolidation.d.ts +2 -2
- package/dist/semantic-consolidation.js +16 -16
- package/dist/semantic-rule-promotion.js +15 -15
- package/dist/semantic-rule-verifier.d.ts +1 -1
- package/dist/semantic-rule-verifier.js +15 -15
- package/dist/{service-CLkA7AQB.d.ts → service-BwpzRduk.d.ts} +2 -2
- 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/source-agent-qualifier.d.ts +1 -1
- package/dist/source-agent-qualifier.js +18 -18
- package/dist/standup/build.js +15 -15
- package/dist/{storage-wvX01lht.d.ts → storage-BprAGBG0.d.ts} +2 -1
- package/dist/storage.d.ts +2 -2
- package/dist/storage.js +14 -14
- package/dist/subject-config.d.ts +1 -1
- package/dist/summarizer.d.ts +1 -1
- package/dist/summarizer.js +5 -5
- package/dist/summary-snapshot.d.ts +1 -1
- package/dist/support-passport/index.d.ts +18 -17
- package/dist/support-passport/index.js +40 -40
- package/dist/task-llm-config.d.ts +16 -0
- package/dist/task-llm-config.js +12 -0
- package/dist/task-llm-config.js.map +1 -0
- package/dist/temporal-supersession.d.ts +2 -2
- package/dist/temporal-timeline-recall.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 +2 -2
- package/dist/tier-routing.d.ts +1 -1
- package/dist/topics.d.ts +1 -1
- package/dist/transcript.d.ts +1 -1
- package/dist/transfer/export-okf.d.ts +1 -1
- package/dist/transfer/export-okf.js +15 -15
- package/dist/trust-score-stage.d.ts +1 -1
- package/dist/trust-score.d.ts +1 -1
- package/dist/{types-Cyr32ABj.d.ts → types-nJV23pa3.d.ts} +1 -1
- package/dist/types.d.ts +1 -1
- package/dist/types.js +1 -1
- package/dist/utility-runtime.d.ts +1 -1
- package/dist/verified-recall.js +15 -15
- package/dist/who-knows-cli.d.ts +16 -14
- package/dist/who-knows-cli.js +16 -16
- package/dist/who-knows.d.ts +16 -14
- package/dist/who-knows.js +15 -15
- package/dist/write-envelope.d.ts +1 -1
- package/package.json +2 -2
- package/src/access-category-alias.test.ts +93 -0
- package/src/access-offline-manifest.ts +52 -2
- package/src/access-schema.ts +9 -4
- package/src/activity/config.test.ts +61 -0
- package/src/activity/config.ts +40 -1
- package/src/activity/timeline/analysis-provider.ts +8 -2
- package/src/activity/timeline/analysis-run.test.ts +82 -0
- package/src/activity/timeline/publish-cli.test.ts +30 -0
- package/src/activity/timeline/publish-cli.ts +7 -0
- package/src/activity/timeline/query.ts +8 -1
- package/src/activity/timeline/regenerate.test.ts +82 -2
- package/src/activity/timeline/regenerate.ts +7 -1
- package/src/activity/vault-frontmatter.test.ts +99 -1
- package/src/activity/vault-frontmatter.ts +131 -0
- package/src/activity/vault-publish.ts +6 -0
- package/src/activity/vault-publisher.test.ts +172 -0
- package/src/activity/vault-publisher.ts +69 -15
- package/src/activity/vault-region.test.ts +7 -2
- package/src/activity/vault-region.ts +7 -3
- package/src/background-generation-config.ts +32 -6
- package/src/background-generation.test.ts +10 -1
- package/src/cli/timeline-publish-commands.ts +9 -0
- package/src/config.test.ts +170 -43
- package/src/config.ts +17 -5
- package/src/extraction-error-classification.ts +36 -1
- package/src/extraction-timeout.test.ts +110 -1
- package/src/extraction.test.ts +19 -1
- package/src/extraction.ts +23 -21
- package/src/fallback-llm-codex-subscription.ts +193 -7
- package/src/fallback-llm-parse-failure.test.ts +156 -0
- package/src/fallback-llm.test.ts +58 -0
- package/src/fallback-llm.ts +187 -186
- package/src/index.ts +1 -0
- package/src/local-llm-config.ts +11 -10
- package/src/local-llm-headers-timeout.test.ts +30 -0
- package/src/local-llm-helpers.ts +28 -0
- package/src/local-llm.ts +8 -19
- package/src/namespaces/search.test.ts +51 -1
- package/src/namespaces/search.ts +48 -3
- package/src/orchestration/extraction-persist-promotion.test.ts +228 -2
- package/src/orchestration/extraction-persist-promotion.ts +17 -14
- package/src/orchestration/orchestrator-helpers.test.ts +104 -0
- package/src/orchestration/orchestrator-init.ts +366 -106
- package/src/orchestration/recall-internal.ts +5 -11
- package/src/orchestration/semantic-merge-promotion-payload.ts +62 -6
- package/src/orchestration/startup-collection-checks.ts +85 -0
- package/src/orchestrator-flush.test.ts +7 -0
- package/src/orchestrator-init.test.ts +1539 -0
- package/src/orchestrator.ts +7 -0
- package/src/qmd.ts +21 -10
- package/src/recall-state-view-admission.ts +11 -1
- package/src/recall-state-view-cron-intent.test.ts +268 -0
- package/src/recall-state-view-widen.test.ts +14 -5
- package/src/recall-state-view-widen.ts +8 -1
- package/src/recall-state-view.ts +5 -2
- package/src/reconcile-identity-cache.test.ts +82 -1
- package/src/search/port.ts +1 -1
- package/src/storage/cas-revision-store.test.ts +4 -0
- package/src/storage/cas-revision-store.ts +104 -12
- package/src/storage-frontmatter-cas.test.ts +19 -17
- package/src/summarizer.ts +5 -1
- package/src/task-llm-config.test.ts +124 -0
- package/src/task-llm-config.ts +88 -0
- package/src/testing/subjects/startup-discovery-lifecycle.test.ts +273 -0
- package/src/types.ts +1 -0
- package/dist/chunk-3CBI2ZSA.js.map +0 -1
- package/dist/chunk-5HYUUFMQ.js.map +0 -1
- package/dist/chunk-6H2G7RFT.js.map +0 -1
- package/dist/chunk-6YAIN5XJ.js.map +0 -1
- package/dist/chunk-ACY4ZPF7.js.map +0 -1
- package/dist/chunk-B36GUU6T.js.map +0 -1
- package/dist/chunk-BLDBT6HZ.js.map +0 -1
- package/dist/chunk-CWTCMZGE.js.map +0 -1
- package/dist/chunk-CZTPU65V.js.map +0 -1
- package/dist/chunk-FWWWUPOE.js.map +0 -1
- package/dist/chunk-IQEJIOEU.js.map +0 -1
- package/dist/chunk-IYKZJVL5.js.map +0 -1
- package/dist/chunk-JXN77SGO.js.map +0 -1
- package/dist/chunk-LPYYY4AP.js.map +0 -1
- package/dist/chunk-LQNRVPTV.js.map +0 -1
- package/dist/chunk-MVAQ2WM3.js.map +0 -1
- package/dist/chunk-P4ZAEYKG.js.map +0 -1
- package/dist/chunk-QHT7MOUF.js.map +0 -1
- package/dist/chunk-QTQ6XKGT.js.map +0 -1
- package/dist/chunk-TNZNSMVJ.js.map +0 -1
- package/dist/chunk-WKDFJXW5.js.map +0 -1
- package/dist/chunk-YDVAM7S4.js.map +0 -1
- package/dist/chunk-YFTNZMGR.js.map +0 -1
- package/dist/chunk-YKREX63Z.js.map +0 -1
- /package/dist/{auto-sync-RP4C6ZPF.js.map → auto-sync-D6BAPIJV.js.map} +0 -0
- /package/dist/{chunk-JTQR6L2N.js.map → chunk-2SKMZUOW.js.map} +0 -0
- /package/dist/{chunk-GG5FHZJJ.js.map → chunk-2SNCQHJZ.js.map} +0 -0
- /package/dist/{chunk-O76F5QPP.js.map → chunk-3QEVOQF5.js.map} +0 -0
- /package/dist/{chunk-3N3PBBEH.js.map → chunk-3XPN7AVY.js.map} +0 -0
- /package/dist/{chunk-X4TD4O2F.js.map → chunk-46Z3VGWF.js.map} +0 -0
- /package/dist/{chunk-2ZTDRNCS.js.map → chunk-4CMXI55L.js.map} +0 -0
- /package/dist/{chunk-MUTVRKKY.js.map → chunk-7D6SER6A.js.map} +0 -0
- /package/dist/{chunk-WBM2MVBK.js.map → chunk-7Z54NXVS.js.map} +0 -0
- /package/dist/{chunk-UHRZ324M.js.map → chunk-BGRTZOJB.js.map} +0 -0
- /package/dist/{chunk-ZEGL7YCC.js.map → chunk-BXIJSPCL.js.map} +0 -0
- /package/dist/{chunk-JKKII6GX.js.map → chunk-BYQX4IOG.js.map} +0 -0
- /package/dist/{chunk-WIWLX65T.js.map → chunk-C5R73BON.js.map} +0 -0
- /package/dist/{chunk-BD7JTBYP.js.map → chunk-D7MAYFQP.js.map} +0 -0
- /package/dist/{chunk-LMLGBG6H.js.map → chunk-DFVSJFHK.js.map} +0 -0
- /package/dist/{chunk-3NPNBVFR.js.map → chunk-ES5BUPYB.js.map} +0 -0
- /package/dist/{chunk-TNSCIPBQ.js.map → chunk-G6NQ3L4T.js.map} +0 -0
- /package/dist/{chunk-5N4MZLEH.js.map → chunk-GO5LOHCD.js.map} +0 -0
- /package/dist/{chunk-AECJY3GJ.js.map → chunk-GSSDHAYH.js.map} +0 -0
- /package/dist/{chunk-TSP5WH72.js.map → chunk-HJUP3K6L.js.map} +0 -0
- /package/dist/{chunk-AAZEKXUP.js.map → chunk-ICNJ6J46.js.map} +0 -0
- /package/dist/{chunk-6EHM2AV7.js.map → chunk-IMBQFHRV.js.map} +0 -0
- /package/dist/{chunk-4RZLTZVM.js.map → chunk-IOPIGX7Y.js.map} +0 -0
- /package/dist/{chunk-EYKIDK33.js.map → chunk-IS2IDFJP.js.map} +0 -0
- /package/dist/{chunk-VJIE4D2I.js.map → chunk-J4WGTN2N.js.map} +0 -0
- /package/dist/{chunk-NXGSONWM.js.map → chunk-J7FVMLBR.js.map} +0 -0
- /package/dist/{chunk-VSL63CFJ.js.map → chunk-JAJIMTFB.js.map} +0 -0
- /package/dist/{chunk-4JVQRFZD.js.map → chunk-JOP7W24J.js.map} +0 -0
- /package/dist/{chunk-YUW66UAH.js.map → chunk-JUDT33RX.js.map} +0 -0
- /package/dist/{chunk-D545Z7UH.js.map → chunk-K4JKAXMO.js.map} +0 -0
- /package/dist/{chunk-BV4ZKIZH.js.map → chunk-K75A5XWU.js.map} +0 -0
- /package/dist/{chunk-M6HBPLBA.js.map → chunk-KOTG3RXE.js.map} +0 -0
- /package/dist/{chunk-OB3XMWX5.js.map → chunk-KVO2BTA4.js.map} +0 -0
- /package/dist/{chunk-GI4ZBWPQ.js.map → chunk-KY236SP5.js.map} +0 -0
- /package/dist/{chunk-4BCHFSC7.js.map → chunk-LFVZD5EC.js.map} +0 -0
- /package/dist/{chunk-O4M4BDIJ.js.map → chunk-LKFVVN7R.js.map} +0 -0
- /package/dist/{chunk-4RX5O34R.js.map → chunk-MJC7UKH7.js.map} +0 -0
- /package/dist/{chunk-UZZ7SQT3.js.map → chunk-NVVZPBKI.js.map} +0 -0
- /package/dist/{chunk-VBSNUH4J.js.map → chunk-PKUJNICO.js.map} +0 -0
- /package/dist/{chunk-OPBFP4TF.js.map → chunk-QE6YVNP5.js.map} +0 -0
- /package/dist/{chunk-ENBPQEVU.js.map → chunk-QPVNK2VE.js.map} +0 -0
- /package/dist/{chunk-RLJHJQUY.js.map → chunk-QS5Q5RBV.js.map} +0 -0
- /package/dist/{chunk-3EKVN2OP.js.map → chunk-RDLPFM7I.js.map} +0 -0
- /package/dist/{chunk-F4EHXVP7.js.map → chunk-RJQAP333.js.map} +0 -0
- /package/dist/{chunk-5SPCMAUC.js.map → chunk-ROEFLU37.js.map} +0 -0
- /package/dist/{chunk-UZEHHXYC.js.map → chunk-SFHLQPBF.js.map} +0 -0
- /package/dist/{chunk-ZBW7A667.js.map → chunk-SUEOG2S4.js.map} +0 -0
- /package/dist/{chunk-Q7CLGFA7.js.map → chunk-TEMKBSV6.js.map} +0 -0
- /package/dist/{chunk-GMIQV6DD.js.map → chunk-TO36VPZI.js.map} +0 -0
- /package/dist/{chunk-FXHOZGSE.js.map → chunk-V2ZA4YWE.js.map} +0 -0
- /package/dist/{chunk-XH3HGI2N.js.map → chunk-VHKXRYQN.js.map} +0 -0
- /package/dist/{chunk-GAS7KYC7.js.map → chunk-VKWFNPBH.js.map} +0 -0
- /package/dist/{chunk-IL6ODG6M.js.map → chunk-VQWBUPSJ.js.map} +0 -0
- /package/dist/{chunk-5YCNDC3C.js.map → chunk-VQYWKCDR.js.map} +0 -0
- /package/dist/{chunk-54NX5EG4.js.map → chunk-W23JARAQ.js.map} +0 -0
- /package/dist/{chunk-YQNNHLCG.js.map → chunk-WPGR3RW4.js.map} +0 -0
- /package/dist/{chunk-FNHLI2RE.js.map → chunk-WZYHPAG5.js.map} +0 -0
- /package/dist/{chunk-TA4C3XB7.js.map → chunk-XM46Y66S.js.map} +0 -0
- /package/dist/{chunk-PCOVEDPK.js.map → chunk-YRIFXXMI.js.map} +0 -0
- /package/dist/{chunk-TRLOFIQC.js.map → chunk-YTK5MVNF.js.map} +0 -0
- /package/dist/{chunk-Q432REND.js.map → chunk-YTZN2UZO.js.map} +0 -0
- /package/dist/{chunk-6AGWBKQU.js.map → chunk-Z4GUX2M6.js.map} +0 -0
- /package/dist/{chunk-AENM6GKU.js.map → chunk-ZAEPD4C2.js.map} +0 -0
- /package/dist/{chunk-KQW3YGEN.js.map → chunk-ZRMMXWYI.js.map} +0 -0
- /package/dist/{chunk-MCRVQ5YQ.js.map → chunk-ZZCR2QYL.js.map} +0 -0
|
@@ -151,6 +151,18 @@ test("#2829 retainedCategoryAlias reads the transform-minted spelling from a raw
|
|
|
151
151
|
assert.equal(categoryAliasCoercion(undefined), undefined);
|
|
152
152
|
});
|
|
153
153
|
|
|
154
|
+
test("#2889 retainedCategoryAlias recovers the spelling from a single-parse envelope's category", () => {
|
|
155
|
+
// Single-parse callers (CLI store command, direct op.run) hand the op the
|
|
156
|
+
// raw envelope: the alias sits on `category`, no `rawCategory` exists yet.
|
|
157
|
+
assert.equal(retainedCategoryAlias({ content: "x", category: "project_state" }), "project_state");
|
|
158
|
+
assert.equal(retainedCategoryAlias({ content: "x", category: "project-state" }), "project-state");
|
|
159
|
+
// Canonical and near-miss categories never mint a retained spelling.
|
|
160
|
+
assert.equal(retainedCategoryAlias({ content: "x", category: "fact" }), undefined);
|
|
161
|
+
assert.equal(retainedCategoryAlias({ content: "x", category: "projection" }), undefined);
|
|
162
|
+
assert.equal(retainedCategoryAlias({ content: "x" }), undefined);
|
|
163
|
+
// A transform-minted rawCategory outranks the raw category spelling.
|
|
164
|
+
assert.equal(retainedCategoryAlias({ category: "project_update", rawCategory: "project" }), "project");
|
|
165
|
+
});
|
|
154
166
|
// ---------------------------------------------------------------------------
|
|
155
167
|
// Type-level regressions (enforced by tsc via check-types)
|
|
156
168
|
// ---------------------------------------------------------------------------
|
|
@@ -303,6 +315,10 @@ function makePersistService(memoryDir: string): PersistProbe {
|
|
|
303
315
|
writes.push({ category, content });
|
|
304
316
|
return { id: `mem-${writes.length}`, duplicateOf: undefined };
|
|
305
317
|
},
|
|
318
|
+
// The suggestion review-queue path re-reads and re-stamps the queued
|
|
319
|
+
// memory (explicit-capture.ts queueExplicitCaptureForReview).
|
|
320
|
+
getMemoryById: async (id: string) => ({ id, status: "active" }),
|
|
321
|
+
writeMemoryFrontmatter: async () => {},
|
|
306
322
|
});
|
|
307
323
|
return { service: new EngramAccessService(orch), writes };
|
|
308
324
|
}
|
|
@@ -410,6 +426,83 @@ test("#2829 peek idempotency ignores the retained spelling", async () => {
|
|
|
410
426
|
});
|
|
411
427
|
});
|
|
412
428
|
|
|
429
|
+
test("#2889 single-pass op.run retains the alias through canonical validation and replay", async () => {
|
|
430
|
+
// The CLI store command's path (PR #2866 review): the raw envelope carries
|
|
431
|
+
// the alias on `category` and op.run performs the ONLY schema parse. The
|
|
432
|
+
// boundary must still retain the spelling, and a same-key replay with a
|
|
433
|
+
// different accepted spelling must report THIS caller's alias while the
|
|
434
|
+
// stored result stays canonical and untouched.
|
|
435
|
+
await withPersistService(async ({ service, writes }) => {
|
|
436
|
+
const base = {
|
|
437
|
+
content: "single-pass aliased idempotent write",
|
|
438
|
+
confidence: 0.9,
|
|
439
|
+
tags: [] as string[],
|
|
440
|
+
idempotencyKey: "k-2889",
|
|
441
|
+
};
|
|
442
|
+
const first = await memoryStoreOperation.run(
|
|
443
|
+
{ ...base, category: "project_state" },
|
|
444
|
+
{ service },
|
|
445
|
+
);
|
|
446
|
+
assert.equal(first.result.status, "stored");
|
|
447
|
+
assert.deepEqual(first.result.categoryCoercion, { from: "project_state", to: "fact" });
|
|
448
|
+
assert.equal(writes.length, 1);
|
|
449
|
+
assert.equal(writes[0]?.category, "fact", "the persisted memory stays canonical");
|
|
450
|
+
|
|
451
|
+
const second = await memoryStoreOperation.run(
|
|
452
|
+
{ ...base, category: "project-state" },
|
|
453
|
+
{ service },
|
|
454
|
+
);
|
|
455
|
+
assert.equal(second.result.idempotencyReplay, true, "alias spellings share the canonical fingerprint");
|
|
456
|
+
assert.deepEqual(second.result.categoryCoercion, { from: "project-state", to: "fact" });
|
|
457
|
+
assert.equal(first.result.categoryCoercion?.from, "project_state", "the replay never mutates the stored note");
|
|
458
|
+
assert.equal(writes.length, 1, "the replay persists nothing");
|
|
459
|
+
|
|
460
|
+
const third = await memoryStoreOperation.run(
|
|
461
|
+
{ ...base, category: "fact" },
|
|
462
|
+
{ service },
|
|
463
|
+
);
|
|
464
|
+
assert.equal(third.result.idempotencyReplay, true);
|
|
465
|
+
assert.equal("categoryCoercion" in third.result, false, "a canonical replay reports no coercion");
|
|
466
|
+
assert.equal(writes.length, 1);
|
|
467
|
+
});
|
|
468
|
+
});
|
|
469
|
+
|
|
470
|
+
test("#2889 a single-pass dry run reports the coercion note and persists nothing", async () => {
|
|
471
|
+
await withPersistService(async ({ service, writes }) => {
|
|
472
|
+
const output = await memoryStoreOperation.run(
|
|
473
|
+
{ content: "single-pass dry-run alias", category: "project_update", confidence: 0.9, tags: [], dryRun: true },
|
|
474
|
+
{ service },
|
|
475
|
+
);
|
|
476
|
+
assert.equal(output.result.status, "validated");
|
|
477
|
+
assert.deepEqual(output.result.categoryCoercion, { from: "project_update", to: "fact" });
|
|
478
|
+
assert.equal(writes.length, 0);
|
|
479
|
+
});
|
|
480
|
+
});
|
|
481
|
+
|
|
482
|
+
test("#2889 suggestion_submit reports the coercion and queues the canonical category", async () => {
|
|
483
|
+
await withPersistService(async ({ service, writes }) => {
|
|
484
|
+
const aliased = await service.suggestionSubmit({
|
|
485
|
+
content: "suggested aliased fact",
|
|
486
|
+
category: "fact",
|
|
487
|
+
confidence: 0.9,
|
|
488
|
+
tags: [],
|
|
489
|
+
rawCategory: "project_update",
|
|
490
|
+
});
|
|
491
|
+
assert.equal(aliased.status, "queued_for_review");
|
|
492
|
+
assert.deepEqual(aliased.categoryCoercion, { from: "project_update", to: "fact" });
|
|
493
|
+
assert.equal(writes.length, 1);
|
|
494
|
+
assert.equal(writes[0]?.category, "fact", "the queued review memory stays canonical");
|
|
495
|
+
|
|
496
|
+
const canonical = await service.suggestionSubmit({
|
|
497
|
+
content: "suggested canonical fact",
|
|
498
|
+
category: "preference",
|
|
499
|
+
confidence: 0.9,
|
|
500
|
+
tags: [],
|
|
501
|
+
});
|
|
502
|
+
assert.equal(canonical.status, "queued_for_review");
|
|
503
|
+
assert.equal("categoryCoercion" in canonical, false, "a no-alias submit reports no coercion");
|
|
504
|
+
});
|
|
505
|
+
});
|
|
413
506
|
// ---------------------------------------------------------------------------
|
|
414
507
|
// Quarantine — the parked payload keeps the raw spelling for replay
|
|
415
508
|
// ---------------------------------------------------------------------------
|
|
@@ -57,11 +57,17 @@ export interface ServerIdentityCacheEntry {
|
|
|
57
57
|
export function planServerIdentityCacheWrite(input: {
|
|
58
58
|
persisted: ReadonlyMap<string, ServerIdentityCacheEntry>;
|
|
59
59
|
yieldedPaths: ReadonlySet<string>;
|
|
60
|
+
/** Paths the walk saw but never yielded (removed by the exclusion
|
|
61
|
+
* callback). Not deleted — pruning them would drop their persisted
|
|
62
|
+
* classification and force a re-classify on every later cycle. */
|
|
63
|
+
retainedPaths?: ReadonlySet<string>;
|
|
60
64
|
streamCompleted: boolean;
|
|
61
65
|
cacheDirty: boolean;
|
|
62
66
|
}): { shouldWrite: boolean; entries: ServerIdentityCacheEntry[] } {
|
|
63
67
|
const entries = input.streamCompleted
|
|
64
|
-
? [...input.persisted.values()].filter(
|
|
68
|
+
? [...input.persisted.values()].filter(
|
|
69
|
+
(entry) => input.yieldedPaths.has(entry.path) || input.retainedPaths?.has(entry.path)
|
|
70
|
+
)
|
|
65
71
|
: [...input.persisted.values()];
|
|
66
72
|
return { shouldWrite: input.cacheDirty || entries.length !== input.persisted.size, entries };
|
|
67
73
|
}
|
|
@@ -147,7 +153,7 @@ async function withServerIdentityCacheWriteLock(cachePath: string, write: () =>
|
|
|
147
153
|
|
|
148
154
|
/** Union of the entries being written and the current on-disk set; on conflict
|
|
149
155
|
* the write wins (it reflects the newer run). Callers hold the write lock. */
|
|
150
|
-
async function mergeServerIdentityCacheEntries(
|
|
156
|
+
export async function mergeServerIdentityCacheEntries(
|
|
151
157
|
fs: typeof import("node:fs/promises"),
|
|
152
158
|
cachePath: string,
|
|
153
159
|
entries: readonly ServerIdentityCacheEntry[],
|
|
@@ -178,6 +184,9 @@ async function mergeServerIdentityCacheEntries(
|
|
|
178
184
|
? { identityResolutionVersion: entry.identityResolutionVersion }
|
|
179
185
|
: {}),
|
|
180
186
|
}),
|
|
187
|
+
...(entry.statIdentity !== undefined && entry.excluded !== undefined
|
|
188
|
+
? { statIdentity: entry.statIdentity, excluded: entry.excluded }
|
|
189
|
+
: {}),
|
|
181
190
|
});
|
|
182
191
|
}
|
|
183
192
|
}
|
|
@@ -187,6 +196,34 @@ async function mergeServerIdentityCacheEntries(
|
|
|
187
196
|
return [...merged.values()];
|
|
188
197
|
}
|
|
189
198
|
|
|
199
|
+
/** Record classifications for files the walk excluded (the exclusion callback
|
|
200
|
+
* returned true, so they were never yielded): they were seen this walk, so
|
|
201
|
+
* their entries must persist and must not be pruned as deleted. Mirrors the
|
|
202
|
+
* per-yield classification application for never-yielded paths. */
|
|
203
|
+
export function retainExcludedClassifications(input: {
|
|
204
|
+
persisted: Map<string, ServerIdentityCacheEntry>;
|
|
205
|
+
classifications: ReadonlyMap<string, { statIdentity: string; excluded: boolean }>;
|
|
206
|
+
yieldedPaths: ReadonlySet<string>;
|
|
207
|
+
}): { retained: Set<string>; changed: boolean } {
|
|
208
|
+
const retained = new Set<string>();
|
|
209
|
+
let changed = false;
|
|
210
|
+
for (const [pathName, classification] of input.classifications) {
|
|
211
|
+
if (input.yieldedPaths.has(pathName)) continue;
|
|
212
|
+
retained.add(pathName);
|
|
213
|
+
const entry = input.persisted.get(pathName) ?? { path: pathName, sha256: "" };
|
|
214
|
+
if (entry.statIdentity === classification.statIdentity && entry.excluded === classification.excluded) {
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
input.persisted.set(pathName, {
|
|
218
|
+
...entry,
|
|
219
|
+
statIdentity: classification.statIdentity,
|
|
220
|
+
excluded: classification.excluded,
|
|
221
|
+
});
|
|
222
|
+
changed = true;
|
|
223
|
+
}
|
|
224
|
+
return { retained, changed };
|
|
225
|
+
}
|
|
226
|
+
|
|
190
227
|
export async function createOfflineSyncManifestStream(
|
|
191
228
|
orchestrator: Orchestrator,
|
|
192
229
|
namespace: string,
|
|
@@ -227,10 +264,12 @@ export async function createOfflineSyncManifestStream(
|
|
|
227
264
|
// near-cold rebuild on the next request.
|
|
228
265
|
const persistedEntries = new Map(identityCache);
|
|
229
266
|
const yieldedPaths = new Set<string>();
|
|
267
|
+
const retainedPaths = new Set<string>();
|
|
230
268
|
const flush = async (): Promise<void> => {
|
|
231
269
|
const { shouldWrite, entries } = planServerIdentityCacheWrite({
|
|
232
270
|
persisted: persistedEntries,
|
|
233
271
|
yieldedPaths,
|
|
272
|
+
retainedPaths,
|
|
234
273
|
streamCompleted,
|
|
235
274
|
cacheDirty,
|
|
236
275
|
});
|
|
@@ -334,6 +373,17 @@ export async function createOfflineSyncManifestStream(
|
|
|
334
373
|
}
|
|
335
374
|
streamCompleted = true;
|
|
336
375
|
} finally {
|
|
376
|
+
// Files the exclusion callback removed from the snapshot were seen
|
|
377
|
+
// this walk but never yielded: persist their classifications so the
|
|
378
|
+
// next cycle skips the read+parse, and keep them out of the
|
|
379
|
+
// deleted-path prune.
|
|
380
|
+
const retained = retainExcludedClassifications({
|
|
381
|
+
persisted: persistedEntries,
|
|
382
|
+
classifications: classificationUpdates,
|
|
383
|
+
yieldedPaths,
|
|
384
|
+
});
|
|
385
|
+
for (const pathName of retained.retained) retainedPaths.add(pathName);
|
|
386
|
+
if (retained.changed) cacheDirty = true;
|
|
337
387
|
await flush();
|
|
338
388
|
}
|
|
339
389
|
})(),
|
package/src/access-schema.ts
CHANGED
|
@@ -323,13 +323,18 @@ export function categoryAliasCoercion(rawCategory: string | undefined): Category
|
|
|
323
323
|
/**
|
|
324
324
|
* Recover the retained alias spelling from a pre-parse raw envelope: the
|
|
325
325
|
* `rawCategory` minted by a previous parse of the same schema (the HTTP/MCP
|
|
326
|
-
* validate-then-dispatch double pass) or
|
|
327
|
-
*
|
|
326
|
+
* validate-then-dispatch double pass), or — for single-parse callers like the
|
|
327
|
+
* CLI store command — the as-yet-untransformed alias still sitting on
|
|
328
|
+
* `category` (issue #2889). A minted `rawCategory` always wins: it names the
|
|
329
|
+
* spelling the transform actually canonicalized.
|
|
328
330
|
*/
|
|
329
331
|
export function retainedCategoryAlias(rawInput: unknown): MemoryCategoryAlias | undefined {
|
|
330
332
|
if (!rawInput || typeof rawInput !== "object") return undefined;
|
|
331
|
-
const
|
|
332
|
-
|
|
333
|
+
const envelope = rawInput as Record<string, unknown>;
|
|
334
|
+
const minted = envelope.rawCategory;
|
|
335
|
+
if (typeof minted === "string" && isMemoryCategoryAlias(minted)) return minted;
|
|
336
|
+
const category = envelope.category;
|
|
337
|
+
return typeof category === "string" && isMemoryCategoryAlias(category) ? category : undefined;
|
|
333
338
|
}
|
|
334
339
|
|
|
335
340
|
/**
|
|
@@ -366,3 +366,64 @@ test("an enabled vault rejects relative or whitespace-only vaultPath at config l
|
|
|
366
366
|
const inert = parseActivityConfig({ timeline: { vault: { enabled: false, vaultPath: "." } } });
|
|
367
367
|
assert.equal(inert.timeline.vault.vaultPath, ".");
|
|
368
368
|
});
|
|
369
|
+
|
|
370
|
+
test("insertUnderHeading must be a trimmed single-line heading (#2917)", () => {
|
|
371
|
+
for (const insertUnderHeading of [" ", " Journal ", "Journal\nExtra"]) {
|
|
372
|
+
assert.throws(
|
|
373
|
+
() => parseActivityConfig({ timeline: { vault: { insertUnderHeading } } }),
|
|
374
|
+
/insertUnderHeading must be a non-empty trimmed single-line heading/,
|
|
375
|
+
`value ${JSON.stringify(insertUnderHeading)} must be rejected`,
|
|
376
|
+
);
|
|
377
|
+
}
|
|
378
|
+
const ok = parseActivityConfig({ timeline: { vault: { insertUnderHeading: "Journal" } } });
|
|
379
|
+
assert.equal(ok.timeline.vault.insertUnderHeading, "Journal");
|
|
380
|
+
});
|
|
381
|
+
|
|
382
|
+
test("readback.journalSection must be a trimmed single-line heading (#2917)", () => {
|
|
383
|
+
for (const journalSection of [" Journal ", "Journal\r\nExtra"]) {
|
|
384
|
+
assert.throws(
|
|
385
|
+
() => parseActivityConfig({ timeline: { vault: { readback: { journalSection } } } }),
|
|
386
|
+
/journalSection must be a non-empty trimmed single-line heading/,
|
|
387
|
+
);
|
|
388
|
+
}
|
|
389
|
+
const ok = parseActivityConfig({ timeline: { vault: { readback: { journalSection: "Journal" } } } });
|
|
390
|
+
assert.equal(ok.timeline.vault.readback.journalSection, "Journal");
|
|
391
|
+
});
|
|
392
|
+
|
|
393
|
+
test("heading-strategy section names that cannot round-trip are rejected at config load (#2917)", () => {
|
|
394
|
+
// `## Timeline #` parses back as `Timeline`. Accepted at load, every
|
|
395
|
+
// publish would throw before producing a status.
|
|
396
|
+
assert.throws(
|
|
397
|
+
() =>
|
|
398
|
+
parseActivityConfig({
|
|
399
|
+
timeline: {
|
|
400
|
+
vault: { sectionStrategy: "heading", publish: { timeline: { section: "Timeline #" } } },
|
|
401
|
+
},
|
|
402
|
+
}),
|
|
403
|
+
/publish\.timeline\.section must survive a heading render-and-parse round trip/,
|
|
404
|
+
);
|
|
405
|
+
const ok = parseActivityConfig({
|
|
406
|
+
timeline: {
|
|
407
|
+
vault: { sectionStrategy: "heading", publish: { timeline: { section: "Timeline" } } },
|
|
408
|
+
},
|
|
409
|
+
});
|
|
410
|
+
assert.equal(ok.timeline.vault.publish.timeline.section, "Timeline");
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
test("marker-strategy still accepts a section name that would fail heading round-trip (#2917)", () => {
|
|
414
|
+
const ok = parseActivityConfig({
|
|
415
|
+
timeline: {
|
|
416
|
+
vault: { sectionStrategy: "markers", publish: { timeline: { section: "Timeline #" } } },
|
|
417
|
+
},
|
|
418
|
+
});
|
|
419
|
+
assert.equal(ok.timeline.vault.publish.timeline.section, "Timeline #");
|
|
420
|
+
});
|
|
421
|
+
|
|
422
|
+
test("insertUnderHeading that cannot round-trip is rejected at config load (#2917)", () => {
|
|
423
|
+
assert.throws(
|
|
424
|
+
() => parseActivityConfig({ timeline: { vault: { insertUnderHeading: "Timeline #" } } }),
|
|
425
|
+
/insertUnderHeading must survive a heading render-and-parse round trip/,
|
|
426
|
+
);
|
|
427
|
+
const ok = parseActivityConfig({ timeline: { vault: { insertUnderHeading: "Journal" } } });
|
|
428
|
+
assert.equal(ok.timeline.vault.insertUnderHeading, "Journal");
|
|
429
|
+
});
|
package/src/activity/config.ts
CHANGED
|
@@ -2,10 +2,11 @@ import path from "node:path";
|
|
|
2
2
|
|
|
3
3
|
import { coerceBooleanLike, coerceNumber } from "../connectors/coerce.js";
|
|
4
4
|
import { assertValidTimezone } from "./digest.js";
|
|
5
|
-
import { applyLegacyJournalHeading } from "./journal-heading.js";
|
|
5
|
+
import { applyLegacyJournalHeading, normalizeJournalHeading } from "./journal-heading.js";
|
|
6
6
|
import { checkVaultJournalPrerequisites } from "./journal-vault-prereq.js";
|
|
7
7
|
import { resolveJournalSource } from "./journal-source.js";
|
|
8
8
|
import { validateVaultNoteTemplate } from "./vault-path.js";
|
|
9
|
+
import { headingSurvivesRoundTrip } from "./vault-publish.js";
|
|
9
10
|
import { validateRegionName } from "./vault-region.js";
|
|
10
11
|
import { TIMELINE_ANALYSIS_DEFAULT_TIMEOUT_MS } from "./timeline/analysis.js";
|
|
11
12
|
import { ANALYSIS_METADATA_MAX_FIELD_LENGTH, isAnalysisIdentifier } from "./timeline/analysis-metadata.js";
|
|
@@ -376,6 +377,23 @@ export function parseTimelineVaultConfig(raw: unknown): ActivityTimelineVaultCon
|
|
|
376
377
|
const noteTemplate = optionalNonEmptyString(vault.noteTemplate, "activity.timeline.vault.noteTemplate") ?? "";
|
|
377
378
|
const insertUnderHeading =
|
|
378
379
|
optionalNonEmptyString(vault.insertUnderHeading, "activity.timeline.vault.insertUnderHeading") ?? "";
|
|
380
|
+
// The configured insertion heading is matched against parsed note
|
|
381
|
+
// headings, so a blank, padded, or multi-line value can never match
|
|
382
|
+
// (issue #2917). Reuse the journal work's canonical heading validator —
|
|
383
|
+
// no second parser — and require the trimmed form like publish sections.
|
|
384
|
+
if (insertUnderHeading.length > 0) {
|
|
385
|
+
const heading = normalizeJournalHeading(insertUnderHeading);
|
|
386
|
+
if (!heading.ok || heading.heading !== insertUnderHeading) {
|
|
387
|
+
throw new RangeError(
|
|
388
|
+
"activity.timeline.vault.insertUnderHeading must be a non-empty trimmed single-line heading",
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
if (!headingSurvivesRoundTrip(insertUnderHeading)) {
|
|
392
|
+
throw new RangeError(
|
|
393
|
+
"activity.timeline.vault.insertUnderHeading must survive a heading render-and-parse round trip",
|
|
394
|
+
);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
379
397
|
|
|
380
398
|
if (typeof vault.sectionStrategy !== "undefined" && typeof vault.sectionStrategy !== "string") {
|
|
381
399
|
throw new TypeError("activity.timeline.vault.sectionStrategy must be a string");
|
|
@@ -423,6 +441,15 @@ export function parseTimelineVaultConfig(raw: unknown): ActivityTimelineVaultCon
|
|
|
423
441
|
}
|
|
424
442
|
|
|
425
443
|
const publish = parseVaultPublishBlock(vault.publish, weeklyNotePath);
|
|
444
|
+
if (sectionStrategy === "heading") {
|
|
445
|
+
for (const kind of ["timeline", "standup", "weekly", "locations"] as const) {
|
|
446
|
+
if (!headingSurvivesRoundTrip(publish[kind].section)) {
|
|
447
|
+
throw new RangeError(
|
|
448
|
+
`activity.timeline.vault.publish.${kind}.section must survive a heading render-and-parse round trip`,
|
|
449
|
+
);
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
}
|
|
426
453
|
const wikilinksRaw = vault.wikilinks;
|
|
427
454
|
const wikilinks =
|
|
428
455
|
wikilinksRaw === undefined
|
|
@@ -439,6 +466,18 @@ export function parseTimelineVaultConfig(raw: unknown): ActivityTimelineVaultCon
|
|
|
439
466
|
(readbackRaw as Record<string, unknown> | undefined)?.journalSection,
|
|
440
467
|
"activity.timeline.vault.readback.journalSection",
|
|
441
468
|
);
|
|
469
|
+
// Readback matches the section by parsed heading text, so a padded or
|
|
470
|
+
// multi-line journalSection can never match and would silently read back
|
|
471
|
+
// an empty journal (issue #2917). Same canonical validator as the legacy
|
|
472
|
+
// journal.heading alias.
|
|
473
|
+
if (readbackJournalSection !== undefined && readbackJournalSection.length > 0) {
|
|
474
|
+
const heading = normalizeJournalHeading(readbackJournalSection);
|
|
475
|
+
if (!heading.ok || heading.heading !== readbackJournalSection) {
|
|
476
|
+
throw new RangeError(
|
|
477
|
+
"activity.timeline.vault.readback.journalSection must be a non-empty trimmed single-line heading",
|
|
478
|
+
);
|
|
479
|
+
}
|
|
480
|
+
}
|
|
442
481
|
const readback = {
|
|
443
482
|
journalSection: readbackJournalSection ?? "",
|
|
444
483
|
};
|
|
@@ -25,6 +25,7 @@ export interface TimelineAnalysisLocalLlm {
|
|
|
25
25
|
operation?: string;
|
|
26
26
|
redactProviderErrors?: boolean;
|
|
27
27
|
model?: string;
|
|
28
|
+
failureDiag?: { lastError?: unknown };
|
|
28
29
|
},
|
|
29
30
|
): Promise<{ content: string } | null>;
|
|
30
31
|
}
|
|
@@ -40,6 +41,7 @@ export interface TimelineAnalysisRemoteLlm {
|
|
|
40
41
|
modelChain?: { primary?: string; fallbacks?: string[] };
|
|
41
42
|
includeDefaultModelFallback?: boolean;
|
|
42
43
|
redactProviderErrors?: boolean;
|
|
44
|
+
failureDiag?: { lastError?: unknown };
|
|
43
45
|
},
|
|
44
46
|
): Promise<{ content: string } | null>;
|
|
45
47
|
}
|
|
@@ -99,6 +101,7 @@ export function timelineAnalysisCompleteFromClients(input: {
|
|
|
99
101
|
"timeline analysis local provider is not configured",
|
|
100
102
|
);
|
|
101
103
|
}
|
|
104
|
+
const failureDiag: { lastError?: unknown } = {};
|
|
102
105
|
const result = await localLlm.chatCompletion(messages, {
|
|
103
106
|
temperature: 0,
|
|
104
107
|
maxTokens: 2048,
|
|
@@ -106,10 +109,11 @@ export function timelineAnalysisCompleteFromClients(input: {
|
|
|
106
109
|
operation: "timeline-analysis",
|
|
107
110
|
redactProviderErrors: true,
|
|
108
111
|
model,
|
|
112
|
+
failureDiag,
|
|
109
113
|
});
|
|
110
114
|
if (result === null) {
|
|
111
115
|
throw new TimelineAnalysisProviderError(
|
|
112
|
-
|
|
116
|
+
classifyAnalysisProviderError(failureDiag.lastError),
|
|
113
117
|
"timeline analysis local provider returned no completion",
|
|
114
118
|
);
|
|
115
119
|
}
|
|
@@ -121,6 +125,7 @@ export function timelineAnalysisCompleteFromClients(input: {
|
|
|
121
125
|
"timeline analysis remote provider is not configured",
|
|
122
126
|
);
|
|
123
127
|
}
|
|
128
|
+
const failureDiag: { lastError?: unknown } = {};
|
|
124
129
|
const result = await remoteLlm.chatCompletion(messages, {
|
|
125
130
|
temperature: 0,
|
|
126
131
|
maxTokens: 2048,
|
|
@@ -128,10 +133,11 @@ export function timelineAnalysisCompleteFromClients(input: {
|
|
|
128
133
|
modelChain: { primary: `${provider}/${model}` },
|
|
129
134
|
includeDefaultModelFallback: false,
|
|
130
135
|
redactProviderErrors: true,
|
|
136
|
+
failureDiag,
|
|
131
137
|
});
|
|
132
138
|
if (result === null) {
|
|
133
139
|
throw new TimelineAnalysisProviderError(
|
|
134
|
-
|
|
140
|
+
classifyAnalysisProviderError(failureDiag.lastError),
|
|
135
141
|
`timeline analysis provider "${provider}" is not configured`,
|
|
136
142
|
);
|
|
137
143
|
}
|
|
@@ -417,3 +417,85 @@ test("adapter pins the call-time provider verbatim with no chain fallback", asyn
|
|
|
417
417
|
});
|
|
418
418
|
assert.deepEqual(seen, ["anthropic/claude-4_1"]);
|
|
419
419
|
});
|
|
420
|
+
|
|
421
|
+
test("remote failureDiag preserves a rate-limited failure as retryable (issue #2891)", async () => {
|
|
422
|
+
const cards = sampleCards();
|
|
423
|
+
const remoteLlm: TimelineAnalysisRemoteLlm = {
|
|
424
|
+
chatCompletion: async (_messages, options) => {
|
|
425
|
+
assert.ok(options.failureDiag, "adapter must pass a failureDiag out-box");
|
|
426
|
+
options.failureDiag.lastError = Object.assign(new Error("provider throttled"), { status: 429 });
|
|
427
|
+
return null;
|
|
428
|
+
},
|
|
429
|
+
};
|
|
430
|
+
const result = await runTimelineCardAnalysis({
|
|
431
|
+
date: DATE,
|
|
432
|
+
timezone: TZ,
|
|
433
|
+
cards,
|
|
434
|
+
observations: [observation()],
|
|
435
|
+
config: ENABLED,
|
|
436
|
+
deps: { remoteLlm },
|
|
437
|
+
});
|
|
438
|
+
assert.equal(result.status, "provider_failed");
|
|
439
|
+
assert.equal(result.failure?.kind, "rate_limited");
|
|
440
|
+
assert.equal(result.failure?.retryable, true);
|
|
441
|
+
assert.equal(result.failure?.preservesDeterministic, true);
|
|
442
|
+
assert.equal(result.cards, cards);
|
|
443
|
+
});
|
|
444
|
+
|
|
445
|
+
test("local failureDiag preserves a rate-limited failure (issue #2891)", async () => {
|
|
446
|
+
const localLlm: TimelineAnalysisLocalLlm = {
|
|
447
|
+
chatCompletion: async (_messages, options) => {
|
|
448
|
+
assert.ok(options.failureDiag, "adapter must pass a failureDiag out-box");
|
|
449
|
+
options.failureDiag.lastError = Object.assign(new Error("local backend throttled"), { status: 429 });
|
|
450
|
+
return null;
|
|
451
|
+
},
|
|
452
|
+
};
|
|
453
|
+
const result = await runTimelineCardAnalysis({
|
|
454
|
+
date: DATE,
|
|
455
|
+
timezone: TZ,
|
|
456
|
+
cards: sampleCards(),
|
|
457
|
+
observations: [observation()],
|
|
458
|
+
config: { enabled: true, provider: "local", model: "local-test" },
|
|
459
|
+
deps: { localLlm },
|
|
460
|
+
});
|
|
461
|
+
assert.equal(result.status, "provider_failed");
|
|
462
|
+
assert.equal(result.failure?.kind, "rate_limited");
|
|
463
|
+
assert.equal(result.failure?.retryable, true);
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
test("failureDiag without a rate limit still classifies as provider_unavailable", async () => {
|
|
467
|
+
const remoteLlm: TimelineAnalysisRemoteLlm = {
|
|
468
|
+
chatCompletion: async (_messages, options) => {
|
|
469
|
+
options.failureDiag!.lastError = Object.assign(new Error("server error"), { status: 500 });
|
|
470
|
+
return null;
|
|
471
|
+
},
|
|
472
|
+
};
|
|
473
|
+
const result = await runTimelineCardAnalysis({
|
|
474
|
+
date: DATE,
|
|
475
|
+
timezone: TZ,
|
|
476
|
+
cards: sampleCards(),
|
|
477
|
+
observations: [observation()],
|
|
478
|
+
config: ENABLED,
|
|
479
|
+
deps: { remoteLlm },
|
|
480
|
+
});
|
|
481
|
+
assert.equal(result.status, "provider_failed");
|
|
482
|
+
assert.equal(result.failure?.kind, "provider_unavailable");
|
|
483
|
+
assert.equal(result.failure?.retryable, true);
|
|
484
|
+
});
|
|
485
|
+
|
|
486
|
+
test("a null completion with no recorded cause keeps the generic kind", async () => {
|
|
487
|
+
const remoteLlm: TimelineAnalysisRemoteLlm = {
|
|
488
|
+
chatCompletion: async () => null,
|
|
489
|
+
};
|
|
490
|
+
const result = await runTimelineCardAnalysis({
|
|
491
|
+
date: DATE,
|
|
492
|
+
timezone: TZ,
|
|
493
|
+
cards: sampleCards(),
|
|
494
|
+
observations: [observation()],
|
|
495
|
+
config: ENABLED,
|
|
496
|
+
deps: { remoteLlm },
|
|
497
|
+
});
|
|
498
|
+
assert.equal(result.status, "provider_failed");
|
|
499
|
+
assert.equal(result.failure?.kind, "provider_unavailable");
|
|
500
|
+
assert.equal(result.failure?.retryable, true);
|
|
501
|
+
});
|
|
@@ -167,3 +167,33 @@ test("range and search reject publish-only flags instead of ignoring them", asyn
|
|
|
167
167
|
assert.equal(searchCode, 1);
|
|
168
168
|
assert.match(searchSink.err, /unknown flag --dry-run \(valid: --from, --limit, --query, --to\)/);
|
|
169
169
|
});
|
|
170
|
+
|
|
171
|
+
test("an explicitly empty --date is invalid, not treated as absent (#2917)", async () => {
|
|
172
|
+
const { config, notePath, note } = makeFixture();
|
|
173
|
+
const sink = capture();
|
|
174
|
+
|
|
175
|
+
const code = await runTimelineCliCommand(
|
|
176
|
+
{ cards: null, qa: { enabled: false, maxRangeDays: 31 }, timelineEnabled: true, config },
|
|
177
|
+
["publish", "--date", ""],
|
|
178
|
+
sink.io,
|
|
179
|
+
);
|
|
180
|
+
|
|
181
|
+
assert.equal(code, 1);
|
|
182
|
+
assert.match(sink.err, /Invalid --date ""/);
|
|
183
|
+
assert.equal(readFileSync(notePath, "utf8"), note, "no note is published on an empty --date");
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
test("publish rejects extra positional arguments instead of discarding them (#2917)", async () => {
|
|
187
|
+
const { config, notePath, note } = makeFixture();
|
|
188
|
+
const sink = capture();
|
|
189
|
+
|
|
190
|
+
const code = await runTimelineCliCommand(
|
|
191
|
+
{ cards: null, qa: { enabled: false, maxRangeDays: 31 }, timelineEnabled: true, config },
|
|
192
|
+
["publish", "extra-arg", "--date", DATE],
|
|
193
|
+
sink.io,
|
|
194
|
+
);
|
|
195
|
+
|
|
196
|
+
assert.equal(code, 1);
|
|
197
|
+
assert.match(sink.err, /takes no positional arguments/);
|
|
198
|
+
assert.equal(readFileSync(notePath, "utf8"), note, "no note is published on excess syntax");
|
|
199
|
+
});
|
|
@@ -51,6 +51,13 @@ export function runTimelinePublishCli(
|
|
|
51
51
|
return 1;
|
|
52
52
|
}
|
|
53
53
|
|
|
54
|
+
// An explicitly empty --date is invalid, not absent (issue #2917): ""
|
|
55
|
+
// can never be a day, and silently falling back to today would publish
|
|
56
|
+
// the wrong note. Only a missing --date means "today".
|
|
57
|
+
if (options.date !== undefined && (typeof options.date !== "string" || options.date.length === 0)) {
|
|
58
|
+
io.stderr.write(`Invalid --date ${JSON.stringify(options.date ?? "")}; expected YYYY-MM-DD.\n`);
|
|
59
|
+
return 1;
|
|
60
|
+
}
|
|
54
61
|
// Timeline artifacts are grouped on the configured activity timezone's
|
|
55
62
|
// calendar day, so "today" must be derived there — the host-local day
|
|
56
63
|
// drifts by one near either timezone's midnight.
|
|
@@ -311,7 +311,14 @@ export async function runTimelineCliCommand(
|
|
|
311
311
|
io.stderr.write("timeline publish requires the Remnic config — run `remnic doctor`\n");
|
|
312
312
|
return 1;
|
|
313
313
|
}
|
|
314
|
-
const publishFlags = parseFlags(rest, PUBLISH_FLAGS)
|
|
314
|
+
const { flags: publishFlags, positional } = parseFlags(rest, PUBLISH_FLAGS);
|
|
315
|
+
// `publish` takes flags only (issue #2917): a stray positional used
|
|
316
|
+
// to be silently discarded while today's note published.
|
|
317
|
+
if (positional.length > 0) {
|
|
318
|
+
throw new TypeError(
|
|
319
|
+
`timeline publish takes no positional arguments (got ${JSON.stringify(positional.join(" "))})`,
|
|
320
|
+
);
|
|
321
|
+
}
|
|
315
322
|
return runTimelinePublishCli(
|
|
316
323
|
deps.config,
|
|
317
324
|
{
|