Files
aurora-admin/安全审计修复与待决事项.md
T
aurora-admin f1fbfc2ddb
Regression / regression (push) Canceled after 0s
feat(品牌标识): 几何 K 图标(favicon/顶栏标记/theme-color) + 并行会话成果入库
## 品牌标识(本次会话)

起因:品牌此前没有任何图形标识 —— 唯一 favicon 是内联 data-URI 里的字母「A」,
那是 v2.0.0「Aurora Admin → Kole UI」改名漏掉的一处(PC 顶栏也是「A」,
移动端站已是「K」;移动端文档站则完全没有 favicon)。

- 几何:24 网格三个互不接触的笔画(竖 + 两斜),圆头描边;
  描边 2.25 → 16px 标签页尺寸下正好 1.5px = 规范原文「描边1.5px」
- 取色分两套(刻意):favicon 硬编码品牌蓝/白(渲染在浏览器标签栏,不继承 kole-dark);
  顶栏标记走 currentColor(实测暗色下自动转 rgb(20,22,28))
- 新增 theme-color 双条(light #FFFFFF / dark #1C1F26,取 --kole-color-card-bg)
- 修 site/app.js hero 标语 KOLE ADMIN → KOLE UI(改名变形残留)
- 移动端 7 个模板补 favicon(此前计数 0)

验收:门禁 9 条全 OK(site-routing/site-routes/mobile-docs/mobile-site/isolation/
theme/nav/i18n/icons);PC 回归 1464/1464 · 移动端 807/807,各连跑 8 次一致;
两端 favicon 405 字节逐字节一致;PC 站控制台错误 1→0。

## 并行会话成果(本次一并入库)

- 图标系统:2576 图标(TDesign/Element Plus,MIT)+ 11 端注入 + 5 个构建门禁工具
  + IconPreview 预览页 + ICON-SPEC.md 冻结规格
- 移动端平台:47 组件 × 6 端 + 文档站 53 页 + 隔离门禁
- PC 组件:103 个大后台组件 / 组件11 批次
- uni-app:PC 端试点 + 移动端端实现 + 真实编译验证

## 工程

- .gitignore 补 .scratch/ 与 .zcode-preexisting-*.txt(会话中间产物,实测 9.1MB,不入库)
- CHANGELOG 补品牌标识条目
- ROADMAP 登 S8-P4(品牌标识任务包 + og:image/apple-touch-icon 未做部分)
2026-09-21 10:05:48 +08:00

297 lines
21 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.
# 安全审计修复说明与待决事项
> 生成时间:2026-09-19 | 审计对象:本仓库 + `192.168.5.7` 上运行的 `kole-ui-showcase` 容器
> 本文档分两部分:**已修复**(我直接做了,含证据)与 **待你拍板**(我做不了主的,逐项给选项与建议)。
---
## 一页速览
| 状态 | 数量 | 说明 |
|---|---|---|
| 已在仓库修复并验证 | 6 项 | 见第二节,全部有 exit 0 证据 |
| **已部署并在线上验收** | 全部 | 2026-09-19 重建容器:6/6 断言 + 396/396 URL + 响应头全项通过,见第三节 |
| 仍待你拍板 | 4 项 | D3 / D4 / D6 / D8(D1、D2、D5、D7、D9、D10 已决,见第四节开头) |
| 过程异常 | 4 项 | 见第五节 E1–E4(你已确认无其它会话,属当时并发写入) |
**一句话**:洞已堵上且已上线——线上访问 `specs/组件1.txt` 现在返回 404,站点 396 条 URL 全部 200。
---
## 二、已修复(仓库层,全部已实测验证)
### 1. 规范原文泄漏的根因(`.dockerignore`)
**问题**:`.dockerignore` 里 `*.md` / `*.ps1` / `*.yml` / `*.png` 这类写法,在 Docker 下**只匹配构建上下文的根目录**。实测(真实 docker build):
```
.dockerignore: *.md
COPY . /out/ -> /out/sub/nested.md ← 嵌套文件照样进镜像
```
所以 `.design_library/kole-ui/SKILL.md`、嵌套 `README.md` 等一直会被打进镜像;而部署目录 `/opt/kole-ui` 干脆**没有** `.dockerignore`,于是 `specs/`、`agent-reports/`、`preview/`、`ui_kits/` 全部随 `COPY .design_library/` 进了镜像并对外可下载。
**修复**:glob 全部加 `**/` 前缀,保留显式目录排除与 `!README.md`(只放行根级 README)。
**验证**(我在服务器上用当前文件做真实构建):
```
应排除 -> specs/ 0 | agent-reports/ 0 | preview/ 0 | ui_kits/ 0 | nested.md 0 | AGENTS.md 0 | docker-compose.yml 0
应保留 -> site/index.html 1 | site/data.json 1 | site/tokens/tokens.css 1 | site/sources/x.txt 1
frameworks/*.css/.vue3 1 | tests/index.html 1 | tests/report.json 1
.design_library/kole-ui/components/button.json 1 | README.md 1
BUILD_EXIT=0
```
### 2. `nginx.conf` 加固
- 补 `absolute_redirect off;` —— 修复根路径 302 丢失宿主端口(`Location: http://192.168.5.7/site/`,而该机 :80 无服务 → 根地址直接打不开)。
- 补 `server_tokens off;` —— 不再暴露 `nginx/1.31.3`。
- 补 CSP + `X-Content-Type-Options` + `Referrer-Policy` + `Permissions-Policy` + `X-Frame-Options`,CSP 与 `site/dev-server.js` 里的 `SECURITY_HEADERS` **逐字一致**(本地长期验证可用的组合,避免过严导致演示页白屏)。
- `/healthz` 改用 `default_type`,消除重复的 `Content-Type`(原先是 `return 200` 的默认类型与 `add_header` 叠加)。
**验证**:子 agent 在真容器里跑 `nginx -t` → `syntax is ok` / `test is successful` / `exit 0`;并做了修复前/修复后运行时对照(`Location` 由绝对变相对、`Server` 由 `nginx/1.31.3` 变 `nginx`、`/healthz` 由两条 Content-Type 变一条且不丢安全头、gzip 行为等价)。
### 3. `Dockerfile`
补 `COPY sitemap.xml /usr/share/nginx/html/sitemap.xml`(此前生产 `/sitemap.xml` → 404)。
未动基础镜像 tag、未加 `USER`(nginx 官方镜像 master 需 root 绑 80,擅自改会让容器起不来)——运行期加固见 D6。
### 4. `site/dev-server.js`:单请求崩溃
**问题**:`GET /site/%00` → `decodeURIComponent` 解出 NUL → `fs.readFile` 同步抛 `ERR_INVALID_ARG_VALUE` → 异常逃逸出请求回调 → **整个进程退出**(畸形百分号编码反而处理正确)。CI 与本地回归都跑这个服务。
**修复**:编码形态拦截补 `00`/`2500`、解码后**再做一次** NUL 校验(双保险)、`readFile` try/catch。未使用 `uncaughtException` 兜底(那是掩盖)。行为不变:92 条合法路径 status / content-type / 字节级一致。
**验证**:`node tools/verify-dev-server.mjs` → **20 checks / EXIT=0**,含 3 条「修复前必失败」的反例断言(进程存活、突发后仍 200、stderr 无崩溃栈)。
### 5. 消除动态求值 sink(运行期 + 构建期)
**问题**:`site/app.js` 与 `tools/precompute.mjs` 都把 `defineEmits([...])` 的数组字面量交给函数构造器求值。实测:
```
输入 defineEmits([1, globalThis.__pwned = "executed-arbitrary-js"])
旧实现 -> 真的执行了
```
即:任何能改 `frameworks/*.vue*` 的人(投毒 PR / 内部威胁)在组件详情页被打开时即可执行同源 JS;构建期同源版本**在构建机上执行**,而 CI 往往带 secrets。
**修复**:改成只解析字符串字面量的 `parseStringLiteralArray`——非字符串元素 / 未识别转义 / 裸换行 / 结构不符一律整体拒绝返回 `null`(跳过抽取、不报错、绝不执行)。构建期实现独立成 `tools/lib/parse-string-literal-array.mjs`。
**等价性验证**:`node tools/verify-emits-parse.mjs` → **17 checks / EXIT=0**,158 个 `frameworks/*.vue` 双实现抽取结果**不一致 0**(54 处字面量 / 96 条事件名),且新实现对 6 类对抗输入全部拒绝、不执行。
### 6. 新增验证脚本与变更记录
- `tools/verify-dev-server.mjs`(20 checks)、`tools/verify-emits-parse.mjs`(17 checks)——均为零依赖、`exit 1` 表示失败、含「修复前会失败」的反例断言。
- `CHANGELOG.md` 追加 `[Unreleased] → Security · 生产部署链审计修复(2026-09-19)`。
- ⚠️ **规划修正**已在 CHANGELOG 标注:`PLAN.md` §8「不改 `site/dev-server.js`(已工作良好)」的立论被实测推翻,按 AGENTS.md 第五节「以实测为准」处理。
### 回归证据
```
连跑 9 次(子 agent):每次 passRate 100% | pages 79 (all-pass 79) | 1017/1017 | N/A 34 | rc=0
主 agent 独立复跑 1 次(独立端口 13411):passRate 100% | 1017/1017 | N/A 34 | EXIT=0
零依赖铁律:zero-dep OK(EXIT=0)
```
---
## 三、已部署(2026-09-19)
按 AGENTS §九 的标准流程部署(备份 → 暂存目录核对 → 替换 → `docker compose build && up -d`)。共执行两次:
1. **修复落地**:把审计修复 + 工作树当前状态推上线(消除 288 文件漂移)。
2. **重新部署**:`npm run build:site` 两步构建重生成 `data.js` / `data.json` / `site/sources` / `site/details` 后,再跑一次打包流程保持线上与仓库一致(实测线上 `/site/data.js` 102,555B、`/site/data.json` 1,251,099B,与仓库一致;`data.json` 仍为完整版,符合铁律 5)。
回滚点:
- `/opt/kole-ui.pre-audit-20260919-0609` —— 审计前的原始状态(含被泄漏的 `specs/`、旧 `nginx.conf.bak`)
- `/opt/kole-ui.prev-20260919-0614` —— 第一次修复部署后的状态
- `/root/kole-ui-backup-20260919-0609.tgz`(877 KB)、`/root/kole-ui-backup-20260919-0614.tgz`(882 KB)
| 项目 | 修复前(实测) | 修复后(实测) |
|---|---|---|
| `/.design_library/kole-ui/specs/组件1.txt` | **200 / 8623B**(规范原文可下载) | **404** |
| `/.design_library/kole-ui/agent-reports/*.json` | 200 | **404** |
| 嵌套 `SKILL.md` / `README.md` | 200 | **404** |
| `/AGENTS.md`、`/package.json`、`/Dockerfile`、`/nginx.conf` | 404 | 404(一直未泄漏) |
| `/sitemap.xml` | 404 | **200** |
| `tests/report.json`(首页通过率角标数据源) | 404 | **200** |
| 根路径 302 | `Location: http://192.168.5.7/site/`(丢端口,落点无服务) | **`Location: /site/`**(相对,保留端口) |
| 响应头 | 无安全头,`Server: nginx/1.31.3` | CSP + `nosniff` + `Referrer-Policy` + `Permissions-Policy` + `X-Frame-Options`,`Server: nginx` |
| `/healthz` | 两条 `Content-Type` | **1 条**,且安全头未丢 |
| `/site/dev-server.js` | 旧版(无白名单/无敏感路径过滤) | 加固版(`isPublicPath` + `KOLE_PORT`) |
| 组件文件 | 09-06 快照,与仓库漂移 288 个文件 | 与工作树一致 |
| sitemap 的 396 条 URL | 396/396 → 200 | **396/396 → 200**(无回归) |
| 容器 | healthy | healthy |
对 Agent 承诺的资源(`.design_library/kole-ui/{metadata.json,components/index.json,css.json,colors_and_type.css}`)仍正常 200 —— 排除的只是规范原文、agent-reports、preview、ui_kits 这些不该外发的部分。
**访问方式**:按你的决定保持 `127.0.0.1:3311` 回环。经实测确认,服务器上**没有任何 frp 隧道 / 反代 / 域名指向该服务**,所以从任何其它机器都打不开是必然的——唯一的访问路径是 SSH 隧道:
```bash
ssh -o ExitOnForwardFailure=yes -N -L 13311:127.0.0.1:3311 root@192.168.5.7
# 浏览器打开 http://127.0.0.1:13311/site/ (本机 13311 是为了不占本地 dev-server 的 3311)
```
已实测:经隧道对线上部署跑完整文档站冒烟(真实浏览器)全部通过——路由、中英切换、主题面板、详情页渲染均正常。
若想让**局域网内其它设备**也能直接打开 `http://192.168.5.7:3311/`,需把 compose 绑定改为 `0.0.0.0:3311` 并注意 Docker 会绕过 ufw —— 这属于显式暴露变更,等你说一句我就改。
---
## 四、待你拍板(D1–D10)
> **2026-09-19 决定记录**(依据你的指示「暂时不考虑线上公用,但是还是得部署,修改原本的设计和计划」):
>
> | 项 | 结论 | 落地位置 |
> |---|---|---|
> | D1 是否部署 | ✅ **已部署**(按流程:备份 → 暂存核对 → 替换 → 重建;6/6 断言 + 396/396 URL 通过) | 本文第三节、CHANGELOG `Deploy` 段 |
> | D2 部署方式 | ✅ **已改为可复现**:新增 `tools/pack-deploy.mjs`(`.dockerignore` 为唯一真源 + 硬断言),流程写进 AGENTS §九 | `tools/pack-deploy.mjs`、`AGENTS.md §九`、`ROADMAP S5-P13` |
> | D5 端口暴露 | ✅ **保持回环**、不对外公用;AGENTS §九 明确「打不开是正常的,用 SSH 隧道」 | `AGENTS.md §九` |
> | D7 PLAN §8 冻结条款 | ✅ **已按实测修正**(§7 与 §8 两处都标注 ⚠️ 规划修正) | `PLAN.md`、`CHANGELOG.md` |
> | D9 测试基线口径 | ✅ **已同步**为 1017 通过 / 0 失败 / 34 N/A / 共 1051(标注口径来源) | `TESTING.md`、`AGENTS.md §八`、`ROADMAP 规划修正记录` |
> | D10 是否还有其它会话 | ✅ **你已确认无**;本次审计中观察到的是当时并行写入,后续已复核无冲突 | 本文第五节 E1–E4 |
>
> **仍未决**:D3(`tests/report.json` 是否随镜像发布)、D4(正式域名)、D6(容器运行期加固)、D8(契约对外承诺口径)。这四项已登记为 ROADMAP 任务包 S5-P14/P15/P16,等你有空再定。
### D1|是否现在重建并重新部署线上容器?【最高优先】
- **选项 A(建议)**:只同步「本次修复的文件集」重建,不动组件文件。范围小、可回滚、立即堵住规范原文泄漏与掉端口问题。
- **选项 B**:把当前工作树整体同步(顺带消除 288 文件的漂移)。代价:会把仓库里 286 个**未提交**的组件改动一起上线(这些改动本地回归 100%,但等于一次完整发布)。
- **选项 C**:暂不部署,只保留仓库修复。
**我的建议**:先做 A(堵漏),B 作为一次独立「发布」动作、等工作树改动提交审阅后再做。
选 A 时的执行序列(等你一句话我就执行):
```bash
# 1) 备份现状(在 192.168.5.7 上)
cd /opt/kole-ui && tar -czf /root/kole-ui-$(date +%Y%m%d-%H%M).tgz .
# 2) 只更新 5 个文件:nginx.conf / Dockerfile / .dockerignore / site/dev-server.js / site/app.js
# (加上新增的 tools/lib、tools/verify-*.mjs 可选)
# 3) 重建并重启
docker compose build && docker compose up -d
# 4) 验收断言(四条必须全中)
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3311/.design_library/kole-ui/specs/组件1.txt # 期望 404
curl -sI http://127.0.0.1:3311/ | grep -i '^Location' # 期望 /site/
curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1:3311/sitemap.xml # 期望 200
curl -sI http://127.0.0.1:3311/healthz | grep -ci '^content-type' # 期望 1
```
### D2|部署方式:怎么根治「手工拷贝导致漂移」
**这就是这次事故的根因**:`/opt/kole-ui` 是手工拷贝的目录,无 git、无 `.dockerignore`,所以
① 排除规则失效导致规范泄漏;② 曾经修好的 `absolute_redirect off;` 被下一次拷贝覆盖(它只存在于 `nginx.conf.bak-20260916`,从未进过仓库 git 历史)。
- **选项 A(建议)**:改用 rsync/脚本按固定排除清单同步 + 重建,排除清单与 `.dockerignore` 保持同一份真源。
- **选项 B**:服务器上 `git clone` 仓库 + `docker compose build`,用 git 版本作为唯一真源。
- **选项 C**:保持现状手工拷贝(不推荐,同样的回退会再来一次)。
### D3|`tests/report.json` 要不要随镜像发布
- **现状**:当前 `.dockerignore` **保留**它 → 重建后首页「通过率」角标会在线上显示(子 agent 一度排除,被我方流程外的改动改回保留,并在文件里写了理由)。
- **选项 A(建议)**:保留 —— 首页那个「79 测试页 + 通过率」卡片本来就在页面上,显示数字才算兑现。
- **选项 B**:排除 —— 镜像更干净,但卡片静默不显示(当前线上就是 404 → 静默隐藏)。
- 若选 B,删掉 `.dockerignore` 中相关保留注释对应的行即可回滚。
### D4|sitemap 与包的正式域名(`SITE_URL_BASE`)
`sitemap.xml` 内容目前是 `https://YOUR-ACCOUNT.github.io/kole-ui/…`(占位域名),`package.json` 的 `repository` / `homepage` 同样是占位。
- **需要你给**:正式域名(或明确「不做 SEO,接受占位」)。
- `build-site.ps1` 已支持通过环境变量 `SITE_URL_BASE` 覆盖;`tools/release.mjs` 已有占位符闸门会拦住正式发布。
- 顺带一提:`tools/verify-site-routing.mjs` 目前**断言 sitemap 里必须含占位 URL**——如果换了真域名,这个断言要同步改(否则校验会失败)。
### D5|端口暴露策略
- **现状**:绑定 `127.0.0.1:3311`,只有本机/SSH 隧道能访问(我从局域网直连 `192.168.5.7:3311` 超时,符合预期)。
- **选项 A(建议)**:保持回环,并在 README/交接文档写明「必须隧道访问」,避免有人以为服务挂了。
- **选项 B**:挂 1Panel 反代 + 域名(要不要加 Basic Auth / IP 白名单?)。
- 影响面:选 B 会让规范原文泄漏面从「本机」变成「公网」,必须先把 D1 做完。
### D6|容器运行期加固(需要一次重启窗口)
`read_only: true` + `tmpfs`、`cap_drop: [ALL]`、`security_opt: no-new-privileges`、基础镜像 digest 固定。
好处明确,但改 compose 后必须重建容器,且 `read_only` 配错会让 nginx 起不来(需要临时可写 `/var/cache/nginx`、`/var/run`)。要不要做、什么时候做,你定。
### D7|`PLAN.md` §8 冻结条款的修正
`PLAN.md` §8 写着 `❌ 不改 site/dev-server.js(已工作良好)`,§7 有对应验收条目。实测推翻了「已工作良好」,我已按 AGENTS.md 路径修了代码并在 CHANGELOG 标注 ⚠️ 规划修正,但**没有改 `PLAN.md` 本身**(它在冻结清单里)。
需要你确认:是否把该行改成「dev-server 的畸形路径处理属必修项」。
### D8|契约 JSON 的对外承诺怎么统一
- **本地**:79 份契约 + `index.json`。
- **线上**:只有 `button/card/input/modal/select/table.json` + `index.json`(7 个文件),`tag.json`、`calendar.json` 等 → 404。
- **文档三处互相矛盾**:`site/llms.txt` 写「契约覆盖全部 79 个组件」;`AGENTS.md` 写「契约 JSON 79」;而 `index.json` 自己的 description 写「其中 **6 个核心组件**另含契约 JSON」。
**选项**:A 全量发布 79 份(镜像略大,但对 Agent 消费的承诺为真);B 只发布核心 6 份,并把 `llms.txt`/`AGENTS.md` 的表述统一改为「6 份核心契约 + 79 组件索引」;C 保持现状(不推荐,等于承诺失实)。
### D9|测试基线数字的口径同步
`TESTING.md` 记的是 `1009 / 35`,HEAD 提交信息也写「回归1009-1009」,而当前工作树实测是 **1017 通过 / 34 N/A**。差异来自工作树里已有的未提交改动,不是本次修复造成。建议在合并这批改动后统一同步(我没改 `TESTING.md`,它不在允许清单内)。
### D10|是否还有别的会话/自动化在动这个仓库
见第五节 E1–E3。**如果有,建议先停掉再合并**,否则两边互相覆盖。这是本次最需要你确认的运维问题。
---
## 五、必须让你知情的过程异常
**E1|`.dockerignore` 在我方子 agent 交付后被第三方进程改写。**
子 agent A 交付的哈希是 `3b34ffa6`(其中排除了 `tests/report.json`),磁盘现状是 `843cb650`(保留 `report.json` 并写了理由注释)。功能上现状更优(首页通过率卡片能显示),但 A 报告的 47 条断言**不覆盖**现状版本——所以我用当前文件独立重做了真实构建复验(第二节 1,全过)。这也意味着我已无法声称「这个文件的每处改动都来自本次派活」。
**E2|`tools/precompute.mjs`(05:56:41)与 `tools/lib/parse-string-literal-array.mjs`(05:56:45)不在任何子 agent 的允许清单内,却被写入了;且 05:56:29 有一次我没派出的构建运行。**
那次运行重写了 **494 个文件**(`site/sources/**` 395、`site/details/*` 79、`site/data.js`、`site/data.json`、`site/changelog.json`),但 `sitemap.xml` 与 `site/tokens/*` 未变——即只跑了第二步 `node tools/precompute.mjs`,没跑 `build-site.ps1`。
我复核了内容与后果:
- `tools/precompute.mjs` 的 `node --check` 通过、`tools/lib/...mjs` 可加载、与 `site/app.js` 在 158 个 `.vue` 上抽取结果一致、对恶意输入不执行;
- **重建后的 `site/data.js` 哈希 `5fdffe24…` 与构建前、与线上部署三方完全一致** → 这次构建是语义无损的,同时**独立证明了新的安全解析器不改变构建输出**(不依赖我方验证脚本的口径);
- 漂移比对从我审计时的「288 个文件不同」变为「289」,差额恰好是本次修复的 `site/app.js`,其余无新增漂移。
**结论**:改动立意是对的(构建期确实有同一个求值 sink,打穿的是构建机而非浏览器),但来源不明、未走派活流程。若这是你的另一个会话在做同一件事,请注意两边会互相覆盖(见 D10)。
**E3|共享模块头部引用的 `tools/verify-precompute-emits.mjs` 并不存在。**
且注释里描述的「源码逐行等价 + 5000 例种子随机等价」比实际存在的检查更强。我已把注释改为描述**真实存在**的门(`tools/verify-emits-parse.mjs`:158 文件结果等价 + 对抗语料),改动后复跑该脚本仍 `17 checks / EXIT=0`。
若你确实想要那道更强的门(源码等价 + 随机 fuzz),需要另派一个任务实现。
**E4|服务器 `/tmp` 残留 `kole-di-final*`(非本次产物)。**
我清理了自己创建的全部临时目录与 scratch 镜像;这三项来源不明,未删以免干扰可能仍在运行的会话。生产容器 `kole-ui-showcase` 全程未动(`Up 2 days (healthy)`)。
---
## 六、审计中被验证为「无问题」的部分(免得重复怀疑)
| 检查项 | 结果 |
|---|---|
| 路径穿越(`../`、`..%2f`、`%2e%2e`、`....//`、反斜杠、`.git/config`) | 全部 403 |
| 搜索框 XSS(`<img src=x onerror=…>`) | 0 个注入节点、0 次执行 |
| 路由滥用 | 无效 slug / 越界路径全部回落首页,无异常 |
| 代码高亮渲染 | 先全量转义再还原 token,无注入 |
| 硬编码凭据 | 未发现(命中的都是 design-token 变量名) |
| 零运行时依赖铁律 | 成立(`dependencies` 为空) |
| sitemap 里的 396 条 URL | 线上 396/396 → 200(静态页无死链;sitemap 文件本身 404 另见第二节 3) |
| 容器健康 | `healthy`,`/healthz` 200 |
---
## 附录:本次审计与修复用到的复验命令
```bash
# 全量回归(需先起服务;服务端口可用 KOLE_PORT 覆盖)
KOLE_PORT=13411 node site/dev-server.js &
REG_BASE=http://127.0.0.1:13411 node tools/run-regression.mjs
# 两处缺陷的定点验证
node tools/verify-dev-server.mjs # 20 checks,含 3 条反例断言
node tools/verify-emits-parse.mjs # 17 checks,158 文件双实现等价
# 铁律
node -e "const p=require('./package.json');const d=Object.keys(p.dependencies||{});if(d.length){console.error('FAIL');process.exit(1)}console.log('zero-dep OK')"
# 部署配置复验(在 192.168.5.7 上,用一次性容器,不碰生产)
docker run --rm -v /tmp/<你的>/default.conf:/etc/nginx/conf.d/default.conf:ro nginx:alpine nginx -t
```
证据留档:`C:\Users\12914\Desktop\组件规范第一套\.zcode\deployed-manifest.txt`(线上 1394 文件哈希清单)、`.zcode\drift-check.mjs`(漂移比对脚本)、`.zcode\sitemap-check.txt`(396 条 URL 清单)。