Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 8 additions & 7 deletions WORKPLAN.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,18 @@ the source of truth; older entries in the chain are `superseded`.

## Current state

**P5E1 backend selector COMPLETE** (PR #137, commit `8e41670`). **P5d cmux-control COMPLETE** (PRs #126, #128, #130, #131, #132) + **P5+ orphan reaper** bug fix merged (#134). **P5d + P5E1 closed; no next slice decided.**
**P5b-2 zellij-terminal backend COMPLETE** (PR #139, commit `3c6e6b8`). **P5E1 backend selector COMPLETE** (PR #137, `8e41670`). **P5d cmux-control COMPLETE** (PRs #126, #128, #130, #131, #132) + **P5+ orphan reaper** bug fix merged (#134). **P5d + P5E1 + P5b-2 closed; no next slice decided.**

- Chain head: `20260704-083722-post-merge-sync-p5e1-backend-selector-co-64a1`
- Chain head: `20260704-104711-post-merge-sync-p5b-2-zellij-terminal-ba-edce`
- Status: active
- Revises: `20260704-054011-post-merge-sync-p5d-cmux-control-complet-7ea6`
- Tags include: `canonical-workplan`, `workplan`, `p5e1`, `p5e1-complete`, `backend-selector`, `post-merge-sync`, `roadmap`, `p5b-next`
- Summary: **Post-merge sync — P5E1 backend selector COMPLETE (#137).** P5d + P5E1 closed; next natural: P5b alternative backends.
- Revises: `20260704-083722-post-merge-sync-p5e1-backend-selector-co-64a1`
- Tags include: `canonical-workplan`, `workplan`, `p5b`, `p5b-2`, `p5b-2-complete`, `zellij`, `zellij-terminal`, `terminal-backend`, `post-merge-sync`, `roadmap`, `p5b-3-next`
- Summary: **Post-merge sync — P5b-2 zellij-terminal backend COMPLETE (#139).** P5d + P5E1 + P5b-2 closed; next natural: wezterm/headless backends or NL→`/agents bg` intent-gate.

### Open follow-ups (none decided; details in canonical episode)
- **P5b alternative terminal backends** — zellij/wezterm/headless. Next natural; now cleanly testable from the CLI via the `--backend <name>` seam P5E1 shipped.
- **NL → `/agents bg` intent-gate workflow** — needs `background` workflow kind in `intent-gate.ts`. Can now emit `--backend <name>` once an NLP mapping is added.
- **P5b-3 wezterm-terminal** / **P5b-4 headless** — same pattern as zellij; the spike/plan/implement/review workflow is now proven for a third backend. Wezterm is the next analog (GUI terminal with a CLI).
- **`zellij-control` extension** — feasible (the spike confirmed `action send-keys`/`dump-screen` cover the tmux-control surface); separate slice.
- **NL → `/agents bg` intent-gate workflow** — needs `background` workflow kind in `intent-gate.ts`; can emit `--backend <name>`.
- **P4R-PROJ Project Background Agents** — deferred (needs disk-backed trust reader).
- **Persistent per-project default backend** — still deferred (needs trust reader); P5E1 is per-launch only.
- **P5+ orphan reaper follow-ups**:
Expand Down
16 changes: 16 additions & 0 deletions agents/P3_IMPLEMENTATION_SLICES.md
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,22 @@ Completed and merged:
- **Fix**: post-launch patch writes `ownerHandle` + `ownerBackendName` on the reservation; reaper now uses an `isAlive(reservation)` seam; 15s status poll also calls the reaper so orphans are caught in the *currently-open* session within 15s.
- **Commit**: `d4c1bd6` (standalone PR, cherry-picked from an in-flight branch — fix was independent of any open slice).
- **Review cycle**: 4 codex rounds. R0–R2 NEEDS REVISION → R3 READY-TO-MERGE → R4 READY-TO-MERGE (final consensus).

### P5b-2 zellij-terminal backend (COMPLETE — single slice MERGED via PR #139, commit `3c6e6b8`)
- Third `TermBgBackend` (`zellij-terminal`); `/agents bg --backend zellij scout task` launches agents in detached zellij sessions. Mirrors tmux-terminal/cmux-terminal structure 1:1.
- **Why**: P5b alternative backends is the next-natural follow-on; zellij is the closest analog to tmux/cmux. The `--backend <name>` selector (P5E1) makes every new backend cleanly testable from the CLI.
- **Single-slice ladder (MERGED)**:

| Slice | Objective | Primary files | Tests | Status | Commit |
|---|---|---|---|---|---|
| `P5b-2` | zellij-terminal backend: `launch`/`kill`/`isAlive`/`list`/`isAvailable`; two-step detached launch (`attach -b` creates detached session, then `-s run` adds the worker pane); windowId = session name (`pi-zellij-<runId>`); preference: 0 (cmux's 10 still auto-wins). `agents/lib/bg-terminal.ts` + `agents/index.ts` + `tmux-terminal/` + `cmux-terminal/` UNCHANGED (REQ-10). | `zellij-terminal/{index.ts, lib/{constants,exec,zellij-backend,resolve-worker-path,path-validate,redact-error,shell-escape}.ts, README.md}`, `zellij-terminal/test-fixtures/{test-zellij-backend,test-extension,test-real-zellij-smoke,run-zellij-tests}.*`, `zellij-terminal/docs/cli-spike-output.txt`, `agents/docs/P5B2_ZELLIJ_TERMINAL_PLAN.md` | 33 unit (fake executor + fake attachSpawner) + 3 UNGUARDED-IN-CI real smoke | **MERGED (PR #139)** | `3c6e6b8` |

- **The two-step detached launch (load-bearing design)**: `zellij attach -b <name>` creates a detached background session (ActiveDetached state — server alive, no clients); `zellij -s <name> run --name <pane> --cwd <cwd> --close-on-exit -- node <worker> <manifest>` returns `terminal_<id>`. The CLI spike (`zellij-terminal/docs/cli-spike-output.txt`, zellij 0.44.3) is the verified contract.
- **Spawn-fix journey (PR review caught a bug the plan review couldn't)**: the original `spawn({ detached: true, stdio: "ignore" }).unref()` did NOT create a session. Three failed approaches: (1) spawn+detached+stdio:ignore+unref → no session; (2) execFile default pipe stdio → hangs (64KB pipe-buffer deadlock); (3) `spawn("sh", ["-c", ...])` → security violation (REQ-9). Root cause: the spike's working bash `&` used /dev/null stdio (writes discarded → zellij exits ~2s, session persists). Fix: `await execFileP("zellij", ["attach","-b",name], { stdio: "ignore", timeout: 6000, env })` — argv-only, /dev/null stdio, awaited.
- **Contracts honored**: REQ-1..2 (registers "zellij" backend; preference: 0), REQ-3 (isAvailable treats exit 1 + "No active zellij sessions found." as healthy), REQ-4..5 (two-step launch; agentName kept out of argv; `--name` derived; `--` terminator), REQ-6 (kill-session idempotent; delete-session -f zombie fallback), REQ-7 (isAlive catches + returns false, matches tmux/cmux), REQ-8 (list parses list-sessions -s), REQ-9 (argv-only, no shell; grep guard returns 0), REQ-10 (no agents/tmux/cmux source changes), REQ-13 (real smoke UNGUARDED-IN-CI).
- **Review trail (codex via cmux, gpt-5.5 high)**: Plan R1 (3 blockers) → R2 (2 carry-overs) → R3 (approve-with-nits, 0 blockers); PR R1 (1 spawn-fix blocker) → R2 (1 stale-checkout) → R3 (approve-with-nits, 0 blockers; 2 stale-comment nits fixed + amended).
- **Stats**: 15 files, +2101 lines.
- **Plan**: `agents/docs/P5B2_ZELLIJ_TERMINAL_PLAN.md` (468 lines, executor-ready Appendix B, 3-pass approved).
- **Process lesson**: reaper error-tolerance is a footgun — when `isAlive` throws, the reaper treats as "alive" (correct for production safety) but it also swallows `ReferenceError` from missing imports (NOT correct — that's a code bug). Caught in codex v3 review.
- **Internal API change**: `isAlive` seam is now `(reservation: BgReservation) => boolean | Promise<boolean>`. Production callers use `buildReaperIsAlive` from `agents/index.ts`.
- **Post-launch patch is best-effort**: an `updateBgReservationOwner` failure leaves the slot active and the reaper falls back to age-only. Not user-facing, but worth flagging if anyone is debugging a stuck slot.
Expand Down
Loading