# dsh-boot-failsafe v2 > Boot failsafe for the DeepSeek Harness web GUI — **pure client, zero disk writes, zero host logic, passive**. If a client plugin crashes while loading (template defects like `exports is not defined` / `received object`, or any factory throw), it is skipped with a visible banner instead of breaking the UI; missing-bundle 404s are reported, not auto-"fixed". You can always get in, even when a plugin is broken. > > WebUI 加载容错(对抗审查修订版)。纯 client、零磁盘写入、零 host 逻辑、被动响应——坏插件加载失败时自动跳过 + 横幅提示,绝不破坏页面与服务端。 --- ## English ### Safety contract (v2 hard rules) - ❌ No disk writes of any kind (node_modules / patch / anything) - ❌ No server routes, no loader service access, no manifest modification - ❌ No probing, no "is it uninstalled" guessing - ✅ The only persistence is browser localStorage - Worst possible outcome: a plugin is skipped (recoverable). The server is never touched. > History (v0.1): a host-side auto-patch that wrote no-op packages into profile node_modules once misclassified 128 official packages → crash loop (NRestarts=65) → 502. v2's host half is explicitly a no-op. ### Capabilities 1. **Factory failsafe**: wraps `window.__ModuleLoader__.load` — installed at **module top level** (during the arrive phase, long before the host EntryTree imports plugins; polls ≤30s if `__ModuleLoader__` is not ready). A factory that throws or does not return `apply` is replaced with a no-op placeholder and listed in a banner (plugin name + reason + disable button). The wrapper itself is fully try/catch-guarded — it can never break the registration chain. - Honest note: ordering is best-effort (script phase ≪ import phase), not a hard guarantee. 2. **Missing-bundle reporting**: strict 404 detection — `error` event (capture) + `SCRIPT` target + `/plugins/` src + id resolved from the boot manifest (read-only). Reports only, never auto-fixes. 3. **Blacklist** (localStorage `dsh.bootFailsafe.blocked.v2`): - Entries are `{id, rev}`; when the manifest `rev` changes the entry auto-clears (the plugin may have been fixed) - Self-protection: refuses to disable `dsh-boot-failsafe` itself or `@deepseek-ai/dsh-client-modules` - "全部解除" escape-hatch button clears the whole blacklist - After fixing a plugin: refresh the page to restore (fresh loadCache, no stale no-op) ### Coverage boundaries (honest) | Scenario | Behavior | |---|---| | Factory template defect (no `apply` / factory throw) | ✅ skipped + banner + disable | | Top-level transpile error (`exports is not defined` at module top) | ⚠️ script-error path: banner + manifest id lookup, not skipped | | Bundle 404 (uninstalled, not restarted) | ⚠️ reported only ("refresh / restart the service") | | Runtime `apply` half-crash | ❌ not covered (runtime error) | ### Install ```bash dsh plugin --profile web add github:fengs2021/dsh-boot-failsafe systemctl restart dsh-web # or hot-mount via dev tools (no restart) ``` Hard-refresh the page afterwards (the browser must load the new client bundle). ## 中文 ### 安全契约(v2 铁律) - ❌ 不写任何磁盘文件(node_modules / patch / 任何路径) - ❌ 不注册服务端路由、不访问 loader 服务、不修改 `__DSH_BOOT__` - ❌ 不探测、不判定「已卸载」 - ✅ 唯一持久状态 = 浏览器 localStorage - 最坏结果 = 某个插件被跳过(可恢复);服务端零影响 > 历史教训(v0.1):host 半自动补写 no-op 包曾把 128 个官方包误判替换成占位 → crash loop(NRestarts=65)→ 502。v2 host 半显式为 no-op。 ### 能力 1. **factory 容错**:包装 `window.__ModuleLoader__.load`(**模块顶层**安装,早于 EntryTree import 阶段;`__ModuleLoader__` 未就绪则 ≤30s 轮询等待)。factory 抛错 / 未返回 `apply` → no-op 占位 + 横幅(插件名+原因+禁用按钮)。包装自身异常全兜底回退原始 load,绝不破坏注册链。 - 诚实声明:时序为尽力而为(script 阶段远早于 import 阶段),非硬保证。 2. **资源缺失提示**:严格 404 检测——`error` 事件(capture)+ `SCRIPT` target + `/plugins/` 前缀 + manifest(只读)id 反查。只提示不自动修。 3. **黑名单**(localStorage `dsh.bootFailsafe.blocked.v2`): - 条目 `{id, rev}`;manifest rev 变化 → 自动解除(可能已修复) - 自我保护:禁止禁用 `dsh-boot-failsafe` 自身与 `@deepseek-ai/dsh-client-modules` - 横幅「全部解除」逃生按钮 - 修复插件后:刷新页面即可恢复(loadCache 全新,无残留 no-op) ### 覆盖边界(诚实) | 场景 | 行为 | |---|---| | factory 模板缺陷(未返回 apply / factory throw) | ✅ 跳过 + 横幅 + 禁用 | | 顶层转译错误(`exports is not defined` 在模块顶层) | ⚠️ script-error 路径:横幅提示 + manifest 反查 id,不跳过 | | bundle 404(已卸载未重启) | ⚠️ 只提示「刷新/重启」,不自动修 | | apply 运行期半崩 | ❌ 不覆盖(运行时错误) | ### 安装 ```bash dsh plugin --profile web add github:fengs2021/dsh-boot-failsafe systemctl restart dsh-web # 或 dev 工具热装配(免重启) ``` 安装后**硬刷新页面**(浏览器需加载新版 client bundle)。 ## License MIT