# ctask v0.2 Feature Spec — Session Traceability & Resumability ## Theme v0.1 = create and resume workspaces v0.2 = understand and continue workspaces later ## Scope Five deliverables: 1. Automatic session snapshot logging 2. Improved seeded CLAUDE.md with handoff instructions 3. `ctask doctor` 4. `ctask last` 5. `ctask delete` ## 1. Automatic Session Snapshot Logging ### Purpose When a developer returns to a workspace after hours or days, they need to immediately understand what happened last time — without relying on memory or manual note-taking. ### How it works ctask wraps the agent/shell launch so it can run logic before and after the session. **On session start:** 1. Create `.ctask/` directory in workspace if it doesn't exist 2. Capture a file manifest: relative path, size in bytes, and modification timestamp for every file in the workspace (excluding `.ctask/` itself) 3. Write manifest to `.ctask/manifest-start.json` 4. Append a session-start entry to `logs/sessions.log` **On session end (agent/shell process exits):** 1. Capture a second manifest using the same format 2. Diff against the start manifest to produce: files added, files modified (size or mtime changed), files deleted 3. Append a session-end entry to `logs/sessions.log` with the diff summary 4. Clean up `.ctask/manifest-start.json` (or keep for debugging — implementer's choice) 5. Exit with the child process's exit code ### Implementation change v0.1 uses `exec` to replace the ctask process with the agent. v0.2 must change this to spawn a child process and wait for it, so ctask can run post-session logic. This applies to `new`, `resume`, and `open`. Session snapshot logging runs for any command that launches an agent or shell session: - `ctask new` (when it launches into agent or shell) - `ctask resume` - `ctask open` - `ctask last` (delegates to `resume`) Session snapshot logging does **not** run for: - `ctask new --no-launch` (no session to capture) - `ctask list`, `ctask info`, `ctask archive`, `ctask doctor`, `ctask delete` On Unix: run the agent as a child process with stdin/stdout/stderr inherited, wait for exit. On Windows: same pattern using `os/exec` with `Cmd.Run()`. Do not use `exec` (process replacement) in v0.2. ### Session log format `logs/sessions.log` is a human-readable, append-only text file. ``` ── Session 2026-04-05 14:30:22 ── Agent: claude Mode: local Start: 2026-04-05 14:30:22 End: 2026-04-05 15:45:10 Duration: 1h 14m 48s Added: output/migration-plan.md output/schema.sql context/reference.md Modified: notes.md CLAUDE.md Deleted: (none) Notes updated: yes ──────────────────────────────── ``` ### Rules - The manifest captures only regular files, not directories - Ignore `.ctask/` contents when diffing - Ignore `task.yaml` changes (ctask updates this itself, not the agent) - Ignore `logs/sessions.log` changes (ctask's own logging would otherwise show as a modification every session) - "Modified" means: file present in both start and end manifests with a different size or mtime. This is a lightweight heuristic, not content hashing. - If the session is very short (< 5 seconds) and no files changed, still log it but with a note like "No changes detected" - If manifest capture fails for any reason, log the error and continue — never block the user from exiting - "Notes updated" is a simple boolean: did `notes.md` change between start and end? - `.ctask/manifest-start.json` is deleted after successful session-end logging. If post-session logging fails, keep it and log the error. ### Manifest format `.ctask/manifest-start.json`: ```json { "captured_at": "2026-04-05T14:30:22Z", "files": [ {"path": "notes.md", "size": 245, "mtime": "2026-04-05T14:30:20Z"}, {"path": "CLAUDE.md", "size": 512, "mtime": "2026-04-05T14:30:20Z"}, {"path": "task.yaml", "size": 310, "mtime": "2026-04-05T14:30:22Z"} ] } ``` ## 2. Improved Seeded CLAUDE.md ### Purpose Nudge the agent to leave a human-readable handoff in `notes.md` so the developer (or a future agent session) can understand what was accomplished and what remains. ### Change Update the seeded `CLAUDE.md` template to include the following instruction (in addition to existing workspace scope guidance): ```markdown ## Session Handoff Before ending a session, append a brief summary to notes.md with: - What was accomplished - Key decisions made - Open follow-ups or unfinished work - How to continue from here Keep it concise — a few bullet points is enough. This helps the developer (or a future session) resume without losing context. ``` ### Rules - This is advisory, not enforced. The agent may or may not follow it. - The automatic session snapshot (§1) provides the structural safety net regardless. - Do not add complex formatting requirements — the simpler the instruction, the more likely the agent complies. ## 3. `ctask doctor` ### Purpose Verify that ctask is correctly set up and help users diagnose common configuration problems. ### Command ``` ctask doctor ``` No arguments, no flags. ### Checks | Check | Pass condition | Fail message | |-------|---------------|--------------| | Workspace root exists | `CTASK_ROOT` directory exists and is writable | `Workspace root not found: . Create it with: mkdir ` | | Default agent on PATH | Configured agent command is found | `Agent command not found: . Install it or set CTASK_AGENT.` | | Status line helper exists | Status line script file exists at expected location | `Status line helper not found. Run ctask setup instructions at .` | | Claude Code status line configured | `~/.claude/settings.json` exists, contains a `statusLine` key with `type: "command"`, and the `command` value references a file that exists on disk | `Claude Code status line not configured or misconfigured. Add to ~/.claude/settings.json: ` | | Workspace root has workspaces | At least one workspace directory exists | `No workspaces found. Create one with: ctask new "my first task"` | ### Output format ``` ctask doctor ✓ Workspace root exists: ~/ai-workspaces ✓ Default agent found: claude ✗ Status line helper not found → Install it to: ~/.local/bin/ctask-statusline.sh ✓ Claude Code status line configured ✓ Workspaces found: 12 tasks (3 archived) 3 checks passed, 1 failed ``` Use ✓ and ✗ (or platform-safe equivalents if Unicode is unreliable on Windows cmd.exe). Provide actionable fix instructions for every failure. ### Rules - doctor never modifies anything — read-only - doctor should work even if ctask has never been used (no workspaces yet) - exit 0 if all checks pass, exit 1 if any fail - check paths using platform-appropriate logic (Windows vs Unix) ## 4. `ctask last` ### Purpose Instantly resume the most recently updated workspace without remembering its name. ### Command ``` ctask last [options] ``` ### Options | Flag | Short | Default | Description | |------|-------|---------|-------------| | `--shell` | | off | Open shell instead of agent | | `--agent` | `-a` | from task.yaml | Override agent command | ### Behavior 1. Scan all non-archived workspaces 2. Find the one with the most recent `updated_at` in `task.yaml` 3. Behave exactly like `ctask resume ` If no workspaces exist, print an error and exit 1. ### Examples ```bash # Resume most recent workspace ctask last # Open most recent workspace in shell ctask last --shell ``` ### Output Same as `resume` — launch banner, then agent or shell. ## 5. `ctask delete` ### Purpose Permanently remove a workspace directory when it's no longer needed. ### Command ``` ctask delete [options] ``` ### Options | Flag | Short | Default | Description | |------|-------|---------|-------------| | `--force` | `-f` | off | Skip confirmation prompt | | `--all` | `-a` | off | Include archived workspaces in query resolution | ### Behavior 1. Resolve workspace (same query rules as `resume`) 2. Print workspace path and contents summary (file count, total size) 3. Prompt for confirmation: `Delete ? This cannot be undone. [y/N]` 4. If confirmed (or `--force`), remove the entire workspace directory 5. Print confirmation message ### Output ``` ctask delete arch-notes Workspace: ~/ai-workspaces/general/2026-04-05_arch-notes Files: 8 (24 KB) Delete this workspace? This cannot be undone. [y/N] y [ctask] deleted: general/2026-04-05_arch-notes ``` ### Rules - Confirmation is required by default. `--force` skips it. - Delete removes the entire directory tree, not just ctask metadata. - Archived workspaces are excluded from query resolution unless `--all` is passed (consistent with other commands). - If the workspace is the most recently updated one, print a note: "This was your most recent workspace." - If `CTASK_WORKSPACE` is set and matches the resolved target (i.e., the user is inside an active ctask session targeting this workspace), refuse to delete and print: "Cannot delete the active workspace. Exit the session first." This check applies even with `--force`. ## Non-Goals for v0.2 - No terminal output recording or command history capture - No automatic agent-generated summaries (the CLAUDE.md nudge is advisory only) - No container mode (still deferred) - No `ctask summarize` command (the automatic snapshot replaces the need) - No manifest history / multiple snapshots per workspace (one start manifest is enough) ## Build Order 1. Change launch model from `exec` to child-process-and-wait (touches `new`, `resume`, `open`) 2. Manifest capture (start snapshot) 3. Session log writer (end snapshot + diff + append to `logs/sessions.log`) 4. Updated CLAUDE.md template 5. `ctask doctor` 6. `ctask last` 7. `ctask delete` 8. Testing and validation