@dzhechkov/harness-core 0.8.5 → 0.8.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/.dz-manifest.json +286 -82
  2. package/README.md +54 -2
  3. package/dist/amendment-trace.d.ts.map +1 -1
  4. package/dist/amendment-trace.js +12 -1
  5. package/dist/amendment-trace.js.map +1 -1
  6. package/dist/compounding.d.ts +54 -0
  7. package/dist/compounding.d.ts.map +1 -1
  8. package/dist/compounding.js +221 -1
  9. package/dist/compounding.js.map +1 -1
  10. package/dist/eta.d.ts +92 -0
  11. package/dist/eta.d.ts.map +1 -0
  12. package/dist/eta.js +488 -0
  13. package/dist/eta.js.map +1 -0
  14. package/dist/feature-adr-checkpoints.d.ts +11 -2
  15. package/dist/feature-adr-checkpoints.d.ts.map +1 -1
  16. package/dist/feature-adr-checkpoints.js +38 -3
  17. package/dist/feature-adr-checkpoints.js.map +1 -1
  18. package/dist/feature-adr-decision-recall.d.ts +167 -0
  19. package/dist/feature-adr-decision-recall.d.ts.map +1 -0
  20. package/dist/feature-adr-decision-recall.js +519 -0
  21. package/dist/feature-adr-decision-recall.js.map +1 -0
  22. package/dist/feature-adr-landing.d.ts +37 -0
  23. package/dist/feature-adr-landing.d.ts.map +1 -0
  24. package/dist/feature-adr-landing.js +59 -0
  25. package/dist/feature-adr-landing.js.map +1 -0
  26. package/dist/feature-adr-routing.d.ts +58 -23
  27. package/dist/feature-adr-routing.d.ts.map +1 -1
  28. package/dist/feature-adr-routing.js +194 -69
  29. package/dist/feature-adr-routing.js.map +1 -1
  30. package/dist/guard-promotion.d.ts +41 -0
  31. package/dist/guard-promotion.d.ts.map +1 -1
  32. package/dist/guard-promotion.js +218 -4
  33. package/dist/guard-promotion.js.map +1 -1
  34. package/dist/guard-volume.d.ts +108 -0
  35. package/dist/guard-volume.d.ts.map +1 -0
  36. package/dist/guard-volume.js +536 -0
  37. package/dist/guard-volume.js.map +1 -0
  38. package/dist/guard.d.ts +34 -0
  39. package/dist/guard.d.ts.map +1 -1
  40. package/dist/guard.js +113 -4
  41. package/dist/guard.js.map +1 -1
  42. package/dist/index.d.ts +18 -4
  43. package/dist/index.d.ts.map +1 -1
  44. package/dist/index.js +12 -2
  45. package/dist/index.js.map +1 -1
  46. package/dist/integration-apply.d.ts +25 -0
  47. package/dist/integration-apply.d.ts.map +1 -0
  48. package/dist/integration-apply.js +299 -0
  49. package/dist/integration-apply.js.map +1 -0
  50. package/dist/integration-evidence.d.ts +46 -0
  51. package/dist/integration-evidence.d.ts.map +1 -0
  52. package/dist/integration-evidence.js +44 -0
  53. package/dist/integration-evidence.js.map +1 -0
  54. package/dist/integration-probe-worker.d.ts +22 -0
  55. package/dist/integration-probe-worker.d.ts.map +1 -0
  56. package/dist/integration-probe-worker.js +334 -0
  57. package/dist/integration-probe-worker.js.map +1 -0
  58. package/dist/integrations-verify.d.ts +60 -0
  59. package/dist/integrations-verify.d.ts.map +1 -0
  60. package/dist/integrations-verify.js +194 -0
  61. package/dist/integrations-verify.js.map +1 -0
  62. package/dist/lesson-generalization.d.ts +29 -0
  63. package/dist/lesson-generalization.d.ts.map +1 -0
  64. package/dist/lesson-generalization.js +84 -0
  65. package/dist/lesson-generalization.js.map +1 -0
  66. package/dist/loop-blobs.generated.js +8 -8
  67. package/dist/loop-blobs.generated.js.map +1 -1
  68. package/dist/loop-plan.d.ts +13 -1
  69. package/dist/loop-plan.d.ts.map +1 -1
  70. package/dist/loop-plan.js +15 -1
  71. package/dist/loop-plan.js.map +1 -1
  72. package/dist/loop-render.d.ts.map +1 -1
  73. package/dist/loop-render.js +51 -6
  74. package/dist/loop-render.js.map +1 -1
  75. package/dist/loop-trace.d.ts +20 -1
  76. package/dist/loop-trace.d.ts.map +1 -1
  77. package/dist/loop-trace.js +83 -1
  78. package/dist/loop-trace.js.map +1 -1
  79. package/dist/model-recommender.d.ts +8 -0
  80. package/dist/model-recommender.d.ts.map +1 -1
  81. package/dist/model-recommender.js +31 -4
  82. package/dist/model-recommender.js.map +1 -1
  83. package/dist/operations.d.ts +27 -0
  84. package/dist/operations.d.ts.map +1 -1
  85. package/dist/operations.js +178 -2
  86. package/dist/operations.js.map +1 -1
  87. package/dist/patterns.d.ts +27 -1
  88. package/dist/patterns.d.ts.map +1 -1
  89. package/dist/patterns.js +211 -45
  90. package/dist/patterns.js.map +1 -1
  91. package/dist/setup.d.ts.map +1 -1
  92. package/dist/setup.js +20 -17
  93. package/dist/setup.js.map +1 -1
  94. package/dist/target-integrations.d.ts +65 -0
  95. package/dist/target-integrations.d.ts.map +1 -0
  96. package/dist/target-integrations.js +152 -0
  97. package/dist/target-integrations.js.map +1 -0
  98. package/dist/vector-tier.d.ts +6 -1
  99. package/dist/vector-tier.d.ts.map +1 -1
  100. package/dist/vector-tier.js +32 -7
  101. package/dist/vector-tier.js.map +1 -1
  102. package/dist/workflow-run.d.ts.map +1 -1
  103. package/dist/workflow-run.js +18 -12
  104. package/dist/workflow-run.js.map +1 -1
  105. package/package.json +19 -15
  106. package/sbom.json +591 -81
  107. package/src/amendment-trace.ts +12 -1
  108. package/src/compounding.ts +300 -1
  109. package/src/eta.ts +590 -0
  110. package/src/feature-adr-checkpoints.ts +39 -3
  111. package/src/feature-adr-decision-recall.ts +652 -0
  112. package/src/feature-adr-landing.ts +109 -0
  113. package/src/feature-adr-routing.ts +224 -65
  114. package/src/guard-promotion.ts +245 -4
  115. package/src/guard-volume.ts +752 -0
  116. package/src/guard.ts +148 -4
  117. package/src/index.ts +65 -3
  118. package/src/integration-apply.ts +332 -0
  119. package/src/integration-evidence.ts +89 -0
  120. package/src/integration-probe-worker.ts +310 -0
  121. package/src/integration-receipts/claude-code/mcp/2.1.235.json +35 -0
  122. package/src/integrations-verify.ts +258 -0
  123. package/src/lesson-generalization.ts +115 -0
  124. package/src/loop-blobs.generated.ts +8 -8
  125. package/src/loop-plan.ts +36 -3
  126. package/src/loop-render.ts +50 -6
  127. package/src/loop-trace.ts +91 -2
  128. package/src/model-recommender.ts +35 -4
  129. package/src/operations.ts +199 -2
  130. package/src/patterns.ts +252 -43
  131. package/src/setup.ts +20 -17
  132. package/src/target-integrations.ts +225 -0
  133. package/src/vector-tier.ts +44 -14
  134. package/src/workflow-run.ts +18 -11
package/src/guard.ts CHANGED
@@ -11,8 +11,16 @@
11
11
  // PURE: `evaluateGuard` operates over INJECTED FACTS (package.json deps, a drift result, lesson text, README
12
12
  // counts, store size) that the CLI gathers. No filesystem here → deterministic + unit-testable without a repo.
13
13
 
14
- import { type RuleTemplate, type TemplateParams, type ChangeSet, templateFires, validTemplateParams } from './guard-promotion.js';
14
+ import { lessonRuleContentAnchor, type RuleTemplate, type TemplateParams, type ChangeSet, templateFires, validTemplateParams } from './guard-promotion.js';
15
15
  import { STUB_MARKERS, STUB_PHRASES, checkNoStubs, type StubWaiver } from './no-stubs.js';
16
+ import {
17
+ VOLUME_SHADOW_RULE_IDS,
18
+ evaluateVolumeShadow,
19
+ unknownVolumeShadow,
20
+ type GuardObservation,
21
+ type VolumeShadowInput,
22
+ type VolumeShadowResult,
23
+ } from './guard-volume.js';
16
24
 
17
25
  export type GuardSeverity = 'hard' | 'soft';
18
26
  export type GuardOp = 'publish' | 'teach' | 'consolidate' | 'reindex';
@@ -39,6 +47,8 @@ export interface Violation {
39
47
  readonly rule: string;
40
48
  readonly severity: GuardSeverity;
41
49
  readonly detail: string;
50
+ /** Present for promoted-template firings; ids alone do not prove equal effective rule content. */
51
+ readonly contentAnchor?: string;
42
52
  }
43
53
 
44
54
  export interface GuardResult {
@@ -54,11 +64,15 @@ export interface GuardResult {
54
64
  * argument; a note is the cheap fix. Present only when non-empty.
55
65
  */
56
66
  readonly notes?: readonly string[];
67
+ /** Versioned shadow measurements. They are evidence only and never enter the verdict reducer. */
68
+ readonly observations?: readonly GuardObservation[];
57
69
  }
58
70
 
59
71
  /** Facts the CLI injects; each rule reads only the fields it needs. Missing evidence ⇒ that rule is skipped. */
60
72
  export interface GuardFacts {
61
73
  readonly op: GuardOp;
74
+ /** Publish-only raw volume facts. Absence preserves the legacy result shape. */
75
+ readonly volume?: VolumeShadowInput;
62
76
  /** for no-workspace-star: each publishable package's deps map. */
63
77
  readonly packages?: readonly { readonly name: string; readonly deps: Readonly<Record<string, string>> }[];
64
78
  /** for no-skill-drift: the names that byte-drift between copies (from sweepSkillDrift). */
@@ -69,6 +83,29 @@ export interface GuardFacts {
69
83
  readonly counts?: readonly { readonly label: string; readonly a: number; readonly b: number }[];
70
84
  /** for store-bloat-cap: current learned-store size vs its cap. */
71
85
  readonly store?: { readonly count: number; readonly cap: number };
86
+ /** Advisory freshness evidence for the auto-cost outcome store. Missing evidence fails open. */
87
+ readonly routingFreshness?: { readonly unfedRunIds: readonly string[] };
88
+ /**
89
+ * for marketplace-parity: the CLI's read-only regeneration result. The whole field being absent
90
+ * means evidence could not be gathered, so this advisory rule reports nothing.
91
+ */
92
+ readonly marketplaceParity?: {
93
+ /** false ⇒ this repository has no .claude-plugin/ showcase and is out of scope. */
94
+ readonly applicable: boolean;
95
+ /** true ⇒ exactly one of plugin.json / marketplace.json is present. */
96
+ readonly onlyOnePresent?: boolean;
97
+ /** true ⇒ registry-derived composition differs from a fresh regeneration. */
98
+ readonly diverged?: boolean;
99
+ /** Operator-owned published version, carried only to render the exact repair command. */
100
+ readonly publishedVersion?: string;
101
+ /** Existing published manifests that could not be read or parsed. */
102
+ readonly manifestFailures?: readonly {
103
+ readonly file: 'plugin.json' | 'marketplace.json';
104
+ readonly error: string;
105
+ }[];
106
+ /** true ⇒ regeneration was attempted but could not complete. */
107
+ readonly regenerateFailed?: boolean;
108
+ };
72
109
  /** for skills-registrable: per skill pack, dirs that would ship un-registrable (no depth-1 SKILL.md). */
73
110
  readonly skillPacks?: readonly { readonly name: string; readonly nonRegistrable: readonly string[] }[];
74
111
  /** for readme-first: per publishable package, is a version bump staged without a README change? */
@@ -262,6 +299,12 @@ export const DEFAULT_RULES: readonly GuardRule[] = [
262
299
  { id: 'readme-consistency', severity: 'soft', ops: ['publish'], description: 'README counts agree (CJM header vs All Commands, etc.)' },
263
300
  { id: 'skills-registrable', severity: 'soft', ops: ['publish'], description: 'every skill directory in a skill pack has a depth-1 SKILL.md (a buried or missing one ships un-registrable — the health-advisor 1.2.0 class)' },
264
301
  { id: 'readme-first', severity: 'soft', ops: ['publish'], description: 'a package with a staged version bump must update its own README.md in the same change (README-first)' },
302
+ { id: 'routing-store-stale', severity: 'soft', ops: ['publish'], description: 'harvested routing telemetry has been applied to the auto-cost outcome store' },
303
+ { id: 'marketplace-parity', severity: 'soft', ops: ['publish'], description: 'the published .claude-plugin/ showcase composition matches a fresh regeneration from the live registry (version excluded — an operator field)' },
304
+ { id: 'template-context-token-weight', severity: 'soft', ops: ['publish'], description: 'observe the UTF-8-byte estimated token weight of each selected template context corpus; measured starting points are advisory only' },
305
+ { id: 'template-context-largest-file-share', severity: 'soft', ops: ['publish'], description: 'observe the largest template file share on the same estimated-token basis as its corpus total; advisory only' },
306
+ { id: 'feature-artifact-diff-ratio', severity: 'soft', ops: ['publish'], description: 'observe feature artifact bytes against attributable unified-diff bytes, explicitly a proxy; advisory only' },
307
+ { id: 'feature-tier-artifact-set', severity: 'soft', ops: ['publish'], description: 'observe artifacts due for the recorded feature tier, active steps, consumers, and lifecycle; advisory only' },
265
308
  { id: 'agents-md-policy-sync', severity: 'soft', ops: ['publish'], description: 'proves the AGENTS.md copy is in SYNC with its source — not that the runtime read or obeyed it; heal drift with dz agents-sync' },
266
309
  { id: 'lockfile-in-sync', severity: 'soft', ops: ['publish'], description: 'every workspace @dzhechkov/* dependency spec matches the specifier pnpm-lock.yaml records for that importer (a dep bump without a lockfile refresh breaks CI with ERR_PNPM_OUTDATED_LOCKFILE). SOFT-ONLY — a config cannot promote it to HARD' },
267
310
  { id: 'store-bloat-cap', severity: 'soft', ops: ['teach', 'consolidate'], description: 'the learned store is within its size cap' },
@@ -360,6 +403,59 @@ const CHECKERS: Record<string, (f: GuardFacts, sev: GuardSeverity) => Violation[
360
403
  }
361
404
  return out;
362
405
  },
406
+ 'routing-store-stale': (f, _sev) => {
407
+ const ids = f.routingFreshness?.unfedRunIds;
408
+ if (!Array.isArray(ids) || ids.length === 0) return [];
409
+ const valid = [...new Set(ids.filter((id): id is string => typeof id === 'string' && id !== ''))].sort();
410
+ if (valid.length === 0) return [];
411
+ return [{
412
+ rule: 'routing-store-stale',
413
+ severity: 'soft',
414
+ detail: `${valid.length} harvested run(s) are not reflected in the auto-cost store: ${valid.slice(0, 5).join(', ')}${valid.length > 5 ? '…' : ''} — run dz routing recommend --apply`,
415
+ }];
416
+ },
417
+ 'marketplace-parity': (f, _sev) => {
418
+ const fact = f.marketplaceParity;
419
+ if (fact === undefined || fact.applicable !== true) return [];
420
+ const hasPublishedVersion = typeof fact.publishedVersion === 'string' && fact.publishedVersion !== '';
421
+ const fix = `dz plugin --version ${hasPublishedVersion ? fact.publishedVersion : 'X.Y.Z'}`;
422
+ const fixHint = hasPublishedVersion ? '' : ' (substitute the published version for X.Y.Z)';
423
+ const manifestFailures = Array.isArray(fact.manifestFailures)
424
+ ? fact.manifestFailures.filter((failure) => failure
425
+ && (failure.file === 'plugin.json' || failure.file === 'marketplace.json')
426
+ && typeof failure.error === 'string'
427
+ && failure.error !== '')
428
+ : [];
429
+ if (manifestFailures.length > 0) {
430
+ return manifestFailures.map((failure) => ({
431
+ rule: 'marketplace-parity',
432
+ severity: 'soft',
433
+ detail: `.claude-plugin/${failure.file} exists but could not be read or parsed: ${failure.error} — run \`${fix}\`${fixHint} and commit the result`,
434
+ }));
435
+ }
436
+ if (fact.onlyOnePresent === true) {
437
+ return [{
438
+ rule: 'marketplace-parity',
439
+ severity: 'soft',
440
+ detail: `.claude-plugin/ has only one of plugin.json / marketplace.json — a broken half-showcase; run \`${fix}\`${fixHint} and commit the result`,
441
+ }];
442
+ }
443
+ if (fact.regenerateFailed === true) {
444
+ return [{
445
+ rule: 'marketplace-parity',
446
+ severity: 'soft',
447
+ detail: 'could not verify .claude-plugin/ composition because fresh regeneration failed',
448
+ }];
449
+ }
450
+ if (fact.diverged === true) {
451
+ return [{
452
+ rule: 'marketplace-parity',
453
+ severity: 'soft',
454
+ detail: `.claude-plugin/ composition does not match a fresh regeneration from the live registry — run \`${fix}\`${fixHint} and commit the result`,
455
+ }];
456
+ }
457
+ return [];
458
+ },
363
459
  'review-round': (f, sev) => {
364
460
  // The publish gate had eleven rules and not one asked whether anyone but the author had read the
365
461
  // code. MEASURED cost (health-advisor slice H): five rounds graded F, thirteen packages published
@@ -508,7 +604,13 @@ const CHECKERS: Record<string, (f: GuardFacts, sev: GuardSeverity) => Violation[
508
604
  * may not understand a file, and "I might be wrong" plus "block the publish" is the wrong pair. Disabling
509
605
  * such a rule stays allowed — only the promotion is refused.
510
606
  */
511
- export const SOFT_ONLY_RULES: readonly string[] = ['lockfile-in-sync', 'agents-md-policy-sync'];
607
+ export const SOFT_ONLY_RULES: readonly string[] = [
608
+ 'lockfile-in-sync',
609
+ 'agents-md-policy-sync',
610
+ 'routing-store-stale',
611
+ 'marketplace-parity',
612
+ ...VOLUME_SHADOW_RULE_IDS,
613
+ ];
512
614
 
513
615
  /**
514
616
  * A well-formed PROMOTED rule: an id the engine does not know, made enforceable by a template +
@@ -534,7 +636,12 @@ function templateChecker(rule: GuardRule & { template: RuleTemplate; params: Tem
534
636
  const r = templateFires(rule.template, rule.params, change);
535
637
  if (Object.hasOwn(r, 'undecidable') || !(r as { fired?: boolean }).fired) return [];
536
638
  // A promoted rule is ALWAYS soft, whatever severity reaches this point (belt to resolveRules' braces).
537
- return [{ rule: rule.id, severity: 'soft', detail: `${(r as { detail?: string }).detail ?? 'template rule fired'} (promoted rule — advisory)` }];
639
+ return [{
640
+ rule: rule.id,
641
+ severity: 'soft',
642
+ detail: `${(r as { detail?: string }).detail ?? 'template rule fired'} (promoted rule — advisory)`,
643
+ contentAnchor: lessonRuleContentAnchor(rule.template, rule.params),
644
+ }];
538
645
  };
539
646
  }
540
647
 
@@ -593,8 +700,32 @@ export function evaluateGuard(facts: GuardFacts, rules: readonly GuardRule[] = D
593
700
  );
594
701
  const violations: Violation[] = [];
595
702
  const checked: string[] = [];
703
+ const observations: GuardObservation[] = [];
704
+ let volumeResult: VolumeShadowResult | undefined;
705
+ let volumeEvaluated = false;
706
+ const volume = (): VolumeShadowResult => {
707
+ if (volumeEvaluated) return volumeResult ?? { observations: [], signals: [], notes: [] };
708
+ volumeEvaluated = true;
709
+ try {
710
+ volumeResult = evaluateVolumeShadow(facts.volume);
711
+ } catch (error) {
712
+ volumeResult = unknownVolumeShadow(
713
+ 'volume-evaluator-failure',
714
+ error instanceof Error ? error.message : String(error),
715
+ );
716
+ }
717
+ return volumeResult;
718
+ };
596
719
  for (const r of active) {
597
720
  checked.push(r.id);
721
+ if ((VOLUME_SHADOW_RULE_IDS as readonly string[]).includes(r.id)) {
722
+ const emission = volume();
723
+ observations.push(...emission.observations.filter((item) => item.rule === r.id));
724
+ violations.push(...emission.signals
725
+ .filter((signal) => signal.rule === r.id)
726
+ .map((signal) => ({ rule: signal.rule, severity: 'soft' as const, detail: signal.detail })));
727
+ continue;
728
+ }
598
729
  // A promoted (template) rule has no built-in checker by design — it is enforceable through the
599
730
  // shared `templateFires` predicate instead. Without this branch a promoted rule written into
600
731
  // `.dz/guard.json` would be INERT: present in the config, listed as checked, enforcing nothing —
@@ -642,7 +773,17 @@ export function evaluateGuard(facts: GuardFacts, rules: readonly GuardRule[] = D
642
773
  notes.push('agents-md-policy-sync: this repository carries a dz:policies fence but its canonical policy sources are unreadable — the advisory rule could not compare, and that gap is on the record, not a silent pass');
643
774
  }
644
775
  }
645
- return { op, verdict, violations, checked, ...(notes.length > 0 ? { notes } : {}) };
776
+ for (const item of observations) {
777
+ if (item.status === 'unknown') notes.push(`${item.rule} ${item.scope}: ${item.detail}`);
778
+ }
779
+ return {
780
+ op,
781
+ verdict,
782
+ violations,
783
+ checked,
784
+ ...(notes.length > 0 ? { notes } : {}),
785
+ ...(observations.length > 0 ? { observations } : {}),
786
+ };
646
787
  }
647
788
 
648
789
  /** An append-only audit record. `ts` is injected by the caller (no wall-clock here → deterministic tests). */
@@ -653,6 +794,8 @@ export interface GuardAuditRecord {
653
794
  readonly violations: readonly Violation[];
654
795
  /** informational notes (FN-7 — e.g. the no-stubs skipped-files note); on the record, never a verdict input. */
655
796
  readonly notes?: readonly string[];
797
+ /** Shadow measurements copied without recomputation from the evaluated result. */
798
+ readonly observations?: readonly GuardObservation[];
656
799
  /** set when the operator overrode a block with `--force <reason>` — the override is logged, never silent. */
657
800
  readonly override?: { readonly forced: true; readonly reason: string };
658
801
  }
@@ -665,6 +808,7 @@ export function auditRecord(result: GuardResult, ts: string, override?: { reason
665
808
  verdict: result.verdict,
666
809
  violations: result.violations,
667
810
  ...(Array.isArray(result.notes) && result.notes.length > 0 ? { notes: result.notes } : {}),
811
+ ...(Array.isArray(result.observations) && result.observations.length > 0 ? { observations: result.observations } : {}),
668
812
  ...(override && typeof override.reason === 'string' ? { override: { forced: true, reason: override.reason } } : {}),
669
813
  };
670
814
  }
package/src/index.ts CHANGED
@@ -15,6 +15,11 @@ export * from './apply.js';
15
15
  export { bundleSkills } from './bundle.js';
16
16
  export type { BundleOptions, BundleResult, BundledSkill } from './bundle.js';
17
17
  export * from './targets.js';
18
+ export * from './target-integrations.js';
19
+ export * from './integration-evidence.js';
20
+ export * from './integration-apply.js';
21
+ export * from './integrations-verify.js';
22
+ export { redactProbeText, PROBE_REDACTION_MARKER } from './integration-probe-worker.js';
18
23
  // Target-parity model (feature target-parity-matrix, ADR-001) — the computed feature×target map.
19
24
  export {
20
25
  RUNTIME_CAPABILITIES,
@@ -94,7 +99,8 @@ export { buildRegistry, searchRegistry, filterByCategory, skillPackBaseDirs, dis
94
99
  export * from './package-skill-layouts.js';
95
100
  export { recommend } from './recommend.js';
96
101
  export { pretrain } from './pretrain.js';
97
- export { loadPatterns, loadSessions, computePatternBoost, readLearningConfig, readMemoryLearningConfig, BOOST_CAP, recordPattern, loadStorePatternsSync, loadStoreRecords, patternToRecord, recordToPattern, patternRecordId, patternIdentityOf, dreamRecordId, isMirrorableLearning, consolidateSessions, recallPatterns, pruneNoisePatterns, removePatternsByIds, snapshotStore, readReinforcementState, encodeReinforcementState, reinforcePattern, updateReinforcementState, storeStats, lessonDeltaReport, lessonDeltaMap, readQuarantineState, encodeQuarantineState, promotePatterns, quarantineExpiryCandidates, pruneQuarantinePatterns } from './patterns.js';
102
+ export { loadPatterns, loadSessions, computePatternBoost, readLearningConfig, readMemoryLearningConfig, BOOST_CAP, recordPattern, recordLessonForms, loadStorePatternsSync, loadStoreRecords, patternToRecord, recordToPattern, patternRecordId, patternIdentityOf, dreamRecordId, isMirrorableLearning, consolidateSessions, recallPatterns, pruneNoisePatterns, removePatternsByIds, snapshotStore, readReinforcementState, encodeReinforcementState, reinforcePattern, updateReinforcementState, storeStats, lessonDeltaReport, lessonDeltaMap, readQuarantineState, encodeQuarantineState, promotePatterns, quarantineExpiryCandidates, pruneQuarantinePatterns } from './patterns.js';
103
+ export { normalizeLessonForms, validateClassTemplate, lessonPairIdOf, mergeLessonFormHits, mergeLessonMatchedForms } from './lesson-generalization.js';
98
104
  export { withStoreLock, withStoreLockSync, storeLockPath, StoreLockTimeoutError, StoreLockCompromisedError, STALE_LOCK_MS, LOCK_TIMEOUT_MS } from './store-lock.js';
99
105
  export type { StoreLockOptions } from './store-lock.js';
100
106
  export { withNamedLockSync, namedLockPath, isSafeLockName, NamedLockNameError, NamedLockTimeoutError, NamedLockCompromisedError } from './named-lock.js';
@@ -121,7 +127,8 @@ export {
121
127
  renderBridgeReport,
122
128
  } from './qe-bridge.js';
123
129
  export type { BridgeFamily, BridgeFailureReason, BridgeFinding, BridgeSignoff, BridgeParse, BridgeParseOk, BridgeParseFail, BridgeChannels, BridgeAudit, ClaudeResultExtraction, NamedExtract, BridgePromptInput } from './qe-bridge.js';
124
- export type { PatternRecord, SessionRecord, LearningConfig, MemoryLearningConfig, LoadOptions, ConsolidateResult, ConsolidateOptions, SqliteBackendMode, RecallHit, SessionsSource, PruneNoiseResult, RemovePatternsResult, SnapshotStoreResult, ReinforcementState, ReinforcePatternResult, StoreStats, LessonDeltaReport, LessonDeltaRow, QuarantineState, PromoteResult, QuarantineExpiryCandidate } from './patterns.js';
130
+ export type { PatternRecord, SessionRecord, LearningConfig, MemoryLearningConfig, LoadOptions, ConsolidateResult, ConsolidateOptions, SqliteBackendMode, RecallHit, RecallPatternsOptions, RecordLessonFormsResult, SessionsSource, PruneNoiseResult, RemovePatternsResult, SnapshotStoreResult, ReinforcementState, ReinforcePatternResult, StoreStats, LessonDeltaReport, LessonDeltaRow, QuarantineState, PromoteResult, QuarantineExpiryCandidate } from './patterns.js';
131
+ export type { LessonForm, LessonMatchedForm, LessonFormsInput, LessonFormRankedHit, MergedLessonFormHit } from './lesson-generalization.js';
125
132
  export { DEFAULT_REINFORCE_THRESHOLD, NoopLearningBackend, NativeReinforcementBackend, resolveLearningBackend, isLearningSignalBackend, applyLearningSignals, applyLearningSignalsWithDelta, applyLearningSignalsWithTerms } from './learning-backend.js';
126
133
  export type { LearningSignalBackend, LearningSignalStats, LearningSample, SignalCandidate, EnhanceContext, TrainingResult, LearningBackendMode, RerankTerm } from './learning-backend.js';
127
134
  // lesson-bandit-rerank (I-8): the ACL's public surface only. The vendored engine class is
@@ -186,6 +193,15 @@ export { runSetup, generateHooksConfig, generateAgentdbWriter, writerVersionOf,
186
193
  agentdbStorePath, agentdbMcpStorePath, agentdbStoreSeparationProblem } from './setup.js';
187
194
  export { statuslineData, readFeatureAdrState, writeFeatureAdrState, featureAdrStateDir, featureAdrStatePath } from './statusline.js';
188
195
  export type { StatuslineData, FeatureAdrState, WriteFeatureAdrStateInput } from './statusline.js';
196
+ export {
197
+ ETA_MAX_STAGE_MS,
198
+ estimateEta,
199
+ extractStageSamples,
200
+ formatEta,
201
+ parseCheckpointLines,
202
+ segmentRun,
203
+ } from './eta.js';
204
+ export type { CheckpointObservation, EtaEstimate, EtaInput, IncompleteCoverageSample, RunSegment, StageDurationSample, StageSample } from './eta.js';
189
205
  export { indexPatternsToAgentdb, resolveAgentdbPath, searchAgentdbPatterns, listAgentdbDzIds, resolveAgentdbEmbedder, cosineSimilarity, importVectorsToAgentdb, reindexAgentdbRows, bumpAgentdbUses, clearAgentdbQuarantine, deleteAgentdbByDzIds, readAgentdbRowsByTaskType, DZ_OWNED_TASK_TYPES } from './agentdb-index.js';
190
206
  export type { AgentdbSearchHit, AgentdbSearchResult, AgentdbImportRow } from './agentdb-index.js';
191
207
  export { DEFAULT_EMBED_MODEL, LEGACY_EMBED_MODEL, DEFAULT_EMBED_DIM, KNOWN_EMBED_DIMS, resolveEmbedModel, readEmbedManifest, writeEmbedManifest, embedManifestPath, legacyEmbedManifest } from './embedding-config.js';
@@ -250,6 +266,50 @@ export { hookDecision, isFenced, isNewLine, ESCAPE_TEACHING } from './claim-chec
250
266
  export type { HookDecision, HookDecisionOpts } from './claim-check-hook-policy.js';
251
267
  export { step8ClaimGate } from './feature-adr-claim-gate.js';
252
268
  export type { Step8ClaimCounts, Step8ClaimGate } from './feature-adr-claim-gate.js';
269
+ export {
270
+ DEFAULT_CODE_LANDING_CEILING_MS,
271
+ CODE_LANDING_CEILING_ENV,
272
+ decideCodeLandingLiveness,
273
+ extractCodexCompanionJobId,
274
+ parseCodeLandingLivenessSignal,
275
+ } from './feature-adr-landing.js';
276
+ export type {
277
+ CodeLandingLivenessVerdict,
278
+ CodeLandingLivenessReason,
279
+ CodeLandingLivenessInput,
280
+ CodeLandingLivenessDecision,
281
+ CodeLandingLivenessProbe,
282
+ } from './feature-adr-landing.js';
283
+ export {
284
+ buildDecisionContext,
285
+ normalizeDecisionRecall,
286
+ parseDecisionRecallFrame,
287
+ parseDecisionRecallApplicationProbe,
288
+ mergeDecisionRecallEvents,
289
+ reduceDecisionRecallMetrics,
290
+ summarizeDecisionRecallReceipts,
291
+ decisionRecallEnterCmd,
292
+ decisionRecallRunCmd,
293
+ decisionRecallAppendCmd,
294
+ decisionRecallApplicationProbeCmd,
295
+ } from './feature-adr-decision-recall.js';
296
+ export type {
297
+ DecisionRecallKind,
298
+ DecisionRecallStage,
299
+ DecisionRecallOutcomeName,
300
+ DecisionRecallContext,
301
+ DecisionRecallFrame,
302
+ DecisionRecallSelection,
303
+ DecisionRecallOutcome,
304
+ DecisionRecallEvent,
305
+ DecisionRecallDisposition,
306
+ DecisionRecallApplicationProbe,
307
+ MergedDecisionRecallAttempt,
308
+ MergedDecisionRecallDecision,
309
+ MergedDecisionRecallEvents,
310
+ DecisionRecallRatio,
311
+ DecisionRecallMetrics,
312
+ } from './feature-adr-decision-recall.js';
253
313
  export {
254
314
  CHECKPOINT_STAGES,
255
315
  STAGE_ARTIFACTS,
@@ -283,7 +343,7 @@ export {
283
343
  codeCheckpointPersistAllowed,
284
344
  codeStageResultShapeValid,
285
345
  } from './feature-adr-checkpoints.js';
286
- export type { CheckpointStage, CheckpointEntry, ResumeMode, ResumeDecision, ParsedCheckpointRead, TrainingPairFamily, TrainingPair, TrainingPairEvaluation, TrainingPairProvenance, TrainingPairTruncation,
346
+ export type { CheckpointStage, CheckpointEntry, ResumeMode, ResumeDecision, ParsedCheckpointRead, TrainingPairFamily, TrainingPair, TrainingPairEvaluation, TrainingPairProvenance, TrainingPairBudget, TrainingPairTruncation,
287
347
  CheckpointWriteVerdict,
288
348
  } from './feature-adr-checkpoints.js';
289
349
 
@@ -627,6 +687,7 @@ export {
627
687
  resolveCoderSpec,
628
688
  coderIsCodex,
629
689
  resolveQeSpec,
690
+ resolveQeSpecForCoder,
630
691
  crossFamilyQe,
631
692
  decideModeBScope,
632
693
  partitionReviewFindings,
@@ -825,6 +886,7 @@ export * from './model-recommender.js';
825
886
  export * from './bto-optimize.js';
826
887
  export * from './discrimination-gate.js';
827
888
  export * from './guard.js';
889
+ export * from './guard-volume.js';
828
890
  // Root AGENTS.md policy projection: pure anchor extraction/render/hash drift +
829
891
  // the shared-emitter I/O entry point exported from operations.
830
892
  export * from './agents-policy.js';