pi-mega-compact 0.20.63 → 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 (95) hide show
  1. package/README.md +1 -1
  2. package/dist/config/vector-cortex-enc2a.js +35 -0
  3. package/dist/config/vector-cortex-enc2b.js +36 -0
  4. package/dist/config/vector-cortex.js +4 -0
  5. package/dist/config.js +1 -1
  6. package/dist/extensions/dashboard-server/routes-rag-settings-vector-cortex.js +2 -0
  7. package/dist/extensions/dashboard-server/routes-setup-enc2a.js +119 -0
  8. package/dist/extensions/dashboard-server/routes-setup-enc2b.js +77 -0
  9. package/dist/extensions/dashboard-server/routes-setup.js +65 -3
  10. package/dist/src/config/vector-cortex-enc2a.js +35 -0
  11. package/dist/src/config/vector-cortex-enc2b.js +36 -0
  12. package/dist/src/config/vector-cortex.js +4 -0
  13. package/dist/src/config.js +1 -1
  14. package/dist/src/vector-cortex/encoder/native-install-artifacts.js +43 -0
  15. package/dist/src/vector-cortex/encoder/native-qualify-retest.js +225 -0
  16. package/dist/vector-cortex/encoder/native-install-artifacts.js +43 -0
  17. package/dist/vector-cortex/encoder/native-qualify-retest.js +225 -0
  18. package/extensions/dashboard-client/dist/assets/{AdminTab-DrJ9VWRu.js → AdminTab-B31efZ_R.js} +2 -2
  19. package/extensions/dashboard-client/dist/assets/{AdminTab-DrJ9VWRu.js.map → AdminTab-B31efZ_R.js.map} +1 -1
  20. package/extensions/dashboard-client/dist/assets/{AreaChart-B1OkLRGT.js → AreaChart-BpjHNUZm.js} +2 -2
  21. package/extensions/dashboard-client/dist/assets/{AreaChart-B1OkLRGT.js.map → AreaChart-BpjHNUZm.js.map} +1 -1
  22. package/extensions/dashboard-client/dist/assets/{BarChart-IWwm38i0.js → BarChart-CY2FndXC.js} +2 -2
  23. package/extensions/dashboard-client/dist/assets/{BarChart-IWwm38i0.js.map → BarChart-CY2FndXC.js.map} +1 -1
  24. package/extensions/dashboard-client/dist/assets/{CacheTab-DvNlBxzX.js → CacheTab-kMSrMD3e.js} +2 -2
  25. package/extensions/dashboard-client/dist/assets/{CacheTab-DvNlBxzX.js.map → CacheTab-kMSrMD3e.js.map} +1 -1
  26. package/extensions/dashboard-client/dist/assets/{ConfigTab-C1t0EM2H.js → ConfigTab-BrKpv2YG.js} +2 -2
  27. package/extensions/dashboard-client/dist/assets/{ConfigTab-C1t0EM2H.js.map → ConfigTab-BrKpv2YG.js.map} +1 -1
  28. package/extensions/dashboard-client/dist/assets/{EventsTab-CCexdJjG.js → EventsTab-DaClreCm.js} +2 -2
  29. package/extensions/dashboard-client/dist/assets/{EventsTab-CCexdJjG.js.map → EventsTab-DaClreCm.js.map} +1 -1
  30. package/extensions/dashboard-client/dist/assets/{HealthTab-BkAKwtxe.js → HealthTab-CxKQDqF3.js} +2 -2
  31. package/extensions/dashboard-client/dist/assets/{HealthTab-BkAKwtxe.js.map → HealthTab-CxKQDqF3.js.map} +1 -1
  32. package/extensions/dashboard-client/dist/assets/{MaintenanceTab-Beb59xuJ.js → MaintenanceTab-BKSlSjv0.js} +2 -2
  33. package/extensions/dashboard-client/dist/assets/{MaintenanceTab-Beb59xuJ.js.map → MaintenanceTab-BKSlSjv0.js.map} +1 -1
  34. package/extensions/dashboard-client/dist/assets/{MemoryMapTab-P04ao17z.js → MemoryMapTab-C2goWDt8.js} +2 -2
  35. package/extensions/dashboard-client/dist/assets/{MemoryMapTab-P04ao17z.js.map → MemoryMapTab-C2goWDt8.js.map} +1 -1
  36. package/extensions/dashboard-client/dist/assets/{MetricsCards-YlmnUe01.js → MetricsCards-DCPuCnrw.js} +2 -2
  37. package/extensions/dashboard-client/dist/assets/{MetricsCards-YlmnUe01.js.map → MetricsCards-DCPuCnrw.js.map} +1 -1
  38. package/extensions/dashboard-client/dist/assets/MetricsTab-Bz0Mdyb_.js +2 -0
  39. package/extensions/dashboard-client/dist/assets/{MetricsTab-C2rXqvoD.js.map → MetricsTab-Bz0Mdyb_.js.map} +1 -1
  40. package/extensions/dashboard-client/dist/assets/{OverviewTab-BBNvmR3X.js → OverviewTab-B-eZ-eDR.js} +2 -2
  41. package/extensions/dashboard-client/dist/assets/{OverviewTab-BBNvmR3X.js.map → OverviewTab-B-eZ-eDR.js.map} +1 -1
  42. package/extensions/dashboard-client/dist/assets/{ReposTab-CjlumghA.js → ReposTab-W_NKRWpk.js} +2 -2
  43. package/extensions/dashboard-client/dist/assets/{ReposTab-CjlumghA.js.map → ReposTab-W_NKRWpk.js.map} +1 -1
  44. package/extensions/dashboard-client/dist/assets/{SessionsTab-D1tWcUn-.js → SessionsTab-GYrtNt4_.js} +2 -2
  45. package/extensions/dashboard-client/dist/assets/{SessionsTab-D1tWcUn-.js.map → SessionsTab-GYrtNt4_.js.map} +1 -1
  46. package/extensions/dashboard-client/dist/assets/SetupTab-_1xa6eTJ.js +3 -0
  47. package/extensions/dashboard-client/dist/assets/SetupTab-_1xa6eTJ.js.map +1 -0
  48. package/extensions/dashboard-client/dist/assets/{TimeSavedCard-DzBeE2y4.js → TimeSavedCard-Ciu8anVG.js} +2 -2
  49. package/extensions/dashboard-client/dist/assets/{TimeSavedCard-DzBeE2y4.js.map → TimeSavedCard-Ciu8anVG.js.map} +1 -1
  50. package/extensions/dashboard-client/dist/assets/{TurnMemoryView-DKVIkjot.js → TurnMemoryView-BhXLIjWr.js} +2 -2
  51. package/extensions/dashboard-client/dist/assets/{TurnMemoryView-DKVIkjot.js.map → TurnMemoryView-BhXLIjWr.js.map} +1 -1
  52. package/extensions/dashboard-client/dist/assets/TurnsTab-C-f3DggL.js +2 -0
  53. package/extensions/dashboard-client/dist/assets/{TurnsTab-Cqyq6fVe.js.map → TurnsTab-C-f3DggL.js.map} +1 -1
  54. package/extensions/dashboard-client/dist/assets/{VcStatusBadge-CBtRo20h.js → VcStatusBadge-D97V04WE.js} +2 -2
  55. package/extensions/dashboard-client/dist/assets/{VcStatusBadge-CBtRo20h.js.map → VcStatusBadge-D97V04WE.js.map} +1 -1
  56. package/extensions/dashboard-client/dist/assets/{VectorCortexTab-Bk53uJZZ.js → VectorCortexTab-cyDJPAPB.js} +2 -2
  57. package/extensions/dashboard-client/dist/assets/{VectorCortexTab-Bk53uJZZ.js.map → VectorCortexTab-cyDJPAPB.js.map} +1 -1
  58. package/extensions/dashboard-client/dist/assets/{WikiTab-CemxY6Lm.js → WikiTab-dQ96DyjP.js} +2 -2
  59. package/extensions/dashboard-client/dist/assets/{WikiTab-CemxY6Lm.js.map → WikiTab-dQ96DyjP.js.map} +1 -1
  60. package/extensions/dashboard-client/dist/assets/{button-BJiUJyhV.js → button-B1beLEiV.js} +2 -2
  61. package/extensions/dashboard-client/dist/assets/{button-BJiUJyhV.js.map → button-B1beLEiV.js.map} +1 -1
  62. package/extensions/dashboard-client/dist/assets/{card-Cg_LPWdl.js → card-CK9KH_ob.js} +2 -2
  63. package/extensions/dashboard-client/dist/assets/{card-Cg_LPWdl.js.map → card-CK9KH_ob.js.map} +1 -1
  64. package/extensions/dashboard-client/dist/assets/{client-extra-DxQFx7HY.js → client-extra-gN7xjggX.js} +2 -2
  65. package/extensions/dashboard-client/dist/assets/{client-extra-DxQFx7HY.js.map → client-extra-gN7xjggX.js.map} +1 -1
  66. package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-sE5oI3Ee.js → generateCategoricalChart-MB2_0u55.js} +2 -2
  67. package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-sE5oI3Ee.js.map → generateCategoricalChart-MB2_0u55.js.map} +1 -1
  68. package/extensions/dashboard-client/dist/assets/{index-CeBW9Vtt.js → index-CKVd_Ym_.js} +3 -3
  69. package/extensions/dashboard-client/dist/assets/{index-CeBW9Vtt.js.map → index-CKVd_Ym_.js.map} +1 -1
  70. package/extensions/dashboard-client/dist/assets/{switch-CmkMKtTG.js → switch-CswmYrO_.js} +2 -2
  71. package/extensions/dashboard-client/dist/assets/{switch-CmkMKtTG.js.map → switch-CswmYrO_.js.map} +1 -1
  72. package/extensions/dashboard-client/dist/assets/{toggle-CqpZacm5.js → toggle-CMepFsf0.js} +2 -2
  73. package/extensions/dashboard-client/dist/assets/{toggle-CqpZacm5.js.map → toggle-CMepFsf0.js.map} +1 -1
  74. package/extensions/dashboard-client/dist/assets/{useSSE-DCKHmvXr.js → useSSE-Bl55LQFZ.js} +2 -2
  75. package/extensions/dashboard-client/dist/assets/{useSSE-DCKHmvXr.js.map → useSSE-Bl55LQFZ.js.map} +1 -1
  76. package/extensions/dashboard-client/dist/index.html +1 -1
  77. package/extensions/dashboard-client/src/tabs/SetupTab/CortexRetestCard.tsx +104 -0
  78. package/extensions/dashboard-client/src/tabs/SetupTab/CortexRuntimeInstallCard.tsx +103 -0
  79. package/extensions/dashboard-client/src/tabs/SetupTab/CortexSetup.tsx +4 -0
  80. package/extensions/dashboard-server/api-contracts/setup.ts +54 -0
  81. package/extensions/dashboard-server/routes-rag-settings-vector-cortex.ts +12 -0
  82. package/extensions/dashboard-server/routes-setup-enc2a.ts +140 -0
  83. package/extensions/dashboard-server/routes-setup-enc2b.ts +82 -0
  84. package/extensions/dashboard-server/routes-setup.ts +65 -3
  85. package/package.json +1 -1
  86. package/src/config/vector-cortex-enc2a.ts +37 -0
  87. package/src/config/vector-cortex-enc2b.ts +38 -0
  88. package/src/config/vector-cortex.ts +4 -0
  89. package/src/config.ts +2 -0
  90. package/src/vector-cortex/encoder/native-install-artifacts.ts +60 -0
  91. package/src/vector-cortex/encoder/native-qualify-retest.ts +264 -0
  92. package/extensions/dashboard-client/dist/assets/MetricsTab-C2rXqvoD.js +0 -2
  93. package/extensions/dashboard-client/dist/assets/SetupTab-CgC4Rz38.js +0 -3
  94. package/extensions/dashboard-client/dist/assets/SetupTab-CgC4Rz38.js.map +0 -1
  95. package/extensions/dashboard-client/dist/assets/TurnsTab-Cqyq6fVe.js +0 -2
@@ -0,0 +1,103 @@
1
+ /**
2
+ * SetupTab/CortexRuntimeInstallCard.tsx — operator-run install guide card
3
+ * (ENC-2a).
4
+ *
5
+ * Pure render. When `SetupStatusResponse.nativeOrtInstallGuide` is non-null
6
+ * (opt-in on, effective runtime still wasm, platform installable), this card
7
+ * surfaces the three copy-paste steps the operator runs OUTSIDE the dashboard:
8
+ * install onnxruntime-node, restart via pi, and the expected next status. When
9
+ * the guide is null the card hides entirely (the modifiers card already
10
+ * surfaces the honest ENC-0g state).
11
+ *
12
+ * NO client-side execution — the install script is never spawned from here.
13
+ * Data comes exclusively from the existing /api/setup-status poll.
14
+ */
15
+ import type React from "react";
16
+ import { useState, useCallback, useEffect } from "react";
17
+ import type { SetupStatusResponse } from "@contracts";
18
+ import { fetchSetupStatus } from "../../api/client";
19
+ import { styles } from "./CortexSetupStyles";
20
+
21
+ function useCopyState(): [boolean, (text: string) => Promise<void>] {
22
+ const [copied, setCopied] = useState(false);
23
+ const copy = useCallback(async (text: string) => {
24
+ try {
25
+ await navigator.clipboard.writeText(text);
26
+ setCopied(true);
27
+ window.setTimeout(() => setCopied(false), 1500);
28
+ } catch {
29
+ setCopied(false);
30
+ }
31
+ }, []);
32
+ return [copied, copy];
33
+ }
34
+
35
+ export default function CortexRuntimeInstallCard(): React.ReactElement {
36
+ const [status, setStatus] = useState<SetupStatusResponse | null>(null);
37
+ const [copied, copy] = useCopyState();
38
+
39
+ const loadStatus = useCallback(() => {
40
+ fetchSetupStatus()
41
+ .then(setStatus)
42
+ .catch(() => {
43
+ /* best-effort poll; hide card when unavailable */
44
+ });
45
+ }, []);
46
+
47
+ useEffect(() => {
48
+ loadStatus();
49
+ const id = setInterval(loadStatus, 5000);
50
+ return () => clearInterval(id);
51
+ }, [loadStatus]);
52
+
53
+ const guide = status?.nativeOrtInstallGuide ?? null;
54
+ const installedVersion = status?.nativeOrtInstalledVersion ?? null;
55
+ if (!guide) return <></>;
56
+
57
+ return (
58
+ <div style={styles.section}>
59
+ <h3 style={styles.sectionTitle}>Encoder Runtime Install</h3>
60
+ <p style={{ ...styles.label, fontSize: "0.85rem", marginBottom: "0.75rem" }}>
61
+ Platform: {guide.platform}
62
+ </p>
63
+ {installedVersion !== null && (
64
+ <div style={styles.row}>
65
+ <span style={styles.label}>Detected:</span>
66
+ <span style={styles.value}>{installedVersion}</span>
67
+ </div>
68
+ )}
69
+ {guide.commands.map((command, i) => (
70
+ <div key={`${i}-${command}`} style={styles.row}>
71
+ <span style={styles.label}>Step {i + 1}:</span>
72
+ <code
73
+ style={{
74
+ ...styles.mono,
75
+ display: "inline-block",
76
+ marginTop: "0.15rem",
77
+ }}
78
+ >
79
+ {command}
80
+ </code>
81
+ <button
82
+ type="button"
83
+ onClick={() => {
84
+ void copy(command);
85
+ }}
86
+ style={{ marginLeft: "0.5rem", fontSize: "0.8rem" }}
87
+ >
88
+ Copy
89
+ </button>
90
+ </div>
91
+ ))}
92
+ <p style={{ ...styles.row, fontSize: "0.85rem" }}>
93
+ <span style={styles.label}>Script:</span>{" "}
94
+ <code style={styles.mono}>{guide.scriptPath}</code>
95
+ </p>
96
+ {copied && (
97
+ <p style={{ color: "#4caf50", fontSize: "0.8rem", margin: "0.25rem 0 0" }}>
98
+ Copied to clipboard
99
+ </p>
100
+ )}
101
+ </div>
102
+ );
103
+ }
@@ -15,6 +15,8 @@ import { CortexEncoderCard } from "./CortexEncoderCard";
15
15
  import { CortexBlockersCard } from "./CortexBlockersCard";
16
16
  import { CortexActionsCard } from "./CortexActionsCard";
17
17
  import CortexRuntimeCard from "./CortexRuntimeCard";
18
+ import CortexRuntimeInstallCard from "./CortexRuntimeInstallCard";
19
+ import CortexRetestCard from "./CortexRetestCard";
18
20
  import { VectorCortexCosineFpCard } from "./VectorCortexCosineFpCard";
19
21
  import { VectorCortexRepoCorpusCard } from "./VectorCortexRepoCorpusCard";
20
22
  import { styles } from "./CortexSetupStyles";
@@ -43,6 +45,8 @@ export default function CortexSetup(): React.ReactElement {
43
45
 
44
46
  <CortexEncoderCard data={state.data} error={state.error} />
45
47
  <CortexRuntimeCard />
48
+ <CortexRuntimeInstallCard />
49
+ <CortexRetestCard />
46
50
  <VectorCortexCosineFpCard />
47
51
  <VectorCortexRepoCorpusCard />
48
52
  <CortexBlockersCard
@@ -64,6 +64,49 @@ export interface SetupStatusResponse {
64
64
  * operand — persists even when `nativeOrtBudgetMib` is absent because the
65
65
  * runtime applies the default when unset. Additive, flag-gated. */
66
66
  readonly nativeOrtBudgetEffectiveMib?: string;
67
+ /** ENC-2a: the native onnxruntime install-guide, present (as an object) when
68
+ * the operator opted into the native backend AND the effective runtime is
69
+ * still wasm (onnxruntime-node absent) AND the host platform is installable.
70
+ * `null` when opt-in is off or the platform is unsupported/demoted (the guide
71
+ * never renders). Built ONLY from the artifacts module constants — no inline
72
+ * URLs or hashes in the route. Additive, flag-gated; absent = no guide. */
73
+ readonly nativeOrtInstallGuide?: {
74
+ /** The host's EncoderPlatform this guide is matched to. */
75
+ readonly platform: string;
76
+ /** The [install, restart, verify] copy-paste commands. */
77
+ readonly commands: readonly string[];
78
+ /** The committed operator script path (repo-rel). */
79
+ readonly scriptPath: string;
80
+ } | null;
81
+ /** ENC-2a: the installed native onnxruntime version read from
82
+ * `~/.pi/mega-compact/native-ort/` when the probe marker/package is present
83
+ * and platform-matched. Absent (NOT null) when not installed, so the client
84
+ * hides the detected-version row. Additive, flag-gated, reader-only. */
85
+ readonly nativeOrtInstalledVersion?: string | null;
86
+ /** ENC-2b: the native onnxruntime qualification retest result, present (as an
87
+ * object) when the flag is on AND a native binding is installed AND the
88
+ * retest ran. `null` when the retest is flag-disabled; ABSENT when no binding
89
+ * is installed (the client hides the retest card). Additive, flag-gated,
90
+ * reader-only — computed per GET, never persisted. */
91
+ readonly nativeOrtRetestResult?: RetestResult | null;
92
+ /** ENC-2b: the effective backend AFTER the retest. `"native"` when the retest
93
+ * verdict is `qualified`; `"wasm"` on a `degraded`/`failed` verdict or flag
94
+ * off (the runtime never silently switches on a failed retest). Additive,
95
+ * flag-gated, absent when no binding installed or flag off. */
96
+ readonly nativeOrtBackendEffective?: "native" | "wasm";
97
+ }
98
+
99
+ /** ENC-2b: the native onnxruntime qualification retest result, mirroring
100
+ * `src/vector-cortex/encoder/native-qualify-retest.ts`. Surfaces only the
101
+ * platform, version string, verdict, latency, and RSS — NEVER the binding
102
+ * binary contents or model weights (SECURITY_PRIVACY). */
103
+ export interface RetestResult {
104
+ readonly platform: string;
105
+ readonly version: string;
106
+ readonly verdict: "qualified" | "degraded" | "failed";
107
+ readonly p95Ms: number;
108
+ readonly rssMiB: number;
109
+ readonly testedAt: string;
67
110
  }
68
111
 
69
112
  /**
@@ -132,6 +175,17 @@ export interface SetupConfigureRequest {
132
175
  * positive integer string within `ENC_2BUDGET_MAX_MIB` (validated; additive,
133
176
  * flag-gated). */
134
177
  readonly nativeOrtBudgetMib?: string;
178
+ /** ENC-2a: an optional { boolean } guide-request key. `true` → 200 + the
179
+ * guide echoed (this sprint conveys the GUIDE only — no server-side
180
+ * execution); `false` → 400 `guide_rejected_false_nothing_to_do`.
181
+ * Flag-gated, additive — ignored (no-op) when the flag is off. */
182
+ readonly nativeOrtInstallGuide?: boolean;
183
+ /** ENC-2b: an optional { boolean } retest-request key. `true` → runs the
184
+ * native onnxruntime qualification retest synchronously (bounded, ~2s, the
185
+ * binding is on disk from the ENC-2a install — never a fetch) and returns
186
+ * the fresh result; `false` → 400 `retest_rejected_false_nothing_to_do`.
187
+ * Flag-gated, additive — ignored (no-op) when the flag is off. */
188
+ readonly nativeOrtRetest?: boolean;
135
189
  }
136
190
 
137
191
  /** Response for POST /api/setup-configure. */
@@ -314,6 +314,18 @@ export const VECTOR_CORTEX_SETTINGS: SettingGroup = {
314
314
  "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).",
315
315
  true,
316
316
  ),
317
+ boolDirect(
318
+ "MEGACOMPACT_ENC_2A",
319
+ "ENC-2a native onnxruntime install GUIDE (detect + copy-paste)",
320
+ "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).",
321
+ true,
322
+ ),
323
+ boolDirect(
324
+ "MEGACOMPACT_ENC_2B",
325
+ "ENC-2b native ONNX runtime qualification retest (detect + re-qualify)",
326
+ "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).",
327
+ true,
328
+ ),
317
329
  boolDirect(
318
330
  "MEGACOMPACT_COSINE_FP_BENCH",
319
331
  "COS-FP-A Synthetic FP Bench",
@@ -0,0 +1,140 @@
1
+ /**
2
+ * dashboard-server/routes-setup-enc2a.ts — ENC-2a native onnxruntime install
3
+ * GUIDE (reader-only) + installed-version probe.
4
+ *
5
+ * Extracted out of routes-setup.ts (which hovers at the 300-line source soft
6
+ * cap, mirroring the ENC-1a/ENC-1b/ENC-2budget sibling extracts) so the
7
+ * ENC-2a additive GET fields — the platform-matched native install guide and
8
+ * the installed-version probe — live in a sibling impl file and routes-setup.ts
9
+ * stays a thin host.
10
+ *
11
+ * The guide's job is OPERATOR run-script assist: when the operator opted into
12
+ * the native backend (`MEGACOMPACT_ENCODER_NATIVE=1`) but the effective runtime
13
+ * is still `"wasm"` (onnxruntime-node not yet installed) AND the host platform
14
+ * is installable, the GET status response carries a `nativeOrtInstallGuide`
15
+ * object with the [install, restart, verify] copy-paste commands + the committed
16
+ * operator script path. The commands/URL/hash are built ONLY from the artifacts
17
+ * module constants (`src/vector-cortex/encoder/native-install-artifacts.ts`) —
18
+ * never an inline registry URL or literal hash (PREVENT-PI-004). The installed-
19
+ * version probe reads the local `~/.pi/mega-compact/native-ort/` package.json
20
+ * when present (reader-only filesystem read, zero network).
21
+ *
22
+ * The flag is off (or opt-in off / unsupported platform / non-wasm backend) ->
23
+ * guide `null` and installedVersion `null` -> the host omits both fields,
24
+ * byte-identical to the ENC-1b-era shape.
25
+ *
26
+ * Guardrails: PREVENT-PI-004 (local filesystem reads + in-memory backend
27
+ * selection only, zero network), PREVENT-001 (null-safe JSON), PREVENT-011
28
+ * (no `any`).
29
+ */
30
+
31
+ import { readFileSync, existsSync } from "node:fs";
32
+ import { join } from "node:path";
33
+ import { ENC_2A_ENABLED } from "../../src/config/vector-cortex.js";
34
+ import { readEnc1bEnv } from "./routes-setup-enc1b.js";
35
+ import { selectRuntimeBackend } from "../../src/vector-cortex/encoder/runtime-select.js";
36
+ import { detectPlatform } from "../../src/vector-cortex/encoder/asset.js";
37
+ import {
38
+ NATIVE_ORT_VERSION,
39
+ NATIVE_ORT_PACKAGE,
40
+ NATIVE_ORT_INSTALLABLE_PLATFORMS,
41
+ } from "../../src/vector-cortex/encoder/native-install-artifacts.js";
42
+ import type { SetupConfigureRequest } from "./api-contracts/setup.js";
43
+
44
+ /** The committed operator script that performs the install (repo-relative). */
45
+ const ENC_2A_SCRIPT_PATH = "scripts/encoder/install-native-ort.mjs";
46
+
47
+ /** Where the operator script installs the native binding (absolute install
48
+ * prefix used verbatim in the guide commands + the version probe). */
49
+ function nativeOrtDir(): string {
50
+ return join(process.env.HOME ?? "", ".pi", "mega-compact", "native-ort");
51
+ }
52
+
53
+ /**
54
+ * True when the payload carries the ENC-2a guide-request key `false`/`true`
55
+ * (flag-gated, additive). `false` -> 400 (operator-driven no-op); `true` -> 200
56
+ * + the guide echoed (still no server execution — the execute path is ENC-2c).
57
+ * Flag-off -> null so the key falls through unrecognized (byte-identical
58
+ * ENC-1b-era predecessor).
59
+ */
60
+ export function enc2aGuideRequest(
61
+ body: SetupConfigureRequest,
62
+ ): { status: 400 } | { status: 200 } | null {
63
+ if (!ENC_2A_ENABLED()) return null;
64
+ if (body.nativeOrtInstallGuide === true) return { status: 200 };
65
+ if (body.nativeOrtInstallGuide === false) return { status: 400 };
66
+ return null;
67
+ }
68
+
69
+ /**
70
+ * Read the ENC-2a native install GUIDE + installed-version, additive GET fields.
71
+ *
72
+ * The guide renders only when EVERY gate passes: flag on, operator opted into
73
+ * native, effective backend is still `"wasm"` (onnxruntime-node absent), and the
74
+ * host platform is installable (darwin-x64 is excluded — no native binding
75
+ * upstream, the ENC-0e demotion sentinel). The effective backend + demotion
76
+ * reason go through the EXISTING `selectRuntimeBackend` (reader-only — never a
77
+ * reimplemented literal). `installedVersion` probes
78
+ * `~/.pi/mega-compact/native-ort/node_modules/onnxruntime-node/package.json`
79
+ * when present; null otherwise. Returns `{ guide: null, installedVersion: null }`
80
+ * when the flag is off (byte-identical predecessor).
81
+ */
82
+ export function readEnc2aGuide(stateDir: string): {
83
+ guide: { platform: string; commands: readonly string[]; scriptPath: string } | null;
84
+ installedVersion: string | null;
85
+ } {
86
+ if (!ENC_2A_ENABLED()) return { guide: null, installedVersion: null };
87
+ const env = readEnc1bEnv(stateDir);
88
+ const platform = detectPlatform();
89
+ const chosen = selectRuntimeBackend({
90
+ platform: platform ?? "unsupported",
91
+ benchRecord: null,
92
+ nativeOptIn: env.nativeOptIn,
93
+ });
94
+ const backend = chosen.backend === "native" ? "native" : "wasm";
95
+
96
+ let guide: { platform: string; commands: readonly string[]; scriptPath: string } | null = null;
97
+ if (
98
+ env.nativeOptIn &&
99
+ backend === "wasm" &&
100
+ platform !== null &&
101
+ (NATIVE_ORT_INSTALLABLE_PLATFORMS as readonly string[]).includes(platform)
102
+ ) {
103
+ guide = {
104
+ platform,
105
+ commands: [
106
+ `npm install --prefix ${nativeOrtDir()} ${NATIVE_ORT_PACKAGE}@${NATIVE_ORT_VERSION}`,
107
+ "pi update --extensions && pi session-start",
108
+ "expect encoderBackend: native on next status poll",
109
+ ],
110
+ scriptPath: ENC_2A_SCRIPT_PATH,
111
+ };
112
+ }
113
+
114
+ return { guide, installedVersion: probeInstalledVersion() };
115
+ }
116
+
117
+ /** Probe the local native-ort package.json for the installed onnxruntime-node
118
+ * version. Null when the package is absent/unreadable (reader-only, local). */
119
+ function probeInstalledVersion(): string | null {
120
+ try {
121
+ const pkgPath = join(
122
+ nativeOrtDir(),
123
+ "node_modules",
124
+ NATIVE_ORT_PACKAGE,
125
+ "package.json",
126
+ );
127
+ if (!existsSync(pkgPath)) return null;
128
+ const raw = JSON.parse(readFileSync(pkgPath, "utf8")) as unknown;
129
+ if (
130
+ typeof raw === "object" &&
131
+ raw !== null &&
132
+ typeof (raw as { version?: unknown }).version === "string"
133
+ ) {
134
+ return (raw as { version: string }).version;
135
+ }
136
+ return null;
137
+ } catch {
138
+ return null;
139
+ }
140
+ }
@@ -0,0 +1,82 @@
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
+
30
+ import { ENC_2B_ENABLED } from "../../src/config/vector-cortex.js";
31
+ import {
32
+ runNativeRetest,
33
+ type RetestResult,
34
+ } from "../../src/vector-cortex/encoder/native-qualify-retest.js";
35
+ import type { SetupConfigureRequest } from "./api-contracts/setup.js";
36
+
37
+ /**
38
+ * Resolve the ENC-2b additive GET fields. Returns BOTH fields when the flag is
39
+ * on AND a native binding is installed (the retest ran); returns `{}` on
40
+ * flag-off AND when no binding is installed — both fields are OMITTED (absent,
41
+ * not null), so the GET stays byte-identical to the ENC-2a-era shape and the
42
+ * client hides the retest card. Flag-off omits, never nulls: the ENC-2a-era
43
+ * host spreads `...{}` so no new key appears. Mirror of the ENC-2a/ENC-1b
44
+ * sibling idiom; async because the retest loads the binding in-process.
45
+ */
46
+ export async function readEnc2bRetest(stateDir: string): Promise<{
47
+ nativeOrtRetestResult?: RetestResult;
48
+ nativeOrtBackendEffective?: "native" | "wasm";
49
+ }> {
50
+ if (!ENC_2B_ENABLED()) return {};
51
+ const result = await runNativeRetest(stateDir);
52
+ if (result === null) return {};
53
+ return {
54
+ nativeOrtRetestResult: result,
55
+ nativeOrtBackendEffective: result.verdict === "qualified" ? "native" : "wasm",
56
+ };
57
+ }
58
+
59
+ /**
60
+ * ENC-2b POST retest-action key handling (flag-gated, additive).
61
+ *
62
+ * `true` → { action: "run" } (the host runs the retest and returns the result)
63
+ * `false` → { action: "reject" } (400 `retest_rejected_false_nothing_to_do`)
64
+ * other → null (key absent or flag off — falls through unrecognized,
65
+ * byte-identical ENC-2a-era predecessor).
66
+ */
67
+ export function enc2bRetestRequest(body: SetupConfigureRequest): "run" | "reject" | null {
68
+ if (!ENC_2B_ENABLED()) return null;
69
+ if (body.nativeOrtRetest === true) return "run";
70
+ if (body.nativeOrtRetest === false) return "reject";
71
+ return null;
72
+ }
73
+
74
+ /**
75
+ * Run the ENC-2b retest now (bounded, synchronous on the request) and return
76
+ * the fresh result. Flag-off or no binding → null. Used by the POST "run"
77
+ * branch; the result is returned on the response body, never persisted.
78
+ */
79
+ export async function runEnc2bRetest(stateDir: string): Promise<RetestResult | null> {
80
+ if (!ENC_2B_ENABLED()) return null;
81
+ return runNativeRetest(stateDir);
82
+ }
@@ -21,6 +21,8 @@ import {
21
21
  tryEnc2BudgetInto,
22
22
  enc2BudgetValidateCombined,
23
23
  } from "./routes-setup-enc2budget.js";
24
+ import { readEnc2aGuide, enc2aGuideRequest } from "./routes-setup-enc2a.js";
25
+ import { readEnc2bRetest, enc2bRetestRequest, runEnc2bRetest } from "./routes-setup-enc2b.js";
24
26
  import { writeEmbedderEnv } from "./routes-setup-env-upsert.js";
25
27
  import {
26
28
  detectOllama,
@@ -85,10 +87,15 @@ export function handleSetupStatus(
85
87
  }
86
88
  const configured = detectConfiguredEmbedder(ctx.stateDir);
87
89
  const active = detectCurrentEmbedder();
90
+ // ENC-2a (flag-gated, additive): the native install-guide + installed-version
91
+ // fields. Optional fields are added only when present/installable; when the
92
+ // flag is off readEnc2aGuide returns nulls so the body stays byte-identical
93
+ // to the ENC-1b-era shape.
94
+ const enc2a = readEnc2aGuide(ctx.stateDir);
88
95
  // ENC-1a (flag-gated, additive): echo the persisted endpoint URL and an
89
96
  // embeddingApiKeySet boolean ONLY — the raw API key is never returned. When
90
97
  // the flag is off (or neither is set) both fields are simply omitted.
91
- const body: SetupStatusResponse = {
98
+ const base: SetupStatusResponse = {
92
99
  currentEmbedder: active,
93
100
  configuredEmbedder: configured.embedder,
94
101
  configuredUrl: configured.url,
@@ -100,10 +107,23 @@ export function handleSetupStatus(
100
107
  ),
101
108
  ...enc1aStatusFields(ctx.stateDir), ...enc1bStatusFields(ctx.stateDir),
102
109
  ...enc2BudgetStatusFields(ctx.stateDir),
110
+ ...(enc2a.guide !== null ? { nativeOrtInstallGuide: enc2a.guide } : {}),
111
+ ...(enc2a.installedVersion !== null ? { nativeOrtInstalledVersion: enc2a.installedVersion } : {}),
103
112
  };
113
+ // ENC-2b (flag-gated, additive): the native qualification retest fields. The
114
+ // retest loads the on-disk binding in-process (bounded, never a fetch), so
115
+ // readEnc2bRetest is async; the handler returns true synchronously for the
116
+ // dispatch and writes the response after the await. Flag-off/none mutates
117
+ // the body additively and stays byte-identical to the ENC-2a-era shape.
104
118
  // guardrails-allow PREVENT-PI-004: loopback dashboard response (local)
105
- res.writeHead(200, { "Content-Type": "application/json" });
106
- res.end(JSON.stringify(body));
119
+ readEnc2bRetest(ctx.stateDir).then((enc2b) => {
120
+ const body: SetupStatusResponse = { ...base, ...enc2b };
121
+ res.writeHead(200, { "Content-Type": "application/json" });
122
+ res.end(JSON.stringify(body));
123
+ }).catch(() => {
124
+ res.writeHead(200, { "Content-Type": "application/json" });
125
+ res.end(JSON.stringify(base));
126
+ });
107
127
  return true;
108
128
  }
109
129
 
@@ -218,10 +238,52 @@ export function handleSetupConfigure(
218
238
  return;
219
239
  }
220
240
  const body = parsed.value as unknown as SetupConfigureRequest;
241
+ // ENC-2a guide-request key (flag-gated, additive): `false` → 400 (an
242
+ // operator-driven no-op — this sprint conveys the GUIDE only, no server
243
+ // execution), `true` → 200 + the guide echoed (still no execution; the
244
+ // execute path is ENC-2c). Flag-off: enc2aGuideRequest returns null so the
245
+ // key falls through unrecognized (byte-identical ENC-1b-era predecessor).
246
+ const guideReq = enc2aGuideRequest(body);
247
+ // guardrails-allow PREVENT-PI-004: loopback dashboard response (local)
248
+ if (guideReq !== null && guideReq.status === 400) {
249
+ res.writeHead(400, { "Content-Type": "application/json" });
250
+ res.end(JSON.stringify({ error: "guide_rejected_false_nothing_to_do" }));
251
+ return;
252
+ }
221
253
  // ENC-1a (flag-gated, additive): a pure external-embedder configure
222
254
  // (new keys, no embedder selection) is handled by the sibling writer.
223
255
  // Flag-off = the keys are simply not recognized, falling through to the
224
256
  // pre-ENC-1a embedder path below (byte-identical predecessor).
257
+ if (guideReq !== null && guideReq.status === 200) {
258
+ // guardrails-allow PREVENT-PI-004: loopback dashboard response (local)
259
+ res.writeHead(200, { "Content-Type": "application/json" });
260
+ res.end(JSON.stringify({ nativeOrtInstallGuide: readEnc2aGuide(ctx.stateDir).guide }));
261
+ return;
262
+ }
263
+ // ENC-2b retest-action key (flag-gated, additive): `false` → 400 (an
264
+ // operator-driven no-op — nothing to retest), `true` → run the bounded
265
+ // retest synchronously and return the fresh result. Flag-off: the key
266
+ // falls through unrecognized (byte-identical ENC-2a-era predecessor).
267
+ // The retest never fetches — the binding is on disk from the ENC-2a
268
+ // install (PREVENT-PI-004 clean).
269
+ const retestReq = enc2bRetestRequest(body);
270
+ // guardrails-allow PREVENT-PI-004: loopback dashboard response (local)
271
+ if (retestReq === "reject") {
272
+ res.writeHead(400, { "Content-Type": "application/json" });
273
+ res.end(JSON.stringify({ error: "retest_rejected_false_nothing_to_do" }));
274
+ return;
275
+ }
276
+ if (retestReq === "run") {
277
+ // guardrails-allow PREVENT-PI-004: loopback dashboard response (local)
278
+ runEnc2bRetest(ctx.stateDir).then((fresh) => {
279
+ res.writeHead(200, { "Content-Type": "application/json" });
280
+ res.end(JSON.stringify({ nativeOrtRetestResult: fresh }));
281
+ }).catch(() => {
282
+ res.writeHead(500, { "Content-Type": "application/json" });
283
+ res.end(JSON.stringify({ error: "retest_failed" }));
284
+ });
285
+ return;
286
+ }
225
287
  if (tryEnc1aConfigure(body, res, ctx)) return;
226
288
  if (tryEnc1bConfigure(body, res, ctx)) return; // pure ENC-1b configure (dim/headers/allow-remote/native)
227
289
  // ENC-1b combined-payload validation: when a payload carries a valid
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pi-mega-compact",
3
- "version": "0.20.63",
3
+ "version": "0.20.65",
4
4
  "description": "Layered, local, vector-backed context compressor for pi — supersede/collapse/cluster compaction with deduped inline recall.",
5
5
  "type": "module",
6
6
  "license": "BSD-3-Clause",
@@ -0,0 +1,37 @@
1
+ /**
2
+ * config/vector-cortex-enc2a.ts — ENC-2a native onnxruntime install-guide flag
3
+ * (operator run-script assist).
4
+ *
5
+ * Sibling of vector-cortex-enc1a.ts / vector-cortex-enc1b.ts /
6
+ * vector-cortex-enc2budget.ts so vector-cortex.ts stays under the 300-line soft
7
+ * limit (soft-as-hard gate). vector-cortex.ts re-exports the flag below and
8
+ * root src/config.ts re-exports it, so no consumer import path changes.
9
+ *
10
+ * ENC-2a, when the operator opted into the native backend
11
+ * (`MEGACOMPACT_ENCODER_NATIVE=1`) but `encoderBackend` is still `"wasm"`
12
+ * (onnxruntime-node absent / not yet installed), surfaces an "Encoder Runtime
13
+ * Install" card on the Cortex sub-tab with copy-paste operator commands: the
14
+ * install + restart + verify steps built ONLY from the artifacts-module
15
+ * constants (`src/vector-cortex/encoder/native-install-artifacts.ts`) — never
16
+ * an inline registry URL or hash in the route (PREVENT-PI-004). The guide
17
+ * renders only on an installable host platform; the ENC-0e darwin-x64 demotion
18
+ * sentinel keeps it absent on an Intel Mac (no native binding upstream).
19
+ *
20
+ * `MEGACOMPACT_ENC_2A=0` disables: no guide fields, no install card, no absent
21
+ * read — byte-identical to the ENC-1b predecessor. The flag MUST also be a
22
+ * dashboard SETTINGS toggle (visible in config UI, never in EXCLUDED_SETTINGS
23
+ * — see `feedback_dashboard-flags-toggleable` memory).
24
+ *
25
+ * Pi-agnostic, dependency-free (PREVENT-PI-004 / PREVENT-011).
26
+ */
27
+
28
+ import { sprintFlag } from "./vector-cortex-flag.js";
29
+
30
+ /**
31
+ * ENC-2a — operator run-script assist (dashboard install guide for the
32
+ * onnxruntime-node native binding). Default ON. `MEGACOMPACT_ENC_2A=0` disables
33
+ * and is byte-identical to the ENC-1b predecessor: no guide/absent fields, no
34
+ * install card. This flag MUST also be a dashboard SETTINGS toggle (visible in
35
+ * config UI, never in EXCLUDED_SETTINGS).
36
+ */
37
+ export const ENC_2A_ENABLED = (): boolean => sprintFlag("MEGACOMPACT_ENC_2A");
@@ -0,0 +1,38 @@
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
+
29
+ import { sprintFlag } from "./vector-cortex-flag.js";
30
+
31
+ /**
32
+ * ENC-2b — native onnxruntime qualification retest (detect installed binding,
33
+ * re-probe p95/RSS, re-qualify). Default ON. `MEGACOMPACT_ENC_2B=0` disables and
34
+ * is byte-identical to the ENC-2a predecessor: no retest GET fields, no retest
35
+ * POST branch, no retest card. This flag MUST also be a dashboard SETTINGS
36
+ * toggle (visible in config UI, never in EXCLUDED_SETTINGS).
37
+ */
38
+ export const ENC_2B_ENABLED = (): boolean => sprintFlag("MEGACOMPACT_ENC_2B");
@@ -92,6 +92,10 @@ export {
92
92
  ENC_2BUDGET_MAX_MIB,
93
93
  ENC_2BUDGET_DEFAULT_MIB,
94
94
  } from "./vector-cortex-enc2budget.js";
95
+ // ENC-2a native onnxruntime install-guide flag extracted to vector-cortex-enc2a.ts.
96
+ export { ENC_2A_ENABLED } from "./vector-cortex-enc2a.js";
97
+ // ENC-2b native onnxruntime qualification-retest flag extracted to vector-cortex-enc2b.ts.
98
+ export { ENC_2B_ENABLED } from "./vector-cortex-enc2b.js";
95
99
  // Breaker constants (TRIAD_RESILIENCE.md §breaker) extracted to vector-cortex-breakers.ts.
96
100
  export {
97
101
  BREAKER_WINDOW_MS,
package/src/config.ts CHANGED
@@ -202,6 +202,8 @@ export {
202
202
  ENC_2BUDGET_NATIVE_ORT_BUDGET_ENV,
203
203
  ENC_2BUDGET_MAX_MIB,
204
204
  ENC_2BUDGET_DEFAULT_MIB,
205
+ ENC_2A_ENABLED,
206
+ ENC_2B_ENABLED,
205
207
  COSINE_FP_BENCH_ENABLED,
206
208
  COSINE_FP_REAL_ENABLED,
207
209
  REPO_CORPUS_ENABLED,