@remnic/core 9.69.88 → 9.69.90
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.js +74 -72
- package/dist/access-authorization-probe.js +75 -73
- package/dist/access-boundary.js +74 -72
- package/dist/access-cli.js +168 -165
- package/dist/access-cli.js.map +1 -1
- package/dist/access-extraction-force-flush.js +74 -72
- package/dist/access-http-briefing.js +75 -73
- package/dist/access-http-query.js +76 -74
- package/dist/access-http.js +98 -96
- package/dist/access-identity-continuity-surface.js +74 -72
- package/dist/access-lcm-surface.js +74 -72
- package/dist/access-mcp-output-schemas.d.ts.map +1 -1
- package/dist/access-mcp-output-schemas.js +1 -1
- package/dist/access-mcp.js +86 -84
- package/dist/access-memory-search-fanout.js +3 -3
- package/dist/access-namespace-preflight.js +74 -72
- package/dist/access-observe-write-category.js +11 -10
- package/dist/access-observe-write-surface.js +74 -72
- package/dist/access-offline-manifest.js +10 -9
- package/dist/access-operations-batch.js +76 -74
- package/dist/access-operations.js +83 -81
- package/dist/access-recall-concurrency.js +74 -72
- package/dist/access-recall-corpus-versions.d.ts +12 -0
- package/dist/access-recall-corpus-versions.d.ts.map +1 -0
- package/dist/access-recall-corpus-versions.js +10 -0
- package/dist/access-recall-diagnostics.js +5 -5
- package/dist/access-recall-response.d.ts +4 -0
- package/dist/access-recall-response.d.ts.map +1 -1
- package/dist/access-recall-response.js +74 -72
- package/dist/access-recall-surface.d.ts +8 -0
- package/dist/access-recall-surface.d.ts.map +1 -1
- package/dist/access-recall-surface.js +74 -72
- package/dist/access-schema.js +10 -9
- package/dist/access-service.d.ts +5 -0
- package/dist/access-service.d.ts.map +1 -1
- package/dist/access-service.js +74 -72
- package/dist/access-surface-catalog.js +76 -74
- package/dist/access-surface-catalog.js.map +1 -1
- package/dist/active-memory-bridge.js +3 -3
- package/dist/active-recall.js +27 -24
- package/dist/active-recall.js.map +1 -1
- package/dist/adapters/index.js +7 -7
- package/dist/adapters/registry.js +3 -3
- package/dist/{auto-sync-U5N3CB5Y.js → auto-sync-PAWBFQWL.js} +5 -5
- package/dist/briefing.js +19 -19
- package/dist/buffer.js +8 -8
- package/dist/calibration.js +2 -2
- package/dist/capabilities.d.ts +2 -1
- package/dist/capabilities.d.ts.map +1 -1
- package/dist/capabilities.js +1 -1
- package/dist/{capsule-crypto-YO5QJ6L3.js → capsule-crypto-7FJQINUR.js} +2 -2
- package/dist/causal-consolidation.js +19 -19
- package/dist/{chunk-BMXEBWBT.js → chunk-2EMROIXS.js} +2 -1
- package/dist/{chunk-BMXEBWBT.js.map → chunk-2EMROIXS.js.map} +1 -1
- package/dist/{chunk-MCTM4YPL.js → chunk-2FLFJTCI.js} +4 -2
- package/dist/chunk-2FLFJTCI.js.map +1 -0
- package/dist/{chunk-RDJ6C7NZ.js → chunk-2IWBHZ3H.js} +5 -5
- package/dist/{chunk-UP75KL3L.js → chunk-2JRB3Z5N.js} +2 -2
- package/dist/{chunk-BXLOS5AJ.js → chunk-2NLLXCJG.js} +2 -2
- package/dist/{chunk-KN6CIN7I.js → chunk-32HO62I4.js} +2 -2
- package/dist/{chunk-JLPNONPH.js → chunk-35A7GCHG.js} +2 -2
- package/dist/{chunk-MXCAJKMA.js → chunk-37ZQYFX4.js} +6 -6
- package/dist/{chunk-LW3HKRL7.js → chunk-3BTHXB7Z.js} +3 -3
- package/dist/{chunk-C7V3KPKJ.js → chunk-47LTKAGL.js} +2 -2
- package/dist/{chunk-3O5BB45T.js → chunk-4DXNOVNW.js} +10 -10
- package/dist/{chunk-65I2LZEK.js → chunk-4G2YCKLT.js} +2 -2
- package/dist/{chunk-OK52IY3W.js → chunk-4GEBLO7S.js} +10 -10
- package/dist/{chunk-M6C7SOR6.js → chunk-4I6PEEFA.js} +3 -3
- package/dist/{chunk-Z4TXB4K7.js → chunk-5BUCKFRE.js} +2 -2
- package/dist/{chunk-BGI4NUAO.js → chunk-5S7SNRSJ.js} +2 -2
- package/dist/{chunk-JVPWRNHA.js → chunk-5YR4UGF2.js} +5 -5
- package/dist/{chunk-YJ7MW627.js → chunk-6BG364RN.js} +2 -2
- package/dist/{chunk-D5BSQR63.js → chunk-76LNUSS5.js} +2 -2
- package/dist/{chunk-7CRUDH7G.js → chunk-77HNHT6S.js} +2 -2
- package/dist/{chunk-OWYHHW67.js → chunk-7XI2UJHL.js} +4 -4
- package/dist/{chunk-BJVO4H5C.js → chunk-7Z2UKRNJ.js} +4 -4
- package/dist/{chunk-2WLMWP2T.js → chunk-A3K2KKSG.js} +2 -2
- package/dist/chunk-A5ZYP4K5.js +130 -0
- package/dist/chunk-A5ZYP4K5.js.map +1 -0
- package/dist/{chunk-AWG3TIAY.js → chunk-ACCOC6UM.js} +2 -2
- package/dist/{chunk-3JDA3XF5.js → chunk-AEGNDL24.js} +2 -2
- package/dist/{chunk-2NAD4YCI.js → chunk-AEUMONCD.js} +2 -2
- package/dist/{chunk-C6U57KG4.js → chunk-AF5PW35O.js} +3 -3
- package/dist/{chunk-IOSZHHJC.js → chunk-ANGZWYL2.js} +6 -6
- package/dist/{chunk-K6T33R4Q.js → chunk-AXGJMDBS.js} +156 -7
- package/dist/chunk-AXGJMDBS.js.map +1 -0
- package/dist/{chunk-6LYAEM54.js → chunk-AXHU56C3.js} +2 -2
- package/dist/{chunk-GWM6T5EQ.js → chunk-BCGMG2RD.js} +2 -2
- package/dist/{chunk-HXCJF4XU.js → chunk-BFIZXFUG.js} +2 -2
- package/dist/{chunk-DBYAY6UW.js → chunk-BTOHGPHC.js} +3 -3
- package/dist/{chunk-5X4MXNEU.js → chunk-C6HPNPNK.js} +3 -3
- package/dist/{chunk-4MP7XR5J.js → chunk-CAKHZAXH.js} +2 -2
- package/dist/{chunk-YSBL7VPO.js → chunk-CDWFWOSZ.js} +2 -2
- package/dist/{chunk-QAW55ZHJ.js → chunk-CZ44FH45.js} +4 -4
- package/dist/{chunk-T3FMRLWQ.js → chunk-D5HQ3VEX.js} +4 -4
- package/dist/{chunk-S7LWX2PQ.js → chunk-DPG5HQLE.js} +4 -4
- package/dist/{chunk-C7ZDKWPS.js → chunk-DVSAMW5T.js} +3 -3
- package/dist/{chunk-WBYQA3VN.js → chunk-E5H4TM4Y.js} +3 -3
- package/dist/{chunk-4RL3JOB3.js → chunk-EEDI3OXB.js} +2 -2
- package/dist/{chunk-3TB2XQ3C.js → chunk-EUL3S3LE.js} +4 -4
- package/dist/{chunk-Q4AUIFUA.js → chunk-F23U5YE7.js} +7 -7
- package/dist/{chunk-ZZZ4I455.js → chunk-GDVORIFM.js} +2 -2
- package/dist/{chunk-QB57WIS6.js → chunk-GXETU7AE.js} +98 -73
- package/dist/chunk-GXETU7AE.js.map +1 -0
- package/dist/{chunk-SWBC3UER.js → chunk-HCPUVB7S.js} +3 -3
- package/dist/{chunk-R3X2T2LP.js → chunk-HFOY2SBG.js} +2 -2
- package/dist/{chunk-LU7E2MXE.js → chunk-HQCUUVG2.js} +20 -20
- package/dist/{chunk-FJLQXMTU.js → chunk-I6B3S62A.js} +2 -2
- package/dist/{chunk-RBITPCMK.js → chunk-IDSSDL4W.js} +9 -9
- package/dist/{chunk-OCFXVDBZ.js → chunk-IVEHY2VT.js} +54 -123
- package/dist/chunk-IVEHY2VT.js.map +1 -0
- package/dist/{chunk-B3OFQP5Y.js → chunk-IY47KPML.js} +6 -6
- package/dist/{chunk-AXC4WSF3.js → chunk-JDOBIFBK.js} +2 -2
- package/dist/{chunk-P2ODTYOF.js → chunk-JGXHQV5N.js} +3 -3
- package/dist/{chunk-7LNHRQKR.js → chunk-JLIGUFPF.js} +2 -2
- package/dist/{chunk-EDIH6X2P.js → chunk-JZ66PN72.js} +2 -2
- package/dist/{chunk-BLVR4WYU.js → chunk-KICEAGKM.js} +2 -2
- package/dist/{chunk-S2GE2K36.js → chunk-KNI4SGQE.js} +109 -96
- package/dist/chunk-KNI4SGQE.js.map +1 -0
- package/dist/{chunk-VDX2J7OX.js → chunk-KQAFEZQX.js} +2 -2
- package/dist/{chunk-PEBHPCX2.js → chunk-KTG23JDX.js} +2 -2
- package/dist/{chunk-BOZJD5PK.js → chunk-KYOZ5E6V.js} +2 -2
- package/dist/{chunk-2DLWLNO4.js → chunk-L3TZXELN.js} +4 -4
- package/dist/{chunk-VALKBYBN.js → chunk-M3N2TUZ7.js} +2 -2
- package/dist/{chunk-76M5OK7V.js → chunk-M7T2NKET.js} +5 -5
- package/dist/chunk-MSAI3Q7D.js +372 -0
- package/dist/chunk-MSAI3Q7D.js.map +1 -0
- package/dist/{chunk-Z5LP6ILP.js → chunk-MZAH3CBT.js} +2 -2
- package/dist/{chunk-QI7K7BZ5.js → chunk-NJW2ZG64.js} +2 -2
- package/dist/{chunk-CZJA2EQE.js → chunk-NSKXRTVZ.js} +2 -2
- package/dist/{chunk-4O4XCBOS.js → chunk-NUSQ3YEL.js} +2 -2
- package/dist/{chunk-4OQET73E.js → chunk-O57FCN42.js} +15 -15
- package/dist/{chunk-WKY7N3L7.js → chunk-OEBUAC3O.js} +10 -10
- package/dist/{chunk-Y23L4YJV.js → chunk-OEIA4IHU.js} +2 -2
- package/dist/{chunk-66DKTOBY.js → chunk-OGZC2WUX.js} +2 -2
- package/dist/{chunk-3SGTV7RD.js → chunk-P62DSJUK.js} +6 -6
- package/dist/{chunk-FKD656D2.js → chunk-PH2V7EXZ.js} +2 -2
- package/dist/{chunk-KKNZ7PUZ.js → chunk-QAIKLICT.js} +2 -2
- package/dist/{chunk-SSUDD72S.js → chunk-QPWUG2S3.js} +2 -2
- package/dist/{chunk-QI2E6ISQ.js → chunk-R2TVWQLR.js} +2 -2
- package/dist/chunk-R2TVWQLR.js.map +1 -0
- package/dist/{chunk-GZDTVYK2.js → chunk-R36IBI2M.js} +3 -3
- package/dist/{chunk-W3XXFPRI.js → chunk-R5B3OWI4.js} +64 -64
- package/dist/{chunk-VL4X7ZHC.js → chunk-RFIJRZ4K.js} +2 -2
- package/dist/{chunk-PWF4JXKD.js → chunk-RKDSELA3.js} +1 -1
- package/dist/chunk-RKDSELA3.js.map +1 -0
- package/dist/{chunk-AEHVZY3X.js → chunk-RPVHRZ5C.js} +2 -2
- package/dist/{chunk-X5SHE2O3.js → chunk-RVBLCU5C.js} +4 -4
- package/dist/{chunk-BUQKSQXL.js → chunk-S533KGX6.js} +5 -5
- package/dist/{chunk-STEOT4DI.js → chunk-SCPHU3RW.js} +7 -7
- package/dist/{chunk-LV5H6FTN.js → chunk-SFSD5Q6O.js} +3 -3
- package/dist/{chunk-AE5U5NMS.js → chunk-SMLKHXPF.js} +2 -2
- package/dist/{chunk-AEU4EQGV.js → chunk-T7R5HI6A.js} +1 -1
- package/dist/{chunk-H5BJWPUI.js → chunk-TVQZAQPE.js} +2 -2
- package/dist/{chunk-H56VY4BY.js → chunk-U36GYZ2P.js} +10 -5
- package/dist/chunk-U36GYZ2P.js.map +1 -0
- package/dist/{chunk-XOV7NRY5.js → chunk-U46P4UAR.js} +3 -3
- package/dist/{chunk-DZ42MDZE.js → chunk-UCJINCZT.js} +2 -2
- package/dist/{chunk-5E6RYRYW.js → chunk-UG5V3Z3R.js} +7 -7
- package/dist/{chunk-IW3RMBPB.js → chunk-VAOC6GHN.js} +2 -2
- package/dist/{chunk-6UQFJULG.js → chunk-VBNA2JEN.js} +2 -2
- package/dist/{chunk-HLB7GKGG.js → chunk-VOZNBQNL.js} +2 -2
- package/dist/{chunk-NYKIUQL6.js → chunk-WHIGRW7T.js} +2 -2
- package/dist/{chunk-AZSGSRIM.js → chunk-WHTMVTU4.js} +3 -3
- package/dist/{chunk-AERXJCOG.js → chunk-WL7N5VGG.js} +5 -5
- package/dist/{chunk-TFA6HPOA.js → chunk-WQUGCOKF.js} +4 -4
- package/dist/{chunk-A4VSOUCB.js → chunk-WTZQM74L.js} +5 -5
- package/dist/{chunk-DQEMWVMT.js → chunk-X7Y7WX73.js} +1 -1
- package/dist/{chunk-T2YX56QI.js → chunk-XWSUK5GL.js} +4 -4
- package/dist/{chunk-ACX55QDO.js → chunk-XYOT5GQU.js} +3 -3
- package/dist/{chunk-Z6EZCN6Z.js → chunk-Y7427SL7.js} +10 -10
- package/dist/{chunk-4KN2JLQV.js → chunk-YHZWVDP7.js} +2 -2
- package/dist/chunk-YVRQ5JRA.js +49 -0
- package/dist/chunk-YVRQ5JRA.js.map +1 -0
- package/dist/{chunk-5MNUBT7T.js → chunk-ZFTODDTX.js} +2 -2
- package/dist/{chunk-VVX5PZFS.js → chunk-ZHXSOMYH.js} +2 -2
- package/dist/{chunk-CRXRZA3G.js → chunk-ZQTYWSO3.js} +2 -2
- package/dist/cli.js +126 -122
- package/dist/coding/export-okf-codegraph.js +17 -17
- package/dist/compounding/engine.js +19 -19
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +27 -24
- package/dist/connectors/codex-materialize-runner.js +18 -18
- package/dist/connectors/index.js +20 -20
- package/dist/contradiction/index.js +3 -3
- package/dist/{contradiction-scan-TAGMOUQ2.js → contradiction-scan-GGRTVB7C.js} +3 -3
- package/dist/convergence-refresh.js +20 -20
- package/dist/conversation-index/backend.js +2 -2
- package/dist/corpus-watermark.js +20 -20
- package/dist/day-summary.js +2 -2
- package/dist/deep-recall-http-glue.js +11 -10
- package/dist/embedding-fallback.js +2 -2
- package/dist/entity-retrieval.js +19 -19
- package/dist/explicit-capture.js +2 -2
- package/dist/external-wiki-access.js +75 -73
- package/dist/extraction-judge.js +3 -3
- package/dist/extraction-normalization.js +3 -3
- package/dist/extraction-prompt.js +2 -2
- package/dist/extraction.js +32 -32
- package/dist/{first-start-migration-7OATHJKB.js → first-start-migration-OM3PHMZO.js} +2 -2
- package/dist/harmonic-retrieval.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +198 -195
- package/dist/lcm/engine.js +4 -4
- package/dist/lcm/index.js +10 -10
- package/dist/local-llm-config.js +1 -1
- package/dist/local-llm.js +3 -3
- package/dist/location/index.js +20 -20
- package/dist/maintenance/memory-governance.js +18 -18
- package/dist/maintenance/rebuild-memory-lifecycle-ledger.js +18 -18
- package/dist/maintenance/rebuild-memory-projection.js +19 -19
- package/dist/memory-browse-operations.js +75 -73
- package/dist/memory-browse.js +5 -5
- package/dist/namespaces/migrate.js +19 -19
- package/dist/namespaces/principal.js +2 -2
- package/dist/namespaces/search.js +13 -13
- package/dist/namespaces/storage.js +18 -18
- package/dist/offline-sync-changeset-generations.d.ts +82 -0
- package/dist/offline-sync-changeset-generations.d.ts.map +1 -0
- package/dist/offline-sync-changeset-generations.js +21 -0
- package/dist/offline-sync-changeset-generations.js.map +1 -0
- package/dist/offline-sync-embedding-generation.d.ts +50 -0
- package/dist/offline-sync-embedding-generation.d.ts.map +1 -1
- package/dist/offline-sync-embedding-generation.js +4 -2
- package/dist/offline-sync-impression-drain.js +5 -5
- package/dist/offline-sync-snapshot-stream.js +5 -4
- package/dist/offline-sync.d.ts +12 -1
- package/dist/offline-sync.d.ts.map +1 -1
- package/dist/offline-sync.js +6 -5
- package/dist/operator-doctor-corpus.js +21 -21
- package/dist/operator-toolkit.js +39 -36
- package/dist/orchestration/compression-guideline-coordinator.js +2 -2
- package/dist/orchestration/maintenance.js +33 -33
- package/dist/orchestration/orchestrator-helpers.d.ts +1 -0
- package/dist/orchestration/orchestrator-helpers.d.ts.map +1 -1
- package/dist/orchestration/recall-entry.d.ts.map +1 -1
- package/dist/orchestration/recall-search-pipeline.d.ts.map +1 -1
- package/dist/orchestrator.js +168 -165
- package/dist/outcome-boost-config.d.ts +17 -0
- package/dist/outcome-boost-config.d.ts.map +1 -0
- package/dist/outcome-boost-config.js +1 -0
- package/dist/outcome-boost-config.js.map +1 -0
- package/dist/qmd.js +4 -4
- package/dist/recall-explain-renderer.js +3 -3
- package/dist/recall-navigate-access.js +2 -2
- package/dist/recall-navigate-disclosure.js +2 -2
- package/dist/recall-navigate.js +2 -2
- package/dist/recall-navigation-operations.js +75 -73
- package/dist/recall-navigation.js +74 -72
- package/dist/recall-state-view-admission.js +5 -5
- package/dist/recall-why-service.js +9 -9
- package/dist/recall-why.js +3 -3
- package/dist/recall-xray-cli.js +4 -4
- package/dist/recall-xray-renderer.js +3 -3
- package/dist/recall-xray.js +2 -2
- package/dist/rerank-outcome.d.ts +73 -0
- package/dist/rerank-outcome.d.ts.map +1 -0
- package/dist/rerank-outcome.js +28 -0
- package/dist/rerank-outcome.js.map +1 -0
- package/dist/{resolution-K4A3VPKZ.js → resolution-BROE3TRO.js} +4 -4
- package/dist/resolution-BROE3TRO.js.map +1 -0
- package/dist/resume-bundles.js +28 -25
- package/dist/search/embed-helper.js +2 -2
- package/dist/search/factory.js +12 -12
- package/dist/search/index.js +18 -18
- package/dist/search/lancedb-backend.js +2 -2
- package/dist/search/meilisearch-backend.js +2 -2
- package/dist/search/orama-backend.js +2 -2
- package/dist/semantic-consolidation.js +19 -19
- package/dist/semantic-rule-promotion.js +18 -18
- package/dist/semantic-rule-verifier.js +18 -18
- package/dist/shared-context/manager.js +2 -2
- package/dist/source-agent-qualifier.js +26 -26
- package/dist/standup/build.js +18 -18
- package/dist/storage.js +17 -17
- package/dist/summarizer.js +4 -4
- package/dist/support-passport/index.js +77 -75
- package/dist/support-passport/offline-sync-guard.d.ts +6 -2
- package/dist/support-passport/offline-sync-guard.d.ts.map +1 -1
- package/dist/{tier-stats-VF6DS52E.js → tier-stats-M2FMMD2N.js} +2 -2
- package/dist/transfer/backup.js +2 -2
- package/dist/transfer/capsule-export.js +2 -2
- package/dist/transfer/capsule-import.js +2 -2
- package/dist/transfer/export-okf.js +18 -18
- package/dist/types.d.ts +4 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +1 -1
- package/dist/verified-recall.js +18 -18
- package/dist/who-knows-cli.js +19 -19
- package/dist/who-knows.js +18 -18
- package/package.json +13 -3
- package/src/access-mcp-output-schemas.ts +2 -0
- package/src/access-recall-corpus-versions.ts +59 -0
- package/src/access-recall-response.ts +3 -0
- package/src/access-recall-surface.ts +22 -23
- package/src/access-service-raw-excerpt-read-gate.test.ts +1 -1
- package/src/access-service.ts +3 -0
- package/src/capabilities.test.ts +1 -0
- package/src/capabilities.ts +6 -8
- package/src/config.ts +3 -0
- package/src/index.ts +1 -1
- package/src/offline-sync-changeset-generations.test.ts +962 -0
- package/src/offline-sync-changeset-generations.ts +549 -0
- package/src/offline-sync-embedding-generation.ts +272 -4
- package/src/offline-sync.ts +75 -162
- package/src/orchestration/orchestrator-helpers.ts +1 -1
- package/src/orchestration/recall-entry.ts +32 -16
- package/src/orchestration/recall-internal.ts +2 -2
- package/src/orchestration/recall-search-pipeline.ts +3 -0
- package/src/outcome-boost-config.ts +16 -0
- package/src/recall-retrieval-failure.test.ts +456 -4
- package/src/rerank-outcome.test.ts +218 -0
- package/src/rerank-outcome.ts +219 -0
- package/src/support-passport/offline-sync-guard.ts +16 -2
- package/src/types.ts +3 -3
- package/dist/chunk-H56VY4BY.js.map +0 -1
- package/dist/chunk-K6T33R4Q.js.map +0 -1
- package/dist/chunk-MCTM4YPL.js.map +0 -1
- package/dist/chunk-OCFXVDBZ.js.map +0 -1
- package/dist/chunk-PWF4JXKD.js.map +0 -1
- package/dist/chunk-QB57WIS6.js.map +0 -1
- package/dist/chunk-QI2E6ISQ.js.map +0 -1
- package/dist/chunk-S2GE2K36.js.map +0 -1
- /package/dist/{capsule-crypto-YO5QJ6L3.js.map → access-recall-corpus-versions.js.map} +0 -0
- /package/dist/{auto-sync-U5N3CB5Y.js.map → auto-sync-PAWBFQWL.js.map} +0 -0
- /package/dist/{contradiction-scan-TAGMOUQ2.js.map → capsule-crypto-7FJQINUR.js.map} +0 -0
- /package/dist/{chunk-RDJ6C7NZ.js.map → chunk-2IWBHZ3H.js.map} +0 -0
- /package/dist/{chunk-UP75KL3L.js.map → chunk-2JRB3Z5N.js.map} +0 -0
- /package/dist/{chunk-BXLOS5AJ.js.map → chunk-2NLLXCJG.js.map} +0 -0
- /package/dist/{chunk-KN6CIN7I.js.map → chunk-32HO62I4.js.map} +0 -0
- /package/dist/{chunk-JLPNONPH.js.map → chunk-35A7GCHG.js.map} +0 -0
- /package/dist/{chunk-MXCAJKMA.js.map → chunk-37ZQYFX4.js.map} +0 -0
- /package/dist/{chunk-LW3HKRL7.js.map → chunk-3BTHXB7Z.js.map} +0 -0
- /package/dist/{chunk-C7V3KPKJ.js.map → chunk-47LTKAGL.js.map} +0 -0
- /package/dist/{chunk-3O5BB45T.js.map → chunk-4DXNOVNW.js.map} +0 -0
- /package/dist/{chunk-65I2LZEK.js.map → chunk-4G2YCKLT.js.map} +0 -0
- /package/dist/{chunk-OK52IY3W.js.map → chunk-4GEBLO7S.js.map} +0 -0
- /package/dist/{chunk-M6C7SOR6.js.map → chunk-4I6PEEFA.js.map} +0 -0
- /package/dist/{chunk-Z4TXB4K7.js.map → chunk-5BUCKFRE.js.map} +0 -0
- /package/dist/{chunk-BGI4NUAO.js.map → chunk-5S7SNRSJ.js.map} +0 -0
- /package/dist/{chunk-JVPWRNHA.js.map → chunk-5YR4UGF2.js.map} +0 -0
- /package/dist/{chunk-YJ7MW627.js.map → chunk-6BG364RN.js.map} +0 -0
- /package/dist/{chunk-D5BSQR63.js.map → chunk-76LNUSS5.js.map} +0 -0
- /package/dist/{chunk-7CRUDH7G.js.map → chunk-77HNHT6S.js.map} +0 -0
- /package/dist/{chunk-OWYHHW67.js.map → chunk-7XI2UJHL.js.map} +0 -0
- /package/dist/{chunk-BJVO4H5C.js.map → chunk-7Z2UKRNJ.js.map} +0 -0
- /package/dist/{chunk-2WLMWP2T.js.map → chunk-A3K2KKSG.js.map} +0 -0
- /package/dist/{chunk-AWG3TIAY.js.map → chunk-ACCOC6UM.js.map} +0 -0
- /package/dist/{chunk-3JDA3XF5.js.map → chunk-AEGNDL24.js.map} +0 -0
- /package/dist/{chunk-2NAD4YCI.js.map → chunk-AEUMONCD.js.map} +0 -0
- /package/dist/{chunk-C6U57KG4.js.map → chunk-AF5PW35O.js.map} +0 -0
- /package/dist/{chunk-IOSZHHJC.js.map → chunk-ANGZWYL2.js.map} +0 -0
- /package/dist/{chunk-6LYAEM54.js.map → chunk-AXHU56C3.js.map} +0 -0
- /package/dist/{chunk-GWM6T5EQ.js.map → chunk-BCGMG2RD.js.map} +0 -0
- /package/dist/{chunk-HXCJF4XU.js.map → chunk-BFIZXFUG.js.map} +0 -0
- /package/dist/{chunk-DBYAY6UW.js.map → chunk-BTOHGPHC.js.map} +0 -0
- /package/dist/{chunk-5X4MXNEU.js.map → chunk-C6HPNPNK.js.map} +0 -0
- /package/dist/{chunk-4MP7XR5J.js.map → chunk-CAKHZAXH.js.map} +0 -0
- /package/dist/{chunk-YSBL7VPO.js.map → chunk-CDWFWOSZ.js.map} +0 -0
- /package/dist/{chunk-QAW55ZHJ.js.map → chunk-CZ44FH45.js.map} +0 -0
- /package/dist/{chunk-T3FMRLWQ.js.map → chunk-D5HQ3VEX.js.map} +0 -0
- /package/dist/{chunk-S7LWX2PQ.js.map → chunk-DPG5HQLE.js.map} +0 -0
- /package/dist/{chunk-C7ZDKWPS.js.map → chunk-DVSAMW5T.js.map} +0 -0
- /package/dist/{chunk-WBYQA3VN.js.map → chunk-E5H4TM4Y.js.map} +0 -0
- /package/dist/{chunk-4RL3JOB3.js.map → chunk-EEDI3OXB.js.map} +0 -0
- /package/dist/{chunk-3TB2XQ3C.js.map → chunk-EUL3S3LE.js.map} +0 -0
- /package/dist/{chunk-Q4AUIFUA.js.map → chunk-F23U5YE7.js.map} +0 -0
- /package/dist/{chunk-ZZZ4I455.js.map → chunk-GDVORIFM.js.map} +0 -0
- /package/dist/{chunk-SWBC3UER.js.map → chunk-HCPUVB7S.js.map} +0 -0
- /package/dist/{chunk-R3X2T2LP.js.map → chunk-HFOY2SBG.js.map} +0 -0
- /package/dist/{chunk-LU7E2MXE.js.map → chunk-HQCUUVG2.js.map} +0 -0
- /package/dist/{chunk-FJLQXMTU.js.map → chunk-I6B3S62A.js.map} +0 -0
- /package/dist/{chunk-RBITPCMK.js.map → chunk-IDSSDL4W.js.map} +0 -0
- /package/dist/{chunk-B3OFQP5Y.js.map → chunk-IY47KPML.js.map} +0 -0
- /package/dist/{chunk-AXC4WSF3.js.map → chunk-JDOBIFBK.js.map} +0 -0
- /package/dist/{chunk-P2ODTYOF.js.map → chunk-JGXHQV5N.js.map} +0 -0
- /package/dist/{chunk-7LNHRQKR.js.map → chunk-JLIGUFPF.js.map} +0 -0
- /package/dist/{chunk-EDIH6X2P.js.map → chunk-JZ66PN72.js.map} +0 -0
- /package/dist/{chunk-BLVR4WYU.js.map → chunk-KICEAGKM.js.map} +0 -0
- /package/dist/{chunk-VDX2J7OX.js.map → chunk-KQAFEZQX.js.map} +0 -0
- /package/dist/{chunk-PEBHPCX2.js.map → chunk-KTG23JDX.js.map} +0 -0
- /package/dist/{chunk-BOZJD5PK.js.map → chunk-KYOZ5E6V.js.map} +0 -0
- /package/dist/{chunk-2DLWLNO4.js.map → chunk-L3TZXELN.js.map} +0 -0
- /package/dist/{chunk-VALKBYBN.js.map → chunk-M3N2TUZ7.js.map} +0 -0
- /package/dist/{chunk-76M5OK7V.js.map → chunk-M7T2NKET.js.map} +0 -0
- /package/dist/{chunk-Z5LP6ILP.js.map → chunk-MZAH3CBT.js.map} +0 -0
- /package/dist/{chunk-QI7K7BZ5.js.map → chunk-NJW2ZG64.js.map} +0 -0
- /package/dist/{chunk-CZJA2EQE.js.map → chunk-NSKXRTVZ.js.map} +0 -0
- /package/dist/{chunk-4O4XCBOS.js.map → chunk-NUSQ3YEL.js.map} +0 -0
- /package/dist/{chunk-4OQET73E.js.map → chunk-O57FCN42.js.map} +0 -0
- /package/dist/{chunk-WKY7N3L7.js.map → chunk-OEBUAC3O.js.map} +0 -0
- /package/dist/{chunk-Y23L4YJV.js.map → chunk-OEIA4IHU.js.map} +0 -0
- /package/dist/{chunk-66DKTOBY.js.map → chunk-OGZC2WUX.js.map} +0 -0
- /package/dist/{chunk-3SGTV7RD.js.map → chunk-P62DSJUK.js.map} +0 -0
- /package/dist/{chunk-FKD656D2.js.map → chunk-PH2V7EXZ.js.map} +0 -0
- /package/dist/{chunk-KKNZ7PUZ.js.map → chunk-QAIKLICT.js.map} +0 -0
- /package/dist/{chunk-SSUDD72S.js.map → chunk-QPWUG2S3.js.map} +0 -0
- /package/dist/{chunk-GZDTVYK2.js.map → chunk-R36IBI2M.js.map} +0 -0
- /package/dist/{chunk-W3XXFPRI.js.map → chunk-R5B3OWI4.js.map} +0 -0
- /package/dist/{chunk-VL4X7ZHC.js.map → chunk-RFIJRZ4K.js.map} +0 -0
- /package/dist/{chunk-AEHVZY3X.js.map → chunk-RPVHRZ5C.js.map} +0 -0
- /package/dist/{chunk-X5SHE2O3.js.map → chunk-RVBLCU5C.js.map} +0 -0
- /package/dist/{chunk-BUQKSQXL.js.map → chunk-S533KGX6.js.map} +0 -0
- /package/dist/{chunk-STEOT4DI.js.map → chunk-SCPHU3RW.js.map} +0 -0
- /package/dist/{chunk-LV5H6FTN.js.map → chunk-SFSD5Q6O.js.map} +0 -0
- /package/dist/{chunk-AE5U5NMS.js.map → chunk-SMLKHXPF.js.map} +0 -0
- /package/dist/{chunk-AEU4EQGV.js.map → chunk-T7R5HI6A.js.map} +0 -0
- /package/dist/{chunk-H5BJWPUI.js.map → chunk-TVQZAQPE.js.map} +0 -0
- /package/dist/{chunk-XOV7NRY5.js.map → chunk-U46P4UAR.js.map} +0 -0
- /package/dist/{chunk-DZ42MDZE.js.map → chunk-UCJINCZT.js.map} +0 -0
- /package/dist/{chunk-5E6RYRYW.js.map → chunk-UG5V3Z3R.js.map} +0 -0
- /package/dist/{chunk-IW3RMBPB.js.map → chunk-VAOC6GHN.js.map} +0 -0
- /package/dist/{chunk-6UQFJULG.js.map → chunk-VBNA2JEN.js.map} +0 -0
- /package/dist/{chunk-HLB7GKGG.js.map → chunk-VOZNBQNL.js.map} +0 -0
- /package/dist/{chunk-NYKIUQL6.js.map → chunk-WHIGRW7T.js.map} +0 -0
- /package/dist/{chunk-AZSGSRIM.js.map → chunk-WHTMVTU4.js.map} +0 -0
- /package/dist/{chunk-AERXJCOG.js.map → chunk-WL7N5VGG.js.map} +0 -0
- /package/dist/{chunk-TFA6HPOA.js.map → chunk-WQUGCOKF.js.map} +0 -0
- /package/dist/{chunk-A4VSOUCB.js.map → chunk-WTZQM74L.js.map} +0 -0
- /package/dist/{chunk-DQEMWVMT.js.map → chunk-X7Y7WX73.js.map} +0 -0
- /package/dist/{chunk-T2YX56QI.js.map → chunk-XWSUK5GL.js.map} +0 -0
- /package/dist/{chunk-ACX55QDO.js.map → chunk-XYOT5GQU.js.map} +0 -0
- /package/dist/{chunk-Z6EZCN6Z.js.map → chunk-Y7427SL7.js.map} +0 -0
- /package/dist/{chunk-4KN2JLQV.js.map → chunk-YHZWVDP7.js.map} +0 -0
- /package/dist/{chunk-5MNUBT7T.js.map → chunk-ZFTODDTX.js.map} +0 -0
- /package/dist/{chunk-VVX5PZFS.js.map → chunk-ZHXSOMYH.js.map} +0 -0
- /package/dist/{chunk-CRXRZA3G.js.map → chunk-ZQTYWSO3.js.map} +0 -0
- /package/dist/{resolution-K4A3VPKZ.js.map → contradiction-scan-GGRTVB7C.js.map} +0 -0
- /package/dist/{first-start-migration-7OATHJKB.js.map → first-start-migration-OM3PHMZO.js.map} +0 -0
- /package/dist/{tier-stats-VF6DS52E.js.map → tier-stats-M2FMMD2N.js.map} +0 -0
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import assert from "node:assert/strict";
|
|
2
|
+
import test from "node:test";
|
|
3
|
+
import { parseConfig } from "./config.js";
|
|
4
|
+
import type { MemoryFile, QmdSearchResult } from "./types.js";
|
|
5
|
+
import {
|
|
6
|
+
OUTCOME_STATE_OBSERVED,
|
|
7
|
+
OUTCOME_STATE_UNOBSERVED,
|
|
8
|
+
applyOutcomePriorScores,
|
|
9
|
+
blendOutcomeScore,
|
|
10
|
+
outcomePriorBoostActive,
|
|
11
|
+
parseOutcomeBoostWeight,
|
|
12
|
+
rerankWithOutcomePrior,
|
|
13
|
+
resolveOutcomeObservation,
|
|
14
|
+
scaleTextScore,
|
|
15
|
+
type OutcomeObservationState,
|
|
16
|
+
} from "./rerank-outcome.js";
|
|
17
|
+
|
|
18
|
+
// @ts-expect-error "bogus" is not an OutcomeObservationState
|
|
19
|
+
const badOutcomeState: OutcomeObservationState = "bogus";
|
|
20
|
+
void badOutcomeState;
|
|
21
|
+
|
|
22
|
+
function memory(counters: { mw_success?: number; mw_fail?: number }): MemoryFile {
|
|
23
|
+
return {
|
|
24
|
+
path: "facts/a.md",
|
|
25
|
+
content: "synthetic fact",
|
|
26
|
+
frontmatter: counters as MemoryFile["frontmatter"],
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function result(path: string, score: number, namespace?: string): QmdSearchResult {
|
|
31
|
+
return { docid: path, path, snippet: "", score, namespace } as QmdSearchResult;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
test("scaleTextScore clamps into [0, 1] without a batch min-max", () => {
|
|
35
|
+
assert.equal(scaleTextScore(0.4), 0.4);
|
|
36
|
+
assert.equal(scaleTextScore(2.5), 1);
|
|
37
|
+
assert.equal(scaleTextScore(-3), 0);
|
|
38
|
+
assert.equal(scaleTextScore(Number.NaN), 0);
|
|
39
|
+
assert.equal(scaleTextScore(Number.POSITIVE_INFINITY), 0);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test("UNOBSERVED is not the Memory Worth Beta prior", () => {
|
|
43
|
+
const unobserved = resolveOutcomeObservation(undefined);
|
|
44
|
+
assert.equal(unobserved.state, OUTCOME_STATE_UNOBSERVED);
|
|
45
|
+
assert.equal(blendOutcomeScore(1, unobserved, 0.5), 1);
|
|
46
|
+
assert.notEqual(blendOutcomeScore(1, unobserved, 0.5), 0.75);
|
|
47
|
+
|
|
48
|
+
const zeros = resolveOutcomeObservation({ success: 0, fail: 0 });
|
|
49
|
+
assert.equal(zeros.state, OUTCOME_STATE_UNOBSERVED);
|
|
50
|
+
|
|
51
|
+
const missing = resolveOutcomeObservation({});
|
|
52
|
+
assert.equal(missing.state, OUTCOME_STATE_UNOBSERVED);
|
|
53
|
+
|
|
54
|
+
const invalid = resolveOutcomeObservation({ success: Number.NaN, fail: 1 });
|
|
55
|
+
assert.equal(invalid.state, OUTCOME_STATE_UNOBSERVED);
|
|
56
|
+
const negative = resolveOutcomeObservation({ success: -1, fail: 2 });
|
|
57
|
+
assert.equal(negative.state, OUTCOME_STATE_UNOBSERVED);
|
|
58
|
+
|
|
59
|
+
const observed = resolveOutcomeObservation({ success: 0, fail: 1 });
|
|
60
|
+
assert.equal(observed.state, OUTCOME_STATE_OBSERVED);
|
|
61
|
+
assert.equal(observed.outcomeScore, 0);
|
|
62
|
+
assert.equal(blendOutcomeScore(1, observed, 0.5), 0.5);
|
|
63
|
+
assert.notEqual(blendOutcomeScore(1, observed, 0.5), 2 / 3);
|
|
64
|
+
|
|
65
|
+
const oneSided = resolveOutcomeObservation({ success: 2 });
|
|
66
|
+
assert.equal(oneSided.state, OUTCOME_STATE_OBSERVED);
|
|
67
|
+
assert.equal(oneSided.outcomeScore, 1);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test("pre-main unit gates cover ties, equal scores, and w=0 identity", () => {
|
|
71
|
+
const unobserved = resolveOutcomeObservation(undefined);
|
|
72
|
+
const observedZero = resolveOutcomeObservation({ success: 0, fail: 4 });
|
|
73
|
+
assert.equal(unobserved.state, OUTCOME_STATE_UNOBSERVED);
|
|
74
|
+
assert.equal(observedZero.state, OUTCOME_STATE_OBSERVED);
|
|
75
|
+
assert.equal(blendOutcomeScore(1.7, unobserved, 0), 1.7);
|
|
76
|
+
assert.equal(blendOutcomeScore(1.7, observedZero, 0), 1.7);
|
|
77
|
+
assert.equal(blendOutcomeScore(1.7, observedZero, 0.5), scaleTextScore(1.7) * 0.5);
|
|
78
|
+
|
|
79
|
+
const tied = rerankWithOutcomePrior(
|
|
80
|
+
[
|
|
81
|
+
{ item: "left", textScore: 0.4, success: 3, fail: 1 },
|
|
82
|
+
{ item: "right", textScore: 0.4, success: 0, fail: 9 },
|
|
83
|
+
],
|
|
84
|
+
0,
|
|
85
|
+
);
|
|
86
|
+
assert.deepEqual(
|
|
87
|
+
tied.map((row) => [row.item, row.score, row.state]),
|
|
88
|
+
[
|
|
89
|
+
["left", 0.4, OUTCOME_STATE_OBSERVED],
|
|
90
|
+
["right", 0.4, OUTCOME_STATE_OBSERVED],
|
|
91
|
+
],
|
|
92
|
+
);
|
|
93
|
+
|
|
94
|
+
const equalBlend = rerankWithOutcomePrior(
|
|
95
|
+
[
|
|
96
|
+
{ item: "first", textScore: 0.2, success: 1, fail: 1 },
|
|
97
|
+
{ item: "second", textScore: 0.2, success: 1, fail: 1 },
|
|
98
|
+
],
|
|
99
|
+
0.5,
|
|
100
|
+
);
|
|
101
|
+
assert.deepEqual(
|
|
102
|
+
equalBlend.map((row) => row.item),
|
|
103
|
+
["first", "second"],
|
|
104
|
+
);
|
|
105
|
+
assert.equal(equalBlend[0]?.score, equalBlend[1]?.score);
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
test("weight 0 keeps raw scores and original order", () => {
|
|
109
|
+
const ranked = rerankWithOutcomePrior(
|
|
110
|
+
[
|
|
111
|
+
{ item: "a", textScore: 1.4, success: 0, fail: 5 },
|
|
112
|
+
{ item: "b", textScore: 0.2 },
|
|
113
|
+
{ item: "c", textScore: -1, success: 9, fail: 0 },
|
|
114
|
+
],
|
|
115
|
+
0,
|
|
116
|
+
);
|
|
117
|
+
assert.deepEqual(
|
|
118
|
+
ranked.map((row) => [row.item, row.score]),
|
|
119
|
+
[
|
|
120
|
+
["a", 1.4],
|
|
121
|
+
["b", 0.2],
|
|
122
|
+
["c", -1],
|
|
123
|
+
],
|
|
124
|
+
);
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
test("equal blended scores keep the original index order", () => {
|
|
128
|
+
const ranked = rerankWithOutcomePrior(
|
|
129
|
+
[
|
|
130
|
+
{ item: "first", textScore: 1 },
|
|
131
|
+
{ item: "second", textScore: 0, success: 1, fail: 0 },
|
|
132
|
+
],
|
|
133
|
+
1,
|
|
134
|
+
);
|
|
135
|
+
assert.deepEqual(
|
|
136
|
+
ranked.map((row) => row.item),
|
|
137
|
+
["first", "second"],
|
|
138
|
+
);
|
|
139
|
+
assert.equal(ranked[0]?.score, ranked[1]?.score);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
test("observed outcomes reorder above a weaker text score", () => {
|
|
143
|
+
const ranked = rerankWithOutcomePrior(
|
|
144
|
+
[
|
|
145
|
+
{ item: "text", textScore: 0.9 },
|
|
146
|
+
{ item: "worked", textScore: 0.2, success: 4, fail: 0 },
|
|
147
|
+
],
|
|
148
|
+
1,
|
|
149
|
+
);
|
|
150
|
+
assert.deepEqual(
|
|
151
|
+
ranked.map((row) => row.item),
|
|
152
|
+
["worked", "text"],
|
|
153
|
+
);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
test("parseOutcomeBoostWeight rejects invalid values and keeps zero", () => {
|
|
157
|
+
assert.equal(parseOutcomeBoostWeight(undefined), 0);
|
|
158
|
+
assert.equal(parseOutcomeBoostWeight(""), 0);
|
|
159
|
+
assert.equal(parseOutcomeBoostWeight("0"), 0);
|
|
160
|
+
assert.equal(parseOutcomeBoostWeight("0.3"), 0.3);
|
|
161
|
+
assert.throws(() => parseOutcomeBoostWeight(false), /outcomeBoostWeight/);
|
|
162
|
+
assert.throws(() => parseOutcomeBoostWeight("false"), /outcomeBoostWeight/);
|
|
163
|
+
assert.throws(() => parseOutcomeBoostWeight("1.5"), /outcomeBoostWeight/);
|
|
164
|
+
assert.throws(() => parseOutcomeBoostWeight(Number.NaN), /outcomeBoostWeight/);
|
|
165
|
+
assert.throws(() => rerankWithOutcomePrior([{ item: "a", textScore: 1 }], 1.2), /outcomeBoostWeight/);
|
|
166
|
+
});
|
|
167
|
+
|
|
168
|
+
test("parseConfig leaves the outcome boost off", () => {
|
|
169
|
+
const defaults = parseConfig({});
|
|
170
|
+
assert.equal(defaults.outcomeBoostEnabled, false);
|
|
171
|
+
assert.equal(defaults.outcomeBoostWeight, 0);
|
|
172
|
+
assert.equal(outcomePriorBoostActive(defaults), false);
|
|
173
|
+
assert.equal(parseConfig({ outcomeBoostEnabled: "false" }).outcomeBoostEnabled, false);
|
|
174
|
+
assert.equal(parseConfig({ outcomeBoostEnabled: "0" }).outcomeBoostEnabled, false);
|
|
175
|
+
assert.equal(parseConfig({ outcomeBoostWeight: "0" }).outcomeBoostWeight, 0);
|
|
176
|
+
assert.equal(outcomePriorBoostActive(parseConfig({ outcomeBoostEnabled: true, outcomeBoostWeight: 0 })), false);
|
|
177
|
+
assert.equal(outcomePriorBoostActive(parseConfig({ outcomeBoostEnabled: false, outcomeBoostWeight: 0.3 })), false);
|
|
178
|
+
assert.equal(outcomePriorBoostActive(parseConfig({ outcomeBoostEnabled: true, outcomeBoostWeight: 0.3 })), true);
|
|
179
|
+
assert.throws(() => parseConfig({ outcomeBoostWeight: "no" }), /outcomeBoostWeight/);
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
test("applyOutcomePriorScores is an identity at weight 0 and uses the namespace key", () => {
|
|
183
|
+
const untouched = [result("facts/a.md", 1.4, "ns-a"), result("facts/a.md", 0.2)];
|
|
184
|
+
const before = untouched.map((row) => ({ path: row.path, score: row.score, namespace: row.namespace }));
|
|
185
|
+
applyOutcomePriorScores(untouched, new Map(), { outcomeBoostWeight: 0 });
|
|
186
|
+
assert.deepEqual(
|
|
187
|
+
untouched.map((row) => ({ path: row.path, score: row.score, namespace: row.namespace })),
|
|
188
|
+
before,
|
|
189
|
+
);
|
|
190
|
+
const negative = [result("facts/a.md", 1.4)];
|
|
191
|
+
applyOutcomePriorScores(negative, new Map(), { outcomeBoostWeight: -1 });
|
|
192
|
+
assert.equal(negative[0]?.score, 1.4);
|
|
193
|
+
assert.throws(
|
|
194
|
+
() => applyOutcomePriorScores([result("facts/a.md", 1)], new Map(), { outcomeBoostWeight: 1.2 }),
|
|
195
|
+
/outcomeBoostWeight/,
|
|
196
|
+
);
|
|
197
|
+
|
|
198
|
+
const namespaced = resolveOutcomeObservation({ success: 0, fail: 1 });
|
|
199
|
+
assert.equal(namespaced.state, OUTCOME_STATE_OBSERVED);
|
|
200
|
+
assert.equal(namespaced.outcomeScore, 0);
|
|
201
|
+
const bare = resolveOutcomeObservation({ success: 8, fail: 0 });
|
|
202
|
+
assert.equal(bare.state, OUTCOME_STATE_OBSERVED);
|
|
203
|
+
assert.equal(bare.outcomeScore, 1);
|
|
204
|
+
|
|
205
|
+
const results = [result("facts/a.md", 1, "ns-a"), result("facts/a.md", 0.2)];
|
|
206
|
+
const memoryByPath = new Map<string, MemoryFile>([
|
|
207
|
+
["ns-a\0facts/a.md", memory({ mw_success: 0, mw_fail: 1 })],
|
|
208
|
+
["facts/a.md", memory({ mw_success: 8, mw_fail: 0 })],
|
|
209
|
+
]);
|
|
210
|
+
applyOutcomePriorScores(results, memoryByPath, { outcomeBoostWeight: 1 });
|
|
211
|
+
// 0/1 is an observed rate of 0, not UNOBSERVED. The namespaced key must not
|
|
212
|
+
// read the bare-path 8/0 counters. At weight 1 the bare path (rate 1) sorts
|
|
213
|
+
// ahead of ns-a (rate 0).
|
|
214
|
+
assert.equal(results[0]?.namespace, undefined);
|
|
215
|
+
assert.equal(results[0]?.score, 1);
|
|
216
|
+
assert.equal(results[1]?.namespace, "ns-a");
|
|
217
|
+
assert.equal(results[1]?.score, 0);
|
|
218
|
+
});
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* H1 outcome-prior blend (issue #1958). Scaffolding only — no experiment runner.
|
|
3
|
+
*
|
|
4
|
+
* Text scores map onto [0, 1] with a fixed clamp. The clamp is not a batch
|
|
5
|
+
* min-max, so one candidate cannot move another's scale.
|
|
6
|
+
*
|
|
7
|
+
* UNOBSERVED (no past result) keeps that unit text score when the weight is
|
|
8
|
+
* positive. It does not use the Memory Worth Laplace prior (s+1)/(s+f+2).
|
|
9
|
+
* An observed result uses the maximum-likelihood rate success/(success+fail).
|
|
10
|
+
*
|
|
11
|
+
* Turning the blend on (enabled and weight > 0) clamps every candidate's text
|
|
12
|
+
* score into [0, 1] before mixing, including UNOBSERVED items. Raw scores
|
|
13
|
+
* outside that range can change order relative to the weight-0 path. Weight 0
|
|
14
|
+
* does not clamp.
|
|
15
|
+
*
|
|
16
|
+
* Weight 0 is an identity on the raw input score: same values, same order.
|
|
17
|
+
* The recall pipeline calls `applyOutcomePriorScores` only when
|
|
18
|
+
* `outcomeBoostEnabled === true` and the weight is greater than 0, so the
|
|
19
|
+
* production default stays on the existing sort.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import {
|
|
23
|
+
type RecallEnhancementConfigProjection,
|
|
24
|
+
resolveRecallEnhancementCapabilities,
|
|
25
|
+
} from "./capabilities.js";
|
|
26
|
+
import { coerceNumber } from "./connectors/coerce.js";
|
|
27
|
+
import { memoryForResult } from "./recall-memory-map.js";
|
|
28
|
+
import type { MemoryFile, QmdSearchResult } from "./types.js";
|
|
29
|
+
|
|
30
|
+
export const OUTCOME_STATE_UNOBSERVED = "UNOBSERVED" as const;
|
|
31
|
+
export const OUTCOME_STATE_OBSERVED = "OBSERVED" as const;
|
|
32
|
+
|
|
33
|
+
export type OutcomeObservationState =
|
|
34
|
+
| typeof OUTCOME_STATE_UNOBSERVED
|
|
35
|
+
| typeof OUTCOME_STATE_OBSERVED;
|
|
36
|
+
|
|
37
|
+
export interface OutcomeCounters {
|
|
38
|
+
success?: number;
|
|
39
|
+
fail?: number;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export interface OutcomeObservation {
|
|
43
|
+
state: OutcomeObservationState;
|
|
44
|
+
/** Present only for OBSERVED. Maximum-likelihood rate in [0, 1]. */
|
|
45
|
+
outcomeScore?: number;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export function scaleTextScore(score: number): number {
|
|
49
|
+
if (!Number.isFinite(score) || score <= 0) return 0;
|
|
50
|
+
if (score >= 1) return 1;
|
|
51
|
+
return score;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
function finiteNonNegative(value: number | undefined): number | undefined {
|
|
55
|
+
if (value === undefined) return undefined;
|
|
56
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 0) return undefined;
|
|
57
|
+
return value;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Both counters missing, explicit 0+0, or any present-but-invalid counter
|
|
62
|
+
* (non-finite or negative) is UNOBSERVED. One counter present and positive
|
|
63
|
+
* with the other missing is OBSERVED; the missing counter counts as 0.
|
|
64
|
+
*/
|
|
65
|
+
export function resolveOutcomeObservation(
|
|
66
|
+
counters: OutcomeCounters | undefined,
|
|
67
|
+
): OutcomeObservation {
|
|
68
|
+
if (!counters) return { state: OUTCOME_STATE_UNOBSERVED };
|
|
69
|
+
const successPresent = counters.success !== undefined;
|
|
70
|
+
const failPresent = counters.fail !== undefined;
|
|
71
|
+
if (!successPresent && !failPresent) return { state: OUTCOME_STATE_UNOBSERVED };
|
|
72
|
+
|
|
73
|
+
const success = finiteNonNegative(counters.success);
|
|
74
|
+
const fail = finiteNonNegative(counters.fail);
|
|
75
|
+
if (successPresent && success === undefined) return { state: OUTCOME_STATE_UNOBSERVED };
|
|
76
|
+
if (failPresent && fail === undefined) return { state: OUTCOME_STATE_UNOBSERVED };
|
|
77
|
+
|
|
78
|
+
const successes = success ?? 0;
|
|
79
|
+
const failures = fail ?? 0;
|
|
80
|
+
if (successes === 0 && failures === 0) return { state: OUTCOME_STATE_UNOBSERVED };
|
|
81
|
+
return {
|
|
82
|
+
state: OUTCOME_STATE_OBSERVED,
|
|
83
|
+
outcomeScore: successes / (successes + failures),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Weight 0 returns `textScore` unchanged. A positive weight clamps `textScore`
|
|
89
|
+
* into [0, 1] first. UNOBSERVED stays on that clamped value. OBSERVED mixes it
|
|
90
|
+
* with the success rate.
|
|
91
|
+
*/
|
|
92
|
+
export function blendOutcomeScore(
|
|
93
|
+
textScore: number,
|
|
94
|
+
observation: OutcomeObservation,
|
|
95
|
+
weight: number,
|
|
96
|
+
): number {
|
|
97
|
+
if (weight === 0) return textScore;
|
|
98
|
+
const textUnit = scaleTextScore(textScore);
|
|
99
|
+
if (observation.state === OUTCOME_STATE_UNOBSERVED || observation.outcomeScore === undefined) {
|
|
100
|
+
return textUnit;
|
|
101
|
+
}
|
|
102
|
+
return (1 - weight) * textUnit + weight * observation.outcomeScore;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export interface OutcomePriorCandidate<T> {
|
|
106
|
+
item: T;
|
|
107
|
+
textScore: number;
|
|
108
|
+
success?: number;
|
|
109
|
+
fail?: number;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export interface OutcomePriorRanked<T> {
|
|
113
|
+
item: T;
|
|
114
|
+
textScore: number;
|
|
115
|
+
score: number;
|
|
116
|
+
state: OutcomeObservationState;
|
|
117
|
+
originalIndex: number;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function assertOutcomeWeight(weight: number): void {
|
|
121
|
+
if (!Number.isFinite(weight) || weight < 0 || weight > 1) {
|
|
122
|
+
throw new Error(
|
|
123
|
+
`outcomeBoostWeight must be a finite number in [0, 1] (got ${JSON.stringify(weight)}).`,
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
function compareRanked(
|
|
129
|
+
left: { score: number; originalIndex: number },
|
|
130
|
+
right: { score: number; originalIndex: number },
|
|
131
|
+
): number {
|
|
132
|
+
const leftScore = Number.isFinite(left.score) ? left.score : Number.NEGATIVE_INFINITY;
|
|
133
|
+
const rightScore = Number.isFinite(right.score) ? right.score : Number.NEGATIVE_INFINITY;
|
|
134
|
+
if (leftScore !== rightScore) return leftScore > rightScore ? -1 : 1;
|
|
135
|
+
if (left.originalIndex === right.originalIndex) return 0;
|
|
136
|
+
return left.originalIndex < right.originalIndex ? -1 : 1;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export function rerankWithOutcomePrior<T>(
|
|
140
|
+
candidates: readonly OutcomePriorCandidate<T>[],
|
|
141
|
+
weight: number,
|
|
142
|
+
): OutcomePriorRanked<T>[] {
|
|
143
|
+
assertOutcomeWeight(weight);
|
|
144
|
+
const ranked = candidates.map((candidate, originalIndex) => {
|
|
145
|
+
const observation = resolveOutcomeObservation({
|
|
146
|
+
success: candidate.success,
|
|
147
|
+
fail: candidate.fail,
|
|
148
|
+
});
|
|
149
|
+
return {
|
|
150
|
+
item: candidate.item,
|
|
151
|
+
textScore: candidate.textScore,
|
|
152
|
+
score: blendOutcomeScore(candidate.textScore, observation, weight),
|
|
153
|
+
state: observation.state,
|
|
154
|
+
originalIndex,
|
|
155
|
+
};
|
|
156
|
+
});
|
|
157
|
+
if (weight === 0) return ranked;
|
|
158
|
+
ranked.sort(compareRanked);
|
|
159
|
+
return ranked;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
export function outcomePriorBoostActive(
|
|
163
|
+
config: RecallEnhancementConfigProjection & { outcomeBoostWeight?: number },
|
|
164
|
+
): boolean {
|
|
165
|
+
const weight = config.outcomeBoostWeight;
|
|
166
|
+
return (
|
|
167
|
+
resolveRecallEnhancementCapabilities(config).outcomeBoost === true &&
|
|
168
|
+
typeof weight === "number" &&
|
|
169
|
+
Number.isFinite(weight) &&
|
|
170
|
+
weight > 0
|
|
171
|
+
);
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
export function applyOutcomePriorScores(
|
|
175
|
+
results: QmdSearchResult[],
|
|
176
|
+
memoryByPath: ReadonlyMap<string, MemoryFile>,
|
|
177
|
+
config: { outcomeBoostWeight?: number },
|
|
178
|
+
): void {
|
|
179
|
+
const weight = config.outcomeBoostWeight;
|
|
180
|
+
// Non-numbers, non-finite values, and negatives are a no-op. Zero is an
|
|
181
|
+
// identity. assertOutcomeWeight is the upper bound (> 1 throws); it is not
|
|
182
|
+
// a second copy of the positivity check.
|
|
183
|
+
if (typeof weight !== "number" || !Number.isFinite(weight) || weight < 0) return;
|
|
184
|
+
assertOutcomeWeight(weight);
|
|
185
|
+
if (weight === 0) return;
|
|
186
|
+
const ranked = results.map((result, originalIndex) => {
|
|
187
|
+
const memory = memoryForResult(memoryByPath, result);
|
|
188
|
+
const observation = resolveOutcomeObservation(
|
|
189
|
+
memory
|
|
190
|
+
? { success: memory.frontmatter.mw_success, fail: memory.frontmatter.mw_fail }
|
|
191
|
+
: undefined,
|
|
192
|
+
);
|
|
193
|
+
return {
|
|
194
|
+
result,
|
|
195
|
+
originalIndex,
|
|
196
|
+
score: blendOutcomeScore(result.score, observation, weight),
|
|
197
|
+
};
|
|
198
|
+
});
|
|
199
|
+
ranked.sort(compareRanked);
|
|
200
|
+
const next = ranked.map((row) =>
|
|
201
|
+
row.score === row.result.score ? row.result : { ...row.result, score: row.score },
|
|
202
|
+
);
|
|
203
|
+
results.splice(0, results.length, ...next);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Absent / null / exact empty string → 0. A present value that is not a
|
|
208
|
+
* finite number in [0, 1] throws. Boolean false is not a zero weight.
|
|
209
|
+
*/
|
|
210
|
+
export function parseOutcomeBoostWeight(raw: unknown): number {
|
|
211
|
+
if (raw === undefined || raw === null || raw === "") return 0;
|
|
212
|
+
const parsed = coerceNumber(raw, "outcomeBoostWeight");
|
|
213
|
+
if (parsed === undefined || parsed < 0 || parsed > 1) {
|
|
214
|
+
throw new Error(
|
|
215
|
+
`outcomeBoostWeight must be a number in [0, 1] (got ${JSON.stringify(raw)}).`,
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
return parsed;
|
|
219
|
+
}
|
|
@@ -26,10 +26,14 @@ type FrontmatterDecision = "allow" | "wait";
|
|
|
26
26
|
interface SupportPassportOfflineSyncStorage {
|
|
27
27
|
dir: string;
|
|
28
28
|
readMemoryByPath(filePath: string): Promise<MemoryFile | null>;
|
|
29
|
-
readOfflineSyncFile(filePath: string): Promise<Buffer>;
|
|
29
|
+
readOfflineSyncFile(filePath: string, opts?: { aadFilePath?: string }): Promise<Buffer>;
|
|
30
30
|
digestOfflineSyncFile(filePath: string): Promise<{ sha256: string; bytes: number }>;
|
|
31
31
|
writeOfflineSyncFile(filePath: string, content: Buffer): Promise<void>;
|
|
32
|
-
writeOfflineSyncStagingFile(
|
|
32
|
+
writeOfflineSyncStagingFile(
|
|
33
|
+
filePath: string,
|
|
34
|
+
content: Buffer,
|
|
35
|
+
opts?: { aadFilePath?: string },
|
|
36
|
+
): Promise<void>;
|
|
33
37
|
writeOfflineSyncFileChunks(filePath: string, chunks: AsyncIterable<Buffer>): Promise<void>;
|
|
34
38
|
deleteOfflineSyncFile(filePath: string, deletionMtimeMs?: number | null): Promise<void>;
|
|
35
39
|
recordReplicatedDeletionRevision(filePath: string, mtimeMs: number): Promise<void>;
|
|
@@ -219,6 +223,16 @@ export async function applySupportPassportOfflineSyncChangeset(
|
|
|
219
223
|
guard.assertContentAllowed(target.path, target.content);
|
|
220
224
|
await storage.writeOfflineSyncFile(target.filePath, target.content);
|
|
221
225
|
},
|
|
226
|
+
// Secure staging for embedding-generation replacement (#3150): staged
|
|
227
|
+
// ciphertext binds the FINAL published path, matching the snapshot apply.
|
|
228
|
+
writeStagingFile: async ({ filePath, content, finalAadFilePath }) =>
|
|
229
|
+
storage.writeOfflineSyncStagingFile(
|
|
230
|
+
filePath,
|
|
231
|
+
content,
|
|
232
|
+
finalAadFilePath === undefined ? undefined : { aadFilePath: finalAadFilePath },
|
|
233
|
+
),
|
|
234
|
+
readStagingFile: async ({ filePath, finalAadFilePath }) =>
|
|
235
|
+
storage.readOfflineSyncFile(filePath, finalAadFilePath === undefined ? undefined : { aadFilePath: finalAadFilePath }),
|
|
222
236
|
deleteFile: async (target) => {
|
|
223
237
|
await guard.assertTargetAllowed(target);
|
|
224
238
|
await storage.deleteOfflineSyncFile(target.filePath, target.mtimeMs ?? null);
|
package/src/types.ts
CHANGED
|
@@ -10,9 +10,9 @@ import type { ReplicaPeersConfig } from "./replica-peers-config.js";
|
|
|
10
10
|
import type { ExternalWikiRoot } from "./external-wiki-config.js";
|
|
11
11
|
import type { StateViewResult } from "./recall-state-view.js";
|
|
12
12
|
import type { ContradictionLocalizationConfig, ContradictionScanConfig } from "./contradiction-config.js";
|
|
13
|
-
import type { GraphPathScoringConfig } from "./graph-path-scoring-config.js";
|
|
13
|
+
import type { GraphPathScoringConfig } from "./graph-path-scoring-config.js"; export type { GraphPathScoringConfig };
|
|
14
|
+
import type { OutcomeBoostConfig } from "./outcome-boost-config.js"; export type { OutcomeBoostConfig };
|
|
14
15
|
export type { ContradictionLocalizationConfig, ContradictionScanConfig } from "./contradiction-config.js";
|
|
15
|
-
export type { GraphPathScoringConfig } from "./graph-path-scoring-config.js";
|
|
16
16
|
export type { BackgroundGenerationConfig } from "./background-generation-config.js";
|
|
17
17
|
import type { BackgroundGenerationConfig } from "./background-generation-config.js";
|
|
18
18
|
import type {
|
|
@@ -700,7 +700,7 @@ export interface PluginConfig
|
|
|
700
700
|
RecallNavigationSettings,
|
|
701
701
|
RecognitionTierSettings,
|
|
702
702
|
SeedGraduationSettings,
|
|
703
|
-
LocalLlmConfig {
|
|
703
|
+
LocalLlmConfig, OutcomeBoostConfig {
|
|
704
704
|
openaiApiKey: string | undefined;
|
|
705
705
|
openaiBaseUrl: string | undefined;
|
|
706
706
|
backgroundGeneration?: BackgroundGenerationConfig;
|