diff --git a/docs/superpowers/plans/2026-05-08-v0.5.3-smoke-test-checklist.md b/docs/superpowers/plans/2026-05-08-v0.5.3-smoke-test-checklist.md new file mode 100644 index 0000000..5702076 --- /dev/null +++ b/docs/superpowers/plans/2026-05-08-v0.5.3-smoke-test-checklist.md @@ -0,0 +1,402 @@ +# v0.5.3 Manual Smoke-Test Checklist (WSL + Native Windows) + +**Branch:** `feat/v0.5.3-persistent-session-mode` +**Build artifact for WSL:** `dist/ctask-linux-amd64` (already produced by `just build-linux`) + +This checklist covers what the automated test suite cannot exercise: TTY + +tmux interaction, real workspace creation/launch, multi-terminal reattach. +Run each step in order; record PASS/FAIL inline as you go. + +--- + +## Setup + +### S1. Stage the binary on PATH inside WSL + +The `claude` agent is not installed in your `debian-dev` WSL distro, so for +the smoke tests we substitute `bash` as the agent via `--agent bash`. The +purpose of these tests is the ctask + tmux dispatch — the agent is just a +"thing that runs inside tmux." + +```bash +# Inside WSL (debian-dev): +mkdir -p ~/.local/bin +cp /mnt/c/Users/Warren/claude_tasks/ctask/dist/ctask-linux-amd64 ~/.local/bin/ctask +chmod +x ~/.local/bin/ctask +export PATH="$HOME/.local/bin:$PATH" +ctask --version # Expect: ctask v0.5.3 +which tmux && tmux -V # Expect: /usr/bin/tmux, tmux 3.5a (or similar) +``` + +If `~/.local/bin` is not already on PATH in your shell init, add `export PATH="$HOME/.local/bin:$PATH"` to `~/.bashrc`. + +### S2. Choose a smoke-test root + +```bash +export CTASK_ROOT=/tmp/ctask-053-smoke +mkdir -p "$CTASK_ROOT" +``` + +Using a temp root keeps your real workspaces untouched. Cleanup is one +`rm -rf` at the end. + +--- + +## Owner-create path (Step 3) + +### O1. Enable persistent mode and create a project + +```bash +export CTASK_SESSION_MODE=persistent +ctask new --project --agent bash ctask-053-smoke +``` + +**Expected:** + +- A line like `[ctask] created projects/2026-05-08_ctask-053-smoke` +- Banner lines: `[ctask] local :: ctask-053-smoke` and the workspace path +- A bash prompt appears (you are inside tmux + bash + the workspace's + `ctask-053-smoke/` project subdirectory) +- Status line indicates you're attached to the tmux session + +### O2. Detach without exiting + +Press `Ctrl-b d` (default tmux prefix). You should return to your outer +shell and see no error. + +### O3. Verify the tmux session is alive + +```bash +tmux ls +``` + +**Expected:** A line containing `ctask-projects-ctask-053-smoke-<6hex>`. + +PASS / FAIL: ___ + +--- + +## Passive reattach (Step 4) + +### P1. Reattach via resume + +```bash +ctask resume ctask-053-smoke +``` + +**Expected:** + +- Immediate reattach (sub-second). No "[ctask] adopting orphaned..." line. +- Same bash prompt as before. Scrollback intact (you can scroll up and see + the original banner). +- No new banner line is printed (passive reattach does not print one). + +### P2. Detach again + +`Ctrl-b d`. + +PASS / FAIL: ___ + +--- + +## Adopted reattach (Step 5) + +### A1. Simulate orphan: kill the heartbeating ctask process + +In a fresh outer shell (NOT inside the tmux session): + +```bash +pgrep -af 'ctask resume ctask-053-smoke' | head -5 +# Note the PID of the ctask process (the parent that owns the lease, NOT bash inside tmux). +# It is usually the most recent one. +pgrep -f 'ctask resume ctask-053-smoke' | xargs -r kill -9 +``` + +The tmux session itself stays alive (only the ctask process owning the +lease is killed). Verify: + +```bash +tmux ls # Expected: ctask-projects-ctask-053-smoke- still listed +``` + +Wait at least 60 seconds so the lease's last_heartbeat_at goes stale (the +threshold is 60s — see `internal/session/heartbeat.go:15`). + +### A2. Reattach — adoption should fire + +```bash +ctask resume ctask-053-smoke +``` + +**Expected:** + +- A line on stderr: `[ctask] adopting orphaned persistent session (previous owner exited without finalizing)` +- Then the user is reattached to the same bash session inside tmux. + +### A3. End the session and inspect the summary + +Inside the bash session: `exit` to leave bash. +Then: `Ctrl-b &` to confirm killing the tmux window, OR +`tmux kill-session -t ctask-projects-ctask-053-smoke-` from outside. + +Wait ~3 seconds (polling interval) for the foreground `ctask resume` to +detect session end and finalize. + +```bash +WS=$CTASK_ROOT/projects/2026-05-08_ctask-053-smoke +cat "$WS/.ctask/last-session-summary.json" | python3 -m json.tool 2>/dev/null \ + || cat "$WS/.ctask/last-session-summary.json" +``` + +**Expected fields present:** + +```json +{ + "end_reason": "tmux_session_ended", + "detected_via": "polling", + "session_ownership": "adopted", + "adopted_from_orphan_at": "2026-05-08T..." +} +``` + +PASS / FAIL: ___ + +--- + +## Non-TTY refusal (Step 6) + +### T1. Pipe stdin to break the TTY check + +```bash +echo "" | ctask resume ctask-053-smoke +``` + +**Expected:** A multi-line refusal message containing: +- `interactive terminal` +- `ssh -t ctask resume ` +- `ctask resume --direct` + +Exit code: 1. + +### T2. SSH-without-t equivalent (optional) + +If you have ssh server running on localhost: + +```bash +ssh localhost -- bash -lc "PATH=\$HOME/.local/bin:\$PATH CTASK_SESSION_MODE=persistent CTASK_ROOT=$CTASK_ROOT ctask resume ctask-053-smoke" +``` + +**Expected:** Same refusal message (no `-t` means no TTY allocation). + +PASS / FAIL: ___ + +--- + +## Nested tmux refusal (Step 7) + +```bash +TMUX=fake-tmux-env-value ctask resume ctask-053-smoke +``` + +**Expected:** Refusal with text containing: +- `cannot attach while already inside tmux` +- `ctask resume --direct` + +PASS / FAIL: ___ + +--- + +## --direct confirmation (Step 8) + +### D1. Recreate a tmux session for the workspace + +If you killed it during the adoption test, recreate via owner-create: + +```bash +ctask resume --agent bash ctask-053-smoke +# Detach with Ctrl-b d. +tmux ls # Expected: session listed again +``` + +### D2. Try opening with --direct + +```bash +ctask open --direct ctask-053-smoke +``` + +**Expected (interactive prompt):** + +``` +A persistent tmux session exists for this workspace: + ctask-projects-ctask-053-smoke- + +Opening a direct-mode shell may create conflicting workspace activity. +The recommended path is: + ctask attach ctask-053-smoke + +Continue with --direct anyway? [y/N] +``` + +Type `n` and press Enter. Expected: exits with `Error: canceled by user`. + +### D3. Confirm --direct then bypass + +Run again: + +```bash +ctask open --direct ctask-053-smoke +``` + +Type `y` and press Enter. Expected: the v0.4 active-session warning fires +(an EXISTING tmux session means there's an active lease too). Either +answer to that prompt is fine — the goal is just to confirm the --direct +prompt fired and the user can proceed past it. + +Detach / exit any shells you opened. + +PASS / FAIL: ___ + +--- + +## tmux missing — workspace NOT created (Step 9) + +This is the most important refusal: a missing tmux must not leave a +half-initialized workspace on disk. + +### M1. Hide tmux from PATH + +```bash +ORIG_PATH=$PATH +export PATH=$(echo "$PATH" | tr ':' '\n' | grep -v '/bin$\|/usr/bin' | paste -sd:) +# Verify tmux is gone: +which tmux && echo "ERROR: tmux still on PATH" # Should NOT print "ERROR..." +``` + +If your `~/.local/bin/ctask` is no longer on PATH after this, copy it +back: `cp $HOME/.local/bin/ctask ./ctask-temp && export PATH=$PWD:$PATH` +(or just use a full path below). + +### M2. Try `ctask new` with persistent mode + +```bash +ctask new --project --agent bash ctask-053-no-tmux +``` + +**Expected (refusal BEFORE workspace.Create):** + +``` +Error: ctask is configured for persistent sessions, but tmux is not installed. + +Install tmux: + Debian/Ubuntu/WSL: sudo apt install tmux + ... +``` + +### M3. Verify NO workspace was created + +```bash +ls "$CTASK_ROOT/projects/" 2>/dev/null +# Expected: empty or only the ctask-053-smoke directory from earlier — NO ctask-053-no-tmux +``` + +PASS / FAIL: ___ + +### M4. Restore PATH + +```bash +export PATH=$ORIG_PATH +which tmux # Expected: /usr/bin/tmux +``` + +--- + +## Native Windows refusal (Step 10) + +In a Windows PowerShell window (NOT WSL): + +```powershell +cd C:\Users\Warren\claude_tasks\ctask +go build -o ctask.exe . +$env:CTASK_SESSION_MODE = "persistent" +$env:WSL_DISTRO_NAME = $null # Make sure we're not pretending to be WSL +.\ctask.exe new --no-launch ctask-053-windows +``` + +**Expected:** + +``` +Error: ctask persistent mode requires tmux, which is not supported on native Windows. + +Recommended: + Run ctask from WSL and install tmux there: + sudo apt install tmux + +Or bypass persistent mode: + ctask new --direct +``` + +Exit code: 1. NO workspace created (verify under `%USERPROFILE%\ai-workspaces\`). + +### --direct under persistent on Windows + +```powershell +.\ctask.exe new --no-launch --direct ctask-053-win-direct +``` + +**Expected:** workspace created with one warning line: +`[ctask] warning: --direct bypassing persistent mode (no tmux session exists for this workspace)` + +Cleanup: + +```powershell +.\ctask.exe delete --force ctask-053-win-direct # if --force exists +# Or remove manually: +Remove-Item -Recurse -Force (Get-ChildItem -Path "$env:USERPROFILE\ai-workspaces\general" -Filter "*ctask-053-win-direct*").FullName +$env:CTASK_SESSION_MODE = $null +Remove-Item ctask.exe +``` + +PASS / FAIL: ___ + +--- + +## Doctor output (Step 11) + +In WSL with the smoke-test root still set: + +```bash +unset CTASK_SESSION_MODE +ctask doctor 2>&1 | grep -E "Session mode|tmux" +# Expected: [INFO] Session mode: direct (tmux not required) + +CTASK_SESSION_MODE=persistent ctask doctor 2>&1 | grep -E "Session mode|tmux" +# Expected: +# [INFO] Session mode: persistent +# [INFO] tmux found: tmux 3.5a (/usr/bin/tmux) +``` + +PASS / FAIL: ___ + +--- + +## Cleanup (Step 12) + +```bash +unset CTASK_SESSION_MODE +# Kill any leftover tmux sessions from smoke testing: +tmux ls 2>/dev/null | grep '^ctask-' | cut -d: -f1 | xargs -r -I{} tmux kill-session -t {} +# Wipe the smoke-test root: +rm -rf "$CTASK_ROOT" +unset CTASK_ROOT +# Optionally remove the WSL-staged binary: +rm -f ~/.local/bin/ctask +``` + +--- + +## Reporting back + +When complete, report PASS/FAIL for each labeled section back to me. If +all pass, I'll merge the branch to `main` and you can `just install` and +optionally `git tag v0.5.3`. If any fail, paste the exact output and I'll +investigate.