dsh-ppt-studio 1.2.0 → 1.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (32) hide show
  1. package/docs/03-/346/233/264/346/226/260/346/227/245/345/277/227.md +10 -0
  2. package/docs/07-/345/244/215/346/235/202/345/233/276/350/203/275/345/212/233/347/253/213/351/241/271/344/270/216/351/243/216/351/231/251/347/231/273/350/256/260.md +1 -1
  3. package/docs/08-/351/230/266/346/256/265A/350/256/276/350/256/241/350/257/264/346/230/216-/347/273/223/346/236/204/345/205/263/347/263/273/344/270/216/345/233/276/344/270/223/345/261/236/346/240/241/351/252/214.md +1 -1
  4. package/docs/13-/345/217/221/347/211/210/345/207/206/345/244/207/350/256/241/345/210/222.md +2 -2
  5. package/docs/14-/345/217/221/345/270/203/346/270/205/345/215/225/357/274/210/350/215/211/347/250/277/357/274/211.md +20 -0
  6. package/docs/15-1.2.0 /345/217/221/345/270/203/346/212/245/345/221/212.md" +46 -0
  7. package/examples/smoke/imported/source.pptx +0 -0
  8. package/examples/smoke/out-smoke.pptx +0 -0
  9. package/lib/scaffold.js +1 -1
  10. package/package.json +1 -1
  11. package/scripts/smoke.mjs +8 -8
  12. package/scripts/verify-preset-scope.mjs +1 -1
  13. package/skills/{diagram-drawing → ppt-studio-diagram}/SKILL.md +7 -0
  14. package/skills/{diagram-drawing → ppt-studio-diagram}/pitfalls.md +8 -0
  15. package/skills/{diagrams/compare.md → ppt-studio-diagram-compare/SKILL.md} +14 -0
  16. package/skills/{diagrams/flow.md → ppt-studio-diagram-flow/SKILL.md} +14 -0
  17. package/skills/{diagrams/funnel.md → ppt-studio-diagram-funnel/SKILL.md} +14 -0
  18. package/skills/{diagrams/layers.md → ppt-studio-diagram-layers/SKILL.md} +14 -0
  19. package/skills/{diagrams/loop.md → ppt-studio-diagram-loop/SKILL.md} +14 -0
  20. package/skills/{diagrams/matrix.md → ppt-studio-diagram-matrix/SKILL.md} +14 -0
  21. package/skills/{diagrams/sequence.md → ppt-studio-diagram-sequence/SKILL.md} +14 -0
  22. package/skills/{diagrams/state.md → ppt-studio-diagram-state/SKILL.md} +14 -0
  23. package/skills/{diagrams/steps-ring.md → ppt-studio-diagram-steps-ring/SKILL.md} +14 -0
  24. package/skills/{diagrams/swimlane.md → ppt-studio-diagram-swimlane/SKILL.md} +14 -0
  25. package/skills/{diagrams/timeline.md → ppt-studio-diagram-timeline/SKILL.md} +14 -0
  26. package/skills/{diagrams/tree.md → ppt-studio-diagram-tree/SKILL.md} +14 -0
  27. /package/skills/{diagram-drawing → ppt-studio-diagram}/capability-matrix.md +0 -0
  28. /package/skills/{diagram-drawing → ppt-studio-diagram}/composition.md +0 -0
  29. /package/skills/{diagram-drawing → ppt-studio-diagram}/mechanisms.md +0 -0
  30. /package/skills/{diagram-drawing → ppt-studio-diagram}/routing.md +0 -0
  31. /package/skills/{diagram-drawing → ppt-studio-diagram}/text-and-spacing.md +0 -0
  32. /package/skills/{diagram-drawing → ppt-studio-diagram}/verify.md +0 -0
@@ -2,6 +2,16 @@
2
2
 
3
3
  > 格式:`## [版本号] 日期` → 目的(为什么改,引测试反馈编号)→ 改动 → 验证 → 影响/后续。
4
4
 
5
+ ## [1.2.1] 2026-09-30 —— 修复:复杂图 skills 未被注册(用户实测)
6
+
7
+ **问题**:新预设会话里,斜杠命令与助手的 skill 清单都找不到复杂图相关 skill(四份 `ppt-studio-*` 正常可见)。
8
+
9
+ **根因(实测)**:DSH 按「`SKILL.md` + frontmatter(`name`/`description`/`whenToUse`)」注册 skill;而 `skills/ppt-studio-diagram/SKILL.md` **没有 frontmatter**,12 份配方只是 `skills/diagrams/` 下**散装的 `.md`**、该目录**没有 `SKILL.md`** ⇒ 两组都不满足注册条件(打包正常,文件都在)。
10
+
11
+ **修法**:① 给 `ppt-studio-diagram/SKILL.md` 补 frontmatter;② 把 12 份配方各自拆成独立 skill 目录(各带 frontmatter),并**统一命名为 `ppt-studio-` 前缀**:`ppt-studio-diagram`(总纲)+ 12 份 `ppt-studio-diagram-<类型>`(tree/matrix/timeline/swimlane/compare/loop/funnel/steps-ring/sequence/state/flow/layers)⇒ 共 **17 个**内置技能(含原有 4 份)随**预设作用域**注册,不进全局技能目录。同期修:描述补足 >20 字符并剔除会破坏 YAML 的 `: ` 写法、正文 >800 字符、每份补「收工自检」与「优先级边界」块、smoke 的 §40/§52 期望技能数 4→17。
12
+
13
+ **验证**:仓库内 17 个 skill 目录均含 `SKILL.md`;安装后应能在预设会话的 skill 清单/斜杠命令中看到 `ppt-studio-diagram` 与 12 份 `diagram-*`。
14
+
5
15
  ## [1.2.0] 2026-09-30 —— 复杂图通路定稿 + 适配 DSH 0.2.0-rc.2
6
16
 
7
17
  **场景**(docs/07 §2 的可验证内核):拿到一份已有风格的参考稿,要在**同一风格**下换/加一页复杂图。
@@ -314,6 +314,6 @@ expectedIntersections:
314
314
  | 5 | 裁决优先级细则(参考稿内部矛盾取舍) | **留待后续版本** |
315
315
  | 6 | `role` 覆盖阈值告警 | 待定 |
316
316
 
317
- > 现行唯一通路是**手写显式 elements**,见 `skills/diagram-drawing/`(SKILL.md / mechanisms.md)。
317
+ > 现行唯一通路是**手写显式 elements**,见 `skills/ppt-studio-diagram/`(SKILL.md / mechanisms.md)。
318
318
  > 本文件仅作历史对照保留。
319
319
 
@@ -301,6 +301,6 @@ resolveDeck → normalizePage
301
301
  - `attach` 只支持"边 + 最近点"锚定;折线中途拐点吸附(`attach` 到中段)不在阶段 A 范围。
302
302
 
303
303
 
304
- > 现行唯一通路是**手写显式 elements**,见 `skills/diagram-drawing/`(SKILL.md / mechanisms.md)。
304
+ > 现行唯一通路是**手写显式 elements**,见 `skills/ppt-studio-diagram/`(SKILL.md / mechanisms.md)。
305
305
  > 本文件仅作历史对照保留。
306
306
 
@@ -43,8 +43,8 @@
43
43
  |---|---|
44
44
  | P4-1 | `docs/09-代码地图与模块职责.md`:修复上轮"删行"后可能出现的**表格缺列/断行**(P1-5 扫描同时核对) |
45
45
  | P4-2 | `docs/07-复杂图能力立项与风险登记.md`:修复删行留下的**段落断口**(列表项悬空等) |
46
- | P4-3 | `skills/diagram-drawing/pitfalls.md`:补 **F 组五条流程坑**(清 fixture 只用 `examples/smoke`/参数化必测缺省路径/改基线必留痕/破坏性脚本先只读定位/先打印现场再动手) |
47
- | P4-4 | `skills/diagram-drawing/mechanisms.md`:写入**门禁原则**(只锁事实与声明自洽;风格与表达取向不入门禁)+ 把 `unknown-key` 登记进 §2 code 对照表 |
46
+ | P4-3 | `skills/ppt-studio-diagram/pitfalls.md`:补 **F 组五条流程坑**(清 fixture 只用 `examples/smoke`/参数化必测缺省路径/改基线必留痕/破坏性脚本先只读定位/先打印现场再动手) |
47
+ | P4-4 | `skills/ppt-studio-diagram/mechanisms.md`:写入**门禁原则**(只锁事实与声明自洽;风格与表达取向不入门禁)+ 把 `unknown-key` 登记进 §2 code 对照表 |
48
48
  | P4-5 | `docs/03-更新日志.md`:补写**本轮条目**(标 `[下一版 · 待发]` ✓,**不写版本号生效** ✗)+ **已知限制**段(见 §6) |
49
49
  | P4-6 | 交付物侧 `手画12+1/结论表.md`:口径修正为"**机制等价 + 0 页变差 + 2 页风格取向不同**" ✓ + 页 04 五条警告的最终处置(内容层面、不涉插件 ✓) |
50
50
  | P4-7 | `README.md` 与根目录文件核查(上一轮未扫 ✗):不得描述已移除方案;如需补一句"复杂图用手写 elements"✓ 则补 |
@@ -35,3 +35,23 @@
35
35
  ## 5. 发布后
36
36
 
37
37
  确认装出来的包可用(`npm run verify:package` 已覆盖"装到干净目录 → `require` 可用");如需回滚,回滚点标签:`pre-P1`/`pre-P1b`/`pre-P2`/`pre-P3`/`pre-P4`/`pre-P5`/`pre-release` ✓。
38
+
39
+ ---
40
+
41
+ ## 7. 发布通道与硬规矩(2026-09-30 实测确立)
42
+
43
+ **通道**:`dsh-ppt-studio` 用 **npm Trusted Publishing(OIDC)** 发布 —— **本机没有也不该有 npm 凭据**。
44
+
45
+ | 事实 | 说明 |
46
+ |---|---|
47
+ | **只有创建 GitHub Release 才触发发布** | `publish.yml` 的触发是 **`release` 事件** ⇒ **只推 tag 不会发布**(1.2.1 首次就因此没发出去);补发用 `workflow_dispatch` 指定 tag。 |
48
+ | 本地 `npm publish` 必然 E401/E404 | 预期行为,**不是故障**;**不得**把它的退出码当发布判据。 |
49
+ | 发布判据 = **registry 现状** | `npm view dsh-ppt-studio version` / `dist-tags` 必须显示目标版本;否则就是没发。 |
50
+ | Release 事件触发后 | 用 `gh run list` 看 `Publish to npm` 是否 success;必要时取消(撤回触发:删 Release + `gh run cancel`)。 |
51
+
52
+ **硬规矩(用户指令)**
53
+ 1. **没有用户明确指令,不得创建 GitHub Release、不得打版本标签、不得改版本号** —— 创建 Release 就等于发布。
54
+ 2. 每次发布前必须逐条跑通发版前检查(本文件 §1–§4)。
55
+ 3. 发布后必须**从 registry 复核**,并把结果写进 `docs/03` 与发布报告。
56
+
57
+ **标准发布序列**:`npm test` 全绿 → `verify:package` / `verify:products` → 版本号 + `docs/03` 定稿 → 提交并推 `main` → 打 `v<版本>` 标签并推 → **创建 Release(附 tgz)** → 轮询 registry 至目标版本 → 两端安装升级 → 复核。
@@ -0,0 +1,46 @@
1
+ # 1.2.0 发布报告
2
+
3
+ > 数据来源:本机实测命令输出(2026-09-30)。**结论:1.2.0 已发布且两端可用。**
4
+
5
+ ## 1. 发布渠道与地址
6
+
7
+ | 渠道 | 状态 |
8
+ |---|---|
9
+ | **npm registry** | `dsh-ppt-studio@1.2.0` 已发布;`dist-tags = { latest: "1.2.0" }` ✓(由 tag `v1.2.0` 触发仓库的 GitHub Actions **OIDC 受信发布**,发布者显示为 `GitHub Actions <npm-oidc-no-reply@github.com>`) |
10
+ | **git** | annotated tag `v1.2.0` → commit `976e97e`;分支 `main` 已推送 ✓ |
11
+ | **GitHub Release** | `https://github.com/zbsph/dsh-ppt-studio/releases/tag/v1.2.0`(含 `dsh-ppt-studio-1.2.0.tgz` 资产,可用于离线/归档安装) |
12
+
13
+ ## 2. 两端安装与激活
14
+
15
+ | 端 | profile | 插件版本 | 说明 |
16
+ |---|---|---|---|
17
+ | 桌面端 | `desktop` | **1.2.0** ✓ | 经**应用侧**插件管理升级成功(`changed: true`,返回 `restart-required`)⇒ **重启应用后生效**;用户已在界面确认显示 **1.2.0** ✓ |
18
+ | Web 端 | `web` | **1.2.0** ✓ | 由 GitHub Release 的 tgz 安装;用户已在界面确认显示 **1.2.0** ✓ |
19
+ | headless | `headless` | 未装 | 按既定决定保持干净;需要时:`dsh plugin --profile headless add dsh-ppt-studio@1.2.0` |
20
+
21
+ ## 3. 发版前检查(全部通过)
22
+
23
+ - `npm test`:**322 通过 / 0 失败** ✓(含 `lib ⟷ src` 39/39 逐字节相同 ✓、未知键零误报 0 ✓、可见文本痕迹扫描 0 ✓、生成器检查网 9/9 ✓、13 页手画摘要与基线一致 ✓)
24
+ - `npm run verify:package`:通过 ✓(`npm pack` 248 文件、必含项齐全、装到干净目录后入口可 `require`、包内无已移除方案的痕迹)
25
+ - `npm run verify:products`:通过 ✓(13 张 PNG 与基线一致,差异 0)
26
+ - 预设漂移:**0 / 缺行 0 / 有意差异 1**(插件 persona)✓
27
+
28
+ ## 4. 本次发布内容
29
+
30
+ 见 `docs/03-更新日志.md` 的 `## [1.2.0] 2026-09-30` 条目:复杂图通路定稿(手写 elements + 门禁)+ 适配 DSH 0.2.0-rc.2(含四条长期适配规则)。
31
+
32
+ ## 5. 已知限制(随版本发布)
33
+
34
+ 1. 无逐形状样式(阴影/高光/笔触);开发期的强样式控制选项未纳入;
35
+ 2. 手写几何由作者给出 ⇒ 单页成本更高、批量大 deck 更慢;
36
+ 3. 生成器检查为**语法级**(运行期类错误仍可能漏网);
37
+ 4. 13 页手画回归语料**不随包发布** ⇒ 该回归只在仓库内可跑;包内只发 `lib`;
38
+ 5. `unknown-key` 仍是**测试链守卫**,尚未进入每页门禁报告。
39
+
40
+ ## 6. 遗留与回滚
41
+
42
+ - **遗留 1**:已发布的 1.2.0 构建自 tag `976e97e`,**不含**其后 `9cb5184` 的"更新日志同名标题"排版修复 ⇒ 若希望包内文档也干净,需发 **1.2.1**(功能无差异)。
43
+ - **遗留 2**:`systemPrompt` 出现在 `inject` 声明中,但源码未发现直接调用点(无害,列为可选清理)。
44
+ - **遗留 3**:装配语义(C)只核到"名字与结构仍在"层,未逐行验证行为等价。
45
+ - **回滚点**:`pre-release`、`pre-adapt-D/E/F`、`pre-release-1.2.0`;上一版 tag `v1.1.5`。
46
+ - **平台事实**:桌面 profile 由 Electron 独占管理(`dsh plugin --profile desktop …` 会被拒 ⇒ 桌面端插件变更只能走应用「插件管理」);`web` / `headless` profile 可用 CLI 管理。
Binary file
Binary file
package/lib/scaffold.js CHANGED
@@ -152,7 +152,7 @@ expectedOverlaps:
152
152
  - 复杂图导出基元:points >2 点 = 折线(一帧 custGeom 开放路径,不是多条拼的);arrow: 'both' = 两端箭头(arrow: true 等价 'end');line.dash: solid|dash|dot|dashDot;kind: notchedRightArrow(流程图常用)。
153
153
 
154
154
 
155
- 不要再指望引擎替你算几何 —— 按需读 skills/diagram-drawing/(调度手册 mechanisms.md + 12 份子 skill 配方),用显式 elements 把图拼出来。
155
+ 不要再指望引擎替你算几何 —— 按需读 skills/ppt-studio-diagram/(调度手册 mechanisms.md + 12 份子 skill 配方),用显式 elements 把图拼出来。
156
156
  这是受支持的正式路径,不是退路(13 页实测:零族依赖、门禁 0 错、与旧族产物同内容对照 10 更好 / 1 持平 / 2 持平偏旧 / 0 变差)。
157
157
 
158
158
  关键机制(都在手画侧):
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-ppt-studio",
3
- "version": "1.2.0",
3
+ "version": "1.2.1",
4
4
  "description": "在 DeepSeek Harness 里做 PPT:说需求 → 逐页制作 → 导出可编辑的 .pptx。含布局检查、Office 真渲染复核,以及可扩展的本地模板库",
5
5
  "//publish": "2026-09-18 定:发 npm,**无 scope** 包名 `dsh-ppt-studio`。**状态(2026-09-26):已发布** —— `dsh-ppt-studio@1.1.0` 在 npm 上(`dist-tags.latest`、public,发布者 `zbsph`),registry 的 tarball 与 GitHub Release 资产**逐字节相同**(sha256 `9303cc5c…`)。首个版本是 `npm publish <发版 tgz>` 直发的;**从下一版起改走 Trusted Publishing(OIDC)全自动通道**:`.github/workflows/publish.yml` 由 release 事件触发 → 下载 Release 资产 → OIDC `npm publish` → 发后自证 integrity —— 零长期 token、零手工(npm 已公告:Bypass-2FA 直发 2027-01 移除)。发布纪律不变:**用发版时那个 tgz**(`.sync-state.json` 的 `localTgz`),**别在 main 前进后跑裸 `npm publish`**(会按当前工作区重新打包 ⇒ 破坏'两条通道同一份字节')。手动补发入口:Actions → Publish to npm → Run workflow。见 README §10 与 docs/05「发布-同步纪律」。",
6
6
  "repository": { "type": "git", "url": "git+https://github.com/zbsph/dsh-ppt-studio.git" },
package/scripts/smoke.mjs CHANGED
@@ -2269,7 +2269,7 @@ ok('bundle:已转为公开发布 npm(无 private + publishConfig.access=publ
2269
2269
  // 第四次修订(2026-09-26)**按预设隔离**:`apply()` 按"作用域档"分两种——
2270
2270
  // · profile 档(`config.scope` 缺省/`auto`/`profile`)= 全局管道 + 预设声明;缺省档还追加一行
2271
2271
  // **自定位行**(本包入口的绝对 `file://`),让本包被自己的预设再挂一次 ⇒ 预设档。
2272
- // · preset 档(`config.scope === 'preset'`,由自定位行挂载)= 22 工具 / `/ppt` 命令 / 4 技能 /
2272
+ // · preset 档(`config.scope === 'preset'`,由自定位行挂载)= 22 工具 / `/ppt` 命令 / 17 技能 /
2273
2273
  // 语义路由 / 提示段**全部注册在预设作用域** ⇒ 只对该预设的会话可见(其他预设零影响)。
2274
2274
  // 安全网:声明失败、注册表不可见、或"声明成功但预设档实例未装配" ⇒ **自动回落全局能力面**。
2275
2275
  // 历史两次失败的正确结论(2026-09-26 源码 + 真宿主实测):① 只对"插件自己按 agent 动态门控"成立;
@@ -2343,7 +2343,7 @@ ok('bundle:已转为公开发布 npm(无 private + publishConfig.access=publ
2343
2343
  `tools=${tools} cmds=${cmds} skills=${skills} listeners=${listeners}`)
2344
2344
  await grace()
2345
2345
  ok('§40 自动回落:声明成功但预设档实例未装配 ⇒ 回落注册全局能力面(**功能不丢**,只是没隔离)',
2346
- tools === 22 && cmds >= 1 && skills === 4 && listeners >= 2
2346
+ tools === 22 && cmds >= 1 && skills === 17 && listeners >= 2
2347
2347
  && presetMod.presetDeliveryStatus().isolation === 'profile-fallback',
2348
2348
  `tools=${tools} cmds=${cmds} skills=${skills} listeners=${listeners}|isolation=${presetMod.presetDeliveryStatus().isolation}`)
2349
2349
  let promptOk = false
@@ -2371,8 +2371,8 @@ ok('bundle:已转为公开发布 npm(无 private + publishConfig.access=publ
2371
2371
  const tierBase = { tools, cmds, skills, listeners }
2372
2372
  indexMod.apply(makeCtx(), { scope: 'preset', autoPreset: false, presetIds: ['ppt'] })
2373
2373
  await flush()
2374
- ok('§40 预设档:22 工具 + `/ppt` 命令 + 4 技能 + 2 监听器**全部注册在预设作用域**(隔离的实现主体)',
2375
- tools - tierBase.tools === 22 && cmds - tierBase.cmds >= 1 && skills - tierBase.skills === 4 && listeners - tierBase.listeners === 2,
2374
+ ok('§40 预设档:22 工具 + `/ppt` 命令 + 17 技能 + 2 监听器**全部注册在预设作用域**(隔离的实现主体)',
2375
+ tools - tierBase.tools === 22 && cmds - tierBase.cmds >= 1 && skills - tierBase.skills === 17 && listeners - tierBase.listeners === 2,
2376
2376
  `增量 tools=${tools - tierBase.tools} cmds=${cmds - tierBase.cmds} skills=${skills - tierBase.skills} listeners=${listeners - tierBase.listeners}`)
2377
2377
  ok('§40 预设档:**不声明**预设(否则注册表对重复 id 直接 throw ⇒ 预设消失)',
2378
2378
  declared.length === 0, `声明次数=${declared.length}`)
@@ -2386,7 +2386,7 @@ ok('bundle:已转为公开发布 npm(无 private + publishConfig.access=publ
2386
2386
  indexMod.apply(makeCtx(), { scope: 'profile' })
2387
2387
  await grace()
2388
2388
  ok('§40 传统档:能力面注册在装入层(全局可见),且声明**不含**自定位行(19 行)',
2389
- tools - trBase.tools === 22 && skills - trBase.skills === 4 && declared.length === 1
2389
+ tools - trBase.tools === 22 && skills - trBase.skills === 17 && declared.length === 1
2390
2390
  && declared[0]?.plugins?.length === 19 && declared[0]?.plugins?.at(-1)?.id !== 'ppt-studio-scope'
2391
2391
  && presetMod.presetDeliveryStatus().isolation === 'profile',
2392
2392
  `增量 tools=${tools - trBase.tools} skills=${skills - trBase.skills}|行数=${declared[0]?.plugins?.length}|isolation=${presetMod.presetDeliveryStatus().isolation}`)
@@ -2407,7 +2407,7 @@ ok('bundle:已转为公开发布 npm(无 private + publishConfig.access=publ
2407
2407
  await new Promise((r) => setTimeout(r, 3400))
2408
2408
  } catch { noRegThrew = true }
2409
2409
  ok('§40 注册表不可见:只告警不抛,并靠**兜底超时**回落全局能力面(极简部署仍完整可用)',
2410
- // 注意:这个假 ctx 连 `skills` 服务都没有(`get` 恒 undefined)⇒ 技能数应为 0,不是 4。
2410
+ // 注意:这个假 ctx 连 `skills` 服务都没有(`get` 恒 undefined)⇒ 技能数应为 0(该假 ctx 没有 skills 服务)。
2411
2411
  noRegThrew === false && tools - noRegBase.tools === 22 && cmds >= 1
2412
2412
  && presetMod.presetDeliveryStatus().isolation === 'profile-fallback',
2413
2413
  `抛错=${noRegThrew}|增量 tools=${tools - noRegBase.tools} cmds=${cmds}|isolation=${presetMod.presetDeliveryStatus().isolation}`)
@@ -2697,8 +2697,8 @@ ok('npm 发布通道:发布的是**下载下来的 Release 资产**(等 .tgz
2697
2697
  // 本节测的是**管道韧性**(附加能力坏掉只该降级),与隔离无关 ⇒ 用传统档(`scope: 'profile'`)
2698
2698
  // 让能力面直接落在装入层;隔离路径的判定见 §40。
2699
2699
  try { indexMod2.apply(pipeCtx, { scope: 'profile', presetIds: ['ppt'] }) } catch (e) { applyThrew = e }
2700
- ok('§52 装配韧性:全局管道抛错时 apply 仍完成装配(22 工具 / 命令面 / 4 技能)——附加能力坏掉只该降级',
2701
- applyThrew === null && pTools === 22 && pCmds >= 1 && pSkills === 4,
2700
+ ok('§52 装配韧性:全局管道抛错时 apply 仍完成装配(22 工具 / 命令面 / 17 技能)——附加能力坏掉只该降级',
2701
+ applyThrew === null && pTools === 22 && pCmds >= 1 && pSkills === 17,
2702
2702
  `threw=${applyThrew ? String(applyThrew.message) : 'null'}|tools=${pTools} cmds=${pCmds} skills=${pSkills}`)
2703
2703
 
2704
2704
  // ③ 真宿主实测的组合顺序:webServer 比本插件**晚激活**。此时直接 `ctx.get('webServer')` 拿不到服务,
@@ -68,7 +68,7 @@ const STRICT = flag('--strict')
68
68
  const NEGATIVE = flag('--negative')
69
69
  const TIMEOUT_MS = Number(opt('--timeout', '180')) * 1000
70
70
  const EXPECT_TOOLS = Number(opt('--expect-tools', '22'))
71
- const EXPECT_SKILLS = Number(opt('--expect-skills', '4'))
71
+ const EXPECT_SKILLS = Number(opt('--expect-skills', '17'))
72
72
  const PRESET = opt('--preset', 'ppt')
73
73
  const OTHER = opt('--other', 'standard')
74
74
  const WORK_ARG = opt('--work', '')
@@ -1,5 +1,12 @@
1
+ ---
2
+ name: ppt-studio-diagram
3
+ description: 复杂图绘制总纲:何时调用哪个机制(attach/正交化/结构声明/门禁 code 对照)、12 类图的配方索引、验证纪律与坑表。
4
+ whenToUse: 要画任何非模板化的复杂图(流程/泳道/层级/时序/状态机/漏斗/环/矩阵/时间轴/对比/分层)或手画遇阻、门禁报错时加载。
5
+ ---
1
6
  # 复杂图绘制总纲(手画 + 按需查阅子 skill)
2
7
 
8
+ > **优先级**:用户指令 > 本手册经验值 > 工具默认。本手册给的是启发式与反例,**不定义任何门禁数值**;
9
+
3
10
  ## 铁律(每条都有代价换来的)
4
11
  1. **先图后数**:任何"画好了/修好了"的结论,必须**先渲染并亲眼看图**才能下;坐标与门禁数字只作辅助。
5
12
  2. **改了引擎/改了页 ⇒ 必须重出产物**(PNG/pptx)并替换到位;只改代码不重出 = 未完成。
@@ -87,3 +87,11 @@ node scripts/smoke.mjs
87
87
  - **F4 破坏性脚本先只读定位、全量断言,再动手** —— 边定位边删 ⇒「定位失败时已删一半」;范式:Phase A 打印现场 + 断言 ⇒ Phase B 执行(异常即 `git reset --hard`)。
88
88
  - **F5 多步脚本里每个判据都要单独取退出码** —— 曾在 `check-*` 子检查失败时因 `$LASTEXITCODE` 取到的是别的命令而**误提交**(后经 amend 更正)⇒ 判据不过不提交。
89
89
  - **F6 Windows 工具链三坑** —— `npm`/`tar` 是垫片 ⇒ 必须 `execSync`(`execFileSync` 直接 ENOENT);命令输出带 `\r` ⇒ 精确匹配前先去掉;检查器扫描要排除自身(词表自指)。
90
+
91
+ ## G. 发布通道坑(2026-09-30 实测)
92
+
93
+ - **G1 推 tag ≠ 发布** ✗ —— `publish.yml` 由 **`release` 事件**触发(OIDC 受信发布)⇒ 只推 `v1.2.1` 不会发;必须创建 GitHub Release。1.2.1 首次就因此静默没发(registry 停在 1.2.0)。
94
+ - **G2 别把本地 `npm publish` 的失败当发布失败** ✗ —— 本机无 npm 凭据(E401)是**设计如此**;发布判据只能是 **registry 现状**(`npm view … version`)。
95
+ - **G3 创建 Release 就等于发布** ✗ —— 未获用户明确指令不得创建 Release;撤回需**删 Release + `gh run cancel`**(本地 pack 的 tag 不会自动发)。
96
+ - **G4 skill 的 frontmatter 是 YAML** ✗ —— 描述里写 `role: decoration` 这类含 **`: `** 的纯量会导致该 skill **静默解析失败**(症状:14 个对、1 个不见)⇒ 描述里用全角「:」或加引号。
97
+ - **G5 用自己的注册器自证** ✓ —— 改完 skill 立刻跑 `bundledSkillNames()`(插件自带扫描器)确认数量与名字,**别等装到用户机器上才发现**。
@@ -1,5 +1,12 @@
1
+ ---
2
+ name: ppt-studio-diagram-compare
3
+ description: 左右对比:双列容器 + 中缝;两侧要点等宽对齐,用对比标记而不是堆字。
4
+ whenToUse: 左右对比、双栏方案比对——需要画这类图时加载;先读 skills/ppt-studio-diagram/mechanisms.md
5
+ ---
1
6
  # 左右对比(compare)· 手画配方
2
7
 
8
+ > **优先级**:用户指令 > 本手册经验值 > 工具默认。本手册给的是启发式与反例,**不定义任何门禁数值**;
9
+
3
10
  ## 骨架
4
11
  两块等宽面板(A/B)各"标题 + 要点卡";中间一个**窄**标记。
5
12
 
@@ -22,3 +29,10 @@
22
29
  - 折线交给引擎**自动正交化**;刻意斜段(环/放射/漏斗)写 `role: decoration` 或 `roleReason` 声明。
23
30
  - 箭头前直段 ≥18px 由引擎自动保证;修不了会由 `arrow-end-short-run` 报出 ⇒ **必须读警告**。
24
31
  - 收工前**逐条解释本页每一条警告**(见 verify.md 铁律之二)。
32
+
33
+
34
+ ## 收工自检(逐条过)
35
+
36
+ - 门禁 0 错;本页**每一条警告**都有处置结论(见 `verify.md` 铁律之二)。
37
+ - 连线端点与图形边重合(优先 `attach`,不手算像素);箭头前直段 ≥18px、折线只用轴对齐段。
38
+ - 容器/分组把内部元素写进 `contains`;刻意穿过或刻意留空用 `roleReason` 说明(不许掩盖真缺陷)。
@@ -1,5 +1,12 @@
1
+ ---
2
+ name: ppt-studio-diagram-flow
3
+ description: 流程图:单行/单列顺序 + 轴对齐连线;回边(如抽检不合格)走车道间隙并带标签。
4
+ whenToUse: 流程、步骤链(顺序 + 回边)——需要画这类图时加载;先读 skills/ppt-studio-diagram/mechanisms.md
5
+ ---
1
6
  # 流程图(flow)· 手画配方
2
7
 
8
+ > **优先级**:用户指令 > 本手册经验值 > 工具默认。本手册给的是启发式与反例,**不定义任何门禁数值**;
9
+
3
10
  ## 骨架
4
11
  横向流程:起止 roundRect、中间 rect;末步 accent;**异常分支用回边并标条件**。
5
12
 
@@ -22,3 +29,10 @@
22
29
  - 折线交给引擎**自动正交化**;刻意斜段(环/放射/漏斗)写 `role: decoration` 或 `roleReason` 声明。
23
30
  - 箭头前直段 ≥18px 由引擎自动保证;修不了会由 `arrow-end-short-run` 报出 ⇒ **必须读警告**。
24
31
  - 收工前**逐条解释本页每一条警告**(见 verify.md 铁律之二)。
32
+
33
+
34
+ ## 收工自检(逐条过)
35
+
36
+ - 门禁 0 错;本页**每一条警告**都有处置结论(见 `verify.md` 铁律之二)。
37
+ - 连线端点与图形边重合(优先 `attach`,不手算像素);箭头前直段 ≥18px、折线只用轴对齐段。
38
+ - 容器/分组把内部元素写进 `contains`;刻意穿过或刻意留空用 `roleReason` 说明(不许掩盖真缺陷)。
@@ -1,5 +1,12 @@
1
+ ---
2
+ name: ppt-studio-diagram-funnel
3
+ description: 漏斗/金字塔:custGeom 真梯形逐段收窄(段间严丝合缝);段内标签声明在段内。
4
+ whenToUse: 漏斗、金字塔(custGeom 梯形逐段收窄)——需要画这类图时加载;先读 skills/ppt-studio-diagram/mechanisms.md
5
+ ---
1
6
  # 漏斗(funnel)· 手画配方
2
7
 
8
+ > **优先级**:用户指令 > 本手册经验值 > 工具默认。本手册给的是启发式与反例,**不定义任何门禁数值**;
9
+
3
10
  ## 骨架
4
11
  用 **custGeom 梯形**逐段收窄(矩形堆叠是台阶,不是漏斗)。
5
12
 
@@ -23,3 +30,10 @@ path:w:800、h:70;moveTo[(800−wTop)/2,0] → lnTo[(800+wTop)/2,0] → lnTo
23
30
  - 折线交给引擎**自动正交化**;刻意斜段(环/放射/漏斗)写 `role: decoration` 或 `roleReason` 声明。
24
31
  - 箭头前直段 ≥18px 由引擎自动保证;修不了会由 `arrow-end-short-run` 报出 ⇒ **必须读警告**。
25
32
  - 收工前**逐条解释本页每一条警告**(见 verify.md 铁律之二)。
33
+
34
+
35
+ ## 收工自检(逐条过)
36
+
37
+ - 门禁 0 错;本页**每一条警告**都有处置结论(见 `verify.md` 铁律之二)。
38
+ - 连线端点与图形边重合(优先 `attach`,不手算像素);箭头前直段 ≥18px、折线只用轴对齐段。
39
+ - 容器/分组把内部元素写进 `contains`;刻意穿过或刻意留空用 `roleReason` 说明(不许掩盖真缺陷)。
@@ -1,5 +1,12 @@
1
+ ---
2
+ name: ppt-studio-diagram-layers
3
+ description: 分层架构:层芯片 + 层带 + 居中箭头;层内一行排布,层间关系用标签写清。
4
+ whenToUse: 分层架构、技术栈(层芯片 + 层带)——需要画这类图时加载;先读 skills/ppt-studio-diagram/mechanisms.md
5
+ ---
1
6
  # 分层架构(layers)· 手画配方
2
7
 
8
+ > **优先级**:用户指令 > 本手册经验值 > 工具默认。本手册给的是启发式与反例,**不定义任何门禁数值**;
9
+
3
10
  ## 骨架
4
11
  左侧**层标签芯片**(窄条)+ 右侧**层内容带**(长条,软填充),自上而下 N 层;层间用竖直箭头表示"上行/下行"。
5
12
  - 标题 (60,34);层带 x=150,w=740,h=72,y=130 起,层距 88。
@@ -16,3 +23,10 @@
16
23
  ## 验收清单
17
24
  - [ ] 每层"芯片 + 带 + 带内卡片"三层包含关系都声明;[ ] 层间箭头两端贴带边;
18
25
  - [ ] 看图能一眼数清层数;[ ] 带内文字对比度 ≥3:1(浅底用深字)。
26
+
27
+
28
+ ## 收工自检(逐条过)
29
+
30
+ - 门禁 0 错;本页**每一条警告**都有处置结论(见 `verify.md` 铁律之二)。
31
+ - 连线端点与图形边重合(优先 `attach`,不手算像素);箭头前直段 ≥18px、折线只用轴对齐段。
32
+ - 容器/分组把内部元素写进 `contains`;刻意穿过或刻意留空用 `roleReason` 说明(不许掩盖真缺陷)。
@@ -1,5 +1,12 @@
1
+ ---
2
+ name: ppt-studio-diagram-loop
3
+ description: 闭环反馈:环形排布 + 环外折线;斜段属设计意图,用 roleReason 声明;环内连线要顺。
4
+ whenToUse: 闭环、反馈回路(环形排布 + 环外折线)——需要画这类图时加载;先读 skills/ppt-studio-diagram/mechanisms.md
5
+ ---
1
6
  # 闭环(loop)· 手画配方
2
7
 
8
+ > **优先级**:用户指令 > 本手册经验值 > 工具默认。本手册给的是启发式与反例,**不定义任何门禁数值**;
9
+
3
10
  ## 骨架
4
11
  N 个步骤卡沿**椭圆环**分布,箭头沿环指向下一步;环心留空(放文字会被线压)。
5
12
 
@@ -23,3 +30,10 @@ N 个步骤卡沿**椭圆环**分布,箭头沿环指向下一步;环心留
23
30
  - 折线交给引擎**自动正交化**;刻意斜段(环/放射/漏斗)写 `role: decoration` 或 `roleReason` 声明。
24
31
  - 箭头前直段 ≥18px 由引擎自动保证;修不了会由 `arrow-end-short-run` 报出 ⇒ **必须读警告**。
25
32
  - 收工前**逐条解释本页每一条警告**(见 verify.md 铁律之二)。
33
+
34
+
35
+ ## 收工自检(逐条过)
36
+
37
+ - 门禁 0 错;本页**每一条警告**都有处置结论(见 `verify.md` 铁律之二)。
38
+ - 连线端点与图形边重合(优先 `attach`,不手算像素);箭头前直段 ≥18px、折线只用轴对齐段。
39
+ - 容器/分组把内部元素写进 `contains`;刻意穿过或刻意留空用 `roleReason` 说明(不许掩盖真缺陷)。
@@ -1,5 +1,12 @@
1
+ ---
2
+ name: ppt-studio-diagram-matrix
3
+ description: 矩阵/象限:行列网格 + 表头(cols/rowLabels/colLabels),每格一张卡,表头与轴说明写清。
4
+ whenToUse: 矩阵、象限、行列网格 + 表头——需要画这类图时加载;先读 skills/ppt-studio-diagram/mechanisms.md
5
+ ---
1
6
  # 矩阵(matrix)· 手画配方
2
7
 
8
+
9
+ > **优先级**:用户指令 > 本手册经验值 > 工具默认。
3
10
  ## 骨架
4
11
  **列 = 处置力度,行 = 频次**;每个条目独占一格(别用通用象限名代替处置档,否则丢信息维度)。
5
12
 
@@ -21,3 +28,10 @@
21
28
  - 折线交给引擎**自动正交化**;刻意斜段(环/放射/漏斗)写 `role: decoration` 或 `roleReason` 声明。
22
29
  - 箭头前直段 ≥18px 由引擎自动保证;修不了会由 `arrow-end-short-run` 报出 ⇒ **必须读警告**。
23
30
  - 收工前**逐条解释本页每一条警告**(见 verify.md 铁律之二)。
31
+
32
+
33
+ ## 收工自检(逐条过)
34
+
35
+ - 门禁 0 错;本页**每一条警告**都有处置结论(见 `verify.md` 铁律之二)。
36
+ - 连线端点与图形边重合(优先 `attach`,不手算像素);箭头前直段 ≥18px、折线只用轴对齐段。
37
+ - 容器/分组把内部元素写进 `contains`;刻意穿过或刻意留空用 `roleReason` 说明(不许掩盖真缺陷)。
@@ -1,5 +1,12 @@
1
+ ---
2
+ name: ppt-studio-diagram-sequence
3
+ description: 时序图:参与者盒 + 生命线 + 水平消息箭头;生命线用虚线与窄矩形,标签用白底芯片遮罩。
4
+ whenToUse: 时序、消息序列(生命线 + 水平消息箭头)——需要画这类图时加载;先读 skills/ppt-studio-diagram/mechanisms.md
5
+ ---
1
6
  # 时序图(sequence)· 手画配方
2
7
 
8
+ > **优先级**:用户指令 > 本手册经验值 > 工具默认。本手册给的是启发式与反例,**不定义任何门禁数值**;
9
+
3
10
  ## 骨架
4
11
  顶部一排**参与者头卡**(等宽)+ 每人一条**虚线生命线**(垂直到页底)+ 自上而下的**消息箭头**(实线,标签在箭头上方)。
5
12
  - 标题 (60,34);头卡 w=170,h=48,y=110,x=70 起,间距 35(4 人占 70..890)。
@@ -15,3 +22,10 @@
15
22
 
16
23
  ## 验收清单
17
24
  - [ ] 每条消息能读出"谁→谁、什么消息";[ ] 生命线不被文字压;[ ] 头和生命线同一条 x 中心。
25
+
26
+
27
+ ## 收工自检(逐条过)
28
+
29
+ - 门禁 0 错;本页**每一条警告**都有处置结论(见 `verify.md` 铁律之二)。
30
+ - 连线端点与图形边重合(优先 `attach`,不手算像素);箭头前直段 ≥18px、折线只用轴对齐段。
31
+ - 容器/分组把内部元素写进 `contains`;刻意穿过或刻意留空用 `roleReason` 说明(不许掩盖真缺陷)。
@@ -1,5 +1,12 @@
1
+ ---
2
+ name: ppt-studio-diagram-state
3
+ description: 状态机:BFS 分层 + 列间走廊 + 转移总线(回边不做特例);每条转移都要有标签。
4
+ whenToUse: 状态机、状态转移(分层 + 转移总线)——需要画这类图时加载;先读 skills/ppt-studio-diagram/mechanisms.md
5
+ ---
1
6
  # 状态机(state)· 手画配方
2
7
 
8
+ > **优先级**:用户指令 > 本手册经验值 > 工具默认。本手册给的是启发式与反例,**不定义任何门禁数值**;
9
+
3
10
  ## 骨架
4
11
  横向一行状态卡 + 卡间箭头 + **回边(返工/异常)走卡片外侧车道**;或竖向一列(见下)。
5
12
  - 5 状态:卡 150×84,y=240,x=60 起,间距 20 ⇒ 卡心 y=282,卡底 y=324。
@@ -32,3 +39,10 @@
32
39
  - 折线交给引擎**自动正交化**;刻意斜段(环/放射/漏斗)写 `role: decoration` 或 `roleReason` 声明。
33
40
  - 箭头前直段 ≥18px 由引擎自动保证;修不了会由 `arrow-end-short-run` 报出 ⇒ **必须读警告**。
34
41
  - 收工前**逐条解释本页每一条警告**(见 verify.md 铁律之二)。
42
+
43
+
44
+ ## 收工自检(逐条过)
45
+
46
+ - 门禁 0 错;本页**每一条警告**都有处置结论(见 `verify.md` 铁律之二)。
47
+ - 连线端点与图形边重合(优先 `attach`,不手算像素);箭头前直段 ≥18px、折线只用轴对齐段。
48
+ - 容器/分组把内部元素写进 `contains`;刻意穿过或刻意留空用 `roleReason` 说明(不许掩盖真缺陷)。
@@ -1,5 +1,12 @@
1
+ ---
2
+ name: ppt-studio-diagram-steps-ring
3
+ description: 步骤环:真圆 + 圆周编号点(更雅,优先)或卡片环(更快);点与圆同心、标签留 ≥24px。
4
+ whenToUse: 步骤环(真圆+编号点 或 卡片环)——需要画这类图时加载;先读 skills/ppt-studio-diagram/mechanisms.md
5
+ ---
1
6
  # 步骤环(steps-ring)· 手画配方
2
7
 
8
+ > **优先级**:用户指令 > 本手册经验值 > 工具默认。本手册给的是启发式与反例,**不定义任何门禁数值**;
9
+
3
10
  ## 两种画法
4
11
  1. **卡片环**(快):N 张卡沿椭圆分布 + 沿环直箭头(数值见 loop.md)。
5
12
  2. **真圆 + 编号点**(更雅,旧版用的,**优先**):ellipse 浅填充+主色描边 + 圆周上编号小圆点 + 圆外标签。
@@ -22,3 +29,10 @@
22
29
  - 折线交给引擎**自动正交化**;刻意斜段(环/放射/漏斗)写 `role: decoration` 或 `roleReason` 声明。
23
30
  - 箭头前直段 ≥18px 由引擎自动保证;修不了会由 `arrow-end-short-run` 报出 ⇒ **必须读警告**。
24
31
  - 收工前**逐条解释本页每一条警告**(见 verify.md 铁律之二)。
32
+
33
+
34
+ ## 收工自检(逐条过)
35
+
36
+ - 门禁 0 错;本页**每一条警告**都有处置结论(见 `verify.md` 铁律之二)。
37
+ - 连线端点与图形边重合(优先 `attach`,不手算像素);箭头前直段 ≥18px、折线只用轴对齐段。
38
+ - 容器/分组把内部元素写进 `contains`;刻意穿过或刻意留空用 `roleReason` 说明(不许掩盖真缺陷)。
@@ -1,5 +1,12 @@
1
+ ---
2
+ name: ppt-studio-diagram-swimlane
3
+ description: 复杂图配方(swimlane):按 ppt-studio-diagram 总纲选用,含骨架/数值/专属坑/验收清单。
4
+ whenToUse: 需要画这一类复杂图时加载;先读 ppt-studio-diagram(何时调用哪个机制 / 验证纪律 / 坑表)。
5
+ ---
1
6
  # 泳道图(swimlane)· 手画配方
2
7
 
8
+ > **优先级**:用户指令 > 本手册经验值 > 工具默认。本手册给的是启发式与反例,**不定义任何门禁数值**;
9
+
3
10
  ## 骨架
4
11
  左泳道名芯片 + 右侧泳道带;任务卡按角色落到对应道;跨道连线允许穿带(**必须声明**)。
5
12
 
@@ -21,3 +28,10 @@
21
28
  - 折线交给引擎**自动正交化**;刻意斜段(环/放射/漏斗)写 `role: decoration` 或 `roleReason` 声明。
22
29
  - 箭头前直段 ≥18px 由引擎自动保证;修不了会由 `arrow-end-short-run` 报出 ⇒ **必须读警告**。
23
30
  - 收工前**逐条解释本页每一条警告**(见 verify.md 铁律之二)。
31
+
32
+
33
+ ## 收工自检(逐条过)
34
+
35
+ - 门禁 0 错;本页**每一条警告**都有处置结论(见 `verify.md` 铁律之二)。
36
+ - 连线端点与图形边重合(优先 `attach`,不手算像素);箭头前直段 ≥18px、折线只用轴对齐段。
37
+ - 容器/分组把内部元素写进 `contains`;刻意穿过或刻意留空用 `roleReason` 说明(不许掩盖真缺陷)。
@@ -1,5 +1,12 @@
1
+ ---
2
+ name: ppt-studio-diagram-timeline
3
+ description: 时间轴/里程碑:水平主轴 + 圆点 + 上下交替标签;轴说明与关键里程碑的高亮取舍。
4
+ whenToUse: 时间轴、里程碑(水平轴 + 上下交替标签)——需要画这类图时加载;先读 skills/ppt-studio-diagram/mechanisms.md
5
+ ---
1
6
  # 时间轴(timeline)· 手画配方
2
7
 
8
+ > **优先级**:用户指令 > 本手册经验值 > 工具默认。本手册给的是启发式与反例,**不定义任何门禁数值**;
9
+
3
10
  ## 骨架
4
11
  水平主轴 + 等距里程碑点 + 标签**上下交替**。
5
12
 
@@ -22,3 +29,10 @@
22
29
  - 折线交给引擎**自动正交化**;刻意斜段(环/放射/漏斗)写 `role: decoration` 或 `roleReason` 声明。
23
30
  - 箭头前直段 ≥18px 由引擎自动保证;修不了会由 `arrow-end-short-run` 报出 ⇒ **必须读警告**。
24
31
  - 收工前**逐条解释本页每一条警告**(见 verify.md 铁律之二)。
32
+
33
+
34
+ ## 收工自检(逐条过)
35
+
36
+ - 门禁 0 错;本页**每一条警告**都有处置结论(见 `verify.md` 铁律之二)。
37
+ - 连线端点与图形边重合(优先 `attach`,不手算像素);箭头前直段 ≥18px、折线只用轴对齐段。
38
+ - 容器/分组把内部元素写进 `contains`;刻意穿过或刻意留空用 `roleReason` 说明(不许掩盖真缺陷)。
@@ -1,5 +1,12 @@
1
+ ---
2
+ name: ppt-studio-diagram-tree
3
+ description: 层级树/组织图:根居中、一级一行、叶一行;正交折线 + 箭头;同组子树要有分组容器。
4
+ whenToUse: 层级树、组织图、分组子树(正交折线 + 分组容器)——需要画这类图时加载;先读 skills/ppt-studio-diagram/mechanisms.md
5
+ ---
1
6
  # 层级树(tree)· 手画配方
2
7
 
8
+ > **优先级**:用户指令 > 本手册经验值 > 工具默认。本手册给的是启发式与反例,**不定义任何门禁数值**;
9
+
3
10
  ## 骨架
4
11
  根居顶中 → 一级一行 → 叶一行;连线用**正交折线 + 箭头**。
5
12
 
@@ -22,3 +29,10 @@
22
29
  - 折线交给引擎**自动正交化**;刻意斜段(环/放射/漏斗)写 `role: decoration` 或 `roleReason` 声明。
23
30
  - 箭头前直段 ≥18px 由引擎自动保证;修不了会由 `arrow-end-short-run` 报出 ⇒ **必须读警告**。
24
31
  - 收工前**逐条解释本页每一条警告**(见 verify.md 铁律之二)。
32
+
33
+
34
+ ## 收工自检(逐条过)
35
+
36
+ - 门禁 0 错;本页**每一条警告**都有处置结论(见 `verify.md` 铁律之二)。
37
+ - 连线端点与图形边重合(优先 `attach`,不手算像素);箭头前直段 ≥18px、折线只用轴对齐段。
38
+ - 容器/分组把内部元素写进 `contains`;刻意穿过或刻意留空用 `roleReason` 说明(不许掩盖真缺陷)。