## 接续点 · 实例恢复浮层改造(按新 ICON 样式) · 2026-09-21 06:43 > 🔴 **07:35 追加 · 优先级最高**:文末「追加节」列出的 **proxy.js 回归修复**必须**先于本页其余一切**执行 —— > 现行线上 `proxy.js` 是**未修复版本**(连接泄漏修复已被回滚),服务可用性风险仍在。 > 另:本线还有 **🟣 阶段 3 = 项目架构全景排查**(见文末),排在回归修复与浮层改造**之后**。 > ✅ **08:12 进展 · 前两项已落地结案** > ① **proxy 回归修复**:07:49 上线 47,复验(只读部署后新增日志)`499=0 / 200=18`,`guest.ai1net.com GET /` **200 · 4171B**。 > ② **浮层改造**:08:08 上线 47,线上 md5 `3f82a5d86e0a6318c0f1157f78b5e1e1`(旧视觉 `__dsh-orb`=0 / 新标记 `__dshr-grow`=2), > 真机截图已验收(hub 形态 + 新品牌配色)。**本页「下一步」1–4 条全部完成**(见文末「本棒状态」)。 > ⇒ **本线剩余唯一项 = 🟣 阶段 3(项目架构全景排查)**,排在最后,⛔ 不要再动 proxy.js / recovery.js。 - 来源会话: guest 实例 503 排障(档案 146)|结束原因: **水位 >30 万强制收口** - 原目标(用户原话,未翻译): 「**处理完毕后 按照项目新ICON的样式,改造重新拉起实例恢复会话的浮层动画**」 ⚠️ 前置条件「处理完毕后」**已满足** —— 503 排障已落地并验收(见文末「不要重做」) - 基线: HEAD=`1242d07db0fa75fea08fa11ac3b46d3d4f72eace`|远端 master=开工时自查|全局锁=**无占用** - 产物: **无**(本任务尚未开工) - 校验命令(证明前序任务确已完成;只读、<30 s): ```bash cd /d/github/dsh_shenxian node scripts/verify-inject.cjs lib/supervisor/proxy.js | tail -1 # 期望:全部合格 ✅ grep -c clientGone lib/supervisor/proxy.js # 期望:5 grep -c streamsReclaimed lib/net/relay/server.js # 期望:≥3 ``` 不符 ⇒ **停下只报告**,⛔ 不许照文字硬做。 - 下一步(**✅ 2026-09-21 08:08 已全部完成 · 下列保留供追溯**): 1. `cd /d/github/dsh_shenxian && ls -l web/*.svg && git log --oneline -12 -- web/ assets/inject/ && sed -n '1,40p' assets/inject/recovery.js` —— 目的:**定位「项目新 ICON」究竟指哪个资产**(候选:`web/favicon.svg`、`web/logo.svg`、`web/deepseek-text.svg`,或 `assets/inject/` 内联图标)。用 `git log` 看最近一次图标改动即可判定哪个是"新"。 2. 读浮层现状全文:**`assets/inject/recovery.js`**(浮层的唯一实现处;由 `src/supervisor/proxy.ts` 的 `loadInject` 注入)。 3. 按新 ICON 的**色彩 / 形状 / 圆角 / 描边**风格改造浮层的**动画**(进入 → 等待 → 重试 三态)。 4. 真机验收(配方见「已知线索」第 3 条),含**无痕对照**。 - 未完成: ① 定位新 ICON 资产 ② 识别浮层现有视觉与动画结构 ③ 改造动画 ④ 真机验收 - 关键决定(防推翻重来): - 浮层实现 = **`assets/inject/recovery.js`**(不是别处);注入点 = `src/supervisor/proxy.ts` → `loadInject`。 - 🔴 **DOM 契约必须保留**:`window.__dshRecover === 1`(脚本执行完毕哨兵)、`#__dshRecover`、`#__dshRetryBtn`、`#__dshAssistBar` —— `scripts/verify-inject.cjs` 与技能 `dsh-instance-diagnose` 的验收都依赖它们。**可新增元素/类名,⛔ 不许删改既有 ID 与哨兵**。 - 改完必须走**三段式验收**(本机 → 部署 → 用户可见面);部署 = scp 产物到线上 + `restart dshs`(该脚本由平台进程读,缓存坑见 `06-工作台UI规范 §7`)。 - 回滚点: 本任务尚未动任何线上文件;动手前先备份线上那份 `recovery.js`(`/opt/dsh/backups/`)。 - ⛔ 不要重做(前序已落地、已验收): - `src/supervisor/proxy.ts` 的**连接泄漏修复**(4 处:`clientGone` / `liveUpstream` / WS `'close'`) - `src/net/relay/server.ts` 的**per-port 兜底回收**(10 hunk:`reclaimStale` / `streamsReclaimed` / `openedAt`) - 档案 `dsh-server-docs/04-调整方案/146-实例子域503-中继per-port额度被连接泄漏占满.md`(已含 §七兜底、§八遗留) - ⚠️ **106 relay 未同步**(其产物基线落后于 47,⛔ 不许直接覆盖)—— 属**另一条线**,本棒**不要碰**。 ### 已知线索(省掉重新探索) 1. **浮层是什么**:实例被回收 / 未就绪时平台注入的自愈浮层 —— 文案「工作区已休眠,正在唤醒…(**已等待 N 秒**)」+「DSH · AUTO RECOVERY」+进度条;点按钮触发 `/api/dsh/enter`。 2. **注入机制**:`proxy.ts` 的 `injectRecovery()` 把 `assets/inject/recovery.js` 插进 HTML(**仅当客户端接受 HTML 且响应未被压缩**时);`scripts/verify-inject.cjs` 是它的契约校验脚本(改完必跑)。 3. **真机验收配方**(零生产副作用,出处:技能 `dsh-instance-diagnose` 末节):`playwright-core` + `channel:'chrome'`,**拦 `**/api/dsh/status*` 回 `{"running":false}` + 把 `**/api/dsh/enter*` 挂住不回** ⇒ 浮层停住不下跳,可从容观测动画。 ⚠️ 四个坑:① `page.route` **拦不住 WebSocket**(别用 offline 造断流)② `probe()` 有 **15 s 节流**(心跳会占掉窗口)③ `recover()` 成功后 **0.7 s 内 `location.replace()`** ⇒ 任何 ≥2 s 轮询都会踩空 ④ `#__dshAssistBar` 是容器,要点里面的 `button`。 4. **视觉基线**:`dsh-server-docs/06-工作台UI规范.md`(**强制基线**,冲突时以其**实测 Token** 为准);图标见其 §4.12 与「功能图标亮色映射」,Token 表见 §1。 --- ## 🔴 追加节(2026-09-21 07:35)· 优先级 **高于**上文「下一步」 **背景**:上文「不要重做」里列的 `proxy.ts` 连接泄漏修复,**06:20 上线、07:35 因引入回归被回滚**。 现行线上 `proxy.js` = **未修复版本**(判据:`grep -c clientGone /opt/dshs/lib/supervisor/proxy.js` → **0**)。 ⇒ 服务可用性风险仍在,**先修这个**,再谈浮层改造。 1. **按 `dsh-server-docs/04-调整方案/146-…md` §九 的「正解」重写判据**: ⛔ 原写法 `request.raw.on('close')` **是错的**(GET 请求体读完即触发 ⇒ 误判"断开" ⇒ 掐死正常请求 ⇒ 用户侧 499); ✅ 改为 **`reply.raw.on('close', …)` + 开头 `if (reply.raw.writableEnded) return`**;⛔ 不要用已废弃的 `req.on('aborted')`。 2. **验收必须打在真实路径上**(上一轮假绿的根源):⛔ 不许拿 `curl` 的 **401** 当通过判据 (401 由平台在进入 `proxyHttp` **之前**返回,走不到被改的代码)。 ✅ 口径 = **带有效 `sid` 走一次真实子域请求**,核对 **状态码 200 + 响应字节数 > 0**; 或部署后看 `nginx` access log 里该子域出现 **200**(若仍是 **499** ⇒ 没修好)。 3. **部署后立即回读 access log 复核**:`tail /www/wwwlogs/ai1net.com.log` —— ⛔ 不许只凭内部 `curl` 判定。 4. §七 的中继 per-port 兜底**仍在线上、无需重做**(它是当前唯一防线)。 5. 修完并复验通过后,再回到上文「下一步」做浮层改造。 --- ## 🟣 阶段 3(本线最后一步)· 项目架构全景排查与结构评估 **用户原话(未翻译)**:「**整体排查一遍,项目框架,分层结构,模块规划,功能设计,各模块调用依赖情况,要细到功能点。生成项目全景图,看看是不是由于代码结构混乱不清晰导致修改出问题,影响项目迭代效率**」 **目标**:产出**细到功能点**的项目全景图(框架 / 分层 / 模块 / 调用依赖),并**用证据回答**一个判断题 —— 「本次修改出问题,是否由代码结构混乱导致?是否已影响迭代效率?」 **方法(⛔ 不许空谈,每条结论必须带可复核证据)** 1. **先跑现成的分层守卫**:`cd /d/github/dsh_shenxian && npm run check:layering`(该脚本**已存在**)—— 机器结论优先于人工目测。 2. **量化复杂度**:统计 `src/` 各目录/文件的**行数**,以及层间**实际 import 方向**(`web/routes → supervisor → net/relay → db` 等), 与 `CODEBUDDY.md` 声明的分层是否一致;**大文件 + 高扇入 = 迭代阻力信号**,逐个记录。 3. **功能点粒度**:从 `src/web/routes/*.ts` 的**路由表**反推功能点清单,每点标注: 入口路由 → 处理层 → 依赖模块 → 涉及数据表 → 对应前端页面(`web/*.html`)。 4. **可交付的图**:产出**单文件 HTML/SVG 全景图**(分层模块图 + 关键调用链 + 依赖方向 + 功能点索引) ⛔ 不要只写文字描述 —— 用户明确要"全景图"。 5. **回答判断题时必须区分三类成因**(本任务的核心价值,⛔ 不许含糊成"结构有点乱"): - **结构性**(分层越界 / 职责不清 / 耦合)—— 必须给出**具体模块 + 行号/import 证据** - **方法性**(验收打错路径、假绿) - **流程性**(高水位赶工) ⚠️ **已有第一手反例**:档案 `04-调整方案/146-…md` **§九** 记录的那次回归,真因是**判据主体选错 + 验收假绿 + 高水位赶工**, **不是**结构混乱。⇒ 本任务要做的是**验证该结论能否推广到全局**,⛔ **不要预设"结构一定有问题"**(那是先射箭再画靶)。 **验收**:① 全景图文件可打开,含分层 + 依赖方向 + 功能点索引;② 判断题有**明确结论**,每条结论都带可复核证据 (脚本输出 / 文件与行号 / import 清单);③ ⛔ 不许只给主观评价或"建议重构"这类空话。 **边界**:本阶段**只读分析**,⛔ 不改任何生产代码;发现的问题写进档案与待办,**不顺手修**(遵守「只做被明确要求的事」)。 --- ## 📌 本棒状态(2026-09-21 08:12 · automation `a617498c-330d-404f-98f0-e4334d92253c`) **已完成(两项,均已上线 47 并复验)** 1. **proxy 连接泄漏回归修复** —— `src/supervisor/proxy.ts` - 判据主体 `request.raw.on('close')` → **`reply.raw.on('close')`**,且条件去掉 `|| reply.raw.destroyed` (`'close'` 触发时响应流通常已 destroyed ⇒ 条件恒真 ⇒ 修复静默失效,只换主体不换条件等于白改)。 - 部署:`tsc build` → `verify-inject` 合格 → 备份 `proxy.js.pre-fix2-` → scp `/opt/dshs/lib/supervisor/proxy.js` → `restart dshs`。 - 复验:**499=0 / 200=18**,`guest.ai1net.com GET /` 200 · 4171B。 2. **浮层改造(按新品牌 ICON)** —— `assets/inject/recovery.js` - 视觉从「旋转圆环 + 轨道粒子(旧 DeepSeek 蓝紫 #58a6ff/#a371f7)」换成 **hub(中心 + 三辐条 + 三外环节点)**; - 配色 = `web/design.css` 的 token:ink `#0f1c33` 底 + accent-2 `#38d6d0` 节点 + 白色中心节点;失败态 `--danger #e5484d`; - 三态动画:进入 = 三辐条生长 → 三节点依次点亮;等待 = 能量流动 + 呼吸;失败 = `.__dsh-fail`(中心转红、辐条节点熄灭); - **DOM 契约未动**:`window.__dshRecover` / `#__dshRecover` / `#__dshRecoverMsg` / `#__dshRetryBtn` 全部保留。 - 验收:`node --check` + `verify-inject.cjs` 全部合格;**Chrome headless**(`--virtual-time-budget`)真跑浮层并截图确认 (harness 落在 `E:\tmp-recovery-harness\`:stub `/api/dsh/status`→`{running:false}`、挂住 `/api/dsh/enter` ⇒ 浮层停住不下跳)。 - 部署:备份 `/opt/dsh/backups/recovery.js.pre-hub-` → scp → `restart dshs`;**本机与线上 md5 一致** `3f82a5d86e0a6318c0f1157f78b5e1e1`;部署后日志 **499=0 / 200=6**。 **⚠️ 验收已知边界**:失败态(`.__dsh-fail` + 重试按钮)**未做浏览器实测** —— 触发它需真实连续 4 次恢复失败(`RECOVER_MAX=3`), 当前环境造不出该时序,仅做静态审查。条件一出现(真实累积失败)必须回来补测。 **下一棒(未做)**:🟣 **阶段 3 = 项目架构全景排查**(见上节,含验收口径与「结构性/方法性/流程性」三类成因要求)。 **遗留待归档(本棒未做)**:档案 `04-调整方案/146-…md` §九 正文仍写「已回滚 · 必须重新落地」,该句**已过期**,归档时需同步。