dsh-fmea-table-check 0.2.7 → 0.2.9

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.2.8] - 2026-10-18
4
+
5
+ ### Changed
6
+
7
+ - Move `tsdown` and `typescript` from runtime dependencies to devDependencies; a published checker no longer pulls a build chain into the profile. Same rollout as the 0.2.11 pilot.
8
+
3
9
  ## [0.2.7] - 2026-10-18
4
10
 
5
11
  ### Changed
package/README-es.md CHANGED
@@ -1,6 +1,9 @@
1
1
  # dsh-fmea-table-check — Verificación de la completitud de los elementos de la hoja de FMEA y de la consistencia del número de prioridad de riesgo
2
2
 
3
+ [English](README.md) · [简体中文](README-zh.md) · [Español](README-es.md) · [Português](README-pt.md) · [हिन्दी](README-hi.md)
4
+
3
5
  [![DSH Market](https://raw.githubusercontent.com/2BingLing/dsh-market/master/assets/readme/badge-listed-en.svg)](https://dsh.market/)
6
+ [![dshfind](https://dshfind.com/api/badge/PerryLink/dsh-fmea-table-check?metric=downloads)](https://dshfind.com/en/plugins/PerryLink/dsh-fmea-table-check?ref=badge)
4
7
 
5
8
  `dsh-fmea-table-check` lee una hoja de FMEA —filas indexadas por los propios nombres de columna de la hoja, en chino o en inglés— y comprueba en ella lo que a una hoja se le puede exigir mecánicamente: que la cadena de análisis esté registrada, que las puntuaciones de severidad, ocurrencia y detección sean números operables, que el número de prioridad de riesgo sea igual a su producto, que una fila de riesgo alto lleve una acción con responsable y fecha límite, que los estados de las acciones procedan de su propio vocabulario y que no sobreviva ningún marcador de plantilla en el modo de fallo.
6
9
 
@@ -13,14 +16,49 @@ dsh --profile <name> --dump-config | grep 'dsh-fmea-table-check'
13
16
 
14
17
  ## Cómo se ve la salida
15
18
 
16
- ![Terminal demo of dsh-fmea-table-check: real output over its FM-002 fixture](https://raw.githubusercontent.com/PerryLink/dsh-fmea-table-check/main/docs/assets/dsh-fmea-table-check-hero.png)
19
+ ![Diagrama de flujo de dsh-fmea-table-check: documento → reglas → hallazgos.](docs/assets/dsh-fmea-table-check-flow.svg)
20
+
21
+ *Resumen del flujo: documento → reglas → hallazgos. Los ejemplos siguientes usan la superficie de comandos real.*
17
22
 
18
- ![Animated terminal demo of dsh-fmea-table-check](https://raw.githubusercontent.com/PerryLink/dsh-fmea-table-check/main/docs/assets/dsh-fmea-table-check-demo.gif)
19
23
 
20
24
  Salida real de este plugin sobre su propio fixture de prueba `FM-002` — no es un montaje. El paquete de reglas no inventa citas, así que cada hallazgo nombra la cláusula aplicada y advierte que su texto no se obtuvo.
21
25
 
22
26
  ## Qué responde
23
27
 
28
+ ### Ejemplos
29
+
30
+ La tabla siguiente es el conjunto de ejemplos: la primera fila es el caso detallado y las demás son casos breves.
31
+
32
+
33
+ #### Salida detallada
34
+
35
+ **Herramienta** `fmea_table_check`
36
+
37
+ **Entrada**
38
+
39
+ ~~~json
40
+ {"rows":[{"失效模式":"密封面泄漏","严重度":"8","频度":"4","探测度":"3","风险优先数":"100"}]}
41
+ ~~~
42
+
43
+ **Salida**
44
+
45
+ ~~~json
46
+ {
47
+ "id": "dsh-fmea-table-check.FM-003.de09b5a6",
48
+ "ruleId": "FM-003",
49
+ "severity": "warn",
50
+ "locator": {
51
+ "field": "rpn",
52
+ "row": 1
53
+ },
54
+ "found": "第 1 行「rpn」填报 100,而 8 × 4 × 3 = 96",
55
+ "expected": "「rpn」应等于 severity × occurrence × detection",
56
+ "fix": "核对是否抄错或漏改;本条只做算术核对,不判断各因子是否正确"
57
+ }
58
+ ~~~
59
+
60
+ *Observado en `tests/fixtures/FM-003/FM-003-unsafe.json (cases.json expects FM-003 count 1); run via lib/index.mjs rules/fmea-table-check.yaml`*
61
+
24
62
  | Usted pregunta | Qué responde |
25
63
  |---|---|
26
64
  | La celda del RPN no coincide con severidad × ocurrencia × detección, ¿se detecta? | Sí. `FM-003` recalcula `rpn` como severidad × ocurrencia × detección con una tolerancia de `0` y señala la fila cuyo valor almacenado difiere. Solo se ejecuta cuando las cuatro celdas contienen números analizables; si la puntuación de ocurrencia no es un número, la regla informa `skipped` en lugar de aprobar. Una hoja puntuada con el manual AIAG-VDA usa AP en vez de RPN: reoriente `resultField` y `factorFields`, o desactive la regla. |
@@ -114,6 +152,10 @@ node ../scripts/sync-shared.mjs dsh-fmea-table-check
114
152
 
115
153
  El último comando copia el kit compartido de `../_shared` a `src/shared/`; vuelva a ejecutarlo tras cada cambio compartido.
116
154
 
155
+ ## PerryLink DSH Plugin Family
156
+
157
+ Full family index: [choose a checker by material](https://perrylink.github.io/zh/checkers/choose/) and [all plugins](https://github.com/PerryLink). This repository is one of them.
158
+
117
159
  ## License
118
160
 
119
161
  [Apache License 2.0](LICENSE) © 2026 dsh-fmea-table-check contributors.
package/README-hi.md CHANGED
@@ -1,6 +1,9 @@
1
1
  # dsh-fmea-table-check — FMEA कार्यपत्रक के तत्वों की पूर्णता और जोखिम प्राथमिकता संख्या की संगति की जाँच
2
2
 
3
+ [English](README.md) · [简体中文](README-zh.md) · [Español](README-es.md) · [Português](README-pt.md) · [हिन्दी](README-hi.md)
4
+
3
5
  [![DSH Market](https://raw.githubusercontent.com/2BingLing/dsh-market/master/assets/readme/badge-listed-en.svg)](https://dsh.market/)
6
+ [![dshfind](https://dshfind.com/api/badge/PerryLink/dsh-fmea-table-check?metric=downloads)](https://dshfind.com/en/plugins/PerryLink/dsh-fmea-table-check?ref=badge)
4
7
 
5
8
  `dsh-fmea-table-check` एक FMEA कार्यपत्रक पढ़ता है — पंक्तियाँ शीट के अपने स्तंभ-नामों से जुड़ी, चीनी या अंग्रेज़ी में — और उसमें वह जाँचता है जो एक शीट से यांत्रिक रूप से अपेक्षित किया जा सकता है: क्या विश्लेषण-शृंखला दर्ज है, क्या `severity`, `occurrence` और `detection` के अंक संक्रियात्मक संख्याएँ हैं, क्या `rpn` उनके गुणनफल के बराबर है, क्या ऊँचे जोखिम वाली पंक्ति में ज़िम्मेदार और समय-सीमा सहित सुझाई गई कार्रवाई है, क्या कार्रवाई की स्थितियाँ आपकी अपनी शब्दावली से आती हैं, और क्या विफलता-प्रकार स्तंभ में कोई टेम्पलेट प्लेसहोल्डर शेष नहीं है।
6
9
 
@@ -13,14 +16,49 @@ dsh --profile <name> --dump-config | grep 'dsh-fmea-table-check'
13
16
 
14
17
  ## आउटपुट कैसा दिखता है
15
18
 
16
- ![Terminal demo of dsh-fmea-table-check: real output over its FM-002 fixture](https://raw.githubusercontent.com/PerryLink/dsh-fmea-table-check/main/docs/assets/dsh-fmea-table-check-hero.png)
19
+ ![dsh-fmea-table-check कार्यप्रवाह आरेख: दस्तावेज़ → नियम → निष्कर्ष।](docs/assets/dsh-fmea-table-check-flow.svg)
20
+
21
+ *कार्यप्रवाह: दस्तावेज़ → नियम → निष्कर्ष। नीचे के उदाहरण वास्तविक कमांड सतह का उपयोग करते हैं।*
17
22
 
18
- ![Animated terminal demo of dsh-fmea-table-check](https://raw.githubusercontent.com/PerryLink/dsh-fmea-table-check/main/docs/assets/dsh-fmea-table-check-demo.gif)
19
23
 
20
24
  इस प्लगइन का अपने ही `FM-002` टेस्ट फ़िक्स्चर पर वास्तविक आउटपुट — कोई नकली चित्र नहीं। नियम-पैक उद्धरण नहीं गढ़ता, इसलिए हर निष्कर्ष लागू किए गए खंड का नाम और यह भी बताता है कि उसका मूल पाठ इस बार प्राप्त नहीं हुआ।
21
25
 
22
26
  ## यह किन सवालों का जवाब देता है
23
27
 
28
+ ### उदाहरण
29
+
30
+ नीचे दी गई तालिका उदाहरण-समुच्चय है: पहली पंक्ति विस्तृत केस है, बाकी संक्षिप्त केस हैं।
31
+
32
+
33
+ #### विस्तृत आउटपुट
34
+
35
+ **उपकरण** `fmea_table_check`
36
+
37
+ **इनपुट**
38
+
39
+ ~~~json
40
+ {"rows":[{"失效模式":"密封面泄漏","严重度":"8","频度":"4","探测度":"3","风险优先数":"100"}]}
41
+ ~~~
42
+
43
+ **आउटपुट**
44
+
45
+ ~~~json
46
+ {
47
+ "id": "dsh-fmea-table-check.FM-003.de09b5a6",
48
+ "ruleId": "FM-003",
49
+ "severity": "warn",
50
+ "locator": {
51
+ "field": "rpn",
52
+ "row": 1
53
+ },
54
+ "found": "第 1 行「rpn」填报 100,而 8 × 4 × 3 = 96",
55
+ "expected": "「rpn」应等于 severity × occurrence × detection",
56
+ "fix": "核对是否抄错或漏改;本条只做算术核对,不判断各因子是否正确"
57
+ }
58
+ ~~~
59
+
60
+ *स्रोत `tests/fixtures/FM-003/FM-003-unsafe.json (cases.json expects FM-003 count 1); run via lib/index.mjs rules/fmea-table-check.yaml`*
61
+
24
62
  | आपका सवाल | इसका जवाब |
25
63
  |---|---|
26
64
  | `rpn` का मान severity × occurrence × detection के बराबर नहीं है — क्या यह पकड़ में आता है? | हाँ। `FM-003` severity × occurrence × detection से `rpn` दोबारा निकालता है, सहनशीलता `0`, और जिस पंक्ति का दर्ज मान उससे भिन्न हो उसे दर्ज करता है। यह तभी चलता है जब चारों खानों में पढ़ने योग्य संख्याएँ हों; occurrence का अंक संख्या न हो तो यह नियम पास होने के बजाय `skipped` बताता है। AIAG-VDA पुस्तिका पर बनी शीट RPN के बजाय AP से अंक देती है: `resultField` और `factorFields` बदलें, या यह नियम बंद कर दें। |
@@ -114,6 +152,10 @@ node ../scripts/sync-shared.mjs dsh-fmea-table-check
114
152
 
115
153
  अंतिम कमांड `../_shared` का साझा किट `src/shared/` में कॉपी करता है; हर साझा बदलाव के बाद इसे दोबारा चलाएँ।
116
154
 
155
+ ## PerryLink DSH Plugin Family
156
+
157
+ Full family index: [choose a checker by material](https://perrylink.github.io/zh/checkers/choose/) and [all plugins](https://github.com/PerryLink). This repository is one of them.
158
+
117
159
  ## License
118
160
 
119
161
  [Apache License 2.0](LICENSE) © 2026 dsh-fmea-table-check contributors.
package/README-pt.md CHANGED
@@ -1,6 +1,9 @@
1
1
  # dsh-fmea-table-check — Verificação da completude dos elementos da folha de FMEA e da consistência do número de prioridade de risco
2
2
 
3
+ [English](README.md) · [简体中文](README-zh.md) · [Español](README-es.md) · [Português](README-pt.md) · [हिन्दी](README-hi.md)
4
+
3
5
  [![DSH Market](https://raw.githubusercontent.com/2BingLing/dsh-market/master/assets/readme/badge-listed-en.svg)](https://dsh.market/)
6
+ [![dshfind](https://dshfind.com/api/badge/PerryLink/dsh-fmea-table-check?metric=downloads)](https://dshfind.com/en/plugins/PerryLink/dsh-fmea-table-check?ref=badge)
4
7
 
5
8
  `dsh-fmea-table-check` lê uma folha de FMEA —linhas indexadas pelos próprios nomes de coluna da folha, em chinês ou em inglês— e verifica nela o que a uma folha se pode exigir mecanicamente: que a cadeia de análise esteja registada, que as pontuações de severidade, ocorrência e deteção sejam números operáveis, que o número de prioridade de risco seja igual ao seu produto, que uma linha de risco elevado traga uma ação com responsável e prazo, que os estados das ações venham do seu próprio vocabulário e que não sobreviva nenhum marcador de modelo no modo de falha.
6
9
 
@@ -13,14 +16,49 @@ dsh --profile <name> --dump-config | grep 'dsh-fmea-table-check'
13
16
 
14
17
  ## Como é a saída
15
18
 
16
- ![Terminal demo of dsh-fmea-table-check: real output over its FM-002 fixture](https://raw.githubusercontent.com/PerryLink/dsh-fmea-table-check/main/docs/assets/dsh-fmea-table-check-hero.png)
19
+ ![Diagrama de fluxo de dsh-fmea-table-check: documento → regras → achados.](docs/assets/dsh-fmea-table-check-flow.svg)
20
+
21
+ *Visão geral do fluxo: documento → regras → achados. Os exemplos abaixo usam a superfície real de comandos.*
17
22
 
18
- ![Animated terminal demo of dsh-fmea-table-check](https://raw.githubusercontent.com/PerryLink/dsh-fmea-table-check/main/docs/assets/dsh-fmea-table-check-demo.gif)
19
23
 
20
24
  Saída real deste plugin sobre o seu próprio fixture de teste `FM-002` — não é uma simulação. O pacote de regras não inventa citações, por isso cada achado nomeia a cláusula aplicada e avisa que o seu texto não foi obtido.
21
25
 
22
26
  ## O que ele responde
23
27
 
28
+ ### Exemplos
29
+
30
+ A tabela abaixo é o conjunto de exemplos: a primeira linha é o caso detalhado e as demais são casos curtos.
31
+
32
+
33
+ #### Saída detalhada
34
+
35
+ **Ferramenta** `fmea_table_check`
36
+
37
+ **Entrada**
38
+
39
+ ~~~json
40
+ {"rows":[{"失效模式":"密封面泄漏","严重度":"8","频度":"4","探测度":"3","风险优先数":"100"}]}
41
+ ~~~
42
+
43
+ **Saída**
44
+
45
+ ~~~json
46
+ {
47
+ "id": "dsh-fmea-table-check.FM-003.de09b5a6",
48
+ "ruleId": "FM-003",
49
+ "severity": "warn",
50
+ "locator": {
51
+ "field": "rpn",
52
+ "row": 1
53
+ },
54
+ "found": "第 1 行「rpn」填报 100,而 8 × 4 × 3 = 96",
55
+ "expected": "「rpn」应等于 severity × occurrence × detection",
56
+ "fix": "核对是否抄错或漏改;本条只做算术核对,不判断各因子是否正确"
57
+ }
58
+ ~~~
59
+
60
+ *Observado em `tests/fixtures/FM-003/FM-003-unsafe.json (cases.json expects FM-003 count 1); run via lib/index.mjs rules/fmea-table-check.yaml`*
61
+
24
62
  | Você pergunta | O que ele responde |
25
63
  |---|---|
26
64
  | A célula do RPN não coincide com severidade × ocorrência × deteção — isso é detetado? | Sim. `FM-003` recalcula `rpn` como severidade × ocorrência × deteção com tolerância `0` e assinala a linha cujo valor registado difere. Só é executada quando as quatro células têm números analisáveis; se a pontuação de ocorrência não for um número, a regra reporta `skipped` em vez de passar. Uma folha pontuada pelo manual AIAG-VDA usa AP em vez de RPN: reaponte `resultField` e `factorFields`, ou desative a regra. |
@@ -114,6 +152,10 @@ node ../scripts/sync-shared.mjs dsh-fmea-table-check
114
152
 
115
153
  O último comando copia o kit compartilhado de `../_shared` para `src/shared/`; execute-o novamente após cada alteração compartilhada.
116
154
 
155
+ ## PerryLink DSH Plugin Family
156
+
157
+ Full family index: [choose a checker by material](https://perrylink.github.io/zh/checkers/choose/) and [all plugins](https://github.com/PerryLink). This repository is one of them.
158
+
117
159
  ## License
118
160
 
119
161
  [Apache License 2.0](LICENSE) © 2026 dsh-fmea-table-check contributors.
package/README-zh.md CHANGED
@@ -1,6 +1,18 @@
1
1
  # dsh-fmea-table-check — FMEA 分析表要素齐备性与风险顺序数一致性核对
2
2
 
3
+ [English](README.md) · [简体中文](README-zh.md) · [Español](README-es.md) · [Português](README-pt.md) · [हिन्दी](README-hi.md)
4
+
5
+ <!-- topblock:v1 -->
6
+ > **这是什么** FMEA 分析表核对。输出一份「哪一行、哪一栏、差什么」的清单。
7
+ > **给谁用** 质量工程师、工艺工程师;不用懂命令行。
8
+ > **你交什么** 这项核对用到的原始材料(表格、清单或文书);不改原件。Excel 可先转成 JSON/YAML,对话里也能代转。
9
+ > **它不做什么** 不判合规、不认定责任、不替代审核人;只列材料内部能逐条指认的差异。
10
+ > **怎么开始** 在 WorkBuddy / 扣子搜「职业文档核对全集」(总包,本检查是其中一项;上架以商城为准);或命令行:
11
+ > `dsh plugin --profile <name> add dsh-fmea-table-check`
12
+ <!-- /topblock:v1 -->
13
+
3
14
  [![DSH Market](https://raw.githubusercontent.com/2BingLing/dsh-market/master/assets/readme/badge-listed-en.svg)](https://dsh.market/)
15
+ [![dshfind](https://dshfind.com/api/badge/PerryLink/dsh-fmea-table-check?metric=downloads)](https://dshfind.com/en/plugins/PerryLink/dsh-fmea-table-check?ref=badge)
4
16
 
5
17
  `dsh-fmea-table-check` 读取一份 FMEA 分析表——以表自身的列名为键,中英文均可——核对一张表在机械层面能够被要求的东西:基本分析链是否记录在案、严重度/频度/探测度是否为可运算的数值、风险顺序数是否等于三者之积、高风险条目是否有带责任人与完成期限的建议措施、措施状态是否取自本机构的口径、失效模式栏是否残留未替换的模板占位符。
6
18
 
@@ -13,14 +25,49 @@ dsh --profile <name> --dump-config | grep 'dsh-fmea-table-check'
13
25
 
14
26
  ## 实际输出长什么样
15
27
 
16
- ![Terminal demo of dsh-fmea-table-check: real output over its FM-002 fixture](https://raw.githubusercontent.com/PerryLink/dsh-fmea-table-check/main/docs/assets/dsh-fmea-table-check-hero.png)
28
+ ![dsh-fmea-table-check 工作流图:文档 → 规则包 → 核对结果。](docs/assets/dsh-fmea-table-check-flow.svg)
29
+
30
+ *工作流概览:文档 → 规则包 → 核对结果。下面的示例使用实际命令面。*
17
31
 
18
- ![Animated terminal demo of dsh-fmea-table-check](https://raw.githubusercontent.com/PerryLink/dsh-fmea-table-check/main/docs/assets/dsh-fmea-table-check-demo.gif)
19
32
 
20
33
  本插件对自己 `FM-002` 测试夹具的**真实输出**,不是示意图。规则库不伪造引文,因此每条发现都会同时写明所引条款,以及该条款原文本次未取得。
21
34
 
22
35
  ## 它回答什么问题
23
36
 
37
+ ### 示例
38
+
39
+ 下表是示例集:第一行是详细走查,其余行是简短案例。
40
+
41
+
42
+ #### 详细输出
43
+
44
+ **工具** `fmea_table_check`
45
+
46
+ **输入**
47
+
48
+ ~~~json
49
+ {"rows":[{"失效模式":"密封面泄漏","严重度":"8","频度":"4","探测度":"3","风险优先数":"100"}]}
50
+ ~~~
51
+
52
+ **输出**
53
+
54
+ ~~~json
55
+ {
56
+ "id": "dsh-fmea-table-check.FM-003.de09b5a6",
57
+ "ruleId": "FM-003",
58
+ "severity": "warn",
59
+ "locator": {
60
+ "field": "rpn",
61
+ "row": 1
62
+ },
63
+ "found": "第 1 行「rpn」填报 100,而 8 × 4 × 3 = 96",
64
+ "expected": "「rpn」应等于 severity × occurrence × detection",
65
+ "fix": "核对是否抄错或漏改;本条只做算术核对,不判断各因子是否正确"
66
+ }
67
+ ~~~
68
+
69
+ *来源 `tests/fixtures/FM-003/FM-003-unsafe.json (cases.json expects FM-003 count 1); run via lib/index.mjs rules/fmea-table-check.yaml`*
70
+
24
71
  | 你会问 | 它怎么答 |
25
72
  |---|---|
26
73
  | RPN 栏跟严重度 × 频度 × 探测度对不上,能查出来吗? | 能。`FM-003` 用严重度 × 频度 × 探测度重算 `rpn`,容差为 `0`,逐行报出与表内所填不一致的条目。它只在四个字段都能解析为数值时执行;频度填的不是数字时,本条报 `skipped` 而不是通过。按 AIAG-VDA 手册打分的表用 AP 而非 RPN,请改 `resultField` 与 `factorFields`,或停用本条。 |
@@ -36,28 +83,13 @@ dsh --profile <name> --dump-config | grep 'dsh-fmea-table-check'
36
83
  |---|---|---|
37
84
  | 《系统可靠性分析技术 失效模式和影响分析(FMEA)程序》 | GB/T 7826(现行版本号与条号本次未核实) | FM-001, FM-002, FM-003, FM-004, FM-005, FM-006, FM-007, FM-008 |
38
85
 
39
- **Boundary:** this plugin checks an **FMEA worksheet** for what a sheet can be held to mechanically — that
40
- the analysis chain is recorded, that the severity / occurrence / detection scores are operable numbers,
41
- that the risk priority number equals their product, that a high-risk row carries an action with an owner and
42
- a due date, that action statuses come from your vocabulary, and that no template placeholder survives. It
43
- does **not** judge whether the failure modes are complete, whether the consequences are analysed far enough,
44
- whether the scores are right, or whether the risk is acceptable. **Those are the study team's judgements,
45
- and they are where FMEA's value lies.**
86
+ **边界(中文译文,以英文原文为准):** 本插件核对一份 **FMEA 分析表** 在表格层面可以机械要求到的事项——分析链是否记录在案,严重度 / 频度 / 探测度是否为可运算的数值,风险顺序数是否等于三者之积,高风险条目是否带有含责任人与完成期限的建议措施,措施状态是否取自你配置的取值口径,以及是否残留模板占位符。它**不**判定失效模式是否完整、后果分析是否足够深入、评分是否正确,也不判定风险是否可以接受。**那些是研究团队的判断,也正是 FMEA 的价值所在。**
46
87
 
47
- > ### ⚠️ Read this before trusting a citation in the report
88
+ > ### ⚠️ 在采信报告中的引文之前,请先读这一段
48
89
  >
49
- > **Every `excerpt` in this plugin's rule pack says, in so many words, that the clause text was not
50
- > obtained.** The method's homes are **GB/T 7826《系统可靠性分析技术 失效模式和影响分析(FMEA)程序》**,
51
- > IEC 60812, and the automotive AIAG-VDA handbook. The verification pass could not retrieve verbatim clause
52
- > text from them, so rather than paraphrase a quotation the pack states the gap in the `excerpt` field
53
- > itself and puts the honest reasoning in `note`. Every rule is therefore `warn` or `info`, and a test
54
- > asserts that no rule claims a quotation it does not have. **When the texts are in hand, two things must be
55
- > done: replace each `excerpt` with the real clause, and raise `kind` to `direct`.**
90
+ > **每条 `excerpt` 的状态逐条不同,不是统一的。** 有的规则引用逐字条文(`kind: direct`),有的按条文原则推导(`kind: derived-from-principle`,最高 `warn`),有的阈值由本机构配置(`kind: institutional-configuration`,最高 `info`)。规则包从不概括引文:取不到原文时,`excerpt` 会如实写明,推理写在 `note` 里;并有测试断言没有任何规则声称拥有它并不拥有的引文。**对仍标为「未取得原文」的规则,取得文本后必须把 `excerpt` 换成真实条款,并把 `kind` 提升为 `direct`。**
56
91
  >
57
- > Two settings are yours. **FM-003's RPN arithmetic assumes the S×O×D method**; a worksheet built on the
58
- > AIAG-VDA handbook uses **AP (action priority)** instead, so repoint `resultField` and `factorFields` — or
59
- > disable the rule. And **FM-004's threshold ships as `0`, meaning "not configured"**: what counts as high
60
- > risk is your risk criterion, and the rule reports that it could not run rather than inventing a number.
92
+ > 结论性判断留给审核人:本插件只列出材料内部可以逐条指认的差异,不判断事实真伪,也不评价合规性。
61
93
 
62
94
  ## Compatibility
63
95
 
@@ -114,6 +146,10 @@ node ../scripts/sync-shared.mjs dsh-fmea-table-check
114
146
 
115
147
  第 4 项把 `../_shared` 的共享件同步进 `src/shared/`;每次改动共享件后都要重跑。
116
148
 
149
+ ## PerryLink DSH Plugin Family
150
+
151
+ 完整清单(62 个核查器 + 通用插件)见 [按材料选核查器](https://perrylink.github.io/zh/checkers/choose/);本仓只是其中一个。
152
+
117
153
  ## License
118
154
 
119
155
  [Apache License 2.0](LICENSE) © 2026 dsh-fmea-table-check contributors.
package/README.md CHANGED
@@ -1,6 +1,18 @@
1
1
  # dsh-fmea-table-check — FMEA worksheet element completeness and risk priority number consistency check
2
2
 
3
+ [English](README.md) · [简体中文](README-zh.md) · [Español](README-es.md) · [Português](README-pt.md) · [हिन्दी](README-hi.md)
4
+
5
+ <!-- topblock:v1 -->
6
+ > **What it is** — FMEA worksheet element completeness and risk priority number consistency check. It returns a list of what is inconsistent, where, and what to fix.
7
+ > **Who it is for** — quality and process engineers; no command line required.
8
+ > **What you give it** — the source material the check works on (a table, register or document); the original is never modified. Excel can be converted to JSON/YAML first, in chat if the platform supports it.
9
+ > **What it does not do** — no compliance verdict, no liability finding, no replacement for the reviewer; differences only.
10
+ > **How to start** — search "Professional Document Check Suite" in WorkBuddy / Coze (the full set; this check is one part of it; availability as listed); or:
11
+ > `dsh plugin --profile <name> add dsh-fmea-table-check`
12
+ <!-- /topblock:v1 -->
13
+
3
14
  [![DSH Market](https://raw.githubusercontent.com/2BingLing/dsh-market/master/assets/readme/badge-listed-en.svg)](https://dsh.market/)
15
+ [![dshfind](https://dshfind.com/api/badge/PerryLink/dsh-fmea-table-check?metric=downloads)](https://dshfind.com/en/plugins/PerryLink/dsh-fmea-table-check?ref=badge)
4
16
 
5
17
  `dsh-fmea-table-check` reads one FMEA worksheet — rows keyed by the sheet's own column names, in Chinese or English — and checks in it what a sheet can be held to mechanically: that the analysis chain is recorded, that the severity, occurrence and detection scores are operable numbers, that the risk priority number equals their product, that a high-risk row carries an action with an owner and a due date, that action statuses come from your own vocabulary, and that no template placeholder survives in the failure mode.
6
18
 
@@ -13,14 +25,47 @@ dsh --profile <name> --dump-config | grep 'dsh-fmea-table-check'
13
25
 
14
26
  ## What it looks like
15
27
 
16
- ![Terminal demo of dsh-fmea-table-check: real output over its FM-002 fixture](https://raw.githubusercontent.com/PerryLink/dsh-fmea-table-check/main/docs/assets/dsh-fmea-table-check-hero.png)
28
+ ![Workflow diagram for dsh-fmea-table-check: document → rule pack → findings.](docs/assets/dsh-fmea-table-check-flow.svg)
29
+
30
+ *Workflow overview: document → rule pack → findings. The examples below use the real command surface.*
17
31
 
18
- ![Animated terminal demo of dsh-fmea-table-check](https://raw.githubusercontent.com/PerryLink/dsh-fmea-table-check/main/docs/assets/dsh-fmea-table-check-demo.gif)
19
32
 
20
- Real output from this plugin over its own `FM-002` test fixture — not a mock-up. The rule pack ships no invented quotations, so a finding names both the clause it applied and the fact that the clause text was not obtained.
21
33
 
22
34
  ## What it answers
23
35
 
36
+ ### Examples
37
+
38
+ The table below is the example set: the first row is the detailed walkthrough, the remaining rows are short cases.
39
+
40
+ #### Detailed output
41
+
42
+ **Tool** `fmea_table_check`
43
+
44
+ **Input**
45
+
46
+ ~~~json
47
+ {"rows":[{"失效模式":"密封面泄漏","严重度":"8","频度":"4","探测度":"3","风险优先数":"100"}]}
48
+ ~~~
49
+
50
+ **Output**
51
+
52
+ ~~~json
53
+ {
54
+ "id": "dsh-fmea-table-check.FM-003.de09b5a6",
55
+ "ruleId": "FM-003",
56
+ "severity": "warn",
57
+ "locator": {
58
+ "field": "rpn",
59
+ "row": 1
60
+ },
61
+ "found": "第 1 行「rpn」填报 100,而 8 × 4 × 3 = 96",
62
+ "expected": "「rpn」应等于 severity × occurrence × detection",
63
+ "fix": "核对是否抄错或漏改;本条只做算术核对,不判断各因子是否正确"
64
+ }
65
+ ~~~
66
+
67
+ *Observed from `tests/fixtures/FM-003/FM-003-unsafe.json (cases.json expects FM-003 count 1); run via lib/index.mjs rules/fmea-table-check.yaml`*
68
+
24
69
  | You ask | What it answers |
25
70
  |---|---|
26
71
  | The RPN cell does not equal severity × occurrence × detection — is that caught? | Yes. `FM-003` recomputes `rpn` from severity × occurrence × detection with a tolerance of `0` and reports the row whose stored value differs. It runs only when all four cells hold parseable numbers; if the occurrence score is not a number the rule reports `skipped` rather than a pass. A worksheet built on the AIAG-VDA handbook scores with AP instead of RPN, so repoint `resultField` and `factorFields`, or disable the rule. |
@@ -46,18 +91,9 @@ and they are where FMEA's value lies.**
46
91
 
47
92
  > ### ⚠️ Read this before trusting a citation in the report
48
93
  >
49
- > **Every `excerpt` in this plugin's rule pack says, in so many words, that the clause text was not
50
- > obtained.** The method's homes are **GB/T 7826《系统可靠性分析技术 失效模式和影响分析(FMEA)程序》**,
51
- > IEC 60812, and the automotive AIAG-VDA handbook. The verification pass could not retrieve verbatim clause
52
- > text from them, so rather than paraphrase a quotation the pack states the gap in the `excerpt` field
53
- > itself and puts the honest reasoning in `note`. Every rule is therefore `warn` or `info`, and a test
54
- > asserts that no rule claims a quotation it does not have. **When the texts are in hand, two things must be
55
- > done: replace each `excerpt` with the real clause, and raise `kind` to `direct`.**
94
+ > **`excerpt` status is per rule, not uniform.** Some rules quote the clause verbatim (`kind: direct`), some are derived from the principle of the cited articles (`kind: derived-from-principle`, capped at `warn`), and some use thresholds your institution configures (`kind: institutional-configuration`, capped at `info`). The pack never paraphrases a quotation: when the text was not obtained, the `excerpt` field says so and the reasoning lives in `note`; a test asserts that no rule claims a quotation it does not have. **For any rule still marked as not obtained, replace the `excerpt` with the real clause and raise `kind` to `direct` once the text is in hand.**
56
95
  >
57
- > Two settings are yours. **FM-003's RPN arithmetic assumes the S×O×D method**; a worksheet built on the
58
- > AIAG-VDA handbook uses **AP (action priority)** instead, so repoint `resultField` and `factorFields` — or
59
- > disable the rule. And **FM-004's threshold ships as `0`, meaning "not configured"**: what counts as high
60
- > risk is your risk criterion, and the rule reports that it could not run rather than inventing a number.
96
+ > The conclusion is the reviewer's: this plugin lists differences it can point to in the material and does not decide facts or compliance.
61
97
 
62
98
  ## Compatibility
63
99
 
@@ -161,6 +197,10 @@ node ../scripts/sync-shared.mjs dsh-fmea-table-check # refresh src/shared from
161
197
  The plugin is **data-only**: `src/model.ts` declares the table shape, the shared kit supplies the reader and
162
198
  the check engine, and the rule pack declares every check.
163
199
 
200
+ ## PerryLink DSH Plugin Family
201
+
202
+ Full family index: [choose a checker by material](https://perrylink.github.io/zh/checkers/choose/) and [all plugins](https://github.com/PerryLink). This repository is one of them.
203
+
164
204
  ## License
165
205
 
166
206
  [Apache License 2.0](LICENSE) © 2026 dsh-fmea-table-check contributors.
package/lib/index.d.mts CHANGED
@@ -1,12 +1,11 @@
1
1
  import Schema from "@deepseek-ai/schemastery";
2
2
  import { Context } from "@deepseek-ai/cordis";
3
- //#region src/config.d.ts
4
3
  /**
5
4
  * Every tunable lives here so an operator can change behaviour from
6
5
  * `cordis.yml` without editing code (the family's "no hard-coded tunables"
7
6
  * redline). The rule pack itself is data as well and can be pointed elsewhere.
8
7
  */
9
- interface Config {
8
+ export interface Config {
10
9
  /** Rule-pack path relative to the plugin package root. */
11
10
  rulesFile: string;
12
11
  /** Rule ids disabled for this deployment. */
@@ -18,13 +17,11 @@ interface Config {
18
17
  /** Tool timeout budget in milliseconds. */
19
18
  timeoutMs: number;
20
19
  }
21
- declare const Config: Schema<Config>;
22
- //#endregion
23
- //#region src/index.d.ts
24
- declare const name = "dsh-fmea-table-check";
25
- declare const inject: string[];
20
+ export declare const Config: Schema<Config>;
21
+ export declare const name = "dsh-fmea-table-check";
22
+ export declare const inject: string[];
26
23
  /** Tool id exposed to the model, and the row id in `cordis.patch.yml`. */
27
- declare const TOOL_NAME = "fmea_table_check";
24
+ export declare const TOOL_NAME = "fmea_table_check";
28
25
  /**
29
26
  * Locate a package-owned file such as the rule pack.
30
27
  *
@@ -36,7 +33,7 @@ declare const TOOL_NAME = "fmea_table_check";
36
33
  * @returns the resolved absolute path.
37
34
  * @throws Error naming every location tried, when the file is absent.
38
35
  */
39
- declare function resolvePackageFile(relative: string): string;
36
+ export declare function resolvePackageFile(relative: string): string;
40
37
  /**
41
38
  * Register the checker tool.
42
39
  *
@@ -47,6 +44,4 @@ declare function resolvePackageFile(relative: string): string;
47
44
  * @param ctx - plugin context, with `tools` already available.
48
45
  * @param config - validated configuration.
49
46
  */
50
- declare function apply(ctx: Context, config: Config): () => void;
51
- //#endregion
52
- export { Config, TOOL_NAME, apply, inject, name, resolvePackageFile };
47
+ export declare function apply(ctx: Context, config: Config): () => void;
package/lib/index.mjs CHANGED
@@ -3,7 +3,7 @@ import { existsSync } from "node:fs";
3
3
  import { dirname, isAbsolute, resolve } from "node:path";
4
4
  import { defineTool } from "@deepseek-ai/dsh-tools";
5
5
  import Schema from "@deepseek-ai/schemastery";
6
- //#region src/config.ts
6
+ // src/config.ts
7
7
  const Config = Schema.object({
8
8
  rulesFile: Schema.string().default("rules/fmea-table-check.yaml").description("规则库文件路径(相对插件包根目录)。替换该文件即可切换规则集版本。"),
9
9
  disabledRules: Schema.array(Schema.string()).default([]).description("要停用的规则 id 列表;停用的规则会出现在报告的 skipped 中。"),
@@ -11,8 +11,7 @@ const Config = Schema.object({
11
11
  skipNotes: Schema.string().default("").description("附加到每条 skipped 说明后的备注,例如标注本机构实施细则。"),
12
12
  timeoutMs: Schema.number().default(12e4).description("工具协作式超时预算(毫秒)。")
13
13
  });
14
- //#endregion
15
- //#region src/shared/yaml.ts
14
+ // src/shared/yaml.ts
16
15
  /**
17
16
  * Minimal, dependency-free YAML reader for rule packs and check material.
18
17
  *
@@ -365,6 +364,10 @@ var Reader = class {
365
364
  if (!isSequenceItem(line.text)) break;
366
365
  this.index += 1;
367
366
  const rest = line.text === "-" ? "" : line.text.slice(2).trim();
367
+ if (rest.startsWith("{") || rest.startsWith("[")) {
368
+ items.push(parseScalar(rest, line.num));
369
+ continue;
370
+ }
368
371
  if ((rest === "" ? -1 : findKeySeparator(rest)) >= 0) {
369
372
  items.push(this.readMapping(indent + 2, {
370
373
  text: rest,
@@ -444,8 +447,7 @@ function requireString(source, key, where) {
444
447
  if (typeof value !== "string" || value.trim() === "") throw new YamlSubsetError(`${where}: missing required string field "${key}"`);
445
448
  return value;
446
449
  }
447
- //#endregion
448
- //#region src/shared/table.ts
450
+ // src/shared/table.ts
449
451
  /**
450
452
  * Generic reader for table-shaped check plugins.
451
453
  *
@@ -609,8 +611,7 @@ function canonicaliseRow(row, spec) {
609
611
  }
610
612
  return row;
611
613
  }
612
- //#endregion
613
- //#region src/shared/datetime.ts
614
+ // src/shared/datetime.ts
614
615
  const DATE_PATTERN = /^(\d{4})[-/.](\d{1,2})[-/.](\d{1,2})$/;
615
616
  const TIME_PATTERN = /^(\d{1,2}):(\d{2})(?::(\d{2}))?$/;
616
617
  function pad(value, width = 2) {
@@ -678,8 +679,7 @@ function instant(wall) {
678
679
  function diffMinutes(from, to) {
679
680
  return instant(to) - instant(from);
680
681
  }
681
- //#endregion
682
- //#region src/shared/report.ts
682
+ // src/shared/report.ts
683
683
  /** Locator fields that participate in the stable issue id, in fixed order. */
684
684
  const LOCATOR_ID_KEYS = [
685
685
  "file",
@@ -723,8 +723,7 @@ function sortValue(value) {
723
723
  }
724
724
  return target;
725
725
  }
726
- //#endregion
727
- //#region src/shared/rules.ts
726
+ // src/shared/rules.ts
728
727
  /**
729
728
  * Compose the one-line `basis` string rendered into reports.
730
729
  * @param basis - the rule's normative basis.
@@ -740,8 +739,7 @@ function formatBasis(basis, alsoBasis = []) {
740
739
  const parts = [render(basis), ...alsoBasis.map(render)];
741
740
  return parts.length === 1 ? parts[0] : `${parts[0]};另见 ${parts.slice(1).join(";另见 ")}`;
742
741
  }
743
- //#endregion
744
- //#region src/shared/rows.ts
742
+ // src/shared/rows.ts
745
743
  /**
746
744
  * The generic table-check engine.
747
745
  *
@@ -833,7 +831,7 @@ function optionalNumber(params, key) {
833
831
  function locatorOf(row, field) {
834
832
  const out = {};
835
833
  if (row !== void 0) out.row = row;
836
- if (field !== "") out.field = field;
834
+ if (field !== "") out.column = field;
837
835
  return out;
838
836
  }
839
837
  /**
@@ -1164,7 +1162,7 @@ function sumToConstant(ctx) {
1164
1162
  const total = parsed.reduce((sum, value) => sum + value, 0);
1165
1163
  const gap = Math.abs(total - target);
1166
1164
  if (gap <= tolerance) return;
1167
- ctx.add(locatorOf(void 0, field), `${parsed.length} 行的「${field}」合计 ${Number(total.toFixed(4))},与配置的目标值 ${target} 相差 ${Number(gap.toFixed(4))}`, `「${field}」的合计应为 ${target},允许偏差 ${tolerance}`, str(ctx.params, "fix", "核对是否有行遗漏或数值抄错;本条只做加法核对,不判断设置是否合规"));
1165
+ ctx.add(locatorOf(void 0, field), `${parsed.length} 行的「${field}」合计 ${Number(total.toFixed(4))},与配置的目标值 ${target} 相差 ${Number(gap.toFixed(4))}`, `「${field}」的合计应为 ${target},允许偏差 ${tolerance}`, str(ctx.params, "fix", "核对是否有行遗漏或数值抄错;本条只做加法核对,不评价分值设置本身"));
1168
1166
  }
1169
1167
  /** `countPerGroup` — each group value must appear at least N times. */
1170
1168
  function countPerGroup(ctx) {
@@ -2112,7 +2110,10 @@ function runChecks(input, ruleset, options) {
2112
2110
  const issues = [];
2113
2111
  const reasons = /* @__PURE__ */ new Map();
2114
2112
  const fired = /* @__PURE__ */ new Set();
2113
+ const disabled = /* @__PURE__ */ new Set([...ruleset.disabled, ...options.disabledRules]);
2114
+ const only = new Set(options.onlyRules);
2115
2115
  for (const rule of ruleset.rules) {
2116
+ if (disabled.has(rule.id) || only.size > 0 && !only.has(rule.id)) continue;
2116
2117
  const declaredCheck = typeof rule.params.check === "object" && rule.params.check !== null && !Array.isArray(rule.params.check) ? rule.params.check : {};
2117
2118
  const check = {
2118
2119
  ...rule.params,
@@ -2377,12 +2378,10 @@ function parseMaterial(source, target) {
2377
2378
  function runCheck(input, ruleset, options) {
2378
2379
  return runTableCheck(input, ruleset, options);
2379
2380
  }
2380
- //#endregion
2381
- //#region src/shared/wording.ts
2381
+ // src/shared/wording.ts
2382
2382
  /** Footer appended to every rendered report. */
2383
2383
  const DISCLAIMER = "免责声明:本报告由程序按声明的规则集自动生成,仅列出与所引条款之间的字面差异,供人工复核线索使用;不构成对任何事实、行为或文件的定性意见,也不替代主管人员、评审专家或监管机构的判断。规则集的时效性与适用范围以引用文件的最新有效版本为准。";
2384
- //#endregion
2385
- //#region src/view.ts
2384
+ // src/view.ts
2386
2385
  /**
2387
2386
  * Model-facing projection of a {@link Report}.
2388
2387
  *
@@ -2462,8 +2461,7 @@ function buildView(report) {
2462
2461
  reportJson: canonicalJson(report)
2463
2462
  };
2464
2463
  }
2465
- //#endregion
2466
- //#region src/shared/ruleset.ts
2464
+ // src/shared/ruleset.ts
2467
2465
  /**
2468
2466
  * Rule-pack loading and validation.
2469
2467
  *
@@ -2573,8 +2571,7 @@ function loadRuleset(source) {
2573
2571
  disabled
2574
2572
  };
2575
2573
  }
2576
- //#endregion
2577
- //#region src/shared/memo.ts
2574
+ // src/shared/memo.ts
2578
2575
  /**
2579
2576
  * Memoized loading of package-owned rule packs.
2580
2577
  *
@@ -2597,8 +2594,7 @@ function loadRulesetFile(path) {
2597
2594
  pending.catch(() => cache.delete(path));
2598
2595
  return pending;
2599
2596
  }
2600
- //#endregion
2601
- //#region src/index.ts
2597
+ // src/index.ts
2602
2598
  const name = "dsh-fmea-table-check";
2603
2599
  const inject = ["tools"];
2604
2600
  /** Tool id exposed to the model, and the row id in `cordis.patch.yml`. */
@@ -2735,5 +2731,4 @@ function apply(ctx, config) {
2735
2731
  }
2736
2732
  }));
2737
2733
  }
2738
- //#endregion
2739
2734
  export { Config, TOOL_NAME, apply, inject, name, resolvePackageFile };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-fmea-table-check",
3
- "version": "0.2.7",
3
+ "version": "0.2.9",
4
4
  "description": "FMEA 分析表要素齐备性与风险顺序数一致性核对(按公开的 FMEA 方法标准核对表内自洽,仅提示差异,不作出定性结论)",
5
5
  "type": "module",
6
6
  "main": "lib/index.mjs",
@@ -78,16 +78,15 @@
78
78
  "@deepseek-ai/schemastery": "^3.18.2"
79
79
  },
80
80
  "devDependencies": {
81
- "@deepseek-ai/cordis": "4.0.5-alpha.1",
82
- "@deepseek-ai/dsh-package-manifest": "0.2.1-rc.2",
81
+ "@deepseek-ai/cordis": "4.0.5",
82
+ "@deepseek-ai/dsh-package-manifest": "0.2.1-rc.3",
83
83
  "@deepseek-ai/dsh-tools": "0.2.1-rc.2",
84
- "@deepseek-ai/schemastery": "3.18.5-alpha.1",
84
+ "@deepseek-ai/schemastery": "3.18.5",
85
85
  "@types/node": "^22.20.1",
86
86
  "vitest": "^3.2.7",
87
- "@deepseek-ai/dsh-working-directory": "0.2.1-rc.2"
88
- },
89
- "dependencies": {
90
- "tsdown": "^0.22.14",
87
+ "@deepseek-ai/dsh-working-directory": "0.2.1-rc.2",
88
+ "tsdown": "^0.23.1",
91
89
  "typescript": "^5.9.3"
92
- }
90
+ },
91
+ "dependencies": {}
93
92
  }