blun-king-cli 9.1.536 → 9.1.561

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 (129) hide show
  1. package/LIESMICH.txt +13 -869
  2. package/README.md +41 -833
  3. package/bin/assistant-message-offload-policy.cjs +3 -1
  4. package/bin/compaction-transaction-policy.cjs +122 -0
  5. package/bin/context-performance-policy.cjs +2 -5
  6. package/bin/context-pressure-policy.cjs +20 -0
  7. package/bin/cron-run-output.cjs +45 -0
  8. package/bin/cron-run-store.cjs +145 -0
  9. package/bin/default-model-output-budget-policy.cjs +28 -0
  10. package/bin/durable-task-resume-policy.cjs +130 -0
  11. package/bin/durable-task-resume-runtime.cjs +117 -0
  12. package/bin/durable-task-resume-store.cjs +88 -0
  13. package/bin/editable-tool-approval-policy.cjs +540 -0
  14. package/bin/editable-tool-approval-runtime.cjs +99 -0
  15. package/bin/file-observation-policy.cjs +133 -0
  16. package/bin/html-to-research-markdown.cjs +146 -0
  17. package/bin/launcher-runtime.js +0 -1
  18. package/bin/micro-compaction-policy.cjs +64 -0
  19. package/bin/mnemo-connect-heartbeat.cjs +1 -3
  20. package/bin/programmatic-tool-runtime.mjs +330 -4
  21. package/bin/read-continuation-policy.cjs +36 -5
  22. package/bin/retry-checkpoint-policy.cjs +13 -0
  23. package/bin/scoped-cron-run-policy.cjs +358 -0
  24. package/bin/session-checkpoint-policy.cjs +25 -0
  25. package/bin/startup-preferences.cjs +4 -3
  26. package/bin/structured-agent-swarm-output.cjs +325 -0
  27. package/bin/subagent-context-fork-policy.cjs +155 -0
  28. package/bin/subagent-skill-policy.cjs +204 -0
  29. package/bin/telegram-approval-relay.cjs +2 -1
  30. package/bin/tool-file-persistence.cjs +141 -0
  31. package/bin/tool-result-offload-policy.cjs +25 -33
  32. package/bin/turn-thinking-policy.cjs +2 -26
  33. package/bin/update-notice.js +30 -18
  34. package/bin/user-message-offload-policy.cjs +3 -1
  35. package/blun.mjs +1564 -640
  36. package/codebase-index/README.md +12 -0
  37. package/codebase-index/codebase_index.py +129 -18
  38. package/package.json +23 -58
  39. package/telegram-plugin/bin/telegram-mnemo-capture.cjs +1 -3
  40. package/telegram-plugin/bin/telegram-typing-keepalive.cjs +89 -0
  41. package/telegram-plugin/dist/bridge.mjs +8 -1
  42. package/CHANGELOG.md +0 -321
  43. package/agent-spine-plugin/CHANGELOG.md +0 -406
  44. package/agent-spine-plugin/CONTRIBUTING.md +0 -52
  45. package/agent-spine-plugin/README.md +0 -344
  46. package/agent-spine-plugin/SECURITY.md +0 -47
  47. package/agent-spine-plugin/docs/acceptance.md +0 -61
  48. package/agent-spine-plugin/docs/architecture.md +0 -183
  49. package/agent-spine-plugin/docs/attention.md +0 -121
  50. package/agent-spine-plugin/docs/automatic-continuity.md +0 -79
  51. package/agent-spine-plugin/docs/channel-runtime.md +0 -92
  52. package/agent-spine-plugin/docs/coordination.md +0 -138
  53. package/agent-spine-plugin/docs/feed-transport.md +0 -99
  54. package/agent-spine-plugin/docs/gateway-runtime.md +0 -116
  55. package/agent-spine-plugin/docs/harness-reference.md +0 -45
  56. package/agent-spine-plugin/docs/host-integration.md +0 -129
  57. package/agent-spine-plugin/docs/https-transport.md +0 -116
  58. package/agent-spine-plugin/docs/learning.md +0 -133
  59. package/agent-spine-plugin/docs/object-transport.md +0 -93
  60. package/agent-spine-plugin/docs/peer-transport.md +0 -88
  61. package/agent-spine-plugin/docs/preflight-recall.md +0 -69
  62. package/agent-spine-plugin/docs/preservation-contract.md +0 -53
  63. package/agent-spine-plugin/docs/quality-gates.md +0 -50
  64. package/agent-spine-plugin/docs/relationships.md +0 -73
  65. package/agent-spine-plugin/docs/releasing.md +0 -83
  66. package/agent-spine-plugin/docs/roadmap.md +0 -307
  67. package/agent-spine-plugin/docs/selfstarter.md +0 -88
  68. package/agent-spine-plugin/docs/session-briefing.md +0 -74
  69. package/agent-spine-plugin/docs/shared-memory.md +0 -259
  70. package/agent-spine-plugin/docs/source-roots.md +0 -86
  71. package/agent-spine-plugin/docs/sqlite-transport.md +0 -76
  72. package/agent-spine-plugin/scripts/check-hosts.js +0 -195
  73. package/agent-spine-plugin/scripts/check-install.js +0 -569
  74. package/agent-spine-plugin/scripts/check-syntax.js +0 -29
  75. package/agent-spine-plugin/scripts/github-actions.js +0 -11
  76. package/agent-spine-plugin/scripts/release-check.js +0 -128
  77. package/agent-spine-plugin/scripts/run-acceptance.js +0 -19
  78. package/agent-spine-plugin/scripts/run-checks.js +0 -46
  79. package/agent-spine-plugin/scripts/run-tests-hermetic.js +0 -73
  80. package/agent-spine-plugin/spine-example/1-identity.md +0 -12
  81. package/agent-spine-plugin/spine-example/2-voice.md +0 -6
  82. package/agent-spine-plugin/spine-example/3-conduct.md +0 -8
  83. package/agent-spine-plugin/spine-example/4-history.md +0 -4
  84. package/bin/empty-response-retry-policy.cjs +0 -29
  85. package/bin/fredrik-glm-provider.cjs +0 -256
  86. package/bin/package-regression-policy.cjs +0 -77
  87. package/fredrik-glm-profile.toml.example +0 -26
  88. package/release-planned-removals.json +0 -15
  89. package/scripts/check-active-profile-plugin-startup.js +0 -36
  90. package/scripts/check-active-work-steer-regression.js +0 -46
  91. package/scripts/check-approval-observability-regression.js +0 -111
  92. package/scripts/check-approval-queue-shortcuts-regression.js +0 -65
  93. package/scripts/check-bundled-agent-spine-regression.js +0 -48
  94. package/scripts/check-codebase-search-packaging-regression.js +0 -92
  95. package/scripts/check-copy-command-regression.js +0 -74
  96. package/scripts/check-current-turn-read-pin-mutation-regression.js +0 -72
  97. package/scripts/check-current-turn-read-pin-regression.js +0 -94
  98. package/scripts/check-deepseek-native-max-regression.js +0 -49
  99. package/scripts/check-empty-response-effort-downgrade-regression.js +0 -48
  100. package/scripts/check-fredrik-glm-mutation-regression.js +0 -18
  101. package/scripts/check-fredrik-glm-regression.js +0 -169
  102. package/scripts/check-historical-tool-result-preview-regression.js +0 -77
  103. package/scripts/check-history-pressure-offload-regression.js +0 -77
  104. package/scripts/check-mcp-startup-wait-budget.js +0 -48
  105. package/scripts/check-package-regression.js +0 -38
  106. package/scripts/check-plugin-startup-regression.js +0 -53
  107. package/scripts/check-programmatic-context-isolation-regression.js +0 -193
  108. package/scripts/check-programmatic-tool-regression.js +0 -294
  109. package/scripts/check-queue-controls-regression.js +0 -189
  110. package/scripts/check-release-metadata.js +0 -103
  111. package/scripts/check-reload-agent-spine-regression.js +0 -76
  112. package/scripts/check-resume-replay-regression.js +0 -102
  113. package/scripts/check-session-cancel-regression.js +0 -43
  114. package/scripts/check-session-picker-resume-metrics-regression.js +0 -97
  115. package/scripts/check-session-start-hook-context-regression.js +0 -228
  116. package/scripts/check-shell-terminal-isolation-regression.js +0 -81
  117. package/scripts/check-slash-escape-regression.js +0 -89
  118. package/scripts/check-startup-swarm-command-regression.js +0 -24
  119. package/scripts/check-structured-subagent-output-regression.js +0 -331
  120. package/scripts/check-telegram-bridge-watchdog.js +0 -60
  121. package/scripts/check-telegram-direct-work-resume-regression.js +0 -53
  122. package/scripts/check-telegram-loop-exactly-once-regression.js +0 -71
  123. package/scripts/check-todo-loop-regression.js +0 -78
  124. package/scripts/check-todo-progress-regression.js +0 -416
  125. package/scripts/check-todo-recovery-catalog-regression.js +0 -50
  126. package/scripts/check-tool-schema-capacity-regression.js +0 -40
  127. package/scripts/programmatic-tool-runtime.test.mjs +0 -365
  128. package/scripts/structured-subagent-output.test.cjs +0 -170
  129. /package/{scripts → bin}/fix-node-pty-perms.js +0 -0
@@ -1,416 +0,0 @@
1
- #!/usr/bin/env node
2
- 'use strict';
3
-
4
- const assert = require('node:assert/strict');
5
- const { spawnSync } = require('node:child_process');
6
- const fs = require('node:fs');
7
- const os = require('node:os');
8
- const path = require('node:path');
9
-
10
- const packageRoot = path.resolve(__dirname, '..');
11
- const bundlePath = process.env.BLUN_TODO_PROGRESS_BUNDLE_UNDER_TEST
12
- ? path.resolve(process.env.BLUN_TODO_PROGRESS_BUNDLE_UNDER_TEST)
13
- : path.join(packageRoot, 'blun.mjs');
14
- const bundle = fs.readFileSync(bundlePath, 'utf8');
15
-
16
- const policyPath = process.env.BLUN_TODO_PROGRESS_POLICY_UNDER_TEST
17
- ? path.resolve(process.env.BLUN_TODO_PROGRESS_POLICY_UNDER_TEST)
18
- : path.join(packageRoot, 'bin', 'todo-list-turn-policy.cjs');
19
-
20
- const {
21
- MAX_TODO_ITEMS,
22
- assessTodoListBounds,
23
- assessTodoMaintenanceUpdate,
24
- canonicalStoredTodos,
25
- } = require(policyPath);
26
- const { normalizeTodoProgressState } = require(path.join(
27
- packageRoot,
28
- 'bin',
29
- 'agent-resume-snapshot.cjs',
30
- ));
31
-
32
- function todos(count, status = 'pending') {
33
- return Array.from({ length: count }, (_, index) => ({
34
- title: `Task ${String(index + 1)}`,
35
- status: index === 0 && status === 'pending' ? 'in_progress' : status,
36
- }));
37
- }
38
-
39
- function between(startNeedle, endNeedle) {
40
- const start = bundle.indexOf(startNeedle);
41
- assert.notEqual(start, -1, `TODO_PROGRESS: missing bundle start ${startNeedle}`);
42
- const end = bundle.indexOf(endNeedle, start + startNeedle.length);
43
- assert.notEqual(end, -1, `TODO_PROGRESS: missing bundle end ${endNeedle}`);
44
- return bundle.slice(start, end);
45
- }
46
-
47
- function extractFunction(name) {
48
- const start = bundle.indexOf(`function ${name}(`);
49
- assert.notEqual(start, -1, `TODO_PROGRESS: missing function ${name}`);
50
- const open = bundle.indexOf('{', start);
51
- let depth = 0;
52
- for (let index = open; index < bundle.length; index += 1) {
53
- if (bundle[index] === '{') depth += 1;
54
- if (bundle[index] === '}') depth -= 1;
55
- if (depth === 0) return bundle.slice(start, index + 1);
56
- }
57
- assert.fail(`TODO_PROGRESS: incomplete function ${name}`);
58
- }
59
-
60
- function assertBundleContract() {
61
- assert.match(
62
- bundle,
63
- /\(\{ assessTodoListBounds, assessTodoMaintenanceUpdate, enforceSingleTodoWritePerStep, todoRefreshWorkCallLimit \} = createRequire\(import\.meta\.url\)\("\.\/bin\/todo-list-turn-policy\.cjs"\)\);/u,
64
- 'TODO_PROGRESS: bundle must import every progress-policy helper',
65
- );
66
- const prepare = between('prepareToolExecution: async (ctx) => {', 'authorizeToolExecution: async (ctx) => {');
67
- const boundsIndex = prepare.indexOf('enforceTodoListBounds(this.agent, ctx)');
68
- const goalIndex = prepare.indexOf('enforceGoalTodoPolicy(this.agent, ctx)');
69
- assert.ok(boundsIndex >= 0 && goalIndex > boundsIndex, 'TODO_PROGRESS: bounds must run before goal/idea exceptions');
70
-
71
- const evidence = between('function recordGoalTodoEvidence(', 'function goalTodoMaintenanceMode(');
72
- assert.doesNotMatch(
73
- evidence,
74
- /name === "TodoList"[\s\S]*recentEvidence = \[\]/u,
75
- 'TODO_PROGRESS: a successful unchanged refresh must not erase its evidence in finalize',
76
- );
77
- assert.match(evidence, /progress\.evidenceRevision = \(Number\(progress\.evidenceRevision\) \|\| 0\) \+ 1/u);
78
-
79
- const mode = between('function goalTodoMaintenanceMode(', 'function goalTodoMaintenanceTools(');
80
- assert.match(mode, /todoRefreshWorkCallLimit\(progress\.unchangedRefreshStreak\)/u);
81
-
82
- const enforcement = between('function enforceGoalTodoPolicy(', 'function ideaOutboundChannel(');
83
- assert.match(enforcement, /assessTodoMaintenanceUpdate\(\{/u);
84
- assert.match(enforcement, /code: "todo-maintenance-stalled"/u);
85
- assert.match(enforcement, /if \(!maintenanceUpdate\.preserveRecentEvidence\) progress\.recentEvidence = \[\]/u);
86
- assert.match(enforcement, /todoRefreshWorkCallLimit\(progress\.unchangedRefreshStreak\)/u);
87
- assert.doesNotMatch(bundle, /const GOAL_TODO_REFRESH_WORK_CALL_LIMIT = 8/u);
88
- assert.doesNotMatch(bundle, /TodoList is unchanged after extended work/u);
89
- assert.match(bundle, /If no boundary is proven, preserve the list unchanged; never invent progress\./u);
90
-
91
- const resumeSource = fs.readFileSync(
92
- path.join(packageRoot, 'bin', 'agent-resume-snapshot.cjs'),
93
- 'utf8',
94
- );
95
- assert.match(resumeSource, /todoProgress: normalizeTodoProgressState\(agent\.goalTodoPolicyState\) \?\? null/u);
96
- assert.match(resumeSource, /agent\.goalTodoPolicyState = normalizeTodoProgressState\(snapshot\.todoProgress\)/u);
97
- }
98
-
99
- function exerciseBundledPolicy() {
100
- const ideaTodos = (agent) => agent.tools.store.todo ?? [];
101
- const goalTodoProgressState = Function(
102
- `"use strict"; return (${extractFunction('goalTodoProgressState')});`,
103
- )();
104
- const enforceTodoListBounds = Function(
105
- 'assessTodoListBounds',
106
- 'ideaTodos',
107
- `"use strict"; return (${extractFunction('enforceTodoListBounds')});`,
108
- )(assessTodoListBounds, ideaTodos);
109
- const enforceGoalTodoPolicy = Function(
110
- 'isIdeaGoal',
111
- 'TELEGRAM_DELIVERY_TOOL_RE',
112
- 'ideaTodos',
113
- 'goalTodoProgressState',
114
- 'validInitialIdeaPlan',
115
- 'IDEA_TERMINAL_TODO_STATUSES',
116
- 'assessTodoMaintenanceUpdate',
117
- 'todoRefreshWorkCallLimit',
118
- `"use strict"; return (${extractFunction('enforceGoalTodoPolicy')});`,
119
- )(
120
- () => false,
121
- /^mcp__[^\s]*telegram[^\s]*__(?:reply|edit_message)$/iu,
122
- ideaTodos,
123
- goalTodoProgressState,
124
- () => true,
125
- Object.freeze(['done', 'blocked', 'waiting_approval', 'aborted']),
126
- assessTodoMaintenanceUpdate,
127
- require(policyPath).todoRefreshWorkCallLimit,
128
- );
129
- const goalTodoMaintenanceMode = Function(
130
- 'isIdeaGoal',
131
- 'ideaTodos',
132
- 'goalTodoProgressState',
133
- 'todoRefreshWorkCallLimit',
134
- `"use strict"; return (${extractFunction('goalTodoMaintenanceMode')});`,
135
- )(
136
- () => false,
137
- ideaTodos,
138
- goalTodoProgressState,
139
- require(policyPath).todoRefreshWorkCallLimit,
140
- );
141
-
142
- const emitted = [];
143
- const agent = {
144
- tools: { store: { todo: current.map((todo) => ({ ...todo })) } },
145
- goal: { getActiveGoal: () => ({ objective: 'exercise policy' }) },
146
- goalTodoPolicyState: {
147
- workCallsSinceRefresh: 8,
148
- refreshRequired: true,
149
- unchangedRefreshStreak: 2,
150
- recentEvidence: ['Bash succeeded: candidate.js'],
151
- evidenceRevision: 4,
152
- lastMaintenanceEvidenceRevision: 3,
153
- },
154
- emitEvent(event) { emitted.push(event); },
155
- };
156
- const unchangedContext = {
157
- toolCall: { id: 'todo-1', name: 'TodoList' },
158
- toolCalls: [{ id: 'todo-1', name: 'TodoList' }],
159
- args: { todos: current.map((todo) => ({ ...todo })) },
160
- };
161
- assert.equal(enforceTodoListBounds(agent, unchangedContext), undefined);
162
- assert.equal(enforceGoalTodoPolicy(agent, unchangedContext), undefined);
163
- assert.equal(agent.goalTodoPolicyState.unchangedRefreshStreak, 3);
164
- assert.deepEqual(agent.goalTodoPolicyState.recentEvidence, ['Bash succeeded: candidate.js']);
165
- assert.equal(agent.goalTodoPolicyState.workCallsSinceRefresh, 0);
166
- assert.equal(agent.goalTodoPolicyState.refreshRequired, false);
167
- assert.equal(emitted.length, 1);
168
- assert.equal(emitted[0].code, 'todo-maintenance-stalled');
169
- assert.equal(emitted[0].blocked, false);
170
-
171
- agent.goalTodoPolicyState.workCallsSinceRefresh = 63;
172
- assert.equal(goalTodoMaintenanceMode(agent), null, '64-call backoff must leave work available');
173
- agent.goalTodoPolicyState.workCallsSinceRefresh = 64;
174
- assert.equal(goalTodoMaintenanceMode(agent), 'refresh');
175
-
176
- agent.goalTodoPolicyState.recentEvidence = ['Write succeeded: candidate.js'];
177
- agent.goalTodoPolicyState.evidenceRevision = 5;
178
- const changedContext = {
179
- ...unchangedContext,
180
- toolCall: { id: 'todo-2', name: 'TodoList' },
181
- toolCalls: [{ id: 'todo-2', name: 'TodoList' }],
182
- args: {
183
- todos: [
184
- { title: 'Measure source', status: 'done' },
185
- { title: 'Write candidate', status: 'in_progress' },
186
- ],
187
- },
188
- };
189
- assert.equal(enforceGoalTodoPolicy(agent, changedContext), undefined);
190
- assert.equal(agent.goalTodoPolicyState.unchangedRefreshStreak, 0);
191
- assert.deepEqual(agent.goalTodoPolicyState.recentEvidence, []);
192
-
193
- const oversizedAgent = {
194
- tools: { store: { todo: [] } },
195
- };
196
- const oversized = enforceTodoListBounds(oversizedAgent, {
197
- toolCall: { name: 'TodoList' },
198
- args: { todos: todos(33) },
199
- });
200
- assert.equal(oversized.block, true);
201
- assert.match(oversized.reason, /at most 32 visible items/u);
202
- }
203
-
204
- assert.equal(MAX_TODO_ITEMS, 32, 'TODO_PROGRESS: visible list cap must be 32');
205
-
206
- const current = [
207
- { title: 'Measure source', status: 'in_progress' },
208
- { title: 'Write candidate', status: 'pending' },
209
- ];
210
-
211
- const unchangedOne = assessTodoMaintenanceUpdate({
212
- currentTodos: current,
213
- nextTodos: current,
214
- unchangedRefreshStreak: 0,
215
- recentEvidenceCount: 8,
216
- });
217
- assert.deepEqual(unchangedOne, {
218
- changed: false,
219
- unchangedRefreshStreak: 1,
220
- refreshWorkCallLimit: 16,
221
- preserveRecentEvidence: true,
222
- requireConcreteProgress: false,
223
- emitStalledWarning: false,
224
- });
225
-
226
- const unchangedTwo = assessTodoMaintenanceUpdate({
227
- currentTodos: current,
228
- nextTodos: current,
229
- unchangedRefreshStreak: unchangedOne.unchangedRefreshStreak,
230
- recentEvidenceCount: 8,
231
- });
232
- assert.equal(unchangedTwo.changed, false);
233
- assert.equal(unchangedTwo.unchangedRefreshStreak, 2);
234
- assert.equal(unchangedTwo.refreshWorkCallLimit, 32);
235
- assert.equal(unchangedTwo.preserveRecentEvidence, true);
236
- assert.equal(unchangedTwo.requireConcreteProgress, true);
237
- assert.equal(unchangedTwo.emitStalledWarning, false);
238
-
239
- const unchangedThree = assessTodoMaintenanceUpdate({
240
- currentTodos: current,
241
- nextTodos: current,
242
- unchangedRefreshStreak: unchangedTwo.unchangedRefreshStreak,
243
- recentEvidenceCount: 8,
244
- });
245
- assert.equal(unchangedThree.unchangedRefreshStreak, 3);
246
- assert.equal(unchangedThree.refreshWorkCallLimit, 64);
247
- assert.equal(unchangedThree.requireConcreteProgress, true);
248
- assert.equal(unchangedThree.emitStalledWarning, true);
249
-
250
- const unchangedWithoutEvidence = assessTodoMaintenanceUpdate({
251
- currentTodos: current,
252
- nextTodos: current,
253
- unchangedRefreshStreak: 2,
254
- recentEvidenceCount: 0,
255
- });
256
- assert.equal(unchangedWithoutEvidence.unchangedRefreshStreak, 2);
257
- assert.equal(unchangedWithoutEvidence.preserveRecentEvidence, true);
258
- assert.equal(unchangedWithoutEvidence.emitStalledWarning, false);
259
-
260
- const changed = assessTodoMaintenanceUpdate({
261
- currentTodos: current,
262
- nextTodos: [
263
- { title: 'Measure source', status: 'done' },
264
- { title: 'Write candidate', status: 'in_progress' },
265
- ],
266
- unchangedRefreshStreak: 3,
267
- recentEvidenceCount: 8,
268
- });
269
- assert.deepEqual(changed, {
270
- changed: true,
271
- unchangedRefreshStreak: 0,
272
- refreshWorkCallLimit: 8,
273
- preserveRecentEvidence: false,
274
- requireConcreteProgress: false,
275
- emitStalledWarning: false,
276
- });
277
- assert.deepEqual(canonicalStoredTodos([
278
- { title: 'Measure source', status: 'done' },
279
- { title: 'Write candidate', status: 'in_progress' },
280
- ]), [{ title: 'Write candidate', status: 'in_progress' }]);
281
-
282
- assert.equal(assessTodoListBounds({ currentTodos: [], nextTodos: todos(32) }), undefined);
283
- assert.match(
284
- assessTodoListBounds({ currentTodos: [], nextTodos: todos(33) }).reason,
285
- /at most 32 visible items/,
286
- );
287
-
288
- const legacy = todos(47);
289
- assert.equal(
290
- assessTodoListBounds({ currentTodos: legacy, nextTodos: legacy }),
291
- undefined,
292
- 'TODO_PROGRESS: unchanged legacy lists must not deadlock',
293
- );
294
- assert.match(
295
- assessTodoListBounds({ currentTodos: legacy, nextTodos: legacy.slice(0, 46) }).reason,
296
- /may remove an unresolved legacy item only by submitting it as done/,
297
- );
298
- const legacyWithDone = legacy.map((todo, index) => index === 46
299
- ? { ...todo, status: 'done' }
300
- : todo);
301
- assert.equal(
302
- assessTodoListBounds({ currentTodos: legacy, nextTodos: legacyWithDone }),
303
- undefined,
304
- 'TODO_PROGRESS: explicit done pruning must shrink an oversized legacy list',
305
- );
306
- const legacyShrunkAndRenamed = legacyWithDone.map((todo, index) => index === 0
307
- ? { ...todo, title: 'Replacement task' }
308
- : todo);
309
- assert.match(
310
- assessTodoListBounds({ currentTodos: legacy, nextTodos: legacyShrunkAndRenamed }).reason,
311
- /Do not add, omit, or rename items/,
312
- 'TODO_PROGRESS: crossing the cap must not bypass legacy identity checks',
313
- );
314
-
315
- assertBundleContract();
316
- exerciseBundledPolicy();
317
-
318
- assert.deepEqual(normalizeTodoProgressState({
319
- workCallsSinceRefresh: 64,
320
- refreshRequired: true,
321
- unchangedRefreshStreak: 3,
322
- recentEvidence: Array.from({ length: 10 }, (_, index) => `evidence-${String(index)}`),
323
- evidenceRevision: 12,
324
- lastMaintenanceEvidenceRevision: 11,
325
- allVisibleWorkCompleted: false,
326
- }), {
327
- workCallsSinceRefresh: 64,
328
- refreshRequired: true,
329
- unchangedRefreshStreak: 3,
330
- recentEvidence: Array.from({ length: 8 }, (_, index) => `evidence-${String(index + 2)}`),
331
- evidenceRevision: 12,
332
- lastMaintenanceEvidenceRevision: 11,
333
- allVisibleWorkCompleted: false,
334
- });
335
- assert.equal(normalizeTodoProgressState(undefined), undefined);
336
-
337
- if (process.env.BLUN_TODO_PROGRESS_SKIP_MUTATIONS !== '1') {
338
- const originalPolicy = fs.readFileSync(policyPath, 'utf8');
339
- const policyMutations = [
340
- ['cap', 'const MAX_TODO_ITEMS = 32;', 'const MAX_TODO_ITEMS = 33;'],
341
- ['unchanged-progress', ')\n !== semanticTodoFingerprint(input?.nextTodos);', ')\n === semanticTodoFingerprint(input?.nextTodos);'],
342
- ['concrete-progress', 'requireConcreteProgress: unchangedRefreshStreak >= 2,', 'requireConcreteProgress: unchangedRefreshStreak >= 99,'],
343
- ['stalled-warning', 'unchangedRefreshStreak === TODO_STALLED_WARNING_STREAK,', 'unchangedRefreshStreak === 99,'],
344
- ];
345
- const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'blun-todo-progress-mutations-'));
346
- try {
347
- for (const [name, needle, replacement] of policyMutations) {
348
- assert.ok(originalPolicy.includes(needle), `TODO_PROGRESS: mutation anchor missing: ${name}`);
349
- const mutatedPath = path.join(tempRoot, `${name}.cjs`);
350
- fs.writeFileSync(mutatedPath, originalPolicy.replace(needle, replacement), 'utf8');
351
- const result = spawnSync(process.execPath, [__filename], {
352
- encoding: 'utf8',
353
- env: {
354
- ...process.env,
355
- BLUN_TODO_PROGRESS_POLICY_UNDER_TEST: mutatedPath,
356
- BLUN_TODO_PROGRESS_SKIP_MUTATIONS: '1',
357
- },
358
- windowsHide: true,
359
- });
360
- assert.notEqual(
361
- result.status,
362
- 0,
363
- `TODO_PROGRESS: ${name} mutation survived the regression gate`,
364
- );
365
- }
366
-
367
- const bundleMutations = [
368
- [
369
- 'bounds-wiring',
370
- '\t\t\t\t\t\t\t\tconst todoBoundsPolicy = enforceTodoListBounds(this.agent, ctx);\n\t\t\t\t\t\t\t\tif (todoBoundsPolicy !== void 0) return todoBoundsPolicy;\n',
371
- '',
372
- __filename,
373
- ],
374
- [
375
- 'done-pruning',
376
- 'todos.filter((todo) => todo.status !== "done")',
377
- 'todos.filter((todo) => todo.status !== "never_done")',
378
- path.join(__dirname, 'check-todo-loop-regression.js'),
379
- ],
380
- [
381
- 'recovery-catalog',
382
- '\t"Bash"\n]);',
383
- '\t"WebSearch"\n]);',
384
- path.join(__dirname, 'check-todo-recovery-catalog-regression.js'),
385
- ],
386
- ];
387
- for (const [name, needle, replacement, gatePath] of bundleMutations) {
388
- assert.ok(bundle.includes(needle), `TODO_PROGRESS: bundle mutation anchor missing: ${name}`);
389
- const mutatedPath = path.join(tempRoot, `${name}.mjs`);
390
- fs.writeFileSync(mutatedPath, bundle.replace(needle, replacement), 'utf8');
391
- const gateIsSelf = gatePath === __filename;
392
- const result = spawnSync(process.execPath, [gatePath], {
393
- encoding: 'utf8',
394
- env: {
395
- ...process.env,
396
- ...(gateIsSelf
397
- ? {
398
- BLUN_TODO_PROGRESS_BUNDLE_UNDER_TEST: mutatedPath,
399
- BLUN_TODO_PROGRESS_SKIP_MUTATIONS: '1',
400
- }
401
- : { BLUN_BUNDLE_UNDER_TEST: mutatedPath }),
402
- },
403
- windowsHide: true,
404
- });
405
- assert.notEqual(
406
- result.status,
407
- 0,
408
- `TODO_PROGRESS: ${name} bundle mutation survived its regression gate`,
409
- );
410
- }
411
- } finally {
412
- fs.rmSync(tempRoot, { recursive: true, force: true });
413
- }
414
- }
415
-
416
- process.stdout.write('todo-progress-regression PASS (bundle + 7 mutations)\n');
@@ -1,50 +0,0 @@
1
- #!/usr/bin/env node
2
- 'use strict';
3
-
4
- const fs = require('node:fs');
5
- const path = require('node:path');
6
-
7
- const bundlePath = process.env.BLUN_BUNDLE_UNDER_TEST
8
- ? path.resolve(process.env.BLUN_BUNDLE_UNDER_TEST)
9
- : path.resolve(__dirname, '..', 'blun.mjs');
10
- const bundle = fs.readFileSync(bundlePath, 'utf8');
11
-
12
- function assert(condition, message) {
13
- if (!condition) throw new Error(message);
14
- }
15
-
16
- const namesMatch = bundle.match(
17
- /const TODO_MAINTENANCE_RECOVERY_TOOL_NAMES = new Set\(\[([\s\S]*?)\]\);/,
18
- );
19
- const functionMatch = bundle.match(
20
- /function goalTodoMaintenanceTools\(eligibleTools, selectedTools\) \{[\s\S]*?\n\}/,
21
- );
22
-
23
- assert(
24
- !/proactive TodoList maintenance step[\s\S]{0,900}tools:\s*\[todoTool\]/.test(bundle),
25
- 'TODO_RECOVERY_CATALOG_REGRESSION: proactive maintenance still switches to TodoList-only',
26
- );
27
- assert(namesMatch, 'TODO_RECOVERY_CATALOG_REGRESSION: recovery tool names are missing');
28
- assert(functionMatch, 'TODO_RECOVERY_CATALOG_REGRESSION: recovery catalogue selector is missing');
29
- assert(
30
- /proactive TodoList maintenance step[\s\S]{0,1100}tools:\s*todoMaintenanceTools/.test(bundle),
31
- 'TODO_RECOVERY_CATALOG_REGRESSION: proactive maintenance is not wired to the recovery catalogue',
32
- );
33
-
34
- const selectMaintenanceTools = Function(
35
- `const TODO_MAINTENANCE_RECOVERY_TOOL_NAMES = new Set([${namesMatch[1]}]); return (${functionMatch[0]});`,
36
- )();
37
- const tools = ['TodoList', 'Read', 'Write', 'Edit', 'Bash', 'WebSearch'].map((name) => ({ name }));
38
- const selected = [tools[5], tools[1]];
39
- const actual = selectMaintenanceTools(tools, selected).map((tool) => tool.name);
40
-
41
- assert(
42
- actual.join(',') === 'WebSearch,Read,TodoList,Write,Edit,Bash',
43
- `TODO_RECOVERY_CATALOG_REGRESSION: unexpected catalogue ${actual.join(',')}`,
44
- );
45
- assert(
46
- new Set(actual).size === actual.length,
47
- 'TODO_RECOVERY_CATALOG_REGRESSION: recovery catalogue contains duplicates',
48
- );
49
-
50
- process.stdout.write('todo-recovery-catalog-regression PASS\n');
@@ -1,40 +0,0 @@
1
- #!/usr/bin/env node
2
- 'use strict';
3
-
4
- const assert = require('node:assert/strict');
5
- const path = require('node:path');
6
-
7
- const packageRoot = process.env.BLUN_PACKAGE_UNDER_TEST
8
- ? path.resolve(process.env.BLUN_PACKAGE_UNDER_TEST)
9
- : path.resolve(__dirname, '..');
10
- const policy = require(path.join(packageRoot, 'bin', 'turn-tool-performance-policy.cjs'));
11
-
12
- assert.equal(policy.TOOL_SCHEMA_BUDGET_RATIO, 0.35);
13
- assert.equal(policy.TOOL_SCHEMA_MAX_TOKENS, 64_000);
14
- assert.equal(policy.MAX_PERSISTENT_DEFERRED_TOOLS, 12);
15
- assert.equal(policy.MAX_AUTO_RANKED_TOOLS, 6);
16
- assert.equal(policy.toolSchemaBudgetTokens(1_048_576), 64_000);
17
- assert.equal(policy.toolSchemaBudgetTokens(100_000), 35_000);
18
-
19
- const tools = Array.from({ length: 20 }, (_, index) => ({
20
- name: `DeferredTool${String(index + 1)}`,
21
- description: `Deferred tool ${String(index + 1)}`,
22
- parameters: { type: 'object', properties: {} },
23
- }));
24
- const selected = [];
25
- const loaded = new Set();
26
- const loader = policy.createDeferredToolLoader(selected, tools, loaded);
27
-
28
- (async () => {
29
- for (let index = 0; index < tools.length; index += 1) {
30
- const execution = loader.resolveExecution({ query: `select:${tools[index].name}` });
31
- const result = await execution.execute();
32
- assert.equal(result.isError, false);
33
- }
34
- assert.equal(loaded.size, 12, 'the twelve most recently loaded schemas must persist');
35
- assert.deepEqual([...loaded], tools.slice(-12).map((tool) => tool.name));
36
- process.stdout.write('tool-schema-capacity-regression PASS\n');
37
- })().catch((error) => {
38
- console.error(error);
39
- process.exitCode = 1;
40
- });