@earendil-works/pi-durable 0.0.1 → 0.86.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.
@@ -0,0 +1,341 @@
1
+ # Pico5 implementation handoff
2
+
3
+ `packages/durable/docs/pico-v5.md` is normative. Implement this list in order.
4
+ After every package: run its tests, run `npm run check`, and stop for user review.
5
+ Do not redesign later packages while implementing the current one.
6
+
7
+ Pico3 is reference material only. Preserve useful behavior, not its capability
8
+ facades, membranes, document routing, view projection, events, or clone chains.
9
+
10
+ ## Status
11
+
12
+ - Obsolete `pico` and `pico4` prototypes were removed.
13
+ - `pico3` remains.
14
+ - No Pico5 implementation exists.
15
+
16
+ ## 1. Records, cursors, and memory tables
17
+
18
+ Implement IDs, sequences, reserved root conversation ID `1`,
19
+ `ConversationRecord`, `EntryRecord`, tagged inputs, live/terminal `TaskRecord`
20
+ values, document lifecycle records, storage writes, backend-opaque JSON cursors, and
21
+ detached `MemoryStorage` tables.
22
+ Reserve `Conversation` for the public conversation object, `Entry` for the typed
23
+ entry definition, and `Task` for the typed executable definition returned by
24
+ `defineTask()`.
25
+
26
+ Test reserved root identity and immutable creation, mixed atomic commits,
27
+ rollback, detached reads/writes, cursor boundaries,
28
+ fork-aware entry scans through deep ancestor caps, head lookup,
29
+ entry-to-commit lookup, and full task replacement.
30
+
31
+ ## 2. Memory document records
32
+
33
+ Add selected document base/delta writes, retirement, reincarnation,
34
+ current/as-of membership, exact logical-address lookup, scoped scans, and
35
+ base-plus-tail reconstruction. Storage receives no definition callbacks or
36
+ unused candidate values.
37
+
38
+ Test Session-, conversation-, and task-scoped documents, half-open lifetimes,
39
+ create-plus-retire, retired historical membership, family queries, current-only
40
+ reclamation, version boundaries, detached ownership, and no scans of unrelated
41
+ document records.
42
+
43
+ ## 3. SQLite backend
44
+
45
+ Implement the complete storage contract with ordinary rows and indexed document
46
+ records. Do not translate Chord operations into SQL JSON patches.
47
+
48
+ Run the memory conformance suite after reopen. Test SQL transaction rollback,
49
+ recent/ancient as-of reads, query plans, latest reclamation, WAL checkpointing,
50
+ deleted-page reuse, and representative storage sizes.
51
+
52
+ ## 4. JSONL publication
53
+
54
+ Implement table writes in `main.jsonl`, one document sidecar per incarnation,
55
+ one sidecar per live task, and one main marker per commit. Do not add a
56
+ standalone-sidecar protocol. Serialization must also provide the storage ownership
57
+ boundary: retained indexes/materializations are detached from write arguments,
58
+ and reads never expose backend-owned cached objects.
59
+
60
+ Fault-test torn/short sidecar writes, failures between sidecars, every marker
61
+ boundary, unconfirmed tails, missing confirmed data, and poisoned writes.
62
+
63
+ ## 5. JSONL reclamation
64
+
65
+ Implement task-document retirement and current-only base reclamation using
66
+ committed markers, temporary replacement, rename, and descriptor invalidation.
67
+
68
+ Crash-test every rewrite/rename boundary. Verify that rewindable history is
69
+ never reclaimed and default no-fsync behavior matches the specification.
70
+
71
+ ## 6. Tracker transaction core
72
+
73
+ Keep one tracker per loaded document. Add transaction begin, callback rollback
74
+ from the unchanged baseline, flush, fatal post-flush failure, committed baseline
75
+ adoption, and eviction. After storage succeeds, materialize one immutable
76
+ published value per changed document with `applyImmutable(previous, ops)`,
77
+ separate from mutable tracker and borrowed storage candidates.
78
+
79
+ Do not add membranes, transaction proxy graphs, capability facades, or defensive
80
+ full-document clones. Test callback failure, no-op transactions, storage failure
81
+ poisoning, immutable prior published values, replacement-payload ownership, and
82
+ unload/reload.
83
+
84
+ ## 7. Document definitions and access
85
+
86
+ Implement `defineDoc`, `defineDocFamily`, document kind/key validation, the three
87
+ direct scopes, and get-or-create `tx.doc`, `snapshot`, and `documentSource`
88
+ acquisition. Definitions are explicit typed arguments, not registered declarations;
89
+ conflicting definitions that claim one persisted kind are unsupported caller
90
+ misuse.
91
+
92
+ Test concurrent initialization once, initial bases, detached snapshots, family
93
+ initializer use only on first creation, scope/target mismatch, terminal-task
94
+ rejection, task-derived conversation identity, retirement, and
95
+ reincarnation-bound sources. Include create-task-then-document,
96
+ document-after-terminal rejection, and create-document-then-terminal settlement
97
+ in one transaction; internal candidate validation must not trigger
98
+ `ReadAfterWrite`.
99
+
100
+ ## 8. Checkpoints and migration
101
+
102
+ After tracker flush, Session evaluates `checkpointWhen(value, ops)` exactly once
103
+ for ordinary mutations and sends Storage only the selected base or delta.
104
+ Implement required creation/version bases and lazy all-older-version migration
105
+ on typed access; Harness open does not scan ordinary documents.
106
+
107
+ Test latest migration persistence, `tx.doc()` migration rollback and coalescing
108
+ with later edits, rewindable migration on current/historical read, first
109
+ post-migration mutation base, newer-version rejection, unaccessed and unavailable-definition
110
+ preservation, predicate failure poisoning, and checkpoint starvation without
111
+ backend heuristics.
112
+
113
+ ## 9. Conversation document forks
114
+
115
+ Using fixture conversations and entry-to-commit mappings, implement the `asOf`,
116
+ `current`, and `initial` settings for singleton and family documents.
117
+
118
+ Test opaque stored-version copying without definitions, retired membership, new
119
+ child incarnations, later lazy migration, lazy `initial` creation, and exclusion
120
+ of task- and Session-scoped documents.
121
+
122
+ ## 10. Chord structural array operations
123
+
124
+ Make ordinary positional mutations encode scattered removals without carrying
125
+ retained payloads. Callers must not write operations manually.
126
+
127
+ Test front/tail/middle/scattered/all/no removal, retained 256 KiB and 1 MiB
128
+ payloads, append plus removal, later nested/index writes, exact replay, and
129
+ unchanged previous immutable snapshots. Internal flushes must remain one commit.
130
+
131
+ ## 11. Chord document source
132
+
133
+ Add the thin opaque-source adapter to `ReplicatedState`. It must use committed
134
+ value/ops directly, with no tracker or re-diff.
135
+
136
+ Test contiguous Chord adapter delivery sequences, atomic hydrate/subscribe,
137
+ attachment races, retirement ending one incarnation, recreation requiring
138
+ reacquisition, and listener isolation. Reuse the transaction core's immutable
139
+ published value; do not materialize another document copy.
140
+
141
+ ## 12. Document watches
142
+
143
+ Implement get-or-create `watchDoc` as an incarnation-bound `WatchHandle` that
144
+ atomically captures one fixed immutable value and registers for later committed
145
+ operation batches. `start()` installs one serialized asynchronous listener.
146
+ Bound the pending queue only by the total number of operations in its undelivered
147
+ batches. Never estimate serialized bytes or call `JSON.stringify()` for delta
148
+ queue accounting. When the operation-count limit is exceeded, compact the entire
149
+ undelivered suffix into one root replacement using the matching latest immutable
150
+ published value from package 6; never retain mutable tracker or borrowed storage
151
+ candidates.
152
+
153
+ Test updates between acquisition/return/start; asynchronous consumer
154
+ initialization; no callback overlap; listener-initiated commits; compaction
155
+ before start and behind an in-flight callback; one over-limit commit batch;
156
+ repeated overload behind a pending reset; empty batches and repeated unchanged
157
+ view commits consuming no queue space; no serialization during queue accounting;
158
+ immutable earlier values; retirement before start and while active;
159
+ recreation; idempotent stop; second-start rejection; cancellation during acquisition;
160
+ cancellation/close during a callback; listener-error settlement; `closed`
161
+ self-join misuse; and invocation-owned
162
+ cleanup in package 15.
163
+
164
+ ## 13. Conversations and entries
165
+
166
+ Implement conversation history/ownership records, entry creation,
167
+ conversation-bound cursor-based fork-aware scans, head lookup, and entry edits.
168
+ Expose public history pagination through `Conversation.entries()`, never through
169
+ `Harness`.
170
+
171
+ Test conversation creation and actual forks, deep ancestor caps, same-commit
172
+ entry prefixes, newest-edit wins, self-head resolution, raw head-to-tail
173
+ transcript, and ownership traversal.
174
+
175
+ ## 14. Context derivation and system messages
176
+
177
+ Implement model-context reduction, PR #9548 positional `SystemMessage` replay,
178
+ tool-result ordering, and missing post-fork tool results. Replay `content`,
179
+ ordered named `sections` with `null` removal, then tool removals/additions.
180
+
181
+ Test model-less and excluded-stop-reason entries, replacements/omissions,
182
+ multiple heads, section replacement/removal/re-addition order, order-only
183
+ configuration changes between separate request preparations, rejection of
184
+ integer-like section keys, tool addition/removal/replacement order, and raw-view
185
+ versus model context.
186
+
187
+ ## 15. Task definitions and invocations
188
+
189
+ Implement `defineTask`, exhaustive phase maps, full checkpoint replacement,
190
+ kind migration, runtime commits, memos, and invocation close gates.
191
+
192
+ Use a fake two-phase effect. Test intent/effect/outcome recovery,
193
+ unchanged-checkpoint faulting, same-phase checkpoint progress, cancellation
194
+ precedence, thrown-handler faulting, close/reopen without abort marks, outcomes,
195
+ or task-document retirement, no fresh phase/abort dispatch while closing,
196
+ first-writer-wins memos, and automatic watch cleanup.
197
+
198
+ ## 16. Scheduler and terminal tasks
199
+
200
+ Implement reservation, running-task reopen reconciliation, dependencies,
201
+ terminal outcomes, waits, holds, joins, and orphaning.
202
+
203
+ Test result values and entry IDs, terminal records after reopen, dependency
204
+ eligibility, unknown kinds, and terminal removal of checkpoints/memos.
205
+
206
+ ## 17. Abort and owned conversations
207
+
208
+ Implement durable abort marks, signal/join/fresh-abort invocation, owned
209
+ conversation creation, subtree traversal, background behavior, and idle waits.
210
+
211
+ Test commit rejection after a run task is marked, crashes at every abort stage,
212
+ close precedence over a previously marked task, deep ownership trees, atomic
213
+ retirement of task-scoped documents, default non-inheritance, inheritance from
214
+ the current committed tail, an empty source conversation, document fork
215
+ policies, and explicit model/section seed overrides.
216
+
217
+ ## 18. Inputs and positional inbox
218
+
219
+ Define the initial inbox and turn-control documents, then implement request-ID
220
+ deduplication, awaitable input handles, busy admission, withdrawal, queue modes,
221
+ and `postTools`/`final` boundaries. Use a fake successor task.
222
+
223
+ Table-test every input transition, interleaved steer/follow-up/write selection,
224
+ self-head cuts, stale targets, successor triggers, reopen waits, compact
225
+ large-payload removals, and orphan/fault cleanup of active turn control.
226
+
227
+ ## 19. Remaining built-in documents and view
228
+
229
+ Define the concrete configuration, preference, and live presentation documents;
230
+ reuse the approved inbox/turn definitions. Record all IDs, fields, history,
231
+ fork settings, migration, and checkpoint predicates in the normative
232
+ specification.
233
+
234
+ Implement `{ conversation, entries, docs }`. Test direct task writes, one
235
+ publication per Session commit, atomic
236
+ entry/preview settlement, head changes, contiguous revisions, stable public
237
+ paths, immutable acquisition snapshots, asynchronous consumer initialization,
238
+ serialized updates, reset compaction, retry/collapse late-join status,
239
+ bounded-output truncation metadata, and absence of semantic projection. Specify which
240
+ diagnostics become entries,
241
+ terminal details, or bounded document state.
242
+
243
+ ## 20. Registries, hooks, and sections
244
+
245
+ Implement task/tool/section registries, Session and owned-subtree hooks,
246
+ positional PR #9548 section/tool updates, complete baselines after a head cut,
247
+ and preparation revision checks. Do not add a Session-kernel semantic event
248
+ journal or extension-state router; package 24 adds the thin product notification
249
+ adapter from specification §9.4.
250
+
251
+ Test registration lifetimes, hook replay with memos, exact persisted rendered
252
+ section strings, minimal section patches and `null` removals, complete baseline
253
+ tool declarations, and a head cut that retains earlier system messages. Verify
254
+ the new baseline entry omits those messages through `ContextEdit` before replay,
255
+ including retained `content`, section order, and tool changes. Include a retained
256
+ delta whose ID precedes the head-carrying entry: select omissions by retained
257
+ context membership, not an ID comparison with the head entry. Test tool loadout
258
+ additions/removals and preparation retry after registry movement. Do
259
+ not implement in-process replacement of Session-side extension code; a host extension
260
+ change uses the Harness close/reopen boundary.
261
+
262
+ ## 21. Tool and post-tools tasks
263
+
264
+ Implement offered-set checks, argument validation, tool hooks, durable bounded
265
+ progress, owned APIs, interrupted/replay-safe recovery, result entries,
266
+ post-tools joining, controls, and boundaries using fake tools.
267
+
268
+ Test recovery from every phase, both stored/current replay-policy directions,
269
+ default and overridden bounds, streamed-content fallback, progress replacement
270
+ and coalesced commit settlement, drain-before-terminal ordering,
271
+ abort/close with buffered output, invocation-bound owned handles, and atomic
272
+ assistant/tool/post-tools settlement. Use a fake
273
+ generation successor; package 22 replaces it and reruns integration.
274
+
275
+ ## 22. Generation task
276
+
277
+ Implement preparation, request intent, durable throttled partials, attempts,
278
+ retry policy, response classification, continuation, and deferred polling/
279
+ cancellation through pi-ai's exported `Models` interface. Do not add a Pico
280
+ model adapter. The faux test double implements that same interface.
281
+
282
+ Test every phase before and after reopen, aborted partial conversion, overflow
283
+ through a fake collapse kind, input settlement, and no visible-undurable update.
284
+ Replace the fake tool successor and rerun the package 21 integration tests.
285
+
286
+ ## 23. Collapse task
287
+
288
+ Implement manual, threshold, and overflow collapse; exchange-boundary range
289
+ selection; summarization; retries; staleness; and headed summary entries.
290
+
291
+ Test context before/after collapse, provider failure, declined/stale work, and
292
+ reopen from every phase. Replace generation's fake overflow target and rerun its
293
+ overflow integration test.
294
+
295
+ ## 24. Harness integration
296
+
297
+ Implement the exact Pico3-shaped public surface in specification §2.2:
298
+ `Harness.open/resume/suspend/close`, lifecycle gates, root/create/lookup
299
+ `Conversation` objects, ordered `write` handles, send/input handles,
300
+ conversation-bound commits and history pagination, fork/collapse/reset/abort/idle,
301
+ typed task wait/abort, generic document access, task/tool/section registries, and structural conversation watches. Do not restore Pico3's
302
+ namespace router, fixed document accessors, semantic view events, or manual Chord
303
+ view bridge.
304
+
305
+ Expose service withdrawal/client detach and product wiring. Implement the §9.4
306
+ agent-mode notification adapter directly from uncoalesced committed publication,
307
+ without another tracker or persistence authority. Migrate TUI hydration to the
308
+ structural conversation watch, make print await its own `InputHandle`, and expose
309
+ JSON/RPC correlated commands plus ordered committed notifications. Test that
310
+ watch reset compaction cannot erase a subscribed notification lifecycle, late
311
+ clients use structural hydration rather than event replay, progress notifications
312
+ reflect durable throttled state rather than every provider frame, and stdout
313
+ backpressure/disconnect policy stays in the mode adapter.
314
+
315
+ Implement the v1 host-extension reload path as stop admission, close/join, dispose,
316
+ rebuild with new document tokens and registered task/tool/section definitions, reopen/migrate live tasks, and resume. Ordinary documents migrate
317
+ on later typed access. Test that closing seals commit and
318
+ get-or-create admission, lets storage settlement for already-flushed admitted
319
+ commits finish despite caller cancellation, stops watches, joins in-flight watch
320
+ callbacks and task/tool/hook invocations outside the Session line, writes no abort
321
+ or terminal outcome, starts no fresh abort invocation, and does not run old and
322
+ new generations concurrently. Include cancellation during watch acquisition and
323
+ a non-cooperative watch callback in shutdown/extension-reload quiescence tests.
324
+
325
+ Test stable persisted root identity; atomic conversation/config/section/input
326
+ creation; default `"off"` thinking; every configuration getter/setter; explicit
327
+ active-tool seed duplicate/unregistered rejection; default active registry
328
+ snapshot; as-of fork inheritance including unavailable historical names; durable
329
+ `missing_active_tool` settlement; fork seed overrides; concrete-entry forks;
330
+ collapse task-ID return;
331
+ busy reset admission and later placement; mark-only versus signalling abort;
332
+ conversation abort/join with surviving passive writes and background tasks;
333
+ quiescence with eligible work; listener initial/future delivery and isolation;
334
+ and runtime registration between open and resume without resurrection of a task
335
+ settled during open.
336
+
337
+ Compile-test every §2.2 signature and the usage sequences in the normative
338
+ specification and Chord guide. The erased registry test must include a concrete task with narrowed
339
+ input, multiple checkpoint phases, and custom hooks. Run all package-specific
340
+ tests and the repository check. Verify a local
341
+ coding-agent turn and a reopened interrupted turn, then stop for final review.