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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,14 +1,173 @@
1
1
  # Changelog
2
2
 
3
+ ## Unreleased
4
+
5
+ ## 0.1.0-beta.10 — 2026-07-26
6
+
7
+ Corrects pi-fleet's execution-ownership boundary: pi-fleet now orchestrates the user's separately installed Pi executable instead of distributing a second managed Pi runtime.
8
+
9
+ ### Changed
10
+
11
+ - pi-fleet now requires a separately installed Pi and launches the exact Pi executable and Node interpreter selected by the invoking environment. It does not install, bundle, copy, or silently substitute Pi.
12
+ - A runtime whose persisted Pi is unavailable still serves passive inspection, response retrieval, watching, and cleanup; `create`, `send`, and `compact` fail before dispatch.
13
+ - Changed existing service Pi/Node selections fail closed as `runtime_upgrade_deferred` until users finish work and explicitly transition supervision. The beta.9 managed-Pi service follows the same manual transition: uninstall only pi-fleet supervision, then install from the intended Pi environment; state and native sessions remain.
14
+
15
+ ### Added
16
+
17
+ - Added `pifleet compact NAME [--human]`, backed by Pi's typed native compaction RPC. It restores an absent idle agent when capacity allows, checks authoritative state immediately before invocation, returns bounded token metrics, emits native compaction activity through raw RPC watchers, and never replays ambiguous compaction after a crash. Pi does not currently provide an atomic idle-only compact primitive, so a narrow trusted-extension activity race remains documented.
18
+
19
+ ### Changed
20
+
21
+ - Replaced `watch` session-file tailing with a live, unfiltered, byte-exact stream of one Pi RPC process incarnation's stdout. Stdout carries only Pi bytes; stderr reports subscription readiness and typed stream failures. Watching remains passive, bounded, and live-only, and never silently concatenates restored process streams.
22
+
23
+ ### Documentation
24
+
25
+ - Reframed pi-fleet as Pi-native, machine-first execution infrastructure for agent systems operating beyond terminal scale rather than a human-facing background terminal tool.
26
+ - Reworked the README and operator skill around programmatic lifecycle control, exact latest-response retrieval, live Pi RPC JSONL, orchestration boundaries, and user-owned sessions.
27
+ - Clarified that `create` creates an agent whose local name is its stable programmatic address, while its process residency and user-controlled native session remain separate concerns.
28
+ - Removed superseded internal implementation, testing, and release-planning documents to keep repository documentation focused on the README, operator skill, and changelog.
29
+
30
+ ### Reliability
31
+
32
+ - Added deterministic fault-injection coverage for receive timeout/cancellation, delivery recovery, runtime crashes, Pi RPC failures, SQLite worker/storage failures, protocol framing, command races, raw RPC byte boundaries, and public-error redaction.
33
+ - Serialized create, send, and destroy transitions per agent so cross-command races cannot orphan or resurrect an agent generation.
34
+ - Made SQLite-worker failures terminal for current and future calls and made send recovery safe when an operation exists but no send record was committed.
35
+ - Redacted Pi stderr and unexpected internal exceptions from public errors while retaining stable typed error codes.
36
+ - Contained asynchronous coordinator event/store failures by stopping the affected Pi process and rejecting waiters instead of producing unhandled promise rejections.
37
+ - Added a nightly reliability workflow and an isolated soak suite covering 500 concurrent ordered sends and 100 name lifecycle cycles.
38
+ - Reject invalid UTF-8 in stdin and Pi RPC stdout instead of silently replacing bytes at either protocol boundary.
39
+ - Keep idle agents `idle + absent` after pi-fleet-initiated orderly shutdown even when Pi reports a nonzero exit; active work remains `failed/runtime_interrupted`.
40
+ - Align explicit stdin input with the runtime's 512 KiB message limit and document credential-environment and receive-timeout behavior before the quick start.
41
+ - Install native services without forcing the default persistent state directory into `PIFLEET_STATE_ROOT`, preserving the default split between durable SQLite state and the private runtime socket.
42
+ - Validated systemd user lingering, idle reboot restoration, active reboot interruption without replay, single-writer restoration, and session preservation in a disposable privileged systemd container.
43
+ - Removed Pi from pi-fleet's production dependency and immutable runtime closure, restored a zero-exception production audit for what pi-fleet distributes, and moved real/process/package/CI validation to a separately installed Pi `0.82.1`. The audit does not certify the user's external Pi installation.
44
+
45
+ ## 0.1.0-beta.9 — 2026-07-20
46
+
47
+ Core product and Linux supervision validation after beta.8.
48
+
49
+ ### Fixed
50
+
51
+ - An orderly pi-fleet shutdown now leaves idle agents `idle + absent` even if Pi reports a nonzero exit; active interrupted work still becomes `failed/runtime_interrupted` without replay.
52
+ - A clean native-service install no longer forces the default persistent state directory into `PIFLEET_STATE_ROOT`, so the service and ordinary CLI agree on the private runtime socket while SQLite remains in durable state storage.
53
+ - Explicit stdin now uses the runtime's default 512 KiB message boundary instead of accepting a larger payload that the runtime later rejects.
54
+ - Onboarding now explains persistent credential environments before the first operational command and uses explicit receive timeout units.
55
+
56
+ ### Validated
57
+
58
+ - Reused one real Pi session through the same pi-fleet entry across a service restart and related follow-up assignment with less re-explanation.
59
+ - Proved user lingering, idle PID-1 restart without eager restoration, single-writer session restoration, active restart interruption without replay, explicit recovery, and session preservation in a disposable systemd container.
60
+
61
+ ### Security
62
+
63
+ - The production audit remains fail-closed except for one deliberate exact exception: managed Pi `0.80.10` currently pins `brace-expansion@5.0.6` affected by local glob-input denial-of-service advisory `GHSA-3jxr-9vmj-r5cp`. The policy verifies the advisory, package versions, and installed path and rejects every additional or changed vulnerability. Upstream tracking is `earendil-works/pi#6882`.
64
+
65
+ ## 0.1.0-beta.8 — 2026-07-20
66
+
67
+ Publishes the beta.7 manual-testing fixes after its immutable tag failed before npm publication.
68
+
69
+ ### Changed
70
+
71
+ - The process-tree fixture now waits for both parent and child SIGTERM handlers through an IPC readiness handshake before exposing their PIDs, removing a CI scheduling race while preserving the real escalation assertion.
72
+ - Includes the beta.7 `watch` EPIPE and pre-dispatch restoration-failure fixes; beta.7 itself was never published to npm.
73
+
74
+ ## 0.1.0-beta.7 — 2026-07-20
75
+
76
+ Continued direct CLI edge-case testing. No intentional command-surface change.
77
+
78
+ ### Fixed
79
+
80
+ - `watch` now treats downstream `EPIPE` as normal client disconnection, exiting successfully without misreporting a closed output pipe as `invalid_arguments`.
81
+ - A restoration failure proven to occur before prompt dispatch now returns `pi_start_failed`, marks the send definitively failed, leaves the agent `failed + absent`, and releases process capacity instead of claiming `delivery_uncertain` and leaving `restoring + starting` state.
82
+ - Restoration cleanup uncertainty remains fail-closed as `incarnation_cleanup_uncertain` with its process slot retained when pi-fleet cannot prove the spawned process is gone.
83
+
84
+ ### Manual validation
85
+
86
+ - Exercised active runtime death with held clients, hanging/HTTP-error/malformed providers, 19 MB watch backpressure, stdin limits, Unicode paths, extension UI cancellation, oversized session records, watch pipe closure, and missing-cwd restoration in isolated environments.
87
+
88
+ ## 0.1.0-beta.6 — 2026-07-20
89
+
90
+ Manual interruption-semantics correction. No intentional command-surface change.
91
+
92
+ ### Fixed
93
+
94
+ - `receive` now returns the agent's stored failure code when the agent is failed instead of returning an older assistant response as successful completion of interrupted work.
95
+ - Added regression coverage for the exact state observed during manual testing: a previous response exists, later work is interrupted, the Pi process is absent, and immediate receive reports `runtime_interrupted`.
96
+
97
+ ## 0.1.0-beta.5 — 2026-07-20
98
+
99
+ Release-pipeline reliability follow-up; includes the beta.4 receive and argument-validation fixes.
100
+
101
+ ### Fixed
102
+
103
+ - On Linux, process-group cleanup now treats zombie processes as exited by inspecting procfs instead of relying only on signal probes. This prevents conservative cleanup waits and CI failures when an orphaned descendant is awaiting reaping.
104
+ - Pi shutdown now waits for the child-process exit callback and coordinator transition before reporting completion, preventing a status read from briefly retaining `resident` after an idle release.
105
+ - Repeated the process-tree and real-Pi process suites five times locally before tagging after beta.4's publish workflow exposed the runner-specific zombie behavior.
106
+
107
+ ## 0.1.0-beta.4 — 2026-07-20
108
+
109
+ Manual edge-case testing fix. No intentional CLI contract change.
110
+
111
+ ### Fixed
112
+
113
+ - Prevented `receive --timeout 0` from rejecting an idle waiter before a handler was attached and terminating the runtime with an unhandled `Receive cancelled` rejection.
114
+ - Added explicit coordinator work tracking so promptless/repeated idle polling returns `no_response` or the latest response immediately, while managed work still waits for Pi settlement.
115
+ - Closed the abort-listener registration race and added regression coverage for timeout, disconnect, repeated receive, and settlement ordering.
116
+ - Return durable `invalid_arguments` errors for rejected Pi startup/positional arguments instead of a generic `internal_error`.
117
+
118
+ ### Manual validation
119
+
120
+ - Direct isolated lifecycle, timeout, repeated receive, raw watch, session mutation, concurrent startup/send, Pi/runtime crash recovery, capacity, and session-preservation scenarios passed against the beta.4 source build.
121
+ - Fresh-registry operational validation remains enforced by the tag workflow after publication.
122
+
123
+ ## 0.1.0-beta.3 — 2026-07-20
124
+
125
+ Reliability fix for fresh global npm installations. No intentional CLI or agent-lifecycle contract change.
126
+
127
+ ### Fixed
128
+
129
+ - Replaced the invalid assumption that npm recreates CI's byte-identical `node_modules` tree. Schema-3 runtime manifests retain exact hashes for pi-fleet-owned files, validate direct dependency name/version, derive the observed dependency-closure hash at materialization, and prove source-before, staged, and source-after closure equality before activation.
130
+ - Made immutable runtime release paths closure-specific, so different legitimate npm dependency layouts do not collide.
131
+ - Strengthened package testing to mutate a fresh installed dependency tree, require an operational `list`, remove the npm installation, stop the runtime, and restart through the materialized release.
132
+
133
+ ### Installation scope
134
+
135
+ - The documented global npm installation layout, where dependencies are package-local, is supported. Arbitrarily hoisted local-prefix, pnpm, and unusual `npx` dependency layouts are not yet supported.
136
+ - The tag workflow now performs a fresh registry-install operational `list` smoke after publishing. That smoke is a release gate and has not yet run for beta.3.
137
+
138
+ ## 0.1.0-beta.2 — 2026-07-20
139
+
140
+ Reliability-focused beta maintenance release. No intentional product-contract changes.
141
+
142
+ ### Reliability
143
+
144
+ - Added deterministic fault coverage and reproducible randomized lifecycle-race soak testing.
145
+ - Fixed timeout/cancellation classification, ambiguous-delivery recovery, no-replay behavior, and coordinator/store failure containment.
146
+ - Validated inbound protocol majors, strict and concurrent runtime materialization, and released beta.0/beta.1 CLI-runtime compatibility.
147
+ - Added unclean SQLite `quick_check` validation, redacted error handling, fatal UTF-8 checks, process cleanup coverage, and nightly resource-stability checks.
148
+
149
+ ### Validation limits
150
+
151
+ - Real disk exhaustion, host logout/reboot, macOS launchd/containment, and multi-hour platform resource soak remain unvalidated.
152
+
153
+ ## 0.1.0-beta.1 — 2026-07-20
154
+
155
+ Release-pipeline validation beta. No product-contract changes from `0.1.0-beta.0`.
156
+
157
+ ### Changed
158
+
159
+ - Publishes through the tag-driven GitHub Actions workflow using npm trusted publishing and provenance.
160
+ - Retains the same Linux x64 validation scope, beta limitations, and user-owned Pi session guarantees as `0.1.0-beta.0`.
161
+
3
162
  ## 0.1.0-beta.0 — 2026-07-20
4
163
 
5
- First public beta of Pi Fleet.
164
+ First public beta of pi-fleet.
6
165
 
7
166
  ### Included
8
167
 
9
168
  - Seven-command JSON-first CLI: `create`, `send`, `receive`, `status`, `list`, `watch`, and `destroy`.
10
- - Named resident Pi processes with restore-on-address from native Pi sessions.
11
- - Exact compatible Pi argument passthrough after `--` and Fleet-owned `--cwd`.
169
+ - Resident Pi processes with stable pi-fleet addresses and restore-on-address from native Pi sessions.
170
+ - Exact compatible Pi argument passthrough after `--` and pi-fleet-owned `--cwd`.
12
171
  - Ordered repeated steering input and idle-based latest-assistant response retrieval.
13
172
  - Raw live Pi session JSONL watching.
14
173
  - SQLite-backed names, latest responses, operation idempotency, and conservative crash recovery.
package/README.md CHANGED
@@ -1,61 +1,143 @@
1
- # Pi Fleet
1
+ # pi-fleet
2
2
 
3
- Pi Fleet is a local runtime and machine-first CLI for named, long-lived Pi agents.
3
+ **Pi orchestration beyond terminal scale.**
4
4
 
5
- ```text
6
- create · send · receive · status · list · watch · destroy
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.
6
+
7
+ **Control execution. Own the session. Build the orchestration above it.**
8
+
9
+ ## Why pi-fleet exists
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
7
44
  ```
8
45
 
9
- Fleet keeps a Pi process resident when possible, restores it from the same native Pi session when absent, accepts repeated steering input, and returns the latest assistant message after Pi becomes idle. Pi sessions remain under your control: Fleet references them but never copies or deletes them.
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.
10
49
 
11
- > **Beta:** `0.1.0-beta.0` is release-validated on Linux x64 with Pi `0.80.10`. macOS, actual logout/reboot recovery, automatic upgrades, and public service-management UX are not yet release-validated.
50
+ Typical callers include:
12
51
 
13
- ## Install
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.
14
57
 
15
- Requirements:
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.
16
59
 
17
- - Linux x64
18
- - Node.js `^22.19.0 || ^24.0.0`
19
- - normal Pi provider credentials and configuration
60
+ ## Installation
20
61
 
21
- Install the beta globally:
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.
22
63
 
23
64
  ```bash
65
+ command -v pi
66
+ pi --version
24
67
  npm install --global @elpapi42/pi-fleet@beta
25
68
  pifleet --version
26
- pifleet list
27
69
  ```
28
70
 
29
- `npx @elpapi42/pi-fleet@beta` is suitable for evaluation, but a global installation is recommended for continued use. Fleet materializes a verified runtime independently of the npm installation/cache, and evaluation can leave that runtime and Fleet state behind intentionally.
30
-
31
- Pi Fleet includes the tested Pi coding-agent package. It uses your normal Pi configuration, provider credentials, extensions, skills, and project resources. **Do not put API keys or other secrets in CLI arguments:** Fleet persists accepted Pi arguments so it can restore the agent. Use Pi's credential configuration or provider environment variables instead.
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.
32
72
 
33
- ## Quick start
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.
34
74
 
35
- Create a promptless named agent in the current project:
75
+ ## Programmatic quick start
36
76
 
37
77
  ```bash
38
- pifleet create reviewer --cwd "$PWD"
78
+ # Create an agent with the stable programmatic address "reviewer".
79
+ pifleet create reviewer --cwd "$PWD" > created.json
80
+
81
+ # Submit work. While Pi is active, later sends use Pi steering semantics.
82
+ pifleet send reviewer "Review the authentication changes" > accepted.json
83
+
84
+ # Inspect the agent without restoring an absent Pi process.
85
+ pifleet status reviewer > status.json
86
+
87
+ # Wait for idle and retrieve the exact latest assistant response.
88
+ pifleet receive reviewer --timeout 10m > result.json
89
+
90
+ # Stream Pi's live RPC stdout to your own tooling.
91
+ pifleet watch reviewer > pi-rpc.jsonl 2> watch-control.jsonl
39
92
  ```
40
93
 
41
- Send work and retrieve the latest assistant message after Pi becomes idle:
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.
95
+
96
+ `--human` exists as a debugging convenience for the seven finite commands; programmatic callers should use the default JSON output.
97
+
98
+ ## Your sessions are the data layer
99
+
100
+ **pi-fleet controls execution. You control the session.**
101
+
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`.
103
+
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.
105
+
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.
112
+
113
+ Pass compatible native Pi selectors after the first literal `--`:
42
114
 
43
115
  ```bash
44
- pifleet send reviewer "Review the authentication changes"
45
- pifleet receive reviewer --human
116
+ # Existing session file
117
+ pifleet create reviewer --cwd /workspace/project -- --session /absolute/session.jsonl
118
+
119
+ # Exact Pi session ID
120
+ pifleet create reviewer -- --session-id SESSION_ID
121
+
122
+ # Native first-launch selection
123
+ pifleet create reviewer -- --fork /absolute/source.jsonl
124
+ pifleet create reviewer -- --continue
46
125
  ```
47
126
 
48
- Inspect and remove Fleet management:
127
+ `--cwd` is a pi-fleet option and belongs before `--`. Native Pi options belong after it and preserve their token order:
49
128
 
50
129
  ```bash
51
- pifleet status reviewer
52
- pifleet list
53
- pifleet destroy reviewer
130
+ pifleet create reviewer \
131
+ --cwd /workspace/project \
132
+ -- \
133
+ --session /absolute/session.jsonl \
134
+ --model anthropic/claude-sonnet-4 \
135
+ --thinking high
54
136
  ```
55
137
 
56
- `destroy` stops Fleet's managed process and removes the Fleet name. It **never deletes the Pi session**.
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.
57
139
 
58
- ## Commands
140
+ ## Pi-aware control primitives
59
141
 
60
142
  ```text
61
143
  pifleet create NAME [INITIAL_INSTRUCTIONS] [--cwd PATH] [--human] [-- PI_OPTIONS...]
@@ -64,138 +146,122 @@ pifleet receive NAME [--timeout DURATION] [--human]
64
146
  pifleet status NAME [--human]
65
147
  pifleet list [--human]
66
148
  pifleet watch NAME
149
+ pifleet compact NAME [--human]
67
150
  pifleet destroy NAME [--human]
68
151
  ```
69
152
 
70
- Finite commands emit JSON by default. Add `--human` for concise human output. `watch` has no human mode: stdout is only raw, complete records appended to the selected Pi session JSONL.
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 |
71
162
 
72
- Messages can be read explicitly from stdin with `-`:
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.
73
164
 
74
- ```bash
75
- git diff | pifleet send reviewer -
76
- pifleet create researcher - < instructions.md
77
- ```
165
+ ### Send and receive
78
166
 
79
- ### Native Pi arguments
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.
80
168
 
81
- Fleet owns only its small command surface. `--cwd` belongs before the first literal `--`; native Pi options belong after it and retain their token order:
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.
82
170
 
83
- ```bash
84
- pifleet create reviewer \
85
- --cwd /workspace/project \
86
- -- \
87
- --session /absolute/path/to/session.jsonl \
88
- --model anthropic/claude-sonnet-4 \
89
- --thinking high
90
- ```
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.
91
172
 
92
- Supported native session selection includes:
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.
93
174
 
94
175
  ```bash
95
- pifleet create existing -- --session /path/to/session.jsonl
96
- pifleet create exact-id -- --session-id SESSION_ID
97
- pifleet create forked -- --fork /path/to/source.jsonl
98
- pifleet create latest -- --continue
176
+ git diff | pifleet send reviewer -
177
+ pifleet create researcher - --cwd "$PWD" < instructions.md
99
178
  ```
100
179
 
101
- Pi interprets these options directly. An existing or missing `--session` path follows native Pi behavior, and an exact `--session-id` remains exact. Fleet records the concrete selected session only so later process restoration reopens the same conversation. Headless `--resume` is not supported because it requires interactive selection before RPC mode.
180
+ ### Lifecycle and recovery
102
181
 
103
- Positional Pi prompts and `@file` inputs after `--` are rejected; use Fleet's optional create instructions or `send` so input remains ordered.
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.
104
183
 
105
- ## Communication semantics
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.
106
185
 
107
- `send` uses Pi's normal context-sensitive prompt operation with steering behavior:
186
+ Inspect failed state before deciding what the orchestrator should do:
108
187
 
109
- - while Pi is active, input is queued as steering;
110
- - while Pi is idle, input begins normal work;
111
- - repeated sends are accepted in order;
112
- - acknowledgement means Pi accepted/queued the input, not that it completed or produced a distinct response.
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.
113
192
 
114
- `receive` deliberately has no per-send response correlation:
193
+ A new explicit send is new work, not evidence that uncertain earlier work did nothing. Semantic retry policy belongs to the calling orchestrator.
115
194
 
116
- - while Pi is busy or restoring, it waits for Pi to become idle;
117
- - once idle, it returns Pi's latest assistant message;
118
- - when already idle, it returns immediately;
119
- - with no assistant message, it returns `no_response`;
120
- - `--timeout 0` performs an immediate poll;
121
- - timing out does not cancel or change Pi.
195
+ ### Live raw Pi RPC stream
122
196
 
123
- ## Sessions and `watch`
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.
124
198
 
125
- Pi and you own session files, IDs, locations, creation, migration, and deletion. Fleet never copies, relocates, or deletes them.
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.
126
200
 
127
- ```bash
128
- pifleet watch reviewer > live-session.jsonl
129
- ```
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.
130
202
 
131
- `watch` is live-only. For an existing file it begins at the current EOF; for a not-yet-materialized file it waits and begins at byte zero. It does not emit Fleet wrappers, history, or transient RPC events. Concurrent external rewrites can invalidate tailing; detectable replacement, truncation, lag, or runtime loss is reported on stderr.
203
+ ## Runtime, data, and maintenance
132
204
 
133
- ## Runtime and local data
134
-
135
- The short-lived CLI connects to one private per-user runtime. On first operational use, Fleet verifies and materializes an immutable runtime release, then starts it in the background. A registered native service is preferred when present; service management is experimental and is not part of the seven-command beta interface.
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.
136
206
 
137
207
  Linux defaults:
138
208
 
139
209
  ```text
140
- Fleet state: ~/.local/state/pi-fleet/
141
- Materialized code: ~/.local/share/pi-fleet/releases/
142
- Runtime socket: $XDG_RUNTIME_DIR/pifleet-$UID/control.sock
143
- (or the system temporary directory when XDG_RUNTIME_DIR is absent)
144
- Pi sessions: Pi's normal ~/.pi storage or the exact path you selected
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
145
215
  ```
146
216
 
147
- `PIFLEET_STATE_ROOT` and `PIFLEET_APPLICATION_ROOT` can override Fleet-owned locations. A CLI invocation whose state root differs from an installed service fails immediately with repair guidance instead of connecting to the wrong database.
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.
148
220
 
149
- ## Uninstall and recovery
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.
150
222
 
151
- Before uninstalling, destroy agents you no longer want Fleet to manage:
223
+ Before uninstalling, destroy agents you no longer want pi-fleet to manage:
152
224
 
153
225
  ```bash
154
- pifleet list --human
155
- pifleet destroy AGENT_NAME
226
+ pifleet list
227
+ pifleet destroy NAME
156
228
  npm uninstall --global @elpapi42/pi-fleet
157
229
  ```
158
230
 
159
- Removing the npm package does not delete Pi sessions, Fleet's SQLite state, materialized runtime releases, or an already-running runtime/service. This protects durable agents from package-manager changes. Reinstalling the same or a compatible version reconnects to the preserved state.
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.
160
232
 
161
- There is intentionally no automatic self-update, telemetry, remote transport, or npm `postinstall` service registration. Database migrations are forward-only; installing an older binary after a newer schema migration is not a supported rollback strategy.
233
+ ## Beta status
162
234
 
163
- For support, include:
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.
164
236
 
165
- ```bash
166
- node --version
167
- pifleet --version
168
- pifleet list
169
- pifleet status AGENT_NAME
170
- ```
171
-
172
- Do not include API keys, message contents, session contents, or private paths unnecessarily. Report reproducible issues at <https://github.com/elpapi42/pi-fleet/issues>.
237
+ Known limits:
173
238
 
174
- ## Beta limitations
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.
175
246
 
176
- - Release validation currently covers Linux x64 only.
177
- - Actual logout and host reboot recovery remain unvalidated.
178
- - launchd and macOS descendant containment remain unvalidated.
179
- - Native service install/repair/uninstall exists internally but has no supported public UX yet.
180
- - Runtime upgrades are not automatic; active runtimes are not silently replaced.
181
- - Session tails cannot promise exactly-once behavior under arbitrary external mutation.
182
- - A promptless missing session path may remain physically unmaterialized until Pi writes conversation content, following native Pi behavior.
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>.
183
248
 
184
249
  ## Development
185
250
 
186
251
  ```bash
187
252
  npm ci
253
+ npm run audit:production
188
254
  npm run typecheck
189
255
  npm run lint
190
256
  npm run format:check
191
257
  npm test
258
+ npm run test:faults
192
259
  npm run build
193
260
  npm run test:package
194
261
  npm run test:platform
262
+ npm run test:soak
195
263
  ```
196
264
 
197
- See [`IMPLEMENTATION_PLAN.md`](./IMPLEMENTATION_PLAN.md) for architecture, completed evidence, and remaining release gates.
198
-
199
265
  ## License
200
266
 
201
267
  MIT © elpapi42
@@ -6,7 +6,7 @@ const isSupported = (major === 22 && minor >= minimumNode22Minor) || major === 2
6
6
 
7
7
  if (!isSupported) {
8
8
  process.stderr.write(
9
- `Pi Fleet runtime requires Node ^22.19.0 or ^24.0.0; found ${process.versions.node}. Run the installer repair operation with a supported Node executable.\n`,
9
+ `pi-fleet runtime requires Node ^22.19.0 or ^24.0.0; found ${process.versions.node}. Run the installer repair operation with a supported Node executable.\n`,
10
10
  );
11
11
  process.exitCode = 1;
12
12
  } else {