devrites 5.11.0 → 5.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (903) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +1 -1
  3. package/docs/agents/issue-driven-rites.md +1 -1
  4. package/docs/agents/issue-tracker.md +3 -0
  5. package/docs/cli.md +90 -0
  6. package/docs/command-map.md +4 -2
  7. package/docs/engine/commands.md +21 -0
  8. package/docs/engine/state-schema.md +1 -1
  9. package/docs/engine/workspace-schema.md +10 -2
  10. package/docs/usage.md +2 -0
  11. package/engine/commands.go +11 -5
  12. package/engine/help.go +80 -3
  13. package/engine/help_test.go +7 -1
  14. package/engine/internal/acceptance/acceptance_test.go +655 -0
  15. package/engine/internal/acceptance/approve.go +142 -0
  16. package/engine/internal/acceptance/cli.go +426 -0
  17. package/engine/internal/acceptance/evidence.go +139 -0
  18. package/engine/internal/acceptance/exec.go +131 -0
  19. package/engine/internal/acceptance/exec_unix.go +22 -0
  20. package/engine/internal/acceptance/exec_windows.go +16 -0
  21. package/engine/internal/acceptance/ledger.go +259 -0
  22. package/engine/internal/acceptance/lint.go +115 -0
  23. package/engine/internal/acceptance/run.go +207 -0
  24. package/engine/internal/acceptance/scaffold.go +55 -0
  25. package/engine/internal/gate/gate.go +12 -2
  26. package/engine/internal/gate/gate_test.go +17 -9
  27. package/engine/internal/gate/gates_ledger.go +76 -0
  28. package/engine/internal/gate/readiness_binding.go +39 -0
  29. package/engine/internal/gate/readiness_binding_test.go +4 -3
  30. package/engine/internal/install/install.go +7 -1
  31. package/engine/internal/install/install_test.go +17 -4
  32. package/engine/internal/install/merge.go +82 -22
  33. package/engine/internal/install/update.go +7 -1
  34. package/engine/internal/install/workspace_advisory.go +46 -0
  35. package/engine/internal/install/workspace_advisory_test.go +54 -0
  36. package/engine/internal/lib/candidate_test.go +1 -1
  37. package/engine/internal/lib/claims.go +411 -0
  38. package/engine/internal/lib/claims_test.go +182 -0
  39. package/engine/internal/lib/closeout_test.go +3 -3
  40. package/engine/internal/lib/context.go +445 -0
  41. package/engine/internal/lib/context_next_test.go +521 -0
  42. package/engine/internal/lib/detect.go +346 -0
  43. package/engine/internal/lib/detect_test.go +105 -0
  44. package/engine/internal/lib/diffscope.go +189 -0
  45. package/engine/internal/lib/dispatch.go +302 -0
  46. package/engine/internal/lib/drift.go +219 -0
  47. package/engine/internal/lib/drift_test.go +106 -0
  48. package/engine/internal/lib/dup.go +1243 -0
  49. package/engine/internal/lib/dup_test.go +488 -0
  50. package/engine/internal/lib/environment_report.go +1 -0
  51. package/engine/internal/lib/environment_report_test.go +2 -2
  52. package/engine/internal/lib/handoff.go +194 -0
  53. package/engine/internal/lib/handoff_test.go +83 -0
  54. package/engine/internal/lib/manifest_union_test.go +1 -1
  55. package/engine/internal/lib/metrics.go +256 -0
  56. package/engine/internal/lib/migrate_test.go +6 -6
  57. package/engine/internal/lib/next.go +155 -0
  58. package/engine/internal/lib/observe_budgets_test.go +3 -3
  59. package/engine/internal/lib/regression.go +378 -0
  60. package/engine/internal/lib/regression_test.go +179 -0
  61. package/engine/internal/lib/resolve_remediation_test.go +1 -1
  62. package/engine/internal/lib/secretscan_test.go +1 -1
  63. package/engine/internal/lib/slicecheck.go +179 -0
  64. package/engine/internal/lib/slicecheck_test.go +111 -0
  65. package/engine/internal/lib/taskgraph_test.go +2 -2
  66. package/engine/internal/lib/triggers.go +133 -0
  67. package/engine/internal/lib/windows.go +353 -0
  68. package/engine/internal/lib/windows_test.go +237 -0
  69. package/engine/internal/notes/cli.go +349 -0
  70. package/engine/internal/notes/notes.go +384 -0
  71. package/engine/internal/notes/notes_test.go +173 -0
  72. package/engine/internal/parallel/lease.go +3 -8
  73. package/engine/internal/parallel/parallel_test.go +34 -0
  74. package/engine/internal/state/budgets.go +13 -8
  75. package/engine/internal/state/observation_test.go +1 -0
  76. package/engine/internal/state/schema.go +4 -3
  77. package/engine/internal/state/state_test.go +3 -3
  78. package/engine/internal/state/workflow_manifest.json +13 -4
  79. package/engine/internal/state/workspaceschema_test.go +2 -2
  80. package/engine/internal/testutil/testutil.go +4 -0
  81. package/engine/main.go +59 -0
  82. package/engine/note_routing_test.go +95 -0
  83. package/engine/observation_contract_test.go +1 -0
  84. package/engine/root_routing_test.go +13 -3
  85. package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/gates.md +4 -0
  86. package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/state.md +1 -1
  87. package/engine/testdata/fixtures/basic/devrites-root/work/search-ranking/state.md +1 -1
  88. package/engine/testdata/golden/TestParityResolve/answer/state.md.golden +1 -1
  89. package/engine/testdata/golden/TestParityResolve/drop/state.md.golden +1 -1
  90. package/engine/tests/adr_0027_readiness_binding_test.go +1 -0
  91. package/engine/tests/gate_test.go +3 -0
  92. package/engine/tests/parity_closeout_test.go +3 -3
  93. package/engine/tests/parity_resolve_test.go +1 -1
  94. package/engine/tests/workspace_observation_migration_test.go +8 -4
  95. package/pack/.claude/agents/_shared/composition-findings.md +1 -0
  96. package/pack/.claude/agents/_shared/composition-result.md +1 -0
  97. package/pack/.claude/agents/_shared/result-admission.md +3 -0
  98. package/pack/.claude/agents/_shared/untrusted-input-devex.md +1 -0
  99. package/pack/.claude/agents/_shared/untrusted-input-retrospector.md +1 -0
  100. package/pack/.claude/agents/_shared/untrusted-input.md +1 -0
  101. package/pack/.claude/agents/devrites-code-reviewer.md +19 -3
  102. package/pack/.claude/agents/devrites-devex-reviewer.md +3 -3
  103. package/pack/.claude/agents/devrites-doubt-reviewer.md +3 -3
  104. package/pack/.claude/agents/devrites-evidence-scout.md +3 -3
  105. package/pack/.claude/agents/devrites-frontend-reviewer.md +3 -3
  106. package/pack/.claude/agents/devrites-performance-reviewer.md +3 -3
  107. package/pack/.claude/agents/devrites-plan-drafter.md +3 -3
  108. package/pack/.claude/agents/devrites-plan-reviewer.md +3 -3
  109. package/pack/.claude/agents/devrites-proof-runner.md +3 -3
  110. package/pack/.claude/agents/devrites-retrospector.md +3 -3
  111. package/pack/.claude/agents/devrites-security-auditor.md +25 -3
  112. package/pack/.claude/agents/devrites-simplifier-reviewer.md +15 -5
  113. package/pack/.claude/agents/devrites-slice-wright.md +3 -3
  114. package/pack/.claude/agents/devrites-spec-reviewer.md +3 -3
  115. package/pack/.claude/agents/devrites-strategy-reviewer.md +3 -3
  116. package/pack/.claude/agents/devrites-test-analyst.md +3 -3
  117. package/pack/.claude/agents/devrites-upgrade-planner.md +3 -3
  118. package/pack/.claude/settings.json +39 -2
  119. package/pack/.claude/skills/devrites-api-interface/SKILL.md +2 -0
  120. package/pack/.claude/skills/devrites-audit/SKILL.md +9 -0
  121. package/pack/.claude/skills/devrites-browser-proof/SKILL.md +2 -0
  122. package/pack/.claude/skills/devrites-debug-recovery/SKILL.md +2 -0
  123. package/pack/.claude/skills/devrites-doubt/SKILL.md +2 -0
  124. package/pack/.claude/skills/devrites-frontend-craft/SKILL.md +2 -0
  125. package/pack/.claude/skills/devrites-frontend-craft/reference/design-references.md +4 -0
  126. package/pack/.claude/skills/devrites-frontend-craft/reference/shape.md +5 -0
  127. package/pack/.claude/skills/devrites-interview/SKILL.md +5 -0
  128. package/pack/.claude/skills/devrites-lib/SKILL.md +40 -5
  129. package/pack/.claude/skills/devrites-lib/reference/_shared/reslice-autocomplete.md +3 -0
  130. package/pack/.claude/skills/devrites-lib/reference/_shared/reslice-plan.md +3 -0
  131. package/pack/.claude/skills/devrites-lib/reference/_shared/reslice-vet.md +3 -0
  132. package/pack/.claude/skills/devrites-lib/reference/candidate-integrity.md +17 -0
  133. package/pack/.claude/skills/devrites-lib/reference/orchestration-profiles.md +20 -0
  134. package/pack/.claude/skills/devrites-lib/reference/parallel-dispatch.md +36 -4
  135. package/pack/.claude/skills/devrites-lib/reference/reply-contract.md +24 -1
  136. package/pack/.claude/skills/devrites-lib/reference/standards/README.md +10 -0
  137. package/pack/.claude/skills/devrites-lib/reference/standards/acceptance-preserving-reslice.md +2 -0
  138. package/pack/.claude/skills/devrites-lib/reference/standards/afk-hitl.md +2 -0
  139. package/pack/.claude/skills/devrites-lib/reference/standards/agents.md +21 -1
  140. package/pack/.claude/skills/devrites-lib/reference/standards/anti-patterns.md +2 -0
  141. package/pack/.claude/skills/devrites-lib/reference/standards/architecture-health.md +64 -0
  142. package/pack/.claude/skills/devrites-lib/reference/standards/assumption-checkpoints.md +42 -0
  143. package/pack/.claude/skills/devrites-lib/reference/standards/audit-coverage.md +103 -0
  144. package/pack/.claude/skills/devrites-lib/reference/standards/browser-proof-checklist.md +2 -0
  145. package/pack/.claude/skills/devrites-lib/reference/standards/ci-cd.md +11 -0
  146. package/pack/.claude/skills/devrites-lib/reference/standards/code-navigation.md +71 -4
  147. package/pack/.claude/skills/devrites-lib/reference/standards/code-review.md +67 -7
  148. package/pack/.claude/skills/devrites-lib/reference/standards/coding-style.md +9 -4
  149. package/pack/.claude/skills/devrites-lib/reference/standards/context-hygiene.md +20 -3
  150. package/pack/.claude/skills/devrites-lib/reference/standards/core.md +10 -1
  151. package/pack/.claude/skills/devrites-lib/reference/standards/data-integrity.md +24 -2
  152. package/pack/.claude/skills/devrites-lib/reference/standards/debug-recovery.md +14 -0
  153. package/pack/.claude/skills/devrites-lib/reference/standards/definition-of-done.md +6 -0
  154. package/pack/.claude/skills/devrites-lib/reference/standards/deprecation.md +18 -0
  155. package/pack/.claude/skills/devrites-lib/reference/standards/developer-experience.md +2 -0
  156. package/pack/.claude/skills/devrites-lib/reference/standards/development-workflow.md +2 -0
  157. package/pack/.claude/skills/devrites-lib/reference/standards/documentation.md +12 -0
  158. package/pack/.claude/skills/devrites-lib/reference/standards/duplicate-code.md +118 -0
  159. package/pack/.claude/skills/devrites-lib/reference/standards/edge-case-trace.md +2 -0
  160. package/pack/.claude/skills/devrites-lib/reference/standards/elicitation.md +29 -0
  161. package/pack/.claude/skills/devrites-lib/reference/standards/error-handling.md +2 -0
  162. package/pack/.claude/skills/devrites-lib/reference/standards/gates.md +117 -0
  163. package/pack/.claude/skills/devrites-lib/reference/standards/git-workflow.md +2 -0
  164. package/pack/.claude/skills/devrites-lib/reference/standards/glossary.md +40 -0
  165. package/pack/.claude/skills/devrites-lib/reference/standards/hooks.md +16 -0
  166. package/pack/.claude/skills/devrites-lib/reference/standards/integration-reliability.md +19 -0
  167. package/pack/.claude/skills/devrites-lib/reference/standards/loop-operations.md +32 -1
  168. package/pack/.claude/skills/devrites-lib/reference/standards/observability.md +2 -0
  169. package/pack/.claude/skills/devrites-lib/reference/standards/one-shot-actions.md +2 -0
  170. package/pack/.claude/skills/devrites-lib/reference/standards/patterns.md +2 -0
  171. package/pack/.claude/skills/devrites-lib/reference/standards/performance.md +8 -1
  172. package/pack/.claude/skills/devrites-lib/reference/standards/principles.md +14 -0
  173. package/pack/.claude/skills/devrites-lib/reference/standards/prose-style.md +3 -0
  174. package/pack/.claude/skills/devrites-lib/reference/standards/release/ship-checklist.md +4 -0
  175. package/pack/.claude/skills/devrites-lib/reference/standards/repository-topology.md +2 -0
  176. package/pack/.claude/skills/devrites-lib/reference/standards/review/README.md +23 -0
  177. package/pack/.claude/skills/devrites-lib/reference/standards/review/ci-workflows.md +50 -0
  178. package/pack/.claude/skills/devrites-lib/reference/standards/review/default.md +42 -0
  179. package/pack/.claude/skills/devrites-lib/reference/standards/review/go.md +47 -0
  180. package/pack/.claude/skills/devrites-lib/reference/standards/review/python.md +46 -0
  181. package/pack/.claude/skills/devrites-lib/reference/standards/review/shell.md +40 -0
  182. package/pack/.claude/skills/devrites-lib/reference/standards/review/ts-js.md +54 -0
  183. package/pack/.claude/skills/devrites-lib/reference/standards/review-checklist.md +2 -0
  184. package/pack/.claude/skills/devrites-lib/reference/standards/security-checklist.md +2 -0
  185. package/pack/.claude/skills/devrites-lib/reference/standards/security.md +58 -6
  186. package/pack/.claude/skills/devrites-lib/reference/standards/skill-authoring.md +48 -0
  187. package/pack/.claude/skills/devrites-lib/reference/standards/spec-grammar.md +18 -4
  188. package/pack/.claude/skills/devrites-lib/reference/standards/test-proof-checklist.md +5 -0
  189. package/pack/.claude/skills/devrites-lib/reference/standards/testing.md +19 -2
  190. package/pack/.claude/skills/devrites-lib/reference/standards/tooling.md +12 -0
  191. package/pack/.claude/skills/devrites-lib/reference/standards/verification-methods.md +110 -0
  192. package/pack/.claude/skills/devrites-lib/reference/standards/windows.md +51 -0
  193. package/pack/.claude/skills/devrites-lib/reference/standards/workflow-artifacts.md +2 -0
  194. package/pack/.claude/skills/devrites-lib/reference/workspace-artifact-schema.md +28 -3
  195. package/pack/.claude/skills/devrites-prose-craft/SKILL.md +3 -1
  196. package/pack/.claude/skills/devrites-source-driven/SKILL.md +2 -0
  197. package/pack/.claude/skills/devrites-ux-shape/SKILL.md +2 -0
  198. package/pack/.claude/skills/rite/SKILL.md +2 -0
  199. package/pack/.claude/skills/rite-adopt/SKILL.md +2 -0
  200. package/pack/.claude/skills/rite-autocomplete/SKILL.md +7 -4
  201. package/pack/.claude/skills/rite-autocomplete/reference/decision-policy.md +1 -3
  202. package/pack/.claude/skills/rite-autocomplete/reference/loop.md +8 -4
  203. package/pack/.claude/skills/rite-autocomplete/reference/stop-conditions.md +1 -3
  204. package/pack/.claude/skills/rite-build/SKILL.md +28 -14
  205. package/pack/.claude/skills/rite-build/reference/checkpoint.md +6 -0
  206. package/pack/.claude/skills/rite-build/reference/parallel-batch.md +11 -2
  207. package/pack/.claude/skills/rite-build/reference/phase-contract.md +8 -4
  208. package/pack/.claude/skills/rite-build/reference/wright-dispatch.md +34 -8
  209. package/pack/.claude/skills/rite-clarify/SKILL.md +4 -0
  210. package/pack/.claude/skills/rite-converge/SKILL.md +14 -2
  211. package/pack/.claude/skills/rite-customize/SKILL.md +2 -0
  212. package/pack/.claude/skills/rite-define/SKILL.md +8 -2
  213. package/pack/.claude/skills/rite-doctor/SKILL.md +6 -1
  214. package/pack/.claude/skills/rite-dogfood/SKILL.md +2 -0
  215. package/pack/.claude/skills/rite-explain/SKILL.md +2 -0
  216. package/pack/.claude/skills/rite-frame/SKILL.md +4 -0
  217. package/pack/.claude/skills/rite-handoff/SKILL.md +8 -1
  218. package/pack/.claude/skills/rite-learn/SKILL.md +2 -0
  219. package/pack/.claude/skills/rite-plan/SKILL.md +7 -3
  220. package/pack/.claude/skills/rite-plan/reference/anti-patterns.md +1 -3
  221. package/pack/.claude/skills/rite-plan/reference/replan-and-repair.md +1 -3
  222. package/pack/.claude/skills/rite-plan/reference/task-breakdown.md +3 -1
  223. package/pack/.claude/skills/rite-polish/SKILL.md +13 -2
  224. package/pack/.claude/skills/rite-polish/reference/code.md +6 -1
  225. package/pack/.claude/skills/rite-polish/reference/ledger.md +3 -1
  226. package/pack/.claude/skills/rite-pov/SKILL.md +2 -0
  227. package/pack/.claude/skills/rite-pr-feedback/SKILL.md +2 -0
  228. package/pack/.claude/skills/rite-pressure-test/SKILL.md +2 -0
  229. package/pack/.claude/skills/rite-prototype/SKILL.md +2 -0
  230. package/pack/.claude/skills/rite-prove/SKILL.md +17 -3
  231. package/pack/.claude/skills/rite-prove/reference/test-command-discovery.md +6 -0
  232. package/pack/.claude/skills/rite-quick/SKILL.md +7 -1
  233. package/pack/.claude/skills/rite-resolve/SKILL.md +2 -0
  234. package/pack/.claude/skills/rite-review/SKILL.md +5 -1
  235. package/pack/.claude/skills/rite-review/reference/performance-checklist.md +14 -3
  236. package/pack/.claude/skills/rite-seal/SKILL.md +27 -3
  237. package/pack/.claude/skills/rite-seal/reference/go-no-go.md +1 -0
  238. package/pack/.claude/skills/rite-seal/reference/phase-contract.md +3 -1
  239. package/pack/.claude/skills/rite-ship/SKILL.md +5 -1
  240. package/pack/.claude/skills/rite-spec/SKILL.md +10 -3
  241. package/pack/.claude/skills/rite-spec/reference/state-workspace.md +5 -0
  242. package/pack/.claude/skills/rite-status/SKILL.md +9 -0
  243. package/pack/.claude/skills/rite-temper/SKILL.md +5 -1
  244. package/pack/.claude/skills/rite-upgrade/SKILL.md +9 -1
  245. package/pack/.claude/skills/rite-vet/SKILL.md +29 -9
  246. package/pack/.claude/skills/rite-vet/reference/anti-patterns.md +1 -3
  247. package/pack/.claude/skills/rite-vet/reference/artifacts.md +20 -3
  248. package/pack/.claude/skills/rite-vet/reference/depth.md +1 -3
  249. package/pack/.claude/skills/rite-vet/reference/review-axes.md +6 -3
  250. package/pack/.claude/skills/rite-watch-pr/SKILL.md +2 -0
  251. package/pack/.claude/skills/rite-zoom-out/SKILL.md +2 -0
  252. package/pack/generated/claude/agents/devrites-code-reviewer.md +17 -1
  253. package/pack/generated/claude/agents/devrites-devex-reviewer.md +1 -1
  254. package/pack/generated/claude/agents/devrites-doubt-reviewer.md +1 -1
  255. package/pack/generated/claude/agents/devrites-evidence-scout.md +1 -1
  256. package/pack/generated/claude/agents/devrites-frontend-reviewer.md +1 -1
  257. package/pack/generated/claude/agents/devrites-performance-reviewer.md +1 -1
  258. package/pack/generated/claude/agents/devrites-plan-drafter.md +1 -1
  259. package/pack/generated/claude/agents/devrites-plan-reviewer.md +1 -1
  260. package/pack/generated/claude/agents/devrites-proof-runner.md +1 -1
  261. package/pack/generated/claude/agents/devrites-retrospector.md +1 -1
  262. package/pack/generated/claude/agents/devrites-security-auditor.md +23 -1
  263. package/pack/generated/claude/agents/devrites-simplifier-reviewer.md +13 -3
  264. package/pack/generated/claude/agents/devrites-slice-wright.md +1 -1
  265. package/pack/generated/claude/agents/devrites-spec-reviewer.md +1 -1
  266. package/pack/generated/claude/agents/devrites-strategy-reviewer.md +1 -1
  267. package/pack/generated/claude/agents/devrites-test-analyst.md +1 -1
  268. package/pack/generated/claude/agents/devrites-upgrade-planner.md +1 -1
  269. package/pack/generated/claude/settings.json +39 -2
  270. package/pack/generated/claude/skills/devrites-api-interface/SKILL.md +2 -0
  271. package/pack/generated/claude/skills/devrites-audit/SKILL.md +9 -0
  272. package/pack/generated/claude/skills/devrites-browser-proof/SKILL.md +2 -0
  273. package/pack/generated/claude/skills/devrites-debug-recovery/SKILL.md +2 -0
  274. package/pack/generated/claude/skills/devrites-doubt/SKILL.md +2 -0
  275. package/pack/generated/claude/skills/devrites-frontend-craft/SKILL.md +2 -0
  276. package/pack/generated/claude/skills/devrites-frontend-craft/reference/design-references.md +4 -0
  277. package/pack/generated/claude/skills/devrites-frontend-craft/reference/shape.md +5 -0
  278. package/pack/generated/claude/skills/devrites-interview/SKILL.md +5 -0
  279. package/pack/generated/claude/skills/devrites-lib/SKILL.md +40 -5
  280. package/pack/generated/claude/skills/devrites-lib/reference/candidate-integrity.md +17 -0
  281. package/pack/generated/claude/skills/devrites-lib/reference/orchestration-profiles.md +20 -0
  282. package/pack/generated/claude/skills/devrites-lib/reference/parallel-dispatch.md +36 -4
  283. package/pack/generated/claude/skills/devrites-lib/reference/reply-contract.md +24 -1
  284. package/pack/generated/claude/skills/devrites-lib/reference/standards/README.md +10 -0
  285. package/pack/generated/claude/skills/devrites-lib/reference/standards/acceptance-preserving-reslice.md +2 -0
  286. package/pack/generated/claude/skills/devrites-lib/reference/standards/afk-hitl.md +2 -0
  287. package/pack/generated/claude/skills/devrites-lib/reference/standards/agents.md +21 -1
  288. package/pack/generated/claude/skills/devrites-lib/reference/standards/anti-patterns.md +2 -0
  289. package/pack/generated/claude/skills/devrites-lib/reference/standards/architecture-health.md +64 -0
  290. package/pack/generated/claude/skills/devrites-lib/reference/standards/assumption-checkpoints.md +42 -0
  291. package/pack/generated/claude/skills/devrites-lib/reference/standards/audit-coverage.md +103 -0
  292. package/pack/generated/claude/skills/devrites-lib/reference/standards/browser-proof-checklist.md +2 -0
  293. package/pack/generated/claude/skills/devrites-lib/reference/standards/ci-cd.md +11 -0
  294. package/pack/generated/claude/skills/devrites-lib/reference/standards/code-navigation.md +71 -4
  295. package/pack/generated/claude/skills/devrites-lib/reference/standards/code-review.md +67 -7
  296. package/pack/generated/claude/skills/devrites-lib/reference/standards/coding-style.md +9 -4
  297. package/pack/generated/claude/skills/devrites-lib/reference/standards/context-hygiene.md +20 -3
  298. package/pack/generated/claude/skills/devrites-lib/reference/standards/core.md +10 -1
  299. package/pack/generated/claude/skills/devrites-lib/reference/standards/data-integrity.md +24 -2
  300. package/pack/generated/claude/skills/devrites-lib/reference/standards/debug-recovery.md +14 -0
  301. package/pack/generated/claude/skills/devrites-lib/reference/standards/definition-of-done.md +6 -0
  302. package/pack/generated/claude/skills/devrites-lib/reference/standards/deprecation.md +18 -0
  303. package/pack/generated/claude/skills/devrites-lib/reference/standards/developer-experience.md +2 -0
  304. package/pack/generated/claude/skills/devrites-lib/reference/standards/development-workflow.md +2 -0
  305. package/pack/generated/claude/skills/devrites-lib/reference/standards/documentation.md +12 -0
  306. package/pack/generated/claude/skills/devrites-lib/reference/standards/duplicate-code.md +118 -0
  307. package/pack/generated/claude/skills/devrites-lib/reference/standards/edge-case-trace.md +2 -0
  308. package/pack/generated/claude/skills/devrites-lib/reference/standards/elicitation.md +29 -0
  309. package/pack/generated/claude/skills/devrites-lib/reference/standards/error-handling.md +2 -0
  310. package/pack/generated/claude/skills/devrites-lib/reference/standards/gates.md +117 -0
  311. package/pack/generated/claude/skills/devrites-lib/reference/standards/git-workflow.md +2 -0
  312. package/pack/generated/claude/skills/devrites-lib/reference/standards/glossary.md +40 -0
  313. package/pack/generated/claude/skills/devrites-lib/reference/standards/hooks.md +16 -0
  314. package/pack/generated/claude/skills/devrites-lib/reference/standards/integration-reliability.md +19 -0
  315. package/pack/generated/claude/skills/devrites-lib/reference/standards/loop-operations.md +32 -1
  316. package/pack/generated/claude/skills/devrites-lib/reference/standards/observability.md +2 -0
  317. package/pack/generated/claude/skills/devrites-lib/reference/standards/one-shot-actions.md +2 -0
  318. package/pack/generated/claude/skills/devrites-lib/reference/standards/patterns.md +2 -0
  319. package/pack/generated/claude/skills/devrites-lib/reference/standards/performance.md +8 -1
  320. package/pack/generated/claude/skills/devrites-lib/reference/standards/principles.md +14 -0
  321. package/pack/generated/claude/skills/devrites-lib/reference/standards/prose-style.md +3 -0
  322. package/pack/generated/claude/skills/devrites-lib/reference/standards/release/ship-checklist.md +4 -0
  323. package/pack/generated/claude/skills/devrites-lib/reference/standards/repository-topology.md +2 -0
  324. package/pack/generated/claude/skills/devrites-lib/reference/standards/review/README.md +23 -0
  325. package/pack/generated/claude/skills/devrites-lib/reference/standards/review/ci-workflows.md +50 -0
  326. package/pack/generated/claude/skills/devrites-lib/reference/standards/review/default.md +42 -0
  327. package/pack/generated/claude/skills/devrites-lib/reference/standards/review/go.md +47 -0
  328. package/pack/generated/claude/skills/devrites-lib/reference/standards/review/python.md +46 -0
  329. package/pack/generated/claude/skills/devrites-lib/reference/standards/review/shell.md +40 -0
  330. package/pack/generated/claude/skills/devrites-lib/reference/standards/review/ts-js.md +54 -0
  331. package/pack/generated/claude/skills/devrites-lib/reference/standards/review-checklist.md +2 -0
  332. package/pack/generated/claude/skills/devrites-lib/reference/standards/security-checklist.md +2 -0
  333. package/pack/generated/claude/skills/devrites-lib/reference/standards/security.md +58 -6
  334. package/pack/generated/claude/skills/devrites-lib/reference/standards/skill-authoring.md +48 -0
  335. package/pack/generated/claude/skills/devrites-lib/reference/standards/spec-grammar.md +18 -4
  336. package/pack/generated/claude/skills/devrites-lib/reference/standards/test-proof-checklist.md +5 -0
  337. package/pack/generated/claude/skills/devrites-lib/reference/standards/testing.md +19 -2
  338. package/pack/generated/claude/skills/devrites-lib/reference/standards/tooling.md +12 -0
  339. package/pack/generated/claude/skills/devrites-lib/reference/standards/verification-methods.md +110 -0
  340. package/pack/generated/claude/skills/devrites-lib/reference/standards/windows.md +51 -0
  341. package/pack/generated/claude/skills/devrites-lib/reference/standards/workflow-artifacts.md +2 -0
  342. package/pack/generated/claude/skills/devrites-lib/reference/workspace-artifact-schema.md +28 -3
  343. package/pack/generated/claude/skills/devrites-prose-craft/SKILL.md +3 -1
  344. package/pack/generated/claude/skills/devrites-source-driven/SKILL.md +2 -0
  345. package/pack/generated/claude/skills/devrites-ux-shape/SKILL.md +2 -0
  346. package/pack/generated/claude/skills/rite/SKILL.md +2 -0
  347. package/pack/generated/claude/skills/rite-adopt/SKILL.md +2 -0
  348. package/pack/generated/claude/skills/rite-autocomplete/SKILL.md +6 -1
  349. package/pack/generated/claude/skills/rite-autocomplete/reference/loop.md +7 -1
  350. package/pack/generated/claude/skills/rite-build/SKILL.md +28 -14
  351. package/pack/generated/claude/skills/rite-build/reference/checkpoint.md +6 -0
  352. package/pack/generated/claude/skills/rite-build/reference/parallel-batch.md +11 -2
  353. package/pack/generated/claude/skills/rite-build/reference/phase-contract.md +8 -4
  354. package/pack/generated/claude/skills/rite-build/reference/wright-dispatch.md +34 -8
  355. package/pack/generated/claude/skills/rite-clarify/SKILL.md +4 -0
  356. package/pack/generated/claude/skills/rite-converge/SKILL.md +14 -2
  357. package/pack/generated/claude/skills/rite-customize/SKILL.md +2 -0
  358. package/pack/generated/claude/skills/rite-define/SKILL.md +8 -2
  359. package/pack/generated/claude/skills/rite-doctor/SKILL.md +6 -1
  360. package/pack/generated/claude/skills/rite-dogfood/SKILL.md +2 -0
  361. package/pack/generated/claude/skills/rite-explain/SKILL.md +2 -0
  362. package/pack/generated/claude/skills/rite-frame/SKILL.md +4 -0
  363. package/pack/generated/claude/skills/rite-handoff/SKILL.md +8 -1
  364. package/pack/generated/claude/skills/rite-learn/SKILL.md +2 -0
  365. package/pack/generated/claude/skills/rite-plan/SKILL.md +6 -0
  366. package/pack/generated/claude/skills/rite-plan/reference/task-breakdown.md +3 -1
  367. package/pack/generated/claude/skills/rite-polish/SKILL.md +13 -2
  368. package/pack/generated/claude/skills/rite-polish/reference/code.md +6 -1
  369. package/pack/generated/claude/skills/rite-polish/reference/ledger.md +3 -1
  370. package/pack/generated/claude/skills/rite-pov/SKILL.md +2 -0
  371. package/pack/generated/claude/skills/rite-pr-feedback/SKILL.md +2 -0
  372. package/pack/generated/claude/skills/rite-pressure-test/SKILL.md +2 -0
  373. package/pack/generated/claude/skills/rite-prototype/SKILL.md +2 -0
  374. package/pack/generated/claude/skills/rite-prove/SKILL.md +17 -3
  375. package/pack/generated/claude/skills/rite-prove/reference/test-command-discovery.md +6 -0
  376. package/pack/generated/claude/skills/rite-quick/SKILL.md +7 -1
  377. package/pack/generated/claude/skills/rite-resolve/SKILL.md +2 -0
  378. package/pack/generated/claude/skills/rite-review/SKILL.md +5 -1
  379. package/pack/generated/claude/skills/rite-review/reference/performance-checklist.md +14 -3
  380. package/pack/generated/claude/skills/rite-seal/SKILL.md +27 -3
  381. package/pack/generated/claude/skills/rite-seal/reference/go-no-go.md +1 -0
  382. package/pack/generated/claude/skills/rite-seal/reference/phase-contract.md +3 -1
  383. package/pack/generated/claude/skills/rite-ship/SKILL.md +5 -1
  384. package/pack/generated/claude/skills/rite-spec/SKILL.md +10 -3
  385. package/pack/generated/claude/skills/rite-spec/reference/state-workspace.md +5 -0
  386. package/pack/generated/claude/skills/rite-status/SKILL.md +9 -0
  387. package/pack/generated/claude/skills/rite-temper/SKILL.md +5 -1
  388. package/pack/generated/claude/skills/rite-upgrade/SKILL.md +9 -1
  389. package/pack/generated/claude/skills/rite-vet/SKILL.md +28 -6
  390. package/pack/generated/claude/skills/rite-vet/reference/artifacts.md +19 -0
  391. package/pack/generated/claude/skills/rite-vet/reference/review-axes.md +5 -0
  392. package/pack/generated/claude/skills/rite-watch-pr/SKILL.md +2 -0
  393. package/pack/generated/claude/skills/rite-zoom-out/SKILL.md +2 -0
  394. package/pack/generated/codex/agents/devrites-code-reviewer.toml +16 -0
  395. package/pack/generated/codex/agents/devrites-security-auditor.toml +22 -0
  396. package/pack/generated/codex/agents/devrites-simplifier-reviewer.toml +12 -2
  397. package/pack/generated/codex/skills/devrites-api-interface/SKILL.md +2 -0
  398. package/pack/generated/codex/skills/devrites-audit/SKILL.md +9 -0
  399. package/pack/generated/codex/skills/devrites-browser-proof/SKILL.md +2 -0
  400. package/pack/generated/codex/skills/devrites-debug-recovery/SKILL.md +2 -0
  401. package/pack/generated/codex/skills/devrites-doubt/SKILL.md +2 -0
  402. package/pack/generated/codex/skills/devrites-frontend-craft/SKILL.md +2 -0
  403. package/pack/generated/codex/skills/devrites-frontend-craft/reference/design-references.md +4 -0
  404. package/pack/generated/codex/skills/devrites-frontend-craft/reference/shape.md +5 -0
  405. package/pack/generated/codex/skills/devrites-interview/SKILL.md +5 -0
  406. package/pack/generated/codex/skills/devrites-lib/SKILL.md +40 -5
  407. package/pack/generated/codex/skills/devrites-lib/reference/candidate-integrity.md +17 -0
  408. package/pack/generated/codex/skills/devrites-lib/reference/orchestration-profiles.md +20 -0
  409. package/pack/generated/codex/skills/devrites-lib/reference/parallel-dispatch.md +36 -4
  410. package/pack/generated/codex/skills/devrites-lib/reference/reply-contract.md +24 -1
  411. package/pack/generated/codex/skills/devrites-lib/reference/standards/README.md +10 -0
  412. package/pack/generated/codex/skills/devrites-lib/reference/standards/acceptance-preserving-reslice.md +2 -0
  413. package/pack/generated/codex/skills/devrites-lib/reference/standards/afk-hitl.md +2 -0
  414. package/pack/generated/codex/skills/devrites-lib/reference/standards/agents.md +21 -1
  415. package/pack/generated/codex/skills/devrites-lib/reference/standards/anti-patterns.md +2 -0
  416. package/pack/generated/codex/skills/devrites-lib/reference/standards/architecture-health.md +64 -0
  417. package/pack/generated/codex/skills/devrites-lib/reference/standards/assumption-checkpoints.md +42 -0
  418. package/pack/generated/codex/skills/devrites-lib/reference/standards/audit-coverage.md +103 -0
  419. package/pack/generated/codex/skills/devrites-lib/reference/standards/browser-proof-checklist.md +2 -0
  420. package/pack/generated/codex/skills/devrites-lib/reference/standards/ci-cd.md +11 -0
  421. package/pack/generated/codex/skills/devrites-lib/reference/standards/code-navigation.md +71 -4
  422. package/pack/generated/codex/skills/devrites-lib/reference/standards/code-review.md +67 -7
  423. package/pack/generated/codex/skills/devrites-lib/reference/standards/coding-style.md +9 -4
  424. package/pack/generated/codex/skills/devrites-lib/reference/standards/context-hygiene.md +20 -3
  425. package/pack/generated/codex/skills/devrites-lib/reference/standards/core.md +10 -1
  426. package/pack/generated/codex/skills/devrites-lib/reference/standards/data-integrity.md +24 -2
  427. package/pack/generated/codex/skills/devrites-lib/reference/standards/debug-recovery.md +14 -0
  428. package/pack/generated/codex/skills/devrites-lib/reference/standards/definition-of-done.md +6 -0
  429. package/pack/generated/codex/skills/devrites-lib/reference/standards/deprecation.md +18 -0
  430. package/pack/generated/codex/skills/devrites-lib/reference/standards/developer-experience.md +2 -0
  431. package/pack/generated/codex/skills/devrites-lib/reference/standards/development-workflow.md +2 -0
  432. package/pack/generated/codex/skills/devrites-lib/reference/standards/documentation.md +12 -0
  433. package/pack/generated/codex/skills/devrites-lib/reference/standards/duplicate-code.md +118 -0
  434. package/pack/generated/codex/skills/devrites-lib/reference/standards/edge-case-trace.md +2 -0
  435. package/pack/generated/codex/skills/devrites-lib/reference/standards/elicitation.md +29 -0
  436. package/pack/generated/codex/skills/devrites-lib/reference/standards/error-handling.md +2 -0
  437. package/pack/generated/codex/skills/devrites-lib/reference/standards/gates.md +117 -0
  438. package/pack/generated/codex/skills/devrites-lib/reference/standards/git-workflow.md +2 -0
  439. package/pack/generated/codex/skills/devrites-lib/reference/standards/glossary.md +40 -0
  440. package/pack/generated/codex/skills/devrites-lib/reference/standards/hooks.md +16 -0
  441. package/pack/generated/codex/skills/devrites-lib/reference/standards/integration-reliability.md +19 -0
  442. package/pack/generated/codex/skills/devrites-lib/reference/standards/loop-operations.md +32 -1
  443. package/pack/generated/codex/skills/devrites-lib/reference/standards/observability.md +2 -0
  444. package/pack/generated/codex/skills/devrites-lib/reference/standards/one-shot-actions.md +2 -0
  445. package/pack/generated/codex/skills/devrites-lib/reference/standards/patterns.md +2 -0
  446. package/pack/generated/codex/skills/devrites-lib/reference/standards/performance.md +8 -1
  447. package/pack/generated/codex/skills/devrites-lib/reference/standards/principles.md +14 -0
  448. package/pack/generated/codex/skills/devrites-lib/reference/standards/prose-style.md +3 -0
  449. package/pack/generated/codex/skills/devrites-lib/reference/standards/release/ship-checklist.md +4 -0
  450. package/pack/generated/codex/skills/devrites-lib/reference/standards/repository-topology.md +2 -0
  451. package/pack/generated/codex/skills/devrites-lib/reference/standards/review/README.md +23 -0
  452. package/pack/generated/codex/skills/devrites-lib/reference/standards/review/ci-workflows.md +50 -0
  453. package/pack/generated/codex/skills/devrites-lib/reference/standards/review/default.md +42 -0
  454. package/pack/generated/codex/skills/devrites-lib/reference/standards/review/go.md +47 -0
  455. package/pack/generated/codex/skills/devrites-lib/reference/standards/review/python.md +46 -0
  456. package/pack/generated/codex/skills/devrites-lib/reference/standards/review/shell.md +40 -0
  457. package/pack/generated/codex/skills/devrites-lib/reference/standards/review/ts-js.md +54 -0
  458. package/pack/generated/codex/skills/devrites-lib/reference/standards/review-checklist.md +2 -0
  459. package/pack/generated/codex/skills/devrites-lib/reference/standards/security-checklist.md +2 -0
  460. package/pack/generated/codex/skills/devrites-lib/reference/standards/security.md +58 -6
  461. package/pack/generated/codex/skills/devrites-lib/reference/standards/skill-authoring.md +48 -0
  462. package/pack/generated/codex/skills/devrites-lib/reference/standards/spec-grammar.md +18 -4
  463. package/pack/generated/codex/skills/devrites-lib/reference/standards/test-proof-checklist.md +5 -0
  464. package/pack/generated/codex/skills/devrites-lib/reference/standards/testing.md +19 -2
  465. package/pack/generated/codex/skills/devrites-lib/reference/standards/tooling.md +12 -0
  466. package/pack/generated/codex/skills/devrites-lib/reference/standards/verification-methods.md +110 -0
  467. package/pack/generated/codex/skills/devrites-lib/reference/standards/windows.md +51 -0
  468. package/pack/generated/codex/skills/devrites-lib/reference/standards/workflow-artifacts.md +2 -0
  469. package/pack/generated/codex/skills/devrites-lib/reference/workspace-artifact-schema.md +28 -3
  470. package/pack/generated/codex/skills/devrites-prose-craft/SKILL.md +3 -1
  471. package/pack/generated/codex/skills/devrites-source-driven/SKILL.md +2 -0
  472. package/pack/generated/codex/skills/devrites-ux-shape/SKILL.md +2 -0
  473. package/pack/generated/codex/skills/rite/SKILL.md +2 -0
  474. package/pack/generated/codex/skills/rite-adopt/SKILL.md +2 -0
  475. package/pack/generated/codex/skills/rite-autocomplete/SKILL.md +6 -1
  476. package/pack/generated/codex/skills/rite-autocomplete/reference/loop.md +7 -1
  477. package/pack/generated/codex/skills/rite-build/SKILL.md +28 -14
  478. package/pack/generated/codex/skills/rite-build/reference/checkpoint.md +6 -0
  479. package/pack/generated/codex/skills/rite-build/reference/parallel-batch.md +11 -2
  480. package/pack/generated/codex/skills/rite-build/reference/phase-contract.md +8 -4
  481. package/pack/generated/codex/skills/rite-build/reference/wright-dispatch.md +34 -8
  482. package/pack/generated/codex/skills/rite-clarify/SKILL.md +4 -0
  483. package/pack/generated/codex/skills/rite-converge/SKILL.md +14 -2
  484. package/pack/generated/codex/skills/rite-customize/SKILL.md +2 -0
  485. package/pack/generated/codex/skills/rite-define/SKILL.md +8 -2
  486. package/pack/generated/codex/skills/rite-doctor/SKILL.md +6 -1
  487. package/pack/generated/codex/skills/rite-dogfood/SKILL.md +2 -0
  488. package/pack/generated/codex/skills/rite-explain/SKILL.md +2 -0
  489. package/pack/generated/codex/skills/rite-frame/SKILL.md +4 -0
  490. package/pack/generated/codex/skills/rite-handoff/SKILL.md +8 -1
  491. package/pack/generated/codex/skills/rite-learn/SKILL.md +2 -0
  492. package/pack/generated/codex/skills/rite-plan/SKILL.md +6 -0
  493. package/pack/generated/codex/skills/rite-plan/reference/task-breakdown.md +3 -1
  494. package/pack/generated/codex/skills/rite-polish/SKILL.md +13 -2
  495. package/pack/generated/codex/skills/rite-polish/reference/code.md +6 -1
  496. package/pack/generated/codex/skills/rite-polish/reference/ledger.md +3 -1
  497. package/pack/generated/codex/skills/rite-pov/SKILL.md +2 -0
  498. package/pack/generated/codex/skills/rite-pr-feedback/SKILL.md +2 -0
  499. package/pack/generated/codex/skills/rite-pressure-test/SKILL.md +2 -0
  500. package/pack/generated/codex/skills/rite-prototype/SKILL.md +2 -0
  501. package/pack/generated/codex/skills/rite-prove/SKILL.md +17 -3
  502. package/pack/generated/codex/skills/rite-prove/reference/test-command-discovery.md +6 -0
  503. package/pack/generated/codex/skills/rite-quick/SKILL.md +7 -1
  504. package/pack/generated/codex/skills/rite-resolve/SKILL.md +2 -0
  505. package/pack/generated/codex/skills/rite-review/SKILL.md +5 -1
  506. package/pack/generated/codex/skills/rite-review/reference/performance-checklist.md +14 -3
  507. package/pack/generated/codex/skills/rite-seal/SKILL.md +27 -3
  508. package/pack/generated/codex/skills/rite-seal/reference/go-no-go.md +1 -0
  509. package/pack/generated/codex/skills/rite-seal/reference/phase-contract.md +3 -1
  510. package/pack/generated/codex/skills/rite-ship/SKILL.md +5 -1
  511. package/pack/generated/codex/skills/rite-spec/SKILL.md +10 -3
  512. package/pack/generated/codex/skills/rite-spec/reference/state-workspace.md +5 -0
  513. package/pack/generated/codex/skills/rite-status/SKILL.md +9 -0
  514. package/pack/generated/codex/skills/rite-temper/SKILL.md +5 -1
  515. package/pack/generated/codex/skills/rite-upgrade/SKILL.md +9 -1
  516. package/pack/generated/codex/skills/rite-vet/SKILL.md +28 -6
  517. package/pack/generated/codex/skills/rite-vet/reference/artifacts.md +19 -0
  518. package/pack/generated/codex/skills/rite-vet/reference/review-axes.md +5 -0
  519. package/pack/generated/codex/skills/rite-watch-pr/SKILL.md +2 -0
  520. package/pack/generated/codex/skills/rite-zoom-out/SKILL.md +2 -0
  521. package/pack/generated/devin/agents/devrites-code-reviewer.md +16 -0
  522. package/pack/generated/devin/agents/devrites-security-auditor.md +22 -0
  523. package/pack/generated/devin/agents/devrites-simplifier-reviewer.md +12 -2
  524. package/pack/generated/devin/skills/devrites-api-interface/SKILL.md +2 -0
  525. package/pack/generated/devin/skills/devrites-audit/SKILL.md +9 -0
  526. package/pack/generated/devin/skills/devrites-browser-proof/SKILL.md +2 -0
  527. package/pack/generated/devin/skills/devrites-debug-recovery/SKILL.md +2 -0
  528. package/pack/generated/devin/skills/devrites-doubt/SKILL.md +2 -0
  529. package/pack/generated/devin/skills/devrites-frontend-craft/SKILL.md +2 -0
  530. package/pack/generated/devin/skills/devrites-frontend-craft/reference/design-references.md +4 -0
  531. package/pack/generated/devin/skills/devrites-frontend-craft/reference/shape.md +5 -0
  532. package/pack/generated/devin/skills/devrites-interview/SKILL.md +5 -0
  533. package/pack/generated/devin/skills/devrites-lib/SKILL.md +40 -5
  534. package/pack/generated/devin/skills/devrites-lib/reference/candidate-integrity.md +17 -0
  535. package/pack/generated/devin/skills/devrites-lib/reference/orchestration-profiles.md +20 -0
  536. package/pack/generated/devin/skills/devrites-lib/reference/parallel-dispatch.md +36 -4
  537. package/pack/generated/devin/skills/devrites-lib/reference/reply-contract.md +24 -1
  538. package/pack/generated/devin/skills/devrites-lib/reference/standards/README.md +10 -0
  539. package/pack/generated/devin/skills/devrites-lib/reference/standards/acceptance-preserving-reslice.md +2 -0
  540. package/pack/generated/devin/skills/devrites-lib/reference/standards/afk-hitl.md +2 -0
  541. package/pack/generated/devin/skills/devrites-lib/reference/standards/agents.md +21 -1
  542. package/pack/generated/devin/skills/devrites-lib/reference/standards/anti-patterns.md +2 -0
  543. package/pack/generated/devin/skills/devrites-lib/reference/standards/architecture-health.md +64 -0
  544. package/pack/generated/devin/skills/devrites-lib/reference/standards/assumption-checkpoints.md +42 -0
  545. package/pack/generated/devin/skills/devrites-lib/reference/standards/audit-coverage.md +103 -0
  546. package/pack/generated/devin/skills/devrites-lib/reference/standards/browser-proof-checklist.md +2 -0
  547. package/pack/generated/devin/skills/devrites-lib/reference/standards/ci-cd.md +11 -0
  548. package/pack/generated/devin/skills/devrites-lib/reference/standards/code-navigation.md +71 -4
  549. package/pack/generated/devin/skills/devrites-lib/reference/standards/code-review.md +67 -7
  550. package/pack/generated/devin/skills/devrites-lib/reference/standards/coding-style.md +9 -4
  551. package/pack/generated/devin/skills/devrites-lib/reference/standards/context-hygiene.md +20 -3
  552. package/pack/generated/devin/skills/devrites-lib/reference/standards/core.md +10 -1
  553. package/pack/generated/devin/skills/devrites-lib/reference/standards/data-integrity.md +24 -2
  554. package/pack/generated/devin/skills/devrites-lib/reference/standards/debug-recovery.md +14 -0
  555. package/pack/generated/devin/skills/devrites-lib/reference/standards/definition-of-done.md +6 -0
  556. package/pack/generated/devin/skills/devrites-lib/reference/standards/deprecation.md +18 -0
  557. package/pack/generated/devin/skills/devrites-lib/reference/standards/developer-experience.md +2 -0
  558. package/pack/generated/devin/skills/devrites-lib/reference/standards/development-workflow.md +2 -0
  559. package/pack/generated/devin/skills/devrites-lib/reference/standards/documentation.md +12 -0
  560. package/pack/generated/devin/skills/devrites-lib/reference/standards/duplicate-code.md +118 -0
  561. package/pack/generated/devin/skills/devrites-lib/reference/standards/edge-case-trace.md +2 -0
  562. package/pack/generated/devin/skills/devrites-lib/reference/standards/elicitation.md +29 -0
  563. package/pack/generated/devin/skills/devrites-lib/reference/standards/error-handling.md +2 -0
  564. package/pack/generated/devin/skills/devrites-lib/reference/standards/gates.md +117 -0
  565. package/pack/generated/devin/skills/devrites-lib/reference/standards/git-workflow.md +2 -0
  566. package/pack/generated/devin/skills/devrites-lib/reference/standards/glossary.md +40 -0
  567. package/pack/generated/devin/skills/devrites-lib/reference/standards/hooks.md +16 -0
  568. package/pack/generated/devin/skills/devrites-lib/reference/standards/integration-reliability.md +19 -0
  569. package/pack/generated/devin/skills/devrites-lib/reference/standards/loop-operations.md +32 -1
  570. package/pack/generated/devin/skills/devrites-lib/reference/standards/observability.md +2 -0
  571. package/pack/generated/devin/skills/devrites-lib/reference/standards/one-shot-actions.md +2 -0
  572. package/pack/generated/devin/skills/devrites-lib/reference/standards/patterns.md +2 -0
  573. package/pack/generated/devin/skills/devrites-lib/reference/standards/performance.md +8 -1
  574. package/pack/generated/devin/skills/devrites-lib/reference/standards/principles.md +14 -0
  575. package/pack/generated/devin/skills/devrites-lib/reference/standards/prose-style.md +3 -0
  576. package/pack/generated/devin/skills/devrites-lib/reference/standards/release/ship-checklist.md +4 -0
  577. package/pack/generated/devin/skills/devrites-lib/reference/standards/repository-topology.md +2 -0
  578. package/pack/generated/devin/skills/devrites-lib/reference/standards/review/README.md +23 -0
  579. package/pack/generated/devin/skills/devrites-lib/reference/standards/review/ci-workflows.md +50 -0
  580. package/pack/generated/devin/skills/devrites-lib/reference/standards/review/default.md +42 -0
  581. package/pack/generated/devin/skills/devrites-lib/reference/standards/review/go.md +47 -0
  582. package/pack/generated/devin/skills/devrites-lib/reference/standards/review/python.md +46 -0
  583. package/pack/generated/devin/skills/devrites-lib/reference/standards/review/shell.md +40 -0
  584. package/pack/generated/devin/skills/devrites-lib/reference/standards/review/ts-js.md +54 -0
  585. package/pack/generated/devin/skills/devrites-lib/reference/standards/review-checklist.md +2 -0
  586. package/pack/generated/devin/skills/devrites-lib/reference/standards/security-checklist.md +2 -0
  587. package/pack/generated/devin/skills/devrites-lib/reference/standards/security.md +58 -6
  588. package/pack/generated/devin/skills/devrites-lib/reference/standards/skill-authoring.md +48 -0
  589. package/pack/generated/devin/skills/devrites-lib/reference/standards/spec-grammar.md +18 -4
  590. package/pack/generated/devin/skills/devrites-lib/reference/standards/test-proof-checklist.md +5 -0
  591. package/pack/generated/devin/skills/devrites-lib/reference/standards/testing.md +19 -2
  592. package/pack/generated/devin/skills/devrites-lib/reference/standards/tooling.md +12 -0
  593. package/pack/generated/devin/skills/devrites-lib/reference/standards/verification-methods.md +110 -0
  594. package/pack/generated/devin/skills/devrites-lib/reference/standards/windows.md +51 -0
  595. package/pack/generated/devin/skills/devrites-lib/reference/standards/workflow-artifacts.md +2 -0
  596. package/pack/generated/devin/skills/devrites-lib/reference/workspace-artifact-schema.md +28 -3
  597. package/pack/generated/devin/skills/devrites-prose-craft/SKILL.md +3 -1
  598. package/pack/generated/devin/skills/devrites-source-driven/SKILL.md +2 -0
  599. package/pack/generated/devin/skills/devrites-ux-shape/SKILL.md +2 -0
  600. package/pack/generated/devin/skills/rite/SKILL.md +2 -0
  601. package/pack/generated/devin/skills/rite-adopt/SKILL.md +2 -0
  602. package/pack/generated/devin/skills/rite-autocomplete/SKILL.md +6 -1
  603. package/pack/generated/devin/skills/rite-autocomplete/reference/loop.md +7 -1
  604. package/pack/generated/devin/skills/rite-build/SKILL.md +28 -14
  605. package/pack/generated/devin/skills/rite-build/reference/checkpoint.md +6 -0
  606. package/pack/generated/devin/skills/rite-build/reference/parallel-batch.md +11 -2
  607. package/pack/generated/devin/skills/rite-build/reference/phase-contract.md +8 -4
  608. package/pack/generated/devin/skills/rite-build/reference/wright-dispatch.md +34 -8
  609. package/pack/generated/devin/skills/rite-clarify/SKILL.md +4 -0
  610. package/pack/generated/devin/skills/rite-converge/SKILL.md +14 -2
  611. package/pack/generated/devin/skills/rite-customize/SKILL.md +2 -0
  612. package/pack/generated/devin/skills/rite-define/SKILL.md +8 -2
  613. package/pack/generated/devin/skills/rite-doctor/SKILL.md +6 -1
  614. package/pack/generated/devin/skills/rite-dogfood/SKILL.md +2 -0
  615. package/pack/generated/devin/skills/rite-explain/SKILL.md +2 -0
  616. package/pack/generated/devin/skills/rite-frame/SKILL.md +4 -0
  617. package/pack/generated/devin/skills/rite-handoff/SKILL.md +8 -1
  618. package/pack/generated/devin/skills/rite-learn/SKILL.md +2 -0
  619. package/pack/generated/devin/skills/rite-plan/SKILL.md +6 -0
  620. package/pack/generated/devin/skills/rite-plan/reference/task-breakdown.md +3 -1
  621. package/pack/generated/devin/skills/rite-polish/SKILL.md +13 -2
  622. package/pack/generated/devin/skills/rite-polish/reference/code.md +6 -1
  623. package/pack/generated/devin/skills/rite-polish/reference/ledger.md +3 -1
  624. package/pack/generated/devin/skills/rite-pov/SKILL.md +2 -0
  625. package/pack/generated/devin/skills/rite-pr-feedback/SKILL.md +2 -0
  626. package/pack/generated/devin/skills/rite-pressure-test/SKILL.md +2 -0
  627. package/pack/generated/devin/skills/rite-prototype/SKILL.md +2 -0
  628. package/pack/generated/devin/skills/rite-prove/SKILL.md +17 -3
  629. package/pack/generated/devin/skills/rite-prove/reference/test-command-discovery.md +6 -0
  630. package/pack/generated/devin/skills/rite-quick/SKILL.md +7 -1
  631. package/pack/generated/devin/skills/rite-resolve/SKILL.md +2 -0
  632. package/pack/generated/devin/skills/rite-review/SKILL.md +5 -1
  633. package/pack/generated/devin/skills/rite-review/reference/performance-checklist.md +14 -3
  634. package/pack/generated/devin/skills/rite-seal/SKILL.md +27 -3
  635. package/pack/generated/devin/skills/rite-seal/reference/go-no-go.md +1 -0
  636. package/pack/generated/devin/skills/rite-seal/reference/phase-contract.md +3 -1
  637. package/pack/generated/devin/skills/rite-ship/SKILL.md +5 -1
  638. package/pack/generated/devin/skills/rite-spec/SKILL.md +10 -3
  639. package/pack/generated/devin/skills/rite-spec/reference/state-workspace.md +5 -0
  640. package/pack/generated/devin/skills/rite-status/SKILL.md +9 -0
  641. package/pack/generated/devin/skills/rite-temper/SKILL.md +5 -1
  642. package/pack/generated/devin/skills/rite-upgrade/SKILL.md +9 -1
  643. package/pack/generated/devin/skills/rite-vet/SKILL.md +28 -6
  644. package/pack/generated/devin/skills/rite-vet/reference/artifacts.md +19 -0
  645. package/pack/generated/devin/skills/rite-vet/reference/review-axes.md +5 -0
  646. package/pack/generated/devin/skills/rite-watch-pr/SKILL.md +2 -0
  647. package/pack/generated/devin/skills/rite-zoom-out/SKILL.md +2 -0
  648. package/pack/generated/omp/agents/devrites-code-reviewer.md +16 -0
  649. package/pack/generated/omp/agents/devrites-security-auditor.md +22 -0
  650. package/pack/generated/omp/agents/devrites-simplifier-reviewer.md +12 -2
  651. package/pack/generated/omp/skills/devrites-api-interface/SKILL.md +2 -0
  652. package/pack/generated/omp/skills/devrites-audit/SKILL.md +9 -0
  653. package/pack/generated/omp/skills/devrites-browser-proof/SKILL.md +2 -0
  654. package/pack/generated/omp/skills/devrites-debug-recovery/SKILL.md +2 -0
  655. package/pack/generated/omp/skills/devrites-doubt/SKILL.md +2 -0
  656. package/pack/generated/omp/skills/devrites-frontend-craft/SKILL.md +2 -0
  657. package/pack/generated/omp/skills/devrites-frontend-craft/reference/design-references.md +4 -0
  658. package/pack/generated/omp/skills/devrites-frontend-craft/reference/shape.md +5 -0
  659. package/pack/generated/omp/skills/devrites-interview/SKILL.md +5 -0
  660. package/pack/generated/omp/skills/devrites-lib/SKILL.md +40 -5
  661. package/pack/generated/omp/skills/devrites-lib/reference/candidate-integrity.md +17 -0
  662. package/pack/generated/omp/skills/devrites-lib/reference/orchestration-profiles.md +20 -0
  663. package/pack/generated/omp/skills/devrites-lib/reference/parallel-dispatch.md +36 -4
  664. package/pack/generated/omp/skills/devrites-lib/reference/reply-contract.md +24 -1
  665. package/pack/generated/omp/skills/devrites-lib/reference/standards/README.md +10 -0
  666. package/pack/generated/omp/skills/devrites-lib/reference/standards/acceptance-preserving-reslice.md +2 -0
  667. package/pack/generated/omp/skills/devrites-lib/reference/standards/afk-hitl.md +2 -0
  668. package/pack/generated/omp/skills/devrites-lib/reference/standards/agents.md +21 -1
  669. package/pack/generated/omp/skills/devrites-lib/reference/standards/anti-patterns.md +2 -0
  670. package/pack/generated/omp/skills/devrites-lib/reference/standards/architecture-health.md +64 -0
  671. package/pack/generated/omp/skills/devrites-lib/reference/standards/assumption-checkpoints.md +42 -0
  672. package/pack/generated/omp/skills/devrites-lib/reference/standards/audit-coverage.md +103 -0
  673. package/pack/generated/omp/skills/devrites-lib/reference/standards/browser-proof-checklist.md +2 -0
  674. package/pack/generated/omp/skills/devrites-lib/reference/standards/ci-cd.md +11 -0
  675. package/pack/generated/omp/skills/devrites-lib/reference/standards/code-navigation.md +71 -4
  676. package/pack/generated/omp/skills/devrites-lib/reference/standards/code-review.md +67 -7
  677. package/pack/generated/omp/skills/devrites-lib/reference/standards/coding-style.md +9 -4
  678. package/pack/generated/omp/skills/devrites-lib/reference/standards/context-hygiene.md +20 -3
  679. package/pack/generated/omp/skills/devrites-lib/reference/standards/core.md +10 -1
  680. package/pack/generated/omp/skills/devrites-lib/reference/standards/data-integrity.md +24 -2
  681. package/pack/generated/omp/skills/devrites-lib/reference/standards/debug-recovery.md +14 -0
  682. package/pack/generated/omp/skills/devrites-lib/reference/standards/definition-of-done.md +6 -0
  683. package/pack/generated/omp/skills/devrites-lib/reference/standards/deprecation.md +18 -0
  684. package/pack/generated/omp/skills/devrites-lib/reference/standards/developer-experience.md +2 -0
  685. package/pack/generated/omp/skills/devrites-lib/reference/standards/development-workflow.md +2 -0
  686. package/pack/generated/omp/skills/devrites-lib/reference/standards/documentation.md +12 -0
  687. package/pack/generated/omp/skills/devrites-lib/reference/standards/duplicate-code.md +118 -0
  688. package/pack/generated/omp/skills/devrites-lib/reference/standards/edge-case-trace.md +2 -0
  689. package/pack/generated/omp/skills/devrites-lib/reference/standards/elicitation.md +29 -0
  690. package/pack/generated/omp/skills/devrites-lib/reference/standards/error-handling.md +2 -0
  691. package/pack/generated/omp/skills/devrites-lib/reference/standards/gates.md +117 -0
  692. package/pack/generated/omp/skills/devrites-lib/reference/standards/git-workflow.md +2 -0
  693. package/pack/generated/omp/skills/devrites-lib/reference/standards/glossary.md +40 -0
  694. package/pack/generated/omp/skills/devrites-lib/reference/standards/hooks.md +16 -0
  695. package/pack/generated/omp/skills/devrites-lib/reference/standards/integration-reliability.md +19 -0
  696. package/pack/generated/omp/skills/devrites-lib/reference/standards/loop-operations.md +32 -1
  697. package/pack/generated/omp/skills/devrites-lib/reference/standards/observability.md +2 -0
  698. package/pack/generated/omp/skills/devrites-lib/reference/standards/one-shot-actions.md +2 -0
  699. package/pack/generated/omp/skills/devrites-lib/reference/standards/patterns.md +2 -0
  700. package/pack/generated/omp/skills/devrites-lib/reference/standards/performance.md +8 -1
  701. package/pack/generated/omp/skills/devrites-lib/reference/standards/principles.md +14 -0
  702. package/pack/generated/omp/skills/devrites-lib/reference/standards/prose-style.md +3 -0
  703. package/pack/generated/omp/skills/devrites-lib/reference/standards/release/ship-checklist.md +4 -0
  704. package/pack/generated/omp/skills/devrites-lib/reference/standards/repository-topology.md +2 -0
  705. package/pack/generated/omp/skills/devrites-lib/reference/standards/review/README.md +23 -0
  706. package/pack/generated/omp/skills/devrites-lib/reference/standards/review/ci-workflows.md +50 -0
  707. package/pack/generated/omp/skills/devrites-lib/reference/standards/review/default.md +42 -0
  708. package/pack/generated/omp/skills/devrites-lib/reference/standards/review/go.md +47 -0
  709. package/pack/generated/omp/skills/devrites-lib/reference/standards/review/python.md +46 -0
  710. package/pack/generated/omp/skills/devrites-lib/reference/standards/review/shell.md +40 -0
  711. package/pack/generated/omp/skills/devrites-lib/reference/standards/review/ts-js.md +54 -0
  712. package/pack/generated/omp/skills/devrites-lib/reference/standards/review-checklist.md +2 -0
  713. package/pack/generated/omp/skills/devrites-lib/reference/standards/security-checklist.md +2 -0
  714. package/pack/generated/omp/skills/devrites-lib/reference/standards/security.md +58 -6
  715. package/pack/generated/omp/skills/devrites-lib/reference/standards/skill-authoring.md +48 -0
  716. package/pack/generated/omp/skills/devrites-lib/reference/standards/spec-grammar.md +18 -4
  717. package/pack/generated/omp/skills/devrites-lib/reference/standards/test-proof-checklist.md +5 -0
  718. package/pack/generated/omp/skills/devrites-lib/reference/standards/testing.md +19 -2
  719. package/pack/generated/omp/skills/devrites-lib/reference/standards/tooling.md +12 -0
  720. package/pack/generated/omp/skills/devrites-lib/reference/standards/verification-methods.md +110 -0
  721. package/pack/generated/omp/skills/devrites-lib/reference/standards/windows.md +51 -0
  722. package/pack/generated/omp/skills/devrites-lib/reference/standards/workflow-artifacts.md +2 -0
  723. package/pack/generated/omp/skills/devrites-lib/reference/workspace-artifact-schema.md +28 -3
  724. package/pack/generated/omp/skills/devrites-prose-craft/SKILL.md +3 -1
  725. package/pack/generated/omp/skills/devrites-source-driven/SKILL.md +2 -0
  726. package/pack/generated/omp/skills/devrites-ux-shape/SKILL.md +2 -0
  727. package/pack/generated/omp/skills/rite/SKILL.md +2 -0
  728. package/pack/generated/omp/skills/rite-adopt/SKILL.md +2 -0
  729. package/pack/generated/omp/skills/rite-autocomplete/SKILL.md +6 -1
  730. package/pack/generated/omp/skills/rite-autocomplete/reference/loop.md +7 -1
  731. package/pack/generated/omp/skills/rite-build/SKILL.md +28 -14
  732. package/pack/generated/omp/skills/rite-build/reference/checkpoint.md +6 -0
  733. package/pack/generated/omp/skills/rite-build/reference/parallel-batch.md +11 -2
  734. package/pack/generated/omp/skills/rite-build/reference/phase-contract.md +8 -4
  735. package/pack/generated/omp/skills/rite-build/reference/wright-dispatch.md +34 -8
  736. package/pack/generated/omp/skills/rite-clarify/SKILL.md +4 -0
  737. package/pack/generated/omp/skills/rite-converge/SKILL.md +14 -2
  738. package/pack/generated/omp/skills/rite-customize/SKILL.md +2 -0
  739. package/pack/generated/omp/skills/rite-define/SKILL.md +8 -2
  740. package/pack/generated/omp/skills/rite-doctor/SKILL.md +6 -1
  741. package/pack/generated/omp/skills/rite-dogfood/SKILL.md +2 -0
  742. package/pack/generated/omp/skills/rite-explain/SKILL.md +2 -0
  743. package/pack/generated/omp/skills/rite-frame/SKILL.md +4 -0
  744. package/pack/generated/omp/skills/rite-handoff/SKILL.md +8 -1
  745. package/pack/generated/omp/skills/rite-learn/SKILL.md +2 -0
  746. package/pack/generated/omp/skills/rite-plan/SKILL.md +6 -0
  747. package/pack/generated/omp/skills/rite-plan/reference/task-breakdown.md +3 -1
  748. package/pack/generated/omp/skills/rite-polish/SKILL.md +13 -2
  749. package/pack/generated/omp/skills/rite-polish/reference/code.md +6 -1
  750. package/pack/generated/omp/skills/rite-polish/reference/ledger.md +3 -1
  751. package/pack/generated/omp/skills/rite-pov/SKILL.md +2 -0
  752. package/pack/generated/omp/skills/rite-pr-feedback/SKILL.md +2 -0
  753. package/pack/generated/omp/skills/rite-pressure-test/SKILL.md +2 -0
  754. package/pack/generated/omp/skills/rite-prototype/SKILL.md +2 -0
  755. package/pack/generated/omp/skills/rite-prove/SKILL.md +17 -3
  756. package/pack/generated/omp/skills/rite-prove/reference/test-command-discovery.md +6 -0
  757. package/pack/generated/omp/skills/rite-quick/SKILL.md +7 -1
  758. package/pack/generated/omp/skills/rite-resolve/SKILL.md +2 -0
  759. package/pack/generated/omp/skills/rite-review/SKILL.md +5 -1
  760. package/pack/generated/omp/skills/rite-review/reference/performance-checklist.md +14 -3
  761. package/pack/generated/omp/skills/rite-seal/SKILL.md +27 -3
  762. package/pack/generated/omp/skills/rite-seal/reference/go-no-go.md +1 -0
  763. package/pack/generated/omp/skills/rite-seal/reference/phase-contract.md +3 -1
  764. package/pack/generated/omp/skills/rite-ship/SKILL.md +5 -1
  765. package/pack/generated/omp/skills/rite-spec/SKILL.md +10 -3
  766. package/pack/generated/omp/skills/rite-spec/reference/state-workspace.md +5 -0
  767. package/pack/generated/omp/skills/rite-status/SKILL.md +9 -0
  768. package/pack/generated/omp/skills/rite-temper/SKILL.md +5 -1
  769. package/pack/generated/omp/skills/rite-upgrade/SKILL.md +9 -1
  770. package/pack/generated/omp/skills/rite-vet/SKILL.md +28 -6
  771. package/pack/generated/omp/skills/rite-vet/reference/artifacts.md +19 -0
  772. package/pack/generated/omp/skills/rite-vet/reference/review-axes.md +5 -0
  773. package/pack/generated/omp/skills/rite-watch-pr/SKILL.md +2 -0
  774. package/pack/generated/omp/skills/rite-zoom-out/SKILL.md +2 -0
  775. package/pack/generated/pi/agents/devrites-code-reviewer.md +16 -0
  776. package/pack/generated/pi/agents/devrites-security-auditor.md +22 -0
  777. package/pack/generated/pi/agents/devrites-simplifier-reviewer.md +12 -2
  778. package/pack/generated/pi/skills/devrites-api-interface/SKILL.md +2 -0
  779. package/pack/generated/pi/skills/devrites-audit/SKILL.md +9 -0
  780. package/pack/generated/pi/skills/devrites-browser-proof/SKILL.md +2 -0
  781. package/pack/generated/pi/skills/devrites-debug-recovery/SKILL.md +2 -0
  782. package/pack/generated/pi/skills/devrites-doubt/SKILL.md +2 -0
  783. package/pack/generated/pi/skills/devrites-frontend-craft/SKILL.md +2 -0
  784. package/pack/generated/pi/skills/devrites-frontend-craft/reference/design-references.md +4 -0
  785. package/pack/generated/pi/skills/devrites-frontend-craft/reference/shape.md +5 -0
  786. package/pack/generated/pi/skills/devrites-interview/SKILL.md +5 -0
  787. package/pack/generated/pi/skills/devrites-lib/SKILL.md +40 -5
  788. package/pack/generated/pi/skills/devrites-lib/reference/candidate-integrity.md +17 -0
  789. package/pack/generated/pi/skills/devrites-lib/reference/orchestration-profiles.md +20 -0
  790. package/pack/generated/pi/skills/devrites-lib/reference/parallel-dispatch.md +36 -4
  791. package/pack/generated/pi/skills/devrites-lib/reference/reply-contract.md +24 -1
  792. package/pack/generated/pi/skills/devrites-lib/reference/standards/README.md +10 -0
  793. package/pack/generated/pi/skills/devrites-lib/reference/standards/acceptance-preserving-reslice.md +2 -0
  794. package/pack/generated/pi/skills/devrites-lib/reference/standards/afk-hitl.md +2 -0
  795. package/pack/generated/pi/skills/devrites-lib/reference/standards/agents.md +21 -1
  796. package/pack/generated/pi/skills/devrites-lib/reference/standards/anti-patterns.md +2 -0
  797. package/pack/generated/pi/skills/devrites-lib/reference/standards/architecture-health.md +64 -0
  798. package/pack/generated/pi/skills/devrites-lib/reference/standards/assumption-checkpoints.md +42 -0
  799. package/pack/generated/pi/skills/devrites-lib/reference/standards/audit-coverage.md +103 -0
  800. package/pack/generated/pi/skills/devrites-lib/reference/standards/browser-proof-checklist.md +2 -0
  801. package/pack/generated/pi/skills/devrites-lib/reference/standards/ci-cd.md +11 -0
  802. package/pack/generated/pi/skills/devrites-lib/reference/standards/code-navigation.md +71 -4
  803. package/pack/generated/pi/skills/devrites-lib/reference/standards/code-review.md +67 -7
  804. package/pack/generated/pi/skills/devrites-lib/reference/standards/coding-style.md +9 -4
  805. package/pack/generated/pi/skills/devrites-lib/reference/standards/context-hygiene.md +20 -3
  806. package/pack/generated/pi/skills/devrites-lib/reference/standards/core.md +10 -1
  807. package/pack/generated/pi/skills/devrites-lib/reference/standards/data-integrity.md +24 -2
  808. package/pack/generated/pi/skills/devrites-lib/reference/standards/debug-recovery.md +14 -0
  809. package/pack/generated/pi/skills/devrites-lib/reference/standards/definition-of-done.md +6 -0
  810. package/pack/generated/pi/skills/devrites-lib/reference/standards/deprecation.md +18 -0
  811. package/pack/generated/pi/skills/devrites-lib/reference/standards/developer-experience.md +2 -0
  812. package/pack/generated/pi/skills/devrites-lib/reference/standards/development-workflow.md +2 -0
  813. package/pack/generated/pi/skills/devrites-lib/reference/standards/documentation.md +12 -0
  814. package/pack/generated/pi/skills/devrites-lib/reference/standards/duplicate-code.md +118 -0
  815. package/pack/generated/pi/skills/devrites-lib/reference/standards/edge-case-trace.md +2 -0
  816. package/pack/generated/pi/skills/devrites-lib/reference/standards/elicitation.md +29 -0
  817. package/pack/generated/pi/skills/devrites-lib/reference/standards/error-handling.md +2 -0
  818. package/pack/generated/pi/skills/devrites-lib/reference/standards/gates.md +117 -0
  819. package/pack/generated/pi/skills/devrites-lib/reference/standards/git-workflow.md +2 -0
  820. package/pack/generated/pi/skills/devrites-lib/reference/standards/glossary.md +40 -0
  821. package/pack/generated/pi/skills/devrites-lib/reference/standards/hooks.md +16 -0
  822. package/pack/generated/pi/skills/devrites-lib/reference/standards/integration-reliability.md +19 -0
  823. package/pack/generated/pi/skills/devrites-lib/reference/standards/loop-operations.md +32 -1
  824. package/pack/generated/pi/skills/devrites-lib/reference/standards/observability.md +2 -0
  825. package/pack/generated/pi/skills/devrites-lib/reference/standards/one-shot-actions.md +2 -0
  826. package/pack/generated/pi/skills/devrites-lib/reference/standards/patterns.md +2 -0
  827. package/pack/generated/pi/skills/devrites-lib/reference/standards/performance.md +8 -1
  828. package/pack/generated/pi/skills/devrites-lib/reference/standards/principles.md +14 -0
  829. package/pack/generated/pi/skills/devrites-lib/reference/standards/prose-style.md +3 -0
  830. package/pack/generated/pi/skills/devrites-lib/reference/standards/release/ship-checklist.md +4 -0
  831. package/pack/generated/pi/skills/devrites-lib/reference/standards/repository-topology.md +2 -0
  832. package/pack/generated/pi/skills/devrites-lib/reference/standards/review/README.md +23 -0
  833. package/pack/generated/pi/skills/devrites-lib/reference/standards/review/ci-workflows.md +50 -0
  834. package/pack/generated/pi/skills/devrites-lib/reference/standards/review/default.md +42 -0
  835. package/pack/generated/pi/skills/devrites-lib/reference/standards/review/go.md +47 -0
  836. package/pack/generated/pi/skills/devrites-lib/reference/standards/review/python.md +46 -0
  837. package/pack/generated/pi/skills/devrites-lib/reference/standards/review/shell.md +40 -0
  838. package/pack/generated/pi/skills/devrites-lib/reference/standards/review/ts-js.md +54 -0
  839. package/pack/generated/pi/skills/devrites-lib/reference/standards/review-checklist.md +2 -0
  840. package/pack/generated/pi/skills/devrites-lib/reference/standards/security-checklist.md +2 -0
  841. package/pack/generated/pi/skills/devrites-lib/reference/standards/security.md +58 -6
  842. package/pack/generated/pi/skills/devrites-lib/reference/standards/skill-authoring.md +48 -0
  843. package/pack/generated/pi/skills/devrites-lib/reference/standards/spec-grammar.md +18 -4
  844. package/pack/generated/pi/skills/devrites-lib/reference/standards/test-proof-checklist.md +5 -0
  845. package/pack/generated/pi/skills/devrites-lib/reference/standards/testing.md +19 -2
  846. package/pack/generated/pi/skills/devrites-lib/reference/standards/tooling.md +12 -0
  847. package/pack/generated/pi/skills/devrites-lib/reference/standards/verification-methods.md +110 -0
  848. package/pack/generated/pi/skills/devrites-lib/reference/standards/windows.md +51 -0
  849. package/pack/generated/pi/skills/devrites-lib/reference/standards/workflow-artifacts.md +2 -0
  850. package/pack/generated/pi/skills/devrites-lib/reference/workspace-artifact-schema.md +28 -3
  851. package/pack/generated/pi/skills/devrites-prose-craft/SKILL.md +3 -1
  852. package/pack/generated/pi/skills/devrites-source-driven/SKILL.md +2 -0
  853. package/pack/generated/pi/skills/devrites-ux-shape/SKILL.md +2 -0
  854. package/pack/generated/pi/skills/rite/SKILL.md +2 -0
  855. package/pack/generated/pi/skills/rite-adopt/SKILL.md +2 -0
  856. package/pack/generated/pi/skills/rite-autocomplete/SKILL.md +6 -1
  857. package/pack/generated/pi/skills/rite-autocomplete/reference/loop.md +7 -1
  858. package/pack/generated/pi/skills/rite-build/SKILL.md +28 -14
  859. package/pack/generated/pi/skills/rite-build/reference/checkpoint.md +6 -0
  860. package/pack/generated/pi/skills/rite-build/reference/parallel-batch.md +11 -2
  861. package/pack/generated/pi/skills/rite-build/reference/phase-contract.md +8 -4
  862. package/pack/generated/pi/skills/rite-build/reference/wright-dispatch.md +34 -8
  863. package/pack/generated/pi/skills/rite-clarify/SKILL.md +4 -0
  864. package/pack/generated/pi/skills/rite-converge/SKILL.md +14 -2
  865. package/pack/generated/pi/skills/rite-customize/SKILL.md +2 -0
  866. package/pack/generated/pi/skills/rite-define/SKILL.md +8 -2
  867. package/pack/generated/pi/skills/rite-doctor/SKILL.md +6 -1
  868. package/pack/generated/pi/skills/rite-dogfood/SKILL.md +2 -0
  869. package/pack/generated/pi/skills/rite-explain/SKILL.md +2 -0
  870. package/pack/generated/pi/skills/rite-frame/SKILL.md +4 -0
  871. package/pack/generated/pi/skills/rite-handoff/SKILL.md +8 -1
  872. package/pack/generated/pi/skills/rite-learn/SKILL.md +2 -0
  873. package/pack/generated/pi/skills/rite-plan/SKILL.md +6 -0
  874. package/pack/generated/pi/skills/rite-plan/reference/task-breakdown.md +3 -1
  875. package/pack/generated/pi/skills/rite-polish/SKILL.md +13 -2
  876. package/pack/generated/pi/skills/rite-polish/reference/code.md +6 -1
  877. package/pack/generated/pi/skills/rite-polish/reference/ledger.md +3 -1
  878. package/pack/generated/pi/skills/rite-pov/SKILL.md +2 -0
  879. package/pack/generated/pi/skills/rite-pr-feedback/SKILL.md +2 -0
  880. package/pack/generated/pi/skills/rite-pressure-test/SKILL.md +2 -0
  881. package/pack/generated/pi/skills/rite-prototype/SKILL.md +2 -0
  882. package/pack/generated/pi/skills/rite-prove/SKILL.md +17 -3
  883. package/pack/generated/pi/skills/rite-prove/reference/test-command-discovery.md +6 -0
  884. package/pack/generated/pi/skills/rite-quick/SKILL.md +7 -1
  885. package/pack/generated/pi/skills/rite-resolve/SKILL.md +2 -0
  886. package/pack/generated/pi/skills/rite-review/SKILL.md +5 -1
  887. package/pack/generated/pi/skills/rite-review/reference/performance-checklist.md +14 -3
  888. package/pack/generated/pi/skills/rite-seal/SKILL.md +27 -3
  889. package/pack/generated/pi/skills/rite-seal/reference/go-no-go.md +1 -0
  890. package/pack/generated/pi/skills/rite-seal/reference/phase-contract.md +3 -1
  891. package/pack/generated/pi/skills/rite-ship/SKILL.md +5 -1
  892. package/pack/generated/pi/skills/rite-spec/SKILL.md +10 -3
  893. package/pack/generated/pi/skills/rite-spec/reference/state-workspace.md +5 -0
  894. package/pack/generated/pi/skills/rite-status/SKILL.md +9 -0
  895. package/pack/generated/pi/skills/rite-temper/SKILL.md +5 -1
  896. package/pack/generated/pi/skills/rite-upgrade/SKILL.md +9 -1
  897. package/pack/generated/pi/skills/rite-vet/SKILL.md +28 -6
  898. package/pack/generated/pi/skills/rite-vet/reference/artifacts.md +19 -0
  899. package/pack/generated/pi/skills/rite-vet/reference/review-axes.md +5 -0
  900. package/pack/generated/pi/skills/rite-watch-pr/SKILL.md +2 -0
  901. package/pack/generated/pi/skills/rite-zoom-out/SKILL.md +2 -0
  902. package/package.json +1 -1
  903. package/scripts/build-host-artifacts.sh +48 -2
@@ -0,0 +1,1243 @@
1
+ package lib
2
+
3
+ // dup.go — deterministic near-duplicate detection.
4
+ //
5
+ // `devrites-engine check dup` finds structurally identical code regions —
6
+ // copies that survive renaming and reformatting — with no model and no
7
+ // network. Reviewers catch verbatim paste; this catches the same block
8
+ // re-typed with different identifiers, which is the class that review
9
+ // memory misses in large trees.
10
+ //
11
+ // Method: strip comments and strings, tokenize each line (keywords and
12
+ // punctuation kept, identifiers/numbers/string literals erased), then
13
+ // match k-line shingles across files and chain co-linear anchor hits into
14
+ // segment pairs. Pairs merge into transitive clusters ranked by similarity
15
+ // boosted by distance — a twin two modules away matters more than a twin
16
+ // in the same file. Each cluster gets a stable content hash so a dismissed
17
+ // cluster stays dismissed in .devrites/dup-ignore until the code changes.
18
+ //
19
+ // devrites-engine check dup [slug] [--all|--worktree|--staged|--base <ref>]
20
+ // [--min-lines n] [--threshold f] [--ignore-file <path>] [--limit n]
21
+ // [--exclude <csv>] [--cwd <dir>]
22
+ //
23
+ // Successful scans exit 0; usage or incomplete scans exit 2. Clusters are
24
+ // leads for reviewer adjudication, not a gate. A reported cluster is an unverified claim until a reader
25
+ // confirms the regions are genuinely interchangeable.
26
+
27
+ import (
28
+ "bytes"
29
+ "crypto/sha256"
30
+ "encoding/hex"
31
+ "fmt"
32
+ "hash/fnv"
33
+ "io"
34
+ "math"
35
+ "os"
36
+ "path"
37
+ "path/filepath"
38
+ "sort"
39
+ "strconv"
40
+ "strings"
41
+
42
+ "github.com/devrites/devrites/internal/devritespaths"
43
+ )
44
+
45
+ const dupUsage = `usage: devrites-engine check dup [slug] [--all|--worktree|--staged|--base <ref>] [--min-lines n] [--threshold f] [--ignore-file <path>] [--limit n] [--exclude <csv>] [--phase p] [--cwd <dir>]
46
+
47
+ Finds near-duplicate code regions that survive renaming: comment/string-stripped
48
+ token shingles are matched across files, chained into segment pairs, clustered,
49
+ and ranked by similarity boosted by distance. In diff modes only clusters
50
+ touching changed lines print, with changed units marked '*'.
51
+ Ignore file: one cluster hash per line, '# comment' allowed; default
52
+ .devrites/dup-ignore. Advisory: exit 0 on success, 2 on usage or scan errors; clusters are leads for review.`
53
+
54
+ const (
55
+ dupMaxFiles = 8192
56
+ dupMaxBytes = 64 << 20
57
+ dupMaxFileBytes = 1 << 20
58
+ dupShingleLines = 3
59
+ dupMaxPostings = 32
60
+ dupMaxPairAnchors = 8192
61
+ dupMergeGap = 4
62
+ dupMaxClusters = 200
63
+ dupHashLength = 12
64
+ dupCrossDirMaxHops = 8
65
+ dupCrossDirBoost = 0.15
66
+ dupSameFileMaxStep = 8
67
+ dupSameFileBoost = 0.10
68
+ dupSameFileStepLn = 250
69
+ )
70
+
71
+ // dupCommentStyle names the comment syntax used to strip noise before
72
+ // tokenizing. Languages sharing a style share one table entry.
73
+ type dupCommentStyle struct {
74
+ line []string
75
+ blocks [][2]string
76
+ }
77
+
78
+ var (
79
+ dupCStyle = dupCommentStyle{line: []string{"//"}, blocks: [][2]string{{"/*", "*/"}}}
80
+ dupHashStyle = dupCommentStyle{line: []string{"#"}, blocks: [][2]string{{"<#", "#>"}}}
81
+ dupDashStyle = dupCommentStyle{line: []string{"--"}, blocks: [][2]string{{"{-", "-}"}}}
82
+ dupSemiStyle = dupCommentStyle{line: []string{";"}}
83
+ dupPctStyle = dupCommentStyle{line: []string{"%"}}
84
+ dupXMLStyle = dupCommentStyle{blocks: [][2]string{{"<!--", "-->"}}}
85
+ dupCSSStyle = dupCommentStyle{blocks: [][2]string{{"/*", "*/"}}}
86
+ dupMixedWeb = dupCommentStyle{line: []string{"//"}, blocks: [][2]string{{"/*", "*/"}, {"<!--", "-->"}}}
87
+ dupShellCfg = dupCommentStyle{line: []string{"#", "//"}, blocks: [][2]string{{"/*", "*/"}}}
88
+ )
89
+
90
+ // dupStyleByExt maps a lowercase file extension (with dot) to its comment
91
+ // style. Extensions absent here are not scanned: prose, data, and lockfile
92
+ // formats produce shingle noise, not reviewable duplication.
93
+ var dupStyleByExt = map[string]dupCommentStyle{
94
+ ".go": dupCStyle, ".c": dupCStyle, ".h": dupCStyle,
95
+ ".cpp": dupCStyle, ".cc": dupCStyle, ".cxx": dupCStyle,
96
+ ".hpp": dupCStyle, ".hh": dupCStyle, ".m": dupCStyle, ".mm": dupCStyle,
97
+ ".java": dupCStyle, ".kt": dupCStyle, ".kts": dupCStyle,
98
+ ".scala": dupCStyle, ".groovy": dupCStyle, ".gradle": dupCStyle,
99
+ ".js": dupCStyle, ".jsx": dupCStyle, ".mjs": dupCStyle, ".cjs": dupCStyle,
100
+ ".ts": dupCStyle, ".tsx": dupCStyle, ".cts": dupCStyle, ".mts": dupCStyle,
101
+ ".rs": dupCStyle, ".swift": dupCStyle, ".cs": dupCStyle,
102
+ ".php": dupCStyle, ".phtml": dupCStyle, ".dart": dupCStyle,
103
+ ".zig": dupCStyle, ".proto": dupCStyle, ".prisma": dupCStyle,
104
+ ".gd": dupCStyle, ".nim": dupCStyle, ".vala": dupCStyle,
105
+ ".py": dupHashStyle, ".pyi": dupHashStyle, ".rb": dupHashStyle,
106
+ ".sh": dupHashStyle, ".bash": dupHashStyle, ".zsh": dupHashStyle,
107
+ ".fish": dupHashStyle, ".pl": dupHashStyle, ".pm": dupHashStyle,
108
+ ".r": dupHashStyle, ".jl": dupHashStyle, ".ex": dupHashStyle,
109
+ ".exs": dupHashStyle, ".yaml": dupHashStyle, ".yml": dupHashStyle,
110
+ ".toml": dupHashStyle, ".tf": dupShellCfg, ".hcl": dupShellCfg,
111
+ ".graphql": dupHashStyle, ".gql": dupHashStyle, ".ps1": dupHashStyle,
112
+ ".psm1": dupHashStyle, ".coffee": dupHashStyle, ".cr": dupHashStyle,
113
+ ".sql": dupDashStyle, ".lua": dupDashStyle, ".hs": dupDashStyle,
114
+ ".lhs": dupDashStyle, ".elm": dupDashStyle, ".ada": dupDashStyle,
115
+ ".adb": dupDashStyle, ".ads": dupDashStyle,
116
+ ".clj": dupSemiStyle, ".cljs": dupSemiStyle, ".lisp": dupSemiStyle,
117
+ ".scm": dupSemiStyle, ".rkt": dupSemiStyle,
118
+ ".erl": dupPctStyle, ".hrl": dupPctStyle, ".tex": dupPctStyle,
119
+ ".html": dupXMLStyle, ".htm": dupXMLStyle, ".xml": dupXMLStyle,
120
+ ".xhtml": dupXMLStyle, ".csproj": dupXMLStyle, ".fsproj": dupXMLStyle,
121
+ ".css": dupCSSStyle,
122
+ ".scss": dupCStyle, ".less": dupCStyle, ".sass": dupHashStyle,
123
+ ".vue": dupMixedWeb, ".svelte": dupMixedWeb,
124
+ }
125
+
126
+ // dupStyleByName covers extensionless code files worth scanning.
127
+ var dupStyleByName = map[string]dupCommentStyle{
128
+ "dockerfile": dupHashStyle, "containerfile": dupHashStyle,
129
+ "makefile": dupHashStyle, "gnumakefile": dupHashStyle,
130
+ "rakefile": dupHashStyle, "gemfile": dupHashStyle,
131
+ "vagrantfile": dupHashStyle, "brewfile": dupHashStyle,
132
+ "cmakelists.txt": dupHashStyle, "justfile": dupHashStyle,
133
+ "jenkinsfile": dupCStyle, "podfile": dupHashStyle,
134
+ }
135
+
136
+ // dupSkipPrefixes are vendored or fixture trees where duplication is
137
+ // deliberate or out of the author's control.
138
+ var dupSkipPrefixes = []string{
139
+ "vendor/", "node_modules/", "third_party/", "external/", "extern/",
140
+ "testdata/", ".devrites/", ".git/",
141
+ }
142
+
143
+ // dupKeywords is one union keyword set across the scanned language families.
144
+ // Keeping control/declaration words verbatim preserves the skeleton
145
+ // difference between `if` and `while`; every other word collapses to `id`,
146
+ // which is what lets renamed copies match.
147
+ var dupKeywords = map[string]bool{
148
+ "if": true, "else": true, "elif": true, "for": true, "while": true,
149
+ "do": true, "switch": true, "case": true, "default": true,
150
+ "break": true, "continue": true, "return": true, "goto": true,
151
+ "func": true, "function": true, "fn": true, "def": true,
152
+ "lambda": true, "class": true, "struct": true, "interface": true,
153
+ "impl": true, "enum": true, "trait": true, "type": true,
154
+ "package": true, "import": true, "from": true, "use": true,
155
+ "mod": true, "pub": true, "let": true, "const": true, "var": true,
156
+ "val": true, "mut": true, "ref": true, "static": true,
157
+ "try": true, "catch": true, "except": true, "finally": true,
158
+ "throw": true, "throws": true, "raise": true, "rescue": true,
159
+ "ensure": true, "async": true, "await": true, "yield": true,
160
+ "go": true, "defer": true, "select": true, "chan": true,
161
+ "public": true, "private": true, "protected": true, "final": true,
162
+ "abstract": true, "override": true, "virtual": true, "internal": true,
163
+ "sealed": true, "new": true, "delete": true, "this": true,
164
+ "self": true, "super": true, "extends": true, "implements": true,
165
+ "nil": true, "null": true, "none": true, "undefined": true,
166
+ "true": true, "false": true, "and": true, "or": true, "not": true,
167
+ "in": true, "is": true, "of": true, "as": true, "with": true,
168
+ "where": true, "when": true, "match": true, "then": true,
169
+ "begin": true, "end": true, "elsif": true, "until": true,
170
+ "unless": true, "repeat": true, "void": true, "int": true,
171
+ "long": true, "short": true, "float": true, "double": true,
172
+ "bool": true, "char": true, "string": true, "byte": true,
173
+ "rune": true, "uint": true, "export": true, "declare": true,
174
+ "namespace": true, "module": true, "fi": true, "esac": true,
175
+ "done": true, "local": true, "readonly": true, "eval": true,
176
+ "echo": true, "sizeof": true, "typeof": true, "instanceof": true,
177
+ "macro": true, "unsafe": true, "extern": true, "inline": true,
178
+ "typedef": true, "union": true, "volatile": true, "const_cast": true,
179
+ }
180
+
181
+ type dupFile struct {
182
+ path string
183
+ lines []dupLine
184
+ }
185
+
186
+ type dupLine struct {
187
+ tokens string // canonical token stream; "" when the line carried nothing
188
+ trivial bool // single punctuation/keyword line that still pads spans
189
+ }
190
+
191
+ type dupPos struct {
192
+ file int
193
+ line int // index into dupFile.lines (0-based)
194
+ }
195
+
196
+ type dupAnchor struct {
197
+ aLine int
198
+ bLine int
199
+ }
200
+
201
+ type dupPairKey struct {
202
+ a int
203
+ b int
204
+ }
205
+
206
+ type dupSegment struct {
207
+ aFile, bFile int
208
+ aStart, aEnd int // 0-based inclusive line indexes into dupFile.lines
209
+ bStart, bEnd int
210
+ anchors int
211
+ score, boosted float64
212
+ }
213
+
214
+ type dupUnit struct {
215
+ file int
216
+ start, end int // 0-based inclusive
217
+ contentHash string
218
+ changed bool
219
+ }
220
+
221
+ type dupEdge struct {
222
+ a, b int // unit indexes
223
+ boosted float64
224
+ }
225
+
226
+ type dupCluster struct {
227
+ units []int
228
+ score float64 // max boosted edge inside the cluster
229
+ hash string
230
+ changed bool
231
+ }
232
+
233
+ // normalizeDupSource strips comments and strings then canonicalizes each
234
+ // line into a token stream. The result keeps line indexes aligned with the
235
+ // source file so reported ranges stay true line numbers.
236
+ func normalizeDupSource(raw string, style dupCommentStyle) []dupLine {
237
+ srcLines := strings.Split(strings.ReplaceAll(raw, "\r\n", "\n"), "\n")
238
+ out := make([]dupLine, len(srcLines))
239
+ var blockEnd string
240
+ for i, src := range srcLines {
241
+ var b strings.Builder
242
+ for j := 0; j < len(src); {
243
+ if blockEnd != "" {
244
+ if k := strings.Index(src[j:], blockEnd); k >= 0 {
245
+ j += k + len(blockEnd)
246
+ blockEnd = ""
247
+ } else {
248
+ break
249
+ }
250
+ continue
251
+ }
252
+ matched := false
253
+ for _, marker := range style.line {
254
+ if strings.HasPrefix(src[j:], marker) {
255
+ j = len(src)
256
+ matched = true
257
+ break
258
+ }
259
+ }
260
+ if matched || j >= len(src) {
261
+ break
262
+ }
263
+ for _, pair := range style.blocks {
264
+ if strings.HasPrefix(src[j:], pair[0]) {
265
+ blockEnd = pair[1]
266
+ j += len(pair[0])
267
+ matched = true
268
+ break
269
+ }
270
+ }
271
+ if matched {
272
+ continue
273
+ }
274
+ c := src[j]
275
+ if c == '\'' || c == '"' || c == '`' {
276
+ b.WriteString(" \x01")
277
+ j++
278
+ for j < len(src) && src[j] != c {
279
+ if src[j] == '\\' && c != '`' {
280
+ j++
281
+ }
282
+ j++
283
+ }
284
+ if j < len(src) {
285
+ j++
286
+ }
287
+ continue
288
+ }
289
+ b.WriteByte(c)
290
+ j++
291
+ }
292
+ out[i] = canonicalizeDupLine(b.String())
293
+ }
294
+ return out
295
+ }
296
+
297
+ // canonicalizeDupLine reduces one comment-free line to a space-joined token
298
+ // string: keywords and punctuation verbatim, identifiers → id, numbers → 0,
299
+ // strings already → s. Fewer than two tokens is a trivial line; it still
300
+ // participates as the wildcard `_` so a copied block stays contiguous.
301
+ func canonicalizeDupLine(text string) dupLine {
302
+ var tokens []string
303
+ for i := 0; i < len(text); {
304
+ c := text[i]
305
+ switch {
306
+ case c == ' ' || c == '\t':
307
+ i++
308
+ case c == '\x01':
309
+ tokens = append(tokens, "s")
310
+ i++
311
+ case isDupIdentStart(c):
312
+ j := i + 1
313
+ for j < len(text) && isDupIdentPart(text[j]) {
314
+ j++
315
+ }
316
+ word := strings.ToLower(text[i:j])
317
+ if dupKeywords[word] {
318
+ tokens = append(tokens, word)
319
+ } else {
320
+ tokens = append(tokens, "id")
321
+ }
322
+ i = j
323
+ case c >= '0' && c <= '9':
324
+ j := i + 1
325
+ for j < len(text) && (isDupIdentPart(text[j]) || text[j] == '.') {
326
+ j++
327
+ }
328
+ tokens = append(tokens, "0")
329
+ i = j
330
+ default:
331
+ tokens = append(tokens, string(c))
332
+ i++
333
+ }
334
+ }
335
+ if len(tokens) < 2 {
336
+ return dupLine{tokens: "_", trivial: true}
337
+ }
338
+ return dupLine{tokens: strings.Join(tokens, " ")}
339
+ }
340
+
341
+ func isDupIdentStart(c byte) bool {
342
+ return c == '_' || c == '$' || c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z' || c >= 0x80
343
+ }
344
+
345
+ func isDupIdentPart(c byte) bool {
346
+ return isDupIdentStart(c) || c >= '0' && c <= '9'
347
+ }
348
+
349
+ // dupShingle is the fnv64a fingerprint of dupShingleLines consecutive
350
+ // canonical lines.
351
+ func dupShingleHash(lines []dupLine, start int) uint64 {
352
+ h := fnv.New64a()
353
+ for i := start; i < start+dupShingleLines; i++ {
354
+ _, _ = h.Write([]byte(lines[i].tokens))
355
+ _, _ = h.Write([]byte{0})
356
+ }
357
+ return h.Sum64()
358
+ }
359
+
360
+ // dupAnchorSegments chains shared-shingle hits between one file pair into
361
+ // maximal similar segments. Hits merge when both sides advance by at most
362
+ // dupMergeGap lines, so copies light edits stay one segment.
363
+ func dupAnchorSegments(key dupPairKey, anchors []dupAnchor, files []dupFile, minLines int, threshold float64) []dupSegment {
364
+ if len(anchors) == 0 {
365
+ return nil
366
+ }
367
+ sort.Slice(anchors, func(i, j int) bool {
368
+ if anchors[i].aLine != anchors[j].aLine {
369
+ return anchors[i].aLine < anchors[j].aLine
370
+ }
371
+ return anchors[i].bLine < anchors[j].bLine
372
+ })
373
+ var segs []dupSegment
374
+ start := 0
375
+ for i := 1; i <= len(anchors); i++ {
376
+ split := i == len(anchors) ||
377
+ anchors[i].aLine-anchors[i-1].aLine > dupMergeGap ||
378
+ abs(anchors[i].bLine-anchors[i-1].bLine) > dupMergeGap
379
+ if !split {
380
+ continue
381
+ }
382
+ run := anchors[start:i]
383
+ start = i
384
+ seg := dupSegment{
385
+ aFile: key.a, bFile: key.b,
386
+ aStart: run[0].aLine, aEnd: run[len(run)-1].aLine + dupShingleLines - 1,
387
+ bStart: run[0].bLine, bEnd: run[len(run)-1].bLine + dupShingleLines - 1,
388
+ anchors: len(run),
389
+ }
390
+ spanA := seg.aEnd - seg.aStart + 1
391
+ spanB := seg.bEnd - seg.bStart + 1
392
+ if spanA < minLines || spanB < minLines {
393
+ continue
394
+ }
395
+ if key.a == key.b && seg.aEnd >= seg.bStart {
396
+ continue // overlapping same-file windows are one region, not a pair
397
+ }
398
+ possible := max(spanA, spanB) - dupShingleLines + 1
399
+ seg.score = min(float64(seg.anchors)/float64(possible), 1.0)
400
+ if seg.score < threshold {
401
+ continue
402
+ }
403
+ seg.boosted = seg.score * (1 + dupDistanceBoost(files[key.a].path, files[key.b].path, seg))
404
+ segs = append(segs, seg)
405
+ }
406
+ return segs
407
+ }
408
+
409
+ // dupDistanceBoost lifts pairs that sit far apart: a twin across modules
410
+ // hides from review where a twin one screen down does not. Same-file
411
+ // distance counts in 250-line steps; cross-file distance counts directory
412
+ // hops from the deepest common ancestor. Both boosts are log-scaled caps
413
+ // ported from the embedding-detector playbook.
414
+ func dupDistanceBoost(pathA, pathB string, seg dupSegment) float64 {
415
+ if pathA == pathB {
416
+ gap := seg.bStart - seg.aEnd
417
+ if gap < 0 {
418
+ gap = 0
419
+ }
420
+ steps := min(gap/dupSameFileStepLn, dupSameFileMaxStep)
421
+ if steps <= 0 {
422
+ return 0
423
+ }
424
+ return math.Log2(1+float64(steps)) / math.Log2(1+dupSameFileMaxStep) * dupSameFileBoost
425
+ }
426
+ da := strings.Split(path.Dir(pathA), "/")
427
+ db := strings.Split(path.Dir(pathB), "/")
428
+ common := 0
429
+ for common < len(da) && common < len(db) && da[common] == db[common] {
430
+ common++
431
+ }
432
+ hops := (len(da) - common) + (len(db) - common)
433
+ if hops <= 0 {
434
+ return 0
435
+ }
436
+ hops = min(hops, dupCrossDirMaxHops)
437
+ return math.Log2(1+float64(hops)) / math.Log2(1+dupCrossDirMaxHops) * dupCrossDirBoost
438
+ }
439
+
440
+ // dupClusterUnits merges per-file ranges into units, unions segments into
441
+ // transitive clusters, and orders clusters by their strongest boosted pair.
442
+ func dupClusterUnits(segs []dupSegment, files []dupFile) ([]dupCluster, []dupUnit, []dupEdge) {
443
+ // Merge each file's overlapping/adjacent ranges into units.
444
+ perFile := map[int][]dupUnit{}
445
+ for _, s := range segs {
446
+ perFile[s.aFile] = append(perFile[s.aFile], dupUnit{file: s.aFile, start: s.aStart, end: s.aEnd})
447
+ perFile[s.bFile] = append(perFile[s.bFile], dupUnit{file: s.bFile, start: s.bStart, end: s.bEnd})
448
+ }
449
+ var units []dupUnit
450
+ for f, list := range perFile {
451
+ sort.Slice(list, func(i, j int) bool { return list[i].start < list[j].start })
452
+ var merged []dupUnit
453
+ for _, u := range list {
454
+ if n := len(merged); n > 0 && u.start <= merged[n-1].end+2 {
455
+ if u.end > merged[n-1].end {
456
+ merged[n-1].end = u.end
457
+ }
458
+ continue
459
+ }
460
+ merged = append(merged, u)
461
+ }
462
+ for _, u := range merged {
463
+ u.contentHash = dupUnitHash(files[f].lines[u.start : u.end+1])
464
+ units = append(units, u)
465
+ }
466
+ }
467
+ // Locate the unit covering a segment endpoint: same file, maximal overlap.
468
+ unitIndex := func(file, start, end int) int {
469
+ best, bestOverlap := -1, 0
470
+ for i, u := range units {
471
+ if u.file != file {
472
+ continue
473
+ }
474
+ ov := min(u.end, end) - max(u.start, start) + 1
475
+ if ov > bestOverlap {
476
+ best, bestOverlap = i, ov
477
+ }
478
+ }
479
+ return best
480
+ }
481
+ var edges []dupEdge
482
+ parent := make([]int, len(units))
483
+ for i := range parent {
484
+ parent[i] = i
485
+ }
486
+ find := func(x int) int {
487
+ for parent[x] != x {
488
+ parent[x] = parent[parent[x]]
489
+ x = parent[x]
490
+ }
491
+ return x
492
+ }
493
+ for _, s := range segs {
494
+ ua := unitIndex(s.aFile, s.aStart, s.aEnd)
495
+ ub := unitIndex(s.bFile, s.bStart, s.bEnd)
496
+ if ua < 0 || ub < 0 || ua == ub {
497
+ continue
498
+ }
499
+ edges = append(edges, dupEdge{a: ua, b: ub, boosted: s.boosted})
500
+ ra, rb := find(ua), find(ub)
501
+ if ra != rb {
502
+ parent[rb] = ra
503
+ }
504
+ }
505
+ groups := map[int][]int{}
506
+ for _, e := range edges {
507
+ r := find(e.a)
508
+ if !containsInt(groups[r], e.a) {
509
+ groups[r] = append(groups[r], e.a)
510
+ }
511
+ if !containsInt(groups[r], e.b) {
512
+ groups[r] = append(groups[r], e.b)
513
+ }
514
+ }
515
+ var clusters []dupCluster
516
+ for _, members := range groups {
517
+ sort.Ints(members)
518
+ c := dupCluster{units: members}
519
+ var sb strings.Builder
520
+ var hashes []string
521
+ for _, u := range members {
522
+ hashes = append(hashes, files[units[u].file].path+"\x00"+units[u].contentHash)
523
+ }
524
+ sort.Strings(hashes)
525
+ for _, h := range hashes {
526
+ sb.WriteString(h)
527
+ sb.WriteByte('\n')
528
+ }
529
+ sum := sha256.Sum256([]byte(sb.String()))
530
+ c.hash = hex.EncodeToString(sum[:])[:dupHashLength]
531
+ clusters = append(clusters, c)
532
+ }
533
+ for i := range clusters {
534
+ best := 0.0
535
+ member := map[int]bool{}
536
+ for _, u := range clusters[i].units {
537
+ member[u] = true
538
+ }
539
+ for _, e := range edges {
540
+ if member[e.a] && member[e.b] && e.boosted > best {
541
+ best = e.boosted
542
+ }
543
+ }
544
+ clusters[i].score = best
545
+ }
546
+ sort.Slice(clusters, func(i, j int) bool {
547
+ if clusters[i].score != clusters[j].score {
548
+ return clusters[i].score > clusters[j].score
549
+ }
550
+ return clusters[i].hash < clusters[j].hash
551
+ })
552
+ return clusters, units, edges
553
+ }
554
+
555
+ func dupUnitHash(lines []dupLine) string {
556
+ // Trivial `_` lines (lone braces, blank padding) carry no identity: a block
557
+ // that moves past padding keeps its hash so the ignore ledger holds.
558
+ var sb strings.Builder
559
+ for _, l := range lines {
560
+ if l.trivial || dupHeaderLine(l.tokens) {
561
+ continue
562
+ }
563
+ sb.WriteString(l.tokens)
564
+ sb.WriteByte('\n')
565
+ }
566
+ sum := sha256.Sum256([]byte(sb.String()))
567
+ return hex.EncodeToString(sum[:])[:16]
568
+ }
569
+
570
+ // dupHeaderLine reports whether a normalized line is a file-scope declaration
571
+ // (package/module/namespace). Header lines are file context, not copied code:
572
+ // including them would make unit hashes flip when a header enters or leaves a
573
+ // unit's matched range.
574
+ func dupHeaderLine(tokens string) bool {
575
+ fields := strings.Fields(tokens)
576
+ if len(fields) == 0 || len(fields) > 2 {
577
+ return false
578
+ }
579
+ switch fields[0] {
580
+ case "package", "module", "namespace":
581
+ return true
582
+ }
583
+ return false
584
+ }
585
+
586
+ func containsInt(xs []int, v int) bool {
587
+ for _, x := range xs {
588
+ if x == v {
589
+ return true
590
+ }
591
+ }
592
+ return false
593
+ }
594
+
595
+ // dupChangedRanges parses `git diff -U0` output into per-file added-line
596
+ // ranges on the new side. Deleted files contribute nothing.
597
+ func dupChangedRanges(diff string) map[string][][2]int {
598
+ ranges := map[string][][2]int{}
599
+ var cur string
600
+ for _, line := range strings.Split(diff, "\n") {
601
+ switch {
602
+ case strings.HasPrefix(line, "+++ "):
603
+ p := strings.TrimSpace(strings.TrimPrefix(line, "+++ "))
604
+ if strings.HasPrefix(p, `"`) {
605
+ decoded, err := strconv.Unquote(p)
606
+ if err != nil {
607
+ cur = ""
608
+ continue
609
+ }
610
+ p = decoded
611
+ }
612
+ if p == "/dev/null" {
613
+ cur = ""
614
+ continue
615
+ }
616
+ cur = strings.TrimPrefix(p, "b/")
617
+ case strings.HasPrefix(line, "@@") && cur != "":
618
+ i := strings.Index(line, "+")
619
+ if i < 0 {
620
+ continue
621
+ }
622
+ rest := line[i+1:]
623
+ end := strings.IndexAny(rest, " @")
624
+ if end < 0 {
625
+ end = len(rest)
626
+ }
627
+ spec := rest[:end] // "start,count" — the comma stays inside spec
628
+ parts := strings.SplitN(spec, ",", 2)
629
+ startN, err := strconv.Atoi(parts[0])
630
+ if err != nil {
631
+ continue
632
+ }
633
+ count := 1
634
+ if len(parts) == 2 {
635
+ if n, err := strconv.Atoi(parts[1]); err == nil {
636
+ count = n
637
+ }
638
+ }
639
+ if count == 0 {
640
+ ranges[cur] = append(ranges[cur], [2]int{startN, startN})
641
+ } else {
642
+ ranges[cur] = append(ranges[cur], [2]int{startN, startN + count - 1})
643
+ }
644
+ }
645
+ }
646
+ return ranges
647
+ }
648
+
649
+ func dupLoadIgnore(path string) map[string]bool {
650
+ ignored := map[string]bool{}
651
+ // #nosec G304 -- path is the documented --ignore-file/default ledger under the project root
652
+ data, err := os.ReadFile(path)
653
+ if err != nil {
654
+ return ignored
655
+ }
656
+ for _, line := range strings.Split(string(data), "\n") {
657
+ if i := strings.Index(line, "#"); i >= 0 {
658
+ line = line[:i]
659
+ }
660
+ if h := strings.TrimSpace(line); h != "" {
661
+ ignored[h] = true
662
+ }
663
+ }
664
+ return ignored
665
+ }
666
+
667
+ type dupOptions struct {
668
+ slug string
669
+ phase string
670
+ mode string // all | worktree | staged | base
671
+ base string
672
+ minLines int
673
+ threshold float64
674
+ ignoreFile string
675
+ limit int
676
+ exclude []string
677
+ cwd string
678
+ root string
679
+ }
680
+
681
+ func parseDupArgs(root string, args []string, stderr io.Writer) (dupOptions, int) {
682
+ opts := dupOptions{mode: "worktree", phase: "review", minLines: 8, threshold: 0.6, limit: 50, root: root}
683
+ var positional []string
684
+ seen := map[string]bool{}
685
+ modeSeen := false
686
+ for i := 0; i < len(args); i++ {
687
+ flag := args[i]
688
+ if strings.HasPrefix(flag, "--") {
689
+ if seen[flag] {
690
+ fmt.Fprintf(stderr, "dup: repeated option %s\n", flag)
691
+ return opts, 2
692
+ }
693
+ seen[flag] = true
694
+ switch flag {
695
+ case "--all", "--worktree", "--staged", "--base":
696
+ if modeSeen {
697
+ fmt.Fprintln(stderr, "dup: conflicting scan modes")
698
+ return opts, 2
699
+ }
700
+ modeSeen = true
701
+ }
702
+ switch flag {
703
+ case "--base", "--phase", "--min-lines", "--threshold", "--ignore-file", "--limit", "--exclude", "--cwd":
704
+ value := argAt(args, i+1)
705
+ if strings.TrimSpace(value) == "" || strings.HasPrefix(value, "-") {
706
+ fmt.Fprintf(stderr, "dup: %s requires a value (not a flag)\n", flag)
707
+ return opts, 2
708
+ }
709
+ }
710
+ }
711
+
712
+ switch args[i] {
713
+ case "--phase":
714
+ opts.phase = argAt(args, i+1)
715
+ i++
716
+ case "--all":
717
+ opts.mode = "all"
718
+ case "--worktree":
719
+ opts.mode = "worktree"
720
+ case "--staged":
721
+ opts.mode = "staged"
722
+ case "--base":
723
+ opts.mode = "base"
724
+ opts.base = argAt(args, i+1)
725
+ i++
726
+ case "--min-lines":
727
+ n, err := strconv.Atoi(argAt(args, i+1))
728
+ if err != nil || n < dupShingleLines {
729
+ fmt.Fprintf(stderr, "dup: --min-lines must be an integer >= %d\n", dupShingleLines)
730
+ return opts, 2
731
+ }
732
+ opts.minLines = n
733
+ i++
734
+ case "--threshold":
735
+ f, err := strconv.ParseFloat(argAt(args, i+1), 64)
736
+ if err != nil || math.IsNaN(f) || math.IsInf(f, 0) || f <= 0 || f > 1 {
737
+ fmt.Fprintln(stderr, "dup: --threshold must be in (0, 1]")
738
+ return opts, 2
739
+ }
740
+ opts.threshold = f
741
+ i++
742
+ case "--ignore-file":
743
+ opts.ignoreFile = argAt(args, i+1)
744
+ i++
745
+ case "--limit":
746
+ n, err := strconv.Atoi(argAt(args, i+1))
747
+ if err != nil || n < 1 {
748
+ fmt.Fprintln(stderr, "dup: --limit must be a positive integer")
749
+ return opts, 2
750
+ }
751
+ opts.limit = n
752
+ i++
753
+ case "--exclude":
754
+ for _, entry := range strings.Split(argAt(args, i+1), ",") {
755
+ if entry = strings.TrimSpace(entry); entry != "" {
756
+ opts.exclude = append(opts.exclude, strings.TrimSuffix(entry, "/")+"/")
757
+ }
758
+ }
759
+ i++
760
+ case "--cwd":
761
+ opts.cwd = argAt(args, i+1)
762
+ i++
763
+ default:
764
+ if strings.HasPrefix(args[i], "-") {
765
+ fmt.Fprintf(stderr, "dup: unknown flag %q\n", args[i])
766
+ return opts, 2
767
+ }
768
+ positional = append(positional, args[i])
769
+ }
770
+ }
771
+ if len(positional) > 1 || opts.mode == "base" && opts.base == "" {
772
+ fmt.Fprint(stderr, dupUsage)
773
+ return opts, 2
774
+ }
775
+ if len(positional) == 1 {
776
+ opts.slug = positional[0]
777
+ }
778
+ return opts, 0
779
+ }
780
+
781
+ // RunCheckDup scans tracked source for near-duplicate regions and prints
782
+ // ranked clusters. Advisory only: it never gates — a cluster is a lead that
783
+ // a reviewer confirms or dismisses into the ignore file.
784
+ func RunCheckDup(root string, args []string, stdout, stderr io.Writer) int {
785
+ opts, code := parseDupArgs(root, args, stderr)
786
+ if code != 0 {
787
+ return code
788
+ }
789
+ dir := opts.cwd
790
+ if dir == "" {
791
+ dir = projectDir(root)
792
+ }
793
+ repoOut, err := runGitCommand(dir, nil, "rev-parse", "--show-toplevel")
794
+ if err != nil {
795
+ fmt.Fprintf(stderr, "dup: %v\n", err)
796
+ return 2
797
+ }
798
+ repo := strings.TrimSpace(string(repoOut))
799
+ listed, err := dupGitOutput(repo, nil, gitOutputLimit, "ls-files", "-z")
800
+ if err != nil {
801
+ fmt.Fprintf(stderr, "dup: %v\n", err)
802
+ return 2
803
+ }
804
+ var paths []string
805
+ for _, p := range strings.Split(strings.TrimRight(string(listed), "\x00"), "\x00") {
806
+ if p != "" && dupScannable(p, opts.exclude) {
807
+ paths = append(paths, p)
808
+ }
809
+ }
810
+ var untracked []string
811
+
812
+ if opts.mode != "staged" {
813
+ out, uerr := dupGitOutput(repo, nil, gitOutputLimit, "ls-files", "--others", "--exclude-standard", "-z")
814
+ if uerr != nil {
815
+ fmt.Fprintf(stderr, "dup: %v\n", uerr)
816
+ return 2
817
+ }
818
+ for _, p := range strings.Split(string(out), "\x00") {
819
+ if p != "" && dupScannable(p, opts.exclude) {
820
+ untracked = append(untracked, p)
821
+ paths = append(paths, p)
822
+ }
823
+ }
824
+ }
825
+
826
+ if len(paths) > dupMaxFiles {
827
+ fmt.Fprintf(stderr, "dup: too many files (%d > %d)\n", len(paths), dupMaxFiles)
828
+ return 2
829
+ }
830
+
831
+ var files []dupFile
832
+ var skipped, failed int
833
+ if opts.mode == "staged" {
834
+ files, skipped, failed, err = dupReadIndex(repo, opts.exclude)
835
+ if err != nil {
836
+ fmt.Fprintf(stderr, "dup: incomplete scan: %v\n", err)
837
+ return 2
838
+ }
839
+ } else {
840
+ files, skipped, failed = dupReadFiles(repo, paths)
841
+ }
842
+ if failed > 0 {
843
+ fmt.Fprintf(stderr, "dup: incomplete scan: %d eligible file(s) unavailable or over resource limits; %d scanned\n", failed, len(files))
844
+ }
845
+ if len(files) == 0 {
846
+ if failed > 0 {
847
+ return 2
848
+ }
849
+ if skipped > 0 {
850
+ fmt.Fprintf(stdout, "dup: no source scanned (%d generated files excluded)\n", skipped)
851
+ } else {
852
+ fmt.Fprintln(stdout, "dup: no eligible source files")
853
+ }
854
+ return 0
855
+ }
856
+
857
+ clusters, units := dupDetect(files, opts)
858
+
859
+ // Changed-range marking and filtering.
860
+ allChanged := false
861
+ changedRanges := map[string][][2]int{}
862
+ switch opts.mode {
863
+ case "all":
864
+ // no changed marking
865
+ case "staged":
866
+ diff, derr := dupGitOutput(repo, nil, gitOutputLimit, "--no-replace-objects", "diff", "--no-ext-diff", "--no-textconv", "--no-color", "--src-prefix=a/", "--dst-prefix=b/", "--cached", "-U0", "--")
867
+ if derr != nil {
868
+ fmt.Fprintf(stderr, "dup: %v\n", derr)
869
+ return 2
870
+ }
871
+ changedRanges = dupChangedRanges(string(diff))
872
+ case "base":
873
+ diff, derr := dupGitOutput(repo, nil, gitOutputLimit, "--no-replace-objects", "diff", "--no-ext-diff", "--no-textconv", "--no-color", "--src-prefix=a/", "--dst-prefix=b/", opts.base, "-U0", "--")
874
+ if derr != nil {
875
+ fmt.Fprintf(stderr, "dup: %v\n", derr)
876
+ return 2
877
+ }
878
+ changedRanges = dupChangedRanges(string(diff))
879
+ default: // worktree
880
+ if isUnbornHEAD(repo) {
881
+ allChanged = true
882
+ } else {
883
+ diff, derr := dupGitOutput(repo, nil, gitOutputLimit, "--no-replace-objects", "diff", "--no-ext-diff", "--no-textconv", "--no-color", "--src-prefix=a/", "--dst-prefix=b/", "HEAD", "-U0", "--")
884
+ if derr != nil {
885
+ fmt.Fprintf(stderr, "dup: %v\n", derr)
886
+ return 2
887
+ }
888
+ changedRanges = dupChangedRanges(string(diff))
889
+ }
890
+ for _, p := range untracked {
891
+ changedRanges[p] = [][2]int{{1, 1 << 30}}
892
+ }
893
+ }
894
+ if allChanged {
895
+ for i := range units {
896
+ units[i].changed = true
897
+ }
898
+ } else {
899
+ for i := range units {
900
+ for _, r := range changedRanges[files[units[i].file].path] {
901
+ // unit lines are 0-based inclusive; ranges are 1-based.
902
+ if units[i].start+1 <= r[1] && r[0] <= units[i].end+1 {
903
+ units[i].changed = true
904
+ break
905
+ }
906
+ }
907
+ }
908
+ }
909
+ for i := range clusters {
910
+ for _, u := range clusters[i].units {
911
+ if units[u].changed {
912
+ clusters[i].changed = true
913
+ break
914
+ }
915
+ }
916
+ }
917
+ totalClusters := len(clusters)
918
+ if opts.mode != "all" {
919
+ var kept []dupCluster
920
+ for _, c := range clusters {
921
+ if c.changed {
922
+ kept = append(kept, c)
923
+ }
924
+ }
925
+ clusters = kept
926
+ }
927
+
928
+ ignoreFile := opts.ignoreFile
929
+ if ignoreFile == "" {
930
+ ignoreFile = filepath.Join(projectDir(root), devritespaths.DevritesRootName, "dup-ignore")
931
+ }
932
+ if !filepath.IsAbs(ignoreFile) {
933
+ ignoreFile = filepath.Join(projectDir(root), ignoreFile)
934
+ }
935
+ ignored := dupLoadIgnore(ignoreFile)
936
+ var shown []dupCluster
937
+ ignoredCount := 0
938
+ for _, c := range clusters {
939
+ if ignored[c.hash] {
940
+ ignoredCount++
941
+ continue
942
+ }
943
+ shown = append(shown, c)
944
+ }
945
+
946
+ relIgnore, rerr := filepath.Rel(projectDir(root), ignoreFile)
947
+ if rerr != nil {
948
+ relIgnore = ignoreFile
949
+ }
950
+ fmt.Fprintf(stdout, "dup: scanned %d files (%d skipped), %d units; ignore-file %s\n",
951
+ len(files), skipped, len(units), filepath.ToSlash(relIgnore))
952
+ if len(shown) == 0 {
953
+ if failed > 0 {
954
+ return 2
955
+ }
956
+ if ignoredCount > 0 {
957
+ fmt.Fprintf(stdout, "dup: ok (all %d cluster(s) ignored via %s)\n", ignoredCount, filepath.ToSlash(relIgnore))
958
+ } else if opts.mode != "all" && totalClusters > 0 {
959
+ fmt.Fprintln(stdout, "dup: ok (no clusters touch the diff)")
960
+ } else {
961
+ fmt.Fprintln(stdout, "dup: ok (no similar regions)")
962
+ }
963
+ if opts.slug != "" {
964
+ recordMetric(root, opts.slug, opts.phase, "dup", "", int64(len(clusters)))
965
+ }
966
+ return 0
967
+ }
968
+ fmt.Fprintf(stdout, "dup: %d cluster(s)", len(shown))
969
+ if ignoredCount > 0 {
970
+ fmt.Fprintf(stdout, " (%d ignored)", ignoredCount)
971
+ }
972
+ fmt.Fprintln(stdout)
973
+ if len(shown) > opts.limit {
974
+ shown = shown[:opts.limit]
975
+ fmt.Fprintf(stdout, "dup: truncated to %d clusters (--limit)\n", opts.limit)
976
+ }
977
+ for i, c := range shown {
978
+ fmt.Fprintf(stdout, "cluster %d (%s) score %.2f:\n", i+1, c.hash, c.score)
979
+ members := append([]int(nil), c.units...)
980
+ sort.Slice(members, func(a, b int) bool {
981
+ ua, ub := units[members[a]], units[members[b]]
982
+ if ua.changed != ub.changed {
983
+ return ua.changed
984
+ }
985
+ if files[ua.file].path != files[ub.file].path {
986
+ return files[ua.file].path < files[ub.file].path
987
+ }
988
+ return ua.start < ub.start
989
+ })
990
+ for _, u := range members {
991
+ unit := units[u]
992
+ marker := " "
993
+ if unit.changed {
994
+ marker = "* "
995
+ }
996
+ fmt.Fprintf(stdout, " %s%s:%d-%d\n", marker, files[unit.file].path, unit.start+1, unit.end+1)
997
+ }
998
+ }
999
+ if failed > 0 {
1000
+ return 2
1001
+ }
1002
+ if opts.slug != "" {
1003
+ recordMetric(root, opts.slug, opts.phase, "dup", "", int64(len(shown)))
1004
+ }
1005
+ return 0
1006
+ }
1007
+
1008
+ func abs(x int) int {
1009
+ if x < 0 {
1010
+ return -x
1011
+ }
1012
+ return x
1013
+ }
1014
+
1015
+ // dupDetect runs the shingle/segment/cluster pipeline over scanned files.
1016
+ func dupDetect(files []dupFile, opts dupOptions) ([]dupCluster, []dupUnit) {
1017
+ postings := map[uint64][]dupPos{}
1018
+ for fi := range files {
1019
+ lines := files[fi].lines
1020
+ for i := 0; i+dupShingleLines <= len(lines); i++ {
1021
+ allTrivial := true
1022
+ for j := i; j < i+dupShingleLines; j++ {
1023
+ if !lines[j].trivial {
1024
+ allTrivial = false
1025
+ break
1026
+ }
1027
+ }
1028
+ if allTrivial {
1029
+ continue // padding runs anchor everywhere and add no signal
1030
+ }
1031
+ h := dupShingleHash(lines, i)
1032
+ postings[h] = append(postings[h], dupPos{file: fi, line: i})
1033
+ }
1034
+ }
1035
+ anchorMap := map[dupPairKey][]dupAnchor{}
1036
+ for _, list := range postings {
1037
+ if len(list) > dupMaxPostings {
1038
+ continue // boilerplate shingle (e.g. brace runs) — no signal
1039
+ }
1040
+ for i := 0; i < len(list); i++ {
1041
+ for j := i + 1; j < len(list); j++ {
1042
+ a, b := list[i], list[j]
1043
+ if a.file > b.file || a.file == b.file && a.line > b.line {
1044
+ a, b = b, a
1045
+ }
1046
+ if a.file == b.file && b.line-a.line < dupShingleLines {
1047
+ continue // overlapping windows in one file match trivially
1048
+ }
1049
+ key := dupPairKey{a: a.file, b: b.file}
1050
+ anchors := anchorMap[key]
1051
+ if len(anchors) >= dupMaxPairAnchors {
1052
+ continue
1053
+ }
1054
+ anchorMap[key] = append(anchors, dupAnchor{aLine: a.line, bLine: b.line})
1055
+ }
1056
+ }
1057
+ }
1058
+ var segs []dupSegment
1059
+ for key, anchors := range anchorMap {
1060
+ segs = append(segs, dupAnchorSegments(key, anchors, files, opts.minLines, opts.threshold)...)
1061
+ }
1062
+ clusters, units, _ := dupClusterUnits(segs, files)
1063
+ return clusters, units
1064
+ }
1065
+
1066
+ // dupReadFiles loads and normalizes every scannable path under budgets.
1067
+ func dupReadFiles(repo string, paths []string) ([]dupFile, int, int) {
1068
+ var files []dupFile
1069
+ var skipped, failed int
1070
+ var remaining int64 = dupMaxBytes
1071
+ for _, p := range paths {
1072
+ full := filepath.Join(repo, filepath.FromSlash(p))
1073
+ info, err := os.Lstat(full)
1074
+ if err != nil || !info.Mode().IsRegular() || info.Size() > dupMaxFileBytes || info.Size() > remaining {
1075
+ failed++
1076
+ continue
1077
+ }
1078
+ // #nosec G304 -- repo-relative path from git ls-files, lstat'd regular file
1079
+ f, err := os.Open(full)
1080
+ if err != nil {
1081
+ failed++
1082
+ continue
1083
+ }
1084
+ raw, err := io.ReadAll(io.LimitReader(f, min(dupMaxFileBytes, remaining)+1))
1085
+ closeErr := f.Close()
1086
+ if err != nil || closeErr != nil || int64(len(raw)) > min(dupMaxFileBytes, remaining) {
1087
+ failed++
1088
+ continue
1089
+ }
1090
+ remaining -= int64(len(raw))
1091
+ if isDupGenerated(raw) {
1092
+ skipped++
1093
+ continue
1094
+ }
1095
+ style := dupStyleFor(p)
1096
+ files = append(files, dupFile{path: p, lines: normalizeDupSource(string(raw), style)})
1097
+ }
1098
+ return files, skipped, failed
1099
+ }
1100
+
1101
+ func isDupGenerated(raw []byte) bool {
1102
+ head := string(raw[:min(len(raw), 2048)])
1103
+ return strings.Contains(head, "Code generated") ||
1104
+ strings.Contains(head, "DO NOT EDIT") ||
1105
+ strings.Contains(head, "auto-generated") ||
1106
+ strings.Contains(head, "Automatically generated")
1107
+ }
1108
+
1109
+ // dupScannable reports whether a repo-relative slash path is in scope: a
1110
+ // known code extension or basename, outside vendored/generated trees, and
1111
+ // not excluded by --exclude prefixes.
1112
+ func dupScannable(p string, exclude []string) bool {
1113
+ for _, prefix := range dupSkipPrefixes {
1114
+ if dupPathPrefixMatch(p, prefix) {
1115
+ return false
1116
+ }
1117
+ }
1118
+ for _, prefix := range exclude {
1119
+ if dupPathPrefixMatch(p, prefix) {
1120
+ return false
1121
+ }
1122
+ }
1123
+ base := strings.ToLower(path.Base(p))
1124
+ if strings.Contains(base, ".min.") || strings.Contains(base, ".pb.") ||
1125
+ strings.Contains(base, ".gen.") || strings.HasSuffix(base, ".designer.cs") {
1126
+ return false
1127
+ }
1128
+ _, ok := dupStyleForOK(p)
1129
+ return ok
1130
+ }
1131
+
1132
+ // dupPathPrefixMatch reports whether path p sits under directory prefix —
1133
+ // gitignore-style: at the root or below any intermediate directory, so a
1134
+ // nested `services/x/vendor/` tree is skipped the same as a root `vendor/`.
1135
+ func dupPathPrefixMatch(p, prefix string) bool {
1136
+ return strings.HasPrefix(p, prefix) || strings.Contains(p, "/"+prefix)
1137
+ }
1138
+
1139
+ func dupStyleFor(p string) dupCommentStyle {
1140
+ style, _ := dupStyleForOK(p)
1141
+ return style
1142
+ }
1143
+
1144
+ func dupStyleForOK(p string) (dupCommentStyle, bool) {
1145
+ if style, ok := dupStyleByName[strings.ToLower(path.Base(p))]; ok {
1146
+ return style, true
1147
+ }
1148
+ style, ok := dupStyleByExt[strings.ToLower(path.Ext(p))]
1149
+ return style, ok
1150
+ }
1151
+
1152
+ // Git listings and blob batches must fail on truncation, not scan a prefix.
1153
+ type dupOutput struct {
1154
+ buffer bytes.Buffer
1155
+ limit int
1156
+ }
1157
+
1158
+ func (w *dupOutput) Write(p []byte) (int, error) {
1159
+ if len(p) > w.limit-w.buffer.Len() {
1160
+ return 0, fmt.Errorf("scan output exceeds resource limit")
1161
+ }
1162
+ return w.buffer.Write(p)
1163
+ }
1164
+
1165
+ func dupGitOutput(repo string, input []byte, limit int, args ...string) ([]byte, error) {
1166
+ out := dupOutput{limit: limit}
1167
+ _, err := runGitCommandIO(repo, nil, input, &out, args...)
1168
+ return out.buffer.Bytes(), err
1169
+ }
1170
+
1171
+ func dupReadIndex(repo string, exclude []string) ([]dupFile, int, int, error) {
1172
+ listing, err := dupGitOutput(repo, nil, gitOutputLimit, "ls-files", "--stage", "-z")
1173
+ if err != nil {
1174
+ return nil, 0, 0, err
1175
+ }
1176
+ var paths, oids []string
1177
+ var input strings.Builder
1178
+ for _, entry := range strings.Split(string(listing), "\x00") {
1179
+ if entry == "" {
1180
+ continue
1181
+ }
1182
+ header, p, ok := strings.Cut(entry, "\t")
1183
+ fields := strings.Fields(header)
1184
+ if !ok || len(fields) != 3 || fields[2] != "0" {
1185
+ return nil, 0, 0, fmt.Errorf("unresolved or malformed index")
1186
+ }
1187
+ if !dupScannable(p, exclude) {
1188
+ continue
1189
+ }
1190
+ if fields[0] != "100644" && fields[0] != "100755" {
1191
+ return nil, 0, 0, fmt.Errorf("non-regular indexed source %q", p)
1192
+ }
1193
+ if !isObjectID(fields[1]) || isZeroObjectID(fields[1]) {
1194
+ return nil, 0, 0, fmt.Errorf("invalid indexed blob")
1195
+ }
1196
+ paths = append(paths, p)
1197
+ oids = append(oids, fields[1])
1198
+ input.WriteString(fields[1] + "\n")
1199
+ if len(paths) > dupMaxFiles {
1200
+ return nil, 0, 0, fmt.Errorf("too many eligible files")
1201
+ }
1202
+ }
1203
+ if len(paths) == 0 {
1204
+ return nil, 0, 0, nil
1205
+ }
1206
+ data, err := dupGitOutput(repo, []byte(input.String()), dupMaxBytes+dupMaxFiles*128, "--no-replace-objects", "cat-file", "--batch")
1207
+ if err != nil {
1208
+ return nil, 0, 0, err
1209
+ }
1210
+ var files []dupFile
1211
+ skipped, failed, total := 0, 0, 0
1212
+ for i, p := range paths {
1213
+ end := bytes.IndexByte(data, '\n')
1214
+ if end < 0 {
1215
+ return nil, 0, 0, fmt.Errorf("missing blob header")
1216
+ }
1217
+ fields := strings.Fields(string(data[:end]))
1218
+ data = data[end+1:]
1219
+ if len(fields) != 3 || fields[0] != oids[i] || fields[1] != "blob" {
1220
+ return nil, 0, 0, fmt.Errorf("unavailable indexed blob")
1221
+ }
1222
+ size, err := strconv.Atoi(fields[2])
1223
+ if err != nil || size < 0 || size >= len(data) || data[size] != '\n' {
1224
+ return nil, 0, 0, fmt.Errorf("invalid blob size")
1225
+ }
1226
+ raw := data[:size]
1227
+ data = data[size+1:]
1228
+ total += size
1229
+ if size > dupMaxFileBytes || total > dupMaxBytes {
1230
+ failed++
1231
+ continue
1232
+ }
1233
+ if isDupGenerated(raw) {
1234
+ skipped++
1235
+ continue
1236
+ }
1237
+ files = append(files, dupFile{path: p, lines: normalizeDupSource(string(raw), dupStyleFor(p))})
1238
+ }
1239
+ if len(data) != 0 {
1240
+ return nil, 0, 0, fmt.Errorf("unexpected blob output")
1241
+ }
1242
+ return files, skipped, failed, nil
1243
+ }