pi-supernova 0.8.2 → 0.9.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 (67) hide show
  1. package/README.md +188 -51
  2. package/docs/CHANGELOG.md +86 -1
  3. package/docs/TOKEN_COSTS.md +38 -0
  4. package/index.js +10 -175
  5. package/package.json +2 -1
  6. package/src/adapters/bash.js +14 -30
  7. package/src/adapters/errors.js +1 -9
  8. package/src/adapters/read-focus.js +98 -0
  9. package/src/adapters/read-image.js +51 -0
  10. package/src/adapters/read-json.js +42 -0
  11. package/src/adapters/read-text.js +71 -0
  12. package/src/adapters/read.js +66 -635
  13. package/src/bridge/catalog.js +3 -2
  14. package/src/bridge/host-bridge.js +35 -167
  15. package/src/bridge/tool-registry.js +104 -0
  16. package/src/bridge/trace.js +41 -0
  17. package/src/context/evidence-graph.js +249 -0
  18. package/src/context/evidence-rank.js +153 -0
  19. package/src/context/evidence.js +10 -424
  20. package/src/context/fuzzy.js +116 -43
  21. package/src/context/query.js +80 -0
  22. package/src/context/repo-index.js +23 -166
  23. package/src/context/search-files.js +19 -0
  24. package/src/context/search.js +2 -24
  25. package/src/context/snap-search.js +203 -0
  26. package/src/context/snap.js +5 -266
  27. package/src/context/source-entry.js +112 -0
  28. package/src/contract/bash.js +6 -1
  29. package/src/contract/program.js +36 -0
  30. package/src/contract/read.js +8 -53
  31. package/src/fs/check.js +1 -1
  32. package/src/fs/commit.js +161 -0
  33. package/src/fs/diff.js +11 -15
  34. package/src/fs/directory.js +79 -0
  35. package/src/fs/file-io.js +100 -0
  36. package/src/fs/glob.js +54 -0
  37. package/src/fs/json-size.js +54 -0
  38. package/src/fs/lines.js +117 -0
  39. package/src/fs/read-window.js +74 -0
  40. package/src/fs/session-resource.js +50 -0
  41. package/src/fs/text-ops.js +7 -227
  42. package/src/fs/vfs.js +5 -239
  43. package/src/fs/workspace.js +2 -1
  44. package/src/output/bottleneck.js +13 -67
  45. package/src/output/final.js +114 -0
  46. package/src/output/format.js +94 -5
  47. package/src/output/outcome.js +91 -0
  48. package/src/runtime/batch-input.js +68 -0
  49. package/src/runtime/guest-api.js +281 -0
  50. package/src/runtime/guest-worker.js +62 -333
  51. package/src/runtime/parallel.js +41 -39
  52. package/src/runtime/program-batch.js +21 -75
  53. package/src/runtime/program-file.js +3 -11
  54. package/src/runtime/program.js +141 -0
  55. package/src/runtime/reference.js +6 -5
  56. package/src/runtime/runtime.js +77 -253
  57. package/src/runtime/worker-pool.js +91 -0
  58. package/src/shared/decode.js +22 -8
  59. package/src/shared/image-worker.js +30 -0
  60. package/src/shared/image.js +78 -0
  61. package/src/shared/png.js +57 -0
  62. package/src/shared/result.js +77 -0
  63. package/src/shared/syntax-context.js +61 -3
  64. package/src/ui/host-render.js +104 -0
  65. package/src/ui/progress.js +51 -0
  66. package/src/ui/render.js +21 -421
  67. package/src/ui/trace.js +277 -0
package/README.md CHANGED
@@ -12,6 +12,69 @@ Ordinary JavaScript control flow remains available; the guest command bindings
12
12
  are only `read`, `edit`, `write`, and `bash`. Supernova supplies retrieval,
13
13
  transactional file operations, batching, bounded results and the grouped nova UI.
14
14
 
15
+ ## What is new in 0.9.0
16
+
17
+ - **Text clipping does not stop batches:** sequential and parallel programs keep
18
+ running when the combined display text exceeds its allowance. Results disclose
19
+ truncation; execution, deadline, host-call, log and image limits remain enforced.
20
+ - **Decoded image validation:** PNG/JPEG/GIF/WebP reads and returned attachments
21
+ require matching formats, canonical base64 and decodable pixels, including all
22
+ GIF/WebP frames. PNG preflight checks chunk boundaries and CRCs too. Failures
23
+ occur before shell boundaries or final commit/delivery, with no image attached.
24
+ - **Isolated image work:** Sharp 0.35.4 decodes at most 32 million pixels across
25
+ all frames, one image at a time, in a Node/Bun subprocess with a 5-second kill
26
+ deadline. Text-only work never loads the decoder. A bounded 16-entry digest cache
27
+ avoids decoding unchanged bytes again; neither image data nor file paths are cached.
28
+ Encoded limits remain 16 attachments / 20 MiB. Sharp's platform-specific optional
29
+ dependencies must be installed; decoder failure never falls back to unchecked data.
30
+ Local decoding does not guarantee acceptance under every provider's image policy.
31
+
32
+ - **Data is not a display preview:** ordinary text reads return complete data up to
33
+ 64 MiB; JSON selections remain actual values and directories remain arrays.
34
+ The former 160-line / 8192-character and 31,744-character restrictions no longer
35
+ constrain computation inside a program. Only returned/logged text is displayed.
36
+ - **Large batches stay bounded:** small reads share one reply; larger items are
37
+ delivered with acknowledgements within eight I/O slots, not retained as one
38
+ giant host-side batch. Explicit arrays and coalesced reads use the same path.
39
+ - **Output work stays in the worker:** bounded formatting avoids expanding large
40
+ values before clipping. Model-visible source previews retain exact ranges and
41
+ continuation; a clipped preview cannot be passed back as a complete edit view.
42
+
43
+ - **Cancellation no longer crashes the host:** bounded reads and CAS signing use
44
+ abort-checked file handles instead of aborting streams. A failed read can cancel
45
+ sibling reads without an uncaught `AbortError` terminating OMP.
46
+ - **Memory is charged to the guest:** worker-local heap and external buffers
47
+ replace process-wide RSS accounting. Bun enforcement remains best-effort.
48
+ - **Focused internals:** read adapters, file I/O, transactions, worker lifecycle,
49
+ tool ownership, source ranking and rendering have separate modules. All read
50
+ modes, batching, checkpoints and rollback behavior remain supported.
51
+
52
+ **Verified release candidate:** 315/315 package tests pass on both Node and Bun;
53
+ actual Pi/OMP checks and clean tarball installation checks also pass. See
54
+ [verification results and coverage limits](#verification) below.
55
+
56
+ ### Concurrent file operations
57
+
58
+ Batching and explicit parallel programs remain supported. Within one program,
59
+ `Promise.all` now overlaps native edits and writes to different files, up to eight
60
+ operations at once:
61
+
62
+ ```js
63
+ await Promise.all([
64
+ edit("src/a.js", "oldA", "newA"),
65
+ edit("src/b.js", "oldB", "newB"),
66
+ ]);
67
+ return await bash("npm test");
68
+ ```
69
+
70
+ Same-file operations retain submission order. Reads before/after mutations,
71
+ `bash`, edit checkpoints, and overridden mutating tools remain ordering barriers.
72
+ Shell calls inside one program stay sequential; use `programs` with
73
+ `parallel:true` for explicitly independent shell workflows or separate JS workers.
74
+ Edits still stage until program success (or a shell boundary); transactional disk
75
+ commits retain their conflict checks. `await edit(...)` one after another is still
76
+ sequential, and multiple replacements in one file remain one edit operation.
77
+
15
78
  ## What is new in 0.8.2
16
79
 
17
80
  This patch release fixes shell failure handling, cancellation and parallel-batch
@@ -28,10 +91,11 @@ limits, and makes one-call batching guidance explicit.
28
91
  and gives pending host calls a bounded drain to retain shell output. Explicit
29
92
  cancellation is reported separately from timeout. The outer `timeoutMs` covers
30
93
  every wait and command, including `sleep`.
31
- - **Parallel budgets fail honestly:** exceeding the shared output, log or image
94
+ - **Parallel budgets fail honestly:** exceeding the shared log or image
32
95
  allowance marks the batch failed and stops queued entries. Already-running
33
96
  entries settle; their results and completed commits remain. Aggregate logs stay
34
- capped rather than multiplying the allowance per guest.
97
+ capped rather than multiplying the allowance per guest. In 0.8.2 this also
98
+ applied to output text; 0.9.0 makes display-text clipping nonfatal.
35
99
  - **Batch known work in one call:** combine independent reads/checks with
36
100
  `Promise.all`, then sequence edits and verification in the same program. Use
37
101
  another invocation when returned evidence is needed for the next decision.
@@ -55,7 +119,7 @@ checks. This is not a claim of exhaustive platform or formal mutation testing.
55
119
  original cause and `committed`/`rolledBack` totals, marks writes whose
56
120
  persistence cannot be attributed as attempted, and labels pure JavaScript runs
57
121
  instead of "complete".
58
- - **Bounded, explicit reads:** errors state both limits (`160 lines / 8192
122
+ - **Historical read limits (superseded in 0.9.0):** errors stated both limits (`160 lines / 8192
59
123
  characters`) with copyable recovery (`offset`, `about`, `complete:true`, and
60
124
  `Promise.allSettled` for optional siblings). Markdown edits skip code-reference
61
125
  searches; exact-symbol evidence excludes generic matches.
@@ -109,12 +173,24 @@ Local checkout installs are for development, not distribution:
109
173
  pi install /path/to/pi-stack/packages/pi-supernova
110
174
  ```
111
175
 
176
+ 0.9.0 adds Sharp for image validation. Keep its platform-specific optional
177
+ dependencies enabled. For a local checkout, refresh dependencies before starting
178
+ the host:
179
+
180
+ ```bash
181
+ npm install --prefix /path/to/pi-stack/packages/pi-supernova --include=optional
182
+ ```
183
+
184
+ Install dependencies on each target machine rather than copying `node_modules`
185
+ between operating systems or CPU architectures. Published-package installation
186
+ resolves these dependencies through the host's package manager.
187
+
112
188
  Git pushes do not update npm installations. Publish the new npm version first,
113
- then reinstall it in your host. To pin **0.8.2** once it is published:
189
+ then reinstall it in your host. To pin **0.9.0** once it is published:
114
190
 
115
191
  ```bash
116
- pi install npm:pi-supernova@0.8.2
117
- omp install npm:pi-supernova@0.8.2
192
+ pi install npm:pi-supernova@0.9.0
193
+ omp install npm:pi-supernova@0.9.0
118
194
  ```
119
195
 
120
196
  In Pi, `pi list` shows the configured package sources. A local path uses that
@@ -184,7 +260,7 @@ questions reuse lexical stemming. Source questions and focused `about` reads
184
260
  accept at most 16 keywords. Ripgrep must be available on PATH.
185
261
 
186
262
  `read(path)` stays raw text. `read("symbol")` is the same view as
187
- `read({query, resolve:true})` — not the file, not a path/range header:
263
+ `read({query, resolve:true})` -- not the file, not a path/range header:
188
264
 
189
265
  ```javascript
190
266
  const v = await read("validateRefreshToken");
@@ -193,7 +269,8 @@ await edit(v, v.text.replace("token.length > 3", "token.length > 5"));
193
269
  ```
194
270
 
195
271
  The view contains `status`, `path`, the matching `line`, span `lines`, unchanged
196
- `text`, `complete`, and `nextOffset` when a budget clip continues. A declaration
272
+ `text`, `complete`, and `nextOffset` when a model-facing preview continues.
273
+ The internal view is not shortened to fit the display. A declaration
197
274
  snap is that span (`complete` is false unless the span is the whole file). Uncertain
198
275
  results report `ambiguous`, `not_found` or `incomplete` with no selected path.
199
276
  Use `{path: directory, about: question}` to narrow the scope. Scoping a query
@@ -225,17 +302,18 @@ lines. Structural warnings and source windows are not substitutes for tests.
225
302
 
226
303
  ### Safe read-modify-write
227
304
 
228
- Path-only `read(path)` requires at most **160 lines and 8192 UTF-16 characters**.
229
- A short document can exceed the character limit. For larger files use
230
- `read(path,{offset:1,limit:80})` (one-based lines), `read(path,{about:"keywords"})`,
231
- or `read(path,{complete:true})`. The default raw-text read budget is **31,744
232
- characters**, derived from the configured call/return budgets, not an unlimited
233
- full-file buffer. Large JSONL needs a bounded parser through `bash({command,args})`.
234
-
235
- Plain reads are bounded views, not guaranteed full-file buffers. Use
236
- `read({path:"file.txt",complete:true})` when code needs the complete file; it
237
- throws rather than handing back partial text. Prefer `edit` for large-file
238
- replacements, or reconstruct exact `resolve:true` windows before writing.
305
+ A plain file read returns its complete text up to the **64 MiB UTF-8 I/O limit**,
306
+ independently of model-facing character budgets. Explicit `offset`/`limit` reads
307
+ return exact line windows, including long lines and LF/CRLF endings, or fail at
308
+ the same byte ceiling. Staged and on-disk data obey the same ceiling.
309
+ `complete:true` additionally rejects a window that omits part of the file.
310
+ For larger files/JSONL, use a bounded parser through `bash({command,args})`.
311
+
312
+ Compute on the full value and return only what the model needs. A direct large
313
+ return is an explicitly truncated display, not a complete artifact to parse or
314
+ write back. `resolve:true` source previews retain path/range/continuation metadata;
315
+ clipped previews are not editable. Prefer `edit` for replacements.
316
+ A write after reading that path still requires `edit` or explicit `replace:true`.
239
317
  Writes reject Supernova truncation markers, including legacy host-result markers.
240
318
  For intentionally writing literal marker documentation only, opt in with
241
319
  `write({path,content,allowReadArtifacts:true})`. This is a data-loss guard, not
@@ -249,6 +327,10 @@ These checks do not provide a cross-process lock or make shell/import mutations
249
327
  transactional. Extensionless filenames also support `complete:true`, for example
250
328
  `read({path:"LICENSE",complete:true})`.
251
329
 
330
+ Directory reads return complete string-entry arrays up to **10,000 unique entries**.
331
+ Larger listings fail with a path and bounded-parser guidance rather than silently
332
+ returning an incomplete array. Metadata lookups overlap eight at a time.
333
+
252
334
  Explicit read arrays reject missing/failed paths. For typed partial outcomes use
253
335
  `Promise.allSettled(paths.map(path => read(path)))`. Successful arrays remain arrays.
254
336
  For literal file content or scripts, prefer the optional tool-level `data` parameter:
@@ -378,7 +460,8 @@ programs that depend on whole-input replacement keep that behavior unless the
378
460
  caller explicitly requests `mergeData:true`.
379
461
 
380
462
  The batch stops on the first failed entry, cancellation/deadline, or exhausted
381
- output/log/image budget. Earlier successful commits remain; only the active
463
+ log/image budget. Display-text clipping does not stop execution or mark a
464
+ successful batch failed. Earlier successful commits remain; only the active
382
465
  program's uncommitted writes roll back. Admission errors throw before any program.
383
466
  Execution failures return a **typed stop report**, rather than throwing away prior
384
467
  results/images: isError and details.ok identify failure, details.programs contains
@@ -390,15 +473,16 @@ Set `parallel: true` with `programs` to run independent entries concurrently
390
473
  in submission order. A failed entry does not stop siblings. Two entries writing
391
474
  the same file race: the losing commit reports a conflict. Sequential remains the
392
475
  default. `parallel` and `mergeData` are invalid on a lone `code` or `file` call.
393
- Budget overflow marks the batch failed and stops queued entries; already-running
394
- entries settle and their completed commits remain. Parallel execution does not
395
- multiply the aggregate output, log, or image allowance.
476
+ Log/image budget overflow marks the batch failed and stops queued entries;
477
+ already-running entries settle and their completed commits remain. Text overflow
478
+ only clips the displayed result and sets `details.returnTruncated`; queued entries
479
+ still run. Parallel execution does not multiply the aggregate allowances.
396
480
 
397
481
  The outer deadline, host-call budget, log allowance, text budget and image limits
398
482
  are shared across the batch. Individual read budgets are not reduced. Every
399
- attempted program's original text is returned in length-delimited blocks; ordinary
400
- limits still disclose clipping. Images retain program/image labels. Split a plan
401
- that would exceed the aggregate output budget.
483
+ attempted program's text is assembled in length-delimited blocks, then the combined
484
+ display is clipped if necessary. Images retain program/image labels. Return
485
+ summaries or use focused windows when you need every result to fit on display.
402
486
 
403
487
  Batch only continuations already chosen by the agent, such as edit then known
404
488
  verification, or create then run known audits. Keep a separate call whenever new
@@ -453,14 +537,14 @@ array length. Only own JSON properties are traversed; nothing is evaluated.
453
537
  Inputs are capped at 16 MiB, including staged files. JSON reads require regular
454
538
  files and reject named pipes without waiting for a writer. The entire input must
455
539
  be valid JSON before any selection. Each selector is budgeted before allocating
456
- the next slice; sparse selector/path/edit arrays are rejected. Selected JSON must
457
- fit the ordinary read budget. Oversized selections return a routing object
458
- `{status:"too_large",path,keys}` (or `length` for an array), not the requested
459
- array/object: check `status` before calling `.map` or `.filter`, then select
460
- narrower fields or slices. The input-size cap still throws before projection;
461
- JSON is never returned malformed or silently truncated. Oversized unwindowed
462
- plain .json reads also fail with a projection hint. Explicit offset/limit or
463
- resolve:true still allow raw inspection, but line windows are not JSON documents.
540
+ the next slice; sparse selector/path/edit arrays are rejected. Selections have a
541
+ separate **64 MiB estimated storage limit per read**, including aggregate
542
+ multi-selector expansion. Within it, arrays/objects/scalars retain their actual
543
+ values, even when larger than the display. No routing object is substituted:
544
+ `.map` and `.filter` work on the selected array. Multi-selector values remain
545
+ independently mutable. The input/storage safety limits throw with guidance.
546
+ Plain .json reads are raw text, including malformed JSON; parsing is requested
547
+ only by `json`. Explicit line windows are not necessarily JSON documents.
464
548
  Do not combine json with complete, line windows, or source views. External read
465
549
  overrides reject JSON projection rather than silently ignoring the option.
466
550
  Uncaught read errors abort the program, including `return {a:await read(...),
@@ -472,9 +556,9 @@ rollback for uncaught failures.
472
556
  Other read options, even false-valued flags, do not bypass a captured external
473
557
  read executor; its policy, transforms and failures remain authoritative.
474
558
 
475
- For large Markdown/log path audits, use read(path,{about:"document path"}) or
476
- explicit offset/limit, not complete:true. Larger JSON needs a streaming parser via
477
- bash. Arbitrary returned objects still have bounded previews, not implicit
559
+ For focused Markdown/log audits, use read(path,{about:"document path"}) or
560
+ explicit offset/limit. Use complete reads for computation within the 64 MiB
561
+ ceiling, and return a summary. JSON over 16 MiB needs a streaming parser via bash. Arbitrary returned objects still have bounded previews, not implicit
478
562
  continuation handles.
479
563
 
480
564
  ## Execution and automatic batching
@@ -487,18 +571,29 @@ use focused read windows to keep the combined result within its output budget.
487
571
 
488
572
  Compatible independently started reads coalesce at the worker/host boundary.
489
573
  No additional batching command is required. Individual promises preserve their
490
- values, errors and per-read budgets. File reads have bounded parallelism; writes,
491
- edits, shell calls and checkpoint transitions form ordering barriers.
574
+ values, errors and per-read safety limits. Reads and known native mutations to
575
+ disjoint files overlap up to eight operations; same-file mutations stay ordered.
576
+ Read/mutation transitions, shells, checkpoints and overrides remain barriers.
492
577
 
493
578
  This does **not** reorder sequential `await`s or predict future model decisions.
494
- An explicit path-array read uses an aggregate text budget; automatic coalescing
495
- retains each independent read's budget instead of silently shrinking its result.
579
+ Explicit path arrays and automatic coalescing share the same typed delivery.
580
+ Small batches retain the single-reply fast path; beyond 64 KiB estimated storage,
581
+ items stream to the guest with acknowledgements. Delivery holds its I/O slot
582
+ until acknowledged, and the final read waits for its host barrier to settle.
496
583
 
497
584
  Every program runs in a fresh worker. One pristine worker is prepared for the next
498
585
  invocation, then disposed on session shutdown. Executed workers are never reused,
499
586
  so guest globals cannot leak into a later program. Worker preparation still costs
500
587
  CPU and memory; it is moved off the next invocation's critical path, not eliminated.
501
588
 
589
+ `maxHeapMb` sets Node's native worker heap cap. A worker-local check also limits
590
+ heap plus external buffers to 1.5 times that value, sampled every 50 ms and before
591
+ host calls and final results. Process-wide RSS is never charged to an individual
592
+ guest. These samples are best-effort: Bun does not enforce Node's native heap cap,
593
+ and non-yielding code can prevent sampling until it reaches a command or returns.
594
+ The outer deadline still terminates non-yielding workers. This is not a hard
595
+ process-memory or security boundary.
596
+
502
597
  File changes are staged until program success. A throw before an external-mutation
503
598
  barrier rolls them back. Shell execution flushes preceding changes; external shell
504
599
  side effects cannot be rolled back. Stale commits fail explicitly rather than
@@ -521,8 +616,9 @@ the active callback are rejected. Await the checkpoint before proceeding.
521
616
 
522
617
  - Plain reads are not replaced with earlier-context references. A local cache hit
523
618
  is not proof the model still retains an earlier result after compaction.
524
- - Oversized text reads provide an exact next-line offset. A single line too large
525
- for the budget fails explicitly instead of pretending it was read completely.
619
+ - Text and JSON computation is independent of display limits. Source previews
620
+ provide exact continuation; raw displayed text can be clipped and must not be
621
+ parsed as a complete file. I/O/storage limits still fail explicitly.
526
622
  - Model attachments support PNG, JPEG, GIF and WebP. BMP and other unsupported
527
623
  MIME types fail before attachment or commit, rather than causing a provider
528
624
  HTTP 400 on the next request. Convert those sources to PNG first; Supernova
@@ -605,18 +701,59 @@ not a claim that every third-party permission extension has been validated.
605
701
  ## Development and evidence
606
702
 
607
703
  Implementation is grouped under `src/`; all replacement tests are under `tests/`.
608
- The original 12 red acceptance tests were left unchanged. Additional strict tests
609
- cover batching fidelity, image/context retention, checkpoints, mutation ordering,
610
- external symlinks, deadlines, worker isolation and execution-context environment.
611
- The former deleted suite has not been silently reinstated.
704
+ Read-budget assertions now test the deliberate 0.9.0 contract: complete internal
705
+ values and bounded model-facing output. Frozen token snapshots are unchanged.
706
+ Strict regressions cover batching fidelity, image/context retention, checkpoints,
707
+ mutation ordering, external symlinks, deadlines, worker isolation, bounded read
708
+ delivery, and execution-context environment.
709
+
710
+ ### Module boundaries
711
+
712
+ | Responsibility | Modules |
713
+ |---|---|
714
+ | Registration and session lifecycle | `index.js` |
715
+ | Program admission and batching | `runtime/program.js`, `runtime/batch-input.js`, `runtime/program-batch.js` |
716
+ | Worker ownership and guest RPC | `runtime/runtime.js`, `runtime/worker-pool.js`, `runtime/guest-worker.js`, `runtime/guest-api.js` |
717
+ | Host permissions, ordering and trace | `bridge/host-bridge.js`, `bridge/tool-registry.js`, `bridge/trace.js` |
718
+ | Read routing and typed readers | `adapters/read.js`, `adapters/read-{text,json,image,focus}.js` |
719
+ | Image validation and isolated decoding | `shared/png.js`, `shared/image.js`, `shared/image-worker.js` |
720
+ | Bounded I/O and atomic transactions | `fs/file-io.js`, `fs/read-window.js`, `fs/vfs.js`, `fs/commit.js` |
721
+ | Source search and ranking | `context/query.js`, `context/snap-search.js`, `context/source-entry.js`, `context/evidence-{graph,rank}.js` |
722
+ | Model output and host rendering | `output/final.js`, `output/outcome.js`, `ui/host-render.js`, `ui/trace.js`, `ui/render.js` |
723
+
724
+ Paths above are relative to `src/`, except `index.js`. Layer tests require an
725
+ acyclic import graph and prohibit context modules from importing runtime code.
726
+
727
+ ### Verification
728
+
729
+ The final 0.9.0 release candidate was verified on **macOS**:
730
+
731
+ | Check | Result |
732
+ |---|---|
733
+ | Node 26.7 package suite | 315 passed; zero failures or skips |
734
+ | Bun 1.4 package suite | 315 passed; zero failures or skips |
735
+ | Pi 0.86.1 / OMP 18.2.6 | Actual host execution checks passed; Pi TUI checks passed |
736
+ | Clean production-only tarball installation | Node/Bun and actual Pi/OMP smoke checks passed |
737
+ | Lint, frozen token gates, repository release check and publish preflight | Passed |
738
+
739
+ Failure-first regressions cover corrupt image data, malformed base64, MIME
740
+ mismatches, decoded-pixel limits and nonfatal batch-text clipping. Additional
741
+ checks cover animated images, content-based validation reuse, cancellation,
742
+ decoder-watchdog recovery, and real failures after clipped output. The compiled
743
+ OMP native-module issue is covered by the actual-host checks, not only unit tests.
744
+
745
+ **Coverage limits:** a live Codex round-trip and Linux/Spark smoke checks were not
746
+ rerun after the final image-validation changes. These results are not a claim of
747
+ exhaustive platform coverage or guaranteed acceptance by every model provider.
612
748
 
613
749
  Test user-visible contracts through registered programs: exact source, on-disk
614
750
  results, failure/rollback, isolation, bounded output, and usable host rendering.
615
751
  Inject filesystem faults only to exercise real failure paths; do not prescribe
616
752
  private helper layouts, staging filenames, or syscall counts. New regressions must
617
753
  fail before the fix; for existing behavior, verify that a named deliberate defect
618
- makes the intended test fail before accepting it. Keep the original 12 acceptance
619
- tests unchanged. Cost gates cover avoidable search processes, per-read budgets and
754
+ makes the intended test fail before accepting it. Preserve existing assertions unless an explicitly requested contract changes;
755
+ then test both the new behavior and the retained safety boundary. Cost gates
756
+ cover avoidable search processes, per-read safety limits and
620
757
  progress flooding; latency claims belong in the explicit measurement lane, not
621
758
  arbitrary wall-clock assertions.
622
759
 
@@ -632,8 +769,8 @@ npm run test:hosts --prefix packages/pi-supernova
632
769
  ```
633
770
 
634
771
  The explicit host runner requires macOS network sandboxing and fails, rather than
635
- skips, when prerequisites are absent. Verified locally against Pi 0.85.1 and OMP
636
- 18.1.11: CodeMode execution, four primitives, automatic read coalescing, checkpoints,
772
+ skips, when prerequisites are absent. Verified locally against Pi 0.86.1 and OMP
773
+ 18.2.6: CodeMode execution, four primitives, automatic read coalescing, checkpoints,
637
774
  images and failed execution. Pi's actual loader/runner and TUI are exercised; OMP
638
775
  runs in a disposable process through its actual session registry, with networking
639
776
  denied. The Pi runner supplies a minimal tool registry, not a full provider session.
package/docs/CHANGELOG.md CHANGED
@@ -1,6 +1,91 @@
1
1
  # Changelog
2
2
 
3
- ## Unreleased
3
+ ## [0.9.0] - 2026-09-20
4
+
5
+ ### Changed
6
+
7
+ - Split read routing, filesystem I/O and commits, guest commands and worker
8
+ lifecycle, host tool ownership and tracing, evidence selection, and rendering
9
+ into focused modules. Public entrypoints and guest command modes remain supported.
10
+ - Reuse bounded file reads, query analysis, overlay lookup, line and JSON
11
+ helpers, diff assembly, and error formatting instead of parallel implementations.
12
+
13
+ - `Promise.all` overlaps native edits, patches and writes to distinct files, up
14
+ to eight operations at once. Same-file operations remain ordered using canonical
15
+ commit destinations; existing alias-conflict protections remain in place.
16
+ - Removed the duplicate guest operation queue. The host owns read/mutation,
17
+ shell, override and checkpoint barriers, and waits for in-flight siblings before
18
+ crossing them. File identities are resolved only after external mutations finish.
19
+ - Batching and explicit `programs` / `parallel:true` execution remain supported;
20
+ standing guidance distinguishes these from per-file concurrency.
21
+
22
+ ### Fixed
23
+
24
+ - Aggregate display-text clipping no longer fails sequential/parallel program
25
+ batches or prevents later entries from running. The combined display remains
26
+ bounded and marks truncation; execution, deadline, log and image failures retain
27
+ their stop behavior.
28
+ - PNG/JPEG/GIF/WebP reads and returned attachments validate canonical base64,
29
+ matching signatures/MIME, and fully decoded pixels before shell boundaries or
30
+ final commit/model delivery. PNG framing/CRC checks reject the exact corrupt
31
+ fixture that caused repeated Codex errors. Tests also cover CRC-correct invalid
32
+ pixels, truncated streams, format mismatches, animated inputs, and rollback.
33
+ - Sharp 0.35.4 decoding runs in an isolated Node/Bun runtime process: at most
34
+ 32 million pixels across frames, one raster at a time, with cancellation and a
35
+ 5-second watchdog. This also fixes native dependency resolution in compiled OMP.
36
+ Text-only calls do not load Sharp; a bounded cache retains only 16 successful
37
+ content digests. Decoder installation failures reject rather than attach blindly.
38
+
39
+ - Native reads carry typed values across RPC rather than serialized display text.
40
+ Full text reads and exact line windows use the 64 MiB byte ceiling, not the
41
+ former 160-line / 8192-character or 31,744-character presentation restrictions.
42
+ JSON selections retain their types under separate input/storage safety limits.
43
+ - Large coalesced and explicit read batches stream with acknowledgements inside
44
+ eight I/O slots; the small-batch path still uses one reply. Sibling cancellation
45
+ drains delivery as well as I/O, and final promises wait for the host barrier.
46
+ - Directory entries remain arrays, metadata stats overlap, and exceeding 10,000
47
+ unique entries fails explicitly instead of returning an apparently complete list.
48
+ - Final formatting runs in the worker. Large string arrays, objects and logs are
49
+ bounded before rendering expansion; sparse positions and Unicode display stay
50
+ valid. Hidden metadata cannot bypass the transfer budget. Source previews keep
51
+ exact continuation and edit guards without shortening internal source values.
52
+ - Removed unused native routing producers and obsolete display-sized read caps;
53
+ legacy external-tool decoding remains. Staged windows retain the disk byte cap.
54
+
55
+ - Cancelled bounded reads and CAS signing use abort-checked file-handle reads,
56
+ avoiding a second unhandled stream error that crashed Node and Bun even when
57
+ the read rejection was caught. Byte caps and file-version checks are retained.
58
+ - Memory enforcement uses worker-local heap and external-buffer usage, not
59
+ process-wide RSS growth from the host or sibling workers. Node's native heap
60
+ cap remains; Bun sampling remains best-effort for non-yielding code. Memory
61
+ failures cancel and drain pending host calls before returning.
62
+
63
+ - Guest stack locations are recognized in both V8 and Bun/JSC; asynchronous
64
+ failures identify the source await consistently without moving direct throws.
65
+ - Commit I/O uses the shared filesystem promises export, so fault injection
66
+ exercises real partial replacement and failed recovery on both Node and Bun.
67
+ - Permission failures during canonical-path resolution retain the affected path
68
+ and actionable guidance instead of leaking raw EACCES errors on Bun.
69
+ - JSON projection recovers missing parse locations for inputs up to 65,536
70
+ characters, with a bounded diagnostic scan and no second value tree. Native
71
+ JSON.parse remains authoritative; caret columns and BOM handling are aligned.
72
+
73
+ ### Verification
74
+
75
+ - Complete package suites: 315 passed on Node 26.7 and 315 passed on Bun 1.4
76
+ on macOS, with zero failures or skips, including failure-first image validation
77
+ and batch-clipping regressions, animated-image preservation, cache invalidation,
78
+ cancellation, and decoder-watchdog recovery. All five former Bun failures remain fixed. Frozen token
79
+ snapshots are unchanged; obsolete internal-display-cap assertions now verify
80
+ full data while preserving real memory, parsing, rollback and edit guards.
81
+ - Lint, frozen token gates, the repository release check, and actual
82
+ Pi 0.86.1 / OMP 18.2.6 host checks passed.
83
+ The fatal cancellation was reproduced against the old Spark installation and
84
+ the fixed package passed Node/Bun checks in an isolated copy; no installed
85
+ copy was patched.
86
+ - See TOKEN_COSTS.md for the refactor's measured gains and small-operation costs.
87
+ Full image decoding adds image-only work and a native dependency; it is not
88
+ presented as a general latency improvement or proof of provider acceptance.
4
89
 
5
90
  ## [0.8.2] - 2026-09-19
6
91
 
@@ -21,6 +21,44 @@ The benchmark uses js-tiktoken 1.0.21, pinned as a development dependency. It ru
21
21
  real Supernova programs in temporary workspaces without provider calls or downloads.
22
22
  The token regression gate also runs in the normal test suite.
23
23
 
24
+ ## 0.9.0 data-path tuning (2026-09-20)
25
+
26
+ Compared with the preserved pre-tuning 0.9.0 package on Apple M5 Max / Node
27
+ 26.7.0. No provider calls, changed reasoning settings or regenerated token
28
+ snapshots. This improves working-data fidelity and bounded execution; it is not
29
+ an across-the-board latency reduction.
30
+
31
+ | Measurement | Before | After |
32
+ | --- | ---: | ---: |
33
+ | 800-entry directory, median / p95 (60 samples) | 13.179 / 23.356 ms | 8.966 / 12.795 ms |
34
+ | Eight coalesced warm reads, median / p95 (80 alternating pairs) | 1.679 / 2.616 ms | 1.788 / 2.596 ms |
35
+ | Eight unbatched cold reads, median / p95 (same pairs) | 12.719 / 15.057 ms | 13.136 / 15.224 ms |
36
+ | Eight coalesced cold reads, median / p95 (same pairs) | 13.292 / 20.052 ms | 13.818 / 18.546 ms |
37
+ | 200-row report formatting, median (10,000 iterations) | 0.1510 ms | 0.1595 ms |
38
+ | Nested source formatting, median (10,000 iterations) | 0.02523 ms | 0.02480 ms |
39
+
40
+ Directory results have identical full-listing hashes/counts: the median fell
41
+ 32%, p95 45%. Small-read medians instead increased about 3--7%; the new accounting
42
+ adds about 0.009 ms to this small report formatter. Earlier non-interleaved samples
43
+ suggested a warm-read gain, so the table uses alternating measurements rather than
44
+ claiming a noisy speedup. Prewarm and provider time are excluded. Output hashes
45
+ for both formatting fixtures match exactly; these are local samples, not latency
46
+ bounds. Directory acceptance required identical data and lower median time;
47
+ read-wave acceptance required identical complete values and unchanged 8-to-1
48
+ coalescing, with regressions reported rather than hidden.
49
+
50
+ The frozen six-call traffic is now 9,771 / 9,647 tokens (o200k_base / cl100k_base),
51
+ versus 9,813 / 9,689 at the pre-tuning checkpoint. The difference is shorter
52
+ standing guidance, not missing observations. Shared-source/object-input traffic
53
+ is 3,567 / 3,511; every output and all 32 files still match the frozen snapshot.
54
+
55
+ Focused regressions verify the formerly failing full-text/JSON/directory cases,
56
+ 64 two-MiB reads in a Node host capped at 128 MiB, blocked-delivery cancellation
57
+ and follow-up use, bounded billion-character string expansions, sparse returns,
58
+ and complete/partial source-view edit rules. Bun runs the same tests, but its
59
+ heap flags and worker sampling do not provide Node's hard heap enforcement.
60
+ Installed copies were not modified; publication and restart remain separate.
61
+
24
62
  ## Unreleased explicit batch reuse (2026-09-19)
25
63
 
26
64
  **79.82% / 79.92% less traffic on the shared-source/object-input workload, not a