devrites 6.0.4 → 6.1.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 (764) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +24 -9
  3. package/SECURITY.md +9 -6
  4. package/bin/devrites.mjs +28 -12
  5. package/docs/adr/0035-claude-root-leaves-plan-mode.md +33 -0
  6. package/docs/adr/0036-archive-recall-is-a-read-time-query.md +32 -0
  7. package/docs/adr/README.md +4 -2
  8. package/docs/cli.md +25 -2
  9. package/docs/command-map.md +10 -8
  10. package/docs/engine/commands.md +6 -3
  11. package/docs/harness-compliance.md +2 -2
  12. package/docs/orchestration.md +5 -4
  13. package/docs/release.md +4 -4
  14. package/docs/skills.md +2 -2
  15. package/engine/commands.go +1 -1
  16. package/engine/help.go +10 -6
  17. package/engine/internal/acceptance/cli.go +4 -1
  18. package/engine/internal/acceptance/exec.go +11 -11
  19. package/engine/internal/devritespaths/paths.go +5 -0
  20. package/engine/internal/hostpack/hostpack.go +48 -3
  21. package/engine/internal/install/apply.go +68 -1
  22. package/engine/internal/install/binary.go +4 -0
  23. package/engine/internal/install/install.go +25 -15
  24. package/engine/internal/install/merge.go +287 -123
  25. package/engine/internal/install/preflight.go +71 -1
  26. package/engine/internal/install/uninstall.go +7 -1
  27. package/engine/internal/install/update.go +7 -3
  28. package/engine/internal/lib/claims.go +30 -14
  29. package/engine/internal/lib/cli_observe.go +6 -0
  30. package/engine/internal/lib/context.go +24 -7
  31. package/engine/internal/lib/diffscope.go +79 -3
  32. package/engine/internal/lib/dispatch.go +34 -7
  33. package/engine/internal/lib/drift.go +9 -2
  34. package/engine/internal/lib/handoff.go +14 -5
  35. package/engine/internal/lib/metrics.go +29 -9
  36. package/engine/internal/lib/migrate.go +30 -12
  37. package/engine/internal/lib/next.go +22 -2
  38. package/engine/internal/lib/open_visual.go +3 -1
  39. package/engine/internal/lib/recall.go +355 -0
  40. package/engine/internal/lib/regression.go +20 -0
  41. package/engine/internal/lib/resolve.go +96 -53
  42. package/engine/internal/lib/secretscan.go +24 -1
  43. package/engine/internal/lib/taskgraph.go +31 -1
  44. package/engine/internal/lib/util.go +18 -7
  45. package/engine/internal/lib/windows.go +68 -15
  46. package/engine/internal/markdowntext/markdowntext.go +45 -6
  47. package/engine/internal/notes/cli.go +5 -3
  48. package/engine/internal/notes/notes.go +8 -3
  49. package/engine/internal/overhaul/admit/run.go +16 -12
  50. package/engine/internal/overhaul/overhaul.go +1 -0
  51. package/engine/internal/overhaul/records/check.go +52 -9
  52. package/engine/internal/overhaul/render/run.go +3 -2
  53. package/engine/internal/overhaul/snapshot/run.go +2 -2
  54. package/engine/internal/parallel/git.go +5 -6
  55. package/engine/internal/parallel/ops.go +3 -0
  56. package/engine/internal/parallel/pathdisjoint.go +9 -4
  57. package/engine/internal/release/release.go +11 -9
  58. package/engine/internal/safepath/safepath.go +17 -1
  59. package/engine/internal/state/budgets.go +8 -4
  60. package/engine/internal/state/feature.go +3 -1
  61. package/engine/internal/state/observation.go +12 -7
  62. package/engine/internal/state/taskgraph.go +67 -12
  63. package/engine/internal/state/write.go +7 -1
  64. package/engine/main.go +5 -1
  65. package/pack/.claude/agents/_shared/composition-overhaul.md +2 -0
  66. package/pack/.claude/agents/devrites-devex-reviewer.md +5 -0
  67. package/pack/.claude/agents/devrites-evidence-scout.md +4 -0
  68. package/pack/.claude/agents/devrites-plan-reviewer.md +4 -1
  69. package/pack/.claude/agents/overhaul-implementer.md +1 -0
  70. package/pack/.claude/settings.json +4 -4
  71. package/pack/.claude/skills/devrites-api-interface/SKILL.md +1 -1
  72. package/pack/.claude/skills/devrites-audit/SKILL.md +1 -1
  73. package/pack/.claude/skills/devrites-browser-proof/SKILL.md +1 -1
  74. package/pack/.claude/skills/devrites-debug-recovery/SKILL.md +3 -2
  75. package/pack/.claude/skills/devrites-doubt/SKILL.md +1 -1
  76. package/pack/.claude/skills/devrites-frontend-craft/SKILL.md +1 -1
  77. package/pack/.claude/skills/devrites-interview/SKILL.md +1 -1
  78. package/pack/.claude/skills/devrites-lib/reference/intent-map.md +3 -3
  79. package/pack/.claude/skills/devrites-lib/reference/parallel-dispatch.md +4 -3
  80. package/pack/.claude/skills/devrites-lib/reference/standards/afk-hitl.md +5 -4
  81. package/pack/.claude/skills/devrites-lib/reference/standards/ci-cd.md +2 -1
  82. package/pack/.claude/skills/devrites-lib/reference/standards/code-review.md +1 -1
  83. package/pack/.claude/skills/devrites-lib/reference/standards/data-integrity.md +4 -0
  84. package/pack/.claude/skills/devrites-lib/reference/standards/developer-experience.md +5 -0
  85. package/pack/.claude/skills/devrites-lib/reference/standards/loop-operations.md +3 -0
  86. package/pack/.claude/skills/devrites-lib/reference/standards/performance.md +2 -0
  87. package/pack/.claude/skills/devrites-lib/reference/standards/skill-authoring.md +13 -1
  88. package/pack/.claude/skills/devrites-lib/reference/standards/testing.md +13 -0
  89. package/pack/.claude/skills/devrites-lib/reference/workspace-artifact-schema.md +10 -6
  90. package/pack/.claude/skills/devrites-prose-craft/SKILL.md +1 -1
  91. package/pack/.claude/skills/devrites-source-driven/SKILL.md +1 -1
  92. package/pack/.claude/skills/devrites-ux-shape/SKILL.md +1 -1
  93. package/pack/.claude/skills/overhaul/references/orchestration.md +6 -2
  94. package/pack/.claude/skills/overhaul/references/records.md +8 -3
  95. package/pack/.claude/skills/rite/SKILL.md +4 -3
  96. package/pack/.claude/skills/rite/reference/menu.md +6 -5
  97. package/pack/.claude/skills/rite-adopt/SKILL.md +4 -3
  98. package/pack/.claude/skills/rite-autocomplete/SKILL.md +6 -5
  99. package/pack/.claude/skills/rite-autocomplete/reference/loop.md +2 -1
  100. package/pack/.claude/skills/rite-autocomplete/reference/stop-conditions.md +2 -1
  101. package/pack/.claude/skills/rite-build/reference/wright-dispatch.md +19 -0
  102. package/pack/.claude/skills/rite-converge/SKILL.md +4 -3
  103. package/pack/.claude/skills/rite-customize/SKILL.md +1 -1
  104. package/pack/.claude/skills/rite-define/SKILL.md +3 -2
  105. package/pack/.claude/skills/rite-doctor/SKILL.md +12 -6
  106. package/pack/.claude/skills/rite-dogfood/SKILL.md +2 -2
  107. package/pack/.claude/skills/rite-explain/SKILL.md +1 -1
  108. package/pack/.claude/skills/rite-fast/SKILL.md +3 -1
  109. package/pack/.claude/skills/rite-handoff/SKILL.md +4 -3
  110. package/pack/.claude/skills/rite-learn/SKILL.md +2 -2
  111. package/pack/.claude/skills/rite-plan/reference/replan-and-repair.md +2 -0
  112. package/pack/.claude/skills/rite-plan/reference/slicing.md +3 -1
  113. package/pack/.claude/skills/rite-pov/SKILL.md +1 -1
  114. package/pack/.claude/skills/rite-pr-feedback/SKILL.md +5 -4
  115. package/pack/.claude/skills/rite-pressure-test/SKILL.md +7 -5
  116. package/pack/.claude/skills/rite-prototype/SKILL.md +1 -1
  117. package/pack/.claude/skills/rite-quick/SKILL.md +10 -5
  118. package/pack/.claude/skills/rite-resolve/SKILL.md +3 -3
  119. package/pack/.claude/skills/rite-resolve/reference/answer-protocol.md +4 -5
  120. package/pack/.claude/skills/rite-review/SKILL.md +2 -1
  121. package/pack/.claude/skills/rite-seal/SKILL.md +3 -3
  122. package/pack/.claude/skills/rite-seal/reference/go-no-go.md +2 -0
  123. package/pack/.claude/skills/rite-seal/reference/seal-template.md +5 -2
  124. package/pack/.claude/skills/rite-ship/reference/close-out.md +3 -2
  125. package/pack/.claude/skills/rite-spec/SKILL.md +4 -1
  126. package/pack/.claude/skills/rite-status/SKILL.md +1 -1
  127. package/pack/.claude/skills/rite-temper/reference/significance.md +2 -0
  128. package/pack/.claude/skills/rite-upgrade/SKILL.md +4 -2
  129. package/pack/.claude/skills/rite-vet/SKILL.md +3 -2
  130. package/pack/.claude/skills/rite-vet/reference/artifacts.md +1 -1
  131. package/pack/.claude/skills/rite-watch-pr/SKILL.md +1 -1
  132. package/pack/.claude/skills/rite-zoom-out/SKILL.md +1 -1
  133. package/pack/generated/claude/agents/devrites-devex-reviewer.md +5 -0
  134. package/pack/generated/claude/agents/devrites-evidence-scout.md +4 -0
  135. package/pack/generated/claude/agents/devrites-plan-reviewer.md +4 -1
  136. package/pack/generated/claude/agents/overhaul-backend-engineer.md +2 -0
  137. package/pack/generated/claude/agents/overhaul-boundary.md +2 -0
  138. package/pack/generated/claude/agents/overhaul-craft.md +2 -0
  139. package/pack/generated/claude/agents/overhaul-frontend-engineer.md +2 -0
  140. package/pack/generated/claude/agents/overhaul-implementer.md +3 -0
  141. package/pack/generated/claude/agents/overhaul-recon.md +2 -0
  142. package/pack/generated/claude/agents/overhaul-specialist.md +2 -0
  143. package/pack/generated/claude/agents/overhaul-verifier.md +2 -0
  144. package/pack/generated/claude/settings.json +4 -4
  145. package/pack/generated/claude/skills/devrites-api-interface/SKILL.md +1 -1
  146. package/pack/generated/claude/skills/devrites-audit/SKILL.md +1 -1
  147. package/pack/generated/claude/skills/devrites-browser-proof/SKILL.md +1 -1
  148. package/pack/generated/claude/skills/devrites-debug-recovery/SKILL.md +3 -2
  149. package/pack/generated/claude/skills/devrites-doubt/SKILL.md +1 -1
  150. package/pack/generated/claude/skills/devrites-frontend-craft/SKILL.md +1 -1
  151. package/pack/generated/claude/skills/devrites-interview/SKILL.md +1 -1
  152. package/pack/generated/claude/skills/devrites-lib/reference/intent-map.md +3 -3
  153. package/pack/generated/claude/skills/devrites-lib/reference/parallel-dispatch.md +4 -3
  154. package/pack/generated/claude/skills/devrites-lib/reference/standards/afk-hitl.md +5 -4
  155. package/pack/generated/claude/skills/devrites-lib/reference/standards/ci-cd.md +2 -1
  156. package/pack/generated/claude/skills/devrites-lib/reference/standards/code-review.md +1 -1
  157. package/pack/generated/claude/skills/devrites-lib/reference/standards/data-integrity.md +4 -0
  158. package/pack/generated/claude/skills/devrites-lib/reference/standards/developer-experience.md +5 -0
  159. package/pack/generated/claude/skills/devrites-lib/reference/standards/loop-operations.md +3 -0
  160. package/pack/generated/claude/skills/devrites-lib/reference/standards/performance.md +2 -0
  161. package/pack/generated/claude/skills/devrites-lib/reference/standards/skill-authoring.md +13 -1
  162. package/pack/generated/claude/skills/devrites-lib/reference/standards/testing.md +13 -0
  163. package/pack/generated/claude/skills/devrites-lib/reference/workspace-artifact-schema.md +10 -6
  164. package/pack/generated/claude/skills/devrites-prose-craft/SKILL.md +1 -1
  165. package/pack/generated/claude/skills/devrites-source-driven/SKILL.md +1 -1
  166. package/pack/generated/claude/skills/devrites-ux-shape/SKILL.md +1 -1
  167. package/pack/generated/claude/skills/overhaul/references/orchestration.md +6 -2
  168. package/pack/generated/claude/skills/overhaul/references/records.md +8 -3
  169. package/pack/generated/claude/skills/rite/SKILL.md +4 -3
  170. package/pack/generated/claude/skills/rite/reference/menu.md +6 -5
  171. package/pack/generated/claude/skills/rite-adopt/SKILL.md +4 -3
  172. package/pack/generated/claude/skills/rite-autocomplete/SKILL.md +6 -5
  173. package/pack/generated/claude/skills/rite-autocomplete/reference/loop.md +2 -1
  174. package/pack/generated/claude/skills/rite-autocomplete/reference/stop-conditions.md +2 -1
  175. package/pack/generated/claude/skills/rite-build/reference/wright-dispatch.md +19 -0
  176. package/pack/generated/claude/skills/rite-converge/SKILL.md +4 -3
  177. package/pack/generated/claude/skills/rite-customize/SKILL.md +1 -1
  178. package/pack/generated/claude/skills/rite-define/SKILL.md +3 -2
  179. package/pack/generated/claude/skills/rite-doctor/SKILL.md +12 -6
  180. package/pack/generated/claude/skills/rite-dogfood/SKILL.md +2 -2
  181. package/pack/generated/claude/skills/rite-explain/SKILL.md +1 -1
  182. package/pack/generated/claude/skills/rite-fast/SKILL.md +3 -1
  183. package/pack/generated/claude/skills/rite-handoff/SKILL.md +4 -3
  184. package/pack/generated/claude/skills/rite-learn/SKILL.md +2 -2
  185. package/pack/generated/claude/skills/rite-plan/reference/replan-and-repair.md +2 -0
  186. package/pack/generated/claude/skills/rite-plan/reference/slicing.md +3 -1
  187. package/pack/generated/claude/skills/rite-pov/SKILL.md +1 -1
  188. package/pack/generated/claude/skills/rite-pr-feedback/SKILL.md +5 -4
  189. package/pack/generated/claude/skills/rite-pressure-test/SKILL.md +7 -5
  190. package/pack/generated/claude/skills/rite-prototype/SKILL.md +1 -1
  191. package/pack/generated/claude/skills/rite-quick/SKILL.md +10 -5
  192. package/pack/generated/claude/skills/rite-resolve/SKILL.md +3 -3
  193. package/pack/generated/claude/skills/rite-resolve/reference/answer-protocol.md +4 -5
  194. package/pack/generated/claude/skills/rite-review/SKILL.md +2 -1
  195. package/pack/generated/claude/skills/rite-seal/SKILL.md +3 -3
  196. package/pack/generated/claude/skills/rite-seal/reference/go-no-go.md +2 -0
  197. package/pack/generated/claude/skills/rite-seal/reference/seal-template.md +5 -2
  198. package/pack/generated/claude/skills/rite-ship/reference/close-out.md +3 -2
  199. package/pack/generated/claude/skills/rite-spec/SKILL.md +4 -1
  200. package/pack/generated/claude/skills/rite-status/SKILL.md +1 -1
  201. package/pack/generated/claude/skills/rite-temper/reference/significance.md +2 -0
  202. package/pack/generated/claude/skills/rite-upgrade/SKILL.md +4 -2
  203. package/pack/generated/claude/skills/rite-vet/SKILL.md +3 -2
  204. package/pack/generated/claude/skills/rite-vet/reference/artifacts.md +1 -1
  205. package/pack/generated/claude/skills/rite-watch-pr/SKILL.md +1 -1
  206. package/pack/generated/claude/skills/rite-zoom-out/SKILL.md +1 -1
  207. package/pack/generated/codex/agents/devrites-code-reviewer.toml +7 -7
  208. package/pack/generated/codex/agents/devrites-devex-reviewer.toml +6 -1
  209. package/pack/generated/codex/agents/devrites-evidence-scout.toml +4 -0
  210. package/pack/generated/codex/agents/devrites-frontend-reviewer.toml +1 -1
  211. package/pack/generated/codex/agents/devrites-plan-drafter.toml +3 -3
  212. package/pack/generated/codex/agents/devrites-plan-reviewer.toml +5 -2
  213. package/pack/generated/codex/agents/devrites-proof-runner.toml +2 -2
  214. package/pack/generated/codex/agents/devrites-security-auditor.toml +1 -1
  215. package/pack/generated/codex/agents/devrites-simplifier-reviewer.toml +1 -1
  216. package/pack/generated/codex/agents/devrites-slice-wright.toml +5 -5
  217. package/pack/generated/codex/agents/devrites-test-analyst.toml +5 -5
  218. package/pack/generated/codex/agents/devrites-upgrade-planner.toml +1 -1
  219. package/pack/generated/codex/agents/fast-builder.toml +3 -3
  220. package/pack/generated/codex/agents/fast-critic.toml +3 -3
  221. package/pack/generated/codex/agents/overhaul-backend-engineer.toml +2 -0
  222. package/pack/generated/codex/agents/overhaul-boundary.toml +2 -0
  223. package/pack/generated/codex/agents/overhaul-craft.toml +2 -0
  224. package/pack/generated/codex/agents/overhaul-frontend-engineer.toml +2 -0
  225. package/pack/generated/codex/agents/overhaul-implementer.toml +2 -0
  226. package/pack/generated/codex/agents/overhaul-recon.toml +2 -0
  227. package/pack/generated/codex/agents/overhaul-specialist.toml +2 -0
  228. package/pack/generated/codex/agents/overhaul-verifier.toml +2 -0
  229. package/pack/generated/codex/skills/devrites-api-interface/SKILL.md +1 -1
  230. package/pack/generated/codex/skills/devrites-audit/SKILL.md +1 -1
  231. package/pack/generated/codex/skills/devrites-browser-proof/SKILL.md +1 -1
  232. package/pack/generated/codex/skills/devrites-debug-recovery/SKILL.md +3 -2
  233. package/pack/generated/codex/skills/devrites-doubt/SKILL.md +1 -1
  234. package/pack/generated/codex/skills/devrites-frontend-craft/SKILL.md +1 -1
  235. package/pack/generated/codex/skills/devrites-interview/SKILL.md +1 -1
  236. package/pack/generated/codex/skills/devrites-lib/reference/intent-map.md +3 -3
  237. package/pack/generated/codex/skills/devrites-lib/reference/parallel-dispatch.md +6 -5
  238. package/pack/generated/codex/skills/devrites-lib/reference/standards/afk-hitl.md +5 -4
  239. package/pack/generated/codex/skills/devrites-lib/reference/standards/agents.md +1 -1
  240. package/pack/generated/codex/skills/devrites-lib/reference/standards/ci-cd.md +2 -1
  241. package/pack/generated/codex/skills/devrites-lib/reference/standards/code-review.md +1 -1
  242. package/pack/generated/codex/skills/devrites-lib/reference/standards/core.md +1 -1
  243. package/pack/generated/codex/skills/devrites-lib/reference/standards/data-integrity.md +4 -0
  244. package/pack/generated/codex/skills/devrites-lib/reference/standards/developer-experience.md +5 -0
  245. package/pack/generated/codex/skills/devrites-lib/reference/standards/loop-operations.md +3 -0
  246. package/pack/generated/codex/skills/devrites-lib/reference/standards/performance.md +2 -0
  247. package/pack/generated/codex/skills/devrites-lib/reference/standards/skill-authoring.md +13 -1
  248. package/pack/generated/codex/skills/devrites-lib/reference/standards/testing.md +13 -0
  249. package/pack/generated/codex/skills/devrites-lib/reference/workspace-artifact-schema.md +11 -7
  250. package/pack/generated/codex/skills/devrites-prose-craft/SKILL.md +1 -1
  251. package/pack/generated/codex/skills/devrites-source-driven/SKILL.md +1 -1
  252. package/pack/generated/codex/skills/devrites-ux-shape/SKILL.md +1 -1
  253. package/pack/generated/codex/skills/overhaul/SKILL.md +15 -15
  254. package/pack/generated/codex/skills/overhaul/references/audit-domains.md +2 -2
  255. package/pack/generated/codex/skills/overhaul/references/orchestration.md +11 -7
  256. package/pack/generated/codex/skills/overhaul/references/records.md +8 -3
  257. package/pack/generated/codex/skills/rite/SKILL.md +4 -3
  258. package/pack/generated/codex/skills/rite/reference/menu.md +6 -5
  259. package/pack/generated/codex/skills/rite-adopt/SKILL.md +4 -3
  260. package/pack/generated/codex/skills/rite-autocomplete/SKILL.md +7 -6
  261. package/pack/generated/codex/skills/rite-autocomplete/reference/loop.md +2 -1
  262. package/pack/generated/codex/skills/rite-autocomplete/reference/stop-conditions.md +2 -1
  263. package/pack/generated/codex/skills/rite-build/SKILL.md +2 -2
  264. package/pack/generated/codex/skills/rite-build/reference/parallel-batch.md +1 -1
  265. package/pack/generated/codex/skills/rite-build/reference/wright-dispatch.md +20 -1
  266. package/pack/generated/codex/skills/rite-clarify/SKILL.md +1 -1
  267. package/pack/generated/codex/skills/rite-converge/SKILL.md +5 -4
  268. package/pack/generated/codex/skills/rite-customize/SKILL.md +1 -1
  269. package/pack/generated/codex/skills/rite-define/SKILL.md +4 -3
  270. package/pack/generated/codex/skills/rite-doctor/SKILL.md +12 -6
  271. package/pack/generated/codex/skills/rite-dogfood/SKILL.md +2 -2
  272. package/pack/generated/codex/skills/rite-explain/SKILL.md +1 -1
  273. package/pack/generated/codex/skills/rite-fast/SKILL.md +8 -6
  274. package/pack/generated/codex/skills/rite-frame/SKILL.md +1 -1
  275. package/pack/generated/codex/skills/rite-handoff/SKILL.md +4 -3
  276. package/pack/generated/codex/skills/rite-learn/SKILL.md +2 -2
  277. package/pack/generated/codex/skills/rite-plan/SKILL.md +1 -1
  278. package/pack/generated/codex/skills/rite-plan/reference/replan-and-repair.md +2 -0
  279. package/pack/generated/codex/skills/rite-plan/reference/slicing.md +3 -1
  280. package/pack/generated/codex/skills/rite-polish/SKILL.md +2 -2
  281. package/pack/generated/codex/skills/rite-pov/SKILL.md +1 -1
  282. package/pack/generated/codex/skills/rite-pr-feedback/SKILL.md +5 -4
  283. package/pack/generated/codex/skills/rite-pressure-test/SKILL.md +7 -5
  284. package/pack/generated/codex/skills/rite-prototype/SKILL.md +1 -1
  285. package/pack/generated/codex/skills/rite-prove/SKILL.md +1 -1
  286. package/pack/generated/codex/skills/rite-quick/SKILL.md +11 -6
  287. package/pack/generated/codex/skills/rite-resolve/SKILL.md +3 -3
  288. package/pack/generated/codex/skills/rite-resolve/reference/answer-protocol.md +4 -5
  289. package/pack/generated/codex/skills/rite-review/SKILL.md +3 -2
  290. package/pack/generated/codex/skills/rite-seal/SKILL.md +4 -4
  291. package/pack/generated/codex/skills/rite-seal/reference/go-no-go.md +2 -0
  292. package/pack/generated/codex/skills/rite-seal/reference/seal-template.md +5 -2
  293. package/pack/generated/codex/skills/rite-ship/SKILL.md +1 -1
  294. package/pack/generated/codex/skills/rite-ship/reference/close-out.md +3 -2
  295. package/pack/generated/codex/skills/rite-spec/SKILL.md +5 -2
  296. package/pack/generated/codex/skills/rite-status/SKILL.md +1 -1
  297. package/pack/generated/codex/skills/rite-temper/SKILL.md +2 -2
  298. package/pack/generated/codex/skills/rite-temper/reference/significance.md +2 -0
  299. package/pack/generated/codex/skills/rite-upgrade/SKILL.md +4 -2
  300. package/pack/generated/codex/skills/rite-vet/SKILL.md +4 -3
  301. package/pack/generated/codex/skills/rite-vet/reference/artifacts.md +1 -1
  302. package/pack/generated/codex/skills/rite-watch-pr/SKILL.md +1 -1
  303. package/pack/generated/codex/skills/rite-zoom-out/SKILL.md +1 -1
  304. package/pack/generated/devin/AGENTS.md +1 -1
  305. package/pack/generated/devin/agents/devrites-devex-reviewer.md +5 -0
  306. package/pack/generated/devin/agents/devrites-evidence-scout.md +4 -0
  307. package/pack/generated/devin/agents/devrites-plan-reviewer.md +4 -1
  308. package/pack/generated/devin/agents/overhaul-backend-engineer.md +2 -0
  309. package/pack/generated/devin/agents/overhaul-boundary.md +2 -0
  310. package/pack/generated/devin/agents/overhaul-craft.md +2 -0
  311. package/pack/generated/devin/agents/overhaul-frontend-engineer.md +2 -0
  312. package/pack/generated/devin/agents/overhaul-implementer.md +2 -0
  313. package/pack/generated/devin/agents/overhaul-recon.md +2 -0
  314. package/pack/generated/devin/agents/overhaul-specialist.md +2 -0
  315. package/pack/generated/devin/agents/overhaul-verifier.md +2 -0
  316. package/pack/generated/devin/skills/devrites-api-interface/SKILL.md +1 -1
  317. package/pack/generated/devin/skills/devrites-audit/SKILL.md +1 -1
  318. package/pack/generated/devin/skills/devrites-browser-proof/SKILL.md +1 -1
  319. package/pack/generated/devin/skills/devrites-debug-recovery/SKILL.md +3 -2
  320. package/pack/generated/devin/skills/devrites-doubt/SKILL.md +1 -1
  321. package/pack/generated/devin/skills/devrites-frontend-craft/SKILL.md +1 -1
  322. package/pack/generated/devin/skills/devrites-interview/SKILL.md +2 -2
  323. package/pack/generated/devin/skills/devrites-lib/reference/intent-map.md +3 -3
  324. package/pack/generated/devin/skills/devrites-lib/reference/parallel-dispatch.md +6 -5
  325. package/pack/generated/devin/skills/devrites-lib/reference/standards/afk-hitl.md +8 -7
  326. package/pack/generated/devin/skills/devrites-lib/reference/standards/agents.md +1 -1
  327. package/pack/generated/devin/skills/devrites-lib/reference/standards/ci-cd.md +2 -1
  328. package/pack/generated/devin/skills/devrites-lib/reference/standards/code-review.md +1 -1
  329. package/pack/generated/devin/skills/devrites-lib/reference/standards/core.md +1 -1
  330. package/pack/generated/devin/skills/devrites-lib/reference/standards/data-integrity.md +4 -0
  331. package/pack/generated/devin/skills/devrites-lib/reference/standards/developer-experience.md +5 -0
  332. package/pack/generated/devin/skills/devrites-lib/reference/standards/loop-operations.md +3 -0
  333. package/pack/generated/devin/skills/devrites-lib/reference/standards/performance.md +2 -0
  334. package/pack/generated/devin/skills/devrites-lib/reference/standards/skill-authoring.md +13 -1
  335. package/pack/generated/devin/skills/devrites-lib/reference/standards/testing.md +13 -0
  336. package/pack/generated/devin/skills/devrites-lib/reference/workspace-artifact-schema.md +11 -7
  337. package/pack/generated/devin/skills/devrites-prose-craft/SKILL.md +1 -1
  338. package/pack/generated/devin/skills/devrites-source-driven/SKILL.md +1 -1
  339. package/pack/generated/devin/skills/devrites-ux-shape/SKILL.md +1 -1
  340. package/pack/generated/devin/skills/overhaul/SKILL.md +15 -15
  341. package/pack/generated/devin/skills/overhaul/references/audit-domains.md +2 -2
  342. package/pack/generated/devin/skills/overhaul/references/orchestration.md +11 -7
  343. package/pack/generated/devin/skills/overhaul/references/records.md +8 -3
  344. package/pack/generated/devin/skills/rite/SKILL.md +4 -3
  345. package/pack/generated/devin/skills/rite/reference/menu.md +6 -5
  346. package/pack/generated/devin/skills/rite-adopt/SKILL.md +4 -3
  347. package/pack/generated/devin/skills/rite-autocomplete/SKILL.md +8 -7
  348. package/pack/generated/devin/skills/rite-autocomplete/reference/decision-policy.md +1 -1
  349. package/pack/generated/devin/skills/rite-autocomplete/reference/loop.md +2 -1
  350. package/pack/generated/devin/skills/rite-autocomplete/reference/stop-conditions.md +3 -2
  351. package/pack/generated/devin/skills/rite-build/SKILL.md +2 -2
  352. package/pack/generated/devin/skills/rite-build/reference/checkpoint-protocol.md +2 -2
  353. package/pack/generated/devin/skills/rite-build/reference/parallel-batch.md +1 -1
  354. package/pack/generated/devin/skills/rite-build/reference/wright-dispatch.md +20 -1
  355. package/pack/generated/devin/skills/rite-clarify/SKILL.md +1 -1
  356. package/pack/generated/devin/skills/rite-converge/SKILL.md +5 -4
  357. package/pack/generated/devin/skills/rite-customize/SKILL.md +1 -1
  358. package/pack/generated/devin/skills/rite-define/SKILL.md +4 -3
  359. package/pack/generated/devin/skills/rite-doctor/SKILL.md +12 -6
  360. package/pack/generated/devin/skills/rite-dogfood/SKILL.md +2 -2
  361. package/pack/generated/devin/skills/rite-explain/SKILL.md +3 -3
  362. package/pack/generated/devin/skills/rite-explain/reference/intake.md +1 -1
  363. package/pack/generated/devin/skills/rite-fast/SKILL.md +8 -6
  364. package/pack/generated/devin/skills/rite-frame/SKILL.md +1 -1
  365. package/pack/generated/devin/skills/rite-handoff/SKILL.md +4 -3
  366. package/pack/generated/devin/skills/rite-learn/SKILL.md +2 -2
  367. package/pack/generated/devin/skills/rite-plan/SKILL.md +1 -1
  368. package/pack/generated/devin/skills/rite-plan/reference/replan-and-repair.md +2 -0
  369. package/pack/generated/devin/skills/rite-plan/reference/slicing.md +3 -1
  370. package/pack/generated/devin/skills/rite-polish/SKILL.md +2 -2
  371. package/pack/generated/devin/skills/rite-pov/SKILL.md +1 -1
  372. package/pack/generated/devin/skills/rite-pr-feedback/SKILL.md +5 -4
  373. package/pack/generated/devin/skills/rite-pressure-test/SKILL.md +7 -5
  374. package/pack/generated/devin/skills/rite-prototype/SKILL.md +1 -1
  375. package/pack/generated/devin/skills/rite-prove/SKILL.md +1 -1
  376. package/pack/generated/devin/skills/rite-quick/SKILL.md +11 -6
  377. package/pack/generated/devin/skills/rite-resolve/SKILL.md +4 -4
  378. package/pack/generated/devin/skills/rite-resolve/reference/answer-protocol.md +4 -5
  379. package/pack/generated/devin/skills/rite-review/SKILL.md +3 -2
  380. package/pack/generated/devin/skills/rite-seal/SKILL.md +4 -4
  381. package/pack/generated/devin/skills/rite-seal/reference/go-no-go.md +2 -0
  382. package/pack/generated/devin/skills/rite-seal/reference/seal-template.md +5 -2
  383. package/pack/generated/devin/skills/rite-ship/SKILL.md +1 -1
  384. package/pack/generated/devin/skills/rite-ship/reference/close-out.md +3 -2
  385. package/pack/generated/devin/skills/rite-spec/SKILL.md +5 -2
  386. package/pack/generated/devin/skills/rite-spec/reference/investigation.md +1 -1
  387. package/pack/generated/devin/skills/rite-status/SKILL.md +1 -1
  388. package/pack/generated/devin/skills/rite-temper/SKILL.md +3 -3
  389. package/pack/generated/devin/skills/rite-temper/reference/scope-modes.md +1 -1
  390. package/pack/generated/devin/skills/rite-temper/reference/significance.md +3 -1
  391. package/pack/generated/devin/skills/rite-upgrade/SKILL.md +4 -2
  392. package/pack/generated/devin/skills/rite-vet/SKILL.md +4 -3
  393. package/pack/generated/devin/skills/rite-vet/reference/artifacts.md +1 -1
  394. package/pack/generated/devin/skills/rite-vet/reference/review-axes.md +2 -2
  395. package/pack/generated/devin/skills/rite-watch-pr/SKILL.md +1 -1
  396. package/pack/generated/devin/skills/rite-zoom-out/SKILL.md +1 -1
  397. package/pack/generated/omp/agents/devrites-code-reviewer.md +7 -7
  398. package/pack/generated/omp/agents/devrites-devex-reviewer.md +6 -1
  399. package/pack/generated/omp/agents/devrites-evidence-scout.md +4 -0
  400. package/pack/generated/omp/agents/devrites-frontend-reviewer.md +1 -1
  401. package/pack/generated/omp/agents/devrites-plan-drafter.md +3 -3
  402. package/pack/generated/omp/agents/devrites-plan-reviewer.md +5 -2
  403. package/pack/generated/omp/agents/devrites-proof-runner.md +2 -2
  404. package/pack/generated/omp/agents/devrites-security-auditor.md +1 -1
  405. package/pack/generated/omp/agents/devrites-simplifier-reviewer.md +1 -1
  406. package/pack/generated/omp/agents/devrites-slice-wright.md +5 -5
  407. package/pack/generated/omp/agents/devrites-test-analyst.md +5 -5
  408. package/pack/generated/omp/agents/devrites-upgrade-planner.md +1 -1
  409. package/pack/generated/omp/agents/fast-builder.md +3 -3
  410. package/pack/generated/omp/agents/fast-critic.md +3 -3
  411. package/pack/generated/omp/agents/overhaul-backend-engineer.md +2 -0
  412. package/pack/generated/omp/agents/overhaul-boundary.md +2 -0
  413. package/pack/generated/omp/agents/overhaul-craft.md +2 -0
  414. package/pack/generated/omp/agents/overhaul-frontend-engineer.md +2 -0
  415. package/pack/generated/omp/agents/overhaul-implementer.md +2 -0
  416. package/pack/generated/omp/agents/overhaul-recon.md +2 -0
  417. package/pack/generated/omp/agents/overhaul-specialist.md +2 -0
  418. package/pack/generated/omp/agents/overhaul-verifier.md +2 -0
  419. package/pack/generated/omp/commands/rite-resolve.md +1 -1
  420. package/pack/generated/omp/skills/devrites-api-interface/SKILL.md +4 -4
  421. package/pack/generated/omp/skills/devrites-audit/SKILL.md +5 -5
  422. package/pack/generated/omp/skills/devrites-browser-proof/SKILL.md +5 -5
  423. package/pack/generated/omp/skills/devrites-browser-proof/reference/browser-performance.md +1 -1
  424. package/pack/generated/omp/skills/devrites-browser-proof/reference/visual-verdict.md +1 -1
  425. package/pack/generated/omp/skills/devrites-debug-recovery/SKILL.md +7 -6
  426. package/pack/generated/omp/skills/devrites-debug-recovery/reference/cleanup-and-classify.md +1 -1
  427. package/pack/generated/omp/skills/devrites-doubt/SKILL.md +6 -6
  428. package/pack/generated/omp/skills/devrites-frontend-craft/SKILL.md +3 -3
  429. package/pack/generated/omp/skills/devrites-frontend-craft/reference/craft.md +1 -1
  430. package/pack/generated/omp/skills/devrites-frontend-craft/reference/design-references.md +4 -4
  431. package/pack/generated/omp/skills/devrites-frontend-craft/reference/fullstack.md +1 -1
  432. package/pack/generated/omp/skills/devrites-frontend-craft/reference/quality-standards.md +8 -8
  433. package/pack/generated/omp/skills/devrites-frontend-craft/reference/reuse-first.md +2 -2
  434. package/pack/generated/omp/skills/devrites-frontend-craft/reference/shape.md +2 -2
  435. package/pack/generated/omp/skills/devrites-interview/SKILL.md +3 -3
  436. package/pack/generated/omp/skills/devrites-lib/reference/intent-map.md +4 -4
  437. package/pack/generated/omp/skills/devrites-lib/reference/parallel-dispatch.md +8 -7
  438. package/pack/generated/omp/skills/devrites-lib/reference/standards/afk-hitl.md +13 -12
  439. package/pack/generated/omp/skills/devrites-lib/reference/standards/agents.md +6 -6
  440. package/pack/generated/omp/skills/devrites-lib/reference/standards/browser-proof-checklist.md +2 -2
  441. package/pack/generated/omp/skills/devrites-lib/reference/standards/ci-cd.md +2 -1
  442. package/pack/generated/omp/skills/devrites-lib/reference/standards/code-review.md +3 -3
  443. package/pack/generated/omp/skills/devrites-lib/reference/standards/coding-style.md +1 -1
  444. package/pack/generated/omp/skills/devrites-lib/reference/standards/context-hygiene.md +2 -2
  445. package/pack/generated/omp/skills/devrites-lib/reference/standards/core.md +3 -3
  446. package/pack/generated/omp/skills/devrites-lib/reference/standards/data-integrity.md +4 -0
  447. package/pack/generated/omp/skills/devrites-lib/reference/standards/debug-recovery.md +1 -1
  448. package/pack/generated/omp/skills/devrites-lib/reference/standards/definition-of-done.md +1 -1
  449. package/pack/generated/omp/skills/devrites-lib/reference/standards/developer-experience.md +8 -3
  450. package/pack/generated/omp/skills/devrites-lib/reference/standards/glossary.md +3 -3
  451. package/pack/generated/omp/skills/devrites-lib/reference/standards/loop-operations.md +3 -0
  452. package/pack/generated/omp/skills/devrites-lib/reference/standards/performance.md +3 -1
  453. package/pack/generated/omp/skills/devrites-lib/reference/standards/prose-style.md +4 -4
  454. package/pack/generated/omp/skills/devrites-lib/reference/standards/release/ship-checklist.md +1 -1
  455. package/pack/generated/omp/skills/devrites-lib/reference/standards/review/README.md +1 -1
  456. package/pack/generated/omp/skills/devrites-lib/reference/standards/review/ci-workflows.md +1 -1
  457. package/pack/generated/omp/skills/devrites-lib/reference/standards/review/react.md +1 -1
  458. package/pack/generated/omp/skills/devrites-lib/reference/standards/review/stack-profile.md +5 -5
  459. package/pack/generated/omp/skills/devrites-lib/reference/standards/skill-authoring.md +15 -3
  460. package/pack/generated/omp/skills/devrites-lib/reference/standards/spec-grammar.md +3 -3
  461. package/pack/generated/omp/skills/devrites-lib/reference/standards/testing.md +14 -1
  462. package/pack/generated/omp/skills/devrites-lib/reference/standards/tooling.md +1 -1
  463. package/pack/generated/omp/skills/devrites-lib/reference/standards/verification-methods.md +1 -1
  464. package/pack/generated/omp/skills/devrites-lib/reference/visual-playbooks/index.md +2 -2
  465. package/pack/generated/omp/skills/devrites-lib/reference/workspace-artifact-schema.md +12 -8
  466. package/pack/generated/omp/skills/devrites-prose-craft/SKILL.md +4 -4
  467. package/pack/generated/omp/skills/devrites-prose-craft/reference/examples.md +1 -1
  468. package/pack/generated/omp/skills/devrites-source-driven/SKILL.md +3 -3
  469. package/pack/generated/omp/skills/devrites-ux-shape/SKILL.md +10 -10
  470. package/pack/generated/omp/skills/devrites-ux-shape/reference/brief-template.md +3 -3
  471. package/pack/generated/omp/skills/devrites-ux-shape/reference/visual-direction-probe.md +1 -1
  472. package/pack/generated/omp/skills/overhaul/references/orchestration.md +6 -2
  473. package/pack/generated/omp/skills/overhaul/references/records.md +8 -3
  474. package/pack/generated/omp/skills/rite/SKILL.md +8 -7
  475. package/pack/generated/omp/skills/rite/reference/menu.md +6 -5
  476. package/pack/generated/omp/skills/rite-adopt/SKILL.md +6 -5
  477. package/pack/generated/omp/skills/rite-adopt/reference/anti-patterns.md +1 -1
  478. package/pack/generated/omp/skills/rite-autocomplete/SKILL.md +11 -10
  479. package/pack/generated/omp/skills/rite-autocomplete/reference/decision-policy.md +1 -1
  480. package/pack/generated/omp/skills/rite-autocomplete/reference/loop.md +4 -3
  481. package/pack/generated/omp/skills/rite-autocomplete/reference/stop-conditions.md +2 -1
  482. package/pack/generated/omp/skills/rite-build/SKILL.md +7 -7
  483. package/pack/generated/omp/skills/rite-build/reference/afk-discipline.md +1 -1
  484. package/pack/generated/omp/skills/rite-build/reference/anti-patterns.md +1 -1
  485. package/pack/generated/omp/skills/rite-build/reference/checkpoint-protocol.md +2 -2
  486. package/pack/generated/omp/skills/rite-build/reference/checkpoint.md +2 -2
  487. package/pack/generated/omp/skills/rite-build/reference/frontend-trigger.md +1 -1
  488. package/pack/generated/omp/skills/rite-build/reference/parallel-batch.md +4 -4
  489. package/pack/generated/omp/skills/rite-build/reference/phase-contract.md +6 -6
  490. package/pack/generated/omp/skills/rite-build/reference/tdd.md +1 -1
  491. package/pack/generated/omp/skills/rite-build/reference/wright-dispatch.md +27 -8
  492. package/pack/generated/omp/skills/rite-clarify/SKILL.md +4 -4
  493. package/pack/generated/omp/skills/rite-clarify/reference/anti-patterns.md +1 -1
  494. package/pack/generated/omp/skills/rite-converge/SKILL.md +16 -15
  495. package/pack/generated/omp/skills/rite-converge/reference/convergence-assessment.md +4 -4
  496. package/pack/generated/omp/skills/rite-customize/SKILL.md +2 -2
  497. package/pack/generated/omp/skills/rite-define/SKILL.md +25 -24
  498. package/pack/generated/omp/skills/rite-define/reference/anti-patterns.md +2 -2
  499. package/pack/generated/omp/skills/rite-define/reference/gates.md +2 -2
  500. package/pack/generated/omp/skills/rite-doctor/SKILL.md +12 -6
  501. package/pack/generated/omp/skills/rite-dogfood/SKILL.md +5 -5
  502. package/pack/generated/omp/skills/rite-explain/SKILL.md +7 -7
  503. package/pack/generated/omp/skills/rite-explain/reference/intake.md +1 -1
  504. package/pack/generated/omp/skills/rite-fast/SKILL.md +12 -10
  505. package/pack/generated/omp/skills/rite-fast/reference/artifacts.md +1 -1
  506. package/pack/generated/omp/skills/rite-frame/SKILL.md +6 -6
  507. package/pack/generated/omp/skills/rite-frame/reference/failure-modes.md +4 -4
  508. package/pack/generated/omp/skills/rite-handoff/SKILL.md +7 -6
  509. package/pack/generated/omp/skills/rite-learn/SKILL.md +6 -6
  510. package/pack/generated/omp/skills/rite-plan/SKILL.md +8 -8
  511. package/pack/generated/omp/skills/rite-plan/reference/anti-patterns.md +1 -1
  512. package/pack/generated/omp/skills/rite-plan/reference/replan-and-repair.md +3 -1
  513. package/pack/generated/omp/skills/rite-plan/reference/slicing.md +6 -4
  514. package/pack/generated/omp/skills/rite-plan/reference/task-breakdown.md +1 -1
  515. package/pack/generated/omp/skills/rite-polish/SKILL.md +6 -6
  516. package/pack/generated/omp/skills/rite-polish/reference/anti-ai-slop.md +9 -9
  517. package/pack/generated/omp/skills/rite-polish/reference/anti-patterns.md +1 -1
  518. package/pack/generated/omp/skills/rite-polish/reference/backend-polish.md +2 -2
  519. package/pack/generated/omp/skills/rite-polish/reference/browser-polish-evidence.md +1 -1
  520. package/pack/generated/omp/skills/rite-polish/reference/code.md +8 -8
  521. package/pack/generated/omp/skills/rite-polish/reference/design-memory.md +3 -3
  522. package/pack/generated/omp/skills/rite-polish/reference/design-system-discovery.md +1 -1
  523. package/pack/generated/omp/skills/rite-polish/reference/harden-checklist.md +1 -1
  524. package/pack/generated/omp/skills/rite-polish/reference/ledger.md +3 -3
  525. package/pack/generated/omp/skills/rite-polish/reference/ui.md +1 -1
  526. package/pack/generated/omp/skills/rite-pov/SKILL.md +2 -2
  527. package/pack/generated/omp/skills/rite-pr-feedback/SKILL.md +6 -5
  528. package/pack/generated/omp/skills/rite-pressure-test/SKILL.md +9 -7
  529. package/pack/generated/omp/skills/rite-prototype/SKILL.md +1 -1
  530. package/pack/generated/omp/skills/rite-prove/SKILL.md +13 -13
  531. package/pack/generated/omp/skills/rite-prove/reference/acceptance-proof.md +7 -7
  532. package/pack/generated/omp/skills/rite-prove/reference/anti-patterns.md +1 -1
  533. package/pack/generated/omp/skills/rite-prove/reference/browser-proof.md +3 -3
  534. package/pack/generated/omp/skills/rite-prove/reference/failure-triage.md +2 -2
  535. package/pack/generated/omp/skills/rite-quick/SKILL.md +19 -14
  536. package/pack/generated/omp/skills/rite-resolve/SKILL.md +6 -6
  537. package/pack/generated/omp/skills/rite-resolve/reference/answer-protocol.md +4 -5
  538. package/pack/generated/omp/skills/rite-review/SKILL.md +23 -22
  539. package/pack/generated/omp/skills/rite-review/reference/anti-patterns.md +1 -1
  540. package/pack/generated/omp/skills/rite-review/reference/cognitive-load.md +2 -2
  541. package/pack/generated/omp/skills/rite-review/reference/nielsen-heuristics.md +1 -1
  542. package/pack/generated/omp/skills/rite-review/reference/performance-checklist.md +1 -1
  543. package/pack/generated/omp/skills/rite-review/reference/performance-review.md +1 -1
  544. package/pack/generated/omp/skills/rite-review/reference/security-review.md +2 -2
  545. package/pack/generated/omp/skills/rite-seal/SKILL.md +11 -11
  546. package/pack/generated/omp/skills/rite-seal/reference/anti-patterns.md +1 -1
  547. package/pack/generated/omp/skills/rite-seal/reference/final-evidence.md +3 -3
  548. package/pack/generated/omp/skills/rite-seal/reference/go-no-go.md +3 -1
  549. package/pack/generated/omp/skills/rite-seal/reference/output.md +1 -1
  550. package/pack/generated/omp/skills/rite-seal/reference/phase-contract.md +4 -4
  551. package/pack/generated/omp/skills/rite-seal/reference/seal-template.md +5 -2
  552. package/pack/generated/omp/skills/rite-ship/SKILL.md +7 -7
  553. package/pack/generated/omp/skills/rite-ship/reference/anti-patterns.md +1 -1
  554. package/pack/generated/omp/skills/rite-ship/reference/close-out.md +5 -4
  555. package/pack/generated/omp/skills/rite-ship/reference/git-ship.md +2 -2
  556. package/pack/generated/omp/skills/rite-ship/reference/rollout.md +3 -3
  557. package/pack/generated/omp/skills/rite-spec/SKILL.md +17 -14
  558. package/pack/generated/omp/skills/rite-spec/reference/anti-patterns.md +1 -1
  559. package/pack/generated/omp/skills/rite-spec/reference/investigation.md +3 -3
  560. package/pack/generated/omp/skills/rite-spec/reference/question-protocol.md +1 -1
  561. package/pack/generated/omp/skills/rite-spec/reference/spec-template.md +2 -2
  562. package/pack/generated/omp/skills/rite-spec/reference/state-workspace.md +8 -8
  563. package/pack/generated/omp/skills/rite-status/SKILL.md +2 -2
  564. package/pack/generated/omp/skills/rite-temper/SKILL.md +13 -13
  565. package/pack/generated/omp/skills/rite-temper/reference/anti-patterns.md +2 -2
  566. package/pack/generated/omp/skills/rite-temper/reference/review-dimensions.md +3 -3
  567. package/pack/generated/omp/skills/rite-temper/reference/scope-modes.md +3 -3
  568. package/pack/generated/omp/skills/rite-temper/reference/significance.md +4 -2
  569. package/pack/generated/omp/skills/rite-upgrade/SKILL.md +7 -5
  570. package/pack/generated/omp/skills/rite-vet/SKILL.md +14 -13
  571. package/pack/generated/omp/skills/rite-vet/reference/anti-patterns.md +2 -2
  572. package/pack/generated/omp/skills/rite-vet/reference/artifacts.md +3 -3
  573. package/pack/generated/omp/skills/rite-vet/reference/depth.md +3 -3
  574. package/pack/generated/omp/skills/rite-vet/reference/review-axes.md +5 -5
  575. package/pack/generated/omp/skills/rite-watch-pr/SKILL.md +2 -2
  576. package/pack/generated/omp/skills/rite-zoom-out/SKILL.md +1 -1
  577. package/pack/generated/pi/agents/devrites-devex-reviewer.md +5 -0
  578. package/pack/generated/pi/agents/devrites-evidence-scout.md +4 -0
  579. package/pack/generated/pi/agents/devrites-plan-reviewer.md +4 -1
  580. package/pack/generated/pi/agents/overhaul-backend-engineer.md +2 -0
  581. package/pack/generated/pi/agents/overhaul-boundary.md +2 -0
  582. package/pack/generated/pi/agents/overhaul-craft.md +2 -0
  583. package/pack/generated/pi/agents/overhaul-frontend-engineer.md +2 -0
  584. package/pack/generated/pi/agents/overhaul-implementer.md +2 -0
  585. package/pack/generated/pi/agents/overhaul-recon.md +2 -0
  586. package/pack/generated/pi/agents/overhaul-specialist.md +2 -0
  587. package/pack/generated/pi/agents/overhaul-verifier.md +2 -0
  588. package/pack/generated/pi/prompts/rite-resolve.md +1 -1
  589. package/pack/generated/pi/skills/devrites-api-interface/SKILL.md +1 -1
  590. package/pack/generated/pi/skills/devrites-audit/SKILL.md +1 -1
  591. package/pack/generated/pi/skills/devrites-browser-proof/SKILL.md +1 -1
  592. package/pack/generated/pi/skills/devrites-debug-recovery/SKILL.md +3 -2
  593. package/pack/generated/pi/skills/devrites-doubt/SKILL.md +1 -1
  594. package/pack/generated/pi/skills/devrites-frontend-craft/SKILL.md +1 -1
  595. package/pack/generated/pi/skills/devrites-interview/SKILL.md +1 -1
  596. package/pack/generated/pi/skills/devrites-lib/reference/intent-map.md +3 -3
  597. package/pack/generated/pi/skills/devrites-lib/reference/parallel-dispatch.md +6 -5
  598. package/pack/generated/pi/skills/devrites-lib/reference/standards/afk-hitl.md +5 -4
  599. package/pack/generated/pi/skills/devrites-lib/reference/standards/agents.md +1 -1
  600. package/pack/generated/pi/skills/devrites-lib/reference/standards/ci-cd.md +2 -1
  601. package/pack/generated/pi/skills/devrites-lib/reference/standards/code-review.md +1 -1
  602. package/pack/generated/pi/skills/devrites-lib/reference/standards/core.md +1 -1
  603. package/pack/generated/pi/skills/devrites-lib/reference/standards/data-integrity.md +4 -0
  604. package/pack/generated/pi/skills/devrites-lib/reference/standards/developer-experience.md +5 -0
  605. package/pack/generated/pi/skills/devrites-lib/reference/standards/loop-operations.md +3 -0
  606. package/pack/generated/pi/skills/devrites-lib/reference/standards/performance.md +2 -0
  607. package/pack/generated/pi/skills/devrites-lib/reference/standards/skill-authoring.md +13 -1
  608. package/pack/generated/pi/skills/devrites-lib/reference/standards/testing.md +13 -0
  609. package/pack/generated/pi/skills/devrites-lib/reference/workspace-artifact-schema.md +11 -7
  610. package/pack/generated/pi/skills/devrites-prose-craft/SKILL.md +1 -1
  611. package/pack/generated/pi/skills/devrites-source-driven/SKILL.md +1 -1
  612. package/pack/generated/pi/skills/devrites-ux-shape/SKILL.md +1 -1
  613. package/pack/generated/pi/skills/overhaul/SKILL.md +15 -15
  614. package/pack/generated/pi/skills/overhaul/references/audit-domains.md +2 -2
  615. package/pack/generated/pi/skills/overhaul/references/orchestration.md +11 -7
  616. package/pack/generated/pi/skills/overhaul/references/records.md +8 -3
  617. package/pack/generated/pi/skills/rite/SKILL.md +4 -3
  618. package/pack/generated/pi/skills/rite/reference/menu.md +6 -5
  619. package/pack/generated/pi/skills/rite-adopt/SKILL.md +4 -3
  620. package/pack/generated/pi/skills/rite-autocomplete/SKILL.md +7 -6
  621. package/pack/generated/pi/skills/rite-autocomplete/reference/loop.md +2 -1
  622. package/pack/generated/pi/skills/rite-autocomplete/reference/stop-conditions.md +2 -1
  623. package/pack/generated/pi/skills/rite-build/SKILL.md +2 -2
  624. package/pack/generated/pi/skills/rite-build/reference/parallel-batch.md +1 -1
  625. package/pack/generated/pi/skills/rite-build/reference/wright-dispatch.md +20 -1
  626. package/pack/generated/pi/skills/rite-clarify/SKILL.md +1 -1
  627. package/pack/generated/pi/skills/rite-converge/SKILL.md +5 -4
  628. package/pack/generated/pi/skills/rite-customize/SKILL.md +1 -1
  629. package/pack/generated/pi/skills/rite-define/SKILL.md +4 -3
  630. package/pack/generated/pi/skills/rite-doctor/SKILL.md +12 -6
  631. package/pack/generated/pi/skills/rite-dogfood/SKILL.md +2 -2
  632. package/pack/generated/pi/skills/rite-explain/SKILL.md +1 -1
  633. package/pack/generated/pi/skills/rite-fast/SKILL.md +8 -6
  634. package/pack/generated/pi/skills/rite-frame/SKILL.md +1 -1
  635. package/pack/generated/pi/skills/rite-handoff/SKILL.md +4 -3
  636. package/pack/generated/pi/skills/rite-learn/SKILL.md +2 -2
  637. package/pack/generated/pi/skills/rite-plan/SKILL.md +1 -1
  638. package/pack/generated/pi/skills/rite-plan/reference/replan-and-repair.md +2 -0
  639. package/pack/generated/pi/skills/rite-plan/reference/slicing.md +3 -1
  640. package/pack/generated/pi/skills/rite-polish/SKILL.md +2 -2
  641. package/pack/generated/pi/skills/rite-pov/SKILL.md +1 -1
  642. package/pack/generated/pi/skills/rite-pr-feedback/SKILL.md +5 -4
  643. package/pack/generated/pi/skills/rite-pressure-test/SKILL.md +7 -5
  644. package/pack/generated/pi/skills/rite-prototype/SKILL.md +1 -1
  645. package/pack/generated/pi/skills/rite-prove/SKILL.md +1 -1
  646. package/pack/generated/pi/skills/rite-quick/SKILL.md +11 -6
  647. package/pack/generated/pi/skills/rite-resolve/SKILL.md +3 -3
  648. package/pack/generated/pi/skills/rite-resolve/reference/answer-protocol.md +4 -5
  649. package/pack/generated/pi/skills/rite-review/SKILL.md +3 -2
  650. package/pack/generated/pi/skills/rite-seal/SKILL.md +4 -4
  651. package/pack/generated/pi/skills/rite-seal/reference/go-no-go.md +2 -0
  652. package/pack/generated/pi/skills/rite-seal/reference/seal-template.md +5 -2
  653. package/pack/generated/pi/skills/rite-ship/SKILL.md +1 -1
  654. package/pack/generated/pi/skills/rite-ship/reference/close-out.md +3 -2
  655. package/pack/generated/pi/skills/rite-spec/SKILL.md +5 -2
  656. package/pack/generated/pi/skills/rite-status/SKILL.md +1 -1
  657. package/pack/generated/pi/skills/rite-temper/SKILL.md +2 -2
  658. package/pack/generated/pi/skills/rite-temper/reference/significance.md +2 -0
  659. package/pack/generated/pi/skills/rite-upgrade/SKILL.md +4 -2
  660. package/pack/generated/pi/skills/rite-vet/SKILL.md +4 -3
  661. package/pack/generated/pi/skills/rite-vet/reference/artifacts.md +1 -1
  662. package/pack/generated/pi/skills/rite-watch-pr/SKILL.md +1 -1
  663. package/pack/generated/pi/skills/rite-zoom-out/SKILL.md +1 -1
  664. package/package.json +3 -2
  665. package/scripts/build-host-artifacts.sh +13 -0
  666. package/scripts/codex-generate.sh +5 -1
  667. package/scripts/devin-generate.sh +4 -3
  668. package/scripts/install-lib.sh +5 -0
  669. package/scripts/omp-generate.sh +23 -1
  670. package/scripts/pi-generate.sh +2 -2
  671. package/engine/cmd/releasepack/main_test.go +0 -239
  672. package/engine/harnessmatrix_test.go +0 -46
  673. package/engine/help_test.go +0 -241
  674. package/engine/internal/acceptance/acceptance_test.go +0 -946
  675. package/engine/internal/devritespaths/paths_test.go +0 -128
  676. package/engine/internal/fsutil/copy_test.go +0 -154
  677. package/engine/internal/gate/gate_test.go +0 -865
  678. package/engine/internal/gate/readiness_binding_test.go +0 -443
  679. package/engine/internal/gitenv/env_test.go +0 -48
  680. package/engine/internal/hostpack/hostpack_test.go +0 -269
  681. package/engine/internal/install/install_test.go +0 -1741
  682. package/engine/internal/install/workspace_advisory_test.go +0 -54
  683. package/engine/internal/lib/candidate_test.go +0 -506
  684. package/engine/internal/lib/claims_test.go +0 -267
  685. package/engine/internal/lib/closeout_test.go +0 -266
  686. package/engine/internal/lib/context_next_test.go +0 -912
  687. package/engine/internal/lib/cursor_compat_test.go +0 -65
  688. package/engine/internal/lib/detect_test.go +0 -118
  689. package/engine/internal/lib/drift_test.go +0 -135
  690. package/engine/internal/lib/dup_test.go +0 -666
  691. package/engine/internal/lib/environment_report_test.go +0 -54
  692. package/engine/internal/lib/evidencefresh_test.go +0 -120
  693. package/engine/internal/lib/handoff_test.go +0 -83
  694. package/engine/internal/lib/manifest_union_test.go +0 -251
  695. package/engine/internal/lib/metrics_test.go +0 -28
  696. package/engine/internal/lib/migrate_test.go +0 -213
  697. package/engine/internal/lib/observe_budgets_test.go +0 -428
  698. package/engine/internal/lib/open_visual_test.go +0 -291
  699. package/engine/internal/lib/regression_test.go +0 -282
  700. package/engine/internal/lib/resolve_remediation_test.go +0 -192
  701. package/engine/internal/lib/secretscan_test.go +0 -556
  702. package/engine/internal/lib/slicecheck_test.go +0 -170
  703. package/engine/internal/lib/taskgraph_test.go +0 -353
  704. package/engine/internal/lib/triggers_test.go +0 -23
  705. package/engine/internal/lib/util_test.go +0 -148
  706. package/engine/internal/lib/visual_outline_test.go +0 -189
  707. package/engine/internal/lib/windows_test.go +0 -420
  708. package/engine/internal/lib/workspace_read_test.go +0 -102
  709. package/engine/internal/markdowntext/markdowntext_fuzz_test.go +0 -36
  710. package/engine/internal/markdowntext/markdowntext_test.go +0 -58
  711. package/engine/internal/markdowntext/testdata/structural.json +0 -277
  712. package/engine/internal/notes/notes_test.go +0 -545
  713. package/engine/internal/overhaul/admit/admit_test.go +0 -204
  714. package/engine/internal/overhaul/admit/packet_test.go +0 -223
  715. package/engine/internal/overhaul/bench/run_test.go +0 -316
  716. package/engine/internal/overhaul/ovio/ovio_test.go +0 -75
  717. package/engine/internal/overhaul/packet/packet_test.go +0 -263
  718. package/engine/internal/overhaul/records/init_test.go +0 -96
  719. package/engine/internal/overhaul/records/records_test.go +0 -696
  720. package/engine/internal/overhaul/records/run_test.go +0 -77
  721. package/engine/internal/overhaul/render/run_test.go +0 -928
  722. package/engine/internal/overhaul/score/run_test.go +0 -636
  723. package/engine/internal/overhaul/snapshot/run_test.go +0 -718
  724. package/engine/internal/parallel/cli_test.go +0 -91
  725. package/engine/internal/parallel/ops_test.go +0 -939
  726. package/engine/internal/parallel/parallel_test.go +0 -645
  727. package/engine/internal/parallel/pathdisjoint_fuzz_test.go +0 -43
  728. package/engine/internal/parallel/pathdisjoint_test.go +0 -193
  729. package/engine/internal/parallel/select_test.go +0 -95
  730. package/engine/internal/parallel/testdata/fuzz/FuzzPathDisjoint/a449b81b4711b7b4 +0 -3
  731. package/engine/internal/reason/reason_test.go +0 -37
  732. package/engine/internal/release/release_test.go +0 -181
  733. package/engine/internal/rootfacts/facts_test.go +0 -364
  734. package/engine/internal/safepath/safepath_fuzz_test.go +0 -21
  735. package/engine/internal/safepath/safepath_test.go +0 -69
  736. package/engine/internal/safepath/safepath_windows_test.go +0 -26
  737. package/engine/internal/state/acceptance_test.go +0 -57
  738. package/engine/internal/state/budgets_test.go +0 -135
  739. package/engine/internal/state/cmd/workflowmanifest/main_test.go +0 -96
  740. package/engine/internal/state/concurrency_test.go +0 -184
  741. package/engine/internal/state/cursor_fuzz_test.go +0 -80
  742. package/engine/internal/state/cursor_test.go +0 -276
  743. package/engine/internal/state/observation_test.go +0 -961
  744. package/engine/internal/state/observation_unix_test.go +0 -68
  745. package/engine/internal/state/state_test.go +0 -986
  746. package/engine/internal/state/taskgraph_fuzz_test.go +0 -38
  747. package/engine/internal/state/taskgraph_test.go +0 -43
  748. package/engine/internal/state/testdata/fuzz/FuzzCursorRoundTrip/114b28f68c1fa4db +0 -4
  749. package/engine/internal/state/testdata/fuzz/FuzzCursorRoundTrip/378a0f2218e812ea +0 -4
  750. package/engine/internal/state/testdata/fuzz/FuzzCursorRoundTrip/39eaa26fcb481e3c +0 -4
  751. package/engine/internal/state/testdata/fuzz/FuzzCursorRoundTrip/776ca1dc0143acf0 +0 -4
  752. package/engine/internal/state/testdata/fuzz/FuzzCursorRoundTrip/9295930c1ebb81df +0 -4
  753. package/engine/internal/state/testdata/fuzz/FuzzCursorRoundTrip/a60de309dc33be0d +0 -4
  754. package/engine/internal/state/testdata/fuzz/FuzzCursorRoundTrip/f04dc7b06ef7c99f +0 -4
  755. package/engine/internal/state/testdata/fuzz/FuzzCursorRoundTrip/f3000ac510878bd6 +0 -4
  756. package/engine/internal/state/testdata/fuzz/FuzzWorkspaceSchemaRow/a75aabb9f2a847d5 +0 -2
  757. package/engine/internal/state/workspaceschema_fuzz_test.go +0 -27
  758. package/engine/internal/state/workspaceschema_test.go +0 -101
  759. package/engine/internal/state/write_test.go +0 -136
  760. package/engine/internal/version/version_test.go +0 -29
  761. package/engine/internal/workflow/commands_test.go +0 -18
  762. package/engine/note_routing_test.go +0 -95
  763. package/engine/observation_contract_test.go +0 -175
  764. package/engine/root_routing_test.go +0 -340
@@ -1,939 +0,0 @@
1
- package parallel
2
-
3
- import (
4
- "errors"
5
- "fmt"
6
- "os"
7
- "path/filepath"
8
- "runtime"
9
- "strings"
10
- "sync"
11
- "testing"
12
- )
13
-
14
- // commitIn makes a one-file green commit inside a worker worktree and returns
15
- // its transfer commit SHA.
16
- func commitIn(t *testing.T, wt, file, marker string) string {
17
- t.Helper()
18
- body := "package main\n\nfunc " + marker + "() {}\n"
19
- if err := os.WriteFile(filepath.Join(wt, file), []byte(body), 0o644); err != nil {
20
- t.Fatal(err)
21
- }
22
- gitOk(t, wt, "add", file)
23
- gitOk(t, wt, "commit", "-m", "WIP(demo-feature): add "+marker+" helper")
24
- return gitOk(t, wt, "rev-parse", "HEAD")
25
- }
26
-
27
- // greenBatch creates a running lease with two recorded-green slices.
28
- func greenBatch(t *testing.T, repo, base, slug, batch string) *Lease {
29
- t.Helper()
30
- lease, err := Create(CreateOpts{
31
- Root: repo,
32
- Slug: slug,
33
- BatchID: batch,
34
- BaseSHA: base,
35
- Slices: []SlicePaths{
36
- {ID: "slice-a", Paths: []string{"src/a.go"}},
37
- {ID: "slice-b", Paths: []string{"src/b.go"}},
38
- },
39
- })
40
- if err != nil {
41
- t.Fatal(err)
42
- }
43
- tcA := commitIn(t, lease.Slices[0].WorktreePath, "src/a.go", "A")
44
- tcB := commitIn(t, lease.Slices[1].WorktreePath, "src/b.go", "B")
45
- if _, err := RecordGreen(repo, slug, "slice-a", tcA); err != nil {
46
- t.Fatal(err)
47
- }
48
- if _, err := RecordGreen(repo, slug, "slice-b", tcB); err != nil {
49
- t.Fatal(err)
50
- }
51
- return lease
52
- }
53
-
54
- type seamRestore struct {
55
- origLease func(string, *Lease) error
56
- origRemove func(string, string) error
57
- origSalvage func(LeaseSlice, string) (string, error)
58
- origWarn func(string, ...any)
59
- }
60
-
61
- func swapSeams(t *testing.T) {
62
- t.Helper()
63
- s := seamRestore{origLease: writeLease, origRemove: removeWorktree, origSalvage: salvage, origWarn: warnf}
64
- t.Cleanup(func() {
65
- writeLease, removeWorktree, salvage, warnf = s.origLease, s.origRemove, s.origSalvage, s.origWarn
66
- })
67
- }
68
-
69
- // TestIntegrateFailedTransitionSurvivesTransientWriteFailure proves the
70
- // integrate-failed lease transition is retried once when the first write
71
- // fails, so the on-disk lease honestly records integrate-failed instead of a
72
- // stale running status.
73
- func TestIntegrateFailedTransitionSurvivesTransientWriteFailure(t *testing.T) {
74
- repo, base := setupRepo(t)
75
- slug, batch := "demo-feature", "batch1"
76
- greenBatch(t, repo, base, slug, batch)
77
- leasePath, err := LeasePath(repo, slug)
78
- if err != nil {
79
- t.Fatal(err)
80
- }
81
-
82
- // Corrupt a transfer commit so Integrate fails mid-flight via fail().
83
- corrupted, err := ReadLease(leasePath)
84
- if err != nil {
85
- t.Fatal(err)
86
- }
87
- corrupted.Slices[0].TransferCommit = strings.Repeat("deadbeef", 5)
88
- if err := WriteLease(leasePath, corrupted); err != nil {
89
- t.Fatal(err)
90
- }
91
-
92
- swapSeams(t)
93
- calls := 0
94
- writeLease = func(path string, l *Lease) error {
95
- calls++
96
- if calls == 1 {
97
- return errors.New("transient lease write failure")
98
- }
99
- // delegates to the real WriteLease captured by swapSeams
100
- return origWriteLease()(path, l)
101
- }
102
-
103
- _, got, err := Integrate(IntegrateOpts{Root: repo, Slug: slug, ApplyToControl: true})
104
- if err == nil {
105
- t.Fatal("expected integrate failure from corrupted transfer commit")
106
- }
107
- if calls != 2 {
108
- t.Fatalf("lease write calls=%d want 2 (initial + one retry)", calls)
109
- }
110
- if got == nil || got.Status != StatusIntegrateFailed {
111
- t.Fatalf("returned lease status=%v want integrate-failed", got)
112
- }
113
- onDisk, err := ReadLease(leasePath)
114
- if err != nil {
115
- t.Fatal(err)
116
- }
117
- if onDisk.Status != StatusIntegrateFailed {
118
- t.Fatalf("on-disk lease status=%s want integrate-failed", onDisk.Status)
119
- }
120
- if head := gitOk(t, repo, "rev-parse", "HEAD"); head != base {
121
- t.Fatalf("control head %s want base %s", head, base)
122
- }
123
- }
124
-
125
- // origWriteLease returns the real WriteLease bypassing any test override.
126
- func origWriteLease() func(string, *Lease) error {
127
- return WriteLease
128
- }
129
-
130
- // TestIntegrateSurfacesStuckStagingWorktree proves a staging-worktree removal
131
- // failure on the integrate success path is propagated (fail closed, status
132
- // integrate-failed, control untouched) instead of silently compounding into
133
- // un-cleanable branch state.
134
- func TestIntegrateSurfacesStuckStagingWorktree(t *testing.T) {
135
- repo, base := setupRepo(t)
136
- slug, batch := "demo-feature", "batch1"
137
- greenBatch(t, repo, base, slug, batch)
138
- leasePath, err := LeasePath(repo, slug)
139
- if err != nil {
140
- t.Fatal(err)
141
- }
142
-
143
- swapSeams(t)
144
- removeWorktree = func(string, string) error {
145
- return errors.New("simulated locked staging worktree")
146
- }
147
-
148
- _, got, err := Integrate(IntegrateOpts{Root: repo, Slug: slug, ApplyToControl: true})
149
- if err == nil {
150
- t.Fatal("expected integrate to surface the stuck staging worktree")
151
- }
152
- if !strings.Contains(err.Error(), "staging worktree") {
153
- t.Fatalf("error should name the staging worktree, got %v", err)
154
- }
155
- if got == nil || got.Status != StatusIntegrateFailed {
156
- t.Fatalf("returned lease status=%v want integrate-failed", got)
157
- }
158
- onDisk, err := ReadLease(leasePath)
159
- if err != nil {
160
- t.Fatal(err)
161
- }
162
- if onDisk.Status != StatusIntegrateFailed {
163
- t.Fatalf("on-disk lease status=%s want integrate-failed", onDisk.Status)
164
- }
165
- if head := gitOk(t, repo, "rev-parse", "HEAD"); head != base {
166
- t.Fatalf("control head %s want base %s (merge must not apply when staging cleanup fails)", head, base)
167
- }
168
- }
169
-
170
- // TestCleanupNeverTouchesForeignWorktreePath proves a lease whose
171
- // worktree_path is not the exact directory Create wrote is never salvaged
172
- // into nor deleted — the lease field is advisory, not a RemoveAll license.
173
- // Two spellings of "not ours" are covered: a path outside the batch scratch
174
- // layout, and the deterministic scratch path itself reached through a symlink.
175
- func TestCleanupNeverTouchesForeignWorktreePath(t *testing.T) {
176
- slug, batch := "demo-feature", "batch1"
177
- slices := []SlicePaths{
178
- {ID: "slice-a", Paths: []string{"src/a.go"}},
179
- {ID: "slice-b", Paths: []string{"src/b.go"}},
180
- }
181
-
182
- t.Run("worktree_path outside the scratch root", func(t *testing.T) {
183
- repo, base := setupRepo(t)
184
- lease, err := Create(CreateOpts{
185
- Root: repo,
186
- Slug: slug,
187
- BatchID: batch,
188
- BaseSHA: base,
189
- Slices: slices,
190
- })
191
- if err != nil {
192
- t.Fatal(err)
193
- }
194
- foreign := filepath.Join(t.TempDir(), "precious")
195
- if err := os.MkdirAll(foreign, 0o755); err != nil {
196
- t.Fatal(err)
197
- }
198
- if err := os.WriteFile(filepath.Join(foreign, "keep.txt"), []byte("x"), 0o644); err != nil {
199
- t.Fatal(err)
200
- }
201
- lease.Slices[0].WorktreePath = foreign
202
- // A forged branch outside the batch namespace must survive too.
203
- gitOk(t, repo, "branch", "user/topic", base)
204
- lease.Slices[0].Branch = "user/topic"
205
- leasePath, err := LeasePath(repo, slug)
206
- if err != nil {
207
- t.Fatal(err)
208
- }
209
- if err := WriteLease(leasePath, lease); err != nil {
210
- t.Fatal(err)
211
- }
212
-
213
- var warnings []string
214
- swapSeams(t)
215
- warnf = func(format string, args ...any) {
216
- warnings = append(warnings, fmt.Sprintf(format, args...))
217
- }
218
- if _, err := Cleanup(repo, slug, true); err != nil {
219
- t.Fatal(err)
220
- }
221
- if _, err := os.Stat(filepath.Join(foreign, "keep.txt")); err != nil {
222
- t.Fatalf("foreign path was touched: %v", err)
223
- }
224
- if tip := gitOk(t, repo, "rev-parse", "user/topic"); tip != base {
225
- t.Fatalf("foreign branch user/topic moved to %s, want %s", tip, base)
226
- }
227
- joined := strings.Join(warnings, "\n")
228
- if !strings.Contains(joined, "outside") {
229
- t.Fatalf("expected warnings naming foreign path and branch, got:\n%s", warnings)
230
- }
231
- })
232
-
233
- // A stale lease still names exactly the path Create wrote; here the batch
234
- // directory was replaced by a symlink, so the directory a forced cleanup
235
- // would delete lives outside the scratch root. filepath.Abs matches both sides
236
- // of the ownership check because neither side resolves symlinks.
237
- t.Run("scratch worktree_path reached through a symlink", func(t *testing.T) {
238
- repo, base := setupRepo(t)
239
- if _, err := Create(CreateOpts{
240
- Root: repo,
241
- Slug: slug,
242
- BatchID: batch,
243
- BaseSHA: base,
244
- Slices: slices,
245
- }); err != nil {
246
- t.Fatal(err)
247
- }
248
-
249
- // An unrelated repository outside the workspace, carrying a committed file
250
- // and a dirty one on the allowlisted path: a salvage would commit inside it
251
- // and a RemoveAll would delete the tree.
252
- outside := t.TempDir()
253
- sliceA := filepath.Join(outside, "slice-a")
254
- if err := os.MkdirAll(filepath.Join(sliceA, "src"), 0o755); err != nil {
255
- t.Fatal(err)
256
- }
257
- gitOk(t, sliceA, "init")
258
- gitOk(t, sliceA, "checkout", "-b", "main")
259
- if err := os.WriteFile(filepath.Join(sliceA, "src", "a.go"), []byte("package main\n"), 0o644); err != nil {
260
- t.Fatal(err)
261
- }
262
- gitOk(t, sliceA, "add", ".")
263
- gitOk(t, sliceA, "commit", "-m", "unrelated base")
264
- unrelatedTip := gitOk(t, sliceA, "rev-parse", "HEAD")
265
- if err := os.WriteFile(filepath.Join(sliceA, "src", "a.go"), []byte("package main\n\nfunc Unrelated() {}\n"), 0o644); err != nil {
266
- t.Fatal(err)
267
- }
268
-
269
- batchDir := filepath.Join(ScratchRoot(repo), batch)
270
- if err := os.RemoveAll(batchDir); err != nil {
271
- t.Fatal(err)
272
- }
273
- if err := os.Symlink(outside, batchDir); err != nil {
274
- t.Fatal(err)
275
- }
276
-
277
- // The lease on disk is what Create wrote; only the filesystem moved.
278
- // Assert the path cleanup will use really does resolve through the symlink,
279
- // so this case cannot pass without traversing it.
280
- leasePath, err := LeasePath(repo, slug)
281
- if err != nil {
282
- t.Fatal(err)
283
- }
284
- lease, err := ReadLease(leasePath)
285
- if err != nil {
286
- t.Fatal(err)
287
- }
288
- claimed := lease.Slices[0].WorktreePath
289
- if want := WorkerWorktreePath(repo, batch, "slice-a"); claimed != want {
290
- t.Fatalf("lease worktree_path %q, want the deterministic %q", claimed, want)
291
- }
292
- resolved, err := filepath.EvalSymlinks(claimed)
293
- if err != nil {
294
- t.Fatalf("claimed worktree_path does not resolve: %v", err)
295
- }
296
- realSliceA, err := filepath.EvalSymlinks(sliceA)
297
- if err != nil {
298
- t.Fatal(err)
299
- }
300
- if resolved != realSliceA {
301
- t.Fatalf("%q resolved to %q, want the symlink target %q", claimed, resolved, realSliceA)
302
- }
303
-
304
- var warnings []string
305
- swapSeams(t)
306
- warnf = func(format string, args ...any) {
307
- warnings = append(warnings, fmt.Sprintf(format, args...))
308
- }
309
- if _, err := Cleanup(repo, slug, true); err != nil {
310
- t.Fatal(err)
311
- }
312
-
313
- if _, err := os.Stat(filepath.Join(sliceA, "src", "a.go")); err != nil {
314
- t.Fatalf("worktree reached through a symlinked batch directory was deleted: %v", err)
315
- }
316
- if tip := gitOk(t, sliceA, "rev-parse", "HEAD"); tip != unrelatedTip {
317
- t.Fatalf("salvage committed inside an unrelated repository: tip %s want %s", tip, unrelatedTip)
318
- }
319
- if joined := strings.Join(warnings, "\n"); !strings.Contains(joined, "worktree_path") {
320
- t.Fatalf("expected a warning naming the refused worktree_path, got:\n%s", warnings)
321
- }
322
- })
323
-
324
- // A symlink that stays inside the scratch root still redirects the delete
325
- // onto a directory the lease does not name.
326
- t.Run("scratch worktree_path reached through a symlink inside the scratch root", func(t *testing.T) {
327
- repo, base := setupRepo(t)
328
- if _, err := Create(CreateOpts{
329
- Root: repo,
330
- Slug: slug,
331
- BatchID: batch,
332
- BaseSHA: base,
333
- Slices: slices,
334
- }); err != nil {
335
- t.Fatal(err)
336
- }
337
- sibling := filepath.Join(ScratchRoot(repo), "sibling-batch")
338
- keep := filepath.Join(sibling, "slice-a", "keep.txt")
339
- if err := os.MkdirAll(filepath.Dir(keep), 0o755); err != nil {
340
- t.Fatal(err)
341
- }
342
- if err := os.WriteFile(keep, []byte("x"), 0o644); err != nil {
343
- t.Fatal(err)
344
- }
345
- batchDir := filepath.Join(ScratchRoot(repo), batch)
346
- if err := os.RemoveAll(batchDir); err != nil {
347
- t.Fatal(err)
348
- }
349
- if err := os.Symlink(sibling, batchDir); err != nil {
350
- t.Fatal(err)
351
- }
352
-
353
- swapSeams(t)
354
- warnf = func(string, ...any) {}
355
- if _, err := Cleanup(repo, slug, true); err != nil {
356
- t.Fatal(err)
357
- }
358
- if _, err := os.Stat(keep); err != nil {
359
- t.Fatalf("directory under an in-scratch symlink was deleted: %v", err)
360
- }
361
- })
362
-
363
- // Ownership is decided by what git registered when Create ran, not by the
364
- // lease. A lease naming a deterministic in-scratch path that Create never
365
- // made (and a stray sibling no lease names) must survive a forced cleanup,
366
- // while the real worktrees are still removed.
367
- t.Run("in-scratch path Create never made", func(t *testing.T) {
368
- repo, base := setupRepo(t)
369
- lease, err := Create(CreateOpts{
370
- Root: repo,
371
- Slug: slug,
372
- BatchID: batch,
373
- BaseSHA: base,
374
- Slices: slices,
375
- })
376
- if err != nil {
377
- t.Fatal(err)
378
- }
379
- forged := WorkerWorktreePath(repo, batch, "slice-x")
380
- stray := filepath.Join(ScratchRoot(repo), batch, "stray")
381
- for _, d := range []string{forged, stray} {
382
- if err := os.MkdirAll(d, 0o755); err != nil {
383
- t.Fatal(err)
384
- }
385
- if err := os.WriteFile(filepath.Join(d, "keep.txt"), []byte("x"), 0o644); err != nil {
386
- t.Fatal(err)
387
- }
388
- }
389
- lease.Slices = append(lease.Slices, LeaseSlice{
390
- ID: "slice-x",
391
- Paths: []string{"src/x.go"},
392
- WorktreePath: forged,
393
- WrightStatus: WrightPending,
394
- })
395
- lease.N = len(lease.Slices)
396
- leasePath, err := LeasePath(repo, slug)
397
- if err != nil {
398
- t.Fatal(err)
399
- }
400
- if err := WriteLease(leasePath, lease); err != nil {
401
- t.Fatal(err)
402
- }
403
-
404
- var warnings []string
405
- swapSeams(t)
406
- warnf = func(format string, args ...any) {
407
- warnings = append(warnings, fmt.Sprintf(format, args...))
408
- }
409
- if _, err := Cleanup(repo, slug, true); err != nil {
410
- t.Fatal(err)
411
- }
412
- for _, d := range []string{forged, stray} {
413
- if _, err := os.Stat(filepath.Join(d, "keep.txt")); err != nil {
414
- t.Fatalf("unregistered scratch directory %s was deleted: %v", d, err)
415
- }
416
- }
417
- for _, id := range []string{"slice-a", "slice-b"} {
418
- if _, err := os.Stat(WorkerWorktreePath(repo, batch, id)); !os.IsNotExist(err) {
419
- t.Fatalf("registered worktree %s was not removed: %v", id, err)
420
- }
421
- }
422
- if joined := strings.Join(warnings, "\n"); !strings.Contains(joined, "not a worktree") {
423
- t.Fatalf("expected a warning naming the refused path, got:\n%s", warnings)
424
- }
425
- })
426
- }
427
-
428
- // TestCleanupFailedSalvageKeepsWorktreeDir proves a salvage error keeps the
429
- // worktree on disk as the only remaining copy — the batch-level scratch
430
- // removal must skip kept slice dirs instead of destroying them.
431
- func TestCleanupFailedSalvageKeepsWorktreeDir(t *testing.T) {
432
- repo, base := setupRepo(t)
433
- slug, batch := "demo-feature", "batch1"
434
- if _, err := Create(CreateOpts{
435
- Root: repo,
436
- Slug: slug,
437
- BatchID: batch,
438
- BaseSHA: base,
439
- Slices: []SlicePaths{
440
- {ID: "slice-a", Paths: []string{"src/a.go"}},
441
- {ID: "slice-b", Paths: []string{"src/b.go"}},
442
- },
443
- }); err != nil {
444
- t.Fatal(err)
445
- }
446
- wtA := WorkerWorktreePath(repo, batch, "slice-a")
447
- wtB := WorkerWorktreePath(repo, batch, "slice-b")
448
-
449
- swapSeams(t)
450
- realSalvage := salvage
451
- salvage = func(sl LeaseSlice, batchID string) (string, error) {
452
- if sl.ID == "slice-a" {
453
- return "", errors.New("injected salvage failure")
454
- }
455
- return realSalvage(sl, batchID)
456
- }
457
- salvaged, err := Cleanup(repo, slug, true)
458
- if err != nil {
459
- t.Fatal(err)
460
- }
461
- if _, err := os.Stat(wtA); err != nil {
462
- t.Fatalf("kept worktree was removed: %v", err)
463
- }
464
- if _, err := os.Stat(wtB); !os.IsNotExist(err) {
465
- t.Fatalf("clean slice-b worktree should be removed, stat err=%v", err)
466
- }
467
- if _, err := git(repo, "rev-parse", "--verify", "devrites/parallel/"+slug+"/"+batch+"/slice-a"); err != nil {
468
- t.Fatalf("slice-a branch should be kept: %v", err)
469
- }
470
- found := false
471
- for _, s := range salvaged {
472
- if s.SliceID == "slice-a" && s.Worktree == wtA {
473
- found = true
474
- }
475
- }
476
- if !found {
477
- t.Fatalf("salvage output should report kept worktree for slice-a, got %+v", salvaged)
478
- }
479
- }
480
-
481
- // TestCleanupNamesDirectoryGitDroppedButNotDeleted proves that when git has
482
- // already dropped a worktree and its directory cannot be deleted, the error
483
- // names the directory and says a rerun will not delete it, and the rerun does
484
- // leave it on disk.
485
- func TestCleanupNamesDirectoryGitDroppedButNotDeleted(t *testing.T) {
486
- if os.Geteuid() == 0 || runtime.GOOS == "windows" {
487
- t.Skip("directory permissions do not bind root or windows")
488
- }
489
- repo, base := setupRepo(t)
490
- slug, batch := "demo-feature", "batch1"
491
- if _, err := Create(CreateOpts{
492
- Root: repo,
493
- Slug: slug,
494
- BatchID: batch,
495
- BaseSHA: base,
496
- Slices: []SlicePaths{
497
- {ID: "slice-a", Paths: []string{"src/a.go"}},
498
- {ID: "slice-b", Paths: []string{"src/b.go"}},
499
- },
500
- }); err != nil {
501
- t.Fatal(err)
502
- }
503
- wt := WorkerWorktreePath(repo, batch, "slice-a")
504
- batchDir := filepath.Dir(wt)
505
-
506
- swapSeams(t)
507
- warnf = func(string, ...any) {}
508
- removeWorktree = func(repo, path string) error {
509
- // Like real git: drop the registration, fail to delete the
510
- // directory, and exit non-zero.
511
- if err := os.RemoveAll(filepath.Join(repo, ".git", "worktrees", filepath.Base(path))); err != nil {
512
- return err
513
- }
514
- if err := os.Chmod(batchDir, 0o500); err != nil {
515
- return err
516
- }
517
- return errors.New("failed to delete '" + path + "': Permission denied")
518
- }
519
- t.Cleanup(func() { _ = os.Chmod(batchDir, 0o700) })
520
-
521
- _, err := Cleanup(repo, slug, true)
522
- if err == nil || !strings.Contains(err.Error(), wt) || !strings.Contains(err.Error(), "remove it by hand") {
523
- t.Fatalf("error must name %s and say it needs manual removal, got %v", wt, err)
524
- }
525
- if err := os.Chmod(batchDir, 0o700); err != nil {
526
- t.Fatal(err)
527
- }
528
- if _, err := Cleanup(repo, slug, true); err != nil {
529
- t.Fatalf("rerun: %v", err)
530
- }
531
- if _, err := os.Stat(wt); err != nil {
532
- t.Fatalf("rerun must leave the unregistered directory in place, stat err=%v", err)
533
- }
534
- }
535
-
536
- // TestCleanupFailedListNamesEachEntryOnce proves a slice whose directory
537
- // removal fails in both the per-slice and the scratch-entry pass is named once,
538
- // in lease order.
539
- func TestCleanupFailedListNamesEachEntryOnce(t *testing.T) {
540
- if os.Geteuid() == 0 || runtime.GOOS == "windows" {
541
- t.Skip("directory permissions do not bind root or windows")
542
- }
543
- repo, base := setupRepo(t)
544
- slug, batch := "demo-feature", "batch1"
545
- if _, err := Create(CreateOpts{
546
- Root: repo,
547
- Slug: slug,
548
- BatchID: batch,
549
- BaseSHA: base,
550
- Slices: []SlicePaths{
551
- {ID: "slice-a", Paths: []string{"src/a.go"}},
552
- {ID: "slice-b", Paths: []string{"src/b.go"}},
553
- },
554
- }); err != nil {
555
- t.Fatal(err)
556
- }
557
- batchDir := filepath.Dir(WorkerWorktreePath(repo, batch, "slice-a"))
558
-
559
- swapSeams(t)
560
- warnf = func(string, ...any) {}
561
- removeWorktree = func(string, string) error {
562
- if err := os.Chmod(batchDir, 0o500); err != nil {
563
- return err
564
- }
565
- return errors.New("simulated stuck worker worktree")
566
- }
567
- t.Cleanup(func() { _ = os.Chmod(batchDir, 0o700) })
568
-
569
- _, err := Cleanup(repo, slug, true)
570
- const want = "cleanup incomplete for slice-a, slice-b; "
571
- if err == nil || !strings.HasPrefix(err.Error(), want) {
572
- t.Fatalf("failed list must name slice-a and slice-b once each, want prefix %q, got %v", want, err)
573
- }
574
- }
575
-
576
- // TestCleanupKeepsRerunGuidanceWhileStillRegistered proves a failed directory
577
- // delete that leaves git's registration intact is retryable: the error asks for
578
- // a rerun and does not tell the operator to remove the directory by hand.
579
- func TestCleanupKeepsRerunGuidanceWhileStillRegistered(t *testing.T) {
580
- if os.Geteuid() == 0 || runtime.GOOS == "windows" {
581
- t.Skip("directory permissions do not bind root or windows")
582
- }
583
- repo, base := setupRepo(t)
584
- slug, batch := "demo-feature", "batch1"
585
- if _, err := Create(CreateOpts{
586
- Root: repo,
587
- Slug: slug,
588
- BatchID: batch,
589
- BaseSHA: base,
590
- Slices: []SlicePaths{
591
- {ID: "slice-a", Paths: []string{"src/a.go"}},
592
- {ID: "slice-b", Paths: []string{"src/b.go"}},
593
- },
594
- }); err != nil {
595
- t.Fatal(err)
596
- }
597
- wt := WorkerWorktreePath(repo, batch, "slice-a")
598
- batchDir := filepath.Dir(wt)
599
-
600
- swapSeams(t)
601
- warnf = func(string, ...any) {}
602
- removeWorktree = func(repo, path string) error {
603
- if err := os.Chmod(batchDir, 0o500); err != nil {
604
- return err
605
- }
606
- return errors.New("failed to delete '" + path + "': Permission denied")
607
- }
608
- t.Cleanup(func() { _ = os.Chmod(batchDir, 0o700) })
609
-
610
- _, err := Cleanup(repo, slug, true)
611
- if err == nil || !strings.Contains(err.Error(), "rerun cleanup") {
612
- t.Fatalf("error must ask for a rerun, got %v", err)
613
- }
614
- if strings.Contains(err.Error(), "remove it by hand") {
615
- t.Fatalf("a still-registered worktree is retryable, got %v", err)
616
- }
617
- leasePath, lerr := LeasePath(repo, slug)
618
- if lerr != nil {
619
- t.Fatal(lerr)
620
- }
621
- if _, rerr := ReadLease(leasePath); rerr != nil {
622
- t.Fatalf("lease must be kept for the rerun: %v", rerr)
623
- }
624
- }
625
-
626
- // TestCleanupDoesNotClaimUnregisteredWhenListUnreadable proves that when git's
627
- // registration cannot be re-read after a failed delete, the error says so
628
- // instead of claiming git dropped the worktree.
629
- func TestCleanupDoesNotClaimUnregisteredWhenListUnreadable(t *testing.T) {
630
- if os.Geteuid() == 0 || runtime.GOOS == "windows" {
631
- t.Skip("directory permissions do not bind root or windows")
632
- }
633
- repo, base := setupRepo(t)
634
- slug, batch := "demo-feature", "batch1"
635
- if _, err := Create(CreateOpts{
636
- Root: repo,
637
- Slug: slug,
638
- BatchID: batch,
639
- BaseSHA: base,
640
- Slices: []SlicePaths{
641
- {ID: "slice-a", Paths: []string{"src/a.go"}},
642
- {ID: "slice-b", Paths: []string{"src/b.go"}},
643
- },
644
- }); err != nil {
645
- t.Fatal(err)
646
- }
647
- wt := WorkerWorktreePath(repo, batch, "slice-a")
648
- batchDir := filepath.Dir(wt)
649
- gitDir := filepath.Join(repo, ".git")
650
-
651
- swapSeams(t)
652
- warnf = func(string, ...any) {}
653
- removeWorktree = func(repo, path string) error {
654
- if err := os.Chmod(batchDir, 0o500); err != nil {
655
- return err
656
- }
657
- if err := os.Chmod(gitDir, 0o000); err != nil {
658
- return err
659
- }
660
- return errors.New("failed to delete '" + path + "': Permission denied")
661
- }
662
- t.Cleanup(func() {
663
- _ = os.Chmod(batchDir, 0o700)
664
- _ = os.Chmod(gitDir, 0o755)
665
- })
666
-
667
- _, err := Cleanup(repo, slug, true)
668
- if err == nil || !strings.Contains(err.Error(), wt) {
669
- t.Fatalf("error must name %s, got %v", wt, err)
670
- }
671
- if strings.Contains(err.Error(), "no longer registers") {
672
- t.Fatalf("registration is unknown, must not be called dropped: %v", err)
673
- }
674
- if !strings.Contains(err.Error(), "could not confirm whether git still registers") {
675
- t.Fatalf("error must say registration could not be confirmed, got %v", err)
676
- }
677
- }
678
-
679
- // TestCleanupStrandedRealGit runs the real git: an undeletable file inside the
680
- // worktree makes `git worktree remove --force` unregister it and still fail,
681
- // so stranding must be decided from git's registration, not the exit code.
682
- func TestCleanupStrandedRealGit(t *testing.T) {
683
- if os.Geteuid() == 0 || runtime.GOOS == "windows" {
684
- t.Skip("directory permissions do not bind root or windows")
685
- }
686
- repo, base := setupRepo(t)
687
- slug, batch := "demo-feature", "batch1"
688
- if _, err := Create(CreateOpts{
689
- Root: repo,
690
- Slug: slug,
691
- BatchID: batch,
692
- BaseSHA: base,
693
- Slices: []SlicePaths{
694
- {ID: "slice-a", Paths: []string{"src/a.go"}},
695
- {ID: "slice-b", Paths: []string{"src/b.go"}},
696
- },
697
- }); err != nil {
698
- t.Fatal(err)
699
- }
700
- wt := WorkerWorktreePath(repo, batch, "slice-a")
701
- locked := filepath.Join(wt, "locked")
702
- if err := os.MkdirAll(locked, 0o755); err != nil {
703
- t.Fatal(err)
704
- }
705
- if err := os.WriteFile(filepath.Join(locked, "f"), []byte("x"), 0o644); err != nil {
706
- t.Fatal(err)
707
- }
708
- if err := os.Chmod(locked, 0o555); err != nil {
709
- t.Fatal(err)
710
- }
711
- t.Cleanup(func() { _ = os.Chmod(locked, 0o755) })
712
-
713
- swapSeams(t)
714
- warnf = func(string, ...any) {}
715
- _, err := Cleanup(repo, slug, true)
716
- if err == nil || !strings.Contains(err.Error(), wt) || !strings.Contains(err.Error(), "remove it by hand") {
717
- t.Fatalf("error must name %s and say it needs manual removal, got %v", wt, err)
718
- }
719
- if err := os.Chmod(locked, 0o755); err != nil {
720
- t.Fatal(err)
721
- }
722
- if _, err := Cleanup(repo, slug, true); err != nil {
723
- t.Fatalf("rerun: %v", err)
724
- }
725
- if _, err := os.Stat(wt); err != nil {
726
- t.Fatalf("rerun must leave the unregistered directory in place, stat err=%v", err)
727
- }
728
- }
729
-
730
- // TestConcurrentRecordGreenKeepsEverySlice proves the feature lock serializes
731
- // concurrent record-green calls so no sibling's transfer commit is lost to a
732
- // read-modify-write race on the lease.
733
- func TestConcurrentRecordGreenKeepsEverySlice(t *testing.T) {
734
- repo, base := setupRepo(t)
735
- slug, batch := "demo-feature", "batch1"
736
- lease, err := Create(CreateOpts{
737
- Root: repo,
738
- Slug: slug,
739
- BatchID: batch,
740
- BaseSHA: base,
741
- Slices: []SlicePaths{
742
- {ID: "slice-a", Paths: []string{"src/a.go"}},
743
- {ID: "slice-b", Paths: []string{"src/b.go"}},
744
- },
745
- })
746
- if err != nil {
747
- t.Fatal(err)
748
- }
749
- tcA := commitIn(t, lease.Slices[0].WorktreePath, "src/a.go", "A")
750
- tcB := commitIn(t, lease.Slices[1].WorktreePath, "src/b.go", "B")
751
-
752
- var wg sync.WaitGroup
753
- errs := make(chan error, 2)
754
- for _, item := range [][2]string{{"slice-a", tcA}, {"slice-b", tcB}} {
755
- wg.Add(1)
756
- go func(sliceID, commit string) {
757
- defer wg.Done()
758
- _, err := RecordGreen(repo, slug, sliceID, commit)
759
- errs <- err
760
- }(item[0], item[1])
761
- }
762
- wg.Wait()
763
- close(errs)
764
- for err := range errs {
765
- if err != nil {
766
- t.Fatal(err)
767
- }
768
- }
769
-
770
- leasePath, err := LeasePath(repo, slug)
771
- if err != nil {
772
- t.Fatal(err)
773
- }
774
- onDisk, err := ReadLease(leasePath)
775
- if err != nil {
776
- t.Fatal(err)
777
- }
778
- got := map[string]string{}
779
- for _, sl := range onDisk.Slices {
780
- got[sl.ID] = sl.TransferCommit
781
- }
782
- if got["slice-a"] != tcA || got["slice-b"] != tcB {
783
- t.Fatalf("lost update: transfer commits %v want a=%s b=%s", got, tcA, tcB)
784
- }
785
- }
786
-
787
- // TestConcurrentCreateSingleWinner proves the feature lock serializes create
788
- // so two racing creates cannot both pass the lease-existence check.
789
- func TestConcurrentCreateSingleWinner(t *testing.T) {
790
- repo, base := setupRepo(t)
791
- opts := CreateOpts{
792
- Root: repo,
793
- Slug: "demo-feature",
794
- BatchID: "batch1",
795
- BaseSHA: base,
796
- Slices: []SlicePaths{
797
- {ID: "slice-a", Paths: []string{"src/a.go"}},
798
- {ID: "slice-b", Paths: []string{"src/b.go"}},
799
- },
800
- }
801
- var wg sync.WaitGroup
802
- errs := make(chan error, 2)
803
- wins := make(chan *Lease, 2)
804
- for i := 0; i < 2; i++ {
805
- wg.Add(1)
806
- go func() {
807
- defer wg.Done()
808
- lease, err := Create(opts)
809
- if err != nil {
810
- errs <- err
811
- return
812
- }
813
- wins <- lease
814
- }()
815
- }
816
- wg.Wait()
817
- close(errs)
818
- close(wins)
819
- succeeded := 0
820
- for range wins {
821
- succeeded++
822
- }
823
- failed := 0
824
- for range errs {
825
- failed++
826
- }
827
- if succeeded != 1 || failed != 1 {
828
- t.Fatalf("concurrent create: %d succeeded, %d failed; want exactly 1/1", succeeded, failed)
829
- }
830
- }
831
-
832
- // stuckBranchBatch creates a two-slice batch and stubs worktree removal so
833
- // cleanup leaves a stale registration behind: Cleanup's own RemoveAll deletes
834
- // the worktree directory while git still lists the branch as checked out, so
835
- // deleteBranch refuses. It returns the repo, slug, the stuck branch and the
836
- // captured warnings.
837
- func stuckBranchBatch(t *testing.T) (repo, slug, branch string, warnings *[]string) {
838
- t.Helper()
839
- repo, base := setupRepo(t)
840
- slug = "demo-feature"
841
- lease, err := Create(CreateOpts{
842
- Root: repo,
843
- Slug: slug,
844
- BatchID: "batch1",
845
- BaseSHA: base,
846
- Slices: []SlicePaths{
847
- {ID: "slice-a", Paths: []string{"src/a.go"}},
848
- {ID: "slice-b", Paths: []string{"src/b.go"}},
849
- },
850
- })
851
- if err != nil {
852
- t.Fatal(err)
853
- }
854
- swapSeams(t)
855
- removeWorktree = func(string, string) error {
856
- return errors.New("simulated stuck worker worktree")
857
- }
858
- warnings = new([]string)
859
- warnf = func(format string, args ...any) {
860
- *warnings = append(*warnings, fmt.Sprintf(format, args...))
861
- }
862
- return repo, slug, lease.Slices[0].Branch, warnings
863
- }
864
-
865
- // TestCleanupWarnsOnFailedBranchCleanup proves Cleanup reports branch cleanup
866
- // failures and keeps the lease so the orphans stay reachable for a rerun.
867
- func TestCleanupWarnsOnFailedBranchCleanup(t *testing.T) {
868
- repo, slug, branchA, warnings := stuckBranchBatch(t)
869
-
870
- if _, err := Cleanup(repo, slug, true); err == nil || !strings.Contains(err.Error(), "slice-a") {
871
- t.Fatalf("cleanup must fail naming slice-a, got %v", err)
872
- }
873
- leasePath, err := LeasePath(repo, slug)
874
- if err != nil {
875
- t.Fatal(err)
876
- }
877
- if _, err := os.Stat(leasePath); err != nil {
878
- t.Fatalf("lease must survive a failed cleanup, got %v", err)
879
- }
880
- // The rerun finds the lease and, with the stale registration pruned by the
881
- // first pass, completes the removal and clears it.
882
- if _, err := Cleanup(repo, slug, true); err != nil {
883
- t.Fatalf("rerun against the kept lease: %v", err)
884
- }
885
- if _, err := os.Stat(leasePath); !os.IsNotExist(err) {
886
- t.Fatalf("rerun should clear the lease, got %v", err)
887
- }
888
- if exists, err := branchExists(repo, branchA); err != nil || exists {
889
- t.Fatalf("rerun should delete %s: exists=%v err=%v", branchA, exists, err)
890
- }
891
- if joined := strings.Join(*warnings, "\n"); !strings.Contains(joined, branchA) {
892
- t.Fatalf("warnings should name the stuck branch %s, got:\n%s", branchA, joined)
893
- }
894
- }
895
-
896
- func TestControlCommitMessage(t *testing.T) {
897
- t.Parallel()
898
- got := controlCommitMessage("admin-report", "WIP(admin-report): SLICE-003 add CSV export")
899
- wantPrefix := "WIP(admin-report): add CSV export\n"
900
- if !strings.HasPrefix(got, wantPrefix) {
901
- t.Fatalf("subject %q want prefix %q", got, wantPrefix)
902
- }
903
- if strings.Contains(got, "SLICE-") || strings.Contains(strings.ToLower(got), "slice-003") {
904
- t.Fatalf("message still names a slice id: %q", got)
905
- }
906
- got = controlCommitMessage("admin-report", "WIP(other): complete slice 3")
907
- if !strings.HasPrefix(got, "WIP(admin-report): complete\n") {
908
- t.Fatalf("foreign WIP prefix / slice N: %q", got)
909
- }
910
- got = controlCommitMessage("admin-report", "add this slice CSV")
911
- if !strings.HasPrefix(got, "WIP(admin-report): add CSV\n") {
912
- t.Fatalf("this slice: %q", got)
913
- }
914
- got = controlCommitMessage("admin-report", "keep array slice helper")
915
- if !strings.HasPrefix(got, "WIP(admin-report): keep array slice helper\n") {
916
- t.Fatalf("ordinary English stripped: %q", got)
917
- }
918
- got = controlCommitMessage("admin-report", "SLICE-001")
919
- if !strings.HasPrefix(got, "WIP(admin-report): land proven work\n") {
920
- t.Fatalf("empty summary after strip: %q", got)
921
- }
922
- }
923
-
924
- func TestCreateRefusesAncestorOverlap(t *testing.T) {
925
- repo, base := setupRepo(t)
926
- _, err := Create(CreateOpts{
927
- Root: repo,
928
- Slug: "demo",
929
- BatchID: "batch1",
930
- BaseSHA: base,
931
- Slices: []SlicePaths{
932
- {ID: "slice-a", Paths: []string{"src"}},
933
- {ID: "slice-b", Paths: []string{"src/a.go"}},
934
- },
935
- })
936
- if err == nil || !strings.Contains(err.Error(), "overlap") {
937
- t.Fatalf("expected overlap refusal, got %v", err)
938
- }
939
- }