@warmdrift/kgauto-compiler 2.0.0-alpha.30 → 2.0.0-alpha.31

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.
@@ -1815,6 +1815,12 @@ function summarizeSectionRewrite(kind, rule) {
1815
1815
  if (kind === "tool_call_contract" && rule === "sequential-tool-cliff-below-floor") {
1816
1816
  return "Sequential tool pattern applied (model cliff cleared at compile time).";
1817
1817
  }
1818
+ if (kind === "narration_contract" && rule === "narration-drift-anthropic") {
1819
+ return "Narration tightened for Anthropic dialect (terse-log shape preserved).";
1820
+ }
1821
+ if (kind === "narration_contract" && rule === "narration-thinking-leak-deepseek") {
1822
+ return "Thinking-block suppression applied (DeepSeek V4 internal reasoning kept off-wire).";
1823
+ }
1818
1824
  return `Translator applied rule "${rule}" to ${kind} section.`;
1819
1825
  }
1820
1826
  function rowToSectionRewrite(raw) {
@@ -295,6 +295,12 @@ function summarizeSectionRewrite(kind, rule) {
295
295
  if (kind === "tool_call_contract" && rule === "sequential-tool-cliff-below-floor") {
296
296
  return "Sequential tool pattern applied (model cliff cleared at compile time).";
297
297
  }
298
+ if (kind === "narration_contract" && rule === "narration-drift-anthropic") {
299
+ return "Narration tightened for Anthropic dialect (terse-log shape preserved).";
300
+ }
301
+ if (kind === "narration_contract" && rule === "narration-thinking-leak-deepseek") {
302
+ return "Thinking-block suppression applied (DeepSeek V4 internal reasoning kept off-wire).";
303
+ }
298
304
  return `Translator applied rule "${rule}" to ${kind} section.`;
299
305
  }
300
306
  function rowToSectionRewrite(raw) {
package/dist/index.d.mts CHANGED
@@ -374,26 +374,42 @@ interface RunAdvisorPhase2Context {
374
374
  declare function runAdvisor(ir: PromptIR, result: AdvisorContext, profile: ModelProfile, policy?: CompilePolicy, phase2?: RunAdvisorPhase2Context): BestPracticeAdvisory[];
375
375
 
376
376
  /**
377
- * Translator primitive — alpha.29.
377
+ * Translator primitive — alpha.31.
378
378
  *
379
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.
380
+ * a per-rule dispatch table keyed on (kind, profile, archetype), and applies
381
+ * a model-aware rewrite when a rule fires. Returns the rewritten IR + the
382
+ * list of rewrites for `CompileResult.sectionRewritesApplied` and brain
383
+ * persistence.
383
384
  *
384
385
  * This is the s37 translator-framing eureka in code: kgauto graduates from
385
386
  * "gate" (alpha.28's cliff advisor: "consumer must accept adapter") to
386
387
  * "translator" (alpha.29: "consumer declared the section kind, kgauto
387
388
  * applies the adapter at compile time without consumer-side branching").
388
389
  *
389
- * alpha.29 ships ONE rule:
390
+ * Rules shipped:
390
391
  *
391
- * tool_call_contract + profile.archetypePerf[archetype] < ARCHETYPE_FLOOR_DEFAULT
392
+ * alpha.29 — tool_call_contract + archetypePerf[archetype] < TRANSLATOR_FLOOR
392
393
  * → prepend sequential-tool-pattern guidance
393
394
  * → emit wireOverrides: { parallelToolCalls: false }
395
+ * → rule_id: 'sequential-tool-cliff-below-floor'
394
396
  *
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
+ * alpha.31 narration_contract + profile.provider === 'anthropic'
398
+ * prepend terse-log narration guidance
399
+ * → no wireOverrides
400
+ * → rule_id: 'narration-drift-anthropic'
401
+ *
402
+ * alpha.31 — narration_contract + profile.provider === 'deepseek'
403
+ * → prepend <thinking>-suppression guidance
404
+ * → no wireOverrides
405
+ * → rule_id: 'narration-thinking-leak-deepseek'
406
+ *
407
+ * Per-rule walk (alpha.31 refactor): the alpha.30 short-circuit
408
+ * `if (!cliffFires) return passthrough` was correct when only the
409
+ * cliff-gated tool_call_contract rule existed; alpha.31's narration rules
410
+ * fire on every call regardless of cliff (narration drift is steady-state,
411
+ * not a cliff condition). Each section now consults the dispatch table
412
+ * independently — first-match wins per (section.kind, profile, archetype).
397
413
  *
398
414
  * **Interaction with the cliff advisor (alpha.28):** when this translator
399
415
  * fires for a `tool_call_contract` section, the advisor's
@@ -402,8 +418,9 @@ declare function runAdvisor(ir: PromptIR, result: AdvisorContext, profile: Model
402
418
  * suppression check lives in `advisor.ts` and consults the
403
419
  * `CompileResult.sectionRewritesApplied` list.
404
420
  *
405
- * Design contract:
421
+ * Design contracts:
406
422
  * command-center/advisory/kgauto/2026-05-21_alpha-29-translator-and-advisories-api.md
423
+ * command-center/advisory/kgauto/2026-05-22_alpha-31-narration-contract.md
407
424
  */
408
425
 
409
426
  /**
@@ -415,8 +432,9 @@ declare function runAdvisor(ir: PromptIR, result: AdvisorContext, profile: Model
415
432
  declare const TRANSLATOR_FLOOR = 6;
416
433
  /**
417
434
  * 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.
435
+ * `SectionRewrite.rule` and in brain aggregates. The brain treats this
436
+ * identifier together with the preamble string as the rule's wire
437
+ * fingerprint — both stay byte-stable across releases.
420
438
  */
421
439
  declare const RULE_SEQUENTIAL_TOOL_CLIFF = "sequential-tool-cliff-below-floor";
422
440
  interface ApplySectionRewritesArgs {
@@ -442,16 +460,14 @@ interface ApplySectionRewritesResult {
442
460
  * Pure function. Apply model-aware section rewrites to the IR at compile time.
443
461
  *
444
462
  * Discipline:
445
- * - Never mutates the input IR; returns a new IR with new sections array.
463
+ * - Never mutates the input IR; returns a new IR with new sections array
464
+ * when at least one rewrite fired; otherwise returns the input IR by
465
+ * reference (referential identity preserved on no-op).
446
466
  * - Sections without a `kind` (or `kind === 'arbitrary'`) pass through
447
467
  * unchanged.
448
468
  * - 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).
469
+ * - Sections of the same `kind` are processed in array order; first-match
470
+ * wins per section. (Today every rule is a single-match rule.)
455
471
  *
456
472
  * @example
457
473
  * ```ts
package/dist/index.d.ts CHANGED
@@ -374,26 +374,42 @@ interface RunAdvisorPhase2Context {
374
374
  declare function runAdvisor(ir: PromptIR, result: AdvisorContext, profile: ModelProfile, policy?: CompilePolicy, phase2?: RunAdvisorPhase2Context): BestPracticeAdvisory[];
375
375
 
376
376
  /**
377
- * Translator primitive — alpha.29.
377
+ * Translator primitive — alpha.31.
378
378
  *
379
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.
380
+ * a per-rule dispatch table keyed on (kind, profile, archetype), and applies
381
+ * a model-aware rewrite when a rule fires. Returns the rewritten IR + the
382
+ * list of rewrites for `CompileResult.sectionRewritesApplied` and brain
383
+ * persistence.
383
384
  *
384
385
  * This is the s37 translator-framing eureka in code: kgauto graduates from
385
386
  * "gate" (alpha.28's cliff advisor: "consumer must accept adapter") to
386
387
  * "translator" (alpha.29: "consumer declared the section kind, kgauto
387
388
  * applies the adapter at compile time without consumer-side branching").
388
389
  *
389
- * alpha.29 ships ONE rule:
390
+ * Rules shipped:
390
391
  *
391
- * tool_call_contract + profile.archetypePerf[archetype] < ARCHETYPE_FLOOR_DEFAULT
392
+ * alpha.29 — tool_call_contract + archetypePerf[archetype] < TRANSLATOR_FLOOR
392
393
  * → prepend sequential-tool-pattern guidance
393
394
  * → emit wireOverrides: { parallelToolCalls: false }
395
+ * → rule_id: 'sequential-tool-cliff-below-floor'
394
396
  *
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
+ * alpha.31 narration_contract + profile.provider === 'anthropic'
398
+ * prepend terse-log narration guidance
399
+ * → no wireOverrides
400
+ * → rule_id: 'narration-drift-anthropic'
401
+ *
402
+ * alpha.31 — narration_contract + profile.provider === 'deepseek'
403
+ * → prepend <thinking>-suppression guidance
404
+ * → no wireOverrides
405
+ * → rule_id: 'narration-thinking-leak-deepseek'
406
+ *
407
+ * Per-rule walk (alpha.31 refactor): the alpha.30 short-circuit
408
+ * `if (!cliffFires) return passthrough` was correct when only the
409
+ * cliff-gated tool_call_contract rule existed; alpha.31's narration rules
410
+ * fire on every call regardless of cliff (narration drift is steady-state,
411
+ * not a cliff condition). Each section now consults the dispatch table
412
+ * independently — first-match wins per (section.kind, profile, archetype).
397
413
  *
398
414
  * **Interaction with the cliff advisor (alpha.28):** when this translator
399
415
  * fires for a `tool_call_contract` section, the advisor's
@@ -402,8 +418,9 @@ declare function runAdvisor(ir: PromptIR, result: AdvisorContext, profile: Model
402
418
  * suppression check lives in `advisor.ts` and consults the
403
419
  * `CompileResult.sectionRewritesApplied` list.
404
420
  *
405
- * Design contract:
421
+ * Design contracts:
406
422
  * command-center/advisory/kgauto/2026-05-21_alpha-29-translator-and-advisories-api.md
423
+ * command-center/advisory/kgauto/2026-05-22_alpha-31-narration-contract.md
407
424
  */
408
425
 
409
426
  /**
@@ -415,8 +432,9 @@ declare function runAdvisor(ir: PromptIR, result: AdvisorContext, profile: Model
415
432
  declare const TRANSLATOR_FLOOR = 6;
416
433
  /**
417
434
  * 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.
435
+ * `SectionRewrite.rule` and in brain aggregates. The brain treats this
436
+ * identifier together with the preamble string as the rule's wire
437
+ * fingerprint — both stay byte-stable across releases.
420
438
  */
421
439
  declare const RULE_SEQUENTIAL_TOOL_CLIFF = "sequential-tool-cliff-below-floor";
422
440
  interface ApplySectionRewritesArgs {
@@ -442,16 +460,14 @@ interface ApplySectionRewritesResult {
442
460
  * Pure function. Apply model-aware section rewrites to the IR at compile time.
443
461
  *
444
462
  * Discipline:
445
- * - Never mutates the input IR; returns a new IR with new sections array.
463
+ * - Never mutates the input IR; returns a new IR with new sections array
464
+ * when at least one rewrite fired; otherwise returns the input IR by
465
+ * reference (referential identity preserved on no-op).
446
466
  * - Sections without a `kind` (or `kind === 'arbitrary'`) pass through
447
467
  * unchanged.
448
468
  * - 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).
469
+ * - Sections of the same `kind` are processed in array order; first-match
470
+ * wins per section. (Today every rule is a single-match rule.)
455
471
  *
456
472
  * @example
457
473
  * ```ts
package/dist/index.js CHANGED
@@ -2630,34 +2630,62 @@ function detectArchetypePerfFloorBreach(ir, profile) {
2630
2630
  // src/translator.ts
2631
2631
  var TRANSLATOR_FLOOR = ARCHETYPE_FLOOR_DEFAULT;
2632
2632
  var RULE_SEQUENTIAL_TOOL_CLIFF = "sequential-tool-cliff-below-floor";
2633
+ var RULE_NARRATION_DRIFT_ANTHROPIC = "narration-drift-anthropic";
2634
+ var RULE_NARRATION_THINKING_LEAK_DEEPSEEK = "narration-thinking-leak-deepseek";
2633
2635
  var SEQUENTIAL_TOOL_PREAMBLE = "IMPORTANT: Use one tool call per response. Wait for the tool result before deciding the next tool. Do NOT batch tool calls in parallel.";
2636
+ var NARRATION_DRIFT_ANTHROPIC_PREAMBLE = "Output ONLY the requested content. Do not narrate your thought process. Each line \u2264 12 words.";
2637
+ var NARRATION_THINKING_LEAK_DEEPSEEK_PREAMBLE = "Reasoning is internal. Output ONLY the requested content; do not emit <thinking> blocks or internal monologue as user-facing text.";
2638
+ function matchRule(kind, profile, archetype) {
2639
+ if (kind === "tool_call_contract") {
2640
+ if (!profile.archetypePerf) return null;
2641
+ const archetypeScore = profile.archetypePerf[archetype];
2642
+ if (typeof archetypeScore !== "number" || archetypeScore >= TRANSLATOR_FLOOR) {
2643
+ return null;
2644
+ }
2645
+ return {
2646
+ id: RULE_SEQUENTIAL_TOOL_CLIFF,
2647
+ preamble: SEQUENTIAL_TOOL_PREAMBLE,
2648
+ wireOverrides: { parallelToolCalls: false }
2649
+ };
2650
+ }
2651
+ if (kind === "narration_contract") {
2652
+ if (profile.provider === "anthropic") {
2653
+ return {
2654
+ id: RULE_NARRATION_DRIFT_ANTHROPIC,
2655
+ preamble: NARRATION_DRIFT_ANTHROPIC_PREAMBLE
2656
+ };
2657
+ }
2658
+ if (profile.provider === "deepseek") {
2659
+ return {
2660
+ id: RULE_NARRATION_THINKING_LEAK_DEEPSEEK,
2661
+ preamble: NARRATION_THINKING_LEAK_DEEPSEEK_PREAMBLE
2662
+ };
2663
+ }
2664
+ return null;
2665
+ }
2666
+ return null;
2667
+ }
2634
2668
  function applySectionRewrites(args) {
2635
2669
  const { ir, profile, archetype } = args;
2636
2670
  if (!Array.isArray(ir.sections) || ir.sections.length === 0) {
2637
2671
  return { rewrittenIR: ir, rewrites: [] };
2638
2672
  }
2639
- if (!profile.archetypePerf) {
2640
- return { rewrittenIR: ir, rewrites: [] };
2641
- }
2642
- const archetypeScore = profile.archetypePerf[archetype];
2643
- const cliffFires = typeof archetypeScore === "number" && archetypeScore < TRANSLATOR_FLOOR;
2644
- if (!cliffFires) {
2645
- return { rewrittenIR: ir, rewrites: [] };
2646
- }
2647
2673
  const rewrites = [];
2648
2674
  const newSections = ir.sections.map((section) => {
2649
- if (section.kind !== "tool_call_contract") return section;
2675
+ if (!section.kind || section.kind === "arbitrary") return section;
2676
+ const rule = matchRule(section.kind, profile, archetype);
2677
+ if (!rule) return section;
2650
2678
  const originalText = section.text;
2651
- const transformedText = `${SEQUENTIAL_TOOL_PREAMBLE}
2679
+ const transformedText = `${rule.preamble}
2652
2680
 
2653
2681
  ${originalText}`;
2654
2682
  rewrites.push({
2655
2683
  sectionId: section.id,
2656
- kind: "tool_call_contract",
2657
- rule: RULE_SEQUENTIAL_TOOL_CLIFF,
2684
+ kind: section.kind,
2685
+ rule: rule.id,
2658
2686
  originalText,
2659
2687
  transformedText,
2660
- wireOverrides: { parallelToolCalls: false }
2688
+ ...rule.wireOverrides ? { wireOverrides: rule.wireOverrides } : {}
2661
2689
  });
2662
2690
  return { ...section, text: transformedText };
2663
2691
  });
package/dist/index.mjs CHANGED
@@ -1056,34 +1056,62 @@ function detectArchetypePerfFloorBreach(ir, profile) {
1056
1056
  // src/translator.ts
1057
1057
  var TRANSLATOR_FLOOR = ARCHETYPE_FLOOR_DEFAULT;
1058
1058
  var RULE_SEQUENTIAL_TOOL_CLIFF = "sequential-tool-cliff-below-floor";
1059
+ var RULE_NARRATION_DRIFT_ANTHROPIC = "narration-drift-anthropic";
1060
+ var RULE_NARRATION_THINKING_LEAK_DEEPSEEK = "narration-thinking-leak-deepseek";
1059
1061
  var SEQUENTIAL_TOOL_PREAMBLE = "IMPORTANT: Use one tool call per response. Wait for the tool result before deciding the next tool. Do NOT batch tool calls in parallel.";
1062
+ var NARRATION_DRIFT_ANTHROPIC_PREAMBLE = "Output ONLY the requested content. Do not narrate your thought process. Each line \u2264 12 words.";
1063
+ var NARRATION_THINKING_LEAK_DEEPSEEK_PREAMBLE = "Reasoning is internal. Output ONLY the requested content; do not emit <thinking> blocks or internal monologue as user-facing text.";
1064
+ function matchRule(kind, profile, archetype) {
1065
+ if (kind === "tool_call_contract") {
1066
+ if (!profile.archetypePerf) return null;
1067
+ const archetypeScore = profile.archetypePerf[archetype];
1068
+ if (typeof archetypeScore !== "number" || archetypeScore >= TRANSLATOR_FLOOR) {
1069
+ return null;
1070
+ }
1071
+ return {
1072
+ id: RULE_SEQUENTIAL_TOOL_CLIFF,
1073
+ preamble: SEQUENTIAL_TOOL_PREAMBLE,
1074
+ wireOverrides: { parallelToolCalls: false }
1075
+ };
1076
+ }
1077
+ if (kind === "narration_contract") {
1078
+ if (profile.provider === "anthropic") {
1079
+ return {
1080
+ id: RULE_NARRATION_DRIFT_ANTHROPIC,
1081
+ preamble: NARRATION_DRIFT_ANTHROPIC_PREAMBLE
1082
+ };
1083
+ }
1084
+ if (profile.provider === "deepseek") {
1085
+ return {
1086
+ id: RULE_NARRATION_THINKING_LEAK_DEEPSEEK,
1087
+ preamble: NARRATION_THINKING_LEAK_DEEPSEEK_PREAMBLE
1088
+ };
1089
+ }
1090
+ return null;
1091
+ }
1092
+ return null;
1093
+ }
1060
1094
  function applySectionRewrites(args) {
1061
1095
  const { ir, profile, archetype } = args;
1062
1096
  if (!Array.isArray(ir.sections) || ir.sections.length === 0) {
1063
1097
  return { rewrittenIR: ir, rewrites: [] };
1064
1098
  }
1065
- if (!profile.archetypePerf) {
1066
- return { rewrittenIR: ir, rewrites: [] };
1067
- }
1068
- const archetypeScore = profile.archetypePerf[archetype];
1069
- const cliffFires = typeof archetypeScore === "number" && archetypeScore < TRANSLATOR_FLOOR;
1070
- if (!cliffFires) {
1071
- return { rewrittenIR: ir, rewrites: [] };
1072
- }
1073
1099
  const rewrites = [];
1074
1100
  const newSections = ir.sections.map((section) => {
1075
- if (section.kind !== "tool_call_contract") return section;
1101
+ if (!section.kind || section.kind === "arbitrary") return section;
1102
+ const rule = matchRule(section.kind, profile, archetype);
1103
+ if (!rule) return section;
1076
1104
  const originalText = section.text;
1077
- const transformedText = `${SEQUENTIAL_TOOL_PREAMBLE}
1105
+ const transformedText = `${rule.preamble}
1078
1106
 
1079
1107
  ${originalText}`;
1080
1108
  rewrites.push({
1081
1109
  sectionId: section.id,
1082
- kind: "tool_call_contract",
1083
- rule: RULE_SEQUENTIAL_TOOL_CLIFF,
1110
+ kind: section.kind,
1111
+ rule: rule.id,
1084
1112
  originalText,
1085
1113
  transformedText,
1086
- wireOverrides: { parallelToolCalls: false }
1114
+ ...rule.wireOverrides ? { wireOverrides: rule.wireOverrides } : {}
1087
1115
  });
1088
1116
  return { ...section, text: transformedText };
1089
1117
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@warmdrift/kgauto-compiler",
3
- "version": "2.0.0-alpha.30",
3
+ "version": "2.0.0-alpha.31",
4
4
  "description": "Prompt compiler + central learning brain for multi-model AI apps. Swap models without rewriting prompts.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",