melete-ai 0.88.2
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/LICENSE +21 -0
- package/README.md +72 -0
- package/bin/melete-server.mjs +345 -0
- package/bin/melete.mjs +165 -0
- package/dist/achievability.d.ts +38 -0
- package/dist/achievability.d.ts.map +1 -0
- package/dist/achievability.js +135 -0
- package/dist/achievability.js.map +1 -0
- package/dist/aegis.d.ts +52 -0
- package/dist/aegis.d.ts.map +1 -0
- package/dist/aegis.js +191 -0
- package/dist/aegis.js.map +1 -0
- package/dist/arms.d.ts +70 -0
- package/dist/arms.d.ts.map +1 -0
- package/dist/arms.js +399 -0
- package/dist/arms.js.map +1 -0
- package/dist/batch.d.ts +30 -0
- package/dist/batch.d.ts.map +1 -0
- package/dist/batch.js +151 -0
- package/dist/batch.js.map +1 -0
- package/dist/bench.d.ts +49 -0
- package/dist/bench.d.ts.map +1 -0
- package/dist/bench.js +124 -0
- package/dist/bench.js.map +1 -0
- package/dist/certify.d.ts +48 -0
- package/dist/certify.d.ts.map +1 -0
- package/dist/certify.js +125 -0
- package/dist/certify.js.map +1 -0
- package/dist/cliff.d.ts +41 -0
- package/dist/cliff.d.ts.map +1 -0
- package/dist/cliff.js +132 -0
- package/dist/cliff.js.map +1 -0
- package/dist/confidence.d.ts +38 -0
- package/dist/confidence.d.ts.map +1 -0
- package/dist/confidence.js +98 -0
- package/dist/confidence.js.map +1 -0
- package/dist/constrained.d.ts +59 -0
- package/dist/constrained.d.ts.map +1 -0
- package/dist/constrained.js +191 -0
- package/dist/constrained.js.map +1 -0
- package/dist/cortex.d.ts +56 -0
- package/dist/cortex.d.ts.map +1 -0
- package/dist/cortex.js +81 -0
- package/dist/cortex.js.map +1 -0
- package/dist/costaware.d.ts +49 -0
- package/dist/costaware.d.ts.map +1 -0
- package/dist/costaware.js +185 -0
- package/dist/costaware.js.map +1 -0
- package/dist/drift.d.ts +36 -0
- package/dist/drift.d.ts.map +1 -0
- package/dist/drift.js +157 -0
- package/dist/drift.js.map +1 -0
- package/dist/efficiency.d.ts +49 -0
- package/dist/efficiency.d.ts.map +1 -0
- package/dist/efficiency.js +143 -0
- package/dist/efficiency.js.map +1 -0
- package/dist/engine.d.ts +64 -0
- package/dist/engine.d.ts.map +1 -0
- package/dist/engine.js +130 -0
- package/dist/engine.js.map +1 -0
- package/dist/federated.d.ts +38 -0
- package/dist/federated.d.ts.map +1 -0
- package/dist/federated.js +121 -0
- package/dist/federated.js.map +1 -0
- package/dist/frontier.d.ts +51 -0
- package/dist/frontier.d.ts.map +1 -0
- package/dist/frontier.js +117 -0
- package/dist/frontier.js.map +1 -0
- package/dist/guardian.d.ts +46 -0
- package/dist/guardian.d.ts.map +1 -0
- package/dist/guardian.js +101 -0
- package/dist/guardian.js.map +1 -0
- package/dist/index.d.ts +90 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +189 -0
- package/dist/index.js.map +1 -0
- package/dist/interaction.d.ts +44 -0
- package/dist/interaction.d.ts.map +1 -0
- package/dist/interaction.js +167 -0
- package/dist/interaction.js.map +1 -0
- package/dist/interactive.d.ts +25 -0
- package/dist/interactive.d.ts.map +1 -0
- package/dist/interactive.js +75 -0
- package/dist/interactive.js.map +1 -0
- package/dist/inverse.d.ts +44 -0
- package/dist/inverse.d.ts.map +1 -0
- package/dist/inverse.js +141 -0
- package/dist/inverse.js.map +1 -0
- package/dist/ipshield.d.ts +62 -0
- package/dist/ipshield.d.ts.map +1 -0
- package/dist/ipshield.js +104 -0
- package/dist/ipshield.js.map +1 -0
- package/dist/journalist.d.ts +56 -0
- package/dist/journalist.d.ts.map +1 -0
- package/dist/journalist.js +132 -0
- package/dist/journalist.js.map +1 -0
- package/dist/lineage.d.ts +43 -0
- package/dist/lineage.d.ts.map +1 -0
- package/dist/lineage.js +112 -0
- package/dist/lineage.js.map +1 -0
- package/dist/metabrain.d.ts +59 -0
- package/dist/metabrain.d.ts.map +1 -0
- package/dist/metabrain.js +215 -0
- package/dist/metabrain.js.map +1 -0
- package/dist/mixedspace.d.ts +61 -0
- package/dist/mixedspace.d.ts.map +1 -0
- package/dist/mixedspace.js +267 -0
- package/dist/mixedspace.js.map +1 -0
- package/dist/multiobjective.d.ts +42 -0
- package/dist/multiobjective.d.ts.map +1 -0
- package/dist/multiobjective.js +123 -0
- package/dist/multiobjective.js.map +1 -0
- package/dist/noise.d.ts +45 -0
- package/dist/noise.d.ts.map +1 -0
- package/dist/noise.js +148 -0
- package/dist/noise.js.map +1 -0
- package/dist/noiserobust.d.ts +71 -0
- package/dist/noiserobust.d.ts.map +1 -0
- package/dist/noiserobust.js +215 -0
- package/dist/noiserobust.js.map +1 -0
- package/dist/oracle.d.ts +63 -0
- package/dist/oracle.d.ts.map +1 -0
- package/dist/oracle.js +106 -0
- package/dist/oracle.js.map +1 -0
- package/dist/poopt.d.ts +79 -0
- package/dist/poopt.d.ts.map +1 -0
- package/dist/poopt.js +148 -0
- package/dist/poopt.js.map +1 -0
- package/dist/portfolio.d.ts +51 -0
- package/dist/portfolio.d.ts.map +1 -0
- package/dist/portfolio.js +132 -0
- package/dist/portfolio.js.map +1 -0
- package/dist/prescription.d.ts +57 -0
- package/dist/prescription.d.ts.map +1 -0
- package/dist/prescription.js +131 -0
- package/dist/prescription.js.map +1 -0
- package/dist/prime.d.ts +85 -0
- package/dist/prime.d.ts.map +1 -0
- package/dist/prime.js +157 -0
- package/dist/prime.js.map +1 -0
- package/dist/provenance.d.ts +77 -0
- package/dist/provenance.d.ts.map +1 -0
- package/dist/provenance.js +155 -0
- package/dist/provenance.js.map +1 -0
- package/dist/rashomon.d.ts +40 -0
- package/dist/rashomon.d.ts.map +1 -0
- package/dist/rashomon.js +93 -0
- package/dist/rashomon.js.map +1 -0
- package/dist/reliability.d.ts +79 -0
- package/dist/reliability.d.ts.map +1 -0
- package/dist/reliability.js +197 -0
- package/dist/reliability.js.map +1 -0
- package/dist/replay.d.ts +62 -0
- package/dist/replay.d.ts.map +1 -0
- package/dist/replay.js +146 -0
- package/dist/replay.js.map +1 -0
- package/dist/replicate.d.ts +72 -0
- package/dist/replicate.d.ts.map +1 -0
- package/dist/replicate.js +103 -0
- package/dist/replicate.js.map +1 -0
- package/dist/resonance.d.ts +32 -0
- package/dist/resonance.d.ts.map +1 -0
- package/dist/resonance.js +190 -0
- package/dist/resonance.js.map +1 -0
- package/dist/sensitivity.d.ts +44 -0
- package/dist/sensitivity.d.ts.map +1 -0
- package/dist/sensitivity.js +109 -0
- package/dist/sensitivity.js.map +1 -0
- package/dist/server.d.ts +26 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +1410 -0
- package/dist/server.js.map +1 -0
- package/dist/shape.d.ts +37 -0
- package/dist/shape.d.ts.map +1 -0
- package/dist/shape.js +170 -0
- package/dist/shape.js.map +1 -0
- package/dist/sloppiness.d.ts +44 -0
- package/dist/sloppiness.d.ts.map +1 -0
- package/dist/sloppiness.js +194 -0
- package/dist/sloppiness.js.map +1 -0
- package/dist/sovereign.d.ts +77 -0
- package/dist/sovereign.d.ts.map +1 -0
- package/dist/sovereign.js +144 -0
- package/dist/sovereign.js.map +1 -0
- package/dist/space.d.ts +38 -0
- package/dist/space.d.ts.map +1 -0
- package/dist/space.js +107 -0
- package/dist/space.js.map +1 -0
- package/dist/surprise.d.ts +43 -0
- package/dist/surprise.d.ts.map +1 -0
- package/dist/surprise.js +123 -0
- package/dist/surprise.js.map +1 -0
- package/dist/territory.d.ts +43 -0
- package/dist/territory.d.ts.map +1 -0
- package/dist/territory.js +102 -0
- package/dist/territory.js.map +1 -0
- package/dist/trace.d.ts +58 -0
- package/dist/trace.d.ts.map +1 -0
- package/dist/trace.js +0 -0
- package/dist/trace.js.map +1 -0
- package/dist/transfer.d.ts +46 -0
- package/dist/transfer.d.ts.map +1 -0
- package/dist/transfer.js +112 -0
- package/dist/transfer.js.map +1 -0
- package/dist/twin.d.ts +41 -0
- package/dist/twin.d.ts.map +1 -0
- package/dist/twin.js +116 -0
- package/dist/twin.js.map +1 -0
- package/examples/train.mjs +8 -0
- package/examples/tune.mjs +11 -0
- package/package.json +56 -0
package/dist/poopt.js
ADDED
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PROOF OF OPTIMIZATION (PoOpt) — the portable, offline-verifiable certificate that a result was reached
|
|
3
|
+
* EFFICIENTLY, not just reached.
|
|
4
|
+
*
|
|
5
|
+
* Cloud optimizers (Vizier, SigOpt, Optuna) hand you a number. None hand you a cryptographic proof that
|
|
6
|
+
* "this was found in N experiments instead of a full grid sweep of M, by an engine certified to be within
|
|
7
|
+
* X% of the global best — here is the signature, verify it yourself without trusting us, even air-gapped."
|
|
8
|
+
* PoOpt fuses what Melete already produces — the signed discovery trace, the fewer-experiments savings, and
|
|
9
|
+
* the optimality certificate — into ONE Ed25519-signed record that a reviewer, regulator, auditor, ESG
|
|
10
|
+
* registry, or counterparty re-checks OFFLINE with the embedded public key alone.
|
|
11
|
+
*
|
|
12
|
+
* Honest by construction (DIAKRISIS): the EFFICIENCY claim (experiments saved vs a grid sweep) is exact and
|
|
13
|
+
* recomputable; the optimality figure is the conditional Lipschitz certificate; and a RESOURCE figure
|
|
14
|
+
* (energy / CO₂ saved) appears ONLY if you supply your own per-experiment energy and grid carbon factors —
|
|
15
|
+
* never fabricated. PoOpt is the verifiable SUBSTRATE a carbon-credit / green-certificate scheme could
|
|
16
|
+
* accept; whether a market accepts it is a business outcome, not a claim this code makes.
|
|
17
|
+
*/
|
|
18
|
+
import { generateKeyPairSync, sign as edSign, verify as edVerify, createHash, createPublicKey } from "node:crypto";
|
|
19
|
+
const GRID_PER_DIM = 8;
|
|
20
|
+
const GRID_CAP = 1_000_000;
|
|
21
|
+
/** A full grid sweep at ~8 points per dimension, capped — the honest brute-force reference. */
|
|
22
|
+
export function gridBaselineFor(dims) {
|
|
23
|
+
const d = Math.max(0, Math.floor(dims || 0));
|
|
24
|
+
return Math.min(GRID_CAP, Math.round(Math.pow(GRID_PER_DIM, Math.max(1, d))));
|
|
25
|
+
}
|
|
26
|
+
/** Deterministic canonical serialisation of the claim fields (sig + payloadHash excluded). */
|
|
27
|
+
function canonical(c) {
|
|
28
|
+
return JSON.stringify([
|
|
29
|
+
c.v, c.subject, c.goal, c.dims, c.experimentsUsed, c.gridBaseline, c.experimentsSaved,
|
|
30
|
+
round(c.efficiencyPct), num(c.bestValue), c.certifiedWithinPct == null ? null : round(c.certifiedWithinPct),
|
|
31
|
+
c.traceHash, c.energyPerExperimentKwh, c.energySavedKwh, c.carbonKgPerKwh, c.co2SavedKg,
|
|
32
|
+
c.issuedAtMs, c.publicKeyPem, c.algo,
|
|
33
|
+
]);
|
|
34
|
+
}
|
|
35
|
+
const round = (x) => Math.round(x * 1e6) / 1e6;
|
|
36
|
+
const num = (x) => (Number.isFinite(x) ? round(x) : 0);
|
|
37
|
+
/** Issue a signed Proof of Optimization. Generates an Ed25519 keypair if none is supplied. */
|
|
38
|
+
export function issueProofOfOptimization(input, keys) {
|
|
39
|
+
const dims = Math.max(0, Math.floor(input.dims || 0));
|
|
40
|
+
const used = Math.max(0, Math.floor(input.experimentsUsed || 0));
|
|
41
|
+
const grid = gridBaselineFor(dims);
|
|
42
|
+
const saved = Math.max(0, grid - used);
|
|
43
|
+
const efficiencyPct = grid > 0 ? (saved / grid) * 100 : 0;
|
|
44
|
+
const energyPer = (typeof input.energyPerExperimentKwh === "number" && input.energyPerExperimentKwh > 0) ? input.energyPerExperimentKwh : null;
|
|
45
|
+
const carbon = (typeof input.carbonKgPerKwh === "number" && input.carbonKgPerKwh > 0) ? input.carbonKgPerKwh : null;
|
|
46
|
+
const energySavedKwh = energyPer != null ? round(saved * energyPer) : null;
|
|
47
|
+
const co2SavedKg = (energySavedKwh != null && carbon != null) ? round(energySavedKwh * carbon) : null;
|
|
48
|
+
const kp = keys ?? generateKeyPairSync("ed25519");
|
|
49
|
+
const publicKeyPem = kp.publicKey.export({ type: "spki", format: "pem" }).toString();
|
|
50
|
+
const base = {
|
|
51
|
+
v: "poopt/1", subject: String(input.subject ?? "optimization"), goal: input.goal === "minimize" ? "minimize" : "maximize",
|
|
52
|
+
dims, experimentsUsed: used, gridBaseline: grid, experimentsSaved: saved, efficiencyPct: round(efficiencyPct),
|
|
53
|
+
bestValue: num(input.bestValue), certifiedWithinPct: input.certifiedWithinPct == null ? null : round(input.certifiedWithinPct),
|
|
54
|
+
traceHash: input.traceHash ?? null, energyPerExperimentKwh: energyPer, energySavedKwh, carbonKgPerKwh: carbon, co2SavedKg,
|
|
55
|
+
issuedAtMs: Math.max(0, Math.floor(input.issuedAtMs ?? 0)), publicKeyPem, algo: "ed25519+sha256",
|
|
56
|
+
};
|
|
57
|
+
const payloadHash = createHash("sha256").update(canonical(base)).digest("hex");
|
|
58
|
+
const sig = edSign(null, Buffer.from(payloadHash, "hex"), kp.privateKey).toString("base64");
|
|
59
|
+
return { ...base, payloadHash, sig };
|
|
60
|
+
}
|
|
61
|
+
/** Verify a PoOpt OFFLINE: recompute the efficiency claim + check the hash + check the Ed25519 signature. */
|
|
62
|
+
export function verifyProofOfOptimization(cert) {
|
|
63
|
+
try {
|
|
64
|
+
if (!cert || cert.v !== "poopt/1")
|
|
65
|
+
return { ok: false, reason: "not a poopt/1 certificate", recomputed: null };
|
|
66
|
+
// 1) recompute the efficiency claim from dims + experimentsUsed — catches a doctored claim
|
|
67
|
+
const grid = gridBaselineFor(cert.dims);
|
|
68
|
+
const saved = Math.max(0, grid - Math.max(0, Math.floor(cert.experimentsUsed)));
|
|
69
|
+
const eff = grid > 0 ? round((saved / grid) * 100) : 0;
|
|
70
|
+
const recomputed = { gridBaseline: grid, experimentsSaved: saved, efficiencyPct: eff };
|
|
71
|
+
if (grid !== cert.gridBaseline || saved !== cert.experimentsSaved || eff !== round(cert.efficiencyPct))
|
|
72
|
+
return { ok: false, reason: "efficiency claim does not recompute", recomputed };
|
|
73
|
+
// 2) recompute resource figures if factors are present
|
|
74
|
+
if (cert.energyPerExperimentKwh != null) {
|
|
75
|
+
const es = round(saved * cert.energyPerExperimentKwh);
|
|
76
|
+
if (cert.energySavedKwh !== es)
|
|
77
|
+
return { ok: false, reason: "energy figure does not recompute", recomputed };
|
|
78
|
+
if (cert.carbonKgPerKwh != null && cert.co2SavedKg !== round(es * cert.carbonKgPerKwh))
|
|
79
|
+
return { ok: false, reason: "CO2 figure does not recompute", recomputed };
|
|
80
|
+
}
|
|
81
|
+
// 3) recompute the payload hash
|
|
82
|
+
const { payloadHash, sig, ...base } = cert;
|
|
83
|
+
const h = createHash("sha256").update(canonical(base)).digest("hex");
|
|
84
|
+
if (h !== payloadHash)
|
|
85
|
+
return { ok: false, reason: "payload hash mismatch (tampered fields)", recomputed };
|
|
86
|
+
// 4) check the Ed25519 signature with the embedded public key
|
|
87
|
+
let pub;
|
|
88
|
+
try {
|
|
89
|
+
pub = createPublicKey(cert.publicKeyPem);
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
return { ok: false, reason: "bad public key", recomputed };
|
|
93
|
+
}
|
|
94
|
+
const sigOk = edVerify(null, Buffer.from(payloadHash, "hex"), pub, Buffer.from(sig, "base64"));
|
|
95
|
+
if (!sigOk)
|
|
96
|
+
return { ok: false, reason: "signature does not verify", recomputed };
|
|
97
|
+
return { ok: true, reason: "valid — efficiency recomputes + signature verifies offline", recomputed };
|
|
98
|
+
}
|
|
99
|
+
catch (e) {
|
|
100
|
+
return { ok: false, reason: "verify error: " + e.message, recomputed: null };
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
// ── gauntlet ──────────────────────────────────────────────────────────────────
|
|
104
|
+
export function pooptGauntlet() {
|
|
105
|
+
const kp = generateKeyPairSync("ed25519");
|
|
106
|
+
const cert = issueProofOfOptimization({ subject: "GPU kernel tuning", goal: "maximize", dims: 3, experimentsUsed: 80, bestValue: 8999.24, certifiedWithinPct: 56.9, traceHash: "abc123", issuedAtMs: 1000, energyPerExperimentKwh: 2, carbonKgPerKwh: 0.4 }, kp);
|
|
107
|
+
const roundtrip = verifyProofOfOptimization(cert).ok;
|
|
108
|
+
// efficiency is real: 8^3=512 grid, 80 used → 432 saved, 84.375%
|
|
109
|
+
const effOK = cert.gridBaseline === 512 && cert.experimentsSaved === 432 && Math.abs(cert.efficiencyPct - 84.375) < 1e-6;
|
|
110
|
+
// resource honesty: energy = 432·2 = 864 kWh; CO2 = 864·0.4 = 345.6 kg; and NULL when no factors
|
|
111
|
+
const certNoFactor = issueProofOfOptimization({ subject: "x", goal: "maximize", dims: 2, experimentsUsed: 30, bestValue: 1 }, kp);
|
|
112
|
+
const resourceOK = cert.energySavedKwh === 864 && cert.co2SavedKg === 345.6 && certNoFactor.co2SavedKg === null && certNoFactor.energySavedKwh === null;
|
|
113
|
+
// tamper the claim → recompute catches it
|
|
114
|
+
const t1 = JSON.parse(JSON.stringify(cert));
|
|
115
|
+
t1.efficiencyPct = 99.9;
|
|
116
|
+
const tamperClaim = verifyProofOfOptimization(t1).ok === false;
|
|
117
|
+
// tamper a signed field (bestValue) → hash + sig catch it
|
|
118
|
+
const t2 = JSON.parse(JSON.stringify(cert));
|
|
119
|
+
t2.bestValue = 9000;
|
|
120
|
+
const tamperField = verifyProofOfOptimization(t2).ok === false;
|
|
121
|
+
// forged key → signature fails
|
|
122
|
+
const t3 = JSON.parse(JSON.stringify(cert));
|
|
123
|
+
t3.publicKeyPem = generateKeyPairSync("ed25519").publicKey.export({ type: "spki", format: "pem" }).toString();
|
|
124
|
+
const forged = verifyProofOfOptimization(t3).ok === false;
|
|
125
|
+
// deterministic: same input + same key → identical cert
|
|
126
|
+
const det = JSON.stringify(issueProofOfOptimization({ subject: "x", goal: "maximize", dims: 2, experimentsUsed: 10, bestValue: 5, issuedAtMs: 7 }, kp)) === JSON.stringify(issueProofOfOptimization({ subject: "x", goal: "maximize", dims: 2, experimentsUsed: 10, bestValue: 5, issuedAtMs: 7 }, kp));
|
|
127
|
+
// offline: verify touches no network (pure) — proven by it working here with no I/O
|
|
128
|
+
const total = (() => { try {
|
|
129
|
+
verifyProofOfOptimization(null);
|
|
130
|
+
verifyProofOfOptimization({ v: "x" });
|
|
131
|
+
return true;
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
return false;
|
|
135
|
+
} })();
|
|
136
|
+
const checks = [
|
|
137
|
+
{ name: "ISSUE-VERIFY-ROUNDTRIP", pass: roundtrip, detail: "a freshly issued PoOpt verifies offline with its embedded public key" },
|
|
138
|
+
{ name: "EFFICIENCY-EXACT", pass: effOK, detail: `512-run grid baseline, 80 used → 432 saved (84.375%) — exact + recomputable` },
|
|
139
|
+
{ name: "RESOURCE-HONEST", pass: resourceOK, detail: "energy/CO₂ computed only from supplied factors (864 kWh, 345.6 kg); null when absent" },
|
|
140
|
+
{ name: "TAMPER-CLAIM-CAUGHT", pass: tamperClaim, detail: "a doctored efficiency figure fails the recompute check" },
|
|
141
|
+
{ name: "TAMPER-FIELD-CAUGHT", pass: tamperField, detail: "changing any signed field breaks the hash + signature" },
|
|
142
|
+
{ name: "FORGED-KEY-CAUGHT", pass: forged, detail: "swapping the public key makes the signature fail" },
|
|
143
|
+
{ name: "DETERMINISTIC", pass: det, detail: "same input + key → byte-identical certificate" },
|
|
144
|
+
{ name: "TOTAL", pass: total, detail: "null / malformed input never throws" },
|
|
145
|
+
];
|
|
146
|
+
return { score: checks.every((c) => c.pass) ? 100 : 0, checks };
|
|
147
|
+
}
|
|
148
|
+
//# sourceMappingURL=poopt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"poopt.js","sourceRoot":"","sources":["../src/poopt.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE PORTFOLIO BRAIN — the production engine. Self-allocating, robust on every landscape, build-once.
|
|
3
|
+
*
|
|
4
|
+
* No-Free-Lunch: no single optimiser wins everywhere. So instead of betting on one algorithm, the
|
|
5
|
+
* portfolio runs several strategy ARMS (kernel-ucb, cmaes, resonance, random) and a multi-armed BANDIT
|
|
6
|
+
* (UCB1) spends each expensive experiment on whichever arm is delivering the most IMPROVEMENT on THIS
|
|
7
|
+
* problem right now. On a smooth low-D surface it converges to the Bayesian arm; on a rugged or high-D
|
|
8
|
+
* surface it shifts budget to evolution; if an arm stops helping the bandit starves it. The result is an
|
|
9
|
+
* engine that adapts to the problem instead of forcing the problem to fit the engine — so it keeps
|
|
10
|
+
* working across domains without being re-engineered. Each experiment's trace records which arm proposed
|
|
11
|
+
* it, so the discovery provenance shows the brain's adaptive reasoning.
|
|
12
|
+
*
|
|
13
|
+
* ★HONEST: the portfolio is not magically better than its best arm on a given problem — its guarantee is
|
|
14
|
+
* ROBUSTNESS (never far behind the best arm, automatically, with no per-problem tuning), which is exactly
|
|
15
|
+
* what a production system needs. The bandit pays a small exploration overhead to buy that robustness.
|
|
16
|
+
*/
|
|
17
|
+
import { type Space, type Experiment } from "./space.js";
|
|
18
|
+
import { type Goal, type Step, type DiscoveryResult } from "./engine.js";
|
|
19
|
+
import { type Arm } from "./arms.js";
|
|
20
|
+
export interface PortfolioOpts {
|
|
21
|
+
space: Space;
|
|
22
|
+
oracle: (e: Experiment) => number | Promise<number>;
|
|
23
|
+
budget: number;
|
|
24
|
+
goal?: Goal;
|
|
25
|
+
seed?: number;
|
|
26
|
+
target?: number;
|
|
27
|
+
arms?: Arm[];
|
|
28
|
+
explore?: number;
|
|
29
|
+
onStep?: (s: Step) => void | Promise<void>;
|
|
30
|
+
}
|
|
31
|
+
export interface ArmStat {
|
|
32
|
+
name: string;
|
|
33
|
+
pulls: number;
|
|
34
|
+
meanReward: number;
|
|
35
|
+
improvements: number;
|
|
36
|
+
}
|
|
37
|
+
export interface PortfolioResult extends DiscoveryResult {
|
|
38
|
+
armStats: ArmStat[];
|
|
39
|
+
}
|
|
40
|
+
/** Run the self-allocating portfolio discovery loop. */
|
|
41
|
+
export declare function portfolioDiscover(opts: PortfolioOpts): Promise<PortfolioResult>;
|
|
42
|
+
export interface PortfolioGauntlet {
|
|
43
|
+
score: 0 | 100;
|
|
44
|
+
checks: Array<{
|
|
45
|
+
name: string;
|
|
46
|
+
pass: boolean;
|
|
47
|
+
detail: string;
|
|
48
|
+
}>;
|
|
49
|
+
}
|
|
50
|
+
export declare function portfolioGauntlet(): Promise<PortfolioGauntlet>;
|
|
51
|
+
//# sourceMappingURL=portfolio.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"portfolio.d.ts","sourceRoot":"","sources":["../src/portfolio.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,KAAK,KAAK,EAAE,KAAK,UAAU,EAAuB,MAAM,YAAY,CAAC;AAC9E,OAAO,EAAE,KAAK,IAAI,EAAoB,KAAK,IAAI,EAAE,KAAK,eAAe,EAAE,MAAM,aAAa,CAAC;AAC3F,OAAO,EAAE,KAAK,GAAG,EAAe,MAAM,WAAW,CAAC;AAElD,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,KAAK,CAAC;IAAC,MAAM,EAAE,CAAC,CAAC,EAAE,UAAU,KAAK,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAClF,IAAI,CAAC,EAAE,IAAI,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,GAAG,EAAE,CAAC;IAAC,OAAO,CAAC,EAAE,MAAM,CAAC;IAC5E,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5C;AACD,MAAM,WAAW,OAAO;IAAG,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE;AAClG,MAAM,WAAW,eAAgB,SAAQ,eAAe;IAAG,QAAQ,EAAE,OAAO,EAAE,CAAA;CAAE;AAIhF,wDAAwD;AACxD,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,aAAa,GAAG,OAAO,CAAC,eAAe,CAAC,CAiDrF;AAGD,MAAM,WAAW,iBAAiB;IAAG,KAAK,EAAE,CAAC,GAAG,GAAG,CAAC;IAAC,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE;AACrH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,iBAAiB,CAAC,CA2BpE"}
|
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE PORTFOLIO BRAIN — the production engine. Self-allocating, robust on every landscape, build-once.
|
|
3
|
+
*
|
|
4
|
+
* No-Free-Lunch: no single optimiser wins everywhere. So instead of betting on one algorithm, the
|
|
5
|
+
* portfolio runs several strategy ARMS (kernel-ucb, cmaes, resonance, random) and a multi-armed BANDIT
|
|
6
|
+
* (UCB1) spends each expensive experiment on whichever arm is delivering the most IMPROVEMENT on THIS
|
|
7
|
+
* problem right now. On a smooth low-D surface it converges to the Bayesian arm; on a rugged or high-D
|
|
8
|
+
* surface it shifts budget to evolution; if an arm stops helping the bandit starves it. The result is an
|
|
9
|
+
* engine that adapts to the problem instead of forcing the problem to fit the engine — so it keeps
|
|
10
|
+
* working across domains without being re-engineered. Each experiment's trace records which arm proposed
|
|
11
|
+
* it, so the discovery provenance shows the brain's adaptive reasoning.
|
|
12
|
+
*
|
|
13
|
+
* ★HONEST: the portfolio is not magically better than its best arm on a given problem — its guarantee is
|
|
14
|
+
* ROBUSTNESS (never far behind the best arm, automatically, with no per-problem tuning), which is exactly
|
|
15
|
+
* what a production system needs. The bandit pays a small exploration overhead to buy that robustness.
|
|
16
|
+
*/
|
|
17
|
+
import { lcg, gridCandidates } from "./space.js";
|
|
18
|
+
import { defaultArms } from "./arms.js";
|
|
19
|
+
const key = (e) => JSON.stringify(e);
|
|
20
|
+
/** Run the self-allocating portfolio discovery loop. */
|
|
21
|
+
export async function portfolioDiscover(opts) {
|
|
22
|
+
const space = opts.space;
|
|
23
|
+
const goal = opts.goal ?? "maximize";
|
|
24
|
+
const budget = Math.max(1, opts.budget | 0);
|
|
25
|
+
const rnd = lcg(opts.seed ?? 1);
|
|
26
|
+
const arms = (opts.arms && opts.arms.length ? opts.arms : defaultArms());
|
|
27
|
+
const cBandit = opts.explore ?? 0.4;
|
|
28
|
+
const better = (a, b) => goal === "maximize" ? a > b : a < b;
|
|
29
|
+
const obs = [];
|
|
30
|
+
const seen = new Set();
|
|
31
|
+
const history = [];
|
|
32
|
+
const stats = arms.map((a) => ({ name: a.name, pulls: 0, sumReward: 0, improvements: 0 }));
|
|
33
|
+
const evalExp = async (e) => { const v = Number(await opts.oracle(e)); return Number.isFinite(v) ? v : (goal === "maximize" ? -1e18 : 1e18); };
|
|
34
|
+
let best = { experiment: {}, value: goal === "maximize" ? -Infinity : Infinity };
|
|
35
|
+
let vmin = Infinity, vmax = -Infinity;
|
|
36
|
+
const record = async (e, armName, rationale) => {
|
|
37
|
+
const v = await evalExp(e);
|
|
38
|
+
obs.push({ experiment: e, value: v });
|
|
39
|
+
seen.add(key(e));
|
|
40
|
+
vmin = Math.min(vmin, v);
|
|
41
|
+
vmax = Math.max(vmax, v);
|
|
42
|
+
const improved = better(v, best.value);
|
|
43
|
+
if (improved)
|
|
44
|
+
best = { experiment: e, value: v };
|
|
45
|
+
const step = { n: obs.length, experiment: e, value: v, acquisition: 0, kappa: 0, rationale: `[${armName}] ${rationale}` };
|
|
46
|
+
history.push(step);
|
|
47
|
+
if (opts.onStep)
|
|
48
|
+
await opts.onStep(step);
|
|
49
|
+
return improved ? v : null;
|
|
50
|
+
};
|
|
51
|
+
// cold start: a coarse grid seed shared by all arms
|
|
52
|
+
const perDim = space.dims.length <= 2 ? 3 : 2;
|
|
53
|
+
for (const e of gridCandidates(space, perDim).slice(0, Math.max(1, Math.min(budget, space.dims.length <= 2 ? 9 : 8)))) {
|
|
54
|
+
if (obs.length >= budget)
|
|
55
|
+
break;
|
|
56
|
+
if (seen.has(key(e)))
|
|
57
|
+
continue;
|
|
58
|
+
await record(e, "seed", "design-of-experiments grid point");
|
|
59
|
+
}
|
|
60
|
+
// active loop: UCB1 bandit over arms; reward = normalised improvement of the new best
|
|
61
|
+
let T = 0;
|
|
62
|
+
for (let t = obs.length; t < budget; t++) {
|
|
63
|
+
if (opts.target != null && better(best.value, opts.target))
|
|
64
|
+
break;
|
|
65
|
+
T++;
|
|
66
|
+
// pick arm: untried arms first, else UCB1
|
|
67
|
+
let ai = stats.findIndex((s) => s.pulls === 0);
|
|
68
|
+
if (ai < 0) {
|
|
69
|
+
let bestU = -Infinity;
|
|
70
|
+
for (let i = 0; i < arms.length; i++) {
|
|
71
|
+
const s = stats[i];
|
|
72
|
+
const mean = s.sumReward / s.pulls;
|
|
73
|
+
const u = mean + cBandit * Math.sqrt(Math.log(T + 1) / s.pulls);
|
|
74
|
+
if (u > bestU) {
|
|
75
|
+
bestU = u;
|
|
76
|
+
ai = i;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const arm = arms[ai];
|
|
81
|
+
const prevBest = best.value;
|
|
82
|
+
const e = arm.propose({ space, obs, t, budget, rnd, goal });
|
|
83
|
+
const newV = await record(e, arm.name, `bandit-selected (pulls=${stats[ai].pulls})`);
|
|
84
|
+
const range = (vmax - vmin) || 1;
|
|
85
|
+
const reward = newV != null ? Math.max(0, Math.min(1, Math.abs(best.value - prevBest) / range)) : 0;
|
|
86
|
+
stats[ai].pulls++;
|
|
87
|
+
stats[ai].sumReward += reward;
|
|
88
|
+
if (newV != null)
|
|
89
|
+
stats[ai].improvements++;
|
|
90
|
+
}
|
|
91
|
+
const armStats = stats.map((s) => ({ name: s.name, pulls: s.pulls, meanReward: s.pulls ? Math.round((s.sumReward / s.pulls) * 1000) / 1000 : 0, improvements: s.improvements }));
|
|
92
|
+
const converged = opts.target != null ? better(best.value, opts.target) || Math.abs(best.value - opts.target) < 1e-9 : true;
|
|
93
|
+
return { best, history, evaluations: obs.length, converged, goal, armStats };
|
|
94
|
+
}
|
|
95
|
+
export async function portfolioGauntlet() {
|
|
96
|
+
const space = { dims: [{ name: "x", type: "real", min: 0, max: 10 }, { name: "y", type: "real", min: 0, max: 10 }] };
|
|
97
|
+
const peak = (e) => Math.exp(-(((e.x ?? 0) - 7.2) ** 2 + ((e.y ?? 0) - 3.4) ** 2) / 3);
|
|
98
|
+
const r = await portfolioDiscover({ space, oracle: (e) => peak(e), budget: 80, seed: 7, goal: "maximize", target: 0.99 });
|
|
99
|
+
const converges = r.best.value >= 0.99;
|
|
100
|
+
const allocates = r.armStats.reduce((s, a) => s + a.pulls, 0) > 0 && r.armStats.some((a) => a.pulls > 0);
|
|
101
|
+
// the bandit should favour a productive arm over pure random on a smooth surface
|
|
102
|
+
const random = r.armStats.find((a) => a.name === "random");
|
|
103
|
+
const bestArm = [...r.armStats].sort((a, b) => b.improvements - a.improvements)[0];
|
|
104
|
+
const banditLearns = bestArm.name !== "random" && bestArm.improvements >= random.improvements;
|
|
105
|
+
const a = await portfolioDiscover({ space, oracle: (e) => peak(e), budget: 60, seed: 5, goal: "maximize" });
|
|
106
|
+
const b = await portfolioDiscover({ space, oracle: (e) => peak(e), budget: 60, seed: 5, goal: "maximize" });
|
|
107
|
+
const deterministic = JSON.stringify(a.best) === JSON.stringify(b.best) && JSON.stringify(a.armStats) === JSON.stringify(b.armStats);
|
|
108
|
+
// robustness: also works on a higher-D surface where a pure kernel arm degrades
|
|
109
|
+
const sp5 = { dims: Array.from({ length: 5 }, (_, i) => ({ name: "x" + i, type: "real", min: 0, max: 1 })) };
|
|
110
|
+
const f5 = (e) => { let s = 0; for (let i = 0; i < 5; i++) {
|
|
111
|
+
const d = (e["x" + i] ?? 0) - 0.6;
|
|
112
|
+
s += d * d;
|
|
113
|
+
} return Math.exp(-s / 0.1); };
|
|
114
|
+
const r5 = await portfolioDiscover({ space: sp5, oracle: (e) => f5(e), budget: 220, seed: 3, goal: "maximize", target: 0.9 });
|
|
115
|
+
const robust5d = r5.best.value >= 0.9;
|
|
116
|
+
const total = (() => { try {
|
|
117
|
+
return true;
|
|
118
|
+
}
|
|
119
|
+
catch {
|
|
120
|
+
return false;
|
|
121
|
+
} })();
|
|
122
|
+
const checks = [
|
|
123
|
+
{ name: "CONVERGES", pass: converges, detail: `portfolio reaches the optimum on a smooth surface (best=${r.best.value.toFixed(3)})` },
|
|
124
|
+
{ name: "ALLOCATES", pass: allocates, detail: "the bandit spends the budget across the arms" },
|
|
125
|
+
{ name: "BANDIT-LEARNS", pass: banditLearns, detail: `a productive arm (${bestArm.name}) earns ≥ as many improvements as random — the bandit doesn't waste budget` },
|
|
126
|
+
{ name: "DETERMINISTIC", pass: deterministic, detail: "same seed → identical discovery + identical arm allocation" },
|
|
127
|
+
{ name: "ROBUST-HIGH-D", pass: robust5d, detail: `also solves a 5-D surface (best=${r5.best.value.toFixed(3)}) — robustness across landscapes` },
|
|
128
|
+
{ name: "TOTAL", pass: total, detail: "runs without throwing" },
|
|
129
|
+
];
|
|
130
|
+
return { score: checks.every((c) => c.pass) ? 100 : 0, checks };
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=portfolio.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"portfolio.js","sourceRoot":"","sources":["../src/portfolio.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* THE PRESCRIPTION — the one thing a human actually wants. Every other module is an engine part: it measures
|
|
3
|
+
* gain, robustness, trust, reachability, coupling. Powerful — and useless to a factory manager, a
|
|
4
|
+
* formulation chemist, or an investor, because they don't speak curvature and Lipschitz bounds. They have
|
|
5
|
+
* exactly one question: "what do I DO now?"
|
|
6
|
+
*
|
|
7
|
+
* THE PRESCRIPTION answers it. It fuses the whole engine into a plain-language, business-ready verdict:
|
|
8
|
+
* • the RECIPE — the exact settings to use, in your own units;
|
|
9
|
+
* • the RESULT — what it scores, and how much better that is than where you started and than guessing;
|
|
10
|
+
* • the DECISION — SHIP IT / RUN A FEW MORE / FIND A NEW LEVER / KEEP GOING — and why;
|
|
11
|
+
* • how to APPLY it — concrete steps a non-expert can follow tomorrow;
|
|
12
|
+
* • the GUARDS — how tightly to hold each knob, whether to re-test, whether it's trustworthy.
|
|
13
|
+
*
|
|
14
|
+
* This is the output you can hold: not a number to interpret, a decision to act on. The math is the engine
|
|
15
|
+
* under the hood; this is the steering wheel.
|
|
16
|
+
*
|
|
17
|
+
* Honest by construction (DIAKRISIS): every field is derived from the run's REAL measured signals (gain vs
|
|
18
|
+
* your own first try, robustness from the local drop-rate, trust from the drift check, reachability from the
|
|
19
|
+
* Lipschitz ceiling) — nothing is invented, no fabricated ROI or dollar figure. The decision is a
|
|
20
|
+
* transparent rule over those signals, and it abstains when the data is too thin to advise.
|
|
21
|
+
*/
|
|
22
|
+
import { type Space } from "./space.js";
|
|
23
|
+
import { type Observation, type Goal } from "./engine.js";
|
|
24
|
+
export type Decision = "ship" | "refine" | "new-lever" | "more-data" | "unknown";
|
|
25
|
+
export interface Prescription {
|
|
26
|
+
recipe: Array<{
|
|
27
|
+
name: string;
|
|
28
|
+
value: number;
|
|
29
|
+
}>;
|
|
30
|
+
expected: number;
|
|
31
|
+
vsStartPct: number;
|
|
32
|
+
vsRandomPct: number;
|
|
33
|
+
decision: Decision;
|
|
34
|
+
confidencePct: number;
|
|
35
|
+
robustnessPct: number;
|
|
36
|
+
trustPct: number;
|
|
37
|
+
tolerances: Array<{
|
|
38
|
+
name: string;
|
|
39
|
+
plusMinus: number;
|
|
40
|
+
}>;
|
|
41
|
+
driftWarning: boolean;
|
|
42
|
+
evaluations: number;
|
|
43
|
+
note: string;
|
|
44
|
+
}
|
|
45
|
+
/** Turn a finished discovery run into a plain-language decision + action plan. */
|
|
46
|
+
export declare function buildPrescription(obs: ReadonlyArray<Observation>, space: Space, goal?: Goal, opts?: {
|
|
47
|
+
target?: number;
|
|
48
|
+
}): Prescription;
|
|
49
|
+
export declare function prescriptionGauntlet(): {
|
|
50
|
+
score: 0 | 100;
|
|
51
|
+
checks: Array<{
|
|
52
|
+
name: string;
|
|
53
|
+
pass: boolean;
|
|
54
|
+
detail: string;
|
|
55
|
+
}>;
|
|
56
|
+
};
|
|
57
|
+
//# sourceMappingURL=prescription.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prescription.d.ts","sourceRoot":"","sources":["../src/prescription.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,OAAO,EAAE,KAAK,KAAK,EAAmB,MAAM,YAAY,CAAC;AACzD,OAAO,EAAE,KAAK,WAAW,EAAE,KAAK,IAAI,EAAE,MAAM,aAAa,CAAC;AAO1D,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,WAAW,GAAG,WAAW,GAAG,SAAS,CAAC;AAEjF,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC/C,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,QAAQ,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvD,YAAY,EAAE,OAAO,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,kFAAkF;AAClF,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,aAAa,CAAC,WAAW,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,GAAE,IAAiB,EAAE,IAAI,GAAE;IAAE,MAAM,CAAC,EAAE,MAAM,CAAA;CAAO,GAAG,YAAY,CAoDtJ;AAKD,wBAAgB,oBAAoB,IAAI;IAAE,KAAK,EAAE,CAAC,GAAG,GAAG,CAAC;IAAC,MAAM,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;CAAE,CAmDzH"}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { discoveryEfficiency } from "./efficiency.js";
|
|
2
|
+
import { stopConfidence } from "./confidence.js";
|
|
3
|
+
import { assessAchievability } from "./achievability.js";
|
|
4
|
+
import { analyzeSensitivity } from "./sensitivity.js";
|
|
5
|
+
import { analyzeDrift } from "./drift.js";
|
|
6
|
+
/** Turn a finished discovery run into a plain-language decision + action plan. */
|
|
7
|
+
export function buildPrescription(obs, space, goal = "maximize", opts = {}) {
|
|
8
|
+
const dims = space?.dims ?? [];
|
|
9
|
+
const hist = (obs ?? []).filter((o) => o && o.experiment && Number.isFinite(o.value));
|
|
10
|
+
const n = hist.length;
|
|
11
|
+
if (!dims.length || n < 4) {
|
|
12
|
+
return { recipe: [], expected: NaN, vsStartPct: NaN, vsRandomPct: NaN, decision: "unknown", confidencePct: 0, robustnessPct: 0, trustPct: 0, tolerances: [], driftWarning: false, evaluations: n, note: `need ≈4+ measurements to prescribe (have ${n})` };
|
|
13
|
+
}
|
|
14
|
+
const sgn = goal === "minimize" ? -1 : 1;
|
|
15
|
+
const best = hist.reduce((a, b) => (sgn * b.value > sgn * a.value ? b : a));
|
|
16
|
+
const start = hist[0].value; // where they began
|
|
17
|
+
const mean = hist.reduce((s, o) => s + o.value, 0) / n; // blind / average
|
|
18
|
+
// honest improvement-% vs a reference: a relative % is only meaningful when the reference isn't ~0.
|
|
19
|
+
// When the baseline is a negligible fraction of the achieved scale, the ratio explodes into a
|
|
20
|
+
// meaningless mega-number (e.g. 286,000,000%), so we clamp to a sane, defensible ±1000% ceiling.
|
|
21
|
+
const pct = (from) => {
|
|
22
|
+
const scale = Math.max(Math.abs(from), Math.abs(best.value), 1e-9);
|
|
23
|
+
const tiny = Math.abs(from) < 0.005 * scale; // reference is effectively zero
|
|
24
|
+
const d = tiny ? (sgn * (best.value - from) > 0 ? 1000 : 0) : sgn * (best.value - from) / Math.abs(from) * 100;
|
|
25
|
+
return +Math.max(-1000, Math.min(1000, d)).toFixed(1);
|
|
26
|
+
};
|
|
27
|
+
const recipe = dims.map((d) => ({ name: d.name, value: +(+best.experiment[d.name]).toFixed(d.type === "int" ? 0 : 4) }));
|
|
28
|
+
// engine signals
|
|
29
|
+
const eff = discoveryEfficiency(hist, space, goal);
|
|
30
|
+
const conf = stopConfidence(hist, goal);
|
|
31
|
+
const sens = analyzeSensitivity(hist, space, goal);
|
|
32
|
+
const drift = analyzeDrift(hist, space, goal);
|
|
33
|
+
const achiev = (typeof opts.target === "number" && Number.isFinite(opts.target)) ? assessAchievability(hist, space, opts.target, goal) : null;
|
|
34
|
+
const confidencePct = Number.isFinite(conf.confidence) ? Math.round(conf.confidence * 100) : 0;
|
|
35
|
+
const robustnessPct = Number.isFinite(eff.robustness) ? Math.round(eff.robustness * 100) : 0;
|
|
36
|
+
const trustPct = Number.isFinite(eff.trust) ? Math.round(eff.trust * 100) : 0;
|
|
37
|
+
const tolerances = (sens?.variables ?? []).slice().sort((a, b) => b.importancePct - a.importancePct).slice(0, 3)
|
|
38
|
+
.map((v) => ({ name: v.name, plusMinus: +Math.abs(v.toleranceAbs).toFixed(Math.abs(v.toleranceAbs) < 1 ? 3 : 2) }));
|
|
39
|
+
// the decision — a transparent rule over the real signals
|
|
40
|
+
let decision;
|
|
41
|
+
if (achiev && achiev.verdict === "unreachable")
|
|
42
|
+
decision = "new-lever";
|
|
43
|
+
else if (eff.grade !== "unknown" && eff.eta < 0.4 && eff.weakestLink === "robustness")
|
|
44
|
+
decision = "refine";
|
|
45
|
+
else if (conf.recommendation === "stop")
|
|
46
|
+
decision = "ship";
|
|
47
|
+
else if (conf.recommendation === "continue")
|
|
48
|
+
decision = "more-data";
|
|
49
|
+
else
|
|
50
|
+
decision = "ship";
|
|
51
|
+
const note = decision === "ship" ? `SHIP: use ${recipe.map((r) => r.name + "=" + r.value).join(", ")} → ${(+best.value).toPrecision(4)} (+${pct(start)}% vs your first try); ${confidencePct}% confident this is the best.`
|
|
52
|
+
: decision === "more-data" ? `KEEP GOING: best so far ${(+best.value).toPrecision(4)} (+${pct(start)}% vs first try), still improving — a few more runs should help.`
|
|
53
|
+
: decision === "refine" ? `REFINE: ${(+best.value).toPrecision(4)} found, but the optimum is fragile (robustness ${robustnessPct}%) — explore nearby for a setting that survives real-world wobble.`
|
|
54
|
+
: decision === "new-lever" ? `NEW LEVER: target out of reach with these knobs (ceiling ~${achiev ? achiev.ceiling : "?"}) — add a new variable or relax the target.`
|
|
55
|
+
: `not enough data`;
|
|
56
|
+
return { recipe, expected: +(+best.value).toPrecision(6), vsStartPct: pct(start), vsRandomPct: pct(mean), decision, confidencePct, robustnessPct, trustPct, tolerances, driftWarning: !!drift.detected, evaluations: n, note };
|
|
57
|
+
}
|
|
58
|
+
// ── gauntlet ──────────────────────────────────────────────────────────────────
|
|
59
|
+
import { lcg } from "./space.js";
|
|
60
|
+
export function prescriptionGauntlet() {
|
|
61
|
+
const space = { dims: [{ name: "x", type: "real", min: 0, max: 1 }, { name: "y", type: "real", min: 0, max: 1 }] };
|
|
62
|
+
const broad = (x, y) => Math.exp(-(((x - 0.5) ** 2) + ((y - 0.5) ** 2)) / 0.5);
|
|
63
|
+
const sharp = (x, y) => Math.exp(-(((x - 0.5) ** 2) + ((y - 0.5) ** 2)) / 0.008);
|
|
64
|
+
// SHIP: converged on a broad robust optimum (records dried up, robust) → ship
|
|
65
|
+
const ship = [];
|
|
66
|
+
const rs = lcg(3);
|
|
67
|
+
for (let i = 0; i < 60; i++) {
|
|
68
|
+
const t = i / 60;
|
|
69
|
+
const x = 0.5 + (rs() - 0.5) * (1 - 0.85 * t), y = 0.5 + (rs() - 0.5) * (1 - 0.85 * t);
|
|
70
|
+
ship.push({ experiment: { x, y }, value: broad(x, y) });
|
|
71
|
+
}
|
|
72
|
+
const pShip = buildPrescription(ship, space, "maximize");
|
|
73
|
+
// MORE-DATA: every step a new record (still climbing) → keep going
|
|
74
|
+
const climb = [];
|
|
75
|
+
for (let i = 0; i < 40; i++) {
|
|
76
|
+
const x = i / 40, y = i / 40;
|
|
77
|
+
climb.push({ experiment: { x, y }, value: 0.5 * (x + y) });
|
|
78
|
+
}
|
|
79
|
+
const pClimb = buildPrescription(climb, space, "maximize");
|
|
80
|
+
// NEW-LEVER: a target above the achievable ceiling → find a new lever
|
|
81
|
+
const lev = [];
|
|
82
|
+
const rl = lcg(7);
|
|
83
|
+
for (let i = 0; i < 70; i++) {
|
|
84
|
+
const x = rl(), y = rl();
|
|
85
|
+
lev.push({ experiment: { x, y }, value: broad(x, y) });
|
|
86
|
+
}
|
|
87
|
+
const pLev = buildPrescription(lev, space, "maximize", { target: 5.0 });
|
|
88
|
+
// REFINE: converged but onto a sharp fragile spike → refine for robustness
|
|
89
|
+
const frag = [];
|
|
90
|
+
const rf = lcg(3);
|
|
91
|
+
for (let i = 0; i < 60; i++) {
|
|
92
|
+
const t = i / 60;
|
|
93
|
+
const x = 0.5 + (rf() - 0.5) * (1 - 0.85 * t), y = 0.5 + (rf() - 0.5) * (1 - 0.85 * t);
|
|
94
|
+
frag.push({ experiment: { x, y }, value: sharp(x, y) });
|
|
95
|
+
}
|
|
96
|
+
const pFrag = buildPrescription(frag, space, "maximize");
|
|
97
|
+
const shipOk = pShip.decision === "ship" && pShip.recipe.length === 2 && pShip.vsStartPct >= 0;
|
|
98
|
+
const climbOk = pClimb.decision === "more-data";
|
|
99
|
+
const levOk = pLev.decision === "new-lever";
|
|
100
|
+
const fragOk = pFrag.decision === "refine";
|
|
101
|
+
// RECIPE-IS-THE-BEST: the prescribed recipe equals the actual best-scoring experiment
|
|
102
|
+
const bestObs = ship.reduce((a, b) => (b.value > a.value ? b : a));
|
|
103
|
+
const recipeRight = Math.abs(pShip.recipe[0].value - bestObs.experiment.x) < 1e-3 && Math.abs(pShip.expected - bestObs.value) < 1e-3; // recipe is rounded for display
|
|
104
|
+
// PLAIN-LANGUAGE: the note contains the actual recipe + a vs-start improvement, no jargon
|
|
105
|
+
const plain = pShip.note.indexOf("SHIP") >= 0 && pShip.note.indexOf("vs your first try") >= 0;
|
|
106
|
+
const tolerances = pShip.tolerances.length >= 1 && pShip.tolerances.every((t) => t.plusMinus >= 0);
|
|
107
|
+
const det = JSON.stringify(buildPrescription(ship, space, "maximize")) === JSON.stringify(buildPrescription(ship, space, "maximize"));
|
|
108
|
+
const abstains = buildPrescription(ship.slice(0, 2), space, "maximize").decision === "unknown";
|
|
109
|
+
const total = (() => { try {
|
|
110
|
+
buildPrescription(null, space);
|
|
111
|
+
buildPrescription([], space, "minimize");
|
|
112
|
+
return true;
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
return false;
|
|
116
|
+
} })();
|
|
117
|
+
const checks = [
|
|
118
|
+
{ name: "SHIP-WHEN-CONVERGED-ROBUST", pass: shipOk, detail: `converged broad optimum → "${pShip.decision}" (+${pShip.vsStartPct}% vs start, ${pShip.confidencePct}% sure)` },
|
|
119
|
+
{ name: "MORE-DATA-WHEN-CLIMBING", pass: climbOk, detail: `still improving → "${pClimb.decision}"` },
|
|
120
|
+
{ name: "NEW-LEVER-WHEN-UNREACHABLE", pass: levOk, detail: `target 5.0 > ceiling → "${pLev.decision}"` },
|
|
121
|
+
{ name: "REFINE-WHEN-FRAGILE", pass: fragOk, detail: `sharp fragile optimum → "${pFrag.decision}" (robustness ${pFrag.robustnessPct}%)` },
|
|
122
|
+
{ name: "RECIPE-IS-THE-BEST", pass: recipeRight, detail: `prescribed recipe == the top-scoring run (${pShip.expected})` },
|
|
123
|
+
{ name: "PLAIN-LANGUAGE-NOTE", pass: plain, detail: "the verdict reads as an instruction, not math" },
|
|
124
|
+
{ name: "TOLERANCES-GIVEN", pass: tolerances, detail: `how tightly to hold each knob (${pShip.tolerances.map((t) => t.name + "±" + t.plusMinus).join(", ")})` },
|
|
125
|
+
{ name: "DETERMINISTIC", pass: det, detail: "same run → same prescription" },
|
|
126
|
+
{ name: "ABSTAINS-WHEN-THIN", pass: abstains, detail: "too few measurements → unknown" },
|
|
127
|
+
{ name: "TOTAL", pass: total, detail: "null / empty never throws" },
|
|
128
|
+
];
|
|
129
|
+
return { score: checks.every((c) => c.pass) ? 100 : 0, checks };
|
|
130
|
+
}
|
|
131
|
+
//# sourceMappingURL=prescription.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prescription.js","sourceRoot":"","sources":["../src/prescription.ts"],"names":[],"mappings":"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"}
|