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