@warmdrift/kgauto-compiler 2.0.0-alpha.80 → 2.0.0-alpha.82

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.
@@ -1,8 +1,19 @@
1
1
  // src/version.ts
2
- var LIBRARY_VERSION = "2.0.0-alpha.80";
2
+ var LIBRARY_VERSION = "2.0.0-alpha.82";
3
3
 
4
4
  // src/key-health.ts
5
5
  var JSON_HEADERS = { "Content-Type": "application/json" };
6
+ var KEY_FINGERPRINT_DOMAIN = "kgauto-key-fingerprint-v1:";
7
+ var KEY_FINGERPRINT_LENGTH = 12;
8
+ async function keyFingerprint(key) {
9
+ const trimmed = key?.trim();
10
+ if (!trimmed) return void 0;
11
+ const subtle = globalThis.crypto?.subtle;
12
+ if (!subtle) return void 0;
13
+ const bytes = new TextEncoder().encode(KEY_FINGERPRINT_DOMAIN + trimmed);
14
+ const digest = await subtle.digest("SHA-256", bytes);
15
+ return [...new Uint8Array(digest)].map((b) => b.toString(16).padStart(2, "0")).join("").slice(0, KEY_FINGERPRINT_LENGTH);
16
+ }
6
17
  function jsonResponse(status, body) {
7
18
  return new Response(JSON.stringify(body), { status, headers: JSON_HEADERS });
8
19
  }
@@ -104,11 +115,13 @@ function createKeyHealthRoute(config) {
104
115
  detail: "key_absent"
105
116
  };
106
117
  }
118
+ const fingerprint = await keyFingerprint(key);
107
119
  const base = {
108
120
  provider: spec.provider,
109
121
  env: envName,
110
122
  present: true,
111
- valid: null
123
+ valid: null,
124
+ ...fingerprint ? { key_fingerprint: fingerprint } : {}
112
125
  };
113
126
  const { url, headers } = spec.buildRequest(key);
114
127
  const started = Date.now();
@@ -199,5 +212,8 @@ function createKeyHealthRoute(config) {
199
212
 
200
213
  export {
201
214
  LIBRARY_VERSION,
215
+ KEY_FINGERPRINT_DOMAIN,
216
+ KEY_FINGERPRINT_LENGTH,
217
+ keyFingerprint,
202
218
  createKeyHealthRoute
203
219
  };
@@ -412,9 +412,15 @@ var COST_RANKING_REFERENCE_SHAPE = {
412
412
  inputTokens: 4e3,
413
413
  outputTokens: 250
414
414
  };
415
- function estimateChainCostUsd(profile, shape = COST_RANKING_REFERENCE_SHAPE) {
415
+ function estimateModelCostUsd(profile, shape = COST_RANKING_REFERENCE_SHAPE) {
416
+ if (!profile || typeof profile !== "object" || Array.isArray(profile) || typeof profile.costInputPer1m !== "number" || typeof profile.costOutputPer1m !== "number") {
417
+ throw new TypeError(
418
+ `estimateModelCostUsd: expected a single ModelProfile, got ${Array.isArray(profile) ? "an array (a chain? map over it)" : typeof profile}. For a chain: chain.map((id) => estimateModelCostUsd(getProfile(id))).`
419
+ );
420
+ }
416
421
  return shape.inputTokens / 1e6 * profile.costInputPer1m + shape.outputTokens / 1e6 * profile.costOutputPer1m;
417
422
  }
423
+ var estimateChainCostUsd = estimateModelCostUsd;
418
424
  function buildCostOrderedChain(archetype) {
419
425
  return allProfiles().filter((p) => p.status === "current").filter(
420
426
  (p) => getArchetypePerfScore(p.id, archetype).score >= ARCHETYPE_FLOOR_DEFAULT
@@ -811,6 +817,7 @@ export {
811
817
  isSameModelRetryEnabledFromEnv,
812
818
  loadChainsFromBrain,
813
819
  COST_RANKING_REFERENCE_SHAPE,
820
+ estimateModelCostUsd,
814
821
  estimateChainCostUsd,
815
822
  chainProviderSpread,
816
823
  getDefaultFallbackChain,
@@ -1,6 +1,6 @@
1
- import { G as GlassboxEvent } from '../types-DpcAMmk-.mjs';
2
- export { A as AdvisoryFiredData, C as CompileDoneData, a as CompileStartData, E as ExecuteAttemptData, b as ExecuteSuccessData, F as FallbackWalkedData, c as GLASSBOX_STREAM_TTL_MS, d as GlassboxEventKind, e as GlassboxPubSub } from '../types-DpcAMmk-.mjs';
3
- import '../ir-BFwWhj2s.mjs';
1
+ import { G as GlassboxEvent } from '../types-CRXaR7nJ.mjs';
2
+ export { A as AdvisoryFiredData, C as CompileDoneData, a as CompileStartData, E as ExecuteAttemptData, b as ExecuteSuccessData, F as FallbackWalkedData, c as GLASSBOX_STREAM_TTL_MS, d as GlassboxEventKind, e as GlassboxPubSub } from '../types-CRXaR7nJ.mjs';
3
+ import '../ir-D4S9R816.mjs';
4
4
  import '../dialect.mjs';
5
5
 
6
6
  /**
@@ -1,6 +1,6 @@
1
- import { G as GlassboxEvent } from '../types-B4kz3Vs0.js';
2
- export { A as AdvisoryFiredData, C as CompileDoneData, a as CompileStartData, E as ExecuteAttemptData, b as ExecuteSuccessData, F as FallbackWalkedData, c as GLASSBOX_STREAM_TTL_MS, d as GlassboxEventKind, e as GlassboxPubSub } from '../types-B4kz3Vs0.js';
3
- import '../ir-DZKS1tI7.js';
1
+ import { G as GlassboxEvent } from '../types-CAs9-0S4.js';
2
+ export { A as AdvisoryFiredData, C as CompileDoneData, a as CompileStartData, E as ExecuteAttemptData, b as ExecuteSuccessData, F as FallbackWalkedData, c as GLASSBOX_STREAM_TTL_MS, d as GlassboxEventKind, e as GlassboxPubSub } from '../types-CAs9-0S4.js';
3
+ import '../ir-Cx9hJj0B.js';
4
4
  import '../dialect.js';
5
5
 
6
6
  /**
@@ -1,5 +1,5 @@
1
- import { T as TraceHealth } from '../types-hjzSWxtv.mjs';
2
- import '../ir-BFwWhj2s.mjs';
1
+ import { T as TraceHealth } from '../types-DHi4FcUu.mjs';
2
+ import '../ir-D4S9R816.mjs';
3
3
  import '../dialect.mjs';
4
4
 
5
5
  /**
@@ -1,5 +1,5 @@
1
- import { T as TraceHealth } from '../types-D_fLt_Xv.js';
2
- import '../ir-DZKS1tI7.js';
1
+ import { T as TraceHealth } from '../types-Cvd6kRNv.js';
2
+ import '../ir-Cx9hJj0B.js';
3
3
  import '../dialect.js';
4
4
 
5
5
  /**
@@ -1,7 +1,7 @@
1
- import { G as GlassboxEvent } from '../types-DpcAMmk-.mjs';
2
- import { a as TraceDetail, b as TraceSummary, c as TraceCounterfactual } from '../types-hjzSWxtv.mjs';
3
- export { A as AdvisoryRecord, T as TraceHealth, d as TraceSectionRewrite } from '../types-hjzSWxtv.mjs';
4
- import '../ir-BFwWhj2s.mjs';
1
+ import { G as GlassboxEvent } from '../types-CRXaR7nJ.mjs';
2
+ import { a as TraceDetail, b as TraceSummary, c as TraceCounterfactual } from '../types-DHi4FcUu.mjs';
3
+ export { A as AdvisoryRecord, T as TraceHealth, d as TraceSectionRewrite } from '../types-DHi4FcUu.mjs';
4
+ import '../ir-D4S9R816.mjs';
5
5
  import '../dialect.mjs';
6
6
 
7
7
  /**
@@ -1,7 +1,7 @@
1
- import { G as GlassboxEvent } from '../types-B4kz3Vs0.js';
2
- import { a as TraceDetail, b as TraceSummary, c as TraceCounterfactual } from '../types-D_fLt_Xv.js';
3
- export { A as AdvisoryRecord, T as TraceHealth, d as TraceSectionRewrite } from '../types-D_fLt_Xv.js';
4
- import '../ir-DZKS1tI7.js';
1
+ import { G as GlassboxEvent } from '../types-CAs9-0S4.js';
2
+ import { a as TraceDetail, b as TraceSummary, c as TraceCounterfactual } from '../types-Cvd6kRNv.js';
3
+ export { A as AdvisoryRecord, T as TraceHealth, d as TraceSectionRewrite } from '../types-Cvd6kRNv.js';
4
+ import '../ir-Cx9hJj0B.js';
5
5
  import '../dialect.js';
6
6
 
7
7
  /**
@@ -1956,9 +1956,15 @@ var COST_RANKING_REFERENCE_SHAPE = {
1956
1956
  inputTokens: 4e3,
1957
1957
  outputTokens: 250
1958
1958
  };
1959
- function estimateChainCostUsd(profile, shape = COST_RANKING_REFERENCE_SHAPE) {
1959
+ function estimateModelCostUsd(profile, shape = COST_RANKING_REFERENCE_SHAPE) {
1960
+ if (!profile || typeof profile !== "object" || Array.isArray(profile) || typeof profile.costInputPer1m !== "number" || typeof profile.costOutputPer1m !== "number") {
1961
+ throw new TypeError(
1962
+ `estimateModelCostUsd: expected a single ModelProfile, got ${Array.isArray(profile) ? "an array (a chain? map over it)" : typeof profile}. For a chain: chain.map((id) => estimateModelCostUsd(getProfile(id))).`
1963
+ );
1964
+ }
1960
1965
  return shape.inputTokens / 1e6 * profile.costInputPer1m + shape.outputTokens / 1e6 * profile.costOutputPer1m;
1961
1966
  }
1967
+ var estimateChainCostUsd = estimateModelCostUsd;
1962
1968
  function buildCostOrderedChain(archetype) {
1963
1969
  return allProfiles().filter((p) => p.status === "current").filter(
1964
1970
  (p) => getArchetypePerfScore(p.id, archetype).score >= ARCHETYPE_FLOOR_DEFAULT
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  ARCHETYPE_FLOOR_DEFAULT,
3
3
  getDefaultFallbackChain
4
- } from "../chunk-PMTT4H5W.mjs";
4
+ } from "../chunk-XPD4I3Q5.mjs";
5
5
  import {
6
6
  tryGetProfile
7
7
  } from "../chunk-VVRDFE6T.mjs";
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { a as TraceDetail } from '../../types-hjzSWxtv.mjs';
3
- import '../../ir-BFwWhj2s.mjs';
2
+ import { a as TraceDetail } from '../../types-DHi4FcUu.mjs';
3
+ import '../../ir-D4S9R816.mjs';
4
4
  import '../../dialect.mjs';
5
5
 
6
6
  /**
@@ -1,6 +1,6 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { a as TraceDetail } from '../../types-D_fLt_Xv.js';
3
- import '../../ir-DZKS1tI7.js';
2
+ import { a as TraceDetail } from '../../types-Cvd6kRNv.js';
3
+ import '../../ir-Cx9hJj0B.js';
4
4
  import '../../dialect.js';
5
5
 
6
6
  /**
package/dist/index.d.mts CHANGED
@@ -1,9 +1,9 @@
1
- import { C as CompilePolicy, N as NormalizedResponse, A as ApiKeys, P as ProviderOverrides, a as CompiledRequest, b as PromptIR, c as CallOptions, d as CallResult, S as SystemModelMessage, e as CompileResult, B as BestPracticeAdvisory, F as FallbackReason, f as SectionRewrite, R as RecordInput, g as RecordOutcomeInput, O as OutcomeResult, h as OracleScore, i as Adapter, j as PerAxisMetrics, k as Provider, l as ChainEntry, G as Grounding } from './ir-BFwWhj2s.mjs';
2
- export { m as CallAttempt, n as CallError, o as ChainModelEntry, p as ChainWithGrounding, q as Constraints, E as EffortLevel, r as GoldenCaptureOptions, H as HistoryCachePolicy, I as IntentDeclaration, M as Message, s as MutationApplied, t as NormalizedTokens, u as OutcomeKind, v as PerAxisMetricsByModel, w as PromptSection, x as SectionKind, y as ShadowProbeConfig, T as ToolCall, z as ToolDefinition, D as captureGoldenIr, J as hasMutation, K as mutationId, L as parseGoldenCaptureRate, Q as resolveGoldenCaptureRate, U as shouldCaptureGolden } from './ir-BFwWhj2s.mjs';
1
+ import { C as CompilePolicy, N as NormalizedResponse, A as ApiKeys, P as ProviderOverrides, a as CompiledRequest, b as PromptIR, c as CallOptions, d as CallResult, S as SystemModelMessage, e as CompileResult, B as BestPracticeAdvisory, F as FallbackReason, f as SectionRewrite, R as RecordInput, g as RecordOutcomeInput, O as OutcomeResult, h as OracleScore, i as Adapter, j as PerAxisMetrics, k as Provider, l as ChainEntry, G as Grounding } from './ir-D4S9R816.mjs';
2
+ export { m as CallAttempt, n as CallError, o as ChainModelEntry, p as ChainWithGrounding, q as Constraints, E as EffortLevel, r as GoldenCaptureOptions, H as HistoryCachePolicy, I as IntentDeclaration, M as Message, s as MutationApplied, t as NormalizedTokens, u as OutcomeKind, v as PerAxisMetricsByModel, w as PromptSection, x as SectionKind, y as ShadowProbeConfig, T as ToolCall, z as ToolDefinition, D as captureGoldenIr, J as hasMutation, K as mutationId, L as parseGoldenCaptureRate, Q as resolveGoldenCaptureRate, U as shouldCaptureGolden } from './ir-D4S9R816.mjs';
3
3
  import { ModelProfile, ArchetypeConvention } from './profiles.mjs';
4
4
  export { ALIASES, CacheStrategy, CliffRule, LATENCY_TIER_MS, LatencyTier, LoweringSpec, RecoveryRule, StructuredOutputCapability, SystemPromptMode, allProfiles, getProfile, latencyTierOf, profilesByProvider, tryGetProfile } from './profiles.mjs';
5
5
  export { BrainForwardConfig, BrainForwardRoutes, createBrainForwardRoutes } from './brain-proxy.mjs';
6
- export { KeyHealthConfig, KeyHealthProvider, KeyHealthResponseBody, KeyHealthResult, KeyHealthRoute, createKeyHealthRoute } from './key-health.mjs';
6
+ export { KEY_FINGERPRINT_DOMAIN, KEY_FINGERPRINT_LENGTH, KeyHealthConfig, KeyHealthProvider, KeyHealthResponseBody, KeyHealthResult, KeyHealthRoute, createKeyHealthRoute, keyFingerprint } from './key-health.mjs';
7
7
  import { IntentArchetypeName, OutputMode } from './dialect.mjs';
8
8
  export { ALL_ARCHETYPES, ContextBucket, DIALECT_VERSION, HistoryDepth, INTENT_ARCHETYPES, ShapeSignature, ToolCountBucket, bucketContext, bucketHistory, bucketToolCount, hashShape, isArchetype, learningKey } from './dialect.mjs';
9
9
 
@@ -1146,7 +1146,7 @@ declare function runStrategyEvalWithAttribution(opts: Omit<GoldenEvalOptions, 'a
1146
1146
  * guard in `tests/version.test.ts` fails the suite (and therefore
1147
1147
  * `prepublishOnly`) when they diverge — a stale constant cannot reach npm.
1148
1148
  */
1149
- declare const LIBRARY_VERSION = "2.0.0-alpha.80";
1149
+ declare const LIBRARY_VERSION = "2.0.0-alpha.82";
1150
1150
 
1151
1151
  /**
1152
1152
  * Oracle contract — how an app tells the brain whether a response was good.
@@ -2540,10 +2540,16 @@ declare const COST_RANKING_REFERENCE_SHAPE: {
2540
2540
  * consumer-side code share ONE derivation of "what does this model cost
2541
2541
  * here" — two independent derivations of one concept will drift (s75).
2542
2542
  */
2543
- declare function estimateChainCostUsd(profile: ModelProfile, shape?: {
2543
+ declare function estimateModelCostUsd(profile: ModelProfile, shape?: {
2544
2544
  inputTokens: number;
2545
2545
  outputTokens: number;
2546
2546
  }): number;
2547
+ /**
2548
+ * @deprecated alpha.81 — renamed to {@link estimateModelCostUsd}; it takes a
2549
+ * single MODEL, not a chain. Preserved because alpha.80 shipped this name and
2550
+ * a consumer adopted it within hours. Identical behavior.
2551
+ */
2552
+ declare const estimateChainCostUsd: typeof estimateModelCostUsd;
2547
2553
  /**
2548
2554
  * How many distinct providers a chain spans. `1` means every fallback shares
2549
2555
  * one provider's fate — the chain buys you retries, not outage independence.
@@ -3754,4 +3760,4 @@ declare function planDecomposition(args: PlanDecompositionArgs): DecompositionPl
3754
3760
  */
3755
3761
  declare function compile(ir: PromptIR, opts?: CompileOptions): CompileResult;
3756
3762
 
3757
- export { ABSOLUTE_FLOOR, type AISDKConvertedMessage, ARCHETYPE_FAMILY_FITS, ARCHETYPE_FLOOR_DEFAULT, type ActionableAdvisory, Adapter, type AdvisoryResolutionSource, type AdvisorySeverity, type AdvisoryStatus, type AdvisorySuggestedFix, ApiKeys, type AppOracle, type ApplySectionRewritesArgs, type ApplySectionRewritesResult, ArchetypeConvention, type ArchetypeFamilyFit, type ArchetypePerfMap, type ArchetypePerfNMap, type ArchetypePerfScoreResult, type AttachCacheControlResult, BRAIN_READ_ENV_NAMES, BestPracticeAdvisory, type BrainConfig, type BrainDeadLetterEntry, type BrainHealthSnapshot, type BrainQueryConfig, type BrainReadEnv, COACH_CFG, COST_RANKING_REFERENCE_SHAPE, CallOptions, CallResult, ChainEntry, type CompatibilityIntent, type CompileForAISDKv6Result, type CompileOptions, CompilePolicy, CompileResult, CompiledRequest, type CreateDelegateOpts, DECOMPOSITION_TEMPLATES, DECOMPOSITION_TEMPLATES_VERSION, DEFAULT_FINDINGS_ENDPOINT, DEFAULT_MEASURED_FAILURE_ENDPOINT, DEFAULT_PROMOTIONS_ENDPOINT, DELEGATE_TOOL_DEFINITION, DISCIPLINE_GATES_V1_ALT_HEADER, type DecompositionPlan, type DecompositionStep, type DecompositionTemplate, type DelegateHandle, type DelegateRefusalReason, type DelegateResult, type DelegateToolArgs, type ExclusionFindingRow, type ExclusionResolutionSource, type ExecuteErr, type ExecuteOk, type ExecuteOptions, type ExecuteResult, type ExecutorCandidate, type FallbackPosture, FallbackReason, FamilyResolutionError, type GetActionableAdvisoriesOptions, type GetApplicablePromotionOpts, type GetDefaultFallbackChainOpts, type GetMeasuredFailureOpts, type GetPerAxisMetricsOpts, type GetRecommendedPrimaryOptions, type GoldenEvalAxis, type GoldenEvalCase, type GoldenEvalOptions, type GoldenEvalRunResult, type GoldenEvalStrategyId, type GoldenIrRecordInput, Grounding, IntentArchetypeName, JUDGE_RUBRICS, LIBRARY_VERSION, type LLMJudgeOptions, MEASURED_FAILURE_CFG, MEASURED_GROUNDING_MIN_N, type MarkAdvisoryResolvedOptions, type MarkExclusionFindingHandledOptions, type MarkPromoteReadyHandledOptions, type MeasuredFailureRuntime, type MeasuredFailureVerdict, type ModelBrainRow, type ModelCompatibility, ModelProfile, NormalizedResponse, type OracleContext, OracleScore, type OutcomePayload, OutcomeResult, OutputMode, PRODUCER_OWNED_RULE_CODES, PROVIDER_ENV_KEYS, PerAxisMetrics, type PlannedStep, type PricingRow, type ProbeShadowOptions, type ProbeShadowServed, type ProfileToRowOptions, type PromoteReadyFindingRow, type PromoteReadyResolution, type PromotionRow, type PromotionsRuntime, PromptIR, Provider, ProviderOverrides, type ProviderReachability, ROLLBACK_SUPPRESSION_WINDOW_DAYS, RULE_DISCIPLINE_GATES_V1, RULE_DISCIPLINE_GATES_V1_STRUCTURED, RULE_SEQUENTIAL_TOOL_CLIFF, type ReachabilityOpts, RecordInput, RecordOutcomeInput, type RunAdvisorPhase2Context, STRATEGY_AUTHORSHIP_LIMITATION, SectionRewrite, type ShadowProbeRecordInput, type StrategyAttribution, type StrategyAttributionResult, type StrategyOutcome, type SupportedProvider, type SurfaceFailureRow, type SurfaceStats, SystemModelMessage, TRANSLATOR_FLOOR, _testResetMeasuredFailure, _testResetPromotions, _testWaitForMeasuredFailureRefresh, _testWaitForPromotionsRefresh, altGatesBlockFor, applyArchetypeConvention, applySectionRewrites, attachCacheControlToStreamTextInput, awaitMeasuredFailureReady, brainHealth, buildGoldenIrRow, buildLLMJudge, buildPairwiseJudgePrompt, buildShadowProbeRow, call, chainProviderSpread, classifyStrategyOutcome, clearBrain, combineOrderSwappedVerdicts, compile, compileForAISDKv6, configureBrain, configureMeasuredFailureBrain, configurePromotionsBrain, countTokens, createDelegate, deriveFamilyFromModelId, deriveOwnership, estimateChainCostUsd, execute, findBetterFit, flushBrainDeadLetter, getActionableAdvisories, getAllStarterChains, getAllStarterChainsWithGrounding, getApplicablePromotion, getArchetypePerfScore, getDefaultFallbackChain, getDefaultFallbackChainWithGrounding, getMeasuredFailureVerdict, getModelCompatibility, getPerAxisMetrics, getReachabilityDiagnostic, getRecentRollback, getRecommendedPrimary, getSequentialStarterChain, getSequentialStarterChainWithGrounding, getStaleExclusionFindings, getStarterChain, getStarterChainWithGrounding, isAutoPromoteEnabledFromEnv, isBrainQueryActiveFor, isBrainSync, isDelegateEnabledFromEnv, isExclusionFindingsBrainActive, isMeasuredFailureBrainActive, isMeasuredFailureGateEnabledFromEnv, isModelReachable, isPromotionsBrainActive, isProviderReachable, judgeMeasuredFailure, loadAliasesFromBrain, loadArchetypePerfFromBrain, loadArchetypePerfNFromBrain, loadChainsFromBrain, loadModelsFromBrain, loadPricingFromBrain, mapMeasuredFailureRows, markAdvisoryResolved, markExclusionFindingHandled, markPromoteReadyHandled, parseJudgeVerdict, peekBrainDeadLetter, planDecomposition, prefetchMeasuredFailure, probeShadow, profileToRow, readBrainReadEnv, record, recordGoldenIr, recordOutcome, recordShadowProbe, renderIrForJudge, resetTokenizer, resolveConventionsForProfile, resolvePricingAt, resolveProviderKey, rubricFor, runAdvisor, runGoldenEval, runStrategyEvalWithAttribution, setTokenizer, wilsonLowerBound, withAltDisciplineContract, withDisciplineContract };
3763
+ export { ABSOLUTE_FLOOR, type AISDKConvertedMessage, ARCHETYPE_FAMILY_FITS, ARCHETYPE_FLOOR_DEFAULT, type ActionableAdvisory, Adapter, type AdvisoryResolutionSource, type AdvisorySeverity, type AdvisoryStatus, type AdvisorySuggestedFix, ApiKeys, type AppOracle, type ApplySectionRewritesArgs, type ApplySectionRewritesResult, ArchetypeConvention, type ArchetypeFamilyFit, type ArchetypePerfMap, type ArchetypePerfNMap, type ArchetypePerfScoreResult, type AttachCacheControlResult, BRAIN_READ_ENV_NAMES, BestPracticeAdvisory, type BrainConfig, type BrainDeadLetterEntry, type BrainHealthSnapshot, type BrainQueryConfig, type BrainReadEnv, COACH_CFG, COST_RANKING_REFERENCE_SHAPE, CallOptions, CallResult, ChainEntry, type CompatibilityIntent, type CompileForAISDKv6Result, type CompileOptions, CompilePolicy, CompileResult, CompiledRequest, type CreateDelegateOpts, DECOMPOSITION_TEMPLATES, DECOMPOSITION_TEMPLATES_VERSION, DEFAULT_FINDINGS_ENDPOINT, DEFAULT_MEASURED_FAILURE_ENDPOINT, DEFAULT_PROMOTIONS_ENDPOINT, DELEGATE_TOOL_DEFINITION, DISCIPLINE_GATES_V1_ALT_HEADER, type DecompositionPlan, type DecompositionStep, type DecompositionTemplate, type DelegateHandle, type DelegateRefusalReason, type DelegateResult, type DelegateToolArgs, type ExclusionFindingRow, type ExclusionResolutionSource, type ExecuteErr, type ExecuteOk, type ExecuteOptions, type ExecuteResult, type ExecutorCandidate, type FallbackPosture, FallbackReason, FamilyResolutionError, type GetActionableAdvisoriesOptions, type GetApplicablePromotionOpts, type GetDefaultFallbackChainOpts, type GetMeasuredFailureOpts, type GetPerAxisMetricsOpts, type GetRecommendedPrimaryOptions, type GoldenEvalAxis, type GoldenEvalCase, type GoldenEvalOptions, type GoldenEvalRunResult, type GoldenEvalStrategyId, type GoldenIrRecordInput, Grounding, IntentArchetypeName, JUDGE_RUBRICS, LIBRARY_VERSION, type LLMJudgeOptions, MEASURED_FAILURE_CFG, MEASURED_GROUNDING_MIN_N, type MarkAdvisoryResolvedOptions, type MarkExclusionFindingHandledOptions, type MarkPromoteReadyHandledOptions, type MeasuredFailureRuntime, type MeasuredFailureVerdict, type ModelBrainRow, type ModelCompatibility, ModelProfile, NormalizedResponse, type OracleContext, OracleScore, type OutcomePayload, OutcomeResult, OutputMode, PRODUCER_OWNED_RULE_CODES, PROVIDER_ENV_KEYS, PerAxisMetrics, type PlannedStep, type PricingRow, type ProbeShadowOptions, type ProbeShadowServed, type ProfileToRowOptions, type PromoteReadyFindingRow, type PromoteReadyResolution, type PromotionRow, type PromotionsRuntime, PromptIR, Provider, ProviderOverrides, type ProviderReachability, ROLLBACK_SUPPRESSION_WINDOW_DAYS, RULE_DISCIPLINE_GATES_V1, RULE_DISCIPLINE_GATES_V1_STRUCTURED, RULE_SEQUENTIAL_TOOL_CLIFF, type ReachabilityOpts, RecordInput, RecordOutcomeInput, type RunAdvisorPhase2Context, STRATEGY_AUTHORSHIP_LIMITATION, SectionRewrite, type ShadowProbeRecordInput, type StrategyAttribution, type StrategyAttributionResult, type StrategyOutcome, type SupportedProvider, type SurfaceFailureRow, type SurfaceStats, SystemModelMessage, TRANSLATOR_FLOOR, _testResetMeasuredFailure, _testResetPromotions, _testWaitForMeasuredFailureRefresh, _testWaitForPromotionsRefresh, altGatesBlockFor, applyArchetypeConvention, applySectionRewrites, attachCacheControlToStreamTextInput, awaitMeasuredFailureReady, brainHealth, buildGoldenIrRow, buildLLMJudge, buildPairwiseJudgePrompt, buildShadowProbeRow, call, chainProviderSpread, classifyStrategyOutcome, clearBrain, combineOrderSwappedVerdicts, compile, compileForAISDKv6, configureBrain, configureMeasuredFailureBrain, configurePromotionsBrain, countTokens, createDelegate, deriveFamilyFromModelId, deriveOwnership, estimateChainCostUsd, estimateModelCostUsd, execute, findBetterFit, flushBrainDeadLetter, getActionableAdvisories, getAllStarterChains, getAllStarterChainsWithGrounding, getApplicablePromotion, getArchetypePerfScore, getDefaultFallbackChain, getDefaultFallbackChainWithGrounding, getMeasuredFailureVerdict, getModelCompatibility, getPerAxisMetrics, getReachabilityDiagnostic, getRecentRollback, getRecommendedPrimary, getSequentialStarterChain, getSequentialStarterChainWithGrounding, getStaleExclusionFindings, getStarterChain, getStarterChainWithGrounding, isAutoPromoteEnabledFromEnv, isBrainQueryActiveFor, isBrainSync, isDelegateEnabledFromEnv, isExclusionFindingsBrainActive, isMeasuredFailureBrainActive, isMeasuredFailureGateEnabledFromEnv, isModelReachable, isPromotionsBrainActive, isProviderReachable, judgeMeasuredFailure, loadAliasesFromBrain, loadArchetypePerfFromBrain, loadArchetypePerfNFromBrain, loadChainsFromBrain, loadModelsFromBrain, loadPricingFromBrain, mapMeasuredFailureRows, markAdvisoryResolved, markExclusionFindingHandled, markPromoteReadyHandled, parseJudgeVerdict, peekBrainDeadLetter, planDecomposition, prefetchMeasuredFailure, probeShadow, profileToRow, readBrainReadEnv, record, recordGoldenIr, recordOutcome, recordShadowProbe, renderIrForJudge, resetTokenizer, resolveConventionsForProfile, resolvePricingAt, resolveProviderKey, rubricFor, runAdvisor, runGoldenEval, runStrategyEvalWithAttribution, setTokenizer, wilsonLowerBound, withAltDisciplineContract, withDisciplineContract };
package/dist/index.d.ts CHANGED
@@ -1,9 +1,9 @@
1
- import { C as CompilePolicy, N as NormalizedResponse, A as ApiKeys, P as ProviderOverrides, a as CompiledRequest, b as PromptIR, c as CallOptions, d as CallResult, S as SystemModelMessage, e as CompileResult, B as BestPracticeAdvisory, F as FallbackReason, f as SectionRewrite, R as RecordInput, g as RecordOutcomeInput, O as OutcomeResult, h as OracleScore, i as Adapter, j as PerAxisMetrics, k as Provider, l as ChainEntry, G as Grounding } from './ir-DZKS1tI7.js';
2
- export { m as CallAttempt, n as CallError, o as ChainModelEntry, p as ChainWithGrounding, q as Constraints, E as EffortLevel, r as GoldenCaptureOptions, H as HistoryCachePolicy, I as IntentDeclaration, M as Message, s as MutationApplied, t as NormalizedTokens, u as OutcomeKind, v as PerAxisMetricsByModel, w as PromptSection, x as SectionKind, y as ShadowProbeConfig, T as ToolCall, z as ToolDefinition, D as captureGoldenIr, J as hasMutation, K as mutationId, L as parseGoldenCaptureRate, Q as resolveGoldenCaptureRate, U as shouldCaptureGolden } from './ir-DZKS1tI7.js';
1
+ import { C as CompilePolicy, N as NormalizedResponse, A as ApiKeys, P as ProviderOverrides, a as CompiledRequest, b as PromptIR, c as CallOptions, d as CallResult, S as SystemModelMessage, e as CompileResult, B as BestPracticeAdvisory, F as FallbackReason, f as SectionRewrite, R as RecordInput, g as RecordOutcomeInput, O as OutcomeResult, h as OracleScore, i as Adapter, j as PerAxisMetrics, k as Provider, l as ChainEntry, G as Grounding } from './ir-Cx9hJj0B.js';
2
+ export { m as CallAttempt, n as CallError, o as ChainModelEntry, p as ChainWithGrounding, q as Constraints, E as EffortLevel, r as GoldenCaptureOptions, H as HistoryCachePolicy, I as IntentDeclaration, M as Message, s as MutationApplied, t as NormalizedTokens, u as OutcomeKind, v as PerAxisMetricsByModel, w as PromptSection, x as SectionKind, y as ShadowProbeConfig, T as ToolCall, z as ToolDefinition, D as captureGoldenIr, J as hasMutation, K as mutationId, L as parseGoldenCaptureRate, Q as resolveGoldenCaptureRate, U as shouldCaptureGolden } from './ir-Cx9hJj0B.js';
3
3
  import { ModelProfile, ArchetypeConvention } from './profiles.js';
4
4
  export { ALIASES, CacheStrategy, CliffRule, LATENCY_TIER_MS, LatencyTier, LoweringSpec, RecoveryRule, StructuredOutputCapability, SystemPromptMode, allProfiles, getProfile, latencyTierOf, profilesByProvider, tryGetProfile } from './profiles.js';
5
5
  export { BrainForwardConfig, BrainForwardRoutes, createBrainForwardRoutes } from './brain-proxy.js';
6
- export { KeyHealthConfig, KeyHealthProvider, KeyHealthResponseBody, KeyHealthResult, KeyHealthRoute, createKeyHealthRoute } from './key-health.js';
6
+ export { KEY_FINGERPRINT_DOMAIN, KEY_FINGERPRINT_LENGTH, KeyHealthConfig, KeyHealthProvider, KeyHealthResponseBody, KeyHealthResult, KeyHealthRoute, createKeyHealthRoute, keyFingerprint } from './key-health.js';
7
7
  import { IntentArchetypeName, OutputMode } from './dialect.js';
8
8
  export { ALL_ARCHETYPES, ContextBucket, DIALECT_VERSION, HistoryDepth, INTENT_ARCHETYPES, ShapeSignature, ToolCountBucket, bucketContext, bucketHistory, bucketToolCount, hashShape, isArchetype, learningKey } from './dialect.js';
9
9
 
@@ -1146,7 +1146,7 @@ declare function runStrategyEvalWithAttribution(opts: Omit<GoldenEvalOptions, 'a
1146
1146
  * guard in `tests/version.test.ts` fails the suite (and therefore
1147
1147
  * `prepublishOnly`) when they diverge — a stale constant cannot reach npm.
1148
1148
  */
1149
- declare const LIBRARY_VERSION = "2.0.0-alpha.80";
1149
+ declare const LIBRARY_VERSION = "2.0.0-alpha.82";
1150
1150
 
1151
1151
  /**
1152
1152
  * Oracle contract — how an app tells the brain whether a response was good.
@@ -2540,10 +2540,16 @@ declare const COST_RANKING_REFERENCE_SHAPE: {
2540
2540
  * consumer-side code share ONE derivation of "what does this model cost
2541
2541
  * here" — two independent derivations of one concept will drift (s75).
2542
2542
  */
2543
- declare function estimateChainCostUsd(profile: ModelProfile, shape?: {
2543
+ declare function estimateModelCostUsd(profile: ModelProfile, shape?: {
2544
2544
  inputTokens: number;
2545
2545
  outputTokens: number;
2546
2546
  }): number;
2547
+ /**
2548
+ * @deprecated alpha.81 — renamed to {@link estimateModelCostUsd}; it takes a
2549
+ * single MODEL, not a chain. Preserved because alpha.80 shipped this name and
2550
+ * a consumer adopted it within hours. Identical behavior.
2551
+ */
2552
+ declare const estimateChainCostUsd: typeof estimateModelCostUsd;
2547
2553
  /**
2548
2554
  * How many distinct providers a chain spans. `1` means every fallback shares
2549
2555
  * one provider's fate — the chain buys you retries, not outage independence.
@@ -3754,4 +3760,4 @@ declare function planDecomposition(args: PlanDecompositionArgs): DecompositionPl
3754
3760
  */
3755
3761
  declare function compile(ir: PromptIR, opts?: CompileOptions): CompileResult;
3756
3762
 
3757
- export { ABSOLUTE_FLOOR, type AISDKConvertedMessage, ARCHETYPE_FAMILY_FITS, ARCHETYPE_FLOOR_DEFAULT, type ActionableAdvisory, Adapter, type AdvisoryResolutionSource, type AdvisorySeverity, type AdvisoryStatus, type AdvisorySuggestedFix, ApiKeys, type AppOracle, type ApplySectionRewritesArgs, type ApplySectionRewritesResult, ArchetypeConvention, type ArchetypeFamilyFit, type ArchetypePerfMap, type ArchetypePerfNMap, type ArchetypePerfScoreResult, type AttachCacheControlResult, BRAIN_READ_ENV_NAMES, BestPracticeAdvisory, type BrainConfig, type BrainDeadLetterEntry, type BrainHealthSnapshot, type BrainQueryConfig, type BrainReadEnv, COACH_CFG, COST_RANKING_REFERENCE_SHAPE, CallOptions, CallResult, ChainEntry, type CompatibilityIntent, type CompileForAISDKv6Result, type CompileOptions, CompilePolicy, CompileResult, CompiledRequest, type CreateDelegateOpts, DECOMPOSITION_TEMPLATES, DECOMPOSITION_TEMPLATES_VERSION, DEFAULT_FINDINGS_ENDPOINT, DEFAULT_MEASURED_FAILURE_ENDPOINT, DEFAULT_PROMOTIONS_ENDPOINT, DELEGATE_TOOL_DEFINITION, DISCIPLINE_GATES_V1_ALT_HEADER, type DecompositionPlan, type DecompositionStep, type DecompositionTemplate, type DelegateHandle, type DelegateRefusalReason, type DelegateResult, type DelegateToolArgs, type ExclusionFindingRow, type ExclusionResolutionSource, type ExecuteErr, type ExecuteOk, type ExecuteOptions, type ExecuteResult, type ExecutorCandidate, type FallbackPosture, FallbackReason, FamilyResolutionError, type GetActionableAdvisoriesOptions, type GetApplicablePromotionOpts, type GetDefaultFallbackChainOpts, type GetMeasuredFailureOpts, type GetPerAxisMetricsOpts, type GetRecommendedPrimaryOptions, type GoldenEvalAxis, type GoldenEvalCase, type GoldenEvalOptions, type GoldenEvalRunResult, type GoldenEvalStrategyId, type GoldenIrRecordInput, Grounding, IntentArchetypeName, JUDGE_RUBRICS, LIBRARY_VERSION, type LLMJudgeOptions, MEASURED_FAILURE_CFG, MEASURED_GROUNDING_MIN_N, type MarkAdvisoryResolvedOptions, type MarkExclusionFindingHandledOptions, type MarkPromoteReadyHandledOptions, type MeasuredFailureRuntime, type MeasuredFailureVerdict, type ModelBrainRow, type ModelCompatibility, ModelProfile, NormalizedResponse, type OracleContext, OracleScore, type OutcomePayload, OutcomeResult, OutputMode, PRODUCER_OWNED_RULE_CODES, PROVIDER_ENV_KEYS, PerAxisMetrics, type PlannedStep, type PricingRow, type ProbeShadowOptions, type ProbeShadowServed, type ProfileToRowOptions, type PromoteReadyFindingRow, type PromoteReadyResolution, type PromotionRow, type PromotionsRuntime, PromptIR, Provider, ProviderOverrides, type ProviderReachability, ROLLBACK_SUPPRESSION_WINDOW_DAYS, RULE_DISCIPLINE_GATES_V1, RULE_DISCIPLINE_GATES_V1_STRUCTURED, RULE_SEQUENTIAL_TOOL_CLIFF, type ReachabilityOpts, RecordInput, RecordOutcomeInput, type RunAdvisorPhase2Context, STRATEGY_AUTHORSHIP_LIMITATION, SectionRewrite, type ShadowProbeRecordInput, type StrategyAttribution, type StrategyAttributionResult, type StrategyOutcome, type SupportedProvider, type SurfaceFailureRow, type SurfaceStats, SystemModelMessage, TRANSLATOR_FLOOR, _testResetMeasuredFailure, _testResetPromotions, _testWaitForMeasuredFailureRefresh, _testWaitForPromotionsRefresh, altGatesBlockFor, applyArchetypeConvention, applySectionRewrites, attachCacheControlToStreamTextInput, awaitMeasuredFailureReady, brainHealth, buildGoldenIrRow, buildLLMJudge, buildPairwiseJudgePrompt, buildShadowProbeRow, call, chainProviderSpread, classifyStrategyOutcome, clearBrain, combineOrderSwappedVerdicts, compile, compileForAISDKv6, configureBrain, configureMeasuredFailureBrain, configurePromotionsBrain, countTokens, createDelegate, deriveFamilyFromModelId, deriveOwnership, estimateChainCostUsd, execute, findBetterFit, flushBrainDeadLetter, getActionableAdvisories, getAllStarterChains, getAllStarterChainsWithGrounding, getApplicablePromotion, getArchetypePerfScore, getDefaultFallbackChain, getDefaultFallbackChainWithGrounding, getMeasuredFailureVerdict, getModelCompatibility, getPerAxisMetrics, getReachabilityDiagnostic, getRecentRollback, getRecommendedPrimary, getSequentialStarterChain, getSequentialStarterChainWithGrounding, getStaleExclusionFindings, getStarterChain, getStarterChainWithGrounding, isAutoPromoteEnabledFromEnv, isBrainQueryActiveFor, isBrainSync, isDelegateEnabledFromEnv, isExclusionFindingsBrainActive, isMeasuredFailureBrainActive, isMeasuredFailureGateEnabledFromEnv, isModelReachable, isPromotionsBrainActive, isProviderReachable, judgeMeasuredFailure, loadAliasesFromBrain, loadArchetypePerfFromBrain, loadArchetypePerfNFromBrain, loadChainsFromBrain, loadModelsFromBrain, loadPricingFromBrain, mapMeasuredFailureRows, markAdvisoryResolved, markExclusionFindingHandled, markPromoteReadyHandled, parseJudgeVerdict, peekBrainDeadLetter, planDecomposition, prefetchMeasuredFailure, probeShadow, profileToRow, readBrainReadEnv, record, recordGoldenIr, recordOutcome, recordShadowProbe, renderIrForJudge, resetTokenizer, resolveConventionsForProfile, resolvePricingAt, resolveProviderKey, rubricFor, runAdvisor, runGoldenEval, runStrategyEvalWithAttribution, setTokenizer, wilsonLowerBound, withAltDisciplineContract, withDisciplineContract };
3763
+ export { ABSOLUTE_FLOOR, type AISDKConvertedMessage, ARCHETYPE_FAMILY_FITS, ARCHETYPE_FLOOR_DEFAULT, type ActionableAdvisory, Adapter, type AdvisoryResolutionSource, type AdvisorySeverity, type AdvisoryStatus, type AdvisorySuggestedFix, ApiKeys, type AppOracle, type ApplySectionRewritesArgs, type ApplySectionRewritesResult, ArchetypeConvention, type ArchetypeFamilyFit, type ArchetypePerfMap, type ArchetypePerfNMap, type ArchetypePerfScoreResult, type AttachCacheControlResult, BRAIN_READ_ENV_NAMES, BestPracticeAdvisory, type BrainConfig, type BrainDeadLetterEntry, type BrainHealthSnapshot, type BrainQueryConfig, type BrainReadEnv, COACH_CFG, COST_RANKING_REFERENCE_SHAPE, CallOptions, CallResult, ChainEntry, type CompatibilityIntent, type CompileForAISDKv6Result, type CompileOptions, CompilePolicy, CompileResult, CompiledRequest, type CreateDelegateOpts, DECOMPOSITION_TEMPLATES, DECOMPOSITION_TEMPLATES_VERSION, DEFAULT_FINDINGS_ENDPOINT, DEFAULT_MEASURED_FAILURE_ENDPOINT, DEFAULT_PROMOTIONS_ENDPOINT, DELEGATE_TOOL_DEFINITION, DISCIPLINE_GATES_V1_ALT_HEADER, type DecompositionPlan, type DecompositionStep, type DecompositionTemplate, type DelegateHandle, type DelegateRefusalReason, type DelegateResult, type DelegateToolArgs, type ExclusionFindingRow, type ExclusionResolutionSource, type ExecuteErr, type ExecuteOk, type ExecuteOptions, type ExecuteResult, type ExecutorCandidate, type FallbackPosture, FallbackReason, FamilyResolutionError, type GetActionableAdvisoriesOptions, type GetApplicablePromotionOpts, type GetDefaultFallbackChainOpts, type GetMeasuredFailureOpts, type GetPerAxisMetricsOpts, type GetRecommendedPrimaryOptions, type GoldenEvalAxis, type GoldenEvalCase, type GoldenEvalOptions, type GoldenEvalRunResult, type GoldenEvalStrategyId, type GoldenIrRecordInput, Grounding, IntentArchetypeName, JUDGE_RUBRICS, LIBRARY_VERSION, type LLMJudgeOptions, MEASURED_FAILURE_CFG, MEASURED_GROUNDING_MIN_N, type MarkAdvisoryResolvedOptions, type MarkExclusionFindingHandledOptions, type MarkPromoteReadyHandledOptions, type MeasuredFailureRuntime, type MeasuredFailureVerdict, type ModelBrainRow, type ModelCompatibility, ModelProfile, NormalizedResponse, type OracleContext, OracleScore, type OutcomePayload, OutcomeResult, OutputMode, PRODUCER_OWNED_RULE_CODES, PROVIDER_ENV_KEYS, PerAxisMetrics, type PlannedStep, type PricingRow, type ProbeShadowOptions, type ProbeShadowServed, type ProfileToRowOptions, type PromoteReadyFindingRow, type PromoteReadyResolution, type PromotionRow, type PromotionsRuntime, PromptIR, Provider, ProviderOverrides, type ProviderReachability, ROLLBACK_SUPPRESSION_WINDOW_DAYS, RULE_DISCIPLINE_GATES_V1, RULE_DISCIPLINE_GATES_V1_STRUCTURED, RULE_SEQUENTIAL_TOOL_CLIFF, type ReachabilityOpts, RecordInput, RecordOutcomeInput, type RunAdvisorPhase2Context, STRATEGY_AUTHORSHIP_LIMITATION, SectionRewrite, type ShadowProbeRecordInput, type StrategyAttribution, type StrategyAttributionResult, type StrategyOutcome, type SupportedProvider, type SurfaceFailureRow, type SurfaceStats, SystemModelMessage, TRANSLATOR_FLOOR, _testResetMeasuredFailure, _testResetPromotions, _testWaitForMeasuredFailureRefresh, _testWaitForPromotionsRefresh, altGatesBlockFor, applyArchetypeConvention, applySectionRewrites, attachCacheControlToStreamTextInput, awaitMeasuredFailureReady, brainHealth, buildGoldenIrRow, buildLLMJudge, buildPairwiseJudgePrompt, buildShadowProbeRow, call, chainProviderSpread, classifyStrategyOutcome, clearBrain, combineOrderSwappedVerdicts, compile, compileForAISDKv6, configureBrain, configureMeasuredFailureBrain, configurePromotionsBrain, countTokens, createDelegate, deriveFamilyFromModelId, deriveOwnership, estimateChainCostUsd, estimateModelCostUsd, execute, findBetterFit, flushBrainDeadLetter, getActionableAdvisories, getAllStarterChains, getAllStarterChainsWithGrounding, getApplicablePromotion, getArchetypePerfScore, getDefaultFallbackChain, getDefaultFallbackChainWithGrounding, getMeasuredFailureVerdict, getModelCompatibility, getPerAxisMetrics, getReachabilityDiagnostic, getRecentRollback, getRecommendedPrimary, getSequentialStarterChain, getSequentialStarterChainWithGrounding, getStaleExclusionFindings, getStarterChain, getStarterChainWithGrounding, isAutoPromoteEnabledFromEnv, isBrainQueryActiveFor, isBrainSync, isDelegateEnabledFromEnv, isExclusionFindingsBrainActive, isMeasuredFailureBrainActive, isMeasuredFailureGateEnabledFromEnv, isModelReachable, isPromotionsBrainActive, isProviderReachable, judgeMeasuredFailure, loadAliasesFromBrain, loadArchetypePerfFromBrain, loadArchetypePerfNFromBrain, loadChainsFromBrain, loadModelsFromBrain, loadPricingFromBrain, mapMeasuredFailureRows, markAdvisoryResolved, markExclusionFindingHandled, markPromoteReadyHandled, parseJudgeVerdict, peekBrainDeadLetter, planDecomposition, prefetchMeasuredFailure, probeShadow, profileToRow, readBrainReadEnv, record, recordGoldenIr, recordOutcome, recordShadowProbe, renderIrForJudge, resetTokenizer, resolveConventionsForProfile, resolvePricingAt, resolveProviderKey, rubricFor, runAdvisor, runGoldenEval, runStrategyEvalWithAttribution, setTokenizer, wilsonLowerBound, withAltDisciplineContract, withDisciplineContract };
package/dist/index.js CHANGED
@@ -40,6 +40,8 @@ __export(index_exports, {
40
40
  FamilyResolutionError: () => FamilyResolutionError,
41
41
  INTENT_ARCHETYPES: () => INTENT_ARCHETYPES,
42
42
  JUDGE_RUBRICS: () => JUDGE_RUBRICS,
43
+ KEY_FINGERPRINT_DOMAIN: () => KEY_FINGERPRINT_DOMAIN,
44
+ KEY_FINGERPRINT_LENGTH: () => KEY_FINGERPRINT_LENGTH,
43
45
  LATENCY_TIER_MS: () => LATENCY_TIER_MS,
44
46
  LIBRARY_VERSION: () => LIBRARY_VERSION,
45
47
  MEASURED_FAILURE_CFG: () => MEASURED_FAILURE_CFG,
@@ -88,6 +90,7 @@ __export(index_exports, {
88
90
  deriveFamilyFromModelId: () => deriveFamilyFromModelId,
89
91
  deriveOwnership: () => deriveOwnership,
90
92
  estimateChainCostUsd: () => estimateChainCostUsd,
93
+ estimateModelCostUsd: () => estimateModelCostUsd,
91
94
  execute: () => execute,
92
95
  findBetterFit: () => findBetterFit,
93
96
  flushBrainDeadLetter: () => flushBrainDeadLetter,
@@ -124,6 +127,7 @@ __export(index_exports, {
124
127
  isPromotionsBrainActive: () => isPromotionsBrainActive,
125
128
  isProviderReachable: () => isProviderReachable,
126
129
  judgeMeasuredFailure: () => judgeMeasuredFailure,
130
+ keyFingerprint: () => keyFingerprint,
127
131
  latencyTierOf: () => latencyTierOf,
128
132
  learningKey: () => learningKey,
129
133
  loadAliasesFromBrain: () => loadAliasesFromBrain,
@@ -3868,9 +3872,15 @@ var COST_RANKING_REFERENCE_SHAPE = {
3868
3872
  inputTokens: 4e3,
3869
3873
  outputTokens: 250
3870
3874
  };
3871
- function estimateChainCostUsd(profile, shape = COST_RANKING_REFERENCE_SHAPE) {
3875
+ function estimateModelCostUsd(profile, shape = COST_RANKING_REFERENCE_SHAPE) {
3876
+ if (!profile || typeof profile !== "object" || Array.isArray(profile) || typeof profile.costInputPer1m !== "number" || typeof profile.costOutputPer1m !== "number") {
3877
+ throw new TypeError(
3878
+ `estimateModelCostUsd: expected a single ModelProfile, got ${Array.isArray(profile) ? "an array (a chain? map over it)" : typeof profile}. For a chain: chain.map((id) => estimateModelCostUsd(getProfile(id))).`
3879
+ );
3880
+ }
3872
3881
  return shape.inputTokens / 1e6 * profile.costInputPer1m + shape.outputTokens / 1e6 * profile.costOutputPer1m;
3873
3882
  }
3883
+ var estimateChainCostUsd = estimateModelCostUsd;
3874
3884
  function buildCostOrderedChain(archetype) {
3875
3885
  return allProfiles().filter((p) => p.status === "current").filter(
3876
3886
  (p) => getArchetypePerfScore(p.id, archetype).score >= ARCHETYPE_FLOOR_DEFAULT
@@ -5176,6 +5186,20 @@ function detectSingleModelArray(ir, policy) {
5176
5186
  }
5177
5187
  ];
5178
5188
  }
5189
+ function suppressedRecommendationReason(ir, archetype, altProfile) {
5190
+ if (getMeasuredFailureVerdict({ appId: ir.appId, archetype, model: altProfile.id })?.gated === true) {
5191
+ return "measured-failure-gate";
5192
+ }
5193
+ if (ir.constraints?.structuredOutput && effectiveConventions(altProfile).some(
5194
+ (c) => c.archetype === archetype && c.structuredOutputHint === "avoid"
5195
+ )) {
5196
+ return "schema-weakness-convention";
5197
+ }
5198
+ if (getRecentRollback({ appId: ir.appId, archetype, model: altProfile.id }) !== void 0) {
5199
+ return "recent-rollback";
5200
+ }
5201
+ return void 0;
5202
+ }
5179
5203
  function openPostureRemedyClause(archetype, recommended, resolveProfile) {
5180
5204
  const openChain = getDefaultFallbackChain({ archetype, posture: "open" });
5181
5205
  const openPrimaryId = openChain[0];
@@ -5213,25 +5237,7 @@ function detectCostMismatchedArchetype(ir, profile, phase2) {
5213
5237
  if (altScore.score < QUALITY_FLOOR_FOR_RECOMMENDATION) continue;
5214
5238
  if (altScore.score < chosenScore.score) continue;
5215
5239
  if (altProfile.costInputPer1m >= profile.costInputPer1m) continue;
5216
- if (getMeasuredFailureVerdict({
5217
- appId: ir.appId,
5218
- archetype,
5219
- model: altProfile.id
5220
- })?.gated === true) {
5221
- continue;
5222
- }
5223
- if (ir.constraints?.structuredOutput && effectiveConventions(altProfile).some(
5224
- (c) => c.archetype === archetype && c.structuredOutputHint === "avoid"
5225
- )) {
5226
- continue;
5227
- }
5228
- if (getRecentRollback({
5229
- appId: ir.appId,
5230
- archetype,
5231
- model: altProfile.id
5232
- }) !== void 0) {
5233
- continue;
5234
- }
5240
+ if (suppressedRecommendationReason(ir, archetype, altProfile)) continue;
5235
5241
  if (!bestAlt || altScore.score > bestAlt.score.score || altScore.score === bestAlt.score.score && altProfile.costInputPer1m < bestAlt.profile.costInputPer1m) {
5236
5242
  bestAlt = { id: altId, profile: altProfile, score: altScore };
5237
5243
  }
@@ -5289,6 +5295,7 @@ function detectTierDown(ir, profile, phase2) {
5289
5295
  if (altScore.score < QUALITY_FLOOR_FOR_RECOMMENDATION) continue;
5290
5296
  if (altScore.score < chosenScore.score) continue;
5291
5297
  if (altProfile.costInputPer1m > chosenCost * TIER_DOWN_COST_RATIO) continue;
5298
+ if (suppressedRecommendationReason(ir, archetype, altProfile)) continue;
5292
5299
  if (!bestAlt || altProfile.costInputPer1m < bestAlt.profile.costInputPer1m || altProfile.costInputPer1m === bestAlt.profile.costInputPer1m && altScore.score > bestAlt.score.score) {
5293
5300
  bestAlt = { id: altId, profile: altProfile, score: altScore };
5294
5301
  }
@@ -5335,7 +5342,18 @@ function detectArchetypePerfFloorBreach(ir, profile) {
5335
5342
  // library pick" endorsement could land on a materially pricier
5336
5343
  // primary. The floor recommendation stands; the axis is now named,
5337
5344
  // and the cost-ordered variant is offered alongside it.
5338
- suggestion: `Swap to a model whose archetypePerf for ${ir.intent.archetype} clears the floor. Use \`getModelCompatibility(candidateId, { archetype: '${ir.intent.archetype}' })\` to vet candidates, or \`getDefaultFallbackChain({ archetype: '${ir.intent.archetype}', posture: 'open' })\` for a library-picked chain that respects the floor by construction \u2014 note that chain is ordered by archetype performance, NOT cost, so it may select a pricier primary than you run today. Add \`optimizeFor: 'cost'\` for a chain that clears the same floor cheapest-first.`,
5345
+ //
5346
+ // alpha.82 (cc-Cairn 2026-07-29, follow-on 1): the suggestion read as
5347
+ // advice about the ARCHETYPE when it is a fact about ONE CALL. Model
5348
+ // selection is input-size dependent, so a rule that fires on the
5349
+ // small-payload tail of a path whose typical case clears the floor
5350
+ // reads as "your primary is wrong" when the accurate statement is
5351
+ // "this call landed here." Ground truth for the wording: tt-intel's
5352
+ // open critical is `gemini-2.5-flash-lite` (ask, 5/10) selected at
5353
+ // ~2.1K tokens_in, while `claude-opus-5` served the same archetype at
5354
+ // ~22K the same day — cc read the evidence set as self-contradictory
5355
+ // precisely because the text did not say which call it described.
5356
+ suggestion: `This fired for \`${profile.id}\`, the model selected for THIS call \u2014 selection is input-size dependent, so other calls on \`${ir.intent.archetype}\` may pick a different model that clears the floor. Swap to a model whose archetypePerf for ${ir.intent.archetype} clears the floor. Use \`getModelCompatibility(candidateId, { archetype: '${ir.intent.archetype}' })\` to vet candidates, or \`getDefaultFallbackChain({ archetype: '${ir.intent.archetype}', posture: 'open' })\` for a library-picked chain that respects the floor by construction \u2014 note that chain is ordered by archetype performance, NOT cost, so it may select a pricier primary than you run today. Add \`optimizeFor: 'cost'\` for a chain that clears the same floor cheapest-first. To stop this model being selected at all, pass \`policy.blockedModels: ['${profile.id}']\`.`,
5339
5357
  recommendationType: "model-swap",
5340
5358
  docsUrl: "https://github.com/stue/command-center/blob/main/interfaces/kgauto.md#best-practice-advisories"
5341
5359
  }
@@ -5834,6 +5852,9 @@ function validateFinalFit(ir, profile, tokens) {
5834
5852
  }
5835
5853
  }
5836
5854
 
5855
+ // src/version.ts
5856
+ var LIBRARY_VERSION = "2.0.0-alpha.82";
5857
+
5837
5858
  // src/pricing-brain.ts
5838
5859
  function isPricingRow(x) {
5839
5860
  if (!x || typeof x !== "object") return false;
@@ -6407,6 +6428,12 @@ function buildAdvisoryRow(outcomeId, a) {
6407
6428
  outcome_id: outcomeId,
6408
6429
  code: a.code,
6409
6430
  level: a.level,
6431
+ // alpha.81 (tt-intel s118, migration 053) — the emitting library version.
6432
+ // A corrected rule cannot rewrite firings that are already open, so a
6433
+ // consumer reading a stale suggestion had no way to tell it predated the
6434
+ // fix. tt-intel spent two hours on exactly that. NULL on pre-053 rows
6435
+ // reads as UNKNOWN; from here every firing self-identifies.
6436
+ rule_version: LIBRARY_VERSION,
6410
6437
  message: a.message,
6411
6438
  recommendation_type: a.recommendationType ?? null,
6412
6439
  suggestion: a.suggestion ?? null,
@@ -6623,13 +6650,16 @@ var FAILED = /* @__PURE__ */ Symbol("parse-failed");
6623
6650
 
6624
6651
  // src/ir.ts
6625
6652
  function mutationId(m) {
6626
- return typeof m === "string" ? m : m.id;
6653
+ if (m == null) return void 0;
6654
+ if (typeof m === "string") return m;
6655
+ return typeof m.id === "string" ? m.id : void 0;
6627
6656
  }
6628
6657
  function hasMutation(list, idOrPrefix) {
6629
6658
  if (!Array.isArray(list)) return false;
6630
6659
  const prefix = idOrPrefix.endsWith("*") ? idOrPrefix.slice(0, -1) : void 0;
6631
6660
  return list.some((m) => {
6632
6661
  const id = mutationId(m);
6662
+ if (id === void 0) return false;
6633
6663
  return prefix !== void 0 ? id.startsWith(prefix) : id === idOrPrefix;
6634
6664
  });
6635
6665
  }
@@ -9382,11 +9412,19 @@ function createBrainForwardRoutes(config) {
9382
9412
  return { handle, segments: KNOWN_SEGMENTS };
9383
9413
  }
9384
9414
 
9385
- // src/version.ts
9386
- var LIBRARY_VERSION = "2.0.0-alpha.80";
9387
-
9388
9415
  // src/key-health.ts
9389
9416
  var JSON_HEADERS2 = { "Content-Type": "application/json" };
9417
+ var KEY_FINGERPRINT_DOMAIN = "kgauto-key-fingerprint-v1:";
9418
+ var KEY_FINGERPRINT_LENGTH = 12;
9419
+ async function keyFingerprint(key) {
9420
+ const trimmed = key?.trim();
9421
+ if (!trimmed) return void 0;
9422
+ const subtle = globalThis.crypto?.subtle;
9423
+ if (!subtle) return void 0;
9424
+ const bytes = new TextEncoder().encode(KEY_FINGERPRINT_DOMAIN + trimmed);
9425
+ const digest = await subtle.digest("SHA-256", bytes);
9426
+ return [...new Uint8Array(digest)].map((b) => b.toString(16).padStart(2, "0")).join("").slice(0, KEY_FINGERPRINT_LENGTH);
9427
+ }
9390
9428
  function jsonResponse2(status, body) {
9391
9429
  return new Response(JSON.stringify(body), { status, headers: JSON_HEADERS2 });
9392
9430
  }
@@ -9488,11 +9526,13 @@ function createKeyHealthRoute(config) {
9488
9526
  detail: "key_absent"
9489
9527
  };
9490
9528
  }
9529
+ const fingerprint = await keyFingerprint(key);
9491
9530
  const base = {
9492
9531
  provider: spec.provider,
9493
9532
  env: envName,
9494
9533
  present: true,
9495
- valid: null
9534
+ valid: null,
9535
+ ...fingerprint ? { key_fingerprint: fingerprint } : {}
9496
9536
  };
9497
9537
  const { url, headers } = spec.buildRequest(key);
9498
9538
  const started = Date.now();
@@ -10440,6 +10480,8 @@ function compile2(ir, opts) {
10440
10480
  FamilyResolutionError,
10441
10481
  INTENT_ARCHETYPES,
10442
10482
  JUDGE_RUBRICS,
10483
+ KEY_FINGERPRINT_DOMAIN,
10484
+ KEY_FINGERPRINT_LENGTH,
10443
10485
  LATENCY_TIER_MS,
10444
10486
  LIBRARY_VERSION,
10445
10487
  MEASURED_FAILURE_CFG,
@@ -10488,6 +10530,7 @@ function compile2(ir, opts) {
10488
10530
  deriveFamilyFromModelId,
10489
10531
  deriveOwnership,
10490
10532
  estimateChainCostUsd,
10533
+ estimateModelCostUsd,
10491
10534
  execute,
10492
10535
  findBetterFit,
10493
10536
  flushBrainDeadLetter,
@@ -10524,6 +10567,7 @@ function compile2(ir, opts) {
10524
10567
  isPromotionsBrainActive,
10525
10568
  isProviderReachable,
10526
10569
  judgeMeasuredFailure,
10570
+ keyFingerprint,
10527
10571
  latencyTierOf,
10528
10572
  learningKey,
10529
10573
  loadAliasesFromBrain,
package/dist/index.mjs CHANGED
@@ -14,9 +14,12 @@ import {
14
14
  resolveOutputMode
15
15
  } from "./chunk-BVEXV5KC.mjs";
16
16
  import {
17
+ KEY_FINGERPRINT_DOMAIN,
18
+ KEY_FINGERPRINT_LENGTH,
17
19
  LIBRARY_VERSION,
18
- createKeyHealthRoute
19
- } from "./chunk-CIBHU67M.mjs";
20
+ createKeyHealthRoute,
21
+ keyFingerprint
22
+ } from "./chunk-L246YOV7.mjs";
20
23
  import {
21
24
  ABSOLUTE_FLOOR,
22
25
  ARCHETYPE_FLOOR_DEFAULT,
@@ -29,6 +32,7 @@ import {
29
32
  createBrainQueryCache,
30
33
  ensureCrossProviderTail,
31
34
  estimateChainCostUsd,
35
+ estimateModelCostUsd,
32
36
  getAllStarterChains,
33
37
  getAllStarterChainsWithGrounding,
34
38
  getArchetypePerfScore,
@@ -50,7 +54,7 @@ import {
50
54
  loadChainsFromBrain,
51
55
  readBrainReadEnv,
52
56
  resolveProviderKey
53
- } from "./chunk-PMTT4H5W.mjs";
57
+ } from "./chunk-XPD4I3Q5.mjs";
54
58
  import {
55
59
  ALIASES,
56
60
  LATENCY_TIER_MS,
@@ -2502,6 +2506,20 @@ function detectSingleModelArray(ir, policy) {
2502
2506
  }
2503
2507
  ];
2504
2508
  }
2509
+ function suppressedRecommendationReason(ir, archetype, altProfile) {
2510
+ if (getMeasuredFailureVerdict({ appId: ir.appId, archetype, model: altProfile.id })?.gated === true) {
2511
+ return "measured-failure-gate";
2512
+ }
2513
+ if (ir.constraints?.structuredOutput && effectiveConventions(altProfile).some(
2514
+ (c) => c.archetype === archetype && c.structuredOutputHint === "avoid"
2515
+ )) {
2516
+ return "schema-weakness-convention";
2517
+ }
2518
+ if (getRecentRollback({ appId: ir.appId, archetype, model: altProfile.id }) !== void 0) {
2519
+ return "recent-rollback";
2520
+ }
2521
+ return void 0;
2522
+ }
2505
2523
  function openPostureRemedyClause(archetype, recommended, resolveProfile) {
2506
2524
  const openChain = getDefaultFallbackChain({ archetype, posture: "open" });
2507
2525
  const openPrimaryId = openChain[0];
@@ -2539,25 +2557,7 @@ function detectCostMismatchedArchetype(ir, profile, phase2) {
2539
2557
  if (altScore.score < QUALITY_FLOOR_FOR_RECOMMENDATION) continue;
2540
2558
  if (altScore.score < chosenScore.score) continue;
2541
2559
  if (altProfile.costInputPer1m >= profile.costInputPer1m) continue;
2542
- if (getMeasuredFailureVerdict({
2543
- appId: ir.appId,
2544
- archetype,
2545
- model: altProfile.id
2546
- })?.gated === true) {
2547
- continue;
2548
- }
2549
- if (ir.constraints?.structuredOutput && effectiveConventions(altProfile).some(
2550
- (c) => c.archetype === archetype && c.structuredOutputHint === "avoid"
2551
- )) {
2552
- continue;
2553
- }
2554
- if (getRecentRollback({
2555
- appId: ir.appId,
2556
- archetype,
2557
- model: altProfile.id
2558
- }) !== void 0) {
2559
- continue;
2560
- }
2560
+ if (suppressedRecommendationReason(ir, archetype, altProfile)) continue;
2561
2561
  if (!bestAlt || altScore.score > bestAlt.score.score || altScore.score === bestAlt.score.score && altProfile.costInputPer1m < bestAlt.profile.costInputPer1m) {
2562
2562
  bestAlt = { id: altId, profile: altProfile, score: altScore };
2563
2563
  }
@@ -2615,6 +2615,7 @@ function detectTierDown(ir, profile, phase2) {
2615
2615
  if (altScore.score < QUALITY_FLOOR_FOR_RECOMMENDATION) continue;
2616
2616
  if (altScore.score < chosenScore.score) continue;
2617
2617
  if (altProfile.costInputPer1m > chosenCost * TIER_DOWN_COST_RATIO) continue;
2618
+ if (suppressedRecommendationReason(ir, archetype, altProfile)) continue;
2618
2619
  if (!bestAlt || altProfile.costInputPer1m < bestAlt.profile.costInputPer1m || altProfile.costInputPer1m === bestAlt.profile.costInputPer1m && altScore.score > bestAlt.score.score) {
2619
2620
  bestAlt = { id: altId, profile: altProfile, score: altScore };
2620
2621
  }
@@ -2661,7 +2662,18 @@ function detectArchetypePerfFloorBreach(ir, profile) {
2661
2662
  // library pick" endorsement could land on a materially pricier
2662
2663
  // primary. The floor recommendation stands; the axis is now named,
2663
2664
  // and the cost-ordered variant is offered alongside it.
2664
- suggestion: `Swap to a model whose archetypePerf for ${ir.intent.archetype} clears the floor. Use \`getModelCompatibility(candidateId, { archetype: '${ir.intent.archetype}' })\` to vet candidates, or \`getDefaultFallbackChain({ archetype: '${ir.intent.archetype}', posture: 'open' })\` for a library-picked chain that respects the floor by construction \u2014 note that chain is ordered by archetype performance, NOT cost, so it may select a pricier primary than you run today. Add \`optimizeFor: 'cost'\` for a chain that clears the same floor cheapest-first.`,
2665
+ //
2666
+ // alpha.82 (cc-Cairn 2026-07-29, follow-on 1): the suggestion read as
2667
+ // advice about the ARCHETYPE when it is a fact about ONE CALL. Model
2668
+ // selection is input-size dependent, so a rule that fires on the
2669
+ // small-payload tail of a path whose typical case clears the floor
2670
+ // reads as "your primary is wrong" when the accurate statement is
2671
+ // "this call landed here." Ground truth for the wording: tt-intel's
2672
+ // open critical is `gemini-2.5-flash-lite` (ask, 5/10) selected at
2673
+ // ~2.1K tokens_in, while `claude-opus-5` served the same archetype at
2674
+ // ~22K the same day — cc read the evidence set as self-contradictory
2675
+ // precisely because the text did not say which call it described.
2676
+ suggestion: `This fired for \`${profile.id}\`, the model selected for THIS call \u2014 selection is input-size dependent, so other calls on \`${ir.intent.archetype}\` may pick a different model that clears the floor. Swap to a model whose archetypePerf for ${ir.intent.archetype} clears the floor. Use \`getModelCompatibility(candidateId, { archetype: '${ir.intent.archetype}' })\` to vet candidates, or \`getDefaultFallbackChain({ archetype: '${ir.intent.archetype}', posture: 'open' })\` for a library-picked chain that respects the floor by construction \u2014 note that chain is ordered by archetype performance, NOT cost, so it may select a pricier primary than you run today. Add \`optimizeFor: 'cost'\` for a chain that clears the same floor cheapest-first. To stop this model being selected at all, pass \`policy.blockedModels: ['${profile.id}']\`.`,
2665
2677
  recommendationType: "model-swap",
2666
2678
  docsUrl: "https://github.com/stue/command-center/blob/main/interfaces/kgauto.md#best-practice-advisories"
2667
2679
  }
@@ -3733,6 +3745,12 @@ function buildAdvisoryRow(outcomeId, a) {
3733
3745
  outcome_id: outcomeId,
3734
3746
  code: a.code,
3735
3747
  level: a.level,
3748
+ // alpha.81 (tt-intel s118, migration 053) — the emitting library version.
3749
+ // A corrected rule cannot rewrite firings that are already open, so a
3750
+ // consumer reading a stale suggestion had no way to tell it predated the
3751
+ // fix. tt-intel spent two hours on exactly that. NULL on pre-053 rows
3752
+ // reads as UNKNOWN; from here every firing self-identifies.
3753
+ rule_version: LIBRARY_VERSION,
3736
3754
  message: a.message,
3737
3755
  recommendation_type: a.recommendationType ?? null,
3738
3756
  suggestion: a.suggestion ?? null,
@@ -3949,13 +3967,16 @@ var FAILED = /* @__PURE__ */ Symbol("parse-failed");
3949
3967
 
3950
3968
  // src/ir.ts
3951
3969
  function mutationId(m) {
3952
- return typeof m === "string" ? m : m.id;
3970
+ if (m == null) return void 0;
3971
+ if (typeof m === "string") return m;
3972
+ return typeof m.id === "string" ? m.id : void 0;
3953
3973
  }
3954
3974
  function hasMutation(list, idOrPrefix) {
3955
3975
  if (!Array.isArray(list)) return false;
3956
3976
  const prefix = idOrPrefix.endsWith("*") ? idOrPrefix.slice(0, -1) : void 0;
3957
3977
  return list.some((m) => {
3958
3978
  const id = mutationId(m);
3979
+ if (id === void 0) return false;
3959
3980
  return prefix !== void 0 ? id.startsWith(prefix) : id === idOrPrefix;
3960
3981
  });
3961
3982
  }
@@ -7099,6 +7120,8 @@ export {
7099
7120
  FamilyResolutionError,
7100
7121
  INTENT_ARCHETYPES,
7101
7122
  JUDGE_RUBRICS,
7123
+ KEY_FINGERPRINT_DOMAIN,
7124
+ KEY_FINGERPRINT_LENGTH,
7102
7125
  LATENCY_TIER_MS,
7103
7126
  LIBRARY_VERSION,
7104
7127
  MEASURED_FAILURE_CFG,
@@ -7147,6 +7170,7 @@ export {
7147
7170
  deriveFamilyFromModelId,
7148
7171
  deriveOwnership,
7149
7172
  estimateChainCostUsd,
7173
+ estimateModelCostUsd,
7150
7174
  execute,
7151
7175
  findBetterFit,
7152
7176
  flushBrainDeadLetter,
@@ -7183,6 +7207,7 @@ export {
7183
7207
  isPromotionsBrainActive,
7184
7208
  isProviderReachable,
7185
7209
  judgeMeasuredFailure,
7210
+ keyFingerprint,
7186
7211
  latencyTierOf,
7187
7212
  learningKey,
7188
7213
  loadAliasesFromBrain,
@@ -454,7 +454,7 @@ type MutationApplied = {
454
454
  * type can change without breaking a live consumer, so the fix is an
455
455
  * accessor that is correct on both.
456
456
  */
457
- declare function mutationId(m: string | MutationApplied): string;
457
+ declare function mutationId(m: string | MutationApplied | null | undefined): string | undefined;
458
458
  /**
459
459
  * alpha.78 — does any mutation in the list match `idOrPrefix` (exact id, or
460
460
  * prefix when it ends with `*`)? Works on both `mutationsApplied` element
@@ -454,7 +454,7 @@ type MutationApplied = {
454
454
  * type can change without breaking a live consumer, so the fix is an
455
455
  * accessor that is correct on both.
456
456
  */
457
- declare function mutationId(m: string | MutationApplied): string;
457
+ declare function mutationId(m: string | MutationApplied | null | undefined): string | undefined;
458
458
  /**
459
459
  * alpha.78 — does any mutation in the list match `idOrPrefix` (exact id, or
460
460
  * prefix when it ends with `*`)? Works on both `mutationsApplied` element
@@ -86,6 +86,34 @@ interface KeyHealthConfig {
86
86
  /** Per-provider probe timeout in ms. Default 3000. */
87
87
  timeoutMs?: number;
88
88
  }
89
+ /**
90
+ * alpha.81 — a NON-REVERSIBLE identity for a provider key, so the fleet can
91
+ * answer "are two consumers on the same key?" without any consumer, or the
92
+ * brain, ever holding a key value.
93
+ *
94
+ * Origin: PB's `one-shared-provider-key-across-four-consumers` (s83). All four
95
+ * provider keys are Vercel team-level Shared Env Vars across four projects, so
96
+ * one exhausted account is a four-consumer outage that each consumer diagnoses
97
+ * locally as its own, and provider spend is a single undifferentiated number.
98
+ * PB's observation that only kgauto can see this is correct: the library runs
99
+ * inside every consumer's process and resolves the key there; no consumer can
100
+ * compare its key against a peer's.
101
+ *
102
+ * **Why truncation is the safety property, not an optimization.** The digest is
103
+ * cut to 12 hex chars (48 bits) — enough that a collision between the handful
104
+ * of keys in one portfolio is negligible, far too little to verify a guessed
105
+ * key against. Provider keys are high-entropy random strings, so even the full
106
+ * digest would not be brute-forceable; the truncation means the stored value is
107
+ * not a verification oracle even if the key space were later reduced. The
108
+ * domain-separation prefix keeps these digests useless against any hash
109
+ * computed for another purpose.
110
+ *
111
+ * Never log, return, or persist the key itself. This function is the only
112
+ * sanctioned way a key becomes a value that may leave the process.
113
+ */
114
+ declare const KEY_FINGERPRINT_DOMAIN = "kgauto-key-fingerprint-v1:";
115
+ declare const KEY_FINGERPRINT_LENGTH = 12;
116
+ declare function keyFingerprint(key: string): Promise<string | undefined>;
89
117
  interface KeyHealthResult {
90
118
  provider: KeyHealthProvider;
91
119
  /** Canonical env var name probed (the resolved one for Google). */
@@ -102,6 +130,13 @@ interface KeyHealthResult {
102
130
  balance_usd?: number;
103
131
  /** Failure class when valid is null with a probe attempted (e.g. 'timeout', 'http_500') or 'key_absent'. */
104
132
  detail?: string;
133
+ /**
134
+ * alpha.81 — truncated, domain-separated SHA-256 of the resolved key. NEVER
135
+ * the key. Identical values across two consumers mean they resolve the same
136
+ * credential; that is the only question it can answer. Absent when the key is
137
+ * absent or the runtime exposes no WebCrypto. See {@link keyFingerprint}.
138
+ */
139
+ key_fingerprint?: string;
105
140
  }
106
141
  interface KeyHealthResponseBody {
107
142
  app_id: string;
@@ -128,4 +163,4 @@ interface KeyHealthRoute {
128
163
  */
129
164
  declare function createKeyHealthRoute(config: KeyHealthConfig): KeyHealthRoute;
130
165
 
131
- export { type KeyHealthConfig, type KeyHealthProvider, type KeyHealthResponseBody, type KeyHealthResult, type KeyHealthRoute, createKeyHealthRoute };
166
+ export { KEY_FINGERPRINT_DOMAIN, KEY_FINGERPRINT_LENGTH, type KeyHealthConfig, type KeyHealthProvider, type KeyHealthResponseBody, type KeyHealthResult, type KeyHealthRoute, createKeyHealthRoute, keyFingerprint };
@@ -86,6 +86,34 @@ interface KeyHealthConfig {
86
86
  /** Per-provider probe timeout in ms. Default 3000. */
87
87
  timeoutMs?: number;
88
88
  }
89
+ /**
90
+ * alpha.81 — a NON-REVERSIBLE identity for a provider key, so the fleet can
91
+ * answer "are two consumers on the same key?" without any consumer, or the
92
+ * brain, ever holding a key value.
93
+ *
94
+ * Origin: PB's `one-shared-provider-key-across-four-consumers` (s83). All four
95
+ * provider keys are Vercel team-level Shared Env Vars across four projects, so
96
+ * one exhausted account is a four-consumer outage that each consumer diagnoses
97
+ * locally as its own, and provider spend is a single undifferentiated number.
98
+ * PB's observation that only kgauto can see this is correct: the library runs
99
+ * inside every consumer's process and resolves the key there; no consumer can
100
+ * compare its key against a peer's.
101
+ *
102
+ * **Why truncation is the safety property, not an optimization.** The digest is
103
+ * cut to 12 hex chars (48 bits) — enough that a collision between the handful
104
+ * of keys in one portfolio is negligible, far too little to verify a guessed
105
+ * key against. Provider keys are high-entropy random strings, so even the full
106
+ * digest would not be brute-forceable; the truncation means the stored value is
107
+ * not a verification oracle even if the key space were later reduced. The
108
+ * domain-separation prefix keeps these digests useless against any hash
109
+ * computed for another purpose.
110
+ *
111
+ * Never log, return, or persist the key itself. This function is the only
112
+ * sanctioned way a key becomes a value that may leave the process.
113
+ */
114
+ declare const KEY_FINGERPRINT_DOMAIN = "kgauto-key-fingerprint-v1:";
115
+ declare const KEY_FINGERPRINT_LENGTH = 12;
116
+ declare function keyFingerprint(key: string): Promise<string | undefined>;
89
117
  interface KeyHealthResult {
90
118
  provider: KeyHealthProvider;
91
119
  /** Canonical env var name probed (the resolved one for Google). */
@@ -102,6 +130,13 @@ interface KeyHealthResult {
102
130
  balance_usd?: number;
103
131
  /** Failure class when valid is null with a probe attempted (e.g. 'timeout', 'http_500') or 'key_absent'. */
104
132
  detail?: string;
133
+ /**
134
+ * alpha.81 — truncated, domain-separated SHA-256 of the resolved key. NEVER
135
+ * the key. Identical values across two consumers mean they resolve the same
136
+ * credential; that is the only question it can answer. Absent when the key is
137
+ * absent or the runtime exposes no WebCrypto. See {@link keyFingerprint}.
138
+ */
139
+ key_fingerprint?: string;
105
140
  }
106
141
  interface KeyHealthResponseBody {
107
142
  app_id: string;
@@ -128,4 +163,4 @@ interface KeyHealthRoute {
128
163
  */
129
164
  declare function createKeyHealthRoute(config: KeyHealthConfig): KeyHealthRoute;
130
165
 
131
- export { type KeyHealthConfig, type KeyHealthProvider, type KeyHealthResponseBody, type KeyHealthResult, type KeyHealthRoute, createKeyHealthRoute };
166
+ export { KEY_FINGERPRINT_DOMAIN, KEY_FINGERPRINT_LENGTH, type KeyHealthConfig, type KeyHealthProvider, type KeyHealthResponseBody, type KeyHealthResult, type KeyHealthRoute, createKeyHealthRoute, keyFingerprint };
@@ -20,15 +20,29 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // src/key-health.ts
21
21
  var key_health_exports = {};
22
22
  __export(key_health_exports, {
23
- createKeyHealthRoute: () => createKeyHealthRoute
23
+ KEY_FINGERPRINT_DOMAIN: () => KEY_FINGERPRINT_DOMAIN,
24
+ KEY_FINGERPRINT_LENGTH: () => KEY_FINGERPRINT_LENGTH,
25
+ createKeyHealthRoute: () => createKeyHealthRoute,
26
+ keyFingerprint: () => keyFingerprint
24
27
  });
25
28
  module.exports = __toCommonJS(key_health_exports);
26
29
 
27
30
  // src/version.ts
28
- var LIBRARY_VERSION = "2.0.0-alpha.80";
31
+ var LIBRARY_VERSION = "2.0.0-alpha.82";
29
32
 
30
33
  // src/key-health.ts
31
34
  var JSON_HEADERS = { "Content-Type": "application/json" };
35
+ var KEY_FINGERPRINT_DOMAIN = "kgauto-key-fingerprint-v1:";
36
+ var KEY_FINGERPRINT_LENGTH = 12;
37
+ async function keyFingerprint(key) {
38
+ const trimmed = key?.trim();
39
+ if (!trimmed) return void 0;
40
+ const subtle = globalThis.crypto?.subtle;
41
+ if (!subtle) return void 0;
42
+ const bytes = new TextEncoder().encode(KEY_FINGERPRINT_DOMAIN + trimmed);
43
+ const digest = await subtle.digest("SHA-256", bytes);
44
+ return [...new Uint8Array(digest)].map((b) => b.toString(16).padStart(2, "0")).join("").slice(0, KEY_FINGERPRINT_LENGTH);
45
+ }
32
46
  function jsonResponse(status, body) {
33
47
  return new Response(JSON.stringify(body), { status, headers: JSON_HEADERS });
34
48
  }
@@ -130,11 +144,13 @@ function createKeyHealthRoute(config) {
130
144
  detail: "key_absent"
131
145
  };
132
146
  }
147
+ const fingerprint = await keyFingerprint(key);
133
148
  const base = {
134
149
  provider: spec.provider,
135
150
  env: envName,
136
151
  present: true,
137
- valid: null
152
+ valid: null,
153
+ ...fingerprint ? { key_fingerprint: fingerprint } : {}
138
154
  };
139
155
  const { url, headers } = spec.buildRequest(key);
140
156
  const started = Date.now();
@@ -224,5 +240,8 @@ function createKeyHealthRoute(config) {
224
240
  }
225
241
  // Annotate the CommonJS export names for ESM import in node:
226
242
  0 && (module.exports = {
227
- createKeyHealthRoute
243
+ KEY_FINGERPRINT_DOMAIN,
244
+ KEY_FINGERPRINT_LENGTH,
245
+ createKeyHealthRoute,
246
+ keyFingerprint
228
247
  });
@@ -1,6 +1,12 @@
1
1
  import {
2
- createKeyHealthRoute
3
- } from "./chunk-CIBHU67M.mjs";
2
+ KEY_FINGERPRINT_DOMAIN,
3
+ KEY_FINGERPRINT_LENGTH,
4
+ createKeyHealthRoute,
5
+ keyFingerprint
6
+ } from "./chunk-L246YOV7.mjs";
4
7
  export {
5
- createKeyHealthRoute
8
+ KEY_FINGERPRINT_DOMAIN,
9
+ KEY_FINGERPRINT_LENGTH,
10
+ createKeyHealthRoute,
11
+ keyFingerprint
6
12
  };
@@ -1,4 +1,4 @@
1
- import { k as Provider } from './ir-BFwWhj2s.mjs';
1
+ import { k as Provider } from './ir-D4S9R816.mjs';
2
2
  import { IntentArchetypeName } from './dialect.mjs';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { k as Provider } from './ir-DZKS1tI7.js';
1
+ import { k as Provider } from './ir-Cx9hJj0B.js';
2
2
  import { IntentArchetypeName } from './dialect.js';
3
3
 
4
4
  /**
@@ -1,4 +1,4 @@
1
- import { s as MutationApplied, B as BestPracticeAdvisory, F as FallbackReason, m as CallAttempt } from './ir-DZKS1tI7.js';
1
+ import { s as MutationApplied, B as BestPracticeAdvisory, F as FallbackReason, m as CallAttempt } from './ir-Cx9hJj0B.js';
2
2
 
3
3
  /**
4
4
  * Glass-Box observability types (alpha.17).
@@ -1,4 +1,4 @@
1
- import { s as MutationApplied, B as BestPracticeAdvisory, F as FallbackReason, m as CallAttempt } from './ir-BFwWhj2s.mjs';
1
+ import { s as MutationApplied, B as BestPracticeAdvisory, F as FallbackReason, m as CallAttempt } from './ir-D4S9R816.mjs';
2
2
 
3
3
  /**
4
4
  * Glass-Box observability types (alpha.17).
@@ -1,4 +1,4 @@
1
- import { i as Adapter, F as FallbackReason, x as SectionKind } from './ir-DZKS1tI7.js';
1
+ import { i as Adapter, F as FallbackReason, x as SectionKind } from './ir-Cx9hJj0B.js';
2
2
 
3
3
  /**
4
4
  * Wire contract for the Glass-Box Chrome extension's brain-poll endpoint.
@@ -1,4 +1,4 @@
1
- import { i as Adapter, F as FallbackReason, x as SectionKind } from './ir-BFwWhj2s.mjs';
1
+ import { i as Adapter, F as FallbackReason, x as SectionKind } from './ir-D4S9R816.mjs';
2
2
 
3
3
  /**
4
4
  * Wire contract for the Glass-Box Chrome extension's brain-poll endpoint.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@warmdrift/kgauto-compiler",
3
- "version": "2.0.0-alpha.80",
3
+ "version": "2.0.0-alpha.82",
4
4
  "description": "Prompt compiler with executable provider knowledge for multi-model AI apps: normalized multi-provider transport with fallback chains, compile-time cliff guards, a curated model registry, and a telemetry flight recorder. Swap models without rewriting prompts.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -60,6 +60,7 @@
60
60
  "build": "tsup src/index.ts src/dialect.ts src/profiles.ts src/brain-proxy.ts src/key-health.ts src/glassbox/index.ts src/glassbox-routes/index.ts src/glassbox-routes/format.ts src/glassbox-routes/react/index.ts --format cjs,esm --dts --clean --external react --external react-dom",
61
61
  "test": "vitest run",
62
62
  "test:watch": "vitest",
63
+ "test:stress": "node scripts/stress-test.mjs",
63
64
  "typecheck": "tsc --noEmit",
64
65
  "prepublishOnly": "npm run typecheck && npm run test && npm run build"
65
66
  },