From 3b6c3283106ffd16e7b5659178bf4dc82b73efae Mon Sep 17 00:00:00 2001 From: "Charlton D. Ho" Date: Sat, 4 Jul 2026 18:49:55 +0800 Subject: [PATCH] docs(workplan): sync WORKPLAN.md and P3 slices after P5b-2 COMPLETE (#139) Co-Authored-By: codex --- WORKPLAN.md | 15 ++++++++------- agents/P3_IMPLEMENTATION_SLICES.md | 16 ++++++++++++++++ 2 files changed, 24 insertions(+), 7 deletions(-) diff --git a/WORKPLAN.md b/WORKPLAN.md index fc75106..8239881 100644 --- a/WORKPLAN.md +++ b/WORKPLAN.md @@ -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 ` seam P5E1 shipped. -- **NL → `/agents bg` intent-gate workflow** — needs `background` workflow kind in `intent-gate.ts`. Can now emit `--backend ` 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 `. - **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**: diff --git a/agents/P3_IMPLEMENTATION_SLICES.md b/agents/P3_IMPLEMENTATION_SLICES.md index b986efa..69eafea 100644 --- a/agents/P3_IMPLEMENTATION_SLICES.md +++ b/agents/P3_IMPLEMENTATION_SLICES.md @@ -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 ` 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-`); 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 ` creates a detached background session (ActiveDetached state — server alive, no clients); `zellij -s run --name --cwd --close-on-exit -- node ` returns `terminal_`. 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`. 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.