devrites 5.4.0 → 5.6.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 (490) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +8 -6
  3. package/docs/command-map.md +2 -2
  4. package/docs/engine/state-schema.md +12 -0
  5. package/docs/flow.md +4 -0
  6. package/docs/orchestration.md +5 -2
  7. package/engine/commands.go +2 -2
  8. package/engine/internal/devritespaths/paths.go +18 -0
  9. package/engine/internal/gate/gate.go +78 -0
  10. package/engine/internal/gate/gate_test.go +118 -0
  11. package/engine/internal/hostpack/hostpack.go +45 -6
  12. package/engine/internal/hostpack/hostpack_test.go +29 -13
  13. package/engine/internal/install/apply.go +14 -5
  14. package/engine/internal/install/install.go +8 -2
  15. package/engine/internal/install/install_test.go +12 -5
  16. package/engine/internal/install/merge.go +5 -0
  17. package/engine/internal/install/preflight.go +20 -2
  18. package/engine/internal/install/uninstall.go +5 -0
  19. package/engine/internal/install/update.go +1 -1
  20. package/engine/internal/lib/candidate.go +7 -3
  21. package/engine/internal/lib/manifest_union.go +326 -0
  22. package/engine/internal/lib/manifest_union_test.go +214 -0
  23. package/engine/internal/lib/observe_budgets.go +73 -0
  24. package/engine/internal/lib/observe_budgets_test.go +142 -0
  25. package/engine/internal/lib/observe_summary.go +74 -13
  26. package/engine/internal/lib/workspace_read.go +11 -6
  27. package/engine/internal/state/budgets.go +163 -0
  28. package/engine/internal/state/budgets_test.go +42 -0
  29. package/engine/internal/state/cursor.go +16 -10
  30. package/engine/internal/state/observation.go +50 -4
  31. package/engine/internal/state/status.go +38 -26
  32. package/engine/internal/state/taskgraph.go +23 -0
  33. package/engine/main.go +32 -13
  34. package/engine/root_routing_test.go +3 -1
  35. package/install.sh +4 -1
  36. package/pack/.claude/agents/devrites-code-reviewer.md +9 -6
  37. package/pack/.claude/agents/devrites-doubt-reviewer.md +6 -0
  38. package/pack/.claude/agents/devrites-plan-reviewer.md +7 -1
  39. package/pack/.claude/agents/devrites-slice-wright.md +42 -46
  40. package/pack/.claude/agents/devrites-test-analyst.md +9 -4
  41. package/pack/.claude/agents/devrites-upgrade-planner.md +9 -1
  42. package/pack/.claude/settings.json +17 -0
  43. package/pack/.claude/skills/devrites-api-interface/SKILL.md +2 -2
  44. package/pack/.claude/skills/devrites-doubt/SKILL.md +9 -17
  45. package/pack/.claude/skills/devrites-lib/reference/candidate-integrity.md +34 -35
  46. package/pack/.claude/skills/devrites-lib/reference/parallel-dispatch.md +11 -12
  47. package/pack/.claude/skills/devrites-lib/reference/standards/afk-hitl.md +104 -51
  48. package/pack/.claude/skills/devrites-lib/reference/standards/agents.md +1 -0
  49. package/pack/.claude/skills/devrites-lib/reference/standards/context-hygiene.md +45 -25
  50. package/pack/.claude/skills/devrites-lib/reference/standards/core.md +1 -1
  51. package/pack/.claude/skills/devrites-lib/reference/workspace-artifact-schema.md +80 -41
  52. package/pack/.claude/skills/rite-autocomplete/SKILL.md +19 -8
  53. package/pack/.claude/skills/rite-autocomplete/reference/loop.md +33 -1
  54. package/pack/.claude/skills/rite-build/SKILL.md +26 -19
  55. package/pack/.claude/skills/rite-build/reference/afk-discipline.md +1 -1
  56. package/pack/.claude/skills/rite-build/reference/parallel-batch.md +90 -40
  57. package/pack/.claude/skills/rite-build/reference/phase-contract.md +79 -59
  58. package/pack/.claude/skills/rite-build/reference/spec-drift-guard.md +14 -15
  59. package/pack/.claude/skills/rite-build/reference/wright-dispatch.md +8 -8
  60. package/pack/.claude/skills/rite-define/SKILL.md +4 -1
  61. package/pack/.claude/skills/rite-plan/SKILL.md +4 -1
  62. package/pack/.claude/skills/rite-plan/reference/replan-and-repair.md +21 -0
  63. package/pack/.claude/skills/rite-plan/reference/slicing.md +117 -15
  64. package/pack/.claude/skills/rite-prove/SKILL.md +20 -22
  65. package/pack/.claude/skills/rite-review/SKILL.md +23 -16
  66. package/pack/.claude/skills/rite-seal/SKILL.md +8 -8
  67. package/pack/.claude/skills/rite-seal/reference/final-evidence.md +6 -5
  68. package/pack/.claude/skills/rite-seal/reference/phase-contract.md +13 -13
  69. package/pack/.claude/skills/rite-ship/SKILL.md +3 -0
  70. package/pack/.claude/skills/rite-ship/reference/close-out.md +16 -2
  71. package/pack/.claude/skills/rite-ship/reference/git-ship.md +14 -5
  72. package/pack/.claude/skills/rite-spec/SKILL.md +6 -0
  73. package/pack/.claude/skills/rite-spec/reference/state-workspace.md +6 -0
  74. package/pack/.claude/skills/rite-status/SKILL.md +4 -1
  75. package/pack/.claude/skills/rite-temper/SKILL.md +14 -11
  76. package/pack/.claude/skills/rite-temper/reference/anti-patterns.md +14 -13
  77. package/pack/.claude/skills/rite-temper/reference/review-dimensions.md +3 -4
  78. package/pack/.claude/skills/rite-upgrade/SKILL.md +11 -2
  79. package/pack/.claude/skills/rite-vet/SKILL.md +22 -15
  80. package/pack/.claude/skills/rite-vet/reference/anti-patterns.md +11 -9
  81. package/pack/.claude/skills/rite-vet/reference/depth.md +6 -7
  82. package/pack/.claude/skills/rite-vet/reference/review-axes.md +39 -14
  83. package/pack/generated/README.md +5 -1
  84. package/pack/generated/claude/agents/devrites-code-reviewer.md +9 -6
  85. package/pack/generated/claude/agents/devrites-doubt-reviewer.md +6 -0
  86. package/pack/generated/claude/agents/devrites-plan-reviewer.md +7 -1
  87. package/pack/generated/claude/agents/devrites-slice-wright.md +42 -46
  88. package/pack/generated/claude/agents/devrites-test-analyst.md +9 -4
  89. package/pack/generated/claude/agents/devrites-upgrade-planner.md +9 -1
  90. package/pack/generated/claude/settings.json +17 -0
  91. package/pack/generated/claude/skills/devrites-api-interface/SKILL.md +2 -2
  92. package/pack/generated/claude/skills/devrites-doubt/SKILL.md +9 -17
  93. package/pack/generated/claude/skills/devrites-lib/reference/candidate-integrity.md +34 -35
  94. package/pack/generated/claude/skills/devrites-lib/reference/parallel-dispatch.md +11 -12
  95. package/pack/generated/claude/skills/devrites-lib/reference/standards/afk-hitl.md +104 -51
  96. package/pack/generated/claude/skills/devrites-lib/reference/standards/agents.md +1 -0
  97. package/pack/generated/claude/skills/devrites-lib/reference/standards/context-hygiene.md +45 -25
  98. package/pack/generated/claude/skills/devrites-lib/reference/standards/core.md +1 -1
  99. package/pack/generated/claude/skills/devrites-lib/reference/workspace-artifact-schema.md +80 -41
  100. package/pack/generated/claude/skills/rite-autocomplete/SKILL.md +19 -8
  101. package/pack/generated/claude/skills/rite-autocomplete/reference/loop.md +33 -1
  102. package/pack/generated/claude/skills/rite-build/SKILL.md +26 -19
  103. package/pack/generated/claude/skills/rite-build/reference/afk-discipline.md +1 -1
  104. package/pack/generated/claude/skills/rite-build/reference/parallel-batch.md +90 -40
  105. package/pack/generated/claude/skills/rite-build/reference/phase-contract.md +79 -59
  106. package/pack/generated/claude/skills/rite-build/reference/spec-drift-guard.md +14 -15
  107. package/pack/generated/claude/skills/rite-build/reference/wright-dispatch.md +8 -8
  108. package/pack/generated/claude/skills/rite-define/SKILL.md +4 -1
  109. package/pack/generated/claude/skills/rite-plan/SKILL.md +4 -1
  110. package/pack/generated/claude/skills/rite-plan/reference/replan-and-repair.md +21 -0
  111. package/pack/generated/claude/skills/rite-plan/reference/slicing.md +117 -15
  112. package/pack/generated/claude/skills/rite-prove/SKILL.md +20 -22
  113. package/pack/generated/claude/skills/rite-review/SKILL.md +23 -16
  114. package/pack/generated/claude/skills/rite-seal/SKILL.md +8 -8
  115. package/pack/generated/claude/skills/rite-seal/reference/final-evidence.md +6 -5
  116. package/pack/generated/claude/skills/rite-seal/reference/phase-contract.md +13 -13
  117. package/pack/generated/claude/skills/rite-ship/SKILL.md +3 -0
  118. package/pack/generated/claude/skills/rite-ship/reference/close-out.md +16 -2
  119. package/pack/generated/claude/skills/rite-ship/reference/git-ship.md +14 -5
  120. package/pack/generated/claude/skills/rite-spec/SKILL.md +6 -0
  121. package/pack/generated/claude/skills/rite-spec/reference/state-workspace.md +6 -0
  122. package/pack/generated/claude/skills/rite-status/SKILL.md +4 -1
  123. package/pack/generated/claude/skills/rite-temper/SKILL.md +14 -11
  124. package/pack/generated/claude/skills/rite-temper/reference/anti-patterns.md +14 -13
  125. package/pack/generated/claude/skills/rite-temper/reference/review-dimensions.md +3 -4
  126. package/pack/generated/claude/skills/rite-upgrade/SKILL.md +11 -2
  127. package/pack/generated/claude/skills/rite-vet/SKILL.md +22 -15
  128. package/pack/generated/claude/skills/rite-vet/reference/anti-patterns.md +11 -9
  129. package/pack/generated/claude/skills/rite-vet/reference/depth.md +6 -7
  130. package/pack/generated/claude/skills/rite-vet/reference/review-axes.md +39 -14
  131. package/pack/generated/codex/agents/devrites-code-reviewer.toml +9 -6
  132. package/pack/generated/codex/agents/devrites-doubt-reviewer.toml +6 -0
  133. package/pack/generated/codex/agents/devrites-plan-reviewer.toml +7 -1
  134. package/pack/generated/codex/agents/devrites-slice-wright.toml +42 -46
  135. package/pack/generated/codex/agents/devrites-test-analyst.toml +9 -4
  136. package/pack/generated/codex/agents/devrites-upgrade-planner.toml +9 -1
  137. package/pack/generated/codex/skills/devrites-api-interface/SKILL.md +2 -2
  138. package/pack/generated/codex/skills/devrites-doubt/SKILL.md +9 -17
  139. package/pack/generated/codex/skills/devrites-lib/reference/candidate-integrity.md +34 -35
  140. package/pack/generated/codex/skills/devrites-lib/reference/parallel-dispatch.md +11 -12
  141. package/pack/generated/codex/skills/devrites-lib/reference/standards/afk-hitl.md +104 -51
  142. package/pack/generated/codex/skills/devrites-lib/reference/standards/agents.md +1 -0
  143. package/pack/generated/codex/skills/devrites-lib/reference/standards/context-hygiene.md +45 -25
  144. package/pack/generated/codex/skills/devrites-lib/reference/standards/core.md +1 -1
  145. package/pack/generated/codex/skills/devrites-lib/reference/workspace-artifact-schema.md +80 -41
  146. package/pack/generated/codex/skills/rite-autocomplete/SKILL.md +19 -8
  147. package/pack/generated/codex/skills/rite-autocomplete/reference/loop.md +33 -1
  148. package/pack/generated/codex/skills/rite-build/SKILL.md +26 -19
  149. package/pack/generated/codex/skills/rite-build/reference/afk-discipline.md +1 -1
  150. package/pack/generated/codex/skills/rite-build/reference/parallel-batch.md +90 -40
  151. package/pack/generated/codex/skills/rite-build/reference/phase-contract.md +79 -59
  152. package/pack/generated/codex/skills/rite-build/reference/spec-drift-guard.md +14 -15
  153. package/pack/generated/codex/skills/rite-build/reference/wright-dispatch.md +8 -8
  154. package/pack/generated/codex/skills/rite-define/SKILL.md +4 -1
  155. package/pack/generated/codex/skills/rite-plan/SKILL.md +4 -1
  156. package/pack/generated/codex/skills/rite-plan/reference/replan-and-repair.md +21 -0
  157. package/pack/generated/codex/skills/rite-plan/reference/slicing.md +117 -15
  158. package/pack/generated/codex/skills/rite-prove/SKILL.md +20 -22
  159. package/pack/generated/codex/skills/rite-review/SKILL.md +23 -16
  160. package/pack/generated/codex/skills/rite-seal/SKILL.md +8 -8
  161. package/pack/generated/codex/skills/rite-seal/reference/final-evidence.md +6 -5
  162. package/pack/generated/codex/skills/rite-seal/reference/phase-contract.md +13 -13
  163. package/pack/generated/codex/skills/rite-ship/SKILL.md +3 -0
  164. package/pack/generated/codex/skills/rite-ship/reference/close-out.md +16 -2
  165. package/pack/generated/codex/skills/rite-ship/reference/git-ship.md +14 -5
  166. package/pack/generated/codex/skills/rite-spec/SKILL.md +6 -0
  167. package/pack/generated/codex/skills/rite-spec/reference/state-workspace.md +6 -0
  168. package/pack/generated/codex/skills/rite-status/SKILL.md +4 -1
  169. package/pack/generated/codex/skills/rite-temper/SKILL.md +14 -11
  170. package/pack/generated/codex/skills/rite-temper/reference/anti-patterns.md +14 -13
  171. package/pack/generated/codex/skills/rite-temper/reference/review-dimensions.md +3 -4
  172. package/pack/generated/codex/skills/rite-upgrade/SKILL.md +11 -2
  173. package/pack/generated/codex/skills/rite-vet/SKILL.md +22 -15
  174. package/pack/generated/codex/skills/rite-vet/reference/anti-patterns.md +11 -9
  175. package/pack/generated/codex/skills/rite-vet/reference/depth.md +6 -7
  176. package/pack/generated/codex/skills/rite-vet/reference/review-axes.md +39 -14
  177. package/pack/generated/omp/agents/devrites-code-reviewer.md +9 -6
  178. package/pack/generated/omp/agents/devrites-doubt-reviewer.md +6 -0
  179. package/pack/generated/omp/agents/devrites-plan-reviewer.md +7 -1
  180. package/pack/generated/omp/agents/devrites-slice-wright.md +42 -46
  181. package/pack/generated/omp/agents/devrites-test-analyst.md +9 -4
  182. package/pack/generated/omp/agents/devrites-upgrade-planner.md +9 -1
  183. package/pack/generated/omp/skills/devrites-api-interface/SKILL.md +2 -2
  184. package/pack/generated/omp/skills/devrites-doubt/SKILL.md +9 -17
  185. package/pack/generated/omp/skills/devrites-lib/reference/candidate-integrity.md +34 -35
  186. package/pack/generated/omp/skills/devrites-lib/reference/parallel-dispatch.md +11 -12
  187. package/pack/generated/omp/skills/devrites-lib/reference/standards/afk-hitl.md +104 -51
  188. package/pack/generated/omp/skills/devrites-lib/reference/standards/agents.md +1 -0
  189. package/pack/generated/omp/skills/devrites-lib/reference/standards/context-hygiene.md +45 -25
  190. package/pack/generated/omp/skills/devrites-lib/reference/standards/core.md +1 -1
  191. package/pack/generated/omp/skills/devrites-lib/reference/workspace-artifact-schema.md +80 -41
  192. package/pack/generated/omp/skills/rite-autocomplete/SKILL.md +19 -8
  193. package/pack/generated/omp/skills/rite-autocomplete/reference/loop.md +33 -1
  194. package/pack/generated/omp/skills/rite-build/SKILL.md +26 -19
  195. package/pack/generated/omp/skills/rite-build/reference/afk-discipline.md +1 -1
  196. package/pack/generated/omp/skills/rite-build/reference/parallel-batch.md +90 -40
  197. package/pack/generated/omp/skills/rite-build/reference/phase-contract.md +79 -59
  198. package/pack/generated/omp/skills/rite-build/reference/spec-drift-guard.md +14 -15
  199. package/pack/generated/omp/skills/rite-build/reference/wright-dispatch.md +8 -8
  200. package/pack/generated/omp/skills/rite-define/SKILL.md +4 -1
  201. package/pack/generated/omp/skills/rite-plan/SKILL.md +4 -1
  202. package/pack/generated/omp/skills/rite-plan/reference/replan-and-repair.md +21 -0
  203. package/pack/generated/omp/skills/rite-plan/reference/slicing.md +117 -15
  204. package/pack/generated/omp/skills/rite-prove/SKILL.md +20 -22
  205. package/pack/generated/omp/skills/rite-review/SKILL.md +23 -16
  206. package/pack/generated/omp/skills/rite-seal/SKILL.md +8 -8
  207. package/pack/generated/omp/skills/rite-seal/reference/final-evidence.md +6 -5
  208. package/pack/generated/omp/skills/rite-seal/reference/phase-contract.md +13 -13
  209. package/pack/generated/omp/skills/rite-ship/SKILL.md +3 -0
  210. package/pack/generated/omp/skills/rite-ship/reference/close-out.md +16 -2
  211. package/pack/generated/omp/skills/rite-ship/reference/git-ship.md +14 -5
  212. package/pack/generated/omp/skills/rite-spec/SKILL.md +6 -0
  213. package/pack/generated/omp/skills/rite-spec/reference/state-workspace.md +6 -0
  214. package/pack/generated/omp/skills/rite-status/SKILL.md +4 -1
  215. package/pack/generated/omp/skills/rite-temper/SKILL.md +14 -11
  216. package/pack/generated/omp/skills/rite-temper/reference/anti-patterns.md +14 -13
  217. package/pack/generated/omp/skills/rite-temper/reference/review-dimensions.md +3 -4
  218. package/pack/generated/omp/skills/rite-upgrade/SKILL.md +11 -2
  219. package/pack/generated/omp/skills/rite-vet/SKILL.md +22 -15
  220. package/pack/generated/omp/skills/rite-vet/reference/anti-patterns.md +11 -9
  221. package/pack/generated/omp/skills/rite-vet/reference/depth.md +6 -7
  222. package/pack/generated/omp/skills/rite-vet/reference/review-axes.md +39 -14
  223. package/pack/generated/pi/AGENTS.md +22 -0
  224. package/pack/generated/pi/agents/devrites-code-reviewer.md +142 -0
  225. package/pack/generated/pi/agents/devrites-devex-reviewer.md +124 -0
  226. package/pack/generated/pi/agents/devrites-doubt-reviewer.md +88 -0
  227. package/pack/generated/pi/agents/devrites-evidence-scout.md +72 -0
  228. package/pack/generated/pi/agents/devrites-frontend-reviewer.md +116 -0
  229. package/pack/generated/pi/agents/devrites-performance-reviewer.md +115 -0
  230. package/pack/generated/pi/agents/devrites-plan-drafter.md +99 -0
  231. package/pack/generated/pi/agents/devrites-plan-reviewer.md +142 -0
  232. package/pack/generated/pi/agents/devrites-proof-runner.md +74 -0
  233. package/pack/generated/pi/agents/devrites-retrospector.md +61 -0
  234. package/pack/generated/pi/agents/devrites-security-auditor.md +109 -0
  235. package/pack/generated/pi/agents/devrites-simplifier-reviewer.md +94 -0
  236. package/pack/generated/pi/agents/devrites-slice-wright.md +204 -0
  237. package/pack/generated/pi/agents/devrites-spec-reviewer.md +96 -0
  238. package/pack/generated/pi/agents/devrites-strategy-reviewer.md +100 -0
  239. package/pack/generated/pi/agents/devrites-test-analyst.md +94 -0
  240. package/pack/generated/pi/agents/devrites-upgrade-planner.md +89 -0
  241. package/pack/generated/pi/prompts/rite-adopt.md +5 -0
  242. package/pack/generated/pi/prompts/rite-autocomplete.md +5 -0
  243. package/pack/generated/pi/prompts/rite-build.md +5 -0
  244. package/pack/generated/pi/prompts/rite-clarify.md +5 -0
  245. package/pack/generated/pi/prompts/rite-converge.md +5 -0
  246. package/pack/generated/pi/prompts/rite-customize.md +5 -0
  247. package/pack/generated/pi/prompts/rite-define.md +5 -0
  248. package/pack/generated/pi/prompts/rite-doctor.md +5 -0
  249. package/pack/generated/pi/prompts/rite-dogfood.md +5 -0
  250. package/pack/generated/pi/prompts/rite-explain.md +5 -0
  251. package/pack/generated/pi/prompts/rite-frame.md +5 -0
  252. package/pack/generated/pi/prompts/rite-handoff.md +5 -0
  253. package/pack/generated/pi/prompts/rite-learn.md +5 -0
  254. package/pack/generated/pi/prompts/rite-plan.md +5 -0
  255. package/pack/generated/pi/prompts/rite-polish.md +5 -0
  256. package/pack/generated/pi/prompts/rite-pov.md +5 -0
  257. package/pack/generated/pi/prompts/rite-pr-feedback.md +5 -0
  258. package/pack/generated/pi/prompts/rite-pressure-test.md +5 -0
  259. package/pack/generated/pi/prompts/rite-prototype.md +5 -0
  260. package/pack/generated/pi/prompts/rite-prove.md +5 -0
  261. package/pack/generated/pi/prompts/rite-quick.md +5 -0
  262. package/pack/generated/pi/prompts/rite-resolve.md +5 -0
  263. package/pack/generated/pi/prompts/rite-review.md +5 -0
  264. package/pack/generated/pi/prompts/rite-seal.md +5 -0
  265. package/pack/generated/pi/prompts/rite-ship.md +5 -0
  266. package/pack/generated/pi/prompts/rite-spec.md +5 -0
  267. package/pack/generated/pi/prompts/rite-status.md +5 -0
  268. package/pack/generated/pi/prompts/rite-temper.md +5 -0
  269. package/pack/generated/pi/prompts/rite-upgrade.md +5 -0
  270. package/pack/generated/pi/prompts/rite-vet.md +5 -0
  271. package/pack/generated/pi/prompts/rite-watch-pr.md +5 -0
  272. package/pack/generated/pi/prompts/rite-zoom-out.md +5 -0
  273. package/pack/generated/pi/prompts/rite.md +5 -0
  274. package/pack/generated/pi/skills/devrites-api-interface/SKILL.md +63 -0
  275. package/pack/generated/pi/skills/devrites-audit/SKILL.md +50 -0
  276. package/pack/generated/pi/skills/devrites-browser-proof/SKILL.md +76 -0
  277. package/pack/generated/pi/skills/devrites-browser-proof/reference/browser-performance.md +15 -0
  278. package/pack/generated/pi/skills/devrites-browser-proof/reference/visual-verdict.md +34 -0
  279. package/pack/generated/pi/skills/devrites-debug-recovery/SKILL.md +96 -0
  280. package/pack/generated/pi/skills/devrites-debug-recovery/reference/build-the-loop.md +58 -0
  281. package/pack/generated/pi/skills/devrites-debug-recovery/reference/cleanup-and-classify.md +34 -0
  282. package/pack/generated/pi/skills/devrites-debug-recovery/reference/hypotheses.md +17 -0
  283. package/pack/generated/pi/skills/devrites-debug-recovery/reference/instrumentation.md +21 -0
  284. package/pack/generated/pi/skills/devrites-debug-recovery/reference/regression-test.md +30 -0
  285. package/pack/generated/pi/skills/devrites-debug-recovery/reference/trace.md +25 -0
  286. package/pack/generated/pi/skills/devrites-doubt/SKILL.md +79 -0
  287. package/pack/generated/pi/skills/devrites-frontend-craft/SKILL.md +86 -0
  288. package/pack/generated/pi/skills/devrites-frontend-craft/reference/craft.md +63 -0
  289. package/pack/generated/pi/skills/devrites-frontend-craft/reference/design-references.md +116 -0
  290. package/pack/generated/pi/skills/devrites-frontend-craft/reference/fullstack.md +46 -0
  291. package/pack/generated/pi/skills/devrites-frontend-craft/reference/quality-standards.md +294 -0
  292. package/pack/generated/pi/skills/devrites-frontend-craft/reference/reuse-first.md +53 -0
  293. package/pack/generated/pi/skills/devrites-frontend-craft/reference/shape.md +56 -0
  294. package/pack/generated/pi/skills/devrites-interview/SKILL.md +102 -0
  295. package/pack/generated/pi/skills/devrites-lib/SKILL.md +58 -0
  296. package/pack/generated/pi/skills/devrites-lib/reference/candidate-integrity.md +42 -0
  297. package/pack/generated/pi/skills/devrites-lib/reference/intent-map.md +64 -0
  298. package/pack/generated/pi/skills/devrites-lib/reference/orchestration-profiles.md +27 -0
  299. package/pack/generated/pi/skills/devrites-lib/reference/parallel-dispatch.md +73 -0
  300. package/pack/generated/pi/skills/devrites-lib/reference/reply-contract.md +88 -0
  301. package/pack/generated/pi/skills/devrites-lib/reference/standards/README.md +60 -0
  302. package/pack/generated/pi/skills/devrites-lib/reference/standards/acceptance-preserving-reslice.md +30 -0
  303. package/pack/generated/pi/skills/devrites-lib/reference/standards/afk-hitl.md +398 -0
  304. package/pack/generated/pi/skills/devrites-lib/reference/standards/agents.md +99 -0
  305. package/pack/generated/pi/skills/devrites-lib/reference/standards/anti-patterns.md +48 -0
  306. package/pack/generated/pi/skills/devrites-lib/reference/standards/browser-proof-checklist.md +24 -0
  307. package/pack/generated/pi/skills/devrites-lib/reference/standards/ci-cd.md +50 -0
  308. package/pack/generated/pi/skills/devrites-lib/reference/standards/code-navigation.md +43 -0
  309. package/pack/generated/pi/skills/devrites-lib/reference/standards/code-review.md +108 -0
  310. package/pack/generated/pi/skills/devrites-lib/reference/standards/coding-style.md +48 -0
  311. package/pack/generated/pi/skills/devrites-lib/reference/standards/context-hygiene.md +109 -0
  312. package/pack/generated/pi/skills/devrites-lib/reference/standards/core.md +167 -0
  313. package/pack/generated/pi/skills/devrites-lib/reference/standards/data-integrity.md +118 -0
  314. package/pack/generated/pi/skills/devrites-lib/reference/standards/debug-recovery.md +28 -0
  315. package/pack/generated/pi/skills/devrites-lib/reference/standards/definition-of-done.md +19 -0
  316. package/pack/generated/pi/skills/devrites-lib/reference/standards/deprecation.md +31 -0
  317. package/pack/generated/pi/skills/devrites-lib/reference/standards/developer-experience.md +119 -0
  318. package/pack/generated/pi/skills/devrites-lib/reference/standards/development-workflow.md +29 -0
  319. package/pack/generated/pi/skills/devrites-lib/reference/standards/documentation.md +43 -0
  320. package/pack/generated/pi/skills/devrites-lib/reference/standards/edge-case-trace.md +92 -0
  321. package/pack/generated/pi/skills/devrites-lib/reference/standards/elicitation.md +85 -0
  322. package/pack/generated/pi/skills/devrites-lib/reference/standards/error-handling.md +47 -0
  323. package/pack/generated/pi/skills/devrites-lib/reference/standards/git-workflow.md +49 -0
  324. package/pack/generated/pi/skills/devrites-lib/reference/standards/hooks.md +25 -0
  325. package/pack/generated/pi/skills/devrites-lib/reference/standards/integration-reliability.md +102 -0
  326. package/pack/generated/pi/skills/devrites-lib/reference/standards/loop-operations.md +85 -0
  327. package/pack/generated/pi/skills/devrites-lib/reference/standards/observability.md +88 -0
  328. package/pack/generated/pi/skills/devrites-lib/reference/standards/one-shot-actions.md +97 -0
  329. package/pack/generated/pi/skills/devrites-lib/reference/standards/patterns.md +68 -0
  330. package/pack/generated/pi/skills/devrites-lib/reference/standards/performance.md +51 -0
  331. package/pack/generated/pi/skills/devrites-lib/reference/standards/principles.md +42 -0
  332. package/pack/generated/pi/skills/devrites-lib/reference/standards/prose-style.md +123 -0
  333. package/pack/generated/pi/skills/devrites-lib/reference/standards/release/ship-checklist.md +8 -0
  334. package/pack/generated/pi/skills/devrites-lib/reference/standards/repository-topology.md +80 -0
  335. package/pack/generated/pi/skills/devrites-lib/reference/standards/review-checklist.md +12 -0
  336. package/pack/generated/pi/skills/devrites-lib/reference/standards/security-checklist.md +25 -0
  337. package/pack/generated/pi/skills/devrites-lib/reference/standards/security.md +202 -0
  338. package/pack/generated/pi/skills/devrites-lib/reference/standards/skill-authoring.md +209 -0
  339. package/pack/generated/pi/skills/devrites-lib/reference/standards/spec-grammar.md +197 -0
  340. package/pack/generated/pi/skills/devrites-lib/reference/standards/test-proof-checklist.md +13 -0
  341. package/pack/generated/pi/skills/devrites-lib/reference/standards/testing.md +212 -0
  342. package/pack/generated/pi/skills/devrites-lib/reference/standards/tooling.md +92 -0
  343. package/pack/generated/pi/skills/devrites-lib/reference/standards/workflow-artifacts.md +427 -0
  344. package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/code.md +44 -0
  345. package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/comparison.md +42 -0
  346. package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/diagram.md +51 -0
  347. package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/index.md +66 -0
  348. package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/input.md +46 -0
  349. package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/outline-template.md +106 -0
  350. package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/plan.md +48 -0
  351. package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/slides.md +40 -0
  352. package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/table.md +42 -0
  353. package/pack/generated/pi/skills/devrites-lib/reference/workspace-artifact-schema.md +267 -0
  354. package/pack/generated/pi/skills/devrites-prose-craft/SKILL.md +73 -0
  355. package/pack/generated/pi/skills/devrites-prose-craft/reference/banned-phrases.md +132 -0
  356. package/pack/generated/pi/skills/devrites-prose-craft/reference/examples.md +131 -0
  357. package/pack/generated/pi/skills/devrites-prose-craft/reference/structures.md +196 -0
  358. package/pack/generated/pi/skills/devrites-source-driven/SKILL.md +52 -0
  359. package/pack/generated/pi/skills/devrites-ux-shape/SKILL.md +134 -0
  360. package/pack/generated/pi/skills/devrites-ux-shape/reference/brief-template.md +108 -0
  361. package/pack/generated/pi/skills/devrites-ux-shape/reference/visual-direction-probe.md +48 -0
  362. package/pack/generated/pi/skills/rite/SKILL.md +148 -0
  363. package/pack/generated/pi/skills/rite/reference/menu.md +48 -0
  364. package/pack/generated/pi/skills/rite-adopt/SKILL.md +52 -0
  365. package/pack/generated/pi/skills/rite-adopt/reference/adoption.md +19 -0
  366. package/pack/generated/pi/skills/rite-adopt/reference/anti-patterns.md +19 -0
  367. package/pack/generated/pi/skills/rite-autocomplete/SKILL.md +132 -0
  368. package/pack/generated/pi/skills/rite-autocomplete/reference/decision-policy.md +41 -0
  369. package/pack/generated/pi/skills/rite-autocomplete/reference/loop.md +148 -0
  370. package/pack/generated/pi/skills/rite-autocomplete/reference/stop-conditions.md +92 -0
  371. package/pack/generated/pi/skills/rite-build/SKILL.md +96 -0
  372. package/pack/generated/pi/skills/rite-build/reference/afk-discipline.md +145 -0
  373. package/pack/generated/pi/skills/rite-build/reference/anti-patterns.md +23 -0
  374. package/pack/generated/pi/skills/rite-build/reference/checkpoint-protocol.md +120 -0
  375. package/pack/generated/pi/skills/rite-build/reference/checkpoint.md +44 -0
  376. package/pack/generated/pi/skills/rite-build/reference/frontend-trigger.md +39 -0
  377. package/pack/generated/pi/skills/rite-build/reference/one-slice-cycle.md +50 -0
  378. package/pack/generated/pi/skills/rite-build/reference/output.md +33 -0
  379. package/pack/generated/pi/skills/rite-build/reference/parallel-batch.md +205 -0
  380. package/pack/generated/pi/skills/rite-build/reference/phase-contract.md +87 -0
  381. package/pack/generated/pi/skills/rite-build/reference/spec-drift-guard.md +84 -0
  382. package/pack/generated/pi/skills/rite-build/reference/tdd.md +27 -0
  383. package/pack/generated/pi/skills/rite-build/reference/wright-dispatch.md +89 -0
  384. package/pack/generated/pi/skills/rite-clarify/SKILL.md +99 -0
  385. package/pack/generated/pi/skills/rite-clarify/reference/anti-patterns.md +24 -0
  386. package/pack/generated/pi/skills/rite-clarify/reference/decision-coverage.md +55 -0
  387. package/pack/generated/pi/skills/rite-converge/SKILL.md +145 -0
  388. package/pack/generated/pi/skills/rite-converge/reference/anti-patterns.md +35 -0
  389. package/pack/generated/pi/skills/rite-converge/reference/convergence-assessment.md +65 -0
  390. package/pack/generated/pi/skills/rite-customize/SKILL.md +60 -0
  391. package/pack/generated/pi/skills/rite-define/SKILL.md +169 -0
  392. package/pack/generated/pi/skills/rite-define/reference/anti-patterns.md +26 -0
  393. package/pack/generated/pi/skills/rite-define/reference/gates.md +154 -0
  394. package/pack/generated/pi/skills/rite-define/reference/plan-template.md +149 -0
  395. package/pack/generated/pi/skills/rite-doctor/SKILL.md +69 -0
  396. package/pack/generated/pi/skills/rite-dogfood/SKILL.md +55 -0
  397. package/pack/generated/pi/skills/rite-explain/SKILL.md +152 -0
  398. package/pack/generated/pi/skills/rite-explain/reference/intake.md +89 -0
  399. package/pack/generated/pi/skills/rite-frame/SKILL.md +115 -0
  400. package/pack/generated/pi/skills/rite-frame/reference/failure-modes.md +66 -0
  401. package/pack/generated/pi/skills/rite-handoff/SKILL.md +97 -0
  402. package/pack/generated/pi/skills/rite-handoff/reference/handoff-template.md +44 -0
  403. package/pack/generated/pi/skills/rite-learn/SKILL.md +72 -0
  404. package/pack/generated/pi/skills/rite-plan/SKILL.md +186 -0
  405. package/pack/generated/pi/skills/rite-plan/reference/anti-patterns.md +34 -0
  406. package/pack/generated/pi/skills/rite-plan/reference/dependency-graph.md +48 -0
  407. package/pack/generated/pi/skills/rite-plan/reference/replan-and-repair.md +105 -0
  408. package/pack/generated/pi/skills/rite-plan/reference/slicing.md +167 -0
  409. package/pack/generated/pi/skills/rite-plan/reference/task-breakdown.md +42 -0
  410. package/pack/generated/pi/skills/rite-polish/SKILL.md +104 -0
  411. package/pack/generated/pi/skills/rite-polish/reference/adr-promotion.md +11 -0
  412. package/pack/generated/pi/skills/rite-polish/reference/anti-ai-slop.md +187 -0
  413. package/pack/generated/pi/skills/rite-polish/reference/anti-patterns.md +30 -0
  414. package/pack/generated/pi/skills/rite-polish/reference/backend-polish.md +80 -0
  415. package/pack/generated/pi/skills/rite-polish/reference/browser-polish-evidence.md +33 -0
  416. package/pack/generated/pi/skills/rite-polish/reference/code.md +82 -0
  417. package/pack/generated/pi/skills/rite-polish/reference/design-memory.md +117 -0
  418. package/pack/generated/pi/skills/rite-polish/reference/design-system-discovery.md +8 -0
  419. package/pack/generated/pi/skills/rite-polish/reference/harden-checklist.md +109 -0
  420. package/pack/generated/pi/skills/rite-polish/reference/ledger.md +65 -0
  421. package/pack/generated/pi/skills/rite-polish/reference/ui.md +137 -0
  422. package/pack/generated/pi/skills/rite-pov/SKILL.md +58 -0
  423. package/pack/generated/pi/skills/rite-pr-feedback/SKILL.md +54 -0
  424. package/pack/generated/pi/skills/rite-pressure-test/SKILL.md +67 -0
  425. package/pack/generated/pi/skills/rite-prototype/SKILL.md +104 -0
  426. package/pack/generated/pi/skills/rite-prove/SKILL.md +120 -0
  427. package/pack/generated/pi/skills/rite-prove/reference/acceptance-proof.md +88 -0
  428. package/pack/generated/pi/skills/rite-prove/reference/anti-patterns.md +25 -0
  429. package/pack/generated/pi/skills/rite-prove/reference/browser-proof.md +51 -0
  430. package/pack/generated/pi/skills/rite-prove/reference/failure-triage.md +43 -0
  431. package/pack/generated/pi/skills/rite-prove/reference/proof-ladder.md +28 -0
  432. package/pack/generated/pi/skills/rite-prove/reference/test-command-discovery.md +30 -0
  433. package/pack/generated/pi/skills/rite-quick/SKILL.md +82 -0
  434. package/pack/generated/pi/skills/rite-resolve/SKILL.md +95 -0
  435. package/pack/generated/pi/skills/rite-resolve/reference/answer-protocol.md +118 -0
  436. package/pack/generated/pi/skills/rite-review/SKILL.md +170 -0
  437. package/pack/generated/pi/skills/rite-review/reference/anti-patterns.md +32 -0
  438. package/pack/generated/pi/skills/rite-review/reference/cognitive-load.md +90 -0
  439. package/pack/generated/pi/skills/rite-review/reference/feature-scoped-review.md +26 -0
  440. package/pack/generated/pi/skills/rite-review/reference/five-axis-review.md +66 -0
  441. package/pack/generated/pi/skills/rite-review/reference/nielsen-heuristics.md +126 -0
  442. package/pack/generated/pi/skills/rite-review/reference/performance-checklist.md +80 -0
  443. package/pack/generated/pi/skills/rite-review/reference/performance-review.md +14 -0
  444. package/pack/generated/pi/skills/rite-review/reference/security-review.md +42 -0
  445. package/pack/generated/pi/skills/rite-seal/SKILL.md +75 -0
  446. package/pack/generated/pi/skills/rite-seal/reference/anti-patterns.md +29 -0
  447. package/pack/generated/pi/skills/rite-seal/reference/final-evidence.md +41 -0
  448. package/pack/generated/pi/skills/rite-seal/reference/go-no-go.md +29 -0
  449. package/pack/generated/pi/skills/rite-seal/reference/output.md +5 -0
  450. package/pack/generated/pi/skills/rite-seal/reference/phase-contract.md +47 -0
  451. package/pack/generated/pi/skills/rite-seal/reference/risk-and-rollback.md +56 -0
  452. package/pack/generated/pi/skills/rite-seal/reference/seal-template.md +27 -0
  453. package/pack/generated/pi/skills/rite-ship/SKILL.md +88 -0
  454. package/pack/generated/pi/skills/rite-ship/reference/anti-patterns.md +28 -0
  455. package/pack/generated/pi/skills/rite-ship/reference/close-out.md +68 -0
  456. package/pack/generated/pi/skills/rite-ship/reference/git-ship.md +120 -0
  457. package/pack/generated/pi/skills/rite-ship/reference/rollout.md +62 -0
  458. package/pack/generated/pi/skills/rite-ship/reference/ship-template.md +39 -0
  459. package/pack/generated/pi/skills/rite-spec/SKILL.md +150 -0
  460. package/pack/generated/pi/skills/rite-spec/reference/acceptance-criteria.md +31 -0
  461. package/pack/generated/pi/skills/rite-spec/reference/ai-spec-template.md +40 -0
  462. package/pack/generated/pi/skills/rite-spec/reference/anti-patterns.md +27 -0
  463. package/pack/generated/pi/skills/rite-spec/reference/interview-patterns.md +56 -0
  464. package/pack/generated/pi/skills/rite-spec/reference/investigation.md +83 -0
  465. package/pack/generated/pi/skills/rite-spec/reference/question-protocol.md +36 -0
  466. package/pack/generated/pi/skills/rite-spec/reference/references-intake.md +62 -0
  467. package/pack/generated/pi/skills/rite-spec/reference/spec-checklists.md +89 -0
  468. package/pack/generated/pi/skills/rite-spec/reference/spec-template.md +154 -0
  469. package/pack/generated/pi/skills/rite-spec/reference/state-workspace.md +227 -0
  470. package/pack/generated/pi/skills/rite-status/SKILL.md +57 -0
  471. package/pack/generated/pi/skills/rite-temper/SKILL.md +130 -0
  472. package/pack/generated/pi/skills/rite-temper/reference/anti-patterns.md +30 -0
  473. package/pack/generated/pi/skills/rite-temper/reference/review-dimensions.md +66 -0
  474. package/pack/generated/pi/skills/rite-temper/reference/scope-modes.md +53 -0
  475. package/pack/generated/pi/skills/rite-temper/reference/significance.md +46 -0
  476. package/pack/generated/pi/skills/rite-temper/reference/strategy-template.md +90 -0
  477. package/pack/generated/pi/skills/rite-upgrade/SKILL.md +121 -0
  478. package/pack/generated/pi/skills/rite-vet/SKILL.md +193 -0
  479. package/pack/generated/pi/skills/rite-vet/reference/anti-patterns.md +43 -0
  480. package/pack/generated/pi/skills/rite-vet/reference/artifacts.md +202 -0
  481. package/pack/generated/pi/skills/rite-vet/reference/cross-model.md +19 -0
  482. package/pack/generated/pi/skills/rite-vet/reference/depth.md +59 -0
  483. package/pack/generated/pi/skills/rite-vet/reference/eng-lenses.md +48 -0
  484. package/pack/generated/pi/skills/rite-vet/reference/review-axes.md +201 -0
  485. package/pack/generated/pi/skills/rite-watch-pr/SKILL.md +85 -0
  486. package/pack/generated/pi/skills/rite-zoom-out/SKILL.md +69 -0
  487. package/package.json +3 -2
  488. package/scripts/build-host-artifacts.sh +54 -4
  489. package/scripts/codex-generate.sh +6 -0
  490. package/scripts/pi-generate.sh +198 -0
@@ -0,0 +1,214 @@
1
+ package lib
2
+
3
+ import (
4
+ "bytes"
5
+ "os"
6
+ "path/filepath"
7
+ "strings"
8
+ "testing"
9
+ )
10
+
11
+ const unionManifest = `# Touched files: SLUG
12
+
13
+ ## Touched files
14
+ SLUG scope.
15
+
16
+ ## Candidate manifest
17
+ | State | File | Slice | Reason |
18
+ | --- | --- | --- | --- |
19
+ ROWS
20
+ ## Review trail
21
+ SLUG trail.
22
+ `
23
+
24
+ func manifestBody(rows ...string) string {
25
+ return strings.Join(rows, "\n") + "\n"
26
+ }
27
+
28
+ func unionWorkspace(t *testing.T, root, slug, rows string, archived bool) {
29
+ t.Helper()
30
+ parent := "work"
31
+ if archived {
32
+ parent = "archive"
33
+ }
34
+ dir := filepath.Join(root, parent, slug)
35
+ if err := os.MkdirAll(dir, 0o755); err != nil {
36
+ t.Fatal(err)
37
+ }
38
+ stateBody := "| phase | seal |\n| schema | 3 |\n"
39
+ if err := os.WriteFile(filepath.Join(dir, "state.md"), []byte(stateBody), 0o644); err != nil {
40
+ t.Fatal(err)
41
+ }
42
+ manifest := strings.ReplaceAll(unionManifest, "SLUG", slug)
43
+ manifest = strings.Replace(manifest, "ROWS\n", rows, 1)
44
+ if err := os.WriteFile(filepath.Join(dir, "touched-files.md"), []byte(manifest), 0o644); err != nil {
45
+ t.Fatal(err)
46
+ }
47
+ }
48
+
49
+ func unionRoot(t *testing.T) string {
50
+ root := filepath.Join(t.TempDir(), ".devrites")
51
+ if err := os.MkdirAll(filepath.Join(root, "work"), 0o755); err != nil {
52
+ t.Fatal(err)
53
+ }
54
+ return root
55
+ }
56
+
57
+ func TestMergeManifestUnionsOrderedPredecessors(t *testing.T) {
58
+ root := unionRoot(t)
59
+ unionWorkspace(t, root, "feat-1", manifestBody(
60
+ "| present | `src/a.ts` | SLICE-001 | Added. |",
61
+ "| present | `src/shared.ts` | SLICE-001 | First write. |",
62
+ ), false)
63
+ unionWorkspace(t, root, "feat-2", manifestBody(
64
+ "| present | `src/b.ts` | SLICE-002 | Added. |",
65
+ "| present | `src/shared.ts` | SLICE-002 | Rewritten. |",
66
+ ), true) // archived predecessor still resolves
67
+ unionWorkspace(t, root, "release", manifestBody(
68
+ "| present | `src/r.ts` | SLICE-001 | Release wiring. |",
69
+ ), false)
70
+
71
+ var stdout, stderr bytes.Buffer
72
+ code := RunMergeManifest(root, []string{"release", "feat-1", "feat-2"}, &stdout, &stderr)
73
+ if code != 0 {
74
+ t.Fatalf("code=%d stderr=%s", code, stderr.String())
75
+ }
76
+ raw, err := os.ReadFile(filepath.Join(root, "work", "release", "touched-files.md"))
77
+ if err != nil {
78
+ t.Fatal(err)
79
+ }
80
+ text := string(raw)
81
+ want := []string{
82
+ "| present | `src/a.ts` | SLICE-001 | Added. |",
83
+ "| present | `src/b.ts` | SLICE-002 | Added. |",
84
+ "| present | `src/r.ts` | SLICE-001 | Release wiring. |",
85
+ "| present | `src/shared.ts` | SLICE-002 | Rewritten. |", // later position wins
86
+ }
87
+ for _, row := range want {
88
+ if !strings.Contains(text, row) {
89
+ t.Fatalf("merged manifest missing %q:\n%s", row, text)
90
+ }
91
+ }
92
+ if strings.Contains(text, "First write.") {
93
+ t.Fatalf("losing collision row survived:\n%s", text)
94
+ }
95
+ if !strings.Contains(text, "## Touched files\nrelease scope.") || !strings.Contains(text, "## Review trail\nrelease trail.") {
96
+ t.Fatalf("non-manifest sections were not preserved:\n%s", text)
97
+ }
98
+ if !strings.Contains(stdout.String(), "collision") {
99
+ t.Fatalf("stdout should report the resolved collision: %q", stdout.String())
100
+ }
101
+ }
102
+
103
+ func TestMergeManifestWalksSequenceChain(t *testing.T) {
104
+ root := unionRoot(t)
105
+ unionWorkspace(t, root, "feat-1", manifestBody("| present | `src/a.ts` | SLICE-001 | Added. |"), false)
106
+ unionWorkspace(t, root, "feat-2", manifestBody(
107
+ "| present | `src/a.ts` | SLICE-002 | Touched again. |",
108
+ "| present | `src/b.ts` | SLICE-002 | Added. |",
109
+ ), false)
110
+ unionWorkspace(t, root, "release", manifestBody("| present | `src/r.ts` | SLICE-001 | Release. |"), false)
111
+ for slug, parent := range map[string]string{"feat-2": "feat-1", "release": "feat-2"} {
112
+ statePath := filepath.Join(root, "work", slug, "state.md")
113
+ raw, _ := os.ReadFile(statePath)
114
+ raw = append(raw, []byte("| sequence_parent | "+parent+" |\n")...)
115
+ if err := os.WriteFile(statePath, raw, 0o644); err != nil {
116
+ t.Fatal(err)
117
+ }
118
+ }
119
+
120
+ var stdout, stderr bytes.Buffer
121
+ if code := RunMergeManifest(root, []string{"release"}, &stdout, &stderr); code != 0 {
122
+ t.Fatalf("chain walk: code=%d stderr=%s", code, stderr.String())
123
+ }
124
+ raw, err := os.ReadFile(filepath.Join(root, "work", "release", "touched-files.md"))
125
+ if err != nil {
126
+ t.Fatal(err)
127
+ }
128
+ text := string(raw)
129
+ for _, row := range []string{
130
+ "| present | `src/a.ts` | SLICE-002 | Touched again. |",
131
+ "| present | `src/b.ts` | SLICE-002 | Added. |",
132
+ "| present | `src/r.ts` | SLICE-001 | Release. |",
133
+ } {
134
+ if !strings.Contains(text, row) {
135
+ t.Fatalf("chain-merged manifest missing %q:\n%s", row, text)
136
+ }
137
+ }
138
+
139
+ // A workspace outside the chain has nothing to walk.
140
+ stderr.Reset()
141
+ unionWorkspace(t, root, "lone", manifestBody("| present | `src/x.ts` | SLICE-001 | Lone. |"), false)
142
+ if code := RunMergeManifest(root, []string{"lone"}, &stdout, &stderr); code != 3 {
143
+ t.Fatalf("no chain: code=%d stderr=%s", code, stderr.String())
144
+ }
145
+ }
146
+
147
+ func TestVerifyReleaseUnionEnforcesChainCoverage(t *testing.T) {
148
+ root := unionRoot(t)
149
+ unionWorkspace(t, root, "feat-1", manifestBody("| present | `src/a.ts` | SLICE-001 | Added. |"), false)
150
+ unionWorkspace(t, root, "release", manifestBody("| present | `src/r.ts` | SLICE-001 | Release. |"), false)
151
+ for slug, extra := range map[string]string{
152
+ "release": "| sequence_parent | feat-1 |\n| sequence_role | release |\n",
153
+ "feat-1": "",
154
+ } {
155
+ if extra == "" {
156
+ continue
157
+ }
158
+ statePath := filepath.Join(root, "work", slug, "state.md")
159
+ raw, _ := os.ReadFile(statePath)
160
+ if err := os.WriteFile(statePath, append(raw, []byte(extra)...), 0o644); err != nil {
161
+ t.Fatal(err)
162
+ }
163
+ }
164
+
165
+ // A release workspace whose manifest misses a predecessor path is blocked.
166
+ if err := VerifyReleaseUnion(root, "release"); err == nil || !strings.Contains(err.Error(), "merge-manifest") {
167
+ t.Fatalf("expected union gap, got %v", err)
168
+ }
169
+ // Workspaces without the role are not checked.
170
+ if err := VerifyReleaseUnion(root, "feat-1"); err != nil {
171
+ t.Fatalf("non-release workspace: %v", err)
172
+ }
173
+
174
+ // After the merge, coverage holds.
175
+ var stdout, stderr bytes.Buffer
176
+ if code := RunMergeManifest(root, []string{"release"}, &stdout, &stderr); code != 0 {
177
+ t.Fatalf("merge: code=%d stderr=%s", code, stderr.String())
178
+ }
179
+ if err := VerifyReleaseUnion(root, "release"); err != nil {
180
+ t.Fatalf("post-merge: %v", err)
181
+ }
182
+ }
183
+
184
+ func TestMergeManifestRejectsParentMismatchAndMissingPredecessor(t *testing.T) {
185
+ root := unionRoot(t)
186
+ unionWorkspace(t, root, "feat-1", manifestBody("| present | `src/a.ts` | SLICE-001 | Added. |"), false)
187
+ unionWorkspace(t, root, "release", manifestBody("| present | `src/r.ts` | SLICE-001 | Release. |"), false)
188
+ statePath := filepath.Join(root, "work", "release", "state.md")
189
+ raw, _ := os.ReadFile(statePath)
190
+ raw = append(raw, []byte("| sequence_parent | feat-1 |\n")...)
191
+ if err := os.WriteFile(statePath, raw, 0o644); err != nil {
192
+ t.Fatal(err)
193
+ }
194
+
195
+ var stdout, stderr bytes.Buffer
196
+ // The recorded parent must be the last predecessor; omitting it blocks.
197
+ if code := RunMergeManifest(root, []string{"release", "other"}, &stdout, &stderr); code != 3 {
198
+ t.Fatalf("parent mismatch: code=%d stderr=%s", code, stderr.String())
199
+ }
200
+ if !strings.Contains(stderr.String(), "sequence_parent") {
201
+ t.Fatalf("stderr=%q", stderr.String())
202
+ }
203
+ stderr.Reset()
204
+ if code := RunMergeManifest(root, []string{"release", "feat-1", "ghost"}, &stdout, &stderr); code != 3 {
205
+ t.Fatalf("missing predecessor: code=%d stderr=%s", code, stderr.String())
206
+ }
207
+ stderr.Reset()
208
+ if code := RunMergeManifest(root, []string{"release", "release", "feat-1"}, &stdout, &stderr); code != 3 {
209
+ t.Fatalf("self predecessor: code=%d", code)
210
+ }
211
+ if code := RunMergeManifest(root, []string{}, &stdout, &stderr); code != 2 {
212
+ t.Fatalf("missing args: code=%d", code)
213
+ }
214
+ }
@@ -0,0 +1,73 @@
1
+ package lib
2
+
3
+ import (
4
+ "os"
5
+ "path/filepath"
6
+ "sort"
7
+
8
+ "github.com/devrites/devrites/internal/state"
9
+ )
10
+
11
+ const bulkFileThreshold = 64 << 10
12
+
13
+ // ArtifactBudget reports one canonical workspace artifact against its budget.
14
+ type ArtifactBudget struct {
15
+ File string `json:"file"`
16
+ Lines int `json:"lines"`
17
+ Bytes int64 `json:"bytes"`
18
+ LineBudget int `json:"line_budget"`
19
+ ByteBudget int64 `json:"byte_budget"`
20
+ Over bool `json:"over"`
21
+ Override bool `json:"override,omitempty"`
22
+ }
23
+
24
+ // BulkFile is a non-canonical regular file in the workspace root above bulkFileThreshold.
25
+ type BulkFile struct {
26
+ File string `json:"file"`
27
+ Bytes int64 `json:"bytes"`
28
+ }
29
+
30
+ // observeArtifactBudgets lists canonical artifacts present in the workspace root with
31
+ // their budget status, plus non-canonical files large enough to hurt a reader.
32
+ func observeArtifactBudgets(workspace string) ([]ArtifactBudget, []BulkFile, error) {
33
+ entries, err := os.ReadDir(workspace)
34
+ if err != nil {
35
+ return nil, nil, err
36
+ }
37
+ var budgets []ArtifactBudget
38
+ var bulk []BulkFile
39
+ for _, entry := range entries {
40
+ if !entry.Type().IsRegular() {
41
+ continue
42
+ }
43
+ info, err := entry.Info()
44
+ if err != nil {
45
+ return nil, nil, err
46
+ }
47
+ name := entry.Name()
48
+ if _, canonical := state.ArtifactLineBudget(name); !canonical {
49
+ if info.Size() > bulkFileThreshold {
50
+ bulk = append(bulk, BulkFile{File: name, Bytes: info.Size()})
51
+ }
52
+ continue
53
+ }
54
+ // #nosec G304 -- canonical workspace artifact name from a fixed table
55
+ raw, err := os.ReadFile(filepath.Join(workspace, name))
56
+ if err != nil {
57
+ return nil, nil, err
58
+ }
59
+ measured, _ := state.ArtifactBudget(name, raw)
60
+ budgets = append(budgets, ArtifactBudget{
61
+ File: name,
62
+ Lines: measured.Lines,
63
+ Bytes: measured.Bytes,
64
+ LineBudget: measured.LineBudget,
65
+ ByteBudget: measured.ByteBudget,
66
+ Over: measured.Over,
67
+ Override: measured.Override,
68
+ })
69
+ }
70
+ sort.Slice(budgets, func(i, j int) bool { return budgets[i].File < budgets[j].File })
71
+ sort.Slice(bulk, func(i, j int) bool { return bulk[i].File < bulk[j].File })
72
+ return budgets, bulk, nil
73
+ }
@@ -0,0 +1,142 @@
1
+ package lib
2
+
3
+ import (
4
+ "bytes"
5
+ "os"
6
+ "path/filepath"
7
+ "strings"
8
+ "testing"
9
+
10
+ "github.com/devrites/devrites/internal/state"
11
+ )
12
+
13
+ const budgetTasks = `# Tasks
14
+
15
+ Current checkpoint: intro text.
16
+
17
+ ## SLICE-001 First
18
+ Goal: one
19
+ Dependencies: none
20
+ depends_on: []
21
+
22
+ ### Notes
23
+ nested heading stays inside the slice
24
+
25
+ ## SLICE-002 Second
26
+ Goal: two
27
+ Dependencies: SLICE-001
28
+ depends_on: [SLICE-001]
29
+
30
+ ## Trailing section
31
+ not a slice
32
+ `
33
+
34
+ func writeBudgetWorkspace(t *testing.T, files map[string]string) (root, workspace string) {
35
+ t.Helper()
36
+ root = filepath.Join(t.TempDir(), ".devrites")
37
+ workspace = filepath.Join(root, "work", "feature")
38
+ if err := os.MkdirAll(workspace, 0o755); err != nil {
39
+ t.Fatal(err)
40
+ }
41
+ for name, body := range files {
42
+ if err := os.WriteFile(filepath.Join(workspace, name), []byte(body), 0o644); err != nil {
43
+ t.Fatal(err)
44
+ }
45
+ }
46
+ return root, workspace
47
+ }
48
+
49
+ func TestExtractTaskSliceStopsAtNextH2AndKeepsH3(t *testing.T) {
50
+ block, ok := state.ExtractTaskSlice([]byte(budgetTasks), "SLICE-001")
51
+ if !ok {
52
+ t.Fatal("expected SLICE-001")
53
+ }
54
+ if !strings.HasPrefix(block, "## SLICE-001 First\n") || !strings.Contains(block, "### Notes") {
55
+ t.Fatalf("block=%q", block)
56
+ }
57
+ if strings.Contains(block, "SLICE-002") || strings.Contains(block, "Trailing") {
58
+ t.Fatalf("block leaked past the next heading: %q", block)
59
+ }
60
+ last, ok := state.ExtractTaskSlice([]byte(budgetTasks), "SLICE-002")
61
+ if !ok || strings.Contains(last, "Trailing section") {
62
+ t.Fatalf("last=%q ok=%v", last, ok)
63
+ }
64
+ if _, ok := state.ExtractTaskSlice([]byte(budgetTasks), "SLICE-003"); ok {
65
+ t.Fatal("SLICE-003 must not resolve")
66
+ }
67
+ }
68
+
69
+ func TestRunObserveSlicePrintsOneSection(t *testing.T) {
70
+ root, _ := writeBudgetWorkspace(t, map[string]string{"tasks.md": budgetTasks})
71
+ var stdout, stderr bytes.Buffer
72
+ if code := RunObserveSlice(root, "feature", "SLICE-002", &stdout, &stderr); code != 0 {
73
+ t.Fatalf("code=%d stderr=%s", code, stderr.String())
74
+ }
75
+ if got := stdout.String(); !strings.HasPrefix(got, "## SLICE-002 Second\n") || strings.Contains(got, "SLICE-001 First") {
76
+ t.Fatalf("stdout=%q", got)
77
+ }
78
+
79
+ stdout.Reset()
80
+ if code := RunObserveSlice(root, "feature", "SLICE-009", &stdout, &stderr); code != 3 || !strings.Contains(stdout.String(), "BLOCKED") {
81
+ t.Fatalf("code=%d stdout=%q", code, stdout.String())
82
+ }
83
+ if code := RunObserveSlice(root, "feature", "slice-1", &stdout, &stderr); code != 2 {
84
+ t.Fatalf("code=%d for malformed id", code)
85
+ }
86
+ }
87
+
88
+ func TestObserveSummaryReportsBudgetsAndBulkFiles(t *testing.T) {
89
+ longLine := strings.Repeat("x", 60_000) + "\n"
90
+ root, _ := writeBudgetWorkspace(t, map[string]string{
91
+ "state.md": "| phase | build |\n| schema | 3 |\n" + longLine,
92
+ "tasks.md": budgetTasks,
93
+ "vet-review-input-1.json": strings.Repeat("{}", 40_000),
94
+ "small-note.json": "{}",
95
+ })
96
+ summary, err := ObserveSummaryFor(root, "feature")
97
+ if err != nil {
98
+ t.Fatal(err)
99
+ }
100
+ byFile := map[string]ArtifactBudget{}
101
+ for _, b := range summary.ArtifactBudgets {
102
+ byFile[b.File] = b
103
+ }
104
+ if st, ok := byFile["state.md"]; !ok || !st.Over || st.Lines != 3 || st.ByteBudget != 120*state.BudgetBytesPerLine {
105
+ t.Fatalf("state.md budget=%+v ok=%v (long line must trip the byte budget)", st, ok)
106
+ }
107
+ if tk, ok := byFile["tasks.md"]; !ok || tk.Over {
108
+ t.Fatalf("tasks.md budget=%+v ok=%v", tk, ok)
109
+ }
110
+ if summary.TaskGraph == nil || len(summary.TaskGraph.Slices) != 2 ||
111
+ summary.TaskGraph.Slices[0].ID != "SLICE-001" || len(summary.TaskGraph.Slices[0].DependsOn) != 0 ||
112
+ summary.TaskGraph.Slices[1].DependsOn[0] != "SLICE-001" {
113
+ t.Fatalf("task_graph.slices=%+v", summary.TaskGraph)
114
+ }
115
+ if len(summary.BulkFiles) != 1 || summary.BulkFiles[0].File != "vet-review-input-1.json" {
116
+ t.Fatalf("bulk_files=%+v", summary.BulkFiles)
117
+ }
118
+ }
119
+
120
+ func TestObserveSummaryReportsSequenceCursor(t *testing.T) {
121
+ root, _ := writeBudgetWorkspace(t, map[string]string{
122
+ "state.md": "| phase | build |\n| schema | 3 |\n| sequence_parent | feat-1 |\n| sequence_position | 2 |\n| sequence_workspaces_remaining | 3 |\n",
123
+ })
124
+ summary, err := ObserveSummaryFor(root, "feature")
125
+ if err != nil {
126
+ t.Fatal(err)
127
+ }
128
+ seq := summary.Sequence
129
+ if seq == nil || seq.Parent != "feat-1" || seq.Position != "2" || seq.WorkspacesRemaining != "3" {
130
+ t.Fatalf("sequence=%+v", seq)
131
+ }
132
+ root, _ = writeBudgetWorkspace(t, map[string]string{
133
+ "state.md": "| phase | build |\n| schema | 3 |\n",
134
+ })
135
+ summary, err = ObserveSummaryFor(root, "feature")
136
+ if err != nil {
137
+ t.Fatal(err)
138
+ }
139
+ if summary.Sequence != nil {
140
+ t.Fatalf("sequence must be absent without cursor fields: %+v", summary.Sequence)
141
+ }
142
+ }
@@ -2,30 +2,50 @@ package lib
2
2
 
3
3
  import (
4
4
  "encoding/json"
5
+ "fmt"
5
6
  "io"
6
7
 
8
+ "github.com/devrites/devrites/internal/devritespaths"
7
9
  "github.com/devrites/devrites/internal/state"
8
10
  )
9
11
 
12
+ // ObserveSlice is one slice's identity and ordering edges, enough for a root to pick
13
+ // the next buildable slice without loading tasks.md.
14
+ type ObserveSlice struct {
15
+ ID string `json:"id"`
16
+ DependsOn []string `json:"depends_on"`
17
+ }
18
+
10
19
  // ObserveTaskGraph is the slice-graph subset of ObserveSummary.
11
20
  type ObserveTaskGraph struct {
12
- SliceCount int `json:"slice_count"`
13
- Cycle []string `json:"cycle,omitempty"`
14
- Unknown []string `json:"unknown_dependencies,omitempty"`
15
- Problems []string `json:"problems,omitempty"`
16
- OK bool `json:"ok"`
21
+ SliceCount int `json:"slice_count"`
22
+ Slices []ObserveSlice `json:"slices,omitempty"`
23
+ Cycle []string `json:"cycle,omitempty"`
24
+ Unknown []string `json:"unknown_dependencies,omitempty"`
25
+ Problems []string `json:"problems,omitempty"`
26
+ OK bool `json:"ok"`
17
27
  }
18
28
 
19
29
  // ObserveSummary is a sanitized, machine-readable workspace snapshot.
30
+ type ObserveSequenceCursor struct {
31
+ Parent string `json:"parent"`
32
+ Position string `json:"position"`
33
+ WorkspacesRemaining string `json:"workspaces_remaining"`
34
+ Role string `json:"role,omitempty"`
35
+ }
36
+
20
37
  type ObserveSummary struct {
21
- Slug string `json:"slug"`
22
- Phase string `json:"phase,omitempty"`
23
- Status string `json:"status,omitempty"`
24
- NextAction string `json:"next_action,omitempty"`
25
- MissingSections []string `json:"missing_sections,omitempty"`
26
- MissingFiles []string `json:"missing_files,omitempty"`
27
- PrinciplesPresent bool `json:"principles_present"`
28
- TaskGraph *ObserveTaskGraph `json:"task_graph,omitempty"`
38
+ Slug string `json:"slug"`
39
+ Phase string `json:"phase,omitempty"`
40
+ Status string `json:"status,omitempty"`
41
+ NextAction string `json:"next_action,omitempty"`
42
+ MissingSections []string `json:"missing_sections,omitempty"`
43
+ MissingFiles []string `json:"missing_files,omitempty"`
44
+ PrinciplesPresent bool `json:"principles_present"`
45
+ TaskGraph *ObserveTaskGraph `json:"task_graph,omitempty"`
46
+ ArtifactBudgets []ArtifactBudget `json:"artifact_budgets,omitempty"`
47
+ BulkFiles []BulkFile `json:"bulk_files,omitempty"`
48
+ Sequence *ObserveSequenceCursor `json:"sequence,omitempty"`
29
49
  }
30
50
 
31
51
  // ObserveSummaryFor builds a summary for one feature slug.
@@ -45,17 +65,58 @@ func ObserveSummaryFor(root, slug string) (ObserveSummary, error) {
45
65
  }
46
66
 
47
67
  if graph, graphErr := CheckTaskGraph(root, slug); graphErr == nil && (len(graph.Slices) > 0 || len(graph.Problems) > 0) {
68
+ slices := make([]ObserveSlice, 0, len(graph.Slices))
69
+ for _, slice := range graph.Slices {
70
+ deps := make([]string, 0, len(slice.Dependencies))
71
+ deps = append(deps, slice.Dependencies...)
72
+ slices = append(slices, ObserveSlice{ID: slice.ID, DependsOn: deps})
73
+ }
48
74
  summary.TaskGraph = &ObserveTaskGraph{
49
75
  SliceCount: len(graph.Slices),
76
+ Slices: slices,
50
77
  Cycle: append([]string(nil), graph.Cycle...),
51
78
  Unknown: append([]string(nil), graph.Unknown...),
52
79
  Problems: append([]string(nil), graph.Problems...),
53
80
  OK: len(graph.Problems) == 0,
54
81
  }
55
82
  }
83
+ if report.SequenceParent != "" || report.SequencePosition != "" || report.SequenceWorkspacesRemaining != "" || report.SequenceRole != "" {
84
+ summary.Sequence = &ObserveSequenceCursor{
85
+ Parent: report.SequenceParent,
86
+ Position: report.SequencePosition,
87
+ WorkspacesRemaining: report.SequenceWorkspacesRemaining,
88
+ Role: report.SequenceRole,
89
+ }
90
+ }
91
+ if workspace, wsErr := devritespaths.ExistingFeatureDirChecked(root, slug); wsErr == nil {
92
+ if budgets, bulk, budgetErr := observeArtifactBudgets(workspace); budgetErr == nil {
93
+ summary.ArtifactBudgets = budgets
94
+ summary.BulkFiles = bulk
95
+ }
96
+ }
56
97
  return summary, nil
57
98
  }
58
99
 
100
+ // RunObserveSlice prints one SLICE-### section of tasks.md for a slug.
101
+ func RunObserveSlice(root, slug, id string, stdout, stderr io.Writer) int {
102
+ if !state.ValidSliceID(id) {
103
+ fmt.Fprintf(stderr, "observe slice: %q is not a SLICE-### id\n", id)
104
+ return 2
105
+ }
106
+ raw, err := readWorkspaceArtifact(root, slug, "tasks.md")
107
+ if err != nil {
108
+ fmt.Fprintf(stderr, "observe slice: %v\n", err)
109
+ return 2
110
+ }
111
+ block, ok := state.ExtractTaskSlice(raw, id)
112
+ if !ok {
113
+ fmt.Fprintf(stdout, "observe slice: BLOCKED: %s not found in tasks.md\n", id)
114
+ return 3
115
+ }
116
+ fmt.Fprint(stdout, block)
117
+ return 0
118
+ }
119
+
59
120
  func missingSectionNames(sections []state.Section) []string {
60
121
  if len(sections) == 0 {
61
122
  return nil
@@ -8,23 +8,28 @@ import (
8
8
  "github.com/devrites/devrites/internal/devritespaths"
9
9
  )
10
10
 
11
+ // workspaceArtifactLimit bounds one artifact read. Slice extraction must keep
12
+ // working on a workspace whose tasks.md is over budget: the budget gate flags the
13
+ // file, while Build still reads its own slice instead of the whole document.
14
+ const workspaceArtifactLimit = 16 << 20
15
+
11
16
  func readWorkspaceArtifact(root, slug, name string) ([]byte, error) {
12
17
  workspace, err := devritespaths.ExistingFeatureDirChecked(root, slug)
13
18
  if err != nil {
14
- return nil, fmt.Errorf("task-graph: workspace unavailable: %w", err)
19
+ return nil, fmt.Errorf("workspace artifact: workspace unavailable: %w", err)
15
20
  }
16
21
  path := filepath.Join(workspace, name)
17
22
  info, err := os.Stat(path)
18
23
  if err != nil {
19
- return nil, fmt.Errorf("task-graph: %s unavailable: %w", name, err)
24
+ return nil, fmt.Errorf("workspace artifact: %s unavailable: %w", name, err)
20
25
  }
21
- if info.Size() > 1<<20 {
22
- return nil, fmt.Errorf("task-graph: %s exceeds 1 MiB limit", name)
26
+ if info.Size() > workspaceArtifactLimit {
27
+ return nil, fmt.Errorf("workspace artifact: %s exceeds %d MiB limit", name, workspaceArtifactLimit>>20)
23
28
  }
24
- // #nosec G304 -- workspace task-graph file; 1 MiB cap checked above
29
+ // #nosec G304 -- workspace artifact; size cap checked above
25
30
  raw, err := os.ReadFile(path)
26
31
  if err != nil {
27
- return nil, fmt.Errorf("task-graph: cannot read %s: %w", name, err)
32
+ return nil, fmt.Errorf("workspace artifact: cannot read %s: %w", name, err)
28
33
  }
29
34
  return raw, nil
30
35
  }