`toClaudeProjectPath` only normalized `/`, `.`, and `:` — but Claude Code's
on-disk slug also folds underscores (and other non-alphanumerics) to `-`.
AO project data dirs are named `<sanitized>_<hash>` (e.g.
`graph-isomorphism_d185b44d56`), so the slug AO computed pointed at a
directory that never existed. Cascading failures:
- `getSessionInfo` couldn't read the JSONL → `claudeSessionUuid` never
got persisted to session metadata.
- On restore, `getRestoreCommand`'s metadata lookup found nothing AND its
workspace-scan fallback also missed (same bad slug), returning `null`.
- Session-manager's native-restore guard then threw
`SessionNotRestorableError` → API returned 409.
Verified on-disk: every session under projects without underscores has
`claudeSessionUuid` persisted; every session under projects with
underscores does not. The orchestrator angle in #1611 is the loudest
symptom — orchestrators die early so they have nothing else to fall back
on — but the same bug silently broke worker restore in any multi-project
setup.
Fix: replace `[/.]` with `[^a-zA-Z0-9-]` in the slug regex, matching
Claude Code's actual encoding. Adds direct unit tests for
`toClaudeProjectPath` covering the underscore case plus existing paths,
and a regression test in the `getSessionInfo` path-conversion suite.
Fixes#1611.
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>