pi-mega-compact 0.20.70 → 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/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/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/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/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/package.json +1 -1
- 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
|
@@ -25,18 +25,18 @@
|
|
|
25
25
|
*/
|
|
26
26
|
import { VC7A_ENABLED } from "../../src/config.js";
|
|
27
27
|
import { sendJson } from "./routes-vector-cortex-shared.js";
|
|
28
|
-
import { countVcEvents, vcCount } from "./vc-event-counts.js";
|
|
29
28
|
import { deriveVcStatus } from "./vc-status.js";
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
];
|
|
29
|
+
import { readLivewireSnapshot } from "../../src/vector-cortex/livewire/livewire-registry.js";
|
|
30
|
+
// The flag-off deferred reason, kept byte-identical to the pre-LIVEWIRE
|
|
31
|
+
// predecessor (VC7A: `crystal_store_not_instantiated_v0_20_23`).
|
|
32
|
+
const DEFERRED_REASON = "crystal_store_not_instantiated_v0_20_23";
|
|
35
33
|
/**
|
|
36
34
|
* Reader-only GET /api/vector-cortex/cache-crystals (VC7A).
|
|
37
35
|
*
|
|
38
|
-
* Counts, byte volumes, and CRY_* codes only
|
|
39
|
-
*
|
|
36
|
+
* Counts, byte volumes, and CRY_* codes only. With the flag ON it surfaces the
|
|
37
|
+
* LIVEWIRE `CrystalStore` aggregate (live reads/writes/collisions accumulated at
|
|
38
|
+
* runtime); with the flag OFF it returns the byte-identical legacy deferred view
|
|
39
|
+
* (mode C, deferredReason present) so flag-off parity holds.
|
|
40
40
|
*/
|
|
41
41
|
export function handleVectorCortexCrystals(req, res, ctx) {
|
|
42
42
|
const url = req.url ?? "";
|
|
@@ -48,31 +48,46 @@ export function handleVectorCortexCrystals(req, res, ctx) {
|
|
|
48
48
|
return true;
|
|
49
49
|
}
|
|
50
50
|
const enabled = VC7A_ENABLED();
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
51
|
+
if (!enabled) {
|
|
52
|
+
// Flag-off parity: byte-identical to the predecessor (mode C + deferred).
|
|
53
|
+
const body = {
|
|
54
|
+
enabled: false,
|
|
55
|
+
mode: "C",
|
|
56
|
+
crystalCount: 0,
|
|
57
|
+
totalBytes: 0,
|
|
58
|
+
hits: 0,
|
|
59
|
+
misses: 0,
|
|
60
|
+
hitBytes: 0,
|
|
61
|
+
writes: 0,
|
|
62
|
+
duplicateWrites: 0,
|
|
63
|
+
collisions: 0,
|
|
64
|
+
lastFailure: null,
|
|
65
|
+
updatedAt: new Date().toISOString(),
|
|
66
|
+
deferredReason: DEFERRED_REASON,
|
|
67
|
+
status: deriveVcStatus({ enabled: false, hasData: false }),
|
|
68
|
+
};
|
|
69
|
+
sendJson(res, 200, body);
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
const snap = readLivewireSnapshot(ctx.stateDir);
|
|
73
|
+
const crystal = snap.crystals;
|
|
74
|
+
const hasData = crystal.crystalCount > 0;
|
|
57
75
|
const body = {
|
|
58
|
-
enabled,
|
|
59
|
-
mode,
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
76
|
+
enabled: true,
|
|
77
|
+
// Surface the store's honest triad mode (B until a hit, A after, C when the
|
|
78
|
+
// store was set unavailable) rather than a hardcoded A.
|
|
79
|
+
mode: crystal.mode,
|
|
80
|
+
crystalCount: crystal.crystalCount,
|
|
81
|
+
totalBytes: crystal.totalBytes,
|
|
82
|
+
hits: crystal.hits,
|
|
83
|
+
misses: crystal.misses,
|
|
84
|
+
hitBytes: crystal.hitBytes,
|
|
85
|
+
writes: crystal.writes,
|
|
86
|
+
duplicateWrites: crystal.duplicateWrites,
|
|
87
|
+
collisions: crystal.collisions,
|
|
68
88
|
lastFailure: null,
|
|
69
89
|
updatedAt: new Date().toISOString(),
|
|
70
|
-
|
|
71
|
-
status: deriveVcStatus({
|
|
72
|
-
enabled,
|
|
73
|
-
deferredReason: "crystal_store_not_instantiated_v0_20_23",
|
|
74
|
-
hasData: vcCount(counts, "vector_cortex_crystal_written") > 0,
|
|
75
|
-
}),
|
|
90
|
+
status: deriveVcStatus({ enabled: true, hasData }),
|
|
76
91
|
};
|
|
77
92
|
sendJson(res, 200, body);
|
|
78
93
|
return true;
|
|
@@ -27,15 +27,18 @@
|
|
|
27
27
|
*/
|
|
28
28
|
import { VC7C_ENABLED } from "../../src/config.js";
|
|
29
29
|
import { sendJson } from "./routes-vector-cortex-shared.js";
|
|
30
|
-
import { countVcEvents, vcCount } from "./vc-event-counts.js";
|
|
31
30
|
import { deriveVcStatus } from "./vc-status.js";
|
|
32
|
-
|
|
33
|
-
|
|
31
|
+
import { readLivewireSnapshot } from "../../src/vector-cortex/livewire/livewire-registry.js";
|
|
32
|
+
// The flag-off deferred reason, kept byte-identical to the pre-LIVEWIRE
|
|
33
|
+
// predecessor (VC7C: `cache_classifier_not_wired_v0_20_23`).
|
|
34
|
+
const DEFERRED_REASON = "cache_classifier_not_wired_v0_20_23";
|
|
34
35
|
/**
|
|
35
36
|
* Reader-only GET /api/vector-cortex/cache-diagnostics (VC7C).
|
|
36
37
|
*
|
|
37
|
-
* Per-miss-class counts, breaker state, and CACHE
|
|
38
|
-
*
|
|
38
|
+
* Per-miss-class counts, serveBlocked, breaker state, and CACHE/M5 codes only.
|
|
39
|
+
* With the flag ON it surfaces the LIVEWIRE classifier/breaker tallies
|
|
40
|
+
* accumulated at runtime; with the flag OFF it returns the byte-identical legacy
|
|
41
|
+
* deferred view (mode C, deferredReason present).
|
|
39
42
|
*/
|
|
40
43
|
export function handleVectorCortexDiagnostics(req, res, ctx) {
|
|
41
44
|
const url = req.url ?? "";
|
|
@@ -47,32 +50,50 @@ export function handleVectorCortexDiagnostics(req, res, ctx) {
|
|
|
47
50
|
return true;
|
|
48
51
|
}
|
|
49
52
|
const enabled = VC7C_ENABLED();
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
53
|
+
if (!enabled) {
|
|
54
|
+
// Flag-off parity: byte-identical to the predecessor (mode C + deferred).
|
|
55
|
+
const body = {
|
|
56
|
+
enabled: false,
|
|
57
|
+
mode: "C",
|
|
58
|
+
profileMisses: 0,
|
|
59
|
+
rangeMisses: 0,
|
|
60
|
+
dependencyMisses: 0,
|
|
61
|
+
requestMisses: 0,
|
|
62
|
+
generationMisses: 0,
|
|
63
|
+
unknownMisses: 0,
|
|
64
|
+
serveBlocked: 0,
|
|
65
|
+
breakerState: "closed",
|
|
66
|
+
lastFailure: null,
|
|
67
|
+
updatedAt: new Date().toISOString(),
|
|
68
|
+
deferredReason: DEFERRED_REASON,
|
|
69
|
+
status: deriveVcStatus({ enabled: false, hasData: false }),
|
|
70
|
+
};
|
|
71
|
+
sendJson(res, 200, body);
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
const diag = readLivewireSnapshot(ctx.stateDir).diagnostics;
|
|
75
|
+
const hasData = diag.profileMisses +
|
|
76
|
+
diag.rangeMisses +
|
|
77
|
+
diag.dependencyMisses +
|
|
78
|
+
diag.requestMisses +
|
|
79
|
+
diag.generationMisses +
|
|
80
|
+
diag.unknownMisses +
|
|
81
|
+
diag.serveBlocked >
|
|
82
|
+
0;
|
|
57
83
|
const body = {
|
|
58
|
-
enabled,
|
|
59
|
-
mode,
|
|
60
|
-
profileMisses:
|
|
61
|
-
rangeMisses:
|
|
62
|
-
dependencyMisses:
|
|
63
|
-
requestMisses:
|
|
64
|
-
generationMisses:
|
|
65
|
-
unknownMisses:
|
|
66
|
-
serveBlocked:
|
|
67
|
-
breakerState:
|
|
68
|
-
lastFailure:
|
|
84
|
+
enabled: true,
|
|
85
|
+
mode: "A",
|
|
86
|
+
profileMisses: diag.profileMisses,
|
|
87
|
+
rangeMisses: diag.rangeMisses,
|
|
88
|
+
dependencyMisses: diag.dependencyMisses,
|
|
89
|
+
requestMisses: diag.requestMisses,
|
|
90
|
+
generationMisses: diag.generationMisses,
|
|
91
|
+
unknownMisses: diag.unknownMisses,
|
|
92
|
+
serveBlocked: diag.serveBlocked,
|
|
93
|
+
breakerState: diag.breakerState,
|
|
94
|
+
lastFailure: diag.lastFailure,
|
|
69
95
|
updatedAt: new Date().toISOString(),
|
|
70
|
-
|
|
71
|
-
status: deriveVcStatus({
|
|
72
|
-
enabled,
|
|
73
|
-
deferredReason: "cache_classifier_not_wired_v0_20_23",
|
|
74
|
-
hasData: vcCount(counts, "vector_cortex_cache_serve_blocked") > 0,
|
|
75
|
-
}),
|
|
96
|
+
status: deriveVcStatus({ enabled: true, hasData }),
|
|
76
97
|
};
|
|
77
98
|
sendJson(res, 200, body);
|
|
78
99
|
return true;
|
|
@@ -25,13 +25,19 @@
|
|
|
25
25
|
import { VC7B_ENABLED } from "../../src/config.js";
|
|
26
26
|
import { sendJson } from "./routes-vector-cortex-shared.js";
|
|
27
27
|
import { deriveVcStatus } from "./vc-status.js";
|
|
28
|
+
import { readLivewireSnapshot } from "../../src/vector-cortex/livewire/livewire-registry.js";
|
|
29
|
+
// The flag-off deferred reason, kept byte-identical to the pre-LIVEWIRE
|
|
30
|
+
// predecessor (VC7B: `economics_not_computed_v0_20_23`).
|
|
31
|
+
const DEFERRED_REASON = "economics_not_computed_v0_20_23";
|
|
28
32
|
/**
|
|
29
33
|
* Reader-only GET /api/vector-cortex/cache-economics (VC7B).
|
|
30
34
|
*
|
|
31
|
-
* Counts, profile tallies, and ECON_* codes only
|
|
32
|
-
*
|
|
35
|
+
* Counts, profile tallies, and ECON_* codes only. With the flag ON it surfaces
|
|
36
|
+
* the LIVEWIRE-provided profile economics tallies + the runtime `computed` bit;
|
|
37
|
+
* with the flag OFF it returns the byte-identical legacy deferred view (mode C,
|
|
38
|
+
* deferredReason present).
|
|
33
39
|
*/
|
|
34
|
-
export function handleVectorCortexEconomics(req, res,
|
|
40
|
+
export function handleVectorCortexEconomics(req, res, ctx) {
|
|
35
41
|
const url = req.url ?? "";
|
|
36
42
|
const path = url.split("?")[0] ?? url;
|
|
37
43
|
if (path !== "/api/vector-cortex/cache-economics")
|
|
@@ -41,25 +47,32 @@ export function handleVectorCortexEconomics(req, res, _ctx) {
|
|
|
41
47
|
return true;
|
|
42
48
|
}
|
|
43
49
|
const enabled = VC7B_ENABLED();
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
50
|
+
if (!enabled) {
|
|
51
|
+
// Flag-off parity: byte-identical to the predecessor (mode C + deferred).
|
|
52
|
+
const body = {
|
|
53
|
+
enabled: false,
|
|
54
|
+
mode: "C",
|
|
55
|
+
profileCount: 0,
|
|
56
|
+
provenExclusions: 0,
|
|
57
|
+
unprovenExclusions: 0,
|
|
58
|
+
lastFailure: null,
|
|
59
|
+
updatedAt: new Date().toISOString(),
|
|
60
|
+
deferredReason: DEFERRED_REASON,
|
|
61
|
+
status: deriveVcStatus({ enabled: false, hasData: false }),
|
|
62
|
+
};
|
|
63
|
+
sendJson(res, 200, body);
|
|
64
|
+
return true;
|
|
65
|
+
}
|
|
66
|
+
const econ = readLivewireSnapshot(ctx.stateDir).economics;
|
|
49
67
|
const body = {
|
|
50
|
-
enabled,
|
|
51
|
-
mode,
|
|
52
|
-
profileCount:
|
|
53
|
-
provenExclusions:
|
|
54
|
-
unprovenExclusions:
|
|
55
|
-
lastFailure:
|
|
68
|
+
enabled: true,
|
|
69
|
+
mode: "A",
|
|
70
|
+
profileCount: econ.profileCount,
|
|
71
|
+
provenExclusions: econ.provenExclusions,
|
|
72
|
+
unprovenExclusions: econ.unprovenExclusions,
|
|
73
|
+
lastFailure: econ.lastFailure,
|
|
56
74
|
updatedAt: new Date().toISOString(),
|
|
57
|
-
|
|
58
|
-
status: deriveVcStatus({
|
|
59
|
-
enabled,
|
|
60
|
-
deferredReason: "economics_not_computed_v0_20_23",
|
|
61
|
-
hasData: false,
|
|
62
|
-
}),
|
|
75
|
+
status: deriveVcStatus({ enabled: true, hasData: econ.computed }),
|
|
63
76
|
};
|
|
64
77
|
sendJson(res, 200, body);
|
|
65
78
|
return true;
|
|
@@ -98,3 +98,57 @@ export async function seedEval(dir) {
|
|
|
98
98
|
{ session: "s1", seq: 4, event: "encode", value: 12, unit: "ms", mode: "A" },
|
|
99
99
|
]);
|
|
100
100
|
}
|
|
101
|
+
/**
|
|
102
|
+
* Seed a LIVEWIRE aggregate snapshot directly on disk so the spawned dashboard
|
|
103
|
+
* server (a separate process) rehydrates real subsystem counts and its reader-only
|
|
104
|
+
* routes report LIVE (non-deferred) data. This is how the LIVEWIRE route tests
|
|
105
|
+
* prove the wiring: the runtimes' persisted counts are exactly what a reader
|
|
106
|
+
* process reconstructs. Counts + codes + triad mode only (SECURITY_PRIVACY).
|
|
107
|
+
*/
|
|
108
|
+
export async function seedLivewireSnapshot(dir, overrides) {
|
|
109
|
+
const { saveLivewireSnapshot } = await import("../../src/vector-cortex/livewire/livewire-snapshot.js");
|
|
110
|
+
const c = overrides?.crystals ?? {};
|
|
111
|
+
const d = overrides?.diagnostics ?? {};
|
|
112
|
+
const e = overrides?.economics ?? {};
|
|
113
|
+
const p = overrides?.policy ?? {};
|
|
114
|
+
saveLivewireSnapshot(dir, {
|
|
115
|
+
schema: "vector-cortex-livewire-v1",
|
|
116
|
+
crystals: {
|
|
117
|
+
mode: "A",
|
|
118
|
+
crystalCount: c.crystalCount ?? 3,
|
|
119
|
+
totalBytes: c.totalBytes ?? 1024,
|
|
120
|
+
hits: c.hits ?? 0,
|
|
121
|
+
misses: c.misses ?? 0,
|
|
122
|
+
hitBytes: c.hitBytes ?? 0,
|
|
123
|
+
writes: c.writes ?? 0,
|
|
124
|
+
duplicateWrites: c.duplicateWrites ?? 0,
|
|
125
|
+
collisions: c.collisions ?? 0,
|
|
126
|
+
},
|
|
127
|
+
diagnostics: {
|
|
128
|
+
profileMisses: d.profileMisses ?? 0,
|
|
129
|
+
rangeMisses: d.rangeMisses ?? 0,
|
|
130
|
+
dependencyMisses: d.dependencyMisses ?? 0,
|
|
131
|
+
requestMisses: d.requestMisses ?? 0,
|
|
132
|
+
generationMisses: d.generationMisses ?? 0,
|
|
133
|
+
unknownMisses: d.unknownMisses ?? 0,
|
|
134
|
+
serveBlocked: d.serveBlocked ?? 0,
|
|
135
|
+
breakerState: d.breakerState ?? "CLOSED_A",
|
|
136
|
+
lastFailure: null,
|
|
137
|
+
},
|
|
138
|
+
economics: {
|
|
139
|
+
profileCount: e.profileCount ?? 4,
|
|
140
|
+
provenExclusions: e.provenExclusions ?? 1,
|
|
141
|
+
unprovenExclusions: e.unprovenExclusions ?? 0,
|
|
142
|
+
computed: e.computed ?? true,
|
|
143
|
+
lastFailure: null,
|
|
144
|
+
},
|
|
145
|
+
policy: {
|
|
146
|
+
shadowDecisions: p.shadowDecisions ?? 0,
|
|
147
|
+
clampedDecisions: p.clampedDecisions ?? 0,
|
|
148
|
+
rejectedInputs: p.rejectedInputs ?? 0,
|
|
149
|
+
liveMutations: p.liveMutations ?? 0,
|
|
150
|
+
pressureVersion: (p.pressureVersion ?? 1),
|
|
151
|
+
lastFailure: null,
|
|
152
|
+
},
|
|
153
|
+
});
|
|
154
|
+
}
|
|
@@ -18,8 +18,12 @@
|
|
|
18
18
|
import { VC8B_ENABLED } from "../../src/config.js";
|
|
19
19
|
import { sendJson } from "./routes-vector-cortex-shared.js";
|
|
20
20
|
import { deriveVcStatus } from "./vc-status.js";
|
|
21
|
+
import { readLivewireSnapshot } from "../../src/vector-cortex/livewire/livewire-registry.js";
|
|
22
|
+
// The flag-off deferred reason, kept byte-identical to the pre-LIVEWIRE
|
|
23
|
+
// predecessor (VC8B: `shadow_controller_not_instantiated_v0_20_23`).
|
|
24
|
+
const DEFERRED_REASON = "shadow_controller_not_instantiated_v0_20_23";
|
|
21
25
|
/** GET /api/vector-cortex/policy — reader-only policy + shadow aggregate (VC8B). */
|
|
22
|
-
export function handleVectorCortexPolicy(req, res,
|
|
26
|
+
export function handleVectorCortexPolicy(req, res, ctx) {
|
|
23
27
|
const url = req.url ?? "";
|
|
24
28
|
const path = url.split("?")[0] ?? url;
|
|
25
29
|
if (path !== "/api/vector-cortex/policy")
|
|
@@ -29,23 +33,36 @@ export function handleVectorCortexPolicy(req, res, _ctx) {
|
|
|
29
33
|
return true;
|
|
30
34
|
}
|
|
31
35
|
const enabled = VC8B_ENABLED();
|
|
32
|
-
|
|
36
|
+
if (!enabled) {
|
|
37
|
+
// Flag-off parity: byte-identical to the predecessor (mode C + deferred).
|
|
38
|
+
const body = {
|
|
39
|
+
enabled: false,
|
|
40
|
+
mode: "C",
|
|
41
|
+
shadowDecisions: 0,
|
|
42
|
+
clampedDecisions: 0,
|
|
43
|
+
rejectedInputs: 0,
|
|
44
|
+
liveMutations: 0,
|
|
45
|
+
pressureVersion: 1,
|
|
46
|
+
lastFailure: null,
|
|
47
|
+
updatedAt: new Date().toISOString(),
|
|
48
|
+
deferredReason: DEFERRED_REASON,
|
|
49
|
+
status: deriveVcStatus({ enabled: false, hasData: false }),
|
|
50
|
+
};
|
|
51
|
+
sendJson(res, 200, body);
|
|
52
|
+
return true;
|
|
53
|
+
}
|
|
54
|
+
const policy = readLivewireSnapshot(ctx.stateDir).policy;
|
|
33
55
|
const body = {
|
|
34
|
-
enabled,
|
|
35
|
-
mode,
|
|
36
|
-
shadowDecisions:
|
|
37
|
-
clampedDecisions:
|
|
38
|
-
rejectedInputs:
|
|
39
|
-
liveMutations:
|
|
40
|
-
pressureVersion:
|
|
41
|
-
lastFailure:
|
|
56
|
+
enabled: true,
|
|
57
|
+
mode: "A",
|
|
58
|
+
shadowDecisions: policy.shadowDecisions,
|
|
59
|
+
clampedDecisions: policy.clampedDecisions,
|
|
60
|
+
rejectedInputs: policy.rejectedInputs,
|
|
61
|
+
liveMutations: policy.liveMutations,
|
|
62
|
+
pressureVersion: policy.pressureVersion,
|
|
63
|
+
lastFailure: policy.lastFailure,
|
|
42
64
|
updatedAt: new Date().toISOString(),
|
|
43
|
-
|
|
44
|
-
status: deriveVcStatus({
|
|
45
|
-
enabled,
|
|
46
|
-
deferredReason: "shadow_controller_not_instantiated_v0_20_23",
|
|
47
|
-
hasData: false,
|
|
48
|
-
}),
|
|
65
|
+
status: deriveVcStatus({ enabled: true, hasData: policy.shadowDecisions > 0 }),
|
|
49
66
|
};
|
|
50
67
|
sendJson(res, 200, body);
|
|
51
68
|
return true;
|
|
@@ -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
|