Paste candidate identifiers (worktree names, session IDs) and see how
safeIdentifier() would handle them in OrchestKit hook input paths.
Background: orchestkit#1826
· prior fix: #1250
· upstream: #1794.
CC harness reads a hook's stdout (legitimately {"continue":true,"suppressOutput":true}) as if it were an identifier, then hands that back to OrchestKit as a worktree name or session ID. The historical incident (2026-05-13) created literal-named directories across 5 repos:
Root cause lives in the CC harness (not OrchestKit). This PR makes OrchestKit fail-closed
instead of propagating: any envelope-shaped identifier collapses to a fallback
("unknown" for worktree names, "invalid" for session IDs).
One candidate per line:
| Input | Verdict | Reason | Fallback used |
|---|
| File | Change |
|---|---|
| src/hooks/src/lib/safe-fs.ts | + looksLikeIdentifier / safeIdentifier |
| src/hooks/src/worktree/worktree-lifecycle-logger.ts | Wrap input.name read in safeIdentifier(_, 'unknown') |
| src/hooks/src/lib/paths.ts | getSessionTempDir collapses envelope IDs into claude-session-invalid |
| src/hooks/src/lifecycle/cleanup-envelope-corruption.ts | NEW · idempotent SessionStart sweep, marker-gated |
| tests · safe-fs / paths / cleanup-envelope-corruption | + 19 regression cases |