docs: add v0.2 spec
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+302
@@ -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
|
||||
Reference in New Issue
Block a user