The per-session record store is now the ONLY cwd mechanism. Deleted:
- env.cwd_owner stamping + prev_owner threading (terminal_tool): the
shared env no longer carries ownership metadata at all
- _resolve_command_cwd's env/prev_owner params: resolution is
workdir > session record > config/override default
- file_tools._live_cwd_if_owned + _get_live_tracking_cwd: path
resolution never consults the shared env's live cwd
- file_tools._last_known_cwd + _remember_last_known_cwd +
_last_known_cwd_for: the #26211 preserved-anchor registry is
subsumed by the session record, which never lived on the env and
therefore cannot be lost to env cleanup. The _get_file_ops
stale-cache rescue now writes the record instead.
- env recreation (both _get_file_ops and terminal_tool) seeds the
fresh env from override > session record > config
Why no transition fallback: the legacy state was process-local and
in-memory exactly like the record store — after a restart both start
empty, and within a running process every legacy write site has been
dual-writing the record since step 1. There is no populated-legacy/
empty-record state to fall back for.
Tests updated to drive the record store instead of the deleted
mechanism; the cross-session isolation suite now asserts the same
behavior contracts (no leak, cd isolation, #26211 persistence)
against the new architecture, plus a new "session C inherits nothing"
case that the old ownership guard could not express.
File tools (read_file, write_file, patch, list_directory, etc.) used
os.path.expanduser() which reads the gateway process HOME env var.
In Docker/systemd/s6 deployments where the gateway HOME differs from
interactive sessions, tilde expanded to the wrong directory.
Add _expand_tilde() helper that delegates to get_subprocess_home() when
available, falling back to os.path.expanduser(). Replace all 9
expanduser() call sites in file_tools.py with _expand_tilde().