Skip to content
Source
Sign inSign up

TransferBudgetV2Fixture.integration.ts

915 lines29.0 KB

1import {
2 CheckpointId,
3 CheckpointRef,
4 CheckpointScopeId,
5 ContextHandoffId,
6 EventId,
7 MessageId,
8 NodeId,
9 PlanId,
10 ProjectId,
11 ProviderInstanceId,
12 ProviderThreadId,
13 ProviderTurnId,
14 RunId,
15 ThreadId,
16 TurnItemId,
17 type ApplicationProjectEvent,
18 type ProviderDriverKind,
19 type OrchestrationV2DomainEvent,
20 type RepositoryIdentity,
21 type OrchestrationV2TurnItem,
22} from "@t3tools/contracts";
23import * as DateTime from "effect/DateTime";
24import {
25 diagnosticOutput,
26 TRANSFER_HISTORY_TOOLS_PER_TURN,
27 TRANSFER_MEASURED_TOOLS,
28 TRANSFER_HISTORY_MCP_RESULT_BYTES,
29 TRANSFER_MEASURED_MCP_RESULT_BYTES,
30} from "./fixtures/transferBudget.ts";
31​
32export const THREAD_ID = ThreadId.make("transfer-budget-thread");
33type ThreadCreatedEvent = Extract<OrchestrationV2DomainEvent, { readonly type: "thread.created" }>;
34export function threadCreated(
35 provider: ProviderDriverKind,
36 threadId: ThreadId = THREAD_ID,
37 overrides: Partial<ThreadCreatedEvent["payload"]> = {},
38): ThreadCreatedEvent {
39 const now = DateTime.makeUnsafe("2026-06-01T00:00:00Z");
40 return {
41 id: EventId.make(`thread-created:${threadId}`),
42 type: "thread.created",
43 threadId,
44 occurredAt: now,
45 payload: {
46 id: threadId,
47 projectId: ProjectId.make("transfer-project"),
48 title: "Transfer budget",
49 providerInstanceId: ProviderInstanceId.make(provider),
50 modelSelection: {
51 instanceId: ProviderInstanceId.make(provider),
52 model: provider === "codex" ? "gpt-5.4" : "claude-sonnet-4-6",
53 },
54 runtimeMode: "full-access",
55 interactionMode: "default",
56 branch: null,
57 worktreePath: null,
58 activeProviderThreadId: null,
59 lineage: { parentThreadId: null, relationshipToParent: null, rootThreadId: threadId },
60 forkedFrom: null,
61 createdBy: "user",
62 creationSource: "web",
63 createdAt: now,
64 updatedAt: now,
65 archivedAt: null,
66 settledOverride: null,
67 settledAt: null,
68 lastVisitedAt: null,
69 deletedAt: null,
70 ...overrides,
71 },
72 };
74export function turnEvents(
75 provider: ProviderDriverKind,
76 index: number,
77 measured: boolean,
78): ReadonlyArray<OrchestrationV2DomainEvent> {
79 const now = DateTime.makeUnsafe(`2026-06-01T00:${String(index + 1).padStart(2, "0")}:00Z`);
80 const runId = RunId.make(`run-${index}`);
81 const nodeId = NodeId.make(`node-${index}`);
82 const userMessageId = MessageId.make(`user-${index}`);
83 const providerInstanceId = ProviderInstanceId.make(provider);
84 const run = {
85 id: runId,
86 threadId: THREAD_ID,
87 ordinal: index + 1,
88 providerInstanceId,
89 modelSelection: {
90 instanceId: ProviderInstanceId.make(provider),
91 model: provider === "codex" ? "gpt-5.4" : "claude-sonnet-4-6",
92 },
93 providerThreadId: null,
94 userMessageId,
95 rootNodeId: nodeId,
96 activeAttemptId: null,
97 status: "running" as const,
98 requestedAt: now,
99 startedAt: now,
100 completedAt: null,
101 checkpointId: null,
102 contextHandoffId: null,
103 };
104 const common = {
105 threadId: THREAD_ID,
106 runId,
107 nodeId,
108 driver: provider,
109 providerInstanceId,
110 occurredAt: now,
111 };
112 const events: OrchestrationV2DomainEvent[] = [
113 { ...common, id: EventId.make(`run-${index}`), type: "run.created", payload: run },
114 ];
115 const answer =
116 `Completed ${provider} inspection ${index}. ` +
117 "The projection preserves transcript text and bounds tool output. ".repeat(60);
118 for (const role of ["user", "assistant"] as const) {
119 events.push({
120 ...common,
121 id: EventId.make(`${role}-${index}`),
122 type: "message.updated",
123 payload: {
124 id: MessageId.make(`${role}-${index}`),
125 threadId: THREAD_ID,
126 runId,
127 nodeId,
128 role,
129 text: role === "user" ? `Inspect transfer ${index}` : answer,
130 attachments: [],
131 streaming: false,
132 createdAt: now,
133 updatedAt: now,
134 createdBy: role === "user" ? "user" : "agent",
135 creationSource: "web",
136 },
137 });
138 }
139 const toolCount = measured ? TRANSFER_MEASURED_TOOLS : TRANSFER_HISTORY_TOOLS_PER_TURN;
140 const item = (id: string, ordinal: number, title: string | null) => ({
141 id: TurnItemId.make(id),
142 threadId: THREAD_ID,
143 runId,
144 nodeId,
145 providerThreadId: null,
146 providerTurnId: null,
147 nativeItemRef: null,
148 parentItemId: null,
149 ordinal,
150 status: "completed" as const,
151 title,
152 startedAt: now,
153 completedAt: now,
154 updatedAt: now,
155 });
156 for (let tool = 0; tool <= toolCount; tool++) {
157 const mcp = tool === toolCount;
158 const output = diagnosticOutput({
159 provider,
160 turnIndex: index,
161 toolIndex: tool,
162 targetBytes: mcp
163 ? measured
164 ? TRANSFER_MEASURED_MCP_RESULT_BYTES
165 : TRANSFER_HISTORY_MCP_RESULT_BYTES
166 : 4096,
167 });
168 const base = item(
169 `item-${index}-${tool}`,
170 tool + 1,
171 mcp ? "MCP search" : `Inspect source ${tool}`,
172 );
173 events.push({
174 ...common,
175 id: EventId.make(`tool-${index}-${tool}`),
176 type: "turn-item.updated",
177 payload: mcp
178 ? {
179 ...base,
180 type: "dynamic_tool",
181 toolName: "mcp__test__search",
182 input: { query: "transfer" },
183 output: { text: output },
184 }
185 : {
186 ...base,
187 type: "command_execution",
188 input: `cat src/module-${tool}.ts`,
189 output,
190 exitCode: 0,
191 },
192 });
193 }
194 // The live turn repeats its answer in a turn item, as adapters do, so live dedupe has work.
195 // History turns skip it to keep the fallback thread snapshot under its wire ceiling.
196 if (measured)
197 events.push({
198 ...common,
199 id: EventId.make(`answer-item-${index}`),
200 type: "turn-item.updated",
201 payload: {
202 ...item(`item-${index}-answer`, toolCount + 2, null),
203 type: "assistant_message",
204 messageId: MessageId.make(`assistant-${index}`),
205 text: answer,
206 streaming: false,
207 },
208 });
209 events.push({
210 ...common,
211 id: EventId.make(`complete-${index}`),
212 type: "run.updated",
213 payload: { ...run, status: "completed", completedAt: now },
214 });
215 return events;
217​
218export const LONG_TURN_THREAD_ID = ThreadId.make("transfer-budget-long-turn");
219export const LONG_TURN_WORK_ROWS = 900;
220​
221/**
222 * Three short user turns, then one agent turn far longer than a cold-open window, with the item
223 * kinds a long agent run produces. One batch per turn; the last batch only finishes the long turn.
224 * Run, node, provider and item IDs follow the composite shapes the Claude adapter stores, and
225 * every assistant message has its record, as real threads do.
226 */
227export function longTurnThreadBatches(
228 provider: ProviderDriverKind,
229): ReadonlyArray<ReadonlyArray<OrchestrationV2DomainEvent>> {
230 const threadId = LONG_TURN_THREAD_ID;
231 const providerInstanceId = ProviderInstanceId.make(provider);
232 const modelSelection = {
233 instanceId: providerInstanceId,
234 model: provider === "codex" ? "gpt-5.4" : "claude-sonnet-4-6",
235 };
236 let ordinal = 0;
237 const text = (turn: number, row: number, targetBytes: number) =>
238 diagnosticOutput({ provider, turnIndex: 100 + turn, toolIndex: row, targetBytes });
239​
240 const turn = (index: number, workRows: number): OrchestrationV2DomainEvent[] => {
241 const now = DateTime.makeUnsafe(`2026-06-02T00:${String(index).padStart(2, "0")}:00Z`);
242 const runId = RunId.make(`run:thread:${threadId}:ordinal:${index + 1}`);
243 const nodeId = NodeId.make(`node:run:${encodeURIComponent(runId)}:root`);
244 const providerThreadId = ProviderThreadId.make(
245 `provider-thread:provider:${provider}:native-thread:${encodeURIComponent(`pending:${runId}`)}`,
246 );
247 const providerTurnId = ProviderTurnId.make(
248 `provider-turn:provider:${provider}:native-turn:${encodeURIComponent(`turn:run-attempt:${encodeURIComponent(runId)}:attempt:1`)}`,
249 );
250 const common = {
251 threadId,
252 runId,
253 nodeId,
254 driver: provider,
255 providerInstanceId,
256 occurredAt: now,
257 };
258 const messageId = (role: "user" | "assistant", row: string) =>
259 MessageId.make(
260 `message:provider:${provider}:native-item:msg_01LongTurn${role}${index}x${row}`,
261 );
262 const run = {
263 id: runId,
264 threadId,
265 ordinal: index + 1,
266 providerInstanceId,
267 modelSelection,
268 providerThreadId: null,
269 userMessageId: messageId("user", "prompt"),
270 rootNodeId: nodeId,
271 activeAttemptId: null,
272 status: "running" as const,
273 requestedAt: now,
274 startedAt: now,
275 completedAt: null,
276 checkpointId: null,
277 contextHandoffId: null,
278 };
279 const base = (row: string, title: string | null) => {
280 ordinal += 1;
281 const nativeId = `toolu_01LongTurn${index}x${row}`;
282 return {
283 id: TurnItemId.make(`turn-item:provider:${provider}:native-item:${nativeId}`),
284 threadId,
285 runId,
286 nodeId,
287 providerThreadId,
288 providerTurnId,
289 nativeItemRef: { driver: provider, nativeId, strength: "strong" as const },
290 parentItemId: null,
291 ordinal,
292 status: "completed" as const,
293 title,
294 startedAt: now,
295 completedAt: now,
296 updatedAt: now,
297 };
298 };
299 const events: OrchestrationV2DomainEvent[] = [
300 { ...common, id: EventId.make(`long-turn-run-${index}`), type: "run.created", payload: run },
301 ];
302 const message = (role: "user" | "assistant", row: string, messageText: string) => {
303 const id = messageId(role, row);
304 const createdBy = role === "user" ? ("user" as const) : ("agent" as const);
305 events.push(
306 {
307 ...common,
308 id: EventId.make(`long-turn-message-${index}-${row}`),
309 type: "message.updated",
310 payload: {
311 id,
312 threadId,
313 runId,
314 nodeId,
315 role,
316 text: messageText,
317 attachments: [],
318 streaming: false,
319 createdAt: now,
320 updatedAt: now,
321 createdBy,
322 creationSource: "web",
323 },
324 },
325 {
326 ...common,
327 id: EventId.make(`long-turn-item-event-${index}-${row}`),
328 type: "turn-item.updated",
329 payload:
330 role === "user"
331 ? {
332 ...base(row, null),
333 type: "user_message",
334 createdBy,
335 creationSource: "web",
336 messageId: id,
337 inputIntent: "turn_start",
338 text: messageText,
339 attachments: [],
340 }
341 : {
342 ...base(row, null),
343 type: "assistant_message",
344 messageId: id,
345 text: messageText,
346 streaming: false,
347 },
348 },
349 );
350 };
351 const workItem = (row: number): OrchestrationV2TurnItem => {
352 if (row % 100 === 50) {
353 return {
354 ...base(String(row), "Checkpoint"),
355 type: "checkpoint",
356 checkpointId: CheckpointId.make(`long-turn-checkpoint-${index}-${row}`),
357 scopeId: CheckpointScopeId.make(`long-turn-scope-${index}`),
358 files: Array.from({ length: 40 }, (_, file) => ({
359 path: `src/feature/module-${row}-${file}.ts`,
360 kind: "modified",
361 additions: file + 1,
362 deletions: file,
363 })),
364 };
365 }
366 if (row % 100 === 99) {
367 return {
368 ...base(String(row), "Subagent"),
369 type: "subagent",
370 subagentId: NodeId.make(`long-turn-subagent-${index}-${row}`),
371 origin: "app_owned",
372 driver: provider,
373 providerInstanceId,
374 childThreadId: null,
375 prompt: text(index, row, 2_048),
376 result: text(index, row + 1, 3_072),
377 };
378 }
379 switch (row % 8) {
380 case 0:
381 case 7:
382 return {
383 ...base(String(row), "Reasoning"),
384 type: "reasoning",
385 text: text(index, row, 1_536),
386 streaming: false,
387 };
388 case 3:
389 return {
390 ...base(String(row), `Edit module ${row}`),
391 type: "file_change",
392 fileName: `src/feature/module-${row}.ts`,
393 additions: 12,
394 deletions: 4,
395 diffStr: text(index, row, 2_048),
396 };
397 case 4:
398 return {
399 ...base(String(row), "MCP search"),
400 type: "dynamic_tool",
401 toolName: "mcp__test__search",
402 input: { query: `module ${row}` },
403 output: { text: text(index, row, 6_144) },
404 };
405 default:
406 return {
407 ...base(String(row), `Run check ${row}`),
408 type: "command_execution",
409 input: `vp test run src/feature/module-${row}.test.ts`,
410 output: text(index, row, 4_096),
411 exitCode: 0,
412 };
413 }
414 };
415​
416 message("user", "prompt", `Continue the feature work, step ${index}.`);
417 for (let row = 0; row < workRows; row++) {
418 if (row % 8 === 5) {
419 message("assistant", String(row), text(index, row, 1_500));
420 continue;
421 }
422 events.push({
423 ...common,
424 id: EventId.make(`long-turn-work-${index}-${row}`),
425 type: "turn-item.updated",
426 payload: workItem(row),
427 });
428 }
429 message("assistant", "answer", text(index, workRows, 1_200));
430 events.push({
431 ...common,
432 id: EventId.make(`long-turn-complete-${index}`),
433 type: "run.updated",
434 payload: { ...run, status: "completed", completedAt: now },
435 });
436 return events;
437 };
438​
439 const longTurn = turn(3, LONG_TURN_WORK_ROWS);
440 return [
441 [threadCreated(provider, threadId)],
442 turn(0, 4),
443 turn(1, 4),
444 turn(2, 4),
445 longTurn.slice(0, -1),
446 longTurn.slice(-1),
447 ];
449​
450export const STALE_TODO_THREAD_ID = ThreadId.make("transfer-budget-stale-todo-lists");
451export const STALE_TODO_SETTLED_RUNS = 40;
452export const STALE_TODO_SUBAGENTS_PER_RUN = 2;
453export const STALE_TODO_LIVE_ROWS = 600;
454const STALE_TODO_HANDOFF_HISTORY_BYTES = 256 * 1024;
455const staleTodoCheckpointId = (index: number) =>
456 CheckpointId.make(`checkpoint:thread:${STALE_TODO_THREAD_ID}:ordinal:${index + 1}`);
457/** The checkpoint clients read the last finished turn's diff from. */
458export const STALE_TODO_LAST_FINISHED_CHECKPOINT_ID = staleTodoCheckpointId(
459 STALE_TODO_SETTLED_RUNS - 1,
460);
461const staleTodoRunId = (index: number) =>
462 RunId.make(`run:thread:${STALE_TODO_THREAD_ID}:ordinal:${index + 1}`);
463export const STALE_TODO_LIVE_RUN_ID = staleTodoRunId(STALE_TODO_SETTLED_RUNS);
464​
465/**
466 * A long thread: many finished runs, then one run still at work with more rows than a window
467 * holds. Every run leaves its todo list node `running` and its plan `active`, as adapters do,
468 * and has subagents, a provider turn and (once finished) a checkpoint. One batch per run.
469 */
470export function staleTodoListThreadBatches(
471 provider: ProviderDriverKind,
472): ReadonlyArray<ReadonlyArray<OrchestrationV2DomainEvent>> {
473 const threadId = STALE_TODO_THREAD_ID;
474 const providerInstanceId = ProviderInstanceId.make(provider);
475 const modelSelection = {
476 instanceId: providerInstanceId,
477 model: provider === "codex" ? "gpt-5.4" : "claude-sonnet-4-6",
478 };
479 const providerThreadId = ProviderThreadId.make(
480 `provider-thread:provider:${provider}:native-thread:stale-todo-lists`,
481 );
482 const scopeId = CheckpointScopeId.make(`checkpoint-scope:thread:${threadId}:root`);
483 let ordinal = 0;
484 const text = (run: number, row: number, targetBytes: number) =>
485 diagnosticOutput({ provider, turnIndex: 200 + run, toolIndex: row, targetBytes });
486​
487 const turn = (index: number, live: boolean): OrchestrationV2DomainEvent[] => {
488 const now = DateTime.makeUnsafe(Date.UTC(2026, 5, 4, 0, index));
489 const runId = staleTodoRunId(index);
490 const runKey = encodeURIComponent(runId);
491 const rootNodeId = NodeId.make(`node:run:${runKey}:root`);
492 const todoNodeId = NodeId.make(`node:run:${runKey}:todo-list`);
493 const planId = PlanId.make(`plan:run:${runKey}:todo-list`);
494 const providerTurnId = ProviderTurnId.make(
495 `provider-turn:provider:${provider}:native-turn:${encodeURIComponent(`turn:run-attempt:${runKey}:attempt:1`)}`,
496 );
497 const status = live ? ("running" as const) : ("completed" as const);
498 const completedAt = live ? null : now;
499 const common = {
500 threadId,
501 runId,
502 nodeId: rootNodeId,
503 driver: provider,
504 providerInstanceId,
505 occurredAt: now,
506 };
507 const messageId = (role: "user" | "assistant") =>
508 MessageId.make(`message:provider:${provider}:native-item:msg_01StaleTodo${role}${index}`);
509 const run = {
510 id: runId,
511 threadId,
512 ordinal: index + 1,
513 providerInstanceId,
514 modelSelection,
515 providerThreadId: null,
516 userMessageId: messageId("user"),
517 rootNodeId,
518 activeAttemptId: null,
519 status: "running" as const,
520 requestedAt: now,
521 startedAt: now,
522 completedAt: null,
523 checkpointId: null,
524 contextHandoffId: null,
525 };
526 const base = (row: string, title: string | null, nodeId: NodeId = rootNodeId) => {
527 ordinal += 1;
528 const nativeId = `toolu_01StaleTodo${index}x${row}`;
529 return {
530 id: TurnItemId.make(`turn-item:provider:${provider}:native-item:${nativeId}`),
531 threadId,
532 runId,
533 nodeId,
534 providerThreadId,
535 providerTurnId,
536 nativeItemRef: { driver: provider, nativeId, strength: "strong" as const },
537 parentItemId: null,
538 ordinal,
539 status: "completed" as const,
540 title,
541 startedAt: now,
542 completedAt: now,
543 updatedAt: now,
544 };
545 };
546 const events: OrchestrationV2DomainEvent[] = [
547 { ...common, id: EventId.make(`stale-todo-run-${index}`), type: "run.created", payload: run },
548 ];
549 const node = (
550 id: NodeId,
551 kind: "root_turn" | "todo_list" | "subagent",
552 nodeStatus: "running" | "completed",
553 ) =>
554 events.push({
555 ...common,
556 id: EventId.make(`stale-todo-node-${id}`),
557 type: "node.updated",
558 nodeId: id,
559 payload: {
560 id,
561 threadId,
562 runId,
563 parentNodeId: kind === "root_turn" ? null : rootNodeId,
564 rootNodeId,
565 kind,
566 status: nodeStatus,
567 countsForRun: kind === "root_turn",
568 providerThreadId,
569 providerTurnId,
570 nativeItemRef: null,
571 runtimeRequestId: null,
572 checkpointScopeId: kind === "root_turn" ? scopeId : null,
573 startedAt: now,
574 completedAt: nodeStatus === "running" ? null : now,
575 },
576 });
577 const message = (role: "user" | "assistant", messageText: string) => {
578 const id = messageId(role);
579 const createdBy = role === "user" ? ("user" as const) : ("agent" as const);
580 events.push(
581 {
582 ...common,
583 id: EventId.make(`stale-todo-message-${index}-${role}`),
584 type: "message.updated",
585 payload: {
586 id,
587 threadId,
588 runId,
589 nodeId: rootNodeId,
590 role,
591 text: messageText,
592 attachments: [],
593 streaming: false,
594 createdAt: now,
595 updatedAt: now,
596 createdBy,
597 creationSource: "web",
598 },
599 },
600 {
601 ...common,
602 id: EventId.make(`stale-todo-message-item-${index}-${role}`),
603 type: "turn-item.updated",
604 payload:
605 role === "user"
606 ? {
607 ...base(role, null),
608 type: "user_message",
609 createdBy,
610 creationSource: "web",
611 messageId: id,
612 inputIntent: "turn_start",
613 text: messageText,
614 attachments: [],
615 }
616 : {
617 ...base(role, null),
618 type: "assistant_message",
619 messageId: id,
620 text: messageText,
621 streaming: false,
622 },
623 },
624 );
625 };
626​
627 if (index === 0)
628 events.push({
629 ...common,
630 id: EventId.make("stale-todo-scope"),
631 type: "checkpoint-scope.created",
632 payload: {
633 id: scopeId,
634 threadId,
635 runId,
636 nodeId: rootNodeId,
637 parentScopeId: null,
638 providerThreadId,
639 kind: "root_run",
640 ordinalWithinParent: 0,
641 advancesAppRunCount: true,
642 cwd: "/workspace/transfer-budget",
643 createdAt: now,
644 },
645 });
646 node(rootNodeId, "root_turn", status);
647 events.push({
648 ...common,
649 id: EventId.make(`stale-todo-provider-turn-${index}`),
650 type: "provider-turn.updated",
651 payload: {
652 id: providerTurnId,
653 providerThreadId,
654 nodeId: rootNodeId,
655 runAttemptId: null,
656 nativeTurnRef: null,
657 ordinal: index + 1,
658 status,
659 startedAt: now,
660 completedAt,
661 },
662 });
663 message("user", `Continue the migration, step ${index}.`);
664​
665 // The list is done but never closed: the node stays running and the plan stays active.
666 const steps = Array.from({ length: 6 }, (_, step) => ({
667 id: `step-${step + 1}`,
668 text: `Migrate module group ${index}.${step + 1} and run its checks`,
669 status: live && step > 2 ? ("pending" as const) : ("completed" as const),
670 }));
671 node(todoNodeId, "todo_list", "running");
672 events.push(
673 {
674 ...common,
675 id: EventId.make(`stale-todo-plan-${index}`),
676 type: "plan.updated",
677 nodeId: todoNodeId,
678 payload: {
679 id: planId,
680 threadId,
681 runId,
682 nodeId: todoNodeId,
683 status: "active",
684 kind: "todo_list",
685 steps,
686 },
687 },
688 {
689 ...common,
690 id: EventId.make(`stale-todo-plan-item-${index}`),
691 type: "turn-item.updated",
692 nodeId: todoNodeId,
693 payload: { ...base("todo", "Todo list", todoNodeId), type: "todo_list", planId, steps },
694 },
695 );
696​
697 for (let subagent = 0; subagent < STALE_TODO_SUBAGENTS_PER_RUN; subagent++) {
698 const subagentId = NodeId.make(`node:run:${runKey}:subagent:${subagent + 1}`);
699 node(subagentId, "subagent", "completed");
700 events.push({
701 ...common,
702 id: EventId.make(`stale-todo-subagent-${index}-${subagent}`),
703 type: "subagent.updated",
704 nodeId: subagentId,
705 payload: {
706 id: subagentId,
707 threadId,
708 runId,
709 parentNodeId: rootNodeId,
710 origin: "app_owned",
711 createdBy: "agent",
712 driver: provider,
713 providerInstanceId,
714 providerThreadId: null,
715 childThreadId: null,
716 nativeTaskRef: null,
717 prompt: text(index, subagent * 2, 2_048),
718 title: `Review module group ${index}.${subagent + 1}`,
719 model: modelSelection.model,
720 status: "completed",
721 result: text(index, subagent * 2 + 1, 4_096),
722 startedAt: now,
723 completedAt: now,
724 updatedAt: now,
725 },
726 });
727 }
728​
729 const workRows = live ? STALE_TODO_LIVE_ROWS : 6;
730 for (let row = 0; row < workRows; row++)
731 events.push({
732 ...common,
733 id: EventId.make(`stale-todo-work-${index}-${row}`),
734 type: "turn-item.updated",
735 payload:
736 row % 10 === 0
737 ? {
738 ...base(String(row), "Reasoning"),
739 type: "reasoning",
740 text: text(index, 10 + row, 1_024),
741 streaming: false,
742 }
743 : {
744 ...base(String(row), `Run check ${row}`),
745 type: "command_execution",
746 input: `vp test run src/migration/module-${index}-${row}.test.ts`,
747 output: text(index, 10 + row, 2_048),
748 exitCode: 0,
749 },
750 });
751 if (live) {
752 // A ready handoff rides along with every window. Its history and delivery are for the
753 // provider turn start and must not reach a client.
754 const earlierItemId = TurnItemId.make(`turn-item:stale-todo:${index}:handoff-source`);
755 events.push({
756 ...common,
757 id: EventId.make(`stale-todo-handoff-${index}`),
758 type: "context-handoff.updated",
759 payload: {
760 id: ContextHandoffId.make(`handoff:run:${runKey}`),
761 transferId: null,
762 threadId,
763 targetRunId: runId,
764 fromProviderThreadIds: [providerThreadId],
765 toProviderThreadId: providerThreadId,
766 coveredRunOrdinals: { from: 1, to: index },
767 strategy: "full_thread_summary",
768 status: "ready",
769 summaryMessageId: null,
770 summaryText: text(index, 6, 1_024),
771 history: {
772 messages: [
773 {
774 role: "user",
775 text: text(index, 7, STALE_TODO_HANDOFF_HISTORY_BYTES),
776 threadId,
777 runId: null,
778 itemId: earlierItemId,
779 providerThreadId,
780 status: "completed",
781 kind: "user_message",
782 },
783 ],
784 coverage: "full",
785 omittedItems: 0,
786 },
787 delivery: { nativeThreadId: "native", status: "injected", itemIds: [earlierItemId] },
788 createdByProviderInstanceId: providerInstanceId,
789 createdAt: now,
790 updatedAt: now,
791 },
792 });
793 return events;
794 }
795​
796 message("assistant", text(index, 5, 1_200));
797 const checkpointId = staleTodoCheckpointId(index);
798 events.push(
799 {
800 ...common,
801 id: EventId.make(`stale-todo-checkpoint-${index}`),
802 type: "checkpoint.captured",
803 payload: {
804 id: checkpointId,
805 threadId,
806 scopeId,
807 runId,
808 nodeId: rootNodeId,
809 parentCheckpointId: index === 0 ? null : staleTodoCheckpointId(index - 1),
810 ordinalWithinScope: index + 1,
811 appRunOrdinal: index + 1,
812 ref: CheckpointRef.make(
813 `refs/t3/orchestration-v2/checkpoints/stale-todo-lists/ordinal/${index + 1}`,
814 ),
815 status: "ready",
816 files: Array.from({ length: 12 }, (_, file) => ({
817 path: `src/migration/module-${index}-${file}.ts`,
818 kind: "modified",
819 additions: file + 1,
820 deletions: file,
821 })),
822 capturedAt: now,
823 },
824 },
825 {
826 ...common,
827 id: EventId.make(`stale-todo-complete-${index}`),
828 type: "run.updated",
829 payload: { ...run, status: "completed", completedAt: now, checkpointId },
830 },
831 );
832 return events;
833 };
834​
835 return [
836 [threadCreated(provider, threadId)],
837 ...Array.from({ length: STALE_TODO_SETTLED_RUNS }, (_, index) => turn(index, false)),
838 turn(STALE_TODO_SETTLED_RUNS, true),
839 ];
841​
842const FLEET_PROJECT_ID = ProjectId.make("transfer-project");
843export const FLEET_PROJECT_IDENTITY: RepositoryIdentity = {
844 canonicalKey: "github.com/t3/transfer-budget",
845 locator: {
846 source: "git-remote",
847 remoteName: "origin",
848 remoteUrl: "git@github.com:t3/transfer-budget.git",
849 },
850 owner: "t3",
851 name: "transfer-budget",
852};
853​
854/**
855 * The project every fixture thread belongs to. The test resolves it to FLEET_PROJECT_IDENTITY,
856 * which a shell resume sends again unless the client names the identities it already holds.
857 */
858export const fleetProjectCreated: ApplicationProjectEvent = {
859 sequence: 0,
860 eventId: EventId.make("project-created:transfer-project"),
861 aggregateKind: "project",
862 aggregateId: FLEET_PROJECT_ID,
863 occurredAt: "2026-06-01T00:00:00.000Z",
864 commandId: null,
865 causationEventId: null,
866 correlationId: null,
867 metadata: {},
868 type: "project.created",
869 payload: {
870 projectId: FLEET_PROJECT_ID,
871 title: "Transfer budget",
872 workspaceRoot: "/tmp/transfer-budget",
873 defaultModelSelection: null,
874 scripts: [],
875 createdAt: "2026-06-01T00:00:00.000Z",
876 updatedAt: "2026-06-01T00:00:00.000Z",
877 },
878};
879​
880export const SHELL_SETTLED_THREADS = 100;
881export const SHELL_IDLE_SUBAGENTS = 40;
882​
883/**
884 * A busy sidebar: settled top-level threads, settled a minute apart, with idle subagent children
885 * under the newest ones. Opted-in cold connects skip the children and all but 25 settled threads.
886 */
887export function shellFleetEvents(
888 provider: ProviderDriverKind,
889): ReadonlyArray<OrchestrationV2DomainEvent> {
890 return Array.from({ length: SHELL_SETTLED_THREADS }, (_, index) => {
891 const threadId = ThreadId.make(`transfer-budget-settled-${index}`);
892 const settledAt = DateTime.makeUnsafe(Date.UTC(2026, 5, 3, 0, index));
893 const settled = threadCreated(provider, threadId, {
894 title: `Settled transfer thread ${index}`,
895 branch: `feature/settled-${index}`,
896 settledOverride: "settled",
897 settledAt,
898 updatedAt: settledAt,
899 });
900 if (index < SHELL_SETTLED_THREADS - SHELL_IDLE_SUBAGENTS) return [settled];
901 const childId = ThreadId.make(`transfer-budget-settled-${index}-subagent`);
902 return [
903 settled,
904 threadCreated(provider, childId, {
905 title: `Subagent of settled thread ${index}`,
906 createdBy: "agent",
907 lineage: {
908 parentThreadId: threadId,
909 relationshipToParent: "subagent",
910 rootThreadId: threadId,
911 },
912 }),
913 ];
914 }).flat();