pi-mega-compact 0.20.40 → 0.20.41
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-ml5e.js +30 -0
- package/dist/config/vector-cortex.js +5 -5
- package/dist/config.js +1 -1
- package/dist/extensions/dashboard-server/routes-rag-settings-vector-cortex.js +1 -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/encoder/promotion.js +58 -0
- package/dist/vector-cortex/encoder/promotion.js +58 -0
- package/extensions/dashboard-server/routes-rag-settings-vector-cortex.ts +6 -0
- package/package.json +1 -1
- package/src/config/vector-cortex-ml5e.ts +32 -0
- package/src/config/vector-cortex.ts +5 -5
- package/src/config.ts +1 -0
- package/src/vector-cortex/encoder/promotion.ts +129 -0
|
@@ -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,9 @@ 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
|
|
243
|
+
// Sibling extracts: stay under the 300-line soft limit.
|
|
245
244
|
export { VC9A_ENABLED } from "./vector-cortex-vc9a.js";
|
|
246
245
|
export { VC9B_ENABLED } from "./vector-cortex-vc9b.js";
|
|
247
246
|
export { VC9C_ENABLED } from "./vector-cortex-vc9c.js";
|
|
@@ -251,5 +250,6 @@ export { ML5A_ENABLED } from "./vector-cortex-ml5a.js";
|
|
|
251
250
|
export { ML5B_ENABLED } from "./vector-cortex-ml5b.js";
|
|
252
251
|
export { ML5C_ENABLED } from "./vector-cortex-ml5c.js";
|
|
253
252
|
export { ML5D_ENABLED } from "./vector-cortex-ml5d.js";
|
|
253
|
+
export { ML5E_ENABLED } from "./vector-cortex-ml5e.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, 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";
|
|
@@ -56,5 +56,6 @@ 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),
|
|
59
60
|
],
|
|
60
61
|
};
|
|
@@ -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,9 @@ 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
|
|
243
|
+
// Sibling extracts: stay under the 300-line soft limit.
|
|
245
244
|
export { VC9A_ENABLED } from "./vector-cortex-vc9a.js";
|
|
246
245
|
export { VC9B_ENABLED } from "./vector-cortex-vc9b.js";
|
|
247
246
|
export { VC9C_ENABLED } from "./vector-cortex-vc9c.js";
|
|
@@ -251,5 +250,6 @@ export { ML5A_ENABLED } from "./vector-cortex-ml5a.js";
|
|
|
251
250
|
export { ML5B_ENABLED } from "./vector-cortex-ml5b.js";
|
|
252
251
|
export { ML5C_ENABLED } from "./vector-cortex-ml5c.js";
|
|
253
252
|
export { ML5D_ENABLED } from "./vector-cortex-ml5d.js";
|
|
253
|
+
export { ML5E_ENABLED } from "./vector-cortex-ml5e.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, 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,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,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
|
+
}
|
|
@@ -240,5 +240,11 @@ export const VECTOR_CORTEX_SETTINGS: SettingGroup = {
|
|
|
240
240
|
"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.",
|
|
241
241
|
true,
|
|
242
242
|
),
|
|
243
|
+
boolDirect(
|
|
244
|
+
"MEGACOMPACT_ML5_E",
|
|
245
|
+
"ML5-E Nightly Retraining Cron",
|
|
246
|
+
"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.",
|
|
247
|
+
true,
|
|
248
|
+
),
|
|
243
249
|
],
|
|
244
250
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-mega-compact",
|
|
3
|
-
"version": "0.20.
|
|
3
|
+
"version": "0.20.41",
|
|
4
4
|
"description": "Layered, local, vector-backed context compressor for pi — supersede/collapse/cluster compaction with deduped inline recall.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "BSD-3-Clause",
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* 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
|
+
|
|
22
|
+
import { sprintFlag } from "./vector-cortex-flag.js";
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* ML5-E — nightly retraining cron + feedback loop. Default ON.
|
|
26
|
+
* `MEGACOMPACT_ML5_E=0` disables and is byte-identical to the ML5-D survivor:
|
|
27
|
+
* the nightly retraining scripts are never invoked by the runtime, the
|
|
28
|
+
* promotion gate is inert, and the dashboard's Improve Cortex flow is
|
|
29
|
+
* byte-identical to the ML5-D tab. The flag gates invocation only — the scripts
|
|
30
|
+
* exist on disk regardless.
|
|
31
|
+
*/
|
|
32
|
+
export const ML5E_ENABLED = (): boolean => sprintFlag("MEGACOMPACT_ML5_E");
|
|
@@ -11,9 +11,8 @@
|
|
|
11
11
|
|
|
12
12
|
import { sprintFlag } from "./vector-cortex-flag.js";
|
|
13
13
|
|
|
14
|
-
// VC0/VC1/VC2 foundation-phase flags
|
|
15
|
-
//
|
|
16
|
-
// `from "./config/vector-cortex.js"` import keeps resolving unchanged.
|
|
14
|
+
// VC0/VC1/VC2 foundation-phase flags in vector-cortex-early.ts; re-exported
|
|
15
|
+
// so every existing `from "./config/vector-cortex.js"` import resolves unchanged.
|
|
17
16
|
export {
|
|
18
17
|
VC0A_ENABLED,
|
|
19
18
|
VC0B_ENABLED,
|
|
@@ -269,9 +268,9 @@ export const VC8A_ENABLED = (): boolean => sprintFlag("MEGACOMPACT_VC8A");
|
|
|
269
268
|
*/
|
|
270
269
|
export const VC8B_ENABLED = (): boolean => sprintFlag("MEGACOMPACT_VC8B");
|
|
271
270
|
|
|
272
|
-
// VC8C
|
|
271
|
+
// VC8C extracted to vector-cortex-vc8c.ts; re-exported so existing imports keep resolving.
|
|
273
272
|
export { VC8C_ENABLED } from "./vector-cortex-vc8c.js";
|
|
274
|
-
// Sibling extracts
|
|
273
|
+
// Sibling extracts: stay under the 300-line soft limit.
|
|
275
274
|
export { VC9A_ENABLED } from "./vector-cortex-vc9a.js";
|
|
276
275
|
export { VC9B_ENABLED } from "./vector-cortex-vc9b.js";
|
|
277
276
|
export { VC9C_ENABLED } from "./vector-cortex-vc9c.js";
|
|
@@ -281,6 +280,7 @@ export { ML5A_ENABLED } from "./vector-cortex-ml5a.js";
|
|
|
281
280
|
export { ML5B_ENABLED } from "./vector-cortex-ml5b.js";
|
|
282
281
|
export { ML5C_ENABLED } from "./vector-cortex-ml5c.js";
|
|
283
282
|
export { ML5D_ENABLED } from "./vector-cortex-ml5d.js";
|
|
283
|
+
export { ML5E_ENABLED } from "./vector-cortex-ml5e.js";
|
|
284
284
|
|
|
285
285
|
// Breaker constants (TRIAD_RESILIENCE.md §breaker) extracted to vector-cortex-breakers.ts.
|
|
286
286
|
export {
|
package/src/config.ts
CHANGED
|
@@ -0,0 +1,129 @@
|
|
|
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
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
// PromotionV1 — the ledger row recording one nightly training + promotion run.
|
|
21
|
+
// ---------------------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
/** Schema tag for the promotion ledger row. */
|
|
24
|
+
export const PROMOTION_SCHEMA = "promotion-v1" as const;
|
|
25
|
+
|
|
26
|
+
/** Per-head calibration verdict: pass or fail. */
|
|
27
|
+
export interface HeadVerdict {
|
|
28
|
+
readonly head: string;
|
|
29
|
+
readonly pass: boolean;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/** PromotionV1 — a single ledger row recording one training + gate run.
|
|
33
|
+
* Digest-only: carries SHA-256 identifiers, never payload content. */
|
|
34
|
+
export interface PromotionV1 {
|
|
35
|
+
readonly schema: typeof PROMOTION_SCHEMA;
|
|
36
|
+
/** ISO-8601 timestamp of the run. */
|
|
37
|
+
readonly ts: string;
|
|
38
|
+
/** SHA-256 of the corpus digest used for this training run. */
|
|
39
|
+
readonly corpusDigest: string;
|
|
40
|
+
/** SHA-256 of the newly trained asset manifest (null when no-op). */
|
|
41
|
+
readonly assetDigest: string | null;
|
|
42
|
+
/** SHA-256 of the previously committed asset (the incumbent). */
|
|
43
|
+
readonly priorAssetDigest: string | null;
|
|
44
|
+
/** Per-head calibration verdicts (all five heads). */
|
|
45
|
+
readonly headVerdicts: readonly HeadVerdict[];
|
|
46
|
+
/** True when all five heads pass their per-head thresholds. */
|
|
47
|
+
readonly fiveHeadsOk: boolean;
|
|
48
|
+
/** True when the new asset beats the incumbent on held-out dev set. */
|
|
49
|
+
readonly heldOutBeat: boolean;
|
|
50
|
+
/** The gate decision: promoted (eligible) or demoted (new asset rejected).
|
|
51
|
+
* `noop` is defined by the spec but unused — the corpus-digest check in
|
|
52
|
+
* retrain-nightly.mjs exits before any ledger append when there is nothing
|
|
53
|
+
* to train on. */
|
|
54
|
+
readonly verdict: "promoted" | "demoted" | "noop";
|
|
55
|
+
/** Present only when verdict is "demoted": the demotion event name. */
|
|
56
|
+
readonly demotedEvent: "demoted_new_asset" | null;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// ---------------------------------------------------------------------------
|
|
60
|
+
// Append-only manifest — every new asset is a NEW entry, never an overwrite.
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
|
|
63
|
+
/** A single entry in the append-only asset manifest. */
|
|
64
|
+
export interface AssetManifestEntry {
|
|
65
|
+
readonly assetDigest: string;
|
|
66
|
+
readonly ts: string;
|
|
67
|
+
readonly source: string;
|
|
68
|
+
readonly verdict: string;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
/** The append-only manifest: an ordered list of asset entries plus the
|
|
72
|
+
* committed pointer (the digest of the currently active asset). */
|
|
73
|
+
export interface AssetManifest {
|
|
74
|
+
readonly entries: readonly AssetManifestEntry[];
|
|
75
|
+
/** SHA-256 of the currently committed (active) asset. */
|
|
76
|
+
committed: string | null;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/** Append a new asset entry to the manifest. Never mutates `entries`;
|
|
80
|
+
* returns a new manifest with the entry appended and `committed` updated. */
|
|
81
|
+
export function appendAsset(
|
|
82
|
+
manifest: AssetManifest,
|
|
83
|
+
entry: AssetManifestEntry,
|
|
84
|
+
): AssetManifest {
|
|
85
|
+
return {
|
|
86
|
+
entries: [...manifest.entries, entry],
|
|
87
|
+
committed: entry.assetDigest,
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/** Restore a prior asset by SHA-256: atomically swap the committed pointer
|
|
92
|
+
* to the prior entry. The prior entry MUST exist in the manifest (append-only
|
|
93
|
+
* guarantees it was never overwritten). Returns null when the digest is not
|
|
94
|
+
* found (defensive: append-only means it should always be findable). */
|
|
95
|
+
export function rollbackTo(
|
|
96
|
+
manifest: AssetManifest,
|
|
97
|
+
digest: string,
|
|
98
|
+
): AssetManifest | null {
|
|
99
|
+
const found = manifest.entries.find((e) => e.assetDigest === digest);
|
|
100
|
+
if (!found) return null;
|
|
101
|
+
return {
|
|
102
|
+
entries: manifest.entries,
|
|
103
|
+
committed: found.assetDigest,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// ---------------------------------------------------------------------------
|
|
108
|
+
// Pure decision rules.
|
|
109
|
+
// ---------------------------------------------------------------------------
|
|
110
|
+
|
|
111
|
+
/** Evaluate the promotion gate: promote only when all five heads pass AND the
|
|
112
|
+
* new asset beats the committed asset on the held-out dev set. Otherwise
|
|
113
|
+
* demote. No training data is ever the held-out set. */
|
|
114
|
+
export function promoteDecision(
|
|
115
|
+
fiveHeadsOk: boolean,
|
|
116
|
+
heldOutBeat: boolean,
|
|
117
|
+
): "promoted" | "demoted" {
|
|
118
|
+
return fiveHeadsOk && heldOutBeat ? "promoted" : "demoted";
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/** Whether a rollback is needed: the current asset at position N regressed
|
|
122
|
+
* relative to the asset at position N-1. True only when regression is
|
|
123
|
+
* confirmed and a prior asset digest exists to restore. */
|
|
124
|
+
export function rollbackNeeded(
|
|
125
|
+
regressionConfirmed: boolean,
|
|
126
|
+
priorAssetDigest: string | null,
|
|
127
|
+
): boolean {
|
|
128
|
+
return regressionConfirmed && priorAssetDigest !== null;
|
|
129
|
+
}
|