devrites 3.0.6 → 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 +18 -0
  2. package/README.md +67 -45
  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 +575 -58
  54. package/engine/internal/install/install_test.go +490 -9
  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
@@ -6,6 +6,7 @@ import (
6
6
  "strings"
7
7
  "testing"
8
8
 
9
+ "github.com/devrites/devrites/internal/reason"
9
10
  "github.com/devrites/devrites/internal/testutil"
10
11
  )
11
12
 
@@ -24,13 +25,16 @@ func TestCheckAndRenderReadiness(t *testing.T) {
24
25
  if !res.Blocked {
25
26
  t.Fatalf("Check blocked=false, want true")
26
27
  }
28
+ if res.ReasonID != reason.GateReadinessMissing {
29
+ t.Fatalf("Check reason=%q, want %q", res.ReasonID, reason.GateReadinessMissing)
30
+ }
27
31
  got := res.Render()
28
32
  for _, want := range []string{
29
33
  "gate: readiness",
30
34
  "feature: alpha",
31
35
  "phase: build",
32
36
  `result: blocked (missing to leave "build": decisions, tasks)`,
33
- "next: add real content to decisions.md, tasks.md, then re-run: devrites-engine readiness alpha",
37
+ "then re-run: devrites-engine readiness alpha",
34
38
  } {
35
39
  if !strings.Contains(got, want) {
36
40
  t.Fatalf("Render() missing %q in:\n%s", want, got)
@@ -38,6 +42,52 @@ func TestCheckAndRenderReadiness(t *testing.T) {
38
42
  }
39
43
  }
40
44
 
45
+ func TestCheckUsesConcreteWorkspaceRequirements(t *testing.T) {
46
+ root := t.TempDir()
47
+ files := map[string]string{
48
+ "state.md": "| phase | vet |\n",
49
+ "brief.md": "brief\n",
50
+ "spec.md": "spec\n",
51
+ "decisions.md": "decisions\n",
52
+ "assumptions.md": "assumptions\n",
53
+ "questions.md": "none\n",
54
+ "decision-coverage.md": "clear\n",
55
+ "architecture.md": "architecture\n",
56
+ "plan.md": "plan\n",
57
+ "tasks.md": "tasks\n",
58
+ "traceability.md": "traceability\n",
59
+ "eng-review.md": "ready\n",
60
+ "test-plan.md": "", // an empty required file must not satisfy the gate
61
+ }
62
+ writeWorkFeature(t, root, "concrete", files)
63
+
64
+ res, err := Check(Readiness, root, "concrete")
65
+ if err != nil {
66
+ t.Fatal(err)
67
+ }
68
+ if !res.Blocked || strings.Join(res.MissingFiles, ",") != "test-plan.md" {
69
+ t.Fatalf("blocked=%v missing=%v, want only test-plan.md", res.Blocked, res.MissingFiles)
70
+ }
71
+ }
72
+
73
+ func TestResultReasonIDsAreStableForEveryGateOutcome(t *testing.T) {
74
+ cases := []struct {
75
+ kind Kind
76
+ blocked bool
77
+ want reason.ID
78
+ }{
79
+ {Readiness, false, reason.GateReadinessPassed},
80
+ {Readiness, true, reason.GateReadinessMissing},
81
+ {Seal, false, reason.GateSealPassed},
82
+ {Seal, true, reason.GateSealMissing},
83
+ }
84
+ for _, tc := range cases {
85
+ if got := ResultReasonID(tc.kind, tc.blocked); got != tc.want {
86
+ t.Fatalf("ResultReasonID(%q, %v)=%q, want %q", tc.kind, tc.blocked, got, tc.want)
87
+ }
88
+ }
89
+ }
90
+
41
91
  func TestStateAwaitingHumanReadsCanonicalCursor(t *testing.T) {
42
92
  data := []byte("| Key | Value |\n| --- | --- |\n| status | awaiting_human |\n")
43
93
  if !stateAwaitingHuman(data) {
@@ -51,6 +101,7 @@ func TestStopGateRestPointInvariants(t *testing.T) {
51
101
  files map[string]string
52
102
  wantBlocked bool
53
103
  wantReasonSub string
104
+ wantReasonID reason.ID
54
105
  }{
55
106
  {
56
107
  name: "red blocks",
@@ -61,6 +112,7 @@ func TestStopGateRestPointInvariants(t *testing.T) {
61
112
  },
62
113
  wantBlocked: true,
63
114
  wantReasonSub: "tests/build RED",
115
+ wantReasonID: reason.HookStopRed,
64
116
  },
65
117
  {
66
118
  name: "unsurfaced human gate blocks",
@@ -71,6 +123,7 @@ func TestStopGateRestPointInvariants(t *testing.T) {
71
123
  },
72
124
  wantBlocked: true,
73
125
  wantReasonSub: "open blocking/validating human question",
126
+ wantReasonID: reason.HookStopUnsurfacedHumanGate,
74
127
  },
75
128
  {
76
129
  name: "awaiting human allows surfaced gate",
@@ -88,6 +141,7 @@ func TestStopGateRestPointInvariants(t *testing.T) {
88
141
  },
89
142
  wantBlocked: true,
90
143
  wantReasonSub: "proof.md is empty",
144
+ wantReasonID: reason.HookStopMissingProof,
91
145
  },
92
146
  {
93
147
  name: "done without proof blocks",
@@ -97,6 +151,7 @@ func TestStopGateRestPointInvariants(t *testing.T) {
97
151
  },
98
152
  wantBlocked: true,
99
153
  wantReasonSub: "proof.md is empty",
154
+ wantReasonID: reason.HookStopMissingProof,
100
155
  },
101
156
  } {
102
157
  t.Run(tc.name, func(t *testing.T) {
@@ -117,6 +172,13 @@ func TestStopGateRestPointInvariants(t *testing.T) {
117
172
  if tc.wantReasonSub != "" && !strings.Contains(got.Reason, tc.wantReasonSub) {
118
173
  t.Fatalf("StopGate reason=%q, want substring %q", got.Reason, tc.wantReasonSub)
119
174
  }
175
+ wantReasonID := tc.wantReasonID
176
+ if wantReasonID == "" {
177
+ wantReasonID = reason.HookStopClear
178
+ }
179
+ if got.ReasonID != wantReasonID {
180
+ t.Fatalf("StopGate reason_id=%q, want %q", got.ReasonID, wantReasonID)
181
+ }
120
182
  })
121
183
  }
122
184
  }
@@ -127,7 +189,7 @@ func TestStopGateUsesWorkspaceOverride(t *testing.T) {
127
189
  if err := os.MkdirAll(root, 0o755); err != nil {
128
190
  t.Fatal(err)
129
191
  }
130
- override := filepath.Join(project, "custom", "alpha")
192
+ override := filepath.Join(root, "work", "alpha")
131
193
  t.Setenv("DEVRITES_WORKSPACE", override)
132
194
  testutil.WriteFile(t, filepath.Join(override, "feature.md"), "---\nphase: build\nschemaVersion: 1\n---\n")
133
195
  testutil.WriteFile(t, filepath.Join(override, "state.md"), "- Phase: build\n")
@@ -159,3 +221,10 @@ func writeFeature(t *testing.T, root, slug string, files map[string]string) {
159
221
  testutil.WriteFile(t, filepath.Join(root, "features", slug, name), content)
160
222
  }
161
223
  }
224
+
225
+ func writeWorkFeature(t *testing.T, root, slug string, files map[string]string) {
226
+ t.Helper()
227
+ for name, content := range files {
228
+ testutil.WriteFile(t, filepath.Join(root, "work", slug, name), content)
229
+ }
230
+ }
@@ -5,31 +5,25 @@ import (
5
5
  "strings"
6
6
  )
7
7
 
8
- // The harness adapter-compliance matrix.
9
- //
10
- // DevRites drives more than one agent runtime from one engine, but the runtimes
11
- // do not expose identical enforcement surfaces. Rather than pretend parity, this
12
- // frozen matrix states, per surface, whether each supported harness enforces it
13
- // natively, through an adapter, or only by instruction the model may ignore. It
14
- // is the single source of truth; `devrites-engine harness-matrix` renders it and
15
- // CI drift-checks the rendered copy in docs/, so the honest picture cannot rot.
8
+ // The compliance matrix records how each harness supports every enforcement
9
+ // surface. `devrites-engine harness-matrix` renders this data, and CI compares
10
+ // the result with the copy in docs.
16
11
 
17
12
  // Tier is how strongly a harness backs a given surface, from strongest to
18
13
  // weakest.
19
14
  type Tier int
20
15
 
21
16
  const (
22
- // Native the harness exposes and delivers the surface directly. Whether a
23
- // delivered policy blocks is stated separately in the surface note.
17
+ // Native means the harness exposes and delivers the surface directly. The
18
+ // surface note says whether its policy blocks.
24
19
  Native Tier = iota
25
- // Adapter supported, but through a translation shim (a different verb,
26
- // a mirrored file tree) rather than the harness's first-class path.
20
+ // Adapter means a translation layer, such as a different verb or mirrored
21
+ // file tree, provides the surface.
27
22
  Adapter
28
- // Instruction no runtime enforcement surface; the behaviour rides on a
29
- // directive the model is asked to follow and may under-fire.
23
+ // Instruction means the runtime has no enforcement surface and relies on a
24
+ // directive that the model may not follow consistently.
30
25
  Instruction
31
- // Conditional natively supported, but gated on an operator precondition
32
- // that silently disables it when unmet.
26
+ // Conditional means native support depends on an operator precondition.
33
27
  Conditional
34
28
  )
35
29
 
@@ -60,13 +54,15 @@ type Surface struct {
60
54
  Note string
61
55
  }
62
56
 
63
- // complianceMatrix is grounded in the shipped wiring: pack/.claude/settings.json
64
- // for Claude, generated host artifacts + AGENTS.md merge for Codex.
65
- // Change a cell only when that wiring changes.
57
+ // complianceMatrix reflects the shipped wiring in pack/.claude/settings.json
58
+ // for Claude and the generated host artifacts plus AGENTS.md for Codex. Change
59
+ // a cell only when that wiring changes.
66
60
  var complianceMatrix = []Surface{
67
61
  {"SessionStart orientation", Native, Native, "all phases", "manual preamble/snapshot", "yes", "high", "Both wire the orient hook; identical additionalContext envelope."},
68
62
  {"PreToolUse policy (allow, a1-guard, reviewer-readonly, wright-scope)", Conditional, Conditional, "build/review safety", "observe-only findings + human review", "yes", "high", "Both deliver the event, but these policies are non-blocking by default; DEVRITES_HOOK_PROFILE=strict enables every guard, or each guard can be enabled through its documented specific variable."},
63
+ {"Destructive Git authority", Conditional, Conditional, "all shell tool calls", "human permission review; no exact one-shot proof", "yes", "high", "Both wire git-guard at PreToolUse. Standard and strict profiles enforce exact 15-minute one-shot authority; minimal profile or the explicit kill list disables the hook."},
69
64
  {"PostToolUse sentinel (redwatch)", Native, Native, "prove/build rest points", "manual red/green check", "yes", "high", "Fail-on-red sentinel wired on both."},
65
+ {"WebFetch ingestion warning trial", Conditional, Instruction, "external research", "inspect retrieved content as untrusted data", "no", "medium", "Claude WebFetch PostToolUse can emit an opt-in metadata-only warning with DEVRITES_INGEST_WARNING=warn; a flagged result remains in context and is omitted from the local source cache. Codex has no matching result event, so this trial is unavailable and silent."},
70
66
  {"Stop gate", Conditional, Conditional, "all rest points", "observe-only finding + manual host-specific rite-status", "yes", "high", "Both deliver Stop; stop-gate blocks with DEVRITES_STOP_GATE=enforce or DEVRITES_HOOK_PROFILE=strict."},
71
67
  {"SubagentStart discipline injection", Native, Native, "review/build fan-out", "agent file preamble", "yes", "high", "subagent-orient wired on both."},
72
68
  {"Skill invocation", Native, Adapter, "all public rites", "explicit file read", "yes", "high", "Claude: native /rite. Codex: $rite over the mirrored .agents/skills tree."},
@@ -75,16 +71,14 @@ var complianceMatrix = []Surface{
75
71
  {"Project activation", Native, Conditional, "Codex-only startup", "inspect hooks/config, decide trust, then rerun doctor", "yes", "medium", "Codex silently skips every .codex/ layer in an untrusted project; trust remains an operator decision after inspection."},
76
72
  }
77
73
 
78
- // Matrix markers delimit the generated block inside a docs file so drift-check
79
- // can extract and compare exactly the rendered region.
74
+ // Matrix markers identify the generated block that the drift check compares.
80
75
  const (
81
76
  MatrixBeginMarker = "<!-- BEGIN harness-matrix (generated by `devrites-engine harness-matrix`) -->"
82
77
  MatrixEndMarker = "<!-- END harness-matrix -->"
83
78
  )
84
79
 
85
- // RenderMatrix returns the marker-delimited Markdown block for the matrix. It is
86
- // deterministic no timestamps so a committed copy only changes when the
87
- // matrix data does.
80
+ // RenderMatrix returns the marker-delimited Markdown block. It has no timestamps,
81
+ // so its output changes only when the matrix data changes.
88
82
  func RenderMatrix() string {
89
83
  var b strings.Builder
90
84
  b.WriteString(MatrixBeginMarker)
@@ -1,9 +1,6 @@
1
- // Package harness holds the thin per-harness adapters at the engine's edge.
2
- //
3
- // One binary serves both Claude Code and Codex. The shared gate/orientation
4
- // logic lives in the middle (internal/orient, internal/gate); this package
5
- // translates each harness's hook stdin schema and its exit/decision convention.
6
- // The engine never calls a model: these adapters only shape stdin/stdout.
1
+ // Package harness translates Claude Code and Codex hook payloads into the shared
2
+ // engine format. It handles stdin, stdout, and decision envelopes but never calls
3
+ // a model.
7
4
  package harness
8
5
 
9
6
  import (
@@ -22,8 +19,8 @@ const (
22
19
  Codex Harness = "codex"
23
20
  )
24
21
 
25
- // Parse validates a --harness flag value. An unknown harness is an error so a
26
- // typo surfaces loudly rather than silently picking a default convention.
22
+ // Parse validates a --harness value. Unknown values return an error instead of
23
+ // choosing a default.
27
24
  func Parse(s string) (Harness, error) {
28
25
  switch Harness(s) {
29
26
  case Claude, Codex:
@@ -84,44 +81,45 @@ type stopDecision struct {
84
81
  Reason string `json:"reason"`
85
82
  }
86
83
 
87
- // StopInput is the subset of a Stop hook's stdin payload the gate reads. The
88
- // loop guard (stop_hook_active) is the one field that keeps a blocking gate from
89
- // wedging the session: once the harness reports it already re-entered the Stop
90
- // hook, the gate must let the turn end.
84
+ // StopInput contains the fields the gate reads from a Stop hook payload.
85
+ // stop_hook_active prevents a blocking gate from reentering indefinitely.
91
86
  type StopInput struct {
92
- StopHookActive bool `json:"stop_hook_active"`
87
+ StopHookActive bool `json:"stop_hook_active"`
88
+ StopHookActivePresent bool `json:"-"`
93
89
  }
94
90
 
95
91
  // ParseStopInput decodes a Stop hook's stdin. An empty or malformed payload is
96
- // not an error: it decodes to the zero value (StopHookActive false), so a
97
- // harness that sends nothing simply gets a first-pass gate check. This keeps the
98
- // hook fail-open: bad stdin never crashes it.
92
+ // not an error, but it must not be confused with an explicit first pass. Only a
93
+ // present boolean stop_hook_active is valid enough for a blocking gate.
99
94
  func (h Harness) ParseStopInput(r io.Reader) StopInput {
100
- var in StopInput
95
+ var payload struct {
96
+ StopHookActive *bool `json:"stop_hook_active"`
97
+ }
101
98
  data, err := io.ReadAll(r)
102
99
  if err != nil || len(strings.TrimSpace(string(data))) == 0 {
103
- return in
100
+ return StopInput{}
101
+ }
102
+ if json.Unmarshal(data, &payload) != nil || payload.StopHookActive == nil {
103
+ return StopInput{}
104
+ }
105
+ return StopInput{
106
+ StopHookActive: *payload.StopHookActive,
107
+ StopHookActivePresent: true,
104
108
  }
105
- _ = json.Unmarshal(data, &in) // best-effort; zero value on failure
106
- return in
107
109
  }
108
110
 
109
- // PreToolInput is the subset of a PreToolUse hook's stdin the reviewer-readonly
110
- // guard reads: which tool is about to run, its command, and: for the optional
111
- // agent-scoping gate: the calling subagent's name. Every field is best-effort:
112
- // a hook that can't identify the tool simply falls through to its silent no-op.
111
+ // PreToolInput contains the tool, command, and optional agent identity read by
112
+ // the reviewer-readonly guard. Missing fields leave the guard silent.
113
113
  type PreToolInput struct {
114
114
  ToolName string
115
115
  Command string
116
116
  AgentType string // the calling subagent's name; empty on the main thread
117
117
  }
118
118
 
119
- // ParsePreToolInput decodes a PreToolUse payload. Like ParseStopInput it never
120
- // errors: an empty or malformed payload decodes to the zero value so a guard hook
121
- // stays fail-open. AgentType reads `agent_type` ONLY: matching
122
- // devrites-reviewer-readonly.sh's node parse exactly (it does not consult the
123
- // subagent_type / agentType aliases; SubagentAgentType does, for the subagent
124
- // hook that needs them).
119
+ // ParsePreToolInput decodes a PreToolUse payload. Empty or malformed input
120
+ // returns the zero value. AgentType reads only `agent_type` to match
121
+ // devrites-reviewer-readonly.sh; SubagentAgentType handles the aliases needed by
122
+ // the subagent hook.
125
123
  func (h Harness) ParsePreToolInput(r io.Reader) PreToolInput {
126
124
  var raw struct {
127
125
  ToolName string `json:"tool_name"`
@@ -143,10 +141,9 @@ func (h Harness) ParsePreToolInput(r io.Reader) PreToolInput {
143
141
  }
144
142
  }
145
143
 
146
- // SubagentAgentType decodes just the spawned subagent's name from a SubagentStart
147
- // payload, reading whichever of agent_type / subagent_type / agentType the harness
148
- // populates (Claude and Codex differ): the exact 3-way fallback
149
- // devrites-subagent-orient.sh uses. Never errors: bad stdin yields "".
144
+ // SubagentAgentType reads the spawned agent name from agent_type, subagent_type,
145
+ // or agentType. This matches the fallback order in
146
+ // devrites-subagent-orient.sh. Invalid input returns an empty string.
150
147
  func (h Harness) SubagentAgentType(r io.Reader) string {
151
148
  var raw struct {
152
149
  AgentType string `json:"agent_type"`
@@ -195,11 +192,9 @@ type preToolEnvelope struct {
195
192
  } `json:"hookSpecificOutput"`
196
193
  }
197
194
 
198
- // GuardInput is the fuller PreToolUse / PostToolUse payload the write-guards read:
199
- // the tool + its command / target path, the calling subagent's identity (both the
200
- // agent_id Claude sends and the agent_type Codex sends), and the tool's response
201
- // text (for the post-hooks that inspect output). Best-effort: bad stdin yields
202
- // the zero value so a guard stays fail-open.
195
+ // GuardInput contains the tool, command or target path, agent identity, and
196
+ // response text used by write guards. Claude sends agent_id, while Codex sends
197
+ // agent_type. Invalid input returns the zero value.
203
198
  type GuardInput struct {
204
199
  ToolName string
205
200
  Command string
@@ -279,11 +274,9 @@ type additionalContextEnvelope struct {
279
274
  } `json:"hookSpecificOutput"`
280
275
  }
281
276
 
282
- // marshalCompact encodes v as compact JSON WITHOUT Go's default HTML escaping
283
- // (`<`, `>`, `&` `<` …). The legacy shell hooks emit their JSON via
284
- // node's JSON.stringify, which does not HTML-escape; matching that is what keeps
285
- // a ported hook byte-parity with the script it replaces. The trailing newline
286
- // json.Encoder appends is trimmed so the caller controls line termination.
277
+ // marshalCompact encodes v as compact JSON without Go's default HTML escaping.
278
+ // Legacy shell hooks use JSON.stringify, so matching its output preserves byte
279
+ // parity. The caller controls line endings.
287
280
  func marshalCompact(v any) (string, error) {
288
281
  var buf bytes.Buffer
289
282
  enc := json.NewEncoder(&buf)
@@ -81,11 +81,27 @@ func TestHarnessEnvelopes(t *testing.T) {
81
81
  }
82
82
 
83
83
  func TestHarnessParsersFailOpenAndFallbacks(t *testing.T) {
84
- if got := Claude.ParseStopInput(strings.NewReader(`{"stop_hook_active":true}`)); !got.StopHookActive {
85
- t.Fatalf("ParseStopInput did not read stop_hook_active")
86
- }
87
- if got := Claude.ParseStopInput(strings.NewReader(`not-json`)); got.StopHookActive {
88
- t.Fatalf("ParseStopInput malformed payload = %#v, want zero value", got)
84
+ for _, test := range []struct {
85
+ name string
86
+ payload string
87
+ present bool
88
+ active bool
89
+ }{
90
+ {"explicit false", `{"stop_hook_active":false}`, true, false},
91
+ {"explicit true", `{"stop_hook_active":true}`, true, true},
92
+ {"empty", ``, false, false},
93
+ {"malformed", `not-json`, false, false},
94
+ {"missing", `{}`, false, false},
95
+ {"null", `{"stop_hook_active":null}`, false, false},
96
+ {"wrong type", `{"stop_hook_active":"false"}`, false, false},
97
+ } {
98
+ t.Run("stop/"+test.name, func(t *testing.T) {
99
+ got := Claude.ParseStopInput(strings.NewReader(test.payload))
100
+ if got.StopHookActivePresent != test.present || got.StopHookActive != test.active {
101
+ t.Fatalf("ParseStopInput(%q) = %#v, want present=%v active=%v",
102
+ test.payload, got, test.present, test.active)
103
+ }
104
+ })
89
105
  }
90
106
 
91
107
  pre := Codex.ParsePreToolInput(strings.NewReader(`{"tool_name":"Bash","tool_input":{"command":"go test ./..."},"agent_type":"reviewer"}`))