Skip to content

fix(workspace): Prevent session file collisions via source-prefixed keys - #792

Merged
JeanMertz merged 5 commits into
mainfrom
rfd-020-filename-collision
Jun 25, 2026
Merged

fix(workspace): Prevent session file collisions via source-prefixed keys#792
JeanMertz merged 5 commits into
mainfrom
rfd-020-filename-collision

Conversation

@JeanMertz

Copy link
Copy Markdown
Collaborator

Two sessions sharing a value but differing in source — e.g. $JP_SESSION=1234 alongside $TMUX_PANE=1234, or an Env value that matched a session-leader PID — resolved to the same 1234.json file, causing one session to silently overwrite the other's active conversation.

The filename now encodes both the session value and its source:

  • getsid-<pid>.json
  • hwnd-<handle>.json
  • env-<KEY>-<hash(value)>.json

The opaque Env value is SHA-256 hashed (first 16 hex chars) so distinct variables holding the same value are kept apart and unsafe characters are excluded from the filename.

The session id is now stored inside the mapping itself, making each file self-describing. Stale detection decodes the id via typed SessionId::as_pid / SessionId::as_hwnd methods — inverses of the encoding in Session::getsid / Session::hwnd — instead of parsing the filename string. This closes the silent failure where a debug-formatted HWND (0x...) was stored but later parsed as decimal, yielding Unknown liveness and disabling stale detection.

Session::getsid and Session::hwnd now accept the raw typed value (i32 / isize) and own the encoding, keeping encode and decode in sync by construction. jp_cli passes the raw platform handle directly.

Existing bare-value files are handled without data loss: reads fall back to the legacy key when the source-prefixed key is absent, and stale-file cleanup migrates surviving legacy files to their new name in one pass.

Two sessions sharing a value but differing in source — e.g.
`$JP_SESSION=1234` alongside `$TMUX_PANE=1234`, or an `Env` value that
matched a session-leader PID — resolved to the same `1234.json` file,
causing one session to silently overwrite the other's active conversation.

The filename now encodes both the session value and its source:

- `getsid-<pid>.json`
- `hwnd-<handle>.json`
- `env-<KEY>-<hash(value)>.json`

The opaque `Env` value is SHA-256 hashed (first 16 hex chars) so
distinct variables holding the same value are kept apart and unsafe
characters are excluded from the filename.

The session id is now stored inside the mapping itself, making each file
self-describing. Stale detection decodes the id via typed
`SessionId::as_pid` / `SessionId::as_hwnd` methods — inverses of the
encoding in `Session::getsid` / `Session::hwnd` — instead of parsing
the filename string. This closes the silent failure where a
debug-formatted HWND (`0x...`) was stored but later parsed as decimal,
yielding `Unknown` liveness and disabling stale detection.

`Session::getsid` and `Session::hwnd` now accept the raw typed value
(`i32` / `isize`) and own the encoding, keeping encode and decode in
sync by construction. `jp_cli` passes the raw platform handle directly.

Existing bare-value files are handled without data loss: reads fall back
to the legacy key when the source-prefixed key is absent, and
stale-file cleanup migrates surviving legacy files to their new name in
one pass.

Signed-off-by: Jean Mertz <git@jeanmertz.com>
@JeanMertz
JeanMertz force-pushed the rfd-020-filename-collision branch from 51fab52 to cc53208 Compare June 25, 2026 05:21
…fixed keys

Signed-off-by: Jean Mertz <git@jeanmertz.com>
…fixed keys

Signed-off-by: Jean Mertz <git@jeanmertz.com>
…fixed keys

Signed-off-by: Jean Mertz <git@jeanmertz.com>
…fixed keys

Signed-off-by: Jean Mertz <git@jeanmertz.com>
@JeanMertz
JeanMertz merged commit aab1e6e into main Jun 25, 2026
16 checks passed
@JeanMertz
JeanMertz deleted the rfd-020-filename-collision branch June 25, 2026 07:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant