@warmdrift/kgauto-compiler 2.0.0-alpha.28 → 2.0.0-alpha.29

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/README.md CHANGED
@@ -89,6 +89,48 @@ await record({
89
89
  });
90
90
  ```
91
91
 
92
+ ## Structured advisories API (alpha.29+)
93
+
94
+ kgauto's compile-time advisories (`caching-off-on-claude`, `tool-bloat`,
95
+ `archetype-perf-floor-breach`, etc.) used to vanish after the consumer read
96
+ the compile result. alpha.29 ships a structured query + resolution surface
97
+ so Admin UIs can render "what's open right now?" without log-scraping.
98
+
99
+ ```ts
100
+ import {
101
+ getActionableAdvisories,
102
+ markAdvisoryResolved,
103
+ } from '@warmdrift/kgauto-compiler';
104
+
105
+ // Query open advisories for this app
106
+ const open = await getActionableAdvisories({
107
+ appId: 'playbacksam',
108
+ brainEndpoint: process.env.KGAUTO_BRAIN_ENDPOINT!,
109
+ brainJwt: process.env.KGAUTO_BRAIN_JWT!,
110
+ brainAnonKey: process.env.KGAUTO_BRAIN_ANON_KEY!,
111
+ });
112
+
113
+ for (const a of open) {
114
+ console.log(`[${a.severity}] ${a.rule} — ${a.observationCount} firings since ${a.openedAt}`);
115
+ console.log(` ${a.message}`);
116
+ if (a.suggestedFix?.docsLink) console.log(` ↳ ${a.suggestedFix.docsLink}`);
117
+ }
118
+
119
+ // After the operator fixes the issue, mark it resolved:
120
+ const r = await markAdvisoryResolved({
121
+ id: open[0].id,
122
+ resolutionNote: 'wired historyCachePolicy in compile() — PR #99',
123
+ brainEndpoint: process.env.KGAUTO_BRAIN_ENDPOINT!,
124
+ brainJwt: process.env.KGAUTO_BRAIN_JWT!,
125
+ brainAnonKey: process.env.KGAUTO_BRAIN_ANON_KEY!,
126
+ });
127
+ if (!r.ok) console.error(r.reason);
128
+ ```
129
+
130
+ The view enforces server-side auto-resolution: advisories with no firing
131
+ in the last 14 days flip to `status='resolved'` automatically; the next
132
+ firing reopens the rule with a fresh stable `id`.
133
+
92
134
  ## Architecture
93
135
 
94
136
  ```
@@ -1,6 +1,6 @@
1
- import { G as GlassboxEvent } from '../types-sDZQzPM6.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-sDZQzPM6.mjs';
3
- import '../ir-MXCJA8L7.mjs';
1
+ import { G as GlassboxEvent } from '../types-BjrIFPGe.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-BjrIFPGe.mjs';
3
+ import '../ir-De2AQtlr.mjs';
4
4
  import '../dialect.mjs';
5
5
 
6
6
  /**
@@ -1,6 +1,6 @@
1
- import { G as GlassboxEvent } from '../types-CiZ9HLIU.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-CiZ9HLIU.js';
3
- import '../ir-5W0efxt9.js';
1
+ import { G as GlassboxEvent } from '../types-D_JAhCv4.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-D_JAhCv4.js';
3
+ import '../ir-BIAT9gJk.js';
4
4
  import '../dialect.js';
5
5
 
6
6
  /**
@@ -1,5 +1,5 @@
1
- import { G as GlassboxEvent } from '../types-sDZQzPM6.mjs';
2
- import { h as Adapter } from '../ir-MXCJA8L7.mjs';
1
+ import { G as GlassboxEvent } from '../types-BjrIFPGe.mjs';
2
+ import { h as Adapter, u as SectionKind } from '../ir-De2AQtlr.mjs';
3
3
  import '../dialect.mjs';
4
4
 
5
5
  /**
@@ -86,6 +86,28 @@ interface TraceHealth {
86
86
  cacheStatus: 'green' | 'yellow' | 'red' | 'na';
87
87
  fallbackStatus: 'green' | 'red';
88
88
  }
89
+ /**
90
+ * alpha.29+ — wire-boundary representation of a translator section-rewrite.
91
+ *
92
+ * Distinct from the package-internal `SectionRewrite` type in `ir.ts`: this
93
+ * shape drops `originalText` + `transformedText` because those may carry
94
+ * consumer PII. The renderer shows the `rule` + `summary` only. Full text
95
+ * stays on `compile_outcomes.section_rewrites_applied` (Supabase row), gated
96
+ * by RLS for brain-side cross-app learning.
97
+ */
98
+ interface TraceSectionRewrite {
99
+ /** Stable id of the rewritten section. */
100
+ sectionId: string;
101
+ /** Section-kind discriminator that triggered the rewrite. */
102
+ kind: SectionKind;
103
+ /** Stable rule identifier (e.g. `'sequential-tool-cliff-below-floor'`). */
104
+ rule: string;
105
+ /**
106
+ * Plain-English one-liner describing what fired and why. Renderer surfaces
107
+ * this on the Coaching card; no internal jargon ("L-040", "below floor").
108
+ */
109
+ summary: string;
110
+ }
89
111
  interface TraceDetail extends TraceSummary {
90
112
  mutationsApplied: string[];
91
113
  advisories: AdvisoryRecord[];
@@ -116,6 +138,13 @@ interface TraceDetail extends TraceSummary {
116
138
  counterfactuals?: TraceCounterfactual[];
117
139
  /** Undefined when 7d volume < 5/day (insufficient data). */
118
140
  projectedDailyCostUsd?: number;
141
+ /**
142
+ * alpha.29+ — translator activity for this trace. Empty array (not
143
+ * undefined) when no rewrites fired or pre-019 row. Surfaced in the
144
+ * Glass-Box Coaching card as synthetic info-level rows. PII-safe by
145
+ * construction: only sectionId + kind + rule + summary cross the wire.
146
+ */
147
+ sectionRewritesApplied: TraceSectionRewrite[];
119
148
  health: TraceHealth;
120
149
  }
121
150
 
@@ -1,5 +1,5 @@
1
- import { G as GlassboxEvent } from '../types-CiZ9HLIU.js';
2
- import { h as Adapter } from '../ir-5W0efxt9.js';
1
+ import { G as GlassboxEvent } from '../types-D_JAhCv4.js';
2
+ import { h as Adapter, u as SectionKind } from '../ir-BIAT9gJk.js';
3
3
  import '../dialect.js';
4
4
 
5
5
  /**
@@ -86,6 +86,28 @@ interface TraceHealth {
86
86
  cacheStatus: 'green' | 'yellow' | 'red' | 'na';
87
87
  fallbackStatus: 'green' | 'red';
88
88
  }
89
+ /**
90
+ * alpha.29+ — wire-boundary representation of a translator section-rewrite.
91
+ *
92
+ * Distinct from the package-internal `SectionRewrite` type in `ir.ts`: this
93
+ * shape drops `originalText` + `transformedText` because those may carry
94
+ * consumer PII. The renderer shows the `rule` + `summary` only. Full text
95
+ * stays on `compile_outcomes.section_rewrites_applied` (Supabase row), gated
96
+ * by RLS for brain-side cross-app learning.
97
+ */
98
+ interface TraceSectionRewrite {
99
+ /** Stable id of the rewritten section. */
100
+ sectionId: string;
101
+ /** Section-kind discriminator that triggered the rewrite. */
102
+ kind: SectionKind;
103
+ /** Stable rule identifier (e.g. `'sequential-tool-cliff-below-floor'`). */
104
+ rule: string;
105
+ /**
106
+ * Plain-English one-liner describing what fired and why. Renderer surfaces
107
+ * this on the Coaching card; no internal jargon ("L-040", "below floor").
108
+ */
109
+ summary: string;
110
+ }
89
111
  interface TraceDetail extends TraceSummary {
90
112
  mutationsApplied: string[];
91
113
  advisories: AdvisoryRecord[];
@@ -116,6 +138,13 @@ interface TraceDetail extends TraceSummary {
116
138
  counterfactuals?: TraceCounterfactual[];
117
139
  /** Undefined when 7d volume < 5/day (insufficient data). */
118
140
  projectedDailyCostUsd?: number;
141
+ /**
142
+ * alpha.29+ — translator activity for this trace. Empty array (not
143
+ * undefined) when no rewrites fired or pre-019 row. Surfaced in the
144
+ * Glass-Box Coaching card as synthetic info-level rows. PII-safe by
145
+ * construction: only sectionId + kind + rule + summary cross the wire.
146
+ */
147
+ sectionRewritesApplied: TraceSectionRewrite[];
119
148
  health: TraceHealth;
120
149
  }
121
150
 
@@ -1803,6 +1803,38 @@ function rowToAdvisory(raw) {
1803
1803
  if (adapter) out.suggestedAdaptation = adapter;
1804
1804
  return out;
1805
1805
  }
1806
+ var SECTION_KINDS = /* @__PURE__ */ new Set([
1807
+ "role_intro",
1808
+ "tool_call_contract",
1809
+ "narration_contract",
1810
+ "user_turn",
1811
+ "reference",
1812
+ "arbitrary"
1813
+ ]);
1814
+ function summarizeSectionRewrite(kind, rule) {
1815
+ if (kind === "tool_call_contract" && rule === "sequential-tool-cliff-below-floor") {
1816
+ return "Sequential tool pattern applied (model cliff cleared at compile time).";
1817
+ }
1818
+ return `Translator applied rule "${rule}" to ${kind} section.`;
1819
+ }
1820
+ function rowToSectionRewrite(raw) {
1821
+ if (!raw || typeof raw !== "object") return void 0;
1822
+ const r = raw;
1823
+ const sectionId = r.sectionId ?? r.section_id;
1824
+ if (typeof sectionId !== "string" || sectionId.length === 0) return void 0;
1825
+ const kind = r.kind;
1826
+ if (typeof kind !== "string" || !SECTION_KINDS.has(kind)) {
1827
+ return void 0;
1828
+ }
1829
+ const rule = r.rule;
1830
+ if (typeof rule !== "string" || rule.length === 0) return void 0;
1831
+ return {
1832
+ sectionId,
1833
+ kind,
1834
+ rule,
1835
+ summary: summarizeSectionRewrite(kind, rule)
1836
+ };
1837
+ }
1806
1838
  function toAdapter(raw) {
1807
1839
  if (!raw || typeof raw !== "object") return void 0;
1808
1840
  const a = raw;
@@ -1872,6 +1904,12 @@ function rowToDetail(row) {
1872
1904
  fellOverFrom,
1873
1905
  target: summary.target
1874
1906
  });
1907
+ const sectionRewritesRaw = Array.isArray(row.section_rewrites_applied) ? row.section_rewrites_applied : [];
1908
+ const sectionRewritesApplied = [];
1909
+ for (const e of sectionRewritesRaw) {
1910
+ const rw = rowToSectionRewrite(e);
1911
+ if (rw) sectionRewritesApplied.push(rw);
1912
+ }
1875
1913
  const detail = {
1876
1914
  ...summary,
1877
1915
  mutationsApplied: asStringArray(row.mutations_applied),
@@ -1891,6 +1929,7 @@ function rowToDetail(row) {
1891
1929
  inputCacheHitRatio,
1892
1930
  fellOverFrom,
1893
1931
  fallbackReason,
1932
+ sectionRewritesApplied,
1894
1933
  health
1895
1934
  };
1896
1935
  return detail;
@@ -283,6 +283,38 @@ function rowToAdvisory(raw) {
283
283
  if (adapter) out.suggestedAdaptation = adapter;
284
284
  return out;
285
285
  }
286
+ var SECTION_KINDS = /* @__PURE__ */ new Set([
287
+ "role_intro",
288
+ "tool_call_contract",
289
+ "narration_contract",
290
+ "user_turn",
291
+ "reference",
292
+ "arbitrary"
293
+ ]);
294
+ function summarizeSectionRewrite(kind, rule) {
295
+ if (kind === "tool_call_contract" && rule === "sequential-tool-cliff-below-floor") {
296
+ return "Sequential tool pattern applied (model cliff cleared at compile time).";
297
+ }
298
+ return `Translator applied rule "${rule}" to ${kind} section.`;
299
+ }
300
+ function rowToSectionRewrite(raw) {
301
+ if (!raw || typeof raw !== "object") return void 0;
302
+ const r = raw;
303
+ const sectionId = r.sectionId ?? r.section_id;
304
+ if (typeof sectionId !== "string" || sectionId.length === 0) return void 0;
305
+ const kind = r.kind;
306
+ if (typeof kind !== "string" || !SECTION_KINDS.has(kind)) {
307
+ return void 0;
308
+ }
309
+ const rule = r.rule;
310
+ if (typeof rule !== "string" || rule.length === 0) return void 0;
311
+ return {
312
+ sectionId,
313
+ kind,
314
+ rule,
315
+ summary: summarizeSectionRewrite(kind, rule)
316
+ };
317
+ }
286
318
  function toAdapter(raw) {
287
319
  if (!raw || typeof raw !== "object") return void 0;
288
320
  const a = raw;
@@ -352,6 +384,12 @@ function rowToDetail(row) {
352
384
  fellOverFrom,
353
385
  target: summary.target
354
386
  });
387
+ const sectionRewritesRaw = Array.isArray(row.section_rewrites_applied) ? row.section_rewrites_applied : [];
388
+ const sectionRewritesApplied = [];
389
+ for (const e of sectionRewritesRaw) {
390
+ const rw = rowToSectionRewrite(e);
391
+ if (rw) sectionRewritesApplied.push(rw);
392
+ }
355
393
  const detail = {
356
394
  ...summary,
357
395
  mutationsApplied: asStringArray(row.mutations_applied),
@@ -371,6 +409,7 @@ function rowToDetail(row) {
371
409
  inputCacheHitRatio,
372
410
  fellOverFrom,
373
411
  fallbackReason,
412
+ sectionRewritesApplied,
374
413
  health
375
414
  };
376
415
  return detail;
package/dist/index.d.mts CHANGED
@@ -1,5 +1,5 @@
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, R as RecordInput, e as RecordOutcomeInput, O as OutcomeResult, f as OracleScore, g as CompileResult, B as BestPracticeAdvisory, h as Adapter, i as PerAxisMetrics, j as Provider, k as ChainEntry, G as Grounding } from './ir-MXCJA8L7.mjs';
2
- export { l as CallAttempt, m as CallError, n as ChainWithGrounding, o as Constraints, F as FallbackReason, H as HistoryCachePolicy, I as IntentDeclaration, M as Message, p as MutationApplied, q as NormalizedTokens, r as OutcomeKind, s as PerAxisMetricsByModel, t as PromptSection, T as ToolCall, u as ToolDefinition } from './ir-MXCJA8L7.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 SectionRewrite, R as RecordInput, e as RecordOutcomeInput, O as OutcomeResult, f as OracleScore, g as CompileResult, B as BestPracticeAdvisory, h as Adapter, i as PerAxisMetrics, j as Provider, k as ChainEntry, G as Grounding } from './ir-De2AQtlr.mjs';
2
+ export { l as CallAttempt, m as CallError, n as ChainWithGrounding, o as Constraints, F as FallbackReason, H as HistoryCachePolicy, I as IntentDeclaration, M as Message, p as MutationApplied, q as NormalizedTokens, r as OutcomeKind, s as PerAxisMetricsByModel, t as PromptSection, u as SectionKind, T as ToolCall, v as ToolDefinition } from './ir-De2AQtlr.mjs';
3
3
  import { ModelProfile } from './profiles.mjs';
4
4
  export { ALIASES, CacheStrategy, CliffRule, LoweringSpec, RecoveryRule, StructuredOutputCapability, SystemPromptMode, allProfiles, getProfile, profilesByProvider, tryGetProfile } from './profiles.mjs';
5
5
  import { IntentArchetypeName } from './dialect.mjs';
@@ -94,16 +94,6 @@ declare function execute(request: CompiledRequest, opts?: ExecuteOptions): Promi
94
94
  */
95
95
  declare function call(ir: PromptIR, opts?: CallOptions): Promise<CallResult>;
96
96
 
97
- /**
98
- * Brain client — fire-and-forget telemetry to the central kgauto Supabase.
99
- *
100
- * The brain is the centralized learning store. Apps POST outcomes here;
101
- * mutations flow back through a separate pull (in v2.1).
102
- *
103
- * Design: never blocks the caller. Failures are silent (logged via optional
104
- * onError hook). Uses fetch() — works in Node 18+, Edge runtimes, and browsers.
105
- */
106
-
107
97
  /**
108
98
  * alpha.11 — opt-in nested config for brain-query mode (chains / archetype
109
99
  * perf / pricing / models registry). Enabled by default when endpoint is
@@ -212,6 +202,13 @@ interface OutcomePayload {
212
202
  system_prompt_chars?: number;
213
203
  fell_over_from?: string;
214
204
  fallback_reason?: 'rate_limit' | 'provider_auth_failed' | 'provider_error' | 'cliff' | 'cost_cap' | 'contract_violation';
205
+ /**
206
+ * Per-call SectionRewrite[] captured at compile time. Omitted (sent as
207
+ * undefined → stored NULL) when no rewrites fired. Powers cross-app
208
+ * learning aggregates ("rule X fired N times on (app, model, archetype),
209
+ * downstream outcome quality lifted by M points").
210
+ */
211
+ section_rewrites_applied?: SectionRewrite[] | null;
215
212
  }
216
213
  /**
217
214
  * alpha.20 Entry 4: record a quality outcome for a previously-compiled call.
@@ -349,6 +346,17 @@ type AdvisorContext = Pick<CompileResult, 'target' | 'provider' | 'tokensIn' | '
349
346
  interface RunAdvisorPhase2Context {
350
347
  fallbackChain: string[];
351
348
  profileResolver?: (id: string) => ModelProfile | undefined;
349
+ /**
350
+ * alpha.29 — translator rewrites that fired this compile. When a rewrite
351
+ * cleared the cliff (e.g. `tool_call_contract` → sequential-tool preamble
352
+ * + `parallelToolCalls: false`), the matching cliff advisor
353
+ * (`archetype-perf-floor-breach`) MUST suppress for the same call. Without
354
+ * suppression both fire — the advisory contradicts the rewrite ("cliff is
355
+ * unaddressed" vs "we just addressed it").
356
+ *
357
+ * Empty array / undefined → no suppression (alpha.28 behavior preserved).
358
+ */
359
+ sectionRewritesApplied?: SectionRewrite[];
352
360
  }
353
361
  /**
354
362
  * Run all phased rules and return collected advisories. Order is fixed so
@@ -365,6 +373,277 @@ interface RunAdvisorPhase2Context {
365
373
  */
366
374
  declare function runAdvisor(ir: PromptIR, result: AdvisorContext, profile: ModelProfile, policy?: CompilePolicy, phase2?: RunAdvisorPhase2Context): BestPracticeAdvisory[];
367
375
 
376
+ /**
377
+ * Translator primitive — alpha.29.
378
+ *
379
+ * Pure function. Walks `IR.sections`, matches each section's `kind` against
380
+ * the model + archetype + profile, and applies a model-aware rewrite when
381
+ * a rule fires. Returns the rewritten IR + the list of rewrites for
382
+ * `CompileResult.sectionRewritesApplied` and brain persistence.
383
+ *
384
+ * This is the s37 translator-framing eureka in code: kgauto graduates from
385
+ * "gate" (alpha.28's cliff advisor: "consumer must accept adapter") to
386
+ * "translator" (alpha.29: "consumer declared the section kind, kgauto
387
+ * applies the adapter at compile time without consumer-side branching").
388
+ *
389
+ * alpha.29 ships ONE rule:
390
+ *
391
+ * tool_call_contract + profile.archetypePerf[archetype] < ARCHETYPE_FLOOR_DEFAULT
392
+ * → prepend sequential-tool-pattern guidance
393
+ * → emit wireOverrides: { parallelToolCalls: false }
394
+ *
395
+ * alpha.30+ will extend the rule table to `narration_contract`, `role_intro`,
396
+ * etc. Each new rule lands here as an explicit branch.
397
+ *
398
+ * **Interaction with the cliff advisor (alpha.28):** when this translator
399
+ * fires for a `tool_call_contract` section, the advisor's
400
+ * `archetype-perf-floor-breach` rule MUST suppress for the same call — the
401
+ * cliff was structurally cleared by the rewrite, not unaddressed. The
402
+ * suppression check lives in `advisor.ts` and consults the
403
+ * `CompileResult.sectionRewritesApplied` list.
404
+ *
405
+ * Design contract:
406
+ * command-center/advisory/kgauto/2026-05-21_alpha-29-translator-and-advisories-api.md
407
+ */
408
+
409
+ /**
410
+ * Re-export of `ARCHETYPE_FLOOR_DEFAULT` as the canonical "translator fires
411
+ * below this score" threshold. Same constant as the cliff advisor — the
412
+ * single threshold is shared (alpha.28's "below this, advisor warns"; alpha.29's
413
+ * "below this, translator AUTO-APPLIES the adapter").
414
+ */
415
+ declare const TRANSLATOR_FLOOR = 6;
416
+ /**
417
+ * Stable identifier of the alpha.29 sequential-tool rule. Surfaces on
418
+ * `SectionRewrite.rule` and in brain aggregates. Future rules extend this
419
+ * list; the brain learns per-rule effectiveness over time.
420
+ */
421
+ declare const RULE_SEQUENTIAL_TOOL_CLIFF = "sequential-tool-cliff-below-floor";
422
+ interface ApplySectionRewritesArgs {
423
+ ir: PromptIR;
424
+ profile: ModelProfile;
425
+ archetype: IntentArchetypeName;
426
+ }
427
+ interface ApplySectionRewritesResult {
428
+ /**
429
+ * IR with section.text fields possibly rewritten. When no rewrites fired,
430
+ * this is identical to the input IR (referentially distinct array but
431
+ * same section payloads).
432
+ */
433
+ rewrittenIR: PromptIR;
434
+ /**
435
+ * One entry per section the translator rewrote. Empty array when no
436
+ * rules fired. Order matches the corresponding section in
437
+ * `rewrittenIR.sections`.
438
+ */
439
+ rewrites: SectionRewrite[];
440
+ }
441
+ /**
442
+ * Pure function. Apply model-aware section rewrites to the IR at compile time.
443
+ *
444
+ * Discipline:
445
+ * - Never mutates the input IR; returns a new IR with new sections array.
446
+ * - Sections without a `kind` (or `kind === 'arbitrary'`) pass through
447
+ * unchanged.
448
+ * - Empty `sections` array → returns `{ rewrittenIR: ir, rewrites: [] }`.
449
+ * - Missing `profile.archetypePerf` → no rewrite (defensive — treat the
450
+ * model as un-classified rather than below-floor).
451
+ * - Sections of the same `kind` are processed in array order; the rule
452
+ * fires once per matching section (today every tool_call_contract
453
+ * section gets the same prepend — multiple sections of the same kind
454
+ * ARE supported but is an unusual consumer shape).
455
+ *
456
+ * @example
457
+ * ```ts
458
+ * import { applySectionRewrites } from '@warmdrift/kgauto-compiler';
459
+ * import { getProfile } from '@warmdrift/kgauto-compiler';
460
+ *
461
+ * const { rewrittenIR, rewrites } = applySectionRewrites({
462
+ * ir,
463
+ * profile: getProfile('deepseek-v4-pro'),
464
+ * archetype: 'hunt',
465
+ * });
466
+ * if (rewrites.length > 0) console.log('translator fired:', rewrites);
467
+ * ```
468
+ */
469
+ declare function applySectionRewrites(args: ApplySectionRewritesArgs): ApplySectionRewritesResult;
470
+
471
+ /**
472
+ * advisories-api — structured advisories API (alpha.29 Workstream B).
473
+ *
474
+ * Closes the L-117 family bottleneck: kgauto's `result.advisories[]` (the
475
+ * compile-time warnings about caching-off, tool-bloat, archetype-perf-floor
476
+ * breaches, etc.) used to disappear after the consumer read the compile
477
+ * result. The s34 caching-off advisory pattern is the canonical failure: an
478
+ * advisory fired 100+ times in 24h on `generate::sonnet` at 99.4% empty
479
+ * rate, and nobody knew because there was no structured channel to surface
480
+ * "what's open right now?"
481
+ *
482
+ * Migration 020 ships the substrate: `compile_outcome_advisories` gains
483
+ * lifecycle columns (`resolved_at`, `resolution_source`, `resolution_note`)
484
+ * and the `actionable_advisories_v` view rolls per-firing rows into
485
+ * per-(app_id, code) tuples with deterministic stable ids + server-side
486
+ * auto-resolution.
487
+ *
488
+ * Public surface:
489
+ * getActionableAdvisories({ appId, severity?, status?, brainEndpoint, brainJwt, brainAnonKey, fetch? })
490
+ * → Promise<ActionableAdvisory[]>
491
+ *
492
+ * markAdvisoryResolved({ id, resolutionNote?, brainEndpoint, brainJwt, brainAnonKey, fetch? })
493
+ * → Promise<{ ok: true } | { ok: false; reason: string }>
494
+ *
495
+ * Both functions are pure I/O — no module-level state. The fetch wiring
496
+ * mirrors `createProxyHandler` in `glassbox-routes/proxy.ts`: scoped JWT in
497
+ * `Authorization: Bearer`, `apikey` header carries the anon key.
498
+ *
499
+ * The auto-resolution rule is enforced server-side in `actionable_advisories_v`:
500
+ * • Latest firing > 14 days ago → status='resolved' (auto-pruned)
501
+ * • All firings have resolved_at set → status='resolved' (consumer-marked)
502
+ * • Otherwise → status='open'
503
+ *
504
+ * `markAdvisoryResolved` is the consumer override: "I fixed it; the next
505
+ * firing will reopen the rule, but until then it stays resolved."
506
+ */
507
+
508
+ /**
509
+ * Severity of an advisory. Maps to the `level` column on
510
+ * `compile_outcome_advisories` (info | warn | critical).
511
+ */
512
+ type AdvisorySeverity = 'info' | 'warn' | 'critical';
513
+ /**
514
+ * Status of an advisory rollup.
515
+ *
516
+ * - `open` — at least one unresolved firing in the last 14 days
517
+ * - `resolved` — either auto-pruned (no firings >14d) or consumer-marked
518
+ * - `snoozed` — reserved for alpha.30+ (snooze-until-date); type-accepted
519
+ * today but the view will never emit this value
520
+ */
521
+ type AdvisoryStatus = 'open' | 'snoozed' | 'resolved';
522
+ /**
523
+ * Source of resolution when status='resolved'.
524
+ *
525
+ * - `auto` — server-side rule auto-pruned (>14d since last firing)
526
+ * - `consumer-marked` — consumer called `markAdvisoryResolved`
527
+ * - `declined` — reserved (alpha.30+: consumer marked the suggestion
528
+ * inapplicable; the advisor will still fire but UIs can hide it)
529
+ */
530
+ type AdvisoryResolutionSource = 'auto' | 'consumer-marked' | 'declined';
531
+ /**
532
+ * Suggested-fix metadata. `null` when the advisor has no actionable fix
533
+ * (info-level rules can be observational). When set, the consumer's
534
+ * Admin UI can render a one-click apply (alpha.30+) or surface the
535
+ * before/after diff inline.
536
+ */
537
+ interface AdvisorySuggestedFix {
538
+ type: 'config-change' | 'one-liner' | 'env-var' | 'manual';
539
+ /** File:line hint if kgauto can infer (reserved — alpha.30+). */
540
+ siteHint?: string;
541
+ before?: string;
542
+ after?: string;
543
+ docsLink?: string;
544
+ }
545
+ /**
546
+ * Per-(app_id, code) advisory rollup. The `id` is stable across polls
547
+ * until the rule auto-resolves and re-opens (a new firing after the 14d
548
+ * boundary advances `opened_at` → new id). Treat id-changes as
549
+ * intentional "fresh re-open" signals.
550
+ *
551
+ * Wire-shape from `actionable_advisories_v`. The transformer maps the
552
+ * view's snake_case columns to camelCase. See `feedback_typed_boundary_transformers.md`
553
+ * (L-118) for the rationale.
554
+ */
555
+ interface ActionableAdvisory {
556
+ id: string;
557
+ rule: string;
558
+ severity: AdvisorySeverity;
559
+ openedAt: string;
560
+ lastObservedAt: string;
561
+ observationCount: number;
562
+ appliesTo: {
563
+ archetype?: IntentArchetypeName;
564
+ model?: string;
565
+ callSiteHint?: string;
566
+ };
567
+ message: string;
568
+ suggestedFix: AdvisorySuggestedFix | null;
569
+ /** Reserved — always `false` in alpha.29. alpha.30+ ships actual auto-apply. */
570
+ autoApplicable: boolean;
571
+ status: AdvisoryStatus;
572
+ resolvedAt?: string;
573
+ resolutionSource?: AdvisoryResolutionSource;
574
+ resolutionNote?: string;
575
+ }
576
+ /**
577
+ * Filter + transport for `getActionableAdvisories`. The brain JWT must
578
+ * carry an `app_id` claim matching `opts.appId` — RLS enforces tenant
579
+ * isolation on the underlying table, so a mismatch silently returns [].
580
+ */
581
+ interface GetActionableAdvisoriesOptions {
582
+ appId: string;
583
+ /** Severity filter; if omitted, all severities are returned. */
584
+ severity?: AdvisorySeverity;
585
+ /** Status filter; defaults to 'open'. Pass 'all' for the full set. */
586
+ status?: 'open' | 'snoozed' | 'resolved' | 'all';
587
+ brainEndpoint: string;
588
+ brainJwt: string;
589
+ brainAnonKey: string;
590
+ fetch?: typeof fetch;
591
+ }
592
+ interface MarkAdvisoryResolvedOptions {
593
+ /** Stable id from a prior `getActionableAdvisories` call. */
594
+ id: string;
595
+ resolutionNote?: string;
596
+ brainEndpoint: string;
597
+ brainJwt: string;
598
+ brainAnonKey: string;
599
+ fetch?: typeof fetch;
600
+ }
601
+ /**
602
+ * Query the open advisory set for an app. Pulls from
603
+ * `actionable_advisories_v` (per-(app_id, code) rollup with stable ids
604
+ * + server-side auto-resolution).
605
+ *
606
+ * Default behavior (no status filter): returns only `status='open'`.
607
+ * Pass `status: 'all'` to see resolved + open together — useful for
608
+ * Admin UIs that show "recently fixed" badges.
609
+ *
610
+ * Fetch failures bubble out as thrown Errors. (`markAdvisoryResolved`
611
+ * uses the ok/reason envelope; this read path throws to match
612
+ * existing kgauto query semantics where the consumer can decide to
613
+ * retry or render an error state.)
614
+ */
615
+ declare function getActionableAdvisories(opts: GetActionableAdvisoriesOptions): Promise<ActionableAdvisory[]>;
616
+ /**
617
+ * Mark an advisory as consumer-resolved.
618
+ *
619
+ * Lookup strategy:
620
+ * 1. Query `actionable_advisories_v?id=eq.<id>` to find the (app_id, code)
621
+ * tuple for this advisory.
622
+ * 2. PATCH the latest unresolved firing in `compile_outcome_advisories`
623
+ * matching that tuple via the underlying outcome's app_id.
624
+ *
625
+ * The (app_id, code) lookup is necessary because `compile_outcome_advisories`
626
+ * has no `app_id` column — it inherits scope via the FK to compile_outcomes.
627
+ * PostgREST cannot PATCH with a JOIN predicate, so the markAdvisoryResolved
628
+ * path is a two-step round-trip. The cost is one extra GET per resolve call;
629
+ * acceptable because marks are low-frequency operator actions, not per-call
630
+ * hot path.
631
+ *
632
+ * Idempotent re-marks: if the advisory is already resolved (no unresolved
633
+ * firings match), the PATCH affects zero rows and the call still returns
634
+ * `ok: true`. The function returns `ok: false` only on transport / auth /
635
+ * lookup failures.
636
+ *
637
+ * Returns ok/reason envelope (vs throwing) because consumer Admin UIs
638
+ * typically want to render the failure inline rather than crash.
639
+ */
640
+ declare function markAdvisoryResolved(opts: MarkAdvisoryResolvedOptions): Promise<{
641
+ ok: true;
642
+ } | {
643
+ ok: false;
644
+ reason: string;
645
+ }>;
646
+
368
647
  /**
369
648
  * Archetype-cliff compatibility — alpha.28 (tt-intel-Cairn ratified).
370
649
  *
@@ -1124,4 +1403,4 @@ declare const loadAliasesFromBrain: () => Record<string, string>;
1124
1403
  */
1125
1404
  declare function compile(ir: PromptIR, opts?: CompileOptions): CompileResult;
1126
1405
 
1127
- export { ABSOLUTE_FLOOR, ARCHETYPE_FLOOR_DEFAULT, Adapter, ApiKeys, type AppOracle, type ArchetypePerfMap, type ArchetypePerfNMap, type ArchetypePerfScoreResult, BestPracticeAdvisory, type BrainConfig, type BrainQueryConfig, CallOptions, CallResult, ChainEntry, type CompatibilityIntent, type CompileOptions, CompilePolicy, CompileResult, CompiledRequest, type ExecuteErr, type ExecuteOk, type ExecuteOptions, type ExecuteResult, type FallbackPosture, type GetDefaultFallbackChainOpts, type GetPerAxisMetricsOpts, Grounding, IntentArchetypeName, type LLMJudgeOptions, MEASURED_GROUNDING_MIN_N, type ModelBrainRow, type ModelCompatibility, ModelProfile, NormalizedResponse, type OracleContext, OracleScore, type OutcomePayload, OutcomeResult, PROVIDER_ENV_KEYS, PerAxisMetrics, type PricingRow, type ProfileToRowOptions, PromptIR, Provider, ProviderOverrides, type ProviderReachability, type ReachabilityOpts, RecordInput, RecordOutcomeInput, type RunAdvisorPhase2Context, type SupportedProvider, buildLLMJudge, call, clearBrain, compile, configureBrain, countTokens, execute, getAllStarterChains, getAllStarterChainsWithGrounding, getArchetypePerfScore, getDefaultFallbackChain, getDefaultFallbackChainWithGrounding, getModelCompatibility, getPerAxisMetrics, getReachabilityDiagnostic, getSequentialStarterChain, getSequentialStarterChainWithGrounding, getStarterChain, getStarterChainWithGrounding, isBrainQueryActiveFor, isModelReachable, isProviderReachable, loadAliasesFromBrain, loadArchetypePerfFromBrain, loadArchetypePerfNFromBrain, loadChainsFromBrain, loadModelsFromBrain, loadPricingFromBrain, profileToRow, record, recordOutcome, resetTokenizer, resolvePricingAt, resolveProviderKey, runAdvisor, setTokenizer };
1406
+ export { ABSOLUTE_FLOOR, ARCHETYPE_FLOOR_DEFAULT, type ActionableAdvisory, Adapter, type AdvisoryResolutionSource, type AdvisorySeverity, type AdvisoryStatus, type AdvisorySuggestedFix, ApiKeys, type AppOracle, type ApplySectionRewritesArgs, type ApplySectionRewritesResult, type ArchetypePerfMap, type ArchetypePerfNMap, type ArchetypePerfScoreResult, BestPracticeAdvisory, type BrainConfig, type BrainQueryConfig, CallOptions, CallResult, ChainEntry, type CompatibilityIntent, type CompileOptions, CompilePolicy, CompileResult, CompiledRequest, type ExecuteErr, type ExecuteOk, type ExecuteOptions, type ExecuteResult, type FallbackPosture, type GetActionableAdvisoriesOptions, type GetDefaultFallbackChainOpts, type GetPerAxisMetricsOpts, Grounding, IntentArchetypeName, type LLMJudgeOptions, MEASURED_GROUNDING_MIN_N, type MarkAdvisoryResolvedOptions, type ModelBrainRow, type ModelCompatibility, ModelProfile, NormalizedResponse, type OracleContext, OracleScore, type OutcomePayload, OutcomeResult, PROVIDER_ENV_KEYS, PerAxisMetrics, type PricingRow, type ProfileToRowOptions, PromptIR, Provider, ProviderOverrides, type ProviderReachability, RULE_SEQUENTIAL_TOOL_CLIFF, type ReachabilityOpts, RecordInput, RecordOutcomeInput, type RunAdvisorPhase2Context, SectionRewrite, type SupportedProvider, TRANSLATOR_FLOOR, applySectionRewrites, buildLLMJudge, call, clearBrain, compile, configureBrain, countTokens, execute, getActionableAdvisories, getAllStarterChains, getAllStarterChainsWithGrounding, getArchetypePerfScore, getDefaultFallbackChain, getDefaultFallbackChainWithGrounding, getModelCompatibility, getPerAxisMetrics, getReachabilityDiagnostic, getSequentialStarterChain, getSequentialStarterChainWithGrounding, getStarterChain, getStarterChainWithGrounding, isBrainQueryActiveFor, isModelReachable, isProviderReachable, loadAliasesFromBrain, loadArchetypePerfFromBrain, loadArchetypePerfNFromBrain, loadChainsFromBrain, loadModelsFromBrain, loadPricingFromBrain, markAdvisoryResolved, profileToRow, record, recordOutcome, resetTokenizer, resolvePricingAt, resolveProviderKey, runAdvisor, setTokenizer };