devrites 5.14.3 → 6.0.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 (716) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/NOTICE.md +6 -4
  3. package/README.md +77 -16
  4. package/SECURITY.md +25 -11
  5. package/bin/devrites.mjs +49 -15
  6. package/docs/adr/0001-go-engine-as-control-plane.md +6 -3
  7. package/docs/adr/0029-v5-workspace-schema-and-native-migration.md +9 -0
  8. package/docs/adr/README.md +3 -2
  9. package/docs/agents/issue-tracker.md +1 -1
  10. package/docs/architecture.md +6 -3
  11. package/docs/cli.md +32 -9
  12. package/docs/command-map.md +5 -3
  13. package/docs/engine/state-schema.md +1 -1
  14. package/docs/flow.md +1 -1
  15. package/docs/harness-compliance.md +2 -2
  16. package/docs/release.md +15 -11
  17. package/docs/usage.md +1 -1
  18. package/engine/commands.go +1 -1
  19. package/engine/go.mod +1 -1
  20. package/engine/help.go +41 -15
  21. package/engine/help_test.go +134 -0
  22. package/engine/internal/acceptance/acceptance_test.go +298 -7
  23. package/engine/internal/acceptance/approve.go +7 -2
  24. package/engine/internal/acceptance/cli.go +3 -0
  25. package/engine/internal/acceptance/evidence.go +69 -5
  26. package/engine/internal/acceptance/lint.go +1 -1
  27. package/engine/internal/acceptance/run.go +5 -3
  28. package/engine/internal/acceptance/scaffold.go +5 -16
  29. package/engine/internal/devritespaths/paths.go +7 -6
  30. package/engine/internal/devritespaths/paths_test.go +18 -0
  31. package/engine/internal/fsutil/copy.go +83 -49
  32. package/engine/internal/fsutil/copy_test.go +70 -109
  33. package/engine/internal/gate/gate.go +89 -16
  34. package/engine/internal/gate/gate_test.go +101 -0
  35. package/engine/internal/hostpack/hostpack.go +52 -2
  36. package/engine/internal/hostpack/hostpack_test.go +83 -2
  37. package/engine/internal/install/apply.go +59 -16
  38. package/engine/internal/install/binary.go +10 -1
  39. package/engine/internal/install/install_test.go +428 -0
  40. package/engine/internal/install/merge.go +69 -38
  41. package/engine/internal/install/preflight.go +7 -0
  42. package/engine/internal/install/uninstall.go +43 -4
  43. package/engine/internal/lib/claims.go +25 -4
  44. package/engine/internal/lib/claims_test.go +57 -0
  45. package/engine/internal/lib/closeout.go +41 -3
  46. package/engine/internal/lib/closeout_test.go +144 -0
  47. package/engine/internal/lib/context.go +8 -4
  48. package/engine/internal/lib/context_next_test.go +100 -0
  49. package/engine/internal/lib/detect.go +1 -1
  50. package/engine/internal/lib/detect_test.go +13 -0
  51. package/engine/internal/lib/diffscope.go +19 -9
  52. package/engine/internal/lib/dispatch.go +7 -0
  53. package/engine/internal/lib/dup.go +40 -37
  54. package/engine/internal/lib/dup_test.go +178 -0
  55. package/engine/internal/lib/manifest_union.go +4 -1
  56. package/engine/internal/lib/manifest_union_test.go +37 -0
  57. package/engine/internal/lib/metrics.go +4 -0
  58. package/engine/internal/lib/metrics_test.go +28 -0
  59. package/engine/internal/lib/migrate_test.go +59 -0
  60. package/engine/internal/lib/observe_budgets.go +25 -9
  61. package/engine/internal/lib/observe_budgets_test.go +254 -0
  62. package/engine/internal/lib/observe_summary.go +23 -2
  63. package/engine/internal/lib/open_visual.go +4 -2
  64. package/engine/internal/lib/open_visual_test.go +11 -0
  65. package/engine/internal/lib/regression.go +62 -23
  66. package/engine/internal/lib/regression_test.go +103 -0
  67. package/engine/internal/lib/resolve.go +36 -17
  68. package/engine/internal/lib/resolve_remediation_test.go +132 -0
  69. package/engine/internal/lib/skilltrust.go +0 -11
  70. package/engine/internal/lib/slicecheck.go +7 -5
  71. package/engine/internal/lib/slicecheck_test.go +18 -0
  72. package/engine/internal/lib/triggers.go +9 -3
  73. package/engine/internal/lib/triggers_test.go +23 -0
  74. package/engine/internal/lib/util.go +17 -3
  75. package/engine/internal/lib/util_test.go +104 -0
  76. package/engine/internal/lib/visual_outline.go +7 -3
  77. package/engine/internal/lib/visual_outline_test.go +28 -0
  78. package/engine/internal/lib/windows.go +13 -9
  79. package/engine/internal/lib/windows_test.go +98 -0
  80. package/engine/internal/lib/workspace_read.go +2 -11
  81. package/engine/internal/lib/workspace_read_test.go +102 -0
  82. package/engine/internal/markdowntext/markdowntext.go +194 -11
  83. package/engine/internal/markdowntext/testdata/structural.json +250 -0
  84. package/engine/internal/notes/cli.go +30 -12
  85. package/engine/internal/notes/notes.go +242 -39
  86. package/engine/internal/notes/notes_test.go +372 -0
  87. package/engine/internal/overhaul/admit/packet.go +89 -0
  88. package/engine/internal/overhaul/admit/packet_test.go +223 -0
  89. package/engine/internal/overhaul/admit/run.go +4 -0
  90. package/engine/internal/overhaul/bench/run.go +6 -0
  91. package/engine/internal/overhaul/bench/run_test.go +46 -0
  92. package/engine/internal/overhaul/overhaul.go +6 -1
  93. package/engine/internal/overhaul/ovio/ovio.go +10 -3
  94. package/engine/internal/overhaul/ovio/ovio_test.go +75 -0
  95. package/engine/internal/overhaul/packet/packet.go +208 -0
  96. package/engine/internal/overhaul/packet/packet_test.go +263 -0
  97. package/engine/internal/overhaul/records/check.go +6 -0
  98. package/engine/internal/overhaul/records/init.go +16 -5
  99. package/engine/internal/overhaul/records/records_test.go +4 -0
  100. package/engine/internal/overhaul/records/run.go +66 -0
  101. package/engine/internal/overhaul/records/run_test.go +77 -0
  102. package/engine/internal/overhaul/render/run.go +15 -11
  103. package/engine/internal/overhaul/render/run_test.go +463 -1
  104. package/engine/internal/overhaul/render/visual.go +95 -33
  105. package/engine/internal/overhaul/score/run.go +20 -0
  106. package/engine/internal/overhaul/score/run_test.go +156 -1
  107. package/engine/internal/overhaul/snapshot/run.go +78 -21
  108. package/engine/internal/overhaul/snapshot/run_test.go +344 -8
  109. package/engine/internal/parallel/cli.go +33 -20
  110. package/engine/internal/parallel/cli_test.go +59 -0
  111. package/engine/internal/parallel/git.go +39 -1
  112. package/engine/internal/parallel/ops.go +101 -11
  113. package/engine/internal/parallel/ops_test.go +552 -69
  114. package/engine/internal/parallel/parallel_test.go +31 -1
  115. package/engine/internal/parallel/pathdisjoint.go +19 -1
  116. package/engine/internal/parallel/pathdisjoint_test.go +72 -0
  117. package/engine/internal/parallel/select.go +6 -2
  118. package/engine/internal/release/release.go +13 -3
  119. package/engine/internal/release/release_test.go +208 -3
  120. package/engine/internal/rootfacts/facts.go +9 -0
  121. package/engine/internal/rootfacts/facts_test.go +38 -0
  122. package/engine/internal/state/acceptance.go +7 -1
  123. package/engine/internal/state/budgets.go +11 -10
  124. package/engine/internal/state/budgets_test.go +93 -0
  125. package/engine/internal/state/cursor.go +19 -8
  126. package/engine/internal/state/cursor_test.go +120 -0
  127. package/engine/internal/state/lock_unix.go +7 -1
  128. package/engine/internal/state/lock_windows.go +7 -1
  129. package/engine/internal/state/state_test.go +49 -18
  130. package/engine/internal/state/taskgraph.go +18 -4
  131. package/engine/internal/state/taskgraph_test.go +43 -0
  132. package/engine/internal/state/workspaceschema.go +16 -2
  133. package/engine/internal/state/workspaceschema_test.go +34 -0
  134. package/engine/internal/state/write.go +67 -6
  135. package/engine/internal/state/write_test.go +136 -0
  136. package/engine/internal/version/version_test.go +2 -0
  137. package/engine/main.go +8 -1
  138. package/engine/observation_contract_test.go +1 -1
  139. package/engine/root_routing_test.go +23 -1
  140. package/install.sh +132 -12
  141. package/pack/.claude/agents/_shared/result-admission.md +3 -1
  142. package/pack/.claude/agents/devrites-code-reviewer.md +3 -2
  143. package/pack/.claude/agents/devrites-doubt-reviewer.md +4 -2
  144. package/pack/.claude/agents/devrites-spec-reviewer.md +5 -4
  145. package/pack/.claude/skills/devrites-browser-proof/SKILL.md +2 -2
  146. package/pack/.claude/skills/devrites-frontend-craft/reference/design-references.md +18 -18
  147. package/pack/.claude/skills/devrites-frontend-craft/reference/quality-standards.md +6 -4
  148. package/pack/.claude/skills/devrites-interview/SKILL.md +4 -4
  149. package/pack/.claude/skills/devrites-lib/reference/parallel-dispatch.md +1 -1
  150. package/pack/.claude/skills/devrites-lib/reference/standards/afk-hitl.md +11 -3
  151. package/pack/.claude/skills/devrites-lib/reference/standards/agents.md +3 -2
  152. package/pack/.claude/skills/devrites-lib/reference/standards/gates.md +6 -5
  153. package/pack/.claude/skills/devrites-lib/reference/standards/spec-grammar.md +1 -1
  154. package/pack/.claude/skills/devrites-lib/reference/standards/verification-methods.md +3 -3
  155. package/pack/.claude/skills/devrites-lib/reference/standards/windows.md +3 -3
  156. package/pack/.claude/skills/devrites-lib/reference/standards/workflow-artifacts.md +2 -2
  157. package/pack/.claude/skills/devrites-lib/reference/visual-playbooks/outline-template.md +1 -1
  158. package/pack/.claude/skills/devrites-lib/reference/workspace-artifact-schema.md +4 -4
  159. package/pack/.claude/skills/devrites-ux-shape/SKILL.md +11 -12
  160. package/pack/.claude/skills/devrites-ux-shape/reference/visual-direction-probe.md +3 -1
  161. package/pack/.claude/skills/overhaul/SKILL.md +1 -1
  162. package/pack/.claude/skills/overhaul/references/orchestration.md +5 -3
  163. package/pack/.claude/skills/overhaul/references/records.md +39 -0
  164. package/pack/.claude/skills/overhaul/references/scoring.md +14 -4
  165. package/pack/.claude/skills/rite/reference/menu.md +1 -1
  166. package/pack/.claude/skills/rite-adopt/SKILL.md +8 -2
  167. package/pack/.claude/skills/rite-autocomplete/SKILL.md +12 -7
  168. package/pack/.claude/skills/rite-autocomplete/reference/decision-policy.md +3 -2
  169. package/pack/.claude/skills/rite-autocomplete/reference/loop.md +3 -3
  170. package/pack/.claude/skills/rite-autocomplete/reference/stop-conditions.md +6 -3
  171. package/pack/.claude/skills/rite-build/SKILL.md +2 -1
  172. package/pack/.claude/skills/rite-build/reference/afk-discipline.md +1 -1
  173. package/pack/.claude/skills/rite-build/reference/checkpoint-protocol.md +1 -1
  174. package/pack/.claude/skills/rite-build/reference/checkpoint.md +5 -0
  175. package/pack/.claude/skills/rite-build/reference/parallel-batch.md +2 -2
  176. package/pack/.claude/skills/rite-build/reference/wright-dispatch.md +3 -2
  177. package/pack/.claude/skills/rite-clarify/SKILL.md +5 -4
  178. package/pack/.claude/skills/rite-clarify/reference/anti-patterns.md +2 -2
  179. package/pack/.claude/skills/rite-clarify/reference/decision-coverage.md +3 -2
  180. package/pack/.claude/skills/rite-converge/SKILL.md +2 -0
  181. package/pack/.claude/skills/rite-customize/SKILL.md +6 -4
  182. package/pack/.claude/skills/rite-define/SKILL.md +2 -0
  183. package/pack/.claude/skills/rite-define/reference/gates.md +8 -7
  184. package/pack/.claude/skills/rite-explain/SKILL.md +1 -1
  185. package/pack/.claude/skills/rite-explain/reference/intake.md +1 -1
  186. package/pack/.claude/skills/rite-fast/SKILL.md +1 -1
  187. package/pack/.claude/skills/rite-plan/SKILL.md +4 -3
  188. package/pack/.claude/skills/rite-plan/reference/replan-and-repair.md +4 -4
  189. package/pack/.claude/skills/rite-plan/reference/slicing.md +3 -3
  190. package/pack/.claude/skills/rite-polish/reference/anti-ai-slop.md +1 -1
  191. package/pack/.claude/skills/rite-prove/reference/browser-proof.md +5 -5
  192. package/pack/.claude/skills/rite-resolve/SKILL.md +3 -3
  193. package/pack/.claude/skills/rite-seal/SKILL.md +4 -3
  194. package/pack/.claude/skills/rite-seal/reference/phase-contract.md +3 -2
  195. package/pack/.claude/skills/rite-seal/reference/seal-template.md +2 -0
  196. package/pack/.claude/skills/rite-ship/SKILL.md +4 -2
  197. package/pack/.claude/skills/rite-ship/reference/git-ship.md +8 -2
  198. package/pack/.claude/skills/rite-ship/reference/ship-template.md +2 -1
  199. package/pack/.claude/skills/rite-spec/SKILL.md +2 -2
  200. package/pack/.claude/skills/rite-spec/reference/spec-checklists.md +1 -1
  201. package/pack/.claude/skills/rite-spec/reference/spec-template.md +7 -3
  202. package/pack/.claude/skills/rite-spec/reference/state-workspace.md +2 -0
  203. package/pack/.claude/skills/rite-temper/SKILL.md +14 -11
  204. package/pack/.claude/skills/rite-temper/reference/scope-modes.md +1 -1
  205. package/pack/.claude/skills/rite-temper/reference/significance.md +10 -3
  206. package/pack/.claude/skills/rite-temper/reference/strategy-template.md +13 -2
  207. package/pack/.claude/skills/rite-vet/SKILL.md +4 -3
  208. package/pack/.claude/skills/rite-vet/reference/artifacts.md +1 -1
  209. package/pack/.claude/workflows/devrites-readonly-review.js +5 -4
  210. package/pack/generated/claude/agents/devrites-code-reviewer.md +6 -3
  211. package/pack/generated/claude/agents/devrites-devex-reviewer.md +3 -1
  212. package/pack/generated/claude/agents/devrites-doubt-reviewer.md +7 -3
  213. package/pack/generated/claude/agents/devrites-evidence-scout.md +3 -1
  214. package/pack/generated/claude/agents/devrites-frontend-reviewer.md +3 -1
  215. package/pack/generated/claude/agents/devrites-performance-reviewer.md +3 -1
  216. package/pack/generated/claude/agents/devrites-plan-reviewer.md +3 -1
  217. package/pack/generated/claude/agents/devrites-proof-runner.md +3 -1
  218. package/pack/generated/claude/agents/devrites-retrospector.md +3 -1
  219. package/pack/generated/claude/agents/devrites-security-auditor.md +3 -1
  220. package/pack/generated/claude/agents/devrites-simplifier-reviewer.md +3 -1
  221. package/pack/generated/claude/agents/devrites-spec-reviewer.md +8 -5
  222. package/pack/generated/claude/agents/devrites-strategy-reviewer.md +3 -1
  223. package/pack/generated/claude/agents/devrites-test-analyst.md +3 -1
  224. package/pack/generated/claude/agents/devrites-upgrade-planner.md +3 -1
  225. package/pack/generated/claude/skills/devrites-browser-proof/SKILL.md +2 -2
  226. package/pack/generated/claude/skills/devrites-frontend-craft/reference/design-references.md +18 -18
  227. package/pack/generated/claude/skills/devrites-frontend-craft/reference/quality-standards.md +6 -4
  228. package/pack/generated/claude/skills/devrites-interview/SKILL.md +4 -4
  229. package/pack/generated/claude/skills/devrites-lib/reference/parallel-dispatch.md +1 -1
  230. package/pack/generated/claude/skills/devrites-lib/reference/standards/afk-hitl.md +11 -3
  231. package/pack/generated/claude/skills/devrites-lib/reference/standards/agents.md +3 -2
  232. package/pack/generated/claude/skills/devrites-lib/reference/standards/gates.md +6 -5
  233. package/pack/generated/claude/skills/devrites-lib/reference/standards/spec-grammar.md +1 -1
  234. package/pack/generated/claude/skills/devrites-lib/reference/standards/verification-methods.md +3 -3
  235. package/pack/generated/claude/skills/devrites-lib/reference/standards/windows.md +3 -3
  236. package/pack/generated/claude/skills/devrites-lib/reference/standards/workflow-artifacts.md +2 -2
  237. package/pack/generated/claude/skills/devrites-lib/reference/visual-playbooks/outline-template.md +1 -1
  238. package/pack/generated/claude/skills/devrites-lib/reference/workspace-artifact-schema.md +4 -4
  239. package/pack/generated/claude/skills/devrites-ux-shape/SKILL.md +11 -12
  240. package/pack/generated/claude/skills/devrites-ux-shape/reference/visual-direction-probe.md +3 -1
  241. package/pack/generated/claude/skills/overhaul/SKILL.md +1 -1
  242. package/pack/generated/claude/skills/overhaul/references/orchestration.md +5 -3
  243. package/pack/generated/claude/skills/overhaul/references/records.md +39 -0
  244. package/pack/generated/claude/skills/overhaul/references/scoring.md +14 -4
  245. package/pack/generated/claude/skills/rite/reference/menu.md +1 -1
  246. package/pack/generated/claude/skills/rite-adopt/SKILL.md +8 -2
  247. package/pack/generated/claude/skills/rite-autocomplete/SKILL.md +12 -7
  248. package/pack/generated/claude/skills/rite-autocomplete/reference/decision-policy.md +3 -2
  249. package/pack/generated/claude/skills/rite-autocomplete/reference/loop.md +3 -3
  250. package/pack/generated/claude/skills/rite-autocomplete/reference/stop-conditions.md +6 -3
  251. package/pack/generated/claude/skills/rite-build/SKILL.md +2 -1
  252. package/pack/generated/claude/skills/rite-build/reference/afk-discipline.md +1 -1
  253. package/pack/generated/claude/skills/rite-build/reference/checkpoint-protocol.md +1 -1
  254. package/pack/generated/claude/skills/rite-build/reference/checkpoint.md +5 -0
  255. package/pack/generated/claude/skills/rite-build/reference/parallel-batch.md +2 -2
  256. package/pack/generated/claude/skills/rite-build/reference/wright-dispatch.md +3 -2
  257. package/pack/generated/claude/skills/rite-clarify/SKILL.md +5 -4
  258. package/pack/generated/claude/skills/rite-clarify/reference/anti-patterns.md +2 -2
  259. package/pack/generated/claude/skills/rite-clarify/reference/decision-coverage.md +3 -2
  260. package/pack/generated/claude/skills/rite-converge/SKILL.md +2 -0
  261. package/pack/generated/claude/skills/rite-customize/SKILL.md +6 -4
  262. package/pack/generated/claude/skills/rite-define/SKILL.md +2 -0
  263. package/pack/generated/claude/skills/rite-define/reference/gates.md +8 -7
  264. package/pack/generated/claude/skills/rite-explain/SKILL.md +1 -1
  265. package/pack/generated/claude/skills/rite-explain/reference/intake.md +1 -1
  266. package/pack/generated/claude/skills/rite-fast/SKILL.md +1 -1
  267. package/pack/generated/claude/skills/rite-plan/SKILL.md +4 -3
  268. package/pack/generated/claude/skills/rite-plan/reference/replan-and-repair.md +4 -4
  269. package/pack/generated/claude/skills/rite-plan/reference/slicing.md +3 -3
  270. package/pack/generated/claude/skills/rite-polish/reference/anti-ai-slop.md +1 -1
  271. package/pack/generated/claude/skills/rite-prove/reference/browser-proof.md +5 -5
  272. package/pack/generated/claude/skills/rite-resolve/SKILL.md +3 -3
  273. package/pack/generated/claude/skills/rite-seal/SKILL.md +4 -3
  274. package/pack/generated/claude/skills/rite-seal/reference/phase-contract.md +3 -2
  275. package/pack/generated/claude/skills/rite-seal/reference/seal-template.md +2 -0
  276. package/pack/generated/claude/skills/rite-ship/SKILL.md +4 -2
  277. package/pack/generated/claude/skills/rite-ship/reference/git-ship.md +8 -2
  278. package/pack/generated/claude/skills/rite-ship/reference/ship-template.md +2 -1
  279. package/pack/generated/claude/skills/rite-spec/SKILL.md +2 -2
  280. package/pack/generated/claude/skills/rite-spec/reference/spec-checklists.md +1 -1
  281. package/pack/generated/claude/skills/rite-spec/reference/spec-template.md +7 -3
  282. package/pack/generated/claude/skills/rite-spec/reference/state-workspace.md +2 -0
  283. package/pack/generated/claude/skills/rite-temper/SKILL.md +14 -11
  284. package/pack/generated/claude/skills/rite-temper/reference/scope-modes.md +1 -1
  285. package/pack/generated/claude/skills/rite-temper/reference/significance.md +10 -3
  286. package/pack/generated/claude/skills/rite-temper/reference/strategy-template.md +13 -2
  287. package/pack/generated/claude/skills/rite-vet/SKILL.md +4 -3
  288. package/pack/generated/claude/skills/rite-vet/reference/artifacts.md +1 -1
  289. package/pack/generated/claude/workflows/devrites-readonly-review.js +5 -4
  290. package/pack/generated/codex/AGENTS.md +1 -1
  291. package/pack/generated/codex/agents/devrites-code-reviewer.toml +6 -3
  292. package/pack/generated/codex/agents/devrites-devex-reviewer.toml +3 -1
  293. package/pack/generated/codex/agents/devrites-doubt-reviewer.toml +7 -3
  294. package/pack/generated/codex/agents/devrites-evidence-scout.toml +3 -1
  295. package/pack/generated/codex/agents/devrites-frontend-reviewer.toml +3 -1
  296. package/pack/generated/codex/agents/devrites-performance-reviewer.toml +3 -1
  297. package/pack/generated/codex/agents/devrites-plan-reviewer.toml +3 -1
  298. package/pack/generated/codex/agents/devrites-proof-runner.toml +3 -1
  299. package/pack/generated/codex/agents/devrites-retrospector.toml +3 -1
  300. package/pack/generated/codex/agents/devrites-security-auditor.toml +3 -1
  301. package/pack/generated/codex/agents/devrites-simplifier-reviewer.toml +3 -1
  302. package/pack/generated/codex/agents/devrites-spec-reviewer.toml +8 -5
  303. package/pack/generated/codex/agents/devrites-strategy-reviewer.toml +3 -1
  304. package/pack/generated/codex/agents/devrites-test-analyst.toml +3 -1
  305. package/pack/generated/codex/agents/devrites-upgrade-planner.toml +3 -1
  306. package/pack/generated/codex/skills/devrites-browser-proof/SKILL.md +2 -2
  307. package/pack/generated/codex/skills/devrites-frontend-craft/reference/design-references.md +18 -18
  308. package/pack/generated/codex/skills/devrites-frontend-craft/reference/quality-standards.md +6 -4
  309. package/pack/generated/codex/skills/devrites-interview/SKILL.md +4 -4
  310. package/pack/generated/codex/skills/devrites-lib/reference/parallel-dispatch.md +1 -1
  311. package/pack/generated/codex/skills/devrites-lib/reference/standards/afk-hitl.md +11 -3
  312. package/pack/generated/codex/skills/devrites-lib/reference/standards/agents.md +3 -2
  313. package/pack/generated/codex/skills/devrites-lib/reference/standards/gates.md +6 -5
  314. package/pack/generated/codex/skills/devrites-lib/reference/standards/spec-grammar.md +1 -1
  315. package/pack/generated/codex/skills/devrites-lib/reference/standards/verification-methods.md +3 -3
  316. package/pack/generated/codex/skills/devrites-lib/reference/standards/windows.md +3 -3
  317. package/pack/generated/codex/skills/devrites-lib/reference/standards/workflow-artifacts.md +2 -2
  318. package/pack/generated/codex/skills/devrites-lib/reference/visual-playbooks/outline-template.md +1 -1
  319. package/pack/generated/codex/skills/devrites-lib/reference/workspace-artifact-schema.md +4 -4
  320. package/pack/generated/codex/skills/devrites-ux-shape/SKILL.md +11 -12
  321. package/pack/generated/codex/skills/devrites-ux-shape/reference/visual-direction-probe.md +3 -1
  322. package/pack/generated/codex/skills/overhaul/SKILL.md +1 -1
  323. package/pack/generated/codex/skills/overhaul/references/orchestration.md +5 -3
  324. package/pack/generated/codex/skills/overhaul/references/records.md +39 -0
  325. package/pack/generated/codex/skills/overhaul/references/scoring.md +14 -4
  326. package/pack/generated/codex/skills/rite/reference/menu.md +1 -1
  327. package/pack/generated/codex/skills/rite-adopt/SKILL.md +8 -2
  328. package/pack/generated/codex/skills/rite-autocomplete/SKILL.md +12 -7
  329. package/pack/generated/codex/skills/rite-autocomplete/reference/decision-policy.md +3 -2
  330. package/pack/generated/codex/skills/rite-autocomplete/reference/loop.md +3 -3
  331. package/pack/generated/codex/skills/rite-autocomplete/reference/stop-conditions.md +6 -3
  332. package/pack/generated/codex/skills/rite-build/SKILL.md +2 -1
  333. package/pack/generated/codex/skills/rite-build/reference/afk-discipline.md +1 -1
  334. package/pack/generated/codex/skills/rite-build/reference/checkpoint-protocol.md +1 -1
  335. package/pack/generated/codex/skills/rite-build/reference/checkpoint.md +5 -0
  336. package/pack/generated/codex/skills/rite-build/reference/parallel-batch.md +2 -2
  337. package/pack/generated/codex/skills/rite-build/reference/wright-dispatch.md +3 -2
  338. package/pack/generated/codex/skills/rite-clarify/SKILL.md +5 -4
  339. package/pack/generated/codex/skills/rite-clarify/reference/anti-patterns.md +2 -2
  340. package/pack/generated/codex/skills/rite-clarify/reference/decision-coverage.md +3 -2
  341. package/pack/generated/codex/skills/rite-converge/SKILL.md +2 -0
  342. package/pack/generated/codex/skills/rite-customize/SKILL.md +6 -4
  343. package/pack/generated/codex/skills/rite-define/SKILL.md +2 -0
  344. package/pack/generated/codex/skills/rite-define/reference/gates.md +8 -7
  345. package/pack/generated/codex/skills/rite-explain/SKILL.md +1 -1
  346. package/pack/generated/codex/skills/rite-explain/reference/intake.md +1 -1
  347. package/pack/generated/codex/skills/rite-fast/SKILL.md +1 -1
  348. package/pack/generated/codex/skills/rite-plan/SKILL.md +4 -3
  349. package/pack/generated/codex/skills/rite-plan/reference/replan-and-repair.md +4 -4
  350. package/pack/generated/codex/skills/rite-plan/reference/slicing.md +3 -3
  351. package/pack/generated/codex/skills/rite-polish/reference/anti-ai-slop.md +1 -1
  352. package/pack/generated/codex/skills/rite-prove/reference/browser-proof.md +5 -5
  353. package/pack/generated/codex/skills/rite-resolve/SKILL.md +3 -3
  354. package/pack/generated/codex/skills/rite-seal/SKILL.md +4 -3
  355. package/pack/generated/codex/skills/rite-seal/reference/phase-contract.md +3 -2
  356. package/pack/generated/codex/skills/rite-seal/reference/seal-template.md +2 -0
  357. package/pack/generated/codex/skills/rite-ship/SKILL.md +4 -2
  358. package/pack/generated/codex/skills/rite-ship/reference/git-ship.md +8 -2
  359. package/pack/generated/codex/skills/rite-ship/reference/ship-template.md +2 -1
  360. package/pack/generated/codex/skills/rite-spec/SKILL.md +2 -2
  361. package/pack/generated/codex/skills/rite-spec/reference/spec-checklists.md +1 -1
  362. package/pack/generated/codex/skills/rite-spec/reference/spec-template.md +7 -3
  363. package/pack/generated/codex/skills/rite-spec/reference/state-workspace.md +2 -0
  364. package/pack/generated/codex/skills/rite-temper/SKILL.md +14 -11
  365. package/pack/generated/codex/skills/rite-temper/reference/scope-modes.md +1 -1
  366. package/pack/generated/codex/skills/rite-temper/reference/significance.md +10 -3
  367. package/pack/generated/codex/skills/rite-temper/reference/strategy-template.md +13 -2
  368. package/pack/generated/codex/skills/rite-vet/SKILL.md +4 -3
  369. package/pack/generated/codex/skills/rite-vet/reference/artifacts.md +1 -1
  370. package/pack/generated/devin/AGENTS.md +1 -1
  371. package/pack/generated/devin/agents/devrites-code-reviewer.md +6 -3
  372. package/pack/generated/devin/agents/devrites-devex-reviewer.md +3 -1
  373. package/pack/generated/devin/agents/devrites-doubt-reviewer.md +7 -3
  374. package/pack/generated/devin/agents/devrites-evidence-scout.md +3 -1
  375. package/pack/generated/devin/agents/devrites-frontend-reviewer.md +3 -1
  376. package/pack/generated/devin/agents/devrites-performance-reviewer.md +3 -1
  377. package/pack/generated/devin/agents/devrites-plan-reviewer.md +3 -1
  378. package/pack/generated/devin/agents/devrites-proof-runner.md +3 -1
  379. package/pack/generated/devin/agents/devrites-retrospector.md +3 -1
  380. package/pack/generated/devin/agents/devrites-security-auditor.md +3 -1
  381. package/pack/generated/devin/agents/devrites-simplifier-reviewer.md +3 -1
  382. package/pack/generated/devin/agents/devrites-spec-reviewer.md +8 -5
  383. package/pack/generated/devin/agents/devrites-strategy-reviewer.md +3 -1
  384. package/pack/generated/devin/agents/devrites-test-analyst.md +3 -1
  385. package/pack/generated/devin/agents/devrites-upgrade-planner.md +3 -1
  386. package/pack/generated/devin/skills/devrites-browser-proof/SKILL.md +2 -2
  387. package/pack/generated/devin/skills/devrites-frontend-craft/reference/design-references.md +18 -18
  388. package/pack/generated/devin/skills/devrites-frontend-craft/reference/quality-standards.md +6 -4
  389. package/pack/generated/devin/skills/devrites-interview/SKILL.md +4 -4
  390. package/pack/generated/devin/skills/devrites-lib/reference/parallel-dispatch.md +1 -1
  391. package/pack/generated/devin/skills/devrites-lib/reference/standards/afk-hitl.md +11 -3
  392. package/pack/generated/devin/skills/devrites-lib/reference/standards/agents.md +3 -2
  393. package/pack/generated/devin/skills/devrites-lib/reference/standards/gates.md +6 -5
  394. package/pack/generated/devin/skills/devrites-lib/reference/standards/spec-grammar.md +1 -1
  395. package/pack/generated/devin/skills/devrites-lib/reference/standards/verification-methods.md +3 -3
  396. package/pack/generated/devin/skills/devrites-lib/reference/standards/windows.md +3 -3
  397. package/pack/generated/devin/skills/devrites-lib/reference/standards/workflow-artifacts.md +2 -2
  398. package/pack/generated/devin/skills/devrites-lib/reference/visual-playbooks/outline-template.md +1 -1
  399. package/pack/generated/devin/skills/devrites-lib/reference/workspace-artifact-schema.md +4 -4
  400. package/pack/generated/devin/skills/devrites-ux-shape/SKILL.md +11 -12
  401. package/pack/generated/devin/skills/devrites-ux-shape/reference/visual-direction-probe.md +3 -1
  402. package/pack/generated/devin/skills/overhaul/SKILL.md +1 -1
  403. package/pack/generated/devin/skills/overhaul/references/orchestration.md +5 -3
  404. package/pack/generated/devin/skills/overhaul/references/records.md +39 -0
  405. package/pack/generated/devin/skills/overhaul/references/scoring.md +14 -4
  406. package/pack/generated/devin/skills/rite/reference/menu.md +1 -1
  407. package/pack/generated/devin/skills/rite-adopt/SKILL.md +8 -2
  408. package/pack/generated/devin/skills/rite-autocomplete/SKILL.md +12 -7
  409. package/pack/generated/devin/skills/rite-autocomplete/reference/decision-policy.md +3 -2
  410. package/pack/generated/devin/skills/rite-autocomplete/reference/loop.md +3 -3
  411. package/pack/generated/devin/skills/rite-autocomplete/reference/stop-conditions.md +6 -3
  412. package/pack/generated/devin/skills/rite-build/SKILL.md +2 -1
  413. package/pack/generated/devin/skills/rite-build/reference/afk-discipline.md +1 -1
  414. package/pack/generated/devin/skills/rite-build/reference/checkpoint-protocol.md +1 -1
  415. package/pack/generated/devin/skills/rite-build/reference/checkpoint.md +5 -0
  416. package/pack/generated/devin/skills/rite-build/reference/parallel-batch.md +2 -2
  417. package/pack/generated/devin/skills/rite-build/reference/wright-dispatch.md +3 -2
  418. package/pack/generated/devin/skills/rite-clarify/SKILL.md +5 -4
  419. package/pack/generated/devin/skills/rite-clarify/reference/anti-patterns.md +2 -2
  420. package/pack/generated/devin/skills/rite-clarify/reference/decision-coverage.md +3 -2
  421. package/pack/generated/devin/skills/rite-converge/SKILL.md +2 -0
  422. package/pack/generated/devin/skills/rite-customize/SKILL.md +6 -4
  423. package/pack/generated/devin/skills/rite-define/SKILL.md +2 -0
  424. package/pack/generated/devin/skills/rite-define/reference/gates.md +8 -7
  425. package/pack/generated/devin/skills/rite-explain/SKILL.md +1 -1
  426. package/pack/generated/devin/skills/rite-explain/reference/intake.md +1 -1
  427. package/pack/generated/devin/skills/rite-fast/SKILL.md +1 -1
  428. package/pack/generated/devin/skills/rite-plan/SKILL.md +4 -3
  429. package/pack/generated/devin/skills/rite-plan/reference/replan-and-repair.md +4 -4
  430. package/pack/generated/devin/skills/rite-plan/reference/slicing.md +3 -3
  431. package/pack/generated/devin/skills/rite-polish/reference/anti-ai-slop.md +1 -1
  432. package/pack/generated/devin/skills/rite-prove/reference/browser-proof.md +5 -5
  433. package/pack/generated/devin/skills/rite-resolve/SKILL.md +3 -3
  434. package/pack/generated/devin/skills/rite-seal/SKILL.md +4 -3
  435. package/pack/generated/devin/skills/rite-seal/reference/phase-contract.md +3 -2
  436. package/pack/generated/devin/skills/rite-seal/reference/seal-template.md +2 -0
  437. package/pack/generated/devin/skills/rite-ship/SKILL.md +4 -2
  438. package/pack/generated/devin/skills/rite-ship/reference/git-ship.md +8 -2
  439. package/pack/generated/devin/skills/rite-ship/reference/ship-template.md +2 -1
  440. package/pack/generated/devin/skills/rite-spec/SKILL.md +2 -2
  441. package/pack/generated/devin/skills/rite-spec/reference/spec-checklists.md +1 -1
  442. package/pack/generated/devin/skills/rite-spec/reference/spec-template.md +7 -3
  443. package/pack/generated/devin/skills/rite-spec/reference/state-workspace.md +2 -0
  444. package/pack/generated/devin/skills/rite-temper/SKILL.md +14 -11
  445. package/pack/generated/devin/skills/rite-temper/reference/scope-modes.md +1 -1
  446. package/pack/generated/devin/skills/rite-temper/reference/significance.md +10 -3
  447. package/pack/generated/devin/skills/rite-temper/reference/strategy-template.md +13 -2
  448. package/pack/generated/devin/skills/rite-vet/SKILL.md +4 -3
  449. package/pack/generated/devin/skills/rite-vet/reference/artifacts.md +1 -1
  450. package/pack/generated/omp/agents/devrites-code-reviewer.md +6 -3
  451. package/pack/generated/omp/agents/devrites-devex-reviewer.md +3 -1
  452. package/pack/generated/omp/agents/devrites-doubt-reviewer.md +7 -3
  453. package/pack/generated/omp/agents/devrites-evidence-scout.md +3 -1
  454. package/pack/generated/omp/agents/devrites-frontend-reviewer.md +3 -1
  455. package/pack/generated/omp/agents/devrites-performance-reviewer.md +3 -1
  456. package/pack/generated/omp/agents/devrites-plan-reviewer.md +3 -1
  457. package/pack/generated/omp/agents/devrites-proof-runner.md +3 -1
  458. package/pack/generated/omp/agents/devrites-retrospector.md +3 -1
  459. package/pack/generated/omp/agents/devrites-security-auditor.md +3 -1
  460. package/pack/generated/omp/agents/devrites-simplifier-reviewer.md +3 -1
  461. package/pack/generated/omp/agents/devrites-spec-reviewer.md +8 -5
  462. package/pack/generated/omp/agents/devrites-strategy-reviewer.md +3 -1
  463. package/pack/generated/omp/agents/devrites-test-analyst.md +3 -1
  464. package/pack/generated/omp/agents/devrites-upgrade-planner.md +3 -1
  465. package/pack/generated/omp/commands/rite-define.md +1 -1
  466. package/pack/generated/omp/commands/rite-handoff.md +1 -1
  467. package/pack/generated/omp/commands/rite-plan.md +1 -1
  468. package/pack/generated/omp/commands/rite-pressure-test.md +1 -1
  469. package/pack/generated/omp/commands/rite-quick.md +1 -1
  470. package/pack/generated/omp/commands/rite-status.md +1 -1
  471. package/pack/generated/omp/commands/rite-temper.md +1 -1
  472. package/pack/generated/omp/commands/rite-zoom-out.md +1 -1
  473. package/pack/generated/omp/skills/devrites-browser-proof/SKILL.md +2 -2
  474. package/pack/generated/omp/skills/devrites-frontend-craft/reference/design-references.md +18 -18
  475. package/pack/generated/omp/skills/devrites-frontend-craft/reference/quality-standards.md +6 -4
  476. package/pack/generated/omp/skills/devrites-interview/SKILL.md +4 -4
  477. package/pack/generated/omp/skills/devrites-lib/reference/parallel-dispatch.md +1 -1
  478. package/pack/generated/omp/skills/devrites-lib/reference/standards/afk-hitl.md +11 -3
  479. package/pack/generated/omp/skills/devrites-lib/reference/standards/agents.md +3 -2
  480. package/pack/generated/omp/skills/devrites-lib/reference/standards/gates.md +6 -5
  481. package/pack/generated/omp/skills/devrites-lib/reference/standards/spec-grammar.md +1 -1
  482. package/pack/generated/omp/skills/devrites-lib/reference/standards/verification-methods.md +3 -3
  483. package/pack/generated/omp/skills/devrites-lib/reference/standards/windows.md +3 -3
  484. package/pack/generated/omp/skills/devrites-lib/reference/standards/workflow-artifacts.md +2 -2
  485. package/pack/generated/omp/skills/devrites-lib/reference/visual-playbooks/outline-template.md +1 -1
  486. package/pack/generated/omp/skills/devrites-lib/reference/workspace-artifact-schema.md +4 -4
  487. package/pack/generated/omp/skills/devrites-ux-shape/SKILL.md +11 -12
  488. package/pack/generated/omp/skills/devrites-ux-shape/reference/visual-direction-probe.md +3 -1
  489. package/pack/generated/omp/skills/overhaul/SKILL.md +1 -1
  490. package/pack/generated/omp/skills/overhaul/references/orchestration.md +5 -3
  491. package/pack/generated/omp/skills/overhaul/references/records.md +39 -0
  492. package/pack/generated/omp/skills/overhaul/references/scoring.md +14 -4
  493. package/pack/generated/omp/skills/rite/reference/menu.md +1 -1
  494. package/pack/generated/omp/skills/rite-adopt/SKILL.md +8 -2
  495. package/pack/generated/omp/skills/rite-autocomplete/SKILL.md +12 -7
  496. package/pack/generated/omp/skills/rite-autocomplete/reference/decision-policy.md +3 -2
  497. package/pack/generated/omp/skills/rite-autocomplete/reference/loop.md +3 -3
  498. package/pack/generated/omp/skills/rite-autocomplete/reference/stop-conditions.md +6 -3
  499. package/pack/generated/omp/skills/rite-build/SKILL.md +2 -1
  500. package/pack/generated/omp/skills/rite-build/reference/afk-discipline.md +1 -1
  501. package/pack/generated/omp/skills/rite-build/reference/checkpoint-protocol.md +1 -1
  502. package/pack/generated/omp/skills/rite-build/reference/checkpoint.md +5 -0
  503. package/pack/generated/omp/skills/rite-build/reference/parallel-batch.md +2 -2
  504. package/pack/generated/omp/skills/rite-build/reference/wright-dispatch.md +3 -2
  505. package/pack/generated/omp/skills/rite-clarify/SKILL.md +5 -4
  506. package/pack/generated/omp/skills/rite-clarify/reference/anti-patterns.md +2 -2
  507. package/pack/generated/omp/skills/rite-clarify/reference/decision-coverage.md +3 -2
  508. package/pack/generated/omp/skills/rite-converge/SKILL.md +2 -0
  509. package/pack/generated/omp/skills/rite-customize/SKILL.md +6 -4
  510. package/pack/generated/omp/skills/rite-define/SKILL.md +2 -0
  511. package/pack/generated/omp/skills/rite-define/reference/gates.md +8 -7
  512. package/pack/generated/omp/skills/rite-explain/SKILL.md +1 -1
  513. package/pack/generated/omp/skills/rite-explain/reference/intake.md +1 -1
  514. package/pack/generated/omp/skills/rite-fast/SKILL.md +1 -1
  515. package/pack/generated/omp/skills/rite-plan/SKILL.md +4 -3
  516. package/pack/generated/omp/skills/rite-plan/reference/replan-and-repair.md +4 -4
  517. package/pack/generated/omp/skills/rite-plan/reference/slicing.md +3 -3
  518. package/pack/generated/omp/skills/rite-polish/reference/anti-ai-slop.md +1 -1
  519. package/pack/generated/omp/skills/rite-prove/reference/browser-proof.md +5 -5
  520. package/pack/generated/omp/skills/rite-resolve/SKILL.md +3 -3
  521. package/pack/generated/omp/skills/rite-seal/SKILL.md +4 -3
  522. package/pack/generated/omp/skills/rite-seal/reference/phase-contract.md +3 -2
  523. package/pack/generated/omp/skills/rite-seal/reference/seal-template.md +2 -0
  524. package/pack/generated/omp/skills/rite-ship/SKILL.md +4 -2
  525. package/pack/generated/omp/skills/rite-ship/reference/git-ship.md +8 -2
  526. package/pack/generated/omp/skills/rite-ship/reference/ship-template.md +2 -1
  527. package/pack/generated/omp/skills/rite-spec/SKILL.md +2 -2
  528. package/pack/generated/omp/skills/rite-spec/reference/spec-checklists.md +1 -1
  529. package/pack/generated/omp/skills/rite-spec/reference/spec-template.md +7 -3
  530. package/pack/generated/omp/skills/rite-spec/reference/state-workspace.md +2 -0
  531. package/pack/generated/omp/skills/rite-temper/SKILL.md +14 -11
  532. package/pack/generated/omp/skills/rite-temper/reference/scope-modes.md +1 -1
  533. package/pack/generated/omp/skills/rite-temper/reference/significance.md +10 -3
  534. package/pack/generated/omp/skills/rite-temper/reference/strategy-template.md +13 -2
  535. package/pack/generated/omp/skills/rite-vet/SKILL.md +4 -3
  536. package/pack/generated/omp/skills/rite-vet/reference/artifacts.md +1 -1
  537. package/pack/generated/pi/AGENTS.md +1 -1
  538. package/pack/generated/pi/agents/devrites-code-reviewer.md +6 -3
  539. package/pack/generated/pi/agents/devrites-devex-reviewer.md +3 -1
  540. package/pack/generated/pi/agents/devrites-doubt-reviewer.md +7 -3
  541. package/pack/generated/pi/agents/devrites-evidence-scout.md +3 -1
  542. package/pack/generated/pi/agents/devrites-frontend-reviewer.md +3 -1
  543. package/pack/generated/pi/agents/devrites-performance-reviewer.md +3 -1
  544. package/pack/generated/pi/agents/devrites-plan-reviewer.md +3 -1
  545. package/pack/generated/pi/agents/devrites-proof-runner.md +3 -1
  546. package/pack/generated/pi/agents/devrites-retrospector.md +3 -1
  547. package/pack/generated/pi/agents/devrites-security-auditor.md +3 -1
  548. package/pack/generated/pi/agents/devrites-simplifier-reviewer.md +3 -1
  549. package/pack/generated/pi/agents/devrites-spec-reviewer.md +8 -5
  550. package/pack/generated/pi/agents/devrites-strategy-reviewer.md +3 -1
  551. package/pack/generated/pi/agents/devrites-test-analyst.md +3 -1
  552. package/pack/generated/pi/agents/devrites-upgrade-planner.md +3 -1
  553. package/pack/generated/pi/prompts/rite-define.md +1 -1
  554. package/pack/generated/pi/prompts/rite-handoff.md +1 -1
  555. package/pack/generated/pi/prompts/rite-plan.md +1 -1
  556. package/pack/generated/pi/prompts/rite-pressure-test.md +1 -1
  557. package/pack/generated/pi/prompts/rite-quick.md +1 -1
  558. package/pack/generated/pi/prompts/rite-status.md +1 -1
  559. package/pack/generated/pi/prompts/rite-temper.md +1 -1
  560. package/pack/generated/pi/prompts/rite-zoom-out.md +1 -1
  561. package/pack/generated/pi/skills/devrites-browser-proof/SKILL.md +2 -2
  562. package/pack/generated/pi/skills/devrites-frontend-craft/reference/design-references.md +18 -18
  563. package/pack/generated/pi/skills/devrites-frontend-craft/reference/quality-standards.md +6 -4
  564. package/pack/generated/pi/skills/devrites-interview/SKILL.md +4 -4
  565. package/pack/generated/pi/skills/devrites-lib/reference/parallel-dispatch.md +1 -1
  566. package/pack/generated/pi/skills/devrites-lib/reference/standards/afk-hitl.md +11 -3
  567. package/pack/generated/pi/skills/devrites-lib/reference/standards/agents.md +3 -2
  568. package/pack/generated/pi/skills/devrites-lib/reference/standards/gates.md +6 -5
  569. package/pack/generated/pi/skills/devrites-lib/reference/standards/spec-grammar.md +1 -1
  570. package/pack/generated/pi/skills/devrites-lib/reference/standards/verification-methods.md +3 -3
  571. package/pack/generated/pi/skills/devrites-lib/reference/standards/windows.md +3 -3
  572. package/pack/generated/pi/skills/devrites-lib/reference/standards/workflow-artifacts.md +2 -2
  573. package/pack/generated/pi/skills/devrites-lib/reference/visual-playbooks/outline-template.md +1 -1
  574. package/pack/generated/pi/skills/devrites-lib/reference/workspace-artifact-schema.md +4 -4
  575. package/pack/generated/pi/skills/devrites-ux-shape/SKILL.md +11 -12
  576. package/pack/generated/pi/skills/devrites-ux-shape/reference/visual-direction-probe.md +3 -1
  577. package/pack/generated/pi/skills/overhaul/SKILL.md +1 -1
  578. package/pack/generated/pi/skills/overhaul/references/orchestration.md +5 -3
  579. package/pack/generated/pi/skills/overhaul/references/records.md +39 -0
  580. package/pack/generated/pi/skills/overhaul/references/scoring.md +14 -4
  581. package/pack/generated/pi/skills/rite/reference/menu.md +1 -1
  582. package/pack/generated/pi/skills/rite-adopt/SKILL.md +8 -2
  583. package/pack/generated/pi/skills/rite-autocomplete/SKILL.md +12 -7
  584. package/pack/generated/pi/skills/rite-autocomplete/reference/decision-policy.md +3 -2
  585. package/pack/generated/pi/skills/rite-autocomplete/reference/loop.md +3 -3
  586. package/pack/generated/pi/skills/rite-autocomplete/reference/stop-conditions.md +6 -3
  587. package/pack/generated/pi/skills/rite-build/SKILL.md +2 -1
  588. package/pack/generated/pi/skills/rite-build/reference/afk-discipline.md +1 -1
  589. package/pack/generated/pi/skills/rite-build/reference/checkpoint-protocol.md +1 -1
  590. package/pack/generated/pi/skills/rite-build/reference/checkpoint.md +5 -0
  591. package/pack/generated/pi/skills/rite-build/reference/parallel-batch.md +2 -2
  592. package/pack/generated/pi/skills/rite-build/reference/wright-dispatch.md +3 -2
  593. package/pack/generated/pi/skills/rite-clarify/SKILL.md +5 -4
  594. package/pack/generated/pi/skills/rite-clarify/reference/anti-patterns.md +2 -2
  595. package/pack/generated/pi/skills/rite-clarify/reference/decision-coverage.md +3 -2
  596. package/pack/generated/pi/skills/rite-converge/SKILL.md +2 -0
  597. package/pack/generated/pi/skills/rite-customize/SKILL.md +6 -4
  598. package/pack/generated/pi/skills/rite-define/SKILL.md +2 -0
  599. package/pack/generated/pi/skills/rite-define/reference/gates.md +8 -7
  600. package/pack/generated/pi/skills/rite-explain/SKILL.md +1 -1
  601. package/pack/generated/pi/skills/rite-explain/reference/intake.md +1 -1
  602. package/pack/generated/pi/skills/rite-fast/SKILL.md +1 -1
  603. package/pack/generated/pi/skills/rite-plan/SKILL.md +4 -3
  604. package/pack/generated/pi/skills/rite-plan/reference/replan-and-repair.md +4 -4
  605. package/pack/generated/pi/skills/rite-plan/reference/slicing.md +3 -3
  606. package/pack/generated/pi/skills/rite-polish/reference/anti-ai-slop.md +1 -1
  607. package/pack/generated/pi/skills/rite-prove/reference/browser-proof.md +5 -5
  608. package/pack/generated/pi/skills/rite-resolve/SKILL.md +3 -3
  609. package/pack/generated/pi/skills/rite-seal/SKILL.md +4 -3
  610. package/pack/generated/pi/skills/rite-seal/reference/phase-contract.md +3 -2
  611. package/pack/generated/pi/skills/rite-seal/reference/seal-template.md +2 -0
  612. package/pack/generated/pi/skills/rite-ship/SKILL.md +4 -2
  613. package/pack/generated/pi/skills/rite-ship/reference/git-ship.md +8 -2
  614. package/pack/generated/pi/skills/rite-ship/reference/ship-template.md +2 -1
  615. package/pack/generated/pi/skills/rite-spec/SKILL.md +2 -2
  616. package/pack/generated/pi/skills/rite-spec/reference/spec-checklists.md +1 -1
  617. package/pack/generated/pi/skills/rite-spec/reference/spec-template.md +7 -3
  618. package/pack/generated/pi/skills/rite-spec/reference/state-workspace.md +2 -0
  619. package/pack/generated/pi/skills/rite-temper/SKILL.md +14 -11
  620. package/pack/generated/pi/skills/rite-temper/reference/scope-modes.md +1 -1
  621. package/pack/generated/pi/skills/rite-temper/reference/significance.md +10 -3
  622. package/pack/generated/pi/skills/rite-temper/reference/strategy-template.md +13 -2
  623. package/pack/generated/pi/skills/rite-vet/SKILL.md +4 -3
  624. package/pack/generated/pi/skills/rite-vet/reference/artifacts.md +1 -1
  625. package/package.json +5 -4
  626. package/scripts/build-host-artifacts.sh +15 -0
  627. package/scripts/codex-generate.sh +1 -1
  628. package/scripts/devin-generate.sh +1 -1
  629. package/scripts/expand-includes.py +46 -0
  630. package/scripts/install-lib.sh +42 -7
  631. package/scripts/omp-generate.sh +11 -0
  632. package/scripts/pi-generate.sh +12 -1
  633. package/update.sh +1 -2
  634. package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/README.md +0 -7
  635. package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/architecture.md +0 -3
  636. package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/assumptions.md +0 -3
  637. package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/brief.md +0 -3
  638. package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/decision-coverage.md +0 -3
  639. package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/decisions.md +0 -4
  640. package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/eng-review.md +0 -3
  641. package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/gates.md +0 -4
  642. package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/plan.md +0 -5
  643. package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/questions.md +0 -3
  644. package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/spec.md +0 -6
  645. package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/state.md +0 -8
  646. package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/tasks.md +0 -1
  647. package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/test-plan.md +0 -3
  648. package/engine/testdata/fixtures/basic/devrites-root/work/auth-tokens/traceability.md +0 -3
  649. package/engine/testdata/fixtures/basic/devrites-root/work/search-ranking/README.md +0 -7
  650. package/engine/testdata/fixtures/basic/devrites-root/work/search-ranking/assumptions.md +0 -3
  651. package/engine/testdata/fixtures/basic/devrites-root/work/search-ranking/brief.md +0 -3
  652. package/engine/testdata/fixtures/basic/devrites-root/work/search-ranking/decisions.md +0 -3
  653. package/engine/testdata/fixtures/basic/devrites-root/work/search-ranking/questions.md +0 -3
  654. package/engine/testdata/fixtures/basic/devrites-root/work/search-ranking/spec.md +0 -6
  655. package/engine/testdata/fixtures/basic/devrites-root/work/search-ranking/state.md +0 -3
  656. package/engine/testdata/golden/TestParityCloseOut/active_pointed_elsewhere.golden +0 -2
  657. package/engine/testdata/golden/TestParityCloseOut/active_slug_cleared.golden +0 -2
  658. package/engine/testdata/golden/TestParityCloseOut/archive_clobber.golden +0 -1
  659. package/engine/testdata/golden/TestParityCloseOut/missing_slug.golden +0 -1
  660. package/engine/testdata/golden/TestParityCloseOut/missing_workspace.golden +0 -1
  661. package/engine/testdata/golden/TestParityLearnings/add.golden +0 -2
  662. package/engine/testdata/golden/TestParityLearnings/list.golden +0 -5
  663. package/engine/testdata/golden/TestParityLearnings/mine-no-archive.golden +0 -2
  664. package/engine/testdata/golden/TestParityLearnings/mine.golden +0 -5
  665. package/engine/testdata/golden/TestParityLearnings/nudge.golden +0 -2
  666. package/engine/testdata/golden/TestParityLearnings/unknown.golden +0 -1
  667. package/engine/testdata/golden/TestParityPackageExistence/ghost-workspace.golden +0 -1
  668. package/engine/testdata/golden/TestParityPackageExistence/no-manifest.golden +0 -1
  669. package/engine/testdata/golden/TestParityPackageExistence/not-git.golden +0 -1
  670. package/engine/testdata/golden/TestParityPackageExistence/undeclared.golden +0 -1
  671. package/engine/testdata/golden/TestParityPreamble/afk/a.golden +0 -14
  672. package/engine/testdata/golden/TestParityPreamble/hitl/active.golden +0 -18
  673. package/engine/testdata/golden/TestParityPreamble/hitl/bare.golden +0 -10
  674. package/engine/testdata/golden/TestParityPreamble/hitl/full.golden +0 -18
  675. package/engine/testdata/golden/TestParityPreamble/hitl/ghost.golden +0 -2
  676. package/engine/testdata/golden/TestParityPreamble/hitl/nonl.golden +0 -11
  677. package/engine/testdata/golden/TestParityPreamble/hitl/openend.golden +0 -13
  678. package/engine/testdata/golden/TestParityProgress/arg=allbuilt.golden +0 -4
  679. package/engine/testdata/golden/TestParityProgress/arg=done.golden +0 -3
  680. package/engine/testdata/golden/TestParityProgress/arg=ghost.golden +0 -1
  681. package/engine/testdata/golden/TestParityProgress/arg=mid.golden +0 -4
  682. package/engine/testdata/golden/TestParityProgress/arg=nophase.golden +0 -3
  683. package/engine/testdata/golden/TestParityProgress/arg=noslice.golden +0 -3
  684. package/engine/testdata/golden/TestParityProgress/arg=plan.golden +0 -4
  685. package/engine/testdata/golden/TestParityProgress/arg=seal.golden +0 -3
  686. package/engine/testdata/golden/TestParityResolve/answer/questions.md.golden +0 -9
  687. package/engine/testdata/golden/TestParityResolve/answer/state.md.golden +0 -7
  688. package/engine/testdata/golden/TestParityResolve/answer.golden +0 -4
  689. package/engine/testdata/golden/TestParityResolve/batch/questions.md.golden +0 -9
  690. package/engine/testdata/golden/TestParityResolve/batch-unterminated/questions.md.golden +0 -9
  691. package/engine/testdata/golden/TestParityResolve/batch-unterminated.golden +0 -2
  692. package/engine/testdata/golden/TestParityResolve/batch.golden +0 -3
  693. package/engine/testdata/golden/TestParityResolve/drop/questions.md.golden +0 -9
  694. package/engine/testdata/golden/TestParityResolve/drop/state.md.golden +0 -9
  695. package/engine/testdata/golden/TestParityResolve/drop.golden +0 -4
  696. package/engine/testdata/golden/TestParityResolve/missing-answer.golden +0 -1
  697. package/engine/testdata/golden/TestParityResolve/no-workspace.golden +0 -1
  698. package/engine/testdata/golden/TestParityResolve/not-found.golden +0 -1
  699. package/engine/testdata/golden/TestParityResolve/not-open.golden +0 -1
  700. package/engine/testdata/golden/TestStatusLiveWorkspace.golden +0 -10
  701. package/engine/testdata/golden/status/auth-tokens.txt +0 -9
  702. package/engine/testdata/golden/status/search-ranking.txt +0 -9
  703. package/engine/testdata/visual/open-visual-smoke.html +0 -675
  704. package/engine/testdata/visual/open-visual-smoke.outline.md +0 -54
  705. package/engine/tests/adr_0003_gate_exit_code_test.go +0 -32
  706. package/engine/tests/adr_0004_required_by_phase_test.go +0 -54
  707. package/engine/tests/adr_0011_define_plan_test.go +0 -32
  708. package/engine/tests/adr_0027_readiness_binding_test.go +0 -107
  709. package/engine/tests/cli_test.go +0 -126
  710. package/engine/tests/gate_test.go +0 -669
  711. package/engine/tests/meta_test.go +0 -37
  712. package/engine/tests/parity_closeout_test.go +0 -105
  713. package/engine/tests/parity_githelpers_test.go +0 -41
  714. package/engine/tests/parity_resolve_test.go +0 -136
  715. package/engine/tests/parity_test.go +0 -86
  716. package/engine/tests/workspace_observation_migration_test.go +0 -1069
@@ -1,1069 +0,0 @@
1
- package main_test
2
-
3
- import (
4
- "fmt"
5
- "go/ast"
6
- "go/parser"
7
- "go/token"
8
- "os"
9
- "path/filepath"
10
- "sort"
11
- "strconv"
12
- "strings"
13
- "testing"
14
- )
15
-
16
- func TestWorkspaceObservationMigrationGuards(t *testing.T) {
17
- engineRoot := filepath.Clean("..")
18
-
19
- t.Run("superseded readers are absent", func(t *testing.T) {
20
- program := parseMigrationProgram(t, engineRoot)
21
- for _, problem := range obsoleteSurfaceProblems(program) {
22
- t.Error(problem)
23
- }
24
- })
25
-
26
- t.Run("acquisition calls are exact", func(t *testing.T) {
27
- program := parseMigrationProgram(t, engineRoot)
28
- for _, problem := range acquisitionProblems(program) {
29
- t.Error(problem)
30
- }
31
- })
32
-
33
- t.Run("consumer reachability stays retained", func(t *testing.T) {
34
- program := parseMigrationProgram(t, engineRoot)
35
- for _, problem := range consumerReachabilityProblems(program, migrationConsumerEntries()) {
36
- t.Error(problem)
37
- }
38
- })
39
-
40
- t.Run("command documentation names closed contract", func(t *testing.T) {
41
- path := filepath.Join(engineRoot, "..", "docs", "engine", "commands.md")
42
- content, err := os.ReadFile(path)
43
- if err != nil {
44
- t.Fatal(err)
45
- }
46
- text := strings.Join(strings.Fields(string(content)), " ")
47
- for _, want := range []string{
48
- "`absent`", "`empty`", "`malformed`", "`unsafe`", "`unreadable`", "`present`",
49
- "`malformed_markdown`", "`parent_symlink`", "`final_symlink`", "`non_regular`",
50
- "`file_too_large`", "`permission_denied`", "`read_failure`",
51
- "next: repair <logical-path>: replace invalid Markdown with valid Markdown; required artifacts need substantive content",
52
- "next: repair <logical-path>: replace the symlinked parent with a real directory",
53
- "next: repair <logical-path>: replace the symlink with a regular file",
54
- "next: repair <logical-path>: replace the non-regular entry with a regular file",
55
- "next: repair <logical-path>: reduce the file to at most 1 MiB",
56
- "next: repair <logical-path>: grant read permission",
57
- "next: repair <logical-path>: restore a readable regular file",
58
- "; optional readiness input may instead be removed",
59
- "readiness input <logical-path> is malformed (malformed_markdown); replace invalid Markdown with valid Markdown",
60
- "readiness input <logical-path> is unsafe (parent_symlink); replace the symlinked parent with a real directory",
61
- "readiness input <logical-path> is unsafe (final_symlink); replace the symlink with a regular file",
62
- "readiness input <logical-path> is unsafe (non_regular); replace the non-regular entry with a regular file",
63
- "readiness input <logical-path> is unsafe (file_too_large); reduce the file to at most 1 MiB",
64
- "readiness input <logical-path> is unreadable (permission_denied); grant read permission",
65
- "readiness input <logical-path> is unreadable (read_failure); restore a readable regular file",
66
- "`workspace_invalid`", "`aggregate_too_large`", "`concurrent_change`",
67
- "workspace observation: workspace_invalid: workspace is unavailable; verify the selected logical workspace and canonical workspace override, then retry",
68
- "workspace observation: aggregate_too_large: retained content exceeds the 8 MiB aggregate limit; reduce retained Markdown below 8 MiB, then retry",
69
- "add real content to state.md and retry", "repair state.md and retry",
70
- "record phase in state.md and retry", "record a known phase in state.md and retry",
71
- "1 MiB per file", "8 MiB aggregate",
72
- "artifact: <logical-path>: <state> (<code>)",
73
- "Status emits diagnostics without recovery or `next:` lines",
74
- "Gate emits diagnostics after `reason` and before recovery, `invariant`, and `retry` lines",
75
- "Whole observation failures use stderr, exit `2`, and no lifecycle result or reason on stdout",
76
- "Standalone readiness-binding failures use one stderr line, exit `3`, and empty stdout",
77
- "These seven codes are the closed Workspace Observation classification and recovery mapping outcomes. A selected public consumer emits only a code reachable for its consumed fixed logical path. Invalid workspace ancestry is `workspace_invalid`, not an artifact `parent_symlink` diagnostic.",
78
- } {
79
- if !strings.Contains(text, want) {
80
- t.Errorf("%s missing %q", path, want)
81
- }
82
- }
83
- })
84
- }
85
-
86
- func TestWorkspaceObservationMigrationGuardFixtures(t *testing.T) {
87
- t.Run("unrelated Present is accepted", func(t *testing.T) {
88
- program := parseMigrationFixture(t, map[string]string{
89
- "internal/state/snapshot.go": `package state
90
- type Snapshot struct {
91
- Present bool
92
- }
93
- func Present() bool { return Snapshot{Present: true}.Present }
94
- `,
95
- })
96
- if problems := obsoleteSurfaceProblems(program); len(problems) != 0 {
97
- t.Fatalf("unrelated Present identifier was rejected: %v", problems)
98
- }
99
- })
100
-
101
- t.Run("obsolete State and Gate surfaces are rejected", func(t *testing.T) {
102
- program := parseMigrationFixture(t, map[string]string{
103
- "internal/state/feature.go": `package state
104
- type Feature struct {
105
- Present map[string]bool
106
- PresentFiles map[string]bool
107
- }
108
- func LoadFeature() *Feature { return nil }
109
- func declaredPhaseFromLedger() {}
110
- `,
111
- "internal/gate/gate.go": `package gate
112
- import lifecycle "github.com/devrites/devrites/internal/state"
113
- func Check() { _ = lifecycle.LoadFeature }
114
- `,
115
- })
116
- problems := obsoleteSurfaceProblems(program)
117
- for _, want := range []string{"state type Feature", "Feature.Present", "Feature.PresentFiles", "state function LoadFeature", "state function declaredPhaseFromLedger", "state.LoadFeature"} {
118
- if !migrationProblemContains(problems, want) {
119
- t.Errorf("obsolete surface %q was not rejected: %v", want, problems)
120
- }
121
- }
122
- })
123
-
124
- t.Run("reachable helper reopen", func(t *testing.T) {
125
- program := parseMigrationFixture(t, map[string]string{
126
- "internal/state/status.go": `package state
127
- func Status() { statusWithCallback() }
128
- func statusWithCallback() { reopen().Read() }
129
- `,
130
- "internal/state/reopen.go": `package state
131
- import "os"
132
- func reopen() any {
133
- _, _ = os.ReadFile("state.md")
134
- return nil
135
- }
136
- `,
137
- })
138
- problems := consumerReachabilityProblems(program, []migrationEntry{{directory: "internal/state", function: "Status"}})
139
- if !migrationProblemContains(problems, "internal/state/reopen.go", `filesystem content-reader package "os"`) {
140
- t.Fatalf("reachable helper reopen was not rejected: %v", problems)
141
- }
142
- })
143
-
144
- t.Run("reachable receiver method reopen", func(t *testing.T) {
145
- program := parseMigrationFixture(t, map[string]string{
146
- "internal/state/status.go": `package state
147
- type retainedConsumer struct{}
148
- func Status() {
149
- var consumer retainedConsumer
150
- consumer.reopen()
151
- }
152
- `,
153
- "internal/state/reopen.go": `package state
154
- import "os"
155
- func (retainedConsumer) reopen() {
156
- _, _ = os.ReadFile("state.md")
157
- }
158
- `,
159
- })
160
- problems := consumerReachabilityProblems(program, []migrationEntry{{directory: "internal/state", function: "Status"}})
161
- if !migrationProblemContains(problems, "internal/state/reopen.go", `filesystem content-reader package "os"`) {
162
- t.Fatalf("reachable receiver-method reopen was not rejected: %v", problems)
163
- }
164
- })
165
-
166
- for _, test := range []struct {
167
- name string
168
- body string
169
- }{
170
- {name: "direct constructor result receiver", body: "newRetainedConsumer().reopen()"},
171
- {name: "assigned constructor result receiver", body: "consumer := newRetainedConsumer()\nconsumer.reopen()"},
172
- } {
173
- t.Run(test.name, func(t *testing.T) {
174
- program := parseMigrationFixture(t, map[string]string{
175
- "internal/state/status.go": fmt.Sprintf(`package state
176
- type retainedConsumer struct{}
177
- func newRetainedConsumer() *retainedConsumer { return &retainedConsumer{} }
178
- func Status() {
179
- %s
180
- }
181
- `, test.body),
182
- "internal/state/reopen.go": `package state
183
- import "os"
184
- func (*retainedConsumer) reopen() {
185
- _, _ = os.ReadFile("state.md")
186
- }
187
- `,
188
- })
189
- problems := consumerReachabilityProblems(program, []migrationEntry{{directory: "internal/state", function: "Status"}})
190
- if !migrationProblemContains(problems, "internal/state/reopen.go", `filesystem content-reader package "os"`) {
191
- t.Fatalf("constructor-result receiver method was not rejected: %v", problems)
192
- }
193
- })
194
- }
195
-
196
- t.Run("reachable internal helper package", func(t *testing.T) {
197
- program := parseMigrationFixture(t, map[string]string{
198
- "internal/gate/gate.go": `package gate
199
- import "github.com/devrites/devrites/internal/workspacereader"
200
- func Check() { workspacereader.Read() }
201
- `,
202
- })
203
- problems := consumerReachabilityProblems(program, []migrationEntry{{directory: "internal/gate", function: "Check"}})
204
- if !migrationProblemContains(problems, "internal/gate/gate.go", `unapproved internal package "github.com/devrites/devrites/internal/workspacereader"`) {
205
- t.Fatalf("reachable internal helper package was not rejected: %v", problems)
206
- }
207
- })
208
-
209
- t.Run("aliased helper second capture", func(t *testing.T) {
210
- program := parseMigrationFixture(t, map[string]string{
211
- "internal/gate/gate.go": `package gate
212
- import observed "github.com/devrites/devrites/internal/state"
213
- func Check() { _, _ = observed.ObserveWorkspace("", "") }
214
- func helper() {
215
- capture := observed.ObserveWorkspace
216
- _, _ = capture("", "")
217
- }
218
- `,
219
- })
220
- problems := acquisitionProblems(program)
221
- if !migrationProblemContains(problems, "internal/gate/gate.go:helper", "state.ObserveWorkspace") {
222
- t.Fatalf("aliased helper second capture was not rejected: %v", problems)
223
- }
224
- })
225
-
226
- t.Run("alias assigned outside loop and called in loop is rejected", func(t *testing.T) {
227
- program := parseCompleteMigrationAcquisitionFixture(t, `capture := state.ObserveWorkspace
228
- for range []int{1, 2} {
229
- capture()
230
- }`)
231
- problems := acquisitionProblems(program)
232
- if !migrationProblemContains(problems, "internal/gate/gate.go:Check", "acquisition function reference", "state.ObserveWorkspace") {
233
- t.Fatalf("loop-called acquisition alias was not rejected: %v", problems)
234
- }
235
- if !migrationProblemContains(problems, "internal/gate/gate.go:Check", "calls state.ObserveWorkspace 0 times, want 1") {
236
- t.Fatalf("acquisition alias satisfied direct-call cardinality: %v", problems)
237
- }
238
- })
239
-
240
- t.Run("anonymous closure assigned outside loop and called in loop is rejected", func(t *testing.T) {
241
- program := parseCompleteMigrationAcquisitionFixture(t, `capture := func() { state.ObserveWorkspace() }
242
- for range []int{1, 2} {
243
- capture()
244
- }`)
245
- problems := acquisitionProblems(program)
246
- if !migrationProblemContains(problems, "internal/gate/gate.go:Check", "acquisition function reference", "state.ObserveWorkspace") {
247
- t.Fatalf("loop-called acquisition closure was not rejected: %v", problems)
248
- }
249
- if !migrationProblemContains(problems, "internal/gate/gate.go:Check", "calls state.ObserveWorkspace 0 times, want 1") {
250
- t.Fatalf("acquisition closure satisfied direct-call cardinality: %v", problems)
251
- }
252
- })
253
-
254
- t.Run("uncalled function value is rejected without satisfying call count", func(t *testing.T) {
255
- program := parseCompleteMigrationAcquisitionFixture(t, `_ = state.ObserveWorkspace`)
256
- problems := acquisitionProblems(program)
257
- if !migrationProblemContains(problems, "internal/gate/gate.go:Check", "acquisition function reference", "state.ObserveWorkspace") {
258
- t.Fatalf("uncalled acquisition function value was not rejected: %v", problems)
259
- }
260
- if !migrationProblemContains(problems, "internal/gate/gate.go:Check", "calls state.ObserveWorkspace 0 times, want 1") {
261
- t.Fatalf("uncalled acquisition function value satisfied direct-call cardinality: %v", problems)
262
- }
263
- })
264
-
265
- t.Run("dot-import direct call is accepted", func(t *testing.T) {
266
- program := parseMigrationFixture(t, map[string]string{
267
- "internal/state/observation.go": `package state
268
- func ObserveWorkspace() { observeWorkspace() }
269
- func observeWorkspace() {}
270
- `,
271
- "internal/state/status.go": `package state
272
- func Status() { statusWithCallback() }
273
- func statusWithCallback() { observeWorkspace() }
274
- `,
275
- "internal/gate/gate.go": fmt.Sprintf(`package gate
276
- import . %q
277
- func Check() { ObserveWorkspace() }
278
- `, migrationStateImport),
279
- "internal/gate/readiness_binding.go": fmt.Sprintf(`package gate
280
- import %q
281
- func ReadinessBinding() { state.ObserveWorkspace() }
282
- func ReadinessInputDigests() { state.ObserveWorkspace() }
283
- `, migrationStateImport),
284
- })
285
- if problems := acquisitionProblems(program); len(problems) != 0 {
286
- t.Fatalf("dot-import acquisition call was rejected: %v", problems)
287
- }
288
- })
289
-
290
- for _, test := range []struct {
291
- name string
292
- checkBody string
293
- wantLoop string
294
- wantAccept bool
295
- }{
296
- {name: "direct call in for initializer is accepted", checkBody: `for state.ObserveWorkspace(); ; {
297
- break
298
- }`, wantAccept: true},
299
- {name: "direct call in for condition is rejected", checkBody: `for ; state.ObserveWorkspace(); {
300
- break
301
- }`, wantLoop: "for"},
302
- {name: "direct call in for post is rejected", checkBody: `for ; false; state.ObserveWorkspace() {}`, wantLoop: "for"},
303
- {name: "direct call in range expression is accepted", checkBody: `for range state.ObserveWorkspace() {}`, wantAccept: true},
304
- {name: "nested loop initializer remains repeat capable", checkBody: `for range []int{1, 2} {
305
- for state.ObserveWorkspace(); ; {
306
- break
307
- }
308
- }`, wantLoop: "range"},
309
- } {
310
- t.Run(test.name, func(t *testing.T) {
311
- program := parseCompleteMigrationAcquisitionFixture(t, test.checkBody)
312
- problems := acquisitionProblems(program)
313
- if test.wantAccept {
314
- if len(problems) != 0 {
315
- t.Fatalf("one-shot acquisition call was rejected: %v", problems)
316
- }
317
- return
318
- }
319
- if !migrationProblemContains(problems, "internal/gate/gate.go:Check", "calls state.ObserveWorkspace", test.wantLoop+" loop", "repeated acquisition risk") {
320
- t.Fatalf("repeat-capable acquisition call was not rejected: %v", problems)
321
- }
322
- })
323
- }
324
-
325
- loops := []struct {
326
- name string
327
- body func(string) string
328
- }{
329
- {
330
- name: "for",
331
- body: func(call string) string {
332
- return "for i := 0; i < 2; i++ {\n" + call + "\n}"
333
- },
334
- },
335
- {
336
- name: "range",
337
- body: func(call string) string {
338
- return "for range []int{1, 2} {\n" + call + "\n}"
339
- },
340
- },
341
- }
342
- sites := []struct {
343
- name string
344
- file string
345
- function string
346
- target string
347
- }{
348
- {name: "state ObserveWorkspace wrapper", file: "internal/state/observation.go", function: "ObserveWorkspace", target: "observeWorkspace"},
349
- {name: "state statusWithCallback", file: "internal/state/status.go", function: "statusWithCallback", target: "observeWorkspace"},
350
- {name: "gate Check", file: "internal/gate/gate.go", function: "Check", target: "state.ObserveWorkspace"},
351
- {name: "gate ReadinessBinding", file: "internal/gate/readiness_binding.go", function: "ReadinessBinding", target: "state.ObserveWorkspace"},
352
- }
353
- for _, loop := range loops {
354
- for _, site := range sites {
355
- t.Run(loop.name+" around "+site.name, func(t *testing.T) {
356
- observationBody := "observeWorkspace()"
357
- statusBody := "observeWorkspace()"
358
- checkBody := "state.ObserveWorkspace()"
359
- bindingBody := "state.ObserveWorkspace()"
360
- switch site.file {
361
- case "internal/state/observation.go":
362
- observationBody = loop.body(observationBody)
363
- case "internal/state/status.go":
364
- statusBody = loop.body(statusBody)
365
- case "internal/gate/gate.go":
366
- checkBody = loop.body(checkBody)
367
- case "internal/gate/readiness_binding.go":
368
- bindingBody = loop.body(bindingBody)
369
- }
370
- program := parseMigrationFixture(t, map[string]string{
371
- "internal/state/observation.go": fmt.Sprintf("package state\nfunc ObserveWorkspace() {\n%s\n}\nfunc observeWorkspace() {}\n", observationBody),
372
- "internal/state/status.go": fmt.Sprintf("package state\nfunc Status() { statusWithCallback() }\nfunc statusWithCallback() {\n%s\n}\n", statusBody),
373
- "internal/gate/gate.go": fmt.Sprintf("package gate\nimport %q\nfunc Check() {\n%s\n}\n", migrationStateImport, checkBody),
374
- "internal/gate/readiness_binding.go": fmt.Sprintf("package gate\nimport %q\nfunc ReadinessBinding() {\n%s\n}\n", migrationStateImport, bindingBody),
375
- })
376
- problems := acquisitionProblems(program)
377
- if !migrationProblemContains(problems, site.file+":"+site.function, site.target, loop.name+" loop", "repeated acquisition risk") {
378
- t.Fatalf("looped acquisition reference was not rejected: %v", problems)
379
- }
380
- })
381
- }
382
- }
383
- }
384
-
385
- const migrationStateImport = "github.com/devrites/devrites/internal/state"
386
-
387
- type migrationEntry struct {
388
- directory string
389
- receiver string
390
- function string
391
- }
392
-
393
- type migrationFile struct {
394
- name string
395
- directory string
396
- packageName string
397
- syntax *ast.File
398
- imports map[string]string
399
- }
400
-
401
- type migrationFunction struct {
402
- file *migrationFile
403
- decl *ast.FuncDecl
404
- }
405
-
406
- type migrationProgram struct {
407
- files []*migrationFile
408
- functions map[migrationEntry]*migrationFunction
409
- }
410
-
411
- type migrationAcquisitionUse struct {
412
- file string
413
- function string
414
- target string
415
- loop string
416
- functionValue bool
417
- }
418
-
419
- type migrationAcquisitionVisitor struct {
420
- file *migrationFile
421
- function string
422
- loop string
423
- functionValue bool
424
- uses *[]migrationAcquisitionUse
425
- }
426
-
427
- func (v migrationAcquisitionVisitor) Visit(node ast.Node) ast.Visitor {
428
- if node == nil {
429
- return nil
430
- }
431
- switch node := node.(type) {
432
- case *ast.FuncLit:
433
- v.functionValue = true
434
- v.walk(node.Body)
435
- return nil
436
- case *ast.ForStmt:
437
- v.walk(node.Init)
438
- repeated := v.repeated("for")
439
- repeated.walk(node.Cond)
440
- repeated.walk(node.Post)
441
- repeated.walk(node.Body)
442
- return nil
443
- case *ast.RangeStmt:
444
- v.walk(node.Key)
445
- v.walk(node.Value)
446
- v.walk(node.X)
447
- v.repeated("range").walk(node.Body)
448
- return nil
449
- case *ast.CallExpr:
450
- if target := migrationAcquisitionTarget(v.file, node.Fun); target != "" {
451
- *v.uses = append(*v.uses, migrationAcquisitionUse{file: v.file.name, function: v.function, target: target, loop: v.loop, functionValue: v.functionValue})
452
- } else {
453
- v.walk(node.Fun)
454
- }
455
- for _, argument := range node.Args {
456
- v.walk(argument)
457
- }
458
- return nil
459
- case *ast.SelectorExpr:
460
- if target := migrationAcquisitionTarget(v.file, node); target != "" {
461
- *v.uses = append(*v.uses, migrationAcquisitionUse{file: v.file.name, function: v.function, target: target, loop: v.loop, functionValue: true})
462
- }
463
- v.walk(node.X)
464
- return nil
465
- case *ast.Ident:
466
- if target := migrationAcquisitionTarget(v.file, node); target != "" {
467
- *v.uses = append(*v.uses, migrationAcquisitionUse{file: v.file.name, function: v.function, target: target, loop: v.loop, functionValue: true})
468
- }
469
- }
470
- return v
471
- }
472
-
473
- func (v migrationAcquisitionVisitor) walk(node ast.Node) {
474
- if node != nil {
475
- ast.Walk(v, node)
476
- }
477
- }
478
-
479
- func (v migrationAcquisitionVisitor) repeated(loop string) migrationAcquisitionVisitor {
480
- if v.loop == "" {
481
- v.loop = loop
482
- }
483
- return v
484
- }
485
-
486
- func migrationAcquisitionTarget(file *migrationFile, expression ast.Expr) string {
487
- switch expression := expression.(type) {
488
- case *ast.ParenExpr:
489
- return migrationAcquisitionTarget(file, expression.X)
490
- case *ast.SelectorExpr:
491
- receiver, ok := expression.X.(*ast.Ident)
492
- if ok && expression.Sel.Name == "ObserveWorkspace" && file.imports[receiver.Name] == migrationStateImport {
493
- return "state.ObserveWorkspace"
494
- }
495
- case *ast.Ident:
496
- if expression.Name == "observeWorkspace" && file.packageName == "state" {
497
- return "observeWorkspace"
498
- }
499
- if expression.Name == "ObserveWorkspace" && file.imports["."] == migrationStateImport {
500
- return "state.ObserveWorkspace"
501
- }
502
- }
503
- return ""
504
- }
505
-
506
- func parseMigrationProgram(t *testing.T, engineRoot string) *migrationProgram {
507
- t.Helper()
508
- program := newMigrationProgram()
509
- for _, name := range productionGoFiles(t, engineRoot) {
510
- program.addFile(t, name, filepath.Join(engineRoot, name), nil)
511
- }
512
- return program
513
- }
514
-
515
- func parseMigrationFixture(t *testing.T, sources map[string]string) *migrationProgram {
516
- t.Helper()
517
- names := make([]string, 0, len(sources))
518
- for name := range sources {
519
- names = append(names, name)
520
- }
521
- sort.Strings(names)
522
- program := newMigrationProgram()
523
- for _, name := range names {
524
- program.addFile(t, name, name, []byte(sources[name]))
525
- }
526
- return program
527
- }
528
-
529
- func parseCompleteMigrationAcquisitionFixture(t *testing.T, checkBody string) *migrationProgram {
530
- t.Helper()
531
- return parseMigrationFixture(t, map[string]string{
532
- "internal/state/observation.go": `package state
533
- func ObserveWorkspace() { observeWorkspace() }
534
- func observeWorkspace() {}
535
- `,
536
- "internal/state/status.go": `package state
537
- func Status() { statusWithCallback() }
538
- func statusWithCallback() { observeWorkspace() }
539
- `,
540
- "internal/gate/gate.go": fmt.Sprintf(`package gate
541
- import %q
542
- func Check() {
543
- %s
544
- }
545
- `, migrationStateImport, checkBody),
546
- "internal/gate/readiness_binding.go": fmt.Sprintf(`package gate
547
- import %q
548
- func ReadinessBinding() { state.ObserveWorkspace() }
549
- func ReadinessInputDigests() { state.ObserveWorkspace() }
550
- `, migrationStateImport),
551
- })
552
- }
553
-
554
- func newMigrationProgram() *migrationProgram {
555
- return &migrationProgram{functions: make(map[migrationEntry]*migrationFunction)}
556
- }
557
-
558
- func (p *migrationProgram) addFile(t *testing.T, name, parsePath string, source []byte) {
559
- t.Helper()
560
- var parserSource any
561
- if source != nil {
562
- parserSource = source
563
- }
564
- file, err := parser.ParseFile(token.NewFileSet(), parsePath, parserSource, 0)
565
- if err != nil {
566
- t.Fatal(err)
567
- }
568
- name = filepath.ToSlash(name)
569
- parsed := &migrationFile{
570
- name: name,
571
- directory: filepath.ToSlash(filepath.Dir(name)),
572
- packageName: file.Name.Name,
573
- syntax: file,
574
- imports: make(map[string]string),
575
- }
576
- for _, spec := range file.Imports {
577
- importPath, err := strconv.Unquote(spec.Path.Value)
578
- if err != nil {
579
- t.Fatal(err)
580
- }
581
- alias := filepath.Base(importPath)
582
- if spec.Name != nil {
583
- alias = spec.Name.Name
584
- }
585
- parsed.imports[alias] = importPath
586
- }
587
- p.files = append(p.files, parsed)
588
- for _, declaration := range file.Decls {
589
- function, ok := declaration.(*ast.FuncDecl)
590
- if !ok || function.Body == nil {
591
- continue
592
- }
593
- entry := migrationEntry{
594
- directory: parsed.directory,
595
- receiver: migrationReceiverName(function),
596
- function: function.Name.Name,
597
- }
598
- p.functions[entry] = &migrationFunction{file: parsed, decl: function}
599
- }
600
- }
601
-
602
- func migrationReceiverName(function *ast.FuncDecl) string {
603
- if function.Recv == nil || len(function.Recv.List) == 0 {
604
- return ""
605
- }
606
- return migrationTypeName(function.Recv.List[0].Type)
607
- }
608
-
609
- func migrationTypeName(expression ast.Expr) string {
610
- switch expression := expression.(type) {
611
- case *ast.Ident:
612
- return expression.Name
613
- case *ast.StarExpr:
614
- return migrationTypeName(expression.X)
615
- case *ast.IndexExpr:
616
- return migrationTypeName(expression.X)
617
- case *ast.IndexListExpr:
618
- return migrationTypeName(expression.X)
619
- default:
620
- return ""
621
- }
622
- }
623
-
624
- func obsoleteSurfaceProblems(program *migrationProgram) []string {
625
- stateFunctions := map[string]bool{
626
- "LoadFeature": true,
627
- "MissingFor": true,
628
- "MissingWorkspaceFiles": true,
629
- "NewReport": true,
630
- }
631
- stateReaders := map[string]bool{
632
- "declaredPhaseFromLedger": true,
633
- "sectionPresentAny": true,
634
- "sectionPresent": true,
635
- }
636
- gateReaders := map[string]bool{
637
- "openHumanGates": true,
638
- "readReadinessInput": true,
639
- }
640
- gateConstants := map[string]bool{
641
- "maxReadinessInputBytes": true,
642
- "maxReadinessTotalBytes": true,
643
- }
644
- stateSelectors := map[string]bool{
645
- "Feature": true,
646
- "LoadFeature": true,
647
- "MissingFor": true,
648
- "MissingWorkspaceFiles": true,
649
- "NewReport": true,
650
- }
651
-
652
- seen := make(map[string]bool)
653
- var problems []string
654
- addProblem := func(problem string) {
655
- if !seen[problem] {
656
- seen[problem] = true
657
- problems = append(problems, problem)
658
- }
659
- }
660
- for _, file := range program.files {
661
- for _, declaration := range file.syntax.Decls {
662
- switch declaration := declaration.(type) {
663
- case *ast.FuncDecl:
664
- receiver := migrationReceiverName(declaration)
665
- switch {
666
- case file.directory == "internal/state" && receiver == "" && (stateFunctions[declaration.Name.Name] || stateReaders[declaration.Name.Name]):
667
- addProblem(fmt.Sprintf("%s defines superseded state function %s", file.name, declaration.Name.Name))
668
- case file.directory == "internal/state" && receiver == "WorkspaceObservation" && declaration.Name.Name == "MissingSections":
669
- addProblem(fmt.Sprintf("%s defines superseded WorkspaceObservation.MissingSections", file.name))
670
- case file.directory == "internal/gate" && receiver == "" && gateReaders[declaration.Name.Name]:
671
- addProblem(fmt.Sprintf("%s defines superseded gate reader %s", file.name, declaration.Name.Name))
672
- }
673
- entry := migrationEntry{directory: file.directory, receiver: receiver, function: declaration.Name.Name}
674
- function := program.functions[entry]
675
- if function == nil {
676
- continue
677
- }
678
- variableTypes := migrationVariableTypes(program, function)
679
- ast.Inspect(declaration.Body, func(node ast.Node) bool {
680
- switch node := node.(type) {
681
- case *ast.CallExpr:
682
- identifier, ok := node.Fun.(*ast.Ident)
683
- if !ok {
684
- return true
685
- }
686
- if file.directory == "internal/state" && (stateFunctions[identifier.Name] || stateReaders[identifier.Name]) {
687
- addProblem(fmt.Sprintf("%s:%s calls superseded state function %s", file.name, declaration.Name.Name, identifier.Name))
688
- }
689
- if file.directory == "internal/gate" && gateReaders[identifier.Name] {
690
- addProblem(fmt.Sprintf("%s:%s calls superseded gate reader %s", file.name, declaration.Name.Name, identifier.Name))
691
- }
692
- case *ast.SelectorExpr:
693
- receiverType := migrationExpressionType(program, function.file.directory, node.X, variableTypes)
694
- if file.directory == "internal/state" && receiverType == "Feature" && (node.Sel.Name == "Present" || node.Sel.Name == "PresentFiles") {
695
- addProblem(fmt.Sprintf("%s:%s selects superseded Feature.%s", file.name, declaration.Name.Name, node.Sel.Name))
696
- }
697
- if file.directory == "internal/state" && receiverType == "WorkspaceObservation" && node.Sel.Name == "MissingSections" {
698
- addProblem(fmt.Sprintf("%s:%s calls superseded WorkspaceObservation.MissingSections", file.name, declaration.Name.Name))
699
- }
700
- }
701
- return true
702
- })
703
- case *ast.GenDecl:
704
- for _, spec := range declaration.Specs {
705
- switch spec := spec.(type) {
706
- case *ast.TypeSpec:
707
- if file.directory == "internal/state" && spec.Name.Name == "Feature" {
708
- addProblem(fmt.Sprintf("%s defines superseded state type Feature", file.name))
709
- if structure, ok := spec.Type.(*ast.StructType); ok {
710
- for _, field := range structure.Fields.List {
711
- for _, name := range field.Names {
712
- if name.Name == "Present" || name.Name == "PresentFiles" {
713
- addProblem(fmt.Sprintf("%s defines superseded Feature.%s", file.name, name.Name))
714
- }
715
- }
716
- }
717
- }
718
- }
719
- case *ast.ValueSpec:
720
- if file.directory == "internal/gate" {
721
- for _, name := range spec.Names {
722
- if gateConstants[name.Name] {
723
- addProblem(fmt.Sprintf("%s defines superseded gate constant %s", file.name, name.Name))
724
- }
725
- }
726
- }
727
- }
728
- }
729
- }
730
- }
731
- ast.Inspect(file.syntax, func(node ast.Node) bool {
732
- selector, ok := node.(*ast.SelectorExpr)
733
- if !ok {
734
- return true
735
- }
736
- receiver, ok := selector.X.(*ast.Ident)
737
- if ok && file.imports[receiver.Name] == migrationStateImport && stateSelectors[selector.Sel.Name] {
738
- addProblem(fmt.Sprintf("%s selects superseded state.%s", file.name, selector.Sel.Name))
739
- }
740
- return true
741
- })
742
- }
743
- sort.Strings(problems)
744
- return problems
745
- }
746
-
747
- func acquisitionProblems(program *migrationProgram) []string {
748
- allowed := map[migrationAcquisitionUse]int{
749
- {file: "internal/state/observation.go", function: "ObserveWorkspace", target: "observeWorkspace"}: 1,
750
- {file: "internal/state/status.go", function: "statusWithCallback", target: "observeWorkspace"}: 1,
751
- {file: "internal/gate/gate.go", function: "Check", target: "state.ObserveWorkspace"}: 1,
752
- {file: "internal/gate/readiness_binding.go", function: "ReadinessBinding", target: "state.ObserveWorkspace"}: 1,
753
- {file: "internal/gate/readiness_binding.go", function: "ReadinessInputDigests", target: "state.ObserveWorkspace"}: 1,
754
- }
755
- counts := make(map[migrationAcquisitionUse]int)
756
- var problems []string
757
- for _, use := range migrationAcquisitionUses(program) {
758
- if use.functionValue {
759
- problems = append(problems, fmt.Sprintf("%s:%s retains acquisition function reference %s; only direct calls are approved", use.file, use.function, use.target))
760
- continue
761
- }
762
- key := use
763
- key.loop = ""
764
- counts[key]++
765
- if _, ok := allowed[key]; !ok {
766
- problems = append(problems, fmt.Sprintf("%s:%s retains unapproved acquisition call %s", use.file, use.function, use.target))
767
- } else if use.loop != "" {
768
- problems = append(problems, fmt.Sprintf("%s:%s calls %s inside a %s loop; repeated acquisition risk", use.file, use.function, use.target, use.loop))
769
- }
770
- }
771
- for acquisition, want := range allowed {
772
- if got := counts[acquisition]; got != want {
773
- problems = append(problems, fmt.Sprintf("%s:%s calls %s %d times, want %d", acquisition.file, acquisition.function, acquisition.target, got, want))
774
- }
775
- }
776
- status := migrationEntry{directory: "internal/state", function: "Status"}
777
- statusFunction, ok := program.functions[status]
778
- if !ok || statusFunction.file.name != "internal/state/status.go" {
779
- problems = append(problems, "internal/state/status.go:Status is missing")
780
- } else if got := migrationLocalReferenceCount(program, status, "statusWithCallback"); got != 1 {
781
- problems = append(problems, fmt.Sprintf("internal/state/status.go:Status references statusWithCallback %d times, want 1", got))
782
- }
783
- sort.Strings(problems)
784
- return problems
785
- }
786
-
787
- func migrationAcquisitionUses(program *migrationProgram) []migrationAcquisitionUse {
788
- var uses []migrationAcquisitionUse
789
- for _, file := range program.files {
790
- for _, declaration := range file.syntax.Decls {
791
- switch declaration := declaration.(type) {
792
- case *ast.FuncDecl:
793
- if declaration.Body != nil {
794
- inspectMigrationAcquisitions(file, declaration.Name.Name, declaration.Body, &uses)
795
- }
796
- case *ast.GenDecl:
797
- for _, spec := range declaration.Specs {
798
- value, ok := spec.(*ast.ValueSpec)
799
- if !ok {
800
- continue
801
- }
802
- for _, expression := range value.Values {
803
- inspectMigrationAcquisitions(file, "<package>", expression, &uses)
804
- }
805
- }
806
- }
807
- }
808
- }
809
- return uses
810
- }
811
-
812
- func inspectMigrationAcquisitions(file *migrationFile, function string, root ast.Node, uses *[]migrationAcquisitionUse) {
813
- ast.Walk(migrationAcquisitionVisitor{file: file, function: function, uses: uses}, root)
814
- }
815
-
816
- func inspectMigrationIdentifiers(root ast.Node, visit func(*ast.Ident)) {
817
- var inspect func(ast.Node) bool
818
- inspect = func(node ast.Node) bool {
819
- if selector, ok := node.(*ast.SelectorExpr); ok {
820
- ast.Inspect(selector.X, inspect)
821
- return false
822
- }
823
- if identifier, ok := node.(*ast.Ident); ok {
824
- visit(identifier)
825
- }
826
- return true
827
- }
828
- ast.Inspect(root, inspect)
829
- }
830
-
831
- func migrationLocalReferenceCount(program *migrationProgram, entry migrationEntry, target string) int {
832
- function, ok := program.functions[entry]
833
- if !ok {
834
- return 0
835
- }
836
- count := 0
837
- inspectMigrationIdentifiers(function.decl.Body, func(identifier *ast.Ident) {
838
- if identifier.Name == target {
839
- count++
840
- }
841
- })
842
- return count
843
- }
844
-
845
- func migrationConsumerEntries() []migrationEntry {
846
- return []migrationEntry{
847
- {directory: "internal/state", function: "Status"},
848
- {directory: "internal/gate", function: "Check"},
849
- {directory: "internal/gate", function: "ReadinessBinding"},
850
- }
851
- }
852
-
853
- func consumerReachabilityProblems(program *migrationProgram, roots []migrationEntry) []string {
854
- forbiddenImports := map[string]bool{
855
- "io": true,
856
- "os": true,
857
- "path/filepath": true,
858
- "github.com/devrites/devrites/internal/devritespaths": true,
859
- }
860
- allowedInternalImports := map[string]bool{
861
- "github.com/devrites/devrites/internal/acceptance": true,
862
- "github.com/devrites/devrites/internal/markdowntext": true,
863
- "github.com/devrites/devrites/internal/reason": true,
864
- migrationStateImport: true,
865
- }
866
- queue := append([]migrationEntry(nil), roots...)
867
- visited := make(map[migrationEntry]bool)
868
- seenProblems := make(map[string]bool)
869
- var problems []string
870
- addProblem := func(problem string) {
871
- if !seenProblems[problem] {
872
- seenProblems[problem] = true
873
- problems = append(problems, problem)
874
- }
875
- }
876
- for len(queue) > 0 {
877
- entry := queue[0]
878
- queue = queue[1:]
879
- if visited[entry] {
880
- continue
881
- }
882
- visited[entry] = true
883
- function, ok := program.functions[entry]
884
- if !ok {
885
- addProblem(fmt.Sprintf("consumer entry %s.%s is missing", entry.directory, entry.function))
886
- continue
887
- }
888
- ast.Inspect(function.decl.Body, func(node ast.Node) bool {
889
- selector, ok := node.(*ast.SelectorExpr)
890
- if !ok {
891
- return true
892
- }
893
- receiver, ok := selector.X.(*ast.Ident)
894
- if !ok {
895
- return true
896
- }
897
- importPath := function.file.imports[receiver.Name]
898
- switch {
899
- case forbiddenImports[importPath]:
900
- addProblem(fmt.Sprintf("reachable consumer file %s imports filesystem content-reader package %q", function.file.name, importPath))
901
- case strings.HasPrefix(importPath, "github.com/devrites/devrites/internal/") && !allowedInternalImports[importPath]:
902
- addProblem(fmt.Sprintf("reachable consumer file %s delegates through unapproved internal package %q", function.file.name, importPath))
903
- }
904
- return true
905
- })
906
- inspectMigrationIdentifiers(function.decl.Body, func(identifier *ast.Ident) {
907
- callee := migrationEntry{directory: entry.directory, function: identifier.Name}
908
- if _, exists := program.functions[callee]; exists && !migrationAcquisitionBoundary(entry, callee) {
909
- queue = append(queue, callee)
910
- }
911
- })
912
- for _, callee := range migrationMethodCallees(program, entry, function) {
913
- if !migrationAcquisitionBoundary(entry, callee) {
914
- queue = append(queue, callee)
915
- }
916
- }
917
- }
918
- sort.Strings(problems)
919
- return problems
920
- }
921
-
922
- func migrationMethodCallees(program *migrationProgram, caller migrationEntry, function *migrationFunction) []migrationEntry {
923
- variableTypes := migrationVariableTypes(program, function)
924
- var callees []migrationEntry
925
- ast.Inspect(function.decl.Body, func(node ast.Node) bool {
926
- call, ok := node.(*ast.CallExpr)
927
- if !ok {
928
- return true
929
- }
930
- selector, ok := call.Fun.(*ast.SelectorExpr)
931
- if !ok {
932
- return true
933
- }
934
- receiver := migrationExpressionType(program, function.file.directory, selector.X, variableTypes)
935
- if receiver == "" {
936
- return true
937
- }
938
- callee := migrationEntry{directory: caller.directory, receiver: receiver, function: selector.Sel.Name}
939
- if _, exists := program.functions[callee]; exists {
940
- callees = append(callees, callee)
941
- }
942
- return true
943
- })
944
- return callees
945
- }
946
-
947
- func migrationVariableTypes(program *migrationProgram, function *migrationFunction) map[string]string {
948
- types := make(map[string]string)
949
- addFields := func(fields *ast.FieldList) {
950
- if fields == nil {
951
- return
952
- }
953
- for _, field := range fields.List {
954
- typeName := migrationTypeName(field.Type)
955
- for _, name := range field.Names {
956
- types[name.Name] = typeName
957
- }
958
- }
959
- }
960
- addFields(function.decl.Recv)
961
- addFields(function.decl.Type.Params)
962
- addFields(function.decl.Type.Results)
963
-
964
- ast.Inspect(function.decl.Body, func(node ast.Node) bool {
965
- switch node := node.(type) {
966
- case *ast.ValueSpec:
967
- for i, name := range node.Names {
968
- typeName := migrationTypeName(node.Type)
969
- if typeName == "" && i < len(node.Values) {
970
- typeName = migrationExpressionType(program, function.file.directory, node.Values[i], types)
971
- }
972
- if typeName != "" {
973
- types[name.Name] = typeName
974
- }
975
- }
976
- case *ast.AssignStmt:
977
- if len(node.Lhs) != len(node.Rhs) {
978
- return true
979
- }
980
- for i, left := range node.Lhs {
981
- identifier, ok := left.(*ast.Ident)
982
- if !ok {
983
- continue
984
- }
985
- typeName := migrationExpressionType(program, function.file.directory, node.Rhs[i], types)
986
- if typeName != "" {
987
- types[identifier.Name] = typeName
988
- }
989
- }
990
- }
991
- return true
992
- })
993
- return types
994
- }
995
-
996
- func migrationExpressionType(program *migrationProgram, directory string, expression ast.Expr, variableTypes map[string]string) string {
997
- switch expression := expression.(type) {
998
- case *ast.Ident:
999
- return variableTypes[expression.Name]
1000
- case *ast.CompositeLit:
1001
- return migrationTypeName(expression.Type)
1002
- case *ast.UnaryExpr:
1003
- return migrationExpressionType(program, directory, expression.X, variableTypes)
1004
- case *ast.ParenExpr:
1005
- return migrationExpressionType(program, directory, expression.X, variableTypes)
1006
- case *ast.CallExpr:
1007
- identifier, ok := expression.Fun.(*ast.Ident)
1008
- if !ok {
1009
- return ""
1010
- }
1011
- if identifier.Name == "new" && len(expression.Args) == 1 {
1012
- return migrationTypeName(expression.Args[0])
1013
- }
1014
- return migrationFunctionResultType(program.functions[migrationEntry{directory: directory, function: identifier.Name}])
1015
- }
1016
- return ""
1017
- }
1018
-
1019
- func migrationFunctionResultType(function *migrationFunction) string {
1020
- if function == nil || function.decl.Type.Results == nil || len(function.decl.Type.Results.List) != 1 {
1021
- return ""
1022
- }
1023
- result := function.decl.Type.Results.List[0]
1024
- if len(result.Names) > 1 {
1025
- return ""
1026
- }
1027
- return migrationTypeName(result.Type)
1028
- }
1029
-
1030
- func migrationAcquisitionBoundary(caller, callee migrationEntry) bool {
1031
- return caller == (migrationEntry{directory: "internal/state", function: "statusWithCallback"}) &&
1032
- callee == (migrationEntry{directory: "internal/state", function: "observeWorkspace"})
1033
- }
1034
-
1035
- func migrationProblemContains(problems []string, fragments ...string) bool {
1036
- for _, problem := range problems {
1037
- matched := true
1038
- for _, fragment := range fragments {
1039
- matched = matched && strings.Contains(problem, fragment)
1040
- }
1041
- if matched {
1042
- return true
1043
- }
1044
- }
1045
- return false
1046
- }
1047
-
1048
- func productionGoFiles(t *testing.T, engineRoot string) []string {
1049
- t.Helper()
1050
- var files []string
1051
- err := filepath.WalkDir(engineRoot, func(path string, entry os.DirEntry, walkErr error) error {
1052
- if walkErr != nil {
1053
- return walkErr
1054
- }
1055
- if entry.IsDir() || !strings.HasSuffix(entry.Name(), ".go") || strings.HasSuffix(entry.Name(), "_test.go") {
1056
- return nil
1057
- }
1058
- relative, err := filepath.Rel(engineRoot, path)
1059
- if err != nil {
1060
- return err
1061
- }
1062
- files = append(files, filepath.ToSlash(relative))
1063
- return nil
1064
- })
1065
- if err != nil {
1066
- t.Fatal(err)
1067
- }
1068
- return files
1069
- }