devrites 3.0.7 → 3.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (472) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +67 -47
  3. package/SECURITY.md +31 -29
  4. package/docs/adr/0001-go-engine-as-control-plane.md +1 -1
  5. package/docs/adr/0002-dual-host-harness.md +1 -1
  6. package/docs/adr/0004-state-schema-phases-sections.md +1 -2
  7. package/docs/adr/0006-clock-seam-and-engine-ci-gates.md +3 -4
  8. package/docs/adr/0009-prebuild-decision-coverage-and-readiness.md +67 -0
  9. package/docs/adr/0010-agent-first-fresh-context-orchestration.md +71 -0
  10. package/docs/adr/0011-define-plan-transition-rights.md +28 -0
  11. package/docs/adr/README.md +3 -0
  12. package/docs/agents/triage-labels.md +7 -7
  13. package/docs/architecture.md +157 -140
  14. package/docs/cli.md +41 -12
  15. package/docs/command-map.md +49 -35
  16. package/docs/engine/agent-contract.md +92 -15
  17. package/docs/engine/commands.md +242 -72
  18. package/docs/engine/state-schema.md +52 -23
  19. package/docs/engine/workspace-schema.md +94 -15
  20. package/docs/extensions.md +1 -1
  21. package/docs/flow.md +80 -50
  22. package/docs/harness-compliance.md +29 -5
  23. package/docs/orchestration.md +107 -79
  24. package/docs/quick-reference.md +7 -3
  25. package/docs/release.md +4 -3
  26. package/docs/skills.md +64 -38
  27. package/docs/usage.md +57 -38
  28. package/engine/cmd/releasepack/main.go +219 -0
  29. package/engine/cmd/releasepack/main_test.go +170 -0
  30. package/engine/commands.go +170 -23
  31. package/engine/git_guard.go +187 -0
  32. package/engine/git_guard_test.go +283 -0
  33. package/engine/hookpolicy.go +53 -55
  34. package/engine/hookpolicy_test.go +91 -1
  35. package/engine/hooks.go +296 -75
  36. package/engine/hooks_events_test.go +276 -6
  37. package/engine/hooks_workspace.go +640 -159
  38. package/engine/internal/devritespaths/paths.go +65 -10
  39. package/engine/internal/devritespaths/paths_test.go +110 -0
  40. package/engine/internal/doctor/doctor.go +153 -23
  41. package/engine/internal/doctor/doctor_test.go +74 -0
  42. package/engine/internal/forge/forge.go +940 -0
  43. package/engine/internal/forge/forge_test.go +576 -0
  44. package/engine/internal/forge/git.go +245 -0
  45. package/engine/internal/forge/liveness_unix.go +48 -0
  46. package/engine/internal/forge/liveness_windows.go +67 -0
  47. package/engine/internal/forge/manifest.go +402 -0
  48. package/engine/internal/gate/gate.go +90 -71
  49. package/engine/internal/gate/gate_test.go +71 -2
  50. package/engine/internal/harness/compliance.go +18 -24
  51. package/engine/internal/harness/harness.go +37 -44
  52. package/engine/internal/harness/harness_test.go +21 -5
  53. package/engine/internal/install/install.go +486 -38
  54. package/engine/internal/install/install_test.go +383 -10
  55. package/engine/internal/iohooks/iohooks.go +350 -59
  56. package/engine/internal/iohooks/iohooks_test.go +421 -1
  57. package/engine/internal/lib/buildreadiness.go +35 -18
  58. package/engine/internal/lib/clarifyreturn.go +91 -0
  59. package/engine/internal/lib/clarifyreturn_test.go +123 -0
  60. package/engine/internal/lib/context.go +54 -15
  61. package/engine/internal/lib/cursor_compat_test.go +8 -0
  62. package/engine/internal/lib/extensions.go +2 -3
  63. package/engine/internal/lib/gitauthority.go +601 -0
  64. package/engine/internal/lib/gitauthority_test.go +346 -0
  65. package/engine/internal/lib/jsonout.go +25 -11
  66. package/engine/internal/lib/jsonout_test.go +16 -0
  67. package/engine/internal/lib/lanes.go +14 -8
  68. package/engine/internal/lib/observability_test.go +358 -0
  69. package/engine/internal/lib/packageexistence.go +151 -35
  70. package/engine/internal/lib/packageexistence_test.go +163 -0
  71. package/engine/internal/lib/progress.go +11 -9
  72. package/engine/internal/lib/provenance.go +462 -0
  73. package/engine/internal/lib/provenance_test.go +154 -0
  74. package/engine/internal/lib/readiness_contract.json +111 -0
  75. package/engine/internal/lib/readinessartifact.go +510 -0
  76. package/engine/internal/lib/readinessartifact_test.go +321 -0
  77. package/engine/internal/lib/reconcile.go +712 -88
  78. package/engine/internal/lib/reconcile_test.go +335 -16
  79. package/engine/internal/lib/recoveryattempts.go +298 -0
  80. package/engine/internal/lib/recoveryattempts_test.go +215 -0
  81. package/engine/internal/lib/resolve.go +23 -19
  82. package/engine/internal/lib/runbook_context_test.go +20 -0
  83. package/engine/internal/lib/session.go +701 -9
  84. package/engine/internal/lib/session_test.go +80 -13
  85. package/engine/internal/lib/testintegrity.go +33 -37
  86. package/engine/internal/lib/testintegrity_test.go +63 -1
  87. package/engine/internal/migrate/migrate.go +81 -1
  88. package/engine/internal/migrate/migrate_test.go +22 -1
  89. package/engine/internal/reason/reason.go +180 -0
  90. package/engine/internal/reason/reason_test.go +35 -0
  91. package/engine/internal/rootfacts/facts.go +466 -0
  92. package/engine/internal/rootfacts/facts_test.go +306 -0
  93. package/engine/internal/safepath/safepath.go +55 -0
  94. package/engine/internal/safepath/safepath_test.go +69 -0
  95. package/engine/internal/safepath/safepath_windows_test.go +26 -0
  96. package/engine/internal/state/clarify_transition.go +165 -0
  97. package/engine/internal/state/clarify_transition_test.go +130 -0
  98. package/engine/internal/state/cmd/workflowmanifest/main.go +12 -8
  99. package/engine/internal/state/cursor.go +58 -0
  100. package/engine/internal/state/cursor_test.go +42 -1
  101. package/engine/internal/state/feature.go +35 -48
  102. package/engine/internal/state/schema.go +90 -37
  103. package/engine/internal/state/snapshot.go +18 -2
  104. package/engine/internal/state/state_test.go +187 -7
  105. package/engine/internal/state/status.go +48 -11
  106. package/engine/internal/state/workflow_manifest.json +231 -50
  107. package/engine/internal/toolpolicy/classifier.go +533 -0
  108. package/engine/internal/toolpolicy/classifier_test.go +424 -0
  109. package/engine/internal/toolpolicy/git.go +616 -0
  110. package/engine/internal/toolpolicy/scanner.go +382 -0
  111. package/engine/main.go +160 -77
  112. package/engine/observability_cli_test.go +52 -0
  113. package/engine/root_routing_test.go +277 -0
  114. package/engine/testdata/golden/TestParityBuildReadiness/arg=approved.golden +1 -1
  115. package/engine/testdata/golden/TestParityBuildReadiness/arg=emptystatus.golden +1 -1
  116. package/engine/testdata/golden/TestParityBuildReadiness/arg=noclarify.golden +1 -0
  117. package/engine/testdata/golden/TestParityBuildReadiness/arg=novet.golden +1 -0
  118. package/engine/testdata/golden/TestParityBuildReadiness/arg=stalevet.golden +1 -0
  119. package/engine/testdata/golden/TestParityBuildReadiness/arg=trailhash.golden +1 -1
  120. package/engine/testdata/golden/TestParityBuildReadiness/arg=trailpipe.golden +1 -1
  121. package/engine/testdata/golden/TestParityBuildReadiness/arg=vetnotready.golden +1 -0
  122. package/engine/testdata/golden/TestParityProgress/arg=allbuilt.golden +1 -1
  123. package/engine/testdata/golden/TestParityProgress/arg=done.golden +1 -1
  124. package/engine/testdata/golden/TestParityProgress/arg=mid.golden +1 -1
  125. package/engine/testdata/golden/TestParityProgress/arg=nophase.golden +1 -1
  126. package/engine/testdata/golden/TestParityProgress/arg=noslice.golden +1 -1
  127. package/engine/testdata/golden/TestParityProgress/arg=plan.golden +1 -1
  128. package/engine/testdata/golden/TestParityProgress/arg=seal.golden +1 -1
  129. package/engine/testdata/golden/TestParityReconcile/check-clean.golden +1 -1
  130. package/engine/testdata/golden/TestParityReconcile/inline-fallback.golden +1 -0
  131. package/engine/testdata/golden/TestParityReconcile/snapshot-no-allowlist.golden +1 -0
  132. package/engine/testdata/golden/TestParityWrightScope/devrites-edit-denied.golden +2 -0
  133. package/engine/testdata/golden/TestParityWrightScope/out-of-scope-enforce-denies.golden +1 -1
  134. package/engine/tests/adr_0011_define_plan_test.go +30 -0
  135. package/engine/tests/budget_test.go +19 -8
  136. package/engine/tests/concurrency_cli_test.go +7 -1
  137. package/engine/tests/doctor_cli_test.go +148 -2
  138. package/engine/tests/forge_cli_test.go +463 -0
  139. package/engine/tests/gate_test.go +63 -8
  140. package/engine/tests/hook_test.go +260 -8
  141. package/engine/tests/hooks_io_test.go +94 -3
  142. package/engine/tests/json_contract_test.go +127 -2
  143. package/engine/tests/migrate_cli_test.go +2 -2
  144. package/engine/tests/parity_buildreadiness_test.go +141 -10
  145. package/engine/tests/parity_learnings_test.go +16 -17
  146. package/engine/tests/parity_reconcile_test.go +20 -17
  147. package/engine/tests/parity_resolve_test.go +12 -11
  148. package/engine/tests/parity_test.go +21 -17
  149. package/pack/.claude/agents/devrites-code-reviewer.md +62 -48
  150. package/pack/.claude/agents/devrites-devex-reviewer.md +69 -53
  151. package/pack/.claude/agents/devrites-doubt-reviewer.md +29 -22
  152. package/pack/.claude/agents/devrites-evidence-scout.md +69 -0
  153. package/pack/.claude/agents/devrites-forge-judge.md +74 -61
  154. package/pack/.claude/agents/devrites-frontend-reviewer.md +48 -39
  155. package/pack/.claude/agents/devrites-performance-reviewer.md +49 -40
  156. package/pack/.claude/agents/devrites-plan-drafter.md +71 -0
  157. package/pack/.claude/agents/devrites-plan-reviewer.md +80 -47
  158. package/pack/.claude/agents/devrites-proof-runner.md +74 -0
  159. package/pack/.claude/agents/devrites-retrospector.md +48 -45
  160. package/pack/.claude/agents/devrites-security-auditor.md +46 -36
  161. package/pack/.claude/agents/devrites-simplifier-reviewer.md +50 -46
  162. package/pack/.claude/agents/devrites-slice-wright.md +153 -165
  163. package/pack/.claude/agents/devrites-spec-reviewer.md +34 -32
  164. package/pack/.claude/agents/devrites-strategy-reviewer.md +63 -34
  165. package/pack/.claude/agents/devrites-test-analyst.md +40 -30
  166. package/pack/.claude/settings.json +2 -1
  167. package/pack/.claude/skills/devrites-audit/SKILL.md +40 -61
  168. package/pack/.claude/skills/devrites-debug-recovery/SKILL.md +24 -13
  169. package/pack/.claude/skills/devrites-debug-recovery/reference/build-the-loop.md +24 -21
  170. package/pack/.claude/skills/devrites-debug-recovery/reference/cleanup-and-classify.md +34 -6
  171. package/pack/.claude/skills/devrites-debug-recovery/reference/instrumentation.md +2 -2
  172. package/pack/.claude/skills/devrites-doubt/SKILL.md +25 -17
  173. package/pack/.claude/skills/devrites-interview/SKILL.md +53 -52
  174. package/pack/.claude/skills/devrites-lib/SKILL.md +11 -9
  175. package/pack/.claude/skills/devrites-lib/reference/intent-map.md +3 -2
  176. package/pack/.claude/skills/devrites-lib/reference/parallel-dispatch.md +82 -137
  177. package/pack/.claude/skills/devrites-lib/reference/reply-contract.md +8 -1
  178. package/pack/.claude/skills/devrites-lib/reference/standards/README.md +38 -55
  179. package/pack/.claude/skills/devrites-lib/reference/standards/afk-hitl.md +53 -27
  180. package/pack/.claude/skills/devrites-lib/reference/standards/agents.md +198 -190
  181. package/pack/.claude/skills/devrites-lib/reference/standards/anti-patterns.md +5 -15
  182. package/pack/.claude/skills/devrites-lib/reference/standards/ci-cd.md +27 -58
  183. package/pack/.claude/skills/devrites-lib/reference/standards/code-review.md +16 -52
  184. package/pack/.claude/skills/devrites-lib/reference/standards/coding-style.md +2 -10
  185. package/pack/.claude/skills/devrites-lib/reference/standards/context-hygiene.md +18 -61
  186. package/pack/.claude/skills/devrites-lib/reference/standards/core.md +23 -18
  187. package/pack/.claude/skills/devrites-lib/reference/standards/deprecation.md +17 -57
  188. package/pack/.claude/skills/devrites-lib/reference/standards/development-workflow.md +4 -33
  189. package/pack/.claude/skills/devrites-lib/reference/standards/git-workflow.md +4 -20
  190. package/pack/.claude/skills/devrites-lib/reference/standards/hooks.md +3 -14
  191. package/pack/.claude/skills/devrites-lib/reference/standards/patterns.md +9 -25
  192. package/pack/.claude/skills/devrites-lib/reference/standards/performance.md +0 -9
  193. package/pack/.claude/skills/devrites-lib/reference/standards/principles.md +1 -3
  194. package/pack/.claude/skills/devrites-lib/reference/standards/security.md +17 -7
  195. package/pack/.claude/skills/devrites-lib/reference/standards/testing.md +1 -27
  196. package/pack/.claude/skills/devrites-lib/reference/standards/tooling.md +46 -50
  197. package/pack/.claude/skills/devrites-lib/reference/workspace-artifact-schema.md +23 -10
  198. package/pack/.claude/skills/devrites-source-driven/SKILL.md +23 -22
  199. package/pack/.claude/skills/rite/SKILL.md +8 -6
  200. package/pack/.claude/skills/rite/reference/menu.md +8 -6
  201. package/pack/.claude/skills/rite-adopt/SKILL.md +33 -37
  202. package/pack/.claude/skills/rite-autocomplete/SKILL.md +33 -28
  203. package/pack/.claude/skills/rite-autocomplete/reference/loop.md +21 -21
  204. package/pack/.claude/skills/rite-autocomplete/reference/stop-conditions.md +15 -6
  205. package/pack/.claude/skills/rite-build/SKILL.md +35 -30
  206. package/pack/.claude/skills/rite-build/reference/afk-discipline.md +38 -38
  207. package/pack/.claude/skills/rite-build/reference/evidence-standard.md +10 -0
  208. package/pack/.claude/skills/rite-build/reference/forge.md +186 -156
  209. package/pack/.claude/skills/rite-build/reference/one-slice-cycle.md +4 -3
  210. package/pack/.claude/skills/rite-build/reference/phase-contract.md +96 -175
  211. package/pack/.claude/skills/rite-build/reference/wright-dispatch.md +129 -134
  212. package/pack/.claude/skills/rite-clarify/SKILL.md +89 -0
  213. package/pack/.claude/skills/rite-clarify/reference/decision-coverage.md +59 -0
  214. package/pack/.claude/skills/rite-converge/SKILL.md +35 -25
  215. package/pack/.claude/skills/rite-define/SKILL.md +57 -32
  216. package/pack/.claude/skills/rite-define/reference/gates.md +16 -15
  217. package/pack/.claude/skills/rite-define/reference/plan-template.md +16 -8
  218. package/pack/.claude/skills/rite-frame/reference/failure-modes.md +22 -24
  219. package/pack/.claude/skills/rite-plan/SKILL.md +44 -16
  220. package/pack/.claude/skills/rite-plan/reference/task-breakdown.md +4 -0
  221. package/pack/.claude/skills/rite-polish/SKILL.md +27 -23
  222. package/pack/.claude/skills/rite-prototype/SKILL.md +25 -26
  223. package/pack/.claude/skills/rite-prove/SKILL.md +27 -17
  224. package/pack/.claude/skills/rite-resolve/SKILL.md +12 -11
  225. package/pack/.claude/skills/rite-resolve/reference/answer-protocol.md +3 -0
  226. package/pack/.claude/skills/rite-review/SKILL.md +37 -28
  227. package/pack/.claude/skills/rite-seal/reference/phase-contract.md +27 -92
  228. package/pack/.claude/skills/rite-seal/reference/risk-and-rollback.md +13 -0
  229. package/pack/.claude/skills/rite-ship/reference/design-memory.md +31 -36
  230. package/pack/.claude/skills/rite-spec/SKILL.md +84 -135
  231. package/pack/.claude/skills/rite-spec/reference/investigation.md +37 -33
  232. package/pack/.claude/skills/rite-spec/reference/question-protocol.md +6 -2
  233. package/pack/.claude/skills/rite-spec/reference/spec-checklists.md +25 -24
  234. package/pack/.claude/skills/rite-spec/reference/spec-template.md +9 -2
  235. package/pack/.claude/skills/rite-spec/reference/state-workspace.md +13 -3
  236. package/pack/.claude/skills/rite-temper/SKILL.md +62 -47
  237. package/pack/.claude/skills/rite-temper/reference/review-dimensions.md +24 -22
  238. package/pack/.claude/skills/rite-vet/SKILL.md +110 -113
  239. package/pack/.claude/skills/rite-vet/reference/artifacts.md +42 -9
  240. package/pack/.claude/skills/rite-vet/reference/review-axes.md +39 -37
  241. package/pack/generated/claude/agents/devrites-code-reviewer.md +62 -48
  242. package/pack/generated/claude/agents/devrites-devex-reviewer.md +69 -53
  243. package/pack/generated/claude/agents/devrites-doubt-reviewer.md +29 -22
  244. package/pack/generated/claude/agents/devrites-evidence-scout.md +69 -0
  245. package/pack/generated/claude/agents/devrites-forge-judge.md +74 -61
  246. package/pack/generated/claude/agents/devrites-frontend-reviewer.md +48 -39
  247. package/pack/generated/claude/agents/devrites-performance-reviewer.md +49 -40
  248. package/pack/generated/claude/agents/devrites-plan-drafter.md +71 -0
  249. package/pack/generated/claude/agents/devrites-plan-reviewer.md +80 -47
  250. package/pack/generated/claude/agents/devrites-proof-runner.md +74 -0
  251. package/pack/generated/claude/agents/devrites-retrospector.md +48 -45
  252. package/pack/generated/claude/agents/devrites-security-auditor.md +46 -36
  253. package/pack/generated/claude/agents/devrites-simplifier-reviewer.md +50 -46
  254. package/pack/generated/claude/agents/devrites-slice-wright.md +153 -165
  255. package/pack/generated/claude/agents/devrites-spec-reviewer.md +34 -32
  256. package/pack/generated/claude/agents/devrites-strategy-reviewer.md +63 -34
  257. package/pack/generated/claude/agents/devrites-test-analyst.md +40 -30
  258. package/pack/generated/claude/settings.json +2 -1
  259. package/pack/generated/claude/skills/devrites-audit/SKILL.md +40 -61
  260. package/pack/generated/claude/skills/devrites-debug-recovery/SKILL.md +24 -13
  261. package/pack/generated/claude/skills/devrites-debug-recovery/reference/build-the-loop.md +24 -21
  262. package/pack/generated/claude/skills/devrites-debug-recovery/reference/cleanup-and-classify.md +34 -6
  263. package/pack/generated/claude/skills/devrites-debug-recovery/reference/instrumentation.md +2 -2
  264. package/pack/generated/claude/skills/devrites-doubt/SKILL.md +25 -17
  265. package/pack/generated/claude/skills/devrites-interview/SKILL.md +53 -52
  266. package/pack/generated/claude/skills/devrites-lib/SKILL.md +11 -9
  267. package/pack/generated/claude/skills/devrites-lib/reference/intent-map.md +3 -2
  268. package/pack/generated/claude/skills/devrites-lib/reference/parallel-dispatch.md +82 -137
  269. package/pack/generated/claude/skills/devrites-lib/reference/reply-contract.md +8 -1
  270. package/pack/generated/claude/skills/devrites-lib/reference/standards/README.md +38 -55
  271. package/pack/generated/claude/skills/devrites-lib/reference/standards/afk-hitl.md +53 -27
  272. package/pack/generated/claude/skills/devrites-lib/reference/standards/agents.md +198 -190
  273. package/pack/generated/claude/skills/devrites-lib/reference/standards/anti-patterns.md +5 -15
  274. package/pack/generated/claude/skills/devrites-lib/reference/standards/ci-cd.md +27 -58
  275. package/pack/generated/claude/skills/devrites-lib/reference/standards/code-review.md +16 -52
  276. package/pack/generated/claude/skills/devrites-lib/reference/standards/coding-style.md +2 -10
  277. package/pack/generated/claude/skills/devrites-lib/reference/standards/context-hygiene.md +18 -61
  278. package/pack/generated/claude/skills/devrites-lib/reference/standards/core.md +23 -18
  279. package/pack/generated/claude/skills/devrites-lib/reference/standards/deprecation.md +17 -57
  280. package/pack/generated/claude/skills/devrites-lib/reference/standards/development-workflow.md +4 -33
  281. package/pack/generated/claude/skills/devrites-lib/reference/standards/git-workflow.md +4 -20
  282. package/pack/generated/claude/skills/devrites-lib/reference/standards/hooks.md +3 -14
  283. package/pack/generated/claude/skills/devrites-lib/reference/standards/patterns.md +9 -25
  284. package/pack/generated/claude/skills/devrites-lib/reference/standards/performance.md +0 -9
  285. package/pack/generated/claude/skills/devrites-lib/reference/standards/principles.md +1 -3
  286. package/pack/generated/claude/skills/devrites-lib/reference/standards/security.md +17 -7
  287. package/pack/generated/claude/skills/devrites-lib/reference/standards/testing.md +1 -27
  288. package/pack/generated/claude/skills/devrites-lib/reference/standards/tooling.md +46 -50
  289. package/pack/generated/claude/skills/devrites-lib/reference/workspace-artifact-schema.md +23 -10
  290. package/pack/generated/claude/skills/devrites-source-driven/SKILL.md +23 -22
  291. package/pack/generated/claude/skills/rite/SKILL.md +8 -6
  292. package/pack/generated/claude/skills/rite/reference/menu.md +8 -6
  293. package/pack/generated/claude/skills/rite-adopt/SKILL.md +33 -37
  294. package/pack/generated/claude/skills/rite-autocomplete/SKILL.md +33 -28
  295. package/pack/generated/claude/skills/rite-autocomplete/reference/loop.md +21 -21
  296. package/pack/generated/claude/skills/rite-autocomplete/reference/stop-conditions.md +15 -6
  297. package/pack/generated/claude/skills/rite-build/SKILL.md +35 -30
  298. package/pack/generated/claude/skills/rite-build/reference/afk-discipline.md +38 -38
  299. package/pack/generated/claude/skills/rite-build/reference/evidence-standard.md +10 -0
  300. package/pack/generated/claude/skills/rite-build/reference/forge.md +186 -156
  301. package/pack/generated/claude/skills/rite-build/reference/one-slice-cycle.md +4 -3
  302. package/pack/generated/claude/skills/rite-build/reference/phase-contract.md +96 -175
  303. package/pack/generated/claude/skills/rite-build/reference/wright-dispatch.md +129 -134
  304. package/pack/generated/claude/skills/rite-clarify/SKILL.md +89 -0
  305. package/pack/generated/claude/skills/rite-clarify/reference/decision-coverage.md +59 -0
  306. package/pack/generated/claude/skills/rite-converge/SKILL.md +35 -25
  307. package/pack/generated/claude/skills/rite-define/SKILL.md +57 -32
  308. package/pack/generated/claude/skills/rite-define/reference/gates.md +16 -15
  309. package/pack/generated/claude/skills/rite-define/reference/plan-template.md +16 -8
  310. package/pack/generated/claude/skills/rite-frame/reference/failure-modes.md +22 -24
  311. package/pack/generated/claude/skills/rite-plan/SKILL.md +44 -16
  312. package/pack/generated/claude/skills/rite-plan/reference/task-breakdown.md +4 -0
  313. package/pack/generated/claude/skills/rite-polish/SKILL.md +27 -23
  314. package/pack/generated/claude/skills/rite-prototype/SKILL.md +25 -26
  315. package/pack/generated/claude/skills/rite-prove/SKILL.md +27 -17
  316. package/pack/generated/claude/skills/rite-resolve/SKILL.md +12 -11
  317. package/pack/generated/claude/skills/rite-resolve/reference/answer-protocol.md +3 -0
  318. package/pack/generated/claude/skills/rite-review/SKILL.md +37 -28
  319. package/pack/generated/claude/skills/rite-seal/reference/phase-contract.md +27 -92
  320. package/pack/generated/claude/skills/rite-seal/reference/risk-and-rollback.md +13 -0
  321. package/pack/generated/claude/skills/rite-ship/reference/design-memory.md +31 -36
  322. package/pack/generated/claude/skills/rite-spec/SKILL.md +84 -135
  323. package/pack/generated/claude/skills/rite-spec/reference/investigation.md +37 -33
  324. package/pack/generated/claude/skills/rite-spec/reference/question-protocol.md +6 -2
  325. package/pack/generated/claude/skills/rite-spec/reference/spec-checklists.md +25 -24
  326. package/pack/generated/claude/skills/rite-spec/reference/spec-template.md +9 -2
  327. package/pack/generated/claude/skills/rite-spec/reference/state-workspace.md +13 -3
  328. package/pack/generated/claude/skills/rite-temper/SKILL.md +62 -47
  329. package/pack/generated/claude/skills/rite-temper/reference/review-dimensions.md +24 -22
  330. package/pack/generated/claude/skills/rite-vet/SKILL.md +110 -113
  331. package/pack/generated/claude/skills/rite-vet/reference/artifacts.md +42 -9
  332. package/pack/generated/claude/skills/rite-vet/reference/review-axes.md +39 -37
  333. package/pack/generated/codex/AGENTS.md +5 -2
  334. package/pack/generated/codex/agents/devrites-code-reviewer.toml +69 -47
  335. package/pack/generated/codex/agents/devrites-devex-reviewer.toml +75 -51
  336. package/pack/generated/codex/agents/devrites-doubt-reviewer.toml +35 -20
  337. package/pack/generated/codex/agents/devrites-evidence-scout.toml +75 -0
  338. package/pack/generated/codex/agents/devrites-forge-judge.toml +80 -59
  339. package/pack/generated/codex/agents/devrites-frontend-reviewer.toml +54 -37
  340. package/pack/generated/codex/agents/devrites-performance-reviewer.toml +55 -38
  341. package/pack/generated/codex/agents/devrites-plan-drafter.toml +77 -0
  342. package/pack/generated/codex/agents/devrites-plan-reviewer.toml +82 -47
  343. package/pack/generated/codex/agents/devrites-proof-runner.toml +80 -0
  344. package/pack/generated/codex/agents/devrites-retrospector.toml +54 -43
  345. package/pack/generated/codex/agents/devrites-security-auditor.toml +53 -35
  346. package/pack/generated/codex/agents/devrites-simplifier-reviewer.toml +56 -44
  347. package/pack/generated/codex/agents/devrites-slice-wright.toml +159 -163
  348. package/pack/generated/codex/agents/devrites-spec-reviewer.toml +40 -30
  349. package/pack/generated/codex/agents/devrites-strategy-reviewer.toml +65 -34
  350. package/pack/generated/codex/agents/devrites-test-analyst.toml +46 -28
  351. package/pack/generated/codex/hooks.json +4 -14
  352. package/pack/generated/codex/skills/devrites-api-interface/SKILL.md +7 -3
  353. package/pack/generated/codex/skills/devrites-audit/SKILL.md +47 -64
  354. package/pack/generated/codex/skills/devrites-browser-proof/SKILL.md +7 -3
  355. package/pack/generated/codex/skills/devrites-debug-recovery/SKILL.md +31 -16
  356. package/pack/generated/codex/skills/devrites-debug-recovery/reference/build-the-loop.md +24 -21
  357. package/pack/generated/codex/skills/devrites-debug-recovery/reference/cleanup-and-classify.md +34 -6
  358. package/pack/generated/codex/skills/devrites-debug-recovery/reference/instrumentation.md +2 -2
  359. package/pack/generated/codex/skills/devrites-doubt/SKILL.md +32 -20
  360. package/pack/generated/codex/skills/devrites-frontend-craft/SKILL.md +7 -3
  361. package/pack/generated/codex/skills/devrites-interview/SKILL.md +60 -55
  362. package/pack/generated/codex/skills/devrites-lib/SKILL.md +18 -12
  363. package/pack/generated/codex/skills/devrites-lib/reference/intent-map.md +3 -2
  364. package/pack/generated/codex/skills/devrites-lib/reference/parallel-dispatch.md +82 -137
  365. package/pack/generated/codex/skills/devrites-lib/reference/reply-contract.md +8 -1
  366. package/pack/generated/codex/skills/devrites-lib/reference/standards/README.md +38 -55
  367. package/pack/generated/codex/skills/devrites-lib/reference/standards/afk-hitl.md +53 -27
  368. package/pack/generated/codex/skills/devrites-lib/reference/standards/agents.md +198 -190
  369. package/pack/generated/codex/skills/devrites-lib/reference/standards/anti-patterns.md +5 -15
  370. package/pack/generated/codex/skills/devrites-lib/reference/standards/ci-cd.md +27 -58
  371. package/pack/generated/codex/skills/devrites-lib/reference/standards/code-review.md +16 -52
  372. package/pack/generated/codex/skills/devrites-lib/reference/standards/coding-style.md +2 -10
  373. package/pack/generated/codex/skills/devrites-lib/reference/standards/context-hygiene.md +18 -61
  374. package/pack/generated/codex/skills/devrites-lib/reference/standards/core.md +23 -18
  375. package/pack/generated/codex/skills/devrites-lib/reference/standards/deprecation.md +17 -57
  376. package/pack/generated/codex/skills/devrites-lib/reference/standards/development-workflow.md +4 -33
  377. package/pack/generated/codex/skills/devrites-lib/reference/standards/git-workflow.md +4 -20
  378. package/pack/generated/codex/skills/devrites-lib/reference/standards/hooks.md +3 -14
  379. package/pack/generated/codex/skills/devrites-lib/reference/standards/patterns.md +9 -25
  380. package/pack/generated/codex/skills/devrites-lib/reference/standards/performance.md +0 -9
  381. package/pack/generated/codex/skills/devrites-lib/reference/standards/principles.md +1 -3
  382. package/pack/generated/codex/skills/devrites-lib/reference/standards/security.md +17 -7
  383. package/pack/generated/codex/skills/devrites-lib/reference/standards/testing.md +1 -27
  384. package/pack/generated/codex/skills/devrites-lib/reference/standards/tooling.md +46 -50
  385. package/pack/generated/codex/skills/devrites-lib/reference/workspace-artifact-schema.md +23 -10
  386. package/pack/generated/codex/skills/devrites-prose-craft/SKILL.md +7 -3
  387. package/pack/generated/codex/skills/devrites-refresh-indexes/SKILL.md +7 -3
  388. package/pack/generated/codex/skills/devrites-source-driven/SKILL.md +29 -24
  389. package/pack/generated/codex/skills/devrites-ux-shape/SKILL.md +7 -3
  390. package/pack/generated/codex/skills/rite/SKILL.md +19 -13
  391. package/pack/generated/codex/skills/rite/reference/menu.md +8 -6
  392. package/pack/generated/codex/skills/rite-adopt/SKILL.md +40 -40
  393. package/pack/generated/codex/skills/rite-autocomplete/SKILL.md +40 -31
  394. package/pack/generated/codex/skills/rite-autocomplete/reference/loop.md +21 -21
  395. package/pack/generated/codex/skills/rite-autocomplete/reference/stop-conditions.md +15 -6
  396. package/pack/generated/codex/skills/rite-build/SKILL.md +42 -33
  397. package/pack/generated/codex/skills/rite-build/reference/afk-discipline.md +38 -38
  398. package/pack/generated/codex/skills/rite-build/reference/evidence-standard.md +10 -0
  399. package/pack/generated/codex/skills/rite-build/reference/forge.md +186 -156
  400. package/pack/generated/codex/skills/rite-build/reference/one-slice-cycle.md +4 -3
  401. package/pack/generated/codex/skills/rite-build/reference/phase-contract.md +96 -175
  402. package/pack/generated/codex/skills/rite-build/reference/wright-dispatch.md +129 -134
  403. package/pack/generated/codex/skills/rite-clarify/SKILL.md +105 -0
  404. package/pack/generated/codex/skills/rite-clarify/reference/decision-coverage.md +59 -0
  405. package/pack/generated/codex/skills/rite-converge/SKILL.md +42 -28
  406. package/pack/generated/codex/skills/rite-customize/SKILL.md +7 -3
  407. package/pack/generated/codex/skills/rite-define/SKILL.md +64 -35
  408. package/pack/generated/codex/skills/rite-define/reference/gates.md +16 -15
  409. package/pack/generated/codex/skills/rite-define/reference/plan-template.md +16 -8
  410. package/pack/generated/codex/skills/rite-doctor/SKILL.md +7 -3
  411. package/pack/generated/codex/skills/rite-dogfood/SKILL.md +7 -3
  412. package/pack/generated/codex/skills/rite-explain/SKILL.md +7 -3
  413. package/pack/generated/codex/skills/rite-frame/SKILL.md +7 -3
  414. package/pack/generated/codex/skills/rite-frame/reference/failure-modes.md +22 -24
  415. package/pack/generated/codex/skills/rite-handoff/SKILL.md +7 -3
  416. package/pack/generated/codex/skills/rite-learn/SKILL.md +7 -3
  417. package/pack/generated/codex/skills/rite-plan/SKILL.md +51 -19
  418. package/pack/generated/codex/skills/rite-plan/reference/task-breakdown.md +5 -1
  419. package/pack/generated/codex/skills/rite-polish/SKILL.md +34 -26
  420. package/pack/generated/codex/skills/rite-pov/SKILL.md +7 -3
  421. package/pack/generated/codex/skills/rite-pr-feedback/SKILL.md +7 -3
  422. package/pack/generated/codex/skills/rite-pressure-test/SKILL.md +7 -3
  423. package/pack/generated/codex/skills/rite-prototype/SKILL.md +32 -29
  424. package/pack/generated/codex/skills/rite-prove/SKILL.md +34 -20
  425. package/pack/generated/codex/skills/rite-quick/SKILL.md +7 -3
  426. package/pack/generated/codex/skills/rite-resolve/SKILL.md +19 -14
  427. package/pack/generated/codex/skills/rite-resolve/reference/answer-protocol.md +3 -0
  428. package/pack/generated/codex/skills/rite-review/SKILL.md +44 -31
  429. package/pack/generated/codex/skills/rite-seal/SKILL.md +7 -3
  430. package/pack/generated/codex/skills/rite-seal/reference/phase-contract.md +27 -92
  431. package/pack/generated/codex/skills/rite-seal/reference/risk-and-rollback.md +13 -0
  432. package/pack/generated/codex/skills/rite-ship/SKILL.md +7 -3
  433. package/pack/generated/codex/skills/rite-ship/reference/design-memory.md +31 -36
  434. package/pack/generated/codex/skills/rite-spec/SKILL.md +91 -138
  435. package/pack/generated/codex/skills/rite-spec/reference/investigation.md +37 -33
  436. package/pack/generated/codex/skills/rite-spec/reference/question-protocol.md +6 -2
  437. package/pack/generated/codex/skills/rite-spec/reference/spec-checklists.md +25 -24
  438. package/pack/generated/codex/skills/rite-spec/reference/spec-template.md +9 -2
  439. package/pack/generated/codex/skills/rite-spec/reference/state-workspace.md +13 -3
  440. package/pack/generated/codex/skills/rite-status/SKILL.md +7 -3
  441. package/pack/generated/codex/skills/rite-temper/SKILL.md +69 -50
  442. package/pack/generated/codex/skills/rite-temper/reference/review-dimensions.md +24 -22
  443. package/pack/generated/codex/skills/rite-vet/SKILL.md +117 -116
  444. package/pack/generated/codex/skills/rite-vet/reference/artifacts.md +42 -9
  445. package/pack/generated/codex/skills/rite-vet/reference/review-axes.md +40 -38
  446. package/pack/generated/codex/skills/rite-zoom-out/SKILL.md +7 -3
  447. package/package.json +1 -1
  448. package/scripts/build-release-tarball.sh +32 -15
  449. package/scripts/check-authority-drift.py +125 -0
  450. package/scripts/check-instruction-size-baseline.mjs +19 -11
  451. package/scripts/check-invocation-integrity.py +2 -0
  452. package/scripts/codex-generate.sh +69 -33
  453. package/scripts/grade-feature.sh +121 -40
  454. package/scripts/live-hosts/agent-result.schema.json +230 -0
  455. package/scripts/live-hosts/claude.sh +87 -0
  456. package/scripts/live-hosts/codex.sh +81 -0
  457. package/scripts/live-hosts/common.sh +113 -0
  458. package/scripts/live-hosts/fake-host.py +264 -0
  459. package/scripts/live-hosts/host-transport.py +287 -0
  460. package/scripts/release-check.sh +5 -1
  461. package/scripts/run-agent-contract-evals.py +1380 -0
  462. package/scripts/run-behavioral-evals.sh +24 -30
  463. package/scripts/run-evals.sh +1 -5
  464. package/scripts/run-live-behavioral-evals.py +1274 -144
  465. package/scripts/run-outcome-evals.sh +414 -88
  466. package/scripts/run-tests.mjs +30 -2
  467. package/scripts/skills-inventory.mjs +1 -1
  468. package/scripts/validate-workflow-security.py +39 -20
  469. package/scripts/validate-workspace-schema.py +362 -10
  470. package/scripts/validate.sh +21 -15
  471. package/engine/testdata/golden/TestParityWrightScope/devrites-edit-allowed.golden +0 -1
  472. /package/engine/testdata/golden/{TestParityReconcile/check-no-claimed.golden → TestParityBuildReadiness/arg=clarifyopen.golden} +0 -0
@@ -1,36 +1,125 @@
1
1
  package main_test
2
2
 
3
- // TestParityBuildReadiness checks the build-readiness gate's stdout + exit code
3
+ // TestParityBuildReadiness checks the build-readiness gate's stdout and exit code
4
4
  // against the golden snapshot for each state.md fixture.
5
5
 
6
- import "testing"
6
+ import (
7
+ "fmt"
8
+ "path/filepath"
9
+ "testing"
10
+
11
+ "github.com/devrites/devrites/internal/lib"
12
+ )
7
13
 
8
14
  func TestParityBuildReadiness(t *testing.T) {
9
15
  work := t.TempDir()
10
16
 
11
- // Status halts (stderr-only messages; parity is stdout + exit code).
17
+ // Status halts write only to stderr; parity covers stdout and the exit code.
12
18
  writeFeatureFile(t, work, "await", "state.md", "- Status: awaiting_human\n") // exit 3
13
19
  writeFeatureFile(t, work, "blocked", "state.md", "- Status: blocked\n") // exit 4
14
20
 
15
- // Ready: plan approved + status.
16
- writeFeatureFile(t, work, "approved", "state.md", "- Plan approved: 2024-01-01\n- Status: running\n") // exit 0
21
+ writeReadyArtifacts := func(slug string) {
22
+ t.Helper()
23
+ writeCoverageArtifacts(t, work, slug)
24
+ for name, body := range map[string]string{
25
+ "architecture.md": "# Architecture\n\nExisting layer.\n",
26
+ "plan.md": "# Plan\n\nOne slice.\n",
27
+ "tasks.md": "# Tasks\n\n## SLICE-001\nBuild.\n",
28
+ "traceability.md": "# Traceability\n\nAC-001 -> SLICE-001.\n",
29
+ "test-plan.md": `# Test plan
30
+
31
+ ## Build-entry preflight
32
+ | Gate | Command | Cwd | Expected | Prerequisites | Provenance to recapture |
33
+ | --- | --- | --- | --- | --- | --- |
34
+ | unit | go test ./... | engine | exit 0 | none | go version |
35
+
36
+ ## Per-gap test requirements
37
+ | ID | Path / flow | Test file | Asserts | Kind | Slice | Priority |
38
+ | --- | --- | --- | --- | --- | --- | --- |
39
+ | T1 | flow | flow_test.go | request → success | unit | SLICE-001 | P1 |
40
+
41
+ ## Acceptance → test map
42
+ - AC-001 → T1
43
+ `,
44
+ } {
45
+ writeFeatureFile(t, work, slug, name, body)
46
+ }
47
+ root := filepath.Join(work, ".devrites")
48
+ digest, err := lib.ReadinessInputDigest(root, slug, "engineering")
49
+ if err != nil {
50
+ t.Fatal(err)
51
+ }
52
+ writeFeatureFile(t, work, slug, "eng-review.md", fmt.Sprintf(`# Eng review
53
+
54
+ Implementation readiness: READY
55
+ Readiness inputs SHA-256: %s
56
+
57
+ ## 2a. Build-entry preflight
58
+ | Gate | Command + cwd | Tool/version | Prerequisite owner | Full provenance inputs | Fixture/smoke | Verdict |
59
+ | --- | --- | --- | --- | --- | --- | --- |
60
+ | unit | go test ./... | go | none | go.mod | focused | pass |
61
+
62
+ ## 2b. Implementation readiness
63
+ | Surface | Requirement/decision | Boundary/wiring | Slice | Proof | Verdict |
64
+ | --- | --- | --- | --- | --- | --- |
65
+ | flow | AC-001 | existing | SLICE-001 | T1 | ready |
66
+
67
+ ## 4. Failure modes
68
+ | New codepath | Realistic failure | Test? | Handling? | Silent? | Verdict |
69
+ | --- | --- | --- | --- | --- | --- |
70
+ | flow | invalid | yes | yes | no | ok |
71
+
72
+ ## 7. Completion summary
73
+ - Ready.
74
+ `, digest))
75
+ }
76
+
77
+ // A ready feature has an approved plan, running status, and current
78
+ // clarification and vet artifacts.
79
+ for _, slug := range []string{"approved", "trailpipe", "trailhash", "emptystatus"} {
80
+ writeReadyArtifacts(slug)
81
+ }
82
+ writeFeatureFile(t, work, "approved", "state.md", "- Phase: vet\n- Plan approved: 2024-01-01\n- Status: running\n") // exit 0
17
83
 
18
84
  // Plan not approved: missing line, or the literal "none".
85
+ writeCoverageArtifacts(t, work, "noapprove")
86
+ writeCoverageArtifacts(t, work, "approvenone")
19
87
  writeFeatureFile(t, work, "noapprove", "state.md", "- Status: running\n") // exit 2
20
88
  writeFeatureFile(t, work, "approvenone", "state.md", "- Plan approved: none\n- Status: running\n") // exit 2
21
89
 
22
90
  // field() strip: a trailing " | none" / " # note" annotation is trimmed off
23
91
  // Status before the case match, so both stay "running" and reach OK.
24
- writeFeatureFile(t, work, "trailpipe", "state.md", "- Plan approved: 2024-01-01\n- Status: running | none\n") // exit 0
25
- writeFeatureFile(t, work, "trailhash", "state.md", "- Plan approved: 2024-01-01\n- Status: running # note\n") // exit 0
92
+ writeFeatureFile(t, work, "trailpipe", "state.md", "- Phase: vet\n- Plan approved: 2024-01-01\n- Status: running | none\n") // exit 0
93
+ writeFeatureFile(t, work, "trailhash", "state.md", "- Phase: vet\n- Plan approved: 2024-01-01\n- Status: running # note\n") // exit 0
26
94
 
27
- // Empty Status value + plan approved status renders as "running".
28
- writeFeatureFile(t, work, "emptystatus", "state.md", "- Plan approved: 2024-01-01\n- Status: \n") // exit 0
95
+ // An empty Status with an approved plan renders as "running".
96
+ writeFeatureFile(t, work, "emptystatus", "state.md", "- Phase: vet\n- Plan approved: 2024-01-01\n- Status: \n") // exit 0
97
+
98
+ // A plan cannot build without an explicit closed clarification scan and a
99
+ // successful engineering-readiness verdict. These are objective routes, not
100
+ // human questions.
101
+ writeFeatureFile(t, work, "noclarify", "state.md", "- Phase: vet\n- Plan approved: 2024-01-01\n- Status: running\n") // exit 6
102
+
103
+ writeFeatureFile(t, work, "clarifyopen", "state.md", "- Phase: vet\n- Plan approved: 2024-01-01\n- Status: running\n") // exit 6
104
+ writeFeatureFile(t, work, "clarifyopen", "brief.md", "# Brief\n\nOutcome.\n")
105
+ writeFeatureFile(t, work, "clarifyopen", "spec.md", "# Spec\n\nAC-001.\n")
106
+ writeFeatureFile(t, work, "clarifyopen", "decision-coverage.md", "# Decision coverage\n\n- Decision coverage: NEEDS CLARIFICATION\n")
107
+
108
+ writeFeatureFile(t, work, "novet", "state.md", "- Phase: plan\n- Plan approved: 2024-01-01\n- Status: running\n") // exit 7
109
+ writeCoverageArtifacts(t, work, "novet")
110
+
111
+ writeFeatureFile(t, work, "vetnotready", "state.md", "- Phase: vet\n- Plan approved: 2024-01-01\n- Status: running\n") // exit 7
112
+ writeCoverageArtifacts(t, work, "vetnotready")
113
+ writeFeatureFile(t, work, "vetnotready", "eng-review.md", "# Engineering review\n\n- Implementation readiness: NEEDS REPLAN\n")
114
+
115
+ writeReadyArtifacts("stalevet")
116
+ writeFeatureFile(t, work, "stalevet", "state.md", "- Phase: plan\n- Plan approved: 2024-01-01\n- Status: running\n") // exit 7
29
117
 
30
118
  // "ghost" is intentionally never created → no workspace/state.md (exit 5).
31
119
  for _, arg := range []string{
32
120
  "await", "blocked", "approved", "noapprove", "approvenone",
33
- "trailpipe", "trailhash", "emptystatus", "ghost",
121
+ "trailpipe", "trailhash", "emptystatus", "noclarify", "clarifyopen",
122
+ "novet", "vetnotready", "stalevet", "ghost",
34
123
  } {
35
124
  c := parityCase{
36
125
  workdir: work,
@@ -40,3 +129,45 @@ func TestParityBuildReadiness(t *testing.T) {
40
129
  t.Run("arg="+arg, func(t *testing.T) { c.assertEqual(t) })
41
130
  }
42
131
  }
132
+
133
+ func writeCoverageArtifacts(t *testing.T, work, slug string) {
134
+ t.Helper()
135
+ writeFeatureFile(t, work, slug, "brief.md", "# Brief\n\nOutcome.\n")
136
+ writeFeatureFile(t, work, slug, "spec.md", "# Spec\n\n## Acceptance criteria\n- AC-001 succeeds.\n")
137
+ writeFeatureFile(t, work, slug, "decisions.md", "# Decisions\n\nNo open product decisions.\n")
138
+ writeFeatureFile(t, work, slug, "assumptions.md", "# Assumptions\n\nNo material assumptions.\n")
139
+ writeFeatureFile(t, work, slug, "questions.md", "# Questions\n\nNone.\n")
140
+ root := filepath.Join(work, ".devrites")
141
+ digest, err := lib.ReadinessInputDigest(root, slug, "coverage")
142
+ if err != nil {
143
+ t.Fatal(err)
144
+ }
145
+ writeFeatureFile(t, work, slug, "decision-coverage.md", fmt.Sprintf(`# Decision coverage
146
+
147
+ Decision coverage: CLEAR
148
+ Coverage inputs SHA-256: %s
149
+
150
+ ## Topology
151
+ | Surface | Kind | Related IDs | Evidence |
152
+ | --- | --- | --- | --- |
153
+ | flow | behavior | AC-001 | spec.md |
154
+
155
+ ## Coverage matrix
156
+ | Surface | Dimension | Status | Canonical reference | Owner / validation gate | Consequence if wrong |
157
+ | --- | --- | --- | --- | --- | --- |
158
+ | flow | behavior | closed | AC-001 | rite-prove | failure |
159
+
160
+ ## Assumption audit
161
+ | Assumption | Evidence | Confidence | Owner | Validation | Consequence if wrong |
162
+ | --- | --- | --- | --- | --- | --- |
163
+ | none | n/a | high | n/a | n/a | n/a |
164
+
165
+ ## Residual uncertainty
166
+ | Item | Why nonblocking | Owner | Validation gate |
167
+ | --- | --- | --- | --- |
168
+ | none | n/a | n/a | n/a |
169
+
170
+ ## Readiness verdict
171
+ No unresolved decision remains.
172
+ `, digest))
173
+ }
@@ -1,10 +1,9 @@
1
1
  package main_test
2
2
 
3
3
  // TestParityLearnings checks the learnings command against the golden snapshots.
4
- // learnings state is ROOT-LEVEL, read from DEVRITES_ROOT=work/.devrites when the
5
- // case runs in workdir=work with libRootEnv(work). The mine/nudge pipelines are
6
- // deterministic from fixtures. Fixture counts are DISTINCT (3 vs 2) so ordering
7
- // never depends on a platform-specific tie-break.
4
+ // Learning state lives at the root selected by DEVRITES_ROOT. The mine and nudge
5
+ // fixtures use counts of 3 and 2 so sorting never depends on a platform-specific
6
+ // tie.
8
7
 
9
8
  import (
10
9
  "path/filepath"
@@ -14,10 +13,11 @@ import (
14
13
  func TestParityLearnings(t *testing.T) {
15
14
  learn := func(a ...string) []string { return append([]string{"learnings"}, a...) }
16
15
 
17
- // --- add: fresh workspace. bash creates the ledger + a dated entry; Go then
18
- // appends a second entry. Only stdout ("learnings: recorded.") + exit 0 are the
19
- // contract: the dated file line is a nondeterministic side effect, not stdout.
16
+ // Add to a fresh workspace. Bash creates the ledger and a dated entry, then Go
17
+ // appends another. Only stdout ("learnings: recorded.") and exit 0 belong to
18
+ // the contract because the dated file entry is nondeterministic.
20
19
  addw := t.TempDir()
20
+ mkdirAllT(t, addw, ".devrites")
21
21
  t.Run("add", func(t *testing.T) {
22
22
  (parityCase{
23
23
  workdir: addw, env: libRootEnv(addw),
@@ -25,7 +25,7 @@ func TestParityLearnings(t *testing.T) {
25
25
  }).assertEqual(t)
26
26
  })
27
27
 
28
- // --- list: a pre-written ledger; both sides cat the same file verbatim.
28
+ // List a prepared ledger. Both implementations print the file unchanged.
29
29
  listw := t.TempDir()
30
30
  writeFile(t, listw, filepath.Join(".devrites", "learnings.md"),
31
31
  "# DevRites learnings ledger\n\n"+
@@ -38,10 +38,9 @@ func TestParityLearnings(t *testing.T) {
38
38
  }).assertEqual(t)
39
39
  })
40
40
 
41
- // --- mine + nudge: two archived features. The shared "recurring finding" bullet
42
- // normalizes identically across features despite differing numbers/paths (the sed
43
- // id/path/number stripping), giving count 3; the "second dead end" bullet gives
44
- // count 2. Distinct counts ⇒ deterministic order on any `sort`.
41
+ // Mine and nudge use two archived features. Normalization strips IDs, paths,
42
+ // and numbers, so "recurring finding" has count 3 and "second dead end" has
43
+ // count 2. The distinct counts keep sort order stable.
45
44
  arch := t.TempDir()
46
45
  writeFile(t, arch, filepath.Join(".devrites", "archive", "feat-a", "decisions.md"),
47
46
  "# decisions for feat-a\n"+
@@ -55,7 +54,7 @@ func TestParityLearnings(t *testing.T) {
55
54
  "- second dead end: retry backoff exceeded 9 attempts\n"+
56
55
  "- a one-off dismiss note about the flaky linter run\n")
57
56
 
58
- // mine: default archive (bash .devrites/archive, Go <root>/archive: same dir).
57
+ // Both implementations resolve the default archive to the same directory.
59
58
  t.Run("mine", func(t *testing.T) {
60
59
  (parityCase{
61
60
  workdir: arch, env: libRootEnv(arch),
@@ -63,8 +62,8 @@ func TestParityLearnings(t *testing.T) {
63
62
  }).assertEqual(t)
64
63
  })
65
64
 
66
- // mine: no archive. An explicit relative path both sides resolve against workdir,
67
- // so the path embedded in the message is identical for bash and Go.
65
+ // Both implementations resolve an explicit relative path against workdir, so
66
+ // the missing path in the message is identical.
68
67
  t.Run("mine-no-archive", func(t *testing.T) {
69
68
  (parityCase{
70
69
  workdir: arch, env: libRootEnv(arch),
@@ -72,7 +71,7 @@ func TestParityLearnings(t *testing.T) {
72
71
  }).assertEqual(t)
73
72
  })
74
73
 
75
- // nudge: >=2 features + a class recurring 3x + no review marker the nudge line.
74
+ // Two features, three occurrences, and no review marker produce a nudge.
76
75
  t.Run("nudge", func(t *testing.T) {
77
76
  (parityCase{
78
77
  workdir: arch, env: libRootEnv(arch),
@@ -80,7 +79,7 @@ func TestParityLearnings(t *testing.T) {
80
79
  }).assertEqual(t)
81
80
  })
82
81
 
83
- // --- unknown cmd: usage to stderr, exit 2 (stdout empty on both sides).
82
+ // An unknown command writes usage to stderr and exits 2 without stdout.
84
83
  t.Run("unknown", func(t *testing.T) {
85
84
  (parityCase{
86
85
  workdir: arch, env: libRootEnv(arch),
@@ -2,14 +2,15 @@ package main_test
2
2
 
3
3
  import (
4
4
  "fmt"
5
+ "strings"
5
6
  "testing"
6
7
  )
7
8
 
8
9
  // TestParityReconcile checks reconcile against the golden snapshots: snapshot
9
- // captures the worktree as a tree object, check diffs it and flags source changes
10
- // outside the claimed manifest. Runs git in a real repo, so stdout + exit are
11
- // captured from the live command. The .devrites/ bookkeeping is skipped by the
12
- // gate, so it never affects the verdict.
10
+ // captures the worktree as a tree object, check diffs it and flags changes
11
+ // outside the orchestrator-authored allowlist, and close ends the retained
12
+ // post-slice baseline. It runs Git in a real repository, so stdout and exit are
13
+ // captured from the live command.
13
14
  func TestParityReconcile(t *testing.T) {
14
15
  requireGit(t)
15
16
 
@@ -25,7 +26,12 @@ func TestParityReconcile(t *testing.T) {
25
26
  }
26
27
  // snapshot is also a setup step for the check-* cases, so it snapshots under a
27
28
  // distinct key to avoid colliding with check's golden in the same subtest.
28
- snapshot := func(t *testing.T, work string) {
29
+ snapshot := func(t *testing.T, work string, allowed ...string) {
30
+ body := ""
31
+ if len(allowed) > 0 {
32
+ body = strings.Join(allowed, "\n") + "\n"
33
+ }
34
+ writeFeatureFile(t, work, "feat", ".wright-allowlist", body)
29
35
  out, code := runArgv(t, work, libRootEnv(work), "", binPath, "reconcile", "snapshot", "feat")
30
36
  assertGoldenKey(t, t.Name()+"/snapshot", fmt.Sprintf("exit %d\n%s", code, out))
31
37
  }
@@ -38,38 +44,35 @@ func TestParityReconcile(t *testing.T) {
38
44
 
39
45
  t.Run("check-clean", func(t *testing.T) {
40
46
  work := newRepo(t)
41
- snapshot(t, work)
47
+ snapshot(t, work, "src/a.js")
42
48
  writeFile(t, work, "src/a.js", "console.log(999)\n") // the wright's change
43
- writeFeatureFile(t, work, "feat", ".reconcile-claimed", "src/a.js\n")
44
49
  check(t, work)
45
50
  })
46
51
 
47
52
  t.Run("check-violation", func(t *testing.T) {
48
53
  work := newRepo(t)
49
- snapshot(t, work)
54
+ snapshot(t, work, "src/a.js")
50
55
  writeFile(t, work, "src/a.js", "console.log(999)\n")
51
- writeFile(t, work, "src/b.js", "console.log(888)\n") // NOT claimed -> A1 breach
52
- writeFeatureFile(t, work, "feat", ".reconcile-claimed", "src/a.js\n")
56
+ writeFile(t, work, "src/b.js", "console.log(888)\n") // Outside the allowlist; an A1 breach.
53
57
  check(t, work)
54
58
  })
55
59
 
56
60
  t.Run("check-no-base", func(t *testing.T) {
57
61
  work := newRepo(t)
58
- writeFeatureFile(t, work, "feat", ".reconcile-claimed", "src/a.js\n")
59
- check(t, work) // no snapshot -> exit 6
62
+ check(t, work) // No snapshot, so exit 6.
60
63
  })
61
64
 
62
- t.Run("check-no-claimed", func(t *testing.T) {
65
+ t.Run("snapshot-no-allowlist", func(t *testing.T) {
63
66
  work := newRepo(t)
64
- snapshot(t, work)
65
- check(t, work) // base present, no claimed -> exit 6
67
+ out, code := runArgv(t, work, libRootEnv(work), "", binPath, "reconcile", "snapshot", "feat")
68
+ assertGolden(t, out, code)
66
69
  })
67
70
 
68
71
  t.Run("inline-fallback", func(t *testing.T) {
69
72
  work := newRepo(t)
70
73
  snapshot(t, work)
71
- writeFeatureFile(t, work, "feat", ".reconcile-inline", "")
72
- check(t, work) // gate skipped -> exit 0
74
+ out, code := runArgv(t, work, libRootEnv(work), "", binPath, "reconcile", "close", "feat")
75
+ assertGolden(t, out, code)
73
76
  })
74
77
 
75
78
  t.Run("not-git", func(t *testing.T) {
@@ -7,8 +7,8 @@ import (
7
7
  "testing"
8
8
  )
9
9
 
10
- // Golden snapshot for resolve: it MUTATES questions.md + state.md. Each case
11
- // snapshots the command's stdout + exit code and, for the mutating cases, the
10
+ // Golden snapshots for resolve include its changes to questions.md and state.md.
11
+ // Each case records stdout and the exit code. Mutating cases also record the
12
12
  // resulting file bytes. The two nondeterministic timestamp fields (answered_at
13
13
  // and the Log entry) are masked out before the file content is snapshotted so the
14
14
  // golden is deterministic across runs.
@@ -45,8 +45,8 @@ const resolveState = `- Status: awaiting_human
45
45
  `
46
46
 
47
47
  func TestParityResolve(t *testing.T) {
48
- // setup writes the fixtures into a Go tree (.devrites/features/feat) and returns
49
- // the workspace root.
48
+ // setup writes fixtures under .devrites/features/feat and returns the
49
+ // workspace root.
50
50
  setup := func(t *testing.T, questions, state string) (gwork string) {
51
51
  t.Helper()
52
52
  gwork = t.TempDir()
@@ -55,7 +55,7 @@ func TestParityResolve(t *testing.T) {
55
55
  writeFile(t, gwork, filepath.Join(".devrites", "ACTIVE"), "feat\n")
56
56
  return gwork
57
57
  }
58
- // run executes resolve in gwork and snapshots its stdout + exit code under the
58
+ // run executes resolve in gwork and snapshots stdout and the exit code under the
59
59
  // current subtest's golden.
60
60
  run := func(t *testing.T, gwork string, args ...string) {
61
61
  t.Helper()
@@ -124,16 +124,17 @@ answer: prior
124
124
  })
125
125
 
126
126
  t.Run("no-workspace", func(t *testing.T) {
127
- // Bare tree: no ACTIVE, no questions.md -> exit 2.
127
+ // A bare tree with no explicit root, ACTIVE, or questions.md exits 2.
128
+ // Pointing DEVRITES_ROOT at the nonexistent .devrites child would instead
129
+ // be an explicit unsafe-root refusal, which is a different contract.
128
130
  gwork := t.TempDir()
129
- run(t, gwork, "q-1", "x")
131
+ out, code := runArgv(t, gwork, libEnv, "", binPath, "resolve", "q-1", "x")
132
+ assertGolden(t, out, code)
130
133
  })
131
134
 
132
135
  t.Run("next-qid", func(t *testing.T) {
133
- // Read-only: computes the next qid for an explicit questions.md path.
134
- // DEVRITES_NOW pins the clock so the golden is stable across day
135
- // boundaries: without it the qid tracks the real date and the snapshot
136
- // fails every day but the one it was recorded on (ADR-0006, clock seam).
136
+ // DEVRITES_NOW fixes the date used by next-qid so the snapshot stays stable.
137
+ // See ADR-0006.
137
138
  dir := t.TempDir()
138
139
  writeFile(t, dir, "questions.md", "## q-2024-01-01-001\nstatus: open\n")
139
140
  qpath := filepath.Join(dir, "questions.md")
@@ -1,12 +1,12 @@
1
1
  package main_test
2
2
 
3
3
  // Golden CLI harness: run `devrites-engine <args>` against a fixture and compare its
4
- // stdout + exit code to a recorded snapshot under testdata/golden/. The snapshots
4
+ // stdout and exit code to a recorded snapshot under testdata/golden. The snapshots
5
5
  // were captured from the commands once they were proven correct, so a later change
6
6
  // that alters observable behaviour fails here. Regenerate them deliberately with
7
7
  // UPDATE_GOLDEN=1 (e.g. `UPDATE_GOLDEN=1 go test ./...`).
8
8
  //
9
- // stderr is intentionally NOT captured: it is diagnostic, not contract. Only
9
+ // stderr is not captured because it is diagnostic rather than contractual. Only
10
10
  // stdout (the output the hook/command consumer reads) and the exit code are.
11
11
 
12
12
  import (
@@ -28,7 +28,7 @@ type parityCase struct {
28
28
  goArgs []string // args to the built devrites-engine binary (binPath is prepended)
29
29
  }
30
30
 
31
- // assertEqual runs the command and compares its stdout + exit code to the golden
31
+ // assertEqual runs the command and compares its stdout and exit code to the golden
32
32
  // snapshot for the current subtest.
33
33
  func (c parityCase) assertEqual(t *testing.T) {
34
34
  t.Helper()
@@ -104,8 +104,8 @@ func TestParityReviewerReadonly(t *testing.T) {
104
104
  {"enforce-deny-mutating", []string{"DEVRITES_REVIEWER_RO=enforce"}, `{"tool_name":"Bash","tool_input":{"command":"rm -rf foo"}}`},
105
105
  {"enforce-deny-git-commit", []string{"DEVRITES_REVIEWER_RO=enforce"}, `{"tool_name":"Bash","tool_input":{"command":"git commit -m x"}}`},
106
106
  {"observe-mutating-silent", nil, `{"tool_name":"Bash","tool_input":{"command":"rm -rf foo"}}`},
107
- // The agent-required gate reads agent_type ONLY (like the bash node parse),
108
- // so a subagent_type-only payload has no identity and is allowed.
107
+ // The agent-required gate reads only agent_type, matching the Bash hook's
108
+ // Node parser, so a subagent_type-only payload has no identity and is allowed.
109
109
  {"agent-required-subagent-type-only-allows",
110
110
  []string{"DEVRITES_REVIEWER_RO=enforce", "DEVRITES_REVIEWER_AGENT_REQUIRED=1"},
111
111
  `{"tool_name":"Bash","tool_input":{"command":"rm -rf foo"},"subagent_type":"devrites-code-reviewer"}`},
@@ -268,7 +268,7 @@ func TestParityRedwatch(t *testing.T) {
268
268
  }
269
269
 
270
270
  // TestParityA1Guard checks `hook a1-guard` against golden snapshots for each
271
- // payload: it blocks a MAIN-thread source edit only when the build window is open
271
+ // payload. It blocks a main-thread source edit only when the build window is open
272
272
  // and enforce is on, and allows subagent edits, .devrites bookkeeping edits, an
273
273
  // inline-fallback window, and a closed window.
274
274
  func TestParityA1Guard(t *testing.T) {
@@ -308,23 +308,27 @@ func TestParityA1Guard(t *testing.T) {
308
308
  }
309
309
 
310
310
  // TestParityWrightScope checks `hook wright-scope` against golden snapshots for
311
- // each payload: a path in touched-files.md is allowed, one outside it is denied
312
- // under enforce, .devrites edits and non-edit tools are allowed, and the
313
- // agent-required gate skips a non-wright caller.
311
+ // each payload: an exact orchestrator-allowlisted path is allowed, one outside
312
+ // it and every .devrites path are denied for an active wright, read-only tools
313
+ // pass, and the agent-required gate skips a non-DevRites caller.
314
314
  func TestParityWrightScope(t *testing.T) {
315
315
  work := t.TempDir()
316
- writeFeatureFile(t, work, "ws", "touched-files.md", "# touched\n- `src/app.js`\n")
316
+ writeFeatureFile(t, work, "ws", ".wright-allowlist", "src/app.js\n")
317
317
 
318
318
  enforce := []string{"DEVRITES_WRIGHT_SCOPE=enforce"}
319
+ activeWright := []string{
320
+ "DEVRITES_AGENT_RUN=1",
321
+ "DEVRITES_ACTIVE_AGENT=devrites-slice-wright",
322
+ }
319
323
  for _, tc := range []struct {
320
324
  name string
321
325
  env []string
322
326
  stdin string
323
327
  }{
324
- {"in-scope-allowed", enforce, `{"tool_name":"Edit","tool_input":{"file_path":"src/app.js"}}`},
325
- {"out-of-scope-enforce-denies", enforce, `{"tool_name":"Edit","tool_input":{"file_path":"src/other.js"}}`},
326
- {"devrites-edit-allowed", enforce, `{"tool_name":"Edit","tool_input":{"file_path":".devrites/x/y.md"}}`},
327
- {"non-edit-tool", enforce, `{"tool_name":"Bash","tool_input":{"command":"ls"}}`},
328
+ {"in-scope-allowed", activeWright, `{"tool_name":"Edit","tool_input":{"file_path":"src/app.js"}}`},
329
+ {"out-of-scope-enforce-denies", activeWright, `{"tool_name":"Edit","tool_input":{"file_path":"src/other.js"}}`},
330
+ {"devrites-edit-denied", activeWright, `{"tool_name":"Edit","tool_input":{"file_path":".devrites/x/y.md"}}`},
331
+ {"non-edit-tool", activeWright, `{"tool_name":"Bash","tool_input":{"command":"ls"}}`},
328
332
  {"out-of-scope-observe-silent", nil, `{"tool_name":"Edit","tool_input":{"file_path":"src/other.js"}}`},
329
333
  {"agent-required-non-wright", append([]string{"DEVRITES_WRIGHT_AGENT_REQUIRED=1"}, enforce...),
330
334
  `{"tool_name":"Edit","tool_input":{"file_path":"src/other.js"},"agent_type":"Explore"}`},
@@ -343,7 +347,7 @@ func TestParityWrightScope(t *testing.T) {
343
347
  }
344
348
 
345
349
  // setActiveAFK points .devrites/ACTIVE at slug (or removes it) and toggles the
346
- // .devrites/AFK sentinel: the two files bash (via CWD) and the migrated Go (via
350
+ // .devrites/AFK sentinel: the two files bash (via CWD) and Go (via
347
351
  // <root>) both read from the same shared location.
348
352
  func setActiveAFK(t *testing.T, work, slug string, afk bool) {
349
353
  t.Helper()
@@ -371,8 +375,8 @@ func TestParityOrientSilentPath(t *testing.T) {
371
375
 
372
376
  c := parityCase{
373
377
  workdir: dir,
374
- // Ensure DEVRITES_ROOT does not leak in and make the Go side resolve a
375
- // real workspace; it must see "not a DevRites project".
378
+ // Clear DEVRITES_ROOT so the Go side cannot resolve a real workspace. It
379
+ // must see "not a DevRites project".
376
380
  env: []string{"DEVRITES_ROOT="},
377
381
  goArgs: []string{"hook", "orient", "--harness=claude"},
378
382
  }