ops-tune-workbench-plugin 0.0.0-stage → 0.0.1-beta.2

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 (183) hide show
  1. package/NOTICE.md +14 -0
  2. package/README.md +39 -2
  3. package/cordis.patch.yml +20 -0
  4. package/lib/client.js +4253 -0
  5. package/lib/host.js +2518 -0
  6. package/package.json +53 -4
  7. package/skills/tool-ops-tune/INSTALL.md +52 -0
  8. package/skills/tool-ops-tune/README.md +167 -0
  9. package/skills/tool-ops-tune/SKILL.md +93 -0
  10. package/skills/tool-ops-tune/agent/AGENTS.md +195 -0
  11. package/skills/tool-ops-tune/agent/agents/perf-implementer.md +68 -0
  12. package/skills/tool-ops-tune/agent/agents/perf-reviewer.md +86 -0
  13. package/skills/tool-ops-tune/agent/workflows/task-prompts.md +362 -0
  14. package/skills/tool-ops-tune/agent/workflows/troubleshooting.md +43 -0
  15. package/skills/tool-ops-tune/docs/figures/opstune-architecture.png +0 -0
  16. package/skills/tool-ops-tune/docs/figures/opstune-architecture.svg +253 -0
  17. package/skills/tool-ops-tune/docs/ops-tune-design.md +404 -0
  18. package/skills/tool-ops-tune/docs//347/224/250/344/276/213/346/236/204/345/273/272.md +714 -0
  19. package/skills/tool-ops-tune/docs//347/237/245/350/257/206/345/272/223/350/247/204/350/214/203.md +103 -0
  20. package/skills/tool-ops-tune/evals/evals.json +242 -0
  21. package/skills/tool-ops-tune/ops-collect/SKILL.md +146 -0
  22. package/skills/tool-ops-tune/ops-collect/references/tool-routing.md +86 -0
  23. package/skills/tool-ops-tune/ops-collect/scripts/collect_board.sh +444 -0
  24. package/skills/tool-ops-tune/ops-collect/scripts/collect_cases.py +368 -0
  25. package/skills/tool-ops-tune/ops-collect/scripts/collect_sim.sh +134 -0
  26. package/skills/tool-ops-tune/ops-collect/scripts/csv_to_db.py +314 -0
  27. package/skills/tool-ops-tune/ops-collect/scripts/db_bench.py +545 -0
  28. package/skills/tool-ops-tune/ops-collect/scripts/facts_bridge.py +1063 -0
  29. package/skills/tool-ops-tune/ops-collect/scripts/isolation_test.py +454 -0
  30. package/skills/tool-ops-tune/ops-collect/scripts/jsonl_to_cases.py +163 -0
  31. package/skills/tool-ops-tune/ops-family/SKILL.md +76 -0
  32. package/skills/tool-ops-tune/ops-family/references/broadcast/advanced_tiling.md +92 -0
  33. package/skills/tool-ops-tune/ops-family/references/broadcast/broadcast_design.md +160 -0
  34. package/skills/tool-ops-tune/ops-family/references/broadcast/code/broadcast_add_kernel.cpp +126 -0
  35. package/skills/tool-ops-tune/ops-family/references/broadcast/code/broadcast_add_tiling.cpp +144 -0
  36. package/skills/tool-ops-tune/ops-family/references/broadcast/code/broadcast_tiling_common.h +401 -0
  37. package/skills/tool-ops-tune/ops-family/references/broadcast/code/onedim_add_kernel.cpp +107 -0
  38. package/skills/tool-ops-tune/ops-family/references/broadcast/code/onedim_add_tiling.cpp +64 -0
  39. package/skills/tool-ops-tune/ops-family/references/broadcast/datacopypad_design.md +46 -0
  40. package/skills/tool-ops-tune/ops-family/references/broadcast/guide.md +14 -0
  41. package/skills/tool-ops-tune/ops-family/references/broadcast/nddma_design.md +53 -0
  42. package/skills/tool-ops-tune/ops-family/references/broadcast/onedim_design.md +114 -0
  43. package/skills/tool-ops-tune/ops-family/references/broadcast/ub_broadcast_design.md +67 -0
  44. package/skills/tool-ops-tune/ops-family/references/common/datacopy_optimization_design.md +351 -0
  45. package/skills/tool-ops-tune/ops-family/references/common/index.md +9 -0
  46. package/skills/tool-ops-tune/ops-family/references/common/tail_block_design.md +268 -0
  47. package/skills/tool-ops-tune/ops-family/references/common/timing_harness/index.md +38 -0
  48. package/skills/tool-ops-tune/ops-family/references/common/timing_harness/timing_harness_aclrt_event.cpp +199 -0
  49. package/skills/tool-ops-tune/ops-family/references/common/timing_harness/timing_harness_torch_event.py +130 -0
  50. package/skills/tool-ops-tune/ops-family/references/common/ub_resident_design.md +342 -0
  51. package/skills/tool-ops-tune/ops-family/references/conversion/guide.md +69 -0
  52. package/skills/tool-ops-tune/ops-family/references/conversion/index.md +4 -0
  53. package/skills/tool-ops-tune/ops-family/references/conversion/templates/dav3510/transpose_base.template +81 -0
  54. package/skills/tool-ops-tune/ops-family/references/conversion/templates/dav3510/transpose_big_dim.template +217 -0
  55. package/skills/tool-ops-tune/ops-family/references/conversion/templates/dav3510/transpose_cut_one_axis.template +336 -0
  56. package/skills/tool-ops-tune/ops-family/references/conversion/templates/dav3510/transpose_cut_two_axis.template +781 -0
  57. package/skills/tool-ops-tune/ops-family/references/conversion/templates/dav3510/transpose_n_last.template +340 -0
  58. package/skills/tool-ops-tune/ops-family/references/conversion/templates/dav3510/transpose_small_shape.template +321 -0
  59. package/skills/tool-ops-tune/ops-family/references/conversion/templates/dav3510/transpose_tensor_move.template +102 -0
  60. package/skills/tool-ops-tune/ops-family/references/conversion/templates/dav3510/transpose_transdata_5hd.template +480 -0
  61. package/skills/tool-ops-tune/ops-family/references/conversion/templates/dav3510/transpose_transdata_5hd_021axis.template +533 -0
  62. package/skills/tool-ops-tune/ops-family/references/conversion/templates/dav3510/transpose_with_gather.template +688 -0
  63. package/skills/tool-ops-tune/ops-family/references/conversion/templates/transpose_tiling_data.template +192 -0
  64. package/skills/tool-ops-tune/ops-family/references/conversion/transpose_big_dim.md +220 -0
  65. package/skills/tool-ops-tune/ops-family/references/conversion/transpose_cut_one_axis.md +175 -0
  66. package/skills/tool-ops-tune/ops-family/references/conversion/transpose_cut_two_axis.md +177 -0
  67. package/skills/tool-ops-tune/ops-family/references/conversion/transpose_fusion_design.md +398 -0
  68. package/skills/tool-ops-tune/ops-family/references/conversion/transpose_gather.md +191 -0
  69. package/skills/tool-ops-tune/ops-family/references/conversion/transpose_n_last.md +276 -0
  70. package/skills/tool-ops-tune/ops-family/references/conversion/transpose_small_shape.md +315 -0
  71. package/skills/tool-ops-tune/ops-family/references/conversion/transpose_tensor_move.md +203 -0
  72. package/skills/tool-ops-tune/ops-family/references/conversion/transpose_tiling_data.md +176 -0
  73. package/skills/tool-ops-tune/ops-family/references/conversion/transpose_vconv_021.md +206 -0
  74. package/skills/tool-ops-tune/ops-family/references/conversion/transpose_vconv_5hd.md +179 -0
  75. package/skills/tool-ops-tune/ops-family/references/elementwise/double_buffer_design.md +288 -0
  76. package/skills/tool-ops-tune/ops-family/references/elementwise/guide.md +46 -0
  77. package/skills/tool-ops-tune/ops-family/references/elementwise/index.md +10 -0
  78. package/skills/tool-ops-tune/ops-family/references/elementwise/templates/add_custom/CMakeLists.txt +131 -0
  79. package/skills/tool-ops-tune/ops-family/references/elementwise/templates/add_custom/README.md +55 -0
  80. package/skills/tool-ops-tune/ops-family/references/elementwise/templates/add_custom/op_extension/add_custom_torch.cpp +80 -0
  81. package/skills/tool-ops-tune/ops-family/references/elementwise/templates/add_custom/op_extension/ops.h +23 -0
  82. package/skills/tool-ops-tune/ops-family/references/elementwise/templates/add_custom/op_extension/register.cpp +30 -0
  83. package/skills/tool-ops-tune/ops-family/references/elementwise/templates/add_custom/op_host/add_custom.asc +149 -0
  84. package/skills/tool-ops-tune/ops-family/references/elementwise/templates/add_custom/op_host/data_utils.h +97 -0
  85. package/skills/tool-ops-tune/ops-family/references/elementwise/templates/add_custom/op_kernel/add_custom_kernel.asc +136 -0
  86. package/skills/tool-ops-tune/ops-family/references/elementwise/templates/add_custom/op_kernel/add_custom_tiling.h +31 -0
  87. package/skills/tool-ops-tune/ops-family/references/elementwise/templates/add_custom/run.sh +86 -0
  88. package/skills/tool-ops-tune/ops-family/references/elementwise/templates/add_custom/scripts/gen_data.py +70 -0
  89. package/skills/tool-ops-tune/ops-family/references/elementwise/templates/add_custom/scripts/golden.py +34 -0
  90. package/skills/tool-ops-tune/ops-family/references/elementwise/templates/add_custom/scripts/test_torch.py +99 -0
  91. package/skills/tool-ops-tune/ops-family/references/elementwise/templates/add_custom/scripts/verify_result.py +56 -0
  92. package/skills/tool-ops-tune/ops-family/references/elementwise/templates/usage_guide.md +61 -0
  93. package/skills/tool-ops-tune/ops-family/references/elementwise/vector_efficiency_design.md +203 -0
  94. package/skills/tool-ops-tune/ops-family/references/fa/fa_mixed_kernel_design.md +174 -0
  95. package/skills/tool-ops-tune/ops-family/references/fa/fa_roofline_design.md +141 -0
  96. package/skills/tool-ops-tune/ops-family/references/fa/guide.md +87 -0
  97. package/skills/tool-ops-tune/ops-family/references/knowledge_gaps.json +56 -0
  98. package/skills/tool-ops-tune/ops-family/references/matmul/best-practices-guide.md +14 -0
  99. package/skills/tool-ops-tune/ops-family/references/matmul/fullload_design.md +344 -0
  100. package/skills/tool-ops-tune/ops-family/references/matmul/guide.md +52 -0
  101. package/skills/tool-ops-tune/ops-family/references/matmul/mte2_preload_design.md +320 -0
  102. package/skills/tool-ops-tune/ops-family/references/matmul/pingpong_design.md +254 -0
  103. package/skills/tool-ops-tune/ops-family/references/matmul/scale_coalescing_design.md +282 -0
  104. package/skills/tool-ops-tune/ops-family/references/matmul/streamk_design.md +374 -0
  105. package/skills/tool-ops-tune/ops-family/references/matmul/swat_design.md +423 -0
  106. package/skills/tool-ops-tune/ops-family/references/matmul/templates/matmul_basic_blaze.template +165 -0
  107. package/skills/tool-ops-tune/ops-family/references/matmul/templates/usage_guide.md +29 -0
  108. package/skills/tool-ops-tune/ops-family/references/mc2/best-practices-guide.md +43 -0
  109. package/skills/tool-ops-tune/ops-family/references/mc2/guide.md +42 -0
  110. package/skills/tool-ops-tune/ops-family/references/mc2/local_matmul_design.md +130 -0
  111. package/skills/tool-ops-tune/ops-family/references/mc2/pipeline_balancing_design.md +502 -0
  112. package/skills/tool-ops-tune/ops-family/references/reduce/guide.md +178 -0
  113. package/skills/tool-ops-tune/ops-family/references/reduce/templates/dav310/kernel_utils.template +75 -0
  114. package/skills/tool-ops-tune/ops-family/references/reduce/templates/dav310/softmax_v2_ar_full_load.template +429 -0
  115. package/skills/tool-ops-tune/ops-family/references/reduce/templates/dav310/softmax_v2_ar_recompute.template +485 -0
  116. package/skills/tool-ops-tune/ops-family/references/reduce/templates/dav310/softmax_v2_ar_small_r.template +348 -0
  117. package/skills/tool-ops-tune/ops-family/references/reduce/templates/dav310/softmax_v2_ara_full_load.template +574 -0
  118. package/skills/tool-ops-tune/ops-family/references/reduce/templates/dav310/softmax_v2_ara_online.template +324 -0
  119. package/skills/tool-ops-tune/ops-family/references/reduce/templates/dav310/softmax_v2_ara_recompute.template +436 -0
  120. package/skills/tool-ops-tune/ops-family/references/reduce/templates/dav310/softmax_v2_base.template +950 -0
  121. package/skills/tool-ops-tune/ops-family/references/reduce/templates/fused_attention_online_softmax_design.md +428 -0
  122. package/skills/tool-ops-tune/ops-family/references/reduce/templates/softmax_v2_ar_full_load.md +137 -0
  123. package/skills/tool-ops-tune/ops-family/references/reduce/templates/softmax_v2_ar_recompute.md +135 -0
  124. package/skills/tool-ops-tune/ops-family/references/reduce/templates/softmax_v2_ar_small_r.md +122 -0
  125. package/skills/tool-ops-tune/ops-family/references/reduce/templates/softmax_v2_ara_full_load.md +144 -0
  126. package/skills/tool-ops-tune/ops-family/references/reduce/templates/softmax_v2_ara_online.md +185 -0
  127. package/skills/tool-ops-tune/ops-family/references/reduce/templates/softmax_v2_ara_recompute.md +163 -0
  128. package/skills/tool-ops-tune/ops-family/references/reduce/templates/softmax_v2_tiling.template +460 -0
  129. package/skills/tool-ops-tune/ops-family/references/reduce/templates/softmax_v2_tiling_data.template +278 -0
  130. package/skills/tool-ops-tune/ops-family/references/reduce/templates/state_resident_design.md +337 -0
  131. package/skills/tool-ops-tune/ops-family/references/reduce/templates/usage_guide.md +253 -0
  132. package/skills/tool-ops-tune/ops-family/references/scalar/coding_principles.md +476 -0
  133. package/skills/tool-ops-tune/ops-family/references/scalar/conv_scalar.md +163 -0
  134. package/skills/tool-ops-tune/ops-family/references/scalar/guide.md +30 -0
  135. package/skills/tool-ops-tune/ops-family/references/simt/guide.md +91 -0
  136. package/skills/tool-ops-tune/ops-family/references/simt/optimization-guide.md +110 -0
  137. package/skills/tool-ops-tune/ops-family/references/sort/guide.md +83 -0
  138. package/skills/tool-ops-tune/ops-family/references/sort/radix_sort.md +354 -0
  139. package/skills/tool-ops-tune/ops-family/scripts/family_asset_audit.py +68 -0
  140. package/skills/tool-ops-tune/ops-family/scripts/tiling_candidates.py +419 -0
  141. package/skills/tool-ops-tune/ops-mechanism/SKILL.md +23 -0
  142. package/skills/tool-ops-tune/ops-mechanism/cases/ascendc/case_groupedmatmul_pipeline.md +23 -0
  143. package/skills/tool-ops-tune/ops-mechanism/cases/ascendc/case_triton_atomic_revert.md +19 -0
  144. package/skills/tool-ops-tune/ops-mechanism/cases/mc2/case_mc2_fusion.md +19 -0
  145. package/skills/tool-ops-tune/ops-mechanism/references/optimize/api-usage.md +70 -0
  146. package/skills/tool-ops-tune/ops-mechanism/references/optimize/ascendc-regbase-vf.md +45 -0
  147. package/skills/tool-ops-tune/ops-mechanism/references/optimize/ascendc-tiling.md +51 -0
  148. package/skills/tool-ops-tune/ops-mechanism/references/optimize/data-copy.md +67 -0
  149. package/skills/tool-ops-tune/ops-mechanism/references/optimize/index.md +45 -0
  150. package/skills/tool-ops-tune/ops-mechanism/references/optimize/mc2-balancing.md +77 -0
  151. package/skills/tool-ops-tune/ops-mechanism/references/optimize/mc2.md +103 -0
  152. package/skills/tool-ops-tune/ops-mechanism/references/optimize/memory-hierarchy.md +40 -0
  153. package/skills/tool-ops-tune/ops-mechanism/references/optimize/pipeline.md +95 -0
  154. package/skills/tool-ops-tune/ops-mechanism/scripts/case_backfill.py +170 -0
  155. package/skills/tool-ops-tune/ops-mechanism/scripts/log_gap.py +145 -0
  156. package/skills/tool-ops-tune/ops-mechanism/scripts/mc2_search.py +367 -0
  157. package/skills/tool-ops-tune/ops-report/SKILL.md +77 -0
  158. package/skills/tool-ops-tune/ops-verdict/evals/run_evals.py +837 -0
  159. package/skills/tool-ops-tune/ops-verdict/evals/smoke/install-hooks.sh +65 -0
  160. package/skills/tool-ops-tune/ops-verdict/evals/smoke/run_smoke.sh +405 -0
  161. package/skills/tool-ops-tune/ops-verdict/fixtures/core_tail_a5.csv +25 -0
  162. package/skills/tool-ops-tune/ops-verdict/fixtures/few_cores_a5.csv +5 -0
  163. package/skills/tool-ops-tune/ops-verdict/fixtures/mte2_bound_a2.csv +17 -0
  164. package/skills/tool-ops-tune/ops-verdict/fixtures/multi_kernel_mix_a5.csv +7 -0
  165. package/skills/tool-ops-tune/ops-verdict/fixtures/no_bound_a5.csv +9 -0
  166. package/skills/tool-ops-tune/ops-verdict/fixtures/serial_no_overlap_a2.csv +9 -0
  167. package/skills/tool-ops-tune/ops-verdict/fixtures/vec_bound_a5.csv +9 -0
  168. package/skills/tool-ops-tune/ops-verdict/references/io-contracts.md +94 -0
  169. package/skills/tool-ops-tune/ops-verdict/references/rule-schema.md +130 -0
  170. package/skills/tool-ops-tune/ops-verdict/references/scope-schema.md +61 -0
  171. package/skills/tool-ops-tune/ops-verdict/references/soc-spec.yaml +140 -0
  172. package/skills/tool-ops-tune/ops-verdict/rules/L0-instruction.yaml +67 -0
  173. package/skills/tool-ops-tune/ops-verdict/rules/L1-single-core.yaml +316 -0
  174. package/skills/tool-ops-tune/ops-verdict/rules/L2-inter-core.yaml +173 -0
  175. package/skills/tool-ops-tune/ops-verdict/rules/L3-inter-card.yaml +156 -0
  176. package/skills/tool-ops-tune/ops-verdict/scripts/batch_pipeline.py +444 -0
  177. package/skills/tool-ops-tune/ops-verdict/scripts/calibrate.py +249 -0
  178. package/skills/tool-ops-tune/ops-verdict/scripts/delta_compare.py +244 -0
  179. package/skills/tool-ops-tune/ops-verdict/scripts/render_html.py +274 -0
  180. package/skills/tool-ops-tune/ops-verdict/scripts/snapshot.py +200 -0
  181. package/skills/tool-ops-tune/ops-verdict/scripts/trace_bubble.py +331 -0
  182. package/skills/tool-ops-tune/ops-verdict/scripts/verdict.py +1072 -0
  183. package/skills/tool-ops-tune/scripts/diff_audit.py +281 -0
@@ -0,0 +1,281 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # ----------------------------------------------------------------------------------------------------------
4
+ # Copyright (c) 2026 Huawei Technologies Co., Ltd.
5
+ # This program is free software, you can redistribute it and/or modify it under the terms and conditions of
6
+ # CANN Open Software License Agreement Version 2.0 (the "License").
7
+ # Please refer to the License for details. You may not use this file except in compliance with the License.
8
+ # THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
9
+ # INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
10
+ # See LICENSE in the root of the software repository for the full text of the License.
11
+ # ----------------------------------------------------------------------------------------------------------
12
+ """diff_audit.py — 实施范围机器校验(REVIEW2 G10 / 反馈 P1-3 ①)
13
+
14
+ 设计对齐:
15
+ - 单变量铁律与 diff 范围此前完全靠 perf-implementer 自报("diff 摘要(改动点
16
+ 列表)"),无机器校验——多机制混入导致的归因失败(KEEP 了无法归因的收益)
17
+ 无机制拦截。
18
+ - 本脚本用目录 diff + 方案卡 diff_sketch 对照做机器校验:改动文件集超出
19
+ 方案卡声明的范围 → 该轮标 UNATTRIBUTABLE,禁止进 KEEP 仲裁(退出码 2)。
20
+ - 与 perf-reviewer subagent 的分工:本脚本只做**范围**校验(哪些文件被动了),
21
+ 代码质量与模板保真(MicroAPI VF 是否被降级)由 perf-reviewer subagent
22
+ 独立审查(P1-3 ②)。
23
+
24
+ 用法:
25
+ python3 diff_audit.py --baseline <原工程目录> --opt <优化副本目录> \
26
+ [--candidates candidates.json --index 0] [-o audit.json]
27
+
28
+ 方案卡对照(--candidates 提供时):
29
+ candidates.json 的条目可带 diff_sketch_files(数组:预期改动的文件/目录,
30
+ 相对工程根,支持目录前缀匹配)——有声明则逐文件对照;未声明时只输出
31
+ 改动清单(audit 记录在案,不判 UNATTRIBUTABLE——不能拿不存在的声明当红线)。
32
+
33
+ 判定:
34
+ exit 0 范围内(或未声明范围:记录不判罚)
35
+ exit 2 超范围(UNATTRIBUTABLE:该轮收益不可归因到方案卡机制,禁进 KEEP 仲裁)
36
+
37
+ 排除项(测量设施与产物,非优化变量——ops-collect 计时口径表既有纪律):
38
+ *.o / *.so / *.d / build/ 输出 / .git / __pycache__ / result.json /
39
+ comparison.md / collection_manifest.json / PROF_* / *.log
40
+ """
41
+
42
+ from __future__ import annotations
43
+
44
+ import argparse
45
+ import datetime
46
+ import json
47
+ import subprocess
48
+ import sys
49
+ from pathlib import Path
50
+
51
+ SCHEMA = "opstune.diff-audit/1.0"
52
+
53
+ # 测量设施与构建产物:复制目录带入的 harness / 采集产物 / 编译中间物不属优化变量
54
+ # (ops-collect 计时口径表既有纪律:harness 属测量设施而非优化变量)
55
+ EXCLUDE_NAMES = {
56
+ "result.json",
57
+ "comparison.md",
58
+ "collection_manifest.json",
59
+ "verdict.json",
60
+ "audit.json",
61
+ "scalars.json",
62
+ "timing_harness.log",
63
+ "iso_result.json",
64
+ "perf_data.csv",
65
+ "scope.json",
66
+ # 计时 harness 文件(timing_harness 货架模板拷入:测量设施非优化变量)
67
+ "timing_harness_aclrt_event.cpp",
68
+ "timing_harness_torch_event.py",
69
+ }
70
+ EXCLUDE_PARTS = {
71
+ "build",
72
+ ".git",
73
+ "__pycache__",
74
+ "out",
75
+ "prof",
76
+ "tuning_artifacts",
77
+ "mindstudio_profiler_output",
78
+ "PROF_DATA",
79
+ "node_modules",
80
+ }
81
+
82
+
83
+ def is_excluded(rel: str) -> bool:
84
+ p = Path(rel)
85
+ if p.name in EXCLUDE_NAMES:
86
+ return True
87
+ if p.suffix in (".o", ".so", ".d", ".log", ".pyc"):
88
+ return True
89
+ return any(part in EXCLUDE_PARTS for part in p.parts)
90
+
91
+
92
+ def diff_files(baseline: Path, opt: Path) -> dict[str, str]:
93
+ """git diff --no-index --name-status(M/A/D 三态;R 罕见按 M 处理)。"""
94
+ proc = subprocess.run(
95
+ [
96
+ "git",
97
+ "diff",
98
+ "--no-index",
99
+ "--name-status",
100
+ "--no-renames",
101
+ str(baseline),
102
+ str(opt),
103
+ ],
104
+ capture_output=True,
105
+ text=True,
106
+ )
107
+ out: dict[str, str] = {}
108
+ for line in proc.stdout.splitlines():
109
+ line = line.strip()
110
+ if not line or "\t" not in line:
111
+ continue
112
+ status, path = line.split("\t", 1)
113
+ # path 形如 <baseline>/xxx 或 <opt>/xxx —— 剥掉前缀取相对路径
114
+ for root in (baseline, opt):
115
+ prefix = str(root).rstrip("/") + "/"
116
+ if path.startswith(prefix):
117
+ rel = path[len(prefix) :]
118
+ status = (
119
+ "D"
120
+ if status.startswith("D")
121
+ else ("A" if status.startswith("A") else "M")
122
+ )
123
+ out[rel] = status
124
+ break
125
+ return out
126
+
127
+
128
+ def declared_files(card: dict) -> list[str] | None:
129
+ """方案卡声明的改动文件集(diff_sketch_files;旧卡无此字段 → None)。"""
130
+ v = card.get("diff_sketch_files")
131
+ if isinstance(v, list) and v and all(isinstance(x, str) for x in v):
132
+ return v
133
+ return None
134
+
135
+
136
+ def matches_declared(rel: str, declared: list[str]) -> bool:
137
+ """rel 命中声明集:精确路径或目录前缀(声明 'op_kernel/' 覆盖其下全部)。"""
138
+ p = Path(rel)
139
+ for d in declared:
140
+ d = d.strip().strip("/")
141
+ if not d:
142
+ continue
143
+ if rel == d or str(p) == d:
144
+ return True
145
+ if d.endswith("/") and rel.startswith(d):
146
+ return True
147
+ if not d.endswith("/") and (rel.startswith(d + "/")):
148
+ return True
149
+ return False
150
+
151
+
152
+ def main() -> int:
153
+ ap = argparse.ArgumentParser(
154
+ description="实施范围机器校验(单变量铁律的 diff 侧闸门)"
155
+ )
156
+ ap.add_argument(
157
+ "--baseline", required=True, help="原工程目录(perf-implementer 复制源)"
158
+ )
159
+ ap.add_argument("--opt", required=True, help="优化副本目录")
160
+ ap.add_argument(
161
+ "--candidates", default=None, help="candidates.json(对照第 index 张方案卡)"
162
+ )
163
+ ap.add_argument("--index", type=int, default=0, help="方案卡序号(默认 0)")
164
+ ap.add_argument(
165
+ "--max-changed-lines",
166
+ type=int,
167
+ default=2000,
168
+ help="改动行数上限(防爆改;超出按超范围处置)",
169
+ )
170
+ ap.add_argument("-o", "--output", default=None, help="audit.json 输出")
171
+ args = ap.parse_args()
172
+
173
+ baseline, opt = Path(args.baseline), Path(args.opt)
174
+ if not baseline.is_dir() or not opt.is_dir():
175
+ print(
176
+ f"ERROR: --baseline/--opt 必须是目录({baseline} / {opt})", file=sys.stderr
177
+ )
178
+ return 1
179
+
180
+ card = {}
181
+ if args.candidates:
182
+ data = json.loads(Path(args.candidates).read_text(encoding="utf-8"))
183
+ cards = (
184
+ data
185
+ if isinstance(data, list)
186
+ else data.get("candidates", data.get("cards", []))
187
+ )
188
+ if not isinstance(cards, list) or args.index >= len(cards):
189
+ print(
190
+ f"ERROR: candidates.json 无序号 {args.index} 的方案卡", file=sys.stderr
191
+ )
192
+ return 1
193
+ card = cards[args.index]
194
+
195
+ changed = {
196
+ rel: st for rel, st in diff_files(baseline, opt).items() if not is_excluded(rel)
197
+ }
198
+ # 统计改动行数(仅 M 文件;A/D 大文件同样计入 diff 语义但极少见)
199
+ n_lines = 0
200
+ if changed:
201
+ proc = subprocess.run(
202
+ [
203
+ "git",
204
+ "diff",
205
+ "--no-index",
206
+ "--numstat",
207
+ "--no-renames",
208
+ str(baseline),
209
+ str(opt),
210
+ ],
211
+ capture_output=True,
212
+ text=True,
213
+ )
214
+ for line in proc.stdout.splitlines():
215
+ parts = line.split("\t")
216
+ if len(parts) >= 3:
217
+ try:
218
+ n_lines += int(parts[0]) + int(parts[1])
219
+ except ValueError:
220
+ pass
221
+
222
+ declared = declared_files(card)
223
+ out_of_scope = []
224
+ if declared is not None:
225
+ out_of_scope = [rel for rel in changed if not matches_declared(rel, declared)]
226
+ oversized = n_lines > args.max_changed_lines
227
+
228
+ audit = {
229
+ "schema": SCHEMA,
230
+ "generated_at": datetime.datetime.now().isoformat(timespec="seconds"),
231
+ "baseline": str(baseline),
232
+ "opt": str(opt),
233
+ "mechanism": card.get("mechanism"),
234
+ "target_rule": card.get("target_rule"),
235
+ "declared_files": declared,
236
+ "changed_files": [
237
+ {"file": rel, "status": st} for rel, st in sorted(changed.items())
238
+ ],
239
+ "changed_lines": n_lines,
240
+ "out_of_scope": out_of_scope,
241
+ "oversized": oversized,
242
+ "verdict": "OK" if (not out_of_scope and not oversized) else "UNATTRIBUTABLE",
243
+ }
244
+ if args.output:
245
+ out = Path(args.output)
246
+ out.parent.mkdir(parents=True, exist_ok=True)
247
+ out.write_text(
248
+ json.dumps(audit, indent=2, ensure_ascii=False) + "\n", encoding="utf-8"
249
+ )
250
+ print(f"audit → {out}")
251
+
252
+ print(
253
+ f"diff audit: {audit['verdict']}({len(changed)} 文件 / {n_lines} 行"
254
+ f"{',方案卡未声明范围:仅记录' if declared is None else ''})"
255
+ )
256
+ for rel, st in sorted(changed.items()):
257
+ mark = " ✗ 超范围" if rel in out_of_scope else ""
258
+ print(f" [{st}] {rel}{mark}")
259
+ if out_of_scope:
260
+ print(
261
+ f"\nERROR: {len(out_of_scope)} 个文件超出方案卡 diff_sketch_files 声明范围——"
262
+ "该轮收益不可归因(UNATTRIBUTABLE),禁止进 KEEP 仲裁;",
263
+ file=sys.stderr,
264
+ )
265
+ print(
266
+ " 处置:回滚超范围改动重测,或确认后把文件补进方案卡并说明为何属同一原子机制。",
267
+ file=sys.stderr,
268
+ )
269
+ return 2
270
+ if oversized:
271
+ print(
272
+ f"\nERROR: 改动 {n_lines} 行 > 上限 {args.max_changed_lines}——疑似混入无关改动"
273
+ "(UNATTRIBUTABLE)。确属大改(如模板整体替换)时用 --max-changed-lines 重估。",
274
+ file=sys.stderr,
275
+ )
276
+ return 2
277
+ return 0
278
+
279
+
280
+ if __name__ == "__main__":
281
+ sys.exit(main())