@animalabs/context-manager 0.5.5 → 0.5.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 (113) hide show
  1. package/dist/src/adaptive/kv-control.d.ts +69 -32
  2. package/dist/src/adaptive/kv-control.d.ts.map +1 -1
  3. package/dist/src/adaptive/kv-control.js +471 -172
  4. package/dist/src/adaptive/kv-control.js.map +1 -1
  5. package/dist/src/adaptive/picker.d.ts +8 -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 +14 -5
  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 +28 -1
  16. package/dist/src/context-manager.d.ts.map +1 -1
  17. package/dist/src/context-manager.js +42 -0
  18. package/dist/src/context-manager.js.map +1 -1
  19. package/dist/src/index.d.ts +3 -2
  20. package/dist/src/index.d.ts.map +1 -1
  21. package/dist/src/index.js +1 -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/strategies/autobiographical.d.ts +223 -2
  28. package/dist/src/strategies/autobiographical.d.ts.map +1 -1
  29. package/dist/src/strategies/autobiographical.js +1487 -142
  30. package/dist/src/strategies/autobiographical.js.map +1 -1
  31. package/dist/src/strategies/index.d.ts +1 -1
  32. package/dist/src/strategies/index.d.ts.map +1 -1
  33. package/dist/src/strategies/index.js.map +1 -1
  34. package/dist/src/strategies/knowledge.d.ts +8 -0
  35. package/dist/src/strategies/knowledge.d.ts.map +1 -1
  36. package/dist/src/strategies/knowledge.js +23 -1
  37. package/dist/src/strategies/knowledge.js.map +1 -1
  38. package/dist/src/types/strategy.d.ts +89 -5
  39. package/dist/src/types/strategy.d.ts.map +1 -1
  40. package/dist/src/types/strategy.js.map +1 -1
  41. package/dist/test/adaptive/doc-plus-chat.test.js +7 -3
  42. package/dist/test/adaptive/doc-plus-chat.test.js.map +1 -1
  43. package/dist/test/adaptive/hard-fail.test.js +103 -0
  44. package/dist/test/adaptive/hard-fail.test.js.map +1 -1
  45. package/dist/test/adaptive/ingestion.test.js +3 -1
  46. package/dist/test/adaptive/ingestion.test.js.map +1 -1
  47. package/dist/test/adaptive/kv-control.test.js +17 -11
  48. package/dist/test/adaptive/kv-control.test.js.map +1 -1
  49. package/dist/test/adaptive/single-path-solve.test.d.ts +16 -0
  50. package/dist/test/adaptive/single-path-solve.test.d.ts.map +1 -0
  51. package/dist/test/adaptive/single-path-solve.test.js +204 -0
  52. package/dist/test/adaptive/single-path-solve.test.js.map +1 -0
  53. package/dist/test/anti-redundancy-budget.test.d.ts +17 -0
  54. package/dist/test/anti-redundancy-budget.test.d.ts.map +1 -0
  55. package/dist/test/anti-redundancy-budget.test.js +197 -0
  56. package/dist/test/anti-redundancy-budget.test.js.map +1 -0
  57. package/dist/test/chunk-persistence.test.d.ts +29 -0
  58. package/dist/test/chunk-persistence.test.d.ts.map +1 -0
  59. package/dist/test/chunk-persistence.test.js +290 -0
  60. package/dist/test/chunk-persistence.test.js.map +1 -0
  61. package/dist/test/compression-dedup.test.d.ts +20 -0
  62. package/dist/test/compression-dedup.test.d.ts.map +1 -0
  63. package/dist/test/compression-dedup.test.js +92 -0
  64. package/dist/test/compression-dedup.test.js.map +1 -0
  65. package/dist/test/compression-shape-invariants.test.js +40 -3
  66. package/dist/test/compression-shape-invariants.test.js.map +1 -1
  67. package/dist/test/head-window-order.test.d.ts +19 -0
  68. package/dist/test/head-window-order.test.d.ts.map +1 -0
  69. package/dist/test/head-window-order.test.js +159 -0
  70. package/dist/test/head-window-order.test.js.map +1 -0
  71. package/dist/test/image-strip-render-stats.test.js +25 -3
  72. package/dist/test/image-strip-render-stats.test.js.map +1 -1
  73. package/dist/test/knowledge-tool-boundary.test.d.ts +14 -0
  74. package/dist/test/knowledge-tool-boundary.test.d.ts.map +1 -0
  75. package/dist/test/knowledge-tool-boundary.test.js +93 -0
  76. package/dist/test/knowledge-tool-boundary.test.js.map +1 -0
  77. package/dist/test/l1-holdback.test.d.ts +15 -0
  78. package/dist/test/l1-holdback.test.d.ts.map +1 -0
  79. package/dist/test/l1-holdback.test.js +119 -0
  80. package/dist/test/l1-holdback.test.js.map +1 -0
  81. package/dist/test/merge-contiguity.test.d.ts +11 -0
  82. package/dist/test/merge-contiguity.test.d.ts.map +1 -0
  83. package/dist/test/merge-contiguity.test.js +82 -0
  84. package/dist/test/merge-contiguity.test.js.map +1 -0
  85. package/dist/test/message-store-window.test.d.ts +13 -0
  86. package/dist/test/message-store-window.test.d.ts.map +1 -0
  87. package/dist/test/message-store-window.test.js +177 -0
  88. package/dist/test/message-store-window.test.js.map +1 -0
  89. package/dist/test/speculation-cap.test.js +4 -0
  90. package/dist/test/speculation-cap.test.js.map +1 -1
  91. package/dist/test/strategy-persistence.test.js +41 -0
  92. package/dist/test/strategy-persistence.test.js.map +1 -1
  93. package/dist/test/summary-log-consistency.test.d.ts +17 -0
  94. package/dist/test/summary-log-consistency.test.d.ts.map +1 -0
  95. package/dist/test/summary-log-consistency.test.js +102 -0
  96. package/dist/test/summary-log-consistency.test.js.map +1 -0
  97. package/dist/test/tool-pairing-invariant.test.d.ts +15 -0
  98. package/dist/test/tool-pairing-invariant.test.d.ts.map +1 -0
  99. package/dist/test/tool-pairing-invariant.test.js +225 -0
  100. package/dist/test/tool-pairing-invariant.test.js.map +1 -0
  101. package/dist/tsconfig.tsbuildinfo +1 -1
  102. package/package.json +11 -3
  103. package/src/adaptive/kv-control.ts +509 -184
  104. package/src/adaptive/picker.ts +8 -0
  105. package/src/adaptive/strategies/kv-stable.ts +22 -10
  106. package/src/context-log.ts +11 -0
  107. package/src/context-manager.ts +48 -2
  108. package/src/index.ts +3 -2
  109. package/src/message-store.ts +202 -9
  110. package/src/strategies/autobiographical.ts +1576 -166
  111. package/src/strategies/index.ts +1 -1
  112. package/src/strategies/knowledge.ts +25 -1
  113. package/src/types/strategy.ts +97 -5
@@ -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
+ * 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"}
@@ -0,0 +1,197 @@
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
+ import { describe, it, before, after } from 'node:test';
17
+ import assert from 'node:assert';
18
+ import { rmSync, existsSync } from 'node:fs';
19
+ import { ContextManager, KnowledgeStrategy } from '../src/index.js';
20
+ const TEST_STORE_PATH = './test-anti-redundancy-budget';
21
+ function cleanup() {
22
+ if (existsSync(TEST_STORE_PATH)) {
23
+ rmSync(TEST_STORE_PATH, { recursive: true, force: true });
24
+ }
25
+ }
26
+ describe('Anti-redundancy vs budget cap (memory-hole repair)', () => {
27
+ before(() => cleanup());
28
+ after(() => cleanup());
29
+ it('re-includes an excluded L2 when the budget drops its L1 children', async () => {
30
+ cleanup();
31
+ const strategy = new KnowledgeStrategy({
32
+ targetChunkTokens: 20, // research max = 40 → one tool pair per chunk
33
+ headWindowTokens: 0,
34
+ recentWindowTokens: 0,
35
+ autoTickOnNewMessage: false,
36
+ // Tight L1 budget: research cap = 0.3 * 1000 = 300 tokens → only 3 of
37
+ // the 10 research L1s (100 tokens each) survive selection.
38
+ l1BudgetTokens: 1000,
39
+ l2BudgetTokens: 0,
40
+ l3BudgetTokens: 0,
41
+ researchL1BudgetCap: 0.3,
42
+ });
43
+ const manager = await ContextManager.open({
44
+ path: TEST_STORE_PATH,
45
+ strategy,
46
+ });
47
+ // 10 research tool pairs → 10 chunks of [tool_use, tool_result].
48
+ for (let k = 0; k < 10; k++) {
49
+ manager.addMessage('Claude', [
50
+ { type: 'tool_use', id: `tu-${k}`, name: 'mcpl:search', input: { q: 'x'.repeat(120) } },
51
+ ]);
52
+ manager.addMessage('User', [
53
+ { type: 'tool_result', toolUseId: `tu-${k}`, content: 'r'.repeat(120) },
54
+ ]);
55
+ }
56
+ const s = strategy;
57
+ const internals = manager;
58
+ s.rebuildChunks(internals.messageStore);
59
+ assert.ok(s.chunks.length >= 6, `need several chunks to exercise the cap, got ${s.chunks.length}`);
60
+ // Inject one research L1 per chunk (sourceIds exactly matching the chunk
61
+ // key, so rebuildChunks re-links them as compressed and the raw fallback
62
+ // does NOT re-emit these messages), plus one L2 covering ALL the L1s.
63
+ // The L1s are unmerged — the candidate shown-set contains all of them, so
64
+ // pre-fix anti-redundancy excludes the L2 outright.
65
+ const l1Ids = [];
66
+ const allMsgIds = [];
67
+ s.chunks.forEach((chunk, i) => {
68
+ const msgIds = chunk.messages.map(m => m.id);
69
+ allMsgIds.push(...msgIds);
70
+ const id = `L1-${i}`;
71
+ l1Ids.push(id);
72
+ s.summaries.push({
73
+ id,
74
+ level: 1,
75
+ content: `[[R${i}]] research memory ${i}`,
76
+ tokens: 100,
77
+ sourceLevel: 0,
78
+ sourceIds: msgIds,
79
+ sourceRange: { first: msgIds[0], last: msgIds[msgIds.length - 1] },
80
+ created: Date.now(),
81
+ phaseType: 'research',
82
+ });
83
+ });
84
+ s.summaries.push({
85
+ id: 'L2-0',
86
+ level: 2,
87
+ content: '[[L2COVER]] consolidated research memory',
88
+ tokens: 150,
89
+ sourceLevel: 1,
90
+ sourceIds: l1Ids,
91
+ sourceRange: { first: allMsgIds[0], last: allMsgIds[allMsgIds.length - 1] },
92
+ created: Date.now(),
93
+ });
94
+ // Render with a generous overall budget — the hole is created by the
95
+ // research cap, not by overall exhaustion.
96
+ const entries = strategy.select(internals.messageStore.createView(), internals.contextLog.createView(), { maxTokens: 50000, reserveForResponse: 0 });
97
+ const renderedText = entries
98
+ .map(e => e.content.filter(b => b.type === 'text').map(b => b.text).join('\n'))
99
+ .join('\n');
100
+ const rawMsgIds = new Set(entries.map(e => e.sourceMessageId).filter(Boolean));
101
+ // Which L1s made it?
102
+ const shownL1Indexes = new Set();
103
+ for (let i = 0; i < l1Ids.length; i++) {
104
+ if (renderedText.includes(`[[R${i}]]`))
105
+ shownL1Indexes.add(i);
106
+ }
107
+ assert.ok(shownL1Indexes.size < l1Ids.length, 'test setup: the research cap should drop at least one L1 (else nothing to repair)');
108
+ // The core assertion: every source message is represented at SOME level —
109
+ // raw, via its L1, or via the L2 that covers everything.
110
+ const l2Shown = renderedText.includes('[[L2COVER]]');
111
+ s.chunks.forEach((chunk, i) => {
112
+ for (const m of chunk.messages) {
113
+ const represented = rawMsgIds.has(m.id) || shownL1Indexes.has(i) || l2Shown;
114
+ assert.ok(represented, `message ${m.id} (chunk ${i}) is represented at no level — silent memory hole`);
115
+ }
116
+ });
117
+ // And specifically: since the cap dropped some L1s, the parent L2 must
118
+ // have been re-included.
119
+ assert.ok(l2Shown, 'excluded L2 must be re-included when its children are budget-dropped');
120
+ await manager.close();
121
+ });
122
+ it('bounds coverage repairs by a per-level allowance and warns on a corrupted store', async () => {
123
+ cleanup();
124
+ const strategy = new KnowledgeStrategy({
125
+ targetChunkTokens: 20,
126
+ headWindowTokens: 0,
127
+ recentWindowTokens: 0,
128
+ autoTickOnNewMessage: false,
129
+ l1BudgetTokens: 1000,
130
+ l2BudgetTokens: 0, // zero level budget → repair falls back to the floor
131
+ l3BudgetTokens: 0,
132
+ researchL1BudgetCap: 0.3, // drops most L1s → every covering L2 is a repair candidate
133
+ });
134
+ const manager = await ContextManager.open({
135
+ path: TEST_STORE_PATH,
136
+ strategy,
137
+ });
138
+ for (let k = 0; k < 10; k++) {
139
+ manager.addMessage('Claude', [
140
+ { type: 'tool_use', id: `tu-${k}`, name: 'mcpl:search', input: { q: 'x'.repeat(120) } },
141
+ ]);
142
+ manager.addMessage('User', [
143
+ { type: 'tool_result', toolUseId: `tu-${k}`, content: 'r'.repeat(120) },
144
+ ]);
145
+ }
146
+ const s = strategy;
147
+ const internals = manager;
148
+ s.rebuildChunks(internals.messageStore);
149
+ const l1Ids = [];
150
+ const allMsgIds = [];
151
+ s.chunks.forEach((chunk, i) => {
152
+ const msgIds = chunk.messages.map(m => m.id);
153
+ allMsgIds.push(...msgIds);
154
+ const id = `L1-${i}`;
155
+ l1Ids.push(id);
156
+ s.summaries.push({
157
+ id, level: 1, content: `[[R${i}]] research memory ${i}`, tokens: 100,
158
+ sourceLevel: 0, sourceIds: msgIds,
159
+ sourceRange: { first: msgIds[0], last: msgIds[msgIds.length - 1] },
160
+ created: Date.now(), phaseType: 'research',
161
+ });
162
+ });
163
+ // Simulate a store damaged mid-merge: MANY excluded L2s, each covering all
164
+ // L1s (so each is individually a repair candidate once the cap drops L1s).
165
+ const L2_COUNT = 6;
166
+ for (let j = 0; j < L2_COUNT; j++) {
167
+ s.summaries.push({
168
+ id: `L2-${j}`, level: 2, content: `[[L2-${j}]] consolidated research ${j}`, tokens: 150,
169
+ sourceLevel: 1, sourceIds: l1Ids,
170
+ sourceRange: { first: allMsgIds[0], last: allMsgIds[allMsgIds.length - 1] },
171
+ created: Date.now(),
172
+ });
173
+ }
174
+ const warnings = [];
175
+ const origWarn = console.warn;
176
+ console.warn = (...args) => { warnings.push(args.join(' ')); };
177
+ let entries;
178
+ try {
179
+ // Small overall budget → floor allowance (0.05 * maxTokens) is small, so
180
+ // only a couple of the six covering L2s can be re-included.
181
+ entries = strategy.select(internals.messageStore.createView(), internals.contextLog.createView(), { maxTokens: 8000, reserveForResponse: 0 });
182
+ }
183
+ finally {
184
+ console.warn = origWarn;
185
+ }
186
+ const renderedText = entries
187
+ .map(e => e.content.filter(b => b.type === 'text').map(b => b.text).join('\n'))
188
+ .join('\n');
189
+ const l2ShownCount = Array.from({ length: L2_COUNT }, (_, j) => j)
190
+ .filter(j => renderedText.includes(`[[L2-${j}]]`)).length;
191
+ assert.ok(l2ShownCount >= 1, 'at least one covering L2 should still be repaired');
192
+ assert.ok(l2ShownCount < L2_COUNT, `repair allowance must cap re-inclusion, but all ${L2_COUNT} L2s rendered`);
193
+ assert.ok(warnings.some(w => w.includes('coverage-repair allowance exceeded')), 'a corrupted store exceeding the repair allowance must warn');
194
+ await manager.close();
195
+ });
196
+ });
197
+ //# sourceMappingURL=anti-redundancy-budget.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anti-redundancy-budget.test.js","sourceRoot":"","sources":["../../test/anti-redundancy-budget.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,QAAQ,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AACxD,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AAIpE,MAAM,eAAe,GAAG,+BAA+B,CAAC;AAExD,SAAS,OAAO;IACd,IAAI,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QAChC,MAAM,CAAC,eAAe,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC;AAED,QAAQ,CAAC,oDAAoD,EAAE,GAAG,EAAE;IAClE,MAAM,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;IACxB,KAAK,CAAC,GAAG,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC;IAEvB,EAAE,CAAC,kEAAkE,EAAE,KAAK,IAAI,EAAE;QAChF,OAAO,EAAE,CAAC;QACV,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CAAC;YACrC,iBAAiB,EAAE,EAAE,EAAE,8CAA8C;YACrE,gBAAgB,EAAE,CAAC;YACnB,kBAAkB,EAAE,CAAC;YACrB,oBAAoB,EAAE,KAAK;YAC3B,sEAAsE;YACtE,2DAA2D;YAC3D,cAAc,EAAE,IAAI;YACpB,cAAc,EAAE,CAAC;YACjB,cAAc,EAAE,CAAC;YACjB,mBAAmB,EAAE,GAAG;SACzB,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC;YACxC,IAAI,EAAE,eAAe;YACrB,QAAQ;SACT,CAAC,CAAC;QAEH,iEAAiE;QACjE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5B,OAAO,CAAC,UAAU,CAAC,QAAQ,EAAE;gBAC3B,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE;aACtE,CAAC,CAAC;YACrB,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE;gBACzB,EAAE,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;aACtD,CAAC,CAAC;QACvB,CAAC;QAED,MAAM,CAAC,GAAG,QAIT,CAAC;QACF,MAAM,SAAS,GAAG,OAGjB,CAAC;QACF,CAAC,CAAC,aAAa,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QAExC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,EAAE,gDAAgD,CAAC,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CAAC;QAEnG,yEAAyE;QACzE,yEAAyE;QACzE,sEAAsE;QACtE,0EAA0E;QAC1E,oDAAoD;QACpD,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;YAC5B,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC7C,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;YAC1B,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC;YACrB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC;gBACf,EAAE;gBACF,KAAK,EAAE,CAAC;gBACR,OAAO,EAAE,MAAM,CAAC,sBAAsB,CAAC,EAAE;gBACzC,MAAM,EAAE,GAAG;gBACX,WAAW,EAAE,CAAC;gBACd,SAAS,EAAE,MAAM;gBACjB,WAAW,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE;gBAClE,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE;gBACnB,SAAS,EAAE,UAAU;aACtB,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC;YACf,EAAE,EAAE,MAAM;YACV,KAAK,EAAE,CAAC;YACR,OAAO,EAAE,0CAA0C;YACnD,MAAM,EAAE,GAAG;YACX,WAAW,EAAE,CAAC;YACd,SAAS,EAAE,KAAK;YAChB,WAAW,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE;YAC3E,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE;SACpB,CAAC,CAAC;QAEH,qEAAqE;QACrE,2CAA2C;QAC3C,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAC7B,SAAS,CAAC,YAAY,CAAC,UAAU,EAAW,EAC5C,SAAS,CAAC,UAAU,CAAC,UAAU,EAAW,EAC1C,EAAE,SAAS,EAAE,KAAK,EAAE,kBAAkB,EAAE,CAAC,EAAE,CAC1B,CAAC;QAEpB,MAAM,YAAY,GAAG,OAAO;aACzB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAE,CAAsB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;aACpG,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,MAAM,SAAS,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;QAE/E,qBAAqB;QACrB,MAAM,cAAc,GAAG,IAAI,GAAG,EAAU,CAAC;QACzC,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YACtC,IAAI,YAAY,CAAC,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC;gBAAE,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAChE,CAAC;QACD,MAAM,CAAC,EAAE,CACP,cAAc,CAAC,IAAI,GAAG,KAAK,CAAC,MAAM,EAClC,mFAAmF,CACpF,CAAC;QAEF,0EAA0E;QAC1E,yDAAyD;QACzD,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;QACrD,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;YAC5B,KAAK,MAAM,CAAC,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;gBAC/B,MAAM,WAAW,GACf,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,EAAW,CAAC,IAAI,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC;gBACnE,MAAM,CAAC,EAAE,CACP,WAAW,EACX,WAAW,CAAC,CAAC,EAAE,WAAW,CAAC,mDAAmD,CAC/E,CAAC;YACJ,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,uEAAuE;QACvE,yBAAyB;QACzB,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,sEAAsE,CAAC,CAAC;QAE3F,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iFAAiF,EAAE,KAAK,IAAI,EAAE;QAC/F,OAAO,EAAE,CAAC;QACV,MAAM,QAAQ,GAAG,IAAI,iBAAiB,CAAC;YACrC,iBAAiB,EAAE,EAAE;YACrB,gBAAgB,EAAE,CAAC;YACnB,kBAAkB,EAAE,CAAC;YACrB,oBAAoB,EAAE,KAAK;YAC3B,cAAc,EAAE,IAAI;YACpB,cAAc,EAAE,CAAC,EAAE,qDAAqD;YACxE,cAAc,EAAE,CAAC;YACjB,mBAAmB,EAAE,GAAG,EAAE,2DAA2D;SACtF,CAAC,CAAC;QAEH,MAAM,OAAO,GAAG,MAAM,cAAc,CAAC,IAAI,CAAC;YACxC,IAAI,EAAE,eAAe;YACrB,QAAQ;SACT,CAAC,CAAC;QAEH,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,EAAE,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5B,OAAO,CAAC,UAAU,CAAC,QAAQ,EAAE;gBAC3B,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAAE,EAAE,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,EAAE;aACtE,CAAC,CAAC;YACrB,OAAO,CAAC,UAAU,CAAC,MAAM,EAAE;gBACzB,EAAE,IAAI,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,CAAC,EAAE,EAAE,OAAO,EAAE,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;aACtD,CAAC,CAAC;QACvB,CAAC;QAED,MAAM,CAAC,GAAG,QAIT,CAAC;QACF,MAAM,SAAS,GAAG,OAGjB,CAAC;QACF,CAAC,CAAC,aAAa,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC;QAExC,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,MAAM,SAAS,GAAa,EAAE,CAAC;QAC/B,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,CAAC,EAAE,EAAE;YAC5B,MAAM,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC7C,SAAS,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAC;YAC1B,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,CAAC;YACrB,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YACf,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC;gBACf,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,sBAAsB,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG;gBACpE,WAAW,EAAE,CAAC,EAAE,SAAS,EAAE,MAAM;gBACjC,WAAW,EAAE,EAAE,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE;gBAClE,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,UAAU;aAC3C,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QAEH,2EAA2E;QAC3E,2EAA2E;QAC3E,MAAM,QAAQ,GAAG,CAAC,CAAC;QACnB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,QAAQ,EAAE,CAAC,EAAE,EAAE,CAAC;YAClC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC;gBACf,EAAE,EAAE,MAAM,CAAC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,CAAC,4BAA4B,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG;gBACvF,WAAW,EAAE,CAAC,EAAE,SAAS,EAAE,KAAK;gBAChC,WAAW,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE;gBAC3E,OAAO,EAAE,IAAI,CAAC,GAAG,EAAE;aACpB,CAAC,CAAC;QACL,CAAC;QAED,MAAM,QAAQ,GAAa,EAAE,CAAC;QAC9B,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC;QAC9B,OAAO,CAAC,IAAI,GAAG,CAAC,GAAG,IAAe,EAAE,EAAE,GAAG,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1E,IAAI,OAAuB,CAAC;QAC5B,IAAI,CAAC;YACH,yEAAyE;YACzE,4DAA4D;YAC5D,OAAO,GAAG,QAAQ,CAAC,MAAM,CACvB,SAAS,CAAC,YAAY,CAAC,UAAU,EAAW,EAC5C,SAAS,CAAC,UAAU,CAAC,UAAU,EAAW,EAC1C,EAAE,SAAS,EAAE,IAAI,EAAE,kBAAkB,EAAE,CAAC,EAAE,CACzB,CAAC;QACtB,CAAC;gBAAS,CAAC;YACT,OAAO,CAAC,IAAI,GAAG,QAAQ,CAAC;QAC1B,CAAC;QAED,MAAM,YAAY,GAAG,OAAO;aACzB,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAE,CAAsB,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;aACpG,IAAI,CAAC,IAAI,CAAC,CAAC;QACd,MAAM,YAAY,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;aAC/D,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC;QAE5D,MAAM,CAAC,EAAE,CAAC,YAAY,IAAI,CAAC,EAAE,mDAAmD,CAAC,CAAC;QAClF,MAAM,CAAC,EAAE,CAAC,YAAY,GAAG,QAAQ,EAAE,mDAAmD,QAAQ,eAAe,CAAC,CAAC;QAC/G,MAAM,CAAC,EAAE,CACP,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,oCAAoC,CAAC,CAAC,EACpE,4DAA4D,CAC7D,CAAC;QAEF,MAAM,OAAO,CAAC,KAAK,EAAE,CAAC;IACxB,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Regression tests for chunk-boundary persistence + close-then-compress.
3
+ *
4
+ * Background (Mythos duplication incident, 2026-07; fleet audit):
5
+ * 1. Chunk boundaries were recomputed from a running token sum on every
6
+ * rebuild; "already compressed" was recovered only by EXACT
7
+ * message-ID-set match against persisted L1 sourceIds. Any boundary
8
+ * shift (config change, restart, message mutation, chain break)
9
+ * re-keyed the tail → mass duplicate L1s over already-lived ground.
10
+ * 2. The trailing PARTIAL chunk (>=4 messages, under targetChunkTokens)
11
+ * was compressed eagerly on every rebuild while it grew → families of
12
+ * prefix-generation L1s (same start, growing span), all retained, all
13
+ * merged upward into the same L2 (content multiplication).
14
+ *
15
+ * New contract pinned here:
16
+ * - A chunk is compressed only after it CLOSES (running sum reaches
17
+ * targetChunkTokens); the trailing partial chunk is never compressed.
18
+ * - Closing a chunk persists a ChunkRecord to the `autobio:chunks`
19
+ * chronicle state slot; persisted records OWN the past — rebuilds and
20
+ * restarts never re-chunk covered ground, regardless of config drift.
21
+ * - L1 production refuses to overlap an existing L1 (strict guard).
22
+ * - If most records resolve to zero live messages (chain-break
23
+ * signature), compression fails CLOSED (no re-chunking of history).
24
+ * - Stores from before this change migrate lazily: records are
25
+ * synthesized from existing L1 sourceIds, longest generation per
26
+ * prefix family.
27
+ */
28
+ export {};
29
+ //# sourceMappingURL=chunk-persistence.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"chunk-persistence.test.d.ts","sourceRoot":"","sources":["../../test/chunk-persistence.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG"}