@idlekit/cli 0.6.0 → 0.7.0

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.
@@ -8198,7 +8198,7 @@ var init_validate = __esm(() => {
8198
8198
  OFFLINE_ACTORS = new Set(["player", "automation"]);
8199
8199
  });
8200
8200
 
8201
- // ../../node_modules/.bun/typia@15.1.0+367f7514c87f1df1/node_modules/typia/lib/internal/_validateReport.mjs
8201
+ // ../../node_modules/.bun/typia@15.2.2+38c91d72aa8392f2/node_modules/typia/lib/internal/_validateReport.mjs
8202
8202
  var _validateReport = (array) => {
8203
8203
  const isAncestor = (ancestor, descendant) => descendant === ancestor || descendant.startsWith(`${ancestor}.`) || descendant.startsWith(`${ancestor}[`);
8204
8204
  const reportable = (path) => {
@@ -8223,7 +8223,7 @@ var _validateReport = (array) => {
8223
8223
  };
8224
8224
  var init__validateReport = () => {};
8225
8225
 
8226
- // ../../node_modules/.bun/typia@15.1.0+367f7514c87f1df1/node_modules/typia/lib/internal/_createStandardSchema.mjs
8226
+ // ../../node_modules/.bun/typia@15.2.2+38c91d72aa8392f2/node_modules/typia/lib/internal/_createStandardSchema.mjs
8227
8227
  var _createStandardSchema = (fn) => Object.assign(fn, { "~standard": {
8228
8228
  version: 1,
8229
8229
  vendor: "typia",
@@ -10404,6 +10404,14 @@ var init_goalRead = __esm(() => {
10404
10404
  ledgers = new WeakMap;
10405
10405
  });
10406
10406
 
10407
+ // ../core/dist/sim/milestoneKeys.js
10408
+ function actionMilestoneKeys(actionId) {
10409
+ return [`action.${actionId}.firstApplied`, "progress.first-upgrade"];
10410
+ }
10411
+ function mayRecordAtActionStart(key) {
10412
+ return key === "progress.first-upgrade" || key.startsWith("action.") && key.endsWith(".firstApplied");
10413
+ }
10414
+
10407
10415
  // ../core/dist/sim/observation.js
10408
10416
  function emitCommittedResets(observer, resets) {
10409
10417
  if (!observer?.onReset || resets.length === 0)
@@ -10584,7 +10592,11 @@ function createObservationRecorder(args) {
10584
10592
  milestones.push(sample);
10585
10593
  }
10586
10594
  if (args.observer?.onMilestone) {
10587
- notify(() => args.observer?.onMilestone?.({ t: sample.firstSeenT, key: sample.key }));
10595
+ notify(() => args.observer?.onMilestone?.({
10596
+ t: sample.firstSeenT,
10597
+ key: sample.key,
10598
+ phase: sample.source === "action" ? "action-start" : "income-end"
10599
+ }));
10588
10600
  }
10589
10601
  };
10590
10602
  const open = (goal) => !reachedGoals.has(goal.id) && !droppedGoals.has(goal.id);
@@ -10642,8 +10654,8 @@ function createObservationRecorder(args) {
10642
10654
  if (args.observer?.onAction) {
10643
10655
  notify(() => args.observer?.onAction?.({ t: step.t0, actionId: event.actionId, outcome: "applied" }));
10644
10656
  }
10645
- rememberMilestone({ key: `action.${event.actionId}.firstApplied`, firstSeenT: step.t0, source: "action" });
10646
- rememberMilestone({ key: "progress.first-upgrade", firstSeenT: step.t0, source: "action" });
10657
+ for (const key of actionMilestoneKeys(event.actionId))
10658
+ rememberMilestone({ key, firstSeenT: step.t0, source: "action" });
10647
10659
  } else if (event.type === "action.skipped") {
10648
10660
  if (event.reason === "cannotApply")
10649
10661
  actions.skippedCannotApply += 1;
@@ -12763,11 +12775,12 @@ function finiteAmountLog10(E, amount) {
12763
12775
  throw new RangeError("Tuning requires finite monetary amounts in the selected engine");
12764
12776
  const value = E.absLog10(amount);
12765
12777
  if (value === Number.NEGATIVE_INFINITY)
12766
- return -300;
12778
+ return ZERO_AMOUNT_LOG10_FLOOR;
12767
12779
  if (!Number.isFinite(value))
12768
12780
  throw new RangeError("Tuning requires a finite monetary logarithm");
12769
- return value;
12781
+ return Math.max(ZERO_AMOUNT_LOG10_FLOOR, value);
12770
12782
  }
12783
+ var ZERO_AMOUNT_LOG10_FLOOR = -300;
12771
12784
 
12772
12785
  // ../core/dist/sim/strategy/opt/objectives/builtins.js
12773
12786
  var builtinObjectiveFactories;
@@ -14875,15 +14888,16 @@ function readBenefit(vars) {
14875
14888
  const value = vars.benefit;
14876
14889
  return typeof value === "number" && Number.isFinite(value) ? value : null;
14877
14890
  }
14878
- function observeMetrics(E, spec, end, startT, reachedAt, elapsedSec) {
14891
+ function observeMetrics(E, spec, end, moneyElapsedSec, milestoneElapsedSec, elapsedSec) {
14879
14892
  const amount = end.wallet.money.amount;
14880
14893
  const benefit = readBenefit(end.vars);
14881
14894
  return metricIds(spec).map((metricId) => {
14882
- if (metricId === "timeToMoney") {
14883
- if (reachedAt === undefined) {
14884
- return { metricId, status: "censored", value: null, lowerBound: { sec: elapsedSec, strict: true } };
14895
+ if (metricId === "timeToMoney" || metricId === "timeToMilestone") {
14896
+ const elapsed = metricId === "timeToMoney" ? moneyElapsedSec : milestoneElapsedSec;
14897
+ if (elapsed === undefined) {
14898
+ const strict = metricId === "timeToMoney" || !mayRecordAtActionStart(spec.milestoneKey ?? "");
14899
+ return { metricId, status: "censored", value: null, lowerBound: { sec: elapsedSec, strict } };
14885
14900
  }
14886
- const elapsed = reachedAt - startT;
14887
14901
  return { metricId, status: "observed", value: String(elapsed), num: elapsed };
14888
14902
  }
14889
14903
  if (metricId === "endMoney") {
@@ -14906,7 +14920,7 @@ function aggregate(E, rows, metricId) {
14906
14920
  }
14907
14921
  if (picked.some((metric) => metric.status !== "observed" || metric.value === null)) {
14908
14922
  const bounded = picked.every((metric) => metric.num !== undefined || metric.lowerBound !== undefined);
14909
- if (metricId !== "timeToMoney" || !bounded)
14923
+ if (metricId !== "timeToMoney" && metricId !== "timeToMilestone" || !bounded)
14910
14924
  return { metricId, status: "censored", value: null };
14911
14925
  const bounds = picked.map((metric) => metric.num ?? metric.lowerBound.sec);
14912
14926
  const total = bounds.reduce((sum, bound) => sum + bound, 0);
@@ -14993,6 +15007,10 @@ function prepareExperiment(request) {
14993
15007
  reject("goal target must be finite");
14994
15008
  if (metrics.includes("timeToMoney") && spec.goal === undefined)
14995
15009
  reject("timeToMoney requires a finite goal target");
15010
+ if (spec.milestoneKey !== undefined && spec.milestoneKey.trim().length === 0)
15011
+ reject("milestoneKey must not be blank");
15012
+ if (metrics.includes("timeToMilestone") && spec.milestoneKey === undefined)
15013
+ reject("timeToMilestone requires milestoneKey");
14996
15014
  if (!isJsonData(request.spec, new Set, true))
14997
15015
  reject("spec must be JSON data, because the spec hashes record it as JSON");
14998
15016
  requireScenarioData(request.scenario);
@@ -15019,7 +15037,8 @@ function checkExperimentSpec(request) {
15019
15037
  }
15020
15038
  function runExperiment(request) {
15021
15039
  const { spec, metrics, base, prepared, specHashes } = prepareExperiment(request);
15022
- const measuresReach = metrics.includes("timeToMoney");
15040
+ const measuresMoney = metrics.includes("timeToMoney");
15041
+ const measuresMilestone = metrics.includes("timeToMilestone");
15023
15042
  const E = request.engine;
15024
15043
  const { strategy: _scenarioStrategy, ...withoutStrategy } = request.scenario;
15025
15044
  const compiled = compileScenario({
@@ -15038,7 +15057,7 @@ function runExperiment(request) {
15038
15057
  models: request.modelRegistry,
15039
15058
  strategies: request.strategyRegistry
15040
15059
  });
15041
- const target = measuresReach && spec.goal !== undefined ? E.from(spec.goal.target) : undefined;
15060
+ const target = measuresMoney && spec.goal !== undefined ? E.from(spec.goal.target) : undefined;
15042
15061
  const stopAtReach = metrics.every((metricId) => metricId === "timeToMoney");
15043
15062
  const tasks = [];
15044
15063
  const perCandidate = [];
@@ -15063,21 +15082,41 @@ function runExperiment(request) {
15063
15082
  try {
15064
15083
  const opened = binding.fresh({ trialId: taskId, seed, plan });
15065
15084
  const scenario = opened.scenario;
15066
- let reachedAt;
15085
+ let moneyElapsedSec;
15086
+ let milestoneElapsedSec;
15087
+ let observedElapsedSec = 0;
15088
+ let stepStartElapsedSec = 0;
15067
15089
  const result = runScenario({
15068
15090
  ...scenario,
15069
15091
  run: {
15070
15092
  ...scenario.run,
15093
+ ...measuresMoney || measuresMilestone ? {
15094
+ observation: { ...scenario.run.observation, enabled: true, ...measuresMilestone ? { maxMilestones: 0 } : {} },
15095
+ observer: {
15096
+ ...scenario.run.observer,
15097
+ onStep: (fact) => {
15098
+ stepStartElapsedSec = observedElapsedSec;
15099
+ observedElapsedSec += fact.dt;
15100
+ scenario.run.observer?.onStep?.(fact);
15101
+ },
15102
+ onMilestone: (fact) => {
15103
+ if (measuresMilestone && milestoneElapsedSec === undefined && fact.key === spec.milestoneKey) {
15104
+ milestoneElapsedSec = fact.phase === "action-start" ? stepStartElapsedSec : observedElapsedSec;
15105
+ }
15106
+ scenario.run.observer?.onMilestone?.(fact);
15107
+ }
15108
+ }
15109
+ } : {},
15071
15110
  ...target !== undefined ? {
15072
15111
  until: (state) => {
15073
- if (reachedAt === undefined && E.cmp(state.wallet.money.amount, target) >= 0)
15074
- reachedAt = state.t;
15075
- return stopAtReach && reachedAt !== undefined;
15112
+ if (moneyElapsedSec === undefined && E.cmp(state.wallet.money.amount, target) >= 0)
15113
+ moneyElapsedSec = observedElapsedSec;
15114
+ return stopAtReach && moneyElapsedSec !== undefined;
15076
15115
  }
15077
15116
  } : {}
15078
15117
  }
15079
15118
  });
15080
- readings = observeMetrics(E, spec, result.end, result.start.t, reachedAt, runElapsedSec(result));
15119
+ readings = observeMetrics(E, spec, result.end, moneyElapsedSec, milestoneElapsedSec, runElapsedSec(result));
15081
15120
  } catch {
15082
15121
  readings = failedMetrics(spec);
15083
15122
  }
@@ -15165,6 +15204,7 @@ function runExperiment(request) {
15165
15204
  originalSpecHash: specHashes.original,
15166
15205
  effectiveSpecHash: specHashes.effective,
15167
15206
  effectiveRunHash: request.effectiveRunHash,
15207
+ ...measuresMilestone ? { milestoneKey: spec.milestoneKey } : {},
15168
15208
  budget: {
15169
15209
  candidates: spec.budget.candidates,
15170
15210
  seeds: spec.budget.seeds,
@@ -15194,30 +15234,31 @@ var EXPERIMENT_ALGORITHM_VERSION = "experiment-oat-v1", EXPERIMENT_ESTIMATOR_VER
15194
15234
  const _ip8 = (input) => typeof input["originalSpecHash"] === "string";
15195
15235
  const _ip9 = (input) => typeof input["effectiveSpecHash"] === "string";
15196
15236
  const _ip10 = (input) => typeof input["effectiveRunHash"] === "string";
15197
- const _ip11 = (input) => typeof input["budget"] === "object" && input["budget"] !== null && _io2(input["budget"]);
15198
- const _ip12 = (input) => Array.isArray(input["tasks"]) && input["tasks"].every((elem) => typeof elem === "object" && elem !== null && _io3(elem));
15199
- const _ip13 = (input) => Array.isArray(input["candidates"]) && input["candidates"].every((elem) => typeof elem === "object" && elem !== null && _io4(elem));
15200
- const _ip14 = (input) => Array.isArray(input["elasticities"]) && input["elasticities"].every((elem) => typeof elem === "object" && elem !== null && _io6(elem));
15201
- const _ip15 = (input) => typeof input["pareto"] === "object" && input["pareto"] !== null && _io7(input["pareto"]);
15202
- const _ip16 = (input) => Array.isArray(input["warnings"]) && input["warnings"].every((elem) => typeof elem === "string");
15203
- const _ip17 = (input) => typeof input["taskId"] === "string";
15204
- const _ip18 = (input) => typeof input["candidateId"] === "string";
15205
- const _ip19 = (input) => typeof input["logicalSeed"] === "number";
15206
- const _ip20 = (input) => typeof input["engineId"] === "string";
15207
- const _ip21 = (input) => typeof input["engineVersion"] === "string";
15208
- const _ip22 = (input) => typeof input["modelId"] === "string";
15209
- const _ip23 = (input) => typeof input["modelVersion"] === "number";
15210
- const _ip24 = (input) => input["strategyId"] === null || typeof input["strategyId"] === "string";
15211
- const _ip25 = (input) => typeof input["modelParams"] === "string";
15212
- const _ip26 = (input) => typeof input["strategyParams"] === "string";
15213
- const _ip27 = (input) => typeof input["sessionPattern"] === "string";
15214
- const _ip28 = (input) => typeof input["sessionDays"] === "number";
15215
- const _ip29 = (input) => typeof input["horizonSec"] === "number";
15216
- const _ip30 = (input) => typeof input["stepSec"] === "number";
15217
- const _ip31 = (input) => input["metricId"] === "endMoney" || input["metricId"] === "timeToMoney" || input["metricId"] === "varBenefit";
15218
- const _ip32 = (input) => input["status"] === "censored" || input["status"] === "failed" || input["status"] === "observed" || input["status"] === "rejected";
15219
- const _ip33 = (input) => input["value"] === null || typeof input["value"] === "string";
15220
- const _ve0 = 'Readonly<{ schemaVersion: 1; contract: "idlekit.experiment.v1"; estimatorVersion: "one-at-a-time-local-v1"; algorithmVersion: "experiment-oat-v1"; method: "fixed-sweep-and-one-at-a-time"; ... 11 more ...; warnings: readonly string[]; }>';
15237
+ const _ip11 = (input) => input["milestoneKey"] === undefined || typeof input["milestoneKey"] === "string";
15238
+ const _ip12 = (input) => typeof input["budget"] === "object" && input["budget"] !== null && _io2(input["budget"]);
15239
+ const _ip13 = (input) => Array.isArray(input["tasks"]) && input["tasks"].every((elem) => typeof elem === "object" && elem !== null && _io3(elem));
15240
+ const _ip14 = (input) => Array.isArray(input["candidates"]) && input["candidates"].every((elem) => typeof elem === "object" && elem !== null && _io4(elem));
15241
+ const _ip15 = (input) => Array.isArray(input["elasticities"]) && input["elasticities"].every((elem) => typeof elem === "object" && elem !== null && _io6(elem));
15242
+ const _ip16 = (input) => typeof input["pareto"] === "object" && input["pareto"] !== null && _io7(input["pareto"]);
15243
+ const _ip17 = (input) => Array.isArray(input["warnings"]) && input["warnings"].every((elem) => typeof elem === "string");
15244
+ const _ip18 = (input) => typeof input["taskId"] === "string";
15245
+ const _ip19 = (input) => typeof input["candidateId"] === "string";
15246
+ const _ip20 = (input) => typeof input["logicalSeed"] === "number";
15247
+ const _ip21 = (input) => typeof input["engineId"] === "string";
15248
+ const _ip22 = (input) => typeof input["engineVersion"] === "string";
15249
+ const _ip23 = (input) => typeof input["modelId"] === "string";
15250
+ const _ip24 = (input) => typeof input["modelVersion"] === "number";
15251
+ const _ip25 = (input) => input["strategyId"] === null || typeof input["strategyId"] === "string";
15252
+ const _ip26 = (input) => typeof input["modelParams"] === "string";
15253
+ const _ip27 = (input) => typeof input["strategyParams"] === "string";
15254
+ const _ip28 = (input) => typeof input["sessionPattern"] === "string";
15255
+ const _ip29 = (input) => typeof input["sessionDays"] === "number";
15256
+ const _ip30 = (input) => typeof input["horizonSec"] === "number";
15257
+ const _ip31 = (input) => typeof input["stepSec"] === "number";
15258
+ const _ip32 = (input) => input["metricId"] === "endMoney" || input["metricId"] === "timeToMilestone" || input["metricId"] === "timeToMoney" || input["metricId"] === "varBenefit";
15259
+ const _ip33 = (input) => input["status"] === "censored" || input["status"] === "failed" || input["status"] === "observed" || input["status"] === "rejected";
15260
+ const _ip34 = (input) => input["value"] === null || typeof input["value"] === "string";
15261
+ const _ve0 = 'Readonly<{ schemaVersion: 1; contract: "idlekit.experiment.v1"; estimatorVersion: "one-at-a-time-local-v1"; algorithmVersion: "experiment-oat-v1"; method: "fixed-sweep-and-one-at-a-time"; ... 12 more ...; warnings: readonly string[]; }>';
15221
15262
  const _vp0 = (input, _path, _exceptionable = true) => input["schemaVersion"] === 1 || _report(_exceptionable, {
15222
15263
  path: _path + ".schemaVersion",
15223
15264
  expected: "1",
@@ -15277,7 +15318,12 @@ var EXPERIMENT_ALGORITHM_VERSION = "experiment-oat-v1", EXPERIMENT_ESTIMATOR_VER
15277
15318
  expected: "string",
15278
15319
  value: input["effectiveRunHash"]
15279
15320
  });
15280
- const _vp11 = (input, _path, _exceptionable = true) => (typeof input["budget"] === "object" && input["budget"] !== null || _report(_exceptionable, {
15321
+ const _vp11 = (input, _path, _exceptionable = true) => input["milestoneKey"] === undefined || typeof input["milestoneKey"] === "string" || _report(_exceptionable, {
15322
+ path: _path + ".milestoneKey",
15323
+ expected: "(string | undefined)",
15324
+ value: input["milestoneKey"]
15325
+ });
15326
+ const _vp12 = (input, _path, _exceptionable = true) => (typeof input["budget"] === "object" && input["budget"] !== null || _report(_exceptionable, {
15281
15327
  path: _path + ".budget",
15282
15328
  expected: "Readonly<{ candidates: number; seeds: number; usedCandidates: number; usedSeeds: number; }>",
15283
15329
  value: input["budget"]
@@ -15286,7 +15332,7 @@ var EXPERIMENT_ALGORITHM_VERSION = "experiment-oat-v1", EXPERIMENT_ESTIMATOR_VER
15286
15332
  expected: "Readonly<{ candidates: number; seeds: number; usedCandidates: number; usedSeeds: number; }>",
15287
15333
  value: input["budget"]
15288
15334
  });
15289
- const _vp12 = (input, _path, _exceptionable = true) => (Array.isArray(input["tasks"]) || _report(_exceptionable, {
15335
+ const _vp13 = (input, _path, _exceptionable = true) => (Array.isArray(input["tasks"]) || _report(_exceptionable, {
15290
15336
  path: _path + ".tasks",
15291
15337
  expected: _ve2,
15292
15338
  value: input["tasks"]
@@ -15305,7 +15351,7 @@ var EXPERIMENT_ALGORITHM_VERSION = "experiment-oat-v1", EXPERIMENT_ESTIMATOR_VER
15305
15351
  });
15306
15352
  const _ve1 = "Readonly<{ taskId: string; candidateId: string; logicalSeed: number; engineId: string; engineVersion: string; modelId: string; modelVersion: number; strategyId: string | null; modelParams: string; ... 7 more ...; value: string | null; }>";
15307
15353
  const _ve2 = "ReadonlyArray<Readonly<{ taskId: string; candidateId: string; logicalSeed: number; engineId: string; engineVersion: string; modelId: string; modelVersion: number; strategyId: string | null; modelParams: string; ... 7 more ...; value: string | null; }>>";
15308
- const _vp13 = (input, _path, _exceptionable = true) => (Array.isArray(input["candidates"]) || _report(_exceptionable, {
15354
+ const _vp14 = (input, _path, _exceptionable = true) => (Array.isArray(input["candidates"]) || _report(_exceptionable, {
15309
15355
  path: _path + ".candidates",
15310
15356
  expected: _ve4,
15311
15357
  value: input["candidates"]
@@ -15324,7 +15370,7 @@ var EXPERIMENT_ALGORITHM_VERSION = "experiment-oat-v1", EXPERIMENT_ESTIMATOR_VER
15324
15370
  });
15325
15371
  const _ve3 = "Readonly<{ id: string; metrics: readonly Readonly<{ metricId: ExperimentMetricId; status: ExperimentMetricStatus; value: string | null; }>[]; constraintViolations: readonly string[]; }>";
15326
15372
  const _ve4 = "ReadonlyArray<Readonly<{ id: string; metrics: readonly Readonly<{ metricId: ExperimentMetricId; status: ExperimentMetricStatus; value: string | null; }>[]; constraintViolations: readonly string[]; }>>";
15327
- const _vp14 = (input, _path, _exceptionable = true) => (Array.isArray(input["elasticities"]) || _report(_exceptionable, {
15373
+ const _vp15 = (input, _path, _exceptionable = true) => (Array.isArray(input["elasticities"]) || _report(_exceptionable, {
15328
15374
  path: _path + ".elasticities",
15329
15375
  expected: _ve6,
15330
15376
  value: input["elasticities"]
@@ -15343,7 +15389,7 @@ var EXPERIMENT_ALGORITHM_VERSION = "experiment-oat-v1", EXPERIMENT_ESTIMATOR_VER
15343
15389
  });
15344
15390
  const _ve5 = 'Readonly<{ dimensionId: string; candidateId: string; metricId: ExperimentMetricId; method: "one-at-a-time-local"; methodVersion: 1; globalSensitivity: false; sobol: false; status: "observed" | "unavailable"; elasticity: string | null; absoluteChange: string | null; direction: "flat" | ... 2 more ... | "unavailable";...';
15345
15391
  const _ve6 = 'ReadonlyArray<Readonly<{ dimensionId: string; candidateId: string; metricId: ExperimentMetricId; method: "one-at-a-time-local"; methodVersion: 1; globalSensitivity: false; sobol: false; status: "observed" | "unavailable"; elasticity: string | null; absoluteChange: string | null; direction: "flat" | ... 2 more ... | "unavailable";...>';
15346
- const _vp15 = (input, _path, _exceptionable = true) => (typeof input["pareto"] === "object" && input["pareto"] !== null || _report(_exceptionable, {
15392
+ const _vp16 = (input, _path, _exceptionable = true) => (typeof input["pareto"] === "object" && input["pareto"] !== null || _report(_exceptionable, {
15347
15393
  path: _path + ".pareto",
15348
15394
  expected: 'Readonly<{ sense: "per-metric"; nonDominated: readonly string[]; uncompared: readonly string[]; }>',
15349
15395
  value: input["pareto"]
@@ -15352,7 +15398,7 @@ var EXPERIMENT_ALGORITHM_VERSION = "experiment-oat-v1", EXPERIMENT_ESTIMATOR_VER
15352
15398
  expected: 'Readonly<{ sense: "per-metric"; nonDominated: readonly string[]; uncompared: readonly string[]; }>',
15353
15399
  value: input["pareto"]
15354
15400
  });
15355
- const _vp16 = (input, _path, _exceptionable = true) => (Array.isArray(input["warnings"]) || _report(_exceptionable, {
15401
+ const _vp17 = (input, _path, _exceptionable = true) => (Array.isArray(input["warnings"]) || _report(_exceptionable, {
15356
15402
  path: _path + ".warnings",
15357
15403
  expected: "ReadonlyArray<string>",
15358
15404
  value: input["warnings"]
@@ -15365,100 +15411,100 @@ var EXPERIMENT_ALGORITHM_VERSION = "experiment-oat-v1", EXPERIMENT_ESTIMATOR_VER
15365
15411
  expected: "ReadonlyArray<string>",
15366
15412
  value: input["warnings"]
15367
15413
  });
15368
- const _vp17 = (input, _path, _exceptionable = true) => typeof input["taskId"] === "string" || _report(_exceptionable, {
15414
+ const _vp18 = (input, _path, _exceptionable = true) => typeof input["taskId"] === "string" || _report(_exceptionable, {
15369
15415
  path: _path + ".taskId",
15370
15416
  expected: "string",
15371
15417
  value: input["taskId"]
15372
15418
  });
15373
- const _vp18 = (input, _path, _exceptionable = true) => typeof input["candidateId"] === "string" || _report(_exceptionable, {
15419
+ const _vp19 = (input, _path, _exceptionable = true) => typeof input["candidateId"] === "string" || _report(_exceptionable, {
15374
15420
  path: _path + ".candidateId",
15375
15421
  expected: "string",
15376
15422
  value: input["candidateId"]
15377
15423
  });
15378
- const _vp19 = (input, _path, _exceptionable = true) => typeof input["logicalSeed"] === "number" || _report(_exceptionable, {
15424
+ const _vp20 = (input, _path, _exceptionable = true) => typeof input["logicalSeed"] === "number" || _report(_exceptionable, {
15379
15425
  path: _path + ".logicalSeed",
15380
15426
  expected: "number",
15381
15427
  value: input["logicalSeed"]
15382
15428
  });
15383
- const _vp20 = (input, _path, _exceptionable = true) => typeof input["engineId"] === "string" || _report(_exceptionable, {
15429
+ const _vp21 = (input, _path, _exceptionable = true) => typeof input["engineId"] === "string" || _report(_exceptionable, {
15384
15430
  path: _path + ".engineId",
15385
15431
  expected: "string",
15386
15432
  value: input["engineId"]
15387
15433
  });
15388
- const _vp21 = (input, _path, _exceptionable = true) => typeof input["engineVersion"] === "string" || _report(_exceptionable, {
15434
+ const _vp22 = (input, _path, _exceptionable = true) => typeof input["engineVersion"] === "string" || _report(_exceptionable, {
15389
15435
  path: _path + ".engineVersion",
15390
15436
  expected: "string",
15391
15437
  value: input["engineVersion"]
15392
15438
  });
15393
- const _vp22 = (input, _path, _exceptionable = true) => typeof input["modelId"] === "string" || _report(_exceptionable, {
15439
+ const _vp23 = (input, _path, _exceptionable = true) => typeof input["modelId"] === "string" || _report(_exceptionable, {
15394
15440
  path: _path + ".modelId",
15395
15441
  expected: "string",
15396
15442
  value: input["modelId"]
15397
15443
  });
15398
- const _vp23 = (input, _path, _exceptionable = true) => typeof input["modelVersion"] === "number" || _report(_exceptionable, {
15444
+ const _vp24 = (input, _path, _exceptionable = true) => typeof input["modelVersion"] === "number" || _report(_exceptionable, {
15399
15445
  path: _path + ".modelVersion",
15400
15446
  expected: "number",
15401
15447
  value: input["modelVersion"]
15402
15448
  });
15403
- const _vp24 = (input, _path, _exceptionable = true) => input["strategyId"] === null || typeof input["strategyId"] === "string" || _report(_exceptionable, {
15449
+ const _vp25 = (input, _path, _exceptionable = true) => input["strategyId"] === null || typeof input["strategyId"] === "string" || _report(_exceptionable, {
15404
15450
  path: _path + ".strategyId",
15405
15451
  expected: "(null | string)",
15406
15452
  value: input["strategyId"]
15407
15453
  });
15408
- const _vp25 = (input, _path, _exceptionable = true) => typeof input["modelParams"] === "string" || _report(_exceptionable, {
15454
+ const _vp26 = (input, _path, _exceptionable = true) => typeof input["modelParams"] === "string" || _report(_exceptionable, {
15409
15455
  path: _path + ".modelParams",
15410
15456
  expected: "string",
15411
15457
  value: input["modelParams"]
15412
15458
  });
15413
- const _vp26 = (input, _path, _exceptionable = true) => typeof input["strategyParams"] === "string" || _report(_exceptionable, {
15459
+ const _vp27 = (input, _path, _exceptionable = true) => typeof input["strategyParams"] === "string" || _report(_exceptionable, {
15414
15460
  path: _path + ".strategyParams",
15415
15461
  expected: "string",
15416
15462
  value: input["strategyParams"]
15417
15463
  });
15418
- const _vp27 = (input, _path, _exceptionable = true) => typeof input["sessionPattern"] === "string" || _report(_exceptionable, {
15464
+ const _vp28 = (input, _path, _exceptionable = true) => typeof input["sessionPattern"] === "string" || _report(_exceptionable, {
15419
15465
  path: _path + ".sessionPattern",
15420
15466
  expected: "string",
15421
15467
  value: input["sessionPattern"]
15422
15468
  });
15423
- const _vp28 = (input, _path, _exceptionable = true) => typeof input["sessionDays"] === "number" || _report(_exceptionable, {
15469
+ const _vp29 = (input, _path, _exceptionable = true) => typeof input["sessionDays"] === "number" || _report(_exceptionable, {
15424
15470
  path: _path + ".sessionDays",
15425
15471
  expected: "number",
15426
15472
  value: input["sessionDays"]
15427
15473
  });
15428
- const _vp29 = (input, _path, _exceptionable = true) => typeof input["horizonSec"] === "number" || _report(_exceptionable, {
15474
+ const _vp30 = (input, _path, _exceptionable = true) => typeof input["horizonSec"] === "number" || _report(_exceptionable, {
15429
15475
  path: _path + ".horizonSec",
15430
15476
  expected: "number",
15431
15477
  value: input["horizonSec"]
15432
15478
  });
15433
- const _vp30 = (input, _path, _exceptionable = true) => typeof input["stepSec"] === "number" || _report(_exceptionable, {
15479
+ const _vp31 = (input, _path, _exceptionable = true) => typeof input["stepSec"] === "number" || _report(_exceptionable, {
15434
15480
  path: _path + ".stepSec",
15435
15481
  expected: "number",
15436
15482
  value: input["stepSec"]
15437
15483
  });
15438
- const _vp31 = (input, _path, _exceptionable = true) => input["metricId"] === "endMoney" || input["metricId"] === "timeToMoney" || input["metricId"] === "varBenefit" || _report(_exceptionable, {
15484
+ const _vp32 = (input, _path, _exceptionable = true) => input["metricId"] === "endMoney" || input["metricId"] === "timeToMilestone" || input["metricId"] === "timeToMoney" || input["metricId"] === "varBenefit" || _report(_exceptionable, {
15439
15485
  path: _path + ".metricId",
15440
- expected: '("endMoney" | "timeToMoney" | "varBenefit")',
15486
+ expected: '("endMoney" | "timeToMilestone" | "timeToMoney" | "varBenefit")',
15441
15487
  value: input["metricId"]
15442
15488
  });
15443
- const _vp32 = (input, _path, _exceptionable = true) => input["status"] === "censored" || input["status"] === "failed" || input["status"] === "observed" || input["status"] === "rejected" || _report(_exceptionable, {
15489
+ const _vp33 = (input, _path, _exceptionable = true) => input["status"] === "censored" || input["status"] === "failed" || input["status"] === "observed" || input["status"] === "rejected" || _report(_exceptionable, {
15444
15490
  path: _path + ".status",
15445
15491
  expected: '("censored" | "failed" | "observed" | "rejected")',
15446
15492
  value: input["status"]
15447
15493
  });
15448
- const _vp33 = (input, _path, _exceptionable = true) => input["value"] === null || typeof input["value"] === "string" || _report(_exceptionable, {
15494
+ const _vp34 = (input, _path, _exceptionable = true) => input["value"] === null || typeof input["value"] === "string" || _report(_exceptionable, {
15449
15495
  path: _path + ".value",
15450
15496
  expected: "(null | string)",
15451
15497
  value: input["value"]
15452
15498
  });
15453
- const _io0 = (input) => _ip0(input) && _ip1(input) && _ip2(input) && _ip3(input) && _ip4(input) && _ip5(input) && _ip6(input) && _ip7(input) && _ip8(input) && _ip9(input) && _ip10(input) && _ip11(input) && _ip12(input) && _ip13(input) && _ip14(input) && _ip15(input) && _ip16(input);
15499
+ const _io0 = (input) => _ip0(input) && _ip1(input) && _ip2(input) && _ip3(input) && _ip4(input) && _ip5(input) && _ip6(input) && _ip7(input) && _ip8(input) && _ip9(input) && _ip10(input) && _ip11(input) && _ip12(input) && _ip13(input) && _ip14(input) && _ip15(input) && _ip16(input) && _ip17(input);
15454
15500
  const _io1 = (input) => typeof input.ref === "string" && typeof input.hash === "string";
15455
15501
  const _io2 = (input) => typeof input.candidates === "number" && typeof input.seeds === "number" && typeof input.usedCandidates === "number" && typeof input.usedSeeds === "number";
15456
- const _io3 = (input) => _ip17(input) && _ip18(input) && _ip19(input) && _ip20(input) && _ip21(input) && _ip22(input) && _ip23(input) && _ip24(input) && _ip25(input) && _ip26(input) && _ip27(input) && _ip28(input) && _ip29(input) && _ip30(input) && _ip31(input) && _ip32(input) && _ip33(input);
15502
+ const _io3 = (input) => _ip18(input) && _ip19(input) && _ip20(input) && _ip21(input) && _ip22(input) && _ip23(input) && _ip24(input) && _ip25(input) && _ip26(input) && _ip27(input) && _ip28(input) && _ip29(input) && _ip30(input) && _ip31(input) && _ip32(input) && _ip33(input) && _ip34(input);
15457
15503
  const _io4 = (input) => typeof input.id === "string" && (Array.isArray(input.metrics) && input.metrics.every((elem) => typeof elem === "object" && elem !== null && _io5(elem))) && (Array.isArray(input.constraintViolations) && input.constraintViolations.every((elem) => typeof elem === "string"));
15458
- const _io5 = (input) => _ip31(input) && _ip32(input) && _ip33(input);
15459
- const _io6 = (input) => typeof input.dimensionId === "string" && _ip18(input) && _ip31(input) && input.method === "one-at-a-time-local" && input.methodVersion === 1 && _ip5(input) && _ip6(input) && (input.status === "observed" || input.status === "unavailable") && (input.elasticity === null || typeof input.elasticity === "string") && (input.absoluteChange === null || typeof input.absoluteChange === "string") && (input.direction === "flat" || input.direction === "higher" || input.direction === "lower" || input.direction === "unavailable");
15504
+ const _io5 = (input) => _ip32(input) && _ip33(input) && _ip34(input);
15505
+ const _io6 = (input) => typeof input.dimensionId === "string" && _ip19(input) && _ip32(input) && input.method === "one-at-a-time-local" && input.methodVersion === 1 && _ip5(input) && _ip6(input) && (input.status === "observed" || input.status === "unavailable") && (input.elasticity === null || typeof input.elasticity === "string") && (input.absoluteChange === null || typeof input.absoluteChange === "string") && (input.direction === "flat" || input.direction === "higher" || input.direction === "lower" || input.direction === "unavailable");
15460
15506
  const _io7 = (input) => input.sense === "per-metric" && (Array.isArray(input.nonDominated) && input.nonDominated.every((elem) => typeof elem === "string")) && (Array.isArray(input.uncompared) && input.uncompared.every((elem) => typeof elem === "string"));
15461
- const _vo0 = (input, _path, _exceptionable = true) => [_vp0(input, _path, _exceptionable), _vp1(input, _path, _exceptionable), _vp2(input, _path, _exceptionable), _vp3(input, _path, _exceptionable), _vp4(input, _path, _exceptionable), _vp5(input, _path, _exceptionable), _vp6(input, _path, _exceptionable), _vp7(input, _path, _exceptionable), _vp8(input, _path, _exceptionable), _vp9(input, _path, _exceptionable), _vp10(input, _path, _exceptionable), _vp11(input, _path, _exceptionable), _vp12(input, _path, _exceptionable), _vp13(input, _path, _exceptionable), _vp14(input, _path, _exceptionable), _vp15(input, _path, _exceptionable), _vp16(input, _path, _exceptionable)].every((flag) => flag);
15507
+ const _vo0 = (input, _path, _exceptionable = true) => [_vp0(input, _path, _exceptionable), _vp1(input, _path, _exceptionable), _vp2(input, _path, _exceptionable), _vp3(input, _path, _exceptionable), _vp4(input, _path, _exceptionable), _vp5(input, _path, _exceptionable), _vp6(input, _path, _exceptionable), _vp7(input, _path, _exceptionable), _vp8(input, _path, _exceptionable), _vp9(input, _path, _exceptionable), _vp10(input, _path, _exceptionable), _vp11(input, _path, _exceptionable), _vp12(input, _path, _exceptionable), _vp13(input, _path, _exceptionable), _vp14(input, _path, _exceptionable), _vp15(input, _path, _exceptionable), _vp16(input, _path, _exceptionable), _vp17(input, _path, _exceptionable)].every((flag) => flag);
15462
15508
  const _vo1 = (input, _path, _exceptionable = true) => [typeof input.ref === "string" || _report(_exceptionable, {
15463
15509
  path: _path + ".ref",
15464
15510
  expected: "string",
@@ -15485,7 +15531,7 @@ var EXPERIMENT_ALGORITHM_VERSION = "experiment-oat-v1", EXPERIMENT_ESTIMATOR_VER
15485
15531
  expected: "number",
15486
15532
  value: input.usedSeeds
15487
15533
  })].every((flag) => flag);
15488
- const _vo3 = (input, _path, _exceptionable = true) => [_vp17(input, _path, _exceptionable), _vp18(input, _path, _exceptionable), _vp19(input, _path, _exceptionable), _vp20(input, _path, _exceptionable), _vp21(input, _path, _exceptionable), _vp22(input, _path, _exceptionable), _vp23(input, _path, _exceptionable), _vp24(input, _path, _exceptionable), _vp25(input, _path, _exceptionable), _vp26(input, _path, _exceptionable), _vp27(input, _path, _exceptionable), _vp28(input, _path, _exceptionable), _vp29(input, _path, _exceptionable), _vp30(input, _path, _exceptionable), _vp31(input, _path, _exceptionable), _vp32(input, _path, _exceptionable), _vp33(input, _path, _exceptionable)].every((flag) => flag);
15534
+ const _vo3 = (input, _path, _exceptionable = true) => [_vp18(input, _path, _exceptionable), _vp19(input, _path, _exceptionable), _vp20(input, _path, _exceptionable), _vp21(input, _path, _exceptionable), _vp22(input, _path, _exceptionable), _vp23(input, _path, _exceptionable), _vp24(input, _path, _exceptionable), _vp25(input, _path, _exceptionable), _vp26(input, _path, _exceptionable), _vp27(input, _path, _exceptionable), _vp28(input, _path, _exceptionable), _vp29(input, _path, _exceptionable), _vp30(input, _path, _exceptionable), _vp31(input, _path, _exceptionable), _vp32(input, _path, _exceptionable), _vp33(input, _path, _exceptionable), _vp34(input, _path, _exceptionable)].every((flag) => flag);
15489
15535
  const _vo4 = (input, _path, _exceptionable = true) => [typeof input.id === "string" || _report(_exceptionable, {
15490
15536
  path: _path + ".id",
15491
15537
  expected: "string",
@@ -15519,12 +15565,12 @@ var EXPERIMENT_ALGORITHM_VERSION = "experiment-oat-v1", EXPERIMENT_ESTIMATOR_VER
15519
15565
  expected: "ReadonlyArray<string>",
15520
15566
  value: input.constraintViolations
15521
15567
  })].every((flag) => flag);
15522
- const _vo5 = (input, _path, _exceptionable = true) => [_vp31(input, _path, _exceptionable), _vp32(input, _path, _exceptionable), _vp33(input, _path, _exceptionable)].every((flag) => flag);
15568
+ const _vo5 = (input, _path, _exceptionable = true) => [_vp32(input, _path, _exceptionable), _vp33(input, _path, _exceptionable), _vp34(input, _path, _exceptionable)].every((flag) => flag);
15523
15569
  const _vo6 = (input, _path, _exceptionable = true) => [typeof input.dimensionId === "string" || _report(_exceptionable, {
15524
15570
  path: _path + ".dimensionId",
15525
15571
  expected: "string",
15526
15572
  value: input.dimensionId
15527
- }), _vp18(input, _path, _exceptionable), _vp31(input, _path, _exceptionable), input.method === "one-at-a-time-local" || _report(_exceptionable, {
15573
+ }), _vp19(input, _path, _exceptionable), _vp32(input, _path, _exceptionable), input.method === "one-at-a-time-local" || _report(_exceptionable, {
15528
15574
  path: _path + ".method",
15529
15575
  expected: '"one-at-a-time-local"',
15530
15576
  value: input.method
@@ -15610,105 +15656,82 @@ var EXPERIMENT_ALGORITHM_VERSION = "experiment-oat-v1", EXPERIMENT_ESTIMATOR_VER
15610
15656
  };
15611
15657
  });
15612
15658
  })())(input), validateExperimentSpecValidator, validateExperimentSpec = (input) => (validateExperimentSpecValidator ??= (() => {
15613
- const _ip0 = (input) => input["metricId"] === "endMoney" || input["metricId"] === "timeToMoney" || input["metricId"] === "varBenefit";
15614
- const _ip1 = (input) => typeof input["id"] === "string";
15615
- const _ip2 = (input) => typeof input["min"] === "number";
15616
- const _ip3 = (input) => typeof input["max"] === "number";
15617
- const _ve0 = "Readonly<{ schemaVersion: 1; scenario: Readonly<{ ref: string; hash: string; }>; model: Readonly<{ id: string; version: number; }>; strategy?: Readonly<{ id: string; }> | undefined; ... 10 more ...; session: Readonly<...>; }>";
15618
- const _vp0 = (input, _path, _exceptionable = true) => input["metricId"] === "endMoney" || input["metricId"] === "timeToMoney" || input["metricId"] === "varBenefit" || _report(_exceptionable, {
15619
- path: _path + ".metricId",
15620
- expected: '("endMoney" | "timeToMoney" | "varBenefit")',
15621
- value: input["metricId"]
15622
- });
15623
- const _ve1 = 'Readonly<{ id: string; target: "model" | "session" | "strategy"; path: string; space: ExperimentParamSpace; baseline: ExperimentScalar; probes?: readonly ExperimentScalar[] | undefined; }>';
15624
- const _ve2 = 'ReadonlyArray<Readonly<{ id: string; target: "model" | "session" | "strategy"; path: string; space: ExperimentParamSpace; baseline: ExperimentScalar; probes?: readonly ExperimentScalar[] | undefined; }>>';
15625
- const _ve3 = "(ReadonlyArray<Readonly<{ id: string; assignments: readonly Readonly<{ dimensionId: string; value: ExperimentScalar; }>[]; }>> | undefined)";
15626
- const _vp1 = (input, _path, _exceptionable = true) => typeof input["id"] === "string" || _report(_exceptionable, {
15627
- path: _path + ".id",
15628
- expected: "string",
15629
- value: input["id"]
15630
- });
15631
- const _ve4 = '(Readonly<{ kind: "bool"; }> | Readonly<{ kind: "choice"; values: readonly ExperimentScalar[]; }> | Readonly<{ kind: "int"; min: number; max: number; }> | Readonly<{ kind: "number"; min: number; max: number; scale?: "linear" | "log" | undefined; }>)';
15632
- const _vp2 = (input, _path, _exceptionable = true) => typeof input["min"] === "number" || _report(_exceptionable, {
15633
- path: _path + ".min",
15634
- expected: "number",
15635
- value: input["min"]
15636
- });
15637
- const _vp3 = (input, _path, _exceptionable = true) => typeof input["max"] === "number" || _report(_exceptionable, {
15638
- path: _path + ".max",
15639
- expected: "number",
15640
- value: input["max"]
15641
- });
15642
- const _ve5 = '(Readonly<{ kind: "bool"; }> | Readonly<{ kind: "int"; min: number; max: number; }> | Readonly<{ kind: "number"; min: number; max: number; scale?: "linear" | "log" | undefined; }> | Readonly<{ kind: "choice"; values: readonly ExperimentScalar[]; }>)';
15643
- const _io0 = (input) => input.schemaVersion === 1 && (typeof input.scenario === "object" && input.scenario !== null && _io1(input.scenario)) && (typeof input.model === "object" && input.model !== null && _io2(input.model)) && (input.strategy === undefined || typeof input.strategy === "object" && input.strategy !== null && _io3(input.strategy)) && _ip0(input) && (input.goal === undefined || typeof input.goal === "object" && input.goal !== null && _io4(input.goal)) && (input.objectives === undefined || Array.isArray(input.objectives) && input.objectives.every((elem) => typeof elem === "object" && elem !== null && _io5(elem))) && (input.constraints === undefined || Array.isArray(input.constraints) && input.constraints.every((elem) => typeof elem === "object" && elem !== null && _io6(elem))) && (Array.isArray(input.dimensions) && input.dimensions.every((elem) => typeof elem === "object" && elem !== null && _io7(elem))) && (input.candidates === undefined || Array.isArray(input.candidates) && input.candidates.every((elem) => typeof elem === "object" && elem !== null && _io12(elem))) && (typeof input.budget === "object" && input.budget !== null && _io14(input.budget)) && (Array.isArray(input.seeds) && input.seeds.every((elem) => typeof elem === "number")) && typeof input.horizonSec === "number" && typeof input.stepSec === "number" && (typeof input.session === "object" && input.session !== null && _io15(input.session));
15644
- const _io1 = (input) => typeof input.ref === "string" && typeof input.hash === "string";
15645
- const _io10 = (input) => input.kind === "number" && _ip2(input) && _ip3(input) && (input.scale === undefined || input.scale === "linear" || input.scale === "log");
15646
- const _io11 = (input) => input.kind === "choice" && (Array.isArray(input.values) && input.values.every((elem) => elem === null || typeof elem === "string" || typeof elem === "number" || typeof elem === "boolean"));
15647
- const _io12 = (input) => _ip1(input) && (Array.isArray(input.assignments) && input.assignments.every((elem) => typeof elem === "object" && elem !== null && _io13(elem)));
15648
- const _io13 = (input) => typeof input.dimensionId === "string" && (input.value === null || typeof input.value === "string" || typeof input.value === "number" || typeof input.value === "boolean");
15649
- const _io14 = (input) => typeof input.candidates === "number" && typeof input.seeds === "number";
15650
- const _io15 = (input) => typeof input.pattern === "string" && typeof input.days === "number";
15651
- const _io2 = (input) => _ip1(input) && typeof input.version === "number";
15652
- const _io3 = (input) => _ip1(input);
15653
- const _io4 = (input) => typeof input.target === "number";
15654
- const _io5 = (input) => _ip1(input) && _ip0(input) && (input.sense === "higher" || input.sense === "lower");
15655
- const _io6 = (input) => _ip1(input) && _ip0(input) && (input.op === "gte" || input.op === "lte") && typeof input.limit === "number";
15656
- const _io7 = (input) => _ip1(input) && (input.target === "model" || input.target === "session" || input.target === "strategy") && typeof input.path === "string" && (typeof input.space === "object" && input.space !== null && _iu0(input.space)) && (input.baseline === null || typeof input.baseline === "string" || typeof input.baseline === "number" || typeof input.baseline === "boolean") && (input.probes === undefined || Array.isArray(input.probes) && input.probes.every((elem) => elem === null || typeof elem === "string" || typeof elem === "number" || typeof elem === "boolean"));
15657
- const _io8 = (input) => input.kind === "bool";
15658
- const _io9 = (input) => input.kind === "int" && _ip2(input) && _ip3(input);
15659
- const _iu0 = (input) => (() => {
15660
- if (input.kind === "bool")
15661
- return _io8(input);
15662
- else if (input.kind === "int")
15663
- return _io9(input);
15664
- else if (input.kind === "number")
15665
- return _io10(input);
15666
- else if (input.kind === "choice")
15667
- return _io11(input);
15668
- else
15669
- return false;
15670
- })();
15671
- const _vo0 = (input, _path, _exceptionable = true) => [input.schemaVersion === 1 || _report(_exceptionable, {
15659
+ const _ip0 = (input) => input["schemaVersion"] === 1;
15660
+ const _ip1 = (input) => typeof input["scenario"] === "object" && input["scenario"] !== null && _io1(input["scenario"]);
15661
+ const _ip2 = (input) => typeof input["model"] === "object" && input["model"] !== null && _io2(input["model"]);
15662
+ const _ip3 = (input) => input["strategy"] === undefined || typeof input["strategy"] === "object" && input["strategy"] !== null && _io3(input["strategy"]);
15663
+ const _ip4 = (input) => input["metricId"] === "endMoney" || input["metricId"] === "timeToMilestone" || input["metricId"] === "timeToMoney" || input["metricId"] === "varBenefit";
15664
+ const _ip5 = (input) => input["goal"] === undefined || typeof input["goal"] === "object" && input["goal"] !== null && _io4(input["goal"]);
15665
+ const _ip6 = (input) => input["milestoneKey"] === undefined || typeof input["milestoneKey"] === "string";
15666
+ const _ip7 = (input) => input["objectives"] === undefined || Array.isArray(input["objectives"]) && input["objectives"].every((elem) => typeof elem === "object" && elem !== null && _io5(elem));
15667
+ const _ip8 = (input) => input["constraints"] === undefined || Array.isArray(input["constraints"]) && input["constraints"].every((elem) => typeof elem === "object" && elem !== null && _io6(elem));
15668
+ const _ip9 = (input) => Array.isArray(input["dimensions"]) && input["dimensions"].every((elem) => typeof elem === "object" && elem !== null && _io7(elem));
15669
+ const _ip10 = (input) => input["candidates"] === undefined || Array.isArray(input["candidates"]) && input["candidates"].every((elem) => typeof elem === "object" && elem !== null && _io12(elem));
15670
+ const _ip11 = (input) => typeof input["budget"] === "object" && input["budget"] !== null && _io14(input["budget"]);
15671
+ const _ip12 = (input) => Array.isArray(input["seeds"]) && input["seeds"].every((elem) => typeof elem === "number");
15672
+ const _ip13 = (input) => typeof input["horizonSec"] === "number";
15673
+ const _ip14 = (input) => typeof input["stepSec"] === "number";
15674
+ const _ip15 = (input) => typeof input["session"] === "object" && input["session"] !== null && _io15(input["session"]);
15675
+ const _ip16 = (input) => typeof input["id"] === "string";
15676
+ const _ip17 = (input) => typeof input["min"] === "number";
15677
+ const _ip18 = (input) => typeof input["max"] === "number";
15678
+ const _ve0 = "Readonly<{ schemaVersion: 1; scenario: Readonly<{ ref: string; hash: string; }>; model: Readonly<{ id: string; version: number; }>; strategy?: Readonly<{ id: string; }> | undefined; ... 11 more ...; session: Readonly<...>; }>";
15679
+ const _vp0 = (input, _path, _exceptionable = true) => input["schemaVersion"] === 1 || _report(_exceptionable, {
15672
15680
  path: _path + ".schemaVersion",
15673
15681
  expected: "1",
15674
- value: input.schemaVersion
15675
- }), (typeof input.scenario === "object" && input.scenario !== null || _report(_exceptionable, {
15682
+ value: input["schemaVersion"]
15683
+ });
15684
+ const _vp1 = (input, _path, _exceptionable = true) => (typeof input["scenario"] === "object" && input["scenario"] !== null || _report(_exceptionable, {
15676
15685
  path: _path + ".scenario",
15677
15686
  expected: "Readonly<{ ref: string; hash: string; }>",
15678
- value: input.scenario
15679
- })) && _vo1(input.scenario, _path + ".scenario", _exceptionable) || _report(_exceptionable, {
15687
+ value: input["scenario"]
15688
+ })) && _vo1(input["scenario"], _path + ".scenario", _exceptionable) || _report(_exceptionable, {
15680
15689
  path: _path + ".scenario",
15681
15690
  expected: "Readonly<{ ref: string; hash: string; }>",
15682
- value: input.scenario
15683
- }), (typeof input.model === "object" && input.model !== null || _report(_exceptionable, {
15691
+ value: input["scenario"]
15692
+ });
15693
+ const _vp2 = (input, _path, _exceptionable = true) => (typeof input["model"] === "object" && input["model"] !== null || _report(_exceptionable, {
15684
15694
  path: _path + ".model",
15685
15695
  expected: "Readonly<{ id: string; version: number; }>",
15686
- value: input.model
15687
- })) && _vo2(input.model, _path + ".model", _exceptionable) || _report(_exceptionable, {
15696
+ value: input["model"]
15697
+ })) && _vo2(input["model"], _path + ".model", _exceptionable) || _report(_exceptionable, {
15688
15698
  path: _path + ".model",
15689
15699
  expected: "Readonly<{ id: string; version: number; }>",
15690
- value: input.model
15691
- }), input.strategy === undefined || (typeof input.strategy === "object" && input.strategy !== null || _report(_exceptionable, {
15700
+ value: input["model"]
15701
+ });
15702
+ const _vp3 = (input, _path, _exceptionable = true) => input["strategy"] === undefined || (typeof input["strategy"] === "object" && input["strategy"] !== null || _report(_exceptionable, {
15692
15703
  path: _path + ".strategy",
15693
15704
  expected: "(Readonly<{ id: string; }> | undefined)",
15694
- value: input.strategy
15695
- })) && _vo3(input.strategy, _path + ".strategy", _exceptionable) || _report(_exceptionable, {
15705
+ value: input["strategy"]
15706
+ })) && _vo3(input["strategy"], _path + ".strategy", _exceptionable) || _report(_exceptionable, {
15696
15707
  path: _path + ".strategy",
15697
15708
  expected: "(Readonly<{ id: string; }> | undefined)",
15698
- value: input.strategy
15699
- }), _vp0(input, _path, _exceptionable), input.goal === undefined || (typeof input.goal === "object" && input.goal !== null || _report(_exceptionable, {
15709
+ value: input["strategy"]
15710
+ });
15711
+ const _vp4 = (input, _path, _exceptionable = true) => input["metricId"] === "endMoney" || input["metricId"] === "timeToMilestone" || input["metricId"] === "timeToMoney" || input["metricId"] === "varBenefit" || _report(_exceptionable, {
15712
+ path: _path + ".metricId",
15713
+ expected: '("endMoney" | "timeToMilestone" | "timeToMoney" | "varBenefit")',
15714
+ value: input["metricId"]
15715
+ });
15716
+ const _vp5 = (input, _path, _exceptionable = true) => input["goal"] === undefined || (typeof input["goal"] === "object" && input["goal"] !== null || _report(_exceptionable, {
15700
15717
  path: _path + ".goal",
15701
15718
  expected: "(Readonly<{ target: number; }> | undefined)",
15702
- value: input.goal
15703
- })) && _vo4(input.goal, _path + ".goal", _exceptionable) || _report(_exceptionable, {
15719
+ value: input["goal"]
15720
+ })) && _vo4(input["goal"], _path + ".goal", _exceptionable) || _report(_exceptionable, {
15704
15721
  path: _path + ".goal",
15705
15722
  expected: "(Readonly<{ target: number; }> | undefined)",
15706
- value: input.goal
15707
- }), input.objectives === undefined || (Array.isArray(input.objectives) || _report(_exceptionable, {
15723
+ value: input["goal"]
15724
+ });
15725
+ const _vp6 = (input, _path, _exceptionable = true) => input["milestoneKey"] === undefined || typeof input["milestoneKey"] === "string" || _report(_exceptionable, {
15726
+ path: _path + ".milestoneKey",
15727
+ expected: "(string | undefined)",
15728
+ value: input["milestoneKey"]
15729
+ });
15730
+ const _vp7 = (input, _path, _exceptionable = true) => input["objectives"] === undefined || (Array.isArray(input["objectives"]) || _report(_exceptionable, {
15708
15731
  path: _path + ".objectives",
15709
15732
  expected: '(ReadonlyArray<Readonly<{ id: string; metricId: ExperimentMetricId; sense: "higher" | "lower"; }>> | undefined)',
15710
- value: input.objectives
15711
- })) && input.objectives.map((elem, _index9) => (typeof elem === "object" && elem !== null || _report(_exceptionable, {
15733
+ value: input["objectives"]
15734
+ })) && input["objectives"].map((elem, _index9) => (typeof elem === "object" && elem !== null || _report(_exceptionable, {
15712
15735
  path: _path + ".objectives[" + _index9 + "]",
15713
15736
  expected: 'Readonly<{ id: string; metricId: ExperimentMetricId; sense: "higher" | "lower"; }>',
15714
15737
  value: elem
@@ -15719,12 +15742,13 @@ var EXPERIMENT_ALGORITHM_VERSION = "experiment-oat-v1", EXPERIMENT_ESTIMATOR_VER
15719
15742
  })).every((flag) => flag) || _report(_exceptionable, {
15720
15743
  path: _path + ".objectives",
15721
15744
  expected: '(ReadonlyArray<Readonly<{ id: string; metricId: ExperimentMetricId; sense: "higher" | "lower"; }>> | undefined)',
15722
- value: input.objectives
15723
- }), input.constraints === undefined || (Array.isArray(input.constraints) || _report(_exceptionable, {
15745
+ value: input["objectives"]
15746
+ });
15747
+ const _vp8 = (input, _path, _exceptionable = true) => input["constraints"] === undefined || (Array.isArray(input["constraints"]) || _report(_exceptionable, {
15724
15748
  path: _path + ".constraints",
15725
15749
  expected: '(ReadonlyArray<Readonly<{ id: string; metricId: ExperimentMetricId; op: "gte" | "lte"; limit: number; }>> | undefined)',
15726
- value: input.constraints
15727
- })) && input.constraints.map((elem, _index10) => (typeof elem === "object" && elem !== null || _report(_exceptionable, {
15750
+ value: input["constraints"]
15751
+ })) && input["constraints"].map((elem, _index10) => (typeof elem === "object" && elem !== null || _report(_exceptionable, {
15728
15752
  path: _path + ".constraints[" + _index10 + "]",
15729
15753
  expected: 'Readonly<{ id: string; metricId: ExperimentMetricId; op: "gte" | "lte"; limit: number; }>',
15730
15754
  value: elem
@@ -15735,12 +15759,13 @@ var EXPERIMENT_ALGORITHM_VERSION = "experiment-oat-v1", EXPERIMENT_ESTIMATOR_VER
15735
15759
  })).every((flag) => flag) || _report(_exceptionable, {
15736
15760
  path: _path + ".constraints",
15737
15761
  expected: '(ReadonlyArray<Readonly<{ id: string; metricId: ExperimentMetricId; op: "gte" | "lte"; limit: number; }>> | undefined)',
15738
- value: input.constraints
15739
- }), (Array.isArray(input.dimensions) || _report(_exceptionable, {
15762
+ value: input["constraints"]
15763
+ });
15764
+ const _vp9 = (input, _path, _exceptionable = true) => (Array.isArray(input["dimensions"]) || _report(_exceptionable, {
15740
15765
  path: _path + ".dimensions",
15741
15766
  expected: _ve2,
15742
- value: input.dimensions
15743
- })) && input.dimensions.map((elem, _index11) => (typeof elem === "object" && elem !== null || _report(_exceptionable, {
15767
+ value: input["dimensions"]
15768
+ })) && input["dimensions"].map((elem, _index11) => (typeof elem === "object" && elem !== null || _report(_exceptionable, {
15744
15769
  path: _path + ".dimensions[" + _index11 + "]",
15745
15770
  expected: _ve1,
15746
15771
  value: elem
@@ -15751,12 +15776,15 @@ var EXPERIMENT_ALGORITHM_VERSION = "experiment-oat-v1", EXPERIMENT_ESTIMATOR_VER
15751
15776
  })).every((flag) => flag) || _report(_exceptionable, {
15752
15777
  path: _path + ".dimensions",
15753
15778
  expected: _ve2,
15754
- value: input.dimensions
15755
- }), input.candidates === undefined || (Array.isArray(input.candidates) || _report(_exceptionable, {
15779
+ value: input["dimensions"]
15780
+ });
15781
+ const _ve1 = 'Readonly<{ id: string; target: "model" | "session" | "strategy"; path: string; space: ExperimentParamSpace; baseline: ExperimentScalar; probes?: readonly ExperimentScalar[] | undefined; }>';
15782
+ const _ve2 = 'ReadonlyArray<Readonly<{ id: string; target: "model" | "session" | "strategy"; path: string; space: ExperimentParamSpace; baseline: ExperimentScalar; probes?: readonly ExperimentScalar[] | undefined; }>>';
15783
+ const _vp10 = (input, _path, _exceptionable = true) => input["candidates"] === undefined || (Array.isArray(input["candidates"]) || _report(_exceptionable, {
15756
15784
  path: _path + ".candidates",
15757
15785
  expected: _ve3,
15758
- value: input.candidates
15759
- })) && input.candidates.map((elem, _index12) => (typeof elem === "object" && elem !== null || _report(_exceptionable, {
15786
+ value: input["candidates"]
15787
+ })) && input["candidates"].map((elem, _index12) => (typeof elem === "object" && elem !== null || _report(_exceptionable, {
15760
15788
  path: _path + ".candidates[" + _index12 + "]",
15761
15789
  expected: "Readonly<{ id: string; assignments: readonly Readonly<{ dimensionId: string; value: ExperimentScalar; }>[]; }>",
15762
15790
  value: elem
@@ -15767,44 +15795,96 @@ var EXPERIMENT_ALGORITHM_VERSION = "experiment-oat-v1", EXPERIMENT_ESTIMATOR_VER
15767
15795
  })).every((flag) => flag) || _report(_exceptionable, {
15768
15796
  path: _path + ".candidates",
15769
15797
  expected: _ve3,
15770
- value: input.candidates
15771
- }), (typeof input.budget === "object" && input.budget !== null || _report(_exceptionable, {
15798
+ value: input["candidates"]
15799
+ });
15800
+ const _ve3 = "(ReadonlyArray<Readonly<{ id: string; assignments: readonly Readonly<{ dimensionId: string; value: ExperimentScalar; }>[]; }>> | undefined)";
15801
+ const _vp11 = (input, _path, _exceptionable = true) => (typeof input["budget"] === "object" && input["budget"] !== null || _report(_exceptionable, {
15772
15802
  path: _path + ".budget",
15773
15803
  expected: "Readonly<{ candidates: number; seeds: number; }>",
15774
- value: input.budget
15775
- })) && _vo14(input.budget, _path + ".budget", _exceptionable) || _report(_exceptionable, {
15804
+ value: input["budget"]
15805
+ })) && _vo14(input["budget"], _path + ".budget", _exceptionable) || _report(_exceptionable, {
15776
15806
  path: _path + ".budget",
15777
15807
  expected: "Readonly<{ candidates: number; seeds: number; }>",
15778
- value: input.budget
15779
- }), (Array.isArray(input.seeds) || _report(_exceptionable, {
15808
+ value: input["budget"]
15809
+ });
15810
+ const _vp12 = (input, _path, _exceptionable = true) => (Array.isArray(input["seeds"]) || _report(_exceptionable, {
15780
15811
  path: _path + ".seeds",
15781
15812
  expected: "ReadonlyArray<number>",
15782
- value: input.seeds
15783
- })) && input.seeds.map((elem, _index13) => typeof elem === "number" || _report(_exceptionable, {
15813
+ value: input["seeds"]
15814
+ })) && input["seeds"].map((elem, _index13) => typeof elem === "number" || _report(_exceptionable, {
15784
15815
  path: _path + ".seeds[" + _index13 + "]",
15785
15816
  expected: "number",
15786
15817
  value: elem
15787
15818
  })).every((flag) => flag) || _report(_exceptionable, {
15788
15819
  path: _path + ".seeds",
15789
15820
  expected: "ReadonlyArray<number>",
15790
- value: input.seeds
15791
- }), typeof input.horizonSec === "number" || _report(_exceptionable, {
15821
+ value: input["seeds"]
15822
+ });
15823
+ const _vp13 = (input, _path, _exceptionable = true) => typeof input["horizonSec"] === "number" || _report(_exceptionable, {
15792
15824
  path: _path + ".horizonSec",
15793
15825
  expected: "number",
15794
- value: input.horizonSec
15795
- }), typeof input.stepSec === "number" || _report(_exceptionable, {
15826
+ value: input["horizonSec"]
15827
+ });
15828
+ const _vp14 = (input, _path, _exceptionable = true) => typeof input["stepSec"] === "number" || _report(_exceptionable, {
15796
15829
  path: _path + ".stepSec",
15797
15830
  expected: "number",
15798
- value: input.stepSec
15799
- }), (typeof input.session === "object" && input.session !== null || _report(_exceptionable, {
15831
+ value: input["stepSec"]
15832
+ });
15833
+ const _vp15 = (input, _path, _exceptionable = true) => (typeof input["session"] === "object" && input["session"] !== null || _report(_exceptionable, {
15800
15834
  path: _path + ".session",
15801
15835
  expected: "Readonly<{ pattern: string; days: number; }>",
15802
- value: input.session
15803
- })) && _vo15(input.session, _path + ".session", _exceptionable) || _report(_exceptionable, {
15836
+ value: input["session"]
15837
+ })) && _vo15(input["session"], _path + ".session", _exceptionable) || _report(_exceptionable, {
15804
15838
  path: _path + ".session",
15805
15839
  expected: "Readonly<{ pattern: string; days: number; }>",
15806
- value: input.session
15807
- })].every((flag) => flag);
15840
+ value: input["session"]
15841
+ });
15842
+ const _vp16 = (input, _path, _exceptionable = true) => typeof input["id"] === "string" || _report(_exceptionable, {
15843
+ path: _path + ".id",
15844
+ expected: "string",
15845
+ value: input["id"]
15846
+ });
15847
+ const _ve4 = '(Readonly<{ kind: "bool"; }> | Readonly<{ kind: "choice"; values: readonly ExperimentScalar[]; }> | Readonly<{ kind: "int"; min: number; max: number; }> | Readonly<{ kind: "number"; min: number; max: number; scale?: "linear" | "log" | undefined; }>)';
15848
+ const _vp17 = (input, _path, _exceptionable = true) => typeof input["min"] === "number" || _report(_exceptionable, {
15849
+ path: _path + ".min",
15850
+ expected: "number",
15851
+ value: input["min"]
15852
+ });
15853
+ const _vp18 = (input, _path, _exceptionable = true) => typeof input["max"] === "number" || _report(_exceptionable, {
15854
+ path: _path + ".max",
15855
+ expected: "number",
15856
+ value: input["max"]
15857
+ });
15858
+ const _ve5 = '(Readonly<{ kind: "bool"; }> | Readonly<{ kind: "int"; min: number; max: number; }> | Readonly<{ kind: "number"; min: number; max: number; scale?: "linear" | "log" | undefined; }> | Readonly<{ kind: "choice"; values: readonly ExperimentScalar[]; }>)';
15859
+ const _io0 = (input) => _ip0(input) && _ip1(input) && _ip2(input) && _ip3(input) && _ip4(input) && _ip5(input) && _ip6(input) && _ip7(input) && _ip8(input) && _ip9(input) && _ip10(input) && _ip11(input) && _ip12(input) && _ip13(input) && _ip14(input) && _ip15(input);
15860
+ const _io1 = (input) => typeof input.ref === "string" && typeof input.hash === "string";
15861
+ const _io10 = (input) => input.kind === "number" && _ip17(input) && _ip18(input) && (input.scale === undefined || input.scale === "linear" || input.scale === "log");
15862
+ const _io11 = (input) => input.kind === "choice" && (Array.isArray(input.values) && input.values.every((elem) => elem === null || typeof elem === "string" || typeof elem === "number" || typeof elem === "boolean"));
15863
+ const _io12 = (input) => _ip16(input) && (Array.isArray(input.assignments) && input.assignments.every((elem) => typeof elem === "object" && elem !== null && _io13(elem)));
15864
+ const _io13 = (input) => typeof input.dimensionId === "string" && (input.value === null || typeof input.value === "string" || typeof input.value === "number" || typeof input.value === "boolean");
15865
+ const _io14 = (input) => typeof input.candidates === "number" && typeof input.seeds === "number";
15866
+ const _io15 = (input) => typeof input.pattern === "string" && typeof input.days === "number";
15867
+ const _io2 = (input) => _ip16(input) && typeof input.version === "number";
15868
+ const _io3 = (input) => _ip16(input);
15869
+ const _io4 = (input) => typeof input.target === "number";
15870
+ const _io5 = (input) => _ip16(input) && _ip4(input) && (input.sense === "higher" || input.sense === "lower");
15871
+ const _io6 = (input) => _ip16(input) && _ip4(input) && (input.op === "gte" || input.op === "lte") && typeof input.limit === "number";
15872
+ const _io7 = (input) => _ip16(input) && (input.target === "model" || input.target === "session" || input.target === "strategy") && typeof input.path === "string" && (typeof input.space === "object" && input.space !== null && _iu0(input.space)) && (input.baseline === null || typeof input.baseline === "string" || typeof input.baseline === "number" || typeof input.baseline === "boolean") && (input.probes === undefined || Array.isArray(input.probes) && input.probes.every((elem) => elem === null || typeof elem === "string" || typeof elem === "number" || typeof elem === "boolean"));
15873
+ const _io8 = (input) => input.kind === "bool";
15874
+ const _io9 = (input) => input.kind === "int" && _ip17(input) && _ip18(input);
15875
+ const _iu0 = (input) => (() => {
15876
+ if (input.kind === "bool")
15877
+ return _io8(input);
15878
+ else if (input.kind === "int")
15879
+ return _io9(input);
15880
+ else if (input.kind === "number")
15881
+ return _io10(input);
15882
+ else if (input.kind === "choice")
15883
+ return _io11(input);
15884
+ else
15885
+ return false;
15886
+ })();
15887
+ const _vo0 = (input, _path, _exceptionable = true) => [_vp0(input, _path, _exceptionable), _vp1(input, _path, _exceptionable), _vp2(input, _path, _exceptionable), _vp3(input, _path, _exceptionable), _vp4(input, _path, _exceptionable), _vp5(input, _path, _exceptionable), _vp6(input, _path, _exceptionable), _vp7(input, _path, _exceptionable), _vp8(input, _path, _exceptionable), _vp9(input, _path, _exceptionable), _vp10(input, _path, _exceptionable), _vp11(input, _path, _exceptionable), _vp12(input, _path, _exceptionable), _vp13(input, _path, _exceptionable), _vp14(input, _path, _exceptionable), _vp15(input, _path, _exceptionable)].every((flag) => flag);
15808
15888
  const _vo1 = (input, _path, _exceptionable = true) => [typeof input.ref === "string" || _report(_exceptionable, {
15809
15889
  path: _path + ".ref",
15810
15890
  expected: "string",
@@ -15818,7 +15898,7 @@ var EXPERIMENT_ALGORITHM_VERSION = "experiment-oat-v1", EXPERIMENT_ESTIMATOR_VER
15818
15898
  path: _path + ".kind",
15819
15899
  expected: '"number"',
15820
15900
  value: input.kind
15821
- }), _vp2(input, _path, _exceptionable), _vp3(input, _path, _exceptionable), input.scale === undefined || input.scale === "linear" || input.scale === "log" || _report(_exceptionable, {
15901
+ }), _vp17(input, _path, _exceptionable), _vp18(input, _path, _exceptionable), input.scale === undefined || input.scale === "linear" || input.scale === "log" || _report(_exceptionable, {
15822
15902
  path: _path + ".scale",
15823
15903
  expected: '("linear" | "log" | undefined)',
15824
15904
  value: input.scale
@@ -15840,7 +15920,7 @@ var EXPERIMENT_ALGORITHM_VERSION = "experiment-oat-v1", EXPERIMENT_ESTIMATOR_VER
15840
15920
  expected: "ReadonlyArray<ExperimentScalar>",
15841
15921
  value: input.values
15842
15922
  })].every((flag) => flag);
15843
- const _vo12 = (input, _path, _exceptionable = true) => [_vp1(input, _path, _exceptionable), (Array.isArray(input.assignments) || _report(_exceptionable, {
15923
+ const _vo12 = (input, _path, _exceptionable = true) => [_vp16(input, _path, _exceptionable), (Array.isArray(input.assignments) || _report(_exceptionable, {
15844
15924
  path: _path + ".assignments",
15845
15925
  expected: "ReadonlyArray<Readonly<{ dimensionId: string; value: ExperimentScalar; }>>",
15846
15926
  value: input.assignments
@@ -15884,23 +15964,23 @@ var EXPERIMENT_ALGORITHM_VERSION = "experiment-oat-v1", EXPERIMENT_ESTIMATOR_VER
15884
15964
  expected: "number",
15885
15965
  value: input.days
15886
15966
  })].every((flag) => flag);
15887
- const _vo2 = (input, _path, _exceptionable = true) => [_vp1(input, _path, _exceptionable), typeof input.version === "number" || _report(_exceptionable, {
15967
+ const _vo2 = (input, _path, _exceptionable = true) => [_vp16(input, _path, _exceptionable), typeof input.version === "number" || _report(_exceptionable, {
15888
15968
  path: _path + ".version",
15889
15969
  expected: "number",
15890
15970
  value: input.version
15891
15971
  })].every((flag) => flag);
15892
- const _vo3 = (input, _path, _exceptionable = true) => [_vp1(input, _path, _exceptionable)].every((flag) => flag);
15972
+ const _vo3 = (input, _path, _exceptionable = true) => [_vp16(input, _path, _exceptionable)].every((flag) => flag);
15893
15973
  const _vo4 = (input, _path, _exceptionable = true) => [typeof input.target === "number" || _report(_exceptionable, {
15894
15974
  path: _path + ".target",
15895
15975
  expected: "number",
15896
15976
  value: input.target
15897
15977
  })].every((flag) => flag);
15898
- const _vo5 = (input, _path, _exceptionable = true) => [_vp1(input, _path, _exceptionable), _vp0(input, _path, _exceptionable), input.sense === "higher" || input.sense === "lower" || _report(_exceptionable, {
15978
+ const _vo5 = (input, _path, _exceptionable = true) => [_vp16(input, _path, _exceptionable), _vp4(input, _path, _exceptionable), input.sense === "higher" || input.sense === "lower" || _report(_exceptionable, {
15899
15979
  path: _path + ".sense",
15900
15980
  expected: '("higher" | "lower")',
15901
15981
  value: input.sense
15902
15982
  })].every((flag) => flag);
15903
- const _vo6 = (input, _path, _exceptionable = true) => [_vp1(input, _path, _exceptionable), _vp0(input, _path, _exceptionable), input.op === "gte" || input.op === "lte" || _report(_exceptionable, {
15983
+ const _vo6 = (input, _path, _exceptionable = true) => [_vp16(input, _path, _exceptionable), _vp4(input, _path, _exceptionable), input.op === "gte" || input.op === "lte" || _report(_exceptionable, {
15904
15984
  path: _path + ".op",
15905
15985
  expected: '("gte" | "lte")',
15906
15986
  value: input.op
@@ -15909,7 +15989,7 @@ var EXPERIMENT_ALGORITHM_VERSION = "experiment-oat-v1", EXPERIMENT_ESTIMATOR_VER
15909
15989
  expected: "number",
15910
15990
  value: input.limit
15911
15991
  })].every((flag) => flag);
15912
- const _vo7 = (input, _path, _exceptionable = true) => [_vp1(input, _path, _exceptionable), input.target === "model" || input.target === "session" || input.target === "strategy" || _report(_exceptionable, {
15992
+ const _vo7 = (input, _path, _exceptionable = true) => [_vp16(input, _path, _exceptionable), input.target === "model" || input.target === "session" || input.target === "strategy" || _report(_exceptionable, {
15913
15993
  path: _path + ".target",
15914
15994
  expected: '("model" | "session" | "strategy")',
15915
15995
  value: input.target
@@ -15951,7 +16031,7 @@ var EXPERIMENT_ALGORITHM_VERSION = "experiment-oat-v1", EXPERIMENT_ESTIMATOR_VER
15951
16031
  path: _path + ".kind",
15952
16032
  expected: '"int"',
15953
16033
  value: input.kind
15954
- }), _vp2(input, _path, _exceptionable), _vp3(input, _path, _exceptionable)].every((flag) => flag);
16034
+ }), _vp17(input, _path, _exceptionable), _vp18(input, _path, _exceptionable)].every((flag) => flag);
15955
16035
  const _vu0 = (input, _path, _exceptionable = true) => (() => {
15956
16036
  if (input.kind === "bool")
15957
16037
  return _vo8(input, _path, _exceptionable);
@@ -18251,7 +18331,7 @@ var init_checks3 = __esm(() => {
18251
18331
  FAIL_ON = ["error", "warn", "inconclusive", "unsupported"];
18252
18332
  });
18253
18333
 
18254
- // ../../node_modules/.bun/typia@15.1.0+367f7514c87f1df1/node_modules/typia/lib/internal/_accessExpressionAsString.mjs
18334
+ // ../../node_modules/.bun/typia@15.2.2+38c91d72aa8392f2/node_modules/typia/lib/internal/_accessExpressionAsString.mjs
18255
18335
  var _accessExpressionAsString = (str) => variable(str) ? `.${str}` : `[${JSON.stringify(str)}]`, variable = (str) => reserved(str) === false && /^[a-zA-Z_$][a-zA-Z_$0-9]*$/g.test(str), reserved = (str) => RESERVED.has(str), RESERVED;
18256
18336
  var init__accessExpressionAsString = __esm(() => {
18257
18337
  RESERVED = /* @__PURE__ */ new Set([
@@ -18315,6 +18395,9 @@ function nonfiniteThresholds(rubric) {
18315
18395
  if (rule.upperThreshold !== null && !Number.isFinite(rule.upperThreshold)) {
18316
18396
  issues.push(`$input.rules[${index}].upperThreshold finite number or null`);
18317
18397
  }
18398
+ if (rule.metricVersion !== undefined && rule.metricVersion !== null && !Number.isFinite(rule.metricVersion)) {
18399
+ issues.push(`$input.rules[${index}].metricVersion finite number or null`);
18400
+ }
18318
18401
  });
18319
18402
  return issues;
18320
18403
  }
@@ -18340,8 +18423,16 @@ function evaluateGroups(failOn, groups, checks) {
18340
18423
  const pass = reports.every((report) => report.pass);
18341
18424
  return { ...first, results, pass, exitCode: pass ? 0 : 2 };
18342
18425
  }
18343
- function findReadings(artifact, metricId) {
18344
- return artifact.metrics.filter((reading) => reading.metricId === metricId);
18426
+ function ruleReadings(artifact, rule) {
18427
+ const pinned = rule.metricVersion ?? null;
18428
+ return artifact.metrics.filter((reading) => reading.metricId === rule.metricId && (pinned === null || reading.metricVersion === pinned));
18429
+ }
18430
+ function metricVersionRef(version) {
18431
+ return `metric-version:${version}`;
18432
+ }
18433
+ function ruleRefLabel(rule) {
18434
+ const pinned = rule.metricVersion ?? null;
18435
+ return pinned === null ? `metric:${rule.metricId}` : `metric:${rule.metricId} ${metricVersionRef(pinned)}`;
18345
18436
  }
18346
18437
  function isUnavailable(reading) {
18347
18438
  return reading.reading === "unavailable" || reading.status !== "ok";
@@ -18508,27 +18599,40 @@ function judgeArtifact(artifact, rubric) {
18508
18599
  const issues = [];
18509
18600
  const groups = new Map;
18510
18601
  const estimatedObservations = [];
18602
+ const estimatedReadings = new Set;
18511
18603
  const prepared = [];
18512
18604
  for (const rule of rubric.rules) {
18513
- const readings = findReadings(artifact, rule.metricId);
18605
+ const label = ruleRefLabel(rule);
18606
+ const readings = ruleReadings(artifact, rule);
18514
18607
  const reading = readings[0];
18515
18608
  if (!reading) {
18516
- issues.push(`missing evidenceRef metric:${rule.metricId}`);
18609
+ const others = artifact.metrics.filter((item) => item.metricId === rule.metricId).map((item) => metricVersionRef(item.metricVersion));
18610
+ issues.push(others.length > 0 ? `missing evidenceRef ${label} (artifact has ${others.join(", ")})` : `missing evidenceRef ${label}`);
18517
18611
  continue;
18518
18612
  }
18519
18613
  if (readings.length > 1) {
18520
- issues.push(`ambiguous evidenceRef metric:${rule.metricId} matches ${readings.length} readings`);
18614
+ issues.push(`ambiguous evidenceRef ${label} matches ${readings.length} readings`);
18521
18615
  continue;
18522
18616
  }
18523
18617
  const mapped = toObservation(artifact, reading, rule);
18524
- const key = JSON.stringify([reading.metricId, mapped.observation.identity.method, mapped.observation.identity.unit]);
18618
+ const key = JSON.stringify([
18619
+ reading.metricId,
18620
+ reading.metricVersion,
18621
+ mapped.observation.identity.method,
18622
+ mapped.observation.identity.unit
18623
+ ]);
18525
18624
  const group = groups.get(key) ?? { observation: mapped.observation, indices: [] };
18526
18625
  group.indices.push(prepared.length);
18527
18626
  groups.set(key, group);
18528
- if (mapped.estimated && !estimatedObservations.some((item) => item.metricId === reading.metricId)) {
18627
+ if (mapped.estimated && !estimatedReadings.has(reading)) {
18628
+ estimatedReadings.add(reading);
18529
18629
  estimatedObservations.push(mapped.estimated);
18530
18630
  }
18531
- prepared.push({ rule, estimated: mapped.estimated, ref: `metric:${rule.metricId}` });
18631
+ prepared.push({
18632
+ rule,
18633
+ estimated: mapped.estimated,
18634
+ refs: [`metric:${rule.metricId}`, metricVersionRef(reading.metricVersion)]
18635
+ });
18532
18636
  }
18533
18637
  if (issues.length > 0)
18534
18638
  return { ok: false, issues };
@@ -18541,7 +18645,7 @@ function judgeArtifact(artifact, rubric) {
18541
18645
  id: item.rule.id,
18542
18646
  category: outcome.category,
18543
18647
  severity: outcome.severity,
18544
- evidenceRefs: [item.ref],
18648
+ evidenceRefs: item.refs,
18545
18649
  assumptionRefs,
18546
18650
  recommendationId: outcome.recommendationId,
18547
18651
  status: outcome.status,
@@ -18565,9 +18669,9 @@ function judgeArtifact(artifact, rubric) {
18565
18669
  return { ok: true, report };
18566
18670
  }
18567
18671
  var JUDGE_ALGORITHM_VERSION = "judge-rules-1", validateRubricValidator, validateRubric = (input) => (validateRubricValidator ??= (() => {
18568
- const _ve0 = 'Readonly<{ schemaVersion: 1; contract: "idlekit.judge.rubric.v1"; rubricVersion: string; failOn: readonly FailOnToken[]; rules: readonly Readonly<{ id: string; metricId: string; operator: CheckOperator; ... 13 more ...; recommendationId: RecommendationId; }>[]; }>';
18569
- const _ve1 = "Readonly<{ id: string; metricId: string; operator: CheckOperator; threshold: number; upperThreshold: number | null; unit: string; severity: CheckSeverity; missingPolicy: MissingPolicy; ... 8 more ...; recommendationId: RecommendationId; }>";
18570
- const _ve2 = "ReadonlyArray<Readonly<{ id: string; metricId: string; operator: CheckOperator; threshold: number; upperThreshold: number | null; unit: string; severity: CheckSeverity; missingPolicy: MissingPolicy; ... 8 more ...; recommendationId: RecommendationId; }>>";
18672
+ const _ve0 = 'Readonly<{ schemaVersion: 1; contract: "idlekit.judge.rubric.v1"; rubricVersion: string; failOn: readonly FailOnToken[]; rules: readonly Readonly<{ id: string; metricId: string; metricVersion?: number | null | undefined; ... 14 more ...; recommendationId: RecommendationId; }>[]; }>';
18673
+ const _ve1 = "Readonly<{ id: string; metricId: string; metricVersion?: number | null | undefined; operator: CheckOperator; threshold: number; upperThreshold: number | null; unit: string; severity: CheckSeverity; ... 9 more ...; recommendationId: RecommendationId; }>";
18674
+ const _ve2 = "ReadonlyArray<Readonly<{ id: string; metricId: string; metricVersion?: number | null | undefined; operator: CheckOperator; threshold: number; upperThreshold: number | null; unit: string; severity: CheckSeverity; ... 9 more ...; recommendationId: RecommendationId; }>>";
18571
18675
  const _ve3 = '("rec.metric.estimate-not-measured" | "rec.metric.identity-mismatch" | "rec.metric.insufficient" | "rec.metric.outside-threshold" | "rec.metric.unsupported" | "rec.metric.within-threshold")';
18572
18676
  const _io0 = (input, _exceptionable = true) => input.schemaVersion === 1 && input.contract === "idlekit.judge.rubric.v1" && typeof input.rubricVersion === "string" && (Array.isArray(input.failOn) && input.failOn.every((elem, _index1) => elem === "error" || elem === "inconclusive" || elem === "unsupported" || elem === "warn")) && (Array.isArray(input.rules) && input.rules.every((elem, _index2) => typeof elem === "object" && elem !== null && _io1(elem, _exceptionable))) && (Object.keys(input).length === 5 || Object.keys(input).every((key) => {
18573
18677
  if (["schemaVersion", "contract", "rubricVersion", "failOn", "rules"].some((prop) => key === prop))
@@ -18577,8 +18681,8 @@ var JUDGE_ALGORITHM_VERSION = "judge-rules-1", validateRubricValidator, validate
18577
18681
  return true;
18578
18682
  return false;
18579
18683
  }));
18580
- const _io1 = (input, _exceptionable = true) => typeof input.id === "string" && typeof input.metricId === "string" && (input.operator === "between" || input.operator === "eq" || input.operator === "gt" || input.operator === "gte" || input.operator === "lt" || input.operator === "lte") && typeof input.threshold === "number" && (input.upperThreshold === null || typeof input.upperThreshold === "number") && typeof input.unit === "string" && (input.severity === "error" || input.severity === "warn") && (input.missingPolicy === "fail" || input.missingPolicy === "inconclusive" || input.missingPolicy === "unsupported") && typeof input.definition === "string" && typeof input.method === "string" && (input.scenarioVersion === null || typeof input.scenarioVersion === "string") && (input.specVersion === null || typeof input.specVersion === "string") && (input.engineId === null || typeof input.engineId === "string") && (input.pluginVersion === null || typeof input.pluginVersion === "string") && (input.seed === null || typeof input.seed === "string") && (input.algorithmVersion === null || typeof input.algorithmVersion === "string") && (input.recommendationId === "rec.metric.estimate-not-measured" || input.recommendationId === "rec.metric.identity-mismatch" || input.recommendationId === "rec.metric.insufficient" || input.recommendationId === "rec.metric.outside-threshold" || input.recommendationId === "rec.metric.unsupported" || input.recommendationId === "rec.metric.within-threshold") && (Object.keys(input).length === 17 || Object.keys(input).every((key) => {
18581
- if (["id", "metricId", "operator", "threshold", "upperThreshold", "unit", "severity", "missingPolicy", "definition", "method", "scenarioVersion", "specVersion", "engineId", "pluginVersion", "seed", "algorithmVersion", "recommendationId"].some((prop) => key === prop))
18684
+ const _io1 = (input, _exceptionable = true) => typeof input.id === "string" && typeof input.metricId === "string" && (input.metricVersion === null || input.metricVersion === undefined || typeof input.metricVersion === "number") && (input.operator === "between" || input.operator === "eq" || input.operator === "gt" || input.operator === "gte" || input.operator === "lt" || input.operator === "lte") && typeof input.threshold === "number" && (input.upperThreshold === null || typeof input.upperThreshold === "number") && typeof input.unit === "string" && (input.severity === "error" || input.severity === "warn") && (input.missingPolicy === "fail" || input.missingPolicy === "inconclusive" || input.missingPolicy === "unsupported") && typeof input.definition === "string" && typeof input.method === "string" && (input.scenarioVersion === null || typeof input.scenarioVersion === "string") && (input.specVersion === null || typeof input.specVersion === "string") && (input.engineId === null || typeof input.engineId === "string") && (input.pluginVersion === null || typeof input.pluginVersion === "string") && (input.seed === null || typeof input.seed === "string") && (input.algorithmVersion === null || typeof input.algorithmVersion === "string") && (input.recommendationId === "rec.metric.estimate-not-measured" || input.recommendationId === "rec.metric.identity-mismatch" || input.recommendationId === "rec.metric.insufficient" || input.recommendationId === "rec.metric.outside-threshold" || input.recommendationId === "rec.metric.unsupported" || input.recommendationId === "rec.metric.within-threshold") && (Object.keys(input).length === 17 || Object.keys(input).every((key) => {
18685
+ if (["id", "metricId", "metricVersion", "operator", "threshold", "upperThreshold", "unit", "severity", "missingPolicy", "definition", "method", "scenarioVersion", "specVersion", "engineId", "pluginVersion", "seed", "algorithmVersion", "recommendationId"].some((prop) => key === prop))
18582
18686
  return true;
18583
18687
  const value = input[key];
18584
18688
  if (value === undefined)
@@ -18651,6 +18755,10 @@ var JUDGE_ALGORITHM_VERSION = "judge-rules-1", validateRubricValidator, validate
18651
18755
  path: _path + ".metricId",
18652
18756
  expected: "string",
18653
18757
  value: input.metricId
18758
+ }), input.metricVersion === null || input.metricVersion === undefined || typeof input.metricVersion === "number" || _report(_exceptionable, {
18759
+ path: _path + ".metricVersion",
18760
+ expected: "(null | number | undefined)",
18761
+ value: input.metricVersion
18654
18762
  }), input.operator === "between" || input.operator === "eq" || input.operator === "gt" || input.operator === "gte" || input.operator === "lt" || input.operator === "lte" || _report(_exceptionable, {
18655
18763
  path: _path + ".operator",
18656
18764
  expected: '("between" | "eq" | "gt" | "gte" | "lt" | "lte")',
@@ -18712,7 +18820,7 @@ var JUDGE_ALGORITHM_VERSION = "judge-rules-1", validateRubricValidator, validate
18712
18820
  expected: _ve3,
18713
18821
  value: input.recommendationId
18714
18822
  }), Object.keys(input).length === 17 || (_exceptionable === false || Object.keys(input).map((key) => {
18715
- if (["id", "metricId", "operator", "threshold", "upperThreshold", "unit", "severity", "missingPolicy", "definition", "method", "scenarioVersion", "specVersion", "engineId", "pluginVersion", "seed", "algorithmVersion", "recommendationId"].some((prop) => key === prop))
18823
+ if (["id", "metricId", "metricVersion", "operator", "threshold", "upperThreshold", "unit", "severity", "missingPolicy", "definition", "method", "scenarioVersion", "specVersion", "engineId", "pluginVersion", "seed", "algorithmVersion", "recommendationId"].some((prop) => key === prop))
18716
18824
  return true;
18717
18825
  const value = input[key];
18718
18826
  if (value === undefined)
@@ -18798,7 +18906,7 @@ var init_judge = __esm(() => {
18798
18906
  // ../core/dist/sim/analysis/flow.js
18799
18907
  var init_flow = () => {};
18800
18908
 
18801
- // ../../node_modules/.bun/typia@15.1.0+367f7514c87f1df1/node_modules/typia/lib/internal/_isTypeUint32.mjs
18909
+ // ../../node_modules/.bun/typia@15.2.2+38c91d72aa8392f2/node_modules/typia/lib/internal/_isTypeUint32.mjs
18802
18910
  var _isTypeUint32 = (value) => Math.floor(value) === value && MINIMUM <= value && value <= MAXIMUM, MINIMUM = 0, MAXIMUM;
18803
18911
  var init__isTypeUint32 = __esm(() => {
18804
18912
  MAXIMUM = 2 ** 32 - 1;
@@ -19232,12 +19340,12 @@ function estimateLtvPerUser(args) {
19232
19340
  const fullDays = Math.floor(Math.max(0, horizonDays));
19233
19341
  const remainder = Math.max(0, horizonDays - fullDays);
19234
19342
  let gross = 0;
19235
- for (let day = 1;day <= fullDays; day++) {
19343
+ for (let day = 0;day < fullDays; day++) {
19236
19344
  const active = retentionAtDay(config.retention, day);
19237
19345
  gross += active * (payerConversion * arppuDaily + adArpDau);
19238
19346
  }
19239
19347
  if (remainder > 0) {
19240
- const active = retentionAtDay(config.retention, fullDays + 1);
19348
+ const active = retentionAtDay(config.retention, fullDays);
19241
19349
  gross += remainder * active * (payerConversion * arppuDaily + adArpDau);
19242
19350
  }
19243
19351
  const net = gross * (1 - config.revenue.platformFeeRate) * config.revenue.grossMarginRate;
@@ -19359,10 +19467,11 @@ function applyLogNormalShock(mean, sigma, z) {
19359
19467
  }
19360
19468
  function makeUncertainConfig(base, rng) {
19361
19469
  const shock = sampleCorrelatedNormals(rng, base.uncertainty.correlation);
19362
- const d1 = clamp013(applyLogNormalShock(base.retention.d1, base.uncertainty.sigma.retention, shock.retention));
19363
- const d7 = Math.min(d1, clamp013(applyLogNormalShock(base.retention.d7, base.uncertainty.sigma.retention, shock.retention)));
19364
- const d30 = Math.min(d7, clamp013(applyLogNormalShock(base.retention.d30, base.uncertainty.sigma.retention, shock.retention)));
19365
- const d90 = Math.min(d30, clamp013(applyLogNormalShock(base.retention.d90, base.uncertainty.sigma.retention, shock.retention)));
19470
+ const retention = (anchor) => clamp013(applyLogNormalShock(anchor, base.uncertainty.sigma.retention, shock.retention));
19471
+ const d1 = retention(base.retention.d1);
19472
+ const d7 = retention(base.retention.d7);
19473
+ const d30 = retention(base.retention.d30);
19474
+ const d90 = retention(base.retention.d90);
19366
19475
  return {
19367
19476
  ...base,
19368
19477
  retention: {
@@ -19386,6 +19495,23 @@ function quantileFromSorted(sorted, q) {
19386
19495
  const idx = Math.max(0, Math.min(sorted.length - 1, Math.floor((sorted.length - 1) * q)));
19387
19496
  return sorted[idx] ?? 0;
19388
19497
  }
19498
+ function quantileKey(q) {
19499
+ const [mantissa = "0", exponent = "0"] = String(q).split("e");
19500
+ const [whole = "0", fraction = ""] = mantissa.split(".");
19501
+ const digits = whole + fraction;
19502
+ const point = whole.length + Number(exponent) + 2;
19503
+ const shifted = point <= 0 ? `0.${"0".repeat(-point)}${digits}` : point >= digits.length ? digits + "0".repeat(point - digits.length) : `${digits.slice(0, point)}.${digits.slice(point)}`;
19504
+ const [int = "0", frac = ""] = shifted.split(".");
19505
+ let start = 0;
19506
+ while (start < int.length - 1 && int[start] === "0")
19507
+ start++;
19508
+ let end = frac.length;
19509
+ while (end > 0 && frac[end - 1] === "0")
19510
+ end--;
19511
+ const trimmedInt = int.slice(start);
19512
+ const trimmedFrac = frac.slice(0, end);
19513
+ return `q${trimmedFrac ? `${trimmedInt}.${trimmedFrac}` : trimmedInt}`;
19514
+ }
19389
19515
  function estimateLtvDistribution(args) {
19390
19516
  const rng = mulberry32(args.seed);
19391
19517
  const grossSamples = [];
@@ -19407,7 +19533,7 @@ function estimateLtvDistribution(args) {
19407
19533
  const sortedLtv = [...ltvSamples].sort((a, b) => a - b);
19408
19534
  const byQuantile = {};
19409
19535
  for (const q of args.quantiles) {
19410
- byQuantile[`q${Math.round(q * 100)}`] = quantileFromSorted(sortedLtv, q);
19536
+ byQuantile[quantileKey(q)] = quantileFromSorted(sortedLtv, q);
19411
19537
  }
19412
19538
  return {
19413
19539
  mean: {
@@ -19442,8 +19568,7 @@ function assertQuantileValues(quantiles) {
19442
19568
  throw new RangeError("quantiles must be nonempty and in 0..1");
19443
19569
  }
19444
19570
  }
19445
- function assertConfig(config) {
19446
- const { retention, ...other } = config;
19571
+ function assertRetention(retention) {
19447
19572
  for (const day of ["d1", "d7", "d30", "d90"]) {
19448
19573
  if (!Number.isFinite(retention[day]) || retention[day] < 0 || retention[day] > 1) {
19449
19574
  throw new RangeError(`retention.${day} must be finite and in 0..1`);
@@ -19452,6 +19577,10 @@ function assertConfig(config) {
19452
19577
  if (!Number.isFinite(retention.longTailDailyDecay) || retention.longTailDailyDecay < 0) {
19453
19578
  throw new RangeError("retention.longTailDailyDecay must be finite and >= 0");
19454
19579
  }
19580
+ }
19581
+ function assertConfig(config) {
19582
+ const { retention, ...other } = config;
19583
+ assertRetention(retention);
19455
19584
  const { quantiles, ...uncertainty } = other.uncertainty;
19456
19585
  assertQuantileValues(quantiles);
19457
19586
  assertMonetization({ ...other, uncertainty });
@@ -19462,6 +19591,14 @@ function deriveMonetizationConfig2(scenario) {
19462
19591
  assertConfig(config);
19463
19592
  return config;
19464
19593
  }
19594
+ function progressionFactor2(startWorthLog10, endWorthLog10, span) {
19595
+ if (Number.isNaN(startWorthLog10) || Number.isNaN(endWorthLog10)) {
19596
+ throw new RangeError("worth logs must not be NaN");
19597
+ }
19598
+ if (!Number.isFinite(span) || span <= 0)
19599
+ throw new RangeError("span must be finite and > 0");
19600
+ return progressionFactor(startWorthLog10, endWorthLog10, span);
19601
+ }
19465
19602
  function assertPoint(args) {
19466
19603
  assertConfig(args.config);
19467
19604
  if (!Number.isFinite(args.horizonDays) || args.horizonDays < 0 || args.horizonDays > 36500) {
@@ -19482,18 +19619,24 @@ function estimateLtvPerUser2(args) {
19482
19619
  }
19483
19620
  function estimateLtvDistribution2(args) {
19484
19621
  assertPoint(args);
19485
- if (!Number.isSafeInteger(args.draws) || args.draws < 1 || args.draws > 1e5 || args.draws * Math.max(1, Math.ceil(args.horizonDays)) > 1e7) {
19622
+ const draws = args.draws ?? args.config.uncertainty.draws;
19623
+ const quantiles = args.quantiles ?? args.config.uncertainty.quantiles;
19624
+ const seed = args.seed ?? args.config.uncertainty.seed;
19625
+ if (!Number.isSafeInteger(draws) || draws < 1 || draws > 1e5 || draws * Math.max(1, Math.ceil(args.horizonDays)) > 1e7) {
19486
19626
  throw new RangeError("draws must be 1..100000 and draws \xD7 ceil(horizonDays) at most 10000000");
19487
19627
  }
19488
- if (!Number.isFinite(args.seed))
19489
- throw new RangeError("seed must be finite");
19490
- if (args.quantiles.length > 101)
19491
- throw new RangeError("quantiles exceed the 101 distinct percent keys");
19492
- assertQuantileValues(args.quantiles);
19493
- if (new Set(args.quantiles.map((q) => Math.round(q * 100))).size !== args.quantiles.length) {
19494
- throw new RangeError("quantiles must be nonempty, in 0..1 and have distinct rounded percent keys");
19628
+ if (seed === undefined)
19629
+ throw new RangeError("seed is required: pass seed or set config.uncertainty.seed");
19630
+ if (!Number.isInteger(seed) || seed < 0 || seed > 4294967295) {
19631
+ throw new RangeError("seed must be an integer in 0..4294967295");
19632
+ }
19633
+ if (quantiles.length > 101)
19634
+ throw new RangeError("quantiles exceed 101 entries");
19635
+ assertQuantileValues(quantiles);
19636
+ if (new Set(quantiles.map(quantileKey)).size !== quantiles.length) {
19637
+ throw new RangeError("quantiles must be distinct values in 0..1");
19495
19638
  }
19496
- const result = estimateLtvDistribution(args);
19639
+ const result = estimateLtvDistribution({ ...args, draws, quantiles, seed });
19497
19640
  finiteResult(result.mean);
19498
19641
  finiteResult(result.quantiles);
19499
19642
  return result;
@@ -19624,7 +19767,7 @@ function planRetentionPatch(observation, assumptions = {}) {
19624
19767
  if (rate === undefined)
19625
19768
  continue;
19626
19769
  if (previous && previous.rate < rate)
19627
- warnings.push(`D${previous.day}=${previous.rate} is below D${day}=${rate}. LTV requires d1 >= d7 >= d30 >= d90; review observations and retained assumptions before applying a patch.`);
19770
+ warnings.push(`D${previous.day}=${previous.rate} is below D${day}=${rate}. A complete scenario retention curve must satisfy d1 >= d7 >= d30 >= d90, and the LTV model would interpolate a rise as given; review observations and retained assumptions before applying a patch.`);
19628
19771
  previous = { day, rate };
19629
19772
  }
19630
19773
  return warnings.length ? { status: "requires-review", retention: {}, warnings } : { status: "ready", retention: rates, warnings };
@@ -19858,13 +20001,78 @@ var init_errors3 = __esm(() => {
19858
20001
  };
19859
20002
  });
19860
20003
 
20004
+ // src/runtime/invocation.ts
20005
+ import { AsyncLocalStorage } from "async_hooks";
20006
+ import { resolve } from "path";
20007
+ function runWithInvocation(invocation, fn) {
20008
+ return storage.run({ ...invocation, reads: new Set }, fn);
20009
+ }
20010
+ function recordInputRead(path) {
20011
+ storage.getStore()?.reads.add(resolve(path));
20012
+ }
20013
+ function flagPaths(key, value) {
20014
+ if (typeof value !== "string" || !value.trim())
20015
+ return [];
20016
+ if (LIST_FLAGS.has(key))
20017
+ return value.split(",").map((item) => item.trim()).filter(Boolean);
20018
+ return INPUT_FLAGS.has(key) ? [value] : [];
20019
+ }
20020
+ function recordNestedInputs(base, positional, flags) {
20021
+ for (const value of positional)
20022
+ if (value.length > 0)
20023
+ recordInputRead(resolve(base, value));
20024
+ for (const [key, value] of Object.entries(flags))
20025
+ for (const path of flagPaths(key, value))
20026
+ recordInputRead(resolve(base, path));
20027
+ }
20028
+ function invocationInputCandidates(options = {}) {
20029
+ const invocation = storage.getStore();
20030
+ if (!invocation)
20031
+ return [];
20032
+ const allow = new Set(options.allow ?? []);
20033
+ const allowed = new Set;
20034
+ const candidates = [];
20035
+ for (const [key, value] of Object.entries(invocation.flags)) {
20036
+ const paths = flagPaths(key, value);
20037
+ if (allow.has(key))
20038
+ for (const path of paths)
20039
+ allowed.add(resolve(path));
20040
+ else
20041
+ candidates.push(...paths);
20042
+ }
20043
+ for (const path of invocation.reads)
20044
+ if (!allowed.has(path))
20045
+ candidates.push(path);
20046
+ return candidates;
20047
+ }
20048
+ var INPUT_FLAGS, LIST_FLAGS, storage;
20049
+ var init_invocation = __esm(() => {
20050
+ INPUT_FLAGS = new Set([
20051
+ "scenario",
20052
+ "baseline",
20053
+ "current",
20054
+ "baseline-artifact",
20055
+ "tune",
20056
+ "checks",
20057
+ "rubric",
20058
+ "cache",
20059
+ "resume",
20060
+ "rc",
20061
+ "plugin-trust-file"
20062
+ ]);
20063
+ LIST_FLAGS = new Set(["plugin"]);
20064
+ storage = new AsyncLocalStorage;
20065
+ });
20066
+
19861
20067
  // src/runtime/bun.ts
19862
20068
  var {$ } = globalThis.Bun;
19863
20069
  import { dirname } from "path";
19864
20070
  async function readTextFile(path) {
20071
+ recordInputRead(path);
19865
20072
  return Bun.file(path).text();
19866
20073
  }
19867
20074
  async function readJsonFile(path) {
20075
+ recordInputRead(path);
19868
20076
  return Bun.file(path).json();
19869
20077
  }
19870
20078
  async function writeTextFile(path, body) {
@@ -19914,6 +20122,7 @@ function runText(args, opts) {
19914
20122
  var MAX_CAPTURE_BYTES;
19915
20123
  var init_bun = __esm(() => {
19916
20124
  init_errors3();
20125
+ init_invocation();
19917
20126
  MAX_CAPTURE_BYTES = 8 * 1024 * 1024;
19918
20127
  });
19919
20128
 
@@ -19921,7 +20130,7 @@ var init_bun = __esm(() => {
19921
20130
  var require_package = __commonJS(function(exports, module) {
19922
20131
  module.exports = {
19923
20132
  name: "@idlekit/cli",
19924
- version: "0.6.0",
20133
+ version: "0.7.0",
19925
20134
  description: "Bun-first idk CLI for idle game scenario validation, simulation, tuning, and reporting.",
19926
20135
  license: "MIT",
19927
20136
  type: "module",
@@ -19974,7 +20183,7 @@ var require_package = __commonJS(function(exports, module) {
19974
20183
  "@clack/prompts": "1.8.1",
19975
20184
  "@gunshi/plugin-completion": "0.37.3",
19976
20185
  "@gunshi/plugin-suggestion": "0.37.3",
19977
- "@idlekit/core": "0.6.0",
20186
+ "@idlekit/core": "0.7.0",
19978
20187
  ajv: "^8.20.0",
19979
20188
  gunshi: "0.37.3",
19980
20189
  "proper-lockfile": "4.1.2",
@@ -19989,7 +20198,7 @@ var require_package = __commonJS(function(exports, module) {
19989
20198
 
19990
20199
  // src/runtime/selfCli.ts
19991
20200
  import { existsSync } from "fs";
19992
- import { dirname as dirname3, resolve as resolve2 } from "path";
20201
+ import { dirname as dirname3, resolve as resolve3 } from "path";
19993
20202
  function currentEntry() {
19994
20203
  return Bun.main;
19995
20204
  }
@@ -20006,11 +20215,11 @@ function cliPackageRoot(entry = currentEntry()) {
20006
20215
  if (isNativeEntry(entry))
20007
20216
  return process.cwd();
20008
20217
  if (isBundledCliProcess(entry))
20009
- return resolve2(dirname3(entry), "..");
20010
- return resolve2(import.meta.dir, "../..");
20218
+ return resolve3(dirname3(entry), "..");
20219
+ return resolve3(import.meta.dir, "../..");
20011
20220
  }
20012
20221
  function bundledCliConfig(entry) {
20013
- const config = resolve2(dirname3(entry), "../../../tools/bundled-cli-bunfig.toml");
20222
+ const config = resolve3(dirname3(entry), "../../../tools/bundled-cli-bunfig.toml");
20014
20223
  if (!existsSync(config))
20015
20224
  return;
20016
20225
  return config;
@@ -20025,7 +20234,7 @@ function selfCliCommand(args, entry = currentEntry()) {
20025
20234
  return [bun, `--config=${config}`, entry, ...args];
20026
20235
  return [bun, entry, ...args];
20027
20236
  }
20028
- const bunfigApplies = resolve2(process.cwd()) === CLI_ROOT;
20237
+ const bunfigApplies = resolve3(process.cwd()) === CLI_ROOT;
20029
20238
  if (entry.endsWith(".ts") && !bunfigApplies) {
20030
20239
  return [bun, "--preload", "@ttsc/unplugin/bun-register", entry, ...args];
20031
20240
  }
@@ -20047,16 +20256,16 @@ function runSelfCli(args) {
20047
20256
  }
20048
20257
  var CLI_ROOT, MAX_CAPTURE_BYTES2;
20049
20258
  var init_selfCli = __esm(() => {
20050
- CLI_ROOT = resolve2(import.meta.dir, "../..");
20259
+ CLI_ROOT = resolve3(import.meta.dir, "../..");
20051
20260
  MAX_CAPTURE_BYTES2 = 8 * 1024 * 1024;
20052
20261
  });
20053
20262
 
20054
20263
  // src/io/outputMeta.ts
20055
- import { dirname as dirname4, resolve as resolve3 } from "path";
20264
+ import { dirname as dirname4, resolve as resolve4 } from "path";
20056
20265
  function repoRoot() {
20057
20266
  if (isBundledCliProcess())
20058
- return resolve3(dirname4(Bun.main), "../..");
20059
- return resolve3(import.meta.dir, "../../..");
20267
+ return resolve4(dirname4(Bun.main), "../..");
20268
+ return resolve4(import.meta.dir, "../../..");
20060
20269
  }
20061
20270
  function stableStringify(value) {
20062
20271
  if (value === null || typeof value !== "object") {
@@ -20169,8 +20378,9 @@ var init_outputMeta = __esm(() => {
20169
20378
  // src/plugin/load.ts
20170
20379
  init_dist2();
20171
20380
  init_bun();
20381
+ init_invocation();
20172
20382
  import { realpathSync } from "fs";
20173
- import { dirname as dirname2, extname, isAbsolute, relative, resolve, sep } from "path";
20383
+ import { dirname as dirname2, extname, isAbsolute, relative, resolve as resolve2, sep } from "path";
20174
20384
  import { fileURLToPath } from "url";
20175
20385
 
20176
20386
  // src/lib/designObjectives.ts
@@ -20182,7 +20392,7 @@ init_dist2();
20182
20392
  function quantile(values, q) {
20183
20393
  return quantileInclusiveFloor(values, q) ?? undefined;
20184
20394
  }
20185
- function quantileKey(quantiles, q) {
20395
+ function quantileKey2(quantiles, q) {
20186
20396
  const percent = Math.round(q * 100);
20187
20397
  const legacy = `q${percent}`;
20188
20398
  const collided = quantiles.some((other) => other !== q && `q${Math.round(other * 100)}` === legacy);
@@ -20195,7 +20405,7 @@ function summarizeNumeric(values, quantiles) {
20195
20405
  return null;
20196
20406
  return {
20197
20407
  mean: values.reduce((sum, value) => sum + value, 0) / values.length,
20198
- quantiles: Object.fromEntries(quantiles.map((q) => [quantileKey(quantiles, q), quantileInclusiveFloor(values, q) ?? Number.NaN]))
20408
+ quantiles: Object.fromEntries(quantiles.map((q) => [quantileKey2(quantiles, q), quantileInclusiveFloor(values, q) ?? Number.NaN]))
20199
20409
  };
20200
20410
  }
20201
20411
  function resolveSessionPatternSpec(args) {
@@ -20836,10 +21046,11 @@ init_errors3();
20836
21046
  function ownedCount(state) {
20837
21047
  return Number(state?.vars?.owned ?? 0);
20838
21048
  }
21049
+ var NUMBER_ONLY_COMMANDS = ["report", "analyze", "eta", "growth", "prestige-cycle"];
20839
21050
  function finiteLinearAmount(E, value, label) {
20840
21051
  if (!E.isFinite(value)) {
20841
21052
  throw cliError("SCENARIO_INVALID", `linear ${label} exceeds the selected engine's finite range. Use --engine breakInfinity with simulate/evaluate/experience/ltv/compare/tune/balance for a large economy, or reduce the inputs.`, {
20842
- hint: "The report command uses the number engine; reduce its inputs."
21053
+ hint: `${NUMBER_ONLY_COMMANDS.join(", ")} run only the number engine; reduce their inputs.`
20843
21054
  });
20844
21055
  }
20845
21056
  return value;
@@ -21075,7 +21286,7 @@ function normalizeSha256(input) {
21075
21286
  return x;
21076
21287
  }
21077
21288
  function parsePluginRoots(input) {
21078
- const list = parseCommaSeparated(input).map((x) => resolve(x));
21289
+ const list = parseCommaSeparated(input).map((x) => resolve2(x));
21079
21290
  return [...new Set(list)];
21080
21291
  }
21081
21292
  function parsePluginSha256(input) {
@@ -21088,7 +21299,7 @@ function parsePluginSha256(input) {
21088
21299
  }
21089
21300
  const key = entry.slice(0, idx).trim();
21090
21301
  const value = entry.slice(idx + 1).trim();
21091
- const abs = resolve(key);
21302
+ const abs = resolve2(key);
21092
21303
  const digest = normalizeSha256(value);
21093
21304
  if (out[abs] && out[abs] !== digest) {
21094
21305
  throw new Error(`Conflicting sha256 values for plugin path: ${key}`);
@@ -21100,7 +21311,7 @@ function parsePluginSha256(input) {
21100
21311
  function parsePluginSecurityOptions(input) {
21101
21312
  const allowedRoots = parsePluginRoots(input.roots);
21102
21313
  const requiredSha256 = parsePluginSha256(input.sha256);
21103
- const trustFile = typeof input.trustFile === "string" && input.trustFile.trim().length > 0 ? resolve(input.trustFile) : undefined;
21314
+ const trustFile = typeof input.trustFile === "string" && input.trustFile.trim().length > 0 ? resolve2(input.trustFile) : undefined;
21104
21315
  return {
21105
21316
  allowedRoots,
21106
21317
  requiredSha256,
@@ -21122,7 +21333,7 @@ async function loadPluginTrustFile(pathAbs) {
21122
21333
  if (typeof v !== "string")
21123
21334
  continue;
21124
21335
  const digest = normalizeSha256(v);
21125
- const absPath = isAbsolute(k) ? resolve(k) : resolve(baseDir, k);
21336
+ const absPath = isAbsolute(k) ? resolve2(k) : resolve2(baseDir, k);
21126
21337
  out[absPath] = digest;
21127
21338
  }
21128
21339
  return out;
@@ -21148,7 +21359,7 @@ async function loadRegistries(pluginPaths = [], securityOptions = {}) {
21148
21359
  let requiredSha256;
21149
21360
  let requiredClosureSha256;
21150
21361
  try {
21151
- allowedRoots = (securityOptions.allowedRoots ?? []).map((x) => resolve(x));
21362
+ allowedRoots = (securityOptions.allowedRoots ?? []).map((x) => resolve2(x));
21152
21363
  const trustFileSha256 = securityOptions.trustFile !== undefined ? await loadPluginTrustFile(securityOptions.trustFile) : {};
21153
21364
  requiredSha256 = mergeShaPolicies(trustFileSha256, securityOptions.requiredSha256 ?? {});
21154
21365
  requiredClosureSha256 = mergeShaPolicies({}, securityOptions.requiredClosureSha256 ?? {});
@@ -21245,6 +21456,7 @@ function isPathInsideRoot(pathAbs, rootAbs) {
21245
21456
  return rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
21246
21457
  }
21247
21458
  async function sha256File(pathAbs) {
21459
+ recordInputRead(pathAbs);
21248
21460
  const buffer = await Bun.file(pathAbs).bytes();
21249
21461
  return sha256Hex(buffer);
21250
21462
  }
@@ -21284,11 +21496,16 @@ async function pluginClosureDigest(entryAbs, entryDigest) {
21284
21496
  return sha256Hex(listing.join(`
21285
21497
  `));
21286
21498
  }
21499
+ async function recordPluginClosureReads(entryAbs) {
21500
+ try {
21501
+ await pluginClosureDigest(entryAbs, await sha256File(entryAbs));
21502
+ } catch {}
21503
+ }
21287
21504
  async function resolveAndValidatePluginPath(input, allowedRoots) {
21288
21505
  if (input.includes("://")) {
21289
21506
  throw new Error(`Plugin path must be a local file path: ${input}`);
21290
21507
  }
21291
- const abs = resolve(input);
21508
+ const abs = resolve2(input);
21292
21509
  const ext = extname(abs).toLowerCase();
21293
21510
  if (!ALLOWED_PLUGIN_EXTENSIONS.has(ext)) {
21294
21511
  throw new Error(`Unsupported plugin extension '${ext}' for ${input}`);
@@ -21793,4 +22010,4 @@ export {
21793
22010
  workerEntryMarker
21794
22011
  };
21795
22012
 
21796
- //# debugId=8F910D642493528C64756E2164756E21
22013
+ //# debugId=FA1764B671C6333464756E2164756E21