pi-mega-compact 0.20.64 → 0.20.65

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.
Files changed (86) hide show
  1. package/README.md +1 -1
  2. package/dist/config/vector-cortex-enc2b.js +36 -0
  3. package/dist/config/vector-cortex.js +2 -0
  4. package/dist/config.js +1 -1
  5. package/dist/extensions/dashboard-server/routes-rag-settings-vector-cortex.js +1 -0
  6. package/dist/extensions/dashboard-server/routes-setup-enc2b.js +77 -0
  7. package/dist/extensions/dashboard-server/routes-setup.js +39 -3
  8. package/dist/src/config/vector-cortex-enc2b.js +36 -0
  9. package/dist/src/config/vector-cortex.js +2 -0
  10. package/dist/src/config.js +1 -1
  11. package/dist/src/vector-cortex/encoder/native-qualify-retest.js +225 -0
  12. package/dist/vector-cortex/encoder/native-qualify-retest.js +225 -0
  13. package/extensions/dashboard-client/dist/assets/{AdminTab-sjV8P5A4.js → AdminTab-B31efZ_R.js} +2 -2
  14. package/extensions/dashboard-client/dist/assets/{AdminTab-sjV8P5A4.js.map → AdminTab-B31efZ_R.js.map} +1 -1
  15. package/extensions/dashboard-client/dist/assets/{AreaChart-C03yuld4.js → AreaChart-BpjHNUZm.js} +2 -2
  16. package/extensions/dashboard-client/dist/assets/{AreaChart-C03yuld4.js.map → AreaChart-BpjHNUZm.js.map} +1 -1
  17. package/extensions/dashboard-client/dist/assets/{BarChart-B9jtJ7ud.js → BarChart-CY2FndXC.js} +2 -2
  18. package/extensions/dashboard-client/dist/assets/{BarChart-B9jtJ7ud.js.map → BarChart-CY2FndXC.js.map} +1 -1
  19. package/extensions/dashboard-client/dist/assets/{CacheTab-B7Eh3qfp.js → CacheTab-kMSrMD3e.js} +2 -2
  20. package/extensions/dashboard-client/dist/assets/{CacheTab-B7Eh3qfp.js.map → CacheTab-kMSrMD3e.js.map} +1 -1
  21. package/extensions/dashboard-client/dist/assets/{ConfigTab-DDTqosv2.js → ConfigTab-BrKpv2YG.js} +2 -2
  22. package/extensions/dashboard-client/dist/assets/{ConfigTab-DDTqosv2.js.map → ConfigTab-BrKpv2YG.js.map} +1 -1
  23. package/extensions/dashboard-client/dist/assets/{EventsTab-BmyQGmUa.js → EventsTab-DaClreCm.js} +2 -2
  24. package/extensions/dashboard-client/dist/assets/{EventsTab-BmyQGmUa.js.map → EventsTab-DaClreCm.js.map} +1 -1
  25. package/extensions/dashboard-client/dist/assets/{HealthTab-DzPqNqpm.js → HealthTab-CxKQDqF3.js} +2 -2
  26. package/extensions/dashboard-client/dist/assets/{HealthTab-DzPqNqpm.js.map → HealthTab-CxKQDqF3.js.map} +1 -1
  27. package/extensions/dashboard-client/dist/assets/{MaintenanceTab-6g3d-M1p.js → MaintenanceTab-BKSlSjv0.js} +2 -2
  28. package/extensions/dashboard-client/dist/assets/{MaintenanceTab-6g3d-M1p.js.map → MaintenanceTab-BKSlSjv0.js.map} +1 -1
  29. package/extensions/dashboard-client/dist/assets/{MemoryMapTab-Nk2yYPMS.js → MemoryMapTab-C2goWDt8.js} +2 -2
  30. package/extensions/dashboard-client/dist/assets/{MemoryMapTab-Nk2yYPMS.js.map → MemoryMapTab-C2goWDt8.js.map} +1 -1
  31. package/extensions/dashboard-client/dist/assets/{MetricsCards-BlIiuZp5.js → MetricsCards-DCPuCnrw.js} +2 -2
  32. package/extensions/dashboard-client/dist/assets/{MetricsCards-BlIiuZp5.js.map → MetricsCards-DCPuCnrw.js.map} +1 -1
  33. package/extensions/dashboard-client/dist/assets/MetricsTab-Bz0Mdyb_.js +2 -0
  34. package/extensions/dashboard-client/dist/assets/{MetricsTab-DfRDIAEU.js.map → MetricsTab-Bz0Mdyb_.js.map} +1 -1
  35. package/extensions/dashboard-client/dist/assets/{OverviewTab-xkuFE5GV.js → OverviewTab-B-eZ-eDR.js} +2 -2
  36. package/extensions/dashboard-client/dist/assets/{OverviewTab-xkuFE5GV.js.map → OverviewTab-B-eZ-eDR.js.map} +1 -1
  37. package/extensions/dashboard-client/dist/assets/{ReposTab-C6qZmmgQ.js → ReposTab-W_NKRWpk.js} +2 -2
  38. package/extensions/dashboard-client/dist/assets/{ReposTab-C6qZmmgQ.js.map → ReposTab-W_NKRWpk.js.map} +1 -1
  39. package/extensions/dashboard-client/dist/assets/{SessionsTab-Bkd_In3n.js → SessionsTab-GYrtNt4_.js} +2 -2
  40. package/extensions/dashboard-client/dist/assets/{SessionsTab-Bkd_In3n.js.map → SessionsTab-GYrtNt4_.js.map} +1 -1
  41. package/extensions/dashboard-client/dist/assets/SetupTab-_1xa6eTJ.js +3 -0
  42. package/extensions/dashboard-client/dist/assets/SetupTab-_1xa6eTJ.js.map +1 -0
  43. package/extensions/dashboard-client/dist/assets/{TimeSavedCard-Dr0KNUed.js → TimeSavedCard-Ciu8anVG.js} +2 -2
  44. package/extensions/dashboard-client/dist/assets/{TimeSavedCard-Dr0KNUed.js.map → TimeSavedCard-Ciu8anVG.js.map} +1 -1
  45. package/extensions/dashboard-client/dist/assets/{TurnMemoryView-CjmSiRQ_.js → TurnMemoryView-BhXLIjWr.js} +2 -2
  46. package/extensions/dashboard-client/dist/assets/{TurnMemoryView-CjmSiRQ_.js.map → TurnMemoryView-BhXLIjWr.js.map} +1 -1
  47. package/extensions/dashboard-client/dist/assets/TurnsTab-C-f3DggL.js +2 -0
  48. package/extensions/dashboard-client/dist/assets/{TurnsTab-JsDstDDA.js.map → TurnsTab-C-f3DggL.js.map} +1 -1
  49. package/extensions/dashboard-client/dist/assets/{VcStatusBadge-C96wfemg.js → VcStatusBadge-D97V04WE.js} +2 -2
  50. package/extensions/dashboard-client/dist/assets/{VcStatusBadge-C96wfemg.js.map → VcStatusBadge-D97V04WE.js.map} +1 -1
  51. package/extensions/dashboard-client/dist/assets/{VectorCortexTab-DGV3kA7X.js → VectorCortexTab-cyDJPAPB.js} +2 -2
  52. package/extensions/dashboard-client/dist/assets/{VectorCortexTab-DGV3kA7X.js.map → VectorCortexTab-cyDJPAPB.js.map} +1 -1
  53. package/extensions/dashboard-client/dist/assets/{WikiTab-EFfy5v-D.js → WikiTab-dQ96DyjP.js} +2 -2
  54. package/extensions/dashboard-client/dist/assets/{WikiTab-EFfy5v-D.js.map → WikiTab-dQ96DyjP.js.map} +1 -1
  55. package/extensions/dashboard-client/dist/assets/{button-CvaPx9Bu.js → button-B1beLEiV.js} +2 -2
  56. package/extensions/dashboard-client/dist/assets/{button-CvaPx9Bu.js.map → button-B1beLEiV.js.map} +1 -1
  57. package/extensions/dashboard-client/dist/assets/{card-Crs5SwRQ.js → card-CK9KH_ob.js} +2 -2
  58. package/extensions/dashboard-client/dist/assets/{card-Crs5SwRQ.js.map → card-CK9KH_ob.js.map} +1 -1
  59. package/extensions/dashboard-client/dist/assets/{client-extra-Bd27WKSo.js → client-extra-gN7xjggX.js} +2 -2
  60. package/extensions/dashboard-client/dist/assets/{client-extra-Bd27WKSo.js.map → client-extra-gN7xjggX.js.map} +1 -1
  61. package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-qnHql9Es.js → generateCategoricalChart-MB2_0u55.js} +2 -2
  62. package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-qnHql9Es.js.map → generateCategoricalChart-MB2_0u55.js.map} +1 -1
  63. package/extensions/dashboard-client/dist/assets/{index-B4twCFnn.js → index-CKVd_Ym_.js} +3 -3
  64. package/extensions/dashboard-client/dist/assets/{index-B4twCFnn.js.map → index-CKVd_Ym_.js.map} +1 -1
  65. package/extensions/dashboard-client/dist/assets/{switch-BXutQI5d.js → switch-CswmYrO_.js} +2 -2
  66. package/extensions/dashboard-client/dist/assets/{switch-BXutQI5d.js.map → switch-CswmYrO_.js.map} +1 -1
  67. package/extensions/dashboard-client/dist/assets/{toggle-uE-OSaba.js → toggle-CMepFsf0.js} +2 -2
  68. package/extensions/dashboard-client/dist/assets/{toggle-uE-OSaba.js.map → toggle-CMepFsf0.js.map} +1 -1
  69. package/extensions/dashboard-client/dist/assets/{useSSE-BRgPAqeS.js → useSSE-Bl55LQFZ.js} +2 -2
  70. package/extensions/dashboard-client/dist/assets/{useSSE-BRgPAqeS.js.map → useSSE-Bl55LQFZ.js.map} +1 -1
  71. package/extensions/dashboard-client/dist/index.html +1 -1
  72. package/extensions/dashboard-client/src/tabs/SetupTab/CortexRetestCard.tsx +104 -0
  73. package/extensions/dashboard-client/src/tabs/SetupTab/CortexSetup.tsx +2 -0
  74. package/extensions/dashboard-server/api-contracts/setup.ts +30 -0
  75. package/extensions/dashboard-server/routes-rag-settings-vector-cortex.ts +6 -0
  76. package/extensions/dashboard-server/routes-setup-enc2b.ts +82 -0
  77. package/extensions/dashboard-server/routes-setup.ts +39 -3
  78. package/package.json +1 -1
  79. package/src/config/vector-cortex-enc2b.ts +38 -0
  80. package/src/config/vector-cortex.ts +2 -0
  81. package/src/config.ts +1 -0
  82. package/src/vector-cortex/encoder/native-qualify-retest.ts +264 -0
  83. package/extensions/dashboard-client/dist/assets/MetricsTab-DfRDIAEU.js +0 -2
  84. package/extensions/dashboard-client/dist/assets/SetupTab-CEXL71VP.js +0 -3
  85. package/extensions/dashboard-client/dist/assets/SetupTab-CEXL71VP.js.map +0 -1
  86. package/extensions/dashboard-client/dist/assets/TurnsTab-JsDstDDA.js +0 -2
package/README.md CHANGED
@@ -90,7 +90,7 @@ Set env vars before starting pi. Defaults are in `src/config/dedup.ts`.
90
90
  | `MEGACOMPACT_WIKI_INCREMENTAL` | `true` | Incremental wiki updates (no full rebuild) |
91
91
  | `MEGACOMPACT_AUTO_WIKI` | `true` | Auto-generate wiki from turns |
92
92
  | `MEGACOMPACT_NEW_UI` | `true` | Use the new Tailwind/shadcn dashboard shell |
93
- | `MEGACOMPACT_COST_API_ENABLED` | `false` | Opt-in: fetch model pricing from an external API (PREVENT-PI-004 network exception). Enriches dashboard cost data for models not in the local pricing table |
93
+ | `MEGACOMPACT_COST_API_ENABLED` | `false` | Opt-in: fetch model pricing from an external API (PREVENT-PI-004 applies to defaults; opt-in features are exempt). Enriches dashboard cost data for models not in the local pricing table |
94
94
  | `MEGACOMPACT_COST_API_URL` | _(unset)_ | OpenRouter-compatible model pricing endpoint (e.g. `https://openrouter.ai/api/v1/models`). Only contacted when `MEGACOMPACT_COST_API_ENABLED=true` |
95
95
 
96
96
  Full config reference: [`docs/CONFIGURATION.md`](docs/CONFIGURATION.md)
@@ -0,0 +1,36 @@
1
+ /**
2
+ * config/vector-cortex-enc2b.ts — ENC-2b native onnxruntime qualification
3
+ * retest flag.
4
+ *
5
+ * Sibling of vector-cortex-enc2a.ts / vector-cortex-enc2budget.ts so
6
+ * vector-cortex.ts stays under the 300-line soft limit (soft-as-hard gate).
7
+ * vector-cortex.ts re-exports the flag below and root src/config.ts re-exports
8
+ * it, so no consumer import path changes.
9
+ *
10
+ * ENC-2b re-probes and re-qualifies the installed native onnxruntime binding
11
+ * (`onnxruntime-node` in `~/.pi/mega-compact/native-ort/`, operator-installed
12
+ * via the ENC-2a guide). When the operator installs the binding the read path
13
+ * does not automatically re-evaluate the qualification verdict; this sprint
14
+ * delivers a reader-only retest that loads the LOCAL on-disk binding, runs a
15
+ * bounded warmup + p95 probe against it, measures RSS, computes a fresh
16
+ * qualification verdict against the ENC-0f p95 budget + the operator
17
+ * install-budget, and surfaces it on the Setup Cortex sub-tab and the GET
18
+ * `/api/setup-status` response.
19
+ *
20
+ * `MEGACOMPACT_ENC_2B=0` disables: the GET omits both new retest fields, the
21
+ * POST ignores the retest-request key, the Cortex sub-tab renders no retest
22
+ * card — byte-identical to the ENC-2a predecessor. The flag MUST also be a
23
+ * dashboard SETTINGS toggle (visible in config UI, never in EXCLUDED_SETTINGS
24
+ * — see `feedback_dashboard-flags-toggleable` memory).
25
+ *
26
+ * Pi-agnostic, dependency-free (PREVENT-PI-004 / PREVENT-011).
27
+ */
28
+ import { sprintFlag } from "./vector-cortex-flag.js";
29
+ /**
30
+ * ENC-2b — native onnxruntime qualification retest (detect installed binding,
31
+ * re-probe p95/RSS, re-qualify). Default ON. `MEGACOMPACT_ENC_2B=0` disables and
32
+ * is byte-identical to the ENC-2a predecessor: no retest GET fields, no retest
33
+ * POST branch, no retest card. This flag MUST also be a dashboard SETTINGS
34
+ * toggle (visible in config UI, never in EXCLUDED_SETTINGS).
35
+ */
36
+ export const ENC_2B_ENABLED = () => sprintFlag("MEGACOMPACT_ENC_2B");
@@ -52,5 +52,7 @@ export { ENC_1B_ENABLED, ENC_1B_MAX_EMBEDDING_DIM, ENC_1B_EMBEDDING_DIM_ENV, ENC
52
52
  export { ENC_2BUDGET_ENABLED, ENC_2BUDGET_NATIVE_ORT_BUDGET_ENV, ENC_2BUDGET_MAX_MIB, ENC_2BUDGET_DEFAULT_MIB, } from "./vector-cortex-enc2budget.js";
53
53
  // ENC-2a native onnxruntime install-guide flag extracted to vector-cortex-enc2a.ts.
54
54
  export { ENC_2A_ENABLED } from "./vector-cortex-enc2a.js";
55
+ // ENC-2b native onnxruntime qualification-retest flag extracted to vector-cortex-enc2b.ts.
56
+ export { ENC_2B_ENABLED } from "./vector-cortex-enc2b.js";
55
57
  // Breaker constants (TRIAD_RESILIENCE.md §breaker) extracted to vector-cortex-breakers.ts.
56
58
  export { BREAKER_WINDOW_MS, BREAKER_MIN_ATTEMPTS, BREAKER_PERF_FAILURES, BREAKER_PERF_FAILURE_RATE, BREAKER_CORRECTNESS_FAILURES, BREAKER_COOLDOWN_MS, BREAKER_PROBE_COUNT, BREAKER_RETRY_BASE_MS, BREAKER_RETRY_CAP_MS, BREAKER_RETRY_JITTER, BREAKER_HYSTERESIS_FAILURE_RATE, BREAKER_HYSTERESIS_BUDGET_P95_MS, BREAKER_MIN_HEALTHY_RESIDENCE_MS, } from "./vector-cortex-breakers.js";
package/dist/config.js CHANGED
@@ -114,4 +114,4 @@ export const NEW_UI = () => ragEnabled("MEGACOMPACT_NEW_UI");
114
114
  // default ON, `=0`/`_DISABLED` off. Re-exported from src/config/vector-cortex.ts
115
115
  // so root consumers share one source of truth.
116
116
  // ---------------------------------------------------------------------------
117
- export { VC0A_ENABLED, VC0B_ENABLED, VC1A_ENABLED, VC0C_ENABLED, VC1B_ENABLED, VC1C_ENABLED, VC2A_ENABLED, VC2B_ENABLED, VC2C_ENABLED, VC3A_ENABLED, VC3B_ENABLED, VC3C_ENABLED, VC4A_ENABLED, VC4B_ENABLED, VC4C_ENABLED, VC5A_ENABLED, VC5B_ENABLED, VC5C_ENABLED, VC6A_ENABLED, VC6B_ENABLED, VC6C_ENABLED, VC7A_ENABLED, VC7B_ENABLED, VC7C_ENABLED, VC8A_ENABLED, VC8B_ENABLED, VC8C_ENABLED, VC9A_ENABLED, VC9B_ENABLED, VC9C_ENABLED, VC9D_ENABLED, PCC_ENABLED, ML5A_ENABLED, ML5B_ENABLED, ML5C_ENABLED, ML5D_ENABLED, ML5E_ENABLED, DEDUP_ATTR_ENABLED, ENC_0A_ENABLED, ENC_0B_ENABLED, ENC_0C_ENABLED, ENC_0D_ENABLED, ENC_0E_ENABLED, ENC_0F_ENABLED, ENC_0G_ENABLED, ENC_1A_ENABLED, ENC_1B_ENABLED, ENC_2BUDGET_ENABLED, ENC_2BUDGET_NATIVE_ORT_BUDGET_ENV, ENC_2BUDGET_MAX_MIB, ENC_2BUDGET_DEFAULT_MIB, ENC_2A_ENABLED, COSINE_FP_BENCH_ENABLED, COSINE_FP_REAL_ENABLED, REPO_CORPUS_ENABLED, DASH_0A_ENABLED, DASH_0B_ENABLED, DASH_0C_ENABLED, DASH_0D_ENABLED, BREAKER_WINDOW_MS, BREAKER_MIN_ATTEMPTS, BREAKER_PERF_FAILURES, BREAKER_PERF_FAILURE_RATE, BREAKER_CORRECTNESS_FAILURES, BREAKER_COOLDOWN_MS, BREAKER_PROBE_COUNT, BREAKER_RETRY_BASE_MS, BREAKER_RETRY_CAP_MS, BREAKER_RETRY_JITTER, BREAKER_HYSTERESIS_FAILURE_RATE, BREAKER_HYSTERESIS_BUDGET_P95_MS, BREAKER_MIN_HEALTHY_RESIDENCE_MS, } from "./config/vector-cortex.js";
117
+ export { VC0A_ENABLED, VC0B_ENABLED, VC1A_ENABLED, VC0C_ENABLED, VC1B_ENABLED, VC1C_ENABLED, VC2A_ENABLED, VC2B_ENABLED, VC2C_ENABLED, VC3A_ENABLED, VC3B_ENABLED, VC3C_ENABLED, VC4A_ENABLED, VC4B_ENABLED, VC4C_ENABLED, VC5A_ENABLED, VC5B_ENABLED, VC5C_ENABLED, VC6A_ENABLED, VC6B_ENABLED, VC6C_ENABLED, VC7A_ENABLED, VC7B_ENABLED, VC7C_ENABLED, VC8A_ENABLED, VC8B_ENABLED, VC8C_ENABLED, VC9A_ENABLED, VC9B_ENABLED, VC9C_ENABLED, VC9D_ENABLED, PCC_ENABLED, ML5A_ENABLED, ML5B_ENABLED, ML5C_ENABLED, ML5D_ENABLED, ML5E_ENABLED, DEDUP_ATTR_ENABLED, ENC_0A_ENABLED, ENC_0B_ENABLED, ENC_0C_ENABLED, ENC_0D_ENABLED, ENC_0E_ENABLED, ENC_0F_ENABLED, ENC_0G_ENABLED, ENC_1A_ENABLED, ENC_1B_ENABLED, ENC_2BUDGET_ENABLED, ENC_2BUDGET_NATIVE_ORT_BUDGET_ENV, ENC_2BUDGET_MAX_MIB, ENC_2BUDGET_DEFAULT_MIB, ENC_2A_ENABLED, ENC_2B_ENABLED, COSINE_FP_BENCH_ENABLED, COSINE_FP_REAL_ENABLED, REPO_CORPUS_ENABLED, DASH_0A_ENABLED, DASH_0B_ENABLED, DASH_0C_ENABLED, DASH_0D_ENABLED, BREAKER_WINDOW_MS, BREAKER_MIN_ATTEMPTS, BREAKER_PERF_FAILURES, BREAKER_PERF_FAILURE_RATE, BREAKER_CORRECTNESS_FAILURES, BREAKER_COOLDOWN_MS, BREAKER_PROBE_COUNT, BREAKER_RETRY_BASE_MS, BREAKER_RETRY_CAP_MS, BREAKER_RETRY_JITTER, BREAKER_HYSTERESIS_FAILURE_RATE, BREAKER_HYSTERESIS_BUDGET_P95_MS, BREAKER_MIN_HEALTHY_RESIDENCE_MS, } from "./config/vector-cortex.js";
@@ -71,6 +71,7 @@ export const VECTOR_CORTEX_SETTINGS = {
71
71
  boolDirect("MEGACOMPACT_ENC_1B", "ENC-1b ONNX runtime backend + embedder API settings", "ENC-1b completes the embedder API Settings surface (dim / headers / allow-remote persisted to the per-repo .mega-compact.env) and surfaces the ONNX runtime selection knob (MEGACOMPACT_ENCODER_NATIVE) as a toggle plus the current effective backend + demotion reason. OFF = no new GET fields, no writer branch, no new Settings rows or toggle (byte-identical ENC-1a predecessor).", true),
72
72
  boolDirect("MEGACOMPACT_ENC_2BUDGET", "ENC-2a operator-configurable native install-budget knob", "ENC-2a exposes the runtime operator knob MEGACOMPACT_NATIVE_ORT_BUDGET_MIB (default 300 MiB, clamp 8192) as a dashboard Settings field. The knob gates budgetOk in the encoder runtime decision (decision.ts installBudgetMib + runtime-select.ts selectRuntimeBackend). Persisted to the per-repo .mega-compact.env via the setup-configure writer branch; the GET status route surfaces the persisted value AND the effective integer installBudgetMib() resolves to (so the dashboard shows the runtime's actual operand). OFF = no new GET fields, no writer branch, no new Settings rows (byte-identical ENC-1b predecessor).", true),
73
73
  boolDirect("MEGACOMPACT_ENC_2A", "ENC-2a native onnxruntime install GUIDE (detect + copy-paste)", "ENC-2a surfaces the platform-matched native onnxruntime install-guide (three copy-paste steps + script path) on the Setup Cortex sub-tab when the operator opted into the native backend but the effective runtime is still wasm (onnxruntime-node absent). Pure guidance — the extension NEVER executes or fetches (PREVENT-PI-004 unchanged); the committed operator script scripts/encoder/install-native-ort.mjs runs in the USER's shell. OFF = no guide GET fields, no guide-request POST branch, no install card (byte-identical ENC-1b predecessor).", true),
74
+ boolDirect("MEGACOMPACT_ENC_2B", "ENC-2b native ONNX runtime qualification retest (detect + re-qualify)", "ENC-2b re-probes and re-qualifies the installed native onnxruntime binding (onnxruntime-node in ~/.pi/mega-compact/native-ort/, operator-installed via the ENC-2a guide): loads the LOCAL on-disk binding, runs a bounded warmup + p95 probe, measures RSS, and computes a fresh qualification verdict against the ENC-0f p95 budget + the operator install-budget. Never downloads or trains (PREVENT-PI-004 / HG-1 unchanged); surfaces nativeOrtRetestResult + nativeOrtBackendEffective on the GET /api/setup-status. OFF = no retest GET fields, no retest POST branch, no retest card (byte-identical ENC-2a predecessor).", true),
74
75
  boolDirect("MEGACOMPACT_COSINE_FP_BENCH", "COS-FP-A Synthetic FP Bench", "Synthetic FP harness + L2 cosine threshold calibration (COS-FP-A): drives the deterministic synthetic-corpus grid sweep (scripts/cosine-fp/bench.mjs) that measures L2 cosine false-positive rates and emits a recommended default, and serves the reader-only GET /api/cosine-fp-report. Synthetic-corpus-only — never reads real session/ledger bytes. OFF = bench inert, endpoint 404s, no report write, L2_COSINE plain MEGACOMPACT_L2_THRESHOLD (byte-identical predecessor).", true),
75
76
  boolDirect("MEGACOMPACT_COSINE_FP_REAL", "COS-FP-R Real-Corpus Validation", "Real-corpus L2 cosine FP validation (COS-FP-R): runs the real-corpus grid sweep (scripts/cosine-fp/real-bench.mjs) against donated, consent-approved sessions only (SECURITY_PRIVACY Lifecycle/Consent), scoring FP/FN with Wilson intervals + session-grouped bootstrap, and appends CI-backed per-content-type recommendations to the cosine-threshold report. Runs only when a valid consented corpus exists; absent corpus = no_corpus (normative pre-donation state, nothing written). OFF = script inert, nothing executes, no writes (byte-identical predecessor).", true),
76
77
  boolDirect("MEGACOMPACT_REPO_CORPUS", "Cross-Repo Corpus (REPO-A)", "Cross-repo corpus preparation (REPO-A): the governed, consent-gated reader-only path that builds a pseudonymous corpus manifest from per-repo events.log slices and serves GET /api/repo-corpus answering which pseudonymous repos/sessions are in the corpus, what cross-repo overlap exists, and whether consent is active for each — counts + IDs + status only, never payload content. Consent is append-only (consent.mjs, CLI/ops-only); revocation freezes the builder + route. OFF = builder refuses to run, reader route 404s, single-repo recall untouched (byte-identical predecessor).", true),
@@ -0,0 +1,77 @@
1
+ /**
2
+ * dashboard-server/routes-setup-enc2b.ts — ENC-2b native onnxruntime
3
+ * qualification retest (reader-only probe) + POST retest action.
4
+ *
5
+ * Extracted out of routes-setup.ts (which hovers at the 300-line source soft
6
+ * cap, mirroring the ENC-1b/ENC-2a sibling extracts) so the ENC-2b additive
7
+ * GET field — the native qualification retest result + effective backend —
8
+ * lives in a sibling impl file and routes-setup.ts stays a thin host.
9
+ *
10
+ * The retest's job is RE-QUALIFICATION: when the operator installed
11
+ * onnxruntime-node via the ENC-2a guide, the encoder read path does not
12
+ * automatically re-evaluate the qualification verdict. This sibling surface
13
+ * runs `runNativeRetest` (a bounded, reader-only, local probe) and:
14
+ *
15
+ * - surfaces `nativeOrtRetestResult` + `nativeOrtBackendEffective` on the GET
16
+ * when the flag is on AND a binding is installed — absent otherwise
17
+ * (byte-identical to the ENC-2a-era shape on flag-off/none);
18
+ * - handles the POST `nativeOrtRetest` key (`false` → 400
19
+ * `retest_rejected_false_nothing_to_do`; `true` → run + echo the fresh
20
+ * result; flag-off → the key is unrecognized, byte-identical predecessor).
21
+ *
22
+ * `nativeOrtBackendEffective` is `"native"` only when the retest verdict is
23
+ * `qualified`; any `degraded`/`failed` verdict keeps the backend `"wasm"` — the
24
+ * runtime never silently switches to a backend whose retest failed.
25
+ *
26
+ * Guardrails: PREVENT-PI-004 (local filesystem + in-process binding load only,
27
+ * zero network — the retest NEVER fetches), PREVENT-011 (no `any`).
28
+ */
29
+ import { ENC_2B_ENABLED } from "../../src/config/vector-cortex.js";
30
+ import { runNativeRetest, } from "../../src/vector-cortex/encoder/native-qualify-retest.js";
31
+ /**
32
+ * Resolve the ENC-2b additive GET fields. Returns BOTH fields when the flag is
33
+ * on AND a native binding is installed (the retest ran); returns `{}` on
34
+ * flag-off AND when no binding is installed — both fields are OMITTED (absent,
35
+ * not null), so the GET stays byte-identical to the ENC-2a-era shape and the
36
+ * client hides the retest card. Flag-off omits, never nulls: the ENC-2a-era
37
+ * host spreads `...{}` so no new key appears. Mirror of the ENC-2a/ENC-1b
38
+ * sibling idiom; async because the retest loads the binding in-process.
39
+ */
40
+ export async function readEnc2bRetest(stateDir) {
41
+ if (!ENC_2B_ENABLED())
42
+ return {};
43
+ const result = await runNativeRetest(stateDir);
44
+ if (result === null)
45
+ return {};
46
+ return {
47
+ nativeOrtRetestResult: result,
48
+ nativeOrtBackendEffective: result.verdict === "qualified" ? "native" : "wasm",
49
+ };
50
+ }
51
+ /**
52
+ * ENC-2b POST retest-action key handling (flag-gated, additive).
53
+ *
54
+ * `true` → { action: "run" } (the host runs the retest and returns the result)
55
+ * `false` → { action: "reject" } (400 `retest_rejected_false_nothing_to_do`)
56
+ * other → null (key absent or flag off — falls through unrecognized,
57
+ * byte-identical ENC-2a-era predecessor).
58
+ */
59
+ export function enc2bRetestRequest(body) {
60
+ if (!ENC_2B_ENABLED())
61
+ return null;
62
+ if (body.nativeOrtRetest === true)
63
+ return "run";
64
+ if (body.nativeOrtRetest === false)
65
+ return "reject";
66
+ return null;
67
+ }
68
+ /**
69
+ * Run the ENC-2b retest now (bounded, synchronous on the request) and return
70
+ * the fresh result. Flag-off or no binding → null. Used by the POST "run"
71
+ * branch; the result is returned on the response body, never persisted.
72
+ */
73
+ export async function runEnc2bRetest(stateDir) {
74
+ if (!ENC_2B_ENABLED())
75
+ return null;
76
+ return runNativeRetest(stateDir);
77
+ }
@@ -15,6 +15,7 @@ import { enc1aStatusFields, writeEnc1aEnv, tryEnc1aConfigure, wantsEnc1a } from
15
15
  import { enc1bStatusFields, tryEnc1bConfigure, tryEnc1bInto, enc1bValidateCombined } from "./routes-setup-enc1b.js";
16
16
  import { enc2BudgetStatusFields, tryEnc2BudgetInto, enc2BudgetValidateCombined, } from "./routes-setup-enc2budget.js";
17
17
  import { readEnc2aGuide, enc2aGuideRequest } from "./routes-setup-enc2a.js";
18
+ import { readEnc2bRetest, enc2bRetestRequest, runEnc2bRetest } from "./routes-setup-enc2b.js";
18
19
  import { writeEmbedderEnv } from "./routes-setup-env-upsert.js";
19
20
  import { detectOllama, detectLlamaCpp, detectOnnx, memoizedDetectOllama, memoizedDetectLlamaCpp, memoizedDetectOnnx, } from "./routes-setup-detect-cache.js";
20
21
  // ---------------------------------------------------------------------------
@@ -69,7 +70,7 @@ export function handleSetupStatus(req, res, ctx) {
69
70
  // ENC-1a (flag-gated, additive): echo the persisted endpoint URL and an
70
71
  // embeddingApiKeySet boolean ONLY — the raw API key is never returned. When
71
72
  // the flag is off (or neither is set) both fields are simply omitted.
72
- const body = {
73
+ const base = {
73
74
  currentEmbedder: active,
74
75
  configuredEmbedder: configured.embedder,
75
76
  configuredUrl: configured.url,
@@ -82,9 +83,20 @@ export function handleSetupStatus(req, res, ctx) {
82
83
  ...(enc2a.guide !== null ? { nativeOrtInstallGuide: enc2a.guide } : {}),
83
84
  ...(enc2a.installedVersion !== null ? { nativeOrtInstalledVersion: enc2a.installedVersion } : {}),
84
85
  };
86
+ // ENC-2b (flag-gated, additive): the native qualification retest fields. The
87
+ // retest loads the on-disk binding in-process (bounded, never a fetch), so
88
+ // readEnc2bRetest is async; the handler returns true synchronously for the
89
+ // dispatch and writes the response after the await. Flag-off/none mutates
90
+ // the body additively and stays byte-identical to the ENC-2a-era shape.
85
91
  // guardrails-allow PREVENT-PI-004: loopback dashboard response (local)
86
- res.writeHead(200, { "Content-Type": "application/json" });
87
- res.end(JSON.stringify(body));
92
+ readEnc2bRetest(ctx.stateDir).then((enc2b) => {
93
+ const body = { ...base, ...enc2b };
94
+ res.writeHead(200, { "Content-Type": "application/json" });
95
+ res.end(JSON.stringify(body));
96
+ }).catch(() => {
97
+ res.writeHead(200, { "Content-Type": "application/json" });
98
+ res.end(JSON.stringify(base));
99
+ });
88
100
  return true;
89
101
  }
90
102
  // ---------------------------------------------------------------------------
@@ -204,6 +216,30 @@ export function handleSetupConfigure(req, res, ctx) {
204
216
  res.end(JSON.stringify({ nativeOrtInstallGuide: readEnc2aGuide(ctx.stateDir).guide }));
205
217
  return;
206
218
  }
219
+ // ENC-2b retest-action key (flag-gated, additive): `false` → 400 (an
220
+ // operator-driven no-op — nothing to retest), `true` → run the bounded
221
+ // retest synchronously and return the fresh result. Flag-off: the key
222
+ // falls through unrecognized (byte-identical ENC-2a-era predecessor).
223
+ // The retest never fetches — the binding is on disk from the ENC-2a
224
+ // install (PREVENT-PI-004 clean).
225
+ const retestReq = enc2bRetestRequest(body);
226
+ // guardrails-allow PREVENT-PI-004: loopback dashboard response (local)
227
+ if (retestReq === "reject") {
228
+ res.writeHead(400, { "Content-Type": "application/json" });
229
+ res.end(JSON.stringify({ error: "retest_rejected_false_nothing_to_do" }));
230
+ return;
231
+ }
232
+ if (retestReq === "run") {
233
+ // guardrails-allow PREVENT-PI-004: loopback dashboard response (local)
234
+ runEnc2bRetest(ctx.stateDir).then((fresh) => {
235
+ res.writeHead(200, { "Content-Type": "application/json" });
236
+ res.end(JSON.stringify({ nativeOrtRetestResult: fresh }));
237
+ }).catch(() => {
238
+ res.writeHead(500, { "Content-Type": "application/json" });
239
+ res.end(JSON.stringify({ error: "retest_failed" }));
240
+ });
241
+ return;
242
+ }
207
243
  if (tryEnc1aConfigure(body, res, ctx))
208
244
  return;
209
245
  if (tryEnc1bConfigure(body, res, ctx))
@@ -0,0 +1,36 @@
1
+ /**
2
+ * config/vector-cortex-enc2b.ts — ENC-2b native onnxruntime qualification
3
+ * retest flag.
4
+ *
5
+ * Sibling of vector-cortex-enc2a.ts / vector-cortex-enc2budget.ts so
6
+ * vector-cortex.ts stays under the 300-line soft limit (soft-as-hard gate).
7
+ * vector-cortex.ts re-exports the flag below and root src/config.ts re-exports
8
+ * it, so no consumer import path changes.
9
+ *
10
+ * ENC-2b re-probes and re-qualifies the installed native onnxruntime binding
11
+ * (`onnxruntime-node` in `~/.pi/mega-compact/native-ort/`, operator-installed
12
+ * via the ENC-2a guide). When the operator installs the binding the read path
13
+ * does not automatically re-evaluate the qualification verdict; this sprint
14
+ * delivers a reader-only retest that loads the LOCAL on-disk binding, runs a
15
+ * bounded warmup + p95 probe against it, measures RSS, computes a fresh
16
+ * qualification verdict against the ENC-0f p95 budget + the operator
17
+ * install-budget, and surfaces it on the Setup Cortex sub-tab and the GET
18
+ * `/api/setup-status` response.
19
+ *
20
+ * `MEGACOMPACT_ENC_2B=0` disables: the GET omits both new retest fields, the
21
+ * POST ignores the retest-request key, the Cortex sub-tab renders no retest
22
+ * card — byte-identical to the ENC-2a predecessor. The flag MUST also be a
23
+ * dashboard SETTINGS toggle (visible in config UI, never in EXCLUDED_SETTINGS
24
+ * — see `feedback_dashboard-flags-toggleable` memory).
25
+ *
26
+ * Pi-agnostic, dependency-free (PREVENT-PI-004 / PREVENT-011).
27
+ */
28
+ import { sprintFlag } from "./vector-cortex-flag.js";
29
+ /**
30
+ * ENC-2b — native onnxruntime qualification retest (detect installed binding,
31
+ * re-probe p95/RSS, re-qualify). Default ON. `MEGACOMPACT_ENC_2B=0` disables and
32
+ * is byte-identical to the ENC-2a predecessor: no retest GET fields, no retest
33
+ * POST branch, no retest card. This flag MUST also be a dashboard SETTINGS
34
+ * toggle (visible in config UI, never in EXCLUDED_SETTINGS).
35
+ */
36
+ export const ENC_2B_ENABLED = () => sprintFlag("MEGACOMPACT_ENC_2B");
@@ -52,5 +52,7 @@ export { ENC_1B_ENABLED, ENC_1B_MAX_EMBEDDING_DIM, ENC_1B_EMBEDDING_DIM_ENV, ENC
52
52
  export { ENC_2BUDGET_ENABLED, ENC_2BUDGET_NATIVE_ORT_BUDGET_ENV, ENC_2BUDGET_MAX_MIB, ENC_2BUDGET_DEFAULT_MIB, } from "./vector-cortex-enc2budget.js";
53
53
  // ENC-2a native onnxruntime install-guide flag extracted to vector-cortex-enc2a.ts.
54
54
  export { ENC_2A_ENABLED } from "./vector-cortex-enc2a.js";
55
+ // ENC-2b native onnxruntime qualification-retest flag extracted to vector-cortex-enc2b.ts.
56
+ export { ENC_2B_ENABLED } from "./vector-cortex-enc2b.js";
55
57
  // Breaker constants (TRIAD_RESILIENCE.md §breaker) extracted to vector-cortex-breakers.ts.
56
58
  export { BREAKER_WINDOW_MS, BREAKER_MIN_ATTEMPTS, BREAKER_PERF_FAILURES, BREAKER_PERF_FAILURE_RATE, BREAKER_CORRECTNESS_FAILURES, BREAKER_COOLDOWN_MS, BREAKER_PROBE_COUNT, BREAKER_RETRY_BASE_MS, BREAKER_RETRY_CAP_MS, BREAKER_RETRY_JITTER, BREAKER_HYSTERESIS_FAILURE_RATE, BREAKER_HYSTERESIS_BUDGET_P95_MS, BREAKER_MIN_HEALTHY_RESIDENCE_MS, } from "./vector-cortex-breakers.js";
@@ -114,4 +114,4 @@ export const NEW_UI = () => ragEnabled("MEGACOMPACT_NEW_UI");
114
114
  // default ON, `=0`/`_DISABLED` off. Re-exported from src/config/vector-cortex.ts
115
115
  // so root consumers share one source of truth.
116
116
  // ---------------------------------------------------------------------------
117
- export { VC0A_ENABLED, VC0B_ENABLED, VC1A_ENABLED, VC0C_ENABLED, VC1B_ENABLED, VC1C_ENABLED, VC2A_ENABLED, VC2B_ENABLED, VC2C_ENABLED, VC3A_ENABLED, VC3B_ENABLED, VC3C_ENABLED, VC4A_ENABLED, VC4B_ENABLED, VC4C_ENABLED, VC5A_ENABLED, VC5B_ENABLED, VC5C_ENABLED, VC6A_ENABLED, VC6B_ENABLED, VC6C_ENABLED, VC7A_ENABLED, VC7B_ENABLED, VC7C_ENABLED, VC8A_ENABLED, VC8B_ENABLED, VC8C_ENABLED, VC9A_ENABLED, VC9B_ENABLED, VC9C_ENABLED, VC9D_ENABLED, PCC_ENABLED, ML5A_ENABLED, ML5B_ENABLED, ML5C_ENABLED, ML5D_ENABLED, ML5E_ENABLED, DEDUP_ATTR_ENABLED, ENC_0A_ENABLED, ENC_0B_ENABLED, ENC_0C_ENABLED, ENC_0D_ENABLED, ENC_0E_ENABLED, ENC_0F_ENABLED, ENC_0G_ENABLED, ENC_1A_ENABLED, ENC_1B_ENABLED, ENC_2BUDGET_ENABLED, ENC_2BUDGET_NATIVE_ORT_BUDGET_ENV, ENC_2BUDGET_MAX_MIB, ENC_2BUDGET_DEFAULT_MIB, ENC_2A_ENABLED, COSINE_FP_BENCH_ENABLED, COSINE_FP_REAL_ENABLED, REPO_CORPUS_ENABLED, DASH_0A_ENABLED, DASH_0B_ENABLED, DASH_0C_ENABLED, DASH_0D_ENABLED, BREAKER_WINDOW_MS, BREAKER_MIN_ATTEMPTS, BREAKER_PERF_FAILURES, BREAKER_PERF_FAILURE_RATE, BREAKER_CORRECTNESS_FAILURES, BREAKER_COOLDOWN_MS, BREAKER_PROBE_COUNT, BREAKER_RETRY_BASE_MS, BREAKER_RETRY_CAP_MS, BREAKER_RETRY_JITTER, BREAKER_HYSTERESIS_FAILURE_RATE, BREAKER_HYSTERESIS_BUDGET_P95_MS, BREAKER_MIN_HEALTHY_RESIDENCE_MS, } from "./config/vector-cortex.js";
117
+ export { VC0A_ENABLED, VC0B_ENABLED, VC1A_ENABLED, VC0C_ENABLED, VC1B_ENABLED, VC1C_ENABLED, VC2A_ENABLED, VC2B_ENABLED, VC2C_ENABLED, VC3A_ENABLED, VC3B_ENABLED, VC3C_ENABLED, VC4A_ENABLED, VC4B_ENABLED, VC4C_ENABLED, VC5A_ENABLED, VC5B_ENABLED, VC5C_ENABLED, VC6A_ENABLED, VC6B_ENABLED, VC6C_ENABLED, VC7A_ENABLED, VC7B_ENABLED, VC7C_ENABLED, VC8A_ENABLED, VC8B_ENABLED, VC8C_ENABLED, VC9A_ENABLED, VC9B_ENABLED, VC9C_ENABLED, VC9D_ENABLED, PCC_ENABLED, ML5A_ENABLED, ML5B_ENABLED, ML5C_ENABLED, ML5D_ENABLED, ML5E_ENABLED, DEDUP_ATTR_ENABLED, ENC_0A_ENABLED, ENC_0B_ENABLED, ENC_0C_ENABLED, ENC_0D_ENABLED, ENC_0E_ENABLED, ENC_0F_ENABLED, ENC_0G_ENABLED, ENC_1A_ENABLED, ENC_1B_ENABLED, ENC_2BUDGET_ENABLED, ENC_2BUDGET_NATIVE_ORT_BUDGET_ENV, ENC_2BUDGET_MAX_MIB, ENC_2BUDGET_DEFAULT_MIB, ENC_2A_ENABLED, ENC_2B_ENABLED, COSINE_FP_BENCH_ENABLED, COSINE_FP_REAL_ENABLED, REPO_CORPUS_ENABLED, DASH_0A_ENABLED, DASH_0B_ENABLED, DASH_0C_ENABLED, DASH_0D_ENABLED, BREAKER_WINDOW_MS, BREAKER_MIN_ATTEMPTS, BREAKER_PERF_FAILURES, BREAKER_PERF_FAILURE_RATE, BREAKER_CORRECTNESS_FAILURES, BREAKER_COOLDOWN_MS, BREAKER_PROBE_COUNT, BREAKER_RETRY_BASE_MS, BREAKER_RETRY_CAP_MS, BREAKER_RETRY_JITTER, BREAKER_HYSTERESIS_FAILURE_RATE, BREAKER_HYSTERESIS_BUDGET_P95_MS, BREAKER_MIN_HEALTHY_RESIDENCE_MS, } from "./config/vector-cortex.js";
@@ -0,0 +1,225 @@
1
+ /**
2
+ * vector-cortex/encoder/native-qualify-retest.ts — ENC-2b native onnxruntime
3
+ * qualification retest (reader-only probe).
4
+ *
5
+ * When an operator installs onnxruntime-node via the ENC-2a guide, the encoder
6
+ * read path does not automatically re-evaluate the qualification verdict — the
7
+ * encoder still reports encoderBackend "wasm" until a retest runs. This module
8
+ * is that retest: a pure, bounded, reader-only probe that
9
+ *
10
+ * (a) resolves the installed binding `<native-ort>/node_modules/onnxruntime-node/`;
11
+ * (b) reads its `package.json` version;
12
+ * (c) dynamic-imports the binding;
13
+ * (d) finds a LOCAL onnx model to probe against (under `~/.pi/mega-compact/`);
14
+ * (e) runs a bounded warmup (3 passes) + 10 timed inference passes on a fixed
15
+ * 512-token synthetic input (the bench-onnx.mjs harness shape, in-process);
16
+ * (f) measures p95 (sorted index) and RSS (`process.memoryUsage().rss`);
17
+ * (g) computes a fresh qualification verdict against the ENC-0f p95 budget
18
+ * (`ENCODER_LATENCY_P95_MS`) and the operator install-budget
19
+ * (`installBudgetMib()` as the RSS ceiling — the ENC-2budget derivative).
20
+ *
21
+ * Results: `{platform, version, verdict: "qualified"|"degraded"|"failed",
22
+ * p95Ms, rssMiB, testedAt}` or `null` when no binding is installed. It NEVER
23
+ * throws into the route layer: every binding-load/session/model failure is
24
+ * caught and reported as a `failed` verdict with the error message surfaced in
25
+ * the engine, never raised. NO network (PREVENT-PI-004 — the binding + model
26
+ * are on disk from the operator's ENC-2a install), NO training (HG-1 unchanged).
27
+ *
28
+ * Pi-agnostic, dependency-free. No `any` (PREVENT-011).
29
+ */
30
+ import { readFileSync, existsSync } from "node:fs";
31
+ import { join } from "node:path";
32
+ import { ENCODER_LATENCY_P95_MS, ENCODER_MAX_TOKENS } from "./types.js";
33
+ import { installBudgetMib } from "./decision.js";
34
+ import { detectPlatform } from "./asset.js";
35
+ import { NATIVE_ORT_PACKAGE } from "./native-install-artifacts.js";
36
+ /** Candidate ONNX runtime native-ort prefixes. The ENC-2a guide installs to
37
+ * the global `~/.pi/mega-compact/native-ort/`; `stateDir` (per-repo) is a
38
+ * secondary probe root so the retest resolves either install location. */
39
+ function nativeOrtRootCandidates(stateDir) {
40
+ return [
41
+ join(process.env.HOME ?? "", ".pi", "mega-compact", "native-ort"),
42
+ join(stateDir, "native-ort"),
43
+ ];
44
+ }
45
+ /** A single bounded inference pass on the fixed 512-token synthetic input;
46
+ * returns latency ms, or null when the session cannot run (caller reports
47
+ * failed). The input mirrors bench-onnx.mjs: batch 1, 512 int64 ids. */
48
+ async function timedPass(ort, session, ids, mask, types) {
49
+ try {
50
+ const dims = [1, ENCODER_MAX_TOKENS];
51
+ const o = ort;
52
+ const s = session;
53
+ const feeds = {};
54
+ if (s.inputNames.includes("input_ids")) {
55
+ feeds.input_ids = new o.Tensor("int64", ids, dims);
56
+ }
57
+ if (s.inputNames.includes("attention_mask")) {
58
+ feeds.attention_mask = new o.Tensor("int64", mask, dims);
59
+ }
60
+ if (s.inputNames.includes("token_type_ids")) {
61
+ feeds.token_type_ids = new o.Tensor("int64", types, dims);
62
+ }
63
+ const t = process.hrtime.bigint();
64
+ await s.run(feeds);
65
+ return Number(process.hrtime.bigint() - t) / 1e6;
66
+ }
67
+ catch {
68
+ return null;
69
+ }
70
+ }
71
+ /** Resolve the first existing installed-binding package root, or the first
72
+ * candidate's path (for a missing-binding probe) when none exists. */
73
+ function bindingRootDir(stateDir) {
74
+ for (const root of nativeOrtRootCandidates(stateDir)) {
75
+ const pkg = join(root, "node_modules", NATIVE_ORT_PACKAGE);
76
+ if (existsSync(pkg))
77
+ return pkg;
78
+ }
79
+ return join(nativeOrtRootCandidates(stateDir)[0], "node_modules", NATIVE_ORT_PACKAGE);
80
+ }
81
+ /** Read the installed binding version from its package.json; null when absent. */
82
+ function readInstalledVersion(pkgJsonPath) {
83
+ try {
84
+ const raw = JSON.parse(readFileSync(pkgJsonPath, "utf8"));
85
+ if (typeof raw === "object" &&
86
+ raw !== null &&
87
+ typeof raw.version === "string") {
88
+ return raw.version;
89
+ }
90
+ return null;
91
+ }
92
+ catch {
93
+ return null;
94
+ }
95
+ }
96
+ /** Locate a LOCAL onnx model to probe against, under the native-ort roots.
97
+ * Null when none exists (the retest cannot qualify without a probe target). */
98
+ function findLocalModel(stateDir) {
99
+ const candidates = [
100
+ join(nativeOrtRootCandidates(stateDir)[0], "model.onnx"),
101
+ join(stateDir, "model.onnx"),
102
+ ];
103
+ for (const c of candidates) {
104
+ if (existsSync(c))
105
+ return c;
106
+ }
107
+ return null;
108
+ }
109
+ /** p95 of sorted latencies (sorted-index percentile, bench-onnx idiom). */
110
+ function p95Of(sorted) {
111
+ if (sorted.length === 0)
112
+ return 0;
113
+ const idx = Math.min(sorted.length - 1, Math.floor(sorted.length * 0.95));
114
+ return +sorted[idx].toFixed(2);
115
+ }
116
+ /**
117
+ * Run the native onnxruntime qualification retest. Returns `RetestResult` on a
118
+ * completed (pass/fail/degrade) probe, or `null` when no binding is installed.
119
+ * Never throws: binding-load / session / model failures produce a `failed`
120
+ * verdict with the message on the result, and the `testedAt`/RSS are filled.
121
+ */
122
+ export async function runNativeRetest(stateDir) {
123
+ const rootDir = bindingRootDir(stateDir);
124
+ const pkgJsonPath = join(rootDir, "package.json");
125
+ if (!existsSync(pkgJsonPath))
126
+ return null;
127
+ const version = readInstalledVersion(pkgJsonPath);
128
+ const platform = detectPlatform();
129
+ const platformStr = platform ?? `${process.platform}-${process.arch}`;
130
+ const testedAt = new Date().toISOString();
131
+ const rssMiB = +((process.memoryUsage().rss / 1048576).toFixed(1));
132
+ // Binding present but version unreadable — report failed (never throw).
133
+ if (version === null) {
134
+ return {
135
+ platform: platformStr,
136
+ version: "unknown",
137
+ verdict: "failed",
138
+ p95Ms: 0,
139
+ rssMiB,
140
+ testedAt,
141
+ };
142
+ }
143
+ // Load the LOCAL binding via dynamic import. Load failure -> failed verdict.
144
+ let ort;
145
+ try {
146
+ ort = await import(join(rootDir, "lib", "index.js"));
147
+ }
148
+ catch {
149
+ try {
150
+ ort = await import(join(rootDir, "dist", "ort.node.mjs"));
151
+ }
152
+ catch {
153
+ return {
154
+ platform: platformStr,
155
+ version,
156
+ verdict: "failed",
157
+ p95Ms: 0,
158
+ rssMiB,
159
+ testedAt,
160
+ };
161
+ }
162
+ }
163
+ // Find a local probe model; without one the binding cannot be qualified.
164
+ const modelPath = findLocalModel(stateDir);
165
+ if (modelPath === null) {
166
+ return {
167
+ platform: platformStr,
168
+ version,
169
+ verdict: "failed",
170
+ p95Ms: 0,
171
+ rssMiB,
172
+ testedAt,
173
+ };
174
+ }
175
+ // Create the session (bounded); failure -> failed.
176
+ try {
177
+ const factory = ort;
178
+ const session = await factory.InferenceSession.create(modelPath, {
179
+ executionProviders: ["cpu"],
180
+ intraOpNumThreads: 4,
181
+ graphOptimizationLevel: "all",
182
+ });
183
+ const n = ENCODER_MAX_TOKENS;
184
+ const ids = BigInt64Array.from({ length: n }, (_, i) => BigInt(i === 0 ? 101 : i === n - 1 ? 102 : 2000 + (i % 500)));
185
+ const mask = BigInt64Array.from({ length: n }, () => 1n);
186
+ const types = new BigInt64Array(n);
187
+ // Bounded warmup (3 passes) + 10 timed passes.
188
+ for (let i = 0; i < 3; i++)
189
+ await timedPass(ort, session, ids, mask, types);
190
+ const lat = [];
191
+ for (let i = 0; i < 10; i++) {
192
+ const ms = await timedPass(ort, session, ids, mask, types);
193
+ if (ms === null)
194
+ break;
195
+ lat.push(ms);
196
+ }
197
+ if (lat.length === 0) {
198
+ return {
199
+ platform: platformStr,
200
+ version,
201
+ verdict: "failed",
202
+ p95Ms: 0,
203
+ rssMiB,
204
+ testedAt,
205
+ };
206
+ }
207
+ lat.sort((a, b) => a - b);
208
+ const p95Ms = p95Of(lat);
209
+ const rssBudgetMib = installBudgetMib();
210
+ const verdict = p95Ms <= ENCODER_LATENCY_P95_MS && rssMiB <= rssBudgetMib
211
+ ? "qualified"
212
+ : "degraded";
213
+ return { platform: platformStr, version, verdict, p95Ms, rssMiB, testedAt };
214
+ }
215
+ catch {
216
+ return {
217
+ platform: platformStr,
218
+ version,
219
+ verdict: "failed",
220
+ p95Ms: 0,
221
+ rssMiB,
222
+ testedAt,
223
+ };
224
+ }
225
+ }