pi-mega-compact 0.20.14 → 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.
Files changed (94) hide show
  1. package/dist/config/vector-cortex.js +20 -0
  2. package/dist/config.js +1 -1
  3. package/dist/extensions/dashboard-server/api-contracts/vector-cortex-diagnostics.js +35 -0
  4. package/dist/extensions/dashboard-server/route-dispatch.js +6 -0
  5. package/dist/extensions/dashboard-server/routes-rag-settings-vector-cortex.js +1 -0
  6. package/dist/extensions/dashboard-server/routes-vector-cortex-diagnostics.js +68 -0
  7. package/dist/src/config/vector-cortex.js +20 -0
  8. package/dist/src/config.js +1 -1
  9. package/dist/src/vector-cortex/cache/_diagnostics-fixture.js +31 -0
  10. package/dist/src/vector-cortex/cache/breaker.js +110 -0
  11. package/dist/src/vector-cortex/cache/diagnostics-emit.js +64 -0
  12. package/dist/src/vector-cortex/cache/diagnostics-types.js +15 -0
  13. package/dist/src/vector-cortex/cache/diagnostics.js +97 -0
  14. package/dist/src/vector-cortex/migrations/request-hash-v2-ops.js +154 -0
  15. package/dist/src/vector-cortex/migrations/request-hash-v2-types.js +30 -0
  16. package/dist/src/vector-cortex/migrations/request-hash-v2.js +42 -147
  17. package/dist/vector-cortex/cache/_diagnostics-fixture.js +31 -0
  18. package/dist/vector-cortex/cache/breaker.js +110 -0
  19. package/dist/vector-cortex/cache/diagnostics-emit.js +64 -0
  20. package/dist/vector-cortex/cache/diagnostics-types.js +15 -0
  21. package/dist/vector-cortex/cache/diagnostics.js +97 -0
  22. package/dist/vector-cortex/migrations/request-hash-v2-ops.js +154 -0
  23. package/dist/vector-cortex/migrations/request-hash-v2-types.js +30 -0
  24. package/dist/vector-cortex/migrations/request-hash-v2.js +42 -147
  25. package/extensions/dashboard-client/dist/assets/{AreaChart-VUd_iOtO.js → AreaChart-B_FKg8xJ.js} +2 -2
  26. package/extensions/dashboard-client/dist/assets/{AreaChart-VUd_iOtO.js.map → AreaChart-B_FKg8xJ.js.map} +1 -1
  27. package/extensions/dashboard-client/dist/assets/{BarChart-BoqeJ5mM.js → BarChart-BU5RJ0In.js} +2 -2
  28. package/extensions/dashboard-client/dist/assets/{BarChart-BoqeJ5mM.js.map → BarChart-BU5RJ0In.js.map} +1 -1
  29. package/extensions/dashboard-client/dist/assets/{CacheTab-1ON7meDK.js → CacheTab-CbX033mt.js} +2 -2
  30. package/extensions/dashboard-client/dist/assets/{CacheTab-1ON7meDK.js.map → CacheTab-CbX033mt.js.map} +1 -1
  31. package/extensions/dashboard-client/dist/assets/{EventsTab-Dr9eqt1k.js → EventsTab-D8Z_4gSB.js} +2 -2
  32. package/extensions/dashboard-client/dist/assets/{EventsTab-Dr9eqt1k.js.map → EventsTab-D8Z_4gSB.js.map} +1 -1
  33. package/extensions/dashboard-client/dist/assets/{HealthTab-Ciaigd4i.js → HealthTab-BUUkoQXo.js} +2 -2
  34. package/extensions/dashboard-client/dist/assets/{HealthTab-Ciaigd4i.js.map → HealthTab-BUUkoQXo.js.map} +1 -1
  35. package/extensions/dashboard-client/dist/assets/{MaintenanceTab-DjZRr3Lf.js → MaintenanceTab-DKZQmY1T.js} +2 -2
  36. package/extensions/dashboard-client/dist/assets/{MaintenanceTab-DjZRr3Lf.js.map → MaintenanceTab-DKZQmY1T.js.map} +1 -1
  37. package/extensions/dashboard-client/dist/assets/{MemoryMapTab-BpZXHA7j.js → MemoryMapTab-DwMGbe3h.js} +2 -2
  38. package/extensions/dashboard-client/dist/assets/{MemoryMapTab-BpZXHA7j.js.map → MemoryMapTab-DwMGbe3h.js.map} +1 -1
  39. package/extensions/dashboard-client/dist/assets/{MetricsTab-QemocY5k.js → MetricsTab-C85lieXW.js} +2 -2
  40. package/extensions/dashboard-client/dist/assets/{MetricsTab-QemocY5k.js.map → MetricsTab-C85lieXW.js.map} +1 -1
  41. package/extensions/dashboard-client/dist/assets/{OverviewTab-VtC1F-mO.js → OverviewTab-D7VPibBT.js} +2 -2
  42. package/extensions/dashboard-client/dist/assets/{OverviewTab-VtC1F-mO.js.map → OverviewTab-D7VPibBT.js.map} +1 -1
  43. package/extensions/dashboard-client/dist/assets/{ReposTab-CJD1cBxp.js → ReposTab-eIHk_mDG.js} +2 -2
  44. package/extensions/dashboard-client/dist/assets/{ReposTab-CJD1cBxp.js.map → ReposTab-eIHk_mDG.js.map} +1 -1
  45. package/extensions/dashboard-client/dist/assets/{SessionsTab-Cj0erPR4.js → SessionsTab-EYOHEzc3.js} +2 -2
  46. package/extensions/dashboard-client/dist/assets/{SessionsTab-Cj0erPR4.js.map → SessionsTab-EYOHEzc3.js.map} +1 -1
  47. package/extensions/dashboard-client/dist/assets/{SetupTab-AOVROZ4G.js → SetupTab-DXpiXu4i.js} +2 -2
  48. package/extensions/dashboard-client/dist/assets/{SetupTab-AOVROZ4G.js.map → SetupTab-DXpiXu4i.js.map} +1 -1
  49. package/extensions/dashboard-client/dist/assets/{TimeSavedCard-ZliVn8DH.js → TimeSavedCard-DUsUC_sm.js} +2 -2
  50. package/extensions/dashboard-client/dist/assets/{TimeSavedCard-ZliVn8DH.js.map → TimeSavedCard-DUsUC_sm.js.map} +1 -1
  51. package/extensions/dashboard-client/dist/assets/{TurnsTab-DsoTWeIh.js → TurnsTab-w7qdB0px.js} +2 -2
  52. package/extensions/dashboard-client/dist/assets/{TurnsTab-DsoTWeIh.js.map → TurnsTab-w7qdB0px.js.map} +1 -1
  53. package/extensions/dashboard-client/dist/assets/VectorCortexTab-BmgdxV5K.js +2 -0
  54. package/extensions/dashboard-client/dist/assets/VectorCortexTab-BmgdxV5K.js.map +1 -0
  55. package/extensions/dashboard-client/dist/assets/{WikiTab-CK8fcW1l.js → WikiTab-B4hwpXpw.js} +2 -2
  56. package/extensions/dashboard-client/dist/assets/{WikiTab-CK8fcW1l.js.map → WikiTab-B4hwpXpw.js.map} +1 -1
  57. package/extensions/dashboard-client/dist/assets/{button-DdPcvex1.js → button-BnbvfQjm.js} +2 -2
  58. package/extensions/dashboard-client/dist/assets/{button-DdPcvex1.js.map → button-BnbvfQjm.js.map} +1 -1
  59. package/extensions/dashboard-client/dist/assets/{card-DXFuZph_.js → card-DCyvWfpF.js} +2 -2
  60. package/extensions/dashboard-client/dist/assets/{card-DXFuZph_.js.map → card-DCyvWfpF.js.map} +1 -1
  61. package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-BagDVGWn.js → generateCategoricalChart-b3HeKJLU.js} +2 -2
  62. package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-BagDVGWn.js.map → generateCategoricalChart-b3HeKJLU.js.map} +1 -1
  63. package/extensions/dashboard-client/dist/assets/{index-DVdDtRY4.js → index-DhlcXMlE.js} +3 -3
  64. package/extensions/dashboard-client/dist/assets/{index-DVdDtRY4.js.map → index-DhlcXMlE.js.map} +1 -1
  65. package/extensions/dashboard-client/dist/assets/{switch-CtdtGyUR.js → switch-B74pQOFy.js} +2 -2
  66. package/extensions/dashboard-client/dist/assets/{switch-CtdtGyUR.js.map → switch-B74pQOFy.js.map} +1 -1
  67. package/extensions/dashboard-client/dist/assets/{toggle-Cvvwlbye.js → toggle-bXDrMX-A.js} +2 -2
  68. package/extensions/dashboard-client/dist/assets/{toggle-Cvvwlbye.js.map → toggle-bXDrMX-A.js.map} +1 -1
  69. package/extensions/dashboard-client/dist/assets/{useSSE-DvlceHjV.js → useSSE-Yq86SUA0.js} +2 -2
  70. package/extensions/dashboard-client/dist/assets/{useSSE-DvlceHjV.js.map → useSSE-Yq86SUA0.js.map} +1 -1
  71. package/extensions/dashboard-client/dist/index.html +1 -1
  72. package/extensions/dashboard-client/src/api/vector-cortex.ts +9 -0
  73. package/extensions/dashboard-client/src/tabs/VectorCortexDiagnosticsCard.tsx +46 -0
  74. package/extensions/dashboard-client/src/tabs/VectorCortexTab.tsx +25 -121
  75. package/extensions/dashboard-client/src/tabs/useVectorCortexPoll.ts +123 -0
  76. package/extensions/dashboard-client/src/types/vector-cortex-vc7.ts +63 -0
  77. package/extensions/dashboard-client/src/types/vector-cortex.ts +5 -33
  78. package/extensions/dashboard-server/api-contracts/vector-cortex-diagnostics.ts +76 -0
  79. package/extensions/dashboard-server/route-dispatch.ts +5 -0
  80. package/extensions/dashboard-server/routes-rag-settings-vector-cortex.ts +6 -0
  81. package/extensions/dashboard-server/routes-vector-cortex-diagnostics.ts +77 -0
  82. package/package.json +1 -1
  83. package/src/config/vector-cortex.ts +21 -0
  84. package/src/config.ts +1 -0
  85. package/src/vector-cortex/cache/_diagnostics-fixture.ts +32 -0
  86. package/src/vector-cortex/cache/breaker.ts +124 -0
  87. package/src/vector-cortex/cache/diagnostics-emit.ts +90 -0
  88. package/src/vector-cortex/cache/diagnostics-types.ts +87 -0
  89. package/src/vector-cortex/cache/diagnostics.ts +119 -0
  90. package/src/vector-cortex/migrations/request-hash-v2-ops.ts +201 -0
  91. package/src/vector-cortex/migrations/request-hash-v2-types.ts +87 -0
  92. package/src/vector-cortex/migrations/request-hash-v2.ts +65 -213
  93. package/extensions/dashboard-client/dist/assets/VectorCortexTab-BBa7rp6C.js +0 -2
  94. package/extensions/dashboard-client/dist/assets/VectorCortexTab-BBa7rp6C.js.map +0 -1
@@ -0,0 +1,87 @@
1
+ /**
2
+ * request-hash-v2-types.ts — M5 request-hash-v2 migration types.
3
+ *
4
+ * Extracted from request-hash-v2.ts to keep the parent file under the 300-line
5
+ * soft limit (soft-as-hard gate). Pure type + constant definitions; no logic.
6
+ * PREVENT-002/011/PI-004 honored.
7
+ */
8
+
9
+ /** The active-version value the v2 pointer is switched to. */
10
+ export const REQUEST_HASH_V2_VERSION = 2;
11
+ /** The legacy (predecessor) active version. */
12
+ export const REQUEST_HASH_LEGACY_VERSION = 1;
13
+
14
+ /** M5 failure codes. */
15
+ export const M5_FAIL = {
16
+ COPY_PARTIAL: "M5_COPY_PARTIAL",
17
+ COUNT_MISMATCH: "M5_COUNT_MISMATCH",
18
+ DIGEST_MISMATCH: "M5_DIGEST_MISMATCH",
19
+ IDENTITY_DRIFT: "M5_IDENTITY_DRIFT",
20
+ /** Two distinct v1 rows map to the same v2 hash — blocks the switch. (VC7C) */
21
+ REQUEST_HASH_COLLISION: "M5_REQUEST_HASH_COLLISION",
22
+ /** The active pointer is not on v1; switching would be a no-op or a regression. */
23
+ NOT_ON_LEGACY: "M5_NOT_ON_LEGACY",
24
+ } as const;
25
+ export type M5MigrationCode = (typeof M5_FAIL)[keyof typeof M5_FAIL];
26
+
27
+ /**
28
+ * Registered M5 conformance IDs (M5-001..020). The acceptance test reads these
29
+ * rows from the v2 `migrations/` domain and asserts each returns its manifest
30
+ * bytes or exactly its listed failure code. Mirrors M6_IDS / M4_IDS.
31
+ */
32
+ export const M5_IDS: readonly string[] = Array.from(
33
+ { length: 20 },
34
+ (_v, i) => `M5-${String(i + 1).padStart(3, "0")}`,
35
+ );
36
+
37
+ /** Named M5 rows surfaced by the conformance corpus (mirrors M6_NAMED_IDS). */
38
+ export const M5_NAMED_IDS = ["M5-COLLIDE-002"] as const;
39
+
40
+ /** A predecessor (v1) request-hash row. */
41
+ export interface RequestHashV1Row {
42
+ readonly profileId: string;
43
+ /** BARE lowercase hex canonical request digest (VC5B convention). */
44
+ readonly requestDigest: string;
45
+ /** The v1 cache-identity hash derived from the request. */
46
+ readonly hash: string;
47
+ }
48
+
49
+ /**
50
+ * A v2 request-hash row. Identity is `(profileId, requestDigest)` — unchanged
51
+ * from v1, which is the point: only `hash` is re-derived, now folding in the
52
+ * economics version.
53
+ */
54
+ export interface RequestHashV2Row {
55
+ readonly profileId: string;
56
+ readonly requestDigest: string;
57
+ /** Economics version folded into the v2 hash (absent in v1). */
58
+ readonly economicsVersion: string;
59
+ /** The v2 cache-identity hash. */
60
+ readonly hash: string;
61
+ }
62
+
63
+ /** The host the migration reads from / writes to (capability-shaped). */
64
+ export interface M5Host {
65
+ /** Every predecessor row being migrated. */
66
+ readonly v1Rows: () => readonly RequestHashV1Row[];
67
+ /** The economics version to fold in, per profile. */
68
+ readonly economicsVersionOf: (profileId: string) => string;
69
+ /** The session a profile belongs to, for M6 generation invalidation lookup. */
70
+ readonly sessionOf: (profileId: string) => string;
71
+ /** The currently live M6 generation for a session (for invalidation checks). */
72
+ readonly liveGenerationOf: (session: string) => bigint;
73
+ /** Persisted v2 rows already written (for resume). */
74
+ readonly existingV2: () => readonly RequestHashV2Row[];
75
+ /** Idempotent write of v2 rows (never mutates v1 rows). */
76
+ readonly putV2: (rows: readonly RequestHashV2Row[]) => void;
77
+ /** The currently ACTIVE version (1 = legacy; only v1 → v2 switching). */
78
+ readonly activeVersion: () => number;
79
+ /** Atomically flip the active pointer to v2. Mirrors M6Host.switchToV2. */
80
+ readonly switchToV2: () => void;
81
+ }
82
+
83
+ /** An M5 validation result. */
84
+ export interface M5ValidateResult {
85
+ readonly ok: boolean;
86
+ readonly codes: readonly M5MigrationCode[];
87
+ }
@@ -1,228 +1,80 @@
1
1
  /**
2
- * vector-cortex/migrations/request-hash-v2.ts — M5 request-hash-v2, COPY +
3
- * VALIDATE ONLY (VC7B). The switch lands in VC7C.
2
+ * vector-cortex/migrations/request-hash-v2.ts — M5 request-hash-v2 migration
3
+ * (COPY + VALIDATE + SWITCH).
4
+ *
5
+ * Delegate-shell: types + constants live in request-hash-v2-types.ts and the
6
+ * operational logic (copy/verify/switch/collision) lives in
7
+ * request-hash-v2-ops.ts. This file re-exports the public surface so callers
8
+ * import from a single module. Split to keep under the 300-line soft limit
9
+ * (soft-as-hard gate).
4
10
  *
5
11
  * M5 versions the canonical request hash: the predecessor hashed the outbound
6
12
  * request under the v1 scheme; v2 folds in the provider profile's ECONOMICS
7
13
  * version so a pricing/TTL/exclusion change cannot silently reuse a cache
8
14
  * identity minted under different economics. Like M4/M6 it follows the
9
- * copy/validate/switch contract — but VC7B deliberately stops after validate:
15
+ * copy/validate/switch contract:
10
16
  *
11
17
  * - copy: resumable per (profile, request) — an interrupted run resumes
12
18
  * without duplicate rows or active-pointer drift.
13
19
  * - validate: every v1 row has exactly one v2 row, every v2 digest re-hashes
14
- * from its own declared fields, and — the M5-specific invariant —
15
- * the migration is IDENTITY-PRESERVING: a v2 row must carry the
16
- * same `requestDigest` as the v1 row it came from. v2 changes how
17
- * a CACHE KEY is derived, never what the request IS. A row whose
18
- * request digest drifted is rejected (`M5_IDENTITY_DRIFT`).
19
- * - switch: NOT IMPLEMENTED IN VC7B. `m5Switch` exists so the shape of the
20
- * lifecycle is reviewable, but it always refuses with
21
- * `M5_SWITCH_DEFERRED` and leaves the active pointer on v1.
20
+ * from its own declared fields, the migration is IDENTITY-PRESERVING
21
+ * (a v2 row carries the same `requestDigest` as its v1 source — v2
22
+ * changes how a CACHE KEY is derived, never what the request IS), and
23
+ * — the M5-specific invariant ADDED in VC7C — there are ZERO
24
+ * collisions: no two distinct v1 rows may map to one v2 hash. A
25
+ * collision (`M5_REQUEST_HASH_COLLISION`) means two different
26
+ * conversations would share a cache key, the most dangerous outcome
27
+ * in the subsystem, so it blocks the switch outright.
28
+ * - switch: ATOMICALLY flip the active pointer to v2 via `host.switchToV2()`.
29
+ * VC7B deferred this; VC7C performs it — but ONLY after re-validating
30
+ * against freshly-read host state at switch time.
22
31
  *
23
- * WHY THE SWITCH IS WITHHELD. Flipping the request-hash version invalidates
24
- * every crystal minted under v1 in one step. VC7C first runs the shadow
25
- * comparison (v1 vs v2 digests over live traffic) so the blast radius is
26
- * measured before it is taken. Shipping the switch here would mean flipping it
27
- * on evidence that does not exist yet — so the function is present, refuses, and
28
- * says why, rather than being a TODO comment someone later mistakes for done.
29
- * Old-binary protocol: a reader that predates v2 keeps reading v1 rows, which
30
- * remain untouched and authoritative for the whole of VC7B.
32
+ * WHY THE COLLISION CHECK RUNS AT SWITCH TIME, NOT VALIDATE TIME. The brief's
33
+ * failure-injection contract is explicit: crash after M5 validation, inject a
34
+ * collision into host state, then resume — and the RESUMED run must detect
35
+ * `M5_REQUEST_HASH_COLLISION`. If the collision were detected only from the result
36
+ * of an earlier `m5Verify` call, the cached result would be replayed and the
37
+ * injected collision would be invisible. So `m5Switch` RE-READS the host (`v1Rows`,
38
+ * `existingV2`, `activeVersion`) and RE-RUNS the collision check against that live
39
+ * state. Validation is a precondition; the switch is the only place that proves the
40
+ * hazard is absent *right now*. This is the same resume-after-crash discipline as
41
+ * M4/M6: a migration that trusts a stale verification is a migration that loses
42
+ * data on restart.
31
43
  *
32
- * Pure logic over an injected M5Host (deterministic + testable; no console).
33
- * PREVENT-002/011/PI-004 honored.
34
- */
35
-
36
- import { createHash } from "node:crypto";
37
-
38
- /** The active-version value the v2 pointer will be switched to — in VC7C. */
39
- export const REQUEST_HASH_V2_VERSION = 2;
40
- /** The legacy (predecessor) active version; VC7B never leaves this. */
41
- export const REQUEST_HASH_LEGACY_VERSION = 1;
42
-
43
- /** M5 failure codes. */
44
- export const M5_FAIL = {
45
- COPY_PARTIAL: "M5_COPY_PARTIAL",
46
- COUNT_MISMATCH: "M5_COUNT_MISMATCH",
47
- DIGEST_MISMATCH: "M5_DIGEST_MISMATCH",
48
- IDENTITY_DRIFT: "M5_IDENTITY_DRIFT",
49
- SWITCH_DEFERRED: "M5_SWITCH_DEFERRED",
50
- } as const;
51
- export type M5MigrationCode = (typeof M5_FAIL)[keyof typeof M5_FAIL];
52
-
53
- /** A predecessor (v1) request-hash row. */
54
- export interface RequestHashV1Row {
55
- readonly profileId: string;
56
- /** BARE lowercase hex canonical request digest (VC5B convention). */
57
- readonly requestDigest: string;
58
- /** The v1 cache-identity hash derived from the request. */
59
- readonly hash: string;
60
- }
61
-
62
- /**
63
- * A v2 request-hash row. Identity is `(profileId, requestDigest)` — unchanged
64
- * from v1, which is the point: only `hash` is re-derived, now folding in the
65
- * economics version.
66
- */
67
- export interface RequestHashV2Row {
68
- readonly profileId: string;
69
- readonly requestDigest: string;
70
- /** Economics version folded into the v2 hash (absent in v1). */
71
- readonly economicsVersion: string;
72
- /** The v2 cache-identity hash. */
73
- readonly hash: string;
74
- }
75
-
76
- /** The host the migration reads from / writes to (capability-shaped). */
77
- export interface M5Host {
78
- /** Every predecessor row being migrated. */
79
- readonly v1Rows: () => readonly RequestHashV1Row[];
80
- /** The economics version to fold in, per profile. */
81
- readonly economicsVersionOf: (profileId: string) => string;
82
- /** Persisted v2 rows already written (for resume). */
83
- readonly existingV2: () => readonly RequestHashV2Row[];
84
- /** Idempotent write of v2 rows (never mutates v1 rows). */
85
- readonly putV2: (rows: readonly RequestHashV2Row[]) => void;
86
- /** The currently ACTIVE version (1 = legacy; VC7B never changes it). */
87
- readonly activeVersion: () => number;
88
- }
89
-
90
- /** An M5 validation result. */
91
- export interface M5ValidateResult {
92
- readonly ok: boolean;
93
- readonly codes: readonly M5MigrationCode[];
94
- }
95
-
96
- /** Length-prefixed framing so the folded fields cannot alias. */
97
- function field(value: string): string {
98
- return `${Buffer.byteLength(value, "utf8")}:${value}`;
99
- }
100
-
101
- /**
102
- * The authoritative v2 hash: SHA-256 over the version tag, profile, request
103
- * digest, and economics version. Length-prefixed for injectivity, exactly as the
104
- * crystal key encoder frames its fields.
105
- */
106
- export function deriveRequestHashV2(
107
- profileId: string,
108
- requestDigest: string,
109
- economicsVersion: string,
110
- ): string {
111
- return createHash("sha256")
112
- .update(
113
- field("request-hash-v2") + field(profileId) + field(requestDigest) + field(economicsVersion),
114
- "utf8",
115
- )
116
- .digest("hex");
117
- }
118
-
119
- /** Derive the v2 row for one v1 row. */
120
- export function deriveRequestHashRow(host: M5Host, v1: RequestHashV1Row): RequestHashV2Row {
121
- const economicsVersion = host.economicsVersionOf(v1.profileId);
122
- return {
123
- profileId: v1.profileId,
124
- // IDENTITY-PRESERVING: carried through verbatim, never re-derived.
125
- requestDigest: v1.requestDigest,
126
- economicsVersion,
127
- hash: deriveRequestHashV2(v1.profileId, v1.requestDigest, economicsVersion),
128
- };
129
- }
130
-
131
- const identity = (profileId: string, requestDigest: string): string =>
132
- `${profileId}::${requestDigest}`;
133
-
134
- /**
135
- * Copy every v1 row into a v2 row BESIDE it (resumable, idempotent). Rows already
136
- * persisted with a matching derivation are left untouched; absent or stale rows
137
- * are (re)written from the authoritative derivation. The active pointer is never
138
- * touched — v1 remains authoritative throughout VC7B.
139
- */
140
- export function m5Copy(host: M5Host): {
141
- readonly written: readonly RequestHashV2Row[];
142
- readonly all: readonly RequestHashV2Row[];
143
- } {
144
- const existing = new Map(host.existingV2().map((r) => [identity(r.profileId, r.requestDigest), r]));
145
- const wanted: RequestHashV2Row[] = [];
146
- for (const v1 of host.v1Rows()) {
147
- const fresh = deriveRequestHashRow(host, v1);
148
- const stored = existing.get(identity(v1.profileId, v1.requestDigest));
149
- if (
150
- stored !== undefined &&
151
- stored.hash === fresh.hash &&
152
- stored.economicsVersion === fresh.economicsVersion
153
- ) {
154
- continue; // healthy, already copied
155
- }
156
- wanted.push(fresh);
157
- }
158
- if (wanted.length > 0) host.putV2(wanted);
159
- return { written: wanted, all: [...host.existingV2()] };
160
- }
161
-
162
- /**
163
- * Validate the copied set: exactly one v2 row per v1 row, every v2 hash
164
- * re-derives from its own declared fields, no orphan v2 rows, and every v2 row's
165
- * request digest equals its v1 source's (identity preservation). Never mutates.
166
- */
167
- export function m5Verify(host: M5Host): M5ValidateResult {
168
- const codes: M5MigrationCode[] = [];
169
- const stored = host.existingV2();
170
- const v1Rows = host.v1Rows();
171
-
172
- const counts = new Map<string, number>();
173
- for (const r of stored) {
174
- const id = identity(r.profileId, r.requestDigest);
175
- counts.set(id, (counts.get(id) ?? 0) + 1);
176
- }
177
-
178
- const expected = new Set<string>();
179
- for (const v1 of v1Rows) {
180
- const id = identity(v1.profileId, v1.requestDigest);
181
- expected.add(id);
182
- const n = counts.get(id) ?? 0;
183
- if (n === 0) codes.push(M5_FAIL.COPY_PARTIAL);
184
- if (n > 1) codes.push(M5_FAIL.COUNT_MISMATCH);
185
- }
186
-
187
- // Every v1 request digest that must survive the migration unchanged.
188
- const v1Digests = new Set(v1Rows.map((r) => identity(r.profileId, r.requestDigest)));
189
- for (const r of stored) {
190
- const fresh = deriveRequestHashV2(r.profileId, r.requestDigest, r.economicsVersion);
191
- if (r.hash !== fresh) codes.push(M5_FAIL.DIGEST_MISMATCH);
192
- const id = identity(r.profileId, r.requestDigest);
193
- // A v2 row whose identity has no v1 source either drifted or is an orphan.
194
- if (!v1Digests.has(id)) {
195
- codes.push(expected.size > 0 ? M5_FAIL.IDENTITY_DRIFT : M5_FAIL.COUNT_MISMATCH);
196
- }
197
- }
198
-
199
- return { ok: codes.length === 0, codes: dedupe(codes) };
200
- }
201
-
202
- /**
203
- * The switch — DEFERRED TO VC7C BY DESIGN.
44
+ * M6 INVALIDATION CONSUMPTION. A v2 request hash is only as trustworthy as the
45
+ * generation it was minted under. The switch consumes M6's structured invalidation
46
+ * keys via the REAL API (`invalidationKey` from `../topology/query.js`) rather than
47
+ * inventing one: when a v2 row's economics version maps to an invalidated router
48
+ * generation, that row cannot be promoted to active. We do not re-derive a
49
+ * generation here — topology is the authority on what generation is live — we only
50
+ * refuse to switch a row whose generation is dead. This keeps M5 from resurrecting
51
+ * cache identities tied to a generation the router has already invalidated.
204
52
  *
205
- * Always refuses and always leaves the active pointer on v1. It exists so the
206
- * lifecycle is complete and reviewable, and so a caller that tries to switch
207
- * early gets an explicit `M5_SWITCH_DEFERRED` instead of silence.
208
- */
209
- export function m5Switch(host: M5Host): M5ValidateResult {
210
- void host;
211
- return { ok: false, codes: [M5_FAIL.SWITCH_DEFERRED] };
212
- }
213
-
214
- /**
215
- * The VC7B M5 lifecycle: copy -> verify. NO SWITCH. Returns the verify result;
216
- * the active version pointer is guaranteed to still be
217
- * `REQUEST_HASH_LEGACY_VERSION` on return.
53
+ * PREVENT-002/011/PI-004 honored.
218
54
  */
219
- export function migrateRequestHashV2CopyValidate(host: M5Host): M5ValidateResult {
220
- m5Copy(host);
221
- return m5Verify(host);
222
- }
223
55
 
224
- function dedupe(codes: readonly M5MigrationCode[]): M5MigrationCode[] {
225
- const out: M5MigrationCode[] = [];
226
- for (const c of codes) if (!out.includes(c)) out.push(c);
227
- return out;
228
- }
56
+ export {
57
+ REQUEST_HASH_V2_VERSION,
58
+ REQUEST_HASH_LEGACY_VERSION,
59
+ M5_FAIL,
60
+ M5_IDS,
61
+ M5_NAMED_IDS,
62
+ } from "./request-hash-v2-types.js";
63
+ export type {
64
+ M5MigrationCode,
65
+ RequestHashV1Row,
66
+ RequestHashV2Row,
67
+ M5Host,
68
+ M5ValidateResult,
69
+ } from "./request-hash-v2-types.js";
70
+
71
+ export {
72
+ deriveRequestHashV2,
73
+ deriveRequestHashRow,
74
+ detectCollision,
75
+ isGenerationInvalidated,
76
+ m5Copy,
77
+ m5Verify,
78
+ m5Switch,
79
+ migrateRequestHashV2,
80
+ } from "./request-hash-v2-ops.js";
@@ -1,2 +0,0 @@
1
- import{j as e,B as r,r as n}from"./index-DVdDtRY4.js";import{C as o,a as d,b as i,c as x}from"./card-DXFuZph_.js";async function J(){const s=await fetch("/api/vector-cortex/evaluation");if(!s.ok)throw new Error(`vector-cortex evaluation: ${s.status}`);return s.json()}async function C(){const s=await fetch("/api/vector-cortex/health");if(!s.ok)throw new Error(`vector-cortex health: ${s.status}`);return s.json()}async function X(){const s=await fetch("/api/vector-cortex/topology");if(!s.ok)throw new Error(`vector-cortex topology: ${s.status}`);return s.json()}async function ee(){const s=await fetch("/api/vector-cortex/query");if(!s.ok)throw new Error(`vector-cortex query: ${s.status}`);return s.json()}async function se(){const s=await fetch("/api/vector-cortex/shards");if(!s.ok)throw new Error(`vector-cortex shards: ${s.status}`);return s.json()}async function te(){const s=await fetch("/api/vector-cortex/reconstruct");if(!s.ok)throw new Error(`vector-cortex reconstruct: ${s.status}`);return s.json()}async function re(){const s=await fetch("/api/vector-cortex/plans");if(!s.ok)throw new Error(`vector-cortex plans: ${s.status}`);return s.json()}async function ae(){const s=await fetch("/api/vector-cortex/render");if(!s.ok)throw new Error(`vector-cortex render: ${s.status}`);return s.json()}async function ne(){const s=await fetch("/api/vector-cortex/rollout");if(!s.ok)throw new Error(`vector-cortex rollout: ${s.status}`);return s.json()}async function le(){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 ce(){const s=await fetch("/api/vector-cortex/restore");if(!s.ok)throw new Error(`vector-cortex restore: ${s.status}`);return s.json()}async function oe(){const s=await fetch("/api/vector-cortex/repair");if(!s.ok)throw new Error(`vector-cortex repair: ${s.status}`);return s.json()}async function de(s="default"){const a=await fetch(`/api/vector-cortex/ledger?session=${encodeURIComponent(s)}`);if(!a.ok)throw new Error(`vector-cortex ledger: ${a.status}`);return a.json()}async function ie(s){const a=await fetch("/api/vector-cortex/breakers/reset",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({subsystem:s})});if(!a.ok)throw new Error(`vector-cortex reset: ${a.status}`);return a.json()}async function xe(){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 ue(){const s=await fetch("/api/vector-cortex/cache-economics");if(!s.ok)throw new Error(`vector-cortex cache-economics: ${s.status}`);return s.json()}function t({label:s,value:a}){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:a})]})}function he({view:s}){return e.jsxs(o,{children:[e.jsx(d,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(i,{children:"Validated Prompt Renderer (VC5B)"}),s?.enabled?e.jsx(r,{variant:"success",children:"ACTIVE"}):e.jsx(r,{variant:"danger",children:"OFF"})]})}),e.jsx(x,{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(t,{label:"Render fixtures",value:String(s.renderCount)}),e.jsx(t,{label:"Provider profiles",value:String(s.providerCount)}),e.jsx(t,{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 je({view:s}){return e.jsxs(o,{children:[e.jsx(d,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(i,{children:"Live Graduated Rollout (VC5C)"}),s?.enabled?e.jsx(r,{variant:"success",children:"ACTIVE"}):e.jsx(r,{variant:"danger",children:"OFF"})]})}),e.jsx(x,{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(t,{label:"Gate",value:`${s.gatePct}%`}),e.jsx(t,{label:"Exposed buckets",value:String(s.bucketCount)}),e.jsx(t,{label:"Total buckets",value:String(s.buckets)}),e.jsx(t,{label:"Promotion",value:s.promotionBlocked?"FROZEN":"OPEN"}),e.jsx(t,{label:"Events",value:String(s.events)}),e.jsx(t,{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 me({view:s}){return e.jsxs(o,{children:[e.jsx(d,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(i,{children:"Closure Optimization (VC6A)"}),s?.enabled?e.jsx(r,{variant:"success",children:"ACTIVE"}):e.jsx(r,{variant:"danger",children:"OFF"})]})}),e.jsx(x,{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(t,{label:"Mode",value:s.mode}),e.jsx(t,{label:"Optimizations",value:String(s.optimizations)}),e.jsx(t,{label:"Proof rejections",value:String(s.proofRejections)}),e.jsx(t,{label:"Last rejection",value:s.lastRejection??"none"}),e.jsx(t,{label:"Retained edges",value:String(s.retainedEdgeTotal)}),e.jsx(t,{label:"Removed edges",value:String(s.removedEdgeTotal)}),e.jsx(t,{label:"Conservative walks",value:String(s.conservativeTraversalTotal)}),e.jsx(t,{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 ge({view:s}){return e.jsxs(o,{children:[e.jsx(d,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(i,{children:"Exact Source Restoration (VC6B)"}),s?.enabled?e.jsx(r,{variant:"success",children:"ACTIVE"}):e.jsx(r,{variant:"danger",children:"OFF"})]})}),e.jsx(x,{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(t,{label:"Mode",value:s.mode}),e.jsx(t,{label:"Restore attempts",value:String(s.restoreAttempts)}),e.jsx(t,{label:"Restored",value:String(s.restoredCount)}),e.jsx(t,{label:"Missing source",value:String(s.missingCount)}),e.jsx(t,{label:"Digest rejections",value:String(s.digestRejections)}),e.jsx(t,{label:"Last rejection",value:s.lastRejection??"none"}),e.jsx(t,{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 fe({view:s}){return e.jsxs(o,{children:[e.jsx(d,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(i,{children:"Self-Healing Derived State (VC6C)"}),s?.enabled?e.jsx(r,{variant:"success",children:"ACTIVE"}):e.jsx(r,{variant:"danger",children:"OFF"})]})}),e.jsx(x,{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(t,{label:"Mode",value:s.mode}),e.jsx(t,{label:"Repair attempts",value:String(s.repairAttempts)}),e.jsx(t,{label:"Repairs planned",value:String(s.repairsPlanned)}),e.jsx(t,{label:"Pointers switched",value:String(s.pointersSwitched)}),e.jsx(t,{label:"Backoffs",value:String(s.backoffs)}),e.jsx(t,{label:"Last backoff",value:s.lastBackoffMs===null?"none":`${s.lastBackoffMs}ms`}),e.jsx(t,{label:"Last failure",value:s.lastFailure??"none"}),e.jsx(t,{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 ve({view:s}){return e.jsxs(o,{children:[e.jsx(d,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(i,{children:"Frozen Range Crystals (VC7A)"}),s?.enabled?e.jsx(r,{variant:"success",children:"ACTIVE"}):e.jsx(r,{variant:"danger",children:"OFF"})]})}),e.jsx(x,{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(t,{label:"Mode",value:s.mode}),e.jsx(t,{label:"Crystals",value:String(s.crystalCount)}),e.jsx(t,{label:"Frozen bytes",value:String(s.totalBytes)}),e.jsx(t,{label:"Hits",value:String(s.hits)}),e.jsx(t,{label:"Misses",value:String(s.misses)}),e.jsx(t,{label:"Hit bytes",value:String(s.hitBytes)}),e.jsx(t,{label:"Writes",value:String(s.writes)}),e.jsx(t,{label:"Duplicate writes",value:String(s.duplicateWrites)}),e.jsx(t,{label:"Collisions",value:String(s.collisions)}),e.jsx(t,{label:"Last failure",value:s.lastFailure??"none"}),e.jsx(t,{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 pe({view:s}){return e.jsxs(o,{children:[e.jsx(d,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(i,{children:"Cache Economics (VC7B)"}),s?.enabled?e.jsx(r,{variant:"success",children:"ACTIVE"}):e.jsx(r,{variant:"danger",children:"OFF"})]})}),e.jsx(x,{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(t,{label:"Mode",value:s.mode}),e.jsx(t,{label:"Profiles",value:String(s.profileCount)}),e.jsx(t,{label:"Proven exclusions",value:String(s.provenExclusions)}),e.jsx(t,{label:"Unproven exclusions",value:String(s.unprovenExclusions)}),e.jsx(t,{label:"Last failure",value:s.lastFailure??"none"}),e.jsx(t,{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 be({view:s}){return e.jsxs(o,{children:[e.jsx(d,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(i,{children:"Dual-Tier Shards (VC4A)"}),s?.enabled?e.jsx(r,{variant:"success",children:"ACTIVE"}):e.jsx(r,{variant:"danger",children:"OFF"})]})}),e.jsx(x,{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(t,{label:"Semantic shards",value:String(s.semanticCount)}),e.jsx(t,{label:"Exact shards",value:String(s.exactCount)}),e.jsx(t,{label:"Byte total",value:String(s.byteTotal)}),e.jsx(t,{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 Ce({view:s}){return e.jsxs(o,{children:[e.jsx(d,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(i,{children:"Reconstruction Fidelity (VC4C)"}),s?.enabled?e.jsx(r,{variant:"success",children:"ACTIVE"}):e.jsx(r,{variant:"danger",children:"OFF"})]})}),e.jsx(x,{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(t,{label:"Closure attempts",value:String(s.closureAttempts)}),e.jsx(t,{label:"Closure rejections",value:String(s.closureRejections)}),e.jsx(t,{label:"Validated",value:String(s.validatedCount)}),e.jsx(t,{label:"Invalidated",value:String(s.invalidatedCount)}),e.jsx(t,{label:"Span total",value:String(s.spanTotal)}),e.jsx(t,{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 ye({view:s}){return e.jsxs(o,{children:[e.jsx(d,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(i,{children:"Plan Manifests (VC5A)"}),s?.enabled?e.jsx(r,{variant:"success",children:"ACTIVE"}):e.jsx(r,{variant:"danger",children:"OFF"})]})}),e.jsx(x,{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(t,{label:"DAG fixtures",value:String(s.dagCount)}),e.jsx(t,{label:"Plan fixtures",value:String(s.plannerCount)}),e.jsx(t,{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 Ne({topology:s,query:a}){return e.jsxs(e.Fragment,{children:[e.jsxs(o,{children:[e.jsx(d,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(i,{children:"Derived Cortex Store (VC3A)"}),s?.enabled?e.jsx(r,{variant:"success",children:"ACTIVE"}):e.jsx(r,{variant:"danger",children:"OFF"})]})}),e.jsx(x,{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(t,{label:"Generation",value:s.generationId??"—"}),e.jsx(t,{label:"Ordinal",value:s.ordinal??"—"}),e.jsx(t,{label:"Records",value:String(s.recordCount)}),e.jsx(t,{label:"Frontier (HW)",value:s.sourceHighWater}),e.jsx(t,{label:"Root digest",value:s.rootDigest?s.rootDigest.slice(0,16):"—"}),s.nodes!==void 0&&e.jsxs(e.Fragment,{children:[e.jsx(t,{label:"Nodes",value:String(s.nodes?.length??0)}),e.jsx(t,{label:"Edges",value:String(s.edges?.length??0)}),e.jsx(t,{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((u,h)=>e.jsxs("tr",{className:"border-b border-border/30",children:[e.jsx("td",{className:"py-1 pr-2 font-mono",children:u.source}),e.jsx("td",{className:"py-1 pr-2 font-mono",children:u.target}),e.jsx("td",{className:"py-1 pr-2 font-mono",children:u.head}),e.jsx("td",{className:"py-1 pr-2",children:u.direction}),e.jsx("td",{className:"py-1 font-mono",children:u.score})]},`${u.source}-${u.target}-${u.head}-${h}`))})]})]})]}):e.jsx("div",{className:"vc-empty",children:"Cortex store disabled (VC3A off)."})})]}),e.jsxs(o,{children:[e.jsx(d,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(i,{children:"Topology Query Diagnostics (VC3C)"}),a?.enabled?e.jsx(r,{variant:"success",children:"ACTIVE"}):e.jsx(r,{variant:"danger",children:"OFF"})]})}),e.jsx(x,{children:a?.enabled?e.jsx("div",{className:"grid grid-cols-2 gap-4 md:grid-cols-3",children:e.jsx(t,{label:"Router version",value:String(a.routerVersion)})}):e.jsx("div",{className:"vc-empty",children:"Query diagnostics unavailable (VC3C off)."})})]})]})}function Se({ledger:s}){return e.jsxs(o,{children:[e.jsx(d,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(i,{children:"Occurrence Ledger (VC1B)"}),s?.enabled?e.jsx(r,{variant:"success",children:"ACTIVE"}):e.jsx(r,{variant:"danger",children:"OFF"})]})}),e.jsx(x,{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(t,{label:"Session",value:s.session}),e.jsx(t,{label:"High-water",value:s.highWater}),e.jsx(t,{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(a=>e.jsxs("tr",{className:"border-b border-border/30",children:[e.jsx("td",{className:"py-1 pr-2 font-mono",children:a.seq}),e.jsx("td",{className:"py-1 pr-2 font-mono",children:a.eventId}),e.jsx("td",{className:"py-1 pr-2",children:a.kind}),e.jsx("td",{className:"py-1 pr-2 font-mono",children:a.toolCallId??"—"}),e.jsx("td",{className:"max-w-[180px] truncate font-mono text-muted-foreground",children:a.digest})]},`${a.seq}-${a.eventId}`))})]})})]}):e.jsx("div",{className:"vc-empty",children:"Ledger disabled (VC1B off)."})})]})}function m({mode:s,count:a}){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:a})]})}function Re(){const[s,a]=n.useState(null),[u,h]=n.useState(null),[y,N]=n.useState(!0),[c,g]=n.useState(null),[f,v]=n.useState(null),[S,V]=n.useState(null),[E,R]=n.useState(null),[F,A]=n.useState(null),[T,k]=n.useState(null),[I,P]=n.useState(null),[$,w]=n.useState(null),[O,B]=n.useState(null),[M,L]=n.useState(null),[D,H]=n.useState(null),[z,U]=n.useState(null),[Y,_]=n.useState(null),[q,G]=n.useState(null),[W,Q]=n.useState(null),j=n.useCallback(()=>{J().then(a).catch(l=>h(l instanceof Error?l.message:String(l))).finally(()=>N(!1)),C().then(g).catch(()=>{}),de().then(V).catch(()=>{}),X().then(R).catch(()=>{}),ee().then(A).catch(()=>{}),se().then(k).catch(()=>{}),te().then(P).catch(()=>{}),re().then(w).catch(()=>{}),ae().then(B).catch(()=>{}),ne().then(L).catch(()=>{}),le().then(H).catch(()=>{}),ce().then(U).catch(()=>{}),oe().then(_).catch(()=>{}),xe().then(G).catch(()=>{}),ue().then(Q).catch(()=>{})},[]);n.useEffect(()=>{j();const l=setInterval(j,5e3);return()=>clearInterval(l)},[j]);const K=()=>{ie("provider").then(l=>(v(`Breaker "${l.subsystem}" ${l.state}; evidence retained: ${l.failures} failures / ${l.attempts} attempts`),C())).then(g).catch(l=>v(l instanceof Error?l.message:String(l)))};if(y&&!s)return e.jsx("div",{className:"vc-loading",children:"Loading vector-cortex evaluation…"});if(u&&!s)return e.jsxs("div",{className:"vc-error",children:["Error: ",u]});if(!s)return e.jsx("div",{className:"vc-empty",children:"No evaluation data available."});const p=Math.max(1,...s.histogram.cells,s.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"}),s.enabled?e.jsx(r,{variant:"warning",children:"OBSERVER PENDING (A)"}):e.jsx(r,{variant:"danger",children:"MODE C (OFF)"})]}),e.jsxs("div",{className:"grid grid-cols-1 gap-4 md:grid-cols-3",children:[e.jsxs(o,{children:[e.jsx(d,{children:e.jsx(i,{children:"Samples"})}),e.jsxs(x,{children:[e.jsx("div",{className:"text-3xl font-bold",children:s.samples}),e.jsxs("div",{className:"mt-2 flex flex-col",children:[e.jsx(m,{mode:"A",count:s.byMode.A}),e.jsx(m,{mode:"B",count:s.byMode.B}),e.jsx(m,{mode:"C",count:s.byMode.C})]})]})]}),e.jsxs(o,{className:"md:col-span-2",children:[e.jsx(d,{children:e.jsx(i,{children:"Latency Histogram (ms, inclusive edges)"})}),e.jsxs(x,{children:[e.jsxs("div",{className:"flex items-end gap-2",style:{height:160},children:[s.histogram.edges.map((l,b)=>{const Z=s.histogram.cells[b]/p*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:s.histogram.cells[b]}),e.jsx("div",{className:"w-full rounded-t",style:{height:Math.max(2,Z),background:"#6366f1"}}),e.jsxs("span",{className:"text-[10px] text-muted-foreground",children:["≤",l]})]},l)}),e.jsxs("div",{className:"flex flex-1 flex-col items-center gap-1",children:[e.jsx("span",{className:"text-xs text-muted-foreground",children:s.histogram.overflow}),e.jsx("div",{className:"w-full rounded-t",style:{height:Math.max(2,s.histogram.overflow/p*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: ",s.histogram.total," · Rejects: ",s.rejects.length]})]})]})]}),e.jsxs(o,{children:[e.jsx(d,{children:e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx(i,{children:"Live Safety Envelope (VC0C)"}),e.jsxs("div",{className:"flex items-center gap-2",children:[c?.stateSource==="ephemeral"&&e.jsx(r,{variant:"outline",children:"EPHEMERAL (non-live)"}),e.jsx("button",{onClick:K,disabled:!c?.enabled,className:"rounded border border-border px-2 py-1 text-xs disabled:opacity-50",children:"Reset Cooldown"})]})]})}),e.jsxs(x,{children:[f&&e.jsx("div",{className:"mb-2 text-xs text-muted-foreground",children:f}),c?e.jsxs("div",{className:"grid grid-cols-2 gap-4 md:grid-cols-4",children:[e.jsx(t,{label:"State",value:c.state}),e.jsx(t,{label:"Mode",value:c.mode}),e.jsx(t,{label:"Window",value:`${c.windowMs}ms`}),e.jsx(t,{label:"Probes",value:String(c.probeCount)}),e.jsx(t,{label:"Backoff",value:`${c.backoffDelayMs}ms`}),e.jsx(t,{label:"Failures",value:`${c.failures}/${c.attempts}`}),e.jsx(t,{label:"Frontier",value:c.stateSource==="ephemeral"?"non-live":c.frontierFrozen?"FROZEN":"LIVE"}),e.jsx(t,{label:"Spool lag",value:String(c.spoolLag)}),e.jsx(t,{label:"Encoder mode",value:c.encoderMode}),e.jsx(t,{label:"Encoder asset",value:c.encoderAssetDigest?c.encoderAssetDigest.slice(0,12):"none"})]}):e.jsx("div",{className:"vc-empty",children:"Health unavailable (VC0C off)."})]})]}),e.jsx(Ne,{topology:E,query:F}),e.jsx(be,{view:T}),e.jsx(Ce,{view:I}),e.jsx(ye,{view:$}),e.jsx(he,{view:O}),e.jsx(je,{view:M}),e.jsx(me,{view:D}),e.jsx(ge,{view:z}),e.jsx(fe,{view:Y}),e.jsx(ve,{view:q}),e.jsx(pe,{view:W}),e.jsx(Se,{ledger:S})]})}export{Re as default};
2
- //# sourceMappingURL=VectorCortexTab-BBa7rp6C.js.map