@warmdrift/kgauto-compiler 2.0.0-alpha.85 → 2.0.0-alpha.86

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
@@ -72,6 +72,7 @@ __export(index_exports, {
72
72
  applySectionRewrites: () => applySectionRewrites,
73
73
  attachCacheControlToStreamTextInput: () => attachCacheControlToStreamTextInput,
74
74
  awaitMeasuredFailureReady: () => awaitMeasuredFailureReady,
75
+ awaitPromotionsReady: () => awaitPromotionsReady,
75
76
  brainHealth: () => brainHealth,
76
77
  bucketContext: () => bucketContext,
77
78
  bucketHistory: () => bucketHistory,
@@ -158,6 +159,7 @@ __export(index_exports, {
158
159
  peekBrainDeadLetter: () => peekBrainDeadLetter,
159
160
  planDecomposition: () => planDecomposition,
160
161
  prefetchMeasuredFailure: () => prefetchMeasuredFailure,
162
+ prefetchPromotions: () => prefetchPromotions,
161
163
  probeShadow: () => probeShadow,
162
164
  profileToRow: () => profileToRow,
163
165
  profilesByProvider: () => profilesByProvider,
@@ -972,9 +974,21 @@ var PROFILES_RAW = [
972
974
  },
973
975
  {
974
976
  id: "gemini-2.5-pro",
975
- verifiedAgainstDocs: "2026-05-08",
977
+ verifiedAgainstDocs: "2026-08-08",
976
978
  provider: "google",
977
- status: "current",
979
+ // alpha.86 — AVAILABILITY demotion, not a provider-lifecycle mirror.
980
+ // Google's docs still list 2.5-pro as Stable, but the serving layer
981
+ // disagrees per account cohort: tt-intel measured 4/4 refusals
982
+ // ("no longer available to new users", 2026-08-02, their bench), and
983
+ // kgauto's own key 429s on a FreeTier per-day quota (probed
984
+ // 2026-08-08). A chain anchor that hard-fails for whole account
985
+ // cohorts is not an anchor; `legacy` removes it from cost-ordered
986
+ // chains and new selection while keeping the profile resolvable for
987
+ // consumers who pass it explicitly. Re-promotion is one status flip
988
+ // if Google restores availability. The registry cannot yet express
989
+ // account-cohort availability as data — see interfaces/kgauto.md
990
+ // ## Requested 2026-08-02.
991
+ status: "legacy",
978
992
  maxContextTokens: 1048576,
979
993
  maxOutputTokens: 65535,
980
994
  maxTools: 128,
@@ -1004,7 +1018,7 @@ var PROFILES_RAW = [
1004
1018
  }
1005
1019
  ],
1006
1020
  strengths: ["reasoning", "1m_context", "structured_output", "tool_use"],
1007
- weaknesses: ["pricing_above_200k"],
1021
+ weaknesses: ["pricing_above_200k", "availability_restricted_by_account_cohort"],
1008
1022
  // Master plan §3.3 anchor: tier-2 cross-provider in almost every chain.
1009
1023
  // Sits on the frontier at perf-9 — close to Sonnet but cheaper input.
1010
1024
  archetypePerf: {
@@ -2848,9 +2862,12 @@ function passApplyCliffs(ir, profile, estimatedInputTokens) {
2848
2862
  if (!triggered) continue;
2849
2863
  switch (cliff.action) {
2850
2864
  case "drop_to_top_relevant": {
2851
- const targetCount = Math.min(
2852
- Math.floor(cliff.threshold * 0.75),
2853
- Math.max(1, Math.floor((nextIR.tools?.length ?? 0) / 2))
2865
+ const targetCount = Math.max(
2866
+ 1,
2867
+ Math.min(
2868
+ Math.floor(cliff.threshold * 0.75),
2869
+ Math.floor((nextIR.tools?.length ?? 0) / 2)
2870
+ )
2854
2871
  );
2855
2872
  if (nextIR.tools && nextIR.tools.length > targetCount) {
2856
2873
  const intent = nextIR.intent.archetype;
@@ -3928,8 +3945,14 @@ var STARTER_CHAINS_GROUNDED = {
3928
3945
  critique: [
3929
3946
  { id: "claude-opus-4-7", grounding: "judgment", reason: "Highest reasoning bar, no degradation tier \u2014 engineer pick, awaiting measured backing" },
3930
3947
  { id: "claude-sonnet-4-6", grounding: "judgment", reason: "Same-provider walk-down from Opus on 429" },
3931
- { id: "gemini-2.5-pro", grounding: "judgment", reason: "Cross-provider anchor in similar quality bracket" },
3932
- { id: "gpt-5.5", grounding: "judgment", reason: "alpha.16: third-provider frontier-tier floor (archetypePerf=9)" }
3948
+ // alpha.86: gemini-2.5-pro dropped availability-restricted (tt-intel
3949
+ // measured 4/4 cohort refusal 2026-08-02; kgauto key free-tier-quota
3950
+ // 429 2026-08-08). No current Google model clears the critique floor
3951
+ // (3.5-flash critique=5; 3.1-pro-preview scores 10 but is preview —
3952
+ // default chains carry promoted models only). deepseek-v4-pro takes the
3953
+ // third-provider tail instead.
3954
+ { id: "gpt-5.5", grounding: "judgment", reason: "alpha.16: third-provider frontier-tier floor (archetypePerf=9)" },
3955
+ { id: "deepseek-v4-pro", grounding: "judgment", reason: "alpha.86: third-provider tail replacing availability-restricted gemini-2.5-pro \u2014 critique=6 clears the floor exactly; last-resort when Anthropic AND OpenAI are down, not a quality peer of the tiers above" }
3933
3956
  ],
3934
3957
  // alpha.62 (eval spine) — pairwise output comparison. Same reasoning-floor
3935
3958
  // posture as critique (a verdict from a weak judge is worse than no
@@ -3938,14 +3961,16 @@ var STARTER_CHAINS_GROUNDED = {
3938
3961
  judge: [
3939
3962
  { id: "claude-opus-4-8", grounding: "judgment", reason: "Highest reasoning bar for pairwise verdicts \u2014 current opus (s64 roster)" },
3940
3963
  { id: "claude-sonnet-4-6", grounding: "judgment", reason: "Same-provider walk-down on 429" },
3941
- { id: "gemini-2.5-pro", grounding: "judgment", reason: "Cross-provider anchor in similar quality bracket" },
3942
- { id: "gpt-5.5", grounding: "judgment", reason: "Third-provider frontier-tier floor" }
3964
+ // alpha.86: gemini-2.5-pro dropped (availability-restricted; see critique
3965
+ // note). gpt-5.5 remains the cross-provider frontier floor for verdicts.
3966
+ { id: "gpt-5.5", grounding: "judgment", reason: "Third-provider frontier-tier floor" },
3967
+ { id: "deepseek-v4-pro", grounding: "judgment", reason: "alpha.86: third-provider tail replacing availability-restricted gemini-2.5-pro \u2014 native structured output per the judge contract; last-resort tier" }
3943
3968
  ],
3944
3969
  // Reasoning matters — Sonnet primary; walk UP to Opus on 429.
3945
3970
  plan: [
3946
3971
  { id: "claude-sonnet-4-6", grounding: "judgment", reason: "Reasoning + cost balance \u2014 engineer pick" },
3947
3972
  { id: "claude-opus-4-7", grounding: "judgment", reason: 'Same-provider walk-UP on 429 (rare exception to "always cheaper")' },
3948
- { id: "gemini-2.5-pro", grounding: "judgment", reason: "Cross-provider anchor" },
3973
+ { id: "gemini-3.5-flash", grounding: "judgment", reason: "alpha.86: cross-provider anchor \u2014 replaces availability-restricted gemini-2.5-pro (tt-intel 4/4 cohort refusal 2026-08-02; probed serving 200 on kgauto key 2026-08-08)" },
3949
3974
  { id: "deepseek-v4-pro", grounding: "judgment", reason: "Tier 3 cost floor \u2014 no brain evidence yet" },
3950
3975
  { id: "gpt-5.4", grounding: "judgment", reason: "alpha.33: third-provider tail (archetypePerf=7) \u2014 closes openai-in-default-fallback-chains" }
3951
3976
  ],
@@ -3953,7 +3978,7 @@ var STARTER_CHAINS_GROUNDED = {
3953
3978
  generate: [
3954
3979
  { id: "claude-sonnet-4-6", grounding: "judgment", reason: "Quality + cost match \u2014 engineer pick" },
3955
3980
  { id: "claude-haiku-4-5", grounding: "judgment", reason: "Same-provider step-down" },
3956
- { id: "gemini-2.5-pro", grounding: "judgment", reason: "Cross-provider anchor" },
3981
+ { id: "gemini-3.5-flash", grounding: "judgment", reason: "alpha.86: cross-provider anchor \u2014 replaces availability-restricted gemini-2.5-pro (tt-intel 4/4 cohort refusal 2026-08-02; probed serving 200 on kgauto key 2026-08-08)" },
3957
3982
  { id: "gpt-5.4-mini", grounding: "judgment", reason: "alpha.16: third-provider tail (archetypePerf=7) \u2014 closes mono-Anthropic gap" }
3958
3983
  ],
3959
3984
  // ask::sonnet — STARTER_CHAINS calls this "Quality + cost match" but
@@ -3962,7 +3987,7 @@ var STARTER_CHAINS_GROUNDED = {
3962
3987
  ask: [
3963
3988
  { id: "claude-sonnet-4-6", grounding: "judgment", reason: "Quality + cost match \u2014 engineer pick. NOTE: tt-intel s78 prod showed 27% empty rate; placement awaits measurement validation" },
3964
3989
  { id: "claude-haiku-4-5", grounding: "judgment", reason: "Same-provider step-down" },
3965
- { id: "gemini-2.5-pro", grounding: "judgment", reason: "Cross-provider anchor" },
3990
+ { id: "gemini-3.5-flash", grounding: "judgment", reason: "alpha.86: cross-provider anchor \u2014 replaces availability-restricted gemini-2.5-pro (tt-intel 4/4 cohort refusal 2026-08-02; probed serving 200 on kgauto key 2026-08-08)" },
3966
3991
  { id: "gpt-5.4-mini", grounding: "judgment", reason: "alpha.16: third-provider tail (archetypePerf=7)" }
3967
3992
  ],
3968
3993
  // Structured-output archetype — Flash skipped (alpha.8 MAX_TOKENS cliff,
@@ -3970,14 +3995,14 @@ var STARTER_CHAINS_GROUNDED = {
3970
3995
  extract: [
3971
3996
  { id: "claude-sonnet-4-6", grounding: "judgment", reason: "Reliable structured-output anchor \u2014 engineer pick" },
3972
3997
  { id: "claude-haiku-4-5", grounding: "judgment", reason: "Same-provider step-down with native structured output" },
3973
- { id: "gemini-2.5-pro", grounding: "judgment", reason: "Cross-provider anchor with structured-output support" },
3998
+ { id: "gemini-3.5-flash", grounding: "judgment", reason: "alpha.86: cross-provider anchor with native structured output \u2014 replaces availability-restricted gemini-2.5-pro" },
3974
3999
  { id: "gpt-5.4", grounding: "capability-fact", reason: "alpha.16: third-provider floor \u2014 native structured-output capability (archetypePerf=8)" }
3975
4000
  ],
3976
4001
  // Forgiving archetype — Sonnet primary but Flash safely floors it.
3977
4002
  transform: [
3978
4003
  { id: "claude-sonnet-4-6", grounding: "judgment", reason: "Quality anchor \u2014 engineer pick" },
3979
4004
  { id: "claude-haiku-4-5", grounding: "judgment", reason: "Same-provider step-down" },
3980
- { id: "gemini-2.5-pro", grounding: "judgment", reason: "Cross-provider anchor" },
4005
+ { id: "gemini-3.5-flash", grounding: "judgment", reason: "alpha.86: cross-provider anchor \u2014 replaces availability-restricted gemini-2.5-pro (tt-intel 4/4 cohort refusal 2026-08-02; probed serving 200 on kgauto key 2026-08-08)" },
3981
4006
  { id: "gemini-2.5-flash", grounding: "judgment", reason: "Cost floor \u2014 forgiving archetype tolerates Flash" },
3982
4007
  { id: "gpt-5.4-mini", grounding: "judgment", reason: "alpha.33: third-provider tail (archetypePerf=7) \u2014 closes openai-in-default-fallback-chains" }
3983
4008
  ],
@@ -3985,7 +4010,7 @@ var STARTER_CHAINS_GROUNDED = {
3985
4010
  // (capability-fact: Flash 15-75 parallel calls/step vs DeepSeek 7-8).
3986
4011
  hunt: [
3987
4012
  { id: "gemini-2.5-flash", grounding: "capability-fact", reason: "L-040 parallel-tool throughput champion (15-75 calls/step)" },
3988
- { id: "gemini-2.5-pro", grounding: "capability-fact", reason: "Cross-provider tier 1 with strong parallel-tool support" },
4013
+ { id: "gemini-3.5-flash", grounding: "capability-fact", reason: "alpha.86: parallel-tool agentic tier (hunt archetypePerf 9, L-040 family) \u2014 replaces availability-restricted gemini-2.5-pro" },
3989
4014
  { id: "claude-sonnet-4-6", grounding: "judgment", reason: "Quality safety net for blocked-Flash case" },
3990
4015
  { id: "claude-haiku-4-5", grounding: "judgment", reason: "Reduced tool budget \u2014 cliff at 16 fires" },
3991
4016
  { id: "gpt-5.4-mini", grounding: "judgment", reason: "alpha.33: third-provider tail \u2014 OpenAI parallel-tool capable archetype" }
@@ -4033,9 +4058,9 @@ var STARTER_CHAINS_BY_MODE_GROUNDED = {
4033
4058
  reason: "Cross-provider safety net \u2014 Sonnet handles sequential agentic loops cleanly"
4034
4059
  },
4035
4060
  {
4036
- id: "gemini-2.5-pro",
4061
+ id: "gemini-3.5-flash",
4037
4062
  grounding: "judgment",
4038
- reason: "Third-provider tail when no DeepSeek key reachable"
4063
+ reason: "alpha.86: third-provider tail when no DeepSeek key reachable \u2014 replaces availability-restricted gemini-2.5-pro"
4039
4064
  }
4040
4065
  ]
4041
4066
  }
@@ -4601,6 +4626,40 @@ function defaultOnError4(err) {
4601
4626
  err
4602
4627
  );
4603
4628
  }
4629
+ function prefetchPromotions(appId) {
4630
+ const rt = runtime4;
4631
+ if (!rt || !appId) return void 0;
4632
+ let snap = snapshots3.get(appId);
4633
+ if (!snap) {
4634
+ snap = { data: [], expiresAt: 0, refreshing: false };
4635
+ snapshots3.set(appId, snap);
4636
+ }
4637
+ if (snap.expiresAt > Date.now()) return void 0;
4638
+ const inflight = pendingRefreshes3.get(appId);
4639
+ if (inflight) return inflight;
4640
+ if (snap.refreshing) return void 0;
4641
+ snap.refreshing = true;
4642
+ void asyncRefresh4(rt, appId);
4643
+ return pendingRefreshes3.get(appId);
4644
+ }
4645
+ async function awaitPromotionsReady(appId, timeoutMs) {
4646
+ if (!runtime4 || !appId) return;
4647
+ const pending = prefetchPromotions(appId) ?? pendingRefreshes3.get(appId);
4648
+ if (!(timeoutMs > 0)) return;
4649
+ if (!pending) return;
4650
+ let timer;
4651
+ try {
4652
+ await Promise.race([
4653
+ pending,
4654
+ new Promise((resolve) => {
4655
+ timer = setTimeout(resolve, timeoutMs);
4656
+ })
4657
+ ]);
4658
+ } catch {
4659
+ } finally {
4660
+ if (timer) clearTimeout(timer);
4661
+ }
4662
+ }
4604
4663
  function _testResetPromotions() {
4605
4664
  runtime4 = void 0;
4606
4665
  snapshots3.clear();
@@ -5131,6 +5190,31 @@ function advisorRuleBlockedModelDrift(ctx) {
5131
5190
  return out;
5132
5191
  }
5133
5192
 
5193
+ // src/advisor-rules/preferred-blocked-overlap.ts
5194
+ var PREFERRED_MODEL_BLOCKED_CODE = "preferred-model-blocked";
5195
+ var DOCS_URL2 = "https://github.com/stue/command-center/blob/main/interfaces/kgauto.md#best-practice-advisories";
5196
+ function advisorRulePreferredBlockedOverlap(ctx) {
5197
+ const preferred = ctx.policy?.preferredModels;
5198
+ const blocked = ctx.policy?.blockedModels;
5199
+ if (!preferred?.length || !blocked?.length) return [];
5200
+ const blockedSet = canonicalPolicySet(blocked);
5201
+ const deadPins = [...new Set(preferred)].filter((p) => policySetHas(blockedSet, p)).sort();
5202
+ if (deadPins.length === 0) return [];
5203
+ const list = deadPins.map((p) => `\`${p}\``).join(", ");
5204
+ const one = deadPins.length === 1;
5205
+ const preferredSet = canonicalPolicySet(preferred);
5206
+ const servedIsPinned = policySetHas(preferredSet, ctx.selectedModelId);
5207
+ return [
5208
+ {
5209
+ level: "warn",
5210
+ code: PREFERRED_MODEL_BLOCKED_CODE,
5211
+ message: `CompilePolicy.preferredModels entr${one ? "y" : "ies"} ${list} ${one ? "is" : "are"} also in \`blockedModels\` (matched canonically, aliases included). A blocked model is hard-rejected before preference boosts apply, so ${one ? "this pin" : "these pins"} can never serve. ` + (servedIsPinned ? `This call was served by \`${ctx.selectedModelId}\`, which is itself a live pin \u2014 the dead entr${one ? "y is" : "ies are"} latent, not currently rerouting traffic.` : `Substitution is your steady state: this call landed on \`${ctx.selectedModelId}\`, which you did not pin.`),
5212
+ suggestion: `Two readings, and kgauto cannot tell them apart: (1) intentional \u2014 your spend gate deliberately outranks the pin, in which case nothing needs doing and you can filter this code; (2) misconfiguration \u2014 the pin and the block were written at different times and the overlap is an accident. tt-intel hit reading (2) on 2026-08-01: a summarize site pinned \`claude-sonnet\` while \`KGAUTO_BLOCKED_MODELS\` carried the same family, and every call silently substituted a reasoning model whose reasoning burn exceeded the site's \`maxOutputTokens\` \u2014 100% empty payloads under HTTP 200. If the block should win, remove the pin so the policy says what it does. If the pin should win, remove ${one ? "the blocking entry" : "the blocking entries"} or re-scope the block to the exact ids you mean. Check what the substitute costs at your input shape while you are here \u2014 a spend gate that lands traffic on a pricier model than the one it blocked is a cost inversion, not a saving.`,
5213
+ docsUrl: DOCS_URL2
5214
+ }
5215
+ ];
5216
+ }
5217
+
5134
5218
  // src/advisor.ts
5135
5219
  var QUALITY_FLOOR_FOR_RECOMMENDATION = 6;
5136
5220
  var TIER_DOWN_COST_RATIO = 0.5;
@@ -5155,6 +5239,12 @@ function runAdvisor(ir, result, profile, policy, phase2) {
5155
5239
  selectedModelId: profile.id
5156
5240
  })
5157
5241
  );
5242
+ out.push(
5243
+ ...advisorRulePreferredBlockedOverlap({
5244
+ policy,
5245
+ selectedModelId: profile.id
5246
+ })
5247
+ );
5158
5248
  if (policy?.posture !== "locked") {
5159
5249
  out.push(...detectCostMismatchedArchetype(ir, profile, phase2));
5160
5250
  out.push(...detectModelStaleEvidence(ir, profile));
@@ -5967,7 +6057,7 @@ function validateFinalFit(ir, profile, tokens) {
5967
6057
  }
5968
6058
 
5969
6059
  // src/version.ts
5970
- var LIBRARY_VERSION = "2.0.0-alpha.85";
6060
+ var LIBRARY_VERSION = "2.0.0-alpha.86";
5971
6061
 
5972
6062
  // src/pricing-brain.ts
5973
6063
  function isPricingRow(x) {
@@ -6078,6 +6168,12 @@ function configureBrain(config) {
6078
6168
  fetchImpl: config.fetchImpl ?? fetch,
6079
6169
  onError: config.onError
6080
6170
  });
6171
+ if (config.appId) {
6172
+ try {
6173
+ void prefetchPromotions(config.appId);
6174
+ } catch {
6175
+ }
6176
+ }
6081
6177
  } else {
6082
6178
  configurePromotionsBrain(void 0);
6083
6179
  }
@@ -6449,6 +6545,7 @@ function buildPayload(input, reg) {
6449
6545
  latency_ms: input.latencyMs,
6450
6546
  success: input.success,
6451
6547
  empty_response: input.emptyResponse ?? input.tokensOut === 0,
6548
+ source: input.source,
6452
6549
  error_type: input.errorType,
6453
6550
  tools_called: input.toolsCalled,
6454
6551
  oracle_score: input.oracleScore?.score,
@@ -7848,7 +7945,11 @@ async function call(ir, opts = {}) {
7848
7945
  )
7849
7946
  })
7850
7947
  );
7851
- await awaitMeasuredFailureReady(ir.appId, resolveGateWarmupMs(opts));
7948
+ const warmupMs = resolveGateWarmupMs(opts);
7949
+ await Promise.all([
7950
+ awaitMeasuredFailureReady(ir.appId, warmupMs),
7951
+ awaitPromotionsReady(ir.appId, warmupMs)
7952
+ ]);
7852
7953
  const initial = compileAndRegister(ir, opts);
7853
7954
  safeEmit(
7854
7955
  () => emitCompileDone(traceId, ir.appId, {
@@ -7888,6 +7989,7 @@ async function call(ir, opts = {}) {
7888
7989
  const latencyMs2 = Date.now() - start;
7889
7990
  await record({
7890
7991
  handle: initial.handle,
7992
+ source: opts.source,
7891
7993
  tokensIn: 0,
7892
7994
  tokensOut: 0,
7893
7995
  latencyMs: latencyMs2,
@@ -7940,6 +8042,7 @@ async function call(ir, opts = {}) {
7940
8042
  const latencyMs2 = Date.now() - start;
7941
8043
  await record({
7942
8044
  handle: initial.handle,
8045
+ source: opts.source,
7943
8046
  tokensIn: 0,
7944
8047
  tokensOut: 0,
7945
8048
  latencyMs: latencyMs2,
@@ -8081,6 +8184,7 @@ async function call(ir, opts = {}) {
8081
8184
  const goldenShapeKey = goldenRate > 0 ? peekRegisteredShapeKey(initial.handle) : void 0;
8082
8185
  await record({
8083
8186
  handle: initial.handle,
8187
+ source: opts.source,
8084
8188
  tokensIn: validated.response.tokens.input,
8085
8189
  tokensOut: validated.response.tokens.output,
8086
8190
  latencyMs: latencyMs2,
@@ -8203,6 +8307,7 @@ async function call(ir, opts = {}) {
8203
8307
  const latencyMs = Date.now() - start;
8204
8308
  await record({
8205
8309
  handle: initial.handle,
8310
+ source: opts.source,
8206
8311
  tokensIn: lastErr?.tokens?.input ?? 0,
8207
8312
  tokensOut: lastErr?.tokens?.output ?? 0,
8208
8313
  latencyMs,
@@ -10743,6 +10848,7 @@ function compile2(ir, opts) {
10743
10848
  applySectionRewrites,
10744
10849
  attachCacheControlToStreamTextInput,
10745
10850
  awaitMeasuredFailureReady,
10851
+ awaitPromotionsReady,
10746
10852
  brainHealth,
10747
10853
  bucketContext,
10748
10854
  bucketHistory,
@@ -10829,6 +10935,7 @@ function compile2(ir, opts) {
10829
10935
  peekBrainDeadLetter,
10830
10936
  planDecomposition,
10831
10937
  prefetchMeasuredFailure,
10938
+ prefetchPromotions,
10832
10939
  probeShadow,
10833
10940
  profileToRow,
10834
10941
  profilesByProvider,
package/dist/index.mjs CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  LIBRARY_VERSION,
20
20
  createKeyHealthRoute,
21
21
  keyFingerprint
22
- } from "./chunk-WXN7FNXP.mjs";
22
+ } from "./chunk-V4T2CBRI.mjs";
23
23
  import {
24
24
  ABSOLUTE_FLOOR,
25
25
  ARCHETYPE_FLOOR_DEFAULT,
@@ -56,7 +56,7 @@ import {
56
56
  policySetHas,
57
57
  readBrainReadEnv,
58
58
  resolveProviderKey
59
- } from "./chunk-LO2JXTGG.mjs";
59
+ } from "./chunk-QDWOMQYN.mjs";
60
60
  import {
61
61
  ALIASES,
62
62
  LATENCY_TIER_MS,
@@ -68,7 +68,7 @@ import {
68
68
  profilesByProvider,
69
69
  resolveModelAlias,
70
70
  tryGetProfile
71
- } from "./chunk-FD3NFXDC.mjs";
71
+ } from "./chunk-2MQIVVEU.mjs";
72
72
  import {
73
73
  emitAdvisoryFired,
74
74
  emitCompileDone,
@@ -683,9 +683,12 @@ function passApplyCliffs(ir, profile, estimatedInputTokens) {
683
683
  if (!triggered) continue;
684
684
  switch (cliff.action) {
685
685
  case "drop_to_top_relevant": {
686
- const targetCount = Math.min(
687
- Math.floor(cliff.threshold * 0.75),
688
- Math.max(1, Math.floor((nextIR.tools?.length ?? 0) / 2))
686
+ const targetCount = Math.max(
687
+ 1,
688
+ Math.min(
689
+ Math.floor(cliff.threshold * 0.75),
690
+ Math.floor((nextIR.tools?.length ?? 0) / 2)
691
+ )
689
692
  );
690
693
  if (nextIR.tools && nextIR.tools.length > targetCount) {
691
694
  const intent = nextIR.intent.archetype;
@@ -1895,6 +1898,40 @@ function defaultOnError3(err) {
1895
1898
  err
1896
1899
  );
1897
1900
  }
1901
+ function prefetchPromotions(appId) {
1902
+ const rt = runtime3;
1903
+ if (!rt || !appId) return void 0;
1904
+ let snap = snapshots3.get(appId);
1905
+ if (!snap) {
1906
+ snap = { data: [], expiresAt: 0, refreshing: false };
1907
+ snapshots3.set(appId, snap);
1908
+ }
1909
+ if (snap.expiresAt > Date.now()) return void 0;
1910
+ const inflight = pendingRefreshes3.get(appId);
1911
+ if (inflight) return inflight;
1912
+ if (snap.refreshing) return void 0;
1913
+ snap.refreshing = true;
1914
+ void asyncRefresh3(rt, appId);
1915
+ return pendingRefreshes3.get(appId);
1916
+ }
1917
+ async function awaitPromotionsReady(appId, timeoutMs) {
1918
+ if (!runtime3 || !appId) return;
1919
+ const pending = prefetchPromotions(appId) ?? pendingRefreshes3.get(appId);
1920
+ if (!(timeoutMs > 0)) return;
1921
+ if (!pending) return;
1922
+ let timer;
1923
+ try {
1924
+ await Promise.race([
1925
+ pending,
1926
+ new Promise((resolve) => {
1927
+ timer = setTimeout(resolve, timeoutMs);
1928
+ })
1929
+ ]);
1930
+ } catch {
1931
+ } finally {
1932
+ if (timer) clearTimeout(timer);
1933
+ }
1934
+ }
1898
1935
  function _testResetPromotions() {
1899
1936
  runtime3 = void 0;
1900
1937
  snapshots3.clear();
@@ -2425,6 +2462,31 @@ function advisorRuleBlockedModelDrift(ctx) {
2425
2462
  return out;
2426
2463
  }
2427
2464
 
2465
+ // src/advisor-rules/preferred-blocked-overlap.ts
2466
+ var PREFERRED_MODEL_BLOCKED_CODE = "preferred-model-blocked";
2467
+ var DOCS_URL2 = "https://github.com/stue/command-center/blob/main/interfaces/kgauto.md#best-practice-advisories";
2468
+ function advisorRulePreferredBlockedOverlap(ctx) {
2469
+ const preferred = ctx.policy?.preferredModels;
2470
+ const blocked = ctx.policy?.blockedModels;
2471
+ if (!preferred?.length || !blocked?.length) return [];
2472
+ const blockedSet = canonicalPolicySet(blocked);
2473
+ const deadPins = [...new Set(preferred)].filter((p) => policySetHas(blockedSet, p)).sort();
2474
+ if (deadPins.length === 0) return [];
2475
+ const list = deadPins.map((p) => `\`${p}\``).join(", ");
2476
+ const one = deadPins.length === 1;
2477
+ const preferredSet = canonicalPolicySet(preferred);
2478
+ const servedIsPinned = policySetHas(preferredSet, ctx.selectedModelId);
2479
+ return [
2480
+ {
2481
+ level: "warn",
2482
+ code: PREFERRED_MODEL_BLOCKED_CODE,
2483
+ message: `CompilePolicy.preferredModels entr${one ? "y" : "ies"} ${list} ${one ? "is" : "are"} also in \`blockedModels\` (matched canonically, aliases included). A blocked model is hard-rejected before preference boosts apply, so ${one ? "this pin" : "these pins"} can never serve. ` + (servedIsPinned ? `This call was served by \`${ctx.selectedModelId}\`, which is itself a live pin \u2014 the dead entr${one ? "y is" : "ies are"} latent, not currently rerouting traffic.` : `Substitution is your steady state: this call landed on \`${ctx.selectedModelId}\`, which you did not pin.`),
2484
+ suggestion: `Two readings, and kgauto cannot tell them apart: (1) intentional \u2014 your spend gate deliberately outranks the pin, in which case nothing needs doing and you can filter this code; (2) misconfiguration \u2014 the pin and the block were written at different times and the overlap is an accident. tt-intel hit reading (2) on 2026-08-01: a summarize site pinned \`claude-sonnet\` while \`KGAUTO_BLOCKED_MODELS\` carried the same family, and every call silently substituted a reasoning model whose reasoning burn exceeded the site's \`maxOutputTokens\` \u2014 100% empty payloads under HTTP 200. If the block should win, remove the pin so the policy says what it does. If the pin should win, remove ${one ? "the blocking entry" : "the blocking entries"} or re-scope the block to the exact ids you mean. Check what the substitute costs at your input shape while you are here \u2014 a spend gate that lands traffic on a pricier model than the one it blocked is a cost inversion, not a saving.`,
2485
+ docsUrl: DOCS_URL2
2486
+ }
2487
+ ];
2488
+ }
2489
+
2428
2490
  // src/advisor.ts
2429
2491
  var QUALITY_FLOOR_FOR_RECOMMENDATION = 6;
2430
2492
  var TIER_DOWN_COST_RATIO = 0.5;
@@ -2449,6 +2511,12 @@ function runAdvisor(ir, result, profile, policy, phase2) {
2449
2511
  selectedModelId: profile.id
2450
2512
  })
2451
2513
  );
2514
+ out.push(
2515
+ ...advisorRulePreferredBlockedOverlap({
2516
+ policy,
2517
+ selectedModelId: profile.id
2518
+ })
2519
+ );
2452
2520
  if (policy?.posture !== "locked") {
2453
2521
  out.push(...detectCostMismatchedArchetype(ir, profile, phase2));
2454
2522
  out.push(...detectModelStaleEvidence(ir, profile));
@@ -3369,6 +3437,12 @@ function configureBrain(config) {
3369
3437
  fetchImpl: config.fetchImpl ?? fetch,
3370
3438
  onError: config.onError
3371
3439
  });
3440
+ if (config.appId) {
3441
+ try {
3442
+ void prefetchPromotions(config.appId);
3443
+ } catch {
3444
+ }
3445
+ }
3372
3446
  } else {
3373
3447
  configurePromotionsBrain(void 0);
3374
3448
  }
@@ -3740,6 +3814,7 @@ function buildPayload(input, reg) {
3740
3814
  latency_ms: input.latencyMs,
3741
3815
  success: input.success,
3742
3816
  empty_response: input.emptyResponse ?? input.tokensOut === 0,
3817
+ source: input.source,
3743
3818
  error_type: input.errorType,
3744
3819
  tools_called: input.toolsCalled,
3745
3820
  oracle_score: input.oracleScore?.score,
@@ -4838,7 +4913,11 @@ async function call(ir, opts = {}) {
4838
4913
  )
4839
4914
  })
4840
4915
  );
4841
- await awaitMeasuredFailureReady(ir.appId, resolveGateWarmupMs(opts));
4916
+ const warmupMs = resolveGateWarmupMs(opts);
4917
+ await Promise.all([
4918
+ awaitMeasuredFailureReady(ir.appId, warmupMs),
4919
+ awaitPromotionsReady(ir.appId, warmupMs)
4920
+ ]);
4842
4921
  const initial = compileAndRegister(ir, opts);
4843
4922
  safeEmit(
4844
4923
  () => emitCompileDone(traceId, ir.appId, {
@@ -4878,6 +4957,7 @@ async function call(ir, opts = {}) {
4878
4957
  const latencyMs2 = Date.now() - start;
4879
4958
  await record({
4880
4959
  handle: initial.handle,
4960
+ source: opts.source,
4881
4961
  tokensIn: 0,
4882
4962
  tokensOut: 0,
4883
4963
  latencyMs: latencyMs2,
@@ -4930,6 +5010,7 @@ async function call(ir, opts = {}) {
4930
5010
  const latencyMs2 = Date.now() - start;
4931
5011
  await record({
4932
5012
  handle: initial.handle,
5013
+ source: opts.source,
4933
5014
  tokensIn: 0,
4934
5015
  tokensOut: 0,
4935
5016
  latencyMs: latencyMs2,
@@ -5071,6 +5152,7 @@ async function call(ir, opts = {}) {
5071
5152
  const goldenShapeKey = goldenRate > 0 ? peekRegisteredShapeKey(initial.handle) : void 0;
5072
5153
  await record({
5073
5154
  handle: initial.handle,
5155
+ source: opts.source,
5074
5156
  tokensIn: validated.response.tokens.input,
5075
5157
  tokensOut: validated.response.tokens.output,
5076
5158
  latencyMs: latencyMs2,
@@ -5193,6 +5275,7 @@ async function call(ir, opts = {}) {
5193
5275
  const latencyMs = Date.now() - start;
5194
5276
  await record({
5195
5277
  handle: initial.handle,
5278
+ source: opts.source,
5196
5279
  tokensIn: lastErr?.tokens?.input ?? 0,
5197
5280
  tokensOut: lastErr?.tokens?.output ?? 0,
5198
5281
  latencyMs,
@@ -7357,6 +7440,7 @@ export {
7357
7440
  applySectionRewrites,
7358
7441
  attachCacheControlToStreamTextInput,
7359
7442
  awaitMeasuredFailureReady,
7443
+ awaitPromotionsReady,
7360
7444
  brainHealth,
7361
7445
  bucketContext,
7362
7446
  bucketHistory,
@@ -7443,6 +7527,7 @@ export {
7443
7527
  peekBrainDeadLetter,
7444
7528
  planDecomposition,
7445
7529
  prefetchMeasuredFailure,
7530
+ prefetchPromotions,
7446
7531
  probeShadow,
7447
7532
  profileToRow,
7448
7533
  profilesByProvider,
@@ -1084,6 +1084,13 @@ interface ShadowProbeConfig {
1084
1084
  skipSlowTierInSync?: boolean;
1085
1085
  }
1086
1086
  interface CallOptions {
1087
+ /**
1088
+ * alpha.86 — self-mark for synthetic callers (canaries, smokes, eval
1089
+ * replays, probes). Passed through to every outcome row this call
1090
+ * records, including failure rows. OMIT for real traffic. See
1091
+ * {@link OutcomeSource}.
1092
+ */
1093
+ source?: OutcomeSource;
1087
1094
  /**
1088
1095
  * alpha.84 — fires once per FAILED attempt during the fallback walk, before
1089
1096
  * the walk continues. IC-Cairn's filing, 2026-07-29.
@@ -1458,9 +1465,34 @@ interface OracleScore {
1458
1465
  /** Free-form explanation for debugging. */
1459
1466
  rationale?: string;
1460
1467
  }
1468
+ /**
1469
+ * alpha.86 — who originated an outcome row (migration 056).
1470
+ *
1471
+ * Absent/undefined means ORGANIC: a real consumer call on behalf of a real
1472
+ * user. Consumers change nothing. Synthetic writers — canaries, smoke
1473
+ * gates, eval replays, probe harnesses — self-mark, so liveness and volume
1474
+ * rules can compute over consumer-originated rows only.
1475
+ *
1476
+ * The incident this closes (cost-watch 2026-08-06 → 08-08): playbacksam's
1477
+ * daily canary wrote exactly 8 rows/day for 13 straight days while PB's
1478
+ * organic traffic was near-zero, and the liveness rule scored PB the
1479
+ * healthiest consumer in the portfolio. On 08-08 EVERY row the brain
1480
+ * received in 24h was canary, and no rule could say so — distinguishing a
1481
+ * replay from real traffic took a hand-reconstructed time-window +
1482
+ * token-fingerprint argument, three mornings running. A consumer whose
1483
+ * only rows are written by kgauto's own machinery is dark, not healthy;
1484
+ * this column is what lets a rule print that sentence.
1485
+ */
1486
+ type OutcomeSource = 'canary' | 'smoke' | 'eval' | 'probe' | 'synthetic';
1461
1487
  interface RecordInput {
1462
1488
  /** Handle from CompileResult. */
1463
1489
  handle: string;
1490
+ /**
1491
+ * alpha.86 — self-mark for synthetic writers (migration 056). OMIT for
1492
+ * real traffic; never write an explicit "organic" value. See
1493
+ * {@link OutcomeSource}.
1494
+ */
1495
+ source?: OutcomeSource;
1464
1496
  /** Actual tokens consumed (post-call). */
1465
1497
  tokensIn: number;
1466
1498
  tokensOut: number;
@@ -1084,6 +1084,13 @@ interface ShadowProbeConfig {
1084
1084
  skipSlowTierInSync?: boolean;
1085
1085
  }
1086
1086
  interface CallOptions {
1087
+ /**
1088
+ * alpha.86 — self-mark for synthetic callers (canaries, smokes, eval
1089
+ * replays, probes). Passed through to every outcome row this call
1090
+ * records, including failure rows. OMIT for real traffic. See
1091
+ * {@link OutcomeSource}.
1092
+ */
1093
+ source?: OutcomeSource;
1087
1094
  /**
1088
1095
  * alpha.84 — fires once per FAILED attempt during the fallback walk, before
1089
1096
  * the walk continues. IC-Cairn's filing, 2026-07-29.
@@ -1458,9 +1465,34 @@ interface OracleScore {
1458
1465
  /** Free-form explanation for debugging. */
1459
1466
  rationale?: string;
1460
1467
  }
1468
+ /**
1469
+ * alpha.86 — who originated an outcome row (migration 056).
1470
+ *
1471
+ * Absent/undefined means ORGANIC: a real consumer call on behalf of a real
1472
+ * user. Consumers change nothing. Synthetic writers — canaries, smoke
1473
+ * gates, eval replays, probe harnesses — self-mark, so liveness and volume
1474
+ * rules can compute over consumer-originated rows only.
1475
+ *
1476
+ * The incident this closes (cost-watch 2026-08-06 → 08-08): playbacksam's
1477
+ * daily canary wrote exactly 8 rows/day for 13 straight days while PB's
1478
+ * organic traffic was near-zero, and the liveness rule scored PB the
1479
+ * healthiest consumer in the portfolio. On 08-08 EVERY row the brain
1480
+ * received in 24h was canary, and no rule could say so — distinguishing a
1481
+ * replay from real traffic took a hand-reconstructed time-window +
1482
+ * token-fingerprint argument, three mornings running. A consumer whose
1483
+ * only rows are written by kgauto's own machinery is dark, not healthy;
1484
+ * this column is what lets a rule print that sentence.
1485
+ */
1486
+ type OutcomeSource = 'canary' | 'smoke' | 'eval' | 'probe' | 'synthetic';
1461
1487
  interface RecordInput {
1462
1488
  /** Handle from CompileResult. */
1463
1489
  handle: string;
1490
+ /**
1491
+ * alpha.86 — self-mark for synthetic writers (migration 056). OMIT for
1492
+ * real traffic; never write an explicit "organic" value. See
1493
+ * {@link OutcomeSource}.
1494
+ */
1495
+ source?: OutcomeSource;
1464
1496
  /** Actual tokens consumed (post-call). */
1465
1497
  tokensIn: number;
1466
1498
  tokensOut: number;
@@ -28,7 +28,7 @@ __export(key_health_exports, {
28
28
  module.exports = __toCommonJS(key_health_exports);
29
29
 
30
30
  // src/version.ts
31
- var LIBRARY_VERSION = "2.0.0-alpha.85";
31
+ var LIBRARY_VERSION = "2.0.0-alpha.86";
32
32
 
33
33
  // src/key-health.ts
34
34
  var JSON_HEADERS = { "Content-Type": "application/json" };
@@ -3,7 +3,7 @@ import {
3
3
  KEY_FINGERPRINT_LENGTH,
4
4
  createKeyHealthRoute,
5
5
  keyFingerprint
6
- } from "./chunk-WXN7FNXP.mjs";
6
+ } from "./chunk-V4T2CBRI.mjs";
7
7
  export {
8
8
  KEY_FINGERPRINT_DOMAIN,
9
9
  KEY_FINGERPRINT_LENGTH,
@@ -1,4 +1,4 @@
1
- import { k as Provider } from './ir-JUoybVM-.mjs';
1
+ import { k as Provider } from './ir-5TJLAYKR.mjs';
2
2
  import { IntentArchetypeName } from './dialect.mjs';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { k as Provider } from './ir-DfrM71pA.js';
1
+ import { k as Provider } from './ir-C1zmvAh6.js';
2
2
  import { IntentArchetypeName } from './dialect.js';
3
3
 
4
4
  /**