pi-mega-compact 0.20.69 → 0.20.71
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/config/vector-cortex-enc2c.js +38 -0
- package/dist/config/vector-cortex.js +2 -0
- package/dist/config.js +1 -1
- package/dist/extensions/dashboard-server/api-contracts/setup-cortex-native-ort.js +22 -0
- package/dist/extensions/dashboard-server/routes-rag-settings-vector-cortex.js +1 -0
- package/dist/extensions/dashboard-server/routes-setup-cortex-actions.js +17 -11
- package/dist/extensions/dashboard-server/routes-vector-cortex-crystals.js +45 -30
- package/dist/extensions/dashboard-server/routes-vector-cortex-diagnostics.js +50 -29
- package/dist/extensions/dashboard-server/routes-vector-cortex-economics.js +33 -20
- package/dist/extensions/dashboard-server/routes-vector-cortex-helpers.js +54 -0
- package/dist/extensions/dashboard-server/routes-vector-cortex-policy.js +33 -16
- package/dist/extensions/dashboard-server/setup-cortex-actions-native-ort.js +107 -0
- package/dist/extensions/dashboard-server/setup-cortex-actions.js +9 -2
- package/dist/src/config/vector-cortex-enc2c.js +38 -0
- package/dist/src/config/vector-cortex.js +2 -0
- package/dist/src/config.js +1 -1
- package/dist/src/vector-cortex/cache/store.js +25 -2
- package/dist/src/vector-cortex/encoder/asset.js +34 -2
- package/dist/src/vector-cortex/encoder/router.js +31 -3
- package/dist/src/vector-cortex/livewire/livewire-live.js +163 -0
- package/dist/src/vector-cortex/livewire/livewire-registry.js +73 -0
- package/dist/src/vector-cortex/livewire/livewire-runtime.js +107 -0
- package/dist/src/vector-cortex/livewire/livewire-snapshot.js +101 -0
- package/dist/src/vector-cortex/livewire/livewire-types.js +19 -0
- package/dist/src/vector-cortex/provider/registry.js +44 -12
- package/dist/src/vector-cortex/setup-cortex-blockers-compute.js +3 -0
- package/dist/vector-cortex/cache/store.js +25 -2
- package/dist/vector-cortex/encoder/asset.js +34 -2
- package/dist/vector-cortex/encoder/router.js +31 -3
- package/dist/vector-cortex/provider/registry.js +44 -12
- package/dist/vector-cortex/setup-cortex-blockers-compute.js +3 -0
- package/extensions/dashboard-client/dist/assets/{AdminTab-BUl1fyQ-.js → AdminTab-ZyVtgYrZ.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{AdminTab-BUl1fyQ-.js.map → AdminTab-ZyVtgYrZ.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{AreaChart-CumzbAON.js → AreaChart-7ms8Hk1m.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{AreaChart-CumzbAON.js.map → AreaChart-7ms8Hk1m.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{BarChart-MvUf2UYv.js → BarChart-DeTE0NXA.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{BarChart-MvUf2UYv.js.map → BarChart-DeTE0NXA.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{CacheTab-CqpJZ5Ok.js → CacheTab-CpIrpr_X.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{CacheTab-CqpJZ5Ok.js.map → CacheTab-CpIrpr_X.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{ConfigTab-Cr0pKYGK.js → ConfigTab-BNMrO7uz.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{ConfigTab-Cr0pKYGK.js.map → ConfigTab-BNMrO7uz.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{EventsTab-FTQ4nJae.js → EventsTab-j42vDTjs.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{EventsTab-FTQ4nJae.js.map → EventsTab-j42vDTjs.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{HealthTab-D7s5lCB0.js → HealthTab-D0Tf8XM_.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{HealthTab-D7s5lCB0.js.map → HealthTab-D0Tf8XM_.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MaintenanceTab-DW5c0ngt.js → MaintenanceTab-CleWX_RM.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MaintenanceTab-DW5c0ngt.js.map → MaintenanceTab-CleWX_RM.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MemoryMapTab-ocR07fD7.js → MemoryMapTab-LUpPJzNP.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MemoryMapTab-ocR07fD7.js.map → MemoryMapTab-LUpPJzNP.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MetricsCards-CNBlWLoU.js → MetricsCards-G4_uynTE.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MetricsCards-CNBlWLoU.js.map → MetricsCards-G4_uynTE.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/MetricsTab-yypKMQXf.js +2 -0
- package/extensions/dashboard-client/dist/assets/{MetricsTab-sks9wzZr.js.map → MetricsTab-yypKMQXf.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{OverviewTab-Duu9zseZ.js → OverviewTab-M47NMRaT.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{OverviewTab-Duu9zseZ.js.map → OverviewTab-M47NMRaT.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{ReposTab-CMd5NYjk.js → ReposTab-BX3ZxrAI.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{ReposTab-CMd5NYjk.js.map → ReposTab-BX3ZxrAI.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{SessionsTab-Ht-k4LKk.js → SessionsTab-CSUmsNeZ.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{SessionsTab-Ht-k4LKk.js.map → SessionsTab-CSUmsNeZ.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{SetupTab-BCfBdL-1.js → SetupTab-jF9BsQjw.js} +3 -3
- package/extensions/dashboard-client/dist/assets/SetupTab-jF9BsQjw.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/{TimeSavedCard-B3CAK2FZ.js → TimeSavedCard-qfwO1WJ3.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{TimeSavedCard-B3CAK2FZ.js.map → TimeSavedCard-qfwO1WJ3.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{TurnMemoryView-7SRtcvZF.js → TurnMemoryView-C7NQo_xi.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{TurnMemoryView-7SRtcvZF.js.map → TurnMemoryView-C7NQo_xi.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/TurnsTab-D-19giqQ.js +2 -0
- package/extensions/dashboard-client/dist/assets/{TurnsTab-Djd-nzlT.js.map → TurnsTab-D-19giqQ.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{VcStatusBadge-BzvdQnVq.js → VcStatusBadge-DTHlwuUJ.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{VcStatusBadge-BzvdQnVq.js.map → VcStatusBadge-DTHlwuUJ.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{VectorCortexTab-qmY0a0E-.js → VectorCortexTab-Dvgdcwvs.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{VectorCortexTab-qmY0a0E-.js.map → VectorCortexTab-Dvgdcwvs.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{WikiTab-DMmc36Xi.js → WikiTab-CYUEAQmZ.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{WikiTab-DMmc36Xi.js.map → WikiTab-CYUEAQmZ.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{button-DcRndiuf.js → button-DPOwTRN8.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{button-DcRndiuf.js.map → button-DPOwTRN8.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{card-CwWLYigw.js → card-CUipkgi9.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{card-CwWLYigw.js.map → card-CUipkgi9.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{client-extra-NQXJNKNj.js → client-extra-9lcKX-iO.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{client-extra-NQXJNKNj.js.map → client-extra-9lcKX-iO.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-BX9n_-am.js → generateCategoricalChart-_WpiJebf.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-BX9n_-am.js.map → generateCategoricalChart-_WpiJebf.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{index-DgKI8jwx.js → index-DlHJ7LBL.js} +3 -3
- package/extensions/dashboard-client/dist/assets/{index-DgKI8jwx.js.map → index-DlHJ7LBL.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{switch-C_xzN77s.js → switch-Cx6-1wnT.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{switch-C_xzN77s.js.map → switch-Cx6-1wnT.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{toggle-807R1-Th.js → toggle-Y3vbE0NG.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{toggle-807R1-Th.js.map → toggle-Y3vbE0NG.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{useSSE-BNG39O7p.js → useSSE-CnJdk56R.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{useSSE-BNG39O7p.js.map → useSSE-CnJdk56R.js.map} +1 -1
- package/extensions/dashboard-client/dist/index.html +1 -1
- package/extensions/dashboard-client/src/tabs/SetupTab/CortexActionsCard.tsx +89 -5
- package/extensions/dashboard-client/src/types/setup-cortex.ts +22 -1
- package/extensions/dashboard-server/api-contracts/setup-cortex-native-ort.ts +52 -0
- package/extensions/dashboard-server/api-contracts/setup-cortex.ts +8 -2
- package/extensions/dashboard-server/routes-rag-settings-vector-cortex.ts +6 -0
- package/extensions/dashboard-server/routes-setup-cortex-actions.ts +22 -11
- package/extensions/dashboard-server/routes-vector-cortex-crystals.ts +46 -30
- package/extensions/dashboard-server/routes-vector-cortex-diagnostics.ts +52 -29
- package/extensions/dashboard-server/routes-vector-cortex-economics.ts +35 -20
- package/extensions/dashboard-server/routes-vector-cortex-helpers.ts +84 -0
- package/extensions/dashboard-server/routes-vector-cortex-policy.ts +35 -16
- package/extensions/dashboard-server/setup-cortex-actions-native-ort.ts +121 -0
- package/extensions/dashboard-server/setup-cortex-actions.ts +9 -3
- package/package.json +1 -1
- package/src/config/vector-cortex-enc2c.ts +40 -0
- package/src/config/vector-cortex.ts +2 -0
- package/src/config.ts +1 -0
- package/src/vector-cortex/cache/store.ts +26 -2
- package/src/vector-cortex/encoder/asset.ts +46 -3
- package/src/vector-cortex/encoder/router.ts +56 -2
- package/src/vector-cortex/encoder/types.ts +3 -0
- package/src/vector-cortex/livewire/livewire-live.ts +223 -0
- package/src/vector-cortex/livewire/livewire-registry.ts +91 -0
- package/src/vector-cortex/livewire/livewire-runtime.ts +117 -0
- package/src/vector-cortex/livewire/livewire-snapshot.ts +108 -0
- package/src/vector-cortex/livewire/livewire-types.ts +84 -0
- package/src/vector-cortex/provider/economics.ts +9 -31
- package/src/vector-cortex/provider/registry.ts +82 -11
- package/src/vector-cortex/provider/types.ts +37 -0
- package/src/vector-cortex/setup-cortex-blockers-compute.ts +8 -1
- package/extensions/dashboard-client/dist/assets/MetricsTab-sks9wzZr.js +0 -2
- package/extensions/dashboard-client/dist/assets/SetupTab-BCfBdL-1.js.map +0 -1
- package/extensions/dashboard-client/dist/assets/TurnsTab-Djd-nzlT.js +0 -2
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dashboard-server/setup-cortex-actions-native-ort.ts — ENC-2c native onnxruntime
|
|
3
|
+
* lazy-download INSTALL action driver (actor surface for install-native-ort).
|
|
4
|
+
*
|
|
5
|
+
* Sibling of setup-cortex-actions.ts (which stays under the 300-line source soft
|
|
6
|
+
* cap). Implements the mechanics behind the VC9B `install-native-ort` action:
|
|
7
|
+
*
|
|
8
|
+
* 1. locate the committed scripts/encoder/install-native-ort.mjs by walking up
|
|
9
|
+
* to the repo root (mirroring setup-cortex-actions.ts vc2ScriptDir);
|
|
10
|
+
* 2. spawn `node <script>` locally with a 60s timeout (npm-delegated,
|
|
11
|
+
* sha256-verified install — the registry URL + sha256 live ONLY in
|
|
12
|
+
* src/vector-cortex/encoder/native-install-artifacts.ts, never here);
|
|
13
|
+
* 3. capture output to <stateDir>/logs/vc9b/install-native-ort-<ts>.log;
|
|
14
|
+
* 4. REGARDLESS of the install exit code, re-qualify the binding via the ENC-2b
|
|
15
|
+
* retest path (`runNativeRetest`) and surface the fresh result +
|
|
16
|
+
* effective backend.
|
|
17
|
+
*
|
|
18
|
+
* PREVENT-PI-004 banner: this is an OPT-IN, confirm-gated, npm-delegated local
|
|
19
|
+
* subprocess of a committed repo script. It performs no network I/O in this
|
|
20
|
+
* module and carries NO URL literals (the codebase-wide no-URL-literal scan
|
|
21
|
+
* covers src/ + extensions/).
|
|
22
|
+
*
|
|
23
|
+
* Guardrails: PREVENT-011 (no `any`); the subprocess is a committed local script,
|
|
24
|
+
* never fetched (PREVENT-PI-004, guardrails-allow below).
|
|
25
|
+
*/
|
|
26
|
+
import { spawnSync } from "node:child_process"; // guardrails-allow PREVENT-PI-004: opt-in, confirm-gated, npm-delegated install subprocess (local spawn of committed repo script; no URL literals)
|
|
27
|
+
import { mkdirSync, writeFileSync, existsSync } from "node:fs";
|
|
28
|
+
import { join, dirname } from "node:path";
|
|
29
|
+
import { fileURLToPath } from "node:url";
|
|
30
|
+
import { runNativeRetest } from "../../src/vector-cortex/encoder/native-qualify-retest.js";
|
|
31
|
+
/** Locate scripts/encoder/install-native-ort.mjs by walking up to the repo root. */
|
|
32
|
+
export function installScriptPath() {
|
|
33
|
+
let dir = dirname(fileURLToPath(import.meta.url));
|
|
34
|
+
const rel = join("scripts", "encoder", "install-native-ort.mjs");
|
|
35
|
+
for (let i = 0; i < 8; i++) {
|
|
36
|
+
const candidate = join(dir, rel);
|
|
37
|
+
// guardrails-allow PREVENT-PI-004: local repo filesystem read (loopback)
|
|
38
|
+
if (existsSync(candidate))
|
|
39
|
+
return candidate;
|
|
40
|
+
const next = dirname(dir);
|
|
41
|
+
if (next === dir)
|
|
42
|
+
break;
|
|
43
|
+
dir = next;
|
|
44
|
+
}
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
/** Ensure the vc9b log dir exists (mirrors setup-cortex-actions.ts). */
|
|
48
|
+
function ensureLogDir(stateDir) {
|
|
49
|
+
const dir = join(stateDir, "logs", "vc9b");
|
|
50
|
+
// guardrails-allow PREVENT-PI-004: local state-dir filesystem write (loopback)
|
|
51
|
+
mkdirSync(dir, { recursive: true });
|
|
52
|
+
return dir;
|
|
53
|
+
}
|
|
54
|
+
function writeLog(logPath, body) {
|
|
55
|
+
// guardrails-allow PREVENT-PI-004: local state-dir filesystem write (loopback)
|
|
56
|
+
writeFileSync(logPath, body, "utf8");
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Run the ENC-2c lazy-download native onnxruntime INSTALL action. Locates and
|
|
60
|
+
* spawns the committed install script (npm-delegated, sha256-verified), logs the
|
|
61
|
+
* captured output, then ALWAYS runs the ENC-2b retest to re-qualify the binding
|
|
62
|
+
* (regardless of install exit code) and surfaces the fresh result.
|
|
63
|
+
*
|
|
64
|
+
* Never throws: a missing script or non-zero exit is surfaced as ok=false on the
|
|
65
|
+
* result; the retest runs even on install failure so the operator sees the
|
|
66
|
+
* post-install qualification state. Returns a combined SetupCortexActionResult
|
|
67
|
+
* with the ENC-2c additive fields (present only for pendant actions).
|
|
68
|
+
*/
|
|
69
|
+
// guardrails-allow PREVENT-PI-004: opt-in, confirm-gated, npm-delegated install action (subprocess of committed repo script; no URL literals)
|
|
70
|
+
export async function runInstallNativeOrt(stateDir) {
|
|
71
|
+
const ts = Date.now();
|
|
72
|
+
const logName = `install-native-ort-${ts}.log`;
|
|
73
|
+
const logPath = join(ensureLogDir(stateDir), logName);
|
|
74
|
+
const scriptPath = installScriptPath();
|
|
75
|
+
if (scriptPath === null) {
|
|
76
|
+
writeLog(logPath, "install-native-ort.mjs not found in this checkout\n");
|
|
77
|
+
return {
|
|
78
|
+
action: "install-native-ort",
|
|
79
|
+
ok: false,
|
|
80
|
+
exitCode: null,
|
|
81
|
+
logPath,
|
|
82
|
+
logName,
|
|
83
|
+
spawned: true,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
// guardrails-allow PREVENT-PI-004: opt-in, confirm-gated, npm-delegated
|
|
87
|
+
// install subprocess (local spawn of committed repo script; no URL literals)
|
|
88
|
+
const result = spawnSync(process.execPath, [scriptPath], {
|
|
89
|
+
encoding: "utf8",
|
|
90
|
+
timeout: 60_000,
|
|
91
|
+
});
|
|
92
|
+
const out = `${result.stdout ?? ""}${result.stderr ?? ""}`;
|
|
93
|
+
writeLog(logPath, out || "(no output)\n");
|
|
94
|
+
// Re-qualify AFTER install regardless of exit code (the retest is the source of
|
|
95
|
+
// truth for whether the binding is actually usable).
|
|
96
|
+
const retest = await runNativeRetest(stateDir);
|
|
97
|
+
return {
|
|
98
|
+
action: "install-native-ort",
|
|
99
|
+
ok: result.status === 0,
|
|
100
|
+
exitCode: result.status === null ? null : result.status,
|
|
101
|
+
logPath,
|
|
102
|
+
logName,
|
|
103
|
+
spawned: true,
|
|
104
|
+
nativeOrtRetestResult: retest,
|
|
105
|
+
nativeOrtBackendEffective: retest !== null && retest.verdict === "qualified" ? "native" : "wasm",
|
|
106
|
+
};
|
|
107
|
+
}
|
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
* vc2-model-prep scripts (fetch-model.sh, bench-onnx.mjs), capturing their
|
|
7
7
|
* output to <stateDir>/logs/vc9b/<action>-<ts>.log, re-running the committed
|
|
8
8
|
* encoder asset verification seam for verify-asset (NO subprocess), and serving
|
|
9
|
-
* a bounded + redacted log tail.
|
|
9
|
+
* a bounded + redacted log tail. ENC-2c adds the `install-native-ort` action,
|
|
10
|
+
* delegated to the sibling setup-cortex-actions-native-ort.ts (the confirm-gated,
|
|
11
|
+
* npm-delegated local install + ENC-2b re-qualification).
|
|
10
12
|
*
|
|
11
13
|
* This module is the ONLY place that touches the filesystem for VC9B actions.
|
|
12
14
|
* The route file (routes-setup-cortex-actions.ts) carries NO path/script/blocker
|
|
@@ -23,6 +25,7 @@ import { fileURLToPath } from "node:url";
|
|
|
23
25
|
import { readEncoderManifest, verifyEncoderAsset, detectPlatform, } from "../../src/vector-cortex/encoder/asset.js";
|
|
24
26
|
import { ENC_0G_ENABLED, ENC_0F_ENABLED } from "../../src/config.js";
|
|
25
27
|
import { readQualificationRecord, encoderStateDir, } from "./qualification-record.js";
|
|
28
|
+
import { runInstallNativeOrt } from "./setup-cortex-actions-native-ort.js";
|
|
26
29
|
/** Cap applied to every log tail served by the action-log route. */
|
|
27
30
|
export const ACTION_LOG_TAIL_BYTES = 8192;
|
|
28
31
|
/** Locate the commit's vc2-model-prep directory by walking up to the repo root. */
|
|
@@ -222,9 +225,13 @@ function writeLog(logPath, body) {
|
|
|
222
225
|
* result on success; throws nothing — every failure is surfaced as a result with
|
|
223
226
|
* ok=false so the route can shape the HTTP response. Never touches the network;
|
|
224
227
|
* the subprocesses it may spawn are the committed local vc2-model-prep scripts.
|
|
228
|
+
* Async (ENC-2c): install-native-ort runs the npm-delegated local install then
|
|
229
|
+
* re-qualifies via the ENC-2b retest path.
|
|
225
230
|
*/
|
|
226
|
-
export function runSetupCortexAction(action, stateDir) {
|
|
231
|
+
export async function runSetupCortexAction(action, stateDir) {
|
|
227
232
|
if (action === "verify-asset")
|
|
228
233
|
return runVerifyAsset(stateDir);
|
|
234
|
+
if (action === "install-native-ort")
|
|
235
|
+
return runInstallNativeOrt(stateDir);
|
|
229
236
|
return runSpawnedAction(action, stateDir);
|
|
230
237
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* config/vector-cortex-enc2c.ts — ENC-2c native onnxruntime lazy-download
|
|
3
|
+
* install-action flag (dashboard-triggered install).
|
|
4
|
+
*
|
|
5
|
+
* Sibling of vector-cortex-enc2a.ts / vector-cortex-enc2b.ts so vector-cortex.ts
|
|
6
|
+
* stays under the 300-line soft limit (soft-as-hard gate). vector-cortex.ts
|
|
7
|
+
* re-exports the flag below and root src/config.ts re-exports it, so no consumer
|
|
8
|
+
* import path changes.
|
|
9
|
+
*
|
|
10
|
+
* ENC-2c turns ENC-2a's operator run-script assist into a dashboard action: the
|
|
11
|
+
* Setup Cortex sub-tab gains an "Install Native ORT" button that, when confirmed
|
|
12
|
+
* by the operator, runs the committed `scripts/encoder/install-native-ort.mjs`
|
|
13
|
+
* subprocess locally (npm-delegated, sha256-verified) and then re-qualifies the
|
|
14
|
+
* binding via the ENC-2b retest path. This is a PREVENT-PI-004 opt-in exemption:
|
|
15
|
+
* it is confirm-gated (never automatic), delegated to a local subprocess of a
|
|
16
|
+
* committed repo script, and carries NO URL literals in src/ or extensions/
|
|
17
|
+
* (the registry URL + sha256 live only in the artifacts-module constants).
|
|
18
|
+
*
|
|
19
|
+
* `MEGACOMPACT_ENC_2C=0` disables: no install action branch, no UI button, no
|
|
20
|
+
* install-related result fields — byte-identical to the ENC-2b predecessor. The
|
|
21
|
+
* flag MUST also be a dashboard SETTINGS toggle (visible in config UI, never in
|
|
22
|
+
* EXCLUDED_SETTINGS — see `feedback_dashboard-flags-toggleable` memory).
|
|
23
|
+
*
|
|
24
|
+
* Pi-agnostic, dependency-free (PREVENT-PI-004 / PREVENT-011).
|
|
25
|
+
*
|
|
26
|
+
* guardrails-allow PREVENT-PI-004: opt-in confirm-gated install action;
|
|
27
|
+
* delegates to local npm install subprocess, no URL literals (registry URL +
|
|
28
|
+
* sha256 live only in native-install-artifacts.ts)
|
|
29
|
+
*/
|
|
30
|
+
import { sprintFlag } from "./vector-cortex-flag.js";
|
|
31
|
+
/**
|
|
32
|
+
* ENC-2c — lazy-download native onnxruntime install action (dashboard-triggered,
|
|
33
|
+
* npm-delegated, confirm-gated). Default ON. `MEGACOMPACT_ENC_2C=0` disables and
|
|
34
|
+
* is byte-identical to the ENC-2b predecessor: no install action POST branch, no
|
|
35
|
+
* UI button, no install result fields. This flag MUST also be a dashboard SETTINGS
|
|
36
|
+
* toggle (visible in config UI, never in EXCLUDED_SETTINGS).
|
|
37
|
+
*/
|
|
38
|
+
export const ENC_2C_ENABLED = () => sprintFlag("MEGACOMPACT_ENC_2C");
|
|
@@ -54,5 +54,7 @@ export { ENC_2BUDGET_ENABLED, ENC_2BUDGET_NATIVE_ORT_BUDGET_ENV, ENC_2BUDGET_MAX
|
|
|
54
54
|
export { ENC_2A_ENABLED } from "./vector-cortex-enc2a.js";
|
|
55
55
|
// ENC-2b native onnxruntime qualification-retest flag extracted to vector-cortex-enc2b.ts.
|
|
56
56
|
export { ENC_2B_ENABLED } from "./vector-cortex-enc2b.js";
|
|
57
|
+
// ENC-2c native onnxruntime lazy-download install-action flag extracted to vector-cortex-enc2c.ts.
|
|
58
|
+
export { ENC_2C_ENABLED } from "./vector-cortex-enc2c.js";
|
|
57
59
|
// Breaker constants (TRIAD_RESILIENCE.md §breaker) extracted to vector-cortex-breakers.ts.
|
|
58
60
|
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/src/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, 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";
|
|
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, ENC_2C_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";
|
|
@@ -70,6 +70,11 @@ export class CrystalStore {
|
|
|
70
70
|
writes = 0;
|
|
71
71
|
duplicateWrites = 0;
|
|
72
72
|
collisions = 0;
|
|
73
|
+
/** Restart-survival crystal count/bytes (LIVEWIRE rehydrate). The `committed`
|
|
74
|
+
* map is empty in a fresh process; these offsets carry the persisted totals
|
|
75
|
+
* so the dashboard does not reset to zero on restart. */
|
|
76
|
+
rehydratedCrystalCount = 0;
|
|
77
|
+
rehydratedTotalBytes = 0;
|
|
73
78
|
/** Freeze a crystal object for a key/bytes pair (digest computed here). */
|
|
74
79
|
static freeze(keyDigest, bytes, key) {
|
|
75
80
|
const copy = new Uint8Array(bytes);
|
|
@@ -178,12 +183,12 @@ export class CrystalStore {
|
|
|
178
183
|
}
|
|
179
184
|
/** Reader-only aggregate for the dashboard seam — counts and bytes only. */
|
|
180
185
|
stats() {
|
|
181
|
-
let totalBytes =
|
|
186
|
+
let totalBytes = this.rehydratedTotalBytes;
|
|
182
187
|
for (const c of this.committed.values())
|
|
183
188
|
totalBytes += c.byteCount;
|
|
184
189
|
return {
|
|
185
190
|
mode: this.mode(),
|
|
186
|
-
crystalCount: this.committed.size,
|
|
191
|
+
crystalCount: this.rehydratedCrystalCount + this.committed.size,
|
|
187
192
|
totalBytes,
|
|
188
193
|
hits: this.hits,
|
|
189
194
|
misses: this.misses,
|
|
@@ -193,4 +198,22 @@ export class CrystalStore {
|
|
|
193
198
|
collisions: this.collisions,
|
|
194
199
|
};
|
|
195
200
|
}
|
|
201
|
+
/**
|
|
202
|
+
* Restart survival: seed the CUMULATIVE counters from a previously-persisted
|
|
203
|
+
* aggregate (LIVEWIRE). The in-memory `committed` map is naturally empty in a
|
|
204
|
+
* fresh process — this only restores the running totals the dashboard reports,
|
|
205
|
+
* so a process restart does not reset the dashboard to zero. It deliberately
|
|
206
|
+
* does NOT reconstruct crystals: frozen bytes are never persisted to the
|
|
207
|
+
* reader aggregate, only the counts.
|
|
208
|
+
*/
|
|
209
|
+
rehydrate(stats) {
|
|
210
|
+
this.rehydratedCrystalCount = stats.crystalCount;
|
|
211
|
+
this.rehydratedTotalBytes = stats.totalBytes;
|
|
212
|
+
this.hits = stats.hits;
|
|
213
|
+
this.misses = stats.misses;
|
|
214
|
+
this.hitBytes = stats.hitBytes;
|
|
215
|
+
this.writes = stats.writes;
|
|
216
|
+
this.duplicateWrites = stats.duplicateWrites;
|
|
217
|
+
this.collisions = stats.collisions;
|
|
218
|
+
}
|
|
196
219
|
}
|
|
@@ -67,7 +67,14 @@ function isManifest(m) {
|
|
|
67
67
|
typeof o.onnx.path === "string" &&
|
|
68
68
|
typeof o.onnx.sha256 === "string" &&
|
|
69
69
|
typeof o.tokenizer.path === "string" &&
|
|
70
|
-
typeof o.tokenizer.sha256 === "string"
|
|
70
|
+
typeof o.tokenizer.sha256 === "string" &&
|
|
71
|
+
// ML5-A (VC2B-2): optional headWeights must, when present, be a valid
|
|
72
|
+
// ManifestAssetFile (path basename + sha256 + bytes).
|
|
73
|
+
(o.headWeights === undefined ||
|
|
74
|
+
(!!o.headWeights &&
|
|
75
|
+
typeof o.headWeights.path === "string" &&
|
|
76
|
+
typeof o.headWeights.sha256 === "string" &&
|
|
77
|
+
typeof o.headWeights.bytes === "number")));
|
|
71
78
|
}
|
|
72
79
|
/**
|
|
73
80
|
* Verify the asset manifest + digest + constraints BEFORE allocation.
|
|
@@ -107,6 +114,11 @@ export function verifyEncoderAsset(assetDir, manifest, platform = detectPlatform
|
|
|
107
114
|
if (!isBasename(manifest.onnx.path) || !isBasename(manifest.tokenizer.path)) {
|
|
108
115
|
return { ok: false, code: ENC_FAIL.MANIFEST_INVALID };
|
|
109
116
|
}
|
|
117
|
+
// ML5-A (VC2B-2): a manifest-declared headWeights path must also be a bare
|
|
118
|
+
// basename (no traversal into arbitrary paths off the asset dir).
|
|
119
|
+
if (manifest.headWeights !== undefined && !isBasename(manifest.headWeights.path)) {
|
|
120
|
+
return { ok: false, code: ENC_FAIL.MANIFEST_INVALID };
|
|
121
|
+
}
|
|
110
122
|
const onnxPath = join(assetDir, manifest.onnx.path);
|
|
111
123
|
const onnxDigest = digestFile(onnxPath);
|
|
112
124
|
if (onnxDigest === null)
|
|
@@ -119,6 +131,19 @@ export function verifyEncoderAsset(assetDir, manifest, platform = detectPlatform
|
|
|
119
131
|
return { ok: false, code: ENC_FAIL.ASSET_UNREADABLE };
|
|
120
132
|
if (tokDigest !== manifest.tokenizer.sha256)
|
|
121
133
|
return { ok: false, code: ENC_FAIL.DIGEST_MISMATCH };
|
|
134
|
+
// ML5-A (VC2B-2): verify the manifest-pinned trained-heads sibling when the
|
|
135
|
+
// manifest declares it. Absent declaration -> headWeightsDigest: null and no
|
|
136
|
+
// failure (committed placeholder bundle ships no trained weights).
|
|
137
|
+
let headWeightsDigest = null;
|
|
138
|
+
if (manifest.headWeights !== undefined) {
|
|
139
|
+
const hwPath = join(assetDir, manifest.headWeights.path);
|
|
140
|
+
const hwDigest = digestFile(hwPath);
|
|
141
|
+
if (hwDigest === null)
|
|
142
|
+
return { ok: false, code: ENC_FAIL.ASSET_UNREADABLE };
|
|
143
|
+
if (hwDigest !== manifest.headWeights.sha256)
|
|
144
|
+
return { ok: false, code: ENC_FAIL.DIGEST_MISMATCH };
|
|
145
|
+
headWeightsDigest = hwDigest;
|
|
146
|
+
}
|
|
122
147
|
let embeddedBytes = 0;
|
|
123
148
|
try {
|
|
124
149
|
embeddedBytes = statSync(onnxPath).size + statSync(tokPath).size;
|
|
@@ -126,7 +151,14 @@ export function verifyEncoderAsset(assetDir, manifest, platform = detectPlatform
|
|
|
126
151
|
catch {
|
|
127
152
|
return { ok: false, code: ENC_FAIL.ASSET_UNREADABLE };
|
|
128
153
|
}
|
|
129
|
-
return {
|
|
154
|
+
return {
|
|
155
|
+
ok: true,
|
|
156
|
+
embeddedBytes,
|
|
157
|
+
maxTokens: manifest.maxTokens,
|
|
158
|
+
onnxDigest,
|
|
159
|
+
tokenizerDigest: tokDigest,
|
|
160
|
+
headWeightsDigest,
|
|
161
|
+
};
|
|
130
162
|
}
|
|
131
163
|
/**
|
|
132
164
|
* Read + shape-check a committed ModelManifestV1 from an asset directory.
|
|
@@ -25,11 +25,12 @@
|
|
|
25
25
|
* Pi-agnostic, zero network (PREVENT-PI-004), no `any` (PREVENT-011).
|
|
26
26
|
*/
|
|
27
27
|
import { createEncoderRuntime } from "./runtime.js";
|
|
28
|
-
import { encodeVectorSet } from "./heads.js";
|
|
28
|
+
import { encodeVectorSet, loadHeadProjections, projectHeadFromTrunk, } from "./heads.js";
|
|
29
29
|
import { embedTrigram512, selectTrigramBFallback } from "./trigram.js";
|
|
30
30
|
import { embedLexical, selectLexicalC } from "./lexical.js";
|
|
31
31
|
import { createEncoderHeadsReporter } from "./emit-vc2b.js";
|
|
32
|
-
import {
|
|
32
|
+
import { ML5A_ENABLED } from "../../config/vector-cortex.js";
|
|
33
|
+
import { ENC_FAIL, ENCODER_HEAD_ORDER, } from "./types.js";
|
|
33
34
|
/** Deterministic text derived from an int token sequence so the asset-free
|
|
34
35
|
* fallback producers operate on the same authority the learned path encoded. */
|
|
35
36
|
function textFromTokens(tokens) {
|
|
@@ -92,9 +93,36 @@ export function encodeOrFallback(input, assetDir, options = {}) {
|
|
|
92
93
|
if (!inferred.ok) {
|
|
93
94
|
return fallbackFromLoad({ ok: false, mode: "B", code: inferred.code }, reporter, tokens);
|
|
94
95
|
}
|
|
95
|
-
const vectorSet =
|
|
96
|
+
const vectorSet = produceVectorSet(inferred.semantic, tokens, options, reporter);
|
|
96
97
|
return { ok: true, mode: "A", vectorSet, code: null };
|
|
97
98
|
}
|
|
99
|
+
/**
|
|
100
|
+
* Produce a mode-A `VectorSetV1` from the [1,384] trunk embedding (the
|
|
101
|
+
* `runtime.infer` result). VC2B-2 ML5-A: when real trained heads are loaded
|
|
102
|
+
* (`MEGACOMPACT_ML5_A` on + a `trainedHeadsPath` that loads), the multi-head
|
|
103
|
+
* output is projected through the real trained projection matrices via
|
|
104
|
+
* `projectHeadFromTrunk`. Otherwise (flag-off / absent / unloadable artifact)
|
|
105
|
+
* the deterministic LCG placeholder `encodeVectorSet` serves mode A —
|
|
106
|
+
* byte-identical to the VC2B predecessor. Non-fatal: an unloadable artifact
|
|
107
|
+
* degrades to the placeholder, never a throw.
|
|
108
|
+
*/
|
|
109
|
+
function produceVectorSet(trunkEmbedding, tokens, options, reporter) {
|
|
110
|
+
const table = ML5A_ENABLED() && options.trainedHeadsPath !== undefined
|
|
111
|
+
? loadHeadProjections(options.trainedHeadsPath)
|
|
112
|
+
: null;
|
|
113
|
+
if (table !== null) {
|
|
114
|
+
const heads = ENCODER_HEAD_ORDER.map((h) => projectHeadFromTrunk(h, trunkEmbedding, table));
|
|
115
|
+
reporter.headsEmitted({
|
|
116
|
+
heads: heads.length,
|
|
117
|
+
dims: heads.map((h) => h.dim).join("/"),
|
|
118
|
+
normalized: true,
|
|
119
|
+
tokens: tokens.length,
|
|
120
|
+
});
|
|
121
|
+
return { schema: "vector-set-v1", inputTokens: [...tokens], heads, normalized: true };
|
|
122
|
+
}
|
|
123
|
+
// ML5-A placeholder fallback (byte-identical predecessor).
|
|
124
|
+
return encodeVectorSet(tokens, { reporter, seed: options.seed });
|
|
125
|
+
}
|
|
98
126
|
/**
|
|
99
127
|
* Catch a (real or forced) A load failure (ok === false only) and select the
|
|
100
128
|
* B/C fallback that emits `vector_cortex_encoder_fallback_selected` from the
|
|
@@ -0,0 +1,163 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vector-cortex/livewire/livewire-live.ts — LIVEWIRE in-process live state.
|
|
3
|
+
*
|
|
4
|
+
* Holds the LIVE subsystem objects for ONE stateDir: the VC7A `CrystalStore`,
|
|
5
|
+
* the VC7C cache breaker, the per-miss-class tallies, the VC8B shadow metrics,
|
|
6
|
+
* and the VC7B economics computed bit. This is the object the RUNTIME accumulates
|
|
7
|
+
* into (`recordMiss`, `recordServeBlocked`, `recordShadowRun`, ...) and that the
|
|
8
|
+
* reader-only dashboard routes snapshot out of. Kept separate from the registry
|
|
9
|
+
* (which owns the per-stateDir `Map` + persistence) so neither file crosses the
|
|
10
|
+
* 300-line soft-as-hard gate.
|
|
11
|
+
*
|
|
12
|
+
* AGGREGATE-FIRST, COUNTS ONLY. `snapshotOf` projects the live objects down to
|
|
13
|
+
* the SECURITY_PRIVACY-safe `LivewireSnapshot` (counts + codes + triad mode) that
|
|
14
|
+
* gets persisted and rendered. No session id, digest, range, profile id, bytes,
|
|
15
|
+
* or prompt text can pass through ANY of these fields.
|
|
16
|
+
*
|
|
17
|
+
* PREVENT-PI-004: no network. PREVENT-011: no `any`. Non-fatal: every derive is
|
|
18
|
+
* a pure read.
|
|
19
|
+
*/
|
|
20
|
+
import { CrystalStore } from "../cache/store.js";
|
|
21
|
+
import { createCacheBreaker } from "../cache/breaker.js";
|
|
22
|
+
import { validateProfileEconomics } from "../provider/economics.js";
|
|
23
|
+
import { BASE_PROVIDER_PROFILES } from "../provider/registry.js";
|
|
24
|
+
/**
|
|
25
|
+
* Static VC7B economics profile tallies derived from the base provider registry.
|
|
26
|
+
* `profileCount` counts profiles that declare economics; `provenExclusions` /
|
|
27
|
+
* `unprovenExclusions` tally the exclusion sets validated against the fixture
|
|
28
|
+
* rule. This is PURE (no storage/clock/network) and identical regardless of the
|
|
29
|
+
* `MEGACOMPACT_VC7B` flag — only the emission/route seam is flag-gated.
|
|
30
|
+
*/
|
|
31
|
+
function baseEconomicsTallies() {
|
|
32
|
+
let profileCount = 0;
|
|
33
|
+
let provenExclusions = 0;
|
|
34
|
+
let unprovenExclusions = 0;
|
|
35
|
+
for (const bundle of BASE_PROVIDER_PROFILES) {
|
|
36
|
+
const econ = bundle.profile.economics;
|
|
37
|
+
if (econ === null)
|
|
38
|
+
continue;
|
|
39
|
+
profileCount += 1;
|
|
40
|
+
const codes = validateProfileEconomics(bundle.profile, econ);
|
|
41
|
+
const failed = new Set(codes);
|
|
42
|
+
for (const _ex of bundle.profile.excludedJsonPointers) {
|
|
43
|
+
if (failed.has("ECON_EXCLUSION_UNPROVEN")) {
|
|
44
|
+
unprovenExclusions += 1;
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
provenExclusions += 1;
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
return { profileCount, provenExclusions, unprovenExclusions };
|
|
52
|
+
}
|
|
53
|
+
/** A zeroed per-class tally map. */
|
|
54
|
+
function zeroTallies() {
|
|
55
|
+
return {
|
|
56
|
+
profile: 0,
|
|
57
|
+
range: 0,
|
|
58
|
+
dependency: 0,
|
|
59
|
+
request: 0,
|
|
60
|
+
generation: 0,
|
|
61
|
+
unknown: 0,
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
/** Build a fresh (empty) live state with real subsystem objects. */
|
|
65
|
+
export function createLiveState() {
|
|
66
|
+
const econTallies = baseEconomicsTallies();
|
|
67
|
+
return {
|
|
68
|
+
crystalStore: new CrystalStore(),
|
|
69
|
+
breaker: createCacheBreaker(),
|
|
70
|
+
diagnostics: {
|
|
71
|
+
tallies: zeroTallies(),
|
|
72
|
+
serveBlocked: 0,
|
|
73
|
+
breakerState: "CLOSED_A",
|
|
74
|
+
lastFailure: null,
|
|
75
|
+
},
|
|
76
|
+
economics: {
|
|
77
|
+
computed: false,
|
|
78
|
+
profileCount: econTallies.profileCount,
|
|
79
|
+
provenExclusions: econTallies.provenExclusions,
|
|
80
|
+
unprovenExclusions: econTallies.unprovenExclusions,
|
|
81
|
+
lastFailure: null,
|
|
82
|
+
},
|
|
83
|
+
shadow: {
|
|
84
|
+
shadowDecisions: 0,
|
|
85
|
+
clampedDecisions: 0,
|
|
86
|
+
rejectedInputs: 0,
|
|
87
|
+
liveMutations: 0,
|
|
88
|
+
pressureVersion: 1,
|
|
89
|
+
lastFailure: null,
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
/** Project the live state down to the persisted, reader-only aggregate. */
|
|
94
|
+
export function snapshotOf(state) {
|
|
95
|
+
const crystals = state.crystalStore.stats();
|
|
96
|
+
const diag = {
|
|
97
|
+
profileMisses: state.diagnostics.tallies.profile,
|
|
98
|
+
rangeMisses: state.diagnostics.tallies.range,
|
|
99
|
+
dependencyMisses: state.diagnostics.tallies.dependency,
|
|
100
|
+
requestMisses: state.diagnostics.tallies.request,
|
|
101
|
+
generationMisses: state.diagnostics.tallies.generation,
|
|
102
|
+
unknownMisses: state.diagnostics.tallies.unknown,
|
|
103
|
+
serveBlocked: state.diagnostics.serveBlocked,
|
|
104
|
+
breakerState: state.diagnostics.breakerState,
|
|
105
|
+
lastFailure: state.diagnostics.lastFailure,
|
|
106
|
+
};
|
|
107
|
+
const econ = {
|
|
108
|
+
profileCount: state.economics.profileCount,
|
|
109
|
+
provenExclusions: state.economics.provenExclusions,
|
|
110
|
+
unprovenExclusions: state.economics.unprovenExclusions,
|
|
111
|
+
computed: state.economics.computed,
|
|
112
|
+
lastFailure: state.economics.lastFailure,
|
|
113
|
+
};
|
|
114
|
+
const policy = {
|
|
115
|
+
shadowDecisions: state.shadow.shadowDecisions,
|
|
116
|
+
clampedDecisions: state.shadow.clampedDecisions,
|
|
117
|
+
rejectedInputs: state.shadow.rejectedInputs,
|
|
118
|
+
liveMutations: state.shadow.liveMutations,
|
|
119
|
+
pressureVersion: state.shadow.pressureVersion,
|
|
120
|
+
lastFailure: state.shadow.lastFailure,
|
|
121
|
+
};
|
|
122
|
+
return {
|
|
123
|
+
schema: "vector-cortex-livewire-v1",
|
|
124
|
+
crystals: {
|
|
125
|
+
mode: crystals.mode,
|
|
126
|
+
crystalCount: crystals.crystalCount,
|
|
127
|
+
totalBytes: crystals.totalBytes,
|
|
128
|
+
hits: crystals.hits,
|
|
129
|
+
misses: crystals.misses,
|
|
130
|
+
hitBytes: crystals.hitBytes,
|
|
131
|
+
writes: crystals.writes,
|
|
132
|
+
duplicateWrites: crystals.duplicateWrites,
|
|
133
|
+
collisions: crystals.collisions,
|
|
134
|
+
},
|
|
135
|
+
diagnostics: diag,
|
|
136
|
+
economics: econ,
|
|
137
|
+
policy,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
/** Seed a fresh live state's CUMULATIVE counters from a persisted snapshot. */
|
|
141
|
+
export function rehydrateLive(state, snap) {
|
|
142
|
+
state.crystalStore.rehydrate(snap.crystals);
|
|
143
|
+
state.diagnostics.tallies.profile = snap.diagnostics.profileMisses;
|
|
144
|
+
state.diagnostics.tallies.range = snap.diagnostics.rangeMisses;
|
|
145
|
+
state.diagnostics.tallies.dependency = snap.diagnostics.dependencyMisses;
|
|
146
|
+
state.diagnostics.tallies.request = snap.diagnostics.requestMisses;
|
|
147
|
+
state.diagnostics.tallies.generation = snap.diagnostics.generationMisses;
|
|
148
|
+
state.diagnostics.tallies.unknown = snap.diagnostics.unknownMisses;
|
|
149
|
+
state.diagnostics.serveBlocked = snap.diagnostics.serveBlocked;
|
|
150
|
+
state.diagnostics.breakerState = snap.diagnostics.breakerState;
|
|
151
|
+
state.diagnostics.lastFailure = snap.diagnostics.lastFailure;
|
|
152
|
+
state.economics.computed = snap.economics.computed;
|
|
153
|
+
state.economics.profileCount = snap.economics.profileCount;
|
|
154
|
+
state.economics.provenExclusions = snap.economics.provenExclusions;
|
|
155
|
+
state.economics.unprovenExclusions = snap.economics.unprovenExclusions;
|
|
156
|
+
state.economics.lastFailure = snap.economics.lastFailure;
|
|
157
|
+
state.shadow.shadowDecisions = snap.policy.shadowDecisions;
|
|
158
|
+
state.shadow.clampedDecisions = snap.policy.clampedDecisions;
|
|
159
|
+
state.shadow.rejectedInputs = snap.policy.rejectedInputs;
|
|
160
|
+
state.shadow.liveMutations = snap.policy.liveMutations;
|
|
161
|
+
state.shadow.pressureVersion = snap.policy.pressureVersion;
|
|
162
|
+
state.shadow.lastFailure = snap.policy.lastFailure;
|
|
163
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vector-cortex/livewire/livewire-registry.ts — per-stateDir LIWIRE registry.
|
|
3
|
+
*
|
|
4
|
+
* The single seam the runtime and the reader-only dashboard routes BOTH access.
|
|
5
|
+
* It owns a `Map<stateDir, LivewireLiveState>` (one live subsystem cluster per
|
|
6
|
+
* repo) and lazily opens a state on first access, rehydrating its cumulative
|
|
7
|
+
* counters from the persisted aggregate snapshot (`livewire-snapshot.ts`) so a
|
|
8
|
+
* freshly-spawned process — e.g. the dashboard server — reports the same counts
|
|
9
|
+
* the runtime has already accumulated.
|
|
10
|
+
*
|
|
11
|
+
* The runtime WRITES through this registry (see `livewire-runtime.ts`): each
|
|
12
|
+
* mutation persists a reduced, count-only snapshot. The routes READ through
|
|
13
|
+
* `livewireOf(stateDir)` and call the pure `snapshotOf`. There is no other path.
|
|
14
|
+
*
|
|
15
|
+
* BEST-EFFORT + NON-FATAL. `openLivewire` never throws: persistence failures are
|
|
16
|
+
* swallowed by the snapshot layer and state is always returned. PREVENT-PI-004
|
|
17
|
+
* (local in-process Map + filesystem only), PREVENT-011 (no `any`).
|
|
18
|
+
*/
|
|
19
|
+
import { createLiveState, rehydrateLive, snapshotOf, } from "./livewire-live.js";
|
|
20
|
+
import { loadLivewireSnapshot, saveLivewireSnapshot, } from "./livewire-snapshot.js";
|
|
21
|
+
/** The per-stateDir registry (process-local; a fresh process starts empty). */
|
|
22
|
+
const REGISTRY = new Map();
|
|
23
|
+
let activeLogger;
|
|
24
|
+
/**
|
|
25
|
+
* Bind the structured logger the snapshot layer uses for its non-fatal write
|
|
26
|
+
* failures. The runtime calls this once at startup with its JSON logger.
|
|
27
|
+
*/
|
|
28
|
+
export function setLivewireLogger(logger) {
|
|
29
|
+
activeLogger = logger;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Open (or return the cached) live state for a stateDir. Lazy: on first access
|
|
33
|
+
* it rehydrates from the persisted aggregate so a separate dashboard process
|
|
34
|
+
* reflects prior runtime work. Never throws.
|
|
35
|
+
*/
|
|
36
|
+
export function livewireOf(stateDir) {
|
|
37
|
+
const cached = REGISTRY.get(stateDir);
|
|
38
|
+
if (cached !== undefined)
|
|
39
|
+
return cached;
|
|
40
|
+
const state = createLiveState();
|
|
41
|
+
const snap = loadLivewireSnapshot(stateDir);
|
|
42
|
+
if (snap !== null)
|
|
43
|
+
rehydrateLive(state, snap);
|
|
44
|
+
REGISTRY.set(stateDir, state);
|
|
45
|
+
return state;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Persist a state's reduced aggregate (counts + codes only). Best-effort and
|
|
49
|
+
* non-fatal. Called by the runtime after every mutation so the snapshot stays
|
|
50
|
+
* fresh for any reader process.
|
|
51
|
+
*/
|
|
52
|
+
export function persistLivewire(state, stateDir) {
|
|
53
|
+
saveLivewireSnapshot(stateDir, snapshotOf(state), activeLogger);
|
|
54
|
+
}
|
|
55
|
+
/** Persist the live state for a stateDir (convenience over open + persist). */
|
|
56
|
+
export function flushLivewire(stateDir) {
|
|
57
|
+
const state = REGISTRY.get(stateDir);
|
|
58
|
+
if (state === undefined)
|
|
59
|
+
return;
|
|
60
|
+
persistLivewire(state, stateDir);
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Build the reader aggregate for one stateDir WITHOUT persisting — the reader
|
|
64
|
+
* seam the dashboard routes call. Reads the live state (rehydrated from disk on
|
|
65
|
+
* first access) and projects it to the count-only snapshot.
|
|
66
|
+
*/
|
|
67
|
+
export function readLivewireSnapshot(stateDir) {
|
|
68
|
+
return snapshotOf(livewireOf(stateDir));
|
|
69
|
+
}
|
|
70
|
+
/** For tests: drop the registry so a fresh stateDir is fully rehydrated. */
|
|
71
|
+
export function _resetLivewireRegistryForTests() {
|
|
72
|
+
REGISTRY.clear();
|
|
73
|
+
}
|