@ccoalm/ccl-skills 0.4.0 → 0.6.0

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 (61) hide show
  1. package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/references/public-data-acquisition.md +3 -1
  2. package/dist/assets/marketplace/plugins/ccl-skills/skills/multi-perspective-research/references/public-disclosure-channels.md +2 -0
  3. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/SKILL.md +4 -4
  4. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/dual-track-review-gate.md +8 -0
  5. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/external-practice-controls.md +12 -0
  6. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/firing-point-placement.md +8 -0
  7. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/references/source-register.md +20 -0
  8. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/check-ccl-skills.sh +12 -1
  9. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_check_ccl_regressions.sh +6 -0
  10. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_ci_checkout_ref_binding.sh +85 -0
  11. package/dist/assets/marketplace/plugins/ccl-skills/skills/skill-extraction-workflow/scripts/test_entrypoint_domain_scan_terms.sh +123 -0
  12. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/SKILL.md +4 -4
  13. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/deliverable-doc-genre-skeletons.md +133 -0
  14. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/doc-charter-first.md +2 -0
  15. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/references/figure-and-table-craft.md +345 -0
  16. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/AGENTS.md +46 -0
  17. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/doc-lint-repo.py +203 -0
  18. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/doc-lint.py +246 -0
  19. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/figure-lint.py +1092 -0
  20. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/mutation_probe.sh +100 -0
  21. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/test_doc_lint_repo.py +420 -0
  22. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/test_figure_and_doc_lint.sh +375 -0
  23. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/control.md +10 -0
  24. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/empty-header.md +6 -0
  25. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/fake-header.md +13 -0
  26. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/fenced-noise.md +14 -0
  27. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/fig-dangling.md +5 -0
  28. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/fig-orphan-captioned.md +11 -0
  29. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/fig-orphan.md +9 -0
  30. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/fig.png +0 -0
  31. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/imbalance.md +41 -0
  32. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/no-unit.md +8 -0
  33. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/should-be-chart.md +11 -0
  34. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/tables-only-clean.md +35 -0
  35. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/unfilled.md +7 -0
  36. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/doc/wide-table.md +5 -0
  37. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/bad-viewbox.svg +9 -0
  38. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/blackmarker.svg +9 -0
  39. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/control.svg +12 -0
  40. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/crossings.svg +12 -0
  41. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/cvd-confusable.svg +9 -0
  42. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/decorative-line.svg +10 -0
  43. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/edge-no-arrow.svg +11 -0
  44. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/edge-vague.svg +12 -0
  45. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/figure-contract.json +21 -0
  46. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/figure-is-a-list.svg +12 -0
  47. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/flow-mixed.svg +13 -0
  48. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/low-contrast.svg +12 -0
  49. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/malformed.svg +1 -0
  50. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/no-aria.svg +9 -0
  51. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/no-group.svg +10 -0
  52. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/no-legend.svg +9 -0
  53. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/no-title.svg +12 -0
  54. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/no-viewbox.svg +9 -0
  55. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/offcontract-shape.svg +13 -0
  56. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/overflow.svg +13 -0
  57. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/transformed.svg +9 -0
  58. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/ungrouped-card.svg +12 -0
  59. package/dist/assets/marketplace/plugins/ccl-skills/skills/tighten-doc/scripts/tests/svg/unlabeled-edge.svg +13 -0
  60. package/dist/assets/release.json +254 -14
  61. package/package.json +1 -1
@@ -0,0 +1,133 @@
1
+ # Deliverable Doc Genre Skeletons(交付型文档的文体族骨架)
2
+
3
+ 交付型文档不是一个体裁。**族判错,骨架就错,之后每一轮打磨都在补首稿本该有的节。** 本文件管三件事:判族、每族首稿必答项与表示形式、可判定的验收。
4
+
5
+ 本文件持有:**族判定**、**跨族的形态规则**(§0 §3 §4 §5 §6)与**方案 / 架构族的必答项**;调研族与现状族的必答项由 `multi-perspective-research` 与 `requirement-baseline` 各自持有,本文件只路由、不复述、也不代它们做完整性判定。文档的**实质**仍归各自 owner。不管:措辞与句子层定稿(本技能 `SKILL.md`)、调研执行本身(`multi-perspective-research`)、单个决定的记录格式与规范族的层级同步闸(均归 `product-rd-workflow`,分别是其 adr-convention 与 rd-standards-doc-family-checklist 参考)。
6
+
7
+ > **全局边界(本文件每一条都受它约束)**:本文件描述交付型文档**应有的形态**,不是授权改动文档集。起草新文档时按这些形态起稿;面对**已存在**的文档,形态不符只产出**标记与建议**——创建、拆分、合并、重排兄弟文档,或把单篇扩成文档族,一律由实质 owner 决定(spec / standards / guideline 族按 `product-rd-workflow` 的 `owner-ready` 闸)。下文出现的「分册」「成族」「拆」均按此读:**是目标形态的描述,不是自授的动作许可**。
8
+
9
+ ## §0 两个分类轴
10
+
11
+ 两轴**不互斥**,一份文档可以同时沾两边(如一份现状说明既描述已建成的系统,又要支撑一个尚未做的决定)。判**主导用途**:读者拿它主要是去**用**那件已存在的东西,还是去**决定/执行**尚未做完的事。两者都真实存在时,**交付面的族骨架为准**(它决定必答节与分册),使用者面的模式只用来决定相关段落内部的写法。
12
+
13
+ | 轴 | 读者在做什么 | 分类 |
14
+ |---|---|---|
15
+ | 使用者面 | 用一件**已存在**的东西 | Diataxis 四模式:**tutorial**(learning by doing)· **how-to**(recipe for one task)· **reference**(look up exact facts)· **explanation**(understand why)|
16
+ | 交付面 | 据此**决定或执行一件尚未做完的事** | 本文件 §1 的五族:方案·架构 / 调研 / 现状梳理 / 评审 / 计划 |
17
+
18
+ 使用者面的既有纪律(从 `SKILL.md` 移来,义务不变):
19
+
20
+ - **每份文档保持一个主导模式**,并盯住 **muddled purpose**——一份文档同时想当完整 tutorial *和*完整 reference,两类读者都服务不好;失败的是这个,不是一份 how-to 里嵌一张紧凑的选项/环境变量表。
21
+ - 四模式是**用来发现混杂的判据**,不是自顶向下强行拆成四份文档的计划。
22
+ - `SKILL.md` 的一页纸操作手册默认形态属于 how-to / reference;tutorial 与 explanation 天然不同,别硬套。
23
+ - **这一步仍在定稿范围内**:**只标记 reader-mode 拆分候选,不得在实质 owner 定下文档集之前创建、拆分、重排兄弟文档,也不得路由文档生成**(spec / standards / guideline 族的 owner 是 `product-rd-workflow`,按其 `owner-ready` 闸)——文档生成类技能只是执行器,永不替代 owner。
24
+
25
+ 交付面同理:族判定与分册是**形态判断**,实质仍归各族 owner。
26
+
27
+ ## §1 先判族
28
+
29
+ | 族 | 读者要用它做什么 | 判据 |
30
+ |---|---|---|
31
+ | 方案 / 架构 | 批准或否决一个尚未建成的做法 | 主张「应该怎么做」,实现尚未发生 |
32
+ | 调研 / 研究 | 在不确定中形成判断 | 主张「外部世界是什么样」,结论由证据强度限定 |
33
+ | 现状 / 梳理 | 知道现在怎么运作、缺口在哪 | 主张「已经是什么样」,可被当前系统证否 |
34
+ | 评审 / 发现 | 判每条问题真不真、要不要排期 | 主张「哪里不对」,逐条可裁决 |
35
+ | 计划 / 整改 | 认领与排期 | 主张「谁在什么阶段做什么」 |
36
+
37
+ 混族的判据不是「出现了两族的内容」,而是**两族的读者与要做的决定不同,却共用一套骨架**——它是「读者读不下去、反复要求重写」最常见的根因。同一条决策链上的相邻族可以同篇(如评审结论后接 owner 已认领的整改条目),但**每段仍按各自族的骨架写**,不混成一套。读者与决定确实分叉时,起草阶段就分开写;已成篇的按全局边界只标记不自行改。
38
+
39
+ ## §2 每族首稿必答项(起草阶段用;缺一项通常预定一轮返工)
40
+
41
+ **作用阶段**:起草新文档时按此清单起稿。**对已成稿的文档做润色时,本清单只用来「标记缺项候选」交实质 owner**——不据此判文档不合规、不据此把润色请求扩成结构返工;实质完整性的裁决权在方案 owner,不在定稿技能。
42
+
43
+ **方案 / 架构族:**(下列是**承载多个决定与实施路径**的方案文档的必答项。只记录单个决定的短稿用 ADR,归 `product-rd-workflow` 的 adr-convention 参考;起草时对不适用项宜写「不适用 + 理由」而非静默省略——省略与判定不适用在评审席上不是一回事;但这是起草建议,不是对既有文档的合规判据。)
44
+
45
+ - **定位与命题定性**:这是设计稿还是已建成描述;本次变更的性质用一个词定死(新建 / 并行 / 替换 / 迁移 / 下线),并列出被误用就会引发全篇返工的**禁用词**。命题设错的返工代价与篇幅成正比,是本族最贵的一类。
46
+ - **非目标**:明确不做什么。业界骨架把它与目标并列为必备节,不是补充说明。
47
+ - **备选与落选理由**:每个候选连同「为什么没选它」;候选若只是陪跑(对照 / 谈判锚),把这个角色写出来。
48
+ - **决策性章节按三段写**:结论(这一层定成什么样)→ 约束(哪些是硬的,越过就出问题)→ 动作(谁 · 哪阶段)。描述性章节(非目标、术语与口径、外部先例、本方案代价)不套这三段,它们不产生动作。
49
+ - **开放决策带闸**:未关闭的决策单列,写明它阻塞什么(如「未关闭不进入实现」)。开放项不是留给下一轮打磨去补的,是首稿就该显式挂起的。
50
+ - **本方案自身的代价**:选定这条路要付出什么、会变差的是什么。与「备选与落选理由」不同——那条讲别的路为什么不选,这条讲**选定的这条路的坏处**;评审席上问不出答案的多半是这一节缺了。
51
+ - **外部先例**:同类问题别人怎么解决的、结果如何、与本处约束的差异。缺这一节最典型的返工触发是评审时被问「参考业界实践了么」。
52
+ - **质量目标与验收场景**:本次要达成的质量属性排序(不是罗列全部),每条给可判定的验收场景;属性口径与取舍归 `product-rd-workflow` 的 quality-attributes 参考,此处只要求它在首稿出现。
53
+ - **术语与口径表**:本文中含义被限定的词逐条定义;上面的**禁用词表是它的一个特例**(被误用会引发全篇返工的那些词)。
54
+ - **退出与降级**:做错了怎么退。
55
+
56
+ **调研 / 研究族**:骨架与执行归 `multi-perspective-research`(estimand、覆盖矩阵与关闭条件、渠道走查、矛盾图、未解清单、自评、多轮 program 节拍),本文件不重述。族间约束:调研结论被引入方案族文档时降为「依据」并附其证据状态,不得升格为方案的结论。
57
+
58
+ **现状 / 梳理族**:归 `requirement-baseline`。族间约束:现状与目标分成两份文档;目标文档首句写明「不代表当前生产能力」并指向现状文档。
59
+
60
+ **评审 / 发现族**:**去重前的原始发现进工作底稿**(去重、归并、定级都是加工,加工前的记录要留得住),按 §3 运作——该族最容易触发 §3 的**写入前置**,因为原始发现常含身份线索与凭据。结论面放**待裁决项**与**已裁决结果**(裁决、依据、责任人、下一步),不放未经核实的原始发现。
61
+
62
+ **计划 / 整改族**:先写**目标与范围**(这轮要达成什么、明确不含什么)、**依赖与前置**(谁挡着谁、外部依赖)、**风险与应对**;再是条目表,每条带 owner、阶段、完成判据——**没有完成判据的条目不进计划**。只有条目表而没有前三项的,是任务清单不是计划。
63
+
64
+ ## §3 结论先行,证据归卷
65
+
66
+ **正文按结论先行组织**:顶层一个主论点(读者只记住一句话时记住的那句)→ 其下若干组支撑论点,同组之间尽量互斥、合起来回答上一层 → 证据在底层。组数**服从内容**:常见是 2–3 组,一组说明没有真正分组、组数过多说明还能再归并,但**不为凑数硬并或硬拆**——真有四个不可合并的风险域就写四组,只有一个足以承重的理由就写一组。分组不得挤掉任何一个已识别的关切(见 §5)。所谓「一页纸」是这个结构的**结果**,不是独立规则;页数不是判据,**能不能一句话说清主张、且每层都真的在支撑上一层**才是。
67
+
68
+ **证据与过程归到独立的一册(工作底稿),按**下表**运作——这些判据借自审计底稿的成文要求(见 §7),本文只借判据,不主张交付文档等同审计:
69
+
70
+ | 判据 | 含义 |
71
+ |---|---|
72
+ | 写入前置 | **先判敏感级,再决定要不要前置**:公开材料与非敏感的过程记录直接写入,无额外义务。**只有敏感 / 受控材料**才在复制之前定留存期、按最小必要裁剪(身份线索按需假名化并单独限权),**不能先全量落盘再回头治理**——第一份副本就已经形成暴露面。凭据与受控材料**不写入会被广泛分发的面**。**本文件到此为止**:收集是否合规、留存是否合法、发现问题后报给谁、要不要吊销或删除,都是安全 / 合规判断与运行态动作,归组织既有的安全与事件响应流程及 `feature-risk-router` 的安全评审闸;文档侧不自行认定违规、不自行吊销或删改既有材料,存疑时暂停扩大分发并交 owner |
73
+ | 收录标准 | **一个未参与本工作、有经验的同行,能据此册重建:做了什么、取到什么证据、如何得出结论**。够不够不由作者的感觉判,由这条判 |
74
+ | 归卷 | 证据册**限期归卷成册**(随交付定稿一并封版);归卷后不再随手增删,**事后的更正本身要留痕**(改了什么、为什么、谁改的),不覆盖原记录 |
75
+ | 保管 | 对**有权保留**的材料,处置是**受控保管**——保密、完整性、可取回三者同时成立——**而不是丢弃唯一证据**;给不了保管条件时暂停写入,把保管方案交由风险 / 数据 owner 决定,作者不自行开通存储或变更权限。留存期限与删除义务(法定、合同、当事人要求)由该 owner 与组织合规流程裁定,本文件不代判 |
76
+
77
+ **访问面由内容决定,不由册名决定**(按册名列清单必然漏):任何一册装了什么就按什么定分发面,正文与摘要页同样受此约束,敏感内容不因为「这是给决策者看的那页」而获得更宽的分发面。凭据类按上表「写入前置」处置(绝不为「保留原始」在册中留下可用凭据);正文中指向受控册的**指针本身也受此约束**——只写既不泄露内容、也不构成访问凭据的指针(受控系统内的记录号、保管人与申请流程),不写直链、带访问参数的 URL、或路径与标题本身即透露内容的定位。**可回查不等于可传播,定位不等于可访问。**
78
+
79
+ 分成几册由内容与读者决定,常见落点是:正文(结论·约束·动作)、工作底稿(证据与过程)、细则(某一层的实施步骤)、明细(逐条发现或定量明细)。**分册规则要在首稿就写下来**,否则「这段该不该进正文」每轮都要重吵一次——这是反复润色的主要来源之一。分册是目标形态的描述,动手改已存在的文档集仍按开头的全局边界。
80
+
81
+ ## §4 表示形式随族定
82
+
83
+ **下表列的是候选,不是必备清单。** 画哪几张由**要承载的主张**决定——有部署差异才画部署图,有跨组件时序才画时序图,没有就不画;缺某张图**不构成形态不合规**。硬约束一列约束的是**画了的图必须怎样**,不是必须画什么。
84
+
85
+ | 族 | 主形态 | 硬约束 |
86
+ |---|---|---|
87
+ | 方案 / 架构 | 分层图(上下文 → 容器 → 组件)、部署拓扑、时序、数据流 | **一张图一个抽象层,不混层**;每层对应一类受众 |
88
+ | 调研 | 常见落点:证据集形成流程图(识别 / 筛除及其理由与计数)、关系结构图、分布定位图 | 是否需要图、需要哪几张由 `multi-perspective-research` 裁定;本表只提供候选,不据此判该族文档不合规 |
89
+ | 现状 / 梳理 | 缺口表;主张涉及规模 / 趋势时再加定量明细与仪表盘 | 每格可追到取证时点;定性盘点不必凑定量件 |
90
+ | 评审 | 结论面(待裁决项 + 已裁决结果)、明细 | 结论面不放**未经核实**的原始发现——后者进工作底稿,按 §3 运作 |
91
+ | 计划 / 整改 | 阶段甘特或里程碑表、依赖关系图 | 每条可认领:有 owner、阶段与完成判据;没有完成判据的条目不上图 |
92
+
93
+ 图的**承载位置与格式**(原生画板 / 图片 / 源文件加导出件)在首稿一并定死;多载体时的载体登记与同步义务归 `multi-perspective-research` 的多轮 program 节。**同批一并冻结版式契约**(画布比例、字号阶梯、色 token 及其对比度、单格文本上限、分组单元)——一致性是外部要求,冻结成哪几档是团队自选,契约缺失则一致性不可判定。
94
+
95
+ **这张表定「画哪几张」,不定「画成什么样」**:图种由主张形态推出(有无显式事件触发)、画了必须满足的记法硬约束、调研族图上实体的回指要求、版式契约与目标端渲染保真,见同目录 `figure-and-table-craft.md`。
96
+
97
+ ## §5 可判定的验收(替代「写得好不好」)
98
+
99
+ - (§5 的验收面向**本文件持有的族**;调研与现状族按其 owner 的完成标准判。)
100
+ - **关切覆盖**:列出干系人与各自关切,**每个关切至少被一个视图或章节回答**——架构描述标准的核心一致性要求,也是最容易机械查的完整性判据。
101
+ - **断言可裁决**:每条载重结论的证据状态显式(来源陈述 / 推论 / 作者判断);分级口径归 `tighten-doc`。
102
+ - **开放项显式**:未关闭项的数量与其阻塞对象可数。
103
+ - **动作可认领**:每条动作有 owner、阶段与完成判据(三者缺一即不可认领)。
104
+ - **表示形式合规**:**已经画出来的图**逐张过 §4 的硬约束(是否混层、是否回答了它该回答的问题);**不以「少了哪张图」判不合规**。调研与现状族的完整性仍按其 owner 的完成标准判。**图级验收测试**:这张图能否脱离正文被独立看懂——把图单独给没读过正文的人,他能否说出图在主张什么;不能就是图没画完。可机械判定的部分(对比度、文本溢出、图例与连线标签缺失、分组、契约偏离、表格真表头、载体错配、图文引用一致)由 `../scripts/figure-lint.py` 与 `../scripts/doc-lint.py` 挡,判据与其档位见 `figure-and-table-craft.md`;检查器本身按该文件 §8 先自测能报失败再信其绿。
105
+
106
+ ## §6 修订与润色不是一件事
107
+
108
+ 全局修订(命题、结构、证据、分册)先于局部润色(措辞、格式),顺序不可倒。**在命题或分册未定时做的润色轮,会被下一次结构变更整段推翻**——它记在账上是「润色轮」,实际是修订轮。这是「几乎每份文档都要反复润色」最常见的机制。判据:本轮在改「说什么」还是「怎么说」;只要还在改「说什么」,就不进润色。
109
+
110
+ 首稿前锁定读者 / 用途 / 载体 / 篇幅预算的 doc charter 见同目录 `doc-charter-first.md`;本文件是那张 charter 表里 **Genre** 一格的展开。
111
+
112
+ ## §7 外部来源
113
+
114
+ - **Malte Ubl**, "Design Docs at Google" — <https://www.industrialempathy.com/posts/design-docs-at-google/>— goals + **non-goals**、**alternatives considered 及未选原因**列为设计文档骨架必备节
115
+ - **Michael Nygard**, "Documenting Architecture Decisions"(2011-11-15)— <https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions>— 单个决定的记录格式;本文件不重述,归 `product-rd-workflow` 的 adr-convention 参考
116
+ - **公开 RFC 提案模板** — <https://github.com/rust-lang/rfcs/blob/master/0000-template.md>;Prior art 一节由 RFC 2333 补入 <https://rust-lang.github.io/rfcs/2333-prior-art.html>— motivation / drawbacks / rationale and alternatives / prior art / unresolved questions;本文件据此补入「本方案自身的代价」与「外部先例」两项必答节
117
+ - **ISO/IEC/IEEE 42010** Architecture description(2nd ed. 2022)— 概念模型 <https://www.iso-architecture.org/42010/cm/>— 干系人 / 关切 / 视角 / 视图;一致性要求为每个被识别的关切至少被一个视角框定
118
+ - **arc42** 架构文档模板 — <https://arc42.org/overview/>(12 节:引言与目标 / 约束 / 上下文与范围 / 解决方案策略 / 构件视图 / 运行时视图 / 部署视图 / 横切概念 / 架构决策 / 质量需求 / 风险与技术债 / 术语表)— 本文件 §2 的必答项按它做过交叉校验,据此补入「质量目标与验收场景」「术语与口径表」两项;本文件不搬它的 12 节编号(那是模板,不是最小必答集)
119
+ - **C4 model**(Simon Brown)— <https://c4model.com/>— context / container / component / code 四层,notation-independent,每层对应不同受众
120
+ - **PRISMA 2020 + PRISMA-S** — 声明原文 <https://pmc.ncbi.nlm.nih.gov/articles/PMC8008539/> — 检索式可复现、排除计数与理由、证据集形成流程图
121
+ - **ICH E9(R1)** Addendum on estimands and sensitivity analysis(ICH 官方指导原则,按标准号可查)— estimand 五属性(population / treatment / endpoint / intercurrent events / population-level summary),「先定测什么再测」的成文来源
122
+ - **Barbara Minto**(<https://www.barbaraminto.com/>), *The Pyramid Principle: Logic in Writing and Thinking*(1985;1996 修订版《The Minto Pyramid Principle》)— 结论先行:顶层主论点 + 分组支撑 + 底层证据;本文件据此把「一页纸」还原为结构的结果而非页数规则
123
+ - **ISA 230** Audit Documentation(IAASB 国际审计准则,按标准号可查)— 「未参与该工作的有经验同行可据此重建工作、证据与结论」的收录判据;限期归卷、归卷后不删弃且更正留痕;保密 / 完整性 / 可取回的保管要求。本文件只借这三条判据用于交付文档的证据册,不主张交付文档等同审计底稿,也不搬其法定留存年限(留存期按各自司法辖区与公司政策定)
124
+ - 写作教学中一致的 revision / editing 区分(多所高校写作中心)— 全局修订先于局部润色
125
+
126
+ ## §8 故意不借鉴
127
+
128
+ | 概念 | 原因 |
129
+ |---|---|
130
+ | 固定页数上限(如「六页备忘录」「一页纸」当规则用) | 页数是某组织的会议口径,换组织不成立;本文件取其**结构**判据(§3 结论先行)与篇幅预算(归同目录 `doc-charter-first.md`),不搬数字 |
131
+ | Diátaxis 四模式直接套交付文档 | 它面向产品 / API 文档的**使用者**模式;交付型方案与调研文档的读者是决策者,不是使用者。只借「先判模式再定骨架」这一层 |
132
+ | 把 ADR 模板当方案文档骨架 | ADR 记一个决定;方案文档承载一组决定加实施路径,粒度不同 |
133
+ | 把 42010 全套视角规范搬进模板 | 该标准面向体系化架构描述;此处只取「关切—视图必须一一有着落」这条可判定要求 |
@@ -8,10 +8,12 @@ For a multi-round deliverable doc (several revision rounds with the reader-owner
8
8
  | Purpose | What should the reader be able to do or decide after reading? |
9
9
  | Venue | Presented (talk outline: one figure + one claim per section) vs self-read (narrative entry page)? Collaborative platform vs repo file? |
10
10
  | Length budget | A hard cap for the entry surface; overflow goes to child pages/appendices, the entry gains only a navigation line. |
11
+ | Genre | Which genre leads here? A doc may sit on both axes at once — a delivery genre (方案/架构, 调研, 现状梳理, 评审, 计划) and a user-facing documentation mode (tutorial / how-to / reference / explanation); record the leading one, and let §0 of the linked file settle precedence rather than forcing an either/or. The genre drives the first-draft section list and the 正文/证据 split, and narrows which diagram forms are candidates — it never mandates a fixed set of diagrams. `deliverable-doc-genre-skeletons.md` owns genre classification, the cross-genre form rules, and the 方案/架构 skeleton, and routes 调研/现状 to their own owners; take all of that from there rather than restating it here (调研 executes under `multi-perspective-research`, 现状 under `requirement-baseline`). |
11
12
 
12
13
  Rules:
13
14
 
14
15
  - **Classify each mid-stream ask against the charter instead of appending reactively.** A new request is either in-charter (edit in place), a charter change (re-confirm the charter first, then restructure once), or out-of-scope (park it). Appending every ask as a new section is how a deliverable doc accretes into an unreadable monolith.
15
16
  - **A second direction-level correction within one doc effort is the charter-not-locked signal**: stop drafting, lock the charter with the reader-owner (one short structured question), then restructure once against it. Continuing to patch per-correction after that signal produces compliant-but-shapeless output — the same failure class as the premise-rejection guard in `SKILL.md`, one level earlier.
17
+ - **Global revision precedes local polish; the order is not reversible.** 判据是本轮在改「说什么」(命题、结构、证据、分册归属)还是「怎么说」(措辞、格式)——只要还在改前者,就不进润色轮:命题或分册未定时做的润色会被下一次结构变更整段推翻,账上记成润色轮,实际是修订轮。这也是 charter 与 Genre 两格必须先锁的原因。**反过来不成立:润色本身就是多轮收敛的,反复润色不等于实质未定。**一致性与口径漂移、跨节重复、密块、元语自证等是**逐位置**缺陷,每一遍改动都可能重新引入前一遍已清掉的类;类目、判法与多轮节拍归 `SKILL.md`(DELETE / FORM / closeout),此处不复述。判据是**实质的状态**,不是本轮请求的措辞:命题 / 结构 / 分册归属尚未定 → 仍不进润色轮,回 charter/Genre(即使本轮只被要求改措辞);实质已定而同类缺陷仍有残留 → 那是执行覆盖问题,按 closeout 补,不因为「又要润色一遍」退回 charter。
16
18
  - The charter is a drafting gate, not a substance owner: substantive decisions still come from the user or the owning skill; the charter only fixes who/what/where/how-long so later asks can be classified.
17
19
  - Without a budget, growth restraint does not survive multi-round pressure — set the length budget at charter time and enforce it at each round's closeout, splitting overflow to child pages instead of raising the cap. Splitting stays inside the doc-set authority rule in `SKILL.md`: for a no-owner deliverable doc the reader-owner agrees the split (structure decision, not self-authorized); for spec/standards/guideline families the doc set is owner-settled — flag a split candidate, do not split.
@@ -0,0 +1,345 @@
1
+ # 图与表的起草期契约
2
+
3
+ `deliverable-doc-genre-skeletons.md` §4 定「哪个族画哪几张图」、§5 定「画了的图怎么验收」。
4
+ 本文件补的是**图与表画成什么样才合规**,以及**哪些判据能机械跑**。三者不重述:族与候选看 §4,
5
+ 验收面看 §5,本文件只管形态与可判定性。
6
+
7
+ ## §1 判据分三档,混档就会被反驳
8
+
9
+ 落任何一条图/表规则前先归档,档位决定它能不能被"你这数字哪来的"问倒:
10
+
11
+ | 档 | 含义 | 用法 |
12
+ |---|---|---|
13
+ | `[外]` | 有权威一手源 | 可声称行业基线,引用时点名来源 |
14
+ | `[工]` | 工程约定 + 观测到的失败类 | 能防返工,**不得声称是业界最佳实践** |
15
+ | `[禁]` | 查证后确认无可靠来源 | 谁拿数字立规则,先要出处 |
16
+
17
+ **`[禁]` 档(已核,勿再立)**:加粗/高亮密度;每 N 字一图的图表密度(唯一数字是学术期刊的
18
+ **印刷页数配额**,成因是版面成本不是可读性);"一行不超过 40 汉字"引 WCAG(该条的 CJK 40 是从
19
+ 拉丁文 80 折半推导,且原文要求是「提供**机制**让用户改」不是「正文必须排这么宽」);"句子不超过
20
+ 25 词";"留白提升理解约 20%"(错误引用链)。
21
+
22
+ **同体裁实测分布 ≠ 规范阈值**:可以说"本稿在同体裁公开样本分布的哪个位置",不能由此推出"写得好"。
23
+ 分布定位的合法输出是描述不是裁决——这条与 `tighten-doc` SKILL.md「外部基线」条同源,按那条执行。
24
+
25
+ ## §2 选哪种图:按主张的形态
26
+
27
+ `[外]` 依据 UML 2.5 图种语义。**判别式是「有没有显式事件触发」**:
28
+
29
+ - 有事件触发,且关心对象的生命周期与合法/非法迁移 → **状态机图**
30
+ - 有跨参与者的消息往返,且顺序本身就是主张 → **时序图**
31
+ - 无事件触发,随动作完成自动流转(含判定分支)→ **流程图 / 活动图**
32
+ - 主张是「谁包含谁、谁依赖谁」的静态结构 → **架构图**(先定抽象层)
33
+
34
+ 反向同样是规则:没有时间顺序不画时序图,没有非法迁移不画状态机。把静态包含关系画成流程图,
35
+ 箭头承载不了「包含」,读者必须回正文才懂——这类图必然过不了 §5 的独立性验收。
36
+
37
+ **架构/方案族的视图三分** `[外]`:C4(Context/Container/Component、Dynamic、Deployment)、
38
+ arc42(§5 Building Block / §6 Runtime / §7 Deployment)、4+1(Logical+Development / Process /
39
+ Physical)三个来源各自独立、收敛到同一组三分:**静态结构 / 运行时行为 / 部署拓扑**。
40
+ 缺哪一类视图就是缺一类受众。完整性判据用 §5 的关切覆盖(每个关切至少被一个视图回答)。
41
+
42
+ ## §3 画了就必须满足的硬约束 `[外]`
43
+
44
+ 通用(C4 记法与其 21 项评审清单):
45
+
46
+ - 标题说清**图的类型与范围**(不是「架构图」,是「XX 系统的容器图」)
47
+ - **有图例**,解释形状、颜色、边框、线型、箭头
48
+ - **每条线单向且标签具体**——禁 `Uses`/`调用`/`依赖` 这类单词,要说清意图与方向
49
+ - 跨进程连线标出协议/技术;每个元素标类型 + 一句职责
50
+ - **配色一致性跨图成立**(原文:consistent within and across diagrams),且要能过黑白打印与色觉障碍
51
+
52
+ 按图种补充:
53
+
54
+ - **时序图**:lifeline 是参与者不是函数;同步/异步用不同箭头并进图例;**错误分支要么画、要么在图注
55
+ 声明本图只画 happy path**——不声明即隐瞒
56
+ - **状态机**:状态穷尽(含初态、终态、异常态);**非法迁移显式**(画禁止边或图注列出不存在的迁移);
57
+ 每条边标**触发事件 + 守卫条件**,缺一即不可验证
58
+ - **流程图**:每个判定框**出边覆盖全部取值**;不用它表达静态包含关系
59
+
60
+ **图注写主张,不写内容** `[工]`:「图 1:系统架构」是废话;「图 1:入口层与 API 路径分离,
61
+ AI 能力跨云调用不与主云绑定」才是主张。图注承担 §5 独立性验收的一半。
62
+
63
+ ## §4 调研/报告族的图与表 `[外]`
64
+
65
+ 依据 ICD 203 九条分析标准中的第 9 条,原文:
66
+
67
+ > visual presentations should be used when information or concepts (e.g., spatial or temporal
68
+ > relationships) **can be conveyed better in graphic form (e.g., tables, flow charts, images) than
69
+ > in written text** … **Analytic content in visual information should also adhere to other analytic
70
+ > tradecraft standards.**
71
+
72
+ 两个可执行推论:
73
+
74
+ 1. **判据是「图形式是否比文字更能传达」,不是「要不要配图」。** 空间关系与时间关系优先出图;
75
+ 不满足这个条件的图是装饰。**反向也成立:量级对比与结构关系压进表格是载体错配**——表适合
76
+ 逐条查证与精确取值,看不出量级差异。
77
+ 2. **图与表里的分析内容同样受其余八条约束**——图上的判断也要能追到来源、表达不确定性、
78
+ 区分信息与假设。落成可跑的判据:图上实体名在证据正文的命中数 / 在标题的命中数 /
79
+ 引用的证据编号是否存在,三项全空即**撤框**,不留「看起来合理」的框。
80
+
81
+ **档位必须拆开标,别整条挂在 `[外]` 名下。** 上面第 1 条的**载体选择原则**是 `[外]`;
82
+ 但检查器用来识别「哪张表算量级对比」的**触发阈值**(行数、数值列占比、列数)是 `[工]`——
83
+ 本检查器自定的保守下界,无外部依据。把两者一起标成 `[外]`,正是 §1 要防的混档,
84
+ 而且本轮独立评审就是在这一条上抓到了本文件自己:一条声称按依据分档的规则自己标错了档。
85
+
86
+ 同族另两条对本轮问题直接相关:**第 2 条**要求不确定性用固定七档词表
87
+ (`almost no chance / very unlikely / unlikely / roughly even chance / likely / very likely /
88
+ almost certain`)并说明什么指标会改变不确定性水平;**第 7 条**要求解释本版判断相对上版的
89
+ 变化或一致性——**这把修订轮从"打磨消耗"变成必答内容,没写是缺项不是勤奋**。
90
+
91
+ 报告中图表与表格的视觉记法另有国际标准 **ISO 24896:2026《Notation for business reporting》**
92
+ (2026-06-11 发布;IBCS 2.0 与之对齐)。本文件不搬其条文,只登记为该族的权威面。
93
+
94
+ ## §4b 图的布局:唯一有实证的那一支 `[外]`
95
+
96
+ §1 判定「图表密度」「行宽」这类无可靠来源是对的,但**图的布局属性另有一支真正做过实验的文献**,
97
+ 本仓此前完全没有覆盖——它是少数几个既有实证依据、又能在 SVG 里精确计算的属性。
98
+
99
+ **Purchase, "Which aesthetic has the greatest effect on human understanding?"(Graph Drawing 1997)**
100
+ 以理解时间与错误数双指标测五项美学,原文结论:
101
+
102
+ > 减少边交叉是**迄今为止最重要**的美学特征,而最小化弯折数与最大化对称性影响较小。
103
+ > **最大化节点出边间最小夹角、以及把边与节点固定到正交网格,其效果在统计上不显著。**
104
+
105
+ **Huang, Eades, Hong, "Larger crossing angles make graphs easier to read"(JVLC 25(4), 2014)**:
106
+ 更大的交叉角让图更易读,且**不必是直角**。
107
+
108
+ 两条可执行推论:
109
+
110
+ 1. **冲突时的取舍序**:边交叉 > 弯折 > 对称。**不要为了对齐正交网格或加大出边夹角去牺牲前三者**——
111
+ 后两项统计上不显著,为它们做取舍没有实证支持。这半句同样是 `[外]`,它是一条"别做什么"的依据。
112
+ 2. **不可避免的交叉,角度越大越好**,但不必强求 90°。
113
+
114
+ **三条边界必须一起引,否则就是误引**:
115
+
116
+ - **实验对象是抽象点线图,不是带标签的架构图。** 受试回答的是图论问题(连通、最短路径),
117
+ 不是「这个系统怎么运作」。架构图的节点有名字、有语义分组、有分层——**外推需声明,不得当作已验证**。
118
+ - **它给的是排序,不是阈值。** "边交叉最重要"不等于"交叉数 ≤ N"。
119
+ 由它推出任何具体数字,就变成了 §9 删掉那四条谓词的同类。
120
+ - **只有前两项可机械计算**:边交叉数(线段求交)与弯折数(path 折点数)可精确算;
121
+ 对称性不可靠,不做。
122
+
123
+ 据此 `figure-lint` 提供 `GRAPH-CROSSINGS`(**WARN,只报数不设阈**):给出连线两两交叉数与最小交叉角,
124
+ 把事实交给人判断。**没有阈值依据就不设阈**——这条谓词的存在形态本身就是 §1 分档纪律的体现。
125
+
126
+ ## §4c 色觉障碍:语义只落在颜色上就会失效 `[外]` 机制 / `[工]` 判据
127
+
128
+ **机制(一手)**:protanopia 源于长波(L)视锥的视蛋白基因缺失或改变,
129
+ 所以 protanope 容易把**红色与黑色**混淆——不是"红变成别的颜色",是长波整体感光下降。
130
+ 色度学上,同一条**混淆线**(confusion line)上的颜色对该类型不可分;
131
+ 标准模拟法是把颜色投影到 LMS 空间的不变平面(Brettel/Viénot/Mollon 1997;Viénot/Brettel/Mollon 1999)。
132
+
133
+ **由此得出的判据不是「避开某些颜色」,而是「别让语义只落在同一条混淆线上的色对」。**
134
+
135
+ - **实算优于模式匹配。** 按"红橙/蓝黄/低饱和"这类色对模式去查,在本仓真实 token 集上
136
+ **只能命中三分之一**——另两对(主色/静默色 protan 距 14、主色/正常态 tritan 距 19)
137
+ 不属于任何预设模式,却同样不可分。
138
+ - **参照点用实测给**:Okabe-Ito 八色两两最小二色视距离 **38**;随机八色 **10**。
139
+ 本仓原 token 集 **14**——落在随机附近。
140
+ - **色不是唯一编码**:语义还应有形状、图标或文字冗余。
141
+ - **只测契约里显式声明为语义的色,且只报数不下判定**(`CVD-DISTANCE`)。两条都是被评审打回来才改对的:
142
+ ①早先比的是图里**全部渲染色**(含装饰、边框、底色),等于假定任意两色都编码不同语义——
143
+ 装饰色撞在一条混淆线上不构成缺陷,所以语义色必须由 `figure-contract.json` 的 `semantic_colors` **声明**,
144
+ 声明缺失就不报,而不是替作者猜;
145
+ ②早先虽写着"只报数",代码里却拿 25 当触发条件——**那就是阈**。
146
+ 上面那三个参照点(38 / 14 / 10)是量出来的,`25` 不是;现在无条件报出距离与参照点,可否接受由人判断;
147
+ ③"只报数"若走 `WARN` 档,退出码就变成非零——**声明会被退出码当场推翻**。
148
+ 故本条单列 `INFO` 档:打印、但不影响退出码。没有阈值依据的测量一律走这一档。
149
+ - **`semantic_colors` 必须受契约校验**:写成数组/字符串会让下游 `.values()` 直接崩;
150
+ 写成含非法颜色的映射会被静默丢成空集,于是"没报 CVD"既可能是"距离没问题"、
151
+ 也可能是"压根没测"——两者必须可区分。现在类型、`#RRGGBB` 语法、以及
152
+ "必须是 `color_tokens` 的子集"三项都在 `validate_contract` 里判,违者 `CONTRACT-INVALID`。
153
+
154
+ **验证锚点也可能是错的(本文件踩过)**:曾用"红色模拟后应变暗"去验实现,结果亮度上升,
155
+ 差点判一个正确算法有 bug。原因是模拟把红投影到 **575nm 黄色不变轴**——
156
+ 亮度上升是算法的正确行为;而"红色看起来暗"说的是**红与黑难分**,是另一个量。
157
+ **用错的尺子量对的实现,比实现出错更难发现**,因为其余锚点会通过。
158
+
159
+ `[外]` 调色板出处:Okabe & Ito,*Color Universal Design (CUD)*,J\*Fly(<https://jfly.uni-koeln.de/color/>);
160
+ Bang Wong 2011 年在 *Nature Methods* 使其广为人知,故常被称作 "Wong palette",但原创归 Okabe 与 Ito。
161
+
162
+ ## §4d 图值不值得画,以及它退化成什么 `[工]`
163
+
164
+ - **一句话说得更快,就写那句话。** 图的价值在于让冷读者看见一个**否则要从散文里拼出来的机制**。
165
+ - **画机制,不画名字。** 一个写着「缓存」的框比散文信息还少;请求穿过它的路径、它夹在哪两个存储之间、
166
+ 移除它会消失哪条箭头——这些才是文字说不清的。
167
+ - **一组互不相连的标注框不是对比,是列表的图形版**(本仓 `FIGURE-IS-A-LIST` 查这条)。
168
+ 比较方案就画**差异**:并排两版、前后对照、每个选项各加/减的那一条边。
169
+ - **图例只在同一编码重复出现时才值得**;否则把含义直接写在标记上。
170
+ - **流向一致**:L→R 或 T→B,不混用(`FLOW-DIRECTION-MIXED`)。该判据**依赖坐标**,
171
+ 所以图里存在 transform 等解析不了的呈现时整条跳过(否则旋转/镜像后的组会被判成另一个方向);
172
+ 两端都有箭头的双向边不计入分布,只有 `marker-start` 的边按反向计;
173
+ **两端都没箭头的连接直接跳过**——按 `d` 的书写顺序给它定向是凭空造方向,
174
+ 三条视觉上无向的线仅因端点书写顺序不同就能触发混合流向。
175
+ - **过期的图比没有图更糟——它主动误导。** 改动了图所描述的东西,同一次提交里改图;
176
+ 评审时即使超出本次范围,也要标出发现的过期图。
177
+ - **载体按规模选**(实践者做法,非实证):≤10 元素用 mermaid;<15 且要布局控制用 flowchart;
178
+ >15 或有持续交叉用 plantuml(其方向提示可修交叉)。
179
+ - **边交叉的实践者目标值**:复杂图 <5、简单图 0。**本仓不设阈**——`GRAPH-CROSSINGS` 只报数,
180
+ 实证(§4b)给的是排序不是门槛,这个目标值记在这里供参考,不作判定。
181
+
182
+ **不可机械判定、故只作提示**:视觉层级(系统边界应最显眼)、Gestalt 邻近性(相关元素成组)。
183
+ 二者归视觉判断,本文件不设检查器;真要判需 `product-ui-ux-design` 的渲染验收。
184
+
185
+ ## §5 版式契约:起草前冻结 `[工]`
186
+
187
+ **一致性本身是 `[外]` 要求**(C4 明文:consistent within and across diagrams;ICD 203 §2:
188
+ consistency in the terms used is critical)。**但「冻结成哪几档」是团队自选**——所以规则是
189
+ **契约符合性**,不是阈值。写成魔数("字号不超过 6 档")是错的:6 无依据,而偏离契约有依据。
190
+
191
+ 首稿动手前写死 `figure-contract.json`,与图源同目录或其上层:
192
+
193
+ ```json
194
+ {
195
+ "canvas_ratios": [1.778],
196
+ "font_scale": [12, 13, 15, 18, 19, 36],
197
+ "color_tokens": { "ink": "#111827", "muted": "#667085", "primary": "#356A8A",
198
+ "ok": "#12805C", "warn": "#B54708", "critical": "#B42318",
199
+ "surface": "#FFFFFF", "surface-2": "#F7F8FA" },
200
+ "semantic_colors": { "ok": "#12805C", "warn": "#B54708", "critical": "#B42318" },
201
+ "themes": { "light": { "surface": "#FFFFFF" }, "dark": { "surface": "#0B0F19" } },
202
+ "_retired": { "#98A2B3": "对白底 2.58:1,不达 WCAG AA 4.5:1,已退役" }
203
+ }
204
+ ```
205
+
206
+ - **契约缺失本身是缺陷**:没有冻结的版式,一致性不可判定,每轮内容变动都要重调几何
207
+ - **退役项写明理由**:下次有人想用,看到的是「为什么不能用」而不是「不在表里」
208
+ - 改契约 = 改规范,不是改一张图
209
+ - 契约还需覆盖 §4 未定的两项:**单格文本上限**(按"必须能在一行放下"定,不按字数拍)与
210
+ **分组单元**(每个卡片 = 形状 + 其文字包一个组)
211
+ - `semantic_colors` 是 `color_tokens` 的**子集声明**:哪些 token 承载语义区分(§4c 只测这些)。
212
+ 不声明 = 不测,不是"测出来没问题"
213
+ - `themes.<名>.surface` 必须是 `#RRGGBB`。写成 `"black"` 或非字符串,早先只判真值会让它通过校验、
214
+ 随后因不是 `#` 开头被静默跳过——**声明了主题却一次都没测,报出来的是绿**。现在按语法拒绝
215
+ - **只有直接压在主题底色上的文字才按主题判**(`THEME-CONTRAST`)。压在局部卡片上的文字,
216
+ 实际底色由卡片决定:深底上一块不随主题换的白卡片 + 深色字是**可读**的,拿全局底色去判会误报。
217
+ 判据是"这块底板是不是覆盖了整幅画布"——整幅底板算页面底色,明显小于画布的才是卡片。
218
+ 另两条前提同样是被评审打回来才补的:**`fill="none"` 的描边框不是底板**
219
+ (否则一个框住低对比文字的边框就把它豁免了);**底色解析不可信时整条跳过并显式报
220
+ `THEME-UNASSESSED`**——圆形/路径/渐变卡片不会进 `rects`,此时"查不到卡片"会被当成
221
+ "文字压在主题底上",判出来的是假红。**未判定必须说成未判定,不能沉默成绿**
222
+
223
+ ## §6 可读性与渲染:两条硬事实 `[外]`
224
+
225
+ - **WCAG 2.2 SC 1.4.3**:正文对底 ≥4.5:1;大字(≥18pt 或 ≥14pt 粗)≥3:1;例外只有纯装饰与 logo。
226
+ 图里的说明小字最容易违反,因为它又小又浅——所以 §5 的 token 表要求标注对比度
227
+ - **WCAG 2.2 SC 1.3.1(Level A)**:加粗若承载信息,必须有语义标记或文字替代。管的是「加粗有没有
228
+ 意义」,不是「加粗了多少」。对表格即:**真表头,不能用加粗行冒充**
229
+ - **SVG `<text>` 默认不换行**:规范行为不是偏好。超出容器的文本不折行、直接溢出,所以
230
+ 「单格文本上限」是功能要求不是审美要求
231
+
232
+ **目标端渲染的三条** `[工]`:
233
+
234
+ 1. **验收以目标端回读为准,不认本地检查器**——本地全绿而目标端丢字是已发生过的事,检查器不模拟
235
+ 目标端的写入行为
236
+ 2. **卡片单元必须分组**——至少一个目标端会对未分组的「形状+文字」做 z 序重排把矩形排到文字上层
237
+ 盖字,且每次覆写受害者不同;载荷顺序正确无用,重排在写入端
238
+ 3. **交互源导成静态图前全部展开再导**(可折叠节点、悬浮标签、滚动区、分页表),导出后对照交互源
239
+ 清点实体
240
+
241
+ 多载体时的载体登记与同步义务归 `multi-perspective-research`,本文件不重述。
242
+
243
+ ## §7 图文一致
244
+
245
+ `[工]`,但它兑现的是 §5 独立性验收与 ICD 203 §6(清晰且合乎逻辑的论证):
246
+
247
+ - 正文引用的图号必须存在——引用悬空即缺陷
248
+ - 采用编号图注约定后,每条图注都应被正文引用;有图从不被正文提及 = 图与正文各说各的,
249
+ 读者不知道该在哪一步看图
250
+ - 单张随文插图不强制编号(否则会把正常写法误判为缺陷)
251
+
252
+ ## §8 检查器自身的规则 `[工]`
253
+
254
+ 这一节的存在本身是教训:本轮第一版对比度检查器把压在色块上的白字判成 1.0:1(假阳性),
255
+ 后又出现过图注把自己算成正文引用(假阴性)。
256
+
257
+ 1. **先证明它能报失败再信它的绿**——逐谓词 fixture + 干净控制组,控制组被误报即检查器有缺陷
258
+ 2. **改判据必同步改 fixture**:本轮修完误报后,orphan 那条谓词的 fixture 当场失效却仍"通过"——
259
+ 这是最容易静默丢覆盖的一步
260
+ 3. **对比度检查必须解析文本实际压着的底色**,不能假定白底
261
+ 4. **谓词钉在结构与实体上**,不钉在文件名或标题词表上——改名后词表谓词要么误报,要么在检查器
262
+ 仍读旧文件时静默通过,后者更危险
263
+ 5. **派生产物新鲜度要两道判据**:实体数与 canonical 一致(抓内容过期)+ 文件时间不早于 canonical
264
+ (抓"改了名字但数量没变")。只查数量会在纯改名的轮次里全绿
265
+ 6. **派生产物不进闸,就是下一个静默过期的载体**——新增派生产物的当刻就加进闸
266
+
267
+ ## §9 已删除的谓词(勿再加回)
268
+
269
+ 以下四条曾经存在,**已删除**:标题过长、单元格塞整段、段落内并列枚举、列表项多句。
270
+
271
+ 删除理由不是"太严",是**判据错了**:它们都拿宽度或计数当「表达好不好」的代理,
272
+ 而这类阈值经查证无可靠来源(见 §1 `[禁]` 档)——等于把 `[禁]` 档的东西改个名字重新立一遍。
273
+
274
+ 代价是实测出来的:在 392 份正常文档上全量试跑,这四条产生 **318 条 ERROR、涉及 150 份文件**,
275
+ 抽样中**没有一条**是其声称的那个缺陷;命中最多的是围栏代码块里的 ASCII 分隔线与示例标题。
276
+ 删除后总发现从 718 条降到 23 条、ERROR 归零、涉及文件 13/392。
277
+
278
+ **一条真正的缺陷判据不会在正常仓库里命中 38% 的文件。** 命中率本身就是判据是否成立的证据,
279
+ 新增谓词前先在真实语料上量一次。
280
+
281
+ 顺带修的两条前提性错误(同样由全量试跑暴露):
282
+ - **围栏代码块与其内容不参与结构分析**——代码块里的分隔线、示例标题、示例表格都不是文档结构
283
+ - **「引用悬空」的前提是文档确实在用图系统**——一张图都没有的文档里出现「图 N」是在谈论图,
284
+ 不是在引用;本文件自己就因此被误判过一次
285
+
286
+ ## §9b 两条代理谓词为何是非阻断(读结果前先知道)
287
+
288
+ `C4-LEGEND` 与 `C4-EDGE-LABEL` 不是精确判据,它们的失败方向不同,报出来的数字含义也不同:
289
+
290
+ - **`C4-LEGEND` 实测为真阳性。** 在 18 张真实架构图上报 17 张缺图例;抽 3 张核对,
291
+ 确实是 0 个小色块、无图例关键字、尾部文本全是内容而非图例项。报什么就是什么。
292
+ - **`C4-EDGE-LABEL` 倾向漏报,不是误报。** 它把「连线中点 90px 内的框外自由文本」当作标签,
293
+ 而实测中框外自由文本大多是**分区标题**(「入口层」「数据层」)与**旁注**,不是边标签。
294
+ 一条真正无标签的连线,只要中点附近恰好有个分区标题,就会被判为有标签。
295
+ **所以它报出的数量是下界,真实情况只会更差**——读结果时不要当成全部。
296
+
297
+ **两条都已降为 WARN(非阻断)。** 对抗评审实测出它们**两个方向都会错**:
298
+ `C4-LEGEND` 拒掉只有两个条目的合法图例,而注释 / `<desc>` / class 里随便出现 `legend` 字样
299
+ 就能让没有图例的图通过;`C4-EDGE-LABEL` 会被中点附近的分区标题掩盖掉未标注的连线,
300
+ 又会拒掉标在连线别处的合法标签。**C4 的规则本身是 `[外]`,但用邻近与色块计数去认它是 `[工]` 代理**——
301
+ 代理不该阻断他人提交。要恢复阻断,需要结构化关联(契约声明的组 / `aria-labelledby` / `textPath`),
302
+ 而不是把阈值调得更准。
303
+
304
+ 把下界当全量会给人虚假的安心。
305
+ `est_width` 同理:它是保守估算(CJK 1em / 拉丁 0.55em),只判「明显装不下」,临界宽度不可靠。
306
+
307
+ ## §10 可跑的检查
308
+
309
+ 同目录 `../scripts/figure-lint.py`(SVG)与 `../scripts/doc-lint.py`(Markdown 表格与结构)实现了
310
+ 上述可机械判定的部分;`../scripts/tests/` 是逐谓词 fixture 与控制组,按 §8 第 1 条先自测再信。
311
+
312
+ ```
313
+ python3 skills/tighten-doc/scripts/figure-lint.py <svg 目录或文件>
314
+ python3 skills/tighten-doc/scripts/doc-lint.py <文档.md>
315
+ ```
316
+
317
+ **整仓文档也能一次扫完**,且**对任何仓库都能跑**——脚本取的 linter 是自己的同级文件,
318
+ 排除项也由此派生,不假定被扫仓库里有这个技能:
319
+
320
+ ```
321
+ python3 <技能安装路径>/skills/tighten-doc/scripts/doc-lint-repo.py <要扫的仓库路径>
322
+ # 在本仓内即:
323
+ python3 skills/tighten-doc/scripts/doc-lint-repo.py .
324
+ ```
325
+
326
+ (实测 483 篇 / 0.15s。本仓把它接在 `make test-repo-gates` 里。)三条规则:
327
+
328
+ - **DOC-STRUCTURE-GATE-TIER:只有 ERROR 一档得阻断,WARN 不得设成阻断。** 这不是保守,
329
+ 是 §9b 那条自己的规矩——判不开缺陷与判断题的代理不得设闸。落地时实测 0 ERROR / 75 WARN,
330
+ 把 WARN 也设成阻断等于当天就用一堆判断题把仓库判红。ERROR 是客观的那一半:
331
+ 表格没有真表头、图引用指向不存在的图、文件读不出来。
332
+ - **DOC-STRUCTURE-GATE-SCOPE:检查器自己的 fixture 目录必须排除,排除只能是一条前缀,
333
+ 且必须从 linter 自身位置派生、不得写死。** 那批文档按构造就带 2 个 ERROR,扫它等于让这道闸对
334
+ "证明检查器有效"的输入永久红。但写死成某个仓库里的路径就换了个方向错——消费仓里这个技能
335
+ 装在别处,写死的前缀反而会去吞掉人家碰巧同名的真文档。派生的前缀在本仓命中、在消费仓解析为
336
+ 空(什么都不排除),两边都对。排除写成模式同样会悄悄长大——它是整个扫描器里唯一能让它
337
+ 一边打印通过、一边覆盖得比声称的少的部件。
338
+ - **DOC-STRUCTURE-GATE-BIDIRECTIONAL:排除必须双向断言,且缺陷必须落在会被吞掉的那条路径上。**
339
+ fixture 要被丢掉,长得像 fixture 的真文档要留下。后一条最初写错了:带缺陷的文档放在了不含
340
+ `tests/` 的路径上,于是把前缀放宽成子串匹配时掉的只是一篇干净文档、判定不变、那条腿照样绿,
341
+ 而它的注释里明写着"双向"。**是突变探针发现的,不是我读出来的**——
342
+ 单向的排除测试在排除已经长到覆盖半个仓库时,一样绿。
343
+
344
+ **不可机械判定的仍归人**:图种选得对不对、图注写的是不是主张、独立性验收、
345
+ 调研族图上实体能否回指证据。检查器只挡机械项,不替代 §5 的验收。
@@ -0,0 +1,46 @@
1
+ # skills/tighten-doc/scripts Agent Contract
2
+
3
+ 这里的脚本对交付文档的**图与表**做起草期确定性检查:`figure-lint.py` 查 SVG,
4
+ `doc-lint.py` 查 Markdown 的表格与结构。判据与其依据档位定义在
5
+ `../references/figure-and-table-craft.md`。
6
+
7
+ Rules:
8
+
9
+ - **每条谓词必须标依据档位**,并与 `figure-and-table-craft.md` §1 的分档一致:
10
+ `[外]` 有权威一手源、`[工]` 工程约定(不得声称行业最佳实践)、`[禁]` 查证后确认无来源。
11
+ 新增谓词若属 `[工]`,其阈值必须在代码注释里明说是拍的下界,不得写成像有依据的样子。
12
+ - **不引入"可读性阈值"类的无据数字**。加粗密度、图表密度、行宽字数、句长这几类已核实无可靠来源
13
+ (见 `figure-and-table-craft.md` §1 的 `[禁]` 档),不得以任何形式重新引入。
14
+ - **一致性判为契约符合性,不判魔数**:偏离已声明的 `figure-contract.json` 才报,
15
+ "几档算多"不是判据;契约缺失单独报 `CONTRACT-MISSING`。
16
+ - **对比度检查必须解析文本实际压着的底色**,不得假定白底——假定白底会把压在色块上的白字误报。
17
+ - 谓词钉在**结构与实体**上,不钉在文件名或标题词表上。
18
+ - 两个 linter 的退出码语义一致(含 `--json` 模式):有 ERROR 返回 1、仅 WARN 返回 2、干净返回 0。
19
+ 改其中一个必须同步另一个,否则调用方会把正常结果当执行失败。
20
+
21
+ Validation(缺一不可):
22
+
23
+ - `bash skills/tighten-doc/scripts/test_figure_and_doc_lint.sh` —— 逐谓词差分 + 契约三态正负例。
24
+ **改判据必须同步改 fixture**:本目录踩过"修完误报后 fixture 当场失效却仍通过"。
25
+ - **新增或修改谓词后必须做突变实测**:跑 `bash skills/tighten-doc/scripts/mutation_probe.sh`——
26
+ 它逐谓词把 code 字面量替换掉使其在结果中消失,确认套件转红;任一谓词仍绿即无覆盖,脚本退出非 0。
27
+ 该脚本是可重跑的证据,不是一次性命令:评审方可自行执行核对。两条已踩过的坑——① 突变要作用在 oracle 实际观测的维度上
28
+ (改 severity 而断言比 code 集合 = 无效突变,会全绿假通过);② 突变判据要看**退出码**,
29
+ 只看有无 `FAIL` 行会把脚本崩溃读成绿。
30
+ - **新增谓词前先在真实语料上量命中率**:fixture 只证明谓词**能**报,不证明它报得**对**——
31
+ fixture 是作者造的,天然符合作者的假设。判据是否成立要看它在**没有为它准备的**真实文档上的分布。
32
+ 本目录实测:四条阈值型谓词在 392 份正常文档上产生 318 条 ERROR、命中 38% 的文件,
33
+ 抽样中无一条是其声称的缺陷,已全部删除。**一条真正的缺陷判据不会在正常仓库里命中 38% 的文件。**
34
+ 参考命令:`python3 doc-lint.py $(find docs skills -name '*.md' -not -path '*/tests/*') --json`。
35
+ - **已删除的谓词勿再加回**:标题过长、单元格塞整段、段落内并列枚举、列表项多句——
36
+ 理由与实测代价见 `../references/figure-and-table-craft.md` §9。
37
+ - 断言不得写成 OR(三选一命中即过)——那会让其余维度永久失去覆盖。
38
+ - **期望表必须全量对应**:报告里出现而期望表未列的文件、或期望表列了而报告里没有的文件,都判红。
39
+ 只断言点名的 fixture 会让意外文件(通配到非目标文件、新增 fixture 忘记登记)的发现无人过问。
40
+ - **改函数签名必须同步改调用点**:曾把参数加进签名却漏改调用点,第一条期望被当成参数吃掉,
41
+ 控制组变脏仍全绿。参数个数不足现在会直接判红。
42
+ - 该测试已注册进 `Makefile` 的 `test-repo-gates`;新增 `test_*.sh` 同样要注册,
43
+ 本目录**不在** `skill-extraction-workflow` 那道注册闸的覆盖范围内,不注册就静默不跑。
44
+ - shell 脚本里凡在字符串中插值一律用 `${var}`:CJK 标点紧跟 `$var` 会被 bash 吞进变量名
45
+ (本目录踩过两次)。
46
+ - `bash skills/skill-extraction-workflow/scripts/check-ccl-skills.sh .`