pi-mega-compact 0.18.1 → 0.19.0
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/assets/vector-cortex/encoder-v1/manifest.json +1 -0
- package/assets/vector-cortex/encoder-v1/model-card.json +1 -0
- package/assets/vector-cortex/encoder-v1/model.onnx +0 -0
- package/assets/vector-cortex/encoder-v1/tokenizer.json +1 -0
- package/dist/config/vector-cortex.js +9 -0
- package/dist/config.js +1 -1
- package/dist/extensions/dashboard-server/routes-rag-settings-helpers.js +1 -0
- package/dist/extensions/dashboard-server/routes-vector-cortex.js +89 -1
- package/dist/src/config/vector-cortex.js +9 -0
- package/dist/src/config.js +1 -1
- package/dist/src/vector-cortex/encoder/calibrate.js +174 -0
- package/dist/src/vector-cortex/encoder/emit-vc2c.js +59 -0
- package/dist/src/vector-cortex/encoder/fallback.js +62 -0
- package/dist/src/vector-cortex/encoder/select.js +172 -0
- package/dist/src/vector-cortex/encoder/types.js +31 -0
- package/dist/vector-cortex/encoder/calibrate.js +174 -0
- package/dist/vector-cortex/encoder/emit-vc2c.js +59 -0
- package/dist/vector-cortex/encoder/fallback.js +62 -0
- package/dist/vector-cortex/encoder/select.js +172 -0
- package/dist/vector-cortex/encoder/types.js +31 -0
- package/extensions/dashboard-client/dist/assets/{AreaChart-BQXFF7UI.js → AreaChart-DywU5SSt.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{AreaChart-BQXFF7UI.js.map → AreaChart-DywU5SSt.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{BarChart-BVtoz9Eg.js → BarChart-But7WN6K.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{BarChart-BVtoz9Eg.js.map → BarChart-But7WN6K.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{CacheTab-trI2TIGy.js → CacheTab-7aZWa1DR.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{CacheTab-trI2TIGy.js.map → CacheTab-7aZWa1DR.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{EventsTab-CNUbk9__.js → EventsTab-Bf_boNG2.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{EventsTab-CNUbk9__.js.map → EventsTab-Bf_boNG2.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{HealthTab-K-bd_CM-.js → HealthTab-AbGc1nXP.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{HealthTab-K-bd_CM-.js.map → HealthTab-AbGc1nXP.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MaintenanceTab-CoEioKzx.js → MaintenanceTab-BfHHhn5F.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MaintenanceTab-CoEioKzx.js.map → MaintenanceTab-BfHHhn5F.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MemoryMapTab-CJo24ulv.js → MemoryMapTab-DrcWti0-.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MemoryMapTab-CJo24ulv.js.map → MemoryMapTab-DrcWti0-.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MetricsTab-DCNlQWWP.js → MetricsTab-ALiglXQq.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MetricsTab-DCNlQWWP.js.map → MetricsTab-ALiglXQq.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{OverviewTab-CQQlyIQ6.js → OverviewTab-nnaJdNyR.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{OverviewTab-CQQlyIQ6.js.map → OverviewTab-nnaJdNyR.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{ReposTab-Cqm82_yn.js → ReposTab-BTK0nofM.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{ReposTab-Cqm82_yn.js.map → ReposTab-BTK0nofM.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{SessionsTab-A8xTAdET.js → SessionsTab-RXPNqO6x.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{SessionsTab-A8xTAdET.js.map → SessionsTab-RXPNqO6x.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{SetupTab-CqaSgaZl.js → SetupTab-Dab0AVfs.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{SetupTab-CqaSgaZl.js.map → SetupTab-Dab0AVfs.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{TimeSavedCard-C_f3q8GR.js → TimeSavedCard-DIVG8hdt.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{TimeSavedCard-C_f3q8GR.js.map → TimeSavedCard-DIVG8hdt.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{TurnsTab-BEsafACo.js → TurnsTab-9uz2fBwx.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{TurnsTab-BEsafACo.js.map → TurnsTab-9uz2fBwx.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{VectorCortexTab-DD1CMK80.js → VectorCortexTab-DnKY61EJ.js} +2 -2
- package/extensions/dashboard-client/dist/assets/VectorCortexTab-DnKY61EJ.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/{WikiTab-Bf01M2_Z.js → WikiTab-CpcgaggS.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{WikiTab-Bf01M2_Z.js.map → WikiTab-CpcgaggS.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{button-BEJPTk_E.js → button-B0Q2fuKY.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{button-BEJPTk_E.js.map → button-B0Q2fuKY.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{card-DK1V382s.js → card-Cnik3TFr.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{card-DK1V382s.js.map → card-Cnik3TFr.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-CRtaPphL.js → generateCategoricalChart-DrSwgn1V.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-CRtaPphL.js.map → generateCategoricalChart-DrSwgn1V.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{index-CB6BslE4.js → index-DraytcOY.js} +3 -3
- package/extensions/dashboard-client/dist/assets/{index-CB6BslE4.js.map → index-DraytcOY.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{switch-C4FV6B9k.js → switch-DVQ1aB9b.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{switch-C4FV6B9k.js.map → switch-DVQ1aB9b.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{toggle-GBmeENMd.js → toggle-Dkppx-49.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{toggle-GBmeENMd.js.map → toggle-Dkppx-49.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{useSSE-BOKZGSn1.js → useSSE-CPkjU4Gx.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{useSSE-BOKZGSn1.js.map → useSSE-CPkjU4Gx.js.map} +1 -1
- package/extensions/dashboard-client/dist/index.html +1 -1
- package/extensions/dashboard-client/src/tabs/VectorCortexTab.tsx +2 -0
- package/extensions/dashboard-client/src/types/vector-cortex.ts +11 -0
- package/extensions/dashboard-server/api-contracts/vector-cortex.ts +11 -0
- package/extensions/dashboard-server/routes-rag-settings-helpers.ts +6 -0
- package/extensions/dashboard-server/routes-vector-cortex.ts +108 -1
- package/package.json +2 -1
- package/src/config/vector-cortex.ts +10 -0
- package/src/config.ts +1 -0
- package/src/vector-cortex/encoder/calibrate.ts +225 -0
- package/src/vector-cortex/encoder/emit-vc2c.ts +70 -0
- package/src/vector-cortex/encoder/fallback.ts +99 -0
- package/src/vector-cortex/encoder/select.ts +237 -0
- package/src/vector-cortex/encoder/types.ts +116 -0
- package/extensions/dashboard-client/dist/assets/VectorCortexTab-DD1CMK80.js.map +0 -1
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vector-cortex/encoder/select.ts — VC2C atomic qualification selection (task 3).
|
|
3
|
+
*
|
|
4
|
+
* Selects mode A (a `QualifiedEncoderV1`) ONLY when EVERY MODEL_ASSET
|
|
5
|
+
* constraint AND every per-head EVALUATION threshold passes — the eligibility
|
|
6
|
+
* check is ATOMIC: any single failed field demotes the ENTIRE candidate to
|
|
7
|
+
* mode B/C (never a partial A). The failed field is reported so the caller/UI
|
|
8
|
+
* can inspect which threshold tripped.
|
|
9
|
+
*
|
|
10
|
+
* - asset fields (MODEL_ASSET §qualification): maxTokens <= 512, p95 latency
|
|
11
|
+
* <= 40 ms, encoder RSS delta <= 150 MiB. When an asset field fails, the
|
|
12
|
+
* demotion code is `ENC_QUALIFICATION_ASSET_FAILED`; per-head / reconstruction
|
|
13
|
+
* failures report `ENC_QUALIFICATION_THRESHOLD_FAILED`. Either way the check is
|
|
14
|
+
* atomic — the field that tripped is surfaced via `failedField`.
|
|
15
|
+
* - per-head EVALUATION thresholds (EVALUATION.md §metrics):
|
|
16
|
+
* semantic spearman >= .75, recall@10 >= .90
|
|
17
|
+
* dependency precision >= .97, recall >= .95
|
|
18
|
+
* contradiction precision >= .98, recall >= .90, ECE <= .05
|
|
19
|
+
* cacheStability precision >= .999, recall >= .90
|
|
20
|
+
* payloadRouting macro-F1 >= .97, exact/anchor recall = 1.0
|
|
21
|
+
* - reconstruction: zero causal/tool/anchor/exact violations, dependency
|
|
22
|
+
* closure recall = 1.0, task-success non-inferior to C.
|
|
23
|
+
*
|
|
24
|
+
* Unique failure injection: when a candidate supplies an expected
|
|
25
|
+
* `qualificationManifestDigest` (the digest of the qualification manifest
|
|
26
|
+
* sealed at calibration time) and the presented calibration digest differs,
|
|
27
|
+
* selection returns ENC_QUALIFICATION_DIGEST_MISMATCH and demotes A — the
|
|
28
|
+
* "corrupt qualification manifest after calibration but before selection" case.
|
|
29
|
+
*
|
|
30
|
+
* Emits `vector_cortex_encoder_qualification_passed` on success and
|
|
31
|
+
* `vector_cortex_encoder_qualification_demoted` on any demotion, via the
|
|
32
|
+
* flag-gated VC2C reporter. Pi-agnostic, zero network (PREVENT-PI-004), no
|
|
33
|
+
* `any` (PREVENT-011).
|
|
34
|
+
*/
|
|
35
|
+
|
|
36
|
+
import { createHash } from "node:crypto";
|
|
37
|
+
import {
|
|
38
|
+
ENC_QUALIFICATION_FAIL,
|
|
39
|
+
EVALUATION_THRESHOLDS,
|
|
40
|
+
type CalibrationV1,
|
|
41
|
+
type EncoderHeldOutMetrics,
|
|
42
|
+
type EncoderHeadName,
|
|
43
|
+
type QualifiedEncoderV1,
|
|
44
|
+
} from "./types.js";
|
|
45
|
+
import {
|
|
46
|
+
createEncoderQualificationReporter,
|
|
47
|
+
type EncoderQualificationReporter,
|
|
48
|
+
} from "./emit-vc2c.js";
|
|
49
|
+
|
|
50
|
+
/** The MODEL_ASSET asset constraints a candidate must satisfy (subset that
|
|
51
|
+
* select.ts evaluates; the rest — supported matrix, opset, batch, digest — are
|
|
52
|
+
* enforced by the VC2A asset verification seam before a candidate exists). */
|
|
53
|
+
export interface CandidateAssetFacts {
|
|
54
|
+
/** Declared/verified per-manifest token capacity (<= 512). */
|
|
55
|
+
readonly maxTokens: number;
|
|
56
|
+
/** Measured p95 inference latency (ms, <= 40). */
|
|
57
|
+
readonly latencyP95Ms: number;
|
|
58
|
+
/** Measured encoder RSS delta (MiB, <= 150). */
|
|
59
|
+
readonly rssDeltaMib: number;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Inputs to the atomic eligibility check. */
|
|
63
|
+
export interface QualificationCandidate {
|
|
64
|
+
readonly modelVersion: string;
|
|
65
|
+
readonly asset: CandidateAssetFacts;
|
|
66
|
+
/** The verified ONNX digest of the candidate asset. */
|
|
67
|
+
readonly onnxDigest: string;
|
|
68
|
+
/**
|
|
69
|
+
* SHA-256 of the asset manifest bytes (ModelManifestV1) that qualified — the
|
|
70
|
+
* same digest the dashboard health card reports as `encoderAssetDigest`
|
|
71
|
+
* (SHA-256 of the committed manifest.json bytes). select.ts stamps this into
|
|
72
|
+
* `QualifiedEncoderV1.assetDigest` verbatim so the record pins the true
|
|
73
|
+
* asset-manifest digest, not a calibration-derived hash.
|
|
74
|
+
*/
|
|
75
|
+
readonly assetManifestDigest: string;
|
|
76
|
+
/** Calibration digest the asset is qualified against (from `CalibrationV1`). */
|
|
77
|
+
readonly calibration: CalibrationV1;
|
|
78
|
+
/** Held-out metrics as evidence (EVALUATION.md). */
|
|
79
|
+
readonly heldOut: EncoderHeldOutMetrics;
|
|
80
|
+
/**
|
|
81
|
+
* The qualification manifest digest sealed at calibration time. When supplied,
|
|
82
|
+
* it must equal SHA-256 over the calibration manifest bytes; a mismatch is the
|
|
83
|
+
* corrupt-qualification-manifest injection (ENC_QUALIFICATION_DIGEST_MISMATCH).
|
|
84
|
+
*/
|
|
85
|
+
readonly expectedQualificationManifestDigest?: string;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* The qualification verdict. A successful candidate is mode A; ANY demotion here
|
|
90
|
+
* is mode B — select.ts never produces mode C. Mode C (lexical/exact) is
|
|
91
|
+
* exclusively the output of the separate fallback seam (`fallback.ts`, selected
|
|
92
|
+
* only when A is absent AND B itself errors or the caller forces C). The type is
|
|
93
|
+
* narrowed to "B" on failure to match the implementation: demoting a candidate
|
|
94
|
+
* is the same "asset-free, non-learned" fallback regardless of which field
|
|
95
|
+
* tripped; the lexical C demotion is not a property of qualification selection.
|
|
96
|
+
*/
|
|
97
|
+
export type QualificationVerdict =
|
|
98
|
+
| { ok: true; mode: "A"; qualified: QualifiedEncoderV1; code: null }
|
|
99
|
+
| { ok: false; mode: "B"; code: string; failedField: string | null };
|
|
100
|
+
|
|
101
|
+
/** Canonical digest over a CalibrationV1's stable identity (split digest, heads,
|
|
102
|
+
* temps, thresholds, seed) — the "qualification manifest digest". */
|
|
103
|
+
export function qualificationManifestDigest(calibration: CalibrationV1): string {
|
|
104
|
+
const payload = JSON.stringify({
|
|
105
|
+
headOrder: [...calibration.headOrder].sort(),
|
|
106
|
+
splitDigest: calibration.calibrationSplitDigest,
|
|
107
|
+
temps: calibration.temperatures,
|
|
108
|
+
thresholds: calibration.thresholds,
|
|
109
|
+
seed: calibration.seed,
|
|
110
|
+
});
|
|
111
|
+
return createHash("sha256").update(payload).digest("hex");
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** True when one per-head metric row clears its normative EVALUATION threshold. */
|
|
115
|
+
function headPasses(head: EncoderHeadName, m: EncoderHeldOutMetrics): boolean {
|
|
116
|
+
switch (head) {
|
|
117
|
+
case "semantic":
|
|
118
|
+
return m.semantic.spearman >= EVALUATION_THRESHOLDS.semantic.spearman &&
|
|
119
|
+
m.semantic.recallAt10 >= EVALUATION_THRESHOLDS.semantic.recallAt10;
|
|
120
|
+
case "dependency":
|
|
121
|
+
return m.dependency.precision >= EVALUATION_THRESHOLDS.dependency.precision &&
|
|
122
|
+
m.dependency.recall >= EVALUATION_THRESHOLDS.dependency.recall;
|
|
123
|
+
case "contradiction":
|
|
124
|
+
return m.contradiction.precision >= EVALUATION_THRESHOLDS.contradiction.precision &&
|
|
125
|
+
m.contradiction.recall >= EVALUATION_THRESHOLDS.contradiction.recall &&
|
|
126
|
+
m.contradiction.ece <= EVALUATION_THRESHOLDS.contradiction.ece;
|
|
127
|
+
case "cacheStability":
|
|
128
|
+
return m.cacheStability.precision >= EVALUATION_THRESHOLDS.cacheStability.precision &&
|
|
129
|
+
m.cacheStability.recall >= EVALUATION_THRESHOLDS.cacheStability.recall;
|
|
130
|
+
case "payloadRouting":
|
|
131
|
+
return m.payloadRouting.macroF1 >= EVALUATION_THRESHOLDS.payloadRouting.macroF1 &&
|
|
132
|
+
m.payloadRouting.exactAnchorRecall >= EVALUATION_THRESHOLDS.payloadRouting.exactAnchorRecall;
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
function reconstructionPasses(m: EncoderHeldOutMetrics): boolean {
|
|
137
|
+
return (
|
|
138
|
+
m.reconstruction.votesOk &&
|
|
139
|
+
m.reconstruction.dependencyClosureRecall >= EVALUATION_THRESHOLDS.reconstruction.dependencyClosureRecall &&
|
|
140
|
+
m.reconstruction.taskSuccessNonInferior
|
|
141
|
+
);
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
function assetPasses(a: CandidateAssetFacts, failed: string[]): boolean {
|
|
145
|
+
let ok = true;
|
|
146
|
+
if (a.maxTokens > EVALUATION_THRESHOLDS.asset.maxTokens) { failed.push("asset.maxTokens"); ok = false; }
|
|
147
|
+
if (a.latencyP95Ms > EVALUATION_THRESHOLDS.asset.maxLatencyP95Ms) { failed.push("asset.latencyP95Ms"); ok = false; }
|
|
148
|
+
if (a.rssDeltaMib > EVALUATION_THRESHOLDS.asset.maxRssDeltaMib) { failed.push("asset.rssDeltaMib"); ok = false; }
|
|
149
|
+
return ok;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* Atomic eligibility check across every MODEL_ASSET + per-head EVALUATION
|
|
154
|
+
* threshold (task 3). Any single failed field demotes ALL of A (returns
|
|
155
|
+
* `ok:false`); there is no partial qualification. On success returns a
|
|
156
|
+
* `QualifiedEncoderV1` pinning asset/calibration digests + held-out evidence.
|
|
157
|
+
*/
|
|
158
|
+
export function selectQualifiedEncoder(
|
|
159
|
+
candidate: QualificationCandidate,
|
|
160
|
+
options: { reporter?: EncoderQualificationReporter } = {},
|
|
161
|
+
): QualificationVerdict {
|
|
162
|
+
const reporter = options.reporter ?? createEncoderQualificationReporter();
|
|
163
|
+
|
|
164
|
+
// Unique failure injection: corrupt qualification manifest between calibration
|
|
165
|
+
// and selection. The sealed manifest digest must match the presented
|
|
166
|
+
// calibration's digest; a mismatch demotes A to B/C with the dedicated code.
|
|
167
|
+
if (candidate.expectedQualificationManifestDigest !== undefined) {
|
|
168
|
+
const presented = qualificationManifestDigest(candidate.calibration);
|
|
169
|
+
if (presented !== candidate.expectedQualificationManifestDigest) {
|
|
170
|
+
reporter.qualificationDemoted({
|
|
171
|
+
reason: ENC_QUALIFICATION_FAIL.DIGEST_MISMATCH,
|
|
172
|
+
modelVersion: candidate.modelVersion,
|
|
173
|
+
mode: "B",
|
|
174
|
+
});
|
|
175
|
+
return {
|
|
176
|
+
ok: false,
|
|
177
|
+
mode: "B",
|
|
178
|
+
code: ENC_QUALIFICATION_FAIL.DIGEST_MISMATCH,
|
|
179
|
+
failedField: "qualificationManifestDigest",
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Atomic: collect EVERY failed field across asset + all heads + reconstruction.
|
|
185
|
+
const failed: string[] = [];
|
|
186
|
+
assetPasses(candidate.asset, failed);
|
|
187
|
+
const heads: EncoderHeadName[] = ["semantic", "dependency", "contradiction", "cacheStability", "payloadRouting"];
|
|
188
|
+
for (const h of heads) {
|
|
189
|
+
if (!headPasses(h, candidate.heldOut)) failed.push(`head.${h}`);
|
|
190
|
+
}
|
|
191
|
+
if (!reconstructionPasses(candidate.heldOut)) failed.push("reconstruction");
|
|
192
|
+
|
|
193
|
+
if (failed.length > 0) {
|
|
194
|
+
// Any failed field demotes all of A — no partial A. Route the demotion code
|
|
195
|
+
// by the failed-field class: an asset-field failure (maxTokens/latency/RSS)
|
|
196
|
+
// reports ENC_QUALIFICATION_ASSET_FAILED; a per-head/reconstruction failure
|
|
197
|
+
// reports ENC_QUALIFICATION_THRESHOLD_FAILED. `failedField` always carries the
|
|
198
|
+
// specific field that tripped, so the code + field together fully identify it.
|
|
199
|
+
const assetFailed = failed.some((f) => f.startsWith("asset."));
|
|
200
|
+
const code = assetFailed
|
|
201
|
+
? ENC_QUALIFICATION_FAIL.ASSET_FAILED
|
|
202
|
+
: ENC_QUALIFICATION_FAIL.THRESHOLD_FAILED;
|
|
203
|
+
reporter.qualificationDemoted({
|
|
204
|
+
reason: code,
|
|
205
|
+
failed: failed.join("/"),
|
|
206
|
+
modelVersion: candidate.modelVersion,
|
|
207
|
+
mode: "B",
|
|
208
|
+
});
|
|
209
|
+
return {
|
|
210
|
+
ok: false,
|
|
211
|
+
mode: "B",
|
|
212
|
+
code,
|
|
213
|
+
failedField: failed[0] ?? null,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
const qualified: QualifiedEncoderV1 = {
|
|
218
|
+
schema: "qualified-encoder-v1",
|
|
219
|
+
modelVersion: candidate.modelVersion,
|
|
220
|
+
mode: "A",
|
|
221
|
+
// The REAL ModelManifestV1 asset-manifest digest (passed through the
|
|
222
|
+
// candidate), not a calibration-derived hash — matches the documented
|
|
223
|
+
// contract and the dashboard health card's encoderAssetDigest.
|
|
224
|
+
assetDigest: candidate.assetManifestDigest,
|
|
225
|
+
calibrationDigest: candidate.calibration.calibrationSplitDigest,
|
|
226
|
+
onnxDigest: candidate.onnxDigest,
|
|
227
|
+
heldOut: candidate.heldOut,
|
|
228
|
+
calibration: candidate.calibration,
|
|
229
|
+
};
|
|
230
|
+
reporter.qualificationPassed({
|
|
231
|
+
modelVersion: candidate.modelVersion,
|
|
232
|
+
mode: "A",
|
|
233
|
+
assetDigest: qualified.assetDigest.slice(0, 12),
|
|
234
|
+
calibrationDigest: qualified.calibrationDigest.slice(0, 12),
|
|
235
|
+
});
|
|
236
|
+
return { ok: true, mode: "A", qualified, code: null };
|
|
237
|
+
}
|
|
@@ -273,3 +273,119 @@ export const ENC2B_IDS: readonly string[] = [
|
|
|
273
273
|
"ENC-015",
|
|
274
274
|
"ENC-016",
|
|
275
275
|
];
|
|
276
|
+
|
|
277
|
+
// ---------------------------------------------------------------------------
|
|
278
|
+
// VC2C — encoder qualification + calibration (QualifiedEncoderV1 / CalibrationV1).
|
|
279
|
+
// ---------------------------------------------------------------------------
|
|
280
|
+
|
|
281
|
+
/**
|
|
282
|
+
* Held-out metrics recorded as qualification evidence for a candidate asset
|
|
283
|
+
* (EVALUATION.md §metrics). Semantic metrics are Spearman rho + recall@10;
|
|
284
|
+
* dependency directed precision/recall; contradiction precision/recall/ECE;
|
|
285
|
+
* cache precision/recall; payload-routing macro-F1 + exact/anchor recall;
|
|
286
|
+
* reconstruction is the binary causality/exact/closure/task-success set. The
|
|
287
|
+
* qualification decision (task 3 `select.ts`) consumes ONLY the per-head rows
|
|
288
|
+
* this record carries; the true EVALUATION thresholds are the normative
|
|
289
|
+
* constants in MODEL_ASSET (mirrored in `EVALUATION_THRESHOLDS` below).
|
|
290
|
+
*/
|
|
291
|
+
export interface EncoderHeldOutMetrics {
|
|
292
|
+
/** Semantic: Spearman rho (>= .75) and recall@10 (>= .90). */
|
|
293
|
+
readonly semantic: { readonly spearman: number; readonly recallAt10: number };
|
|
294
|
+
/** Dependency: directed precision (>= .97) and recall (>= .95). */
|
|
295
|
+
readonly dependency: { readonly precision: number; readonly recall: number };
|
|
296
|
+
/** Contradiction: precision (>= .98), recall (>= .90), ECE (<= .05). */
|
|
297
|
+
readonly contradiction: { readonly precision: number; readonly recall: number; readonly ece: number };
|
|
298
|
+
/** Cache: precision (>= .999, zero false-stable) and recall (>= .90). */
|
|
299
|
+
readonly cacheStability: { readonly precision: number; readonly recall: number };
|
|
300
|
+
/** Payload routing: macro-F1 (>= .97) and exact/anchor recall (1.0). */
|
|
301
|
+
readonly payloadRouting: { readonly macroF1: number; readonly exactAnchorRecall: number };
|
|
302
|
+
/** Reconstruction: binary gates — zero causal/tool/anchor/exact violations. */
|
|
303
|
+
readonly reconstruction: {
|
|
304
|
+
readonly votesOk: boolean;
|
|
305
|
+
readonly dependencyClosureRecall: number;
|
|
306
|
+
readonly taskSuccessNonInferior: boolean;
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/** Normative per-head + asset qualification thresholds (MODEL_ASSET §qualification
|
|
311
|
+
* + EVALUATION.md §metrics). These are the constants `select.ts` evaluates the
|
|
312
|
+
* candidate's held-out metrics against (task 3 atomic check). */
|
|
313
|
+
export const EVALUATION_THRESHOLDS = {
|
|
314
|
+
semantic: { spearman: 0.75, recallAt10: 0.9 },
|
|
315
|
+
dependency: { precision: 0.97, recall: 0.95 },
|
|
316
|
+
contradiction: { precision: 0.98, recall: 0.9, ece: 0.05 },
|
|
317
|
+
cacheStability: { precision: 0.999, recall: 0.9 },
|
|
318
|
+
payloadRouting: { macroF1: 0.97, exactAnchorRecall: 1.0 },
|
|
319
|
+
reconstruction: { dependencyClosureRecall: 1.0 },
|
|
320
|
+
asset: { maxTokens: 512, maxLatencyP95Ms: 40, maxRssDeltaMib: 150 },
|
|
321
|
+
} as const;
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* CalibrationV1 — fitted temperature/isotonic calibration, frozen on the
|
|
325
|
+
* CALIBRATION split only (VC2C task 2). Held-out test labels NEVER enter the
|
|
326
|
+
* fit inputs (calibration-fit prohibition). The split digest proves the exact
|
|
327
|
+
* calibration assignment (grouped by repository+session); the frozen temp/threshold
|
|
328
|
+
* values are what `select.ts` stamps into a `QualifiedEncoderV1`.
|
|
329
|
+
*/
|
|
330
|
+
export interface CalibrationV1 {
|
|
331
|
+
readonly schema: "calibration-v1";
|
|
332
|
+
readonly headOrder: readonly EncoderHeadName[];
|
|
333
|
+
/** SHA-256 of the calibration split assignment (grouped repository+session). */
|
|
334
|
+
readonly calibrationSplitDigest: string;
|
|
335
|
+
/** Fitted on the calibration split only; held-out labels excluded from fit. */
|
|
336
|
+
readonly fittedOnCalibrationOnly: true;
|
|
337
|
+
/** Frozen per-head temperature (isotonic calibration reference points). */
|
|
338
|
+
readonly temperatures: Readonly<Record<EncoderHeadName, number>>;
|
|
339
|
+
/** Frozen per-head decision thresholds for the qualified decision. */
|
|
340
|
+
readonly thresholds: Readonly<Record<EncoderHeadName, number>>;
|
|
341
|
+
/** Seed of the deterministic calibration fit. */
|
|
342
|
+
readonly seed: number;
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* QualifiedEncoderV1 — the VC2C-owned eligibility record (mode A). Produced by
|
|
347
|
+
* `select.ts` ONLY when EVERY MODEL_ASSET + per-head EVALUATION threshold
|
|
348
|
+
* passes (atomic — one failed field demotes all of A). Pins the asset digest,
|
|
349
|
+
* the calibration digest, the held-out metrics that justified eligibility, and
|
|
350
|
+
* the calibration reference, so VC3A receives a fully self-describing candidate.
|
|
351
|
+
*/
|
|
352
|
+
export interface QualifiedEncoderV1 {
|
|
353
|
+
readonly schema: "qualified-encoder-v1";
|
|
354
|
+
readonly modelVersion: string;
|
|
355
|
+
readonly mode: "A";
|
|
356
|
+
/** SHA-256 of the asset manifest bytes (ModelManifestV1) that qualified.
|
|
357
|
+
* Identical semantics to the dashboard health card's `encoderAssetDigest`
|
|
358
|
+
* (both hash the committed manifest.json ModelManifestV1 bytes), so
|
|
359
|
+
* downstream consumers (VC3A) pin the same digest across the seam. */
|
|
360
|
+
readonly assetDigest: string;
|
|
361
|
+
/** SHA-256 of the calibration split assignment (grouped repository+session)
|
|
362
|
+
* that the CalibrationV1 was fitted on — the calibration's core identity. */
|
|
363
|
+
readonly calibrationDigest: string;
|
|
364
|
+
/** SHA-256 of the qualified asset's verified ONNX bytes (digest-pinned). */
|
|
365
|
+
readonly onnxDigest: string;
|
|
366
|
+
/** Held-out metrics recorded as the eligibility evidence. */
|
|
367
|
+
readonly heldOut: EncoderHeldOutMetrics;
|
|
368
|
+
/** Calibration reference this qualification is grounded in. */
|
|
369
|
+
readonly calibration: CalibrationV1;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/** VC2C-specific qualification failure codes (returned, never thrown). */
|
|
373
|
+
export const ENC_QUALIFICATION_FAIL = {
|
|
374
|
+
/** The qualification manifest hash does not match the calibration that was fit
|
|
375
|
+
* (corrupt qualification manifest after calibration before selection). */
|
|
376
|
+
DIGEST_MISMATCH: "ENC_QUALIFICATION_DIGEST_MISMATCH",
|
|
377
|
+
/** One or more per-head EVALUATION thresholds failed (demotes all of A). */
|
|
378
|
+
THRESHOLD_FAILED: "ENC_QUALIFICATION_THRESHOLD_FAILED",
|
|
379
|
+
/** An asset-field qualification check (asset/latency/RSS) failed. */
|
|
380
|
+
ASSET_FAILED: "ENC_QUALIFICATION_ASSET_FAILED",
|
|
381
|
+
/** Calibration was attempted using held-out labels (fit prohibition). */
|
|
382
|
+
HELD_OUT_IN_FIT: "ENC_QUALIFICATION_HELD_OUT_IN_FIT",
|
|
383
|
+
} as const;
|
|
384
|
+
|
|
385
|
+
/** The 4 registered VC2C conformance IDs (task 1: "register ENC-017..020"). */
|
|
386
|
+
export const ENC2C_IDS: readonly string[] = [
|
|
387
|
+
"ENC-017",
|
|
388
|
+
"ENC-018",
|
|
389
|
+
"ENC-019",
|
|
390
|
+
"ENC-020",
|
|
391
|
+
];
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"VectorCortexTab-DD1CMK80.js","sources":["../../src/api/vector-cortex.ts","../../src/tabs/VectorCortexTab.tsx"],"sourcesContent":["/**\n * dashboard-client/src/api/vector-cortex.ts — vector-cortex API client.\n * PREVENT-PI-004: relative path only (loopback dashboard).\n */\n\nimport type {\n\tVectorCortexEvaluationSummary,\n\tVectorCortexHealthCard,\n\tVectorCortexLedgerView,\n\tVectorCortexResetResult,\n} from \"../types/vector-cortex\";\n\nexport type {\n\tVectorCortexEvaluationSummary,\n\tVectorCortexHealthCard,\n\tVectorCortexLedgerView,\n\tVectorCortexResetResult,\n};\n\nexport async function fetchVectorCortexEvaluation(): Promise<VectorCortexEvaluationSummary> {\n\tconst r = await fetch(\"/api/vector-cortex/evaluation\");\n\tif (!r.ok) throw new Error(`vector-cortex evaluation: ${r.status}`);\n\treturn r.json() as Promise<VectorCortexEvaluationSummary>;\n}\n\nexport async function fetchVectorCortexHealth(): Promise<VectorCortexHealthCard> {\n\tconst r = await fetch(\"/api/vector-cortex/health\");\n\tif (!r.ok) throw new Error(`vector-cortex health: ${r.status}`);\n\treturn r.json() as Promise<VectorCortexHealthCard>;\n}\n\n/** Reader-only occurrence-ledger identity view (VC1B). */\nexport async function fetchVectorCortexLedger(\n\tsession = \"default\",\n): Promise<VectorCortexLedgerView> {\n\tconst r = await fetch(\n\t\t`/api/vector-cortex/ledger?session=${encodeURIComponent(session)}`,\n\t);\n\tif (!r.ok) throw new Error(`vector-cortex ledger: ${r.status}`);\n\treturn r.json() as Promise<VectorCortexLedgerView>;\n}\n\n/** Admin capability: reset a breaker's cooldown (never evidence). */\nexport async function resetVectorCortexBreaker(\n\tsubsystem: string,\n): Promise<VectorCortexResetResult> {\n\tconst r = await fetch(\"/api/vector-cortex/breakers/reset\", {\n\t\tmethod: \"POST\",\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\tbody: JSON.stringify({ subsystem }),\n\t});\n\tif (!r.ok) throw new Error(`vector-cortex reset: ${r.status}`);\n\treturn r.json() as Promise<VectorCortexResetResult>;\n}\n","/**\n * VectorCortexTab.tsx — vector-cortex dashboard tab.\n * VC0A: reader-only aggregate latency histogram + per-mode sample counts from\n * GET /api/vector-cortex/evaluation. VC0C (task 5): live safety envelope health\n * card (breaker state, window/probe/backoff, durable spool frontier/lag) from\n * GET /api/vector-cortex/health plus an admin \"reset cooldown\" action. Polls\n * every 5s.\n */\n\nimport { useState, useEffect, useCallback } from \"react\";\nimport {\n\tfetchVectorCortexEvaluation,\n\tfetchVectorCortexHealth,\n\tfetchVectorCortexLedger,\n\tresetVectorCortexBreaker,\n\ttype VectorCortexEvaluationSummary,\n\ttype VectorCortexHealthCard,\n\ttype VectorCortexLedgerView,\n} from \"../api/vector-cortex\";\nimport { Card, CardContent, CardHeader, CardTitle } from \"../components/ui/card\";\nimport { Badge } from \"../components/ui/badge\";\n\nfunction ModeChip({ mode, count }: { mode: string; count: number }): React.ReactElement {\n\treturn (\n\t\t<div className=\"flex items-center justify-between border-b border-border/50 py-1 text-sm\">\n\t\t\t<span className=\"text-muted-foreground\">Mode {mode}</span>\n\t\t\t<span className=\"font-mono\">{count}</span>\n\t\t</div>\n\t);\n}\n\nfunction Metric({ label, value }: { label: string; value: string }): React.ReactElement {\n\treturn (\n\t\t<div>\n\t\t\t<div className=\"text-xs text-muted-foreground\">{label}</div>\n\t\t\t<div className=\"font-mono text-sm\">{value}</div>\n\t\t</div>\n\t);\n}\n\nexport default function VectorCortexTab(): React.ReactElement {\n\tconst [data, setData] = useState<VectorCortexEvaluationSummary | null>(null);\n\tconst [err, setError] = useState<string | null>(null);\n\tconst [loading, setLoading] = useState(true);\n\tconst [health, setHealth] = useState<VectorCortexHealthCard | null>(null);\n\tconst [resetMsg, setResetMsg] = useState<string | null>(null);\n\tconst [ledger, setLedger] = useState<VectorCortexLedgerView | null>(null);\n\n\tconst poll = useCallback(() => {\n\t\tfetchVectorCortexEvaluation()\n\t\t\t.then(setData)\n\t\t\t.catch((e: unknown) =>\n\t\t\t\tsetError(e instanceof Error ? e.message : String(e)),\n\t\t\t)\n\t\t\t.finally(() => setLoading(false));\n\t\tfetchVectorCortexHealth().then(setHealth).catch(() => {\n\t\t\t/* health card is best-effort (VC0C) */\n\t\t});\n\t\tfetchVectorCortexLedger().then(setLedger).catch(() => {\n\t\t\t/* ledger card is best-effort (VC1B) */\n\t\t});\n\t}, []);\n\n\tuseEffect(() => {\n\t\tpoll();\n\t\tconst id = setInterval(poll, 5000);\n\t\treturn () => clearInterval(id);\n\t}, [poll]);\n\n\tconst onReset = () => {\n\t\tresetVectorCortexBreaker(\"provider\")\n\t\t\t.then((r) => {\n\t\t\t\tsetResetMsg(\n\t\t\t\t\t`Breaker \"${r.subsystem}\" ${r.state}; evidence retained: ${r.failures} failures / ${r.attempts} attempts`,\n\t\t\t\t);\n\t\t\t\treturn fetchVectorCortexHealth();\n\t\t\t})\n\t\t\t.then(setHealth)\n\t\t\t.catch((e: unknown) =>\n\t\t\t\tsetResetMsg(e instanceof Error ? e.message : String(e)),\n\t\t\t);\n\t};\n\n\tif (loading && !data)\n\t\treturn <div className=\"vc-loading\">Loading vector-cortex evaluation…</div>;\n\tif (err && !data)\n\t\treturn <div className=\"vc-error\">Error: {err}</div>;\n\tif (!data)\n\t\treturn <div className=\"vc-empty\">No evaluation data available.</div>;\n\n\tconst max = Math.max(1, ...data.histogram.cells, data.histogram.overflow);\n\treturn (\n\t\t<div className=\"flex flex-col gap-4\">\n\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t<h2 className=\"text-lg font-semibold\">Vector Cortex Evaluation</h2>\n\t\t\t\t{data.enabled ? (\n\t\t\t\t\t<Badge variant=\"warning\">OBSERVER PENDING (A)</Badge>\n\t\t\t\t) : (\n\t\t\t\t\t<Badge variant=\"danger\">MODE C (OFF)</Badge>\n\t\t\t\t)}\n\t\t\t</div>\n\n\t\t\t<div className=\"grid grid-cols-1 gap-4 md:grid-cols-3\">\n\t\t\t\t<Card>\n\t\t\t\t\t<CardHeader>\n\t\t\t\t\t\t<CardTitle>Samples</CardTitle>\n\t\t\t\t\t</CardHeader>\n\t\t\t\t\t<CardContent>\n\t\t\t\t\t\t<div className=\"text-3xl font-bold\">{data.samples}</div>\n\t\t\t\t\t\t<div className=\"mt-2 flex flex-col\">\n\t\t\t\t\t\t\t<ModeChip mode=\"A\" count={data.byMode.A} />\n\t\t\t\t\t\t\t<ModeChip mode=\"B\" count={data.byMode.B} />\n\t\t\t\t\t\t\t<ModeChip mode=\"C\" count={data.byMode.C} />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</CardContent>\n\t\t\t\t</Card>\n\n\t\t\t\t<Card className=\"md:col-span-2\">\n\t\t\t\t\t<CardHeader>\n\t\t\t\t\t\t<CardTitle>Latency Histogram (ms, inclusive edges)</CardTitle>\n\t\t\t\t\t</CardHeader>\n\t\t\t\t\t<CardContent>\n\t\t\t\t\t\t<div className=\"flex items-end gap-2\" style={{ height: 160 }}>\n\t\t\t\t\t\t\t{data.histogram.edges.map((edge, i) => {\n\t\t\t\t\t\t\t\tconst h = (data.histogram.cells[i] / max) * 140;\n\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t<div key={edge} className=\"flex flex-1 flex-col items-center gap-1\">\n\t\t\t\t\t\t\t\t\t\t<span className=\"text-xs text-muted-foreground\">\n\t\t\t\t\t\t\t\t\t\t\t{data.histogram.cells[i]}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\tclassName=\"w-full rounded-t\"\n\t\t\t\t\t\t\t\t\t\t\tstyle={{ height: Math.max(2, h), background: \"#6366f1\" }}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t<span className=\"text-[10px] text-muted-foreground\">≤{edge}</span>\n\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t<div className=\"flex flex-1 flex-col items-center gap-1\">\n\t\t\t\t\t\t\t\t<span className=\"text-xs text-muted-foreground\">\n\t\t\t\t\t\t\t\t\t{data.histogram.overflow}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\tclassName=\"w-full rounded-t\"\n\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\theight: Math.max(2, (data.histogram.overflow / max) * 140),\n\t\t\t\t\t\t\t\t\t\tbackground: \"#f87171\",\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t<span className=\"text-[10px] text-muted-foreground\">>250</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<div className=\"mt-1 text-xs text-muted-foreground\">\n\t\t\t\t\t\t\tTotal: {data.histogram.total} · Rejects: {data.rejects.length}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</CardContent>\n\t\t\t\t</Card>\n\t\t\t</div>\n\n\t\t\t<Card>\n\t\t\t\t<CardHeader>\n\t\t\t\t\t<div className=\"flex items-center justify-between\">\n\t\t\t\t\t\t<CardTitle>Live Safety Envelope (VC0C)</CardTitle>\n\t\t\t\t\t\t<div className=\"flex items-center gap-2\">\n\t\t\t\t\t\t\t{health?.stateSource === \"ephemeral\" && (\n\t\t\t\t\t\t\t\t<Badge variant=\"outline\">EPHEMERAL (non-live)</Badge>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\tonClick={onReset}\n\t\t\t\t\t\t\t\tdisabled={!health?.enabled}\n\t\t\t\t\t\t\t\tclassName=\"rounded border border-border px-2 py-1 text-xs disabled:opacity-50\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\tReset Cooldown\n\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t</CardHeader>\n\t\t\t\t<CardContent>\n\t\t\t\t\t{resetMsg && (\n\t\t\t\t\t\t<div className=\"mb-2 text-xs text-muted-foreground\">{resetMsg}</div>\n\t\t\t\t\t)}\n\t\t\t\t\t{!health ? (\n\t\t\t\t\t\t<div className=\"vc-empty\">Health unavailable (VC0C off).</div>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<div className=\"grid grid-cols-2 gap-4 md:grid-cols-4\">\n\t\t\t\t\t\t\t<Metric label=\"State\" value={health.state} />\n\t\t\t\t\t\t\t<Metric label=\"Mode\" value={health.mode} />\n\t\t\t\t\t\t\t<Metric label=\"Window\" value={`${health.windowMs}ms`} />\n\t\t\t\t\t\t\t<Metric label=\"Probes\" value={String(health.probeCount)} />\n\t\t\t\t\t\t\t<Metric label=\"Backoff\" value={`${health.backoffDelayMs}ms`} />\n\t\t\t\t\t\t\t<Metric\n\t\t\t\t\t\t\t\tlabel=\"Failures\"\n\t\t\t\t\t\t\t\tvalue={`${health.failures}/${health.attempts}`}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<Metric\n\t\t\t\t\t\t\t\tlabel=\"Frontier\"\n\t\t\t\t\t\t\t\tvalue={\n\t\t\t\t\t\t\t\t\thealth.stateSource === \"ephemeral\"\n\t\t\t\t\t\t\t\t\t\t? \"non-live\"\n\t\t\t\t\t\t\t\t\t\t: health.frontierFrozen\n\t\t\t\t\t\t\t\t\t\t\t? \"FROZEN\"\n\t\t\t\t\t\t\t\t\t\t\t: \"LIVE\"\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t<Metric label=\"Spool lag\" value={String(health.spoolLag)} />\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t</CardContent>\n\t\t\t</Card>\n\t\t\t<Card>\n\t\t\t\t<CardHeader>\n\t\t\t\t\t<div className=\"flex items-center justify-between\">\n\t\t\t\t\t\t<CardTitle>Occurrence Ledger (VC1B)</CardTitle>\n\t\t\t\t\t\t{ledger?.enabled ? (\n\t\t\t\t\t\t\t<Badge variant=\"success\">ACTIVE</Badge>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<Badge variant=\"danger\">OFF</Badge>\n\t\t\t\t\t\t)}\n\t\t\t\t\t</div>\n\t\t\t\t</CardHeader>\n\t\t\t\t<CardContent>\n\t\t\t\t\t{!ledger?.enabled ? (\n\t\t\t\t\t\t<div className=\"vc-empty\">Ledger disabled (VC1B off).</div>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<>\n\t\t\t\t\t\t\t<div className=\"mb-3 grid grid-cols-2 gap-4 md:grid-cols-3\">\n\t\t\t\t\t\t\t\t<Metric label=\"Session\" value={ledger.session} />\n\t\t\t\t\t\t\t\t<Metric label=\"High-water\" value={ledger.highWater} />\n\t\t\t\t\t\t\t\t<Metric label=\"Occurrences\" value={String(ledger.count)} />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t{ledger.occurrences.length === 0 ? (\n\t\t\t\t\t\t\t\t<div className=\"vc-empty\">No occurrences recorded.</div>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<div className=\"max-h-64 overflow-y-auto\">\n\t\t\t\t\t\t\t\t\t<table className=\"w-full text-left text-xs\">\n\t\t\t\t\t\t\t\t\t\t<thead>\n\t\t\t\t\t\t\t\t\t\t\t<tr className=\"border-b border-border/50 text-muted-foreground\">\n\t\t\t\t\t\t\t\t\t\t\t\t<th className=\"py-1 pr-2\">seq</th>\n\t\t\t\t\t\t\t\t\t\t\t\t<th className=\"py-1 pr-2\">eventId</th>\n\t\t\t\t\t\t\t\t\t\t\t\t<th className=\"py-1 pr-2\">kind</th>\n\t\t\t\t\t\t\t\t\t\t\t\t<th className=\"py-1 pr-2\">toolCall</th>\n\t\t\t\t\t\t\t\t\t\t\t\t<th className=\"py-1\">digest</th>\n\t\t\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t\t\t</thead>\n\t\t\t\t\t\t\t\t\t\t<tbody>\n\t\t\t\t\t\t\t\t\t\t\t{ledger.occurrences.map((o) => (\n\t\t\t\t\t\t\t\t\t\t\t\t<tr\n\t\t\t\t\t\t\t\t\t\t\t\t\tkey={`${o.seq}-${o.eventId}`}\n\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"border-b border-border/30\"\n\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<td className=\"py-1 pr-2 font-mono\">{o.seq}</td>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<td className=\"py-1 pr-2 font-mono\">{o.eventId}</td>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<td className=\"py-1 pr-2\">{o.kind}</td>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<td className=\"py-1 pr-2 font-mono\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{o.toolCallId ?? \"\\u2014\"}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<td className=\"max-w-[180px] truncate font-mono text-muted-foreground\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{o.digest}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</td>\n\t\t\t\t\t\t\t\t\t\t\t\t</tr>\n\t\t\t\t\t\t\t\t\t\t\t))}\n\t\t\t\t\t\t\t\t\t\t</tbody>\n\t\t\t\t\t\t\t\t\t</table>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</>\n\t\t\t\t\t)}\n\t\t\t\t</CardContent>\n\t\t\t</Card>\n\t\t</div>\n\t);\n}\n"],"names":["fetchVectorCortexEvaluation","r","fetchVectorCortexHealth","fetchVectorCortexLedger","session","resetVectorCortexBreaker","subsystem","ModeChip","mode","count","jsxs","jsx","Metric","label","value","VectorCortexTab","data","setData","useState","err","setError","loading","setLoading","health","setHealth","resetMsg","setResetMsg","ledger","setLedger","poll","useCallback","e","useEffect","id","onReset","max","Badge","Card","CardHeader","CardTitle","CardContent","edge","i","h","Fragment","o"],"mappings":"kHAmBA,eAAsBA,GAAsE,CAC3F,MAAMC,EAAI,MAAM,MAAM,+BAA+B,EACrD,GAAI,CAACA,EAAE,GAAI,MAAM,IAAI,MAAM,6BAA6BA,EAAE,MAAM,EAAE,EAClE,OAAOA,EAAE,KAAA,CACV,CAEA,eAAsBC,GAA2D,CAChF,MAAMD,EAAI,MAAM,MAAM,2BAA2B,EACjD,GAAI,CAACA,EAAE,GAAI,MAAM,IAAI,MAAM,yBAAyBA,EAAE,MAAM,EAAE,EAC9D,OAAOA,EAAE,KAAA,CACV,CAGA,eAAsBE,EACrBC,EAAU,UACwB,CAClC,MAAM,EAAI,MAAM,MACf,qCAAqC,mBAAmBA,CAAO,CAAC,EAAA,EAEjE,GAAI,CAAC,EAAE,GAAI,MAAM,IAAI,MAAM,yBAAyB,EAAE,MAAM,EAAE,EAC9D,OAAO,EAAE,KAAA,CACV,CAGA,eAAsBC,EACrBC,EACmC,CACnC,MAAM,EAAI,MAAM,MAAM,oCAAqC,CAC1D,OAAQ,OACR,QAAS,CAAE,eAAgB,kBAAA,EAC3B,KAAM,KAAK,UAAU,CAAE,UAAAA,EAAW,CAAA,CAClC,EACD,GAAI,CAAC,EAAE,GAAI,MAAM,IAAI,MAAM,wBAAwB,EAAE,MAAM,EAAE,EAC7D,OAAO,EAAE,KAAA,CACV,CC/BA,SAASC,EAAS,CAAE,KAAAC,EAAM,MAAAC,GAA8D,CACvF,OACCC,EAAAA,KAAC,MAAA,CAAI,UAAU,2EACd,SAAA,CAAAA,EAAAA,KAAC,OAAA,CAAK,UAAU,wBAAwB,SAAA,CAAA,QAAMF,CAAA,EAAK,EACnDG,EAAAA,IAAC,OAAA,CAAK,UAAU,YAAa,SAAAF,CAAA,CAAM,CAAA,EACpC,CAEF,CAEA,SAASG,EAAO,CAAE,MAAAC,EAAO,MAAAC,GAA+D,CACvF,cACE,MAAA,CACA,SAAA,CAAAH,EAAAA,IAAC,MAAA,CAAI,UAAU,gCAAiC,SAAAE,EAAM,EACtDF,EAAAA,IAAC,MAAA,CAAI,UAAU,oBAAqB,SAAAG,CAAA,CAAM,CAAA,EAC3C,CAEF,CAEA,SAAwBC,GAAsC,CAC7D,KAAM,CAACC,EAAMC,CAAO,EAAIC,EAAAA,SAA+C,IAAI,EACrE,CAACC,EAAKC,CAAQ,EAAIF,EAAAA,SAAwB,IAAI,EAC9C,CAACG,EAASC,CAAU,EAAIJ,EAAAA,SAAS,EAAI,EACrC,CAACK,EAAQC,CAAS,EAAIN,EAAAA,SAAwC,IAAI,EAClE,CAACO,EAAUC,CAAW,EAAIR,EAAAA,SAAwB,IAAI,EACtD,CAACS,EAAQC,CAAS,EAAIV,EAAAA,SAAwC,IAAI,EAElEW,EAAOC,EAAAA,YAAY,IAAM,CAC9B9B,IACE,KAAKiB,CAAO,EACZ,MAAOc,GACPX,EAASW,aAAa,MAAQA,EAAE,QAAU,OAAOA,CAAC,CAAC,CAAA,EAEnD,QAAQ,IAAMT,EAAW,EAAK,CAAC,EACjCpB,EAAA,EAA0B,KAAKsB,CAAS,EAAE,MAAM,IAAM,CAEtD,CAAC,EACDrB,EAAA,EAA0B,KAAKyB,CAAS,EAAE,MAAM,IAAM,CAEtD,CAAC,CACF,EAAG,CAAA,CAAE,EAELI,EAAAA,UAAU,IAAM,CACfH,EAAA,EACA,MAAMI,EAAK,YAAYJ,EAAM,GAAI,EACjC,MAAO,IAAM,cAAcI,CAAE,CAC9B,EAAG,CAACJ,CAAI,CAAC,EAET,MAAMK,EAAU,IAAM,CACrB7B,EAAyB,UAAU,EACjC,KAAMJ,IACNyB,EACC,YAAYzB,EAAE,SAAS,KAAKA,EAAE,KAAK,wBAAwBA,EAAE,QAAQ,eAAeA,EAAE,QAAQ,WAAA,EAExFC,EAAA,EACP,EACA,KAAKsB,CAAS,EACd,MAAOO,GACPL,EAAYK,aAAa,MAAQA,EAAE,QAAU,OAAOA,CAAC,CAAC,CAAA,CAEzD,EAEA,GAAIV,GAAW,CAACL,EACf,OAAOL,EAAAA,IAAC,MAAA,CAAI,UAAU,aAAa,SAAA,oCAAiC,EACrE,GAAIQ,GAAO,CAACH,EACX,OAAON,EAAAA,KAAC,MAAA,CAAI,UAAU,WAAW,SAAA,CAAA,UAAQS,CAAA,EAAI,EAC9C,GAAI,CAACH,EACJ,OAAOL,EAAAA,IAAC,MAAA,CAAI,UAAU,WAAW,SAAA,gCAA6B,EAE/D,MAAMwB,EAAM,KAAK,IAAI,EAAG,GAAGnB,EAAK,UAAU,MAAOA,EAAK,UAAU,QAAQ,EACxE,OACCN,EAAAA,KAAC,MAAA,CAAI,UAAU,sBACd,SAAA,CAAAA,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACd,SAAA,CAAAC,EAAAA,IAAC,KAAA,CAAG,UAAU,wBAAwB,SAAA,2BAAwB,EAC7DK,EAAK,QACLL,EAAAA,IAACyB,EAAA,CAAM,QAAQ,UAAU,SAAA,sBAAA,CAAoB,EAE7CzB,EAAAA,IAACyB,EAAA,CAAM,QAAQ,SAAS,SAAA,cAAA,CAAY,CAAA,EAEtC,EAEA1B,EAAAA,KAAC,MAAA,CAAI,UAAU,wCACd,SAAA,CAAAA,OAAC2B,EAAA,CACA,SAAA,CAAA1B,MAAC2B,EAAA,CACA,SAAA3B,EAAAA,IAAC4B,EAAA,CAAU,SAAA,SAAA,CAAO,EACnB,SACCC,EAAA,CACA,SAAA,CAAA7B,EAAAA,IAAC,MAAA,CAAI,UAAU,qBAAsB,SAAAK,EAAK,QAAQ,EAClDN,EAAAA,KAAC,MAAA,CAAI,UAAU,qBACd,SAAA,CAAAC,MAACJ,GAAS,KAAK,IAAI,MAAOS,EAAK,OAAO,EAAG,QACxCT,EAAA,CAAS,KAAK,IAAI,MAAOS,EAAK,OAAO,EAAG,QACxCT,EAAA,CAAS,KAAK,IAAI,MAAOS,EAAK,OAAO,CAAA,CAAG,CAAA,CAAA,CAC1C,CAAA,CAAA,CACD,CAAA,EACD,EAEAN,EAAAA,KAAC2B,EAAA,CAAK,UAAU,gBACf,SAAA,CAAA1B,MAAC2B,EAAA,CACA,SAAA3B,EAAAA,IAAC4B,EAAA,CAAU,SAAA,yCAAA,CAAuC,EACnD,SACCC,EAAA,CACA,SAAA,CAAA9B,OAAC,OAAI,UAAU,uBAAuB,MAAO,CAAE,OAAQ,KACrD,SAAA,CAAAM,EAAK,UAAU,MAAM,IAAI,CAACyB,EAAMC,IAAM,CACtC,MAAMC,EAAK3B,EAAK,UAAU,MAAM0B,CAAC,EAAIP,EAAO,IAC5C,OACCzB,EAAAA,KAAC,MAAA,CAAe,UAAU,0CACzB,SAAA,CAAAC,EAAAA,IAAC,QAAK,UAAU,gCACd,WAAK,UAAU,MAAM+B,CAAC,EACxB,EACA/B,EAAAA,IAAC,MAAA,CACA,UAAU,mBACV,MAAO,CAAE,OAAQ,KAAK,IAAI,EAAGgC,CAAC,EAAG,WAAY,SAAA,CAAU,CAAA,EAExDjC,EAAAA,KAAC,OAAA,CAAK,UAAU,oCAAoC,SAAA,CAAA,IAAK+B,CAAA,CAAA,CAAK,CAAA,CAAA,EARrDA,CASV,CAEF,CAAC,EACD/B,EAAAA,KAAC,MAAA,CAAI,UAAU,0CACd,SAAA,CAAAC,MAAC,OAAA,CAAK,UAAU,gCACd,SAAAK,EAAK,UAAU,SACjB,EACAL,EAAAA,IAAC,MAAA,CACA,UAAU,mBACV,MAAO,CACN,OAAQ,KAAK,IAAI,EAAIK,EAAK,UAAU,SAAWmB,EAAO,GAAG,EACzD,WAAY,SAAA,CACb,CAAA,EAEDxB,EAAAA,IAAC,OAAA,CAAK,UAAU,oCAAoC,SAAA,MAAA,CAAO,CAAA,CAAA,CAC5D,CAAA,EACD,EACAD,EAAAA,KAAC,MAAA,CAAI,UAAU,qCAAqC,SAAA,CAAA,UAC3CM,EAAK,UAAU,MAAM,eAAaA,EAAK,QAAQ,MAAA,CAAA,CACxD,CAAA,CAAA,CACD,CAAA,CAAA,CACD,CAAA,EACD,SAECqB,EAAA,CACA,SAAA,CAAA1B,MAAC2B,EAAA,CACA,SAAA5B,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACd,SAAA,CAAAC,EAAAA,IAAC4B,GAAU,SAAA,6BAAA,CAA2B,EACtC7B,EAAAA,KAAC,MAAA,CAAI,UAAU,0BACb,SAAA,CAAAa,GAAQ,cAAgB,aACxBZ,MAACyB,EAAA,CAAM,QAAQ,UAAU,SAAA,uBAAoB,EAE9CzB,EAAAA,IAAC,SAAA,CACA,QAASuB,EACT,SAAU,CAACX,GAAQ,QACnB,UAAU,qEACV,SAAA,gBAAA,CAAA,CAED,CAAA,CACD,CAAA,CAAA,CACD,CAAA,CACD,SACCiB,EAAA,CACC,SAAA,CAAAf,GACAd,EAAAA,IAAC,MAAA,CAAI,UAAU,qCAAsC,SAAAc,EAAS,EAE7DF,EAGDb,EAAAA,KAAC,MAAA,CAAI,UAAU,wCACd,SAAA,CAAAC,EAAAA,IAACC,EAAA,CAAO,MAAM,QAAQ,MAAOW,EAAO,MAAO,QAC1CX,EAAA,CAAO,MAAM,OAAO,MAAOW,EAAO,KAAM,EACzCZ,EAAAA,IAACC,GAAO,MAAM,SAAS,MAAO,GAAGW,EAAO,QAAQ,KAAM,EACtDZ,MAACC,GAAO,MAAM,SAAS,MAAO,OAAOW,EAAO,UAAU,EAAG,EACzDZ,EAAAA,IAACC,GAAO,MAAM,UAAU,MAAO,GAAGW,EAAO,cAAc,KAAM,EAC7DZ,EAAAA,IAACC,EAAA,CACA,MAAM,WACN,MAAO,GAAGW,EAAO,QAAQ,IAAIA,EAAO,QAAQ,EAAA,CAAA,EAE7CZ,EAAAA,IAACC,EAAA,CACA,MAAM,WACN,MACCW,EAAO,cAAgB,YACpB,WACAA,EAAO,eACN,SACA,MAAA,CAAA,EAGNZ,MAACC,GAAO,MAAM,YAAY,MAAO,OAAOW,EAAO,QAAQ,CAAA,CAAG,CAAA,CAAA,CAC3D,EAvBAZ,EAAAA,IAAC,MAAA,CAAI,UAAU,WAAW,SAAA,gCAAA,CAA8B,CAuBxD,CAAA,CAEF,CAAA,EACD,SACC0B,EAAA,CACA,SAAA,CAAA1B,MAAC2B,EAAA,CACA,SAAA5B,EAAAA,KAAC,MAAA,CAAI,UAAU,oCACd,SAAA,CAAAC,EAAAA,IAAC4B,GAAU,SAAA,0BAAA,CAAwB,EAClCZ,GAAQ,QACRhB,EAAAA,IAACyB,EAAA,CAAM,QAAQ,UAAU,SAAA,QAAA,CAAM,EAE/BzB,EAAAA,IAACyB,EAAA,CAAM,QAAQ,SAAS,SAAA,KAAA,CAAG,CAAA,CAAA,CAE7B,CAAA,CACD,EACAzB,EAAAA,IAAC6B,EAAA,CACC,SAACb,GAAQ,QAGTjB,OAAAkC,EAAAA,SAAA,CACC,SAAA,CAAAlC,EAAAA,KAAC,MAAA,CAAI,UAAU,6CACd,SAAA,CAAAC,EAAAA,IAACC,EAAA,CAAO,MAAM,UAAU,MAAOe,EAAO,QAAS,QAC9Cf,EAAA,CAAO,MAAM,aAAa,MAAOe,EAAO,UAAW,EACpDhB,MAACC,GAAO,MAAM,cAAc,MAAO,OAAOe,EAAO,KAAK,CAAA,CAAG,CAAA,EAC1D,EACCA,EAAO,YAAY,SAAW,EAC9BhB,EAAAA,IAAC,OAAI,UAAU,WAAW,SAAA,0BAAA,CAAwB,QAEjD,MAAA,CAAI,UAAU,2BACd,SAAAD,OAAC,QAAA,CAAM,UAAU,2BAChB,SAAA,CAAAC,MAAC,QAAA,CACA,SAAAD,EAAAA,KAAC,KAAA,CAAG,UAAU,kDACb,SAAA,CAAAC,EAAAA,IAAC,KAAA,CAAG,UAAU,YAAY,SAAA,MAAG,EAC7BA,EAAAA,IAAC,KAAA,CAAG,UAAU,YAAY,SAAA,UAAO,EACjCA,EAAAA,IAAC,KAAA,CAAG,UAAU,YAAY,SAAA,OAAI,EAC9BA,EAAAA,IAAC,KAAA,CAAG,UAAU,YAAY,SAAA,WAAQ,EAClCA,EAAAA,IAAC,KAAA,CAAG,UAAU,OAAO,SAAA,QAAA,CAAM,CAAA,CAAA,CAC5B,CAAA,CACD,QACC,QAAA,CACC,SAAAgB,EAAO,YAAY,IAAKkB,GACxBnC,EAAAA,KAAC,KAAA,CAEA,UAAU,4BAEV,SAAA,CAAAC,EAAAA,IAAC,KAAA,CAAG,UAAU,sBAAuB,SAAAkC,EAAE,IAAI,EAC3ClC,EAAAA,IAAC,KAAA,CAAG,UAAU,sBAAuB,WAAE,QAAQ,EAC/CA,EAAAA,IAAC,KAAA,CAAG,UAAU,YAAa,WAAE,KAAK,QACjC,KAAA,CAAG,UAAU,sBACZ,SAAAkC,EAAE,YAAc,IAClB,EACAlC,EAAAA,IAAC,KAAA,CAAG,UAAU,yDACZ,WAAE,MAAA,CACJ,CAAA,CAAA,EAXK,GAAGkC,EAAE,GAAG,IAAIA,EAAE,OAAO,EAAA,CAa3B,CAAA,CACF,CAAA,CAAA,CACD,CAAA,CACD,CAAA,CAAA,CAEF,EA3CAlC,EAAAA,IAAC,MAAA,CAAI,UAAU,WAAW,SAAA,6BAAA,CAA2B,CA2CrD,CAEF,CAAA,CAAA,CACD,CAAA,EACD,CAEF"}
|