docs(v0.5.3): manual WSL smoke-test checklist for the user
This commit is contained in:
@@ -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-<hash> 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-<hash>` 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 <host> ctask resume <workspace>`
|
||||
- `ctask resume <workspace> --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 <workspace> --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-<hash>
|
||||
|
||||
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 <workspace> --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.
|
||||
Reference in New Issue
Block a user