- New persisted built-in pref workspaceFence (default true) under the
files card's secondary settings modal; host reads it per request via
the settings seam (fenceEnabledOf — absent/malformed stays ON).
- ensureWorkspacePath/ensureWorkspaceWritePath gain a fence param:
disarmed skips the containment assert but keeps realpath resolution;
wired through fs.tree/fs.read/fs.write, the media + html routes, and
the upload path (writeWorkspaceUpload fence input).
- Editor load failures and file-tree level errors show the localized
reason plus a one-click global off (FenceErrorNotice) that flips the
pref, adopts it into the store, and auto-retries the failed operation
(reloadSeq / retryDir) — the raw wire text is never shown.
- GitView's two client-side pre-checks (hidden open action + no-op
defense) respect the pref; store threaded through TreePanel/FileTree.
- i18n: 4 new keys across all 21 dictionaries; tests: fence-off route
coverage, prefs parsing, schema default, editor toggles list;
docs: guide §8/§8.1 + plans/2026-08-29 design record.
A reveal on a deep tree shifted the whole panel (tab bar included) out
of the viewport: the reveal used native scrollIntoView, which scrolls
every scrollable ancestor, and the fixed panel host
([data-dsh-panel-host], overflow hidden) is still a programmatically
scrollable container — the host scrolled instead of (or besides) the
tree, with no way to scroll back. Reported on DSH 0.1.2-alpha.1.
Two layers:
- FileTree: compute the centered, clamped target and scrollTo the tree
body only; scrollIntoView is never called.
- panel host: overflow hidden -> clip. A hidden box remains
programmatically scrollable; clip keeps the same viewport-edge
clipping (collapsed panels sliding off-screen) while making the host
impossible to scroll, killing the whole leak class (md-toc jumps,
future consumer scrollIntoView calls).