fix: #80 — session-lookup error messages now show actual workspace-fingerprint directory

## Problem

Two session error messages advertised `.claw/sessions/` as the managed-session
location, but the actual on-disk layout is `.claw/sessions/<workspace_fingerprint>/`
where the fingerprint is a 16-char FNV-1a hash of the CWD path.

Users see error messages like:
```
no managed sessions found in .claw/sessions/
```

But the real directory is:
```
.claw/sessions/8497f4bcf995fc19/
```

The error copy was a direct lie — it made workspace-fingerprint partitioning
invisible and left users confused about whether sessions were lost or just in
a different partition.

## Fix

Updated two error formatters to accept the resolved `sessions_root` path
and extract the actual workspace-fingerprint directory:

1. **format_missing_session_reference**: now shows the actual fingerprint dir
   and explains that it's a workspace-specific partition

2. **format_no_managed_sessions**: now shows the actual fingerprint dir and
   includes a note that sessions from other CWDs are intentionally invisible

Updated all three call sites to pass `&self.sessions_root` to the formatters.

## Examples

**Before:**
```
no managed sessions found in .claw/sessions/
```

**After:**
```
no managed sessions found in .claw/sessions/8497f4bcf995fc19/
Start `claw` to create a session, then rerun with `--resume latest`.
Note: claw partitions sessions per workspace fingerprint; sessions from other CWDs are invisible.
```

```
session not found: nonexistent-id
Hint: managed sessions live in .claw/sessions/8497f4bcf995fc19/ (workspace-specific partition).
Try `latest` for the most recent session or `/session list` in the REPL.
```

## Impact

- Users can now tell from the error message that they're looking in the right
  directory (the one their current CWD maps to)
- The workspace-fingerprint partitioning stops being invisible
- Operators understand why sessions from adjacent CWDs don't appear
- Error copy matches the actual on-disk structure

## Tests

All 466 runtime tests pass. Verified on two real workspaces with actual
workspace-fingerprint directories.

Closes ROADMAP #80.
This commit is contained in:
YeonGyu-Kim 2026-04-21 22:18:12 +09:00
parent 4b53b97e36
commit ff45e971aa

View File

@ -112,7 +112,7 @@ impl SessionStore {
candidate
} else if looks_like_path {
return Err(SessionControlError::Format(
format_missing_session_reference(reference),
format_missing_session_reference(reference, &self.sessions_root),
));
} else {
self.resolve_managed_path(reference)?
@ -143,7 +143,7 @@ impl SessionStore {
}
}
Err(SessionControlError::Format(
format_missing_session_reference(session_id),
format_missing_session_reference(session_id, &self.sessions_root),
))
}
@ -161,7 +161,7 @@ impl SessionStore {
self.list_sessions()?
.into_iter()
.next()
.ok_or_else(|| SessionControlError::Format(format_no_managed_sessions()))
.ok_or_else(|| SessionControlError::Format(format_no_managed_sessions(&self.sessions_root)))
}
pub fn load_session(
@ -522,15 +522,25 @@ fn session_id_from_path(path: &Path) -> Option<String> {
.map(ToOwned::to_owned)
}
fn format_missing_session_reference(reference: &str) -> String {
fn format_missing_session_reference(reference: &str, sessions_root: &Path) -> String {
// #80: show the actual workspace-fingerprint directory instead of lying about .claw/sessions/
let fingerprint_dir = sessions_root
.file_name()
.and_then(|f| f.to_str())
.unwrap_or("<unknown>");
format!(
"session not found: {reference}\nHint: managed sessions live in .claw/sessions/. Try `{LATEST_SESSION_REFERENCE}` for the most recent session or `/session list` in the REPL."
"session not found: {reference}\nHint: managed sessions live in .claw/sessions/{fingerprint_dir}/ (workspace-specific partition).\nTry `{LATEST_SESSION_REFERENCE}` for the most recent session or `/session list` in the REPL."
)
}
fn format_no_managed_sessions() -> String {
fn format_no_managed_sessions(sessions_root: &Path) -> String {
// #80: show the actual workspace-fingerprint directory instead of lying about .claw/sessions/
let fingerprint_dir = sessions_root
.file_name()
.and_then(|f| f.to_str())
.unwrap_or("<unknown>");
format!(
"no managed sessions found in .claw/sessions/\nStart `claw` to create a session, then rerun with `--resume {LATEST_SESSION_REFERENCE}`."
"no managed sessions found in .claw/sessions/{fingerprint_dir}/\nStart `claw` to create a session, then rerun with `--resume {LATEST_SESSION_REFERENCE}`.\nNote: claw partitions sessions per workspace fingerprint; sessions from other CWDs are invisible."
)
}