@animalabs/context-manager 0.5.4 → 0.5.9

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 (128) hide show
  1. package/dist/src/adaptive/kv-control.d.ts +84 -33
  2. package/dist/src/adaptive/kv-control.d.ts.map +1 -1
  3. package/dist/src/adaptive/kv-control.js +510 -145
  4. package/dist/src/adaptive/kv-control.js.map +1 -1
  5. package/dist/src/adaptive/picker.d.ts +21 -0
  6. package/dist/src/adaptive/picker.d.ts.map +1 -1
  7. package/dist/src/adaptive/picker.js.map +1 -1
  8. package/dist/src/adaptive/strategies/kv-stable.d.ts +12 -4
  9. package/dist/src/adaptive/strategies/kv-stable.d.ts.map +1 -1
  10. package/dist/src/adaptive/strategies/kv-stable.js +67 -7
  11. package/dist/src/adaptive/strategies/kv-stable.js.map +1 -1
  12. package/dist/src/context-log.d.ts.map +1 -1
  13. package/dist/src/context-log.js +11 -0
  14. package/dist/src/context-log.js.map +1 -1
  15. package/dist/src/context-manager.d.ts +38 -6
  16. package/dist/src/context-manager.d.ts.map +1 -1
  17. package/dist/src/context-manager.js +51 -0
  18. package/dist/src/context-manager.js.map +1 -1
  19. package/dist/src/index.d.ts +4 -2
  20. package/dist/src/index.d.ts.map +1 -1
  21. package/dist/src/index.js +3 -0
  22. package/dist/src/index.js.map +1 -1
  23. package/dist/src/message-store.d.ts +60 -0
  24. package/dist/src/message-store.d.ts.map +1 -1
  25. package/dist/src/message-store.js +165 -10
  26. package/dist/src/message-store.js.map +1 -1
  27. package/dist/src/phase-channel.d.ts +13 -0
  28. package/dist/src/phase-channel.d.ts.map +1 -0
  29. package/dist/src/phase-channel.js +55 -0
  30. package/dist/src/phase-channel.js.map +1 -0
  31. package/dist/src/strategies/autobiographical.d.ts +247 -8
  32. package/dist/src/strategies/autobiographical.d.ts.map +1 -1
  33. package/dist/src/strategies/autobiographical.js +1419 -141
  34. package/dist/src/strategies/autobiographical.js.map +1 -1
  35. package/dist/src/strategies/index.d.ts +1 -1
  36. package/dist/src/strategies/index.d.ts.map +1 -1
  37. package/dist/src/strategies/index.js.map +1 -1
  38. package/dist/src/strategies/knowledge.d.ts +8 -0
  39. package/dist/src/strategies/knowledge.d.ts.map +1 -1
  40. package/dist/src/strategies/knowledge.js +23 -1
  41. package/dist/src/strategies/knowledge.js.map +1 -1
  42. package/dist/src/types/index.d.ts +1 -1
  43. package/dist/src/types/index.d.ts.map +1 -1
  44. package/dist/src/types/index.js.map +1 -1
  45. package/dist/src/types/strategy.d.ts +112 -11
  46. package/dist/src/types/strategy.d.ts.map +1 -1
  47. package/dist/src/types/strategy.js.map +1 -1
  48. package/dist/test/adaptive/doc-plus-chat.test.js +7 -3
  49. package/dist/test/adaptive/doc-plus-chat.test.js.map +1 -1
  50. package/dist/test/adaptive/hard-fail.test.js +22 -0
  51. package/dist/test/adaptive/hard-fail.test.js.map +1 -1
  52. package/dist/test/adaptive/ingestion.test.js +3 -1
  53. package/dist/test/adaptive/ingestion.test.js.map +1 -1
  54. package/dist/test/adaptive/kv-control.test.js +17 -11
  55. package/dist/test/adaptive/kv-control.test.js.map +1 -1
  56. package/dist/test/adaptive/pin-at-level.test.d.ts +16 -0
  57. package/dist/test/adaptive/pin-at-level.test.d.ts.map +1 -0
  58. package/dist/test/adaptive/pin-at-level.test.js +133 -0
  59. package/dist/test/adaptive/pin-at-level.test.js.map +1 -0
  60. package/dist/test/adaptive/single-path-solve.test.d.ts +16 -0
  61. package/dist/test/adaptive/single-path-solve.test.d.ts.map +1 -0
  62. package/dist/test/adaptive/single-path-solve.test.js +204 -0
  63. package/dist/test/adaptive/single-path-solve.test.js.map +1 -0
  64. package/dist/test/anti-redundancy-budget.test.d.ts +17 -0
  65. package/dist/test/anti-redundancy-budget.test.d.ts.map +1 -0
  66. package/dist/test/anti-redundancy-budget.test.js +197 -0
  67. package/dist/test/anti-redundancy-budget.test.js.map +1 -0
  68. package/dist/test/chunk-persistence.test.d.ts +29 -0
  69. package/dist/test/chunk-persistence.test.d.ts.map +1 -0
  70. package/dist/test/chunk-persistence.test.js +290 -0
  71. package/dist/test/chunk-persistence.test.js.map +1 -0
  72. package/dist/test/compression-dedup.test.d.ts +20 -0
  73. package/dist/test/compression-dedup.test.d.ts.map +1 -0
  74. package/dist/test/compression-dedup.test.js +92 -0
  75. package/dist/test/compression-dedup.test.js.map +1 -0
  76. package/dist/test/compression-shape-invariants.test.js +40 -3
  77. package/dist/test/compression-shape-invariants.test.js.map +1 -1
  78. package/dist/test/head-window-order.test.d.ts +19 -0
  79. package/dist/test/head-window-order.test.d.ts.map +1 -0
  80. package/dist/test/head-window-order.test.js +159 -0
  81. package/dist/test/head-window-order.test.js.map +1 -0
  82. package/dist/test/image-strip-render-stats.test.js +25 -3
  83. package/dist/test/image-strip-render-stats.test.js.map +1 -1
  84. package/dist/test/knowledge-tool-boundary.test.d.ts +14 -0
  85. package/dist/test/knowledge-tool-boundary.test.d.ts.map +1 -0
  86. package/dist/test/knowledge-tool-boundary.test.js +93 -0
  87. package/dist/test/knowledge-tool-boundary.test.js.map +1 -0
  88. package/dist/test/l1-holdback.test.d.ts +15 -0
  89. package/dist/test/l1-holdback.test.d.ts.map +1 -0
  90. package/dist/test/l1-holdback.test.js +119 -0
  91. package/dist/test/l1-holdback.test.js.map +1 -0
  92. package/dist/test/merge-contiguity.test.d.ts +11 -0
  93. package/dist/test/merge-contiguity.test.d.ts.map +1 -0
  94. package/dist/test/merge-contiguity.test.js +74 -0
  95. package/dist/test/merge-contiguity.test.js.map +1 -0
  96. package/dist/test/message-store-window.test.d.ts +13 -0
  97. package/dist/test/message-store-window.test.d.ts.map +1 -0
  98. package/dist/test/message-store-window.test.js +177 -0
  99. package/dist/test/message-store-window.test.js.map +1 -0
  100. package/dist/test/pins.test.js +40 -0
  101. package/dist/test/pins.test.js.map +1 -1
  102. package/dist/test/speculation-cap.test.d.ts +9 -3
  103. package/dist/test/speculation-cap.test.d.ts.map +1 -1
  104. package/dist/test/speculation-cap.test.js +179 -3
  105. package/dist/test/speculation-cap.test.js.map +1 -1
  106. package/dist/test/summary-log-consistency.test.d.ts +18 -0
  107. package/dist/test/summary-log-consistency.test.d.ts.map +1 -0
  108. package/dist/test/summary-log-consistency.test.js +97 -0
  109. package/dist/test/summary-log-consistency.test.js.map +1 -0
  110. package/dist/test/tool-pairing-invariant.test.d.ts +15 -0
  111. package/dist/test/tool-pairing-invariant.test.d.ts.map +1 -0
  112. package/dist/test/tool-pairing-invariant.test.js +225 -0
  113. package/dist/test/tool-pairing-invariant.test.js.map +1 -0
  114. package/dist/tsconfig.tsbuildinfo +1 -1
  115. package/package.json +11 -3
  116. package/src/adaptive/kv-control.ts +554 -152
  117. package/src/adaptive/picker.ts +21 -0
  118. package/src/adaptive/strategies/kv-stable.ts +62 -12
  119. package/src/context-log.ts +11 -0
  120. package/src/context-manager.ts +61 -4
  121. package/src/index.ts +6 -2
  122. package/src/message-store.ts +202 -9
  123. package/src/phase-channel.ts +57 -0
  124. package/src/strategies/autobiographical.ts +1482 -167
  125. package/src/strategies/index.ts +1 -1
  126. package/src/strategies/knowledge.ts +25 -1
  127. package/src/types/index.ts +1 -0
  128. package/src/types/strategy.ts +120 -7
@@ -70,19 +70,25 @@ test('W is the only hard wall: escalates instead of exceeding it', () => {
70
70
  });
71
71
  assert.ok(r.escalations > 0, 'unfoldable content over W must escalate, not silently overflow');
72
72
  });
73
- test('reach cap is the cost↔continuity knob: tighter reach = gentler + less recompute', () => {
73
+ test('trust region P never distorts the outcome only the payment schedule (§13)', () => {
74
+ // Rev 5.0 retires the old premise (tighter reach → gentler): the old
75
+ // controller achieved gentleness by folding the WRONG (recent) content —
76
+ // the mechanism behind the 2026-07-12 inversion incident. Under the
77
+ // single-path solve, P bounds per-turn perturbation when the relevance-
78
+ // correct repair can be amortized (suffix adoption), and is overridden when
79
+ // it can't — so WHAT the profile converges to is P-invariant.
74
80
  const inputs = session();
75
- // Small reach bounds per-turn divergence (gentle KV) but compresses less
76
- // efficiently; large reach reaches deep. The robust signals are average
77
- // per-turn perturbation (RMS) and total recompute. (Worst-case maxPert and
78
- // fold *frequency* are noisy — a too-tight reach can trip an emergency deep
79
- // fold to stay under W.)
80
81
  const shallow = replayControlled(inputs, { ...BASE, reachTokens: 8_000 });
81
82
  const deep = replayControlled(inputs, { ...BASE, reachTokens: 60_000 });
82
- assert.equal(shallow.escalations, 0, 'tight reach stays feasible here');
83
- assert.equal(deep.escalations, 0, 'wide reach stays feasible here');
84
- assert.ok(shallow.rmsPerturbation < deep.rmsPerturbation, `tighter reach → lower average per-turn perturbation (${shallow.rmsPerturbation.toFixed(0)} < ${deep.rmsPerturbation.toFixed(0)})`);
85
- assert.ok(shallow.totalRecomputed <= deep.totalRecomputed, `tighter reach → no more total recompute (${shallow.totalRecomputed} ${deep.totalRecomputed})`);
83
+ assert.equal(shallow.escalations, 0, 'tight P stays feasible');
84
+ assert.equal(deep.escalations, 0, 'wide P stays feasible');
85
+ const lastS = shallow.steps[shallow.steps.length - 1];
86
+ const lastD = deep.steps[deep.steps.length - 1];
87
+ assert.equal(lastS.renderedTokens, lastD.renderedTokens, 'same final render size');
88
+ assert.equal(lastS.deepestLevel, lastD.deepestLevel, 'same final fold depth');
89
+ // The relevance-correct shed folds at the prefix start, which cannot be
90
+ // amortized below the invalidation floor — so a tight P pays the same bill.
91
+ assert.equal(shallow.totalRecomputed, deep.totalRecomputed, 'P does not change what gets folded at these settings');
86
92
  });
87
93
  test('bidirectional: under budget with a folded F_prev, un-folds to use headroom', () => {
88
94
  const inputs = session(); // 72 chunks × 1000 = 72k raw
@@ -122,7 +128,7 @@ test('foldDepthCap is monotone non-decreasing in age and capped', () => {
122
128
  let prev = -1;
123
129
  for (let age = 0; age <= 5000; age += 50) {
124
130
  const cap = foldDepthCap(mk(0), age, new Set(), 10, 6);
125
- assert.ok(cap >= 0 && cap <= 3, 'cap in [0,3]');
131
+ assert.ok(cap >= 0 && cap <= 8, 'cap in [0, MAX_FOLD_LEVEL]');
126
132
  assert.ok(cap >= prev, 'non-decreasing in age');
127
133
  prev = cap;
128
134
  }
@@ -1 +1 @@
1
- {"version":3,"file":"kv-control.test.js","sourceRoot":"","sources":["../../../test/adaptive/kv-control.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"kv-control.test.js","sourceRoot":"","sources":["../../../test/adaptive/kv-control.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Tests for V2 dynamic pins — pin-at-level-k and pin-max-level
3
+ * (`docs/best-fit-frontier-resolution.md` §7). These extend the classic
4
+ * pin-as-raw with a fold-depth bound honored by the KV-stable controller:
5
+ *
6
+ * - `fixedLevels` (ProtectedRange.level): the chunk is fixed at EXACTLY level k
7
+ * — neither un-folded shallower (even under generous budget) nor folded
8
+ * deeper (even under budget pressure);
9
+ * - `pinCaps` (ProtectedRange.maxLevel): a HARD cap on fold depth — the chunk
10
+ * may render raw..k but never deeper, enforced in normal AND emergency
11
+ * shedding, and a carried resolution deeper than the cap is un-folded to it;
12
+ * - level clamps to the deepest produced level (can't render at a missing L_k);
13
+ * - the KvStableStrategy walks the picker to a pin-at-k target.
14
+ */
15
+ export {};
16
+ //# sourceMappingURL=pin-at-level.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pin-at-level.test.d.ts","sourceRoot":"","sources":["../../../test/adaptive/pin-at-level.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Tests for V2 dynamic pins — pin-at-level-k and pin-max-level
3
+ * (`docs/best-fit-frontier-resolution.md` §7). These extend the classic
4
+ * pin-as-raw with a fold-depth bound honored by the KV-stable controller:
5
+ *
6
+ * - `fixedLevels` (ProtectedRange.level): the chunk is fixed at EXACTLY level k
7
+ * — neither un-folded shallower (even under generous budget) nor folded
8
+ * deeper (even under budget pressure);
9
+ * - `pinCaps` (ProtectedRange.maxLevel): a HARD cap on fold depth — the chunk
10
+ * may render raw..k but never deeper, enforced in normal AND emergency
11
+ * shedding, and a carried resolution deeper than the cap is un-folded to it;
12
+ * - level clamps to the deepest produced level (can't render at a missing L_k);
13
+ * - the KvStableStrategy walks the picker to a pin-at-k target.
14
+ */
15
+ import { test } from 'node:test';
16
+ import assert from 'node:assert/strict';
17
+ import { SummaryTree } from '../../src/adaptive/summary-tree.js';
18
+ import { planControlledFrontier } from '../../src/adaptive/kv-control.js';
19
+ import { Picker } from '../../src/adaptive/picker.js';
20
+ import { KvStableStrategy } from '../../src/adaptive/strategies/kv-stable.js';
21
+ import { buildChronicleWithChain } from './harness.js';
22
+ function inputsOf(ch) {
23
+ return {
24
+ chunks: ch.chunks, summaries: ch.summaries, recallPairTokens: ch.recallPairTokens,
25
+ headTokens: 0, tailTokens: 0, headChunkIds: new Set(), tailChunkIds: new Set(),
26
+ };
27
+ }
28
+ // 90 chunks × 1000t = 90k raw; mergeThreshold 6 → 15 L1s → 2 L2s (max level 2).
29
+ // c-0000 has an L1 and an L2 ancestor.
30
+ function session() {
31
+ const ch = buildChronicleWithChain({ chunkCount: 90, tokensPerChunk: 1000, mergeThreshold: 6, recallPairTokens: 200 });
32
+ const inputs = inputsOf(ch);
33
+ return { ch, inputs, tree: new SummaryTree(inputs) };
34
+ }
35
+ const NOW = 89;
36
+ test('pin-at-level-k: fixed at exactly k under BOTH generous and tight budgets', () => {
37
+ const { tree, inputs } = session();
38
+ const pinned = 'c-0000';
39
+ // Group-consistent pin: the whole L2 node covering c-0000 is fixed at L2 (an
40
+ // L2 recall pair is atomic over its range — this is what the strategy expands
41
+ // a single-chunk pin-at-k into).
42
+ const node = tree.ancestorAt(pinned, 2);
43
+ const fixedLevels = new Map(node.leafChunkIds.map((id) => [id, 2]));
44
+ const outside = 'c-0040'; // in the OTHER L2 group → free to move
45
+ assert.ok(!node.leafChunkIds.includes(outside), 'neighbor is outside the pinned node');
46
+ // Generous budget → the controller un-folds everything toward raw to use
47
+ // headroom. The pinned node must stay at L2 (NOT un-folded to raw).
48
+ const loose = planControlledFrontier(inputs, tree, {
49
+ previous: new Map(fixedLevels),
50
+ foldAtTokens: 200_000, expandAtTokens: 200_000, targetTokens: 200_000,
51
+ windowTokens: 200_000, rawZone: new Set(), fixedLevels, now: NOW, mergeThreshold: 6,
52
+ });
53
+ assert.equal(loose.resolutions.get(pinned), 2, 'pinned held at L2 under generous budget (not un-folded)');
54
+ assert.equal(loose.resolutions.get(outside), 0, 'un-pinned old chunk un-folds to raw');
55
+ // Tight budget → the controller folds the middle deep. The pinned node must
56
+ // still be EXACTLY L2 (not folded deeper — no L3 exists — and not shallower).
57
+ const tight = planControlledFrontier(inputs, tree, {
58
+ previous: new Map(),
59
+ foldAtTokens: 12_000, expandAtTokens: 0, targetTokens: 12_000,
60
+ windowTokens: 90_000, rawZone: new Set(), fixedLevels, now: NOW, mergeThreshold: 6,
61
+ });
62
+ assert.equal(tight.resolutions.get(pinned), 2, 'pinned fixed at L2 under tight budget');
63
+ });
64
+ test('pin-at-level clamps to the deepest produced level (no phantom L_k)', () => {
65
+ const { tree, inputs } = session();
66
+ const pinned = 'c-0000';
67
+ // Ask for L5, which does not exist (max is L2) → clamp to L2.
68
+ const r = planControlledFrontier(inputs, tree, {
69
+ previous: new Map(),
70
+ foldAtTokens: 12_000, expandAtTokens: 0, targetTokens: 12_000,
71
+ windowTokens: 90_000, rawZone: new Set(), fixedLevels: new Map([[pinned, 5]]),
72
+ now: NOW, mergeThreshold: 6,
73
+ });
74
+ assert.equal(r.resolutions.get(pinned), 2, 'clamped to the deepest available level (L2)');
75
+ });
76
+ test('pin-max-level: a HARD fold-depth cap, enforced even under the W emergency', () => {
77
+ const { tree, inputs } = session();
78
+ const capped = 'c-0006'; // in the second L1 group (L1-1 → L2-0)
79
+ const pinCaps = new Map([[capped, 1]]); // never fold deeper than L1
80
+ // Very tight target: folding everything to L1 (15 groups × 200 = 3000t) does
81
+ // NOT fit, so the controller must fold to L2 — forcing the deepest available
82
+ // level. The capped chunk must still never exceed L1 (a pin is hard-protected).
83
+ const r = planControlledFrontier(inputs, tree, {
84
+ previous: new Map(),
85
+ foldAtTokens: 1_500, expandAtTokens: 0, targetTokens: 1_200,
86
+ windowTokens: 2_000, rawZone: new Set(), pinCaps, now: NOW, mergeThreshold: 6,
87
+ });
88
+ assert.ok((r.resolutions.get(capped) ?? 0) <= 1, `capped chunk never folds past L1 (got L${r.resolutions.get(capped)})`);
89
+ // An un-capped neighbor in a DIFFERENT L2 group is free to fold to L2 under
90
+ // the same pressure (a chunk sharing the capped chunk's L2 node would be held
91
+ // by group-consistency, which is correct — so pick one outside it).
92
+ assert.ok((r.resolutions.get('c-0040') ?? 0) >= 2, 'un-capped neighbor folds deeper');
93
+ });
94
+ test('pin-max-level un-folds a carried resolution deeper than the cap (on pin-add)', () => {
95
+ const { tree, inputs } = session();
96
+ const capped = 'c-0006';
97
+ // F_prev has it deep at L2; adding maxLevel:1 must un-fold it to L1 immediately,
98
+ // even though the render is comfortably under budget (dead band).
99
+ const r = planControlledFrontier(inputs, tree, {
100
+ previous: new Map([[capped, 2]]),
101
+ foldAtTokens: 200_000, expandAtTokens: 0, targetTokens: 200_000,
102
+ windowTokens: 200_000, rawZone: new Set(), pinCaps: new Map([[capped, 1]]),
103
+ now: NOW, mergeThreshold: 6,
104
+ });
105
+ assert.equal(r.resolutions.get(capped), 1, 'carried L2 clamped down to the L1 cap at plan start');
106
+ });
107
+ test('KvStableStrategy walks the picker to a pin-at-level-k target', () => {
108
+ const { ch, inputs } = session();
109
+ // Pin c-0000 at L2 via the PickerChunk field the strategy reads.
110
+ const target = ch.chunks.find((c) => c.id === 'c-0000');
111
+ target.pinLevel = 2;
112
+ target.currentResolution = 0; // starts raw → must be raised to L2
113
+ const picker = new Picker(new KvStableStrategy(inputs));
114
+ const result = picker.run(inputs, { totalBudget: 12_000, targetBudget: 10_000, slack: 0 });
115
+ assert.equal(result.finalResolutions.get('c-0000'), 2, 'picker walked the pinned chunk to exactly L2');
116
+ });
117
+ test('pinned-at-level render survives a full budget sweep (no oscillation)', () => {
118
+ const { tree, inputs } = session();
119
+ const pinned = 'c-0000';
120
+ const l1 = tree.ancestorAt(pinned, 1);
121
+ const fixedLevels = new Map(l1.leafChunkIds.map((id) => [id, 1]));
122
+ let prev = new Map();
123
+ for (const budget of [12_000, 40_000, 90_000, 40_000, 12_000]) {
124
+ const r = planControlledFrontier(inputs, tree, {
125
+ previous: prev,
126
+ foldAtTokens: budget, expandAtTokens: budget * 0.9, targetTokens: budget * 0.9,
127
+ windowTokens: 90_000, rawZone: new Set(), fixedLevels, now: NOW, mergeThreshold: 6,
128
+ });
129
+ assert.equal(r.resolutions.get(pinned), 1, `pinned held at L1 at budget ${budget}`);
130
+ prev = r.resolutions;
131
+ }
132
+ });
133
+ //# sourceMappingURL=pin-at-level.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pin-at-level.test.js","sourceRoot":"","sources":["../../../test/adaptive/pin-at-level.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Rev 5.0 single-path solve (design §13) — regression tests.
3
+ *
4
+ * Load-bearing properties:
5
+ * - a bootstrap solve (no carried frontier) produces an age-monotone
6
+ * resolution gradient — the 2026-07-12 mythos inversion (old fine / recent
7
+ * deep) is unconstructible from scratch;
8
+ * - an INVERTED carried profile sitting comfortably in the dead band is
9
+ * detected as a quality gap and self-heals (override 'quality-gap') instead
10
+ * of fossilizing;
11
+ * - low-salience chunks fold before equally-aged high-salience ones;
12
+ * - when the trust region P binds, the solver adopts the ideal's newest
13
+ * changes only (suffix adoption) with perturbation ≤ P and no override.
14
+ */
15
+ export {};
16
+ //# sourceMappingURL=single-path-solve.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"single-path-solve.test.d.ts","sourceRoot":"","sources":["../../../test/adaptive/single-path-solve.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG"}
@@ -0,0 +1,204 @@
1
+ /**
2
+ * Rev 5.0 single-path solve (design §13) — regression tests.
3
+ *
4
+ * Load-bearing properties:
5
+ * - a bootstrap solve (no carried frontier) produces an age-monotone
6
+ * resolution gradient — the 2026-07-12 mythos inversion (old fine / recent
7
+ * deep) is unconstructible from scratch;
8
+ * - an INVERTED carried profile sitting comfortably in the dead band is
9
+ * detected as a quality gap and self-heals (override 'quality-gap') instead
10
+ * of fossilizing;
11
+ * - low-salience chunks fold before equally-aged high-salience ones;
12
+ * - when the trust region P binds, the solver adopts the ideal's newest
13
+ * changes only (suffix adoption) with perturbation ≤ P and no override.
14
+ */
15
+ import { test } from 'node:test';
16
+ import assert from 'node:assert/strict';
17
+ import { SummaryTree } from '../../src/adaptive/summary-tree.js';
18
+ import { planControlledFrontier } from '../../src/adaptive/kv-control.js';
19
+ import { buildChronicleWithChain } from './harness.js';
20
+ function inputsOf(ch) {
21
+ return {
22
+ chunks: ch.chunks, summaries: ch.summaries, recallPairTokens: ch.recallPairTokens,
23
+ headTokens: 0, tailTokens: 0, headChunkIds: new Set(), tailChunkIds: new Set(),
24
+ };
25
+ }
26
+ /** 90 chunks × 1000t, base-6 chain (15 L1s, 2 L2s over c-0000..0071). */
27
+ function session() {
28
+ const ch = buildChronicleWithChain({
29
+ chunkCount: 90, tokensPerChunk: 1000, mergeThreshold: 6, recallPairTokens: 200,
30
+ });
31
+ const inputs = inputsOf(ch);
32
+ return { ch, inputs, tree: new SummaryTree(inputs) };
33
+ }
34
+ /** Newest `n` chunk ids (the flat zone / attended tail). */
35
+ function tailZone(inputs, n) {
36
+ const ordered = [...inputs.chunks].sort((a, b) => a.sequence - b.sequence);
37
+ return new Set(ordered.slice(-n).map((c) => c.id));
38
+ }
39
+ /** Assert resolution levels are non-increasing with recency (older ≥ newer). */
40
+ function assertAgeMonotone(resolutions, inputs, skip) {
41
+ const ordered = [...inputs.chunks].sort((a, b) => a.sequence - b.sequence);
42
+ let prevLevel = Number.POSITIVE_INFINITY;
43
+ for (const c of ordered) {
44
+ if (skip.has(c.id))
45
+ continue;
46
+ const lvl = resolutions.get(c.id) ?? 0;
47
+ assert.ok(lvl <= prevLevel, `age-monotone violated at ${c.id}: L${lvl} deeper than older neighbor's L${prevLevel}`);
48
+ prevLevel = lvl;
49
+ }
50
+ }
51
+ test('bootstrap solve is age-monotone — the inversion is unconstructible from scratch', () => {
52
+ const { inputs, tree } = session();
53
+ const rawZone = tailZone(inputs, 12);
54
+ const plan = planControlledFrontier(inputs, tree, {
55
+ previous: new Map(),
56
+ foldAtTokens: 30_000, expandAtTokens: 24_000, targetTokens: 24_000,
57
+ windowTokens: 60_000, rawZone, now: 89, mergeThreshold: 6,
58
+ });
59
+ assert.equal(plan.override, 'bootstrap', 'empty F_prev → bootstrap override');
60
+ assert.ok(plan.tokens <= 30_000, `fits the operating band (${plan.tokens})`);
61
+ assertAgeMonotone(plan.resolutions, inputs, rawZone);
62
+ // The gradient actually folds something (this fixture is 90k raw vs 24k target).
63
+ const deepest = Math.max(...[...plan.resolutions.values()]);
64
+ assert.ok(deepest >= 1, 'bootstrap under pressure folds');
65
+ });
66
+ test('inverted carried profile in the dead band self-heals (quality-gap override)', () => {
67
+ const { inputs, tree } = session();
68
+ const rawZone = tailZone(inputs, 18); // c-0072..0089 attended
69
+ // The mythos shape: NEWER middle (c-0036..0071, the second L2 group) crushed
70
+ // to L2 while the OLDEST middle (c-0000..0035) sits raw. Group-consistent by
71
+ // construction. Renders ≈ 36k(old raw) + 200(L2 recall) + 18k(tail) ≈ 54k.
72
+ const inverted = new Map();
73
+ for (const c of inputs.chunks) {
74
+ const seq = c.sequence;
75
+ inverted.set(c.id, seq >= 36 && seq <= 71 ? 2 : 0);
76
+ }
77
+ // Band chosen so the inverted profile is comfortably feasible and in-band:
78
+ // the OLD solver would hold it forever (dead band → zero perturbation).
79
+ const band = {
80
+ foldAtTokens: 55_000, expandAtTokens: 20_000, targetTokens: 40_000,
81
+ windowTokens: 60_000, rawZone, now: 89, mergeThreshold: 6,
82
+ };
83
+ // Default trust region (= W): the misallocation is detected THROUGH the dead
84
+ // band and repaired within P — no override needed, real perturbation paid.
85
+ const plan = planControlledFrontier(inputs, tree, { previous: inverted, ...band });
86
+ assert.equal(plan.override, undefined, 'repair fits the default trust region');
87
+ assertAgeMonotone(plan.resolutions, inputs, rawZone);
88
+ assert.ok(plan.perturbation > 0, 'self-heal pays a real (reported) perturbation');
89
+ assert.ok(plan.tokens <= 55_000, 'result stays inside the band');
90
+ // Tiny trust region: no useful suffix fits under P, and holding the inverted
91
+ // profile is certifiably bad → the quality-gap override fires and the ideal
92
+ // is adopted anyway. This is the anti-fossilization property.
93
+ const tiny = planControlledFrontier(inputs, tree, {
94
+ previous: inverted, ...band, reachTokens: 1_000,
95
+ });
96
+ assert.equal(tiny.override, 'quality-gap', 'P priced out by the quality gap');
97
+ assertAgeMonotone(tiny.resolutions, inputs, rawZone);
98
+ });
99
+ test('a WELL-allocated in-band profile still holds (dead band preserved)', () => {
100
+ const { inputs, tree } = session();
101
+ const rawZone = tailZone(inputs, 18);
102
+ // First get a sane profile from the solver itself…
103
+ const first = planControlledFrontier(inputs, tree, {
104
+ previous: new Map(),
105
+ foldAtTokens: 55_000, expandAtTokens: 20_000, targetTokens: 40_000,
106
+ windowTokens: 60_000, rawZone, now: 89, mergeThreshold: 6,
107
+ });
108
+ // …then feed it back: nothing should move, zero perturbation.
109
+ const second = planControlledFrontier(inputs, tree, {
110
+ previous: first.resolutions,
111
+ foldAtTokens: 55_000, expandAtTokens: 20_000, targetTokens: 40_000,
112
+ windowTokens: 60_000, rawZone, now: 89, mergeThreshold: 6,
113
+ });
114
+ assert.equal(second.perturbation, 0, 'quiet turn: zero perturbation');
115
+ assert.ok(!second.folded && !second.expanded, 'quiet turn: no movement');
116
+ assert.equal(second.override, undefined, 'no override on a quiet turn');
117
+ });
118
+ test('low-salience chunks fold before equally-aged high-salience ones', () => {
119
+ const { ch, inputs, tree } = session();
120
+ // Mark ONE L1 group (c-0060..0065 — among the youngest with L1 coverage)
121
+ // as fold-cheap; everything else default salience.
122
+ for (const c of ch.chunks) {
123
+ if (c.sequence >= 60 && c.sequence <= 65)
124
+ c.salience = 0.1;
125
+ }
126
+ const rawZone = tailZone(inputs, 12);
127
+ // Target trims just a little: only the cheapest information should fold.
128
+ const plan = planControlledFrontier(inputs, tree, {
129
+ previous: new Map(),
130
+ foldAtTokens: 85_000, expandAtTokens: 84_500, targetTokens: 84_500,
131
+ windowTokens: 200_000, rawZone, now: 89, mergeThreshold: 6,
132
+ });
133
+ const lowSalLevel = plan.resolutions.get('c-0060') ?? 0;
134
+ const oldHighSalLevel = plan.resolutions.get('c-0000') ?? 0;
135
+ assert.ok(lowSalLevel >= 1, `fold-cheap group folded first (got L${lowSalLevel})`);
136
+ assert.equal(oldHighSalLevel, 0, 'older but salient content stays raw');
137
+ });
138
+ test('trust region binds → suffix adoption: newest changes only, perturbation ≤ P', () => {
139
+ const { inputs, tree } = session();
140
+ const rawZone = tailZone(inputs, 12);
141
+ // Carried = everything raw (a real F_prev: non-empty, all zeros), over foldAt.
142
+ const carried = new Map(inputs.chunks.map((c) => [c.id, 0]));
143
+ // P above the physical floor but below the full repair (≈26.2k here). Note
144
+ // the floor is HIGH relative to the repair: rev-5.0 folds oldest-first, so
145
+ // the ideal's changes cluster at the OLD end and even the newest-changes
146
+ // suffix invalidates most of the render — the trust region's amortization
147
+ // value on shed turns is structurally thin (it matters most for tail-near
148
+ // rebalances). The pack phase's approach-target acceptance (2026-07-12)
149
+ // raised the floor further by keeping the newest group raw in the ideal.
150
+ const P = 26_000;
151
+ const plan = planControlledFrontier(inputs, tree, {
152
+ previous: carried,
153
+ foldAtTokens: 30_000, expandAtTokens: 24_000, targetTokens: 24_000,
154
+ windowTokens: 200_000, reachTokens: P, rawZone, now: 89, mergeThreshold: 6,
155
+ });
156
+ assert.equal(plan.override, undefined, 'trust region honored — no override');
157
+ assert.ok(plan.perturbation <= P, `perturbation ${plan.perturbation} ≤ P ${P}`);
158
+ assert.ok(plan.folded, 'made progress toward the ideal');
159
+ assert.ok(plan.tokens < 90_000, 'render shrank');
160
+ // Receding horizon: iterating converges (overrides allowed when the
161
+ // remaining old-end changes can't fit any suffix under P).
162
+ let prev = plan.resolutions;
163
+ let tokens = plan.tokens;
164
+ for (let i = 0; i < 40 && tokens > 30_000; i++) {
165
+ const next = planControlledFrontier(inputs, tree, {
166
+ previous: prev,
167
+ foldAtTokens: 30_000, expandAtTokens: 24_000, targetTokens: 24_000,
168
+ windowTokens: 200_000, reachTokens: P, rawZone, now: 89, mergeThreshold: 6,
169
+ });
170
+ assert.ok(next.override !== undefined || next.perturbation <= P, `iteration ${i}: perturbation ${next.perturbation} ≤ P unless overridden`);
171
+ prev = next.resolutions;
172
+ tokens = next.tokens;
173
+ }
174
+ assert.ok(tokens <= 30_000, `converged into the band over turns (${tokens})`);
175
+ });
176
+ test('P below the physical floor cannot stall: no-progress partial is overridden', () => {
177
+ const { inputs, tree } = session();
178
+ const rawZone = tailZone(inputs, 12);
179
+ const carried = new Map(inputs.chunks.map((c) => [c.id, 0]));
180
+ // P far below the smallest meaningful fold's invalidation (~19k): the only
181
+ // suffix within P is "adopt nothing", which must NOT be accepted while a
182
+ // shed is required — the solver overrides instead of stalling over budget.
183
+ const plan = planControlledFrontier(inputs, tree, {
184
+ previous: carried,
185
+ foldAtTokens: 30_000, expandAtTokens: 24_000, targetTokens: 24_000,
186
+ windowTokens: 200_000, reachTokens: 2_000, rawZone, now: 89, mergeThreshold: 6,
187
+ });
188
+ assert.ok(plan.override !== undefined, 'no-progress plan is overridden');
189
+ assert.ok(plan.tokens <= 30_000, `sheds to the band anyway (${plan.tokens})`);
190
+ });
191
+ test('infeasible within P → override, feasibility beats the trust region', () => {
192
+ const { inputs, tree } = session();
193
+ const rawZone = tailZone(inputs, 6);
194
+ const carried = new Map(inputs.chunks.map((c) => [c.id, 0]));
195
+ // W below the raw size: something MUST fold beyond what a tiny P allows.
196
+ const plan = planControlledFrontier(inputs, tree, {
197
+ previous: carried,
198
+ foldAtTokens: 40_000, expandAtTokens: 30_000, targetTokens: 30_000,
199
+ windowTokens: 50_000, reachTokens: 1_000, rawZone, now: 89, mergeThreshold: 6,
200
+ });
201
+ assert.ok(plan.override === 'infeasible' || plan.override === 'quality-gap', `P priced out (got ${plan.override ?? 'none'})`);
202
+ assert.ok(plan.tokens <= 50_000, 'fits under W');
203
+ });
204
+ //# sourceMappingURL=single-path-solve.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"single-path-solve.test.js","sourceRoot":"","sources":["../../../test/adaptive/single-path-solve.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Bug 6.9: anti-redundancy × budget-cap = silent memory holes.
3
+ *
4
+ * `getAntiRedundantSummaries` excludes an L2 when ALL of its source L1s are
5
+ * in the CANDIDATE shown-set — computed BEFORE budget selection. When the
6
+ * budget cap (e.g. KnowledgeStrategy's research L1 cap) then drops some of
7
+ * those L1s, their parent L2 was already excluded, so the covered history
8
+ * appears at NEITHER level — unrecoverable until a later merge changes the
9
+ * shown-set. Long research-heavy runs lose their oldest research memories
10
+ * entirely and the agent re-researches (a token-burning feedback loop).
11
+ *
12
+ * Fix: a post-selection coverage-repair pass in selectHierarchical
13
+ * re-includes an excluded L2/L3 whose children did not all survive budget
14
+ * selection.
15
+ */
16
+ export {};
17
+ //# sourceMappingURL=anti-redundancy-budget.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anti-redundancy-budget.test.d.ts","sourceRoot":"","sources":["../../test/anti-redundancy-budget.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG"}