docs(v0.4): document --force, session lease, stale-workspace detection, and coexisting-session limitation

This commit is contained in:
2026-04-21 17:16:54 -04:00
parent 0e7d4a5717
commit 46c7ef2c5c
+89
View File
@@ -123,6 +123,7 @@ Resolves the workspace by query (exact directory name, exact slug, or case-insen
|------|-------|---------|-------------|
| `--shell` | | off | Open shell instead of agent |
| `--agent` | `-a` | from task.yaml | Override agent command |
| `--force` | | off | Skip active-session and stale-workspace warnings |
| `--container` | | off | Deferred to a future release |
**Examples:**
@@ -132,6 +133,7 @@ ctask resume auth-bug
ctask resume backup
ctask resume --shell auth-bug
ctask resume --agent aider auth-bug
ctask resume --force auth-bug
```
If multiple workspaces match, prints all matches and exits. If none match, prints an error.
@@ -155,6 +157,7 @@ Spawns a new subshell in the workspace directory. Does not modify the caller's s
| Flag | Short | Default | Description |
|------|-------|---------|-------------|
| `--all` | `-a` | off | Include archived workspaces in query resolution |
| `--force` | | off | Skip active-session and stale-workspace warnings |
**Examples:**
@@ -221,6 +224,7 @@ ctask last [flags]
|------|-------|---------|-------------|
| `--shell` | | off | Open shell instead of agent |
| `--agent` | `-a` | from task.yaml | Override agent command |
| `--force` | | off | Skip active-session and stale-workspace warnings |
**Examples:**
@@ -335,6 +339,91 @@ Configure ctask behavior with:
---
## Concurrency and safety
ctask v0.4 protects workspaces from conflicts when multiple sessions (or manual file edits) touch the same workspace.
### Session lease
Each active `ctask resume`, `open`, `last`, or `new` writes a lease file at `<workspace>/.ctask/session.json` identifying the ctask process, hostname, user, agent, mode, and a heartbeat timestamp. A background goroutine updates the heartbeat every 30 seconds.
On session start, if a fresh lease already exists (heartbeat within 60 seconds), ctask warns:
```
[ctask] This workspace has an active session:
Session: <id>
Host: <host>
Agent: <agent>
Started: <timestamp> (<elapsed> ago)
Last seen: <seconds> ago
Opening a second session may cause conflicts.
Continue anyway? [y/N]
```
If the user answers `y`, the second session proceeds **without writing its own lease** (see "Known limitation: coexisting sessions" below). If the lease is older than 60 seconds (crash, lost connection), ctask cleans it up silently and proceeds.
### Metadata write lock
All ctask-owned file writes (`task.yaml`, `logs/sessions.log`, `.ctask/session.json`, `.ctask/manifest-start.json`, `.ctask/last-session-summary.json`) are serialized through `<workspace>/.ctask/write.lock`. The lock is held for the duration of one write only. If the lock cannot be acquired within 2 seconds, the write is skipped with a warning rather than blocking.
### Stale-workspace detection
On session start, ctask compares the current workspace state against the end-state recorded by the previous session's summary. If anything changed outside a ctask session (another machine, manual edits), ctask warns:
```
[ctask] Workspace modified since last session ended:
Last session: <timestamp> (<host>, <agent>)
Modified since then:
notes.md (modified)
output/report.md (new file)
These changes were not made during a ctask session.
Review before continuing? [Y/n]
```
Press Enter (or `y`) to proceed. Press `n` to exit without launching.
This check is skipped silently for workspaces that have never completed a v0.4 session (no `last-session-summary.json`).
### Session handoff summary
At end of session, ctask writes `<workspace>/.ctask/last-session-summary.json` containing:
- `session_id`, `hostname`, `agent`, `mode`
- `started_at`, `ended_at`, `duration_seconds`
- `files_added`, `files_modified`, `files_deleted`
- `notes_updated`
- `end_manifest` (snapshot of workspace file list at session end -- used by the stale-workspace detector)
The next session prints a short orientation banner from this file:
```
[ctask] local :: api-cleanup
[ctask] ~/ai-workspaces/general/2026-04-21_api-cleanup
[ctask] Last session: 2026-04-21 14:30-15:45 (warren-desktop, claude)
[ctask] Changed: notes.md, output/plan.md
```
### `--force`
`--force` on `resume`, `open`, and `last` suppresses both the active-session warning and the stale-workspace warning. It does **not** disable the metadata write lock or the session summary -- those are always active.
Use `--force` only for automation where the human has already decided to proceed.
### Known limitation: coexisting sessions
When the user confirms "Continue anyway?" on an active-session warning (or passes `--force`), the second session runs **without writing its own lease**. This keeps the lease model simple (one lease file per workspace), but has two consequences:
1. A third session attempt will only see the original lease. The second (coexisting) session is invisible to lease-based detection.
2. If the original session exits and removes its lease before the coexisting session finishes, the coexisting session is unprotected for its remaining lifetime.
The metadata write lock still serializes all ctask-owned file writes regardless of session count, so no state corruption can occur. If you need stronger guarantees, exit the existing session before starting another one.
---
## Exit Codes
| Code | Meaning |