@warmdrift/kgauto-compiler 2.0.0-alpha.60 → 2.0.0-alpha.62

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.
Files changed (36) hide show
  1. package/README.md +81 -46
  2. package/dist/brain-proxy.js +5 -1
  3. package/dist/brain-proxy.mjs +1 -1
  4. package/dist/{chunk-5TI6PNSK.mjs → chunk-3KQAID63.mjs} +5 -0
  5. package/dist/{chunk-IUWFML6Z.mjs → chunk-65ZMX5OT.mjs} +5 -1
  6. package/dist/{chunk-RQ3BUUB6.mjs → chunk-ABFXMO73.mjs} +1 -1
  7. package/dist/{chunk-IIMPJZNH.mjs → chunk-YZRPNSSQ.mjs} +10 -0
  8. package/dist/dialect.d.mts +14 -2
  9. package/dist/dialect.d.ts +14 -2
  10. package/dist/dialect.js +5 -0
  11. package/dist/dialect.mjs +1 -1
  12. package/dist/glassbox/index.d.mts +3 -3
  13. package/dist/glassbox/index.d.ts +3 -3
  14. package/dist/glassbox-routes/format.d.mts +2 -2
  15. package/dist/glassbox-routes/format.d.ts +2 -2
  16. package/dist/glassbox-routes/index.d.mts +4 -4
  17. package/dist/glassbox-routes/index.d.ts +4 -4
  18. package/dist/glassbox-routes/index.js +10 -0
  19. package/dist/glassbox-routes/index.mjs +1 -1
  20. package/dist/glassbox-routes/react/index.d.mts +2 -2
  21. package/dist/glassbox-routes/react/index.d.ts +2 -2
  22. package/dist/index.d.mts +255 -7
  23. package/dist/index.d.ts +255 -7
  24. package/dist/index.js +841 -7
  25. package/dist/index.mjs +808 -9
  26. package/dist/{ir-BC4uDL98.d.mts → ir-B2dRyJXO.d.mts} +84 -11
  27. package/dist/{ir-B2h0GAEL.d.ts → ir-ClU56aBc.d.ts} +84 -11
  28. package/dist/key-health.js +1 -1
  29. package/dist/key-health.mjs +1 -1
  30. package/dist/profiles.d.mts +1 -1
  31. package/dist/profiles.d.ts +1 -1
  32. package/dist/{types-CKuu7Clz.d.ts → types-ByN3r0_7.d.ts} +1 -1
  33. package/dist/{types-CsB2YASc.d.ts → types-C-Wp7HpI.d.ts} +1 -1
  34. package/dist/{types-B-pzBJKf.d.mts → types-CSDweZsl.d.mts} +1 -1
  35. package/dist/{types-CRy90cjp.d.mts → types-axAX1Bg0.d.mts} +1 -1
  36. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -30,6 +30,7 @@ __export(index_exports, {
30
30
  DIALECT_VERSION: () => DIALECT_VERSION,
31
31
  FamilyResolutionError: () => FamilyResolutionError,
32
32
  INTENT_ARCHETYPES: () => INTENT_ARCHETYPES,
33
+ JUDGE_RUBRICS: () => JUDGE_RUBRICS,
33
34
  LATENCY_TIER_MS: () => LATENCY_TIER_MS,
34
35
  LIBRARY_VERSION: () => LIBRARY_VERSION,
35
36
  MEASURED_GROUNDING_MIN_N: () => MEASURED_GROUNDING_MIN_N,
@@ -41,13 +42,18 @@ __export(index_exports, {
41
42
  applyArchetypeConvention: () => applyArchetypeConvention,
42
43
  applySectionRewrites: () => applySectionRewrites,
43
44
  attachCacheControlToStreamTextInput: () => attachCacheControlToStreamTextInput,
45
+ brainHealth: () => brainHealth,
44
46
  bucketContext: () => bucketContext,
45
47
  bucketHistory: () => bucketHistory,
46
48
  bucketToolCount: () => bucketToolCount,
49
+ buildGoldenIrRow: () => buildGoldenIrRow,
47
50
  buildLLMJudge: () => buildLLMJudge,
51
+ buildPairwiseJudgePrompt: () => buildPairwiseJudgePrompt,
48
52
  buildShadowProbeRow: () => buildShadowProbeRow,
49
53
  call: () => call,
54
+ captureGoldenIr: () => captureGoldenIr,
50
55
  clearBrain: () => clearBrain,
56
+ combineOrderSwappedVerdicts: () => combineOrderSwappedVerdicts,
51
57
  compile: () => compile2,
52
58
  compileForAISDKv6: () => compileForAISDKv6,
53
59
  configureBrain: () => configureBrain,
@@ -58,6 +64,7 @@ __export(index_exports, {
58
64
  deriveOwnership: () => deriveOwnership,
59
65
  execute: () => execute,
60
66
  findBetterFit: () => findBetterFit,
67
+ flushBrainDeadLetter: () => flushBrainDeadLetter,
61
68
  getActionableAdvisories: () => getActionableAdvisories,
62
69
  getAllStarterChains: () => getAllStarterChains,
63
70
  getAllStarterChainsWithGrounding: () => getAllStarterChainsWithGrounding,
@@ -92,19 +99,28 @@ __export(index_exports, {
92
99
  markAdvisoryResolved: () => markAdvisoryResolved,
93
100
  markExclusionFindingHandled: () => markExclusionFindingHandled,
94
101
  markPromoteReadyHandled: () => markPromoteReadyHandled,
102
+ parseGoldenCaptureRate: () => parseGoldenCaptureRate,
103
+ parseJudgeVerdict: () => parseJudgeVerdict,
104
+ peekBrainDeadLetter: () => peekBrainDeadLetter,
95
105
  probeShadow: () => probeShadow,
96
106
  profileToRow: () => profileToRow,
97
107
  profilesByProvider: () => profilesByProvider,
98
108
  readBrainReadEnv: () => readBrainReadEnv,
99
109
  record: () => record,
110
+ recordGoldenIr: () => recordGoldenIr,
100
111
  recordOutcome: () => recordOutcome,
101
112
  recordShadowProbe: () => recordShadowProbe,
113
+ renderIrForJudge: () => renderIrForJudge,
102
114
  resetTokenizer: () => resetTokenizer,
103
115
  resolveConventionsForProfile: () => resolveConventionsForProfile,
116
+ resolveGoldenCaptureRate: () => resolveGoldenCaptureRate,
104
117
  resolvePricingAt: () => resolvePricingAt,
105
118
  resolveProviderKey: () => resolveProviderKey,
119
+ rubricFor: () => rubricFor,
106
120
  runAdvisor: () => runAdvisor,
121
+ runGoldenEval: () => runGoldenEval,
107
122
  setTokenizer: () => setTokenizer,
123
+ shouldCaptureGolden: () => shouldCaptureGolden,
108
124
  tryGetProfile: () => tryGetProfile
109
125
  });
110
126
  module.exports = __toCommonJS(index_exports);
@@ -2292,6 +2308,11 @@ var INTENT_ARCHETYPES = {
2292
2308
  name: "transform",
2293
2309
  description: "Change format or style while preserving content",
2294
2310
  examples: ["markdown \u2192 html", "formal \u2192 casual", "translate"]
2311
+ },
2312
+ judge: {
2313
+ name: "judge",
2314
+ description: "Pairwise comparison of two candidate outputs for the same input",
2315
+ examples: ["golden-set eval A/B verdict", "model-swap non-inferiority check", "response bake-off"]
2295
2316
  }
2296
2317
  };
2297
2318
  var ALL_ARCHETYPES = Object.keys(INTENT_ARCHETYPES);
@@ -4468,6 +4489,134 @@ function clearBrain() {
4468
4489
  configureBrainQuery(void 0);
4469
4490
  configureExclusionFindingsBrain(void 0);
4470
4491
  }
4492
+ var DEAD_LETTER_MAX_ENTRIES = 50;
4493
+ var DEAD_LETTER_MAX_ATTEMPTS = 3;
4494
+ var ledger = {
4495
+ sent: 0,
4496
+ acked: 0,
4497
+ failed: 0,
4498
+ redirected: 0,
4499
+ lastAckAt: void 0,
4500
+ lastFailureAt: void 0,
4501
+ lastFailure: void 0
4502
+ };
4503
+ var deadLetter = [];
4504
+ var flushing = false;
4505
+ function noteSent() {
4506
+ ledger.sent += 1;
4507
+ }
4508
+ function noteAck() {
4509
+ ledger.acked += 1;
4510
+ ledger.lastAckAt = (/* @__PURE__ */ new Date()).toISOString();
4511
+ }
4512
+ function noteFailure(err) {
4513
+ ledger.failed += 1;
4514
+ ledger.lastFailureAt = (/* @__PURE__ */ new Date()).toISOString();
4515
+ const msg = err instanceof Error ? err.message : String(err);
4516
+ ledger.lastFailure = msg.length > 300 ? `${msg.slice(0, 300)}\u2026` : msg;
4517
+ }
4518
+ function assertNotRedirected(res, route) {
4519
+ if (!res.redirected) return;
4520
+ ledger.redirected += 1;
4521
+ throw new Error(
4522
+ `brain ${route} POST was redirected to ${res.url} \u2014 the write did NOT land. Likely cause: consumer middleware (auth/login allowlist) intercepts the brain proxy path. Add your kgauto proxy routes to the middleware public paths (the 2026-07-02 tt-intel/IC middleware-drift class).`
4523
+ );
4524
+ }
4525
+ function pushDeadLetter(route, endpoint, payload, err) {
4526
+ if (deadLetter.length >= DEAD_LETTER_MAX_ENTRIES) deadLetter.shift();
4527
+ deadLetter.push({
4528
+ route,
4529
+ endpoint,
4530
+ payload,
4531
+ failedAt: (/* @__PURE__ */ new Date()).toISOString(),
4532
+ attempts: 1,
4533
+ lastError: err instanceof Error ? err.message : String(err)
4534
+ });
4535
+ }
4536
+ function maybeAutoFlush() {
4537
+ if (deadLetter.length === 0 || flushing) return;
4538
+ void flushBrainDeadLetter();
4539
+ }
4540
+ function brainHealth() {
4541
+ let endpointHost;
4542
+ if (activeConfig) {
4543
+ try {
4544
+ endpointHost = new URL(activeConfig.endpoint).host;
4545
+ } catch {
4546
+ endpointHost = void 0;
4547
+ }
4548
+ }
4549
+ return {
4550
+ configState: activeConfig ? "configured" : "not_configured",
4551
+ endpointHost,
4552
+ sync: activeConfig?.sync === true,
4553
+ sent: ledger.sent,
4554
+ acked: ledger.acked,
4555
+ failed: ledger.failed,
4556
+ redirected: ledger.redirected,
4557
+ lastAckAt: ledger.lastAckAt,
4558
+ lastFailureAt: ledger.lastFailureAt,
4559
+ lastFailure: ledger.lastFailure,
4560
+ deadLetterCount: deadLetter.length
4561
+ };
4562
+ }
4563
+ function peekBrainDeadLetter() {
4564
+ return deadLetter.slice();
4565
+ }
4566
+ async function flushBrainDeadLetter() {
4567
+ if (!activeConfig || flushing || deadLetter.length === 0) {
4568
+ return { attempted: 0, delivered: 0, remaining: deadLetter.length };
4569
+ }
4570
+ flushing = true;
4571
+ const config = activeConfig;
4572
+ const fetchFn = brainWriteFetch(config);
4573
+ let attempted = 0;
4574
+ let delivered = 0;
4575
+ try {
4576
+ const batch = deadLetter.filter((e) => e.endpoint === config.endpoint);
4577
+ for (const entry of batch) {
4578
+ attempted += 1;
4579
+ noteSent();
4580
+ try {
4581
+ const res = await fetchFn(`${config.endpoint}/${entry.route}`, {
4582
+ method: "POST",
4583
+ headers: {
4584
+ "Content-Type": "application/json",
4585
+ // Replay never chains a secondary — minimal is correct for all routes.
4586
+ Prefer: "return=minimal",
4587
+ ...config.apiKey ? { Authorization: `Bearer ${config.apiKey}` } : {}
4588
+ },
4589
+ body: JSON.stringify(entry.payload)
4590
+ });
4591
+ assertNotRedirected(res, entry.route);
4592
+ if (!res.ok) {
4593
+ const text = await res.text().catch(() => "<no body>");
4594
+ throw new Error(describeBrainWriteFailure(res.status, entry.route, text));
4595
+ }
4596
+ noteAck();
4597
+ delivered += 1;
4598
+ const idx = deadLetter.indexOf(entry);
4599
+ if (idx !== -1) deadLetter.splice(idx, 1);
4600
+ } catch (err) {
4601
+ noteFailure(err);
4602
+ entry.attempts += 1;
4603
+ entry.lastError = err instanceof Error ? err.message : String(err);
4604
+ if (entry.attempts >= DEAD_LETTER_MAX_ATTEMPTS) {
4605
+ const idx = deadLetter.indexOf(entry);
4606
+ if (idx !== -1) deadLetter.splice(idx, 1);
4607
+ (config.onError ?? defaultOnError5)(
4608
+ new Error(
4609
+ `brain dead-letter: dropping ${entry.route} payload after ${entry.attempts} attempts \u2014 last error: ${entry.lastError}`
4610
+ )
4611
+ );
4612
+ }
4613
+ }
4614
+ }
4615
+ } finally {
4616
+ flushing = false;
4617
+ }
4618
+ return { attempted, delivered, remaining: deadLetter.length };
4619
+ }
4471
4620
  var compileRegistry = /* @__PURE__ */ new Map();
4472
4621
  var REGISTRY_MAX_ENTRIES = 1e4;
4473
4622
  function registerCompile(appId, archetype, ir, result) {
@@ -4575,6 +4724,7 @@ async function record(input) {
4575
4724
  const fetchFn = brainWriteFetch(config);
4576
4725
  const send = async () => {
4577
4726
  let outcomeId;
4727
+ noteSent();
4578
4728
  try {
4579
4729
  const res = await fetchFn(`${config.endpoint}/outcomes`, {
4580
4730
  method: "POST",
@@ -4594,20 +4744,26 @@ async function record(input) {
4594
4744
  },
4595
4745
  body: JSON.stringify(payload)
4596
4746
  });
4747
+ assertNotRedirected(res, "outcomes");
4597
4748
  if (!res.ok) {
4598
4749
  const text = await res.text().catch(() => "<no body>");
4599
4750
  throw new Error(describeBrainWriteFailure(res.status, "outcomes", text));
4600
4751
  }
4752
+ noteAck();
4601
4753
  outcomeId = await tryExtractOutcomeId(res);
4602
4754
  } catch (err) {
4755
+ noteFailure(err);
4756
+ pushDeadLetter("outcomes", config.endpoint, payload, err);
4603
4757
  (config.onError ?? defaultOnError5)(err);
4604
4758
  return;
4605
4759
  }
4760
+ maybeAutoFlush();
4606
4761
  const advisories = input.advisories ?? reg?.advisoriesFromCompile;
4607
4762
  if (!advisories || advisories.length === 0) return;
4608
4763
  if (outcomeId === void 0) return;
4764
+ const advisoryPayload = advisories.map((a) => buildAdvisoryRow(outcomeId, a));
4765
+ noteSent();
4609
4766
  try {
4610
- const advisoryPayload = advisories.map((a) => buildAdvisoryRow(outcomeId, a));
4611
4767
  const res = await fetchFn(`${config.endpoint}/compile_outcome_advisories`, {
4612
4768
  method: "POST",
4613
4769
  headers: {
@@ -4617,11 +4773,15 @@ async function record(input) {
4617
4773
  },
4618
4774
  body: JSON.stringify(advisoryPayload)
4619
4775
  });
4776
+ assertNotRedirected(res, "compile_outcome_advisories");
4620
4777
  if (!res.ok) {
4621
4778
  const text = await res.text().catch(() => "<no body>");
4622
4779
  throw new Error(`brain advisories ${res.status}: ${text}`);
4623
4780
  }
4781
+ noteAck();
4624
4782
  } catch (err) {
4783
+ noteFailure(err);
4784
+ pushDeadLetter("compile_outcome_advisories", config.endpoint, advisoryPayload, err);
4625
4785
  (config.onError ?? defaultOnError5)(err);
4626
4786
  }
4627
4787
  };
@@ -4760,6 +4920,7 @@ async function recordOutcome(input) {
4760
4920
  observed_confidence: input.observedConfidence ?? null
4761
4921
  };
4762
4922
  const send = async () => {
4923
+ noteSent();
4763
4924
  try {
4764
4925
  const res = await fetchFn(`${config.endpoint}/compile_outcome_quality`, {
4765
4926
  method: "POST",
@@ -4769,16 +4930,19 @@ async function recordOutcome(input) {
4769
4930
  },
4770
4931
  body: JSON.stringify(payload)
4771
4932
  });
4933
+ assertNotRedirected(res, "compile_outcome_quality");
4772
4934
  if (!res.ok) {
4773
4935
  const text = await res.text().catch(() => "<no body>");
4774
- const err = new Error(
4936
+ throw new Error(
4775
4937
  describeBrainWriteFailure(res.status, "compile_outcome_quality", text)
4776
4938
  );
4777
- (config.onError ?? defaultOnError5)(err);
4778
- return { ok: false, reason: "persistence_failed" };
4779
4939
  }
4940
+ noteAck();
4941
+ maybeAutoFlush();
4780
4942
  return { ok: true };
4781
4943
  } catch (err) {
4944
+ noteFailure(err);
4945
+ pushDeadLetter("compile_outcome_quality", config.endpoint, payload, err);
4782
4946
  (config.onError ?? defaultOnError5)(err);
4783
4947
  return { ok: false, reason: "persistence_failed" };
4784
4948
  }
@@ -4787,7 +4951,7 @@ async function recordOutcome(input) {
4787
4951
  return send();
4788
4952
  }
4789
4953
  void send();
4790
- return { ok: true };
4954
+ return { ok: "queued" };
4791
4955
  }
4792
4956
  function isBrainSync() {
4793
4957
  return activeConfig?.sync === true;
@@ -4829,6 +4993,7 @@ async function recordShadowProbe(input) {
4829
4993
  const fetchFn = brainWriteFetch(config);
4830
4994
  const row = buildShadowProbeRow(input);
4831
4995
  const send = async () => {
4996
+ noteSent();
4832
4997
  try {
4833
4998
  const res = await fetchFn(`${config.endpoint}/probe_outcomes`, {
4834
4999
  method: "POST",
@@ -4839,11 +5004,71 @@ async function recordShadowProbe(input) {
4839
5004
  },
4840
5005
  body: JSON.stringify(row)
4841
5006
  });
5007
+ assertNotRedirected(res, "probe_outcomes");
4842
5008
  if (!res.ok) {
4843
5009
  const text = await res.text().catch(() => "<no body>");
4844
5010
  throw new Error(describeBrainWriteFailure(res.status, "probe_outcomes", text));
4845
5011
  }
5012
+ noteAck();
5013
+ maybeAutoFlush();
4846
5014
  } catch (err) {
5015
+ noteFailure(err);
5016
+ pushDeadLetter("probe_outcomes", config.endpoint, row, err);
5017
+ (config.onError ?? defaultOnError5)(err);
5018
+ }
5019
+ };
5020
+ if (config.sync) {
5021
+ await send();
5022
+ } else {
5023
+ void send();
5024
+ }
5025
+ }
5026
+ function peekRegisteredShapeKey(handle) {
5027
+ return compileRegistry.get(handle)?.shapeKey;
5028
+ }
5029
+ function buildGoldenIrRow(input) {
5030
+ return {
5031
+ app_id: input.appId,
5032
+ intent_archetype: input.archetype,
5033
+ shape_key: input.shapeKey ?? null,
5034
+ ir: input.ir,
5035
+ incumbent_model: input.incumbentModel,
5036
+ incumbent_output: input.incumbentOutput ?? null,
5037
+ incumbent_latency_ms: input.incumbentLatencyMs ?? null,
5038
+ incumbent_tokens_in: input.incumbentTokensIn ?? null,
5039
+ incumbent_tokens_out: input.incumbentTokensOut ?? null,
5040
+ source: input.source,
5041
+ consent: input.consent,
5042
+ outcome_handle: input.outcomeHandle ?? null
5043
+ };
5044
+ }
5045
+ async function recordGoldenIr(input) {
5046
+ if (!activeConfig) return;
5047
+ const config = activeConfig;
5048
+ const fetchFn = brainWriteFetch(config);
5049
+ const row = buildGoldenIrRow(input);
5050
+ const send = async () => {
5051
+ noteSent();
5052
+ try {
5053
+ const res = await fetchFn(`${config.endpoint}/golden_irs`, {
5054
+ method: "POST",
5055
+ headers: {
5056
+ "Content-Type": "application/json",
5057
+ Prefer: "return=minimal",
5058
+ ...config.apiKey ? { Authorization: `Bearer ${config.apiKey}` } : {}
5059
+ },
5060
+ body: JSON.stringify(row)
5061
+ });
5062
+ assertNotRedirected(res, "golden_irs");
5063
+ if (!res.ok) {
5064
+ const text = await res.text().catch(() => "<no body>");
5065
+ throw new Error(describeBrainWriteFailure(res.status, "golden_irs", text));
5066
+ }
5067
+ noteAck();
5068
+ maybeAutoFlush();
5069
+ } catch (err) {
5070
+ noteFailure(err);
5071
+ pushDeadLetter("golden_irs", config.endpoint, row, err);
4847
5072
  (config.onError ?? defaultOnError5)(err);
4848
5073
  }
4849
5074
  };
@@ -4868,6 +5093,45 @@ var CallError = class extends Error {
4868
5093
  }
4869
5094
  };
4870
5095
 
5096
+ // src/golden.ts
5097
+ function parseGoldenCaptureRate(raw) {
5098
+ if (raw === void 0 || raw.trim() === "") return 0;
5099
+ const n = Number(raw);
5100
+ if (!Number.isFinite(n)) return 0;
5101
+ return Math.max(0, Math.min(1, n));
5102
+ }
5103
+ function resolveGoldenCaptureRate(optRate) {
5104
+ if (optRate !== void 0 && Number.isFinite(optRate)) {
5105
+ return Math.max(0, Math.min(1, optRate));
5106
+ }
5107
+ const env = typeof process !== "undefined" && process.env ? process.env.KGAUTO_GOLDEN_CAPTURE : void 0;
5108
+ return parseGoldenCaptureRate(env);
5109
+ }
5110
+ function shouldCaptureGolden(rate, rng = Math.random) {
5111
+ if (rate <= 0) return false;
5112
+ if (rate >= 1) return true;
5113
+ return rng() < rate;
5114
+ }
5115
+ async function captureGoldenIr(ctx) {
5116
+ try {
5117
+ await recordGoldenIr({
5118
+ appId: ctx.ir.appId,
5119
+ archetype: ctx.ir.intent.archetype,
5120
+ shapeKey: ctx.shapeKey,
5121
+ ir: ctx.ir,
5122
+ incumbentModel: ctx.servedModel,
5123
+ incumbentOutput: ctx.response.text,
5124
+ incumbentLatencyMs: ctx.latencyMs,
5125
+ incumbentTokensIn: ctx.response.tokens.input,
5126
+ incumbentTokensOut: ctx.response.tokens.output,
5127
+ source: "sampled",
5128
+ consent: ctx.consent,
5129
+ outcomeHandle: ctx.handle
5130
+ });
5131
+ } catch {
5132
+ }
5133
+ }
5134
+
4871
5135
  // src/env.ts
4872
5136
  var SUPPORTED_PROVIDERS = Object.freeze([
4873
5137
  "anthropic",
@@ -5502,6 +5766,16 @@ var STARTER_CHAINS_GROUNDED = {
5502
5766
  { id: "gemini-2.5-pro", grounding: "judgment", reason: "Cross-provider anchor in similar quality bracket" },
5503
5767
  { id: "gpt-5.5", grounding: "judgment", reason: "alpha.16: third-provider frontier-tier floor (archetypePerf=9)" }
5504
5768
  ],
5769
+ // alpha.62 (eval spine) — pairwise output comparison. Same reasoning-floor
5770
+ // posture as critique (a verdict from a weak judge is worse than no
5771
+ // verdict); tier 0 anchored on the CURRENT opus (4-8, s64 roster). Strict
5772
+ // JSON output, so every tier declares native structured output.
5773
+ judge: [
5774
+ { id: "claude-opus-4-8", grounding: "judgment", reason: "Highest reasoning bar for pairwise verdicts \u2014 current opus (s64 roster)" },
5775
+ { id: "claude-sonnet-4-6", grounding: "judgment", reason: "Same-provider walk-down on 429" },
5776
+ { id: "gemini-2.5-pro", grounding: "judgment", reason: "Cross-provider anchor in similar quality bracket" },
5777
+ { id: "gpt-5.5", grounding: "judgment", reason: "Third-provider frontier-tier floor" }
5778
+ ],
5505
5779
  // Reasoning matters — Sonnet primary; walk UP to Opus on 429.
5506
5780
  plan: [
5507
5781
  { id: "claude-sonnet-4-6", grounding: "judgment", reason: "Reasoning + cost balance \u2014 engineer pick" },
@@ -6294,6 +6568,8 @@ async function call(ir, opts = {}) {
6294
6568
  );
6295
6569
  const fellOver = targetModel !== initial.target;
6296
6570
  const fallbackReason = fellOver ? normalizeFallbackReason(attempts) : void 0;
6571
+ const goldenRate = resolveGoldenCaptureRate(opts.goldenCapture?.sampleRate);
6572
+ const goldenShapeKey = goldenRate > 0 ? peekRegisteredShapeKey(initial.handle) : void 0;
6297
6573
  await record({
6298
6574
  handle: initial.handle,
6299
6575
  tokensIn: validated.response.tokens.input,
@@ -6346,6 +6622,23 @@ async function call(ir, opts = {}) {
6346
6622
  void probe;
6347
6623
  }
6348
6624
  }
6625
+ if (goldenRate > 0 && validated.response.tokens.output > 0 && shouldCaptureGolden(goldenRate)) {
6626
+ const consent = opts.goldenCapture?.sampleRate !== void 0 ? `CallOptions.goldenCapture.sampleRate=${goldenRate} (consumer code opt-in)` + (opts.goldenCapture.consentNote ? ` \u2014 ${opts.goldenCapture.consentNote}` : "") : `KGAUTO_GOLDEN_CAPTURE=${goldenRate} (consumer env opt-in)`;
6627
+ const capture = captureGoldenIr({
6628
+ ir,
6629
+ servedModel: targetModel,
6630
+ response: validated.response,
6631
+ latencyMs: latencyMs2,
6632
+ handle: initial.handle,
6633
+ shapeKey: goldenShapeKey,
6634
+ consent
6635
+ });
6636
+ if (isBrainSync()) {
6637
+ await capture;
6638
+ } else {
6639
+ void capture;
6640
+ }
6641
+ }
6349
6642
  return {
6350
6643
  handle: initial.handle,
6351
6644
  actualModel: targetModel,
@@ -6685,6 +6978,18 @@ function safeEmit(fn) {
6685
6978
  } catch {
6686
6979
  }
6687
6980
  }
6981
+ var _internal = {
6982
+ compileAndRegister,
6983
+ validateStructuredContract,
6984
+ extractPromptPreview,
6985
+ normalizeFallbackReason,
6986
+ generateTraceId,
6987
+ safeEmit,
6988
+ shouldSampleProbe,
6989
+ normalizeProbeCandidates,
6990
+ runShadowProbe,
6991
+ runProbeCandidates
6992
+ };
6688
6993
 
6689
6994
  // src/streamtext-helpers.ts
6690
6995
  function attachCacheControlToStreamTextInput(result, convertedMessages) {
@@ -6784,12 +7089,525 @@ function extractKeptToolNames(result) {
6784
7089
  return names;
6785
7090
  }
6786
7091
 
7092
+ // src/golden-eval.ts
7093
+ var GENERIC_RUBRIC = "overall correctness, completeness against the request, clarity, and adherence to any requested format";
7094
+ var JUDGE_RUBRICS = {
7095
+ summarize: "faithfulness to the source (no fabricated facts), coverage of the key points, concision, and adherence to the requested output format",
7096
+ classify: "assignment of the correct category from the allowed set, and nothing outside the allowed set",
7097
+ generate: "relevance to the brief, quality and coherence of the writing, and adherence to the requested format and tone",
7098
+ extract: "completeness of extraction (nothing relevant missed), precision (no invented fields or values), and exact schema adherence",
7099
+ ask: "correctness of the answer with respect to the provided data, relevance, and absence of fabrication",
7100
+ hunt: "relevance and novelty of the discovered entities, and absence of duplicates or fabricated entries",
7101
+ plan: "quality of the decomposition (complete, ordered, actionable steps) and realism of the sequencing",
7102
+ critique: "specificity and correctness of the assessment, and actionability of the feedback",
7103
+ transform: "preservation of the source content and correctness of the target format or style"
7104
+ };
7105
+ function rubricFor(archetype) {
7106
+ return JUDGE_RUBRICS[archetype] ?? GENERIC_RUBRIC;
7107
+ }
7108
+ var INPUT_TRUNCATE_CHARS = 24e3;
7109
+ var OUTPUT_TRUNCATE_CHARS = 12e3;
7110
+ function renderIrForJudge(ir) {
7111
+ const sections = (ir.sections ?? []).map((s) => s.text).filter(Boolean).join("\n\n");
7112
+ const turn = typeof ir.currentTurn?.content === "string" ? ir.currentTurn.content : "";
7113
+ const combined = [
7114
+ sections ? `[system]
7115
+ ${sections}` : "",
7116
+ turn ? `[user]
7117
+ ${turn}` : ""
7118
+ ].filter(Boolean).join("\n\n");
7119
+ return combined.length > INPUT_TRUNCATE_CHARS ? `${combined.slice(0, INPUT_TRUNCATE_CHARS)}
7120
+ \u2026[truncated]` : combined;
7121
+ }
7122
+ function buildPairwiseJudgePrompt(args) {
7123
+ const clip = (s) => s.length > OUTPUT_TRUNCATE_CHARS ? `${s.slice(0, OUTPUT_TRUNCATE_CHARS)}
7124
+ \u2026[truncated]` : s;
7125
+ return `You are a strict pairwise judge comparing two AI responses to the SAME request.
7126
+
7127
+ The request (archetype: ${args.archetype}):
7128
+ <request>
7129
+ ${args.renderedInput}
7130
+ </request>
7131
+
7132
+ Response A:
7133
+ <response_a>
7134
+ ${clip(args.outputA)}
7135
+ </response_a>
7136
+
7137
+ Response B:
7138
+ <response_b>
7139
+ ${clip(args.outputB)}
7140
+ </response_b>
7141
+
7142
+ Judge which response better satisfies the request. Rubric for ${args.archetype}: ${rubricFor(args.archetype)}.
7143
+
7144
+ A tie is a legitimate verdict \u2014 declare it when the responses are of genuinely comparable quality. Do NOT prefer a response merely for being longer.
7145
+
7146
+ Output ONLY this JSON, no other text:
7147
+ {"winner": "A" | "B" | "tie", "rationale": "<one sentence>"}`;
7148
+ }
7149
+ function parseJudgeVerdict(raw) {
7150
+ const cleaned = raw.replace(/^```(?:json)?\s*/i, "").replace(/\s*```\s*$/, "").trim();
7151
+ let parsed;
7152
+ try {
7153
+ parsed = JSON.parse(cleaned);
7154
+ } catch {
7155
+ const match = cleaned.match(/\{[\s\S]*\}/);
7156
+ if (!match) return void 0;
7157
+ try {
7158
+ parsed = JSON.parse(match[0]);
7159
+ } catch {
7160
+ return void 0;
7161
+ }
7162
+ }
7163
+ if (!parsed || typeof parsed !== "object") return void 0;
7164
+ const obj = parsed;
7165
+ const winner = obj.winner;
7166
+ if (winner !== "A" && winner !== "B" && winner !== "tie") return void 0;
7167
+ return {
7168
+ winner,
7169
+ rationale: typeof obj.rationale === "string" ? obj.rationale : void 0
7170
+ };
7171
+ }
7172
+ function combineOrderSwappedVerdicts(run1, run2) {
7173
+ if (run1 === run2) return run1;
7174
+ return "tied";
7175
+ }
7176
+ function p50(values) {
7177
+ if (values.length === 0) return null;
7178
+ const sorted = [...values].sort((a, b) => a - b);
7179
+ return sorted[Math.floor(sorted.length / 2)] ?? null;
7180
+ }
7181
+ function costUsd(model, tokensIn, tokensOut) {
7182
+ const profile = tryGetProfile(model);
7183
+ if (!profile) return null;
7184
+ return tokensIn / 1e6 * profile.costInputPer1m + tokensOut / 1e6 * profile.costOutputPer1m;
7185
+ }
7186
+ function hashForGolden(s) {
7187
+ let h = 5381;
7188
+ for (let i = 0; i < s.length; i += 1) {
7189
+ h = (h << 5) + h + s.charCodeAt(i) >>> 0;
7190
+ }
7191
+ return `g${h.toString(36)}`;
7192
+ }
7193
+ async function runGoldenEval(opts) {
7194
+ const fetchFn = opts.fetchImpl ?? fetch;
7195
+ const progress = opts.onProgress ?? (() => {
7196
+ });
7197
+ const limit = opts.limit ?? 50;
7198
+ const threshold = opts.winOrTieThreshold ?? 0.8;
7199
+ const latencyFloorRatio = opts.latencyFloorRatio ?? 3;
7200
+ const minJudgeable = opts.minJudgeableCases ?? 5;
7201
+ const judgeModel = opts.judgeModel ?? "claude-opus-4-8";
7202
+ const notes = [];
7203
+ const restHeaders = {
7204
+ apikey: opts.serviceKey,
7205
+ Authorization: `Bearer ${opts.serviceKey}`
7206
+ };
7207
+ const rest = (path) => `${opts.supabaseUrl}/rest/v1/${path}`;
7208
+ const setUrl = rest(
7209
+ `kgauto_golden_irs?app_id=eq.${encodeURIComponent(opts.appId)}&intent_archetype=eq.${encodeURIComponent(opts.archetype)}&active=is.true&select=id,app_id,intent_archetype,ir,incumbent_model&order=captured_at.desc&limit=${limit}`
7210
+ );
7211
+ const setRes = await fetchFn(setUrl, { headers: restHeaders });
7212
+ if (!setRes.ok) {
7213
+ throw new Error(
7214
+ `golden-eval: failed to load golden set (${setRes.status}): ${await setRes.text().catch(() => "<no body>")}`
7215
+ );
7216
+ }
7217
+ const goldenRows = await setRes.json();
7218
+ if (goldenRows.length === 0) {
7219
+ throw new Error(
7220
+ `golden-eval: no active golden IRs for (${opts.appId}, ${opts.archetype}) \u2014 seed via KGAUTO_GOLDEN_CAPTURE or scripts/seed-golden-set.mjs first.`
7221
+ );
7222
+ }
7223
+ progress(`Loaded ${goldenRows.length} golden case(s).`);
7224
+ let incumbentModel = opts.incumbentModel;
7225
+ if (!incumbentModel) {
7226
+ const counts = /* @__PURE__ */ new Map();
7227
+ for (const row of goldenRows) {
7228
+ counts.set(row.incumbent_model, (counts.get(row.incumbent_model) ?? 0) + 1);
7229
+ }
7230
+ const top = [...counts.entries()].sort((a, b) => b[1] - a[1])[0];
7231
+ if (!top) throw new Error("golden-eval: could not resolve an incumbent from the golden set.");
7232
+ incumbentModel = top[0];
7233
+ notes.push(`incumbent defaulted to most-captured model: ${incumbentModel}`);
7234
+ }
7235
+ if (incumbentModel === opts.candidateModel) {
7236
+ throw new Error("golden-eval: candidate and incumbent are the same model.");
7237
+ }
7238
+ const judgeProfile = tryGetProfile(judgeModel);
7239
+ if (!judgeProfile) {
7240
+ throw new Error(`golden-eval: judge model '${judgeModel}' is not in the roster.`);
7241
+ }
7242
+ if (judgeProfile.family && [incumbentModel, opts.candidateModel].some(
7243
+ (m) => tryGetProfile(m)?.family === judgeProfile.family
7244
+ )) {
7245
+ notes.push(
7246
+ `WARNING: judge family (${judgeProfile.family}) overlaps a compared model \u2014 self-preference risk; consider --judge from another provider.`
7247
+ );
7248
+ }
7249
+ const replay = async (ir, model) => {
7250
+ try {
7251
+ const evalIr = {
7252
+ ...ir,
7253
+ models: [model],
7254
+ constraints: { ...ir.constraints ?? {}, forceModel: model }
7255
+ };
7256
+ const compiled = compile(evalIr);
7257
+ const attempt = () => execute(compiled.request, { apiKeys: opts.apiKeys, fetchImpl: opts.fetchImpl });
7258
+ let started = Date.now();
7259
+ let exec = await attempt();
7260
+ if (!exec.ok && exec.errorType === "retryable") {
7261
+ await new Promise((r) => setTimeout(r, 2e3));
7262
+ started = Date.now();
7263
+ exec = await attempt();
7264
+ }
7265
+ const latencyMs = Date.now() - started;
7266
+ if (!exec.ok) {
7267
+ return {
7268
+ ok: false,
7269
+ text: "",
7270
+ structuredOutput: null,
7271
+ tokensIn: 0,
7272
+ tokensOut: 0,
7273
+ latencyMs,
7274
+ errorClass: exec.errorCode
7275
+ };
7276
+ }
7277
+ const validated = _internal.validateStructuredContract(exec, evalIr);
7278
+ if (!validated.ok) {
7279
+ return {
7280
+ ok: true,
7281
+ text: exec.response.text,
7282
+ structuredOutput: null,
7283
+ tokensIn: exec.response.tokens.input,
7284
+ tokensOut: exec.response.tokens.output,
7285
+ latencyMs,
7286
+ contractViolation: validated.errorCode
7287
+ };
7288
+ }
7289
+ return {
7290
+ ok: true,
7291
+ text: validated.response.text,
7292
+ structuredOutput: validated.response.structuredOutput,
7293
+ parseError: validated.response.parseError,
7294
+ tokensIn: validated.response.tokens.input,
7295
+ tokensOut: validated.response.tokens.output,
7296
+ latencyMs
7297
+ };
7298
+ } catch (err) {
7299
+ return {
7300
+ ok: false,
7301
+ text: "",
7302
+ structuredOutput: null,
7303
+ tokensIn: 0,
7304
+ tokensOut: 0,
7305
+ latencyMs: 0,
7306
+ errorClass: err instanceof Error ? `execute_rejected:${err.message}` : "execute_rejected"
7307
+ };
7308
+ }
7309
+ };
7310
+ const judgeOnce = async (ir, outputA, outputB) => {
7311
+ const judgeIr = {
7312
+ appId: opts.appId,
7313
+ intent: { name: "golden-eval-judge", archetype: "judge" },
7314
+ sections: [
7315
+ {
7316
+ id: "role",
7317
+ text: "You are a strict, impartial pairwise judge. You output only JSON.",
7318
+ weight: 10
7319
+ }
7320
+ ],
7321
+ currentTurn: {
7322
+ role: "user",
7323
+ content: buildPairwiseJudgePrompt({
7324
+ archetype: opts.archetype,
7325
+ renderedInput: renderIrForJudge(ir),
7326
+ outputA,
7327
+ outputB
7328
+ })
7329
+ },
7330
+ models: [judgeModel],
7331
+ constraints: { forceModel: judgeModel }
7332
+ };
7333
+ try {
7334
+ const compiled = compile(judgeIr);
7335
+ const exec = await execute(compiled.request, {
7336
+ apiKeys: opts.apiKeys,
7337
+ fetchImpl: opts.fetchImpl
7338
+ });
7339
+ if (!exec.ok) return void 0;
7340
+ return parseJudgeVerdict(exec.response.text);
7341
+ } catch {
7342
+ return void 0;
7343
+ }
7344
+ };
7345
+ const cases = [];
7346
+ const floorDetail = {};
7347
+ const bumpFloor = (k) => {
7348
+ floorDetail[k] = (floorDetail[k] ?? 0) + 1;
7349
+ };
7350
+ for (const [i, row] of goldenRows.entries()) {
7351
+ progress(
7352
+ `Case ${i + 1}/${goldenRows.length} (golden #${row.id}): replaying ${incumbentModel} + ${opts.candidateModel}\u2026`
7353
+ );
7354
+ const [inc, cand] = await Promise.all([
7355
+ replay(row.ir, incumbentModel),
7356
+ replay(row.ir, opts.candidateModel)
7357
+ ]);
7358
+ if (!inc.ok || inc.contractViolation) {
7359
+ const why = !inc.ok ? `incumbent replay failed (${inc.errorClass ?? "unknown"})` : `incumbent contract violation (${inc.contractViolation})`;
7360
+ cases.push({
7361
+ goldenIrId: row.id,
7362
+ verdict: "inconclusive",
7363
+ floorViolations: [],
7364
+ excludedReason: why
7365
+ });
7366
+ notes.push(`case #${row.id}: ${why} \u2014 excluded`);
7367
+ continue;
7368
+ }
7369
+ const incumbentLeg = {
7370
+ latencyMs: inc.latencyMs,
7371
+ tokensIn: inc.tokensIn,
7372
+ tokensOut: inc.tokensOut,
7373
+ text: inc.text
7374
+ };
7375
+ const violations = [];
7376
+ if (!cand.ok) {
7377
+ violations.push("candidate_error");
7378
+ bumpFloor("candidate_error");
7379
+ } else if (cand.tokensOut === 0 || cand.text.trim() === "" && !cand.structuredOutput) {
7380
+ violations.push("empty");
7381
+ bumpFloor("empty");
7382
+ } else if (cand.contractViolation) {
7383
+ violations.push("schema");
7384
+ bumpFloor("schema");
7385
+ }
7386
+ if (violations.length > 0) {
7387
+ cases.push({
7388
+ goldenIrId: row.id,
7389
+ verdict: "current-better",
7390
+ floorViolations: violations,
7391
+ errorClass: cand.errorClass ?? cand.contractViolation,
7392
+ incumbent: incumbentLeg,
7393
+ candidate: cand.ok ? { latencyMs: cand.latencyMs, tokensIn: cand.tokensIn, tokensOut: cand.tokensOut, text: cand.text } : void 0
7394
+ });
7395
+ continue;
7396
+ }
7397
+ const [order1, order2] = await Promise.all([
7398
+ judgeOnce(row.ir, inc.text, cand.text),
7399
+ judgeOnce(row.ir, cand.text, inc.text)
7400
+ ]);
7401
+ if (!order1 || !order2) {
7402
+ cases.push({
7403
+ goldenIrId: row.id,
7404
+ verdict: "inconclusive",
7405
+ floorViolations: [],
7406
+ incumbent: incumbentLeg,
7407
+ candidate: { latencyMs: cand.latencyMs, tokensIn: cand.tokensIn, tokensOut: cand.tokensOut, text: cand.text },
7408
+ excludedReason: "judge call failed or unparseable"
7409
+ });
7410
+ notes.push(`case #${row.id}: judge failed \u2014 excluded`);
7411
+ continue;
7412
+ }
7413
+ const v1 = order1.winner === "tie" ? "tied" : order1.winner === "B" ? "candidate-better" : "current-better";
7414
+ const v2 = order2.winner === "tie" ? "tied" : order2.winner === "A" ? "candidate-better" : "current-better";
7415
+ const verdict2 = combineOrderSwappedVerdicts(v1, v2);
7416
+ cases.push({
7417
+ goldenIrId: row.id,
7418
+ verdict: verdict2,
7419
+ judgeRationale: order1.rationale ?? order2.rationale,
7420
+ floorViolations: [],
7421
+ incumbent: incumbentLeg,
7422
+ candidate: { latencyMs: cand.latencyMs, tokensIn: cand.tokensIn, tokensOut: cand.tokensOut, text: cand.text }
7423
+ });
7424
+ }
7425
+ const evaluable = cases.filter((c) => !c.excludedReason);
7426
+ const wins = evaluable.filter((c) => c.verdict === "candidate-better").length;
7427
+ const ties = evaluable.filter((c) => c.verdict === "tied").length;
7428
+ const losses = evaluable.filter((c) => c.verdict === "current-better").length;
7429
+ const floorViolations = evaluable.reduce((n, c) => n + c.floorViolations.length, 0);
7430
+ const winOrTieRatio = evaluable.length > 0 ? (wins + ties) / evaluable.length : null;
7431
+ const incP50 = p50(evaluable.map((c) => c.incumbent?.latencyMs ?? NaN).filter(Number.isFinite));
7432
+ const candP50 = p50(evaluable.map((c) => c.candidate?.latencyMs ?? NaN).filter(Number.isFinite));
7433
+ const latencyRatio = incP50 && candP50 ? candP50 / incP50 : null;
7434
+ const sum = (xs) => xs.some((x) => x === null) ? null : xs.reduce((a, b) => a + b, 0);
7435
+ const costIncumbentUsd = sum(
7436
+ evaluable.map(
7437
+ (c) => c.incumbent ? costUsd(incumbentModel, c.incumbent.tokensIn, c.incumbent.tokensOut) : null
7438
+ )
7439
+ );
7440
+ const costCandidateUsd = sum(
7441
+ evaluable.map(
7442
+ (c) => c.candidate ? costUsd(opts.candidateModel, c.candidate.tokensIn, c.candidate.tokensOut) : null
7443
+ )
7444
+ );
7445
+ const latencyFloorOk = latencyRatio === null || latencyRatio <= latencyFloorRatio;
7446
+ if (!latencyFloorOk) bumpFloor("latency");
7447
+ let verdict;
7448
+ if (evaluable.length < minJudgeable) {
7449
+ verdict = "inconclusive";
7450
+ notes.push(
7451
+ `only ${evaluable.length} evaluable case(s) < minJudgeableCases=${minJudgeable}`
7452
+ );
7453
+ } else if (winOrTieRatio !== null && winOrTieRatio >= threshold && floorViolations === 0 && latencyFloorOk) {
7454
+ verdict = "promote-ready";
7455
+ } else {
7456
+ verdict = "not-inferior";
7457
+ }
7458
+ const result = {
7459
+ verdict,
7460
+ appId: opts.appId,
7461
+ archetype: opts.archetype,
7462
+ incumbentModel,
7463
+ candidateModel: opts.candidateModel,
7464
+ judgeModel,
7465
+ nCases: evaluable.length,
7466
+ wins,
7467
+ ties,
7468
+ losses,
7469
+ floorViolations: floorViolations + (latencyFloorOk ? 0 : 1),
7470
+ floorDetail,
7471
+ winOrTieRatio,
7472
+ latencyRatio,
7473
+ costIncumbentUsd,
7474
+ costCandidateUsd,
7475
+ cases,
7476
+ notes
7477
+ };
7478
+ if (opts.dryRun) {
7479
+ notes.push("dry-run: no brain rows written");
7480
+ return result;
7481
+ }
7482
+ progress("Writing eval evidence to the brain\u2026");
7483
+ const runRes = await fetchFn(rest("kgauto_golden_eval_runs"), {
7484
+ method: "POST",
7485
+ headers: {
7486
+ ...restHeaders,
7487
+ "Content-Type": "application/json",
7488
+ Prefer: "return=representation"
7489
+ },
7490
+ body: JSON.stringify({
7491
+ app_id: opts.appId,
7492
+ intent_archetype: opts.archetype,
7493
+ incumbent_model: incumbentModel,
7494
+ candidate_model: opts.candidateModel,
7495
+ trigger_source: opts.triggerSource ?? "manual",
7496
+ judge_model: judgeModel,
7497
+ n_cases: result.nCases,
7498
+ wins,
7499
+ ties,
7500
+ losses,
7501
+ floor_violations: result.floorViolations,
7502
+ floor_detail: floorDetail,
7503
+ win_or_tie_ratio: winOrTieRatio,
7504
+ latency_ratio: latencyRatio,
7505
+ verdict,
7506
+ win_or_tie_threshold: threshold,
7507
+ notes: notes.join(" | ") || null
7508
+ })
7509
+ });
7510
+ if (!runRes.ok) {
7511
+ throw new Error(
7512
+ `golden-eval: run-row write failed (${runRes.status}): ${await runRes.text().catch(() => "<no body>")}`
7513
+ );
7514
+ }
7515
+ const runRows = await runRes.json();
7516
+ result.runId = runRows[0]?.id;
7517
+ const caseRows = cases.filter((c) => !c.excludedReason).map((c) => {
7518
+ const row = goldenRows.find((g) => g.id === c.goldenIrId);
7519
+ const turn = typeof row?.ir.currentTurn?.content === "string" ? row.ir.currentTurn.content : "";
7520
+ return {
7521
+ app_id: opts.appId,
7522
+ intent_archetype: opts.archetype,
7523
+ family: tryGetProfile(opts.candidateModel)?.family ?? "unknown",
7524
+ candidate_model: opts.candidateModel,
7525
+ current_model: incumbentModel,
7526
+ prompt_hash: hashForGolden(turn),
7527
+ current_response: c.incumbent?.text.slice(0, 500) ?? null,
7528
+ candidate_response: c.candidate?.text.slice(0, 500) ?? null,
7529
+ judge_verdict: c.floorViolations.length > 0 ? null : c.verdict,
7530
+ judge_rationale: c.floorViolations.length > 0 ? `hard-floor violation: ${c.floorViolations.join(",")}` : c.judgeRationale ?? null,
7531
+ judge_model: judgeModel,
7532
+ tokens_current_in: c.incumbent?.tokensIn ?? null,
7533
+ tokens_current_out: c.incumbent?.tokensOut ?? null,
7534
+ tokens_candidate_in: c.candidate?.tokensIn ?? null,
7535
+ tokens_candidate_out: c.candidate?.tokensOut ?? null,
7536
+ latency_current_ms: c.incumbent?.latencyMs ?? null,
7537
+ latency_candidate_ms: c.candidate?.latencyMs ?? null,
7538
+ prompt_fidelity: 1,
7539
+ replay_source: "golden-replay",
7540
+ outcome: c.floorViolations.includes("candidate_error") ? "candidate_error" : "completed",
7541
+ // migration-032 taxonomy: error_class only on candidate_error rows;
7542
+ // schema-floor detail rides in judge_rationale + the run's floor_detail.
7543
+ error_class: c.floorViolations.includes("candidate_error") ? c.errorClass ?? null : null,
7544
+ golden_run_id: result.runId ?? null,
7545
+ golden_ir_id: c.goldenIrId
7546
+ };
7547
+ });
7548
+ if (caseRows.length > 0) {
7549
+ const casesRes = await fetchFn(rest("probe_outcomes"), {
7550
+ method: "POST",
7551
+ headers: { ...restHeaders, "Content-Type": "application/json", Prefer: "return=minimal" },
7552
+ body: JSON.stringify(caseRows)
7553
+ });
7554
+ if (!casesRes.ok) {
7555
+ notes.push(
7556
+ `case-row write failed (${casesRes.status}): ${await casesRes.text().catch(() => "<no body>")}`
7557
+ );
7558
+ }
7559
+ }
7560
+ const latestRes = await fetchFn(
7561
+ rest(
7562
+ `compile_outcomes?app_id=eq.${encodeURIComponent(opts.appId)}&select=id&order=id.desc&limit=1`
7563
+ ),
7564
+ { headers: restHeaders }
7565
+ );
7566
+ const latest = latestRes.ok ? await latestRes.json() : [];
7567
+ const latestOutcomeId = latest[0]?.id;
7568
+ if (latestOutcomeId !== void 0) {
7569
+ const costLine = costIncumbentUsd !== null && costCandidateUsd !== null ? ` Eval cost basis: incumbent $${costIncumbentUsd.toFixed(4)} vs candidate $${costCandidateUsd.toFixed(4)} across the set.` : "";
7570
+ const message = `Golden-set eval (run #${result.runId}): ${opts.candidateModel} vs ${incumbentModel} on ${opts.appId}/${opts.archetype} \u2014 verdict ${verdict.toUpperCase()}. ${wins}W/${ties}T/${losses}L over ${result.nCases} real workload case(s), wins-or-ties ${(100 * (winOrTieRatio ?? 0)).toFixed(0)}% (threshold ${(100 * threshold).toFixed(0)}%), ${result.floorViolations} hard-floor violation(s), latency ratio ${latencyRatio?.toFixed(2) ?? "n/a"}.` + costLine;
7571
+ const suggestion = verdict === "promote-ready" ? `Candidate passed the non-inferiority rule on your real workload. To promote: node v2/scripts/promote-model.mjs --model ${opts.candidateModel} (or ask kgauto-Cairn). Evidence: kgauto_golden_eval_runs #${result.runId} + probe_outcomes golden_run_id=${result.runId}.` : `Candidate did NOT clear the non-inferiority rule \u2014 no action needed; the incumbent stays. Evidence rows: golden_run_id=${result.runId}.`;
7572
+ const advRes = await fetchFn(rest("compile_outcome_advisories"), {
7573
+ method: "POST",
7574
+ headers: { ...restHeaders, "Content-Type": "application/json", Prefer: "return=minimal" },
7575
+ body: JSON.stringify({
7576
+ outcome_id: latestOutcomeId,
7577
+ code: "golden-eval-verdict",
7578
+ level: "info",
7579
+ recommendation_type: "model-swap",
7580
+ message,
7581
+ suggestion
7582
+ })
7583
+ });
7584
+ if (advRes.ok) {
7585
+ result.advisoryOutcomeId = latestOutcomeId;
7586
+ await fetchFn(rest(`kgauto_golden_eval_runs?id=eq.${result.runId}`), {
7587
+ method: "PATCH",
7588
+ headers: { ...restHeaders, "Content-Type": "application/json", Prefer: "return=minimal" },
7589
+ body: JSON.stringify({ advisory_outcome_id: latestOutcomeId })
7590
+ }).catch(() => {
7591
+ });
7592
+ } else {
7593
+ notes.push(`advisory write failed (${advRes.status})`);
7594
+ }
7595
+ } else {
7596
+ notes.push("no compile_outcomes row for app \u2014 evidence advisory skipped (view needs a real outcome_id)");
7597
+ }
7598
+ return result;
7599
+ }
7600
+
6787
7601
  // src/brain-proxy.ts
6788
7602
  var SEGMENT_TO_TABLE = {
6789
7603
  outcomes: "compile_outcomes",
6790
7604
  compile_outcome_advisories: "compile_outcome_advisories",
6791
7605
  compile_outcome_quality: "compile_outcome_quality",
6792
- probe_outcomes: "probe_outcomes"
7606
+ probe_outcomes: "probe_outcomes",
7607
+ // alpha.62 (eval spine): golden-set capture. Only receives rows when the
7608
+ // consumer has explicitly opted in via KGAUTO_GOLDEN_CAPTURE — the segment
7609
+ // existing here does not by itself store anything.
7610
+ golden_irs: "kgauto_golden_irs"
6793
7611
  };
6794
7612
  var KNOWN_SEGMENTS = Object.keys(SEGMENT_TO_TABLE);
6795
7613
  var JSON_HEADERS = { "Content-Type": "application/json" };
@@ -6947,7 +7765,7 @@ function createBrainForwardRoutes(config) {
6947
7765
  }
6948
7766
 
6949
7767
  // src/version.ts
6950
- var LIBRARY_VERSION = "2.0.0-alpha.60";
7768
+ var LIBRARY_VERSION = "2.0.0-alpha.62";
6951
7769
 
6952
7770
  // src/key-health.ts
6953
7771
  var JSON_HEADERS2 = { "Content-Type": "application/json" };
@@ -7570,6 +8388,7 @@ function compile2(ir, opts) {
7570
8388
  DIALECT_VERSION,
7571
8389
  FamilyResolutionError,
7572
8390
  INTENT_ARCHETYPES,
8391
+ JUDGE_RUBRICS,
7573
8392
  LATENCY_TIER_MS,
7574
8393
  LIBRARY_VERSION,
7575
8394
  MEASURED_GROUNDING_MIN_N,
@@ -7581,13 +8400,18 @@ function compile2(ir, opts) {
7581
8400
  applyArchetypeConvention,
7582
8401
  applySectionRewrites,
7583
8402
  attachCacheControlToStreamTextInput,
8403
+ brainHealth,
7584
8404
  bucketContext,
7585
8405
  bucketHistory,
7586
8406
  bucketToolCount,
8407
+ buildGoldenIrRow,
7587
8408
  buildLLMJudge,
8409
+ buildPairwiseJudgePrompt,
7588
8410
  buildShadowProbeRow,
7589
8411
  call,
8412
+ captureGoldenIr,
7590
8413
  clearBrain,
8414
+ combineOrderSwappedVerdicts,
7591
8415
  compile,
7592
8416
  compileForAISDKv6,
7593
8417
  configureBrain,
@@ -7598,6 +8422,7 @@ function compile2(ir, opts) {
7598
8422
  deriveOwnership,
7599
8423
  execute,
7600
8424
  findBetterFit,
8425
+ flushBrainDeadLetter,
7601
8426
  getActionableAdvisories,
7602
8427
  getAllStarterChains,
7603
8428
  getAllStarterChainsWithGrounding,
@@ -7632,18 +8457,27 @@ function compile2(ir, opts) {
7632
8457
  markAdvisoryResolved,
7633
8458
  markExclusionFindingHandled,
7634
8459
  markPromoteReadyHandled,
8460
+ parseGoldenCaptureRate,
8461
+ parseJudgeVerdict,
8462
+ peekBrainDeadLetter,
7635
8463
  probeShadow,
7636
8464
  profileToRow,
7637
8465
  profilesByProvider,
7638
8466
  readBrainReadEnv,
7639
8467
  record,
8468
+ recordGoldenIr,
7640
8469
  recordOutcome,
7641
8470
  recordShadowProbe,
8471
+ renderIrForJudge,
7642
8472
  resetTokenizer,
7643
8473
  resolveConventionsForProfile,
8474
+ resolveGoldenCaptureRate,
7644
8475
  resolvePricingAt,
7645
8476
  resolveProviderKey,
8477
+ rubricFor,
7646
8478
  runAdvisor,
8479
+ runGoldenEval,
7647
8480
  setTokenizer,
8481
+ shouldCaptureGolden,
7648
8482
  tryGetProfile
7649
8483
  });