@matteeh/osq 0.2.1 → 0.2.2

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 (606) hide show
  1. package/README.md +234 -15
  2. package/dist/cli/approve.d.ts +7 -0
  3. package/dist/cli/approve.d.ts.map +1 -1
  4. package/dist/cli/approve.js +34 -0
  5. package/dist/cli/approve.js.map +1 -1
  6. package/dist/cli/bin.js +2 -3
  7. package/dist/cli/bin.js.map +1 -1
  8. package/dist/cli/check.d.ts +15 -0
  9. package/dist/cli/check.d.ts.map +1 -0
  10. package/dist/cli/check.js +65 -0
  11. package/dist/cli/check.js.map +1 -0
  12. package/dist/cli/index.d.ts.map +1 -1
  13. package/dist/cli/index.js +10 -10
  14. package/dist/cli/index.js.map +1 -1
  15. package/dist/cli/init.d.ts.map +1 -1
  16. package/dist/cli/init.js +6 -1
  17. package/dist/cli/init.js.map +1 -1
  18. package/dist/cli/lint.d.ts +3 -0
  19. package/dist/cli/lint.d.ts.map +1 -1
  20. package/dist/cli/lint.js +33 -14
  21. package/dist/cli/lint.js.map +1 -1
  22. package/dist/cli/plan-queue.d.ts +10 -4
  23. package/dist/cli/plan-queue.d.ts.map +1 -1
  24. package/dist/cli/plan-queue.js +20 -19
  25. package/dist/cli/plan-queue.js.map +1 -1
  26. package/dist/cli/plan-sections.d.ts +15 -0
  27. package/dist/cli/plan-sections.d.ts.map +1 -0
  28. package/dist/cli/plan-sections.js +47 -0
  29. package/dist/cli/plan-sections.js.map +1 -0
  30. package/dist/cli/plan.d.ts +1 -0
  31. package/dist/cli/plan.d.ts.map +1 -1
  32. package/dist/cli/plan.js +14 -4
  33. package/dist/cli/plan.js.map +1 -1
  34. package/dist/cli/report.d.ts.map +1 -1
  35. package/dist/cli/report.js +73 -1
  36. package/dist/cli/report.js.map +1 -1
  37. package/dist/cli/run.d.ts +7 -0
  38. package/dist/cli/run.d.ts.map +1 -0
  39. package/dist/cli/run.js +22 -0
  40. package/dist/cli/run.js.map +1 -0
  41. package/dist/cli/verified.d.ts +15 -0
  42. package/dist/cli/verified.d.ts.map +1 -0
  43. package/dist/cli/verified.js +34 -0
  44. package/dist/cli/verified.js.map +1 -0
  45. package/dist/core/foundation/config-agents.d.ts +16 -0
  46. package/dist/core/foundation/config-agents.d.ts.map +1 -0
  47. package/dist/core/foundation/config-agents.js +2 -0
  48. package/dist/core/foundation/config-agents.js.map +1 -0
  49. package/dist/core/foundation/config-claude.d.ts +48 -0
  50. package/dist/core/foundation/config-claude.d.ts.map +1 -0
  51. package/dist/core/foundation/config-claude.js +106 -0
  52. package/dist/core/foundation/config-claude.js.map +1 -0
  53. package/dist/core/foundation/config-codex-resolve.d.ts +10 -0
  54. package/dist/core/foundation/config-codex-resolve.d.ts.map +1 -0
  55. package/dist/core/foundation/config-codex-resolve.js +24 -0
  56. package/dist/core/foundation/config-codex-resolve.js.map +1 -0
  57. package/dist/core/foundation/config-file.d.ts +18 -0
  58. package/dist/core/foundation/config-file.d.ts.map +1 -0
  59. package/dist/core/foundation/config-file.js +46 -0
  60. package/dist/core/foundation/config-file.js.map +1 -0
  61. package/dist/core/foundation/config-gates.d.ts +2 -0
  62. package/dist/core/foundation/config-gates.d.ts.map +1 -1
  63. package/dist/core/foundation/config-gates.js +8 -0
  64. package/dist/core/foundation/config-gates.js.map +1 -1
  65. package/dist/core/foundation/config-opencode.d.ts +25 -0
  66. package/dist/core/foundation/config-opencode.d.ts.map +1 -0
  67. package/dist/core/foundation/config-opencode.js +55 -0
  68. package/dist/core/foundation/config-opencode.js.map +1 -0
  69. package/dist/core/foundation/config-pi.d.ts +10 -0
  70. package/dist/core/foundation/config-pi.d.ts.map +1 -1
  71. package/dist/core/foundation/config-pi.js +13 -0
  72. package/dist/core/foundation/config-pi.js.map +1 -1
  73. package/dist/core/foundation/config-planning.d.ts +12 -1
  74. package/dist/core/foundation/config-planning.d.ts.map +1 -1
  75. package/dist/core/foundation/config-planning.js +29 -1
  76. package/dist/core/foundation/config-planning.js.map +1 -1
  77. package/dist/core/foundation/config-traceability.d.ts +28 -0
  78. package/dist/core/foundation/config-traceability.d.ts.map +1 -0
  79. package/dist/core/foundation/config-traceability.js +63 -0
  80. package/dist/core/foundation/config-traceability.js.map +1 -0
  81. package/dist/core/foundation/config-user.d.ts +32 -0
  82. package/dist/core/foundation/config-user.d.ts.map +1 -0
  83. package/dist/core/foundation/config-user.js +2 -0
  84. package/dist/core/foundation/config-user.js.map +1 -0
  85. package/dist/core/foundation/config-vcs.d.ts +29 -0
  86. package/dist/core/foundation/config-vcs.d.ts.map +1 -0
  87. package/dist/core/foundation/config-vcs.js +57 -0
  88. package/dist/core/foundation/config-vcs.js.map +1 -0
  89. package/dist/core/foundation/config.d.ts +23 -24
  90. package/dist/core/foundation/config.d.ts.map +1 -1
  91. package/dist/core/foundation/config.js +29 -36
  92. package/dist/core/foundation/config.js.map +1 -1
  93. package/dist/core/foundation/decisions-validate.d.ts +16 -0
  94. package/dist/core/foundation/decisions-validate.d.ts.map +1 -0
  95. package/dist/core/foundation/decisions-validate.js +74 -0
  96. package/dist/core/foundation/decisions-validate.js.map +1 -0
  97. package/dist/core/foundation/decisions.d.ts +34 -0
  98. package/dist/core/foundation/decisions.d.ts.map +1 -0
  99. package/dist/core/foundation/decisions.js +152 -0
  100. package/dist/core/foundation/decisions.js.map +1 -0
  101. package/dist/core/foundation/doctor-decisions.d.ts +9 -0
  102. package/dist/core/foundation/doctor-decisions.d.ts.map +1 -0
  103. package/dist/core/foundation/doctor-decisions.js +49 -0
  104. package/dist/core/foundation/doctor-decisions.js.map +1 -0
  105. package/dist/core/foundation/doctor-managed.d.ts.map +1 -1
  106. package/dist/core/foundation/doctor-managed.js +3 -0
  107. package/dist/core/foundation/doctor-managed.js.map +1 -1
  108. package/dist/core/foundation/doctor-prices.d.ts +8 -0
  109. package/dist/core/foundation/doctor-prices.d.ts.map +1 -0
  110. package/dist/core/foundation/doctor-prices.js +25 -0
  111. package/dist/core/foundation/doctor-prices.js.map +1 -0
  112. package/dist/core/foundation/doctor.d.ts.map +1 -1
  113. package/dist/core/foundation/doctor.js +20 -30
  114. package/dist/core/foundation/doctor.js.map +1 -1
  115. package/dist/core/foundation/harness-catalog.d.ts +7 -8
  116. package/dist/core/foundation/harness-catalog.d.ts.map +1 -1
  117. package/dist/core/foundation/harness-catalog.js +26 -41
  118. package/dist/core/foundation/harness-catalog.js.map +1 -1
  119. package/dist/core/foundation/init-blocks.d.ts +1 -1
  120. package/dist/core/foundation/init-blocks.d.ts.map +1 -1
  121. package/dist/core/foundation/init-blocks.js +51 -14
  122. package/dist/core/foundation/init-blocks.js.map +1 -1
  123. package/dist/core/foundation/init.d.ts +4 -0
  124. package/dist/core/foundation/init.d.ts.map +1 -1
  125. package/dist/core/foundation/init.js +7 -0
  126. package/dist/core/foundation/init.js.map +1 -1
  127. package/dist/core/foundation/new.d.ts +4 -1
  128. package/dist/core/foundation/new.d.ts.map +1 -1
  129. package/dist/core/foundation/new.js +18 -8
  130. package/dist/core/foundation/new.js.map +1 -1
  131. package/dist/core/foundation/package-root.d.ts +6 -0
  132. package/dist/core/foundation/package-root.d.ts.map +1 -1
  133. package/dist/core/foundation/package-root.js +6 -0
  134. package/dist/core/foundation/package-root.js.map +1 -1
  135. package/dist/core/foundation/rules-block.d.ts +11 -0
  136. package/dist/core/foundation/rules-block.d.ts.map +1 -0
  137. package/dist/core/foundation/rules-block.js +90 -0
  138. package/dist/core/foundation/rules-block.js.map +1 -0
  139. package/dist/core/foundation/traceability-block.d.ts +13 -0
  140. package/dist/core/foundation/traceability-block.d.ts.map +1 -0
  141. package/dist/core/foundation/traceability-block.js +124 -0
  142. package/dist/core/foundation/traceability-block.js.map +1 -0
  143. package/dist/core/lifecycle/done.d.ts.map +1 -1
  144. package/dist/core/lifecycle/done.js +2 -4
  145. package/dist/core/lifecycle/done.js.map +1 -1
  146. package/dist/core/lifecycle/recertify.d.ts +9 -0
  147. package/dist/core/lifecycle/recertify.d.ts.map +1 -0
  148. package/dist/core/lifecycle/recertify.js +27 -0
  149. package/dist/core/lifecycle/recertify.js.map +1 -0
  150. package/dist/core/lifecycle/reject.d.ts.map +1 -1
  151. package/dist/core/lifecycle/reject.js +3 -4
  152. package/dist/core/lifecycle/reject.js.map +1 -1
  153. package/dist/core/lifecycle/retry.d.ts.map +1 -1
  154. package/dist/core/lifecycle/retry.js +6 -20
  155. package/dist/core/lifecycle/retry.js.map +1 -1
  156. package/dist/core/lifecycle/verification-record.d.ts +42 -0
  157. package/dist/core/lifecycle/verification-record.d.ts.map +1 -0
  158. package/dist/core/lifecycle/verification-record.js +76 -0
  159. package/dist/core/lifecycle/verification-record.js.map +1 -0
  160. package/dist/core/report/approval-flags.d.ts +16 -3
  161. package/dist/core/report/approval-flags.d.ts.map +1 -1
  162. package/dist/core/report/approval-flags.js +59 -22
  163. package/dist/core/report/approval-flags.js.map +1 -1
  164. package/dist/core/report/brief-to-approval.d.ts +7 -0
  165. package/dist/core/report/brief-to-approval.d.ts.map +1 -0
  166. package/dist/core/report/brief-to-approval.js +43 -0
  167. package/dist/core/report/brief-to-approval.js.map +1 -0
  168. package/dist/core/report/planning-price-gaps.d.ts +10 -0
  169. package/dist/core/report/planning-price-gaps.d.ts.map +1 -0
  170. package/dist/core/report/planning-price-gaps.js +37 -0
  171. package/dist/core/report/planning-price-gaps.js.map +1 -0
  172. package/dist/core/report/planning-slice-lookup.d.ts.map +1 -1
  173. package/dist/core/report/planning-slice-lookup.js +3 -9
  174. package/dist/core/report/planning-slice-lookup.js.map +1 -1
  175. package/dist/core/report/recent-disclosures.d.ts +18 -0
  176. package/dist/core/report/recent-disclosures.d.ts.map +1 -0
  177. package/dist/core/report/recent-disclosures.js +105 -0
  178. package/dist/core/report/recent-disclosures.js.map +1 -0
  179. package/dist/core/report/record-disclosures.d.ts +14 -0
  180. package/dist/core/report/record-disclosures.d.ts.map +1 -0
  181. package/dist/core/report/record-disclosures.js +30 -0
  182. package/dist/core/report/record-disclosures.js.map +1 -0
  183. package/dist/core/report/record-estimates.d.ts +25 -0
  184. package/dist/core/report/record-estimates.d.ts.map +1 -0
  185. package/dist/core/report/record-estimates.js +83 -0
  186. package/dist/core/report/record-estimates.js.map +1 -0
  187. package/dist/core/report/record-rework.d.ts +19 -0
  188. package/dist/core/report/record-rework.d.ts.map +1 -0
  189. package/dist/core/report/record-rework.js +50 -0
  190. package/dist/core/report/record-rework.js.map +1 -0
  191. package/dist/core/report/record-verification.d.ts +16 -0
  192. package/dist/core/report/record-verification.d.ts.map +1 -0
  193. package/dist/core/report/record-verification.js +33 -0
  194. package/dist/core/report/record-verification.js.map +1 -0
  195. package/dist/core/report/report-dependencies.d.ts +29 -0
  196. package/dist/core/report/report-dependencies.d.ts.map +1 -0
  197. package/dist/core/report/report-dependencies.js +92 -0
  198. package/dist/core/report/report-dependencies.js.map +1 -0
  199. package/dist/core/report/report-events.d.ts +1 -0
  200. package/dist/core/report/report-events.d.ts.map +1 -1
  201. package/dist/core/report/report-events.js +8 -26
  202. package/dist/core/report/report-events.js.map +1 -1
  203. package/dist/core/report/report-mutation.d.ts +34 -0
  204. package/dist/core/report/report-mutation.d.ts.map +1 -0
  205. package/dist/core/report/report-mutation.js +191 -0
  206. package/dist/core/report/report-mutation.js.map +1 -0
  207. package/dist/core/report/report-scope.d.ts +21 -0
  208. package/dist/core/report/report-scope.d.ts.map +1 -0
  209. package/dist/core/report/report-scope.js +61 -0
  210. package/dist/core/report/report-scope.js.map +1 -0
  211. package/dist/core/report/report-traceability.d.ts +29 -0
  212. package/dist/core/report/report-traceability.d.ts.map +1 -0
  213. package/dist/core/report/report-traceability.js +94 -0
  214. package/dist/core/report/report-traceability.js.map +1 -0
  215. package/dist/core/report/report.d.ts +35 -1
  216. package/dist/core/report/report.d.ts.map +1 -1
  217. package/dist/core/report/report.js +130 -111
  218. package/dist/core/report/report.js.map +1 -1
  219. package/dist/core/report/result-sections.d.ts +30 -0
  220. package/dist/core/report/result-sections.d.ts.map +1 -0
  221. package/dist/core/report/result-sections.js +125 -0
  222. package/dist/core/report/result-sections.js.map +1 -0
  223. package/dist/core/report/scope-size.d.ts +7 -0
  224. package/dist/core/report/scope-size.d.ts.map +1 -0
  225. package/dist/core/report/scope-size.js +22 -0
  226. package/dist/core/report/scope-size.js.map +1 -0
  227. package/dist/core/run/commit-message.d.ts +24 -0
  228. package/dist/core/run/commit-message.d.ts.map +1 -0
  229. package/dist/core/run/commit-message.js +76 -0
  230. package/dist/core/run/commit-message.js.map +1 -0
  231. package/dist/core/run/dead-commit.d.ts +10 -0
  232. package/dist/core/run/dead-commit.d.ts.map +1 -0
  233. package/dist/core/run/dead-commit.js +70 -0
  234. package/dist/core/run/dead-commit.js.map +1 -0
  235. package/dist/core/run/focused-tests.d.ts +43 -0
  236. package/dist/core/run/focused-tests.d.ts.map +1 -0
  237. package/dist/core/run/focused-tests.js +116 -0
  238. package/dist/core/run/focused-tests.js.map +1 -0
  239. package/dist/core/run/manifest-approval.d.ts +7 -0
  240. package/dist/core/run/manifest-approval.d.ts.map +1 -0
  241. package/dist/core/run/manifest-approval.js +30 -0
  242. package/dist/core/run/manifest-approval.js.map +1 -0
  243. package/dist/core/run/manifest.d.ts +11 -1
  244. package/dist/core/run/manifest.d.ts.map +1 -1
  245. package/dist/core/run/manifest.js +52 -11
  246. package/dist/core/run/manifest.js.map +1 -1
  247. package/dist/core/run/mutation-report.d.ts +29 -0
  248. package/dist/core/run/mutation-report.d.ts.map +1 -0
  249. package/dist/core/run/mutation-report.js +107 -0
  250. package/dist/core/run/mutation-report.js.map +1 -0
  251. package/dist/core/run/mutation-run.d.ts +32 -0
  252. package/dist/core/run/mutation-run.d.ts.map +1 -0
  253. package/dist/core/run/mutation-run.js +80 -0
  254. package/dist/core/run/mutation-run.js.map +1 -0
  255. package/dist/core/run/verification.d.ts +12 -1
  256. package/dist/core/run/verification.d.ts.map +1 -1
  257. package/dist/core/run/verification.js +24 -2
  258. package/dist/core/run/verification.js.map +1 -1
  259. package/dist/core/spec/approve-worktree-shared.d.ts +33 -0
  260. package/dist/core/spec/approve-worktree-shared.d.ts.map +1 -0
  261. package/dist/core/spec/approve-worktree-shared.js +59 -0
  262. package/dist/core/spec/approve-worktree-shared.js.map +1 -0
  263. package/dist/core/spec/approve-worktree.d.ts +21 -0
  264. package/dist/core/spec/approve-worktree.d.ts.map +1 -0
  265. package/dist/core/spec/approve-worktree.js +153 -0
  266. package/dist/core/spec/approve-worktree.js.map +1 -0
  267. package/dist/core/spec/approve.d.ts +20 -10
  268. package/dist/core/spec/approve.d.ts.map +1 -1
  269. package/dist/core/spec/approve.js +57 -54
  270. package/dist/core/spec/approve.js.map +1 -1
  271. package/dist/core/spec/capability-impact.d.ts +43 -0
  272. package/dist/core/spec/capability-impact.d.ts.map +1 -0
  273. package/dist/core/spec/capability-impact.js +85 -0
  274. package/dist/core/spec/capability-impact.js.map +1 -0
  275. package/dist/core/spec/decisions-lint.d.ts +18 -0
  276. package/dist/core/spec/decisions-lint.d.ts.map +1 -0
  277. package/dist/core/spec/decisions-lint.js +127 -0
  278. package/dist/core/spec/decisions-lint.js.map +1 -0
  279. package/dist/core/spec/delta.d.ts +6 -0
  280. package/dist/core/spec/delta.d.ts.map +1 -1
  281. package/dist/core/spec/delta.js +73 -5
  282. package/dist/core/spec/delta.js.map +1 -1
  283. package/dist/core/spec/digest-decisions.d.ts +27 -0
  284. package/dist/core/spec/digest-decisions.d.ts.map +1 -0
  285. package/dist/core/spec/digest-decisions.js +86 -0
  286. package/dist/core/spec/digest-decisions.js.map +1 -0
  287. package/dist/core/spec/digest-format.d.ts +4 -0
  288. package/dist/core/spec/digest-format.d.ts.map +1 -0
  289. package/dist/core/spec/digest-format.js +44 -0
  290. package/dist/core/spec/digest-format.js.map +1 -0
  291. package/dist/core/spec/digest.d.ts +5 -3
  292. package/dist/core/spec/digest.d.ts.map +1 -1
  293. package/dist/core/spec/digest.js +14 -33
  294. package/dist/core/spec/digest.js.map +1 -1
  295. package/dist/core/spec/human-steps.d.ts +20 -0
  296. package/dist/core/spec/human-steps.d.ts.map +1 -0
  297. package/dist/core/spec/human-steps.js +52 -0
  298. package/dist/core/spec/human-steps.js.map +1 -0
  299. package/dist/core/spec/impact-lint.d.ts +24 -0
  300. package/dist/core/spec/impact-lint.d.ts.map +1 -0
  301. package/dist/core/spec/impact-lint.js +39 -0
  302. package/dist/core/spec/impact-lint.js.map +1 -0
  303. package/dist/core/spec/import-graph.d.ts +35 -0
  304. package/dist/core/spec/import-graph.d.ts.map +1 -0
  305. package/dist/core/spec/import-graph.js +155 -0
  306. package/dist/core/spec/import-graph.js.map +1 -0
  307. package/dist/core/spec/lint-findings.d.ts +44 -0
  308. package/dist/core/spec/lint-findings.d.ts.map +1 -0
  309. package/dist/core/spec/lint-findings.js +56 -0
  310. package/dist/core/spec/lint-findings.js.map +1 -0
  311. package/dist/core/spec/lint-output.d.ts +53 -0
  312. package/dist/core/spec/lint-output.d.ts.map +1 -0
  313. package/dist/core/spec/lint-output.js +87 -0
  314. package/dist/core/spec/lint-output.js.map +1 -0
  315. package/dist/core/spec/linter.d.ts +14 -4
  316. package/dist/core/spec/linter.d.ts.map +1 -1
  317. package/dist/core/spec/linter.js +271 -111
  318. package/dist/core/spec/linter.js.map +1 -1
  319. package/dist/core/spec/merged-spec-check.d.ts +24 -0
  320. package/dist/core/spec/merged-spec-check.d.ts.map +1 -0
  321. package/dist/core/spec/merged-spec-check.js +95 -0
  322. package/dist/core/spec/merged-spec-check.js.map +1 -0
  323. package/dist/core/spec/openspec-issues.d.ts +58 -0
  324. package/dist/core/spec/openspec-issues.d.ts.map +1 -0
  325. package/dist/core/spec/openspec-issues.js +166 -0
  326. package/dist/core/spec/openspec-issues.js.map +1 -0
  327. package/dist/core/spec/parser.d.ts +1 -0
  328. package/dist/core/spec/parser.d.ts.map +1 -1
  329. package/dist/core/spec/parser.js +16 -6
  330. package/dist/core/spec/parser.js.map +1 -1
  331. package/dist/core/spec/scenario-impact.d.ts +47 -0
  332. package/dist/core/spec/scenario-impact.d.ts.map +1 -0
  333. package/dist/core/spec/scenario-impact.js +130 -0
  334. package/dist/core/spec/scenario-impact.js.map +1 -0
  335. package/dist/core/spec/test-impact.d.ts +28 -0
  336. package/dist/core/spec/test-impact.d.ts.map +1 -0
  337. package/dist/core/spec/test-impact.js +119 -0
  338. package/dist/core/spec/test-impact.js.map +1 -0
  339. package/dist/core/spec/traceability-links.d.ts +50 -0
  340. package/dist/core/spec/traceability-links.d.ts.map +1 -0
  341. package/dist/core/spec/traceability-links.js +120 -0
  342. package/dist/core/spec/traceability-links.js.map +1 -0
  343. package/dist/core/spec/traceability-lint.d.ts +29 -0
  344. package/dist/core/spec/traceability-lint.d.ts.map +1 -0
  345. package/dist/core/spec/traceability-lint.js +143 -0
  346. package/dist/core/spec/traceability-lint.js.map +1 -0
  347. package/dist/core/status/blocked-item.d.ts +8 -0
  348. package/dist/core/status/blocked-item.d.ts.map +1 -0
  349. package/dist/core/status/blocked-item.js +45 -0
  350. package/dist/core/status/blocked-item.js.map +1 -0
  351. package/dist/core/status/change-locations.d.ts +44 -0
  352. package/dist/core/status/change-locations.d.ts.map +1 -0
  353. package/dist/core/status/change-locations.js +138 -0
  354. package/dist/core/status/change-locations.js.map +1 -0
  355. package/dist/core/status/dependency-readiness.d.ts +11 -0
  356. package/dist/core/status/dependency-readiness.d.ts.map +1 -0
  357. package/dist/core/status/dependency-readiness.js +39 -0
  358. package/dist/core/status/dependency-readiness.js.map +1 -0
  359. package/dist/core/status/inbox-projection.d.ts.map +1 -1
  360. package/dist/core/status/inbox-projection.js +23 -4
  361. package/dist/core/status/inbox-projection.js.map +1 -1
  362. package/dist/core/status/inbox-text.d.ts.map +1 -1
  363. package/dist/core/status/inbox-text.js +34 -3
  364. package/dist/core/status/inbox-text.js.map +1 -1
  365. package/dist/core/status/inbox.d.ts +10 -1
  366. package/dist/core/status/inbox.d.ts.map +1 -1
  367. package/dist/core/status/inbox.js +19 -1
  368. package/dist/core/status/inbox.js.map +1 -1
  369. package/dist/core/status/layout.d.ts +6 -0
  370. package/dist/core/status/layout.d.ts.map +1 -1
  371. package/dist/core/status/layout.js +8 -0
  372. package/dist/core/status/layout.js.map +1 -1
  373. package/dist/core/status/next-step.d.ts +17 -0
  374. package/dist/core/status/next-step.d.ts.map +1 -0
  375. package/dist/core/status/next-step.js +85 -0
  376. package/dist/core/status/next-step.js.map +1 -0
  377. package/dist/core/status/pre-spawn-words.d.ts +13 -0
  378. package/dist/core/status/pre-spawn-words.d.ts.map +1 -0
  379. package/dist/core/status/pre-spawn-words.js +26 -0
  380. package/dist/core/status/pre-spawn-words.js.map +1 -0
  381. package/dist/core/status/queue-parser.d.ts +1 -0
  382. package/dist/core/status/queue-parser.d.ts.map +1 -1
  383. package/dist/core/status/queue-parser.js +41 -2
  384. package/dist/core/status/queue-parser.js.map +1 -1
  385. package/dist/core/status/queue-planning.d.ts +1 -0
  386. package/dist/core/status/queue-planning.d.ts.map +1 -1
  387. package/dist/core/status/queue-planning.js +24 -12
  388. package/dist/core/status/queue-planning.js.map +1 -1
  389. package/dist/core/status/queue-report-detail.d.ts.map +1 -1
  390. package/dist/core/status/queue-report-detail.js +5 -3
  391. package/dist/core/status/queue-report-detail.js.map +1 -1
  392. package/dist/core/status/queue-state.d.ts +1 -1
  393. package/dist/core/status/queue-state.d.ts.map +1 -1
  394. package/dist/core/status/queue-state.js +27 -41
  395. package/dist/core/status/queue-state.js.map +1 -1
  396. package/dist/core/status/show.d.ts +25 -0
  397. package/dist/core/status/show.d.ts.map +1 -1
  398. package/dist/core/status/show.js +354 -91
  399. package/dist/core/status/show.js.map +1 -1
  400. package/dist/core/status/state.d.ts.map +1 -1
  401. package/dist/core/status/state.js +1 -23
  402. package/dist/core/status/state.js.map +1 -1
  403. package/dist/core/status/status.d.ts +18 -0
  404. package/dist/core/status/status.d.ts.map +1 -1
  405. package/dist/core/status/status.js +59 -80
  406. package/dist/core/status/status.js.map +1 -1
  407. package/dist/core/status/verification.d.ts +27 -0
  408. package/dist/core/status/verification.d.ts.map +1 -0
  409. package/dist/core/status/verification.js +111 -0
  410. package/dist/core/status/verification.js.map +1 -0
  411. package/dist/core/trace/function-ranges.d.ts +30 -0
  412. package/dist/core/trace/function-ranges.d.ts.map +1 -0
  413. package/dist/core/trace/function-ranges.js +250 -0
  414. package/dist/core/trace/function-ranges.js.map +1 -0
  415. package/dist/core/trace/mutation-pick.d.ts +55 -0
  416. package/dist/core/trace/mutation-pick.d.ts.map +1 -0
  417. package/dist/core/trace/mutation-pick.js +96 -0
  418. package/dist/core/trace/mutation-pick.js.map +1 -0
  419. package/dist/core/trace/scenario-index.d.ts +27 -0
  420. package/dist/core/trace/scenario-index.d.ts.map +1 -0
  421. package/dist/core/trace/scenario-index.js +76 -0
  422. package/dist/core/trace/scenario-index.js.map +1 -0
  423. package/dist/core/trace/scenario-lookup.d.ts +14 -0
  424. package/dist/core/trace/scenario-lookup.d.ts.map +1 -0
  425. package/dist/core/trace/scenario-lookup.js +179 -0
  426. package/dist/core/trace/scenario-lookup.js.map +1 -0
  427. package/dist/core/trace/tag-scan.d.ts +44 -0
  428. package/dist/core/trace/tag-scan.d.ts.map +1 -0
  429. package/dist/core/trace/tag-scan.js +200 -0
  430. package/dist/core/trace/tag-scan.js.map +1 -0
  431. package/dist/core/vcs/doctor-git.d.ts +13 -0
  432. package/dist/core/vcs/doctor-git.d.ts.map +1 -0
  433. package/dist/core/vcs/doctor-git.js +114 -0
  434. package/dist/core/vcs/doctor-git.js.map +1 -0
  435. package/dist/core/vcs/git-vcs-write.d.ts +47 -0
  436. package/dist/core/vcs/git-vcs-write.d.ts.map +1 -0
  437. package/dist/core/vcs/git-vcs-write.js +210 -0
  438. package/dist/core/vcs/git-vcs-write.js.map +1 -0
  439. package/dist/core/vcs/git-vcs.d.ts +40 -0
  440. package/dist/core/vcs/git-vcs.d.ts.map +1 -0
  441. package/dist/core/vcs/git-vcs.js +170 -0
  442. package/dist/core/vcs/git-vcs.js.map +1 -0
  443. package/dist/core/vcs/no-vcs.d.ts +26 -0
  444. package/dist/core/vcs/no-vcs.d.ts.map +1 -0
  445. package/dist/core/vcs/no-vcs.js +62 -0
  446. package/dist/core/vcs/no-vcs.js.map +1 -0
  447. package/dist/core/vcs/select.d.ts +11 -0
  448. package/dist/core/vcs/select.d.ts.map +1 -0
  449. package/dist/core/vcs/select.js +33 -0
  450. package/dist/core/vcs/select.js.map +1 -0
  451. package/dist/core/vcs/snapshot.d.ts +34 -0
  452. package/dist/core/vcs/snapshot.d.ts.map +1 -0
  453. package/dist/core/vcs/snapshot.js +71 -0
  454. package/dist/core/vcs/snapshot.js.map +1 -0
  455. package/dist/core/vcs/vcs.d.ts +55 -0
  456. package/dist/core/vcs/vcs.d.ts.map +1 -0
  457. package/dist/core/vcs/vcs.js +2 -0
  458. package/dist/core/vcs/vcs.js.map +1 -0
  459. package/dist/core/vcs/worktree.d.ts +10 -0
  460. package/dist/core/vcs/worktree.d.ts.map +1 -0
  461. package/dist/core/vcs/worktree.js +25 -0
  462. package/dist/core/vcs/worktree.js.map +1 -0
  463. package/dist/core/web/web-data-folders.d.ts.map +1 -1
  464. package/dist/core/web/web-data-folders.js +18 -33
  465. package/dist/core/web/web-data-folders.js.map +1 -1
  466. package/dist/core/web/web-data-lifecycle.d.ts.map +1 -1
  467. package/dist/core/web/web-data-lifecycle.js +2 -1
  468. package/dist/core/web/web-data-lifecycle.js.map +1 -1
  469. package/dist/core/web/web-events.d.ts +8 -6
  470. package/dist/core/web/web-events.d.ts.map +1 -1
  471. package/dist/core/web/web-events.js +7 -31
  472. package/dist/core/web/web-events.js.map +1 -1
  473. package/dist/core/web/web-server.d.ts.map +1 -1
  474. package/dist/core/web/web-server.js +3 -0
  475. package/dist/core/web/web-server.js.map +1 -1
  476. package/dist/core/web/web-trees.d.ts +27 -0
  477. package/dist/core/web/web-trees.d.ts.map +1 -0
  478. package/dist/core/web/web-trees.js +82 -0
  479. package/dist/core/web/web-trees.js.map +1 -0
  480. package/dist/harness/claude/claude-exec-args.d.ts +13 -0
  481. package/dist/harness/claude/claude-exec-args.d.ts.map +1 -0
  482. package/dist/harness/claude/claude-exec-args.js +61 -0
  483. package/dist/harness/claude/claude-exec-args.js.map +1 -0
  484. package/dist/harness/claude/claude-exec.d.ts +12 -0
  485. package/dist/harness/claude/claude-exec.d.ts.map +1 -0
  486. package/dist/harness/claude/claude-exec.js +79 -0
  487. package/dist/harness/claude/claude-exec.js.map +1 -0
  488. package/dist/harness/claude/claude-stream.d.ts +31 -0
  489. package/dist/harness/claude/claude-stream.d.ts.map +1 -0
  490. package/dist/harness/claude/claude-stream.js +150 -0
  491. package/dist/harness/claude/claude-stream.js.map +1 -0
  492. package/dist/harness/claude/claude-tools.d.ts +5 -0
  493. package/dist/harness/claude/claude-tools.d.ts.map +1 -0
  494. package/dist/harness/claude/claude-tools.js +30 -0
  495. package/dist/harness/claude/claude-tools.js.map +1 -0
  496. package/dist/harness/index.d.ts +1 -0
  497. package/dist/harness/index.d.ts.map +1 -1
  498. package/dist/harness/index.js +3 -0
  499. package/dist/harness/index.js.map +1 -1
  500. package/dist/harness/opencode/opencode-session.d.ts +42 -0
  501. package/dist/harness/opencode/opencode-session.d.ts.map +1 -0
  502. package/dist/harness/opencode/opencode-session.js +123 -0
  503. package/dist/harness/opencode/opencode-session.js.map +1 -0
  504. package/dist/harness/opencode/opencode.d.ts +2 -1
  505. package/dist/harness/opencode/opencode.d.ts.map +1 -1
  506. package/dist/harness/opencode/opencode.js +52 -28
  507. package/dist/harness/opencode/opencode.js.map +1 -1
  508. package/dist/harness/prompt.js +1 -1
  509. package/dist/harness/prompt.js.map +1 -1
  510. package/dist/harness/types.d.ts +112 -1
  511. package/dist/harness/types.d.ts.map +1 -1
  512. package/dist/harness/types.js.map +1 -1
  513. package/dist/index.d.ts +3 -1
  514. package/dist/index.d.ts.map +1 -1
  515. package/dist/index.js +1 -0
  516. package/dist/index.js.map +1 -1
  517. package/dist/testing/index.d.ts +3 -0
  518. package/dist/testing/index.d.ts.map +1 -0
  519. package/dist/testing/index.js +2 -0
  520. package/dist/testing/index.js.map +1 -0
  521. package/dist/testing/scenario.d.ts +29 -0
  522. package/dist/testing/scenario.d.ts.map +1 -0
  523. package/dist/testing/scenario.js +157 -0
  524. package/dist/testing/scenario.js.map +1 -0
  525. package/dist/watcher/archiver.d.ts +2 -1
  526. package/dist/watcher/archiver.d.ts.map +1 -1
  527. package/dist/watcher/archiver.js +27 -2
  528. package/dist/watcher/archiver.js.map +1 -1
  529. package/dist/watcher/auto-recertify.d.ts +27 -0
  530. package/dist/watcher/auto-recertify.d.ts.map +1 -0
  531. package/dist/watcher/auto-recertify.js +113 -0
  532. package/dist/watcher/auto-recertify.js.map +1 -0
  533. package/dist/watcher/auto-retry.d.ts +1 -1
  534. package/dist/watcher/auto-retry.d.ts.map +1 -1
  535. package/dist/watcher/auto-retry.js +3 -11
  536. package/dist/watcher/auto-retry.js.map +1 -1
  537. package/dist/watcher/baseline-key.d.ts +17 -0
  538. package/dist/watcher/baseline-key.d.ts.map +1 -0
  539. package/dist/watcher/baseline-key.js +31 -0
  540. package/dist/watcher/baseline-key.js.map +1 -0
  541. package/dist/watcher/baseline.d.ts +32 -0
  542. package/dist/watcher/baseline.d.ts.map +1 -0
  543. package/dist/watcher/baseline.js +166 -0
  544. package/dist/watcher/baseline.js.map +1 -0
  545. package/dist/watcher/blocked.d.ts +12 -0
  546. package/dist/watcher/blocked.d.ts.map +1 -0
  547. package/dist/watcher/blocked.js +24 -0
  548. package/dist/watcher/blocked.js.map +1 -0
  549. package/dist/watcher/dependencies.d.ts +28 -0
  550. package/dist/watcher/dependencies.d.ts.map +1 -0
  551. package/dist/watcher/dependencies.js +152 -0
  552. package/dist/watcher/dependencies.js.map +1 -0
  553. package/dist/watcher/done-metadata.d.ts +4 -0
  554. package/dist/watcher/done-metadata.d.ts.map +1 -0
  555. package/dist/watcher/done-metadata.js +20 -0
  556. package/dist/watcher/done-metadata.js.map +1 -0
  557. package/dist/watcher/failure-reason.d.ts +1 -1
  558. package/dist/watcher/failure-reason.d.ts.map +1 -1
  559. package/dist/watcher/focused-verify.d.ts +17 -0
  560. package/dist/watcher/focused-verify.d.ts.map +1 -0
  561. package/dist/watcher/focused-verify.js +54 -0
  562. package/dist/watcher/focused-verify.js.map +1 -0
  563. package/dist/watcher/git-guard.d.ts +24 -0
  564. package/dist/watcher/git-guard.d.ts.map +1 -0
  565. package/dist/watcher/git-guard.js +95 -0
  566. package/dist/watcher/git-guard.js.map +1 -0
  567. package/dist/watcher/instructions-drift.d.ts +21 -0
  568. package/dist/watcher/instructions-drift.d.ts.map +1 -0
  569. package/dist/watcher/instructions-drift.js +115 -0
  570. package/dist/watcher/instructions-drift.js.map +1 -0
  571. package/dist/watcher/loop.d.ts.map +1 -1
  572. package/dist/watcher/loop.js +36 -50
  573. package/dist/watcher/loop.js.map +1 -1
  574. package/dist/watcher/measures.d.ts.map +1 -1
  575. package/dist/watcher/measures.js +22 -39
  576. package/dist/watcher/measures.js.map +1 -1
  577. package/dist/watcher/mutation-check.d.ts +42 -0
  578. package/dist/watcher/mutation-check.d.ts.map +1 -0
  579. package/dist/watcher/mutation-check.js +147 -0
  580. package/dist/watcher/mutation-check.js.map +1 -0
  581. package/dist/watcher/regression.d.ts +10 -5
  582. package/dist/watcher/regression.d.ts.map +1 -1
  583. package/dist/watcher/regression.js +29 -22
  584. package/dist/watcher/regression.js.map +1 -1
  585. package/dist/watcher/runner.d.ts.map +1 -1
  586. package/dist/watcher/runner.js +12 -14
  587. package/dist/watcher/runner.js.map +1 -1
  588. package/dist/watcher/spawn.d.ts.map +1 -1
  589. package/dist/watcher/spawn.js +5 -0
  590. package/dist/watcher/spawn.js.map +1 -1
  591. package/dist/watcher/task-verify.d.ts +7 -2
  592. package/dist/watcher/task-verify.d.ts.map +1 -1
  593. package/dist/watcher/task-verify.js +33 -8
  594. package/dist/watcher/task-verify.js.map +1 -1
  595. package/dist/watcher/verify.d.ts +1 -5
  596. package/dist/watcher/verify.d.ts.map +1 -1
  597. package/dist/watcher/verify.js +2 -6
  598. package/dist/watcher/verify.js.map +1 -1
  599. package/package.json +5 -1
  600. package/templates/PLANNER.md +35 -9
  601. package/templates/openspec/config.yaml +1 -1
  602. package/templates/openspec/schemas/osq/schema.yaml +4 -2
  603. package/templates/openspec/schemas/osq/templates/proposal.md +9 -2
  604. package/templates/proposal.md +9 -2
  605. package/ui/dist/assets/{index-CZYeQ8la.js → index-D39uYbbL.js} +1 -1
  606. package/ui/dist/index.html +1 -1
package/README.md CHANGED
@@ -22,6 +22,12 @@ Run `osq init --refresh-schema` to pick up a new OpenSpec schema. It overwrites
22
22
 
23
23
  ## Upgrading
24
24
 
25
+ To 0.2.2:
26
+
27
+ - The opencode adapter needs opencode 2. `osq doctor` and the watcher's preflight refuse opencode 1.
28
+ - A config file that exists but fails to import or validate now stops every command with `Error: Failed to load <path>: <message>` and exit 1. Earlier releases carried on with the defaults.
29
+ - The managed `AGENTS.md` and `PLANNER.md` blocks changed. Run `osq init` to refresh them; until you do, `osq doctor` reports the drift.
30
+
25
31
  Resolver 2 changes the automated done-marker hashes for active changes. On the first watcher cycle after upgrading, a completed task in an active change whose `.run/done/<n>` lacks `scope_resolver: 2` is detected even when its recorded aggregate hash still matches. This is a one-time recertification wave: the watcher runs each affected task's `verify` at detection, writes one idempotent `.run/regressed/<n>.md` scope-regression marker carrying the recorded and current resolver versions, and halts the change. Review each marker and run `osq retry <id> <task>` to recertify that task explicitly; a passing verification refreshes the marker with resolver-2 hashes. Markers inside `openspec/changes/archive/` are not rewritten or audited by this migration.
26
32
 
27
33
  ## What it puts in your repo
@@ -41,7 +47,7 @@ openspec/
41
47
  specs/ living capability specifications (e.g. cli-foundation/spec.md)
42
48
  changes/
43
49
  042-order-cancellation/
44
- proposal.md parent spec: goal, verify, non-goals, contract, human steps, delta
50
+ proposal.md parent spec: goal, verify, non-goals, surface, decisions, contract, human steps, delta
45
51
  plan-prompt.md the planning prompt `osq plan` writes; removed at archive
46
52
  tasks.md task checklist, ticked by the watcher
47
53
  tasks/1.md unit of work: acceptance, verify, scope, entry, tests.modify, verify_starts
@@ -73,13 +79,14 @@ Smart models author specs and never execute them. Cheap models execute specs and
73
79
  ## Gates and permissions
74
80
 
75
81
  - **Approval gate.** Nothing runs until a human runs `osq approve`. It lints the change, hashes the folder, and writes `.run/approved` plus `.run/manifest.json`.
76
- - **Approval digest.** Before sealing, `osq approve` prints a short digest: the goal, one line per task with its resolved-scope file count, and the requirements each delta adds, modifies, or removes. It then flags six things worth a human look: `shared_file` (a path two tasks share), `sensitive_path` (a package manifest, lockfile, CI workflow, osq or OpenSpec config, managed instruction file, or env file in scope), `verify_without_test` (a verify naming no test file or runner), `removed_requirement` (a delta that removes requirements), `unknown_capability` (a delta for a capability with no living spec that either has no `## Purpose` or has a name resembling a living capability, and the label names which; a deliberate new capability instead prints `(new capability)` on its digest heading), and `verify_starts_conflict` (a task that declares `green` or `any` while its verify names a missing test its own scope creates). Flags never block by default: they print last, as information, and the approval line names them (`Approved <id> with N flags: ...`). Add `--confirm` to stop and ask about them instead.
82
+ - **Approval digest.** Before sealing, `osq approve` prints a short digest: the goal, one line per task with its resolved-scope file count, and the requirements each delta adds, modifies, or removes. It then flags eight things worth a human look: `shared_file` (a path two tasks share), `sensitive_path` (a package manifest, lockfile, CI workflow, osq or OpenSpec config, managed instruction file, or env file in scope), `verify_without_test` (a verify naming no test file or runner), `removed_requirement` (a delta that removes requirements), `unknown_capability` (a delta for a capability with no living spec that either has no `## Purpose` or has a name resembling a living capability, and the label names which; a deliberate new capability instead prints `(new capability)` on its digest heading), `verify_starts_conflict` (a task that declares `green` or `any` while its verify names a missing test its own scope creates), `adr_departure` (a `Departs from ADR <n>:` line in `## Decisions`), and `adr_check_modified` (a task that may change an ADR's check file; see Architecture decisions). Flags never block by default: they print last, as information, and the approval line names them (`Approved <id> with N flags: ...`). Add `--confirm` to stop and ask about them instead.
77
83
  - **Verification gate.** The watcher never trusts the agent's claim. It runs each task's `verify` in its own process after the agent exits and writes `.run/done/<n>` only on exit 0; a non-zero exit becomes `.run/dead/<n>.md`.
78
84
  - **Change verification after every task.** When the task's `verify` passes, the watcher also runs the proposal's change-level `verify` (`gates.changeVerifyAfterTask`, on by default). A red result kills the task with `change_verify_red`, so every task must leave the whole change green.
85
+ - **Baseline verify.** When `gates.baselineVerify` names a command, the watcher runs it once in the project root before a change's first task spawns, to prove the tree was green before the change started. A non-zero exit kills the first task with `baseline_red` and prints "tree was red before this change started"; no agent spawns and the reason waits for `osq retry`. Under git, when HEAD and every dirty file outside a `.run/` folder are unchanged since the latest green baseline in any active or archived change, the watcher reuses it and records `baseline_ran` with `outcome: reused` instead of running the command; outside git, or with no commit, the command always runs.
79
86
  - **Pre-spawn verify check.** Before a task's first attempt, the watcher runs that task's `verify` once and expects it to fail: a verify already green before any agent work means the work is done or the verify does not exercise the task. A task declares its expected start with `verify_starts` — `red` by default, `green` for work like a refactor that should already pass, or `any` when either is fine. A mismatch warns by default and the task continues; `gates.preSpawnVerify: fail` kills the task with `verify_precondition` before the agent spawns, and `off` disables the check. A mismatch shows in the task's `verify_ran` event, `osq show`, and `osq report`. A named path the verify refers to that does not exist yet is recorded as `missingPaths` on that event and does not count as a mismatch for a `red` task. The check adds one extra verify per task, on its first attempt only.
80
- - **Automatic retry.** When a task dies for a reason a fresh attempt could fix — `verify_red`, `change_verify_red`, `undeclared_test_change`, `verify_path_missing`, `no_result`, `crashed`, or `timeout` — the watcher retries it without asking. Every other reason (`spec_conflict`, `verify_precondition`, `already_running`) waits for you. `gates.autoRetries` caps how many automatic retries a task gets since its approval or its last manual retry; it defaults to 1, `0` turns automatic retries off entirely, and a manual `osq retry` grants one more. Each retry's prompt carries the previous dead marker's body, so the fresh agent sees exactly what failed.
87
+ - **Automatic retry.** When a task dies for a reason a fresh attempt could fix — `verify_red`, `change_verify_red`, `undeclared_test_change`, `verify_path_missing`, `denied_dependency`, `no_result`, `crashed`, or `timeout` — the watcher retries it without asking. Every other reason (`spec_conflict`, `verify_precondition`, `already_running`, `blocked`, `baseline_red`) waits for you. `gates.autoRetries` caps how many automatic retries a task gets since its approval or its last manual retry; it defaults to 1, `0` turns automatic retries off entirely, and a manual `osq retry` grants one more. Each retry's prompt carries the previous dead marker's body, so the fresh agent sees exactly what failed.
81
88
  - **Stuck tasks.** Every dead marker records a `fingerprint` over its reason and body, ignoring details a rerun changes: ISO timestamps, durations, PIDs, ANSI codes, and absolute paths under the project root. When a task dies again with the same fingerprint as its most recent retained death, the watcher stops retrying and marks it stuck — `stuck: true` on the active marker, one `stuck` event, one line. The inbox shows the task as stuck and `osq --json` gives its `task-dead` item a `stuck` field carrying the fingerprint; `osq retry <id> <n>` still retries it after you fix the cause.
82
- - **Scope recertification.** Before each task and again before archiving, the watcher re-hashes the resolved `scope` of every done task. If a later task changed any of those files, it re-runs that task's `verify`, writes `.run/regressed/<n>.md`, and halts the change until you run `osq retry <id> <n>`.
89
+ - **Scope recertification.** Before each task and again before archiving, the watcher re-hashes the resolved `scope` of every done task. When a later task whose `scope` covers a changed file changed it, the recorded hashes show nothing else did, and the task's `verify` still passes, the watcher recertifies that task by itself. Every other change halts the change until you run `osq retry <id> <n>`.
83
90
  - **Archive verification.** Before archiving, the watcher re-runs every task's `verify` and the change-level `verify` against the final tree, halting with `.run/regressed/<n>.md` (or `.run/regressed/change.md`) if any fails.
84
91
  - **State from disk.** The only authoritative state is which marker files exist under `.run/`: `running/<n>.pid`, `done/<n>`, `dead/<n>.md`, `regressed/<n>.md`, and `approved`. There is no in-memory state that matters, so the watcher can be killed and restarted at any time.
85
92
  - **Executor permissions.** A coding agent may write only `.run/results/<n>.md` and files inside its task's `scope`. It may not edit living capability specs, `tasks.md`, or marker files. The watcher writes markers and checkboxes automatically; a human writes the rest through `osq approve`, `osq retry`, `osq reject`, and `osq done`.
@@ -101,12 +108,17 @@ features:
101
108
  ## Verify
102
109
  ## Non-goals
103
110
  ## Surface
111
+ ## Decisions
104
112
  ## Contract
105
113
  ## Human steps
114
+ ### Before approval
115
+ ### After landing
106
116
  ## Delta
107
117
  ```
108
118
 
109
- The frontmatter `verify` is the change-level command the watcher runs after every task and before archiving. Capability writes are not declared in frontmatter: the set of delta specs under `specs/<capability>/spec.md` is the authoritative declaration of what the change writes.
119
+ The frontmatter `verify` is the change-level command the watcher runs after every task and before archiving. An optional `fixes` list names the changes this one reworks; lint fails on an id that names no active, archived, or rejected change, and `fixes` never affects execution order. Capability writes are not declared in frontmatter: the set of delta specs under `specs/<capability>/spec.md` is the authoritative declaration of what the change writes.
120
+
121
+ `## Human steps` holds what osq cannot do. Steps under `### Before approval` show in the approval digest and on the inbox's approval item. Steps under `### After landing`, or a `check: <command>` in the frontmatter, leave the change **verification pending** once it archives: changes that depend on it wait until you run `osq check <id>` (for a `check` command) and record the outcome with `osq verified <id> --passed` or `--failed`. `osq status`, `osq show`, and the inbox list pending changes with their next command. Write `None` under a heading with no steps.
110
122
 
111
123
  `## Surface` lists the user-facing names the change adds, changes, or removes — commands, flags, config keys, frontmatter fields, document sections, dead reasons, and event types; a change with none of those writes `None`.
112
124
 
@@ -146,7 +158,9 @@ skills: []
146
158
 
147
159
  Tasks run in order. The agent reads its task, the parent `proposal.md`, the delta specs and capability docs it names, `AGENTS.md`, and a previous result file for that task if there is one. The runner also injects capability-specific constraints and code ownership rules extracted from living capability specs. The delta is applied by the watcher, so the agent never edits living specs under `openspec/specs/`.
148
160
 
149
- Lint, run by `osq approve` and `osq lint`. Limits come from `osq.config.ts`; defaults are shown.
161
+ Before exiting, the agent writes `.run/results/<n>.md` with these headings, leaving out any that would be empty: `## Changed`, `## Deviated` (for the reviewer), `## Missing context` (for the planner), `## Outside scope` (for the human), `## Blocked`, and `## Next`, ending with a `Touched: <paths>` line. A task that cannot finish within its scope writes what it needs under `## Blocked` and no code; the watcher records it dead with reason `blocked`, never retries it automatically, and the inbox shows the stated need. `osq show` prints each task's disclosures, and the plan prompt quotes those from recent archived changes, bounded by `planning.disclosures.recentChanges` (default 3) and `planning.disclosures.maxCharacters` (default 4000).
162
+
163
+ Lint, run by `osq approve` and `osq lint`. Limits come from `osq.config.ts`; defaults are shown. `osq lint` prints each finding as `<change>: <severity> <file> (<requirement or section>): <message>`, with repository-wide findings in their own group at the end, and `osq lint --json` prints them as JSON.
150
164
 
151
165
  | Check | Result |
152
166
  | --- | --- |
@@ -154,6 +168,7 @@ Lint, run by `osq approve` and `osq lint`. Limits come from `osq.config.ts`; def
154
168
  | proposal declares `features.writes` | reject |
155
169
  | more than one table under `## Contract` | reject |
156
170
  | `depends_on` names a missing change | reject |
171
+ | `fixes` names a missing change | reject |
157
172
  | task `scope` has more than 8 patterns (`limits.maxScopeFiles`) | reject |
158
173
  | task acceptance longer than 7 lines (`limits.maxAcceptanceLines`), or two lines fused into one | reject |
159
174
  | task scope names a preexisting test without `tests.modify: true` | reject |
@@ -162,14 +177,140 @@ Lint, run by `osq approve` and `osq lint`. Limits come from `osq.config.ts`; def
162
177
  | `verify` names an absent package script | reject |
163
178
  | `verify` names no existing path or package script | warn |
164
179
  | a delta targets a requirement the living spec lacks, or is written as an instruction | reject |
180
+ | a project with ADRs has no usable `## Decisions` section (`None` with no governing ADR passes) | reject |
181
+ | `## Decisions` omits an accepted ADR that governs a capability the change writes | reject |
182
+ | the AGENTS.md project rules block is stale or exceeds `limits.maxProjectRules` | reject |
183
+ | `## Decisions` names an ADR that does not exist or is not accepted | warn |
165
184
  | a file contains a prohibited control character | reject |
166
185
  | OpenSpec schema or validator drift | reject |
167
186
  | two tasks resolve the same scope file | warn |
187
+ | a task scope reaches a preexisting test no task may modify (`limits.importGraphDepth`) | warn |
188
+ | a scoped file imports code owned by a capability the proposal neither reads nor has a delta for | warn |
189
+ | a scoped file is owned by a capability with no delta in the change | warn |
190
+ | a task `verify` runs only tests that import nothing in the task's scope | warn |
168
191
 
169
192
  `osq init` and `osq new` seed `verify: node -e "process.exit(0)"`. That is a planning sentinel, not trusted coverage: replace it before approval with a command that verifies the completed change's final tree. Checked-in fixtures use a local `node verify.cjs` verifier backed by files in their own execution root, never the sentinel, the network, a TTY, or this repository's full verification suite.
170
193
 
171
194
  The rules lint can't check live in the managed `PLANNER.md` block: titles read "When X, Y"; every task leaves the change green on its own; a file belongs to one task; approve the task list before writing any task in full.
172
195
 
196
+ ### Architecture decisions
197
+
198
+ Architecture decision records live under `paths.decisions` (default `decisions/`). A markdown file there is an ADR when its YAML frontmatter carries `status` (`proposed`, `accepted`, or `superseded`); its number is the leading digits of the file name, its title the first `# ` heading without that number prefix. Only accepted ADRs take effect. An accepted ADR states `applies_to`, either `all` or a list of capability names, and a one-line `rule`; a superseded ADR states `superseded_by`. `limits.maxRuleLength` (default 160) caps a rule's length. A file without frontmatter is ignored and reported.
199
+
200
+ `osq init` writes the rules block for every accepted system-wide ADR into `AGENTS.md` between `<!-- OSQ:RULES:START -->` and `<!-- OSQ:RULES:END -->`: a `## Project rules` heading and one `- <rule> ADR <number>` line per ADR, in number order. `limits.maxProjectRules` (default 10) caps how many lines the block may hold. The `decisions` check in `osq doctor` validates every ADR, fails on a stale or oversized rules block, and warns about ignored files and capability names with no living spec.
201
+
202
+ When the project has any ADR with osq frontmatter, every proposal needs a `## Decisions` section after `## Surface`. Name each accepted ADR that governs a capability the change writes, or write `None` when none does. A departure line begins `Departs from ADR <n>:` and gives the reason. `osq lint` and `osq approve` reject a missing or empty section, reject an unnamed governing ADR, and fail while the AGENTS.md rules block is out of date.
203
+
204
+ An accepted ADR may also name `checks`, the repository-relative test files that enforce it, and `denies`, the package names it forbids. A check path is trimmed, uses forward slashes, and drops a leading `./`; only accepted ADRs' checks and denials take effect. The `decisions` doctor check fails when an accepted ADR names a check file that does not exist. When a task declares `tests.modify: true` and its resolved scope covers an accepted ADR's check file, approval raises one `adr_check_modified` flag labelled `task <n> may modify a check of ADR <number>`, and `osq report` counts it in `approvalFlags.byFlag`.
205
+
206
+ After an agent exits, the watcher compares each scoped `package.json` against the baseline recorded on the attempt's `measures` start event. A new package appends one `dependencies_added` event; if an accepted ADR denies it, the task dies with `denied_dependency`, eligible for one automatic retry, and the marker names each package, file, ADR, and rule. `osq show` prints a `Dependencies added: <name> (<file>), ...` line under such a task, and `osq report` prints a `Dependencies added:` section with one `<change>: <name> (<file>), ...` line per change that added packages.
207
+
208
+ ### Traceability
209
+
210
+ Opt a capability in through the `traceability` block in `osq.config.ts`:
211
+
212
+ ```ts
213
+ export default defineConfig({
214
+ traceability: {
215
+ capabilities: ['pricing'], // or 'all'
216
+ mode: 'warn', // or 'require'
217
+ focusedTests: 'node --test --test-reporter=tap {files}', // optional
218
+ },
219
+ });
220
+ ```
221
+
222
+ The resolved config always holds `traceability`, defaulting to `{ capabilities: [], mode: 'warn' }`. With no capability opted in, `osq init`, `osq lint`, `osq report`, and both managed blocks are exactly what they were, and a project that never imports the helper sees no change.
223
+
224
+ When at least one capability is opted in, `osq init` writes a `<!-- OSQ:TRACEABILITY:START -->` … `<!-- OSQ:TRACEABILITY:END -->` block directly after the managed block in `AGENTS.md` and `PLANNER.md`. Its scope is `every capability` for `'all'`, otherwise the opted-in names joined by `, `. Removing the opt-in removes the block and restores both files.
225
+
226
+ A test proves a scenario by importing from `@matteeh/osq/testing`:
227
+
228
+ ```ts
229
+ import { scenario } from '@matteeh/osq/testing';
230
+
231
+ scenario('pricing', 'Volume pricing', { covers: quote }, ({ run, then, each }) => {
232
+ then('the subtotal is 1800.00', () => assert.equal(run(100).subtotal, 1800));
233
+ each('the unit price follows this table', (row) => assert.equal(quote(+row.quantity).unit, +row['unit price']));
234
+ });
235
+ ```
236
+
237
+ `scenario(capability, name, { covers }, body)` registers one `node:test` test titled `Scenario: <name>`. It fails unless the covered function ran through `run`, every outcome was asserted by a `then` or `each` that completed, and every table row passed. `run` takes the covered function's parameters and returns its result, `then(outcome, check)` asserts one outcome, and `each(outcome, check)` calls the check once per table row, in order, with the row as an object keyed by the header cells. The helper's failure messages are exact: a missing name is `"<text>" is not a THEN of this scenario`; a `then` on a table is `THEN <text>: has a table, so check it with each`; an `each` on a non-table is `THEN <text>: has no table`; a failed check is `THEN <text>: failed` or `THEN <text>: failed at <column> <value>, ...`; a check before the function ran or settled is `THEN <text>: checked before <fn> ran` or `THEN <text>: checked before <fn> settled`; a body that never called `run` is `<fn> never ran`; and a missing assertion is `No assertion for: <text>; <text>`. A lookup failure is reported unchanged.
238
+
239
+ A scenario with more than one case puts a Markdown table directly under its THEN or AND line, with only blank lines between:
240
+
241
+ ```
242
+ - **THEN** the unit price follows this table
243
+
244
+ | quantity | unit price |
245
+ | -------- | ---------- |
246
+ | 100 | 9.00 |
247
+ | 500 | 8.00 |
248
+ ```
249
+
250
+ The first row names the columns, the dashes row is skipped, and later rows are keyed by the trimmed header cells with trimmed string values. Lint accepts a table under a THEN or AND line in a delta and in a living spec.
251
+
252
+ Lint reads tags only from a `/** ... */` doc comment directly above `export function`/`export async function`, or `export const <name>` bound to an arrow or function expression. A `@scenario <capability>: <scenario name>` line names a scenario the function serves; `@adr <number>` names a decision it follows. A file is a scenario test file when it imports from `@matteeh/osq/testing`, and its `scenario(` calls are read when capability and name are string literals and the third argument is `{ covers: <identifier> }`; anything else is reported as unreadable as `<file>:<line>: <reason>`.
253
+
254
+ A task lists the scenarios its tests prove under `## Scenarios`, one `- <capability>: <scenario name>` bullet each. A listed scenario counts as planned while the task's resolved scope holds a test path, so lint passes before the test exists; once a scoped test names it, only real `scenario(...)` calls count.
255
+
256
+ The watcher sets `OSQ_CHANGE` to the absolute change folder for every verify, so the helper resolves scenarios from the change's delta while it is still active. `osq check` on an archived change runs without it, because its deltas are already in the living spec.
257
+
258
+ For an opted-in capability, `osq lint` reports each scenario an ADDED or MODIFIED requirement holds that no scoped test names and that is not planned (`<capability>: no test names scenario "<name>"`), a `@scenario` tag naming a missing scenario (`<fn>: names a scenario the <capability> spec doesn't have: "<name>"`) or one no test covers (`<fn>: no test for "<name>" covers it`), a bad `@adr` tag (`<fn>: ADR <n> doesn't exist or isn't accepted`, `<fn>: ADR <n> doesn't apply to any capability it serves`), and a duplicate scenario name (`<capability>: two scenarios named "<name>"`). For every capability it also lists the tests naming a scenario a MODIFIED or REMOVED requirement changes and warns `<file> names changed scenario "<name>" but no task scopes it with tests.modify: true`. Every finding is a warning under `mode: 'warn'` and an error under `mode: 'require'`.
259
+
260
+ When a capability is opted in, `osq report` prints a `Traceability:` section with `<capability>: <n> untested scenarios, <m> unclaimed functions` and ` untested: <name>` / ` unclaimed: <file>#<name>` lines, also carried in JSON under `traceability`. `osq show` prints ` Scenarios: <capability>: <name>; ...` under a task whose scoped tests name scenarios.
261
+
262
+ Set the optional `traceability.focusedTests` to a command containing `{files}`, such as the reference `node --test --test-reporter=tap {files}`, to run a task's scenario tests before its full verify. When a task's resolved scope holds scenario test files naming opted-in scenarios, the watcher replaces `{files}` with every scenario test file in the repository that names one of those scenarios, each single-quoted and separated by spaces, and runs it through the verify's environment, `OSQ_CHANGE` included. The outcome is `passed` when the command succeeds, `failed` when the TAP output has a `not ok` line for a collected `Scenario: <name>`, and `problem` when it exits nonzero, times out, or cannot start and isn't `failed`. Only a `failed` outcome ends the attempt: the task dies with `verify_red` and its verify is skipped, so the next attempt receives the focused output; a `problem` or `passed` outcome goes on to the full verify, which alone decides the task. Each run appends one `focused_ran` event carrying the command, files, scenarios, outcome, exit code, duration, timeout state, and output. `osq show` prints ` Focused runs: <outcome> <duration>s, ...` under the task after its `Scenarios:` line, adding ` (attempt ended, verify skipped)` to each `failed` entry.
263
+
264
+ ### Mutation checks
265
+
266
+ Set the optional `traceability.mutation` block to the project's mutation command
267
+ and an optional per-task budget in seconds (default `300`):
268
+
269
+ ```ts
270
+ export default defineConfig({
271
+ traceability: {
272
+ capabilities: ['pricing'], // or 'all'
273
+ mode: 'warn',
274
+ mutation: {
275
+ command: 'npx stryker run', // or a command using {mutate}, {tests}, {report}
276
+ budgetSeconds: 300, // optional
277
+ },
278
+ },
279
+ });
280
+ ```
281
+
282
+ After a task passes, osq picks the covered functions the task changed or newly tested. A covered function is an exported function carrying a `@scenario` tag naming an opted-in capability whose tagged scenario a scenario test file names. A function is picked when its file is in the task's resolved scope and its own range's hash differs from the task's last start `measures` event's `functionHashes` entry (a missing entry counts as different), or when a scenario test file the task changed covers it.
283
+
284
+ Each run gets that function's own range plus the range of every non-exported top-level function in the same file it calls, sorted by start line as `<file>:<start>-<end>`, and the sorted, distinct scenario test files naming its tagged scenarios. The command is run once per pick through the verify's environment, `OSQ_CHANGE` included, and receives:
285
+
286
+ - `{mutate}` and `OSQ_MUTATE`: the ranges, comma-joined for the placeholder and a JSON array for the variable
287
+ - `{tests}` and `OSQ_MUTATION_TESTS`: the tests, single-quoted and space-separated for the placeholder and a JSON array for the variable
288
+ - `{report}` and `OSQ_MUTATION_REPORT`: an absolute path in a fresh temporary folder, single-quoted for the placeholder
289
+
290
+ Each run's timeout is the budget left, and picks left once `budgetSeconds` of total wall time for the task is spent are not run. Each pick appends one `mutation_ran` event to the task's stream with `file`, `function`, `ranges`, `scenarios`, `tests`, `outcome`, `killed`, `survived`, `invalid`, `survivors`, `duration`, and `exitCode`. When a pick can't be measured the event says why: `range_unknown` (unknown ranges), `budget`, `timed_out`, `command_failed`, or `report_invalid`; a failed or timed-out run also carries the command's last 2,000 output characters. The check is observe only: it never fails, retries, or halts a task.
291
+
292
+ `osq show` prints, under a task whose stream holds `mutation_ran` events after its last `measures` start event, ` Mutation: <entry>; <entry>` with one entry per event in stream order. A measured entry is `<file>#<function> <killed> of <killed + survived> killed`, a not-measured one is `<file>#<function> not measured (<reason>)`, and each survivor adds a ` Survived: <file>:<line>:<column> <mutator> -> <replacement>` line. When a capability is opted in, `osq report` prints a `Mutation:` section with ` <capability>: <killed> of <killed + survived> killed (<percent>%), <n> survivors not yet reviewed`, the percent to one decimal, then a ` survived: ...` line per survivor, also carried under `mutation` in JSON. Every listed survivor counts as not yet reviewed.
293
+
294
+ The reference setup uses StrykerJS with its command test runner. Add `@stryker-mutator/core` as a dev dependency of the project, set `traceability.mutation.command` to `npx stryker run`, and add this `stryker.config.mjs`:
295
+
296
+ ```js
297
+ const tests = JSON.parse(process.env.OSQ_MUTATION_TESTS ?? '[]')
298
+ .map((file) => `'build/${file.replace(/\.(m|c)?ts$/, (_, k) => `.${k ?? ''}js`)}'`)
299
+ .join(' ');
300
+ export default {
301
+ testRunner: 'command',
302
+ commandRunner: { command: `node --test ${tests}` },
303
+ buildCommand: 'npx tsc',
304
+ mutate: JSON.parse(process.env.OSQ_MUTATE ?? '[]'),
305
+ coverageAnalysis: 'off',
306
+ reporters: ['json'],
307
+ jsonReporter: { fileName: process.env.OSQ_MUTATION_REPORT },
308
+ tempDirName: '.stryker-tmp',
309
+ };
310
+ ```
311
+
312
+ The config assumes `tsc` compiles `tests/` to `build/tests/`; follow the project's own layout if it differs. Leave `thresholds.break` unset so survivors never change the command's exit code, and add `.stryker-tmp` to `.gitignore`.
313
+
173
314
  ## What the watcher guarantees
174
315
 
175
316
  - **Rebuilt from disk**: State is rebuilt from `openspec/` on every change. Kill it and restart it any time.
@@ -182,17 +323,40 @@ The rules lint can't check live in the managed `PLANNER.md` block: titles read "
182
323
  - **Deterministic spec merges**: Capability specs are only ever changed by the watcher applying an approved delta merge (ADR 002). Agents never touch `openspec/specs/`.
183
324
  - **Synthesized results**: An agent that exits without writing `.run/results/<n>.md` is not lost: if the adapter captured a final text message, the watcher synthesizes a result file (`synthesized: true`) from it and proceeds to verify. Only an exit with neither a result file nor final text is `dead` with `reason: no_result`. Nothing disappears silently.
184
325
 
185
- Dead reasons: `verify_red` (with `timed_out: true` if verify exceeded its timeout), `change_verify_red`, `verify_precondition`, `undeclared_test_change`, `verify_path_missing` (a path the task's `verify` names did not exist after the agent exited), `no_result`, `crashed`, `timeout`, `spec_conflict`, and `already_running`. A done task whose scoped files changed afterwards is recorded under `.run/regressed/<n>.md` with `reason: scope_regression`, and a failed archive-time change verify under `.run/regressed/change.md`; either stops the run before the next task spawns. Every dead marker also carries a `fingerprint` of its reason and body, and a marker the watcher stopped retrying carries `stuck: true`.
326
+ Dead reasons: `verify_red` (with `timed_out: true` if verify exceeded its timeout), `change_verify_red`, `verify_precondition`, `baseline_red` (the configured baseline verify failed before the change's first task), `undeclared_test_change`, `verify_path_missing` (a path the task's `verify` names did not exist after the agent exited), `denied_dependency` (a scoped `package.json` gained a package an accepted ADR denies; retried automatically once), `blocked` (the agent wrote `## Blocked` in its result; never retried automatically), `no_result`, `crashed`, `timeout`, `spec_conflict`, and `already_running`. A done task whose scoped files changed afterwards is recorded under `.run/regressed/<n>.md` with `reason: scope_regression`, and a failed archive-time change verify under `.run/regressed/change.md`; either stops the run before the next task spawns. Every dead marker also carries a `fingerprint` of its reason and body, and a marker the watcher stopped retrying carries `stuck: true`.
327
+
328
+ ## Version control
329
+
330
+ osq reads git when it is available: `osq doctor` reports it, baseline reuse compares HEAD, and the watcher records `scope_violation` and `vcs_violation` events. Agents never run git. osq makes no git writes unless `vcs.enabled` is true, and in this release that support is **unfinished**. Leave it off.
331
+
332
+ ```ts
333
+ export default defineConfig({
334
+ vcs: {
335
+ enabled: false, // default; no git writes
336
+ author: 'osq <osq@example.com>', // required when enabled
337
+ // defaultBranch: 'main', // approval's base branch when origin has no HEAD; default main
338
+ // worktreeRoot: '~/.osq/worktrees',
339
+ // prepare: 'pnpm install', // run once in each new worktree
340
+ },
341
+ timeouts: {
342
+ gitSeconds: 10, // each git read
343
+ gitCommitSeconds: 120, // each commit
344
+ },
345
+ });
346
+ ```
347
+
348
+ With `vcs.enabled`, `osq approve` creates branch `osq/<folder>` and a linked worktree under `vcs.worktreeRoot`, runs `vcs.prepare` there, writes the seal plus `.run/base` and `.run/approver` into the worktree's copy, commits `osq: <id> approved`, and prints `Worktree:` and `Branch:` lines. Your checkout is left untouched, and `osq status` warns when the checkout's copy of the change is edited afterwards. The watcher does not yet run changes in their worktrees, so a change approved this way does not run.
186
349
 
187
350
  ## Harnesses
188
351
 
189
- `OSQ_HARNESS` picks an adapter. An adapter does two things: spawn an agent for a tier (`coding` or `smart`) and write its harness's config files (`osq setup`). Adapters translate the harness's own event stream into typed events (`started`, `tokens`, `tool`, `text`, `file_changed`, `result_written`, `exited`), and the watcher appends its own (`measures`, `verify_ran`, `done`, `done_manual`, `dead`, `regressed`, `retry`, `recertification`, `rejected`), all to the task's `.run/events/<n>.jsonl`. Hooks are optional shims that append to the same file. The loop works without them.
352
+ `OSQ_HARNESS` picks an adapter. An adapter does two things: spawn an agent for a tier (`coding` or `smart`) and write its harness's config files (`osq setup`). Adapters translate the harness's own event stream into typed events (`started`, `tokens`, `tool`, `text`, `file_changed`, `result_written`, `exited`), and the watcher appends its own, among them `measures`, `verify_ran`, `baseline_ran`, `focused_ran`, `mutation_ran`, `dependencies_added`, `done`, `done_manual`, `dead`, `stuck`, `regressed`, `retry`, `recertification`, and `rejected`, to the task's `.run/events/<n>.jsonl`. Change-level events such as `archived`, `check_ran`, and `verification_recorded` go to `.run/events/change.jsonl`. Hooks are optional shims that append to the same file. The loop works without them.
190
353
 
191
354
  Available adapters:
192
355
 
193
356
  - `agy`: Antigravity harness adapter
357
+ - `claude`: Claude Code harness adapter running fresh headless `claude -p` tasks
194
358
  - `codex`: Codex CLI harness adapter running tasks via `codex exec` and planning via the Codex TUI
195
- - `opencode`: OpenCode harness adapter running tasks via `opencode run`
359
+ - `opencode`: OpenCode harness adapter running tasks via `opencode run` (requires opencode 2)
196
360
  - `pi`: Pi coding agent harness adapter running fresh one-shot tasks in JSON mode
197
361
  - `mock`: In-memory deterministic simulation for tests
198
362
 
@@ -207,11 +371,13 @@ export default defineConfig({
207
371
  bin: 'opencode',
208
372
  model: 'deepseek/deepseek-flash',
209
373
  agent: 'osq-coder',
210
- variant: 'thinking', // optional
374
+ variant: 'thinking', // optional; passed as <model>#<variant>
211
375
  },
212
376
  });
213
377
  ```
214
378
 
379
+ The adapter needs opencode 2; `osq doctor` reports a failing `harness-version` check for opencode 1 and a warning above the tested range. Tasks run with `opencode run --standalone` from the project root, and a configured `variant` is appended to the model as `<model>#<variant>`.
380
+
215
381
  Running `osq setup` with the `opencode` harness scaffolds `.opencode/agent/osq-coder.md` with restricted permissions (denying `webfetch` and `websearch`) and the managed `AGENTS.md` execution procedure. Note that the `--auto` flag approves any action the agent file does not deny. The agent file must have mode `all` or `primary`; a subagent cannot be selected with --agent and OpenCode silently falls back to an unrestricted default. `webfetch` and `websearch` are denied at the tool level, but `bash` is allowed and unrestricted, so the agent can reach the network through the shell. Network isolation requires a sandbox, which osq does not provide.
216
382
 
217
383
  ### Codex CLI
@@ -306,6 +472,46 @@ As with every harness, scope is a protocol, not confinement: the prompt and the
306
472
 
307
473
  Pi cannot plan: the adapter has no interactive session, so `osq plan --session` with Pi selected as the planner stops with the existing "does not support interactive sessions" error, and `planner.agent` is unsupported for Pi and rejected by configuration validation.
308
474
 
475
+ ### Claude Code
476
+
477
+ Select Claude Code as the executor in `osq.config.ts`:
478
+
479
+ ```ts
480
+ import { defineConfig } from '@matteeh/osq';
481
+
482
+ export default defineConfig({
483
+ harness: 'claude',
484
+ claude: {
485
+ // All fields are optional; omit any to use Claude Code's native value.
486
+ // bin: '/path/to/claude', // claude.bin -> `claude`
487
+ // model: '<your-model>', // claude.model -> OSQ_MODEL (Claude executor only) -> native
488
+ // sandbox: true, // confine Bash with Claude Code's OS sandbox (needs bubblewrap and socat)
489
+ },
490
+ });
491
+ ```
492
+
493
+ Setting `OSQ_HARNESS=claude` in the environment or `.env` also selects Claude Code, but an explicit `harness` in `osq.config.ts` wins over that fallback. Binary precedence is `claude.bin`, then `claude` on `PATH`. Model precedence is `claude.model`, then `OSQ_MODEL` only when Claude Code is the executor, then Claude Code's native default; with no model configured, osq records `default` rather than guessing one. This release requires Claude Code `2.1.278` or newer, the version every flag below was verified on; `osq doctor`'s `harness-version` check and the watcher's preflight both fail under it.
494
+
495
+ Each task is a fresh `claude -p --output-format stream-json --verbose` process in the project root with stdin closed and `--no-session-persistence`, so there is no session to resume.
496
+
497
+ #### Claude Code setup and prerequisites
498
+
499
+ Install the Claude Code CLI and log in as usual: by default osq reuses your Claude Code login. When `ANTHROPIC_API_KEY` is set to a non-empty value, osq adds `--bare` and uses the key instead; `--bare` never reads your login, which is why it is tied to the key. The `started` event records which one ran through `harnessAuth`: `api_key` with a key and `login` otherwise.
500
+
501
+ `osq setup` writes no Claude Code files for execution; it only maintains the shared managed `AGENTS.md` block. Planning with Claude Code uses the tool-native `/osq-plan` command that `osq init` installs, not this adapter.
502
+
503
+ #### Claude Code stripped tool surface
504
+
505
+ Each task loads only six built-in tools: `Bash`, `Read`, `Edit`, `Write`, `Glob`, and `Grep`. osq passes `--tools Bash,Read,Edit,Write,Glob,Grep`, `--strict-mcp-config` with no `--mcp-config`, `--disable-slash-commands`, `--setting-sources ""`, `--no-session-persistence`, and `--settings '{"autoMemoryEnabled":false}'`. That strips MCP servers, skills, plugins, hooks, user, project and local settings, saved sessions, and auto-memory so the agent pays no tokens for harness features a coding task never uses: measured on a one-line prompt, input fell from about 29,500 to about 13,300 tokens per request. No configuration key re-enables any of them.
506
+
507
+ #### Claude Code permissions
508
+
509
+ Executor tasks run with `--permission-mode dontAsk`, so anything not allowed is denied rather than prompting. `Read`, `Glob`, and `Grep` are allowed; `Edit` and `Write` are confined to the project through `Edit(./**)` and `Write(./**)`; `Bash` is allowed but `git` is denied by `Bash(git:*)`, which still denies `git` inside compound commands such as `echo a && git status`.
510
+
511
+ Without `claude.sandbox`, Bash is not confined: a shell command can still write outside the project or reach the network. Set `claude.sandbox: true` to add Claude Code's Bash sandbox with no network. It fails at startup if the sandbox is unavailable instead of running unconfined, and on Linux and WSL2 it needs the OS packages `bubblewrap` and `socat` (`apt install bubblewrap socat`).
512
+
513
+ As with every harness, scope is a protocol, not confinement beyond what the harness itself enforces.
514
+
309
515
  ## Commands
310
516
 
311
517
  ```
@@ -317,11 +523,13 @@ osq setup write harness config for OSQ_HARNESS
317
523
  osq new <name> new change folder from template in openspec/changes/
318
524
  osq plan [name] create a change, write plan-prompt.md, and hand off to your planning tool
319
525
  osq queue print the read-only brief queue from openspec/queue.md
320
- osq lint [ids...] validate change folders and OpenSpec artifacts against constraints
526
+ osq lint [ids...] validate change folders and OpenSpec artifacts against constraints (--json for JSON)
321
527
  osq approve <ids...> lint, print the digest, approve change; write .run/approved and .run/manifest.json
322
528
  osq retry <id> <target> retry a dead or regressed task, or a change-level regression
323
529
  osq reject <id> move an unapproved or failed change intact into rejected history
324
530
  osq done <id> <task> mark a task done manually with required justification (--manual)
531
+ osq check <id> run an archived change's recorded check command
532
+ osq verified <id> record an after-landing outcome (--passed or --failed, optional --note <text>)
325
533
  osq watch run the watcher loop
326
534
  osq status overview of all changes, tasks, and runtime states
327
535
  osq show <id> change details, tasks, results, dead markers, and event timeline (--json for JSON)
@@ -335,14 +543,19 @@ osq migrate openspec migrate a legacy osq layout to the canonical openspec/
335
543
  ### Approval
336
544
 
337
545
  ```sh
338
- osq approve <id> --confirm # show the digest, then ask about any flags before sealing
339
- osq show <id> --json # details, tasks, events, and the digest as JSON
546
+ osq approve <id> --confirm # show the digest, then ask about any flags before sealing
547
+ osq approve <id> --base-ok # approve even when HEAD is not the default branch
548
+ osq approve <id> --ignore-dirty # approve despite uncommitted changes in task scope
549
+ osq show <id> --json # details, tasks, events, and the digest as JSON
340
550
  ```
341
551
 
342
552
  By default `osq approve` prints the digest and its flags, then approves without
343
553
  asking; flags never block. `--confirm` asks only when flags fire, defaults to no,
344
554
  and refuses without a terminal rather than waiting. A declined or refused approval
345
555
  writes nothing, and `--confirm` on a flag-free change approves without a prompt.
556
+ With `vcs.enabled`, approve normally requires HEAD on the default branch and a
557
+ clean checkout in task scope; `--base-ok` and `--ignore-dirty` override those
558
+ two refusals.
346
559
  `osq show <id> --json` prints the same details as JSON, with the digest and flags
347
560
  for an unapproved change and a null digest once it is approved.
348
561
 
@@ -502,7 +715,13 @@ Run `osq doctor` to verify repository health:
502
715
 
503
716
  - `config`: confirms `osq.config.ts` is valid and well-formed
504
717
  - `harness`: checks that the configured harness binary (e.g. `opencode`, `agy`) exists and is executable
505
- - `harness-version`, `harness-auth`: Pi's extra checks (only when Pi is selected) warn on an untested Pi version and, with `pi.provider` set, fail unless `pi auth check` reports `ready`
718
+ - `harness-version`: the installed harness's version. Pi warns outside its tested range; Claude Code fails under `2.1.278`; opencode fails under 2 and warns from 3
719
+ - `harness-auth`: with Pi and `pi.provider` set, fails unless `pi auth check` reports `ready`
720
+ - `harness-containment`: with Claude Code, states what confines the agent's Bash
721
+ - `decisions`: validates every ADR, the AGENTS.md rules block, and each accepted ADR's check files
722
+ - `planning-prices`: warns, only when it applies, that a model with recorded planning tokens has no price in `planning.prices`
723
+ - `git`: git's version, or a warning saying why git is off. `git-env` warns when a variable such as `GIT_DIR` is set
724
+ - `vcs-prepare`, `git-hooks`, `git-signing`: with `vcs.enabled` only, warn about a lockfile without `vcs.prepare`, active commit hooks, and commit signing
506
725
  - `managed-blocks`: verifies the `AGENTS.md`, `PLANNER.md`, and `.claude/commands/osq-plan.md` managed sections match the installed osq version (run `osq init` to repair drift)
507
726
  - `locks`: checks for orphaned `.run/running/*.pid` locks and processes
508
727
  - `archives`: validates integrity of archived change folders
@@ -515,7 +734,7 @@ To release a new version of `osq`:
515
734
 
516
735
  1. Bump `"version"` in `package.json`.
517
736
  2. Add a corresponding release section in `CHANGELOG.md`.
518
- 3. Commit the changes: `git commit -am "release: v<x.y.z>"`.
737
+ 3. Commit the changes: `git commit -am "chore: release <x.y.z>"`.
519
738
  4. Create and push the release tag: `git tag v<x.y.z> && git push --tags`.
520
739
  5. GitHub Actions (`release.yml`) verifies the build and publishes to npm with provenance via trusted publishing.
521
740
 
@@ -1,3 +1,4 @@
1
+ import type { Command } from 'commander';
1
2
  import { type OsqConfig } from '../core/foundation/config.js';
2
3
  import type { PlanningSessionReader } from '../core/report/planning-observed.js';
3
4
  export interface ApproveCommandOptions {
@@ -7,10 +8,16 @@ export interface ApproveCommandOptions {
7
8
  now?: Date | string;
8
9
  /** Block on flagged approvals by asking before the seal is written. */
9
10
  confirm?: boolean;
11
+ /** Approve from a branch other than the default branch. */
12
+ baseOk?: boolean;
13
+ /** Approve despite uncommitted changes covered by a task's scope. */
14
+ ignoreDirty?: boolean;
10
15
  /** Injectable terminal check; defaults to both stdio streams being TTYs. */
11
16
  isTerminal?: () => boolean;
12
17
  /** Injectable prompt; defaults to a `node:readline/promises` question. */
13
18
  ask?: (question: string) => Promise<string | null>;
14
19
  }
15
20
  export declare function approveCommand(specIds: string[], options?: ApproveCommandOptions): Promise<void>;
21
+ /** Register `osq approve` and its approval-only flags. */
22
+ export declare function registerApproveCommand(program: Command): void;
16
23
  //# sourceMappingURL=approve.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"approve.d.ts","sourceRoot":"","sources":["../../src/cli/approve.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,SAAS,EAAc,MAAM,8BAA8B,CAAC;AAE1E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAajF,MAAM,WAAW,qBAAqB;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,eAAe,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACnD,GAAG,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;IACpB,uEAAuE;IACvE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC;IAC3B,0EAA0E;IAC1E,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACpD;AA0BD,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,IAAI,CAAC,CAsDf"}
1
+ {"version":3,"file":"approve.d.ts","sourceRoot":"","sources":["../../src/cli/approve.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,KAAK,SAAS,EAAc,MAAM,8BAA8B,CAAC;AAE1E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qCAAqC,CAAC;AAgBjF,MAAM,WAAW,qBAAqB;IACpC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,SAAS,CAAC;IACnB,eAAe,CAAC,EAAE,SAAS,qBAAqB,EAAE,CAAC;IACnD,GAAG,CAAC,EAAE,IAAI,GAAG,MAAM,CAAC;IACpB,uEAAuE;IACvE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,2DAA2D;IAC3D,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,qEAAqE;IACrE,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,OAAO,CAAC;IAC3B,0EAA0E;IAC1E,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAAC;CACpD;AA0BD,wBAAsB,cAAc,CAClC,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,IAAI,CAAC,CAoEf;AAED,0DAA0D;AAC1D,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmB7D"}
@@ -1,7 +1,10 @@
1
1
  import { loadConfig } from '../core/foundation/config.js';
2
2
  import { resolveHarnessExecutable } from '../core/foundation/harness-catalog.js';
3
+ import { formatPriceKey } from '../core/report/planning-price-gaps.js';
3
4
  import { approveSpec } from '../core/spec/approve.js';
4
5
  import { formatApprovalDigest, formatApprovalFlags, summarizeApprovalFlags, } from '../core/spec/digest.js';
6
+ import { findChange } from '../core/status/change-locations.js';
7
+ import { formatNextStep, readNextStep } from '../core/status/next-step.js';
5
8
  import { readClaudePlanningSessions } from '../harness/claude/claude-usage.js';
6
9
  import { readCodexPlanningSessions } from '../harness/codex/codex-observe-usage.js';
7
10
  import { readOpencodePlanningSessions } from '../harness/opencode/opencode-observe-usage.js';
@@ -60,22 +63,53 @@ export async function approveCommand(specIds, options = {}) {
60
63
  planningReaders,
61
64
  now: options.now,
62
65
  review,
66
+ baseOk: options.baseOk,
67
+ ignoreDirty: options.ignoreDirty,
63
68
  });
64
69
  const summary = summarizeApprovalFlags(result.digest.flags);
65
70
  console.log(`Approved ${result.specId} (${result.folderName})${summary ? ` with ${summary}` : ''}`);
66
71
  console.log(` Hash: ${result.hash}`);
72
+ if (result.worktreePath !== undefined && result.branch !== undefined) {
73
+ console.log(` Worktree: ${result.worktreePath}`);
74
+ console.log(` Branch: ${result.branch}`);
75
+ }
67
76
  for (const warning of result.warnings) {
68
77
  console.warn(` Warning: ${warning}`);
69
78
  }
70
79
  if (result.planningMatches === 0) {
71
80
  console.log(`No planning record found for ${result.specId}.`);
72
81
  }
82
+ for (const model of result.missingPrices) {
83
+ console.log(`Planning cost for ${model} stays unreported; add ${formatPriceKey(model)}.`);
84
+ }
73
85
  }
74
86
  catch (error) {
75
87
  const message = error instanceof Error ? error.message : String(error);
76
88
  console.error(`Error approving ${specId}:\n ${message}`);
89
+ try {
90
+ const { folderPath } = await findChange(cwd, config, specId);
91
+ const nextStep = await readNextStep(cwd, folderPath, config);
92
+ console.log(`Next: ${formatNextStep(nextStep)}`);
93
+ }
94
+ catch { }
77
95
  process.exit(1);
78
96
  }
79
97
  }
80
98
  }
99
+ /** Register `osq approve` and its approval-only flags. */
100
+ export function registerApproveCommand(program) {
101
+ program
102
+ .command('approve <ids...>')
103
+ .description('lint, hash, and approve change folders')
104
+ .option('--confirm', 'ask about approval flags before sealing')
105
+ .option('--base-ok', 'approve even when HEAD is not the default branch')
106
+ .option('--ignore-dirty', 'approve despite uncommitted changes in task scope')
107
+ .action(async (ids, options) => {
108
+ await approveCommand(ids, {
109
+ confirm: options.confirm,
110
+ baseOk: options.baseOk,
111
+ ignoreDirty: options.ignoreDirty,
112
+ });
113
+ });
114
+ }
81
115
  //# sourceMappingURL=approve.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"approve.js","sourceRoot":"","sources":["../../src/cli/approve.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"approve.js","sourceRoot":"","sources":["../../src/cli/approve.ts"],"names":[],"mappings":"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"}
package/dist/cli/bin.js CHANGED
@@ -1,5 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import { createProgram, resolvePackageVersion } from './index.js';
3
- const program = createProgram(resolvePackageVersion());
4
- await program.parseAsync(process.argv);
2
+ import { runCli } from './run.js';
3
+ await runCli(process.argv);
5
4
  //# sourceMappingURL=bin.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bin.js","sourceRoot":"","sources":["../../src/cli/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,aAAa,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AAElE,MAAM,OAAO,GAAG,aAAa,CAAC,qBAAqB,EAAE,CAAC,CAAC;AACvD,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../../src/cli/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAElC,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC"}
@@ -0,0 +1,15 @@
1
+ import type { Command } from 'commander';
2
+ import { type OsqConfig } from '../core/foundation/config.js';
3
+ export interface CheckCommandOptions {
4
+ cwd?: string;
5
+ config?: OsqConfig;
6
+ }
7
+ /**
8
+ * Run an archived change's recorded `check` command once, append one
9
+ * `check_ran` event, print the result and next step, and exit zero only when
10
+ * the check passed. A refusal writes nothing.
11
+ */
12
+ export declare function checkCommand(specId: string, options?: CheckCommandOptions): Promise<void>;
13
+ /** Register `osq check` and `osq verified` on the root program. */
14
+ export declare function registerVerificationCommands(program: Command): void;
15
+ //# sourceMappingURL=check.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check.d.ts","sourceRoot":"","sources":["../../src/cli/check.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,KAAK,SAAS,EAAc,MAAM,8BAA8B,CAAC;AAK1E,MAAM,WAAW,mBAAmB;IAClC,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,SAAS,CAAC;CACpB;AA4BD;;;;GAIG;AACH,wBAAsB,YAAY,CAChC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,IAAI,CAAC,CAcf;AAED,mEAAmE;AACnE,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAiBnE"}