Files
dsh_shenxian/dsh-server-docs/08-skills/dsh-change-workflow/references/02-红线详解-R5-R7-R8.md
T
admin e6207aa691
build / build-and-scan (push) Canceled after 0s
chore(仓库对齐): 文档库结构治理 + IM/插件线落地
文档库:目录改为编号制(01-规范/02-架构设计/03-数据库/04-调整方案/
05-交接单/06-ops/07-scripts/08-skills/09-archive),顶层散文件归入 01-规范/;
INDEX.md 与 docs-manifest.json 重刷(档案 146 篇);旧目录名引用全量对齐。

IM 线:src/im/**(SDK / hub / store / presence / ws / gateway-token)、
src/web/routes/im.ts、src/db/plugin-data/**、src/supervisor/plugin-assembly.ts
及对应 test/**。

插件线:poc/{im-agent-bridge,im-connection-gateway,im-conversation-tabs,
business-plugins-im,carbon-mcp-probe}、src/web/routes/{sessions,overlay-device}.ts、
src/net/relay/{device-grant,instance-credential}.ts。

仓库卫生:清出 40 个历史误入库 / 已改名文件(34 个交接单归档 + 6 个旧结构,
本地均有副本);dsh-server-docs/.gitignore 补 tmp/;交接单不入库(政策)。
2026-09-24 07:25:16 +08:00

78 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 红线详解 · R7 批量写入门禁 / R8 生产变更知会 / R5 权限扩大门禁
> **归属**:技能 `dsh-change-workflow` 的详情档(**按需读**,不是每次都要读)。
> **本档覆盖**:R7 批量写入门禁 · R8 生产变更知会 · R5 权限扩大门禁(原行 L414–L480)。
> **主文件 / 判据与流程主干** = `../SKILL.md`(§1 六阶段流程 · §2 红线 R1–R8 原文速查 · §3 本机 Git Bash 环境坑 · §4 并行调度结论)。
> **来源**:2026-09-22「技能重组线」把 `../SKILL.md` 的 L414–L480 段**逐行原样**下沉到本文件,未改一字。
> **跨档引用**:正文里的「§N / 见 §8 坑 N / 见下表」等编号,用 `../SKILL.md` 末节「详情索引」的原章节列定位。
> **维护**:本文件与 `../SKILL.md` 的指针行成对;改内容时同时核对主文件的指针描述是否仍准确。
---
### R7 批量写入门禁(2026-09-12 用户新增红线)
> **用户原话**:「为什么会犯这种错误,容易把服务器搞崩,必须记录在红线中。」
**由来(真实事故)**:为了让 scp 出去的文件行尾干净,写脚本遍历整个代码库把 **147 个文本文件** CRLF→LF。当期被要求的只是一句「把某个 UI 字符串改个名」,**操作半径放大了两个数量级**。
**已经造成的实际损害**(不是理论风险):
- 147 个文件被标记为 M —— 若继续 scp / 提交 / 推送,会覆盖服务器上正确的版本、产生巨型 diff 掩盖真实改动、并与并行会话冲突;
- 随后用 `cp -r` 同步插件目录时,把**当期并没有改过的** `cordis.patch.yml`、`lib/index.js` 也用 CRLF 覆盖到了**服务器**(已发现并恢复)。
**规则(硬性)**:
1. **只做被明确要求的事**。执行中发现的额外问题(哪怕看起来"很小、很好修")一律**先报告、后动手**,不得顺手改。用户说"按建议处理"只授权**那条建议本身**,不是授权一切顺带优化。
2. **禁止**对仓库或生产目录做:全库遍历改写(`os.walk` / `find -exec` / `grep -rl | xargs`)、通配符重写、批量 `chmod`/`chown`、**批量换行符转换**、`cp -r` 整目录覆盖、`git add -A`。
3. **阈值**:一次操作若**可能影响 >10 个文件**,或表述里出现「所有 / 整个 / 全库 / 全部」→ **停下来先问**,先产出**受影响清单**再决定。
4. **本机不是沙箱**:本机镜像与服务器是两份独立副本;本机的批量改动即便不带任何"部署"动作,也会在下一次 scp 时传导到生产。
5. **先用单点验证**:任何批量手段先对 **1 个对象**试,确认后果(`git status`、`file`、`md5`)符合预期再考虑推广。
6. **传播前比对待传清单**:scp / 同步前必须 `git status` 确认**待传清单只含本次真实改动**,不含被工具顺手改动的文件。
7. **行尾类问题一律先报告**:仓库 blobs 是 LF 而本机工作树因 system 级 `core.autocrlf=true` 呈现 CRLF(`D:/Program Files/Git/etc/gitconfig`)—— 这是**既有环境事实**,不构成"需要当场修复"的缺陷;要动必须先与用户确认范围。
### R8 生产变更知会(2026-09-12 用户新增红线)
**由来**:档案 58(内存优化)、59(重连反馈)两次改动都需要重启 `dshs`,**连续两次把在线用户踢下线**,直接引发用户"会话连接异常"报障。
**规则**:
1. 以下动作**都会中断在线用户**,执行前必须先说明「**影响谁、断多久、为什么必须现在做**」并取得确认:
- `systemctl restart dshs`(drain 全部实例)
- `systemctl stop dsh-*.scope`(停某个用户实例)
- 批量铺插件 / 改 `MemoryMax` / 改实例 env(都要实例重启才生效)
- 重建 profile、改 profile patch
2. **能选低峰期就不要在用户活跃时做**;无法避免时明确告知"会断一次"。
3. **改完即验证**:重启后必须确认服务 active + 门户 200 + 实例能被拉起,再向用户交代。
4. 附带:本机 `D:\github` 下的镜像**任何批量改动都视为"可能影响生产"**(见 R7 第 4 条)。
### R5 权限扩大门禁(2026-09-11 用户新增红线)
**先判方向:这次改动是「扩大」还是「收窄」?**
| 方向 | 例子 | 处置 |
|---|---|---|
| **收窄** | 减少挂载、去掉白名单项、收紧 nft、收窄 env | 可直接做,但**仍须验证**(遮蔽类可能让实例起不来 → 档案 42) |
| **扩大** ⚠️ | 新增 bwrap 挂载 / `--bind`、放开被遮蔽的路径、把平台目录或文件暴露给实例、给实例注入新 env、放宽 `ALLOWED_ENV`、放松 nft(出网或宿主访问)、提高权限档位或放宽 `approval`、新增用户可读/可写路径、把 root 执行链路(解压 / chown / pnpm)的对象变成用户可控 | **一律先出「权限影响评估」并等用户明确同意**,禁止"顺手做了" |
**「权限影响评估」四问(方案里必须逐条写,档案留痕)**:
1. **扩了什么** —— 逐条列具体路径 / 端口 / env / 权限位(不要写"优化了访问"这种含糊话);
2. **谁受影响** —— 全部租户 / 单租户 / 仅 admin;
3. **有没有不扩大也能实现的方案** —— 若有,必须先提;若确实没有,说明为什么;
4. **回滚方式 + 验收方式** —— 回滚命令写清楚;验收**必须 diff 技能里的「实例可访问路径清单(权威版)」**,
逐项确认"新增项都是用户已同意的"。
**🔒 安装类操作 = 扩大,必须先出「安装确认清单」并经用户确认**(2026-09-11 用户明确要求:
「需要安装哪些依赖和工具,需要确认后才能安装,避免安装有风险的内容」)。
凡是要往**平台共享位**(`/usr/local/dsh-runtime`、`/usr/local/bin`、系统包)装东西,**一律不得自动执行**,
先列七项等用户点头:① 名称+版本 ② **为什么需要**(哪个技能/插件在用)③ **来源与校验方式**(官方 URL + sha256)
④ 体积 ⑤ 影响面(**全部租户**)⑥ 风险点 ⑦ 卸载方式。
技能/插件**导入时的依赖体检只做「报告 + 拦截」(缺失即 409),绝不代装**。
**触发文件(改这些就必须走 R5,无一例外)**:
`src/supervisor/orchestrator.ts`(bwrap args / `baseEnv`)、`src/supervisor/spawn.ts`(`ALLOWED_ENV`)、
`/etc/nftables-dsh-egress.nft`、`src/web/routes/skills.ts`、`src/web/routes/business-plugins.ts`、
`ensure-role-profile-patch.cjs`(角色 profile patch)。
> **历史依据**:档案 39(`/etc` 白名单化)、40(bundled-skills 挂载)、41(技能上传/启停)、42(Python 运行时)
> 里每一次"扩大"都是在用户明确要求下才做的;反例是档案 42 的遮蔽尝试 —— 属"收窄"但因触碰挂载结构
> 直接让实例起不来,**收窄也必须跑真启动验证**。