pi-mega-compact 0.20.15 → 0.20.16
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/api-contracts/vector-cortex-diagnostics.js +35 -0
- package/dist/extensions/dashboard-server/route-dispatch.js +6 -1
- package/dist/extensions/dashboard-server/routes-vector-cortex-diagnostics.js +68 -0
- package/dist/src/vector-cortex/cache/_diagnostics-fixture.js +31 -0
- package/dist/src/vector-cortex/cache/breaker.js +110 -0
- package/dist/src/vector-cortex/cache/diagnostics-emit.js +64 -0
- package/dist/src/vector-cortex/cache/diagnostics-types.js +15 -0
- package/dist/src/vector-cortex/cache/diagnostics.js +97 -0
- package/dist/src/vector-cortex/migrations/request-hash-v2-ops.js +17 -6
- package/dist/vector-cortex/cache/_diagnostics-fixture.js +31 -0
- package/dist/vector-cortex/cache/breaker.js +110 -0
- package/dist/vector-cortex/cache/diagnostics-emit.js +64 -0
- package/dist/vector-cortex/cache/diagnostics-types.js +15 -0
- package/dist/vector-cortex/cache/diagnostics.js +97 -0
- package/dist/vector-cortex/migrations/request-hash-v2-ops.js +17 -6
- package/extensions/dashboard-client/dist/assets/{AreaChart-CV8WqMmt.js → AreaChart-B_FKg8xJ.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{AreaChart-CV8WqMmt.js.map → AreaChart-B_FKg8xJ.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{BarChart-M-HEBq9l.js → BarChart-BU5RJ0In.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{BarChart-M-HEBq9l.js.map → BarChart-BU5RJ0In.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{CacheTab-DJ_yPAhP.js → CacheTab-CbX033mt.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{CacheTab-DJ_yPAhP.js.map → CacheTab-CbX033mt.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{EventsTab-DNVlKzt6.js → EventsTab-D8Z_4gSB.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{EventsTab-DNVlKzt6.js.map → EventsTab-D8Z_4gSB.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{HealthTab-B5yjuInb.js → HealthTab-BUUkoQXo.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{HealthTab-B5yjuInb.js.map → HealthTab-BUUkoQXo.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MaintenanceTab-DoQedESF.js → MaintenanceTab-DKZQmY1T.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MaintenanceTab-DoQedESF.js.map → MaintenanceTab-DKZQmY1T.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MemoryMapTab-CuL5CzdH.js → MemoryMapTab-DwMGbe3h.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MemoryMapTab-CuL5CzdH.js.map → MemoryMapTab-DwMGbe3h.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MetricsTab-CZSTaCpK.js → MetricsTab-C85lieXW.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MetricsTab-CZSTaCpK.js.map → MetricsTab-C85lieXW.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{OverviewTab-vkZlXRW6.js → OverviewTab-D7VPibBT.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{OverviewTab-vkZlXRW6.js.map → OverviewTab-D7VPibBT.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{ReposTab-DgPD96rF.js → ReposTab-eIHk_mDG.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{ReposTab-DgPD96rF.js.map → ReposTab-eIHk_mDG.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{SessionsTab-XPbWh7XN.js → SessionsTab-EYOHEzc3.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{SessionsTab-XPbWh7XN.js.map → SessionsTab-EYOHEzc3.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{SetupTab-Dz74XAtR.js → SetupTab-DXpiXu4i.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{SetupTab-Dz74XAtR.js.map → SetupTab-DXpiXu4i.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{TimeSavedCard-FynCpJdx.js → TimeSavedCard-DUsUC_sm.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{TimeSavedCard-FynCpJdx.js.map → TimeSavedCard-DUsUC_sm.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{TurnsTab-C7m3GDy0.js → TurnsTab-w7qdB0px.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{TurnsTab-C7m3GDy0.js.map → TurnsTab-w7qdB0px.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/VectorCortexTab-BmgdxV5K.js +2 -0
- package/extensions/dashboard-client/dist/assets/VectorCortexTab-BmgdxV5K.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/{WikiTab-C6viLa0u.js → WikiTab-B4hwpXpw.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{WikiTab-C6viLa0u.js.map → WikiTab-B4hwpXpw.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{button-mBEgbBVU.js → button-BnbvfQjm.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{button-mBEgbBVU.js.map → button-BnbvfQjm.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{card-CalUQAKG.js → card-DCyvWfpF.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{card-CalUQAKG.js.map → card-DCyvWfpF.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-CMmkuwj5.js → generateCategoricalChart-b3HeKJLU.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-CMmkuwj5.js.map → generateCategoricalChart-b3HeKJLU.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{index-Dz8GPBOE.js → index-DhlcXMlE.js} +3 -3
- package/extensions/dashboard-client/dist/assets/{index-Dz8GPBOE.js.map → index-DhlcXMlE.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{switch-8QKO6CTU.js → switch-B74pQOFy.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{switch-8QKO6CTU.js.map → switch-B74pQOFy.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{toggle-9eCkWI4q.js → toggle-bXDrMX-A.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{toggle-9eCkWI4q.js.map → toggle-bXDrMX-A.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{useSSE-s6IqOKoD.js → useSSE-Yq86SUA0.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{useSSE-s6IqOKoD.js.map → useSSE-Yq86SUA0.js.map} +1 -1
- package/extensions/dashboard-client/dist/index.html +1 -1
- package/extensions/dashboard-client/src/tabs/VectorCortexDiagnosticsCard.tsx +46 -0
- package/extensions/dashboard-client/src/tabs/VectorCortexTab.tsx +2 -0
- package/extensions/dashboard-server/api-contracts/vector-cortex-diagnostics.ts +76 -0
- package/extensions/dashboard-server/route-dispatch.ts +5 -1
- package/extensions/dashboard-server/routes-vector-cortex-diagnostics.ts +77 -0
- package/package.json +1 -1
- package/src/vector-cortex/cache/_diagnostics-fixture.ts +32 -0
- package/src/vector-cortex/cache/breaker.ts +124 -0
- package/src/vector-cortex/cache/diagnostics-emit.ts +90 -0
- package/src/vector-cortex/cache/diagnostics-types.ts +87 -0
- package/src/vector-cortex/cache/diagnostics.ts +119 -0
- package/src/vector-cortex/migrations/request-hash-v2-ops.ts +15 -9
- package/extensions/dashboard-client/dist/assets/VectorCortexTab-jRd_Iztk.js +0 -2
- package/extensions/dashboard-client/dist/assets/VectorCortexTab-jRd_Iztk.js.map +0 -1
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dashboard-server/routes-vector-cortex-diagnostics.ts — VC7C cache-diagnostics
|
|
3
|
+
* dashboard route.
|
|
4
|
+
*
|
|
5
|
+
* Reader-only GET /api/vector-cortex/cache-diagnostics returning the cache miss
|
|
6
|
+
* classification aggregate: whether the VC7C flag is enabled, the runtime triad
|
|
7
|
+
* mode, one count per exclusive miss class (profile, range, dependency, request,
|
|
8
|
+
* generation, unknown), how many cache serves the breaker blocked, the breaker
|
|
9
|
+
* state, and the last CACHE/M5 failure code.
|
|
10
|
+
*
|
|
11
|
+
* COUNTS + CODES ONLY. A cache miss diagnostic answers "why did THIS request
|
|
12
|
+
* miss?", so the natural (and forbidden) payload is the request itself: the
|
|
13
|
+
* hashed request bytes, its RequestHashV2 digest, the covered source ranges, the
|
|
14
|
+
* span/covered digests, the provider profile digest, and the session id. This
|
|
15
|
+
* route NEVER exposes any of them — the classification is projected to a count
|
|
16
|
+
* per closed-enumeration class before it reaches the wire (reader-only,
|
|
17
|
+
* SECURITY_PRIVACY). There is no mutation seam: misses are classified and
|
|
18
|
+
* breakers are tripped by the cache serve path, never by a dashboard request,
|
|
19
|
+
* and in particular the breaker can NOT be reset through this route. Non-GET is
|
|
20
|
+
* rejected outright.
|
|
21
|
+
*
|
|
22
|
+
* Split into its own file (rather than grown into routes-vector-cortex-economics.ts)
|
|
23
|
+
* to keep every extensions/ file well under the 400-line soft-as-hard limit.
|
|
24
|
+
*
|
|
25
|
+
* Guardrails: PREVENT-PI-004 (local in-process state only), PREVENT-011 (no
|
|
26
|
+
* `any`), reader-only aggregate (counts + codes only).
|
|
27
|
+
*/
|
|
28
|
+
|
|
29
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
30
|
+
import type { RouteContext } from "./routes-core.js";
|
|
31
|
+
import { VC7C_ENABLED } from "../../src/config.js";
|
|
32
|
+
import { sendJson } from "./routes-vector-cortex-shared.js";
|
|
33
|
+
import type { VectorCortexDiagnosticsView } from "./api-contracts/vector-cortex-diagnostics.js";
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Reader-only GET /api/vector-cortex/cache-diagnostics (VC7C).
|
|
37
|
+
*
|
|
38
|
+
* Per-miss-class counts, breaker state, and CACHE and M5 codes only — a static
|
|
39
|
+
* reader-only aggregate seam with the same shape as the VC7B economics handler.
|
|
40
|
+
*/
|
|
41
|
+
export function handleVectorCortexDiagnostics(
|
|
42
|
+
req: IncomingMessage,
|
|
43
|
+
res: ServerResponse,
|
|
44
|
+
_ctx: RouteContext,
|
|
45
|
+
): boolean {
|
|
46
|
+
const url = req.url ?? "";
|
|
47
|
+
const path = url.split("?")[0] ?? url;
|
|
48
|
+
if (path !== "/api/vector-cortex/cache-diagnostics") return false;
|
|
49
|
+
if (req.method !== "GET") {
|
|
50
|
+
sendJson(res, 405, { error: "method_not_allowed" });
|
|
51
|
+
return true;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const enabled = VC7C_ENABLED();
|
|
55
|
+
// Flag-off routes to mode C: with VC7C off the diagnostics/breaker reporter is
|
|
56
|
+
// suppressed, so no cache serve is attested here and the surface reports the
|
|
57
|
+
// all-cache bypass outcome. Reporting A (crystal served) or B (fresh render
|
|
58
|
+
// forced by a breaker) would attest a cache decision this seam is not wired to
|
|
59
|
+
// observe. Mirrors how the VC7A/VC7B OFF views report the mode they take.
|
|
60
|
+
const mode: "A" | "B" | "C" = enabled ? "A" : "C";
|
|
61
|
+
const body: VectorCortexDiagnosticsView = {
|
|
62
|
+
enabled,
|
|
63
|
+
mode,
|
|
64
|
+
profileMisses: 0,
|
|
65
|
+
rangeMisses: 0,
|
|
66
|
+
dependencyMisses: 0,
|
|
67
|
+
requestMisses: 0,
|
|
68
|
+
generationMisses: 0,
|
|
69
|
+
unknownMisses: 0,
|
|
70
|
+
serveBlocked: 0,
|
|
71
|
+
breakerState: "closed",
|
|
72
|
+
lastFailure: null,
|
|
73
|
+
updatedAt: new Date().toISOString(),
|
|
74
|
+
};
|
|
75
|
+
sendJson(res, 200, body);
|
|
76
|
+
return true;
|
|
77
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-mega-compact",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.16",
|
|
4
4
|
"description": "Layered, local, vector-backed context compressor for pi — supersede/collapse/cluster compaction with deduped inline recall.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "BSD-3-Clause",
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cache/_diagnostics-fixture.ts — VC7C acceptance-test fixture helpers.
|
|
3
|
+
*
|
|
4
|
+
* Reads conformance fixtures from the v2 `cache-diagnostics/` domain and provides
|
|
5
|
+
* a flag-toggling wrapper for VC7C parity tests. Mirrors `_economics-fixture.ts`.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { readFileSync } from "node:fs";
|
|
9
|
+
import { join, dirname } from "node:path";
|
|
10
|
+
import { fileURLToPath } from "node:url";
|
|
11
|
+
|
|
12
|
+
const here = dirname(fileURLToPath(import.meta.url));
|
|
13
|
+
const V2 = join(here, "..", "..", "..", "conformance", "vector-cortex", "v2");
|
|
14
|
+
const DIR = join(V2, "cache-diagnostics");
|
|
15
|
+
|
|
16
|
+
/** Read + parse one conformance fixture by ID. */
|
|
17
|
+
export function diagnosticsFixture(id: string): Record<string, unknown> {
|
|
18
|
+
const raw = readFileSync(join(DIR, `${id}.json`), "utf8");
|
|
19
|
+
return JSON.parse(raw);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/** Run `fn` with MEGACOMPACT_VC7C set to `value`, restoring the prior value after. */
|
|
23
|
+
export function withVc7cFlag<T>(value: string, fn: () => T): T {
|
|
24
|
+
const prior = process.env.MEGACOMPACT_VC7C;
|
|
25
|
+
process.env.MEGACOMPACT_VC7C = value;
|
|
26
|
+
try {
|
|
27
|
+
return fn();
|
|
28
|
+
} finally {
|
|
29
|
+
if (prior === undefined) delete process.env.MEGACOMPACT_VC7C;
|
|
30
|
+
else process.env.MEGACOMPACT_VC7C = prior;
|
|
31
|
+
}
|
|
32
|
+
}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cache/breaker.ts — VC7C cache-serve breaker (composes VC0C's createBreaker).
|
|
3
|
+
*
|
|
4
|
+
* This file does NOT reinvent a state machine. It wraps the TRIAD breaker from
|
|
5
|
+
* `../resilience/breaker-core.js` (VC0C) — the same CLOSED_A / OPEN_B / OPEN_C /
|
|
6
|
+
* PROBE_* / MANUAL_HALT states that protect every other subsystem — and adds the
|
|
7
|
+
* ONE cache-specific decision: whether a classified miss should block a cache
|
|
8
|
+
* SERVE before it can answer from a stale or invalid identity.
|
|
9
|
+
*
|
|
10
|
+
* TRIP KIND CLASSIFICATION (per team-lead correction + TRIAD_RESILIENCE §breaker):
|
|
11
|
+
* The four cache demotion conditions map onto `BreakerTripKind` as follows:
|
|
12
|
+
*
|
|
13
|
+
* CORRECTNESS trips (trip on the FIRST failure, no rolling window):
|
|
14
|
+
* - profile mismatch — the crystal was minted under a different provider
|
|
15
|
+
* profile; serving it would return bytes for the wrong
|
|
16
|
+
* model tier. This is never "recovered from" by waiting.
|
|
17
|
+
* - range mismatch — the crystal's covered digest differs from the
|
|
18
|
+
* request's; the crystal covers different spans and
|
|
19
|
+
* serving it would return another conversation's frozen
|
|
20
|
+
* bytes. (Includes digest failure / collision.)
|
|
21
|
+
* - request mismatch — the request digest differs; the crystal was built
|
|
22
|
+
* for a different request entirely.
|
|
23
|
+
*
|
|
24
|
+
* PERFORMANCE trips (accumulated over a rolling window before opening):
|
|
25
|
+
* - dependency advanced — the dependency high-water moved past the crystal's
|
|
26
|
+
* cached position. The crystal is stale but not WRONG;
|
|
27
|
+
* a single advance is normal churn. Repeated advances
|
|
28
|
+
* across a window indicate the cache is systematically
|
|
29
|
+
* behind the frontier — that is a performance signal.
|
|
30
|
+
* - generation invalidated — the M6 router generation was invalidated. A single
|
|
31
|
+
* invalidation is expected during a router cut; repeated
|
|
32
|
+
* invalidations indicate a systematic generation
|
|
33
|
+
* instability.
|
|
34
|
+
*
|
|
35
|
+
* The distinction matters because a CORRECTNESS trip opens the breaker IMMEDIATELY
|
|
36
|
+
* (first failure), while a PERFORMANCE trip requires BREAKER_PERF_FAILURES within
|
|
37
|
+
* BREAKER_WINDOW_MS. The VC0C breaker-core already implements this via
|
|
38
|
+
* `BreakerTripKind`; we map each miss class to its trip kind and let breaker-core
|
|
39
|
+
* handle the window/threshold logic.
|
|
40
|
+
*
|
|
41
|
+
* "PROBE OUTPUT IS NEVER SERVED" (TRIAD_RESILIENCE line 13): when the breaker is in
|
|
42
|
+
* PROBE_A or PROBE_B, the probe is a TEST serve — its output must not be returned
|
|
43
|
+
* to the caller. `decideCacheServe` enforces this: PROBE_* states always return
|
|
44
|
+
* `block: true` and the fallback mode, never serving from cache.
|
|
45
|
+
*
|
|
46
|
+
* The decision is a CORRECTNESS behavior and is NEVER flag-gated (unlike the
|
|
47
|
+
* reporter seam in `./diagnostics-emit.ts`): flag-off must be byte-identical to
|
|
48
|
+
* the predecessor. `breakerRetryDelay()` from VC0C already implements the
|
|
49
|
+
* deterministic +-10% jitter from the subsystem digest — we use it, don't re-derive.
|
|
50
|
+
*
|
|
51
|
+
* PREVENT-002/011/PI-004 honored.
|
|
52
|
+
*/
|
|
53
|
+
|
|
54
|
+
import { createBreaker, type ConcreteBreaker } from "../resilience/breaker-core.js";
|
|
55
|
+
import type { BreakerRecord, BreakerTripKind, Mode } from "../resilience/types.js";
|
|
56
|
+
import type { MissClass } from "./diagnostics-types.js";
|
|
57
|
+
|
|
58
|
+
/** The cache subsystem the breaker tracks (one triad state machine). */
|
|
59
|
+
export const CACHE_SUBSYSTEM = "vector-cortex-cache-serve";
|
|
60
|
+
|
|
61
|
+
/** Build the cache breaker. Composes VC0C — no parallel state machine here. */
|
|
62
|
+
export function createCacheBreaker(opts?: {
|
|
63
|
+
now?: () => number;
|
|
64
|
+
onEvent?: (event: Record<string, unknown>) => void;
|
|
65
|
+
}): ConcreteBreaker {
|
|
66
|
+
return createBreaker({ now: opts?.now, onEvent: opts?.onEvent });
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Map a miss class to its breaker trip kind. Profile, range (digest/collision),
|
|
71
|
+
* and request mismatches are CORRECTNESS trips — they trip on the FIRST failure
|
|
72
|
+
* because serving a crystal with the wrong identity is never safe, no matter how
|
|
73
|
+
* rarely it happens. Dependency advance and generation invalidation are
|
|
74
|
+
* PERFORMANCE trips — a single occurrence is normal churn; only repeated
|
|
75
|
+
* failures within a window indicate a systematic problem.
|
|
76
|
+
*/
|
|
77
|
+
export function tripKindForMiss(missClass: MissClass): BreakerTripKind {
|
|
78
|
+
switch (missClass) {
|
|
79
|
+
case "profile":
|
|
80
|
+
case "range":
|
|
81
|
+
case "request":
|
|
82
|
+
return "correctness";
|
|
83
|
+
case "dependency":
|
|
84
|
+
case "generation":
|
|
85
|
+
return "performance";
|
|
86
|
+
case "unknown":
|
|
87
|
+
return "performance";
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Whether a classified miss must block the cache serve. Pure over the class; the
|
|
93
|
+
* ONLY thing that is allowed to demote an otherwise-healthy cache is a real
|
|
94
|
+
* disagreement between what was cached and what the request now requires.
|
|
95
|
+
* `unknown` is not auto-blocked — the triad's own performance window handles it.
|
|
96
|
+
*/
|
|
97
|
+
export function shouldBlockServe(missClass: MissClass): boolean {
|
|
98
|
+
return missClass !== "unknown";
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Decide the triad mode to render under, given a classified miss and the live
|
|
103
|
+
* breaker. A blockable miss forces mode B (fresh render) unless the breaker is
|
|
104
|
+
* already in a deeper open state (C = all-cache bypass) — never contradicting the
|
|
105
|
+
* triad's own resilience verdict. PROBE_* states are NEVER served from cache
|
|
106
|
+
* (TRIAD_RESILIENCE line 13: "probe output is never served").
|
|
107
|
+
*/
|
|
108
|
+
export function decideCacheServe(
|
|
109
|
+
missClass: MissClass,
|
|
110
|
+
breaker: ConcreteBreaker,
|
|
111
|
+
): { block: boolean; fallbackMode: Mode; tripKind: BreakerTripKind } {
|
|
112
|
+
const tripKind = tripKindForMiss(missClass);
|
|
113
|
+
if (!shouldBlockServe(missClass)) {
|
|
114
|
+
return { block: false, fallbackMode: breaker.modeFor(CACHE_SUBSYSTEM), tripKind };
|
|
115
|
+
}
|
|
116
|
+
const record: BreakerRecord = breaker.snapshot(CACHE_SUBSYSTEM);
|
|
117
|
+
if (record.state === "OPEN_C" || record.state === "MANUAL_HALT") {
|
|
118
|
+
return { block: true, fallbackMode: "C", tripKind };
|
|
119
|
+
}
|
|
120
|
+
if (record.state === "PROBE_A" || record.state === "PROBE_B") {
|
|
121
|
+
return { block: true, fallbackMode: record.state === "PROBE_A" ? "C" : "B", tripKind };
|
|
122
|
+
}
|
|
123
|
+
return { block: true, fallbackMode: "B", tripKind };
|
|
124
|
+
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cache/diagnostics-emit.ts — VC7C reporter seam (FLAG-GATED).
|
|
3
|
+
*
|
|
4
|
+
* Mirrors `./economics-emit.ts`: a thin `safe()` wrapper around an optional
|
|
5
|
+
* injected `emit`, and the two event names the sprint spec requires verbatim:
|
|
6
|
+
* - `vector_cortex_cache_miss_classified` — a miss was classified.
|
|
7
|
+
* - `vector_cortex_cache_serve_blocked` — a cache serve was blocked by a
|
|
8
|
+
* breaker condition before it could answer from a stale/invalid identity.
|
|
9
|
+
*
|
|
10
|
+
* FLAG SEMANTICS. `classifyMiss` (`./diagnostics.ts`) is PURE and runs REGARDLESS
|
|
11
|
+
* of `MEGACOMPACT_VC7C`. The flag gates ONLY this reporting + dashboard seam:
|
|
12
|
+
* with the flag off the classifier still returns the SAME class, the breaker
|
|
13
|
+
* still blocks the SAME serve — we just do not announce them under the VC7C
|
|
14
|
+
* event namespace, and the dashboard reports `enabled:false` + mode C. That is
|
|
15
|
+
* what makes flag-off byte-identical to the predecessor (VC7B): the arithmetic
|
|
16
|
+
* and the correctness decision are never skipped, only the emission. (NOTE the
|
|
17
|
+
* asymmetry vs VC7B: VC7B gated pure telemetry; here the blocked-serve DECISION
|
|
18
|
+
* is a correctness behavior and is never flag-gated — only its announcement is.)
|
|
19
|
+
*
|
|
20
|
+
* PAYLOAD DISCIPLINE. These events carry the `missClass` and the payload-free
|
|
21
|
+
* `evidence` booleans/counts (see `./diagnostics-types.ts`) — never a session
|
|
22
|
+
* id, never a covered range, never a request or covered digest. The classifier
|
|
23
|
+
* is payload-free by construction, so there is no slot to leak into
|
|
24
|
+
* (SECURITY_PRIVACY — the exact ledger is not diagnostic data).
|
|
25
|
+
*
|
|
26
|
+
* No console, no storage, no network (PREVENT-PI-004 / PREVENT-011). Every line
|
|
27
|
+
* is a structured JSON event with `ts` + `event`.
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
import { VC7C_ENABLED } from "../../config/vector-cortex.js";
|
|
31
|
+
import type { CacheDiagnosticV1, MissClass } from "./diagnostics-types.js";
|
|
32
|
+
|
|
33
|
+
/** The two structured events the VC7C reporter emits. */
|
|
34
|
+
export type CacheDiagnosticEventName =
|
|
35
|
+
| "vector_cortex_cache_miss_classified"
|
|
36
|
+
| "vector_cortex_cache_serve_blocked";
|
|
37
|
+
|
|
38
|
+
/** Optional emit fn injected by the runtime; tests pass `undefined`. */
|
|
39
|
+
export type CacheDiagnosticEmit = (name: string, payload: unknown) => void;
|
|
40
|
+
|
|
41
|
+
/** Run `fn` only when an emit exists; a reporting failure is never fatal. */
|
|
42
|
+
function safe(
|
|
43
|
+
emit: CacheDiagnosticEmit | undefined,
|
|
44
|
+
fn: (emit: CacheDiagnosticEmit) => void,
|
|
45
|
+
): void {
|
|
46
|
+
if (emit === undefined) return;
|
|
47
|
+
try {
|
|
48
|
+
fn(emit);
|
|
49
|
+
} catch {
|
|
50
|
+
// Non-fatal: a reporting failure must never break the agent loop.
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/** Report a classified miss. Gated only by the reporter/dashboard flag. */
|
|
55
|
+
export function reportCacheMissClassified(
|
|
56
|
+
emit: CacheDiagnosticEmit | undefined,
|
|
57
|
+
diagnostic: CacheDiagnosticV1,
|
|
58
|
+
): void {
|
|
59
|
+
if (!VC7C_ENABLED()) return;
|
|
60
|
+
safe(emit, (e) =>
|
|
61
|
+
e("vector_cortex_cache_miss_classified", {
|
|
62
|
+
ts: undefined,
|
|
63
|
+
event: "vector_cortex_cache_miss_classified",
|
|
64
|
+
schema: diagnostic.schema,
|
|
65
|
+
missClass: diagnostic.missClass,
|
|
66
|
+
evidence: diagnostic.evidence,
|
|
67
|
+
}),
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** Report a cache serve that was blocked before answering. Gated by the flag. */
|
|
72
|
+
export function reportCacheServeBlocked(
|
|
73
|
+
emit: CacheDiagnosticEmit | undefined,
|
|
74
|
+
blocked: {
|
|
75
|
+
readonly missClass: MissClass;
|
|
76
|
+
readonly triadState: string;
|
|
77
|
+
readonly reason: string;
|
|
78
|
+
},
|
|
79
|
+
): void {
|
|
80
|
+
if (!VC7C_ENABLED()) return;
|
|
81
|
+
safe(emit, (e) =>
|
|
82
|
+
e("vector_cortex_cache_serve_blocked", {
|
|
83
|
+
ts: undefined,
|
|
84
|
+
event: "vector_cortex_cache_serve_blocked",
|
|
85
|
+
missClass: blocked.missClass,
|
|
86
|
+
triadState: blocked.triadState,
|
|
87
|
+
reason: blocked.reason,
|
|
88
|
+
}),
|
|
89
|
+
);
|
|
90
|
+
}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cache/diagnostics-types.ts — VC7C cache miss-diagnostic contract types.
|
|
3
|
+
*
|
|
4
|
+
* Single source of truth for the miss-classification vocabulary. Kept separate
|
|
5
|
+
* from the arithmetic (`diagnostics.ts`) so the dashboard client, the emit layer
|
|
6
|
+
* and the acceptance test all import ONE definition. No logic here; pure types
|
|
7
|
+
* + the registered ID lists. PREVENT-011 honored (no `any`).
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
/** The exclusive miss classes, in the order the classifier ranks them. */
|
|
11
|
+
export type MissClass =
|
|
12
|
+
| "profile"
|
|
13
|
+
| "range"
|
|
14
|
+
| "dependency"
|
|
15
|
+
| "request"
|
|
16
|
+
| "generation"
|
|
17
|
+
| "unknown";
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Payload-free by construction. Every field is a boolean or a bounded,
|
|
21
|
+
* non-negative count — there is no string slot into which a request body, a
|
|
22
|
+
* session id, or a covered range of user content could be placed. See
|
|
23
|
+
* SECURITY_PRIVACY: a diagnostic that carried the offending payload would leak
|
|
24
|
+
* it to the dashboard.
|
|
25
|
+
*/
|
|
26
|
+
export interface MissEvidence {
|
|
27
|
+
readonly profileMismatch: boolean;
|
|
28
|
+
readonly rangeMismatch: boolean;
|
|
29
|
+
readonly dependencyAdvanced: boolean;
|
|
30
|
+
readonly requestMismatch: boolean;
|
|
31
|
+
readonly generationInvalidated: boolean;
|
|
32
|
+
/** Ranges the caller asked for (always observable, even on a cold key). */
|
|
33
|
+
readonly requestedRangeCount: number;
|
|
34
|
+
/** Ranges the cache could serve; 0 on a cold key (no crystal). */
|
|
35
|
+
readonly cachedRangeCount: number;
|
|
36
|
+
/** max(0, requestHighWater - cachedHighWater), saturated at MAX_SAFE_INTEGER. */
|
|
37
|
+
readonly dependencyDelta: number;
|
|
38
|
+
/** True when nothing was cached for this key (null cached fields). */
|
|
39
|
+
readonly absent: boolean;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* A single observation fed to the classifier. A `null` cached field means that
|
|
44
|
+
* piece of state was never persisted — "absence is not a mismatch". Digests
|
|
45
|
+
* follow convention: `coveredDigest` is `sha256:<hex>` (WITH prefix);
|
|
46
|
+
* `requestDigest` is BARE lowercase hex (NO prefix).
|
|
47
|
+
*/
|
|
48
|
+
export interface MissObservation {
|
|
49
|
+
readonly requestProfileId: string;
|
|
50
|
+
readonly requestProfileVersion: string;
|
|
51
|
+
readonly cachedProfileId: string | null;
|
|
52
|
+
readonly cachedProfileVersion: string | null;
|
|
53
|
+
readonly requestCoveredDigest: string;
|
|
54
|
+
readonly cachedCoveredDigest: string | null;
|
|
55
|
+
readonly requestedRangeCount: number;
|
|
56
|
+
readonly cachedRangeCount: number | null;
|
|
57
|
+
readonly requestDigest: string;
|
|
58
|
+
readonly cachedRequestDigest: string | null;
|
|
59
|
+
/** Dependency validation high-water (monotonic frontier), as a bigint. */
|
|
60
|
+
readonly requestDependencyHighWater: bigint;
|
|
61
|
+
readonly cachedDependencyHighWater: bigint | null;
|
|
62
|
+
readonly generationInvalidated: boolean;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/** The versioned diagnostic record emitted for every classified miss. */
|
|
66
|
+
export interface CacheDiagnosticV1 {
|
|
67
|
+
readonly schema: "cache-diagnostic-v1";
|
|
68
|
+
readonly missClass: MissClass;
|
|
69
|
+
readonly evidence: MissEvidence;
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
/** Registered conformance IDs (CACHE-016..030). */
|
|
73
|
+
export const CACHE_DIAGNOSTIC_IDS: readonly string[] = Array.from(
|
|
74
|
+
{ length: 15 },
|
|
75
|
+
(_v, i) => `CACHE-${String(i + 16).padStart(3, "0")}`,
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
/** Named headlines surfaced by the conformance corpus. */
|
|
79
|
+
export const CACHE_DIAGNOSTIC_NAMED_IDS = [
|
|
80
|
+
"CACHE-MISS-001",
|
|
81
|
+
"CACHE-STALE-003",
|
|
82
|
+
] as const;
|
|
83
|
+
|
|
84
|
+
/** Event names this subsystem emits (gated by MEGACOMPACT_VC7C). */
|
|
85
|
+
export type CacheDiagnosticEventName =
|
|
86
|
+
| "vector_cortex_cache_miss_classified"
|
|
87
|
+
| "vector_cortex_cache_serve_blocked";
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cache/diagnostics.ts — VC7C pure miss classification (flag-independent).
|
|
3
|
+
*
|
|
4
|
+
* The classifier is PURE arithmetic: given a `MissObservation` it returns
|
|
5
|
+
* exactly ONE `MissClass` and the payload-free `MissEvidence`. It is NOT gated by
|
|
6
|
+
* MEGACOMPACT_VC7C — flag-off must be byte-identical to the predecessor, so the
|
|
7
|
+
* SAME class a user sees today, they see tomorrow. The flag gates only the
|
|
8
|
+
* reporter/dashboard seam (see `diagnostics-emit.ts`).
|
|
9
|
+
*
|
|
10
|
+
* Exclusive ranking: profile -> range -> dependency -> request -> generation ->
|
|
11
|
+
* unknown. First match wins; the ranking itself is the contract and is pinned by
|
|
12
|
+
* CACHE-016..030. "Absence is not a mismatch": a cold key (null cached fields)
|
|
13
|
+
* classifies `unknown`, never `profile`. PREVENT-002/011/PI-004 honored.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import type {
|
|
17
|
+
CacheDiagnosticV1,
|
|
18
|
+
MissClass,
|
|
19
|
+
MissEvidence,
|
|
20
|
+
MissObservation,
|
|
21
|
+
} from "./diagnostics-types.js";
|
|
22
|
+
|
|
23
|
+
/** A cached field is present iff it is non-null. */
|
|
24
|
+
function isPresent(value: string | number | bigint | null): boolean {
|
|
25
|
+
return value !== null;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Clamp the dependency delta to a non-negative, safe-integer count. A request
|
|
30
|
+
* BEHIND the cached frontier is not an advance (delta 0); a huge advance
|
|
31
|
+
* saturates rather than losing precision.
|
|
32
|
+
*/
|
|
33
|
+
function advanceDelta(
|
|
34
|
+
request: bigint,
|
|
35
|
+
cached: bigint | null,
|
|
36
|
+
): { advanced: boolean; delta: number } {
|
|
37
|
+
if (cached === null) return { advanced: false, delta: 0 };
|
|
38
|
+
if (request <= cached) return { advanced: false, delta: 0 };
|
|
39
|
+
const diff = request - cached;
|
|
40
|
+
if (diff > BigInt(Number.MAX_SAFE_INTEGER)) {
|
|
41
|
+
return { advanced: true, delta: Number.MAX_SAFE_INTEGER };
|
|
42
|
+
}
|
|
43
|
+
return { advanced: true, delta: Number(diff) };
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/** Collect the payload-free evidence from one observation. */
|
|
47
|
+
export function collectEvidence(o: MissObservation): MissEvidence {
|
|
48
|
+
const profileMismatch =
|
|
49
|
+
isPresent(o.cachedProfileId) &&
|
|
50
|
+
isPresent(o.cachedProfileVersion) &&
|
|
51
|
+
(o.cachedProfileId !== o.requestProfileId ||
|
|
52
|
+
o.cachedProfileVersion !== o.requestProfileVersion);
|
|
53
|
+
|
|
54
|
+
const rangeMismatch =
|
|
55
|
+
(isPresent(o.cachedCoveredDigest) &&
|
|
56
|
+
o.cachedCoveredDigest !== o.requestCoveredDigest) ||
|
|
57
|
+
(isPresent(o.cachedRangeCount) &&
|
|
58
|
+
o.cachedRangeCount !== o.requestedRangeCount);
|
|
59
|
+
|
|
60
|
+
const dep = advanceDelta(
|
|
61
|
+
o.requestDependencyHighWater,
|
|
62
|
+
o.cachedDependencyHighWater,
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
const requestMismatch =
|
|
66
|
+
isPresent(o.cachedRequestDigest) &&
|
|
67
|
+
o.cachedRequestDigest !== o.requestDigest;
|
|
68
|
+
|
|
69
|
+
const absent =
|
|
70
|
+
!isPresent(o.cachedProfileId) &&
|
|
71
|
+
!isPresent(o.cachedCoveredDigest) &&
|
|
72
|
+
!isPresent(o.cachedRequestDigest) &&
|
|
73
|
+
!isPresent(o.cachedDependencyHighWater);
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
profileMismatch,
|
|
77
|
+
rangeMismatch,
|
|
78
|
+
dependencyAdvanced: dep.advanced,
|
|
79
|
+
requestMismatch,
|
|
80
|
+
generationInvalidated: o.generationInvalidated,
|
|
81
|
+
requestedRangeCount: o.requestedRangeCount,
|
|
82
|
+
// Nothing was cached when the observation is absent, so a stale
|
|
83
|
+
// cachedRangeCount on the observation is not real — report 0.
|
|
84
|
+
cachedRangeCount:
|
|
85
|
+
o.cachedRangeCount === null || absent ? 0 : o.cachedRangeCount,
|
|
86
|
+
dependencyDelta: dep.delta,
|
|
87
|
+
absent,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** The exclusive ranking: first true cause wins. */
|
|
92
|
+
export function classFor(e: MissEvidence): MissClass {
|
|
93
|
+
if (e.profileMismatch) return "profile";
|
|
94
|
+
if (e.rangeMismatch) return "range";
|
|
95
|
+
if (e.dependencyAdvanced) return "dependency";
|
|
96
|
+
if (e.requestMismatch) return "request";
|
|
97
|
+
if (e.generationInvalidated) return "generation";
|
|
98
|
+
return "unknown";
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** Classify one observation: exactly one deterministic class. */
|
|
102
|
+
export function classifyMiss(o: MissObservation): CacheDiagnosticV1 {
|
|
103
|
+
const evidence = collectEvidence(o);
|
|
104
|
+
return {
|
|
105
|
+
schema: "cache-diagnostic-v1",
|
|
106
|
+
missClass: classFor(evidence),
|
|
107
|
+
evidence,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* A miss a caller can self-heal on the next turn (re-fetch under a fresh
|
|
113
|
+
* profile / a new generation), so a triad recovery path may treat it as
|
|
114
|
+
* transient. Only profile + generation qualify; the rest are hard mismatches.
|
|
115
|
+
* An `unknown` miss is NEVER transient.
|
|
116
|
+
*/
|
|
117
|
+
export function isTransientMiss(d: CacheDiagnosticV1): boolean {
|
|
118
|
+
return d.missClass === "profile" || d.missClass === "generation";
|
|
119
|
+
}
|
|
@@ -75,16 +75,17 @@ function generationFromEconomics(economicsVersion: string): bigint {
|
|
|
75
75
|
|
|
76
76
|
export function detectCollision(host: M5Host): boolean {
|
|
77
77
|
const byHash = new Map<string, string>();
|
|
78
|
+
const seenIdentities = new Set<string>();
|
|
78
79
|
for (const v1 of host.v1Rows()) {
|
|
79
80
|
const row = deriveRequestHashRow(host, v1);
|
|
81
|
+
const id = identity(v1.profileId, v1.requestDigest);
|
|
82
|
+
// Two distinct v1 rows (different v1 hash) with the same v2 hash collide,
|
|
83
|
+
// even if they share an identity — the v2 table cannot distinguish them.
|
|
84
|
+
if (seenIdentities.has(id)) return true;
|
|
85
|
+
seenIdentities.add(id);
|
|
80
86
|
const prior = byHash.get(row.hash);
|
|
81
|
-
if (
|
|
82
|
-
|
|
83
|
-
prior !== identity(v1.profileId, v1.requestDigest)
|
|
84
|
-
) {
|
|
85
|
-
return true;
|
|
86
|
-
}
|
|
87
|
-
byHash.set(row.hash, identity(v1.profileId, v1.requestDigest));
|
|
87
|
+
if (prior !== undefined && prior !== id) return true;
|
|
88
|
+
byHash.set(row.hash, id);
|
|
88
89
|
}
|
|
89
90
|
return false;
|
|
90
91
|
}
|
|
@@ -148,6 +149,9 @@ export function m5Verify(host: M5Host): M5ValidateResult {
|
|
|
148
149
|
const expected = new Set<string>();
|
|
149
150
|
for (const v1 of v1Rows) {
|
|
150
151
|
const id = identity(v1.profileId, v1.requestDigest);
|
|
152
|
+
// Dead-generation rows are intentionally skipped by copy; do not flag.
|
|
153
|
+
const fresh = deriveRequestHashRow(host, v1);
|
|
154
|
+
if (isGenerationInvalidated(host, fresh)) continue;
|
|
151
155
|
expected.add(id);
|
|
152
156
|
const n = counts.get(id) ?? 0;
|
|
153
157
|
if (n === 0) codes.push(M5_FAIL.COPY_PARTIAL);
|
|
@@ -181,10 +185,12 @@ export function m5Switch(host: M5Host): M5ValidateResult {
|
|
|
181
185
|
if (host.activeVersion() !== REQUEST_HASH_LEGACY_VERSION) {
|
|
182
186
|
return { ok: false, codes: [M5_FAIL.NOT_ON_LEGACY] };
|
|
183
187
|
}
|
|
184
|
-
|
|
185
|
-
|
|
188
|
+
// Collision check runs before copy-completeness verify: a structural
|
|
189
|
+
// collision is a switch-blocker regardless of copy state.
|
|
186
190
|
if (detectCollision(host))
|
|
187
191
|
return { ok: false, codes: [M5_FAIL.REQUEST_HASH_COLLISION] };
|
|
192
|
+
const verify = m5Verify(host);
|
|
193
|
+
if (!verify.ok) return verify;
|
|
188
194
|
host.switchToV2();
|
|
189
195
|
return { ok: true, codes: [] };
|
|
190
196
|
}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{j as e,r as m,B as l}from"./index-Dz8GPBOE.js";import{C as i,a as x,b as u,c as h}from"./card-CalUQAKG.js";async function N(){const s=await fetch("/api/vector-cortex/evaluation");if(!s.ok)throw new Error(`vector-cortex evaluation: ${s.status}`);return s.json()}async function b(){const s=await fetch("/api/vector-cortex/health");if(!s.ok)throw new Error(`vector-cortex health: ${s.status}`);return s.json()}async function V(){const s=await fetch("/api/vector-cortex/topology");if(!s.ok)throw new Error(`vector-cortex topology: ${s.status}`);return s.json()}async function S(){const s=await fetch("/api/vector-cortex/query");if(!s.ok)throw new Error(`vector-cortex query: ${s.status}`);return s.json()}async function E(){const s=await fetch("/api/vector-cortex/shards");if(!s.ok)throw new Error(`vector-cortex shards: ${s.status}`);return s.json()}async function R(){const s=await fetch("/api/vector-cortex/reconstruct");if(!s.ok)throw new Error(`vector-cortex reconstruct: ${s.status}`);return s.json()}async function F(){const s=await fetch("/api/vector-cortex/plans");if(!s.ok)throw new Error(`vector-cortex plans: ${s.status}`);return s.json()}async function A(){const s=await fetch("/api/vector-cortex/render");if(!s.ok)throw new Error(`vector-cortex render: ${s.status}`);return s.json()}async function k(){const s=await fetch("/api/vector-cortex/rollout");if(!s.ok)throw new Error(`vector-cortex rollout: ${s.status}`);return s.json()}async function T(){const s=await fetch("/api/vector-cortex/closure-proof");if(!s.ok)throw new Error(`vector-cortex closure-proof: ${s.status}`);return s.json()}async function I(){const s=await fetch("/api/vector-cortex/restore");if(!s.ok)throw new Error(`vector-cortex restore: ${s.status}`);return s.json()}async function $(){const s=await fetch("/api/vector-cortex/repair");if(!s.ok)throw new Error(`vector-cortex repair: ${s.status}`);return s.json()}async function P(s="default"){const t=await fetch(`/api/vector-cortex/ledger?session=${encodeURIComponent(s)}`);if(!t.ok)throw new Error(`vector-cortex ledger: ${t.status}`);return t.json()}async function w(s){const t=await fetch("/api/vector-cortex/breakers/reset",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({subsystem:s})});if(!t.ok)throw new Error(`vector-cortex reset: ${t.status}`);return t.json()}async function O(){const s=await fetch("/api/vector-cortex/cache-crystals");if(!s.ok)throw new Error(`vector-cortex cache-crystals: ${s.status}`);return s.json()}async function B(){const s=await fetch("/api/vector-cortex/cache-economics");if(!s.ok)throw new Error(`vector-cortex cache-economics: ${s.status}`);return s.json()}async function M(){const s=await fetch("/api/vector-cortex/cache-diagnostics");if(!s.ok)throw new Error(`vector-cortex cache-diagnostics: ${s.status}`);return s.json()}function r({label:s,value:t}){return e.jsxs("div",{children:[e.jsx("div",{className:"text-xs text-muted-foreground",children:s}),e.jsx("div",{className:"font-mono text-sm",children:t})]})}function D(){const[s,t]=m.useState({loading:!0,error:null,data:null,health:null,ledger:null,topology:null,query:null,shards:null,reconstruct:null,plans:null,render:null,rollout:null,closureProof:null,restore:null,repair:null,crystals:null,economics:null,diagnostics:null}),o=m.useCallback(()=>{t(a=>({...a,loading:!0})),N().then(a=>t(n=>({...n,data:a,loading:!1,error:null}))).catch(a=>t(n=>({...n,loading:!1,error:a instanceof Error?a.message:String(a)}))),b().then(a=>t(n=>({...n,health:a}))).catch(()=>{}),P().then(a=>t(n=>({...n,ledger:a}))).catch(()=>{}),V().then(a=>t(n=>({...n,topology:a}))).catch(()=>{}),S().then(a=>t(n=>({...n,query:a}))).catch(()=>{}),E().then(a=>t(n=>({...n,shards:a}))).catch(()=>{}),R().then(a=>t(n=>({...n,reconstruct:a}))).catch(()=>{}),F().then(a=>t(n=>({...n,plans:a}))).catch(()=>{}),A().then(a=>t(n=>({...n,render:a}))).catch(()=>{}),k().then(a=>t(n=>({...n,rollout:a}))).catch(()=>{}),T().then(a=>t(n=>({...n,closureProof:a}))).catch(()=>{}),I().then(a=>t(n=>({...n,restore:a}))).catch(()=>{}),$().then(a=>t(n=>({...n,repair:a}))).catch(()=>{}),O().then(a=>t(n=>({...n,crystals:a}))).catch(()=>{}),B().then(a=>t(n=>({...n,economics:a}))).catch(()=>{}),M().then(a=>t(n=>({...n,diagnostics:a}))).catch(()=>{})},[]);return m.useEffect(()=>{o();const a=setInterval(o,5e3);return()=>clearInterval(a)},[o]),[s,o]}function L({view:s}){return e.jsxs(i,{children:[e.jsx(x,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(u,{children:"Validated Prompt Renderer (VC5B)"}),s?.enabled?e.jsx(l,{variant:"success",children:"ACTIVE"}):e.jsx(l,{variant:"danger",children:"OFF"})]})}),e.jsx(h,{children:s?.enabled?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4 md:grid-cols-4",children:[e.jsx(r,{label:"Render fixtures",value:String(s.renderCount)}),e.jsx(r,{label:"Provider profiles",value:String(s.providerCount)}),e.jsx(r,{label:"Known profiles",value:String(s.knownProfiles.length)})]}),e.jsx("div",{className:"mt-3 text-xs text-muted-foreground",children:"Reader-only render conformance route — no prompt text or session payloads exposed."})]}):e.jsx("div",{className:"vc-empty",children:"Renderer disabled (VC5B off)."})})]})}function z({view:s}){return e.jsxs(i,{children:[e.jsx(x,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(u,{children:"Live Graduated Rollout (VC5C)"}),s?.enabled?e.jsx(l,{variant:"success",children:"ACTIVE"}):e.jsx(l,{variant:"danger",children:"OFF"})]})}),e.jsx(h,{children:s?.enabled?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4 md:grid-cols-4",children:[e.jsx(r,{label:"Gate",value:`${s.gatePct}%`}),e.jsx(r,{label:"Exposed buckets",value:String(s.bucketCount)}),e.jsx(r,{label:"Total buckets",value:String(s.buckets)}),e.jsx(r,{label:"Promotion",value:s.promotionBlocked?"FROZEN":"OPEN"}),e.jsx(r,{label:"Events",value:String(s.events)}),e.jsx(r,{label:"Sessions",value:String(s.sessions)})]}),e.jsx("div",{className:"mt-3 text-xs text-muted-foreground",children:"Reader-only rollout route — no session payloads or bucket→session mappings exposed."})]}):e.jsx("div",{className:"vc-empty",children:"Rollout disabled (VC5C off)."})})]})}function H({view:s}){return e.jsxs(i,{children:[e.jsx(x,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(u,{children:"Closure Optimization (VC6A)"}),s?.enabled?e.jsx(l,{variant:"success",children:"ACTIVE"}):e.jsx(l,{variant:"danger",children:"OFF"})]})}),e.jsx(h,{children:s?.enabled?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4 md:grid-cols-4",children:[e.jsx(r,{label:"Mode",value:s.mode}),e.jsx(r,{label:"Optimizations",value:String(s.optimizations)}),e.jsx(r,{label:"Proof rejections",value:String(s.proofRejections)}),e.jsx(r,{label:"Last rejection",value:s.lastRejection??"none"}),e.jsx(r,{label:"Retained edges",value:String(s.retainedEdgeTotal)}),e.jsx(r,{label:"Removed edges",value:String(s.removedEdgeTotal)}),e.jsx(r,{label:"Conservative walks",value:String(s.conservativeTraversalTotal)}),e.jsx(r,{label:"Optimized walks",value:String(s.optimizedTraversalTotal)})]}),e.jsx("div",{className:"mt-3 text-xs text-muted-foreground",children:"Reader-only closure diagnostics — aggregate counts only; per-edge proof rows, node ids, and source payloads are never exposed (SECURITY_PRIVACY)."})]}):e.jsx("div",{className:"vc-empty",children:"Closure optimization disabled (VC6A off) — conservative VC4C closure used directly (mode B)."})})]})}function U({view:s}){return e.jsxs(i,{children:[e.jsx(x,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(u,{children:"Exact Source Restoration (VC6B)"}),s?.enabled?e.jsx(l,{variant:"success",children:"ACTIVE"}):e.jsx(l,{variant:"danger",children:"OFF"})]})}),e.jsx(h,{children:s?.enabled?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4 md:grid-cols-4",children:[e.jsx(r,{label:"Mode",value:s.mode}),e.jsx(r,{label:"Restore attempts",value:String(s.restoreAttempts)}),e.jsx(r,{label:"Restored",value:String(s.restoredCount)}),e.jsx(r,{label:"Missing source",value:String(s.missingCount)}),e.jsx(r,{label:"Digest rejections",value:String(s.digestRejections)}),e.jsx(r,{label:"Last rejection",value:s.lastRejection??"none"}),e.jsx(r,{label:"Updated",value:s.updatedAt})]}),e.jsx("div",{className:"mt-3 text-xs text-muted-foreground",children:"Reader-only restore diagnostics — counts and HEAL_RESTORE_* codes only. There is no payload endpoint: restored bytes, span ids, node ids, and ledger text are never exposed (SECURITY_PRIVACY)."})]}):e.jsx("div",{className:"vc-empty",children:"Exact source restoration disabled (VC6B off) — no exact source is restored; omitted context is disclosed as loss (mode C)."})})]})}function Y({view:s}){return e.jsxs(i,{children:[e.jsx(x,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(u,{children:"Self-Healing Derived State (VC6C)"}),s?.enabled?e.jsx(l,{variant:"success",children:"ACTIVE"}):e.jsx(l,{variant:"danger",children:"OFF"})]})}),e.jsx(h,{children:s?.enabled?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4 md:grid-cols-4",children:[e.jsx(r,{label:"Mode",value:s.mode}),e.jsx(r,{label:"Repair attempts",value:String(s.repairAttempts)}),e.jsx(r,{label:"Repairs planned",value:String(s.repairsPlanned)}),e.jsx(r,{label:"Pointers switched",value:String(s.pointersSwitched)}),e.jsx(r,{label:"Backoffs",value:String(s.backoffs)}),e.jsx(r,{label:"Last backoff",value:s.lastBackoffMs===null?"none":`${s.lastBackoffMs}ms`}),e.jsx(r,{label:"Last failure",value:s.lastFailure??"none"}),e.jsx(r,{label:"Updated",value:s.updatedAt})]}),e.jsx("div",{className:"mt-3 text-xs text-muted-foreground",children:"Reader-only repair diagnostics — counts and HEAL_REPAIR_* codes only. There is no payload endpoint: subsystem source bytes, gap ranges, high-water marks, root digests, and ledger text are never exposed (SECURITY_PRIVACY)."})]}):e.jsx("div",{className:"vc-empty",children:"Self-healing derived state disabled (VC6C off) — no controller detects gaps or rebuilds derived state; derived state is reported disabled rather than healed (mode C)."})})]})}function _({view:s}){return e.jsxs(i,{children:[e.jsx(x,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(u,{children:"Frozen Range Crystals (VC7A)"}),s?.enabled?e.jsx(l,{variant:"success",children:"ACTIVE"}):e.jsx(l,{variant:"danger",children:"OFF"})]})}),e.jsx(h,{children:s?.enabled?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4 md:grid-cols-4",children:[e.jsx(r,{label:"Mode",value:s.mode}),e.jsx(r,{label:"Crystals",value:String(s.crystalCount)}),e.jsx(r,{label:"Frozen bytes",value:String(s.totalBytes)}),e.jsx(r,{label:"Hits",value:String(s.hits)}),e.jsx(r,{label:"Misses",value:String(s.misses)}),e.jsx(r,{label:"Hit bytes",value:String(s.hitBytes)}),e.jsx(r,{label:"Writes",value:String(s.writes)}),e.jsx(r,{label:"Duplicate writes",value:String(s.duplicateWrites)}),e.jsx(r,{label:"Collisions",value:String(s.collisions)}),e.jsx(r,{label:"Last failure",value:s.lastFailure??"none"}),e.jsx(r,{label:"Updated",value:s.updatedAt})]}),e.jsx("div",{className:"mt-3 text-xs text-muted-foreground",children:"Reader-only crystal diagnostics — counts, byte volumes, and CRY_* codes only. A crystal is a frozen rendered prompt, so frozen bytes, covered ranges, span/covered digests, request digests, and session ids are never exposed (SECURITY_PRIVACY). Keys exclude the global ledger frontier, so an unrelated append does not invalidate a crystal; a covered-byte, dependency, renderer, or profile change does. Collisions mean two renders of one identity disagreed — the stored crystal is never overwritten."})]}):e.jsx("div",{className:"vc-empty",children:"Frozen range crystals disabled (VC7A off) — nothing is served from the crystal cache and every render is produced fresh; the cache is reported bypassed rather than hit (mode C)."})})]})}function q({view:s}){return e.jsxs(i,{children:[e.jsx(x,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(u,{children:"Cache Economics (VC7B)"}),s?.enabled?e.jsx(l,{variant:"success",children:"ACTIVE"}):e.jsx(l,{variant:"danger",children:"OFF"})]})}),e.jsx(h,{children:s?.enabled?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4 md:grid-cols-4",children:[e.jsx(r,{label:"Mode",value:s.mode}),e.jsx(r,{label:"Profiles",value:String(s.profileCount)}),e.jsx(r,{label:"Proven exclusions",value:String(s.provenExclusions)}),e.jsx(r,{label:"Unproven exclusions",value:String(s.unprovenExclusions)}),e.jsx(r,{label:"Last failure",value:s.lastFailure??"none"}),e.jsx(r,{label:"Updated",value:s.updatedAt})]}),e.jsx("div",{className:"mt-3 text-xs text-muted-foreground",children:"Reader-only cache-economics diagnostics — counts and ECON_* codes only. Cache economics price a frozen rendered prompt's reuse, so provider prices, covered ranges, span/covered digests, request digests, and session ids are never exposed (SECURITY_PRIVACY). An unproven exclusion (declared without a proving fixture id) is rejected by the exclusion-proof rule and is reported here only as a count."})]}):e.jsx("div",{className:"vc-empty",children:"Cache economics disabled (VC7B off) — no cache reuse is priced; the cache-economics surface is reported bypassed rather than priced (mode C)."})})]})}function G({view:s}){return e.jsxs(i,{children:[e.jsx(x,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(u,{children:"Dual-Tier Shards (VC4A)"}),s?.enabled?e.jsx(l,{variant:"success",children:"ACTIVE"}):e.jsx(l,{variant:"danger",children:"OFF"})]})}),e.jsx(h,{children:s?.enabled?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4 md:grid-cols-4",children:[e.jsx(r,{label:"Semantic shards",value:String(s.semanticCount)}),e.jsx(r,{label:"Exact shards",value:String(s.exactCount)}),e.jsx(r,{label:"Byte total",value:String(s.byteTotal)}),e.jsx(r,{label:"Protected bytes",value:String(s.protectedByteTotal)})]}),e.jsx("div",{className:"mt-3 text-xs text-muted-foreground",children:"Reader-only count/byte aggregate; staged in-memory this sprint."})]}):e.jsx("div",{className:"vc-empty",children:"Dual-tier shards disabled (VC4A off)."})})]})}function W({view:s}){return e.jsxs(i,{children:[e.jsx(x,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(u,{children:"Reconstruction Fidelity (VC4C)"}),s?.enabled?e.jsx(l,{variant:"success",children:"ACTIVE"}):e.jsx(l,{variant:"danger",children:"OFF"})]})}),e.jsx(h,{children:s?.enabled?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4 md:grid-cols-4",children:[e.jsx(r,{label:"Closure attempts",value:String(s.closureAttempts)}),e.jsx(r,{label:"Closure rejections",value:String(s.closureRejections)}),e.jsx(r,{label:"Validated",value:String(s.validatedCount)}),e.jsx(r,{label:"Invalidated",value:String(s.invalidatedCount)}),e.jsx(r,{label:"Span total",value:String(s.spanTotal)}),e.jsx(r,{label:"Byte total",value:String(s.byteTotal)})]}),e.jsx("div",{className:"mt-3 text-xs text-muted-foreground",children:"Reader-only closure/validation aggregate; staged in-memory this sprint."})]}):e.jsx("div",{className:"vc-empty",children:"Reconstruction fidelity disabled (VC4C off)."})})]})}function Q({view:s}){return e.jsxs(i,{children:[e.jsx(x,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(u,{children:"Plan Manifests (VC5A)"}),s?.enabled?e.jsx(l,{variant:"success",children:"ACTIVE"}):e.jsx(l,{variant:"danger",children:"OFF"})]})}),e.jsx(h,{children:s?.enabled?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4 md:grid-cols-4",children:[e.jsx(r,{label:"DAG fixtures",value:String(s.dagCount)}),e.jsx(r,{label:"Plan fixtures",value:String(s.plannerCount)}),e.jsx(r,{label:"Plans exposed",value:String(s.plans.length)})]}),e.jsx("div",{className:"mt-3 text-xs text-muted-foreground",children:"Reader-only plan manifests only — no session payloads or prompt text. Per-run plan outputs are staged in-memory this sprint."})]}):e.jsx("div",{className:"vc-empty",children:"PromptDagV1 + budgeted planner disabled (VC5A off)."})})]})}function K({topology:s,query:t}){return e.jsxs(e.Fragment,{children:[e.jsxs(i,{children:[e.jsx(x,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(u,{children:"Derived Cortex Store (VC3A)"}),s?.enabled?e.jsx(l,{variant:"success",children:"ACTIVE"}):e.jsx(l,{variant:"danger",children:"OFF"})]})}),e.jsx(h,{children:s?.enabled?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"grid grid-cols-2 gap-4 md:grid-cols-3",children:[e.jsx(r,{label:"Generation",value:s.generationId??"—"}),e.jsx(r,{label:"Ordinal",value:s.ordinal??"—"}),e.jsx(r,{label:"Records",value:String(s.recordCount)}),e.jsx(r,{label:"Frontier (HW)",value:s.sourceHighWater}),e.jsx(r,{label:"Root digest",value:s.rootDigest?s.rootDigest.slice(0,16):"—"}),s.nodes!==void 0&&e.jsxs(e.Fragment,{children:[e.jsx(r,{label:"Nodes",value:String(s.nodes?.length??0)}),e.jsx(r,{label:"Edges",value:String(s.edges?.length??0)}),e.jsx(r,{label:"Graph digest",value:s.generationDigest?s.generationDigest.slice(0,16):"—"})]})]}),s.nodes!==void 0&&(s.edges?.length??0)>0&&e.jsxs("div",{className:"mt-4 max-h-56 overflow-y-auto",children:[e.jsx("div",{className:"mb-1 text-xs font-medium text-muted-foreground",children:"Topology edges (VC3B)"}),e.jsxs("table",{className:"w-full text-left text-xs",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-border/50 text-muted-foreground",children:[e.jsx("th",{className:"py-1 pr-2",children:"source"}),e.jsx("th",{className:"py-1 pr-2",children:"target"}),e.jsx("th",{className:"py-1 pr-2",children:"head"}),e.jsx("th",{className:"py-1 pr-2",children:"dir"}),e.jsx("th",{className:"py-1",children:"score"})]})}),e.jsx("tbody",{children:s.edges?.map((o,a)=>e.jsxs("tr",{className:"border-b border-border/30",children:[e.jsx("td",{className:"py-1 pr-2 font-mono",children:o.source}),e.jsx("td",{className:"py-1 pr-2 font-mono",children:o.target}),e.jsx("td",{className:"py-1 pr-2 font-mono",children:o.head}),e.jsx("td",{className:"py-1 pr-2",children:o.direction}),e.jsx("td",{className:"py-1 font-mono",children:o.score})]},`${o.source}-${o.target}-${o.head}-${a}`))})]})]})]}):e.jsx("div",{className:"vc-empty",children:"Cortex store disabled (VC3A off)."})})]}),e.jsxs(i,{children:[e.jsx(x,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(u,{children:"Topology Query Diagnostics (VC3C)"}),t?.enabled?e.jsx(l,{variant:"success",children:"ACTIVE"}):e.jsx(l,{variant:"danger",children:"OFF"})]})}),e.jsx(h,{children:t?.enabled?e.jsx("div",{className:"grid grid-cols-2 gap-4 md:grid-cols-3",children:e.jsx(r,{label:"Router version",value:String(t.routerVersion)})}):e.jsx("div",{className:"vc-empty",children:"Query diagnostics unavailable (VC3C off)."})})]})]})}function Z({ledger:s}){return e.jsxs(i,{children:[e.jsx(x,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(u,{children:"Occurrence Ledger (VC1B)"}),s?.enabled?e.jsx(l,{variant:"success",children:"ACTIVE"}):e.jsx(l,{variant:"danger",children:"OFF"})]})}),e.jsx(h,{children:s?.enabled?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"mb-3 grid grid-cols-2 gap-4 md:grid-cols-3",children:[e.jsx(r,{label:"Session",value:s.session}),e.jsx(r,{label:"High-water",value:s.highWater}),e.jsx(r,{label:"Occurrences",value:String(s.count)})]}),s.occurrences.length===0?e.jsx("div",{className:"vc-empty",children:"No occurrences recorded."}):e.jsx("div",{className:"max-h-64 overflow-y-auto",children:e.jsxs("table",{className:"w-full text-left text-xs",children:[e.jsx("thead",{children:e.jsxs("tr",{className:"border-b border-border/50 text-muted-foreground",children:[e.jsx("th",{className:"py-1 pr-2",children:"seq"}),e.jsx("th",{className:"py-1 pr-2",children:"eventId"}),e.jsx("th",{className:"py-1 pr-2",children:"kind"}),e.jsx("th",{className:"py-1 pr-2",children:"toolCall"}),e.jsx("th",{className:"py-1",children:"digest"})]})}),e.jsx("tbody",{children:s.occurrences.map(t=>e.jsxs("tr",{className:"border-b border-border/30",children:[e.jsx("td",{className:"py-1 pr-2 font-mono",children:t.seq}),e.jsx("td",{className:"py-1 pr-2 font-mono",children:t.eventId}),e.jsx("td",{className:"py-1 pr-2",children:t.kind}),e.jsx("td",{className:"py-1 pr-2 font-mono",children:t.toolCallId??"—"}),e.jsx("td",{className:"max-w-[180px] truncate font-mono text-muted-foreground",children:t.digest})]},`${t.seq}-${t.eventId}`))})]})})]}):e.jsx("div",{className:"vc-empty",children:"Ledger disabled (VC1B off)."})})]})}function g({mode:s,count:t}){return e.jsxs("div",{className:"flex items-center justify-between border-b border-border/50 py-1 text-sm",children:[e.jsxs("span",{className:"text-muted-foreground",children:["Mode ",s]}),e.jsx("span",{className:"font-mono",children:t})]})}function ee(){const[s,t]=D(),[o,a]=m.useState(null),{loading:n,error:f,data:c,health:d}=s,C=()=>{w("provider").then(j=>(a(`Breaker "${j.subsystem}" ${j.state}; evidence retained: ${j.failures} failures / ${j.attempts} attempts`),b())).then(j=>{t()}).catch(j=>a(j instanceof Error?j.message:String(j)))};if(n&&!c)return e.jsx("div",{className:"vc-loading",children:"Loading vector-cortex evaluation…"});if(f&&!c)return e.jsxs("div",{className:"vc-error",children:["Error: ",f]});if(!c)return e.jsx("div",{className:"vc-empty",children:"No evaluation data available."});const v=Math.max(1,...c.histogram.cells,c.histogram.overflow);return e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx("h2",{className:"text-lg font-semibold",children:"Vector Cortex Evaluation"}),c.enabled?e.jsx(l,{variant:"warning",children:"OBSERVER PENDING (A)"}):e.jsx(l,{variant:"danger",children:"MODE C (OFF)"})]}),e.jsxs("div",{className:"grid grid-cols-1 gap-4 md:grid-cols-3",children:[e.jsxs(i,{children:[e.jsx(x,{children:e.jsx(u,{children:"Samples"})}),e.jsxs(h,{children:[e.jsx("div",{className:"text-3xl font-bold",children:c.samples}),e.jsxs("div",{className:"mt-2 flex flex-col",children:[e.jsx(g,{mode:"A",count:c.byMode.A}),e.jsx(g,{mode:"B",count:c.byMode.B}),e.jsx(g,{mode:"C",count:c.byMode.C})]})]})]}),e.jsxs(i,{className:"md:col-span-2",children:[e.jsx(x,{children:e.jsx(u,{children:"Latency Histogram (ms, inclusive edges)"})}),e.jsxs(h,{children:[e.jsxs("div",{className:"flex items-end gap-2",style:{height:160},children:[c.histogram.edges.map((j,p)=>{const y=c.histogram.cells[p]/v*140;return e.jsxs("div",{className:"flex flex-1 flex-col items-center gap-1",children:[e.jsx("span",{className:"text-xs text-muted-foreground",children:c.histogram.cells[p]}),e.jsx("div",{className:"w-full rounded-t",style:{height:Math.max(2,y),background:"#6366f1"}}),e.jsxs("span",{className:"text-[10px] text-muted-foreground",children:["≤",j]})]},j)}),e.jsxs("div",{className:"flex flex-1 flex-col items-center gap-1",children:[e.jsx("span",{className:"text-xs text-muted-foreground",children:c.histogram.overflow}),e.jsx("div",{className:"w-full rounded-t",style:{height:Math.max(2,c.histogram.overflow/v*140),background:"#f87171"}}),e.jsx("span",{className:"text-[10px] text-muted-foreground",children:">250"})]})]}),e.jsxs("div",{className:"mt-1 text-xs text-muted-foreground",children:["Total: ",c.histogram.total," · Rejects: ",c.rejects.length]})]})]})]}),e.jsxs(i,{children:[e.jsx(x,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(u,{children:"Live Safety Envelope (VC0C)"}),e.jsxs("div",{className:"flex items-center gap-2",children:[d?.stateSource==="ephemeral"&&e.jsx(l,{variant:"outline",children:"EPHEMERAL (non-live)"}),e.jsx("button",{onClick:C,disabled:!d?.enabled,className:"rounded border border-border px-2 py-1 text-xs disabled:opacity-50",children:"Reset Cooldown"})]})]})}),e.jsxs(h,{children:[o&&e.jsx("div",{className:"mb-2 text-xs text-muted-foreground",children:o}),d?e.jsxs("div",{className:"grid grid-cols-2 gap-4 md:grid-cols-4",children:[e.jsx(r,{label:"State",value:d.state}),e.jsx(r,{label:"Mode",value:d.mode}),e.jsx(r,{label:"Window",value:`${d.windowMs}ms`}),e.jsx(r,{label:"Probes",value:String(d.probeCount)}),e.jsx(r,{label:"Backoff",value:`${d.backoffDelayMs}ms`}),e.jsx(r,{label:"Failures",value:`${d.failures}/${d.attempts}`}),e.jsx(r,{label:"Frontier",value:d.stateSource==="ephemeral"?"non-live":d.frontierFrozen?"FROZEN":"LIVE"}),e.jsx(r,{label:"Spool lag",value:String(d.spoolLag)}),e.jsx(r,{label:"Encoder mode",value:d.encoderMode}),e.jsx(r,{label:"Encoder asset",value:d.encoderAssetDigest?d.encoderAssetDigest.slice(0,12):"none"})]}):e.jsx("div",{className:"vc-empty",children:"Health unavailable (VC0C off)."})]})]}),e.jsx(K,{topology:s.topology,query:s.query}),e.jsx(G,{view:s.shards}),e.jsx(W,{view:s.reconstruct}),e.jsx(Q,{view:s.plans}),e.jsx(L,{view:s.render}),e.jsx(z,{view:s.rollout}),e.jsx(H,{view:s.closureProof}),e.jsx(U,{view:s.restore}),e.jsx(Y,{view:s.repair}),e.jsx(_,{view:s.crystals}),e.jsx(q,{view:s.economics}),e.jsx(Z,{ledger:s.ledger})]})}export{ee as default};
|
|
2
|
-
//# sourceMappingURL=VectorCortexTab-jRd_Iztk.js.map
|