coding-agent-harness 1.0.5 → 1.0.6

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 (260) hide show
  1. package/CONTRIBUTING.md +2 -2
  2. package/README.md +63 -3
  3. package/README.zh-CN.md +52 -3
  4. package/SKILL.md +43 -43
  5. package/dist/build-dist.mjs +189 -0
  6. package/dist/check-dist-observation.mjs +428 -0
  7. package/dist/check-harness.mjs +489 -0
  8. package/dist/check-import-graph.mjs +511 -0
  9. package/dist/check-runtime-emit.mjs +304 -0
  10. package/dist/check-type-boundaries.mjs +139 -0
  11. package/dist/commands/dashboard-command.mjs +80 -0
  12. package/dist/commands/migration-command.mjs +152 -0
  13. package/dist/commands/preset-command.mjs +91 -0
  14. package/dist/commands/task-command.mjs +324 -0
  15. package/dist/harness.mjs +304 -0
  16. package/dist/lib/capability-registry.mjs +643 -0
  17. package/dist/lib/check-module-parallel.mjs +227 -0
  18. package/dist/lib/check-profiles.mjs +414 -0
  19. package/dist/lib/check-task-contracts.mjs +54 -0
  20. package/dist/lib/core-shared.mjs +254 -0
  21. package/dist/lib/dashboard-data.mjs +608 -0
  22. package/dist/lib/dashboard-workbench.mjs +334 -0
  23. package/dist/lib/dashboard-writer.mjs +200 -0
  24. package/dist/lib/git-status-summary.mjs +45 -0
  25. package/dist/lib/governance-index-generator.mjs +236 -0
  26. package/dist/lib/governance-sync.mjs +617 -0
  27. package/dist/lib/governance-table-boundary.mjs +161 -0
  28. package/{scripts → dist}/lib/harness-core.mjs +2 -0
  29. package/dist/lib/harness-paths.mjs +338 -0
  30. package/dist/lib/lesson-maintenance.mjs +139 -0
  31. package/dist/lib/markdown-utils.mjs +193 -0
  32. package/dist/lib/migration-planner.mjs +439 -0
  33. package/dist/lib/migration-support.mjs +317 -0
  34. package/dist/lib/phase-kind.mjs +46 -0
  35. package/dist/lib/preset-audit-contracts.mjs +40 -0
  36. package/dist/lib/preset-engine.mjs +516 -0
  37. package/dist/lib/preset-registry.mjs +831 -0
  38. package/dist/lib/preset-resource-contracts.mjs +83 -0
  39. package/dist/lib/review-confirm-git-gate.mjs +244 -0
  40. package/dist/lib/status-builder.mjs +87 -0
  41. package/{scripts → dist}/lib/status-dashboard-renderer.mjs +44 -46
  42. package/dist/lib/structure-migration.mjs +404 -0
  43. package/dist/lib/subagent-authorization-audit.mjs +198 -0
  44. package/dist/lib/task-audit-metadata.mjs +376 -0
  45. package/dist/lib/task-audit-migration.mjs +355 -0
  46. package/dist/lib/task-completion-consistency.mjs +29 -0
  47. package/dist/lib/task-index.mjs +133 -0
  48. package/dist/lib/task-lesson-candidates.mjs +239 -0
  49. package/dist/lib/task-lesson-sedimentation.mjs +300 -0
  50. package/dist/lib/task-lifecycle/create-task-helpers.mjs +84 -0
  51. package/dist/lib/task-lifecycle/phase-sync.mjs +82 -0
  52. package/dist/lib/task-lifecycle/review-confirm.mjs +93 -0
  53. package/dist/lib/task-lifecycle/review-gates.mjs +62 -0
  54. package/dist/lib/task-lifecycle/review-submission.mjs +52 -0
  55. package/dist/lib/task-lifecycle/scaffold-provenance.mjs +54 -0
  56. package/dist/lib/task-lifecycle/template-files.mjs +52 -0
  57. package/dist/lib/task-lifecycle/text-utils.mjs +26 -0
  58. package/dist/lib/task-lifecycle.mjs +611 -0
  59. package/dist/lib/task-metadata.mjs +116 -0
  60. package/dist/lib/task-review-model.mjs +474 -0
  61. package/dist/lib/task-scanner.mjs +439 -0
  62. package/dist/lib/task-tombstone-commands.mjs +125 -0
  63. package/dist/postinstall.mjs +14 -0
  64. package/dist/run-built-tests.mjs +84 -0
  65. package/docs-release/README.md +1 -0
  66. package/docs-release/architecture/overview.md +12 -12
  67. package/docs-release/architecture/overview.zh-CN.md +12 -12
  68. package/docs-release/architecture/system-explainer/01-system-overview.md +15 -14
  69. package/docs-release/architecture/system-explainer/02-module-dependency.md +8 -8
  70. package/docs-release/architecture/system-explainer/03-task-lifecycle.md +3 -3
  71. package/docs-release/architecture/system-explainer/04-check-and-governance.md +9 -7
  72. package/docs-release/architecture/system-explainer/05-data-flow.md +5 -5
  73. package/docs-release/architecture/system-explainer/06-preset-and-migration.md +1 -4
  74. package/docs-release/architecture/system-explainer/en-US/01-system-overview.md +15 -14
  75. package/docs-release/architecture/system-explainer/en-US/02-module-dependency.md +8 -8
  76. package/docs-release/architecture/system-explainer/en-US/03-task-lifecycle.md +3 -3
  77. package/docs-release/architecture/system-explainer/en-US/04-check-and-governance.md +10 -8
  78. package/docs-release/architecture/system-explainer/en-US/05-data-flow.md +5 -5
  79. package/docs-release/architecture/system-explainer/en-US/06-preset-and-migration.md +1 -4
  80. package/docs-release/guides/agent-installation.en-US.md +14 -8
  81. package/docs-release/guides/agent-installation.md +14 -8
  82. package/docs-release/guides/contributing.md +3 -3
  83. package/docs-release/guides/contributing.zh-CN.md +3 -3
  84. package/docs-release/guides/document-audience-and-surfaces.en-US.md +10 -10
  85. package/docs-release/guides/document-audience-and-surfaces.md +10 -10
  86. package/docs-release/guides/legacy-migration-agent-prompt.md +25 -2
  87. package/docs-release/guides/legacy-migration-agent-prompt.zh-CN.md +25 -2
  88. package/docs-release/guides/migration-playbook.en-US.md +63 -1
  89. package/docs-release/guides/migration-playbook.md +59 -1
  90. package/docs-release/guides/parent-control-repository-pattern.en-US.md +25 -25
  91. package/docs-release/guides/parent-control-repository-pattern.md +25 -25
  92. package/docs-release/guides/preset-development.md +2 -2
  93. package/docs-release/guides/repository-operating-models.en-US.md +21 -21
  94. package/docs-release/guides/repository-operating-models.md +21 -21
  95. package/docs-release/guides/task-state-machine.en-US.md +5 -5
  96. package/docs-release/guides/task-state-machine.md +5 -5
  97. package/docs-release/guides/typescript-runtime-migration-closeout.md +96 -0
  98. package/examples/minimal-project/AGENTS.md +2 -2
  99. package/examples/minimal-project/coding-agent-harness/harness.yaml +14 -0
  100. package/examples/minimal-project/coding-agent-harness/planning/tasks/demo-task/progress.md +11 -0
  101. package/examples/minimal-project/{docs/09-PLANNING/TASKS → coding-agent-harness/planning/tasks}/demo-task/review.md +1 -1
  102. package/package.json +20 -12
  103. package/presets/legacy-migration/preset.yaml +5 -5
  104. package/presets/legacy-migration/templates/execution_strategy.append.md +1 -1
  105. package/presets/lesson-sedimentation/preset.yaml +3 -3
  106. package/presets/module/preset.yaml +2 -2
  107. package/presets/module/templates/execution_strategy.append.md +1 -1
  108. package/presets/module/templates/task_plan.append.md +3 -3
  109. package/presets/standard-task/preset.yaml +2 -2
  110. package/references/adversarial-review-standard.md +2 -2
  111. package/references/agents-md-pattern.md +14 -14
  112. package/references/cadence-ledger.md +1 -1
  113. package/references/ci-cd-standard.md +1 -1
  114. package/references/delivery-operating-model-standard.md +4 -4
  115. package/references/docs-directory-standard.md +65 -159
  116. package/references/external-source-intake-standard.md +10 -10
  117. package/references/harness-ledger.md +5 -5
  118. package/references/legacy-12-phase-bootstrap.md +2 -2
  119. package/references/lessons-governance.md +15 -15
  120. package/references/long-running-task-standard.md +6 -6
  121. package/references/module-parallel-standard.md +34 -34
  122. package/references/planning-loop.md +6 -6
  123. package/references/project-onboarding-audit.md +4 -4
  124. package/references/regression-system.md +2 -2
  125. package/references/repo-governance-standard.md +4 -4
  126. package/references/review-routing-standard.md +1 -1
  127. package/references/ssot-governance.md +19 -19
  128. package/references/taskr-gap-analysis.md +5 -5
  129. package/references/walkthrough-closeout.md +14 -14
  130. package/references/worktree-parallel.md +3 -3
  131. package/skills/preset-creator/references/complex-task-skeleton/task_plan.md +1 -1
  132. package/skills/preset-creator/references/preset-package-skeleton.md +5 -5
  133. package/templates/AGENTS.md.template +26 -26
  134. package/templates/architecture/README.md +4 -4
  135. package/templates/architecture/service-catalog.md +2 -2
  136. package/templates/architecture/services/service-template.md +1 -1
  137. package/templates/dashboard/assets/app-src/20-overview.js +11 -5
  138. package/templates/dashboard/assets/app-src/40-modules.js +1 -1
  139. package/templates/dashboard/assets/app.js +12 -6
  140. package/templates/dashboard/assets/i18n.js +4 -2
  141. package/templates/development/README.md +10 -10
  142. package/templates/development/cross-repo-debugging.md +3 -3
  143. package/templates/development/external-context/service-template.md +2 -2
  144. package/templates/development/external-source-packs/README.md +4 -4
  145. package/templates/integrations/README.md +4 -4
  146. package/templates/integrations/api-contract.md +2 -2
  147. package/templates/integrations/event-contract.md +2 -2
  148. package/templates/integrations/third-party/vendor-template.md +2 -2
  149. package/templates/integrations/webhook-contract.md +2 -2
  150. package/templates/ledger/Harness-Ledger.md +1 -1
  151. package/templates/planning/INDEX.md +1 -0
  152. package/templates/planning/module_session_prompt.md +1 -1
  153. package/templates/planning/task_plan.md +1 -1
  154. package/templates/planning/walkthrough.md +47 -0
  155. package/templates/reference/docs-library-standard.md +8 -8
  156. package/templates/reference/external-source-intake-standard.md +15 -15
  157. package/templates/reference/repo-governance-standard.md +1 -1
  158. package/templates/ssot/Module-Registry.md +1 -1
  159. package/templates/walkthrough/walkthrough-template.md +2 -2
  160. package/templates-zh-CN/AGENTS.md.template +26 -26
  161. package/templates-zh-CN/CLAUDE.md.template +1 -1
  162. package/templates-zh-CN/architecture/README.md +4 -4
  163. package/templates-zh-CN/architecture/service-catalog.md +2 -2
  164. package/templates-zh-CN/architecture/services/service-template.md +1 -1
  165. package/templates-zh-CN/development/README.md +10 -10
  166. package/templates-zh-CN/development/cross-repo-debugging.md +3 -3
  167. package/templates-zh-CN/development/external-context/service-template.md +2 -2
  168. package/templates-zh-CN/development/external-source-packs/README.md +4 -4
  169. package/templates-zh-CN/integrations/README.md +4 -4
  170. package/templates-zh-CN/integrations/api-contract.md +2 -2
  171. package/templates-zh-CN/integrations/event-contract.md +2 -2
  172. package/templates-zh-CN/integrations/third-party/vendor-template.md +2 -2
  173. package/templates-zh-CN/integrations/webhook-contract.md +2 -2
  174. package/templates-zh-CN/ledger/Harness-Ledger.md +1 -1
  175. package/templates-zh-CN/lessons/lesson-arch-process-change.md +1 -1
  176. package/templates-zh-CN/lessons/lesson-new-doc.md +3 -3
  177. package/templates-zh-CN/lessons/lesson-ref-change.md +4 -4
  178. package/templates-zh-CN/planning/module_session_prompt.md +11 -11
  179. package/templates-zh-CN/planning/walkthrough.md +47 -0
  180. package/templates-zh-CN/reference/adversarial-review-standard.md +2 -2
  181. package/templates-zh-CN/reference/delivery-operating-model-standard.md +3 -3
  182. package/templates-zh-CN/reference/docs-library-standard.md +28 -28
  183. package/templates-zh-CN/reference/execution-workflow-standard.md +1 -1
  184. package/templates-zh-CN/reference/external-source-intake-standard.md +16 -16
  185. package/templates-zh-CN/reference/harness-ledger-standard.md +6 -6
  186. package/templates-zh-CN/reference/regression-ssot-governance.md +2 -2
  187. package/templates-zh-CN/reference/repo-governance-standard.md +1 -1
  188. package/templates-zh-CN/reference/review-routing-standard.md +1 -1
  189. package/templates-zh-CN/reference/walkthrough-standard.md +7 -7
  190. package/templates-zh-CN/reference/worktree-standard.md +1 -1
  191. package/templates-zh-CN/regression/Cadence-Ledger.md +2 -2
  192. package/templates-zh-CN/ssot/Delivery-SSoT.md +3 -3
  193. package/templates-zh-CN/ssot/Module-Registry.md +3 -3
  194. package/templates-zh-CN/ssot/Regression-SSoT.md +2 -2
  195. package/templates-zh-CN/walkthrough/walkthrough-template.md +5 -5
  196. package/tsconfig.dist.json +16 -0
  197. package/tsconfig.json +25 -0
  198. package/tsconfig.runtime.json +24 -0
  199. package/examples/minimal-project/.harness-capabilities.json +0 -8
  200. package/examples/minimal-project/docs/09-PLANNING/TASKS/demo-task/progress.md +0 -11
  201. package/scripts/check-harness.mjs +0 -508
  202. package/scripts/commands/dashboard-command.mjs +0 -67
  203. package/scripts/commands/migration-command.mjs +0 -126
  204. package/scripts/commands/preset-command.mjs +0 -73
  205. package/scripts/commands/task-command.mjs +0 -328
  206. package/scripts/harness.mjs +0 -291
  207. package/scripts/lib/capability-registry.mjs +0 -587
  208. package/scripts/lib/check-module-parallel.mjs +0 -230
  209. package/scripts/lib/check-profiles.mjs +0 -372
  210. package/scripts/lib/check-task-contracts.mjs +0 -55
  211. package/scripts/lib/core-shared.mjs +0 -249
  212. package/scripts/lib/dashboard-data.mjs +0 -520
  213. package/scripts/lib/dashboard-workbench.mjs +0 -336
  214. package/scripts/lib/dashboard-writer.mjs +0 -202
  215. package/scripts/lib/git-status-summary.mjs +0 -46
  216. package/scripts/lib/governance-index-generator.mjs +0 -174
  217. package/scripts/lib/governance-sync.mjs +0 -611
  218. package/scripts/lib/governance-table-boundary.mjs +0 -175
  219. package/scripts/lib/lesson-maintenance.mjs +0 -152
  220. package/scripts/lib/markdown-utils.mjs +0 -191
  221. package/scripts/lib/migration-planner.mjs +0 -476
  222. package/scripts/lib/migration-support.mjs +0 -312
  223. package/scripts/lib/phase-kind.mjs +0 -50
  224. package/scripts/lib/preset-audit-contracts.mjs +0 -37
  225. package/scripts/lib/preset-engine.mjs +0 -494
  226. package/scripts/lib/preset-registry.mjs +0 -776
  227. package/scripts/lib/preset-resource-contracts.mjs +0 -83
  228. package/scripts/lib/review-confirm-git-gate.mjs +0 -248
  229. package/scripts/lib/status-builder.mjs +0 -88
  230. package/scripts/lib/subagent-authorization-audit.mjs +0 -196
  231. package/scripts/lib/task-audit-metadata.mjs +0 -385
  232. package/scripts/lib/task-audit-migration.mjs +0 -350
  233. package/scripts/lib/task-completion-consistency.mjs +0 -26
  234. package/scripts/lib/task-index.mjs +0 -93
  235. package/scripts/lib/task-lesson-candidates.mjs +0 -242
  236. package/scripts/lib/task-lesson-sedimentation.mjs +0 -326
  237. package/scripts/lib/task-lifecycle/create-task-helpers.mjs +0 -67
  238. package/scripts/lib/task-lifecycle/phase-sync.mjs +0 -88
  239. package/scripts/lib/task-lifecycle/review-confirm.mjs +0 -112
  240. package/scripts/lib/task-lifecycle/review-gates.mjs +0 -73
  241. package/scripts/lib/task-lifecycle/review-submission.mjs +0 -63
  242. package/scripts/lib/task-lifecycle/scaffold-provenance.mjs +0 -49
  243. package/scripts/lib/task-lifecycle/template-files.mjs +0 -53
  244. package/scripts/lib/task-lifecycle/text-utils.mjs +0 -24
  245. package/scripts/lib/task-lifecycle.mjs +0 -616
  246. package/scripts/lib/task-metadata.mjs +0 -118
  247. package/scripts/lib/task-review-model.mjs +0 -455
  248. package/scripts/lib/task-scanner.mjs +0 -503
  249. package/scripts/lib/task-tombstone-commands.mjs +0 -140
  250. package/scripts/postinstall.mjs +0 -14
  251. package/templates/walkthrough/Closeout-SSoT.md +0 -43
  252. package/templates-zh-CN/walkthrough/Closeout-SSoT.md +0 -42
  253. /package/examples/minimal-project/{docs → coding-agent-harness/governance/generated}/Harness-Ledger.md +0 -0
  254. /package/examples/minimal-project/{docs/09-PLANNING/TASKS → coding-agent-harness/planning/tasks}/demo-task/INDEX.md +0 -0
  255. /package/examples/minimal-project/{docs/09-PLANNING/TASKS → coding-agent-harness/planning/tasks}/demo-task/brief.md +0 -0
  256. /package/examples/minimal-project/{docs/09-PLANNING/TASKS → coding-agent-harness/planning/tasks}/demo-task/execution_strategy.md +0 -0
  257. /package/examples/minimal-project/{docs/09-PLANNING/TASKS → coding-agent-harness/planning/tasks}/demo-task/findings.md +0 -0
  258. /package/examples/minimal-project/{docs/09-PLANNING/TASKS → coding-agent-harness/planning/tasks}/demo-task/lesson_candidates.md +0 -0
  259. /package/examples/minimal-project/{docs/09-PLANNING/TASKS → coding-agent-harness/planning/tasks}/demo-task/task_plan.md +0 -0
  260. /package/examples/minimal-project/{docs/09-PLANNING/TASKS → coding-agent-harness/planning/tasks}/demo-task/visual_map.md +0 -0
@@ -0,0 +1,489 @@
1
+ #!/usr/bin/env node
2
+ // @ts-nocheck
3
+ import fs from "node:fs";
4
+ import path from "node:path";
5
+ import { checkModuleParallelStructure } from "./lib/check-module-parallel.mjs";
6
+ const targetRoot = path.resolve(process.argv[2] || process.cwd());
7
+ const requireGlobalModuleSync = process.env.HARNESS_REQUIRE_GLOBAL_MODULE_SYNC === "1";
8
+ const requiredFiles = [
9
+ "AGENTS.md",
10
+ "CLAUDE.md",
11
+ "docs/Harness-Ledger.md",
12
+ "docs/11-REFERENCE/testing-standard.md",
13
+ "docs/11-REFERENCE/execution-workflow-standard.md",
14
+ "docs/11-REFERENCE/repo-governance-standard.md",
15
+ "docs/11-REFERENCE/ci-cd-standard.md",
16
+ "docs/11-REFERENCE/long-running-task-standard.md",
17
+ "docs/11-REFERENCE/adversarial-review-standard.md",
18
+ "docs/11-REFERENCE/review-routing-standard.md",
19
+ "docs/11-REFERENCE/docs-library-standard.md",
20
+ "docs/11-REFERENCE/harness-ledger-standard.md",
21
+ "docs/10-WALKTHROUGH/_walkthrough-template.md",
22
+ "docs/10-WALKTHROUGH/Closeout-SSoT.md",
23
+ "docs/05-TEST-QA/Regression-SSoT.md",
24
+ "docs/05-TEST-QA/Cadence-Ledger.md",
25
+ ];
26
+ const legacyPlanningFiles = [
27
+ "docs/09-PLANNING/TASKS/_task-template/task_plan.md",
28
+ "docs/09-PLANNING/TASKS/_task-template/findings.md",
29
+ "docs/09-PLANNING/TASKS/_task-template/progress.md",
30
+ "docs/09-PLANNING/TASKS/_task-template/review.md",
31
+ "docs/09-PLANNING/TASKS/_task-template/long-running-task-contract.md",
32
+ ];
33
+ const agAgentsRefs = [
34
+ "repo-governance-standard.md",
35
+ "ci-cd-standard.md",
36
+ "execution-workflow-standard.md",
37
+ "adversarial-review-standard.md",
38
+ "review-routing-standard.md",
39
+ "walkthrough-standard.md",
40
+ "harness-ledger-standard.md",
41
+ "Closeout-SSoT.md",
42
+ ];
43
+ const forbiddenTemplatePatterns = [
44
+ /\[如有[^\]]*\]/,
45
+ /\[[^\]]*(根据项目|框架名|目标覆盖率|列出关键|示例)[^\]]*\]/,
46
+ /\[TODO\]/i,
47
+ /\bTODO\b/,
48
+ /\bTBD\b/i,
49
+ /\[command\]/,
50
+ /\[workflow path\]/,
51
+ /\[owner\/repo or URL\]/,
52
+ ];
53
+ const statusWords = ["designed", "implemented", "verified", "blocked-with-owner"];
54
+ const closedLedgerStatuses = new Set(["closed", "closed-with-residual", "closed-local-only"]);
55
+ const allowedWalkthroughSkip = /walkthrough skipped-with-reason:\s*(docs-only|no-runtime|superseded|historical-backfill|owner-deferred)/i;
56
+ const lessonsCreatedPattern = /checked-created:\s*(L-\d{4}-\d{2}-\d{2}-\d{3}|L-\d+)/i;
57
+ const lessonsNonePattern = /checked-none:\s*\S+/i;
58
+ const lessonsCandidatePattern = /checked-candidate:\s*(LC-[A-Za-z0-9-]+)/i;
59
+ const lessonsQueuedPromotionPattern = /queued-promotion:\s*(LC-[A-Za-z0-9-]+)/i;
60
+ const failures = [];
61
+ const warnings = [];
62
+ function rel(file) {
63
+ return file.split(path.sep).join("/");
64
+ }
65
+ function filePath(relativePath) {
66
+ return path.join(targetRoot, relativePath);
67
+ }
68
+ function exists(relativePath) {
69
+ return fs.existsSync(filePath(relativePath));
70
+ }
71
+ function read(relativePath) {
72
+ return fs.readFileSync(filePath(relativePath), "utf8");
73
+ }
74
+ function fail(message) {
75
+ failures.push(message);
76
+ }
77
+ function warn(message) {
78
+ warnings.push(message);
79
+ }
80
+ function requireFile(relativePath) {
81
+ if (!exists(relativePath)) {
82
+ fail(`missing required file: ${relativePath}`);
83
+ return false;
84
+ }
85
+ return true;
86
+ }
87
+ function checkRequiredFiles() {
88
+ for (const requiredFile of requiredFiles) {
89
+ requireFile(requiredFile);
90
+ }
91
+ }
92
+ function checkPlanningStructure() {
93
+ if (exists("docs/09-PLANNING/Module-Registry.md")) {
94
+ checkModuleParallelStructure({
95
+ exists,
96
+ fail,
97
+ filePath,
98
+ markdownTable,
99
+ read,
100
+ rel,
101
+ requireFile,
102
+ requireGlobalModuleSync,
103
+ targetRoot,
104
+ warn,
105
+ });
106
+ return;
107
+ }
108
+ for (const legacyFile of legacyPlanningFiles) {
109
+ requireFile(legacyFile);
110
+ }
111
+ }
112
+ function checkAgentsIndex() {
113
+ if (!exists("AGENTS.md"))
114
+ return;
115
+ const content = read("AGENTS.md");
116
+ for (const ref of agAgentsRefs) {
117
+ if (!content.includes(ref)) {
118
+ fail(`AGENTS.md does not route to ${ref}`);
119
+ }
120
+ }
121
+ if (exists("docs/11-REFERENCE/delivery-operating-model-standard.md") && !content.includes("delivery-operating-model-standard.md")) {
122
+ fail("AGENTS.md does not route to delivery-operating-model-standard.md");
123
+ }
124
+ if (exists("docs/09-PLANNING/Module-Registry.md")) {
125
+ for (const ref of ["Module-Registry.md", "Session-Prompt-Pack.md"]) {
126
+ if (!content.includes(ref)) {
127
+ fail(`AGENTS.md does not route to ${ref}`);
128
+ }
129
+ }
130
+ if (!/Subagent|worker/i.test(content) || !/worktree/i.test(content) || !/commit SHA|commit/i.test(content)) {
131
+ fail("AGENTS.md does not define subagent worker worktree/commit handoff rule");
132
+ }
133
+ }
134
+ }
135
+ function checkNoGenericPlaceholders(relativePath, { allowTemplates = false } = {}) {
136
+ if (!exists(relativePath))
137
+ return;
138
+ const content = read(relativePath);
139
+ if (allowTemplates)
140
+ return;
141
+ for (const pattern of forbiddenTemplatePatterns) {
142
+ if (pattern.test(content)) {
143
+ fail(`${relativePath} still contains generic placeholder matching ${pattern}`);
144
+ }
145
+ }
146
+ }
147
+ function checkGovernanceContent() {
148
+ const governancePath = "docs/11-REFERENCE/repo-governance-standard.md";
149
+ if (!exists(governancePath))
150
+ return;
151
+ const content = read(governancePath);
152
+ const requiredTerms = [
153
+ ["Repo Platform Profile", "仓库平台画像"],
154
+ ["Branch Model", "分支模型"],
155
+ ["PR Policy", "PR 规则"],
156
+ ["Required Checks", "必要检查"],
157
+ ["Branch Protection", "分支保护"],
158
+ ["Worktree Concurrency", "Worktree 并发"],
159
+ ];
160
+ for (const terms of requiredTerms) {
161
+ if (!contentIncludesAny(content, terms))
162
+ fail(`${governancePath} missing section: ${terms[0]}`);
163
+ }
164
+ if (!statusWords.some((status) => content.includes(status))) {
165
+ fail(`${governancePath} does not use evidence status model`);
166
+ }
167
+ checkNoGenericPlaceholders(governancePath);
168
+ }
169
+ function checkCiCdContent() {
170
+ const ciPath = "docs/11-REFERENCE/ci-cd-standard.md";
171
+ if (!exists(ciPath))
172
+ return;
173
+ const content = read(ciPath);
174
+ const requiredTerms = [
175
+ ["CI Profile", "CI 画像"],
176
+ ["Workflow", "工作流"],
177
+ ["Required Checks", "必要检查"],
178
+ ["Evidence Status", "证据状态"],
179
+ ];
180
+ for (const terms of requiredTerms) {
181
+ if (!contentIncludesAny(content, terms))
182
+ fail(`${ciPath} missing section: ${terms[0]}`);
183
+ }
184
+ if (!statusWords.some((status) => content.includes(status))) {
185
+ fail(`${ciPath} does not use evidence status model`);
186
+ }
187
+ checkNoGenericPlaceholders(ciPath);
188
+ }
189
+ function checkDeliveryOperatingModelContent() {
190
+ const deliveryPath = "docs/11-REFERENCE/delivery-operating-model-standard.md";
191
+ if (!exists(deliveryPath))
192
+ return;
193
+ const content = read(deliveryPath);
194
+ const normalized = content.toLowerCase();
195
+ const requiredTerms = [
196
+ ["operating model profile", "运行模型"],
197
+ ["work decomposition rule", "工作拆分规则"],
198
+ ["agent visibility", "agent 可见性"],
199
+ ["integration owner", "集成 owner"],
200
+ ["delivery ssot", "交付 ssot"],
201
+ ];
202
+ for (const terms of requiredTerms) {
203
+ if (!contentIncludesAny(normalized, terms.map((term) => term.toLowerCase())))
204
+ fail(`${deliveryPath} missing section: ${terms[0]}`);
205
+ }
206
+ if (!/solo-orchestrator|team-feature-lead|split-repo-contract|program-multi-repo|waterfall-stage-gate|kanban-continuous/.test(content)) {
207
+ fail(`${deliveryPath} does not define a recognized operating model`);
208
+ }
209
+ checkNoGenericPlaceholders(deliveryPath);
210
+ }
211
+ function checkPrTemplateOrResidual() {
212
+ const templateCandidates = [
213
+ ".github/pull_request_template.md",
214
+ ".github/PULL_REQUEST_TEMPLATE.md",
215
+ ".gitlab/merge_request_templates/default.md",
216
+ ];
217
+ if (templateCandidates.some((candidate) => exists(candidate)))
218
+ return;
219
+ if (exists("docs/11-REFERENCE/repo-governance-standard.md")) {
220
+ const content = read("docs/11-REFERENCE/repo-governance-standard.md");
221
+ if (/PR template/i.test(content) && /blocked-with-owner|manual setup residual|manual-setup-residual/i.test(content)) {
222
+ warn("PR template missing, but repo governance records residual");
223
+ return;
224
+ }
225
+ }
226
+ fail("missing PR template or explicit blocked-with-owner residual");
227
+ }
228
+ function checkWorkflowOrResidual() {
229
+ const workflowDir = filePath(".github/workflows");
230
+ const hasGitHubWorkflow = fs.existsSync(workflowDir) &&
231
+ fs.readdirSync(workflowDir).some((name) => /\.(ya?ml)$/i.test(name));
232
+ if (hasGitHubWorkflow)
233
+ return;
234
+ if (exists("docs/11-REFERENCE/ci-cd-standard.md")) {
235
+ const content = read("docs/11-REFERENCE/ci-cd-standard.md");
236
+ if (/blocked-with-owner|unsupported checks|residual/i.test(content)) {
237
+ warn("CI workflow missing, but CI/CD standard records residual");
238
+ return;
239
+ }
240
+ }
241
+ fail("missing CI workflow or explicit blocked-with-owner residual");
242
+ }
243
+ function checkReviewTemplate() {
244
+ const reviewPath = "docs/09-PLANNING/TASKS/_task-template/review.md";
245
+ if (!exists(reviewPath))
246
+ return;
247
+ const content = read(reviewPath);
248
+ if (!contentIncludesAny(content, ["Confidence Challenge", "信心挑战"])) {
249
+ fail(`${reviewPath} missing Confidence Challenge`);
250
+ }
251
+ if (/\|\s*R-001\s*\|\s*P[01]\s*\|.*\|\s*open\s*\|/i.test(content)) {
252
+ fail(`${reviewPath} ships with an open P0/P1 example finding`);
253
+ }
254
+ }
255
+ function checkHarnessLedger() {
256
+ if (!exists("docs/Harness-Ledger.md"))
257
+ return;
258
+ const content = read("docs/Harness-Ledger.md");
259
+ if (!/Repo Governance|CI\/CD|ci-cd|repo-governance/i.test(content)) {
260
+ fail("docs/Harness-Ledger.md does not mention repo governance / CI-CD update status");
261
+ }
262
+ }
263
+ function markdownTableRows(content, idPattern) {
264
+ return content
265
+ .split(/\r?\n/)
266
+ .filter((line) => line.trim().startsWith("|"))
267
+ .map((line) => line.split("|").slice(1, -1).map((cell) => cell.trim()))
268
+ .filter((cells) => cells.length > 0 && idPattern.test(cells[0] || ""));
269
+ }
270
+ function markdownTable(content) {
271
+ return content
272
+ .split(/\r?\n/)
273
+ .filter((line) => line.trim().startsWith("|"))
274
+ .map((line) => line.split("|").slice(1, -1).map((cell) => cell.trim()));
275
+ }
276
+ function findHeaderIndex(rows, pattern) {
277
+ return rows.findIndex((cells) => cells.some((cell) => pattern.test(cell)));
278
+ }
279
+ function contentIncludesAny(content, terms) {
280
+ return terms.some((term) => (term instanceof RegExp ? term.test(content) : content.includes(term)));
281
+ }
282
+ function columnIndexAny(header, patterns) {
283
+ return header.findIndex((cell) => patterns.some((pattern) => pattern.test(cell)));
284
+ }
285
+ function checkDuplicateIds(rows, sourcePath) {
286
+ const seen = new Set();
287
+ for (const cells of rows) {
288
+ const id = cells[0];
289
+ if (seen.has(id)) {
290
+ fail(`${sourcePath} contains duplicate closeout id: ${id}`);
291
+ }
292
+ seen.add(id);
293
+ }
294
+ }
295
+ function checkCloseoutSsot() {
296
+ const closeoutPath = "docs/10-WALKTHROUGH/Closeout-SSoT.md";
297
+ if (!exists(closeoutPath))
298
+ return;
299
+ const closeoutContent = read(closeoutPath);
300
+ for (const terms of [["Walkthrough"], ["Lessons Check", "Lessons 检查"], ["Closeout Status", "收口状态"]]) {
301
+ if (!contentIncludesAny(closeoutContent, terms)) {
302
+ fail(`${closeoutPath} missing required closeout column or section: ${terms[0]}`);
303
+ }
304
+ }
305
+ checkNoGenericPlaceholders(closeoutPath);
306
+ const closeoutTable = markdownTable(closeoutContent);
307
+ const closeoutHeaderIndex = findHeaderIndex(closeoutTable, /^Harness ID$/i);
308
+ const closeoutHeader = closeoutHeaderIndex >= 0 ? closeoutTable[closeoutHeaderIndex] : [];
309
+ const lessonsColumn = columnIndexAny(closeoutHeader, [/^Lessons Check$/i, /^Lessons 检查$/i, /^Lessons 检查\s*\/\s*Lessons Check$/i]);
310
+ if (lessonsColumn < 0) {
311
+ fail(`${closeoutPath} missing Lessons Check column`);
312
+ }
313
+ if (!exists("docs/Harness-Ledger.md"))
314
+ return;
315
+ const ledgerContent = read("docs/Harness-Ledger.md");
316
+ const lessonIds = collectLessonIds();
317
+ const lessonCandidateIds = collectLessonCandidateIds();
318
+ const ledgerTable = markdownTable(ledgerContent);
319
+ const ledgerHeaderIndex = findHeaderIndex(ledgerTable, /^ID$/i);
320
+ const ledgerHeader = ledgerHeaderIndex >= 0 ? ledgerTable[ledgerHeaderIndex] : [];
321
+ const ledgerLessonsColumn = columnIndexAny(ledgerHeader, [/^Lessons Check$/i, /^Lessons 检查$/i, /^Lessons 检查\s*\/\s*Lessons Check$/i]);
322
+ if (ledgerLessonsColumn < 0) {
323
+ fail("docs/Harness-Ledger.md missing Lessons Check column");
324
+ }
325
+ const ledgerRows = markdownTableRows(ledgerContent, /^H-\d+/i);
326
+ const closeoutTableRows = markdownTableRows(closeoutContent, /^H-\d+/i);
327
+ checkDuplicateIds(ledgerRows, "docs/Harness-Ledger.md");
328
+ checkDuplicateIds(closeoutTableRows, closeoutPath);
329
+ const closeoutRows = new Map(closeoutTableRows.map((cells) => [cells[0], cells]));
330
+ for (const cells of ledgerRows) {
331
+ const id = cells[0];
332
+ const status = (cells[cells.length - 1] || "").toLowerCase();
333
+ if (!closedLedgerStatuses.has(status))
334
+ continue;
335
+ const closeout = closeoutRows.get(id);
336
+ if (!closeout) {
337
+ fail(`${closeoutPath} missing row for closed Harness Ledger item ${id}`);
338
+ continue;
339
+ }
340
+ const joined = closeout.join(" ");
341
+ const hasWalkthrough = /docs\/10-WALKTHROUGH\/[^|\s]+\.md/.test(joined);
342
+ const hasAllowedSkip = allowedWalkthroughSkip.test(joined);
343
+ if (!hasWalkthrough && !hasAllowedSkip) {
344
+ fail(`${closeoutPath} row ${id} needs walkthrough path or allowed skipped-with-reason`);
345
+ }
346
+ if (lessonsColumn >= 0) {
347
+ const lessonsCheck = closeout[lessonsColumn] || "";
348
+ const createdMatch = lessonsCheck.match(lessonsCreatedPattern);
349
+ const candidateMatch = lessonsCheck.match(lessonsCandidatePattern) || lessonsCheck.match(lessonsQueuedPromotionPattern);
350
+ if (!createdMatch && !candidateMatch && !lessonsNonePattern.test(lessonsCheck)) {
351
+ fail(`${closeoutPath} row ${id} needs Lessons Check value: checked-created:<lesson-id>, checked-candidate:<candidate-id>, queued-promotion:<candidate-id>, or checked-none:<reason>`);
352
+ }
353
+ else if (createdMatch && !lessonIds.has(createdMatch[1])) {
354
+ fail(`${closeoutPath} row ${id} references missing lesson detail doc id: ${createdMatch[1]}`);
355
+ }
356
+ else if (candidateMatch && !lessonCandidateIds.has(candidateMatch[1])) {
357
+ fail(`${closeoutPath} row ${id} references missing lesson candidate id: ${candidateMatch[1]}`);
358
+ }
359
+ }
360
+ if (ledgerLessonsColumn >= 0) {
361
+ const ledgerLessonsCheck = cells[ledgerLessonsColumn] || "";
362
+ const ledgerCreatedMatch = ledgerLessonsCheck.match(lessonsCreatedPattern);
363
+ const ledgerCandidateMatch = ledgerLessonsCheck.match(lessonsCandidatePattern) || ledgerLessonsCheck.match(lessonsQueuedPromotionPattern);
364
+ if (!ledgerCreatedMatch && !ledgerCandidateMatch && !lessonsNonePattern.test(ledgerLessonsCheck)) {
365
+ fail(`docs/Harness-Ledger.md row ${id} needs Lessons Check value: checked-created:<lesson-id>, checked-candidate:<candidate-id>, queued-promotion:<candidate-id>, or checked-none:<reason>`);
366
+ }
367
+ else if (ledgerCreatedMatch && !lessonIds.has(ledgerCreatedMatch[1])) {
368
+ fail(`docs/Harness-Ledger.md row ${id} references missing lesson detail doc id: ${ledgerCreatedMatch[1]}`);
369
+ }
370
+ else if (ledgerCandidateMatch && !lessonCandidateIds.has(ledgerCandidateMatch[1])) {
371
+ fail(`docs/Harness-Ledger.md row ${id} references missing lesson candidate id: ${ledgerCandidateMatch[1]}`);
372
+ }
373
+ }
374
+ }
375
+ }
376
+ function collectLessonIds() {
377
+ const root = filePath("docs/01-GOVERNANCE/lessons");
378
+ const ids = new Set();
379
+ if (!fs.existsSync(root))
380
+ return ids;
381
+ for (const entry of fs.readdirSync(root)) {
382
+ if (!entry.endsWith(".md"))
383
+ continue;
384
+ const full = path.join(root, entry);
385
+ if (!fs.statSync(full).isFile())
386
+ continue;
387
+ const content = fs.readFileSync(full, "utf8");
388
+ const pathMatch = entry.match(/(L-\d{4}(?:-\d{2}-\d{2})?-\d+)/i);
389
+ const titleMatch = content.match(/#\s*(L-\d{4}(?:-\d{2}-\d{2})?-\d+)/i);
390
+ const id = titleMatch?.[1] || pathMatch?.[1];
391
+ if (id)
392
+ ids.add(id);
393
+ }
394
+ return ids;
395
+ }
396
+ function collectLessonCandidateIds() {
397
+ const root = filePath("docs/09-PLANNING");
398
+ const ids = new Set();
399
+ if (!fs.existsSync(root))
400
+ return ids;
401
+ function visit(dir) {
402
+ for (const entry of fs.readdirSync(dir)) {
403
+ const full = path.join(dir, entry);
404
+ const stat = fs.statSync(full);
405
+ if (stat.isDirectory()) {
406
+ if (entry === "_archive")
407
+ continue;
408
+ visit(full);
409
+ continue;
410
+ }
411
+ if (entry !== "lesson_candidates.md")
412
+ continue;
413
+ const content = fs.readFileSync(full, "utf8");
414
+ for (const match of content.matchAll(/\|\s*(LC-[A-Za-z0-9-]+)\s*\|/g)) {
415
+ ids.add(match[1]);
416
+ }
417
+ }
418
+ }
419
+ visit(root);
420
+ return ids;
421
+ }
422
+ function checkLessonDetailDocs() {
423
+ const root = filePath("docs/01-GOVERNANCE/lessons");
424
+ if (!fs.existsSync(root))
425
+ return;
426
+ for (const entry of fs.readdirSync(root)) {
427
+ if (!entry.endsWith(".md"))
428
+ continue;
429
+ const relativePath = `docs/01-GOVERNANCE/lessons/${entry}`;
430
+ const content = read(relativePath);
431
+ const id = entry.match(/(L-\d{4}(?:-\d{2}-\d{2})?-\d+)/i)?.[1];
432
+ if (id && !content.includes(id)) {
433
+ fail(`${relativePath} does not include lesson id ${id}`);
434
+ }
435
+ }
436
+ }
437
+ function checkWalkthroughTemplate() {
438
+ const walkthroughTemplate = "docs/10-WALKTHROUGH/_walkthrough-template.md";
439
+ if (!exists(walkthroughTemplate))
440
+ return;
441
+ const content = read(walkthroughTemplate);
442
+ if (!contentIncludesAny(content, ["Lessons Reflection", "Lessons 回看"])) {
443
+ fail(`${walkthroughTemplate} missing Lessons Reflection section`);
444
+ }
445
+ }
446
+ function checkReferencePlaceholders() {
447
+ const refDir = filePath("docs/11-REFERENCE");
448
+ if (!fs.existsSync(refDir))
449
+ return;
450
+ for (const entry of fs.readdirSync(refDir)) {
451
+ const full = path.join(refDir, entry);
452
+ if (!fs.statSync(full).isFile() || !entry.endsWith(".md"))
453
+ continue;
454
+ checkNoGenericPlaceholders(rel(path.relative(targetRoot, full)));
455
+ }
456
+ }
457
+ function main() {
458
+ if (!fs.existsSync(targetRoot)) {
459
+ console.error(`Target path does not exist: ${targetRoot}`);
460
+ process.exit(2);
461
+ }
462
+ checkRequiredFiles();
463
+ checkPlanningStructure();
464
+ checkAgentsIndex();
465
+ checkGovernanceContent();
466
+ checkCiCdContent();
467
+ checkDeliveryOperatingModelContent();
468
+ checkPrTemplateOrResidual();
469
+ checkWorkflowOrResidual();
470
+ checkReviewTemplate();
471
+ checkHarnessLedger();
472
+ checkCloseoutSsot();
473
+ checkLessonDetailDocs();
474
+ checkWalkthroughTemplate();
475
+ checkReferencePlaceholders();
476
+ if (warnings.length > 0) {
477
+ console.log("Warnings:");
478
+ for (const warning of warnings)
479
+ console.log(`- ${warning}`);
480
+ }
481
+ if (failures.length > 0) {
482
+ console.error("Harness check failed:");
483
+ for (const failure of failures)
484
+ console.error(`- ${failure}`);
485
+ process.exit(1);
486
+ }
487
+ console.log(`Harness check passed: ${targetRoot}`);
488
+ }
489
+ main();