a5e508bcb6
Update notes.md with the v0.5.1 Linux portability baseline (commits7a7b249,1033072): WSL-native validation passed, install.sh works, ctask doctor recognizes the Linux statusline helper, the cross-built Linux binary is statically linked, and WorkspacePath was removed from new task.yaml metadata. Add load-bearing notes for the new invariants (CGO_ENABLED=0, install script does not modify shell config) and a "Next: v0.5.2" pointer. Also check in v0.5.2-spec.md so the workspace-retrieval round has the same on-disk durability as the prior specs.
278 lines
23 KiB
Markdown
278 lines
23 KiB
Markdown
# ctask — Session Handoff Notes
|
|
|
|
Last touched: 2026-05-07 (after v0.5.1 Linux baseline merge). Pause before starting v0.5.2.
|
|
|
|
## Where we are
|
|
|
|
**v0.5.1 is shipped on `main` and installed locally.** v0.5 added nested project structure (project subdir scaffolding, `launch_dir`-driven cd into the subdir, default discovery including `$CTASK_ROOT/projects/`). v0.5.1 is a tiny follow-up that fixes a UTC-date confusion surfaced during v0.5 smoke testing.
|
|
|
|
- Version string: `v0.5.1` (see `cmd/root.go`)
|
|
- Branch: `main`
|
|
- Remote: none (local-only, intentional — see `CLAUDE.md`)
|
|
- Tests: all pass across 7 packages (`go test ./... -count=1`)
|
|
- `go vet ./...` clean, `go build ./...` clean
|
|
- Installed at `%LOCALAPPDATA%\ctask\bin\ctask.exe` via `just install` — reflects both v0.5 and v0.5.1
|
|
- `ctask doctor` now reports 5 pass/fail checks + 2 seed-directory checks + 1 `CTASK_PROJECT_ROOT` check (all three-state)
|
|
|
|
### What v0.4 delivered (still true, unchanged)
|
|
|
|
Workspace concurrency protection — session lease with heartbeat (Layer 1), metadata write lock (Layer 2), stale-workspace detection (Layer 3), session handoff summary (Layer 4). `--force` flag on `resume`/`last`/`open`. `WriteMetaLocked`, `LaunchOpts.Force`, `Preflight`. All unchanged in v0.5.
|
|
|
|
### What v0.4.1 delivered (still true, unchanged)
|
|
|
|
Correctness and polish: `config.SearchRoots()` multi-root discovery; two-depth `scanWorkspaces` (flat + category, first-match-wins); nested-git documentation; doctor seed-dir three-state checks; archive active-session warning with non-TTY refuse; provisional-cleanup exit-code gate. Still load-bearing — see "From v0.4.1" section below.
|
|
|
|
### What v0.5 delivered
|
|
|
|
Theme: **separate workspace management from project code**. `--project` now scaffolds a project subdirectory and session commands `cd` into it. Twelve commits on `main` (`175fbb0..8130a68`).
|
|
|
|
1. **`launch_dir` field in `TaskMeta`** (`175fbb0`)
|
|
- New `LaunchDir string` with `yaml:"launch_dir,omitempty"` — empty for tasks and pre-v0.5 projects, defaults to the project slug for new projects.
|
|
- Omitempty keeps on-disk task.yaml clean for backward compatibility.
|
|
2. **`workspace.ResolveLaunch` helper** (`dcb1610`)
|
|
- Converts a relative `launch_dir` into an absolute child-cwd with three outcomes:
|
|
- Valid dir → return absolute path, no warning, no error.
|
|
- Missing path (`os.IsNotExist`) or path-is-a-file → return `(wsDir, warning, nil)` so the caller warns and falls back.
|
|
- Absolute path, `..`-escape, or any non-`IsNotExist` stat error (permission, ENOTDIR, invalid name) → return `("", "", error)` — caller must surface.
|
|
- This asymmetry is deliberate — masking a permission error as a warning fallback would silently strip launch-dir semantics.
|
|
3. **Project subdirectory scaffolding** (`7cfafdc`)
|
|
- `ctask new --project` creates an empty subdir named after the **final suffixed slug** (so `dup-2` collisions produce matching `dup-2/` subdir).
|
|
- ctask does not seed anything inside the subdir — the user places their own CLAUDE.md, source code, project configuration.
|
|
- Task workspaces are completely unchanged — no subdir, no `launch_dir`.
|
|
4. **`CTASK_LAUNCH_DIR` env var** (`509a6d6`)
|
|
- Added as a 7th arg to `config.EnvVars`. All three cmd callers (`new`, `resume`, `open`) pass `ws.Meta.LaunchDir`.
|
|
5. **Session launch routed through `LaunchDir`** (`103f2cd`)
|
|
- `LaunchOpts.LaunchDir` added. `session.Run` calls `ResolveLaunch` before banner/exec, prints any warning to stderr, aborts on security error, and passes the absolute path to `shell.ExecAgent` / `shell.ExecShell` as the child's working directory.
|
|
- Banner gains a `[ctask] project dir: <name>/` line when `launch_dir` is set.
|
|
- Lease, manifest, heartbeat, and summary scope stays the **workspace root** — only the child's cwd changes.
|
|
6. **`ctask info` shows launch fields** (`cdff7f3`)
|
|
- For workspaces with `launch_dir` set, info prints `Launch dir:`, `Launch path:`, and `Dir exists: yes|no` (via direct `os.Stat`, not via `ResolveLaunch` — info is a display command, not a launch command).
|
|
7. **`SearchRoots` default fallback** (`47430a1`)
|
|
- When `CTASK_PROJECT_ROOT` is unset, `SearchRoots()` now appends `$CTASK_ROOT/projects/` so default-location projects are findable from any shell (resolves the v0.4.1 env-var scoping footgun from the previous follow-up list).
|
|
- Dedupe in `scanAllRoots` prevents duplicate results when the same workspace is reachable via both the depth-2 scan under `CTASK_ROOT` and the explicit `$CTASK_ROOT/projects/` search root.
|
|
8. **Doctor `CTASK_PROJECT_ROOT` check** (`70bd167`)
|
|
- Three-state, matching the `checkSeedDir` pattern: `[INFO]` when unset (points at `$CTASK_ROOT/projects/`), `[INFO]` with user-scope advisory when set+exists, `[FAIL]` when set but missing. Only FAIL increments the failure counter.
|
|
- Wording is advisory ("recommended: set at user scope…"), not prescriptive.
|
|
9. **Project CLAUDE.md template rewrite** (`cdf1c55`)
|
|
- Adds a "Workspace Structure" section explicitly describing the root-vs-subdir split.
|
|
- Keeps the "Git" section from v0.4.1, now with an explicit mention that the project subdir is tracked by the root repo.
|
|
10. **Status line helpers show effective launch path** (`0976dce`)
|
|
- Both `.sh` and `.ps1` build `DISPLAY_PATH = $CTASK_WORKSPACE + (CTASK_LAUNCH_DIR if set)`. When `CTASK_LAUNCH_DIR != CTASK_TASK`, the tag becomes `|project:<launch_dir>` (user-overridden launch directory).
|
|
11. **Docs updated** (`82c9445`)
|
|
- `docs/commands.md`: workspace-layout diagram, `launch_dir` semantics (default, override, fallback vs error), `CTASK_LAUNCH_DIR` env var, doctor example with new INFO line, Query Resolution default-discovery paragraph.
|
|
12. **Version bump `0.4.1` → `0.5.0`** (`8130a68`).
|
|
|
|
### What v0.5.1 delivered
|
|
|
|
Two rounds shipped under the v0.5.1 tag: **wall-clock date for user-facing surfaces** (`a162aec`, `a11d48b`) and **Linux portability baseline** (`7a7b249`, `1033072`).
|
|
|
|
#### Round 1 — date fix (a162aec, a11d48b)
|
|
|
|
- **Bug:** workspace directory names used UTC date, so at 20:22 EDT on April 22 a new workspace was named `2026-04-23_foo`. Confusing in file explorer, `ctask list`, and `ctask info`.
|
|
- **Fix:** `internal/workspace/create.go` now uses `time.Now()` (local) for the directory-prefix date and the `YYYYMMDD-HHMMSS` ID. `cmd/info.go` formats `Created` / `Updated` / `Archived` with `.Local()`.
|
|
- **Stored timestamps still UTC.** `task.yaml` `CreatedAt` / `UpdatedAt` / `ArchivedAt`, session logs, lease, manifest, and summary all continue to store UTC. Only user-facing surfaces (directory prefix + info display) switched.
|
|
- **Regression guards:** `TestCreateDirectoryPrefixUsesLocalDate` and `TestInfoFormatsTimestampsInLocalZone` enforce both invariants.
|
|
|
|
#### Round 2 — Linux portability baseline (7a7b249, 1033072)
|
|
|
|
- **Build targets** (`justfile`): `build-linux`, `build-windows`, `build-all` output to `dist/`. Both cross-targets force `CGO_ENABLED=0` so the artifact is pure-Go statically linked regardless of build host (a native Linux build otherwise defaults to `CGO_ENABLED=1` and links against host glibc).
|
|
- **POSIX install scripts** (`scripts/install.sh`, `scripts/uninstall.sh`): mirror the `.ps1` UX. Default install dir `~/.local/bin`, optional override arg, PATH check warns with the right shell snippet (zsh / bash / fallback) — the script does NOT modify shell config. Statusline helper `ctask-statusline.sh` ships alongside the binary; the `.ps1` helper is intentionally not installed on Linux. Workspace data is preserved on uninstall.
|
|
- **`.gitignore`** now covers `ctask`, `ctask-*`, `dist/` (in addition to `*.exe`).
|
|
- **`WorkspacePath` removed from `TaskMeta`.** The audit (`audit-report.md`) confirmed the field was write-only with no production readers — it persisted an absolute Windows path into `task.yaml` that would have been misleading on cross-OS shares. Existing `task.yaml` files with `workspace_path` continue to load (Go's YAML unmarshal silently ignores unknown fields). `TestMetaTypeMissingDefaultsToTask` keeps the legacy YAML literal in its fixture as a backward-compat regression guard.
|
|
- **Validation:** Windows `go test ./...` green across all 7 packages; cross-compile produces ELF x86-64. **WSL-native validation passed:** `go test ./... -count=1` green; `just build-linux` produces a `statically linked` ELF (`ldd` reports `not a dynamic executable`); `./scripts/install.sh` installs to `~/.local/bin/ctask` and registers the statusline helper; `ctask doctor` recognizes the Linux statusline helper.
|
|
|
|
### Next: v0.5.2
|
|
|
|
Workspace retrieval and cross-workspace context (spec at `v0.5.2-spec.md`):
|
|
|
|
- `ctask restore <workspace>` — un-archive (metadata-only)
|
|
- `ctask notes <workspace>` — print another workspace's `notes.md` to stdout (raw, agent-consumable)
|
|
- `ctask path <workspace>` — print the absolute filesystem path
|
|
- `ctask info <workspace>` — archived-inclusive by default; drop the `--all` flag
|
|
- `ctask resume <archived-workspace>` — fail with a restore hint instead of generic "not found"
|
|
- `ctask list --names` — machine-readable enumeration of workspace directory basenames
|
|
- `ctask completion {bash,zsh,fish,powershell}` — Cobra-generated, with `ValidArgsFunction` hooks per command
|
|
- Seed CLAUDE.md gets a concise cross-workspace context section
|
|
|
|
Lookup policy: **listing is filtered, direct lookup is comprehensive**. Active-only (`resume`, `archive`); archived-inclusive by default (`info`, `notes`, `path`, `restore`); current `--all/-a` semantics preserved on `delete` and `open`.
|
|
|
|
## Post-v0.4 bugfixes (still live, carried forward)
|
|
|
|
### Provisional-workspace cleanup (2026-04-22, commits `02dcdcc`, `ba8b3a1`)
|
|
|
|
Covered in v0.4.1 notes. The exit-code gate (`childExitCode != 0 && startManifest != nil && emptyDiff && NewlyCreated`) is unchanged in v0.5.
|
|
|
|
## Tree state at pause
|
|
|
|
- `main` clean with respect to v0.4, v0.4.1, v0.5, v0.5.1.
|
|
- Installed `ctask.exe` is **v0.5.1** — no reinstall needed unless source changes.
|
|
- Untracked files (do NOT touch without asking):
|
|
- `.claude/settings.local.json` (modified — Claude Code local settings)
|
|
- `bugfix-provisional-workspace.md` (spec for the 2026-04-22 initial provisional fix; may be deleted or archived)
|
|
- `docs/superpowers/plans/2026-04-06-install-workflow.md` (install-workflow plan from an earlier session)
|
|
- `docs/superpowers/plans/2026-04-21-v0.4-implementation.md` (v0.4 plan — executed)
|
|
- `docs/superpowers/plans/2026-04-22-v0.4.1-patch.md` (v0.4.1 plan — executed)
|
|
- `docs/superpowers/plans/2026-04-22-v0.5-implementation.md` (v0.5 plan — executed)
|
|
- `v0.4-spec.md`, `v0.4.1-patch-spec.md`, `v0.5-spec.md` (specs the implementations followed)
|
|
- `v0.5.2-spec.md` (next-round spec, in progress)
|
|
|
|
## How to resume
|
|
|
|
```powershell
|
|
cd C:\Users\Warren\claude_tasks\ctask
|
|
just test # go test ./... -count=1
|
|
just build # or: go build -o ctask.exe .
|
|
just install # only reinstall if source changed
|
|
```
|
|
|
|
Quick sanity checks that v0.5.1 is live:
|
|
|
|
```powershell
|
|
ctask --version # expect: ctask v0.5.1
|
|
ctask doctor # expect: 5 pass/fail + 2 seed-dir INFO + 1 CTASK_PROJECT_ROOT INFO
|
|
|
|
# Local-time directory prefix (v0.5.1):
|
|
ctask new --project "tz-check" --no-launch
|
|
# Expected output: [ctask] created projects/YYYY-MM-DD_tz-check — YYYY-MM-DD matches
|
|
# the user's local wall-clock date, not UTC.
|
|
ctask info tz-check # Created/Updated in local zone
|
|
ctask delete --force tz-check
|
|
|
|
# Project subdir + banner (v0.5):
|
|
ctask new --project "smoke" --no-launch
|
|
# A subdir named smoke/ exists inside the workspace.
|
|
ctask resume smoke # banner shows "[ctask] project dir: smoke/" and Claude
|
|
# launches with cwd inside smoke/. /exit to leave.
|
|
ctask delete --force smoke
|
|
|
|
# Default discovery (v0.5):
|
|
# Projects created without $CTASK_PROJECT_ROOT should now be findable from any shell.
|
|
ctask list --projects
|
|
```
|
|
|
|
## Load-bearing design points (don't forget)
|
|
|
|
### From v0.4 (unchanged)
|
|
|
|
- **Coexisting-session limitation:** "Continue anyway?" or `--force` → second session runs without its own lease. Documented in `docs/commands.md`. Don't redesign without a real user complaint.
|
|
- **`end_manifest` in the summary** is ctask-internal (not in spec example JSON) and powers Layer-3 stale-workspace diff. Removing it breaks Layer 3.
|
|
- **Write-lock skip classification** (best-effort vs important-but-non-fatal): unchanged.
|
|
- **`cmd/delete.go` two-check invariant:** unchanged. `CTASK_WORKSPACE` match → refuse; `.ctask/manifest-start.json` exists → refuse. Both before any mutation.
|
|
- **`session.Run()` lifecycle** in `internal/session/run.go`:
|
|
1. `PreflightFull` (Layers 3 + 1)
|
|
2. Write lock → write lease (unless coexisting)
|
|
3. Write lock → capture + write start manifest
|
|
4. Print launch-context banner (Layer 4)
|
|
5. Start heartbeat (only if we own the lease)
|
|
6. **v0.5: `workspace.ResolveLaunch(opts.WsDir, opts.LaunchDir)` — print warning or abort on security error**
|
|
7. Banner lines (including `project dir:` when LaunchDir set) + exec child with cwd = resolved launch path
|
|
8. Stop heartbeat
|
|
9. `handleProvisional` (gated on `NewlyCreated && childExitCode != 0 && emptyDiff`) — if it removes the workspace, skip finalize entirely
|
|
10. `finalize`: single write-lock acquire → append log + write summary + remove lease (if owned) + remove manifest-start
|
|
- **`new` is intentionally not given `--force`.** Brand-new workspaces have nothing for Layer 1/3 to warn about.
|
|
- **`internal/lockfile` is a neutral package** — no other ctask imports.
|
|
|
|
### From v0.4.1 (unchanged, still load-bearing)
|
|
|
|
- **`config.SearchRoots()` is the canonical way to enumerate workspace roots.** Always includes CTASK_ROOT. In v0.5 the semantics of the second entry expanded — see "From v0.5" below.
|
|
- **`QueryResult.Root`** is how callers render relative paths and compute `CTASK_ROOT` env var. Populated by `scanAllRoots`.
|
|
- **`scanWorkspaces` is a two-depth scan, first-match-wins.** Depth-1 (flat) check wins if present; never descends into a detected workspace.
|
|
- **Archive's non-TTY stdin refuses.** Fresh lease + non-TTY = exit non-zero without mutating. Don't regress to "silent proceed".
|
|
- **Doctor seed-dir checks are three-state.** Only "configured but missing" counts as a failure.
|
|
- **Provisional-cleanup exit-code gate.** `childExitCode == 0` means preserve. Don't special-case specific codes.
|
|
|
|
### From v0.5 (new — don't unlearn)
|
|
|
|
- **`launch_dir` is stored as workspace-relative in `task.yaml`**, empty for tasks and pre-v0.5 projects. Never store absolute paths. Never interpret `launch_dir` outside `workspace.ResolveLaunch`.
|
|
- **`workspace.ResolveLaunch` has three outcomes: valid, soft fallback (with warning), security/permission error.** Soft fallback is `(wsDir, warning, nil)` — caller warns and keeps launching. Error is `("", "", err)` — caller must abort. The asymmetry between `os.IsNotExist` (fallback) and other stat errors (propagate) is intentional; masking a permission error as a warning would silently strip launch-dir semantics.
|
|
- **Project subdir name = final suffixed slug.** `dup-2` collision means subdir is `dup-2/`, not `dup/`. The `actualSlug` variable in `workspace.Create` is the single source of truth.
|
|
- **Subdir is created after seeds, empty, never seeded.** Layer 1 (built-in defaults), Layer 2 (general seed), Layer 3 (project seed) all target the workspace root. The `if opts.IsProject { os.MkdirAll(projDir, 0755) }` block runs AFTER seed overlays and BEFORE `task.yaml` is written.
|
|
- **Session scope is workspace-wide even when launched in the subdir.** Lease, manifest capture, write lock, summary, stale-workspace diff all operate on `opts.WsDir` (the workspace root), not on the resolved launch path. Only the child process's cwd changes.
|
|
- **`CTASK_LAUNCH_DIR` is always exported** (empty string for tasks). Status line helpers and any future child-side integration can check `-n "$CTASK_LAUNCH_DIR"` safely.
|
|
- **`SearchRoots()` now appends `$CTASK_ROOT/projects/` by default** when `CTASK_PROJECT_ROOT` is unset. This is redundant with the v0.4.1 two-depth scan under `$CTASK_ROOT` but explicit per spec. Dedupe in `scanAllRoots` (`searchRootKey` — cleaned + lower-cased on Windows) prevents double-counting. Don't remove the default fallback without also reverting the spec-driven expectation that default projects are findable from any shell.
|
|
- **Doctor check for `CTASK_PROJECT_ROOT` is advisory, not prescriptive.** "Recommended: set at user scope so all terminals can discover these workspaces." Don't harden into a FAIL when the variable is set but the path exists.
|
|
|
|
### From v0.5.1 (new — don't unlearn)
|
|
|
|
- **Workspace directory prefix uses LOCAL time.** `time.Now()` in `workspace.Create` feeds the `YYYY-MM-DD` date and the `YYYYMMDD-HHMMSS` ID. Don't switch back to `.UTC()` for these. The `TestCreateDirectoryPrefixUsesLocalDate` regression test enforces this.
|
|
- **`ctask info` displays timestamps in local zone via `.Local().Format(...)`.** Stored timestamps in `task.yaml` are still UTC (`meta.CreatedAt = nowLocal.UTC().Truncate(time.Second)`) — only the display converts.
|
|
- **Stored timestamps everywhere else remain UTC.** Session logs, lease `StartedAt`/`LastHeartbeatAt`, manifest capture times, summary timestamps are all unambiguous UTC. Don't "localize" those — they're machine-readable.
|
|
- **Cross-builds force `CGO_ENABLED=0`.** `just build-linux` and `just build-windows` set this explicitly so the artifact is pure-Go static. Don't drop the flag — a native Linux build defaults to cgo and produces a glibc-linked binary that won't run in Alpine / distroless / scratch containers.
|
|
- **`WorkspacePath` is gone from `TaskMeta`.** Don't add it back. If a persistent workspace identifier is ever needed, add a properly relative-to-root `workspace_id` (forward-slash normalized). Old `task.yaml` files with `workspace_path` parse silently — the field is ignored on read.
|
|
- **POSIX install script does not modify shell config.** It warns the user about PATH but never edits `~/.bashrc` / `~/.zshrc`. Don't change this without an explicit user request.
|
|
|
|
## Open follow-ups (NOT in v0.4/v0.4.1/v0.5, deferred)
|
|
|
|
### Potentially worth doing
|
|
|
|
- **Pre-v0.5 project workspaces have no `launch_dir`.** They launch from the workspace root, not from any project subdir. No migration path today. Acceptable — users can manually add a `launch_dir` to their `task.yaml` if they want the new behavior. Revisit only if someone complains.
|
|
- **Drop unused `slug` / `category` / `workspacePath` parameters from `seed.ClaudeMD`** (v0.3 follow-up, still open).
|
|
- **Status-line: color the `|project` / `|project:<dir>` marker** if Claude Code's `statusLine` ever supports ANSI.
|
|
|
|
### Concurrency-related (from v0.4)
|
|
|
|
- Coexisting-session detection (more than one live lease per workspace).
|
|
- Cross-machine PID liveness check.
|
|
- `--force` symmetry on other commands — no use case yet.
|
|
- A `ctask sessions` subcommand to inspect lease/summary.
|
|
|
|
### Repo hygiene
|
|
|
|
- Several untracked working docs (`v0.4-spec.md`, `v0.4.1-patch-spec.md`, `v0.5-spec.md`, `bugfix-provisional-workspace.md`, the plan files) could be committed alongside `v0.2-spec.md`/`v0.3-spec.md` for durability. Currently session-local.
|
|
- `.claude/settings.local.json` has uncommitted changes of unknown scope. Leave alone unless asked.
|
|
|
|
### Resolved (don't re-add to this list)
|
|
|
|
- ~~CTASK_PROJECT_ROOT env-var scoping UX footgun~~ → resolved in v0.5 via the default `$CTASK_ROOT/projects/` fallback in `SearchRoots()`.
|
|
- ~~UTC date in directory names / info display~~ → resolved in v0.5.1.
|
|
|
|
## Files to read first when resuming
|
|
|
|
For the v0.5 surface:
|
|
|
|
1. `v0.5-spec.md` — the spec v0.5 followed
|
|
2. `docs/superpowers/plans/2026-04-22-v0.5-implementation.md` — the executed plan (includes scanner-safety regression tests, dedupe tests, amendment history)
|
|
3. `internal/workspace/launchdir.go` — `ResolveLaunch` with the three-outcome contract
|
|
4. `internal/workspace/create.go` — subdir scaffold + local-time date + `launch_dir` default
|
|
5. `internal/session/run.go` — `LaunchOpts.LaunchDir`, `ResolveLaunch` call site, banner extension
|
|
6. `cmd/info.go` — local-time display + launch fields
|
|
7. `cmd/doctor.go` — `checkProjectRoot` helper
|
|
8. `scripts/ctask-statusline.{sh,ps1}` — effective-path display logic
|
|
9. `internal/seed/templates.go` — `ClaudeMDProject` with Workspace Structure section
|
|
|
|
For the v0.4.1 surface (still load-bearing):
|
|
|
|
10. `internal/config/config.go` — `SearchRoots()`, `samePath`, `searchRootKey` dedup; default `$CTASK_ROOT/projects/` fallback
|
|
11. `internal/workspace/query.go` — two-depth `scanWorkspaces`, `scanAllRoots`, `QueryResult.Root`
|
|
12. `cmd/archive.go` — active-session check + non-TTY refusal + `isStdinTerminal`
|
|
|
|
For the v0.4 surface:
|
|
|
|
13. `internal/session/run_preflight.go` — Layer 3 + Layer 1 preflight
|
|
14. `internal/session/lease.go` — Lease + freshness + cleanup
|
|
15. `internal/session/summary.go` — SessionSummary + launch-context banner
|
|
16. `internal/lockfile/writelock.go` — write-lock primitive
|
|
17. `internal/session/run_provisional.go` — `handleProvisional` with `childExitCode` gate
|
|
18. `docs/commands.md` — user-facing surface
|
|
|
|
## Don't re-do
|
|
|
|
- Do not invent remote install / `go install` commands (per `CLAUDE.md`, this project is local-only)
|
|
- Do not touch `cmd/delete.go`'s two-check protection
|
|
- Do not weaken the v0.3 `.gitignore` seed-wins rule
|
|
- Do not redesign the lease model around multiple concurrent leases without a real user-reported problem
|
|
- Do not re-run the v0.4 smoke tests in a fresh session unless source has changed
|
|
- Do not expand the provisional-cleanup gate beyond "strictly empty manifest diff AND non-zero child exit". No size thresholds, no heuristics, no exit-code-specific mappings.
|
|
- Do not extend provisional cleanup to `resume` / `open` / `last`. `NewlyCreated` is set only by `cmd/new.go`.
|
|
- Do not drop `QueryResult.Root` or collapse `SearchRoots()` back to a single string.
|
|
- Do not change archive's non-TTY behavior back to "proceed silently".
|
|
- Do not add a workspace registry file. The default `$CTASK_ROOT/projects/` fallback solved the discovery footgun.
|
|
- **v0.5:** Do not change `launch_dir` storage to absolute paths. Workspace-relative is load-bearing.
|
|
- **v0.5:** Do not mask non-`os.IsNotExist` stat errors in `ResolveLaunch` as warning fallbacks. The asymmetry between soft-fallback (missing / not-a-dir) and hard-error (permission / ENOTDIR / invalid name) is deliberate.
|
|
- **v0.5:** Do not seed anything inside the project subdirectory. Seeds target the workspace root only.
|
|
- **v0.5:** Do not let the session launch change scope (lease, manifest, summary, write-lock) away from the workspace root. Only the child's cwd is the launch dir.
|
|
- **v0.5:** Do not remove the default `$CTASK_ROOT/projects/` fallback in `SearchRoots()` — it resolves the v0.4.1 env-var scoping footgun.
|
|
- **v0.5.1:** Do not switch the directory prefix / ID back to UTC. The `TestCreateDirectoryPrefixUsesLocalDate` test enforces local time.
|
|
- **v0.5.1:** Do not remove `.Local()` from the `ctask info` Created/Updated/Archived formatting. `TestInfoFormatsTimestampsInLocalZone` enforces local display.
|
|
- **v0.5.1:** Do not change *stored* timestamps (task.yaml, session logs, lease, manifest, summary) to local time. UTC storage is deliberate — only display converts.
|