pi-mega-compact 0.20.40 → 0.20.42
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-dedup-attr.js +14 -0
- package/dist/config/vector-cortex-ml5e.js +30 -0
- package/dist/config/vector-cortex.js +5 -5
- package/dist/config.js +1 -1
- package/dist/extensions/dashboard-server/api-contracts/dedup-attribution.js +13 -0
- package/dist/extensions/dashboard-server/api-contracts/endpoints/registry-ext.js +7 -0
- package/dist/extensions/dashboard-server/route-dispatch.js +3 -1
- package/dist/extensions/dashboard-server/routes-dedup-attribution.js +150 -0
- package/dist/extensions/dashboard-server/routes-rag-settings-vector-cortex.js +2 -0
- package/dist/extensions/dashboard-server/routes.js +1 -0
- package/dist/src/config/vector-cortex-dedup-attr.js +14 -0
- package/dist/src/config/vector-cortex-ml5e.js +30 -0
- package/dist/src/config/vector-cortex.js +5 -5
- package/dist/src/config.js +1 -1
- package/dist/src/vector-cortex/dedup-attr/rollup.js +97 -0
- package/dist/src/vector-cortex/encoder/promotion.js +58 -0
- package/dist/vector-cortex/dedup-attr/rollup.js +97 -0
- package/dist/vector-cortex/encoder/promotion.js +58 -0
- package/extensions/dashboard-client/dist/assets/{AreaChart-BT7YPcp7.js → AreaChart-Cn6X7epL.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{AreaChart-BT7YPcp7.js.map → AreaChart-Cn6X7epL.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{BarChart-DceGcBUh.js → BarChart-APy1Wc7z.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{BarChart-DceGcBUh.js.map → BarChart-APy1Wc7z.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{CacheTab-B9lCouRl.js → CacheTab-CEv_Ss9O.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{CacheTab-B9lCouRl.js.map → CacheTab-CEv_Ss9O.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{EventsTab-oqJ11jY7.js → EventsTab-8jV1Pr0C.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{EventsTab-oqJ11jY7.js.map → EventsTab-8jV1Pr0C.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{HealthTab-Dbosf2Ik.js → HealthTab-B2VgEz1j.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{HealthTab-Dbosf2Ik.js.map → HealthTab-B2VgEz1j.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MaintenanceTab-6TiApCVE.js → MaintenanceTab-m37AlTbg.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MaintenanceTab-6TiApCVE.js.map → MaintenanceTab-m37AlTbg.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MemoryMapTab-cBsE4mTf.js → MemoryMapTab-Co2jbqdT.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MemoryMapTab-cBsE4mTf.js.map → MemoryMapTab-Co2jbqdT.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{MetricsTab-CX-X9hhy.js → MetricsTab-D0yV9X6D.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{MetricsTab-CX-X9hhy.js.map → MetricsTab-D0yV9X6D.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{OverviewTab-CpPYaTJF.js → OverviewTab-J5TjXB14.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{OverviewTab-CpPYaTJF.js.map → OverviewTab-J5TjXB14.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{ReposTab-D_Ot4QbU.js → ReposTab-BadNIkWu.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{ReposTab-D_Ot4QbU.js.map → ReposTab-BadNIkWu.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{SessionsTab-BUzO3iGK.js → SessionsTab-CdKShJuR.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{SessionsTab-BUzO3iGK.js.map → SessionsTab-CdKShJuR.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{SetupTab-Be4w9v4j.js → SetupTab-CPemizDx.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{SetupTab-Be4w9v4j.js.map → SetupTab-CPemizDx.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{TimeSavedCard-Cx-g6CXH.js → TimeSavedCard-TvULibwW.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{TimeSavedCard-Cx-g6CXH.js.map → TimeSavedCard-TvULibwW.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{TurnsTab-CC_7T7ad.js → TurnsTab-CglFIcYy.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{TurnsTab-CC_7T7ad.js.map → TurnsTab-CglFIcYy.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{VcStatusBadge-ZTItXSiH.js → VcStatusBadge-H2bBNhrR.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{VcStatusBadge-ZTItXSiH.js.map → VcStatusBadge-H2bBNhrR.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{VectorCortexTab-DgAUZ4Pg.js → VectorCortexTab-CXPv3sYQ.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{VectorCortexTab-DgAUZ4Pg.js.map → VectorCortexTab-CXPv3sYQ.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{WikiTab-DnKupXTv.js → WikiTab-BNfN175_.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{WikiTab-DnKupXTv.js.map → WikiTab-BNfN175_.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{button-CFt3e0yc.js → button-DjN7aqD2.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{button-CFt3e0yc.js.map → button-DjN7aqD2.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{card-C6ZjsHrl.js → card-DLHA5XP8.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{card-C6ZjsHrl.js.map → card-DLHA5XP8.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{client-extra-DdEdGTIe.js → client-extra-ZT6mIQZS.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{client-extra-DdEdGTIe.js.map → client-extra-ZT6mIQZS.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-C9_fu2hc.js → generateCategoricalChart-DAl4dRVG.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{generateCategoricalChart-C9_fu2hc.js.map → generateCategoricalChart-DAl4dRVG.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{index-DY81TY4f.js → index-H-sfROoW.js} +16 -16
- package/extensions/dashboard-client/dist/assets/index-H-sfROoW.js.map +1 -0
- package/extensions/dashboard-client/dist/assets/{switch-BOqa1d6x.js → switch-BCxvJYon.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{switch-BOqa1d6x.js.map → switch-BCxvJYon.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{toggle-DToFaIEd.js → toggle-DviUMYeg.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{toggle-DToFaIEd.js.map → toggle-DviUMYeg.js.map} +1 -1
- package/extensions/dashboard-client/dist/assets/{useSSE-CZqkhU18.js → useSSE-DP2O8vHY.js} +2 -2
- package/extensions/dashboard-client/dist/assets/{useSSE-CZqkhU18.js.map → useSSE-DP2O8vHY.js.map} +1 -1
- package/extensions/dashboard-client/dist/index.html +1 -1
- package/extensions/dashboard-server/api-contracts/dedup-attribution.ts +69 -0
- package/extensions/dashboard-server/api-contracts/endpoints/registry-ext.ts +15 -0
- package/extensions/dashboard-server/api-contracts/index.ts +8 -0
- package/extensions/dashboard-server/route-dispatch.ts +2 -0
- package/extensions/dashboard-server/routes-dedup-attribution.ts +166 -0
- package/extensions/dashboard-server/routes-rag-settings-vector-cortex.ts +12 -0
- package/extensions/dashboard-server/routes.ts +1 -0
- package/package.json +1 -1
- package/src/config/vector-cortex-dedup-attr.ts +16 -0
- package/src/config/vector-cortex-ml5e.ts +32 -0
- package/src/config/vector-cortex.ts +5 -5
- package/src/config.ts +2 -0
- package/src/vector-cortex/dedup-attr/rollup.ts +136 -0
- package/src/vector-cortex/encoder/promotion.ts +129 -0
- package/extensions/dashboard-client/dist/assets/index-DY81TY4f.js.map +0 -1
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* config/vector-cortex-dedup-attr.ts — DEDUP-ATTR tier-attribution flag.
|
|
3
|
+
*
|
|
4
|
+
* The single positive sprint flag for the dedup tier-attribution rollup
|
|
5
|
+
* (external-audit item #6). Default ON; `MEGACOMPACT_DEDUP_ATTR=0` / `=false` /
|
|
6
|
+
* `_DISABLED=true` disables and is byte-identical to the predecessor: the
|
|
7
|
+
* `/api/dedup-tier-attribution` endpoint 404s and no rollup cache file is
|
|
8
|
+
* written.
|
|
9
|
+
*
|
|
10
|
+
* Pi-agnostic, dependency-free (PREVENT-PI-004 / PREVENT-011).
|
|
11
|
+
*/
|
|
12
|
+
import { sprintFlag } from "./vector-cortex-flag.js";
|
|
13
|
+
/** Positive sprint flag: `=0` or `_DISABLED=true` disables (default ON). */
|
|
14
|
+
export const DEDUP_ATTR_ENABLED = () => sprintFlag("MEGACOMPACT_DEDUP_ATTR");
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* config/vector-cortex-ml5e.ts — ML5-E nightly retraining cron + feedback loop.
|
|
3
|
+
*
|
|
4
|
+
* Sibling extract mirroring vector-cortex-ml5a.ts / ml5b.ts / ml5c.ts / ml5d.ts,
|
|
5
|
+
* so vector-cortex.ts stays under its 300-line soft limit (soft-as-hard gate).
|
|
6
|
+
* vector-cortex.ts re-exports the ENUM below and root src/config.ts re-exports
|
|
7
|
+
* it, so no consumer import path changes.
|
|
8
|
+
*
|
|
9
|
+
* ML5-E turns one-shot training (ML5-D's Improve button) into a living loop:
|
|
10
|
+
* the user's own post-redaction conversation turns become fresh training signal,
|
|
11
|
+
* the five heads are re-fit nightly, calibration is re-validated, and mode-A
|
|
12
|
+
* promotion is re-checked without human intervention. The cron is system-
|
|
13
|
+
* configured (`crontab -e` on the operator device); the extension never installs
|
|
14
|
+
* or writes a crontab. The flag gates **invocation** only — the scripts
|
|
15
|
+
* (retrain-nightly.mjs, promotion-gate.mjs, promotion.ts) exist on disk
|
|
16
|
+
* regardless; `=0` means the runtime never invokes them and the dashboard's
|
|
17
|
+
* Improve Cortex flow is byte-identical to the ML5-D survivor.
|
|
18
|
+
*
|
|
19
|
+
* Pi-agnostic, dependency-free (PREVENT-PI-004 / PREVENT-011).
|
|
20
|
+
*/
|
|
21
|
+
import { sprintFlag } from "./vector-cortex-flag.js";
|
|
22
|
+
/**
|
|
23
|
+
* ML5-E — nightly retraining cron + feedback loop. Default ON.
|
|
24
|
+
* `MEGACOMPACT_ML5_E=0` disables and is byte-identical to the ML5-D survivor:
|
|
25
|
+
* the nightly retraining scripts are never invoked by the runtime, the
|
|
26
|
+
* promotion gate is inert, and the dashboard's Improve Cortex flow is
|
|
27
|
+
* byte-identical to the ML5-D tab. The flag gates invocation only — the scripts
|
|
28
|
+
* exist on disk regardless.
|
|
29
|
+
*/
|
|
30
|
+
export const ML5E_ENABLED = () => sprintFlag("MEGACOMPACT_ML5_E");
|
|
@@ -9,9 +9,8 @@
|
|
|
9
9
|
* them without re-declaring the ownership boundary. Pi-agnostic, dependency-free.
|
|
10
10
|
*/
|
|
11
11
|
import { sprintFlag } from "./vector-cortex-flag.js";
|
|
12
|
-
// VC0/VC1/VC2 foundation-phase flags
|
|
13
|
-
//
|
|
14
|
-
// `from "./config/vector-cortex.js"` import keeps resolving unchanged.
|
|
12
|
+
// VC0/VC1/VC2 foundation-phase flags in vector-cortex-early.ts; re-exported
|
|
13
|
+
// so every existing `from "./config/vector-cortex.js"` import resolves unchanged.
|
|
15
14
|
export { VC0A_ENABLED, VC0B_ENABLED, VC0C_ENABLED, VC1A_ENABLED, VC1B_ENABLED, VC1C_ENABLED, VC2A_ENABLED, VC2B_ENABLED, VC2C_ENABLED, } from "./vector-cortex-early.js";
|
|
16
15
|
/**
|
|
17
16
|
* VC3A — capability-gated cortex store (CortexReader/Writer/Admin, CortexRecordV1).
|
|
@@ -239,9 +238,8 @@ export const VC8A_ENABLED = () => sprintFlag("MEGACOMPACT_VC8A");
|
|
|
239
238
|
* mirroring VC4A..VC8A.
|
|
240
239
|
*/
|
|
241
240
|
export const VC8B_ENABLED = () => sprintFlag("MEGACOMPACT_VC8B");
|
|
242
|
-
// VC8C
|
|
241
|
+
// VC8C extracted to vector-cortex-vc8c.ts; re-exported so existing imports keep resolving.
|
|
243
242
|
export { VC8C_ENABLED } from "./vector-cortex-vc8c.js";
|
|
244
|
-
// Sibling extracts to stay under the 300-line soft limit.
|
|
245
243
|
export { VC9A_ENABLED } from "./vector-cortex-vc9a.js";
|
|
246
244
|
export { VC9B_ENABLED } from "./vector-cortex-vc9b.js";
|
|
247
245
|
export { VC9C_ENABLED } from "./vector-cortex-vc9c.js";
|
|
@@ -251,5 +249,7 @@ export { ML5A_ENABLED } from "./vector-cortex-ml5a.js";
|
|
|
251
249
|
export { ML5B_ENABLED } from "./vector-cortex-ml5b.js";
|
|
252
250
|
export { ML5C_ENABLED } from "./vector-cortex-ml5c.js";
|
|
253
251
|
export { ML5D_ENABLED } from "./vector-cortex-ml5d.js";
|
|
252
|
+
export { ML5E_ENABLED } from "./vector-cortex-ml5e.js";
|
|
253
|
+
export { DEDUP_ATTR_ENABLED } from "./vector-cortex-dedup-attr.js";
|
|
254
254
|
// Breaker constants (TRIAD_RESILIENCE.md §breaker) extracted to vector-cortex-breakers.ts.
|
|
255
255
|
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, VC9B_ENABLED, VC9C_ENABLED, VC9D_ENABLED, PCC_ENABLED, ML5A_ENABLED, ML5B_ENABLED, ML5C_ENABLED, ML5D_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, VC9D_ENABLED, PCC_ENABLED, ML5A_ENABLED, ML5B_ENABLED, ML5C_ENABLED, ML5D_ENABLED, ML5E_ENABLED, DEDUP_ATTR_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";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* api-contracts/dedup-attribution.ts — Dedup tier-attribution rollup types (DEDUP-ATTR).
|
|
3
|
+
*
|
|
4
|
+
* Types for GET /api/dedup-tier-attribution — the reader-only aggregate that
|
|
5
|
+
* answers "L0/L1/L2/new percent of dedup decisions in window W". Inputs are the
|
|
6
|
+
* produced `dedup_audit` events in the local events.log (shape DedupAuditEvent
|
|
7
|
+
* in src/vectorStore/dedup-audit.ts). Outputs are counts + shares only — never
|
|
8
|
+
* matched checkpoint paths/text, never raw user query (EVAL-REDACT-002).
|
|
9
|
+
*
|
|
10
|
+
* PREVENT-PI-004: type definitions only, no network code.
|
|
11
|
+
* PREVENT-011: no `any` type — all types are explicit.
|
|
12
|
+
*/
|
|
13
|
+
export {};
|
|
@@ -67,4 +67,11 @@ export const EXTRA_ENDPOINTS = {
|
|
|
67
67
|
path: "/api/cortex/improve/status/:jobId",
|
|
68
68
|
description: "Poll an in-process Cortex improve job to terminal qualified / demoted_to_B. Unknown jobId or flag-off returns 404. Read-only, in-memory job state.",
|
|
69
69
|
},
|
|
70
|
+
// ─── DEDUP-ATTR tier-attribution rollup ───────────────────────────
|
|
71
|
+
/** GET /api/dedup-tier-attribution — reader-only per-tier dedup shares. */
|
|
72
|
+
dedupTierAttribution: {
|
|
73
|
+
method: "GET",
|
|
74
|
+
path: "/api/dedup-tier-attribution",
|
|
75
|
+
description: "Reader-only dedup tier-attribution rollup (DEDUP-ATTR): L0/L1/L2/new percent of dedup decisions in a query window (default 24h, ?windowMs=, capped 30d). Counts + shares only, never matched checkpoint contents or raw query text. Flag-off returns 404.",
|
|
76
|
+
},
|
|
70
77
|
};
|
|
@@ -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, handlePrefixStability, 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, handleImproveCortex, handleImproveCortexStatus, } from "./routes.js";
|
|
11
|
+
import { handleIndex, handleRepoIndex, handleEvents, handleGameState, handleGameScores, handlePerfSamples, handlePerf, handleAchievements, handleSessions, handleTopics, handleTurns, handleMaintenance, handleProviderCache, handleMemoryStatus, handleCacheStripes, handlePrefixStability, 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, handleImproveCortex, handleImproveCortexStatus, handleDedupTierAttribution, } 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";
|
|
@@ -153,5 +153,7 @@ export function dispatchRoutes(req, res, ctx) {
|
|
|
153
153
|
return true;
|
|
154
154
|
if (handleImproveCortexStatus(req, res, ctx))
|
|
155
155
|
return true;
|
|
156
|
+
if (handleDedupTierAttribution(req, res, ctx))
|
|
157
|
+
return true;
|
|
156
158
|
return false;
|
|
157
159
|
}
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* dashboard-server/routes-dedup-attribution.ts — DEDUP-ATTR tier attribution route.
|
|
3
|
+
*
|
|
4
|
+
* GET /api/dedup-tier-attribution?windowMs=<n> — reader-only aggregate answering
|
|
5
|
+
* "L0/L1/L2/new percent of dedup decisions in window W". Reads the repo's local
|
|
6
|
+
* events.log (per-repo stateDir, bounded 8 MiB tail), parses `dedup_audit` lines
|
|
7
|
+
* (PREVENT-001 guarded), and sends the pure rollup with a shared-derived status.
|
|
8
|
+
*
|
|
9
|
+
* Flag-off (MEGACOMPACT_DEDUP_ATTR=0) returns 404 and writes NO durable cache
|
|
10
|
+
* file — byte-identical predecessor. Reader-only: emits tier counts + shares,
|
|
11
|
+
* never matched checkpoint paths/text, never raw user query (EVAL-REDACT-002).
|
|
12
|
+
*
|
|
13
|
+
* Memoization mirrors routes-vector-cortex-health.ts: an in-memory facts cache
|
|
14
|
+
* keyed on {events.log mtime+size, windowMs} is served when ≤5s old, so repeated
|
|
15
|
+
* dashboard polls stay cheap while any on-disk log mutation still invalidates.
|
|
16
|
+
*
|
|
17
|
+
* Guardrails: PREVENT-PI-004 (local filesystem read + loopback response only),
|
|
18
|
+
* PREVENT-001 (JSON.parse guarded), PREVENT-011 (no `any`).
|
|
19
|
+
*/
|
|
20
|
+
import { readFileSync, statSync, writeFileSync, mkdirSync } from "node:fs";
|
|
21
|
+
import { join, dirname } from "node:path";
|
|
22
|
+
import { sendJson } from "./routes-vector-cortex-shared.js";
|
|
23
|
+
import { DEDUP_ATTR_ENABLED } from "../../src/config.js";
|
|
24
|
+
import { computeDedupTierRollup } from "../../src/vector-cortex/dedup-attr/rollup.js";
|
|
25
|
+
import { deriveVcStatus } from "./vc-status.js";
|
|
26
|
+
const DEFAULT_WINDOW_MS = 24 * 60 * 60 * 1000; // 24h
|
|
27
|
+
const MAX_WINDOW_MS = 30 * 24 * 60 * 60 * 1000; // 30 days
|
|
28
|
+
const MAX_TAIL_BYTES = 8 * 1024 * 1024; // 8 MiB
|
|
29
|
+
const MEMO_TTL_MS = 5000; // ≤5s per stateDir
|
|
30
|
+
let memo = null;
|
|
31
|
+
/** Parse one events.log line into a DedupAuditEvent, or null (PREVENT-001). */
|
|
32
|
+
function parseAuditLine(line) {
|
|
33
|
+
if (!line.includes('"dedup_audit"'))
|
|
34
|
+
return null;
|
|
35
|
+
let parsed;
|
|
36
|
+
try {
|
|
37
|
+
parsed = JSON.parse(line);
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
43
|
+
return null;
|
|
44
|
+
const obj = parsed;
|
|
45
|
+
if (obj.type !== "dedup_audit")
|
|
46
|
+
return null;
|
|
47
|
+
if (typeof obj.ts !== "string")
|
|
48
|
+
return null;
|
|
49
|
+
const tier = obj.tier;
|
|
50
|
+
const status = obj.status;
|
|
51
|
+
if (tier !== "L0" && tier !== "L1" && tier !== "L2" && tier !== "new")
|
|
52
|
+
return null;
|
|
53
|
+
if (status !== "deduped" && status !== "passed" && status !== "stored")
|
|
54
|
+
return null;
|
|
55
|
+
// sessionId is never read by the rollup; a parsed line may omit richer fields.
|
|
56
|
+
return { type: "dedup_audit", ts: obj.ts, tier, status, sessionId: "" };
|
|
57
|
+
}
|
|
58
|
+
/** Read the bounded tail of events.log into parsed dedup_audit events. */
|
|
59
|
+
function readAuditEvents(eventsPath) {
|
|
60
|
+
let buf;
|
|
61
|
+
try {
|
|
62
|
+
buf = readFileSync(eventsPath); // guardrails-allow PREVENT-PI-004: local events.log read (loopback dashboard)
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return [];
|
|
66
|
+
}
|
|
67
|
+
const tail = buf.length > MAX_TAIL_BYTES ? buf.subarray(buf.length - MAX_TAIL_BYTES) : buf;
|
|
68
|
+
const text = tail.toString("utf-8");
|
|
69
|
+
const lines = text.split("\n");
|
|
70
|
+
// Drop a leading fragment when we truncated mid-line (first line may be partial).
|
|
71
|
+
const start = buf.length > MAX_TAIL_BYTES ? 1 : 0;
|
|
72
|
+
const out = [];
|
|
73
|
+
for (let i = start; i < lines.length; i++) {
|
|
74
|
+
const line = lines[i];
|
|
75
|
+
if (!line)
|
|
76
|
+
continue;
|
|
77
|
+
const ev = parseAuditLine(line);
|
|
78
|
+
if (ev)
|
|
79
|
+
out.push(ev);
|
|
80
|
+
}
|
|
81
|
+
return out;
|
|
82
|
+
}
|
|
83
|
+
/** Resolve windowMs from the ?windowMs= query param (default 24h, capped 30d). */
|
|
84
|
+
function resolveWindowMs(url) {
|
|
85
|
+
if (!url.includes("?"))
|
|
86
|
+
return DEFAULT_WINDOW_MS;
|
|
87
|
+
const params = new URLSearchParams(url.slice(url.indexOf("?")));
|
|
88
|
+
const raw = params.get("windowMs");
|
|
89
|
+
if (raw == null)
|
|
90
|
+
return DEFAULT_WINDOW_MS;
|
|
91
|
+
const n = Number(raw);
|
|
92
|
+
if (!Number.isFinite(n) || n <= 0)
|
|
93
|
+
return DEFAULT_WINDOW_MS;
|
|
94
|
+
return Math.min(n, MAX_WINDOW_MS);
|
|
95
|
+
}
|
|
96
|
+
/** Best-effort durable snapshot write (never breaks the response). */
|
|
97
|
+
function writeDurableSnapshot(stateDir, rollup) {
|
|
98
|
+
try {
|
|
99
|
+
mkdirSync(dirname(join(stateDir, "dedup-tier-attribution.json")), { recursive: true });
|
|
100
|
+
writeFileSync(join(stateDir, "dedup-tier-attribution.json"), `${JSON.stringify(rollup)}\n`, "utf-8");
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
/* best-effort — instrumentation must never break the read path */
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
export function handleDedupTierAttribution(req, res, ctx) {
|
|
107
|
+
const url = req.url ?? "";
|
|
108
|
+
const path = url.split("?", 1)[0] ?? url;
|
|
109
|
+
if (path !== "/api/dedup-tier-attribution")
|
|
110
|
+
return false;
|
|
111
|
+
if (req.method !== "GET") {
|
|
112
|
+
sendJson(res, 405, { error: "method_not_allowed" });
|
|
113
|
+
return true;
|
|
114
|
+
}
|
|
115
|
+
if (!DEDUP_ATTR_ENABLED()) {
|
|
116
|
+
// Flag-off: 404 + no durable cache write — byte-identical predecessor.
|
|
117
|
+
sendJson(res, 404, { error: "not_found" });
|
|
118
|
+
return true;
|
|
119
|
+
}
|
|
120
|
+
const eventsPath = ctx.eventsPath;
|
|
121
|
+
const windowMs = resolveWindowMs(url);
|
|
122
|
+
const now = new Date();
|
|
123
|
+
// Memoized-facts pattern (mirrors routes-vector-cortex-health.ts): serve a
|
|
124
|
+
// still-fresh entry keyed on {events.log mtime+size, windowMs}.
|
|
125
|
+
let keyBase = null;
|
|
126
|
+
try {
|
|
127
|
+
const s = statSync(eventsPath); // guardrails-allow PREVENT-PI-004: local events.log stat (loopback)
|
|
128
|
+
keyBase = { mtimeMs: s.mtimeMs, size: s.size };
|
|
129
|
+
}
|
|
130
|
+
catch {
|
|
131
|
+
keyBase = { mtimeMs: 0, size: 0 };
|
|
132
|
+
}
|
|
133
|
+
const key = `${keyBase.mtimeMs}:${keyBase.size}:${windowMs}`;
|
|
134
|
+
if (memo !== null && memo.key === key && now.getTime() - memo.at <= MEMO_TTL_MS) {
|
|
135
|
+
sendJson(res, 200, memo.body);
|
|
136
|
+
return true;
|
|
137
|
+
}
|
|
138
|
+
const auditEvents = readAuditEvents(eventsPath);
|
|
139
|
+
const rollup = computeDedupTierRollup(auditEvents, windowMs, now);
|
|
140
|
+
const status = deriveVcStatus({
|
|
141
|
+
enabled: true,
|
|
142
|
+
hasData: auditEvents.length > 0,
|
|
143
|
+
structuralOnly: false,
|
|
144
|
+
});
|
|
145
|
+
const body = { ...rollup, status };
|
|
146
|
+
memo = { key, at: now.getTime(), body };
|
|
147
|
+
writeDurableSnapshot(ctx.stateDir, body);
|
|
148
|
+
sendJson(res, 200, body);
|
|
149
|
+
return true;
|
|
150
|
+
}
|
|
@@ -56,5 +56,7 @@ export const VECTOR_CORTEX_SETTINGS = {
|
|
|
56
56
|
boolDirect("MEGACOMPACT_ML5_A", "ML5-A Five-Head Training Load", "ML5-A real trained-head loading: loadHeadProjections (trained-heads-v1) feeds selectQualifiedEncoder (trainedHeadsPath atomic demotion) + loadCalibrationV1. ON (default) = a pinned trained-heads path must load for mode A. OFF = loaders return null and selection ignores trainedHeadsPath — byte-identical to the placeholder-weighted VC2C path.", true),
|
|
57
57
|
boolDirect("MEGACOMPACT_ML5_C", "ML5-C Runtime Decision + Packaging", "ML5-C runtime backend selection (WASM vs native): selects the ONNX runtime backend based on the ML5-B bench record and platform support. ON (default) = the runtime-selection dispatch runs and emits vector_cortex_runtime_selected. OFF = no selection runs — encoder serves mode B trigram, byte-identical to ML5-B.", true),
|
|
58
58
|
boolDirect("MEGACOMPACT_ML5_D", "ML5-D Dashboard Improve Cortex", "ML5-D dashboard 'Improve Cortex' surface: the ModelImprovementCard + POST /api/cortex/improve + GET /api/cortex/improve/status/:jobId. ON (default) = the card renders and Improve launches a local ML5-A training job. OFF = both improve endpoints return 404 and VectorCortexTab omits the card, byte-identical to ML5-C.", true),
|
|
59
|
+
boolDirect("MEGACOMPACT_ML5_E", "ML5-E Nightly Retraining Cron", "ML5-E nightly retraining + feedback loop: the user's own post-redaction conversation turns become fresh training signal, the five heads are re-fit nightly via system cron, calibration is re-validated, and mode-A promotion is re-checked without human intervention. The cron is system-configured (crontab -e); the extension never installs or writes a crontab. Candidates are written to ~/.pi/mega-compact-encoder/candidates/ and promoted via the ML5-D Improve Cortex flow. ON (default) = the scripts may be invoked by the system cron. OFF = scripts are never invoked; byte-identical to ML5-D.", true),
|
|
60
|
+
boolDirect("MEGACOMPACT_DEDUP_ATTR", "Dedup Tier Attribution Rollup", "Dedup tier-attribution rollup: per-tier dedup catch shares (L0/L1/L2/new percent of dedup decisions) read from the local events.log dedup_audit stream (GET /api/dedup-tier-attribution). OFF = 404 + no cache file, byte-identical predecessor.", true),
|
|
59
61
|
],
|
|
60
62
|
};
|
|
@@ -28,3 +28,4 @@ export { handleVectorCortexEvaluation, handleVectorCortexHealth, handleVectorCor
|
|
|
28
28
|
export { handleSetupCortexStatus } from "./routes-setup-cortex.js";
|
|
29
29
|
export { handleSetupCortexAction, handleSetupCortexActionLog, } from "./routes-setup-cortex-actions.js";
|
|
30
30
|
export { handleImproveCortex, handleImproveCortexStatus, } from "./routes-cortex-improve.js";
|
|
31
|
+
export { handleDedupTierAttribution } from "./routes-dedup-attribution.js";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* config/vector-cortex-dedup-attr.ts — DEDUP-ATTR tier-attribution flag.
|
|
3
|
+
*
|
|
4
|
+
* The single positive sprint flag for the dedup tier-attribution rollup
|
|
5
|
+
* (external-audit item #6). Default ON; `MEGACOMPACT_DEDUP_ATTR=0` / `=false` /
|
|
6
|
+
* `_DISABLED=true` disables and is byte-identical to the predecessor: the
|
|
7
|
+
* `/api/dedup-tier-attribution` endpoint 404s and no rollup cache file is
|
|
8
|
+
* written.
|
|
9
|
+
*
|
|
10
|
+
* Pi-agnostic, dependency-free (PREVENT-PI-004 / PREVENT-011).
|
|
11
|
+
*/
|
|
12
|
+
import { sprintFlag } from "./vector-cortex-flag.js";
|
|
13
|
+
/** Positive sprint flag: `=0` or `_DISABLED=true` disables (default ON). */
|
|
14
|
+
export const DEDUP_ATTR_ENABLED = () => sprintFlag("MEGACOMPACT_DEDUP_ATTR");
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* config/vector-cortex-ml5e.ts — ML5-E nightly retraining cron + feedback loop.
|
|
3
|
+
*
|
|
4
|
+
* Sibling extract mirroring vector-cortex-ml5a.ts / ml5b.ts / ml5c.ts / ml5d.ts,
|
|
5
|
+
* so vector-cortex.ts stays under its 300-line soft limit (soft-as-hard gate).
|
|
6
|
+
* vector-cortex.ts re-exports the ENUM below and root src/config.ts re-exports
|
|
7
|
+
* it, so no consumer import path changes.
|
|
8
|
+
*
|
|
9
|
+
* ML5-E turns one-shot training (ML5-D's Improve button) into a living loop:
|
|
10
|
+
* the user's own post-redaction conversation turns become fresh training signal,
|
|
11
|
+
* the five heads are re-fit nightly, calibration is re-validated, and mode-A
|
|
12
|
+
* promotion is re-checked without human intervention. The cron is system-
|
|
13
|
+
* configured (`crontab -e` on the operator device); the extension never installs
|
|
14
|
+
* or writes a crontab. The flag gates **invocation** only — the scripts
|
|
15
|
+
* (retrain-nightly.mjs, promotion-gate.mjs, promotion.ts) exist on disk
|
|
16
|
+
* regardless; `=0` means the runtime never invokes them and the dashboard's
|
|
17
|
+
* Improve Cortex flow is byte-identical to the ML5-D survivor.
|
|
18
|
+
*
|
|
19
|
+
* Pi-agnostic, dependency-free (PREVENT-PI-004 / PREVENT-011).
|
|
20
|
+
*/
|
|
21
|
+
import { sprintFlag } from "./vector-cortex-flag.js";
|
|
22
|
+
/**
|
|
23
|
+
* ML5-E — nightly retraining cron + feedback loop. Default ON.
|
|
24
|
+
* `MEGACOMPACT_ML5_E=0` disables and is byte-identical to the ML5-D survivor:
|
|
25
|
+
* the nightly retraining scripts are never invoked by the runtime, the
|
|
26
|
+
* promotion gate is inert, and the dashboard's Improve Cortex flow is
|
|
27
|
+
* byte-identical to the ML5-D tab. The flag gates invocation only — the scripts
|
|
28
|
+
* exist on disk regardless.
|
|
29
|
+
*/
|
|
30
|
+
export const ML5E_ENABLED = () => sprintFlag("MEGACOMPACT_ML5_E");
|
|
@@ -9,9 +9,8 @@
|
|
|
9
9
|
* them without re-declaring the ownership boundary. Pi-agnostic, dependency-free.
|
|
10
10
|
*/
|
|
11
11
|
import { sprintFlag } from "./vector-cortex-flag.js";
|
|
12
|
-
// VC0/VC1/VC2 foundation-phase flags
|
|
13
|
-
//
|
|
14
|
-
// `from "./config/vector-cortex.js"` import keeps resolving unchanged.
|
|
12
|
+
// VC0/VC1/VC2 foundation-phase flags in vector-cortex-early.ts; re-exported
|
|
13
|
+
// so every existing `from "./config/vector-cortex.js"` import resolves unchanged.
|
|
15
14
|
export { VC0A_ENABLED, VC0B_ENABLED, VC0C_ENABLED, VC1A_ENABLED, VC1B_ENABLED, VC1C_ENABLED, VC2A_ENABLED, VC2B_ENABLED, VC2C_ENABLED, } from "./vector-cortex-early.js";
|
|
16
15
|
/**
|
|
17
16
|
* VC3A — capability-gated cortex store (CortexReader/Writer/Admin, CortexRecordV1).
|
|
@@ -239,9 +238,8 @@ export const VC8A_ENABLED = () => sprintFlag("MEGACOMPACT_VC8A");
|
|
|
239
238
|
* mirroring VC4A..VC8A.
|
|
240
239
|
*/
|
|
241
240
|
export const VC8B_ENABLED = () => sprintFlag("MEGACOMPACT_VC8B");
|
|
242
|
-
// VC8C
|
|
241
|
+
// VC8C extracted to vector-cortex-vc8c.ts; re-exported so existing imports keep resolving.
|
|
243
242
|
export { VC8C_ENABLED } from "./vector-cortex-vc8c.js";
|
|
244
|
-
// Sibling extracts to stay under the 300-line soft limit.
|
|
245
243
|
export { VC9A_ENABLED } from "./vector-cortex-vc9a.js";
|
|
246
244
|
export { VC9B_ENABLED } from "./vector-cortex-vc9b.js";
|
|
247
245
|
export { VC9C_ENABLED } from "./vector-cortex-vc9c.js";
|
|
@@ -251,5 +249,7 @@ export { ML5A_ENABLED } from "./vector-cortex-ml5a.js";
|
|
|
251
249
|
export { ML5B_ENABLED } from "./vector-cortex-ml5b.js";
|
|
252
250
|
export { ML5C_ENABLED } from "./vector-cortex-ml5c.js";
|
|
253
251
|
export { ML5D_ENABLED } from "./vector-cortex-ml5d.js";
|
|
252
|
+
export { ML5E_ENABLED } from "./vector-cortex-ml5e.js";
|
|
253
|
+
export { DEDUP_ATTR_ENABLED } from "./vector-cortex-dedup-attr.js";
|
|
254
254
|
// Breaker constants (TRIAD_RESILIENCE.md §breaker) extracted to vector-cortex-breakers.ts.
|
|
255
255
|
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/src/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, VC9B_ENABLED, VC9C_ENABLED, VC9D_ENABLED, PCC_ENABLED, ML5A_ENABLED, ML5B_ENABLED, ML5C_ENABLED, ML5D_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, VC9D_ENABLED, PCC_ENABLED, ML5A_ENABLED, ML5B_ENABLED, ML5C_ENABLED, ML5D_ENABLED, ML5E_ENABLED, DEDUP_ATTR_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";
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vector-cortex/dedup-attr/rollup.ts — DEDUP-ATTR pure tier-attribution rollup.
|
|
3
|
+
*
|
|
4
|
+
* Pure function: reads an array of parsed dedup-audit events, buckets them by
|
|
5
|
+
* tier over a query window, and returns the per-tier catch shares. No I/O, no
|
|
6
|
+
* clock — the route passes `now: Date` (new Date()) at request time, so this
|
|
7
|
+
* module is deterministically reproducible and trivially testable (DEDUP-ATTR-004).
|
|
8
|
+
*
|
|
9
|
+
* Missing `similarity` is fine here: L0/L1 are hash/verify tiers and emit no
|
|
10
|
+
* score, and the rollup never consults it. Malformed lines (non-object, wrong
|
|
11
|
+
* type) are skipped silently — the route's events.log reader already guards its
|
|
12
|
+
* JSON.parse (PREVENT-001), and this layer defends against a hostile/mixed
|
|
13
|
+
* `dedup_audit` array as well.
|
|
14
|
+
*
|
|
15
|
+
* The returned shape is structurally identical to the authoritative contract in
|
|
16
|
+
* `extensions/dashboard-server/api-contracts/dedup-attribution.ts` (the existing
|
|
17
|
+
* src-mirrors-dashboard-contract pattern); src/ stays pi-agnostic and never
|
|
18
|
+
* imports dashboard types. Status here is computed from the pure signal the
|
|
19
|
+
* rollup owns (a non-empty window) — the route additionally derives the sent
|
|
20
|
+
* `status` via `deriveVcStatus` from the shared vc-status module.
|
|
21
|
+
*
|
|
22
|
+
* Guardrails: PREVENT-PI-004 (zero I/O/network), PREVENT-011 (no `any`).
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* Roll up dedup-audit events over [now - windowMs, now] into per-tier shares.
|
|
26
|
+
*
|
|
27
|
+
* Only events whose ISO-8601 `ts` falls inside the window are counted; events of
|
|
28
|
+
* any other `type` (or a missing/unparseable `ts`) are skipped silently. Shares
|
|
29
|
+
* are fractions of the window's total decisions, each in [0, 1]; an empty window
|
|
30
|
+
* yields all-zero shares with `status:"awaiting_data"` — never a fabricated
|
|
31
|
+
* zero-share table presented as real.
|
|
32
|
+
*/
|
|
33
|
+
export function computeDedupTierRollup(events, windowMs, now) {
|
|
34
|
+
const winMs = windowMs > 0 ? windowMs : 24 * 60 * 60 * 1000;
|
|
35
|
+
const windowStart = now.getTime() - winMs;
|
|
36
|
+
const windowEnd = now.getTime();
|
|
37
|
+
const acc = {
|
|
38
|
+
l0: { deduped: 0, passed: 0 },
|
|
39
|
+
l1: { deduped: 0, passed: 0 },
|
|
40
|
+
l2: { deduped: 0, passed: 0 },
|
|
41
|
+
storedNew: 0,
|
|
42
|
+
};
|
|
43
|
+
let total = 0;
|
|
44
|
+
for (const ev of events) {
|
|
45
|
+
if (!ev || typeof ev !== "object")
|
|
46
|
+
continue;
|
|
47
|
+
if (ev.type !== "dedup_audit")
|
|
48
|
+
continue;
|
|
49
|
+
const ts = Date.parse(ev.ts);
|
|
50
|
+
if (Number.isNaN(ts) || ts < windowStart || ts > windowEnd)
|
|
51
|
+
continue;
|
|
52
|
+
total += 1;
|
|
53
|
+
switch (ev.tier) {
|
|
54
|
+
case "L0":
|
|
55
|
+
if (ev.status === "deduped")
|
|
56
|
+
acc.l0.deduped += 1;
|
|
57
|
+
else if (ev.status === "passed")
|
|
58
|
+
acc.l0.passed += 1;
|
|
59
|
+
break;
|
|
60
|
+
case "L1":
|
|
61
|
+
if (ev.status === "deduped")
|
|
62
|
+
acc.l1.deduped += 1;
|
|
63
|
+
else if (ev.status === "passed")
|
|
64
|
+
acc.l1.passed += 1;
|
|
65
|
+
break;
|
|
66
|
+
case "L2":
|
|
67
|
+
if (ev.status === "deduped")
|
|
68
|
+
acc.l2.deduped += 1;
|
|
69
|
+
else if (ev.status === "passed")
|
|
70
|
+
acc.l2.passed += 1;
|
|
71
|
+
break;
|
|
72
|
+
case "new":
|
|
73
|
+
acc.storedNew += 1;
|
|
74
|
+
break;
|
|
75
|
+
default:
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const byTier = {
|
|
80
|
+
l0: { deduped: acc.l0.deduped, passed: acc.l0.passed },
|
|
81
|
+
l1: { deduped: acc.l1.deduped, passed: acc.l1.passed },
|
|
82
|
+
l2: { deduped: acc.l2.deduped, passed: acc.l2.passed },
|
|
83
|
+
new: acc.storedNew,
|
|
84
|
+
};
|
|
85
|
+
const shareOf = (n) => (total > 0 ? n / total : 0);
|
|
86
|
+
return {
|
|
87
|
+
schema: "dedup-tier-rollup-v1",
|
|
88
|
+
windowStart: new Date(windowStart).toISOString(),
|
|
89
|
+
windowEnd: now.toISOString(),
|
|
90
|
+
totalDecisions: total,
|
|
91
|
+
byTier,
|
|
92
|
+
l0Share: shareOf(acc.l0.deduped + acc.l0.passed),
|
|
93
|
+
l1Share: shareOf(acc.l1.deduped + acc.l1.passed),
|
|
94
|
+
l2Share: shareOf(acc.l2.deduped + acc.l2.passed),
|
|
95
|
+
status: total > 0 ? "live" : "awaiting_data",
|
|
96
|
+
};
|
|
97
|
+
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vector-cortex/encoder/promotion.ts — ML5-E PromotionV1 ledger row type +
|
|
3
|
+
* append-only manifest helper + atomic digest-swap rollback.
|
|
4
|
+
*
|
|
5
|
+
* Pure-function discipline: zero I/O, no clock, no storage, no network
|
|
6
|
+
* (PREVENT-PI-004 / PREVENT-011). Every function is total over its inputs.
|
|
7
|
+
* The cron orchestrator (scripts/ml5/retrain-nightly.mjs) and the promotion
|
|
8
|
+
* gate (scripts/ml5/promotion-gate.mjs) consume these helpers; the acceptance
|
|
9
|
+
* aggregator (ml5e-acceptance.test.ts) validates them synthetically without a
|
|
10
|
+
* real training run.
|
|
11
|
+
*
|
|
12
|
+
* The promotion manifest is an APPEND-ONLY ledger: every new asset is a new
|
|
13
|
+
* entry, never an overwrite. Rollback restores a prior entry by SHA-256 via
|
|
14
|
+
* an atomic digest swap (flip the committed pointer to the prior entry's
|
|
15
|
+
* digest in one step) — no partial state is possible because the swap is a
|
|
16
|
+
* single value assignment.
|
|
17
|
+
*/
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// PromotionV1 — the ledger row recording one nightly training + promotion run.
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
/** Schema tag for the promotion ledger row. */
|
|
22
|
+
export const PROMOTION_SCHEMA = "promotion-v1";
|
|
23
|
+
/** Append a new asset entry to the manifest. Never mutates `entries`;
|
|
24
|
+
* returns a new manifest with the entry appended and `committed` updated. */
|
|
25
|
+
export function appendAsset(manifest, entry) {
|
|
26
|
+
return {
|
|
27
|
+
entries: [...manifest.entries, entry],
|
|
28
|
+
committed: entry.assetDigest,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
/** Restore a prior asset by SHA-256: atomically swap the committed pointer
|
|
32
|
+
* to the prior entry. The prior entry MUST exist in the manifest (append-only
|
|
33
|
+
* guarantees it was never overwritten). Returns null when the digest is not
|
|
34
|
+
* found (defensive: append-only means it should always be findable). */
|
|
35
|
+
export function rollbackTo(manifest, digest) {
|
|
36
|
+
const found = manifest.entries.find((e) => e.assetDigest === digest);
|
|
37
|
+
if (!found)
|
|
38
|
+
return null;
|
|
39
|
+
return {
|
|
40
|
+
entries: manifest.entries,
|
|
41
|
+
committed: found.assetDigest,
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
// ---------------------------------------------------------------------------
|
|
45
|
+
// Pure decision rules.
|
|
46
|
+
// ---------------------------------------------------------------------------
|
|
47
|
+
/** Evaluate the promotion gate: promote only when all five heads pass AND the
|
|
48
|
+
* new asset beats the committed asset on the held-out dev set. Otherwise
|
|
49
|
+
* demote. No training data is ever the held-out set. */
|
|
50
|
+
export function promoteDecision(fiveHeadsOk, heldOutBeat) {
|
|
51
|
+
return fiveHeadsOk && heldOutBeat ? "promoted" : "demoted";
|
|
52
|
+
}
|
|
53
|
+
/** Whether a rollback is needed: the current asset at position N regressed
|
|
54
|
+
* relative to the asset at position N-1. True only when regression is
|
|
55
|
+
* confirmed and a prior asset digest exists to restore. */
|
|
56
|
+
export function rollbackNeeded(regressionConfirmed, priorAssetDigest) {
|
|
57
|
+
return regressionConfirmed && priorAssetDigest !== null;
|
|
58
|
+
}
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* vector-cortex/dedup-attr/rollup.ts — DEDUP-ATTR pure tier-attribution rollup.
|
|
3
|
+
*
|
|
4
|
+
* Pure function: reads an array of parsed dedup-audit events, buckets them by
|
|
5
|
+
* tier over a query window, and returns the per-tier catch shares. No I/O, no
|
|
6
|
+
* clock — the route passes `now: Date` (new Date()) at request time, so this
|
|
7
|
+
* module is deterministically reproducible and trivially testable (DEDUP-ATTR-004).
|
|
8
|
+
*
|
|
9
|
+
* Missing `similarity` is fine here: L0/L1 are hash/verify tiers and emit no
|
|
10
|
+
* score, and the rollup never consults it. Malformed lines (non-object, wrong
|
|
11
|
+
* type) are skipped silently — the route's events.log reader already guards its
|
|
12
|
+
* JSON.parse (PREVENT-001), and this layer defends against a hostile/mixed
|
|
13
|
+
* `dedup_audit` array as well.
|
|
14
|
+
*
|
|
15
|
+
* The returned shape is structurally identical to the authoritative contract in
|
|
16
|
+
* `extensions/dashboard-server/api-contracts/dedup-attribution.ts` (the existing
|
|
17
|
+
* src-mirrors-dashboard-contract pattern); src/ stays pi-agnostic and never
|
|
18
|
+
* imports dashboard types. Status here is computed from the pure signal the
|
|
19
|
+
* rollup owns (a non-empty window) — the route additionally derives the sent
|
|
20
|
+
* `status` via `deriveVcStatus` from the shared vc-status module.
|
|
21
|
+
*
|
|
22
|
+
* Guardrails: PREVENT-PI-004 (zero I/O/network), PREVENT-011 (no `any`).
|
|
23
|
+
*/
|
|
24
|
+
/**
|
|
25
|
+
* Roll up dedup-audit events over [now - windowMs, now] into per-tier shares.
|
|
26
|
+
*
|
|
27
|
+
* Only events whose ISO-8601 `ts` falls inside the window are counted; events of
|
|
28
|
+
* any other `type` (or a missing/unparseable `ts`) are skipped silently. Shares
|
|
29
|
+
* are fractions of the window's total decisions, each in [0, 1]; an empty window
|
|
30
|
+
* yields all-zero shares with `status:"awaiting_data"` — never a fabricated
|
|
31
|
+
* zero-share table presented as real.
|
|
32
|
+
*/
|
|
33
|
+
export function computeDedupTierRollup(events, windowMs, now) {
|
|
34
|
+
const winMs = windowMs > 0 ? windowMs : 24 * 60 * 60 * 1000;
|
|
35
|
+
const windowStart = now.getTime() - winMs;
|
|
36
|
+
const windowEnd = now.getTime();
|
|
37
|
+
const acc = {
|
|
38
|
+
l0: { deduped: 0, passed: 0 },
|
|
39
|
+
l1: { deduped: 0, passed: 0 },
|
|
40
|
+
l2: { deduped: 0, passed: 0 },
|
|
41
|
+
storedNew: 0,
|
|
42
|
+
};
|
|
43
|
+
let total = 0;
|
|
44
|
+
for (const ev of events) {
|
|
45
|
+
if (!ev || typeof ev !== "object")
|
|
46
|
+
continue;
|
|
47
|
+
if (ev.type !== "dedup_audit")
|
|
48
|
+
continue;
|
|
49
|
+
const ts = Date.parse(ev.ts);
|
|
50
|
+
if (Number.isNaN(ts) || ts < windowStart || ts > windowEnd)
|
|
51
|
+
continue;
|
|
52
|
+
total += 1;
|
|
53
|
+
switch (ev.tier) {
|
|
54
|
+
case "L0":
|
|
55
|
+
if (ev.status === "deduped")
|
|
56
|
+
acc.l0.deduped += 1;
|
|
57
|
+
else if (ev.status === "passed")
|
|
58
|
+
acc.l0.passed += 1;
|
|
59
|
+
break;
|
|
60
|
+
case "L1":
|
|
61
|
+
if (ev.status === "deduped")
|
|
62
|
+
acc.l1.deduped += 1;
|
|
63
|
+
else if (ev.status === "passed")
|
|
64
|
+
acc.l1.passed += 1;
|
|
65
|
+
break;
|
|
66
|
+
case "L2":
|
|
67
|
+
if (ev.status === "deduped")
|
|
68
|
+
acc.l2.deduped += 1;
|
|
69
|
+
else if (ev.status === "passed")
|
|
70
|
+
acc.l2.passed += 1;
|
|
71
|
+
break;
|
|
72
|
+
case "new":
|
|
73
|
+
acc.storedNew += 1;
|
|
74
|
+
break;
|
|
75
|
+
default:
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
const byTier = {
|
|
80
|
+
l0: { deduped: acc.l0.deduped, passed: acc.l0.passed },
|
|
81
|
+
l1: { deduped: acc.l1.deduped, passed: acc.l1.passed },
|
|
82
|
+
l2: { deduped: acc.l2.deduped, passed: acc.l2.passed },
|
|
83
|
+
new: acc.storedNew,
|
|
84
|
+
};
|
|
85
|
+
const shareOf = (n) => (total > 0 ? n / total : 0);
|
|
86
|
+
return {
|
|
87
|
+
schema: "dedup-tier-rollup-v1",
|
|
88
|
+
windowStart: new Date(windowStart).toISOString(),
|
|
89
|
+
windowEnd: now.toISOString(),
|
|
90
|
+
totalDecisions: total,
|
|
91
|
+
byTier,
|
|
92
|
+
l0Share: shareOf(acc.l0.deduped + acc.l0.passed),
|
|
93
|
+
l1Share: shareOf(acc.l1.deduped + acc.l1.passed),
|
|
94
|
+
l2Share: shareOf(acc.l2.deduped + acc.l2.passed),
|
|
95
|
+
status: total > 0 ? "live" : "awaiting_data",
|
|
96
|
+
};
|
|
97
|
+
}
|