pi-mega-compact 0.20.26 → 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.
- package/dist/config/vector-cortex-vc9a.js +29 -0
- package/dist/config/vector-cortex-vc9b.js +29 -0
- package/dist/config/vector-cortex-vc9c.js +34 -0
- package/dist/config/vector-cortex.js +4 -0
- package/dist/config.js +1 -1
- package/dist/extensions/dashboard-server/api-contracts/endpoints/registry-ext.js +20 -0
- package/dist/extensions/dashboard-server/api-contracts/setup-cortex.js +13 -0
- package/dist/extensions/dashboard-server/route-dispatch.js +7 -1
- package/dist/extensions/dashboard-server/routes-rag-settings-vector-cortex.js +3 -0
- package/dist/extensions/dashboard-server/routes-setup-cortex-actions.js +116 -0
- package/dist/extensions/dashboard-server/routes-setup-cortex.js +143 -0
- package/dist/extensions/dashboard-server/routes.js +2 -0
- package/dist/extensions/dashboard-server/setup-cortex-actions.js +213 -0
- package/dist/extensions/dashboard-server/setup-cortex-blockers.js +70 -0
- package/dist/src/config/vector-cortex-vc9a.js +29 -0
- package/dist/src/config/vector-cortex-vc9b.js +29 -0
- package/dist/src/config/vector-cortex-vc9c.js +34 -0
- package/dist/src/config/vector-cortex.js +4 -0
- package/dist/src/config.js +1 -1
- package/extensions/dashboard-client/dist/assets/{AreaChart-DRErPez1.js → AreaChart-DIKsPqLG.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{AreaChart-DRErPez1.js.map → AreaChart-DIKsPqLG.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{BarChart-Cwxel3M7.js → BarChart-DeqN74Hn.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{BarChart-Cwxel3M7.js.map → BarChart-DeqN74Hn.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{CacheTab-D4j3vwFu.js → CacheTab-x1YU4tYc.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{CacheTab-D4j3vwFu.js.map → CacheTab-x1YU4tYc.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{EventsTab-BA7t_fsH.js → EventsTab-6BuEbd8Y.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{EventsTab-BA7t_fsH.js.map → EventsTab-6BuEbd8Y.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{HealthTab-Ci9gtYDP.js → HealthTab-B71Ft1ac.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{HealthTab-Ci9gtYDP.js.map → HealthTab-B71Ft1ac.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MaintenanceTab-BeqWn-xu.js → MaintenanceTab-dysyJtHk.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MaintenanceTab-BeqWn-xu.js.map → MaintenanceTab-dysyJtHk.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MemoryMapTab-BreZegCV.js → MemoryMapTab-B3dKRb_4.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MemoryMapTab-BreZegCV.js.map → MemoryMapTab-B3dKRb_4.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MetricsTab-DLbgfJT2.js → MetricsTab-COn4GoUK.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MetricsTab-DLbgfJT2.js.map → MetricsTab-COn4GoUK.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{OverviewTab-BtcXdrnC.js → OverviewTab-Cd9qAEB3.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{OverviewTab-BtcXdrnC.js.map → OverviewTab-Cd9qAEB3.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{ReposTab-DpDLEzV9.js → ReposTab-DpiP1-Vv.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{ReposTab-DpDLEzV9.js.map → ReposTab-DpiP1-Vv.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{SessionsTab-CMe5jSrZ.js → SessionsTab-BwRUeGZM.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{SessionsTab-CMe5jSrZ.js.map → SessionsTab-BwRUeGZM.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/SetupTab-CJFDD2_v.js +3 -0
- package/extensions/dashboard-client/dist/assets/SetupTab-CJFDD2_v.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/{TimeSavedCard-BFPJUQzs.js → TimeSavedCard-_XsdjQ7Z.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{TimeSavedCard-BFPJUQzs.js.map → TimeSavedCard-_XsdjQ7Z.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{TurnsTab-Ujt29pKI.js → TurnsTab-CWPscPLL.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{TurnsTab-Ujt29pKI.js.map → TurnsTab-CWPscPLL.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/VcStatusBadge-Cx56rAIM.js +2 -0
- package/extensions/dashboard-client/dist/assets/VcStatusBadge-Cx56rAIM.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/VectorCortexTab-B5ElUM7S.js +2 -0
- package/extensions/dashboard-client/dist/assets/VectorCortexTab-B5ElUM7S.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/{WikiTab-BiKXVwGT.js → WikiTab-uZ5Mq3XG.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{WikiTab-BiKXVwGT.js.map → WikiTab-uZ5Mq3XG.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{button-DJwGcw0u.js → button-Kc18bYFz.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{button-DJwGcw0u.js.map → button-Kc18bYFz.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{card-CgjBf5LZ.js → card-COJZoG08.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{card-CgjBf5LZ.js.map → card-COJZoG08.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-CTQIl2qs.js → generateCategoricalChart-ChEYo017.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-CTQIl2qs.js.map → generateCategoricalChart-ChEYo017.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{index-Bu8CZUMX.js → index-CB7Rn5FP.js} +14 -14
- package/extensions/dashboard-client/dist/assets/index-CB7Rn5FP.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/index-DbuGwYD7.css +1 -0
- package/extensions/dashboard-client/dist/assets/{switch-uUiS1Raq.js → switch-BFhl_tNh.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{switch-uUiS1Raq.js.map → switch-BFhl_tNh.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{toggle-Dv3OEscH.js → toggle-DJ68kATc.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{toggle-Dv3OEscH.js.map → toggle-DJ68kATc.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{useSSE-n6ymAic3.js → useSSE-CXWh42xX.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{useSSE-n6ymAic3.js.map → useSSE-CXWh42xX.js.map} +1 -1
- package/extensions/dashboard-client/dist/index.html +2 -2
- package/extensions/dashboard-client/src/api/setup-cortex.ts +62 -0
- package/extensions/dashboard-client/src/tabs/SetupTab/CortexActionsCard.tsx +221 -0
- package/extensions/dashboard-client/src/tabs/SetupTab/CortexBlockersCard.tsx +74 -0
- package/extensions/dashboard-client/src/tabs/SetupTab/CortexEncoderCard.tsx +113 -0
- package/extensions/dashboard-client/src/tabs/SetupTab/CortexSetup.tsx +53 -0
- package/extensions/dashboard-client/src/tabs/SetupTab/CortexSetupStyles.ts +98 -0
- package/extensions/dashboard-client/src/tabs/SetupTab.tsx +22 -6
- package/extensions/dashboard-client/src/tabs/useSetupCortexPoll.ts +64 -0
- package/extensions/dashboard-client/src/types/setup-cortex.ts +118 -0
- package/extensions/dashboard-server/api-contracts/endpoints/registry-ext.ts +44 -0
- package/extensions/dashboard-server/api-contracts/setup-cortex.ts +123 -0
- package/extensions/dashboard-server/route-dispatch.ts +6 -0
- package/extensions/dashboard-server/routes-rag-settings-vector-cortex.ts +18 -0
- package/extensions/dashboard-server/routes-setup-cortex-actions.ts +133 -0
- package/extensions/dashboard-server/routes-setup-cortex.ts +167 -0
- package/extensions/dashboard-server/routes.ts +5 -0
- package/extensions/dashboard-server/setup-cortex-actions.ts +242 -0
- package/extensions/dashboard-server/setup-cortex-blockers.ts +98 -0
- package/package.json +1 -1
- package/src/config/vector-cortex-vc9a.ts +31 -0
- package/src/config/vector-cortex-vc9b.ts +31 -0
- package/src/config/vector-cortex-vc9c.ts +36 -0
- package/src/config/vector-cortex.ts +5 -0
- package/src/config.ts +3 -0
- package/extensions/dashboard-client/dist/assets/SetupTab-C3OY8mc7.js +0 -2
- package/extensions/dashboard-client/dist/assets/SetupTab-C3OY8mc7.js.map +0 -1
- package/extensions/dashboard-client/dist/assets/VectorCortexTab-CfxZW91A.js +0 -2
- package/extensions/dashboard-client/dist/assets/VectorCortexTab-CfxZW91A.js.map +0 -1
- package/extensions/dashboard-client/dist/assets/index-Bu8CZUMX.js.map +0 -1
- package/extensions/dashboard-client/dist/assets/index-Difwoltx.css +0 -1
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dashboard-server/routes-setup-cortex.ts — VC9A Setup Cortex status route.
|
|
3
|
+
*
|
|
4
|
+
* GET /api/setup-cortex-status — reader-only aggregate surfacing the
|
|
5
|
+
* vector-cortex encoder gate (mode A/B/C, qualification verdict,
|
|
6
|
+
* blockers, encoder health) for the dashboard Setup tab. Does NOT close
|
|
7
|
+
* the ML gate: the hard-gate blockers are read-only and stay open.
|
|
8
|
+
*
|
|
9
|
+
* Reuses readEncoderManifest / verifyEncoderAsset / detectPlatform
|
|
10
|
+
* (src/vector-cortex/encoder/asset.ts) and deriveVcStatus (vc-status.ts),
|
|
11
|
+
* plus the memoized encoder-facts pattern from routes-vector-cortex-health.ts
|
|
12
|
+
* (manifest bytes + file size/mtime + platform cache key) so the expensive
|
|
13
|
+
* full-asset hashing is skipped on repeat polls.
|
|
14
|
+
*
|
|
15
|
+
* The blocker rows carry NO string literals here — they come from the static
|
|
16
|
+
* manifest module setup-cortex-blockers.ts (single canonical source).
|
|
17
|
+
*
|
|
18
|
+
* Guardrails: PREVENT-PI-004 (local filesystem read only), PREVENT-011 (no
|
|
19
|
+
* `any`), reader-only aggregate (never payloads/prompts/ledger — EVAL-REDACT-002).
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import type { IncomingMessage, ServerResponse } from "node:http";
|
|
23
|
+
import { createHash } from "node:crypto";
|
|
24
|
+
import { readFileSync, statSync } from "node:fs";
|
|
25
|
+
import { join, dirname } from "node:path";
|
|
26
|
+
import { fileURLToPath } from "node:url";
|
|
27
|
+
import type { RouteContext } from "./routes-core.js";
|
|
28
|
+
import { VC9A_ENABLED } from "../../src/config.js";
|
|
29
|
+
import { readEncoderManifest, verifyEncoderAsset, detectPlatform } from "../../src/vector-cortex/encoder/asset.js";
|
|
30
|
+
import { sendJson } from "./routes-vector-cortex-shared.js";
|
|
31
|
+
import { deriveVcStatus } from "./vc-status.js";
|
|
32
|
+
import { SETUP_CORTEX_BLOCKERS } from "./setup-cortex-blockers.js";
|
|
33
|
+
import type {
|
|
34
|
+
SetupCortexStatusResponse,
|
|
35
|
+
BlockerV1,
|
|
36
|
+
} from "./api-contracts/setup-cortex.js";
|
|
37
|
+
|
|
38
|
+
/** Resolve the committed encoder-v1 asset dir by walking up to the repo root. */
|
|
39
|
+
function encoderAssetDir(): string | null {
|
|
40
|
+
let dir = dirname(fileURLToPath(import.meta.url));
|
|
41
|
+
const rel = join("assets", "vector-cortex", "encoder-v1");
|
|
42
|
+
for (let i = 0; i < 8; i++) {
|
|
43
|
+
const candidate = join(dir, rel);
|
|
44
|
+
try {
|
|
45
|
+
// guardrails-allow PREVENT-PI-004: local asset filesystem read (loopback)
|
|
46
|
+
readFileSync(join(candidate, "manifest.json"));
|
|
47
|
+
return candidate;
|
|
48
|
+
} catch {
|
|
49
|
+
/* keep walking */
|
|
50
|
+
}
|
|
51
|
+
const next = dirname(dir);
|
|
52
|
+
if (next === dir) break;
|
|
53
|
+
dir = next;
|
|
54
|
+
}
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** Reader-only encoder health facts: mode + asset digest (+ vertex/verdict). */
|
|
59
|
+
interface SetupCortexFacts {
|
|
60
|
+
mode: "A" | "B" | "C";
|
|
61
|
+
assetDigestPrefix: string | null;
|
|
62
|
+
verdict: "qualified" | "demoted" | "unavailable";
|
|
63
|
+
thresholdFailures: string[];
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
interface SetupCortexFactCache {
|
|
67
|
+
key: string;
|
|
68
|
+
facts: SetupCortexFacts;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
let factCache: SetupCortexFactCache | null = null;
|
|
72
|
+
|
|
73
|
+
/** Stable cache key: manifest bytes + (size,mtime) of the asset files + platform. */
|
|
74
|
+
function factCacheKey(dir: string, manifestPath: string): string | null {
|
|
75
|
+
const platform = detectPlatform();
|
|
76
|
+
if (!platform) return null;
|
|
77
|
+
const parts: string[] = [platform];
|
|
78
|
+
try {
|
|
79
|
+
for (const p of [manifestPath, join(dir, "model.onnx"), join(dir, "tokenizer.json")]) {
|
|
80
|
+
const s = statSync(p);
|
|
81
|
+
parts.push(`${s.size}:${s.mtimeMs}`);
|
|
82
|
+
}
|
|
83
|
+
// guardrails-allow PREVENT-PI-004: local manifest filesystem read (loopback)
|
|
84
|
+
parts.push(createHash("sha256").update(readFileSync(manifestPath)).digest("hex"));
|
|
85
|
+
} catch {
|
|
86
|
+
return null;
|
|
87
|
+
}
|
|
88
|
+
return parts.join("|");
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function computeSetupCortexFacts(dir: string): SetupCortexFacts | null {
|
|
92
|
+
const manifest = readEncoderManifest(dir);
|
|
93
|
+
if (manifest === null) {
|
|
94
|
+
return { mode: "C", assetDigestPrefix: null, verdict: "unavailable", thresholdFailures: [] };
|
|
95
|
+
}
|
|
96
|
+
const manifestPath = join(dir, "manifest.json");
|
|
97
|
+
const key = factCacheKey(dir, manifestPath);
|
|
98
|
+
if (key === null) return null;
|
|
99
|
+
if (factCache !== null && factCache.key === key) return factCache.facts;
|
|
100
|
+
let digest: string;
|
|
101
|
+
try {
|
|
102
|
+
// guardrails-allow PREVENT-PI-004: local manifest filesystem read (loopback)
|
|
103
|
+
digest = createHash("sha256").update(readFileSync(manifestPath)).digest("hex");
|
|
104
|
+
} catch {
|
|
105
|
+
const facts: SetupCortexFacts = { mode: "B", assetDigestPrefix: null, verdict: "demoted", thresholdFailures: ["ENC_ASSET_UNREADABLE"] };
|
|
106
|
+
factCache = { key, facts };
|
|
107
|
+
return facts;
|
|
108
|
+
}
|
|
109
|
+
const verify = verifyEncoderAsset(dir, manifest, detectPlatform());
|
|
110
|
+
const prefix = digest.slice(0, 12);
|
|
111
|
+
const facts: SetupCortexFacts = verify.ok
|
|
112
|
+
? { mode: "A", assetDigestPrefix: prefix, verdict: "qualified", thresholdFailures: [] }
|
|
113
|
+
: { mode: "B", assetDigestPrefix: prefix, verdict: "demoted", thresholdFailures: [verify.code] };
|
|
114
|
+
factCache = { key, facts };
|
|
115
|
+
return facts;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function setupCortexFacts(): SetupCortexFacts {
|
|
119
|
+
const dir = encoderAssetDir();
|
|
120
|
+
if (dir === null) {
|
|
121
|
+
return { mode: "C", assetDigestPrefix: null, verdict: "unavailable", thresholdFailures: [] };
|
|
122
|
+
}
|
|
123
|
+
const facts = computeSetupCortexFacts(dir);
|
|
124
|
+
return facts ?? { mode: "C", assetDigestPrefix: null, verdict: "unavailable", thresholdFailures: [] };
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* Reader-only GET /api/setup-cortex-status (VC9A).
|
|
129
|
+
*
|
|
130
|
+
* Purely read: no mutation, never payloads/prompts/ledger. Flag-off returns the
|
|
131
|
+
* byte-identical VC8C-era shape `{enabled:false, mode:"C", status:"off"}` with
|
|
132
|
+
* the encoder-health mode C and no qualification/blocker detail leaked.
|
|
133
|
+
*/
|
|
134
|
+
export function handleSetupCortexStatus(
|
|
135
|
+
req: IncomingMessage,
|
|
136
|
+
res: ServerResponse,
|
|
137
|
+
_ctx: RouteContext,
|
|
138
|
+
): boolean {
|
|
139
|
+
const url = req.url ?? "";
|
|
140
|
+
if (url !== "/api/setup-cortex-status") return false;
|
|
141
|
+
if (req.method !== "GET") {
|
|
142
|
+
sendJson(res, 405, { error: "method_not_allowed" });
|
|
143
|
+
return true;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
const enabled = VC9A_ENABLED();
|
|
147
|
+
const facts = enabled ? setupCortexFacts() : null;
|
|
148
|
+
const blocks: BlockerV1[] = enabled ? [...SETUP_CORTEX_BLOCKERS] : [];
|
|
149
|
+
|
|
150
|
+
const body: SetupCortexStatusResponse = {
|
|
151
|
+
enabled,
|
|
152
|
+
flag: "MEGACOMPACT_VC9A",
|
|
153
|
+
mode: facts ? facts.mode : "C",
|
|
154
|
+
assetDigestPrefix: facts ? facts.assetDigestPrefix : null,
|
|
155
|
+
qualification: facts
|
|
156
|
+
? { verdict: facts.verdict, thresholdFailures: facts.thresholdFailures }
|
|
157
|
+
: { verdict: "unavailable", thresholdFailures: [] },
|
|
158
|
+
blockers: blocks,
|
|
159
|
+
encoderHealth: facts
|
|
160
|
+
? { assetDigestPrefix: facts.assetDigestPrefix, mode: facts.mode }
|
|
161
|
+
: { assetDigestPrefix: null, mode: "C" },
|
|
162
|
+
updatedAt: new Date().toISOString(),
|
|
163
|
+
status: deriveVcStatus({ enabled, hasData: !!facts && facts.verdict !== "unavailable", structuralOnly: true }),
|
|
164
|
+
};
|
|
165
|
+
sendJson(res, 200, body);
|
|
166
|
+
return true;
|
|
167
|
+
}
|
|
@@ -56,3 +56,8 @@ export {
|
|
|
56
56
|
handleVectorCortexClosureProof,
|
|
57
57
|
handleVectorCortexRestore,
|
|
58
58
|
} from "./routes-vector-cortex.js";
|
|
59
|
+
export { handleSetupCortexStatus } from "./routes-setup-cortex.js";
|
|
60
|
+
export {
|
|
61
|
+
handleSetupCortexAction,
|
|
62
|
+
handleSetupCortexActionLog,
|
|
63
|
+
} from "./routes-setup-cortex-actions.js";
|
|
@@ -0,0 +1,242 @@
|
|
|
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
|
+
|
|
20
|
+
import { spawnSync } from "node:child_process"; // guardrails-allow PREVENT-PI-004: local subprocess spawn of committed repo script (loopback)
|
|
21
|
+
import {
|
|
22
|
+
mkdirSync,
|
|
23
|
+
readFileSync,
|
|
24
|
+
writeFileSync,
|
|
25
|
+
existsSync,
|
|
26
|
+
readdirSync,
|
|
27
|
+
} from "node:fs";
|
|
28
|
+
import { join, dirname, basename } from "node:path";
|
|
29
|
+
import { fileURLToPath } from "node:url";
|
|
30
|
+
import type {
|
|
31
|
+
SetupCortexActionKind,
|
|
32
|
+
SetupCortexActionResult,
|
|
33
|
+
} from "./api-contracts/setup-cortex.js";
|
|
34
|
+
import {
|
|
35
|
+
readEncoderManifest,
|
|
36
|
+
verifyEncoderAsset,
|
|
37
|
+
detectPlatform,
|
|
38
|
+
} from "../../src/vector-cortex/encoder/asset.js";
|
|
39
|
+
|
|
40
|
+
/** Cap applied to every log tail served by the action-log route. */
|
|
41
|
+
export const ACTION_LOG_TAIL_BYTES = 8192;
|
|
42
|
+
|
|
43
|
+
/** Locate the commit's vc2-model-prep directory by walking up to the repo root. */
|
|
44
|
+
function vc2ScriptDir(): string | null {
|
|
45
|
+
let dir = dirname(fileURLToPath(import.meta.url));
|
|
46
|
+
const rel = join("scripts", "vc2-model-prep");
|
|
47
|
+
for (let i = 0; i < 8; i++) {
|
|
48
|
+
const candidate = join(dir, rel);
|
|
49
|
+
if (existsSync(join(candidate, "fetch-model.sh"))) return candidate;
|
|
50
|
+
const next = dirname(dir);
|
|
51
|
+
if (next === dir) break;
|
|
52
|
+
dir = next;
|
|
53
|
+
}
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** Absolute dir holding this repo's <stateDir>/logs/vc9b/ action logs. */
|
|
58
|
+
export function vc9bLogDir(stateDir: string): string {
|
|
59
|
+
return join(stateDir, "logs", "vc9b");
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/** Ensure the vc9b log dir exists and return its absolute path. */
|
|
63
|
+
function ensureLogDir(stateDir: string): string {
|
|
64
|
+
const dir = vc9bLogDir(stateDir);
|
|
65
|
+
// guardrails-allow PREVENT-PI-004: local state-dir filesystem write (loopback)
|
|
66
|
+
mkdirSync(dir, { recursive: true });
|
|
67
|
+
return dir;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
/** Safe log basename: non-empty, no separators, not a dot/double-dot segment. */
|
|
71
|
+
export function isSafeLogName(name: string): boolean {
|
|
72
|
+
if (!name || name.length === 0) return false;
|
|
73
|
+
if (name.includes("/") || name.includes("\\")) return false;
|
|
74
|
+
if (name === "." || name === "..") return false;
|
|
75
|
+
// Must match our own file naming: <action>-<ts>.log where ts is digits.
|
|
76
|
+
return /^[a-z-]+-\d+\.log$/.test(name);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Redact a fragment of action-log output: bound long digests to their prefix and
|
|
81
|
+
* collapse long base64-looking tokens, so the served tail carries digest prefixes
|
|
82
|
+
* + codes only — never arbitrary payload bytes. Returns the redacted text.
|
|
83
|
+
*/
|
|
84
|
+
export function redactLog(text: string): string {
|
|
85
|
+
let out = text;
|
|
86
|
+
// SHA-256 (64 hex) or any long hex digest -> keep the first 12 chars.
|
|
87
|
+
out = out.replace(/\b[0-9a-fA-F]{32,}\b/g, (m) => `sha256:${m.slice(0, 12)}`);
|
|
88
|
+
// Long base64-ish tokens (26+ chars from the base64 alphabet) -> collapse.
|
|
89
|
+
out = out.replace(/[A-Za-z0-9+/=]{26,}/g, (m) => `<redacted:${m.length}>`);
|
|
90
|
+
return out;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/** Read + bound + redact the tail of one vc9b log file. */
|
|
94
|
+
export function readActionLogTail(
|
|
95
|
+
stateDir: string,
|
|
96
|
+
name: string,
|
|
97
|
+
): { name: string; tail: string; complete: boolean } | null {
|
|
98
|
+
if (!isSafeLogName(name)) return null;
|
|
99
|
+
const dir = vc9bLogDir(stateDir);
|
|
100
|
+
const full = join(dir, name);
|
|
101
|
+
if (basename(full) !== name) return null; // belt-and-suspenders: no traversal
|
|
102
|
+
if (!existsSync(full)) return null;
|
|
103
|
+
let raw: string;
|
|
104
|
+
try {
|
|
105
|
+
// guardrails-allow PREVENT-PI-004: local state-dir filesystem read (loopback)
|
|
106
|
+
raw = readFileSync(full, "utf8");
|
|
107
|
+
} catch {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
const bounded = raw.length > ACTION_LOG_TAIL_BYTES
|
|
111
|
+
? raw.slice(-ACTION_LOG_TAIL_BYTES)
|
|
112
|
+
: raw;
|
|
113
|
+
return {
|
|
114
|
+
name,
|
|
115
|
+
tail: redactLog(bounded),
|
|
116
|
+
complete: raw.length <= ACTION_LOG_TAIL_BYTES,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** Run a vc2-model-prep subprocess and capture its output to a vc9b log file. */
|
|
121
|
+
function runSpawnedAction(
|
|
122
|
+
action: Extract<SetupCortexActionKind, "fetch-model" | "bench">,
|
|
123
|
+
stateDir: string,
|
|
124
|
+
): SetupCortexActionResult {
|
|
125
|
+
const dir = vc2ScriptDir();
|
|
126
|
+
const { name, logPath } = writeLogName(action, stateDir);
|
|
127
|
+
if (dir === null) {
|
|
128
|
+
writeLog(logPath, "vc2-model-prep scripts not found in this checkout\n");
|
|
129
|
+
return { action, ok: false, exitCode: null, logPath, logName: name, spawned: true };
|
|
130
|
+
}
|
|
131
|
+
let result;
|
|
132
|
+
if (action === "fetch-model") {
|
|
133
|
+
// guardrails-allow PREVENT-PI-004: local subprocess spawn of committed repo script (loopback)
|
|
134
|
+
result = spawnSync("bash", [join(dir, "fetch-model.sh"), join(stateDir, "vc2-model-prep")], {
|
|
135
|
+
encoding: "utf8",
|
|
136
|
+
timeout: 60_000,
|
|
137
|
+
});
|
|
138
|
+
} else {
|
|
139
|
+
// guardrails-allow PREVENT-PI-004: local subprocess spawn of committed repo script (loopback)
|
|
140
|
+
result = spawnSync(process.execPath, [join(dir, "bench-onnx.mjs")], {
|
|
141
|
+
encoding: "utf8",
|
|
142
|
+
timeout: 60_000,
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
const out = `${result.stdout ?? ""}${result.stderr ?? ""}`;
|
|
146
|
+
writeLog(logPath, out || "(no output)\n");
|
|
147
|
+
return {
|
|
148
|
+
action,
|
|
149
|
+
ok: result.status === 0,
|
|
150
|
+
exitCode: result.status === null ? null : result.status,
|
|
151
|
+
logPath,
|
|
152
|
+
logName: name,
|
|
153
|
+
spawned: true,
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Re-run the committed encoder asset verification seam (readEncoderManifest +
|
|
159
|
+
* verifyEncoderAsset + detectPlatform) WITHOUT any subprocess, and log a
|
|
160
|
+
* redacted summary (mode + digest prefix + verdict/code only). Uses the same
|
|
161
|
+
* repo-root walk the VC9A status route uses to find assets/vector-cortex.
|
|
162
|
+
*/
|
|
163
|
+
function runVerifyAsset(stateDir: string): SetupCortexActionResult {
|
|
164
|
+
const { name, logPath } = writeLogName("verify-asset", stateDir);
|
|
165
|
+
const body = buildVerifySummary();
|
|
166
|
+
writeLog(logPath, body);
|
|
167
|
+
return {
|
|
168
|
+
action: "verify-asset",
|
|
169
|
+
ok: body.includes("verdict=qualified"),
|
|
170
|
+
exitCode: null,
|
|
171
|
+
logPath,
|
|
172
|
+
logName: name,
|
|
173
|
+
spawned: false,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
/** Compute the redacted verify-asset summary lines (digests + codes only). */
|
|
178
|
+
function buildVerifySummary(): string {
|
|
179
|
+
const dir = encoderAssetDir();
|
|
180
|
+
if (dir === null) {
|
|
181
|
+
return "mode=C verdict=unavailable reason=asset_missing\n";
|
|
182
|
+
}
|
|
183
|
+
const manifest = readEncoderManifest(dir);
|
|
184
|
+
if (manifest === null) {
|
|
185
|
+
return "mode=B verdict=demoted reason=ENC_MANIFEST_INVALID\n";
|
|
186
|
+
}
|
|
187
|
+
const platform = detectPlatform();
|
|
188
|
+
const verify = verifyEncoderAsset(dir, manifest, platform);
|
|
189
|
+
if (verify.ok) {
|
|
190
|
+
const prefix = verify.onnxDigest.slice(0, 12);
|
|
191
|
+
return `mode=A verdict=qualified onnx_digest_prefix=${prefix} embedded_bytes=${verify.embeddedBytes}\n`;
|
|
192
|
+
}
|
|
193
|
+
return `mode=B verdict=demoted reason=${verify.code}\n`;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
/** Walk up to the committed encoder-v1 asset dir (mirrors routes-setup-cortex.ts). */
|
|
197
|
+
function encoderAssetDir(): string | null {
|
|
198
|
+
let dir = dirname(fileURLToPath(import.meta.url));
|
|
199
|
+
const rel = join("assets", "vector-cortex", "encoder-v1");
|
|
200
|
+
for (let i = 0; i < 8; i++) {
|
|
201
|
+
const candidate = join(dir, rel);
|
|
202
|
+
// guardrails-allow PREVENT-PI-004: local asset filesystem read (loopback)
|
|
203
|
+
if (existsSync(join(candidate, "manifest.json"))) return candidate;
|
|
204
|
+
const next = dirname(dir);
|
|
205
|
+
if (next === dir) break;
|
|
206
|
+
dir = next;
|
|
207
|
+
}
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
interface LogFileRef {
|
|
212
|
+
name: string;
|
|
213
|
+
logPath: string;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
/** Unique <action>-<ts>.log name + absolute path under the vc9b log dir. */
|
|
217
|
+
function writeLogName(action: SetupCortexActionKind, stateDir: string): LogFileRef {
|
|
218
|
+
let ts = Date.now();
|
|
219
|
+
const existing = new Set(readdirSync(ensureLogDir(stateDir)));
|
|
220
|
+
while (existing.has(`${action}-${ts}.log`)) ts++;
|
|
221
|
+
const name = `${action}-${ts}.log`;
|
|
222
|
+
return { name, logPath: join(vc9bLogDir(stateDir), name) };
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function writeLog(logPath: string, body: string): void {
|
|
226
|
+
// guardrails-allow PREVENT-PI-004: local state-dir filesystem write (loopback)
|
|
227
|
+
writeFileSync(logPath, body, "utf8");
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Run one Setup Cortex action against the given stateDir. Returns the action
|
|
232
|
+
* result on success; throws nothing — every failure is surfaced as a result with
|
|
233
|
+
* ok=false so the route can shape the HTTP response. Never touches the network;
|
|
234
|
+
* the subprocesses it may spawn are the committed local vc2-model-prep scripts.
|
|
235
|
+
*/
|
|
236
|
+
export function runSetupCortexAction(
|
|
237
|
+
action: SetupCortexActionKind,
|
|
238
|
+
stateDir: string,
|
|
239
|
+
): SetupCortexActionResult {
|
|
240
|
+
if (action === "verify-asset") return runVerifyAsset(stateDir);
|
|
241
|
+
return runSpawnedAction(action, stateDir);
|
|
242
|
+
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dashboard-server/setup-cortex-blockers.ts — canonical blocker manifest for the
|
|
3
|
+
* dashboard Setup Cortex status read path (VC9A).
|
|
4
|
+
*
|
|
5
|
+
* The hard-gate items enumerated in docs/vector-cortex/vc2-model-prep.md §6
|
|
6
|
+
* (per the 2026-08-05 research update: the opset-14→17 re-export blocker is
|
|
7
|
+
* REMOVED because onnx-community exports are now opset 21). This module is the
|
|
8
|
+
* SINGLE canonical source of those blockers — the route file
|
|
9
|
+
* (routes-setup-cortex.ts) carries NO string literals for them; it reads this
|
|
10
|
+
* static manifest so the UI rows and the spec stay in one place.
|
|
11
|
+
*
|
|
12
|
+
* Reader-only, static: zero network, no writes (PREVENT-PI-004), no `any`
|
|
13
|
+
* (PREVENT-011).
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
/** The open hard-gate items VC9A surfaces (nothing is closed in-workstream). */
|
|
17
|
+
export interface SetupCortexBlockerV1 {
|
|
18
|
+
/** Stable machine id (e.g. HG-1) the client can key rows on. */
|
|
19
|
+
readonly id: string;
|
|
20
|
+
/** Human title shown on the blockers card. */
|
|
21
|
+
readonly title: string;
|
|
22
|
+
/** Severity: blocker | high | medium. */
|
|
23
|
+
readonly severity: "blocker" | "high" | "medium";
|
|
24
|
+
/** Lifecycle state — all OPEN (hard gates are never silently closed). */
|
|
25
|
+
readonly status: "open";
|
|
26
|
+
/** Optional candidate resolution surfaced for the controller / user. */
|
|
27
|
+
readonly resolution?: string;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* The four blockers VC9A reports. Enumerates the vc2-model-prep §6 items that
|
|
32
|
+
* remain per the 2026-08-05 research. The opset re-export blocker (formerly
|
|
33
|
+
* §6 #2) is NOT listed: onnx-community exports are opset 21, so it is removed.
|
|
34
|
+
*/
|
|
35
|
+
export const SETUP_CORTEX_BLOCKERS: readonly SetupCortexBlockerV1[] = [
|
|
36
|
+
{
|
|
37
|
+
id: "HG-1",
|
|
38
|
+
title: "Five projection heads do not exist",
|
|
39
|
+
severity: "blocker",
|
|
40
|
+
status: "open",
|
|
41
|
+
resolution:
|
|
42
|
+
"Supervision transfer onto a frozen bge-small-en-v1.5 trunk (contradiction distilled from cross-encoder/nli-deberta-v3-small; dependency NLI-assisted; cache-stability deterministic; payload-routing small MLP) — VC2B training + export.",
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
id: "HG-3",
|
|
46
|
+
title: "onnxruntime-node install exceeds the 80 MiB asset budget",
|
|
47
|
+
severity: "blocker",
|
|
48
|
+
status: "open",
|
|
49
|
+
resolution:
|
|
50
|
+
"onnxruntime-node bundles ~258 MiB across all platforms. Candidate: transformers.js v4.2.0 (9.5 MiB shell, pure-Node via onnxruntime-web WASM) measured against budget + p95 gate before committing.",
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
id: "HG-4",
|
|
54
|
+
title: "No darwin-x64 binary in onnxruntime-node",
|
|
55
|
+
severity: "high",
|
|
56
|
+
status: "open",
|
|
57
|
+
resolution:
|
|
58
|
+
"Intel-Mac mode-A users demote to the WASM path (if HG-3 resolves that way) or mode B.",
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
id: "HG-5",
|
|
62
|
+
title: "RSS margin at 512 tokens is ~0.5%",
|
|
63
|
+
severity: "medium",
|
|
64
|
+
status: "open",
|
|
65
|
+
resolution:
|
|
66
|
+
"149.2 MiB vs 150 MiB cap with run-to-run variance 119-149 MiB; considers capping mode A at 384 tokens or using the marginal-footprint accounting runtime.ts already implements.",
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
|
|
70
|
+
/** Look up one blocker by id; undefined when unknown (defensive). */
|
|
71
|
+
export function setupCortexBlocker(id: string): SetupCortexBlockerV1 | undefined {
|
|
72
|
+
return SETUP_CORTEX_BLOCKERS.find((b) => b.id === id);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// ─── VC9B action gating ─────────────────────────────────────────────────────
|
|
76
|
+
|
|
77
|
+
/** The VC9B action kinds the drivers know how to run. */
|
|
78
|
+
export type SetupCortexActionKind = "fetch-model" | "bench" | "verify-asset";
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* The open hard-gate ids that BLOCK a given action. fetch-model and bench are
|
|
82
|
+
* gated by HG-1 (five-head training open) and HG-3 (install budget open) per the
|
|
83
|
+
* VC9 workstream plan; verify-asset is a pure re-read of committed assets and is
|
|
84
|
+
* NOT gated. When a gated action is requested, the route returns
|
|
85
|
+
* action_blocked_by_open_item with these ids and does NOT spawn. The ids are
|
|
86
|
+
* always drawn from SETUP_CORTEX_BLOCKERS (each exists — verified by test).
|
|
87
|
+
*/
|
|
88
|
+
export function setupCortexActionBlockers(
|
|
89
|
+
action: SetupCortexActionKind,
|
|
90
|
+
): readonly string[] {
|
|
91
|
+
switch (action) {
|
|
92
|
+
case "fetch-model":
|
|
93
|
+
case "bench":
|
|
94
|
+
return ["HG-1", "HG-3"];
|
|
95
|
+
case "verify-asset":
|
|
96
|
+
return [];
|
|
97
|
+
}
|
|
98
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-mega-compact",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.28",
|
|
4
4
|
"description": "Layered, local, vector-backed context compressor for pi — supersede/collapse/cluster compaction with deduped inline recall.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "BSD-3-Clause",
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* config/vector-cortex-vc9a.ts — VC9A setup-cortex status-read-path 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-vc8c.ts,
|
|
6
|
+
* vector-cortex-breakers.ts and vector-cortex-early.ts were. This is the
|
|
7
|
+
* SETUP-DASHBOARD reader flag (the dashboard Setup tab cortex status endpoint).
|
|
8
|
+
* vector-cortex.ts re-exports it below and root src/config.ts re-exports it, so
|
|
9
|
+
* no consumer import path changes.
|
|
10
|
+
*
|
|
11
|
+
* The split is purely mechanical: VC9A_ENABLED is byte-identical in name,
|
|
12
|
+
* semantics, and default to the definition it replaces, and vector-cortex.ts
|
|
13
|
+
* re-exports it so every existing `from "./config/vector-cortex.js"` import
|
|
14
|
+
* keeps resolving unchanged.
|
|
15
|
+
*
|
|
16
|
+
* Pi-agnostic, dependency-free (PREVENT-PI-004 / PREVENT-011).
|
|
17
|
+
*/
|
|
18
|
+
|
|
19
|
+
import { sprintFlag } from "./vector-cortex-flag.js";
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* VC9A — Setup Cortex status read path (GET /api/setup-cortex-status).
|
|
23
|
+
* Default ON. `MEGACOMPACT_VC9A=0` disables and is byte-identical to the
|
|
24
|
+
* predecessor (VC8C-era shape): the endpoint returns `{enabled:false,
|
|
25
|
+
* mode:"C", status:"off"}` and surfaces no qualification/blocker/health detail —
|
|
26
|
+
* a pure reader-only projection, never a mutation. This flag MUST also be a
|
|
27
|
+
* dashboard SETTINGS toggle (visible in config UI, never in EXCLUDED_SETTINGS),
|
|
28
|
+
* mirroring VC4A..VC8C. The dashboard reader itself performs only local
|
|
29
|
+
* filesystem reads (no network, PREVENT-PI-004).
|
|
30
|
+
*/
|
|
31
|
+
export const VC9A_ENABLED = (): boolean => sprintFlag("MEGACOMPACT_VC9A");
|
|
@@ -0,0 +1,31 @@
|
|
|
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
|
+
|
|
18
|
+
import { sprintFlag } from "./vector-cortex-flag.js";
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* VC9B — Setup Cortex action drivers (POST /api/setup-cortex-action +
|
|
22
|
+
* GET /api/setup-cortex-action-log). Default ON. `MEGACOMPACT_VC9B=0` disables
|
|
23
|
+
* and is byte-identical to the predecessor (VC9A-era): the action POST returns
|
|
24
|
+
* the disabled shape (404/disabled) and flag-off bytes are unchanged. The
|
|
25
|
+
* actions only spawn the existing committed local scripts
|
|
26
|
+
* (scripts/vc2-model-prep/fetch-model.sh / bench-onnx.mjs) or re-read the
|
|
27
|
+
* committed encoder assets — never payload bytes, no network (PREVENT-PI-004).
|
|
28
|
+
* This flag MUST also be a dashboard SETTINGS toggle (visible in config UI,
|
|
29
|
+
* never in EXCLUDED_SETTINGS), mirroring VC9A.
|
|
30
|
+
*/
|
|
31
|
+
export const VC9B_ENABLED = (): boolean => sprintFlag("MEGACOMPACT_VC9B");
|
|
@@ -0,0 +1,36 @@
|
|
|
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
|
+
|
|
23
|
+
import { sprintFlag } from "./vector-cortex-flag.js";
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* VC9C — SetupTab Cortex sub-tab (client UI). Default ON. `MEGACOMPACT_VC9C=0`
|
|
27
|
+
* disables and is byte-identical to the predecessor (VC9B-era): the Cortex
|
|
28
|
+
* sub-tab is filtered from SUB_TABS and the Setup tab renders exactly as it
|
|
29
|
+
* did before this sprint. The sub-tab is a pure consumer of the VC9A status
|
|
30
|
+
* endpoint (GET /api/setup-cortex-status) + VC9B action endpoints (POST
|
|
31
|
+
* /api/setup-cortex-action, GET /api/setup-cortex-action-log); it adds NO
|
|
32
|
+
* server logic and never surfaces payload bytes/prompts/ledger. This flag MUST
|
|
33
|
+
* also be a dashboard SETTINGS toggle (visible in config UI, never in
|
|
34
|
+
* EXCLUDED_SETTINGS), mirroring VC9A/VC9B.
|
|
35
|
+
*/
|
|
36
|
+
export const VC9C_ENABLED = (): boolean => sprintFlag("MEGACOMPACT_VC9C");
|
|
@@ -275,6 +275,11 @@ export const VC8B_ENABLED = (): boolean => sprintFlag("MEGACOMPACT_VC8B");
|
|
|
275
275
|
// import keeps resolving unchanged.
|
|
276
276
|
export { VC8C_ENABLED } from "./vector-cortex-vc8c.js";
|
|
277
277
|
|
|
278
|
+
// VC9A/VC9B/VC9C split to vector-cortex-vc9{a,b,c}.ts to stay under the 300-line soft limit.
|
|
279
|
+
export { VC9A_ENABLED } from "./vector-cortex-vc9a.js";
|
|
280
|
+
export { VC9B_ENABLED } from "./vector-cortex-vc9b.js";
|
|
281
|
+
export { VC9C_ENABLED } from "./vector-cortex-vc9c.js";
|
|
282
|
+
|
|
278
283
|
// Breaker state machine constants (TRIAD_RESILIENCE.md §breaker) extracted to
|
|
279
284
|
// vector-cortex-breakers.ts to keep this file under the 300-line soft limit.
|
|
280
285
|
export {
|