@warmdrift/kgauto-compiler 2.0.0-alpha.71 → 2.0.0-alpha.73

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -49,6 +49,7 @@ __export(index_exports, {
49
49
  applyArchetypeConvention: () => applyArchetypeConvention,
50
50
  applySectionRewrites: () => applySectionRewrites,
51
51
  attachCacheControlToStreamTextInput: () => attachCacheControlToStreamTextInput,
52
+ awaitMeasuredFailureReady: () => awaitMeasuredFailureReady,
52
53
  brainHealth: () => brainHealth,
53
54
  bucketContext: () => bucketContext,
54
55
  bucketHistory: () => bucketHistory,
@@ -118,6 +119,7 @@ __export(index_exports, {
118
119
  parseGoldenCaptureRate: () => parseGoldenCaptureRate,
119
120
  parseJudgeVerdict: () => parseJudgeVerdict,
120
121
  peekBrainDeadLetter: () => peekBrainDeadLetter,
122
+ prefetchMeasuredFailure: () => prefetchMeasuredFailure,
121
123
  probeShadow: () => probeShadow,
122
124
  profileToRow: () => profileToRow,
123
125
  profilesByProvider: () => profilesByProvider,
@@ -362,7 +364,8 @@ var PROFILES_RAW = [
362
364
  id: "claude-fable-5",
363
365
  verifiedAgainstDocs: "2026-06-21",
364
366
  provider: "anthropic",
365
- status: "preview",
367
+ status: "current",
368
+ // s76 2026-07-25: GA since 2026-06-09 per docs; was preview.
366
369
  maxContextTokens: 1e6,
367
370
  maxOutputTokens: 128e3,
368
371
  maxTools: 64,
@@ -416,7 +419,8 @@ var PROFILES_RAW = [
416
419
  id: "claude-opus-4-8",
417
420
  verifiedAgainstDocs: "2026-06-21",
418
421
  provider: "anthropic",
419
- status: "current",
422
+ status: "legacy",
423
+ // s76 2026-07-25: docs list as LEGACY (Opus 5 generation is current).
420
424
  maxContextTokens: 1e6,
421
425
  maxOutputTokens: 128e3,
422
426
  maxTools: 64,
@@ -456,11 +460,78 @@ var PROFILES_RAW = [
456
460
  classify: 8
457
461
  }
458
462
  },
463
+ {
464
+ // ── Claude Opus 5 — added s76 (2026-07-25, alpha.72) ──────────────────
465
+ // The model every seat in the portfolio actually runs, absent from the
466
+ // roster until now. Found by a catalog QA, not by the release watcher:
467
+ // the watcher detects unknown IDs on a provider's /models endpoint, but
468
+ // detection was never wired to ingestion, so the gap sat open. (That is
469
+ // what `scripts/catalog-sync.mjs` exists to close.)
470
+ //
471
+ // PROVENANCE — doc-verified 2026-07-25 against
472
+ // platform.claude.com/docs/en/docs/about-claude/models/overview:
473
+ // 1M context · 128k max output · $5/$25 per MTok · adaptive thinking YES
474
+ // · extended thinking NO · `effort` defaults to 'high' on the Claude API
475
+ // · reliable knowledge cutoff May 2026.
476
+ //
477
+ // FAMILY-INHERITED (not doc-read): maxTools, parallelToolCalls,
478
+ // structuredOutput, systemPromptMode, streaming. These are identical
479
+ // across opus-4-6 / 4-7 / 4-8 / sonnet-5 / fable-5 — five consecutive
480
+ // models — so they are a structural provider constant rather than a
481
+ // per-model value. Deliberately distinguished from the gemini-3.1-flash-lite
482
+ // failure, where a template-clone of PRICE (the field that actually varies,
483
+ // there by 2.5-3.75x) went unverified for 65 days.
484
+ id: "claude-opus-5",
485
+ verifiedAgainstDocs: "2026-07-25",
486
+ provider: "anthropic",
487
+ status: "current",
488
+ maxContextTokens: 1e6,
489
+ maxOutputTokens: 128e3,
490
+ maxTools: 64,
491
+ parallelToolCalls: true,
492
+ structuredOutput: "grammar",
493
+ systemPromptMode: "inline",
494
+ streaming: true,
495
+ cliffs: [],
496
+ costInputPer1m: 5,
497
+ costOutputPer1m: 25,
498
+ lowering: ANTHROPIC_LOWERING_BASE,
499
+ recovery: [
500
+ {
501
+ signal: "rate_limit",
502
+ action: "escalate",
503
+ reason: "429 from Anthropic \u2014 escalate to fallback chain"
504
+ },
505
+ {
506
+ signal: "model_not_found",
507
+ action: "escalate",
508
+ reason: "Model deprecated/renamed \u2014 escalate (L-061)"
509
+ }
510
+ ],
511
+ strengths: ["reasoning", "agentic_coding", "long_context", "reliable_tool_use", "structured_output"],
512
+ weaknesses: ["cost", "latency"],
513
+ notes: "Anthropic frontier for complex agentic coding + enterprise work; the Opus-tier current default as of 2026-07-25, superseding 4.8/4.7/4.6 (all now legacy). Doc-verified 2026-07-25: 1M ctx, 128k out, $5/$25, adaptive thinking (extended thinking NOT supported \u2014 that is Haiku 4.5 only in this generation), `effort` defaults to high on the Claude API. Price is unchanged from 4.5 through 5 \u2014 the tier moved without a cost change.",
514
+ // COLD-START PRIOR cloned from claude-opus-4-8. Self-labelling: below
515
+ // MEASURED_GROUNDING_MIN_N (10) brain rows these resolve as
516
+ // grounding:'judgment', so nothing reads them as measured until they are.
517
+ archetypePerf: {
518
+ critique: 10,
519
+ plan: 10,
520
+ generate: 9,
521
+ ask: 9,
522
+ extract: 9,
523
+ transform: 9,
524
+ hunt: 8,
525
+ summarize: 8,
526
+ classify: 8
527
+ }
528
+ },
459
529
  {
460
530
  id: "claude-opus-4-7",
461
531
  verifiedAgainstDocs: "2026-05-08",
462
532
  provider: "anthropic",
463
- status: "current",
533
+ status: "legacy",
534
+ // s76 2026-07-25: docs list as LEGACY (Opus 5 is current). Bundle said current while the brain already said legacy — the two disagreed.
464
535
  maxContextTokens: 1e6,
465
536
  maxOutputTokens: 128e3,
466
537
  maxTools: 64,
@@ -554,7 +625,8 @@ var PROFILES_RAW = [
554
625
  id: "claude-sonnet-4-6",
555
626
  verifiedAgainstDocs: "2026-05-08",
556
627
  provider: "anthropic",
557
- status: "current",
628
+ status: "legacy",
629
+ // s76 2026-07-25: docs list as LEGACY (Sonnet 5 is current).
558
630
  maxContextTokens: 1e6,
559
631
  maxOutputTokens: 64e3,
560
632
  maxTools: 64,
@@ -1693,7 +1765,8 @@ var PROFILES_RAW = [
1693
1765
  id: "claude-sonnet-5",
1694
1766
  verifiedAgainstDocs: "2026-07-02",
1695
1767
  provider: "anthropic",
1696
- status: "preview",
1768
+ status: "current",
1769
+ // s76 2026-07-25: GA per docs; was preview.
1697
1770
  maxContextTokens: 1e6,
1698
1771
  maxOutputTokens: 128e3,
1699
1772
  maxTools: 64,
@@ -2910,20 +2983,27 @@ function passScoreTargets(ir, opts) {
2910
2983
  });
2911
2984
  }
2912
2985
  if (qualityGatePenalty > 0) {
2986
+ const rankBefore = rank + qualityGatePenalty;
2913
2987
  if (measuredGate) {
2914
2988
  const pct = (x) => `${(x * 100).toFixed(0)}%`;
2915
2989
  policyMutations.push({
2916
2990
  id: `quality-gate-measured-${modelId}`,
2917
2991
  source: "quality_gate",
2918
2992
  passName: "score_targets",
2919
- description: `Model ${modelId} gated below the quality floor for archetype '${ir.intent.archetype}' by MEASURED evidence from this app's own outcomes \u2014 ${measuredGate.nFail} of ${measuredGate.n} attempts failed on the quality axis in the trailing window (${pct(measuredGate.rate)}; 95% lower bound ${pct(measuredGate.lowerBound)} > 50%). Down-ranked out of leadership; retained as graceful fallback only. The gate is derived, not stored \u2014 it lifts on its own once the failures age out of the window.`
2993
+ rankDelta: -qualityGatePenalty,
2994
+ rankBefore,
2995
+ rankAfter: rank,
2996
+ description: `Model ${modelId} gated below the quality floor for archetype '${ir.intent.archetype}' by MEASURED evidence from this app's own outcomes \u2014 ${measuredGate.nFail} of ${measuredGate.n} attempts failed on the quality axis in the trailing window (${pct(measuredGate.rate)}; 95% lower bound ${pct(measuredGate.lowerBound)} > 50%). Rank ${rankBefore.toFixed(2)} \u2192 ${rank.toFixed(2)} (\u2212${qualityGatePenalty.toFixed(2)}). Down-ranked out of leadership; retained as graceful fallback only. The gate is derived, not stored \u2014 it lifts on its own once the failures age out of the window.`
2920
2997
  });
2921
2998
  } else {
2922
2999
  policyMutations.push({
2923
3000
  id: `quality-gate-structured-${modelId}`,
2924
3001
  source: "quality_gate",
2925
3002
  passName: "score_targets",
2926
- description: `Model ${modelId} gated below the quality floor for archetype '${ir.intent.archetype}' \u2014 declared structuredOutput + kgauto convention flags it schema-weak for this contract (structuredOutputHint:'avoid'). Down-ranked out of leadership; retained as graceful fallback only.`
3003
+ rankDelta: -qualityGatePenalty,
3004
+ rankBefore,
3005
+ rankAfter: rank,
3006
+ description: `Model ${modelId} gated below the quality floor for archetype '${ir.intent.archetype}' \u2014 declared structuredOutput + kgauto convention flags it schema-weak for this contract (structuredOutputHint:'avoid'). Rank ${rankBefore.toFixed(2)} \u2192 ${rank.toFixed(2)} (\u2212${qualityGatePenalty.toFixed(2)}). Down-ranked out of leadership; retained as graceful fallback only.`
2927
3007
  });
2928
3008
  }
2929
3009
  }
@@ -3171,6 +3251,12 @@ function lower(ir, profile, hints = {}) {
3171
3251
  }
3172
3252
  function lowerAnthropic(ir, profile, hints) {
3173
3253
  const systemBlocks = buildAnthropicSystemBlocks(ir.sections, profile);
3254
+ if (ir.constraints?.structuredOutput) {
3255
+ systemBlocks.push({
3256
+ type: "text",
3257
+ text: "Respond with a single valid JSON value and nothing else. Do not wrap it in a markdown code fence, and do not add any prose before or after it."
3258
+ });
3259
+ }
3174
3260
  const history = (ir.history ?? []).filter((m) => m.role !== "system");
3175
3261
  const policy = ir.historyCachePolicy;
3176
3262
  const markIndex = resolveHistoryMarkIndex(history.length, policy);
@@ -4657,6 +4743,40 @@ function configureMeasuredFailureBrain(rt) {
4657
4743
  function isMeasuredFailureBrainActive() {
4658
4744
  return runtime6 !== void 0;
4659
4745
  }
4746
+ function prefetchMeasuredFailure(appId) {
4747
+ const rt = runtime6;
4748
+ if (!rt || !appId) return void 0;
4749
+ let snap = snapshots5.get(appId);
4750
+ if (!snap) {
4751
+ snap = { data: [], expiresAt: 0, refreshing: false };
4752
+ snapshots5.set(appId, snap);
4753
+ }
4754
+ if (snap.expiresAt > Date.now()) return void 0;
4755
+ const inflight = pendingRefreshes5.get(appId);
4756
+ if (inflight) return inflight;
4757
+ if (snap.refreshing) return void 0;
4758
+ snap.refreshing = true;
4759
+ void asyncRefresh6(rt, appId);
4760
+ return pendingRefreshes5.get(appId);
4761
+ }
4762
+ async function awaitMeasuredFailureReady(appId, timeoutMs) {
4763
+ if (!runtime6 || !appId) return;
4764
+ const pending = prefetchMeasuredFailure(appId) ?? pendingRefreshes5.get(appId);
4765
+ if (!(timeoutMs > 0)) return;
4766
+ if (!pending) return;
4767
+ let timer;
4768
+ try {
4769
+ await Promise.race([
4770
+ pending,
4771
+ new Promise((resolve) => {
4772
+ timer = setTimeout(resolve, timeoutMs);
4773
+ })
4774
+ ]);
4775
+ } catch {
4776
+ } finally {
4777
+ if (timer) clearTimeout(timer);
4778
+ }
4779
+ }
4660
4780
  function getMeasuredFailureVerdict(opts) {
4661
4781
  const rt = runtime6;
4662
4782
  if (!rt) return void 0;
@@ -5162,6 +5282,12 @@ function configureBrain(config) {
5162
5282
  fetchImpl: config.fetchImpl ?? fetch,
5163
5283
  onError: config.onError
5164
5284
  });
5285
+ if (config.appId) {
5286
+ try {
5287
+ void prefetchMeasuredFailure(config.appId);
5288
+ } catch {
5289
+ }
5290
+ }
5165
5291
  } else {
5166
5292
  configureMeasuredFailureBrain(void 0);
5167
5293
  }
@@ -5788,6 +5914,41 @@ async function recordGoldenIr(input) {
5788
5914
  }
5789
5915
  }
5790
5916
 
5917
+ // src/json-loose.ts
5918
+ function parseJsonLoose(raw) {
5919
+ const attempt = (s) => {
5920
+ try {
5921
+ return JSON.parse(s);
5922
+ } catch {
5923
+ return FAILED;
5924
+ }
5925
+ };
5926
+ const direct = attempt(raw);
5927
+ if (direct !== FAILED) return { ok: true, value: direct, recovered: false };
5928
+ const cleaned = raw.trim().replace(/^```(?:json|JSON)?\s*/, "").replace(/\s*```$/, "").trim();
5929
+ const fenced = attempt(cleaned);
5930
+ if (fenced !== FAILED) return { ok: true, value: fenced, recovered: true };
5931
+ const objStart = cleaned.indexOf("{");
5932
+ const arrStart = cleaned.indexOf("[");
5933
+ const start = objStart === -1 ? arrStart : arrStart === -1 ? objStart : Math.min(objStart, arrStart);
5934
+ if (start !== -1) {
5935
+ const openChar = cleaned[start];
5936
+ const closeChar = openChar === "{" ? "}" : "]";
5937
+ const end = cleaned.lastIndexOf(closeChar);
5938
+ if (end > start) {
5939
+ const span = attempt(cleaned.slice(start, end + 1));
5940
+ if (span !== FAILED) return { ok: true, value: span, recovered: true };
5941
+ }
5942
+ }
5943
+ try {
5944
+ JSON.parse(raw);
5945
+ return { ok: false, error: "unreachable" };
5946
+ } catch (err) {
5947
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
5948
+ }
5949
+ }
5950
+ var FAILED = /* @__PURE__ */ Symbol("parse-failed");
5951
+
5791
5952
  // src/ir.ts
5792
5953
  var CallError = class extends Error {
5793
5954
  attempts;
@@ -7146,6 +7307,14 @@ function emitFallbackWalked(traceId, appId, data) {
7146
7307
  }
7147
7308
 
7148
7309
  // src/call.ts
7310
+ function resolveGateWarmupMs(opts) {
7311
+ const declared = opts.gateWarmupMs;
7312
+ if (typeof declared === "number" && Number.isFinite(declared) && declared >= 0) {
7313
+ return declared;
7314
+ }
7315
+ return DEFAULT_GATE_WARMUP_MS;
7316
+ }
7317
+ var DEFAULT_GATE_WARMUP_MS = 400;
7149
7318
  async function call(ir, opts = {}) {
7150
7319
  const traceId = generateTraceId();
7151
7320
  safeEmit(
@@ -7161,6 +7330,7 @@ async function call(ir, opts = {}) {
7161
7330
  )
7162
7331
  })
7163
7332
  );
7333
+ await awaitMeasuredFailureReady(ir.appId, resolveGateWarmupMs(opts));
7164
7334
  const initial = compileAndRegister(ir, opts);
7165
7335
  safeEmit(
7166
7336
  () => emitCompileDone(traceId, ir.appId, {
@@ -7744,10 +7914,12 @@ function validateStructuredContract(exec, ir) {
7744
7914
  if (!exec.response.text) {
7745
7915
  return { ok: true, response: exec.response };
7746
7916
  }
7747
- try {
7748
- const parsed = JSON.parse(exec.response.text);
7749
- return { ok: true, response: { ...exec.response, structuredOutput: parsed } };
7750
- } catch (err) {
7917
+ const parsedResult = parseJsonLoose(exec.response.text);
7918
+ if (parsedResult.ok) {
7919
+ return { ok: true, response: { ...exec.response, structuredOutput: parsedResult.value } };
7920
+ }
7921
+ {
7922
+ const err = new Error(parsedResult.error);
7751
7923
  return {
7752
7924
  ok: false,
7753
7925
  status: exec.status,
@@ -8627,7 +8799,7 @@ function createBrainForwardRoutes(config) {
8627
8799
  }
8628
8800
 
8629
8801
  // src/version.ts
8630
- var LIBRARY_VERSION = "2.0.0-alpha.71";
8802
+ var LIBRARY_VERSION = "2.0.0-alpha.73";
8631
8803
 
8632
8804
  // src/key-health.ts
8633
8805
  var JSON_HEADERS2 = { "Content-Type": "application/json" };
@@ -9282,6 +9454,7 @@ function compile2(ir, opts) {
9282
9454
  applyArchetypeConvention,
9283
9455
  applySectionRewrites,
9284
9456
  attachCacheControlToStreamTextInput,
9457
+ awaitMeasuredFailureReady,
9285
9458
  brainHealth,
9286
9459
  bucketContext,
9287
9460
  bucketHistory,
@@ -9351,6 +9524,7 @@ function compile2(ir, opts) {
9351
9524
  parseGoldenCaptureRate,
9352
9525
  parseJudgeVerdict,
9353
9526
  peekBrainDeadLetter,
9527
+ prefetchMeasuredFailure,
9354
9528
  probeShadow,
9355
9529
  profileToRow,
9356
9530
  profilesByProvider,
package/dist/index.mjs CHANGED
@@ -16,7 +16,7 @@ import {
16
16
  import {
17
17
  LIBRARY_VERSION,
18
18
  createKeyHealthRoute
19
- } from "./chunk-URFQR3SB.mjs";
19
+ } from "./chunk-65KZE7AC.mjs";
20
20
  import {
21
21
  ABSOLUTE_FLOOR,
22
22
  ARCHETYPE_FLOOR_DEFAULT,
@@ -42,7 +42,7 @@ import {
42
42
  loadChainsFromBrain,
43
43
  readBrainReadEnv,
44
44
  resolveProviderKey
45
- } from "./chunk-SBFSYCQG.mjs";
45
+ } from "./chunk-46U2NVOL.mjs";
46
46
  import {
47
47
  ALIASES,
48
48
  LATENCY_TIER_MS,
@@ -53,7 +53,7 @@ import {
53
53
  latencyTierOf,
54
54
  profilesByProvider,
55
55
  tryGetProfile
56
- } from "./chunk-4UO4CCSP.mjs";
56
+ } from "./chunk-N36LE3MK.mjs";
57
57
  import {
58
58
  emitAdvisoryFired,
59
59
  emitCompileDone,
@@ -877,20 +877,27 @@ function passScoreTargets(ir, opts) {
877
877
  });
878
878
  }
879
879
  if (qualityGatePenalty > 0) {
880
+ const rankBefore = rank + qualityGatePenalty;
880
881
  if (measuredGate) {
881
882
  const pct = (x) => `${(x * 100).toFixed(0)}%`;
882
883
  policyMutations.push({
883
884
  id: `quality-gate-measured-${modelId}`,
884
885
  source: "quality_gate",
885
886
  passName: "score_targets",
886
- description: `Model ${modelId} gated below the quality floor for archetype '${ir.intent.archetype}' by MEASURED evidence from this app's own outcomes \u2014 ${measuredGate.nFail} of ${measuredGate.n} attempts failed on the quality axis in the trailing window (${pct(measuredGate.rate)}; 95% lower bound ${pct(measuredGate.lowerBound)} > 50%). Down-ranked out of leadership; retained as graceful fallback only. The gate is derived, not stored \u2014 it lifts on its own once the failures age out of the window.`
887
+ rankDelta: -qualityGatePenalty,
888
+ rankBefore,
889
+ rankAfter: rank,
890
+ description: `Model ${modelId} gated below the quality floor for archetype '${ir.intent.archetype}' by MEASURED evidence from this app's own outcomes \u2014 ${measuredGate.nFail} of ${measuredGate.n} attempts failed on the quality axis in the trailing window (${pct(measuredGate.rate)}; 95% lower bound ${pct(measuredGate.lowerBound)} > 50%). Rank ${rankBefore.toFixed(2)} \u2192 ${rank.toFixed(2)} (\u2212${qualityGatePenalty.toFixed(2)}). Down-ranked out of leadership; retained as graceful fallback only. The gate is derived, not stored \u2014 it lifts on its own once the failures age out of the window.`
887
891
  });
888
892
  } else {
889
893
  policyMutations.push({
890
894
  id: `quality-gate-structured-${modelId}`,
891
895
  source: "quality_gate",
892
896
  passName: "score_targets",
893
- description: `Model ${modelId} gated below the quality floor for archetype '${ir.intent.archetype}' \u2014 declared structuredOutput + kgauto convention flags it schema-weak for this contract (structuredOutputHint:'avoid'). Down-ranked out of leadership; retained as graceful fallback only.`
897
+ rankDelta: -qualityGatePenalty,
898
+ rankBefore,
899
+ rankAfter: rank,
900
+ description: `Model ${modelId} gated below the quality floor for archetype '${ir.intent.archetype}' \u2014 declared structuredOutput + kgauto convention flags it schema-weak for this contract (structuredOutputHint:'avoid'). Rank ${rankBefore.toFixed(2)} \u2192 ${rank.toFixed(2)} (\u2212${qualityGatePenalty.toFixed(2)}). Down-ranked out of leadership; retained as graceful fallback only.`
894
901
  });
895
902
  }
896
903
  }
@@ -1138,6 +1145,12 @@ function lower(ir, profile, hints = {}) {
1138
1145
  }
1139
1146
  function lowerAnthropic(ir, profile, hints) {
1140
1147
  const systemBlocks = buildAnthropicSystemBlocks(ir.sections, profile);
1148
+ if (ir.constraints?.structuredOutput) {
1149
+ systemBlocks.push({
1150
+ type: "text",
1151
+ text: "Respond with a single valid JSON value and nothing else. Do not wrap it in a markdown code fence, and do not add any prose before or after it."
1152
+ });
1153
+ }
1141
1154
  const history = (ir.history ?? []).filter((m) => m.role !== "system");
1142
1155
  const policy = ir.historyCachePolicy;
1143
1156
  const markIndex = resolveHistoryMarkIndex(history.length, policy);
@@ -2624,6 +2637,40 @@ function configureMeasuredFailureBrain(rt) {
2624
2637
  function isMeasuredFailureBrainActive() {
2625
2638
  return runtime5 !== void 0;
2626
2639
  }
2640
+ function prefetchMeasuredFailure(appId) {
2641
+ const rt = runtime5;
2642
+ if (!rt || !appId) return void 0;
2643
+ let snap = snapshots5.get(appId);
2644
+ if (!snap) {
2645
+ snap = { data: [], expiresAt: 0, refreshing: false };
2646
+ snapshots5.set(appId, snap);
2647
+ }
2648
+ if (snap.expiresAt > Date.now()) return void 0;
2649
+ const inflight = pendingRefreshes5.get(appId);
2650
+ if (inflight) return inflight;
2651
+ if (snap.refreshing) return void 0;
2652
+ snap.refreshing = true;
2653
+ void asyncRefresh5(rt, appId);
2654
+ return pendingRefreshes5.get(appId);
2655
+ }
2656
+ async function awaitMeasuredFailureReady(appId, timeoutMs) {
2657
+ if (!runtime5 || !appId) return;
2658
+ const pending = prefetchMeasuredFailure(appId) ?? pendingRefreshes5.get(appId);
2659
+ if (!(timeoutMs > 0)) return;
2660
+ if (!pending) return;
2661
+ let timer;
2662
+ try {
2663
+ await Promise.race([
2664
+ pending,
2665
+ new Promise((resolve) => {
2666
+ timer = setTimeout(resolve, timeoutMs);
2667
+ })
2668
+ ]);
2669
+ } catch {
2670
+ } finally {
2671
+ if (timer) clearTimeout(timer);
2672
+ }
2673
+ }
2627
2674
  function getMeasuredFailureVerdict(opts) {
2628
2675
  const rt = runtime5;
2629
2676
  if (!rt) return void 0;
@@ -3129,6 +3176,12 @@ function configureBrain(config) {
3129
3176
  fetchImpl: config.fetchImpl ?? fetch,
3130
3177
  onError: config.onError
3131
3178
  });
3179
+ if (config.appId) {
3180
+ try {
3181
+ void prefetchMeasuredFailure(config.appId);
3182
+ } catch {
3183
+ }
3184
+ }
3132
3185
  } else {
3133
3186
  configureMeasuredFailureBrain(void 0);
3134
3187
  }
@@ -3755,6 +3808,41 @@ async function recordGoldenIr(input) {
3755
3808
  }
3756
3809
  }
3757
3810
 
3811
+ // src/json-loose.ts
3812
+ function parseJsonLoose(raw) {
3813
+ const attempt = (s) => {
3814
+ try {
3815
+ return JSON.parse(s);
3816
+ } catch {
3817
+ return FAILED;
3818
+ }
3819
+ };
3820
+ const direct = attempt(raw);
3821
+ if (direct !== FAILED) return { ok: true, value: direct, recovered: false };
3822
+ const cleaned = raw.trim().replace(/^```(?:json|JSON)?\s*/, "").replace(/\s*```$/, "").trim();
3823
+ const fenced = attempt(cleaned);
3824
+ if (fenced !== FAILED) return { ok: true, value: fenced, recovered: true };
3825
+ const objStart = cleaned.indexOf("{");
3826
+ const arrStart = cleaned.indexOf("[");
3827
+ const start = objStart === -1 ? arrStart : arrStart === -1 ? objStart : Math.min(objStart, arrStart);
3828
+ if (start !== -1) {
3829
+ const openChar = cleaned[start];
3830
+ const closeChar = openChar === "{" ? "}" : "]";
3831
+ const end = cleaned.lastIndexOf(closeChar);
3832
+ if (end > start) {
3833
+ const span = attempt(cleaned.slice(start, end + 1));
3834
+ if (span !== FAILED) return { ok: true, value: span, recovered: true };
3835
+ }
3836
+ }
3837
+ try {
3838
+ JSON.parse(raw);
3839
+ return { ok: false, error: "unreachable" };
3840
+ } catch (err) {
3841
+ return { ok: false, error: err instanceof Error ? err.message : String(err) };
3842
+ }
3843
+ }
3844
+ var FAILED = /* @__PURE__ */ Symbol("parse-failed");
3845
+
3758
3846
  // src/ir.ts
3759
3847
  var CallError = class extends Error {
3760
3848
  attempts;
@@ -4374,6 +4462,14 @@ function tryParseJson2(s) {
4374
4462
  }
4375
4463
 
4376
4464
  // src/call.ts
4465
+ function resolveGateWarmupMs(opts) {
4466
+ const declared = opts.gateWarmupMs;
4467
+ if (typeof declared === "number" && Number.isFinite(declared) && declared >= 0) {
4468
+ return declared;
4469
+ }
4470
+ return DEFAULT_GATE_WARMUP_MS;
4471
+ }
4472
+ var DEFAULT_GATE_WARMUP_MS = 400;
4377
4473
  async function call(ir, opts = {}) {
4378
4474
  const traceId = generateTraceId();
4379
4475
  safeEmit(
@@ -4389,6 +4485,7 @@ async function call(ir, opts = {}) {
4389
4485
  )
4390
4486
  })
4391
4487
  );
4488
+ await awaitMeasuredFailureReady(ir.appId, resolveGateWarmupMs(opts));
4392
4489
  const initial = compileAndRegister(ir, opts);
4393
4490
  safeEmit(
4394
4491
  () => emitCompileDone(traceId, ir.appId, {
@@ -4972,10 +5069,12 @@ function validateStructuredContract(exec, ir) {
4972
5069
  if (!exec.response.text) {
4973
5070
  return { ok: true, response: exec.response };
4974
5071
  }
4975
- try {
4976
- const parsed = JSON.parse(exec.response.text);
4977
- return { ok: true, response: { ...exec.response, structuredOutput: parsed } };
4978
- } catch (err) {
5072
+ const parsedResult = parseJsonLoose(exec.response.text);
5073
+ if (parsedResult.ok) {
5074
+ return { ok: true, response: { ...exec.response, structuredOutput: parsedResult.value } };
5075
+ }
5076
+ {
5077
+ const err = new Error(parsedResult.error);
4979
5078
  return {
4980
5079
  ok: false,
4981
5080
  status: exec.status,
@@ -6144,6 +6243,7 @@ export {
6144
6243
  applyArchetypeConvention,
6145
6244
  applySectionRewrites,
6146
6245
  attachCacheControlToStreamTextInput,
6246
+ awaitMeasuredFailureReady,
6147
6247
  brainHealth,
6148
6248
  bucketContext,
6149
6249
  bucketHistory,
@@ -6213,6 +6313,7 @@ export {
6213
6313
  parseGoldenCaptureRate,
6214
6314
  parseJudgeVerdict,
6215
6315
  peekBrainDeadLetter,
6316
+ prefetchMeasuredFailure,
6216
6317
  probeShadow,
6217
6318
  profileToRow,
6218
6319
  profilesByProvider,
@@ -419,6 +419,28 @@ type MutationApplied = {
419
419
  source: string;
420
420
  passName: string;
421
421
  description: string;
422
+ /**
423
+ * alpha.73 — the ranking delta this mutation applied, when it applied one.
424
+ * Negative de-ranks, positive boosts. Absent for mutations that do not touch
425
+ * rank (advisory/labelling mutations).
426
+ *
427
+ * Exists because a consumer could previously see *that* a gate fired and
428
+ * *why*, but not *how much* — which cannot distinguish "the gate did not see
429
+ * this model" from "the gate saw it and the penalty lost to a price
430
+ * advantage." PB spent two days and three wrong conclusions inside that gap
431
+ * (2026-07-25/26), and both wrong conclusions were inferences substituted
432
+ * for a quantity that was known at emit time and thrown away. Same class as
433
+ * the `rankedOn` request: a consumer cannot reason about ranking behaviour
434
+ * it cannot observe, so it will guess.
435
+ */
436
+ rankDelta?: number;
437
+ /**
438
+ * alpha.73 — the model's rank before and after this mutation, when it
439
+ * changed one. Together with `rankDelta` this answers the question a
440
+ * penalty magnitude alone cannot: whether the gated model still WON.
441
+ */
442
+ rankBefore?: number;
443
+ rankAfter?: number;
422
444
  };
423
445
  /**
424
446
  * Target-specific wire request. Shape varies by provider — caller passes the
@@ -1051,6 +1073,23 @@ interface CallOptions {
1051
1073
  * fire-and-forget. See {@link ShadowProbeConfig}.
1052
1074
  */
1053
1075
  shadowProbe?: ShadowProbeConfig;
1076
+ /**
1077
+ * alpha.73 — how long `call()` may wait for the measured-failure gate's
1078
+ * first brain read before compiling, in ms. Default 400.
1079
+ *
1080
+ * Exists because `compile()` is synchronous and therefore reads only what
1081
+ * the SWR cache already holds: on a cold isolate that is nothing, so the
1082
+ * gate silently does not fire on the first compile — measured on
1083
+ * playbacksam as two billed inferences and ~27–34s of added latency, every
1084
+ * time an isolate is new. Low-traffic consumers are cold most of the time,
1085
+ * so this hits them hardest, inverting the usual severity ordering.
1086
+ *
1087
+ * The wait is bounded and never required: on timeout, brain-down, or no
1088
+ * brain configured, the call proceeds un-gated exactly as before. Set `0`
1089
+ * to disable the wait entirely (the background prefetch still runs, so
1090
+ * later calls in the same isolate are gated either way).
1091
+ */
1092
+ gateWarmupMs?: number;
1054
1093
  toolRelevanceThreshold?: number;
1055
1094
  compressHistoryAfter?: number;
1056
1095
  /** Override API keys (defaults: process.env). */
@@ -419,6 +419,28 @@ type MutationApplied = {
419
419
  source: string;
420
420
  passName: string;
421
421
  description: string;
422
+ /**
423
+ * alpha.73 — the ranking delta this mutation applied, when it applied one.
424
+ * Negative de-ranks, positive boosts. Absent for mutations that do not touch
425
+ * rank (advisory/labelling mutations).
426
+ *
427
+ * Exists because a consumer could previously see *that* a gate fired and
428
+ * *why*, but not *how much* — which cannot distinguish "the gate did not see
429
+ * this model" from "the gate saw it and the penalty lost to a price
430
+ * advantage." PB spent two days and three wrong conclusions inside that gap
431
+ * (2026-07-25/26), and both wrong conclusions were inferences substituted
432
+ * for a quantity that was known at emit time and thrown away. Same class as
433
+ * the `rankedOn` request: a consumer cannot reason about ranking behaviour
434
+ * it cannot observe, so it will guess.
435
+ */
436
+ rankDelta?: number;
437
+ /**
438
+ * alpha.73 — the model's rank before and after this mutation, when it
439
+ * changed one. Together with `rankDelta` this answers the question a
440
+ * penalty magnitude alone cannot: whether the gated model still WON.
441
+ */
442
+ rankBefore?: number;
443
+ rankAfter?: number;
422
444
  };
423
445
  /**
424
446
  * Target-specific wire request. Shape varies by provider — caller passes the
@@ -1051,6 +1073,23 @@ interface CallOptions {
1051
1073
  * fire-and-forget. See {@link ShadowProbeConfig}.
1052
1074
  */
1053
1075
  shadowProbe?: ShadowProbeConfig;
1076
+ /**
1077
+ * alpha.73 — how long `call()` may wait for the measured-failure gate's
1078
+ * first brain read before compiling, in ms. Default 400.
1079
+ *
1080
+ * Exists because `compile()` is synchronous and therefore reads only what
1081
+ * the SWR cache already holds: on a cold isolate that is nothing, so the
1082
+ * gate silently does not fire on the first compile — measured on
1083
+ * playbacksam as two billed inferences and ~27–34s of added latency, every
1084
+ * time an isolate is new. Low-traffic consumers are cold most of the time,
1085
+ * so this hits them hardest, inverting the usual severity ordering.
1086
+ *
1087
+ * The wait is bounded and never required: on timeout, brain-down, or no
1088
+ * brain configured, the call proceeds un-gated exactly as before. Set `0`
1089
+ * to disable the wait entirely (the background prefetch still runs, so
1090
+ * later calls in the same isolate are gated either way).
1091
+ */
1092
+ gateWarmupMs?: number;
1054
1093
  toolRelevanceThreshold?: number;
1055
1094
  compressHistoryAfter?: number;
1056
1095
  /** Override API keys (defaults: process.env). */
@@ -25,7 +25,7 @@ __export(key_health_exports, {
25
25
  module.exports = __toCommonJS(key_health_exports);
26
26
 
27
27
  // src/version.ts
28
- var LIBRARY_VERSION = "2.0.0-alpha.71";
28
+ var LIBRARY_VERSION = "2.0.0-alpha.73";
29
29
 
30
30
  // src/key-health.ts
31
31
  var JSON_HEADERS = { "Content-Type": "application/json" };
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  createKeyHealthRoute
3
- } from "./chunk-URFQR3SB.mjs";
3
+ } from "./chunk-65KZE7AC.mjs";
4
4
  export {
5
5
  createKeyHealthRoute
6
6
  };
@@ -1,4 +1,4 @@
1
- import { k as Provider } from './ir-CnnJST_N.mjs';
1
+ import { k as Provider } from './ir-CZukZvDn.mjs';
2
2
  import { IntentArchetypeName } from './dialect.mjs';
3
3
 
4
4
  /**