@elpapi42/pi-fleet 0.1.0-beta.10 → 0.1.0-beta.14

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 (43) hide show
  1. package/CHANGELOG.md +34 -1
  2. package/README.md +99 -167
  3. package/dist/cli-meta.json +313 -315
  4. package/dist/cli.mjs +2504 -1812
  5. package/dist/cli.mjs.map +4 -4
  6. package/dist/client/agent-target.d.ts +33 -0
  7. package/dist/client/contracts.d.ts +81 -0
  8. package/dist/client/fleet-client.d.ts +118 -0
  9. package/dist/client/index.d.ts +4 -0
  10. package/dist/client/sdk-connector.d.ts +7 -0
  11. package/dist/client/sdk-facade.d.ts +84 -0
  12. package/dist/client/sdk-transport.d.ts +24 -0
  13. package/dist/client/shared-client.d.ts +18 -0
  14. package/dist/client/socket-fleet-client.d.ts +21 -0
  15. package/dist/client-meta.json +5736 -0
  16. package/dist/client.mjs +4434 -0
  17. package/dist/client.mjs.map +7 -0
  18. package/dist/installer-meta.json +7 -7
  19. package/dist/installer.mjs +47 -13
  20. package/dist/installer.mjs.map +2 -2
  21. package/dist/journal-sqlite-worker-meta.json +149 -0
  22. package/dist/journal-sqlite-worker.mjs +1110 -0
  23. package/dist/journal-sqlite-worker.mjs.map +7 -0
  24. package/dist/pi/external-installation.d.ts +23 -0
  25. package/dist/platform/client/start-runtime.d.ts +25 -0
  26. package/dist/platform/install/runtime-release.d.ts +8 -0
  27. package/dist/platform/install/tree-integrity.d.ts +7 -0
  28. package/dist/platform/shared/paths.d.ts +8 -0
  29. package/dist/platform/shared/runtime-ownership.d.ts +14 -0
  30. package/dist/protocol/jsonl.d.ts +3 -0
  31. package/dist/protocol/pi-identity.d.ts +16 -0
  32. package/dist/protocol/semantic-segmentation.d.ts +22 -0
  33. package/dist/protocol/version.d.ts +2 -0
  34. package/dist/runtime/semantic-events.d.ts +43 -0
  35. package/dist/runtime-manifest.json +156 -31
  36. package/dist/runtime-meta.json +378 -53
  37. package/dist/runtime.mjs +3173 -581
  38. package/dist/runtime.mjs.map +4 -4
  39. package/dist/shared/result.d.ts +9 -0
  40. package/package.json +14 -1
  41. package/dist/sqlite-worker-meta.json +0 -84
  42. package/dist/sqlite-worker.mjs +0 -359
  43. package/dist/sqlite-worker.mjs.map +0 -7
package/CHANGELOG.md CHANGED
@@ -1,6 +1,39 @@
1
1
  # Changelog
2
2
 
3
- ## Unreleased
3
+ ## 0.1.0-beta.14 — 2026-07-27
4
+
5
+ ### Fixed
6
+
7
+ - Fixed the destructive-transition ownership proof rejecting startup on ordinary Linux desktops: a same-user zombie process exposes an unreadable `/proc/<pid>/fd` while owning no descriptors, which made the new runtime refuse to open a legacy database with `Cannot prove legacy runtime <pid> released pi-fleet state`. Live same-user processes that cannot be inspected still fail closed.
8
+
9
+ ## 0.1.0-beta.13 — 2026-07-27
10
+
11
+ Makes local programs first-class pi-fleet clients: a supported TypeScript SDK plus continuous, replayable semantic receive over shared per-user agents. This beta replaces the previous receive and watch contracts and resets pi-fleet-owned state.
12
+
13
+ ### Added
14
+
15
+ - Added the side-effect-free `@elpapi42/pi-fleet/client` TypeScript SDK inside the existing package, with direct client methods, UUID-bound agent handles, steering and follow-up input, generated declarations, stable content-safe errors, and continuity-safe receive reconnection.
16
+ - Added durable semantic receive with initial and event cursors and exactly six lifecycle types: thinking, assistant-message, and tool-execution started/finished.
17
+ - Added byte-faithful durable Pi stdout journaling, bounded replay, content-free storage diagnostics, passive WAL checkpointing, and bounded incremental reclamation.
18
+
19
+ ### Changed
20
+
21
+ - Replaced idle-gated latest-response receive with a continuous passive semantic event stream. CLI `receive --until-idle` is now the explicit live one-off projection; historical replay uses `--after` or `--from-start`.
22
+ - Added `send --follow-up`; steering remains the default. Follow-up delivery is best effort: Pi queues
23
+ follow-up input only for a run already in flight, so idle follow-up input is delivered as an ordinary
24
+ prompt, and input accepted while a turn is ending may be queued against a run that never resumes.
25
+ - Bound every SDK handle, CLI invocation, durable operation, send, incarnation, cursor, and recovery path to the immutable agent creation UUID so same-name recreation cannot inherit stale work.
26
+ - Made durable recording fail closed and require explicit continuation after an unclean-runtime observation gap.
27
+ - Limited this release scope to Linux x64 with external Pi 0.82.1.
28
+
29
+ ### Removed
30
+
31
+ - Removed the public raw `watch` command and its protocol, limits, errors, and compatibility shims.
32
+ - Removed finite latest-assistant-response retrieval and the old latest-response storage model.
33
+
34
+ ### Upgrade note
35
+
36
+ - This beta transition transactionally resets all prior pi-fleet-owned agents, operations, responses, and journal state without deleting native Pi session files. Stop old supervision and prove the old runtime and Pi process trees absent before activation. After the reset, older binaries are not a supported rollback path.
4
37
 
5
38
  ## 0.1.0-beta.10 — 2026-07-26
6
39
 
package/README.md CHANGED
@@ -2,249 +2,180 @@
2
2
 
3
3
  **Pi orchestration beyond terminal scale.**
4
4
 
5
- pi-fleet is a local, machine-first runtime for software that orchestrates Pi agents and their native sessions. It provides precise lifecycle control, exact latest-response retrieval, and live raw Pi RPC JSONL without scraping terminals.
5
+ pi-fleet is local, Pi-native execution infrastructure for programs that coordinate long-lived Pi agents. It keeps one shared per-user pool reachable through a TypeScript SDK and a JSON-first CLI while every native Pi session remains under the user's control.
6
6
 
7
7
  **Control execution. Own the session. Build the orchestration above it.**
8
8
 
9
9
  ## Why pi-fleet exists
10
10
 
11
- A terminal pane is useful observability for one Pi agent. It is not an observability model for dozens or hundreds of them.
12
-
13
- Terminal multiplexers such as tmux, cmux, and Herdr expose processes, panes, and rendered output. Agent software needs Pi-aware state: whether an agent is working or idle, whether input was accepted, which native session it is using, what its exact latest settled assistant response was, and whether interrupted work can be retried safely.
14
-
15
- | Terminal multiplexers (tmux, cmux, Herdr) | pi-fleet |
16
- | ------------------------------------------ | ------------------------------------------ |
17
- | Human-facing panes | Machine-readable lifecycle control |
18
- | Rendered stdout and scrollback | Live raw Pi RPC JSONL |
19
- | Last _n_ terminal lines | Exact latest settled assistant response |
20
- | Generic terminal input | Pi-native prompt and steering semantics |
21
- | Caller-defined recovery | Explicit restoration and failure state |
22
- | Human attention as the observability layer | Data for custom observability and analysis |
23
-
24
- pi-fleet is specialized for Pi. It gives up bundled terminal UX in exchange for semantic control and data that higher-level systems can reliably consume.
25
-
26
- ## Infrastructure for orchestration
27
-
28
- ```mermaid
29
- flowchart TB
30
- callers["Pi extensions · calling agents · orchestrators · AI software factories"]
31
- cli["pifleet CLI"]
32
- runtime["local pi-fleet runtime"]
33
- agent1["Pi agent"]
34
- agent2["Pi agent"]
35
- agent3["Pi agent"]
36
- session1["native user-controlled session"]
37
- session2["native user-controlled session"]
38
- session3["native user-controlled session"]
39
-
40
- callers --> cli --> runtime
41
- runtime --> agent1 --> session1
42
- runtime --> agent2 --> session2
43
- runtime --> agent3 --> session3
44
- ```
45
-
46
- pi-fleet is infrastructure **for orchestration**, not an orchestration framework. It owns execution lifecycle, process availability, ordered communication, restoration references, exact result retrieval, and explicit failure state.
47
-
48
- Callers own roles, task decomposition, scheduling, semantic retries, approval, aggregation, dashboards, notifications, knowledge mining, and autonomy.
49
-
50
- Typical callers include:
11
+ Terminal multiplexers such as tmux, cmux, and Herdr are useful for human-facing panes. Programmatic orchestration needs different primitives: stable agent addresses, immutable generation identity, ordered steering or follow-up input, process and recovery state, replayable high-level activity, and explicit uncertainty after a crash.
51
12
 
52
- - an existing agent delegating through the [pi-fleet operator skill](./SKILL.md);
53
- - a Pi extension coordinating specialized agents;
54
- - a local service collecting exact results from many Pi agents;
55
- - an AI software factory implementing its own scheduling and quality gates;
56
- - observability, audit, or knowledge systems consuming native Pi sessions.
13
+ pi-fleet supplies those execution primitives. It does not define roles, workflows, schedules, dashboards, semantic retries, memory policy, or autonomy. Agents act only on explicit instructions unless a higher layer implements its own bounded policy.
57
14
 
58
- If your primary requirement is watching one or two agents in terminal panes, a terminal multiplexer such as tmux, cmux, or Herdr will probably fit better. pi-fleet is for builders ready to move control and observability into software.
15
+ ## Requirements and installation
59
16
 
60
- ## Installation
61
-
62
- pi-fleet currently supports Linux x64 with Node.js `^22.19.0 || ^24.0.0` and a separately installed, compatibility-tested Pi executable. pi-fleet does not install, bundle, copy, or substitute Pi.
17
+ The current support target is **Linux x64**, Node.js `^22.19.0 || ^24.0.0`, and a separately installed **Pi 0.82.1** executable. pi-fleet launches the Pi selected by the invoking environment; it never bundles, copies, or substitutes Pi.
63
18
 
64
19
  ```bash
65
20
  command -v pi
66
- pi --version
21
+ pi --version # 0.82.1
67
22
  npm install --global @elpapi42/pi-fleet@beta
68
23
  pifleet --version
69
24
  ```
70
25
 
71
- pi-fleet selects the executable `pi` found on the invoking command's `PATH`, together with the `node` selected from that same PATH for Pi shims using `#!/usr/bin/env node`. Use `PIFLEET_PI_EXECUTABLE=/absolute/path/to/pi` only to select an explicit absolute executable; aliases and shell functions are not supported. A registered service persists the selected Pi and Node paths, so switching NVM, fnm, Volta, or a global Pi installation requires an explicit supervision transition rather than silently changing a live runtime.
26
+ pi-fleet resolves `pi` and `node` from the invoking `PATH` and persists their absolute selected paths for supervised startup. `PIFLEET_PI_EXECUTABLE=/absolute/path/to/pi` is an advanced override. Shell aliases and functions are unsupported.
72
27
 
73
- Configure normal Pi provider credentials before the first operational command. pi-fleet commands start or reuse a persistent runtime, so environment variables added only to later invocations do not change that runtime's environment. Use normal Pi credential configuration or configure the persistent runtime/service environment.
28
+ Configure provider credentials before starting the persistent runtime. Environment variables added only to later commands do not change an already-running runtime.
74
29
 
75
- ## Programmatic quick start
30
+ ## TypeScript SDK
76
31
 
77
- ```bash
78
- # Create an agent with the stable programmatic address "reviewer".
79
- pifleet create reviewer --cwd "$PWD" > created.json
32
+ The SDK ships in the same npm package as the CLI and runtime:
33
+
34
+ ```ts
35
+ import { connectPiFleet } from "@elpapi42/pi-fleet/client";
80
36
 
81
- # Submit work. While Pi is active, later sends use Pi steering semantics.
82
- pifleet send reviewer "Review the authentication changes" > accepted.json
37
+ const fleet = await connectPiFleet();
38
+ const reviewer = await fleet.create({
39
+ name: "reviewer",
40
+ cwd: process.cwd(),
41
+ instructions: "Review the current change.",
42
+ });
83
43
 
84
- # Inspect the agent without restoring an absent Pi process.
85
- pifleet status reviewer > status.json
44
+ const events = await reviewer.receive(); // live from attachment
45
+ console.log("attached at", events.cursor);
86
46
 
87
- # Wait for idle and retrieve the exact latest assistant response.
88
- pifleet receive reviewer --timeout 10m > result.json
47
+ await reviewer.send("Focus on lifecycle races."); // steering by default
48
+ await reviewer.send("Then check documentation.", { delivery: "followUp" });
89
49
 
90
- # Stream Pi's live RPC stdout to your own tooling.
91
- pifleet watch reviewer > pi-rpc.jsonl 2> watch-control.jsonl
50
+ for await (const event of events) {
51
+ if (event.type === "assistant.message.finished") {
52
+ console.log(event.text);
53
+ }
54
+ }
92
55
  ```
93
56
 
94
- Finite commands emit one compact JSON object on stdout. Expected failures emit one structured JSON error object on stderr. Exit status `0` means success, `1` means error, and receive timeout uses `124`. `watch` reserves stdout exclusively for Pi's raw RPC byte stream and writes pi-fleet readiness or errors to stderr.
57
+ `connectPiFleet()` connects to the shared per-user control plane; it does not create a private pool. Agents created through one SDK client are immediately addressable by other SDK clients and the CLI. `client.close()` closes only that client's local resources and receive streams—it never stops the runtime or shared agents.
95
58
 
96
- `--human` exists as a debugging convenience for the seven finite commands; programmatic callers should use the default JSON output.
59
+ Use `connectPiFleet({ autoStartRuntime: false })` when another process owns control-plane startup; connecting still verifies the runtime is reachable and protocol-compatible, so it fails with `runtime_unavailable` when nothing is running and `protocol_incompatible` against an older runtime, which is left untouched. Imports are inert, and passive operations remain available when Pi is missing; Pi is validated only for `create`, `send`, and `compact`.
97
60
 
98
- ## Your sessions are the data layer
61
+ ### Agent handles and input
99
62
 
100
- **pi-fleet controls execution. You control the session.**
63
+ `client.create()` and `client.get()` return remote `Agent` handles; `client.list()` returns lightweight summaries for discovery. A handle carries both the reusable friendly name and the immutable creation UUID, so an old handle cannot retarget a later same-name recreation.
101
64
 
102
- `create` creates an agent: a durable logical resource with a stable local name, a native Pi session, and a managed process lifecycle. Its Pi process may be resident or absent, but the agent remains addressable until `destroy`.
65
+ `agent.send()` means durable acceptance and ordering, not task completion or one-send/one-response correlation.
103
66
 
104
- The agent's session is not opaque pi-fleet data. It remains a native, user-controlled resource that can support independent observability, auditing, provenance, search, evaluation, and knowledge mining.
67
+ - `delivery: "steer"` is the default and matches ordinary Pi prompt/steering behavior.
68
+ - `delivery: "followUp"` asks Pi to queue input until it finishes current work. Pi only queues
69
+ follow-up input for a run that is already in flight, so pi-fleet delivers follow-up input to an
70
+ authoritatively idle session as an ordinary prompt instead. Follow-up delivery is therefore best
71
+ effort: input accepted in the narrow window while a turn is ending may be queued against a run
72
+ that never resumes, and no later turn will carry it. Use `steer` when delivery must be certain.
73
+ - Cancellation stops only the caller's wait; it does not cancel accepted remote work.
105
74
 
106
- - Use Pi's normal session storage or provide exact paths, IDs, directories, forks, and continuation selectors.
107
- - pi-fleet records the concrete session selected by Pi only so it can restore and observe execution.
108
- - pi-fleet never copies, relocates, normalizes, wraps, or deletes session files.
109
- - `destroy` removes pi-fleet management and its process; it never removes the Pi session.
110
- - External tools may read or analyze the same session without a pi-fleet-specific data format.
111
- - Deliberate concurrent writers remain under user control, but they can invalidate restoration guarantees. pi-fleet fails visibly rather than silently taking ownership or substituting a copy.
75
+ ### Continuous receive
112
76
 
113
- Pass compatible native Pi selectors after the first literal `--`:
77
+ `agent.receive()` is a passive broadcast stream and never wakes or restores Pi. Any number of consumers may attach independently.
114
78
 
115
- ```bash
116
- # Existing session file
117
- pifleet create reviewer --cwd /workspace/project -- --session /absolute/session.jsonl
79
+ ```ts
80
+ await agent.receive(); // live from invocation
81
+ await agent.receive({ after: cursor }); // replay strictly after a cursor, then follow live
82
+ await agent.receive({ fromStart: true });
83
+ ```
118
84
 
119
- # Exact Pi session ID
120
- pifleet create reviewer -- --session-id SESSION_ID
85
+ The returned stream exposes its initial opaque `cursor` before its first event. Each event has its own stable ID and cursor; lifecycle pairs share an activity ID. Delivery is at-least-once after reconnect, so consumers should checkpoint cursors and deduplicate by event ID.
121
86
 
122
- # Native first-launch selection
123
- pifleet create reviewer -- --fork /absolute/source.jsonl
124
- pifleet create reviewer -- --continue
125
- ```
87
+ The public event model contains exactly six types:
126
88
 
127
- `--cwd` is a pi-fleet option and belongs before `--`. Native Pi options belong after it and preserve their token order:
89
+ - `assistant.thinking.started` / `assistant.thinking.finished`
90
+ - `assistant.message.started` / `assistant.message.finished`
91
+ - `tool.execution.started` / `tool.execution.finished`
128
92
 
129
- ```bash
130
- pifleet create reviewer \
131
- --cwd /workspace/project \
132
- -- \
133
- --session /absolute/session.jsonl \
134
- --model anthropic/claude-sonnet-4 \
135
- --thinking high
136
- ```
93
+ There are no public deltas, raw RPC frames, turn events, retry events, or synthetic gap events. Starts mean pi-fleet durably observed meaningful activity begin. A crash may leave a start unmatched; pi-fleet never invents a finish.
137
94
 
138
- Headless `--resume` is unsupported because it requires interactive selection before RPC mode. Positional Pi prompts and `@file` inputs after `--` are rejected; use optional create instructions or `send` so pi-fleet can preserve ordered delivery.
95
+ After an unclean runtime death that may have left any Pi incarnation alive—even a logically idle one—old streams stop at their last safe cursor with `observation_uncertain`. The error provides the last-safe cursor and, when available, an explicit continuation cursor. Crossing that gap is a caller decision; pi-fleet never bridges it silently.
139
96
 
140
- ## Pi-aware control primitives
97
+ ## CLI
98
+
99
+ The CLI is a shell adapter over the same shared agents and semantic client contract:
141
100
 
142
101
  ```text
143
102
  pifleet create NAME [INITIAL_INSTRUCTIONS] [--cwd PATH] [--human] [-- PI_OPTIONS...]
144
- pifleet send NAME MESSAGE [--human]
145
- pifleet receive NAME [--timeout DURATION] [--human]
103
+ pifleet send NAME MESSAGE [--follow-up] [--human]
104
+ pifleet receive NAME [--after CURSOR | --from-start] [--until-idle] [--human]
146
105
  pifleet status NAME [--human]
147
106
  pifleet list [--human]
148
- pifleet watch NAME
149
107
  pifleet compact NAME [--human]
150
108
  pifleet destroy NAME [--human]
151
109
  ```
152
110
 
153
- | Purpose | Commands | Semantics |
154
- | ---------------------- | ---------------- | ------------------------------------------------------------------------- |
155
- | Create an agent | `create` | Assign a stable local name and start Pi, optionally with initial input |
156
- | Communicate | `send` | Start ordinary work while idle or steer active work at Pi's next decision |
157
- | Retrieve exact results | `receive` | Wait for idle and return Pi's latest assistant text |
158
- | Inspect lifecycle | `status`, `list` | Observe logical and process state without restoring Pi |
159
- | Observe live Pi RPC | `watch` | Stream one Pi process incarnation's unfiltered RPC stdout |
160
- | Compact context | `compact` | Compact an idle agent with Pi's native compaction RPC |
161
- | Release execution | `destroy` | Stop pi-fleet management without deleting the Pi session |
162
-
163
- Every agent has a local name of 1–63 lowercase letters, digits, or interior hyphens. The name is its stable programmatic address—not a persona, role, or second source of truth.
111
+ Finite commands emit one compact JSON object on stdout. Expected failures emit one structured JSON error on stderr. `receive` emits semantic event JSONL on stdout and one readiness record with the initial cursor on stderr. Downstream EPIPE is a successful caller disconnect.
164
112
 
165
- ### Send and receive
113
+ Normal `receive` stays open across work, idle periods, absent Pi processes, and same-agent restorations. `--until-idle` is a CLI-only live convenience: it atomically attaches, emits subsequent events through the exact durable idle boundary, and exits. If the agent is already idle at attachment it exits successfully with no historical output. Historical modes cannot be combined with `--until-idle`.
166
114
 
167
- A successful `send` means pi-fleet accepted and ordered the input. It does not mean work completed or guarantee a distinct response. Repeated sends may steer the same active run.
115
+ The former raw `watch` command and finite latest-response receive contract were removed during the beta cutover. Use semantic `receive`; inspect native Pi sessions directly when raw session history is required.
168
116
 
169
- `receive` waits for Pi to become idle and returns the exact latest assistant text known to pi-fleet. It is non-consuming and intentionally not correlated one-to-one with a particular send. This is semantic result retrieval, not terminal scrollback.
117
+ ## Native sessions remain yours
170
118
 
171
- `--timeout 0` polls immediately. Use explicit durations such as `30s`, `5m`, or `1h`; unitless values are milliseconds. Timeout never cancels Pi work, and canceling a held receive affects only that client.
119
+ `create` assigns a stable local address to a Pi agent and its native session. The process may be resident or absent; the logical agent remains addressable until `destroy`.
172
120
 
173
- Use explicit stdin for large or shell-sensitive input. pi-fleet never consumes piped stdin implicitly. Input must be valid, nonempty UTF-8 and is limited to 512 KiB by default.
121
+ - Native selectors after the first literal `--` are passed to Pi in their original order.
122
+ - Exact `--session`, `--session-id`, `--session-dir`, `--fork`, and `--continue` choices remain authoritative.
123
+ - pi-fleet never copies, relocates, normalizes, wraps, or deletes session files.
124
+ - `destroy` stops execution ownership and logically deletes pi-fleet-owned control, journal, and semantic history for that agent UUID while preserving the native session; only a minimal content-free idempotency receipt may remain.
125
+ - Deliberate concurrent native-session writers remain possible at the user's risk.
174
126
 
175
127
  ```bash
176
- git diff | pifleet send reviewer -
177
- pifleet create researcher - --cwd "$PWD" < instructions.md
128
+ pifleet create reviewer --cwd /workspace/project -- --session /absolute/session.jsonl
178
129
  ```
179
130
 
180
- ### Lifecycle and recovery
131
+ `--cwd` is a pi-fleet option before `--`; Pi options come after it. Headless `--resume` and Pi positional prompts are unsupported.
181
132
 
182
- `compact` is an explicit process-starting action for an idle absent agent. It restores the exact native session when capacity allows, then uses Pi's typed compaction RPC and returns bounded token metrics. It checks authoritative Pi state immediately before invocation and refuses observed active, queued, restoring, or already-compacting work. Pi does not provide an atomic idle-only compact operation, so trusted extension activity beginning in the narrow interval after that check can still encounter Pi's native abort-first compaction behavior. During compaction the agent is not idle; `receive` waits, and `watch` streams Pi's native `compaction_start`, `compaction_end`, command response, and any other RPC stdout unchanged. Treat `compaction_uncertain` as potentially applied and never retry it automatically.
133
+ ## Persistence, privacy, and failure
183
134
 
184
- An idle agent's Pi process normally remains resident. If the process is absent, a later `send` restores the agent from its concrete native session when safe. `status`, `list`, `watch`, and retrieval of an already settled response do not restore the process.
135
+ pi-fleet durably stores every complete LF-terminated Pi RPC stdout record byte-for-byte before parsing it or exposing derived receive events. This private journal can contain prompts, thinking, tool input/output, paths, extension data, and secrets emitted by Pi. It is retained for the logical agent's lifetime and removed by successful `destroy` as a logical SQLite deletion. pi-fleet does not claim immediate file shrinkage or forensic erasure from WAL files, freelist pages, backups, snapshots, or physical media.
185
136
 
186
- Inspect failed state before deciding what the orchestrator should do:
137
+ Storage failure is fail-closed: affected work stops, receive ends at the last durable cursor, committed history is preserved, and pi-fleet never bridges an unrecorded gap. Operational diagnostics contain counts, sizes, ages, health, and UUIDs—not retained payloads or paths.
187
138
 
188
- - `runtime_interrupted` means active work stopped and was not silently replayed.
189
- - `delivery_uncertain` means Pi may have received the input; replay could duplicate tool side effects.
190
- - `incarnation_cleanup_uncertain` means pi-fleet cannot prove an old process writer is gone.
191
- - `session_unavailable` or `session_ambiguous` means continuity cannot safely be claimed.
139
+ `status` and `list` are passive. An idle agent may be `resident` or `absent`; a later work operation restores an absent process from the concrete native session when safe. Treat `delivery_uncertain`, `compaction_uncertain`, `runtime_interrupted`, `incarnation_cleanup_uncertain`, and session failures conservatively. Semantic retry policy belongs to the orchestrator.
192
140
 
193
- A new explicit send is new work, not evidence that uncertain earlier work did nothing. Semantic retry policy belongs to the calling orchestrator.
141
+ ## Destructive beta transition
194
142
 
195
- ### Live raw Pi RPC stream
143
+ This release intentionally resets all prior pi-fleet-owned agent, operation, response, and journal state when upgrading the old schema. Native Pi session files are preserved. There is no compatibility alias for raw `watch` or finite receive.
196
144
 
197
- `watch` is a live, byte-faithful copy of one Pi RPC process incarnation's stdout from attachment until that process exits. It forwards every byte without parsing, filtering, aggregation, normalization, or reserialization. That includes command responses, text and thinking deltas, tool-call deltas, tool execution, lifecycle, queue, retry, compaction, extension UI, unknown future records, and even malformed or partial output exactly as Pi emitted it.
145
+ Before the new runtime opens the old database:
198
146
 
199
- The stream is live-only: it has no history or replay. A resident agent attaches immediately to future bytes. An absent idle agent remains unwoken and the watcher waits for its next incarnation, binding before startup RPC traffic. Once bound, the watcher ends with that incarnation and never silently concatenates a restored process.
147
+ 1. Finish work on the old runtime.
148
+ 2. Stop and uninstall only pi-fleet supervision with `dist/installer.mjs uninstall`.
149
+ 3. Prove the old runtime and Pi process trees are absent.
150
+ 4. Install supervision from the environment selecting the intended Pi and Node with `dist/installer.mjs install`.
151
+ 5. Start the new runtime; no old agents are restored automatically.
200
152
 
201
- Stdout contains only Pi bytes. Stderr emits one `watch.ready` JSON record after atomic subscription registration and carries any later pi-fleet error. Private transport may split or coalesce chunks, so clients must treat concatenated bytes as authoritative and buffer through LF themselves when parsing JSONL. A lagging watcher fails with `watcher_lagged` without blocking Pi or healthy watchers.
153
+ A responsive older runtime is never killed or replaced automatically. After the destructive schema reset, reinstalling beta.10 or another older binary is **not** rollback; use a forward fix or an externally managed pre-reset state backup. User-owned native sessions remain untouched throughout.
202
154
 
203
- ## Runtime, data, and maintenance
204
-
205
- The short-lived CLI connects to one private per-user runtime. On first operational use, pi-fleet verifies and materializes an immutable runtime release, then starts it in the background. A registered native service is preferred when present; service management remains experimental and outside the public beta command interface.
155
+ ## Runtime locations and service behavior
206
156
 
207
157
  Linux defaults:
208
158
 
209
159
  ```text
210
- pi-fleet state: ~/.local/state/pi-fleet/
211
- Materialized: ~/.local/share/pi-fleet/releases/
212
- Runtime socket: $XDG_RUNTIME_DIR/pifleet-$UID/control.sock
213
- (or the system temporary directory without XDG_RUNTIME_DIR)
214
- Pi sessions: Pi's normal ~/.pi storage or the exact selected path
160
+ State: ~/.local/state/pi-fleet/
161
+ Releases: ~/.local/share/pi-fleet/releases/
162
+ Socket: $XDG_RUNTIME_DIR/pifleet-$UID/control.sock
163
+ Pi sessions: Pi's normal ~/.pi storage or the exact selected path
215
164
  ```
216
165
 
217
- `PIFLEET_STATE_ROOT` and `PIFLEET_APPLICATION_ROOT` override pi-fleet-owned locations. A CLI whose state root differs from an installed service fails with repair guidance rather than connecting to the wrong database. If a persisted Pi later disappears or becomes incompatible, the runtime still serves passive `status`, `list`, stored `receive`, `watch`, and `destroy`; only `create`, `send`, and `compact` fail before Pi dispatch.
218
-
219
- A service whose persisted Pi or Node selection differs from the terminal selection rejects new work with `pi_service_mismatch`. Automatic replacement is deliberately fail-closed as `runtime_upgrade_deferred`: finish work, stop/remove only pi-fleet supervision with the installer `uninstall`, then run installer `install` from the environment selecting the intended Pi. This preserves pi-fleet state and every native Pi session. The beta.9 managed-Pi service requires this same explicit transition; pi-fleet never kills or replaces it automatically.
220
-
221
- `npx @elpapi42/pi-fleet@beta` is suitable for evaluation; global installation is recommended for continued use. pi-fleet materializes its runtime independently of the npm cache or installation, so evaluation can leave runtime and state behind.
222
-
223
- Before uninstalling, destroy agents you no longer want pi-fleet to manage:
224
-
225
- ```bash
226
- pifleet list
227
- pifleet destroy NAME
228
- npm uninstall --global @elpapi42/pi-fleet
229
- ```
230
-
231
- Removing the npm package does not delete Pi sessions, pi-fleet SQLite state, materialized releases, or an already-running runtime/service. Reinstalling a compatible version reconnects to preserved state. There is no automatic self-update, telemetry, remote transport, or npm `postinstall` service registration. Database migrations are forward-only; reinstalling an older binary is not database rollback.
232
-
233
- ## Beta status
166
+ `PIFLEET_STATE_ROOT` and `PIFLEET_APPLICATION_ROOT` override pi-fleet-owned paths. State, database, WAL, SHM, socket, and immutable-release paths are private and fail closed on unsafe ownership, type, or symlink conditions.
234
167
 
235
- Beta.9 historically shipped a managed Pi `0.80.10`. Current source has removed Pi from pi-fleet's package and immutable runtime, and has compatibility evidence for the terminal-selected Pi `0.82.1`; this correction is not published until its supervised-runtime and fresh-registry gates pass.
168
+ A service whose selected Pi or Node differs from the terminal environment returns `pi_service_mismatch` or `runtime_upgrade_deferred`; it is not silently rewritten. Global installation is recommended for continued use; `npx` is suitable for evaluation only.
236
169
 
237
- Known limits:
170
+ ## Scope and known limits
238
171
 
239
- - Linux x64 is the only validated support target. Arbitrarily hoisted local-prefix, pnpm, and unusual `npx` dependency layouts are unsupported.
240
- - Disposable systemd/PID-1 restart and user-lingering recovery are validated; a full host logout and kernel reboot are not.
241
- - macOS launchd and descendant containment, real disk exhaustion, and multi-hour resource growth remain unvalidated.
242
- - Runtime upgrades are not automatic, and active runtimes are not silently replaced.
243
- - Raw RPC watch is live-only: it provides no replay and ends with its Pi process incarnation.
244
- - A promptless missing session path can remain unmaterialized until Pi writes conversation content, following native Pi behavior.
245
- - Existing beta.9 releases include managed Pi `0.80.10` and its historical audit exception. Current source requires zero known vulnerabilities in pi-fleet's own production closure. That audit does not certify the separately installed Pi's dependency posture.
172
+ - Linux x64 is the only current release target.
173
+ - Pi 0.82.1 is the current compatibility target.
174
+ - macOS, host logout/reboot, real disk exhaustion, and multi-hour resource behavior require separate validation.
175
+ - pi-fleet has no workflow engine, scheduler queue, idle-process eviction, remote transport, telemetry, automatic semantic retry, or automatic service upgrade.
176
+ - A promptless missing session path may remain unmaterialized until Pi writes conversation content.
246
177
 
247
- For support, include `node --version`, `pifleet --version`, `pifleet list`, and `pifleet status NAME`. Never include API keys, message contents, session contents, or private paths unnecessarily. Report reproducible issues at <https://github.com/elpapi42/pi-fleet/issues>.
178
+ For support, include `node --version`, `pi --version`, `pifleet --version`, `pifleet list`, and `pifleet status NAME`. Do not include credentials, messages, thinking, tool payloads, session contents, cursors, or private paths unnecessarily.
248
179
 
249
180
  ## Development
250
181
 
@@ -258,6 +189,7 @@ npm test
258
189
  npm run test:faults
259
190
  npm run build
260
191
  npm run test:package
192
+ npm run test:client-types
261
193
  npm run test:platform
262
194
  npm run test:soak
263
195
  ```