docs: add v0.2 spec

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-06 10:05:27 -04:00
parent 69c487cf79
commit f967064331
5 changed files with 3603 additions and 0 deletions
+302
View File
@@ -0,0 +1,302 @@
# 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: <path>. Create it with: mkdir <path>` |
| Default agent on PATH | Configured agent command is found | `Agent command not found: <cmd>. 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 <doc link>.` |
| 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: <example>` |
| 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 <that-workspace>`
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 <query> [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 <path>? 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