pi-supernova 0.10.2 → 0.11.0

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 (81) hide show
  1. package/README.md +365 -90
  2. package/docs/CHANGELOG.md +89 -5
  3. package/docs/TOKEN_COSTS.md +149 -324
  4. package/index.js +40 -11
  5. package/package.json +4 -3
  6. package/src/adapters/bash.js +40 -10
  7. package/src/adapters/edit.js +77 -23
  8. package/src/adapters/errors.js +4 -0
  9. package/src/adapters/index.js +1 -0
  10. package/src/adapters/list.js +6 -3
  11. package/src/adapters/read-focus.js +6 -0
  12. package/src/adapters/read-image.js +17 -9
  13. package/src/adapters/read-indexed.js +72 -0
  14. package/src/adapters/read-text.js +19 -2
  15. package/src/adapters/read.js +57 -13
  16. package/src/adapters/refs.js +17 -7
  17. package/src/adapters/write.js +14 -21
  18. package/src/bridge/host-bridge.js +152 -39
  19. package/src/bridge/invoke.js +3 -1
  20. package/src/bridge/tool-registry.js +132 -16
  21. package/src/context/evidence-graph.js +1 -0
  22. package/src/context/evidence-rank.js +1 -0
  23. package/src/context/evidence.js +4 -2
  24. package/src/context/fuzzy.js +31 -8
  25. package/src/context/outline.js +33 -9
  26. package/src/context/query.js +7 -2
  27. package/src/context/repo-index.js +8 -3
  28. package/src/context/search-files.js +20 -0
  29. package/src/context/search.js +25 -10
  30. package/src/context/snap-search.js +28 -6
  31. package/src/context/snap.js +8 -3
  32. package/src/context/source-entry.js +64 -28
  33. package/src/context/spans.js +1 -0
  34. package/src/contract/bash.js +16 -7
  35. package/src/contract/edit.js +26 -7
  36. package/src/contract/program.js +2 -1
  37. package/src/contract/read.js +46 -46
  38. package/src/fs/background.js +10 -2
  39. package/src/fs/check.js +844 -46
  40. package/src/fs/commit.js +89 -15
  41. package/src/fs/diff.js +12 -9
  42. package/src/fs/directory.js +14 -4
  43. package/src/fs/file-io.js +28 -7
  44. package/src/fs/glob.js +93 -11
  45. package/src/fs/json-read.js +3 -2
  46. package/src/fs/json-size.js +2 -1
  47. package/src/fs/lines.js +49 -2
  48. package/src/fs/patch.js +26 -10
  49. package/src/fs/process-tree.js +19 -1
  50. package/src/fs/read-window.js +36 -20
  51. package/src/fs/source-window.js +5 -10
  52. package/src/fs/text-ops.js +38 -18
  53. package/src/fs/vfs.js +296 -41
  54. package/src/fs/workspace.js +24 -6
  55. package/src/output/bottleneck.js +50 -25
  56. package/src/output/final.js +20 -0
  57. package/src/output/format.js +97 -36
  58. package/src/output/outcome.js +16 -4
  59. package/src/runtime/batch-input.js +17 -3
  60. package/src/runtime/guest-api.js +32 -7
  61. package/src/runtime/guest-worker.js +22 -4
  62. package/src/runtime/parallel.js +9 -49
  63. package/src/runtime/program-batch.js +53 -28
  64. package/src/runtime/program-file.js +2 -1
  65. package/src/runtime/program.js +94 -41
  66. package/src/runtime/reference.js +10 -9
  67. package/src/runtime/runtime.js +69 -18
  68. package/src/runtime/worker-pool.js +10 -1
  69. package/src/shared/decode.js +9 -8
  70. package/src/shared/image-worker.js +7 -0
  71. package/src/shared/image.js +58 -15
  72. package/src/shared/png.js +18 -0
  73. package/src/shared/result.js +30 -9
  74. package/src/shared/syntax-context.js +7 -1
  75. package/src/shared/utf8.js +11 -13
  76. package/src/ui/host-render.js +4 -0
  77. package/src/ui/omp-frame.js +2 -0
  78. package/src/ui/progress.js +2 -1
  79. package/src/ui/render-measure.js +11 -0
  80. package/src/ui/render.js +92 -31
  81. package/src/ui/trace.js +8 -5
package/README.md CHANGED
@@ -11,39 +11,26 @@ The model submits JavaScript, not four separately advertised native tools.
11
11
  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
-
15
- ## What is new in 0.10.2
16
-
17
- - Results print the `mutations:` line only when it informs: files committed or
18
- rolled back, an uncertain filesystem outcome, or shell side effects left behind
19
- by a failed program. It had appeared on most results, usually all zeros.
20
- - Clearer guest errors: naming a variable after a command (`const read = await
21
- read(...)`) says so, `supernova(...)` inside a program says to call the
22
- commands directly, and an empty `oldText` explains how to insert.
23
-
24
- Earlier releases: [changelog](https://github.com/AdityaVG13/pi-stack/blob/main/packages/pi-supernova/docs/CHANGELOG.md).
25
-
26
- ## Tokens: native tool calls vs Supernova
27
-
28
- Fixed 13-program workload (inspect, reproduce, repair, verify; JSON report update;
29
- five-term audit), full tool-history replay, `js-tiktoken`. Regenerate with
30
- `npm run test:tokens --prefix packages/pi-supernova`.
31
-
32
- | Workload | Tokenizer | Without Supernova batching | Through Supernova 0.10.2 | Reduction |
33
- |---|---|---:|---:|---:|
34
- | Mixed 13-program workload | o200k_base | 28,130 | 9,631 | **65.8%** |
35
- | | cl100k_base | 27,841 | 9,476 | **66.0%** |
36
- | 16 programs, shared source + data (32 files) | o200k_base | 17,771 | 3,559 | **80.0%** |
37
- | | cl100k_base | 17,595 | 3,493 | **80.1%** |
38
- | 8 programs sharing a 48-path input | o200k_base | 16,309 | 5,471 | **66.5%** |
39
- | | cl100k_base | 14,649 | 5,157 | **64.8%** |
40
- | Standing tool definition per request | o200k_base / cl100k_base | 908 / 901 | 617 / 606 | 32.0% / 32.7% |
41
-
42
- All rows deliver identical complete outputs and files; only call and argument
43
- placement change. The baseline is a frozen non-batched snapshot, not a separate
44
- product. Excludes provider envelopes, unrelated conversation, reasoning tokens and
45
- caching; no model-quality claim. Method and speed measurements:
46
- [TOKEN_COSTS.md](https://github.com/AdityaVG13/pi-stack/blob/main/packages/pi-supernova/docs/TOKEN_COSTS.md).
14
+ There is no `supernova` object inside a program: use `await bash(...)`, not
15
+ `const { bash } = supernova`. Do not shadow the four command names with variables.
16
+
17
+ ## Contents
18
+
19
+ 1. [Install and update](#install-and-update)
20
+ 2. [Four guest commands](#four-guest-commands)
21
+ 3. [Tokens: native tool calls vs Supernova](#tokens-native-tool-calls-vs-supernova)
22
+ 4. [TUI presentation](#tui-presentation)
23
+ 5. [Background terminal sessions](#background-terminal-sessions)
24
+ 6. [JSON reports and targeted text audits](#json-reports-and-targeted-text-audits)
25
+ 7. [Execution and automatic batching](#execution-and-automatic-batching)
26
+ 8. [Context, caching and failure fidelity](#context-caching-and-failure-fidelity)
27
+ 9. [Optional workspace change notifications](#optional-workspace-change-notifications)
28
+ 10. [Security and host boundary](#security-and-host-boundary)
29
+ 11. [Development and evidence](#development-and-evidence)
30
+ 12. [Research and prior art](#research-and-prior-art)
31
+ 13. [Release notes](#release-notes)
32
+ 14. [Limits](#limits)
33
+ 15. [License](#license)
47
34
 
48
35
  ## Install and update
49
36
 
@@ -62,7 +49,13 @@ pi install /path/to/pi-stack/packages/pi-supernova
62
49
 
63
50
  Image reads and returned images are validated with Sharp: at most 32 million
64
51
  decoded pixels across all frames, one image at a time, in a subprocess with a
65
- 5-second kill deadline; text-only work never loads it. Keep Sharp's
52
+ 5-second kill deadline; text-only work never loads it. Exact-content cache hits
53
+ do not wait for unrelated decoders. Cancelled queued validations withdraw without
54
+ releasing the active decoder's memory slot. Decoder errors retain that slot and
55
+ watchdog until the child closes; repeated errors keep the original diagnostic.
56
+ Whole image reads and whole text
57
+ windows sign their loaded bytes rather than rereading the file; partial windows
58
+ still sign the complete file. Keep Sharp's
66
59
  platform-specific optional dependencies enabled. For a local checkout, refresh dependencies before starting
67
60
  the host:
68
61
 
@@ -75,11 +68,11 @@ between operating systems or CPU architectures. Published-package installation
75
68
  resolves these dependencies through the host's package manager.
76
69
 
77
70
  Git pushes do not update npm installations. Publish the new npm version first,
78
- then reinstall it in your host. To pin **0.9.0** once it is published:
71
+ then reinstall it in your host. To pin **0.11.0** after it is published:
79
72
 
80
73
  ```bash
81
- pi install npm:pi-supernova@0.9.0
82
- omp install npm:pi-supernova@0.9.0
74
+ pi install npm:pi-supernova@0.11.0
75
+ omp install npm:pi-supernova@0.11.0
83
76
  ```
84
77
 
85
78
  In Pi, `pi list` shows the configured package sources. A local path uses that
@@ -114,10 +107,15 @@ settings. The runtime does not silently rewrite your tool policy.
114
107
  | `edit` | `edit(view,text)` CAS-replaces that span; `edit(view,old,new)` is unique inside it |
115
108
  | `edit` | `edit({path,patch})`; unified patch application |
116
109
  | `edit` | `edit(async () => {...})`; filesystem-only checkpoint, described below |
117
- | `write` | `write(path,text)`, `write({path,content})`; atomic replacement |
110
+ | `write` | `write(path,text,options?)`, `write({path,content})`; atomic replacement |
118
111
  | `bash` | `bash(command,{cwd,timeoutMs})`, `bash({command,timeoutMs})`; bounded output, nonzero exits throw |
119
112
  | `bash` | `bash({command,args:[...]})`; literal executable argv, without shell expansion of argument strings |
120
113
 
114
+ Patch hunks must advance past the preceding hunk's output region, including its
115
+ context lines. Neither nominal matches nor relocation may consume earlier output;
116
+ adjacent hunks at the boundary remain valid. A rejected patch leaves its target
117
+ unchanged, and an uncaught rejection rolls back the current staged writes.
118
+
121
119
  `bash` also accepts `timeout` in seconds for familiar object arguments. `timeoutMs`
122
120
  is milliseconds and takes precedence. The owned adapter launches executable argv
123
121
  directly on every supported OS, including Windows; use the string form for shell
@@ -129,6 +127,10 @@ Windows limits process command lines to 32K characters; use a workspace script f
129
127
  for larger payloads. Argument payloads are not repeated in owned direct-execution errors;
130
128
  stdout/stderr, exit status and source context remain. Session environment variables are taken
131
129
  from the current execution context, not inherited from a different parent session.
130
+ Pending owned writes are committed before foreground or background launch. A `cwd`
131
+ created by those writes is accepted, including in-workspace symlink spellings.
132
+ Unrelated missing directories, file paths, and escaping paths still fail before
133
+ pending files commit; bash remains forbidden inside an edit checkpoint.
132
134
 
133
135
  Shell strings are executed unchanged, including quoted executable paths. For inline
134
136
  Python/Node scripts, prefer literal argv with `data` instead of nested shell quotes:
@@ -175,7 +177,20 @@ not as an absent match. Do not combine incompatible modes such as `outline:true`
175
177
  and `evidence:true`.
176
178
 
177
179
  Ordinary reads stay self-contained. Outlines and graph evidence remain explicit
178
- options, not mandatory stages of source resolution. Ordinary calls also get:
180
+ options, not mandatory stages of source resolution. An exact declaration-name
181
+ `about` query expands matching declarations ahead of enclosing keyword-heavy
182
+ scopes; this also preserves identifiers such as `get` that are prose stop words.
183
+ Other questions retain relevance ranking, and folded declarations keep line-based
184
+ recovery guidance. If the view exceeds its budget, expanded bodies appear before
185
+ the folded declaration map with their original source line numbers; clipped
186
+ navigation is explicitly disclosed. Views that fit retain source order.
187
+ Focused outlines collect
188
+ lexical caller hints for all expanded declarations in one workspace scan. The
189
+ per-name order and counts are preserved, staged callers stay visible, and the
190
+ matching-row snapshot lives only for that outline. Existing index cache rules
191
+ still apply; these hints are not semantic caller resolution. Focused text shaping
192
+ for files without declarations skips the unrelated caller catalog entirely.
193
+ Ordinary calls also get:
179
194
 
180
195
  - Bounded fuzzy filename hints when a bare source name has no literal match. Existing
181
196
  frecency/directory ranking orders hints; fuzzy matches never select a path. This
@@ -193,12 +208,52 @@ options, not mandatory stages of source resolution. Ordinary calls also get:
193
208
  Distant edit regions have separate windows and continuation pointers for omitted
194
209
  lines. Structural warnings and source windows are not substitutes for tests.
195
210
 
211
+ ### Optional indexed source discovery
212
+
213
+ ```js
214
+ const view = await read({query:"formatLabel", path:"src/labels.js", indexed:true});
215
+ if (view.status !== "found") return view;
216
+ await edit(view, "label.trim()", "label.trimStart()");
217
+ ```
218
+
219
+ This opt-in route uses a callable `isearch` tool (pi-indexer protocol 6), then
220
+ performs Supernova's own byte read and returns an ordinary source view. Indexer
221
+ text/fingerprints are locators, not read receipts or edit tokens. Returned paths
222
+ must stay inside both the workspace and requested scope, including symlink targets.
223
+ Canonical absolute locator paths for an aliased workspace are mapped back to its
224
+ logical scoped path; this does not admit external paths or escaping symlinks.
225
+ Multiple or incompletely selected candidates remain ambiguous. Staged writes use
226
+ the existing overlay-aware resolver instead, so uncommitted source stays visible.
227
+ Unavailable/disabled/excluded providers fail explicitly. The host's callable set
228
+ is authoritative: on Pi v0.99, inactive `codemode`/`deferred` tools may remain
229
+ callable, while hidden, model-only and inactive direct tools cannot be invoked.
230
+ Normal call budgets and traces include the internal isearch operation.
231
+
232
+ Pi v0.99 delegation uses the current tool invocation's `ctx.tools` and
233
+ `ctx.executeTool()`. Indexer and host overrides pass through host validation,
234
+ permissions, cancellation and nested tool hooks; a denied call never falls back
235
+ to a captured raw executor. No legacy event-bus delegation runs on that path.
236
+ Older Pi hosts can use the synchronous, version-1
237
+ `pi-indexer:readonly-provider` handshake, bound to the active definition's schema
238
+ identity and session. Exactly one provider is accepted; withdrawal, replacement,
239
+ session changes and shutdown revoke access. That older read-only API does not
240
+ replay nested Pi hooks. OMP keeps its native registry/approval route.
241
+
242
+ Both packages work independently. Ordinary source reads retain their existing
243
+ resolver. Explicit windows, about, evidence, outline and JSON cannot combine with
244
+ indexed:true. Named edits already read source internally; no new blanket prior-read
245
+ authorization rule is claimed. View-span comparison and commit CAS are unchanged.
246
+
196
247
  ### Safe read-modify-write
197
248
 
198
249
  A plain file read returns its complete text up to the **64 MiB UTF-8 I/O limit**,
199
250
  independently of model-facing character budgets. Explicit `offset`/`limit` reads
200
- return exact line windows, including long lines and LF/CRLF endings, or fail at
201
- the same byte ceiling. Staged and on-disk data obey the same ceiling.
251
+ return exact line windows, including long lines, BOM characters and LF/CRLF
252
+ endings, or fail at the same byte ceiling. Malformed UTF-8 fails rather than
253
+ discarding bytes. Only JSON parsing consumes a leading BOM. Staged and on-disk
254
+ data obey the same ceiling. Line-statistics scans adapt to dense newline regions
255
+ after collecting the bounded preview, then return to native searches for sparse
256
+ regions; counts, EOF handling and preview bytes remain unchanged.
202
257
  `complete:true` additionally rejects a window that omits part of the file.
203
258
  For larger files/JSONL, use a bounded parser through `bash({command,args})`.
204
259
 
@@ -206,6 +261,10 @@ Compute on the full value and return only what the model needs. A direct large
206
261
  return is an explicitly truncated display, not a complete artifact to parse or
207
262
  write back. `resolve:true` source previews retain path/range/continuation metadata;
208
263
  clipped previews are not editable. Prefer `edit` for replacements.
264
+ Plain read text is not an editable view: pass the filename to `edit`, or use
265
+ `read(path,{resolve:true})`. Overlong edit/patch paths fail with bounded recovery
266
+ guidance instead of echoing a source body mistaken for a filename. Near-match
267
+ previews show exact nearby bytes without guessing why a replacement failed.
209
268
  A write after reading that path still requires `edit` or explicit `replace:true`.
210
269
  Writes reject Supernova truncation markers, including legacy host-result markers.
211
270
  For intentionally writing literal marker documentation only, opt in with
@@ -213,9 +272,18 @@ For intentionally writing literal marker documentation only, opt in with
213
272
  full dataflow tracking or a security sandbox.
214
273
 
215
274
  Read/modify/write conflict checks retain a signature of the actual disk bytes,
216
- including for partial and large-file reads. A fresh explicit text read refreshes
275
+ including for empty windows, partial and large-file reads. A fresh explicit text read refreshes
217
276
  that observation; internal receipt reads and body-cache eviction do not. Commits
218
- reject changed content and conflicting symlink aliases, including new file paths.
277
+ reject changed content; explicit checkpoints also reject conflicting symlink aliases,
278
+ including new file paths.
279
+ Overlays, read observations and commits share canonical filesystem identity:
280
+ reading through another symlink spelling sees staged bytes, including in directory
281
+ listings and source queries. A retargeted observed or staged path conflicts rather
282
+ than redirecting a write. Internal edit/patch reads do not refresh that observation.
283
+ Logical paths remain in receipts. Identity lookups are shared only within one
284
+ native operation; the next operation and commit resolve them afresh. Missing paths
285
+ canonicalize their existing ancestors; case/Unicode collisions between new names
286
+ are checked by the filesystem at publication, not guessed by case folding.
219
287
  These checks do not provide a cross-process lock or make shell/import mutations
220
288
  transactional. Extensionless filenames also support `complete:true`, for example
221
289
  `read({path:"LICENSE",complete:true})`.
@@ -278,7 +346,9 @@ an arbitrary JavaScript module or a Python/shell script.
278
346
 
279
347
  Program files must be regular UTF-8 files inside the workspace, including symlink
280
348
  targets. Invalid encoding, oversized input and syntax errors fail before commands;
281
- no truncated prefix is executed. Review untrusted source before running it.
349
+ no truncated prefix is executed. A file changed during loading is rejected before
350
+ compilation; diagnostic source windows omit unstable snapshots as well. Review
351
+ untrusted source before running it.
282
352
  Use ordinary `edit` to revise saved programs. This is explicit source reuse, not
283
353
  conversation compression: prior calls and read results remain intact. Creation
284
354
  costs an additional call unless combined with other work, so prefer inline code
@@ -352,30 +422,42 @@ arguments do not authorize result deduplication or context rewriting. Existing
352
422
  programs that depend on whole-input replacement keep that behavior unless the
353
423
  caller explicitly requests `mergeData:true`.
354
424
 
355
- The batch stops on the first failed entry, cancellation/deadline, or exhausted
356
- log/image budget. Display-text clipping does not stop execution or mark a
357
- successful batch failed. Earlier successful commits remain; only the active
358
- program's uncommitted writes roll back. Admission errors throw before any program.
359
- Execution failures return a **typed stop report**, rather than throwing away prior
360
- results/images: isError and details.ok identify failure, details.programs contains
361
- every attempted result, and details.attempted/total identifies unstarted work.
362
- Single code/file invocations retain their existing throwing behavior.
425
+ Independent batch entries continue after ordinary failures, including in sequential
426
+ mode. Cancellation/deadline, exhausted shared call/image budgets, or an uncertain
427
+ filesystem outcome stop remaining work. Display-text and console-log clipping do not stop execution or mark
428
+ a successful batch failed; clipped logs set `details.logTruncated` and carry a
429
+ bounded warning. Completed edit/write steps remain saved; only an active explicit
430
+ checkpoint's uncommitted writes roll back. Admission errors throw before any program.
431
+ Execution failures return a **typed partial/stop report**, rather than throwing away prior
432
+ results/images. A `tool_result` hook also projects the error flag into Pi, which
433
+ otherwise treats a resolved tool call as successful. `isError` and `details.ok`
434
+ identify failure, `details.programs` contains
435
+ every attempted result with its zero-based `details.programIndex`.
436
+ `details.failedPrograms` and `details.notRunPrograms` identify exactly what needs
437
+ attention; `details.attempted/total` gives the counts. Single code/file invocations
438
+ still throw on uncaught errors, but saved edits are listed in the error and
439
+ `details.savedPaths`. Do not repeat them. Arbitrary dependent JavaScript cannot
440
+ be resumed after an uncaught exception; split independent work into `programs`
441
+ or use `Promise.allSettled` for independent commands.
363
442
 
364
443
  Set `parallel: true` with `programs` to run independent entries concurrently
365
444
  (up to 8 at once). Each still gets a fresh guest and its own commit; results stay
366
445
  in submission order. A failed entry does not stop siblings. Two entries writing
367
446
  the same file race: the losing commit reports a conflict. Sequential remains the
368
447
  default. `parallel` and `mergeData` are invalid on a lone `code` or `file` call.
369
- Log/image budget overflow marks the batch failed and stops queued entries;
370
- already-running entries settle and their completed commits remain. Text overflow
371
- only clips the displayed result and sets `details.returnTruncated`; queued entries
372
- still run. Parallel execution does not multiply the aggregate allowances.
373
-
374
- The outer deadline, host-call budget, log allowance, text budget and image limits
375
- are shared across the batch. Individual read budgets are not reduced. Every
376
- attempted program's text is assembled in length-delimited blocks, then the combined
377
- display is clipped if necessary. Images retain program/image labels. Return
378
- summaries or use focused windows when you need every result to fit on display.
448
+ Image budget overflow marks the batch failed and stops queued entries;
449
+ already-running entries settle and their completed commits remain. Text/log
450
+ overflow only clips delivery and sets `details.returnTruncated` or
451
+ `details.logTruncated`; queued entries still run. Parallel execution does not multiply the aggregate allowances.
452
+
453
+ The outer deadline, host-call budget, batch log allowance, text budget and image
454
+ limits are shared across the batch. Batch `details.logs` stays capped at the log
455
+ allowance; individual receipts retain their bounded per-program logs. Individual read budgets are not reduced. Every
456
+ attempted program's text is assembled in length-delimited blocks. Oversized batches
457
+ divide the available text budget among per-program previews, so a large success
458
+ does not hide a later failure. Extremely small budgets may also clip the framing.
459
+ Images retain program/image labels. Return summaries or use focused windows when
460
+ you need complete results on display.
379
461
 
380
462
  Batch only continuations already chosen by the agent, such as edit then known
381
463
  verification, or create then run known audits. Keep a separate call whenever new
@@ -390,15 +472,25 @@ to serialized JSON `data`, including quote/newline escaping and object keys.
390
472
  Oversized input fails before commands run and reports its actual serialized size.
391
473
  Split larger documents into
392
474
  separate invocations: first `write(path, firstChunk)`, then
393
- `write({path,content:nextChunk,append:true})`. Append uses the complete internal
475
+ `write({path,content:nextChunk,append:true})`. Positional `write(path,text,options)`
476
+ also accepts `append`, `replace`, and `allowReadArtifacts` boolean flags. Unknown
477
+ options and mixed object/positional signatures reject; options never override the
478
+ path or content arguments. Append uses the complete internal
394
479
  file buffer, never a bounded model-facing read; it retains conflict checks and
395
- per-program rollback. Missing files are created. Multiple invocations are not
480
+ explicit-checkpoint rollback. Missing files are created. Multiple invocations are not
396
481
  one atomic transaction: for an all-or-nothing publication, assemble a new staging
397
482
  file and publish it only when complete. External write overrides reject append.
398
483
 
399
484
  Supernova supports bounded foreground execution and session-owned background terminals
400
485
  (see below), not durable jobs across host restarts. For long archive scans, use a
401
486
  background terminal or resumable chunks and write progress records under `.work`.
487
+ Owned foreground `bash` returns complete combined stdout/stderr to the program
488
+ within a 2,097,152 UTF-16-code-unit capture ceiling; model/trace output remains a
489
+ bounded preview. Exceeding the capture ceiling throws instead of returning
490
+ corrupted partial JSON. Redirect larger output to a file and use
491
+ `read({path,complete:true})` or JSON projection. External bash overrides remain
492
+ authoritative and may have their own output limits.
493
+
402
494
  Foreground shell commands inherit the current program `timeoutMs` unless they
403
495
  specify their own; increasing the outer deadline no longer
404
496
  leaves a hidden 60-second shell cap. Set the inner `bash` timeout shorter than the
@@ -407,15 +499,77 @@ deadline covers **all** waits and commands, including `sleep`; a shell's own `ti
407
499
  command does not extend it. On a deadline or cancellation, the worker stops and
408
500
  pending host calls get a bounded 250ms drain to retain owned-shell diagnostics and
409
501
  finalize process termination. Non-cooperating host executors may still outlive that
410
- drain. Cancellation is reported separately from timeout; neither triggers a retry.
411
- Progress files survive shell execution but staged VFS writes may roll back.
502
+ drain. The same deadline covers the final workspace commit; cancelled queued
503
+ commits withdraw without writing later or releasing another transaction's lock.
504
+ Read-only results do not wait for that lock. In-progress filesystem I/O and safe
505
+ rollback must settle before reporting completion, so they can extend elapsed time.
506
+ Cancellation or session invalidation during publication triggers recovery, including
507
+ on the final file. After a completed flush, cancellation keeps the committed files
508
+ but prevents the pending external command from starting; those versions are not
509
+ reported as rolled back.
510
+ Cancellation is reported separately from timeout; neither triggers a retry.
511
+ Progress files and completed edit/write steps survive later failures; active explicit
512
+ checkpoint writes may roll back.
513
+ Termination is a hard stop: guest `catch`/`finally` cleanup is not guaranteed to run.
412
514
  On macOS/Linux, foreground and background commands share process-group cleanup:
413
515
  normal leader exit, cancellation and timeout retire ordinary descendants before
414
516
  reporting completion. A shell's `command &` does not create a durable job; launch
415
517
  the long-running command itself with `background:true` instead.
416
518
 
417
- Large returned objects are bounded previews, not retained artifacts. Select fields
418
- and array windows before returning, rather than parsing a truncated preview.
519
+ Filesystem paths preserve literal leading/trailing filename whitespace; malformed
520
+ Unicode paths are rejected instead of aliasing replacement-character filenames.
521
+ Owned text writes, appends, edits and patches require well-formed Unicode. Unpaired
522
+ UTF-16 surrogates are rejected rather than silently encoded as replacement characters.
523
+ Valid surrogate pairs, BOMs, combining characters and line endings are preserved.
524
+ Use an explicit byte-writing command for non-UTF-8 file content.
525
+
526
+ Large returned objects are bounded previews, not retained artifacts. Oversized
527
+ named/record batches divide the display budget among sibling entries instead of
528
+ letting the first file hide the rest. Clipped strings disclose their original
529
+ UTF-16 length; collections that cannot fit disclose omitted item counts. Error
530
+ messages escape lone surrogate code units before display budgeting, preserving
531
+ valid Unicode and newlines. This
532
+ does not shorten values inside the guest or create resumable artifact handles.
533
+ Select fields and array windows before returning, rather than parsing a truncated
534
+ preview; read explicit file windows when you need complete source.
535
+
536
+ ## Tokens: native tool calls vs Supernova
537
+
538
+ 0.11.0 keeps complete results: committed native edits and writes stay, independent `programs` continue after ordinary errors, and `indexed:true` opens owned source.
539
+ Source and result text are not compressed; the remaining lever is the standing definition (645 / 633 tokens on o200k_base / cl100k_base).
540
+ Fixed 13-program replay (`js-tiktoken` 1.0.21): 28,130 -> 9,819 tokens on o200k_base (65% less than unbatched). Shared source and data, 16 programs, one model call: 17,771 -> 3,487 (80%).
541
+ Eight programs sharing a 48-path input: 16,309 -> 5,527 (66%). Same six-call schedule versus `d444eb7`: 18,535 -> 9,819 (47%).
542
+ Local 8-file worker, Apple M5 Max, Node 22.23.3: unbatched cold p95 19.7 ms (8 bridge calls); coalesced pristine-warm p95 3.1 ms (1 call).
543
+ Method, both encodings, and limits: [TOKEN_COSTS.md](https://github.com/AdityaVG13/pi-stack/blob/main/packages/pi-supernova/docs/TOKEN_COSTS.md).
544
+
545
+ ## TUI presentation
546
+
547
+ Pi and OMP use the compact Nova result card. The default view stays anchored to
548
+ its latest eight calls during execution and after completion, rather than jumping
549
+ back to the earliest operations. Completion is explicitly labelled.
550
+
551
+ - Successful collapsed cards show call rows, not returned source or JSON bodies;
552
+ expand to inspect the result. JavaScript-only runs still show a short result.
553
+ Latest-change previews use five diff rows; failures keep at most eight
554
+ diagnostic rows with expansion hints. Failed or rolled-back changes are
555
+ labelled as attempts, not successful persistence.
556
+ - Expansion shows up to 24 recent calls, up to 24 diff rows per operation, logs,
557
+ and a larger result preview. It is not an unlimited transcript or file artifact.
558
+ - Partial updates deliver the latest state on a coalesced 32 ms cadence (about
559
+ 31 updates/second at most), not one repaint per operation. Completion cancels
560
+ queued updates; snapshot frames do not change after delivery.
561
+ - Each displayed value has a 32,000-character UI text budget before layout.
562
+ Long strings retain a labelled head/tail preview; clipping does not shorten
563
+ the machine-facing value. Select fields or read explicit source windows when
564
+ complete content is needed. Expansion does not remove the UI text budget.
565
+ - Printable ASCII wraps in bulk; Unicode uses grapheme-aware wrapping. Each card
566
+ retains one bounded, uncolored result layout across repaints and expansion.
567
+ Content or width changes replace it; theme invalidation still repaints all rows.
568
+ Terminal-width safety remains part of the renderer contract.
569
+
570
+ These are package-owned renderers using the host TUI, not modifications to Pi or
571
+ a second terminal renderer. Headless host checks establish layout and repaint
572
+ contracts, not live-terminal frame-rate, subjective smoothness or model speed.
419
573
 
420
574
  ## Background terminal sessions
421
575
 
@@ -467,7 +621,10 @@ return await bash({action:"list"});
467
621
  - `cursor` is an absolute UTF-16 output offset. Pass the previous cursor for
468
622
  incremental output, or omit it to replay retained output. stdout/stderr share
469
623
  a 65,536-character tail. `truncated:true` and `outputStart` disclose discarded
470
- history; polling does not consume it. `waitMs` is 0--30,000 (default 0).
624
+ history; polling does not consume it. A retained boundary or manually supplied
625
+ cursor inside a UTF-16 pair advances to the next complete code point, with
626
+ `outputStart` and `truncated:true` disclosing the skipped partial character.
627
+ `waitMs` is 0--30,000 (default 0).
471
628
  - Input is literal, at most 16,384 characters per call. Include `\n` for Enter
472
629
  and `\u0003` for Ctrl-C in a PTY. Input is not echoed into tool traces, but
473
630
  the child/terminal may echo it into output. Do not send secrets casually.
@@ -508,7 +665,6 @@ return await bash({action:"list"});
508
665
  override is rejected rather than silently ignoring background options or
509
666
  bypassing the override's permissions.
510
667
 
511
-
512
668
  ## JSON reports and targeted text audits
513
669
 
514
670
  For JSON, select fields inside the read adapter, **before** output budgeting:
@@ -519,6 +675,9 @@ return {verdict, values};
519
675
  ```
520
676
 
521
677
  Selectors support "." (root), .field, .nested[0], .items[0:10], and .["quoted.key"].
678
+ Hyphenated names such as `.credentials.openai-codex` are literal own-property
679
+ keys, not subtraction. Other punctuation and leading hyphens use quoted keys;
680
+ selectors still never evaluate code or traverse prototypes.
522
681
  Use json:true for the complete parsed value. Put the selector in `json`
523
682
  (`json:".field"`), not a second `selector` key; a leftover `selector` folds
524
683
  when `json` is absent, `true`, or `"."`. Selectors are not full jq: pipes,
@@ -534,7 +693,9 @@ separate **64 MiB estimated storage limit per read**, including aggregate
534
693
  multi-selector expansion. Within it, arrays/objects/scalars retain their actual
535
694
  values, even when larger than the display. No routing object is substituted:
536
695
  `.map` and `.filter` work on the selected array. Multi-selector values remain
537
- independently mutable. The input/storage safety limits throw with guidance.
696
+ independently mutable. Storage accounting charges scalar strings in the same
697
+ pass rather than retaining a second string worklist; container and alias
698
+ accounting, aggregate limits and failure guidance are unchanged.
538
699
  Plain .json reads are raw text, including malformed JSON; parsing is requested
539
700
  only by `json`. Explicit line windows are not necessarily JSON documents.
540
701
  Do not combine json with complete, line windows, or source views. External read
@@ -552,7 +713,7 @@ Uncaught read errors abort the program, including `return {a:await read(...),
552
713
  b:await read(...)}`; earlier successful values are not an implicit partial return.
553
714
  For optional sources, explicitly return `await Promise.allSettled(paths.map(path =>
554
715
  read(path)))`. This keeps successful text and per-path errors without weakening
555
- rollback for uncaught failures.
716
+ explicit checkpoint rollback. Completed edits outside a checkpoint remain saved.
556
717
 
557
718
  Other read options, even false-valued flags, do not bypass a captured external
558
719
  read executor; its policy, transforms and failures remain authoritative.
@@ -562,6 +723,11 @@ explicit offset/limit. Use complete reads for computation within the 64 MiB
562
723
  ceiling, and return a summary. JSON over 16 MiB needs a streaming parser via bash. Arbitrary returned objects still have bounded previews, not implicit
563
724
  continuation handles.
564
725
 
726
+ Successful subprocess cleanup wakes on pipe closure rather than waiting for the
727
+ fallback poll. Completion still requires both closed output pipes and retired
728
+ owned POSIX process groups; cancellation, escalation and cleanup deadlines are
729
+ unchanged. This applies to source-search subprocesses and background terminals.
730
+
565
731
  ## Execution and automatic batching
566
732
 
567
733
  ```js
@@ -603,18 +769,30 @@ and non-yielding code can prevent sampling until it reaches a command or returns
603
769
  The outer deadline still terminates non-yielding workers. This is not a hard
604
770
  process-memory or security boundary.
605
771
 
606
- File changes are staged until program success. A throw before an external-mutation
607
- barrier rolls them back. Shell execution flushes preceding changes; external shell
608
- side effects cannot be rolled back. Stale commits fail explicitly rather than
609
- silently overwriting successful concurrent changes. This is not a cross-process
610
- filesystem lock. Outcomes explicitly report committed/rolledBack **file versions**
772
+ Each successful `edit` or `write` command publishes its changes before returning.
773
+ A later failed command, returned-image error, or uncaught exception does not undo
774
+ those saved steps. A single multi-replacement `edit({path,edits:[...]})` is still one
775
+ atomic step: its replacements use original coordinates and must all validate.
776
+ Use separate commands or independent `programs` for best-effort work; use an explicit
777
+ checkpoint when the changes must succeed together. Shell execution flushes any
778
+ pending changes; external shell side effects cannot be rolled back. Stale commits fail explicitly rather than
779
+ silently overwriting successful concurrent changes. New files use atomic
780
+ no-clobber publication, so filesystem-equivalent names and destinations created
781
+ during staging conflict rather than replace existing data. This requires hard-link
782
+ support on the workspace filesystem; unsupported creation fails without an unsafe
783
+ rename/copy fallback. Existing files recheck their observed version after staging
784
+ and before atomic replacement. These checks are not a cross-process filesystem
785
+ lock. Outcomes explicitly report
786
+ committed/rolledBack **file versions**
611
787
  (counted per flush/checkpoint, not unique paths) and external-call attempts. A
612
- successful inner checkpoint merges into the program, not necessarily onto disk.
613
- Pending commits or failed recovery are reported as uncertain: inspect disk and
614
- recovery backups before retrying. Import-based mutations and shell side effects
788
+ successful explicit checkpoint publishes the group together before returning.
789
+ Recovery checks destinations against the bytes this transaction published before
790
+ restoring or removing them. Detected intervening changes remain intact, and any
791
+ original backup is retained. Pending commits or failed recovery are reported as
792
+ uncertain: inspect disk and recovery backups before retrying. Import-based mutations and shell side effects
615
793
  are outside the VFS counters; this is not a filesystem audit.
616
794
 
617
- `edit(async () => {...})` creates a nested filesystem checkpoint. It returns
795
+ `edit(async () => {...})` creates an explicit atomic filesystem checkpoint. It returns
618
796
  `{ok:true,committed:true,value}` on success. On failure it rolls back and rethrows
619
797
  the cause, so an ignored failed checkpoint cannot report program success. Use
620
798
  `try { await edit(async () => {...}); } catch (error) {...}` for deliberate recovery.
@@ -623,15 +801,17 @@ checkpoints, and concurrent commands outside the active callback are rejected.
623
801
  Await the checkpoint before running shell checks. A checkpoint cannot roll back
624
802
  external shell effects. For a temporary mutation test, save the original text,
625
803
  edit and run the check outside a checkpoint, then explicitly restore it. Catch
626
- the check failure, restore, and let that program succeed so the restoration
627
- commits before reporting the failure. A `finally` restoration followed by an
628
- uncaught error is only staged and rolls back too. Keep a backup: cancellation
804
+ the check failure and restore before reporting it. A completed `finally` restoration
805
+ outside a checkpoint stays saved even if the program subsequently throws. Keep a backup: cancellation
629
806
  or a worker deadline can prevent cleanup from running.
630
807
 
631
808
  ## Context, caching and failure fidelity
632
809
 
633
810
  - Plain reads are not replaced with earlier-context references. A local cache hit
634
811
  is not proof the model still retains an earlier result after compaction.
812
+ - Concurrent windows into the same observed file version share only an in-flight
813
+ conflict-signature hash. Completed hashes are not a read cache; every window
814
+ still checks its own version, and writes retain compare-and-swap validation.
635
815
  - Text and JSON computation is independent of display limits. Source previews
636
816
  provide exact continuation; raw displayed text can be clipped and must not be
637
817
  parsed as a complete file. I/O/storage limits still fail explicitly.
@@ -682,7 +862,7 @@ provides an advisory `workspace:changed` event for independent cache/index consu
682
862
  `cwd` identifies the calling workspace. `paths` contains absolute file paths after
683
863
  a successful disk flush; paths may contain filesystem aliases. The frozen event
684
864
  and path array contain no source text. Checkpoint merges, restored rollbacks, and
685
- read-only programs emit nothing. A shell boundary can flush paths before a later
865
+ read-only programs emit no change event. A shell boundary can flush paths before a later
686
866
  program failure, so notifications are not conditional on overall tool success.
687
867
 
688
868
  `paths: null` means the changed paths are unknown: shell or delegated mutation
@@ -696,6 +876,29 @@ Observer failures cannot roll back writes. This is an optional extension convent
696
876
  not a built-in host standard, durable event log, or cross-process filesystem watcher.
697
877
  There is no dependency on or automatic routing to any consumer package.
698
878
 
879
+ ### Optional file-read receipts
880
+
881
+ A successful program may emit `workspace:read` with the same frozen
882
+ `{version:1,cwd,paths}` envelope, containing at most 256 distinct absolute paths.
883
+ These are file-open hints from native on-disk text reads, not source versions or
884
+ proof that the model saw the text. A program can summarize a read and still
885
+ qualify. Receipts cover ordinary, ranged and resolved text reads, including
886
+ inline/streamed batches; paths may contain filesystem aliases.
887
+
888
+ Provenance is carried by a private host-side marker, never inferred from source
889
+ content, result-shaped JSON or the truncated tool trace. Staged overlay reads,
890
+ empty windows, failed reads, JSON projections, directories, images and
891
+ structural/focused-only outputs do not qualify. Failed programs publish no read
892
+ receipt; caught read failures do not discard successfully delivered siblings.
893
+ Checkpoint merges do not publish before outer program success. Successful earlier
894
+ programs in a later-failing batch may already have published, like disk commits.
895
+
896
+ `pi.events.on("workspace:read", handler)` is optional, synchronous and best-effort.
897
+ Subscriber errors do not fail the read/program, and there is no import or
898
+ requirement on an indexer, cache or memory service. A consumer should deduplicate
899
+ these hints and apply its own repository/inclusion rules; this is neither a
900
+ complete I/O audit nor an authenticated or durable cross-process event stream.
901
+
699
902
  ## Security and host boundary
700
903
 
701
904
  CodeMode executes trusted JavaScript in a terminable worker, **not a security
@@ -706,14 +909,30 @@ or a separately authorized external command. Errors identify the rejected path
706
909
  and workspace, including symlink escapes. JavaScript imports and shell commands still have process
707
910
  privileges. Do not run untrusted programs as though these adapters isolate them.
708
911
 
709
- Pi preflights the outer `supernova` call. Internal primitives do not emit ordinary
710
- native `tool_call` events, so third-party guards that only recognize top-level
711
- `edit` or `bash` need CodeMode-aware handling. Configured exclusions and supported
912
+ Pi preflights the outer `supernova` call. It registers with `model-only` exposure
913
+ on hosts supporting that contract, preventing recursive invocation by native
914
+ codemode. The guest surface is still exactly `read`, `write`, `edit`, and `bash`;
915
+ this does not expose arbitrary registered tools as guest functions.
916
+
917
+ Owned filesystem primitives keep their transactional adapters and do not emit
918
+ ordinary native `tool_call` events, so third-party guards that only recognize
919
+ top-level `edit` or `bash` need CodeMode-aware handling. On Pi v0.99, delegated
920
+ host overrides and indexed discovery emit real nested hooks with the host's
921
+ parent IDs. Their usage is aggregated by Pi, not added again by Supernova. Configured exclusions and supported
712
922
  host-session execution safeguards remain enforced. Guards inspecting code/file
713
923
  inputs must also understand the programs array; its entries do not emit separate
714
924
  top-level tool_call events. Actual-host smoke checks are
715
925
  not a claim that every third-party permission extension has been validated.
716
926
 
927
+ Delegated tools with `outputSchema` can return `structuredContent`: successful
928
+ values reach the existing command as data, independently of UI text/details.
929
+ Oversized structured values become explicitly clipped JSON display strings under
930
+ `maxCallResultChars`, never silently reshaped objects or complete-file claims.
931
+ Host errors still throw through the guest command, even when the nested outcome
932
+ stores its error flag outside the result. Redaction hooks can remove structured
933
+ content; Supernova then uses the redacted text rather than stale data. Use explicit
934
+ `read({path:...})` for remote filenames that could otherwise look like symbols.
935
+
717
936
  ## Development and evidence
718
937
 
719
938
  Implementation is grouped under `src/`; all replacement tests are under `tests/`.
@@ -849,6 +1068,9 @@ not hard real-time guarantees.
849
1068
  It excludes model latency, provider tokens and prewarm time; it is not a universal
850
1069
  comparison against every CodeMode implementation.
851
1070
 
1071
+ Supernova retains its own execution engine and supported public Pi/OMP host
1072
+ APIs. A rebase onto native Pi codemode is not part of this release.
1073
+
852
1074
  See [the changelog](https://github.com/AdityaVG13/pi-stack/blob/main/packages/pi-supernova/docs/CHANGELOG.md) for changes and compatibility notes.
853
1075
 
854
1076
  ## Research and prior art
@@ -860,12 +1082,65 @@ an additional model call are not silently invoked by the tools.
860
1082
 
861
1083
  | Work | What we use it for | Where |
862
1084
  |------|--------------------|-------|
863
- | **Zero-Mem: Zero-Token Memory Operations for LLM Agents**, Xiao, Zhu, Zhang, Chen, Hong, Zhuang, Zhang, Chen, Ouyang, Ren, Huang (arXiv:2607.29377) | Evidence selection: entity–context graph with co-occurrence weights (eq. 3–4), turn/window/episode hierarchy as line/span/file (eq. 5, 11), query profile and relational/local routing (eq. 6–7), lexical entity alignment and one propagation step (eq. 8–9), personalized PageRank over spans (eq. 10), per-view normalisation and ρ-weighted fusion (eq. 12–13), closure with bridges and neighbours (eq. 14), deterministic calibration (eq. 15). Top-K = 5 follows the paper's Top-5 ≈ Top-10 finding. | `src/context/evidence.js` |
1085
+ | **Zero-Mem: Zero-Token Memory Operations for LLM Agents**, Xiao, Zhu, Zhang, Chen, Hong, Zhuang, Zhang, Chen, Ouyang, Ren, Huang (arXiv:2607.29377) | Evidence selection: entity-context graph with co-occurrence weights (eq. 3-4), turn/window/episode hierarchy as line/span/file (eq. 5, 11), query profile and relational/local routing (eq. 6-7), lexical entity alignment and one propagation step (eq. 8-9), personalized PageRank over spans (eq. 10), per-view normalisation and ρ-weighted fusion (eq. 12-13), closure with bridges and neighbours (eq. 14), deterministic calibration (eq. 15). Top-K = 5 follows the paper's Top-5 ≈ Top-10 finding. | `src/context/evidence.js` |
864
1086
  | **Agent Zero Memory: Provenance-Aware Long-Term Memory for LLM Agents**, Zhu, Wu (arXiv:2608.29606) | Every returned unit carries provenance (path, line range, verbatim text); the L0→L1→L2 read discipline (`read(query)` → `read(path, {about})` → `read(path, offset, limit)`); the citation-lock idea that a model should only cite what it actually opened. | `src/context/evidence.js`, `src/context/outline.js`, tool guidance |
865
1087
  | **Harness-of-Harness: Multi-Day Autonomous Software Development with Continual Improvement**, Yan, Su, et al. (arXiv:2609.01481) | Progressive disclosure (index first, detail on demand) and carrying evidence forward instead of reconstructing it from code. | outline / result shaping |
866
1088
  | **Act More, Decide Less: Skill-Guided Adaptive Action Chunking for Long-Horizon LLM Agents**, Yang, Jin, Zhao, et al. (arXiv:2609.02042) | Framing: one supernova program is an action chunk (one model decision, many primitive actions, stop at the first failing one). | runtime design |
867
- | **fff**, Dmitriy Kovalenko, MIT, <https://github.com/dmtrKovalenko/fff> | File search. We reimplemented fff's ranking in plain JavaScript after reading its Rust sources (`crates/fff-core/src/score.rs`, `dbs/frecency.rs`, `path_utils.rs`); the formulas and constants are fff's, the code is ours, and nothing runs out of process. Bounded fuzzy filename hints now run automatically for unmatched bare source names, using in-memory frecency and directory distance without extra filesystem probes. The full internal search implementation also retains typo-tolerant fuzzy path matching with boundary/consecutive/case bonuses; smart-case; exact-filename +40% and filename +20% bonuses; frecency boost `base·f/100` with fff's AI-mode decay (3-day half-life, 7-day window) and modification-recency steps (30s/5m/15m/1h/4h); git-modified +15%; directory-distance penalty from the current file (−1 per hop, floor −20); definition-first result hinting; fuzzy fallback on zero literal matches; weak-match cutoff; watcher-driven index refresh. Git/mtime boosts and full indexed grep are not mandatory stages of ordinary reads. Not ported: fff's SIMD/frizbee matcher (ours is an fzf-style greedy match with backward tightening), LMDB persistence (frecency is per session), and the MCP/Neovim surfaces. | `src/context/fuzzy.js`, `src/context/repo-index.js`, `src/bridge/host-bridge.js` |
1089
+ | **fff**, Dmitriy Kovalenko, MIT, <https://github.com/dmtrKovalenko/fff> | File search. We reimplemented fff's ranking in plain JavaScript after reading its Rust sources (`crates/fff-core/src/score.rs`, `dbs/frecency.rs`, `path_utils.rs`); the formulas and constants are fff's, the code is ours, and nothing runs out of process. Bounded fuzzy filename hints now run automatically for unmatched bare source names, using in-memory frecency and directory distance without extra filesystem probes. The full internal search implementation also retains typo-tolerant fuzzy path matching with boundary/consecutive/case bonuses; smart-case; exact-filename +40% and filename +20% bonuses; frecency boost `base·f/100` with fff's AI-mode decay (3-day half-life, 7-day window) and modification-recency steps (30s/5m/15m/1h/4h); git-modified +15%; directory-distance penalty from the current file (-1 per hop, floor -20); definition-first result hinting; fuzzy fallback on zero literal matches; weak-match cutoff; watcher-driven index refresh. Git/mtime boosts and full indexed grep are not mandatory stages of ordinary reads. Not ported: fff's SIMD/frizbee matcher (ours is an fzf-style greedy match with backward tightening), LMDB persistence (frecency is per session), and the MCP/Neovim surfaces. | `src/context/fuzzy.js`, `src/context/repo-index.js`, `src/bridge/host-bridge.js` |
1090
+
1091
+ ## Release notes
1092
+
1093
+ - Pi 0.99+ nested execution uses the current host invocation and its permissions;
1094
+ optional `indexed:true` source lookup opens owned, editable source bytes.
1095
+ - Final commit deadlines, concurrent filesystem reads and atomic publication
1096
+ keep transaction outcomes explicit under cancellation and contention.
1097
+ - Compact Nova cards retain successful call rows without source/JSON clutter;
1098
+ Unicode layout reuse and dense-line scans reduce measured local costs.
1099
+ - Command capture, write options, JSON selectors and edit diagnostics fix
1100
+ session-derived failures without weakening exact-match or workspace guards.
1101
+ - Image decoders retain ownership until close; repeated errors, watchdogs and
1102
+ failed retries remain fail-closed. Background output preserves code points.
1103
+ - Overlay keys, conflict signatures and commit destinations share canonical
1104
+ filesystem identity. Logical paths stay in receipts; identity reuse is
1105
+ call-local; commits resolve destinations afresh.
1106
+ - Successful native `edit`/`write` steps stay saved. Later read errors, failed
1107
+ shells, invalid images or uncaught JavaScript do not undo them. Independent
1108
+ `programs` continue after ordinary errors. `edit(async () => { ... })` and a
1109
+ single `edits[]` replacement set remain atomic. Failed results expose
1110
+ `details.savedPaths` and batch indices so only unsaved work is retried.
1111
+
1112
+ ### Previous release: 0.10.2
1113
+
1114
+ - Results print the `mutations:` line only when it informs: files committed or
1115
+ rolled back, an uncertain filesystem outcome, or shell side effects left behind
1116
+ by a failed program. It had appeared on most results, usually all zeros.
1117
+ - Clearer guest errors: naming a variable after a command (`const read = await
1118
+ read(...)`) says so, `supernova(...)` inside a program says to call the
1119
+ commands directly, and an empty `oldText` explains how to insert.
1120
+
1121
+ Earlier releases: [changelog](https://github.com/AdityaVG13/pi-stack/blob/main/packages/pi-supernova/docs/CHANGELOG.md).
1122
+
1123
+ ## Limits
1124
+
1125
+ ### Reviewed concurrency and ranking boundaries
1126
+
1127
+ Owned reads reject a view if an in-process Supernova commit overlapped its read path or search scope; disk text, window and image observations settle pending commits before publishing or validating their baseline. Query/evidence views use the same read-revision check. A rejected view must be retried. This is conservative within a directory/search scope, not a repeatable-read or multi-file snapshot promise. Read cancellation does not release another transaction's commit ownership. Staged overlay reads remain speculative by design.
1128
+
1129
+ Markdown `about` reads use bounded keyword windows over prose and code blocks, not declaration outlines. Unmatched terms report no matching text.
1130
+
1131
+ Existing destinations with multiple hard links are refused rather than silently splitting their aliases. Other processes, older Supernova instances, delegated tools and shell commands do not participate in the in-process protocol. In particular, existing-file version checks still have a check-to-rename race against an uncooperative external writer, including during recovery. Portable Node provides no atomic exchange/compare-and-swap primitive here; **external-writer losslessness is not established**. Failed recovery continues to retain backups and report uncertain state.
1132
+
1133
+ Frecency capacity eviction is now LRU. Fuzzy matching uses a length-preserving lowercase projection so expanding characters cannot shift source offsets or filename bonuses; it preserves contextual lowercase but is not full Unicode normalization. Evidence ranking remains heuristic: min-max fusion is outlier-sensitive and fixed-iteration floating-point PageRank is approximate, not a certified converged ranking.
1134
+
1135
+ ### Read-only reference outlines
1136
+
1137
+ `read({path, outline:true})` uses the same read-only filesystem path rules as
1138
+ plain reads, including absolute external references and symlinks to them.
1139
+ The outline remains bounded to a 2 MiB source read. This does not grant external
1140
+ write or edit access; those operations still require workspace admission, and
1141
+ a denied mutation rolls back pending workspace writes before a barrier.
868
1142
 
869
1143
  ## License
870
1144
 
871
1145
  MIT. fff is © Dmitriy Kovalenko and contributors, also MIT.
1146
+