pi-mega-compact 0.20.27 → 0.20.28

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-vc9b.js +29 -0
  2. package/dist/config/vector-cortex-vc9c.js +34 -0
  3. package/dist/config/vector-cortex.js +3 -3
  4. package/dist/config.js +1 -1
  5. package/dist/extensions/dashboard-server/api-contracts/endpoints/registry-ext.js +13 -0
  6. package/dist/extensions/dashboard-server/api-contracts/setup-cortex.js +6 -5
  7. package/dist/extensions/dashboard-server/route-dispatch.js +5 -1
  8. package/dist/extensions/dashboard-server/routes-rag-settings-vector-cortex.js +2 -0
  9. package/dist/extensions/dashboard-server/routes-setup-cortex-actions.js +116 -0
  10. package/dist/extensions/dashboard-server/routes.js +1 -0
  11. package/dist/extensions/dashboard-server/setup-cortex-actions.js +213 -0
  12. package/dist/extensions/dashboard-server/setup-cortex-blockers.js +17 -0
  13. package/dist/src/config/vector-cortex-vc9b.js +29 -0
  14. package/dist/src/config/vector-cortex-vc9c.js +34 -0
  15. package/dist/src/config/vector-cortex.js +3 -3
  16. package/dist/src/config.js +1 -1
  17. package/extensions/dashboard-client/dist/assets/{AreaChart-Bl8FQm-w.js → AreaChart-DIKsPqLG.js} +2 -2
  18. package/extensions/dashboard-client/dist/assets/{AreaChart-Bl8FQm-w.js.map → AreaChart-DIKsPqLG.js.map} +1 -1
  19. package/extensions/dashboard-client/dist/assets/{BarChart-BXn1a_v9.js → BarChart-DeqN74Hn.js} +2 -2
  20. package/extensions/dashboard-client/dist/assets/{BarChart-BXn1a_v9.js.map → BarChart-DeqN74Hn.js.map} +1 -1
  21. package/extensions/dashboard-client/dist/assets/{CacheTab-DzZpIHkZ.js → CacheTab-x1YU4tYc.js} +2 -2
  22. package/extensions/dashboard-client/dist/assets/{CacheTab-DzZpIHkZ.js.map → CacheTab-x1YU4tYc.js.map} +1 -1
  23. package/extensions/dashboard-client/dist/assets/{EventsTab-rn_Ncwk0.js → EventsTab-6BuEbd8Y.js} +2 -2
  24. package/extensions/dashboard-client/dist/assets/{EventsTab-rn_Ncwk0.js.map → EventsTab-6BuEbd8Y.js.map} +1 -1
  25. package/extensions/dashboard-client/dist/assets/{HealthTab-D4d20PFh.js → HealthTab-B71Ft1ac.js} +2 -2
  26. package/extensions/dashboard-client/dist/assets/{HealthTab-D4d20PFh.js.map → HealthTab-B71Ft1ac.js.map} +1 -1
  27. package/extensions/dashboard-client/dist/assets/{MaintenanceTab-44lwue_H.js → MaintenanceTab-dysyJtHk.js} +2 -2
  28. package/extensions/dashboard-client/dist/assets/{MaintenanceTab-44lwue_H.js.map → MaintenanceTab-dysyJtHk.js.map} +1 -1
  29. package/extensions/dashboard-client/dist/assets/{MemoryMapTab-BPCPyPqp.js → MemoryMapTab-B3dKRb_4.js} +2 -2
  30. package/extensions/dashboard-client/dist/assets/{MemoryMapTab-BPCPyPqp.js.map → MemoryMapTab-B3dKRb_4.js.map} +1 -1
  31. package/extensions/dashboard-client/dist/assets/{MetricsTab-B1is6D7F.js → MetricsTab-COn4GoUK.js} +2 -2
  32. package/extensions/dashboard-client/dist/assets/{MetricsTab-B1is6D7F.js.map → MetricsTab-COn4GoUK.js.map} +1 -1
  33. package/extensions/dashboard-client/dist/assets/{OverviewTab-DIC_cUjS.js → OverviewTab-Cd9qAEB3.js} +2 -2
  34. package/extensions/dashboard-client/dist/assets/{OverviewTab-DIC_cUjS.js.map → OverviewTab-Cd9qAEB3.js.map} +1 -1
  35. package/extensions/dashboard-client/dist/assets/{ReposTab-KhTQqt5Z.js → ReposTab-DpiP1-Vv.js} +2 -2
  36. package/extensions/dashboard-client/dist/assets/{ReposTab-KhTQqt5Z.js.map → ReposTab-DpiP1-Vv.js.map} +1 -1
  37. package/extensions/dashboard-client/dist/assets/{SessionsTab-CeOUPRIM.js → SessionsTab-BwRUeGZM.js} +2 -2
  38. package/extensions/dashboard-client/dist/assets/{SessionsTab-CeOUPRIM.js.map → SessionsTab-BwRUeGZM.js.map} +1 -1
  39. package/extensions/dashboard-client/dist/assets/SetupTab-CJFDD2_v.js +3 -0
  40. package/extensions/dashboard-client/dist/assets/SetupTab-CJFDD2_v.js.map +1 -0
  41. package/extensions/dashboard-client/dist/assets/{TimeSavedCard-CXmxE5_8.js → TimeSavedCard-_XsdjQ7Z.js} +2 -2
  42. package/extensions/dashboard-client/dist/assets/{TimeSavedCard-CXmxE5_8.js.map → TimeSavedCard-_XsdjQ7Z.js.map} +1 -1
  43. package/extensions/dashboard-client/dist/assets/{TurnsTab-Dbx9pZPX.js → TurnsTab-CWPscPLL.js} +2 -2
  44. package/extensions/dashboard-client/dist/assets/{TurnsTab-Dbx9pZPX.js.map → TurnsTab-CWPscPLL.js.map} +1 -1
  45. package/extensions/dashboard-client/dist/assets/VcStatusBadge-Cx56rAIM.js +2 -0
  46. package/extensions/dashboard-client/dist/assets/VcStatusBadge-Cx56rAIM.js.map +1 -0
  47. package/extensions/dashboard-client/dist/assets/VectorCortexTab-B5ElUM7S.js +2 -0
  48. package/extensions/dashboard-client/dist/assets/VectorCortexTab-B5ElUM7S.js.map +1 -0
  49. package/extensions/dashboard-client/dist/assets/{WikiTab-B1mKp1SA.js → WikiTab-uZ5Mq3XG.js} +2 -2
  50. package/extensions/dashboard-client/dist/assets/{WikiTab-B1mKp1SA.js.map → WikiTab-uZ5Mq3XG.js.map} +1 -1
  51. package/extensions/dashboard-client/dist/assets/{button-BFHPDVb1.js → button-Kc18bYFz.js} +2 -2
  52. package/extensions/dashboard-client/dist/assets/{button-BFHPDVb1.js.map → button-Kc18bYFz.js.map} +1 -1
  53. package/extensions/dashboard-client/dist/assets/{card-XrbSJiOF.js → card-COJZoG08.js} +2 -2
  54. package/extensions/dashboard-client/dist/assets/{card-XrbSJiOF.js.map → card-COJZoG08.js.map} +1 -1
  55. package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-B9Ba91Tu.js → generateCategoricalChart-ChEYo017.js} +2 -2
  56. package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-B9Ba91Tu.js.map → generateCategoricalChart-ChEYo017.js.map} +1 -1
  57. package/extensions/dashboard-client/dist/assets/{index-P13AO5ni.js → index-CB7Rn5FP.js} +14 -14
  58. package/extensions/dashboard-client/dist/assets/index-CB7Rn5FP.js.map +1 -0
  59. package/extensions/dashboard-client/dist/assets/index-DbuGwYD7.css +1 -0
  60. package/extensions/dashboard-client/dist/assets/{switch-jnYDePmb.js → switch-BFhl_tNh.js} +2 -2
  61. package/extensions/dashboard-client/dist/assets/{switch-jnYDePmb.js.map → switch-BFhl_tNh.js.map} +1 -1
  62. package/extensions/dashboard-client/dist/assets/{toggle-JO-vvubb.js → toggle-DJ68kATc.js} +2 -2
  63. package/extensions/dashboard-client/dist/assets/{toggle-JO-vvubb.js.map → toggle-DJ68kATc.js.map} +1 -1
  64. package/extensions/dashboard-client/dist/assets/{useSSE-DAkXqUOy.js → useSSE-CXWh42xX.js} +2 -2
  65. package/extensions/dashboard-client/dist/assets/{useSSE-DAkXqUOy.js.map → useSSE-CXWh42xX.js.map} +1 -1
  66. package/extensions/dashboard-client/dist/index.html +2 -2
  67. package/extensions/dashboard-client/src/api/setup-cortex.ts +62 -0
  68. package/extensions/dashboard-client/src/tabs/SetupTab/CortexActionsCard.tsx +221 -0
  69. package/extensions/dashboard-client/src/tabs/SetupTab/CortexBlockersCard.tsx +74 -0
  70. package/extensions/dashboard-client/src/tabs/SetupTab/CortexEncoderCard.tsx +113 -0
  71. package/extensions/dashboard-client/src/tabs/SetupTab/CortexSetup.tsx +53 -0
  72. package/extensions/dashboard-client/src/tabs/SetupTab/CortexSetupStyles.ts +98 -0
  73. package/extensions/dashboard-client/src/tabs/SetupTab.tsx +22 -6
  74. package/extensions/dashboard-client/src/tabs/useSetupCortexPoll.ts +64 -0
  75. package/extensions/dashboard-client/src/types/setup-cortex.ts +118 -0
  76. package/extensions/dashboard-server/api-contracts/endpoints/registry-ext.ts +34 -1
  77. package/extensions/dashboard-server/api-contracts/setup-cortex.ts +63 -5
  78. package/extensions/dashboard-server/route-dispatch.ts +4 -0
  79. package/extensions/dashboard-server/routes-rag-settings-vector-cortex.ts +12 -0
  80. package/extensions/dashboard-server/routes-setup-cortex-actions.ts +133 -0
  81. package/extensions/dashboard-server/routes.ts +4 -0
  82. package/extensions/dashboard-server/setup-cortex-actions.ts +242 -0
  83. package/extensions/dashboard-server/setup-cortex-blockers.ts +25 -0
  84. package/package.json +1 -1
  85. package/src/config/vector-cortex-vc9b.ts +31 -0
  86. package/src/config/vector-cortex-vc9c.ts +36 -0
  87. package/src/config/vector-cortex.ts +3 -3
  88. package/src/config.ts +2 -0
  89. package/extensions/dashboard-client/dist/assets/SetupTab-DnN0mX0J.js +0 -2
  90. package/extensions/dashboard-client/dist/assets/SetupTab-DnN0mX0J.js.map +0 -1
  91. package/extensions/dashboard-client/dist/assets/VectorCortexTab-MzqdB6zI.js +0 -2
  92. package/extensions/dashboard-client/dist/assets/VectorCortexTab-MzqdB6zI.js.map +0 -1
  93. package/extensions/dashboard-client/dist/assets/index-Difwoltx.css +0 -1
  94. package/extensions/dashboard-client/dist/assets/index-P13AO5ni.js.map +0 -1
@@ -0,0 +1,29 @@
1
+ /**
2
+ * config/vector-cortex-vc9b.ts — VC9B setup-cortex action-drivers sprint flag.
3
+ *
4
+ * Extracted from vector-cortex.ts so that file stays under the 300-line soft
5
+ * limit (soft-as-hard gate), exactly as vector-cortex-vc9a.ts was. This is the
6
+ * SETUP-DASHBOARD action flag (the dashboard Setup tab fetch/bench/verify action
7
+ * drivers). vector-cortex.ts re-exports it below and root src/config.ts
8
+ * re-exports it, so no consumer import path changes.
9
+ *
10
+ * The split is purely mechanical: VC9B_ENABLED is byte-identical in name,
11
+ * semantics, and default to the definition it replaces, and vector-cortex.ts
12
+ * re-exports it so every existing `from "./config/vector-cortex.js"` import
13
+ * keeps resolving unchanged.
14
+ *
15
+ * Pi-agnostic, dependency-free (PREVENT-PI-004 / PREVENT-011).
16
+ */
17
+ import { sprintFlag } from "./vector-cortex-flag.js";
18
+ /**
19
+ * VC9B — Setup Cortex action drivers (POST /api/setup-cortex-action +
20
+ * GET /api/setup-cortex-action-log). Default ON. `MEGACOMPACT_VC9B=0` disables
21
+ * and is byte-identical to the predecessor (VC9A-era): the action POST returns
22
+ * the disabled shape (404/disabled) and flag-off bytes are unchanged. The
23
+ * actions only spawn the existing committed local scripts
24
+ * (scripts/vc2-model-prep/fetch-model.sh / bench-onnx.mjs) or re-read the
25
+ * committed encoder assets — never payload bytes, no network (PREVENT-PI-004).
26
+ * This flag MUST also be a dashboard SETTINGS toggle (visible in config UI,
27
+ * never in EXCLUDED_SETTINGS), mirroring VC9A.
28
+ */
29
+ export const VC9B_ENABLED = () => sprintFlag("MEGACOMPACT_VC9B");
@@ -0,0 +1,34 @@
1
+ /**
2
+ * config/vector-cortex-vc9c.ts — VC9C SetupTab Cortex sub-tab sprint flag.
3
+ *
4
+ * Extracted from vector-cortex.ts so that file stays under the 300-line soft
5
+ * limit (soft-as-hard gate), exactly as vector-cortex-vc9a.ts and
6
+ * vector-cortex-vc9b.ts were. This is the SETUP-DASHBOARD UI flag (the Cortex
7
+ * sub-tab inside SetupTab). vector-cortex.ts re-exports it below and root
8
+ * src/config.ts re-exports it, so no consumer import path changes.
9
+ *
10
+ * The split is purely mechanical: VC9C_ENABLED is byte-identical in name,
11
+ * semantics, and default to the definition it replaces, and vector-cortex.ts
12
+ * re-exports it so every existing `from "./config/vector-cortex.js"` import
13
+ * keeps resolving unchanged.
14
+ *
15
+ * The client gates the Cortex sub-tab's visible state on the flag via the
16
+ * VC0E honest-status pattern: when the VC9A status payload reports the
17
+ * off/disabled shape (or VC9C is off), the sub-tab is filtered from
18
+ * SUB_TABS. Flag-off is byte-identical to the predecessor (VC9B-era).
19
+ *
20
+ * Pi-agnostic, dependency-free (PREVENT-PI-004 / PREVENT-011).
21
+ */
22
+ import { sprintFlag } from "./vector-cortex-flag.js";
23
+ /**
24
+ * VC9C — SetupTab Cortex sub-tab (client UI). Default ON. `MEGACOMPACT_VC9C=0`
25
+ * disables and is byte-identical to the predecessor (VC9B-era): the Cortex
26
+ * sub-tab is filtered from SUB_TABS and the Setup tab renders exactly as it
27
+ * did before this sprint. The sub-tab is a pure consumer of the VC9A status
28
+ * endpoint (GET /api/setup-cortex-status) + VC9B action endpoints (POST
29
+ * /api/setup-cortex-action, GET /api/setup-cortex-action-log); it adds NO
30
+ * server logic and never surfaces payload bytes/prompts/ledger. This flag MUST
31
+ * also be a dashboard SETTINGS toggle (visible in config UI, never in
32
+ * EXCLUDED_SETTINGS), mirroring VC9A/VC9B.
33
+ */
34
+ export const VC9C_ENABLED = () => sprintFlag("MEGACOMPACT_VC9C");
@@ -244,10 +244,10 @@ export const VC8B_ENABLED = () => sprintFlag("MEGACOMPACT_VC8B");
244
244
  // Re-exported here so every existing `from "./config/vector-cortex.js"`
245
245
  // import keeps resolving unchanged.
246
246
  export { VC8C_ENABLED } from "./vector-cortex-vc8c.js";
247
- // VC9A (setup-cortex status read path) extracted to vector-cortex-vc9a.ts to
248
- // keep this file under the 300-line soft limit. Re-exported here so every
249
- // existing `from "./config/vector-cortex.js"` import keeps resolving unchanged.
247
+ // VC9A/VC9B/VC9C split to vector-cortex-vc9{a,b,c}.ts to stay under the 300-line soft limit.
250
248
  export { VC9A_ENABLED } from "./vector-cortex-vc9a.js";
249
+ export { VC9B_ENABLED } from "./vector-cortex-vc9b.js";
250
+ export { VC9C_ENABLED } from "./vector-cortex-vc9c.js";
251
251
  // Breaker state machine constants (TRIAD_RESILIENCE.md §breaker) extracted to
252
252
  // vector-cortex-breakers.ts to keep this file under the 300-line soft limit.
253
253
  export { BREAKER_WINDOW_MS, BREAKER_MIN_ATTEMPTS, BREAKER_PERF_FAILURES, BREAKER_PERF_FAILURE_RATE, BREAKER_CORRECTNESS_FAILURES, BREAKER_COOLDOWN_MS, BREAKER_PROBE_COUNT, BREAKER_RETRY_BASE_MS, BREAKER_RETRY_CAP_MS, BREAKER_RETRY_JITTER, BREAKER_HYSTERESIS_FAILURE_RATE, BREAKER_HYSTERESIS_BUDGET_P95_MS, BREAKER_MIN_HEALTHY_RESIDENCE_MS, } from "./vector-cortex-breakers.js";
package/dist/config.js CHANGED
@@ -114,4 +114,4 @@ export const NEW_UI = () => ragEnabled("MEGACOMPACT_NEW_UI");
114
114
  // default ON, `=0`/`_DISABLED` off. Re-exported from src/config/vector-cortex.ts
115
115
  // so root consumers share one source of truth.
116
116
  // ---------------------------------------------------------------------------
117
- export { VC0A_ENABLED, VC0B_ENABLED, VC1A_ENABLED, VC0C_ENABLED, VC1B_ENABLED, VC1C_ENABLED, VC2A_ENABLED, VC2B_ENABLED, VC2C_ENABLED, VC3A_ENABLED, VC3B_ENABLED, VC3C_ENABLED, VC4A_ENABLED, VC4B_ENABLED, VC4C_ENABLED, VC5A_ENABLED, VC5B_ENABLED, VC5C_ENABLED, VC6A_ENABLED, VC6B_ENABLED, VC6C_ENABLED, VC7A_ENABLED, VC7B_ENABLED, VC7C_ENABLED, VC8A_ENABLED, VC8B_ENABLED, VC8C_ENABLED, VC9A_ENABLED, BREAKER_WINDOW_MS, BREAKER_MIN_ATTEMPTS, BREAKER_PERF_FAILURES, BREAKER_PERF_FAILURE_RATE, BREAKER_CORRECTNESS_FAILURES, BREAKER_COOLDOWN_MS, BREAKER_PROBE_COUNT, BREAKER_RETRY_BASE_MS, BREAKER_RETRY_CAP_MS, BREAKER_RETRY_JITTER, BREAKER_HYSTERESIS_FAILURE_RATE, BREAKER_HYSTERESIS_BUDGET_P95_MS, BREAKER_MIN_HEALTHY_RESIDENCE_MS, } from "./config/vector-cortex.js";
117
+ export { VC0A_ENABLED, VC0B_ENABLED, VC1A_ENABLED, VC0C_ENABLED, VC1B_ENABLED, VC1C_ENABLED, VC2A_ENABLED, VC2B_ENABLED, VC2C_ENABLED, VC3A_ENABLED, VC3B_ENABLED, VC3C_ENABLED, VC4A_ENABLED, VC4B_ENABLED, VC4C_ENABLED, VC5A_ENABLED, VC5B_ENABLED, VC5C_ENABLED, VC6A_ENABLED, VC6B_ENABLED, VC6C_ENABLED, VC7A_ENABLED, VC7B_ENABLED, VC7C_ENABLED, VC8A_ENABLED, VC8B_ENABLED, VC8C_ENABLED, VC9A_ENABLED, VC9B_ENABLED, VC9C_ENABLED, BREAKER_WINDOW_MS, BREAKER_MIN_ATTEMPTS, BREAKER_PERF_FAILURES, BREAKER_PERF_FAILURE_RATE, BREAKER_CORRECTNESS_FAILURES, BREAKER_COOLDOWN_MS, BREAKER_PROBE_COUNT, BREAKER_RETRY_BASE_MS, BREAKER_RETRY_CAP_MS, BREAKER_RETRY_JITTER, BREAKER_HYSTERESIS_FAILURE_RATE, BREAKER_HYSTERESIS_BUDGET_P95_MS, BREAKER_MIN_HEALTHY_RESIDENCE_MS, } from "./config/vector-cortex.js";
@@ -34,4 +34,17 @@ export const EXTRA_ENDPOINTS = {
34
34
  path: "/api/setup-cortex-status",
35
35
  description: "Reader-only vector-cortex encoder gate: mode A/B/C, qualification verdict, blockers, encoder health — for the dashboard Setup tab. Never closes the ML gate.",
36
36
  },
37
+ // ─── VC9B Setup Cortex actions (dashboard Setup tab action drivers) ─────
38
+ /** POST /api/setup-cortex-action — confirmation-gated fetch/bench/verify. */
39
+ setupCortexAction: {
40
+ method: "POST",
41
+ path: "/api/setup-cortex-action",
42
+ description: "Confirmation-gated driver: fetch-model / bench / verify-asset. Executes only the committed local scripts (scripts/vc2-model-prep/*) or re-reads the committed encoder assets; an OPEN hard-gate item returns action_blocked_by_open_item and does NOT spawn. Never payload bytes; confirm:true required.",
43
+ },
44
+ /** GET /api/setup-cortex-action-log — bounded, redacted action log tail. */
45
+ setupCortexActionLog: {
46
+ method: "GET",
47
+ path: "/api/setup-cortex-action-log",
48
+ description: "Bounded (8 KiB) redacted tail of a VC9B action log under <stateDir>/logs/vc9b/; the name must be a validated basename (path traversal rejected).",
49
+ },
37
50
  };
@@ -1,10 +1,11 @@
1
1
  /**
2
- * api-contracts/setup-cortex.ts — Setup Cortex status API types (VC9A).
2
+ * api-contracts/setup-cortex.ts — Setup Cortex status + action API types (VC9A/VC9B).
3
3
  *
4
- * Types for GET /api/setup-cortex-status, the reader-only aggregate that
5
- * surfaces the vector-cortex encoder gate (mode A/B/C, qualification verdict,
6
- * blockers, encoder health) in the dashboard Setup tab WITHOUT closing the ML
7
- * gate. Reader-only: never payloads/prompts/ledger (EVAL-REDACT-002).
4
+ * Types for GET /api/setup-cortex-status (reader-only aggregate that surfaces
5
+ * the vector-cortex encoder gate WITHOUT closing the ML gate) and the VC9B
6
+ * action drivers POST /api/setup-cortex-action + GET /api/setup-cortex-action-log
7
+ * (confirmation-gated, hard-gate-aware fetches/bench/verify). Reader/actor-only:
8
+ * never payload bytes/prompts/ledger (EVAL-REDACT-002).
8
9
  *
9
10
  * PREVENT-PI-004: type definitions only, no network code.
10
11
  * PREVENT-011: no `any` type — all types are explicit.
@@ -8,7 +8,7 @@
8
8
  * PREVENT-PI-004: local filesystem read only, no network.
9
9
  * PREVENT-011: no `any` type.
10
10
  */
11
- import { handleIndex, handleRepoIndex, handleEvents, handleGameState, handleGameScores, handlePerfSamples, handlePerf, handleAchievements, handleSessions, handleTopics, handleTurns, handleMaintenance, handleProviderCache, handleMemoryStatus, handleCacheStripes, handleSetupStatus, handleSetupDetect, handleSetupConfigure, handleMemoryMap, handleRaptorTree, handleRaptorBuildHistory, handleContextHealth, handleCachePoison, handleHealthSettings, handleEmbedderHealth, handleRagSettings, handleRagMetrics, handleModelThresholds, handleWiki, handleVectorCortexEvaluation, handleVectorCortexHealth, handleVectorCortexBreakersReset, handleVectorCortexLedger, handleVectorCortexTopology, handleVectorCortexQuery, handleVectorCortexShards, handleVectorCortexResidual, handleVectorCortexReconstruct, handleVectorCortexPlans, handleVectorCortexRender, handleVectorCortexRollout, handleVectorCortexClosureProof, handleVectorCortexRestore, handleSetupCortexStatus, } from "./routes.js";
11
+ import { handleIndex, handleRepoIndex, handleEvents, handleGameState, handleGameScores, handlePerfSamples, handlePerf, handleAchievements, handleSessions, handleTopics, handleTurns, handleMaintenance, handleProviderCache, handleMemoryStatus, handleCacheStripes, handleSetupStatus, handleSetupDetect, handleSetupConfigure, handleMemoryMap, handleRaptorTree, handleRaptorBuildHistory, handleContextHealth, handleCachePoison, handleHealthSettings, handleEmbedderHealth, handleRagSettings, handleRagMetrics, handleModelThresholds, handleWiki, handleVectorCortexEvaluation, handleVectorCortexHealth, handleVectorCortexBreakersReset, handleVectorCortexLedger, handleVectorCortexTopology, handleVectorCortexQuery, handleVectorCortexShards, handleVectorCortexResidual, handleVectorCortexReconstruct, handleVectorCortexPlans, handleVectorCortexRender, handleVectorCortexRollout, handleVectorCortexClosureProof, handleVectorCortexRestore, handleSetupCortexStatus, handleSetupCortexAction, handleSetupCortexActionLog, } from "./routes.js";
12
12
  // VC6C repair lives in its own module (routes-vector-cortex-repair.ts) so the
13
13
  // heal route file stays well under the 400-line extension soft limit.
14
14
  import { handleVectorCortexRepair } from "./routes-vector-cortex-repair.js";
@@ -143,5 +143,9 @@ export function dispatchRoutes(req, res, ctx) {
143
143
  return true;
144
144
  if (handleSetupCortexStatus(req, res, ctx))
145
145
  return true;
146
+ if (handleSetupCortexAction(req, res, ctx))
147
+ return true;
148
+ if (handleSetupCortexActionLog(req, res, ctx))
149
+ return true;
146
150
  return false;
147
151
  }
@@ -49,5 +49,7 @@ export const VECTOR_CORTEX_SETTINGS = {
49
49
  boolDirect("MEGACOMPACT_VC8B", "VC8B Shadow Adaptive Policy", "Bounded shadow adaptive policy + M7 pressure-v2 migration. Policy actions are from a finite set (admit/dampen/defer/escalate/reject) chosen deterministically by the canonical pressure level; token budgets are clamped into a configured window after the pressure factor. Unknown pressure labels are rejected as POL_PRESSURE_UNKNOWN, never coerced to a neighbour. The shadow engine is structurally incapable of affecting the live path: inputs are deep-copied, the canonical prompt digest is pinned before and after to prove non-mutation, and liveMutations is always zero. M7 migrates legacy pressure labels to the v2 canonical five by copy/validate/switch; an unknown label blocks the switch and keeps the legacy pointer (M7_PRESSURE_UNKNOWN). A shadow decision is mode A, static calibrated policy is mode B (forced by invalid A), and fixed legacy thresholds is mode C (forced by M7 or B failure). OFF = byte-identical predecessor (VC8A); the policy/shadow/migration arithmetic still runs, only the reporter + dashboard seam is suppressed.", true),
50
50
  boolDirect("MEGACOMPACT_VC8C", "VC8C Canary Platform + Rust Parity", "Canary selection and external Rust parity. The selector admits a qualified external Rust artifact only when ABI version, URL metadata, commit, Cargo.lock digest, and platform all match evidence; a Cargo.lock digest mismatch rejects the artifact (RUST_CARGO_DIGEST_MISMATCH). The cross-conformance runner exchanges length-framed neutral records over a local stdin/stdout channel — a subprocess, never a URL (PREVENT-PI-004). A parity mismatch selects TS mode B. A qualified external artifact is mode A, TS reference is mode B, legacy path is mode C. OFF = byte-identical predecessor (VC8B); the selector and cross-conformance arithmetic still run, only the reporter + dashboard seam is suppressed.", true),
51
51
  boolDirect("MEGACOMPACT_VC9A", "VC9A Setup Cortex Status", "Reader-only Setup Cortex status read path (GET /api/setup-cortex-status): surfaces the vector-cortex encoder gate — mode A/B/C, qualification verdict, open blockers, encoder health — to the dashboard Setup tab without closing the ML gate. OFF = byte-identical predecessor (VC8C-era): returns enabled:false / mode:C / status:off.", true),
52
+ boolDirect("MEGACOMPACT_VC9B", "VC9B Setup Cortex Actions", "Setup Cortex action drivers (POST /api/setup-cortex-action + GET /api/setup-cortex-action-log): confirmation-gated wrappers that fetch-model / bench / verify-asset by spawning only the committed local scripts (scripts/vc2-model-prep/fetch-model.sh, bench-onnx.mjs) or re-reading the committed encoder assets — never payload bytes, no network. Actions gated by an OPEN hard-gate item (HG-1/HG-3) return action_blocked_by_open_item and do NOT spawn. OFF = byte-identical predecessor (VC9A-era): the action POST returns a disabled/404 shape and flag-off bytes are unchanged.", true),
53
+ boolDirect("MEGACOMPACT_VC9C", "VC9C SetupTab Cortex Sub-tab", "SetupTab Cortex sub-tab (client UI): a Cortex sub-tab inside SetupTab that consumes the VC9A status endpoint (GET /api/setup-cortex-status) + the VC9B action endpoints. It surfaces the encoder mode A/B/C, asset digest prefix, qualification verdict + threshold failures, the open hard-gate blockers, and the confirmation-gated fetch/bench/verify actions. OFF = byte-identical predecessor (VC9B-era): the Cortex sub-tab is filtered from SUB_TABS and the Setup tab renders exactly as before.", true),
52
54
  ],
53
55
  };
@@ -0,0 +1,116 @@
1
+ /**
2
+ * dashboard-server/routes-setup-cortex-actions.ts — VC9B Setup Cortex action routes.
3
+ *
4
+ * POST /api/setup-cortex-action — confirmation-gated driver
5
+ * GET /api/setup-cortex-action-log — bounded, redacted log tail
6
+ *
7
+ * Reader/actor-only: NEVER exposes payload bytes, prompts, or ledger. Actions
8
+ * only spawn the committed local vc2-model-prep scripts or re-read the committed
9
+ * encoder assets (verify-asset) — no network (PREVENT-PI-004). A hard gate
10
+ * (HG-1/HG-3) blocking the requested action yields 423 action_blocked_by_open_item
11
+ * with the blocker ids and NO subprocess is spawned. Missing confirm:true yields
12
+ * 400 confirmation_required. Flag-off (MEGACOMPACT_VC9B=0) is byte-identical to
13
+ * the VC9A-era predecessor: the routes are absent, so they return the 404
14
+ * disabled shape and no action runs.
15
+ *
16
+ * Guardrails: PREVENT-011 (no `any`), PREVENT-001 (guarded JSON.parse via
17
+ * readJsonBody), no string literals for scripts/blockers (delegated to
18
+ * setup-cortex-actions.ts + setup-cortex-blockers.ts).
19
+ */
20
+ import { sendJson, readJsonBody } from "./routes-vector-cortex-shared.js";
21
+ import { VC9B_ENABLED } from "../../src/config.js";
22
+ import { setupCortexActionBlockers } from "./setup-cortex-blockers.js";
23
+ import { runSetupCortexAction, readActionLogTail, } from "./setup-cortex-actions.js";
24
+ const ACTION_KINDS = new Set([
25
+ "fetch-model",
26
+ "bench",
27
+ "verify-asset",
28
+ ]);
29
+ function isActionKind(v) {
30
+ return typeof v === "string" && ACTION_KINDS.has(v);
31
+ }
32
+ /** Flag-off response, byte-identical regardless of request (VC9B absent). */
33
+ function sendDisabled(res) {
34
+ sendJson(res, 404, { error: "disabled" });
35
+ }
36
+ /**
37
+ * POST /api/setup-cortex-action (VC9B). Returns true when it claims the request.
38
+ */
39
+ export function handleSetupCortexAction(req, res, ctx) {
40
+ const url = req.url ?? "";
41
+ if (url !== "/api/setup-cortex-action")
42
+ return false;
43
+ if (req.method !== "POST") {
44
+ sendJson(res, 405, { error: "method_not_allowed" });
45
+ return true;
46
+ }
47
+ if (!VC9B_ENABLED()) {
48
+ sendDisabled(res);
49
+ return true;
50
+ }
51
+ readJsonBody(req, (parsed) => {
52
+ if (!parsed.ok) {
53
+ sendJson(res, 400, { error: "invalid_body" });
54
+ return;
55
+ }
56
+ const value = parsed.value;
57
+ const action = value.action;
58
+ if (!isActionKind(action)) {
59
+ sendJson(res, 400, { error: "invalid_action" });
60
+ return;
61
+ }
62
+ if (value.confirm !== true) {
63
+ sendJson(res, 400, { error: "confirmation_required" });
64
+ return;
65
+ }
66
+ // Hard-gate check: when an OPEN hard-gate item gates this action, do NOT
67
+ // spawn — surface the blocker ids so the client highlights the matching rows.
68
+ const blockers = setupCortexActionBlockers(action);
69
+ if (blockers.length > 0) {
70
+ sendJson(res, 423, {
71
+ error: "action_blocked_by_open_item",
72
+ blockers: [...blockers],
73
+ });
74
+ return;
75
+ }
76
+ const result = runSetupCortexAction(action, ctx.stateDir);
77
+ sendJson(res, result.ok ? 200 : 500, result);
78
+ });
79
+ return true;
80
+ }
81
+ /**
82
+ * GET /api/setup-cortex-action-log?name=<basename> (VC9B). Returns true when it
83
+ * claims the request. Bounded tail (8 KiB max) + redacted (digest prefixes +
84
+ * codes); the name must validate to a basename inside the vc9b log dir.
85
+ */
86
+ export function handleSetupCortexActionLog(req, res, ctx) {
87
+ const url = req.url ?? "";
88
+ if (url.split("?")[0] !== "/api/setup-cortex-action-log")
89
+ return false;
90
+ if (req.method !== "GET") {
91
+ sendJson(res, 405, { error: "method_not_allowed" });
92
+ return true;
93
+ }
94
+ if (!VC9B_ENABLED()) {
95
+ sendDisabled(res);
96
+ return true;
97
+ }
98
+ let name = null;
99
+ try {
100
+ name = new URL(url, "http://localhost").searchParams.get("name");
101
+ }
102
+ catch {
103
+ name = null;
104
+ }
105
+ if (!name) {
106
+ sendJson(res, 400, { error: "invalid_log_name" });
107
+ return true;
108
+ }
109
+ const tail = readActionLogTail(ctx.stateDir, name);
110
+ if (tail === null) {
111
+ sendJson(res, 404, { error: "log_not_found" });
112
+ return true;
113
+ }
114
+ sendJson(res, 200, tail);
115
+ return true;
116
+ }
@@ -25,3 +25,4 @@ export { handleModelThresholds } from "./routes-model-thresholds.js";
25
25
  export { handleWiki } from "./routes-wiki.js";
26
26
  export { handleVectorCortexEvaluation, handleVectorCortexHealth, handleVectorCortexBreakersReset, handleVectorCortexLedger, handleVectorCortexTopology, handleVectorCortexQuery, handleVectorCortexShards, handleVectorCortexResidual, handleVectorCortexReconstruct, handleVectorCortexPlans, handleVectorCortexRender, handleVectorCortexRollout, handleVectorCortexClosureProof, handleVectorCortexRestore, } from "./routes-vector-cortex.js";
27
27
  export { handleSetupCortexStatus } from "./routes-setup-cortex.js";
28
+ export { handleSetupCortexAction, handleSetupCortexActionLog, } from "./routes-setup-cortex-actions.js";
@@ -0,0 +1,213 @@
1
+ /**
2
+ * dashboard-server/setup-cortex-actions.ts — VC9B action driver (actor surface).
3
+ *
4
+ * Implements the actual mechanics behind POST /api/setup-cortex-action and
5
+ * GET /api/setup-cortex-action-log: locating + spawning ONLY the committed local
6
+ * vc2-model-prep scripts (fetch-model.sh, bench-onnx.mjs), capturing their
7
+ * output to <stateDir>/logs/vc9b/<action>-<ts>.log, re-running the committed
8
+ * encoder asset verification seam for verify-asset (NO subprocess), and serving
9
+ * a bounded + redacted log tail.
10
+ *
11
+ * This module is the ONLY place that touches the filesystem for VC9B actions.
12
+ * The route file (routes-setup-cortex-actions.ts) carries NO path/script/blocker
13
+ * string literals — it delegates here. Guardrails: the spawned scripts are the
14
+ * existing committed local developer-tooling scripts (never fetched, no network,
15
+ * PREVENT-PI-004); the log tail is bounded at 8 KiB and redacted (digest
16
+ * prefixes + codes only, never payload bytes — EVAL-REDACT-002); PREVENT-011
17
+ * (no `any`).
18
+ */
19
+ import { spawnSync } from "node:child_process"; // guardrails-allow PREVENT-PI-004: local subprocess spawn of committed repo script (loopback)
20
+ import { mkdirSync, readFileSync, writeFileSync, existsSync, readdirSync, } from "node:fs";
21
+ import { join, dirname, basename } from "node:path";
22
+ import { fileURLToPath } from "node:url";
23
+ import { readEncoderManifest, verifyEncoderAsset, detectPlatform, } from "../../src/vector-cortex/encoder/asset.js";
24
+ /** Cap applied to every log tail served by the action-log route. */
25
+ export const ACTION_LOG_TAIL_BYTES = 8192;
26
+ /** Locate the commit's vc2-model-prep directory by walking up to the repo root. */
27
+ function vc2ScriptDir() {
28
+ let dir = dirname(fileURLToPath(import.meta.url));
29
+ const rel = join("scripts", "vc2-model-prep");
30
+ for (let i = 0; i < 8; i++) {
31
+ const candidate = join(dir, rel);
32
+ if (existsSync(join(candidate, "fetch-model.sh")))
33
+ return candidate;
34
+ const next = dirname(dir);
35
+ if (next === dir)
36
+ break;
37
+ dir = next;
38
+ }
39
+ return null;
40
+ }
41
+ /** Absolute dir holding this repo's <stateDir>/logs/vc9b/ action logs. */
42
+ export function vc9bLogDir(stateDir) {
43
+ return join(stateDir, "logs", "vc9b");
44
+ }
45
+ /** Ensure the vc9b log dir exists and return its absolute path. */
46
+ function ensureLogDir(stateDir) {
47
+ const dir = vc9bLogDir(stateDir);
48
+ // guardrails-allow PREVENT-PI-004: local state-dir filesystem write (loopback)
49
+ mkdirSync(dir, { recursive: true });
50
+ return dir;
51
+ }
52
+ /** Safe log basename: non-empty, no separators, not a dot/double-dot segment. */
53
+ export function isSafeLogName(name) {
54
+ if (!name || name.length === 0)
55
+ return false;
56
+ if (name.includes("/") || name.includes("\\"))
57
+ return false;
58
+ if (name === "." || name === "..")
59
+ return false;
60
+ // Must match our own file naming: <action>-<ts>.log where ts is digits.
61
+ return /^[a-z-]+-\d+\.log$/.test(name);
62
+ }
63
+ /**
64
+ * Redact a fragment of action-log output: bound long digests to their prefix and
65
+ * collapse long base64-looking tokens, so the served tail carries digest prefixes
66
+ * + codes only — never arbitrary payload bytes. Returns the redacted text.
67
+ */
68
+ export function redactLog(text) {
69
+ let out = text;
70
+ // SHA-256 (64 hex) or any long hex digest -> keep the first 12 chars.
71
+ out = out.replace(/\b[0-9a-fA-F]{32,}\b/g, (m) => `sha256:${m.slice(0, 12)}`);
72
+ // Long base64-ish tokens (26+ chars from the base64 alphabet) -> collapse.
73
+ out = out.replace(/[A-Za-z0-9+/=]{26,}/g, (m) => `<redacted:${m.length}>`);
74
+ return out;
75
+ }
76
+ /** Read + bound + redact the tail of one vc9b log file. */
77
+ export function readActionLogTail(stateDir, name) {
78
+ if (!isSafeLogName(name))
79
+ return null;
80
+ const dir = vc9bLogDir(stateDir);
81
+ const full = join(dir, name);
82
+ if (basename(full) !== name)
83
+ return null; // belt-and-suspenders: no traversal
84
+ if (!existsSync(full))
85
+ return null;
86
+ let raw;
87
+ try {
88
+ // guardrails-allow PREVENT-PI-004: local state-dir filesystem read (loopback)
89
+ raw = readFileSync(full, "utf8");
90
+ }
91
+ catch {
92
+ return null;
93
+ }
94
+ const bounded = raw.length > ACTION_LOG_TAIL_BYTES
95
+ ? raw.slice(-ACTION_LOG_TAIL_BYTES)
96
+ : raw;
97
+ return {
98
+ name,
99
+ tail: redactLog(bounded),
100
+ complete: raw.length <= ACTION_LOG_TAIL_BYTES,
101
+ };
102
+ }
103
+ /** Run a vc2-model-prep subprocess and capture its output to a vc9b log file. */
104
+ function runSpawnedAction(action, stateDir) {
105
+ const dir = vc2ScriptDir();
106
+ const { name, logPath } = writeLogName(action, stateDir);
107
+ if (dir === null) {
108
+ writeLog(logPath, "vc2-model-prep scripts not found in this checkout\n");
109
+ return { action, ok: false, exitCode: null, logPath, logName: name, spawned: true };
110
+ }
111
+ let result;
112
+ if (action === "fetch-model") {
113
+ // guardrails-allow PREVENT-PI-004: local subprocess spawn of committed repo script (loopback)
114
+ result = spawnSync("bash", [join(dir, "fetch-model.sh"), join(stateDir, "vc2-model-prep")], {
115
+ encoding: "utf8",
116
+ timeout: 60_000,
117
+ });
118
+ }
119
+ else {
120
+ // guardrails-allow PREVENT-PI-004: local subprocess spawn of committed repo script (loopback)
121
+ result = spawnSync(process.execPath, [join(dir, "bench-onnx.mjs")], {
122
+ encoding: "utf8",
123
+ timeout: 60_000,
124
+ });
125
+ }
126
+ const out = `${result.stdout ?? ""}${result.stderr ?? ""}`;
127
+ writeLog(logPath, out || "(no output)\n");
128
+ return {
129
+ action,
130
+ ok: result.status === 0,
131
+ exitCode: result.status === null ? null : result.status,
132
+ logPath,
133
+ logName: name,
134
+ spawned: true,
135
+ };
136
+ }
137
+ /**
138
+ * Re-run the committed encoder asset verification seam (readEncoderManifest +
139
+ * verifyEncoderAsset + detectPlatform) WITHOUT any subprocess, and log a
140
+ * redacted summary (mode + digest prefix + verdict/code only). Uses the same
141
+ * repo-root walk the VC9A status route uses to find assets/vector-cortex.
142
+ */
143
+ function runVerifyAsset(stateDir) {
144
+ const { name, logPath } = writeLogName("verify-asset", stateDir);
145
+ const body = buildVerifySummary();
146
+ writeLog(logPath, body);
147
+ return {
148
+ action: "verify-asset",
149
+ ok: body.includes("verdict=qualified"),
150
+ exitCode: null,
151
+ logPath,
152
+ logName: name,
153
+ spawned: false,
154
+ };
155
+ }
156
+ /** Compute the redacted verify-asset summary lines (digests + codes only). */
157
+ function buildVerifySummary() {
158
+ const dir = encoderAssetDir();
159
+ if (dir === null) {
160
+ return "mode=C verdict=unavailable reason=asset_missing\n";
161
+ }
162
+ const manifest = readEncoderManifest(dir);
163
+ if (manifest === null) {
164
+ return "mode=B verdict=demoted reason=ENC_MANIFEST_INVALID\n";
165
+ }
166
+ const platform = detectPlatform();
167
+ const verify = verifyEncoderAsset(dir, manifest, platform);
168
+ if (verify.ok) {
169
+ const prefix = verify.onnxDigest.slice(0, 12);
170
+ return `mode=A verdict=qualified onnx_digest_prefix=${prefix} embedded_bytes=${verify.embeddedBytes}\n`;
171
+ }
172
+ return `mode=B verdict=demoted reason=${verify.code}\n`;
173
+ }
174
+ /** Walk up to the committed encoder-v1 asset dir (mirrors routes-setup-cortex.ts). */
175
+ function encoderAssetDir() {
176
+ let dir = dirname(fileURLToPath(import.meta.url));
177
+ const rel = join("assets", "vector-cortex", "encoder-v1");
178
+ for (let i = 0; i < 8; i++) {
179
+ const candidate = join(dir, rel);
180
+ // guardrails-allow PREVENT-PI-004: local asset filesystem read (loopback)
181
+ if (existsSync(join(candidate, "manifest.json")))
182
+ return candidate;
183
+ const next = dirname(dir);
184
+ if (next === dir)
185
+ break;
186
+ dir = next;
187
+ }
188
+ return null;
189
+ }
190
+ /** Unique <action>-<ts>.log name + absolute path under the vc9b log dir. */
191
+ function writeLogName(action, stateDir) {
192
+ let ts = Date.now();
193
+ const existing = new Set(readdirSync(ensureLogDir(stateDir)));
194
+ while (existing.has(`${action}-${ts}.log`))
195
+ ts++;
196
+ const name = `${action}-${ts}.log`;
197
+ return { name, logPath: join(vc9bLogDir(stateDir), name) };
198
+ }
199
+ function writeLog(logPath, body) {
200
+ // guardrails-allow PREVENT-PI-004: local state-dir filesystem write (loopback)
201
+ writeFileSync(logPath, body, "utf8");
202
+ }
203
+ /**
204
+ * Run one Setup Cortex action against the given stateDir. Returns the action
205
+ * result on success; throws nothing — every failure is surfaced as a result with
206
+ * ok=false so the route can shape the HTTP response. Never touches the network;
207
+ * the subprocesses it may spawn are the committed local vc2-model-prep scripts.
208
+ */
209
+ export function runSetupCortexAction(action, stateDir) {
210
+ if (action === "verify-asset")
211
+ return runVerifyAsset(stateDir);
212
+ return runSpawnedAction(action, stateDir);
213
+ }
@@ -51,3 +51,20 @@ export const SETUP_CORTEX_BLOCKERS = [
51
51
  export function setupCortexBlocker(id) {
52
52
  return SETUP_CORTEX_BLOCKERS.find((b) => b.id === id);
53
53
  }
54
+ /**
55
+ * The open hard-gate ids that BLOCK a given action. fetch-model and bench are
56
+ * gated by HG-1 (five-head training open) and HG-3 (install budget open) per the
57
+ * VC9 workstream plan; verify-asset is a pure re-read of committed assets and is
58
+ * NOT gated. When a gated action is requested, the route returns
59
+ * action_blocked_by_open_item with these ids and does NOT spawn. The ids are
60
+ * always drawn from SETUP_CORTEX_BLOCKERS (each exists — verified by test).
61
+ */
62
+ export function setupCortexActionBlockers(action) {
63
+ switch (action) {
64
+ case "fetch-model":
65
+ case "bench":
66
+ return ["HG-1", "HG-3"];
67
+ case "verify-asset":
68
+ return [];
69
+ }
70
+ }
@@ -0,0 +1,29 @@
1
+ /**
2
+ * config/vector-cortex-vc9b.ts — VC9B setup-cortex action-drivers sprint flag.
3
+ *
4
+ * Extracted from vector-cortex.ts so that file stays under the 300-line soft
5
+ * limit (soft-as-hard gate), exactly as vector-cortex-vc9a.ts was. This is the
6
+ * SETUP-DASHBOARD action flag (the dashboard Setup tab fetch/bench/verify action
7
+ * drivers). vector-cortex.ts re-exports it below and root src/config.ts
8
+ * re-exports it, so no consumer import path changes.
9
+ *
10
+ * The split is purely mechanical: VC9B_ENABLED is byte-identical in name,
11
+ * semantics, and default to the definition it replaces, and vector-cortex.ts
12
+ * re-exports it so every existing `from "./config/vector-cortex.js"` import
13
+ * keeps resolving unchanged.
14
+ *
15
+ * Pi-agnostic, dependency-free (PREVENT-PI-004 / PREVENT-011).
16
+ */
17
+ import { sprintFlag } from "./vector-cortex-flag.js";
18
+ /**
19
+ * VC9B — Setup Cortex action drivers (POST /api/setup-cortex-action +
20
+ * GET /api/setup-cortex-action-log). Default ON. `MEGACOMPACT_VC9B=0` disables
21
+ * and is byte-identical to the predecessor (VC9A-era): the action POST returns
22
+ * the disabled shape (404/disabled) and flag-off bytes are unchanged. The
23
+ * actions only spawn the existing committed local scripts
24
+ * (scripts/vc2-model-prep/fetch-model.sh / bench-onnx.mjs) or re-read the
25
+ * committed encoder assets — never payload bytes, no network (PREVENT-PI-004).
26
+ * This flag MUST also be a dashboard SETTINGS toggle (visible in config UI,
27
+ * never in EXCLUDED_SETTINGS), mirroring VC9A.
28
+ */
29
+ export const VC9B_ENABLED = () => sprintFlag("MEGACOMPACT_VC9B");
@@ -0,0 +1,34 @@
1
+ /**
2
+ * config/vector-cortex-vc9c.ts — VC9C SetupTab Cortex sub-tab sprint flag.
3
+ *
4
+ * Extracted from vector-cortex.ts so that file stays under the 300-line soft
5
+ * limit (soft-as-hard gate), exactly as vector-cortex-vc9a.ts and
6
+ * vector-cortex-vc9b.ts were. This is the SETUP-DASHBOARD UI flag (the Cortex
7
+ * sub-tab inside SetupTab). vector-cortex.ts re-exports it below and root
8
+ * src/config.ts re-exports it, so no consumer import path changes.
9
+ *
10
+ * The split is purely mechanical: VC9C_ENABLED is byte-identical in name,
11
+ * semantics, and default to the definition it replaces, and vector-cortex.ts
12
+ * re-exports it so every existing `from "./config/vector-cortex.js"` import
13
+ * keeps resolving unchanged.
14
+ *
15
+ * The client gates the Cortex sub-tab's visible state on the flag via the
16
+ * VC0E honest-status pattern: when the VC9A status payload reports the
17
+ * off/disabled shape (or VC9C is off), the sub-tab is filtered from
18
+ * SUB_TABS. Flag-off is byte-identical to the predecessor (VC9B-era).
19
+ *
20
+ * Pi-agnostic, dependency-free (PREVENT-PI-004 / PREVENT-011).
21
+ */
22
+ import { sprintFlag } from "./vector-cortex-flag.js";
23
+ /**
24
+ * VC9C — SetupTab Cortex sub-tab (client UI). Default ON. `MEGACOMPACT_VC9C=0`
25
+ * disables and is byte-identical to the predecessor (VC9B-era): the Cortex
26
+ * sub-tab is filtered from SUB_TABS and the Setup tab renders exactly as it
27
+ * did before this sprint. The sub-tab is a pure consumer of the VC9A status
28
+ * endpoint (GET /api/setup-cortex-status) + VC9B action endpoints (POST
29
+ * /api/setup-cortex-action, GET /api/setup-cortex-action-log); it adds NO
30
+ * server logic and never surfaces payload bytes/prompts/ledger. This flag MUST
31
+ * also be a dashboard SETTINGS toggle (visible in config UI, never in
32
+ * EXCLUDED_SETTINGS), mirroring VC9A/VC9B.
33
+ */
34
+ export const VC9C_ENABLED = () => sprintFlag("MEGACOMPACT_VC9C");
@@ -244,10 +244,10 @@ export const VC8B_ENABLED = () => sprintFlag("MEGACOMPACT_VC8B");
244
244
  // Re-exported here so every existing `from "./config/vector-cortex.js"`
245
245
  // import keeps resolving unchanged.
246
246
  export { VC8C_ENABLED } from "./vector-cortex-vc8c.js";
247
- // VC9A (setup-cortex status read path) extracted to vector-cortex-vc9a.ts to
248
- // keep this file under the 300-line soft limit. Re-exported here so every
249
- // existing `from "./config/vector-cortex.js"` import keeps resolving unchanged.
247
+ // VC9A/VC9B/VC9C split to vector-cortex-vc9{a,b,c}.ts to stay under the 300-line soft limit.
250
248
  export { VC9A_ENABLED } from "./vector-cortex-vc9a.js";
249
+ export { VC9B_ENABLED } from "./vector-cortex-vc9b.js";
250
+ export { VC9C_ENABLED } from "./vector-cortex-vc9c.js";
251
251
  // Breaker state machine constants (TRIAD_RESILIENCE.md §breaker) extracted to
252
252
  // vector-cortex-breakers.ts to keep this file under the 300-line soft limit.
253
253
  export { BREAKER_WINDOW_MS, BREAKER_MIN_ATTEMPTS, BREAKER_PERF_FAILURES, BREAKER_PERF_FAILURE_RATE, BREAKER_CORRECTNESS_FAILURES, BREAKER_COOLDOWN_MS, BREAKER_PROBE_COUNT, BREAKER_RETRY_BASE_MS, BREAKER_RETRY_CAP_MS, BREAKER_RETRY_JITTER, BREAKER_HYSTERESIS_FAILURE_RATE, BREAKER_HYSTERESIS_BUDGET_P95_MS, BREAKER_MIN_HEALTHY_RESIDENCE_MS, } from "./vector-cortex-breakers.js";
@@ -114,4 +114,4 @@ export const NEW_UI = () => ragEnabled("MEGACOMPACT_NEW_UI");
114
114
  // default ON, `=0`/`_DISABLED` off. Re-exported from src/config/vector-cortex.ts
115
115
  // so root consumers share one source of truth.
116
116
  // ---------------------------------------------------------------------------
117
- export { VC0A_ENABLED, VC0B_ENABLED, VC1A_ENABLED, VC0C_ENABLED, VC1B_ENABLED, VC1C_ENABLED, VC2A_ENABLED, VC2B_ENABLED, VC2C_ENABLED, VC3A_ENABLED, VC3B_ENABLED, VC3C_ENABLED, VC4A_ENABLED, VC4B_ENABLED, VC4C_ENABLED, VC5A_ENABLED, VC5B_ENABLED, VC5C_ENABLED, VC6A_ENABLED, VC6B_ENABLED, VC6C_ENABLED, VC7A_ENABLED, VC7B_ENABLED, VC7C_ENABLED, VC8A_ENABLED, VC8B_ENABLED, VC8C_ENABLED, VC9A_ENABLED, BREAKER_WINDOW_MS, BREAKER_MIN_ATTEMPTS, BREAKER_PERF_FAILURES, BREAKER_PERF_FAILURE_RATE, BREAKER_CORRECTNESS_FAILURES, BREAKER_COOLDOWN_MS, BREAKER_PROBE_COUNT, BREAKER_RETRY_BASE_MS, BREAKER_RETRY_CAP_MS, BREAKER_RETRY_JITTER, BREAKER_HYSTERESIS_FAILURE_RATE, BREAKER_HYSTERESIS_BUDGET_P95_MS, BREAKER_MIN_HEALTHY_RESIDENCE_MS, } from "./config/vector-cortex.js";
117
+ export { VC0A_ENABLED, VC0B_ENABLED, VC1A_ENABLED, VC0C_ENABLED, VC1B_ENABLED, VC1C_ENABLED, VC2A_ENABLED, VC2B_ENABLED, VC2C_ENABLED, VC3A_ENABLED, VC3B_ENABLED, VC3C_ENABLED, VC4A_ENABLED, VC4B_ENABLED, VC4C_ENABLED, VC5A_ENABLED, VC5B_ENABLED, VC5C_ENABLED, VC6A_ENABLED, VC6B_ENABLED, VC6C_ENABLED, VC7A_ENABLED, VC7B_ENABLED, VC7C_ENABLED, VC8A_ENABLED, VC8B_ENABLED, VC8C_ENABLED, VC9A_ENABLED, VC9B_ENABLED, VC9C_ENABLED, BREAKER_WINDOW_MS, BREAKER_MIN_ATTEMPTS, BREAKER_PERF_FAILURES, BREAKER_PERF_FAILURE_RATE, BREAKER_CORRECTNESS_FAILURES, BREAKER_COOLDOWN_MS, BREAKER_PROBE_COUNT, BREAKER_RETRY_BASE_MS, BREAKER_RETRY_CAP_MS, BREAKER_RETRY_JITTER, BREAKER_HYSTERESIS_FAILURE_RATE, BREAKER_HYSTERESIS_BUDGET_P95_MS, BREAKER_MIN_HEALTHY_RESIDENCE_MS, } from "./config/vector-cortex.js";