# PRD — ezpn v0.10.0: Stability, Automation & Discoverability

**Status:** Draft → Approved
**Owner:** @subinium
**Target release:** v0.10.0 (no public 1.0 commitment until this milestone closes)
**Tracking milestone:** [v0.10.0](https://github.com/subinium/ezpn/milestone) (single milestone — no version bumps in between)

---

## 1. Problem

ezpn v0.9.0 ships the headline grid-splitting UX and a daemon/client architecture, but a thorough audit against tmux exposes three classes of gaps that block ezpn from being a credible **"supertmux"** replacement:

1. **Resource hygiene gaps that tmux solved years ago** — slow-client write backpressure can stall the daemon main loop, scrollback has no `clear-history` and no per-pane bound, snapshot encoding runs synchronously on the main thread, and several maps/threads are not garbage-collected when panes close. A user running ezpn for a week on real workloads will hit RSS bloat, intermittent freezes, or thread leaks before they hit any feature gap.
2. **No scripted-input or event-stream API** — `send-keys`, hooks, and a control-mode-style event subscription are table stakes for editor integrations, AI agents, and CI workflows. Without them, ezpn cannot be driven by anything other than a human at a keyboard.
3. **Discoverability deficit relative to modern competitors** — tmux's own pain (cryptic `#{?cond,a,b}` formats, 40 prefix combos to memorize, no command palette) is the single biggest lever a modern alternative has. ezpn currently inherits the "memorize the keymap" model with no contextual hints, no fuzzy command palette, and no user-defined keybindings.

We are deliberately holding the version at 0.x until **all** of the above is fixed. v0.10.0 is the cut where ezpn becomes safe to recommend over tmux for daily use.

---

## 2. Goals (in priority order)

1. **Zero known resource leaks or main-loop stall paths.** Daemon survives a 7-day soak with bounded RSS, no orphaned threads, no zombie children.
2. **Scriptable.** Anything a human can do interactively (split, send input, navigate, copy) can also be done over IPC, and the daemon emits structured events any external client can subscribe to.
3. **Discoverable.** A first-time user can find every command without reading the README, via a fuzzy command palette and contextual key hints.
4. **Customizable.** Power users can rebind keys via TOML without recompiling.
5. **Feature-parity floor with tmux on `break-pane`/`join-pane`, regex copy-mode search, and named paste buffers.**

## 3. Non-Goals (deferred to v0.11+ or later)

- Automatic session persistence across reboots / `tmux-resurrect`-style continuum (kept manual via `--restore` for now)
- Mosh-like resilient SSH transport
- WASM plugin runtime
- OSC 133-based semantic scrollback
- Memory-budgeted scrollback (`--scrollback-mem 256MB`) — v0.10 ships line-count cap only
- Status bar `#()` shell-substitution DSL — v0.10 ships declarative segments only

These are tracked in a separate v2.0 vision doc and are not required for v0.10.0 release.

---

## 4. Audience & Use Cases

| Persona | What v0.10.0 unlocks |
|---|---|
| **Daily tmux user** considering switching | Stable long-running sessions, no RSS surprises, familiar `break-pane`/regex search |
| **AI/agent integrator** (Claude Code, scripted setups) | `send-keys` + event stream lets agents drive ezpn deterministically |
| **Power user** with a 200-line tmux.conf | Custom keymap in TOML; hooks for workflow automation |
| **Newcomer** | Command palette + contextual key hints; doesn't need to memorize |

---

## 5. Scope — 13 grouped initiatives

Grouped into 4 categories. Each row maps to one GitHub issue and one SPEC under `docs/spec/v0.10.0/`.

### A. Stability & Resource Hygiene (5 issues)

| # | Initiative | Severity origin |
|---|---|---|
| 01 | Daemon I/O resilience — slow-client write backpressure + IPC thread pool/timeout | P1 #1, P1 #2 |
| 02 | Scrollback memory hygiene — per-pane `history-limit` + `clear-history` IPC + line-count cap enforcement | P2 #3 |
| 03 | Lifecycle GC — `restart_state` cleanup, PTY reader join, `kill_all_inactive` drain | P2 #4, P2 #5, Nit #10 |
| 04 | Snapshot pipeline async — off-main-thread gzip+bincode, detach debounce | P2 #6 |
| 05 | Render-loop micro-perf — drop `track_dec_modes`, bound `wake_rx`, `tabs` → `VecDeque` | P2 #7, P2 #8, Nit #9 |

### B. Automation & Scripting (3 issues)

| # | Initiative |
|---|---|
| 06 | `send-keys` IPC + CLI command (the foundation for all scripted input) |
| 07 | Event subscription stream over `ezpn-ctl` (`-CC`-equivalent for editors / agents) |
| 08 | Hooks system — before/after-* for the 10 highest-value events (pane-died, client-attached, layout-changed, etc.) |

### C. UX & Discoverability (3 issues)

| # | Initiative |
|---|---|
| 09 | Custom keymap in TOML — user-defined key tables (root / prefix / copy-mode) |
| 10 | Command palette — fuzzy search across sessions, panes, windows, and commands |
| 11 | Discoverable UI — opt-in contextual key-hint mode-line + declarative status-bar segments |

### D. Feature parity (2 issues)

| # | Initiative |
|---|---|
| 12 | `break-pane` / `join-pane` — move panes between tabs / sessions |
| 13 | Copy-mode upgrades — regex search, named paste buffers, emacs key table |

---

## 6. Success Metrics & Release Criteria

v0.10.0 ships when **all** of the below are green:

### Functional
- All 13 SPECs marked `Done`, with their acceptance criteria checked off.
- `cargo test` and `cargo clippy --all-targets -- -D warnings` clean.
- Manual smoke test: tmux's official "Getting Started" walkthrough executable on ezpn end-to-end.

### Performance / stability gates
- **7-day soak**: 4 panes running `yes | head -c $((1<<30))` repeatedly, daemon RSS drift < 50 MB over 7 days.
- **Slow-client test**: `pv -L 100` consuming the client socket; daemon main loop responsiveness (median latency to local input) stays < 16 ms.
- **History-limit**: `clear-history` reduces per-pane vt100 RSS by ≥ 95% within 100 ms.
- **Thread budget**: `ps -o nlwp` on daemon stays constant across 1000 `ezpn-ctl` invocations (no thread leak).
- **Snapshot debounce**: rapid attach/detach (10 cycles in 1 second) triggers ≤ 2 snapshot writes.

### API / scriptability gates
- `ezpn-ctl send-keys --pane N -- 'echo hello\n'` reaches the target pane.
- `ezpn-ctl events --subscribe pane,client,layout` emits NDJSON events to stdout, schema documented.
- A 50-line TOML keymap can fully override prefix-mode bindings; `ezpn config check` validates without daemon restart.

### UX gates
- Command palette (`prefix + p` default) reachable in ≤ 1 keystroke from any mode.
- Contextual key hints render < 5 ms after mode change, can be toggled off without restart.

---

## 7. Risks & Mitigations

| Risk | Mitigation |
|---|---|
| Backpressure refactor changes wire format → breaks attached clients during dev | Bump protocol version; reject mismatched clients with a clear error; ship daemon + ezpn-ctl together. |
| Custom keymap TOML schema gets locked in too early | Ship as `[keymap.experimental]` table; document that pre-1.0 schema may break. |
| Hooks system invites users to write blocking shell-outs that stall the daemon | Run hook commands in a worker thread with a 5 s timeout; document the contract. |
| Command palette + fuzzy matcher adds dependency surface | Use `nucleo-matcher` (already in zellij ecosystem, audited) — add to `deny.toml` allowlist. |
| 13 issues in one milestone is large | Strong PR/merge cadence (target: ≤ 3 days per issue, parallel branches per category). Each SPEC has its own acceptance criteria so progress is incremental. |

---

## 8. Out of scope, explicitly

- **Public 1.0 commitment.** v0.10.0 is the *internal* "are we tmux-credible yet" cut. 1.0 happens after a quiet period of dogfooding.
- **Breaking config changes.** Existing `~/.config/ezpn/config.toml` keeps working; new options are additive.
- **macOS-only or Linux-only features.** Everything must work on both.

---

## 9. Open questions

1. Should `clear-history` also drop the on-disk snapshot blob for that pane, or only in-memory? (Default proposal: in-memory only; explicit flag for disk.)
2. Hooks: shell-out string contract, or structured action enum? (Default proposal: shell string for v0.10, action enum tracked for v0.11.)
3. Command palette: fuzzy backend choice — `nucleo-matcher` vs `fuzzy-matcher`. (Default proposal: `nucleo-matcher`.)

These will be resolved inside the relevant SPECs.

---

## 10. References

- Audit reports that produced this scope: see meeting notes and `docs/spec/v0.10.0/00-audit-summary.md` (to be added).
- tmux issues that motivate the perf work: [tmux #4029](https://github.com/tmux/tmux/issues/4029), [#3194](https://github.com/tmux/tmux/issues/3194), [#4859](https://github.com/tmux/tmux/issues/4859).
- Modern competitor reference: [Zellij features](https://zellij.dev/features/).
