@trevonistrevon/pi-loop 0.4.11 → 0.5.1

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 (87) hide show
  1. package/README.md +20 -9
  2. package/dist/commands/loop-command.d.ts +22 -0
  3. package/dist/commands/loop-command.js +148 -0
  4. package/dist/commands/tasks-command.d.ts +15 -0
  5. package/dist/commands/tasks-command.js +117 -0
  6. package/dist/coordinator.d.ts +35 -0
  7. package/dist/coordinator.js +56 -0
  8. package/dist/goal-coordinator.d.ts +22 -0
  9. package/dist/goal-coordinator.js +28 -0
  10. package/dist/goal-reducer.d.ts +89 -0
  11. package/dist/goal-reducer.js +181 -0
  12. package/dist/goal-store.d.ts +31 -0
  13. package/dist/goal-store.js +298 -0
  14. package/dist/goal-types.d.ts +82 -0
  15. package/dist/goal-types.js +1 -0
  16. package/dist/goal-verifier.d.ts +20 -0
  17. package/dist/goal-verifier.js +198 -0
  18. package/dist/index.js +130 -1087
  19. package/dist/loop-reducer.d.ts +63 -0
  20. package/dist/loop-reducer.js +67 -0
  21. package/dist/monitor-completion-coordinator.d.ts +10 -0
  22. package/dist/monitor-completion-coordinator.js +13 -0
  23. package/dist/monitor-manager.d.ts +2 -0
  24. package/dist/monitor-manager.js +107 -29
  25. package/dist/monitor-reducer.d.ts +82 -0
  26. package/dist/monitor-reducer.js +69 -0
  27. package/dist/notification-reducer.d.ts +81 -0
  28. package/dist/notification-reducer.js +65 -0
  29. package/dist/runtime/monitor-ondone-runtime.d.ts +13 -0
  30. package/dist/runtime/monitor-ondone-runtime.js +49 -0
  31. package/dist/runtime/notification-runtime.d.ts +34 -0
  32. package/dist/runtime/notification-runtime.js +152 -0
  33. package/dist/runtime/scope.d.ts +8 -0
  34. package/dist/runtime/scope.js +33 -0
  35. package/dist/runtime/session-runtime.d.ts +39 -0
  36. package/dist/runtime/session-runtime.js +110 -0
  37. package/dist/runtime/task-backlog-runtime.d.ts +36 -0
  38. package/dist/runtime/task-backlog-runtime.js +105 -0
  39. package/dist/runtime/task-rpc.d.ts +19 -0
  40. package/dist/runtime/task-rpc.js +118 -0
  41. package/dist/store.d.ts +7 -4
  42. package/dist/store.js +129 -49
  43. package/dist/task-backlog-coordinator.d.ts +12 -0
  44. package/dist/task-backlog-coordinator.js +22 -0
  45. package/dist/task-reducer.d.ts +66 -0
  46. package/dist/task-reducer.js +76 -0
  47. package/dist/task-store.d.ts +8 -4
  48. package/dist/task-store.js +102 -33
  49. package/dist/tools/loop-tools.d.ts +41 -0
  50. package/dist/tools/loop-tools.js +241 -0
  51. package/dist/tools/monitor-tools.d.ts +25 -0
  52. package/dist/tools/monitor-tools.js +110 -0
  53. package/dist/tools/native-task-tools.d.ts +15 -0
  54. package/dist/tools/native-task-tools.js +127 -0
  55. package/docs/architecture/goal-state-schema.md +505 -0
  56. package/docs/architecture/state-machine-migration.md +546 -0
  57. package/docs/architecture/state-machine-reducer-event-model.md +823 -0
  58. package/docs/architecture/state-machine-test-matrix.md +249 -0
  59. package/docs/architecture/state-machine-transition-map.md +436 -0
  60. package/package.json +1 -1
  61. package/src/commands/loop-command.ts +184 -0
  62. package/src/commands/tasks-command.ts +135 -0
  63. package/src/coordinator.ts +115 -0
  64. package/src/goal-coordinator.ts +58 -0
  65. package/src/goal-reducer.ts +280 -0
  66. package/src/goal-store.ts +315 -0
  67. package/src/goal-types.ts +104 -0
  68. package/src/goal-verifier.ts +241 -0
  69. package/src/index.ts +134 -1147
  70. package/src/loop-reducer.ts +148 -0
  71. package/src/monitor-completion-coordinator.ts +24 -0
  72. package/src/monitor-manager.ts +115 -27
  73. package/src/monitor-reducer.ts +166 -0
  74. package/src/notification-reducer.ts +155 -0
  75. package/src/runtime/monitor-ondone-runtime.ts +75 -0
  76. package/src/runtime/notification-runtime.ts +212 -0
  77. package/src/runtime/scope.ts +37 -0
  78. package/src/runtime/session-runtime.ts +168 -0
  79. package/src/runtime/task-backlog-runtime.ts +163 -0
  80. package/src/runtime/task-rpc.ts +150 -0
  81. package/src/store.ts +132 -50
  82. package/src/task-backlog-coordinator.ts +32 -0
  83. package/src/task-reducer.ts +152 -0
  84. package/src/task-store.ts +103 -31
  85. package/src/tools/loop-tools.ts +304 -0
  86. package/src/tools/monitor-tools.ts +145 -0
  87. package/src/tools/native-task-tools.ts +144 -0
@@ -0,0 +1,546 @@
1
+ # pi-loop State Machine Migration
2
+
3
+ ## Purpose
4
+
5
+ This document records the migration from ad hoc runtime control flow toward reducer-driven state handling in `pi-loop`.
6
+
7
+ It is the capstone document for the architecture work captured in:
8
+
9
+ - `docs/architecture/state-machine-transition-map.md`
10
+ - `docs/architecture/state-machine-test-matrix.md`
11
+ - `docs/architecture/state-machine-reducer-event-model.md`
12
+ - `docs/architecture/goal-state-schema.md`
13
+
14
+ The goal of this document is to explain:
15
+
16
+ 1. what the original runtime looked like
17
+ 2. what has already been extracted
18
+ 3. what remains to be integrated
19
+ 4. how the coordinator should be adopted safely
20
+ 5. what risks still exist
21
+
22
+ ---
23
+
24
+ ## 1. Background
25
+
26
+ The original `pi-loop` runtime was correct in many important respects, but its control flow was concentrated in a small number of imperative modules, especially `src/index.ts`, `src/store.ts`, `src/task-store.ts`, and `src/monitor-manager.ts`.
27
+
28
+ This architecture had several strengths:
29
+
30
+ - straightforward implementation
31
+ - strong feature velocity
32
+ - pragmatic reliability fixes added close to the bug sites
33
+
34
+ However, it also had several long-term costs:
35
+
36
+ - state was distributed across stores, runtime maps, booleans, timers, and callbacks
37
+ - cross-entity coordination rules were implicit rather than named
38
+ - verification of lifecycle invariants required integration reasoning rather than local reducer reasoning
39
+ - new features such as Goals risked growing additional ad hoc coordination paths unless a state model was introduced first
40
+
41
+ The migration therefore aimed to preserve runtime behavior while replacing hidden control flow with explicit events, reducer-owned state, and effect-driven coordination.
42
+
43
+ ---
44
+
45
+ ## 2. Migration principles
46
+
47
+ Five principles guided the migration.
48
+
49
+ ### 2.1 Preserve semantics first
50
+
51
+ The migration is not a feature rewrite. It is a representation change.
52
+
53
+ Every reducer extraction was required to preserve:
54
+
55
+ - existing tool behavior
56
+ - current cleanup semantics
57
+ - current buffering/dedupe rules
58
+ - current session lifecycle behavior
59
+ - current test suite expectations
60
+
61
+ ### 2.2 Add tests before extraction
62
+
63
+ The migration followed a test-first sequence:
64
+
65
+ 1. map state and transitions
66
+ 2. define invariant and scenario matrix
67
+ 3. add entity transition tests
68
+ 4. add scenario tests
69
+ 5. extract reducers behind those tests
70
+
71
+ This ordering reduced the likelihood of silently changing semantics while improving internal structure.
72
+
73
+ ### 2.3 Keep reducers pure
74
+
75
+ Reducers own logical state only.
76
+
77
+ They do **not** own:
78
+
79
+ - child process handles
80
+ - scheduler timer maps
81
+ - event subscription unsubscriber functions
82
+ - Pi UI contexts
83
+ - direct `sendMessage()` calls
84
+ - `AbortController` instances
85
+
86
+ These remain in the effect layer or runtime wrapper modules.
87
+
88
+ ### 2.4 Keep state local by entity family
89
+
90
+ The migration intentionally avoided a single global FSM.
91
+
92
+ Instead, it uses separate reducer families for:
93
+
94
+ - tasks
95
+ - loops
96
+ - notifications
97
+ - monitors
98
+ - later, goals
99
+
100
+ ### 2.5 Name coordination rules explicitly
101
+
102
+ The original runtime embedded many coordination rules directly in imperative logic.
103
+
104
+ The migration names them as explicit events and effects so they can be tested and reasoned about separately.
105
+
106
+ ---
107
+
108
+ ## 3. Original runtime shape
109
+
110
+ Before reducer extraction, the most important state was spread across the following surfaces.
111
+
112
+ ### 3.1 Tasks
113
+
114
+ Logical task state lived in `TaskStore` and native task tool handlers.
115
+
116
+ Hidden coordination included:
117
+
118
+ - pruning after successful `git commit`
119
+ - worker-loop creation at backlog threshold
120
+ - worker-loop cleanup on zero pending tasks
121
+
122
+ ### 3.2 Loops
123
+
124
+ Loop state was partly persisted and partly runtime-owned.
125
+
126
+ Visible loop fields included:
127
+
128
+ - `status`
129
+ - `trigger`
130
+ - `fireCount`
131
+ - `expiresAt`
132
+
133
+ Hidden loop runtime state included:
134
+
135
+ - scheduler fire-time tracking
136
+ - event subscriptions
137
+ - debounce timers
138
+ - notification queueing behavior
139
+
140
+ ### 3.3 Notifications
141
+
142
+ Notification behavior was correct but previously implemented directly in `src/index.ts` through local maps and booleans.
143
+
144
+ That made delivery rules harder to isolate and test as a pure state machine.
145
+
146
+ ### 3.4 Monitors
147
+
148
+ Monitor logical lifecycle and child-process runtime were tightly coupled.
149
+
150
+ The migration needed to separate:
151
+
152
+ - logical lifecycle (`running`, `completed`, `error`, `stopped`)
153
+ - runtime process ownership and signal handling
154
+
155
+ ### 3.5 Cross-entity coordination
156
+
157
+ Rules such as:
158
+
159
+ - backlog threshold -> worker loop creation
160
+ - monitor completion -> wake delivery
161
+ - session switch -> queue clearing
162
+ - zero pending tasks -> backlog loop deletion
163
+
164
+ were all present, but not yet formalized as named coordinator transitions.
165
+
166
+ ---
167
+
168
+ ## 4. Architecture artifacts produced during migration
169
+
170
+ The migration generated a layered architecture record.
171
+
172
+ ### 4.1 Transition inventory
173
+
174
+ `docs/architecture/state-machine-transition-map.md`
175
+
176
+ This document identifies:
177
+
178
+ - explicit states
179
+ - hidden states
180
+ - transition tables
181
+ - duplicated lifecycle encoding
182
+ - refactor hotspots
183
+
184
+ ### 4.2 Test matrix
185
+
186
+ `docs/architecture/state-machine-test-matrix.md`
187
+
188
+ This document turns the transition inventory into a test contract covering:
189
+
190
+ - entity transitions
191
+ - invariants
192
+ - coordination scenarios
193
+
194
+ ### 4.3 Event/effect model
195
+
196
+ `docs/architecture/state-machine-reducer-event-model.md`
197
+
198
+ This defines:
199
+
200
+ - shared reducer event envelope
201
+ - shared effect envelope
202
+ - reducer ownership boundaries
203
+ - event vocabulary
204
+ - coordinator rules
205
+
206
+ ### 4.4 Goal schema
207
+
208
+ `docs/architecture/goal-state-schema.md`
209
+
210
+ This defines the future Goal layer as a reducer-owned, verification-oriented composition of existing reducer state.
211
+
212
+ ---
213
+
214
+ ## 5. Implemented extraction status
215
+
216
+ At the time of this document, the following extractions are complete.
217
+
218
+ ### 5.1 Task reducer extraction
219
+
220
+ Implemented:
221
+
222
+ - `src/task-reducer.ts`
223
+ - `test/task-reducer.test.ts`
224
+ - integration through `src/task-store.ts`
225
+
226
+ Preserved semantics include:
227
+
228
+ - monotonic ids
229
+ - completion timestamps
230
+ - reopen semantics
231
+ - prune semantics
232
+
233
+ ### 5.2 Loop reducer extraction
234
+
235
+ Implemented:
236
+
237
+ - `src/loop-reducer.ts`
238
+ - `test/loop-reducer.test.ts`
239
+ - integration through `src/store.ts`
240
+
241
+ Reducer-owned logical transitions now cover:
242
+
243
+ - create
244
+ - pause
245
+ - resume
246
+ - fire count increments
247
+ - delete
248
+ - expiry deletion
249
+ - backlog-empty deletion
250
+
251
+ ### 5.3 Notification reducer extraction
252
+
253
+ Implemented:
254
+
255
+ - `src/notification-reducer.ts`
256
+ - `test/notification-reducer.test.ts`
257
+ - integration through `src/index.ts`
258
+
259
+ Reducer-owned logical behavior now covers:
260
+
261
+ - queueing
262
+ - recurring dedupe
263
+ - flush gating
264
+ - clearing
265
+ - delivery selection
266
+
267
+ The effect layer still owns actual Pi delivery via `pi.sendMessage()`.
268
+
269
+ ### 5.4 Monitor reducer extraction
270
+
271
+ Implemented:
272
+
273
+ - `src/monitor-reducer.ts`
274
+ - `test/monitor-reducer.test.ts`
275
+ - integration through `src/monitor-manager.ts`
276
+
277
+ Reducer-owned logical behavior now covers:
278
+
279
+ - create
280
+ - output accumulation
281
+ - complete
282
+ - error
283
+ - stop
284
+ - prune
285
+ - onDone registration marker
286
+
287
+ ### 5.5 Coordinator module
288
+
289
+ Implemented:
290
+
291
+ - `src/coordinator.ts`
292
+ - `test/coordinator.test.ts`
293
+
294
+ The coordinator currently exists as a reusable module with:
295
+
296
+ - ordered reducer fan-out
297
+ - ordered effect execution
298
+ - derived event dispatch
299
+ - depth limiting
300
+
301
+ It is not yet fully wired through the main runtime.
302
+
303
+ ### 5.6 Goal verifier prototype
304
+
305
+ Implemented:
306
+
307
+ - `src/goal-types.ts`
308
+ - `src/goal-verifier.ts`
309
+ - `test/goal-verifier.test.ts`
310
+
311
+ This is intentionally read-only and verification-oriented.
312
+
313
+ ---
314
+
315
+ ## 6. Current architecture after extraction
316
+
317
+ The codebase now sits in an intermediate but useful state.
318
+
319
+ ### 6.1 What is already improved
320
+
321
+ - entity state transitions are increasingly centralized in pure reducers
322
+ - transition semantics are backed by focused reducer tests
323
+ - scenario coverage exists for the highest-risk lifecycle behavior
324
+ - goal work no longer needs to start from an undefined state model
325
+
326
+ ### 6.2 What remains transitional
327
+
328
+ The runtime still contains a hybrid structure.
329
+
330
+ For example:
331
+
332
+ - `src/index.ts` still coordinates many behaviors directly
333
+ - stores and managers invoke reducers, but not yet through a single event coordinator path
334
+ - reducer effects are mostly informative today rather than universally executed through the coordinator
335
+
336
+ This is acceptable as a migration phase, but it is not the final architecture.
337
+
338
+ ### 6.3 Default scope decision
339
+
340
+ The recommended default remains `PI_LOOP_SCOPE=session`.
341
+
342
+ Reasoning:
343
+
344
+ - `session` preserves useful intent across a session restart without leaking loops/tasks across concurrent sessions or worktrees
345
+ - `memory` is safer for disposable experiments, but too lossy as a default for long-running loop/task workflows
346
+ - `project` is appropriate only when shared automation is explicitly desired, because it intentionally exposes persisted state across sessions in the same repo
347
+
348
+ This recommendation also fits the current wake model:
349
+
350
+ - pending notifications stay in memory and remain cancelable
351
+ - durable loop/task intent stays isolated per session
352
+ - stale event wakes are already treated as harmless and cleaned up defensively
353
+
354
+ ---
355
+
356
+ ## 7. Recommended final target architecture
357
+
358
+ The recommended end state is:
359
+
360
+ 1. runtime adapters gather facts and external inputs
361
+ 2. coordinator converts them into reducer events
362
+ 3. reducers return next state plus effects
363
+ 4. coordinator executes effects in deterministic order
364
+ 5. runtime wrappers own only imperative side effects
365
+
366
+ ### 7.1 Runtime adapters
367
+
368
+ Examples:
369
+
370
+ - tool handlers
371
+ - scheduler callbacks
372
+ - monitor process callbacks
373
+ - Pi session lifecycle hooks
374
+
375
+ ### 7.2 Reducers
376
+
377
+ Reducers own logical state transitions for:
378
+
379
+ - tasks
380
+ - loops
381
+ - notifications
382
+ - monitors
383
+ - goals
384
+
385
+ ### 7.3 Coordinator
386
+
387
+ The coordinator should become the single place where cross-entity rules are expressed as named dispatch flows.
388
+
389
+ ### 7.4 Effect executors
390
+
391
+ Effect executors should perform:
392
+
393
+ - persistence writes
394
+ - runtime arming/disarming
395
+ - wake delivery
396
+ - pruning and cleanup requests
397
+
398
+ This gives the system a clear separation between meaning and mechanism.
399
+
400
+ ---
401
+
402
+ ## 8. Recommended adoption sequence from here
403
+
404
+ The safest rollout sequence is incremental.
405
+
406
+ ### Step 1 — keep current reducer-backed wrappers stable
407
+
408
+ Do not remove the current `TaskStore`, `LoopStore`, `MonitorManager`, or notification helpers yet.
409
+
410
+ Instead, continue using them as adapter layers around reducer logic.
411
+
412
+ ### Step 2 — introduce coordinator wiring in narrow slices
413
+
414
+ The first coordinator adoption should focus on one contained path at a time.
415
+
416
+ Suggested order:
417
+
418
+ 1. notification queue/flush path inside `src/index.ts`
419
+ 2. loop fire -> notification dispatch path
420
+ 3. task backlog threshold / empty-queue coordination path
421
+ 4. monitor completion -> wake path
422
+
423
+ ### Step 3 — move effect execution behind coordinator handlers
424
+
425
+ As each slice moves over, imperative code should become effect execution rather than state mutation.
426
+
427
+ ### Step 4 — add a goal reducer
428
+
429
+ Once the coordinator is meaningfully integrated, add a true `reduceGoalState(...)` layer rather than keeping goal work verifier-only.
430
+
431
+ ### Step 5 — remove redundant imperative state paths
432
+
433
+ Only after coordinator-owned dispatch is proven stable should old duplicated state paths be deleted.
434
+
435
+ ---
436
+
437
+ ## 9. Risks and sharp edges
438
+
439
+ Several risks remain even after the current extraction work.
440
+
441
+ ### 9.1 Dual paths during migration
442
+
443
+ During transition, some state moves through reducers while orchestration remains imperative.
444
+
445
+ Risk:
446
+
447
+ - duplicated semantics
448
+ - logic drift between wrappers and coordinator adoption
449
+
450
+ Mitigation:
451
+
452
+ - keep reducer tests authoritative
453
+ - convert one path at a time
454
+ - avoid broad rewrites
455
+
456
+ ### 9.2 Notification delivery is still timing-sensitive
457
+
458
+ Notification logic is much clearer now, but actual delivery still depends on runtime conditions such as:
459
+
460
+ - agent activity
461
+ - pending message state
462
+ - delivery-time task counts
463
+
464
+ Mitigation:
465
+
466
+ - preserve scenario tests
467
+ - move flush triggering into coordinator slices carefully
468
+
469
+ ### 9.3 Monitor runtime is still inherently imperative
470
+
471
+ Child processes, signals, and close/error ordering remain imperative concerns even after reducer extraction.
472
+
473
+ Mitigation:
474
+
475
+ - keep runtime handle ownership in `MonitorManager`
476
+ - only reduce logical state
477
+ - preserve stop/completion race tests
478
+
479
+ ### 9.4 Goals can grow too ambitious too early
480
+
481
+ The goal prototype is intentionally read-only.
482
+
483
+ Risk:
484
+
485
+ - adding autonomous write-side goal behavior before coordinator adoption is mature
486
+
487
+ Mitigation:
488
+
489
+ - keep goal verification read-only until reducer/coordinator integration is stable
490
+
491
+ ---
492
+
493
+ ## 10. Validation strategy
494
+
495
+ The migration should continue to rely on three validation layers.
496
+
497
+ ### 10.1 Reducer unit tests
498
+
499
+ These verify pure transition correctness.
500
+
501
+ ### 10.2 Existing integration/scenario tests
502
+
503
+ These ensure runtime semantics remain stable while adapters are refactored.
504
+
505
+ ### 10.3 Full repo validation
506
+
507
+ Continue using:
508
+
509
+ - `npm run lint`
510
+ - `npm run typecheck`
511
+ - `npm run test`
512
+ - `git diff --check`
513
+
514
+ for every migration step.
515
+
516
+ ---
517
+
518
+ ## 11. What this migration has achieved
519
+
520
+ The most important result is not merely new code. It is a new constraint on future code.
521
+
522
+ We now have:
523
+
524
+ - a transition inventory
525
+ - a test contract
526
+ - reducer modules for the four existing entity families
527
+ - a coordinator abstraction
528
+ - a goal schema and verifier prototype
529
+
530
+ This means future work can be judged against a coherent architecture instead of a collection of local fixes.
531
+
532
+ ---
533
+
534
+ ## 12. Summary
535
+
536
+ The migration has moved `pi-loop` from a runtime whose correctness depended heavily on imperative control flow toward one whose semantics are increasingly explicit, reducer-owned, and test-backed.
537
+
538
+ The system is not yet at the final architecture. However, it now has the essential ingredients needed to finish the transition safely:
539
+
540
+ - named events
541
+ - reducer state boundaries
542
+ - effect boundaries
543
+ - coordinator machinery
544
+ - verification-oriented goal design
545
+
546
+ The recommended next step, if further work continues, is to adopt the coordinator in narrow runtime slices rather than attempt a single large integration rewrite.