@humanbased/crosscheck 0.14.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 (381) hide show
  1. package/AGENT.md +207 -0
  2. package/ISSUE.md +234 -0
  3. package/LICENSE +21 -0
  4. package/README.md +234 -0
  5. package/README.zh.md +169 -0
  6. package/assets/logo.png +0 -0
  7. package/assets/screenshot-watch-timing.png +0 -0
  8. package/assets/screenshot-watch-timing.svg +1 -0
  9. package/assets/screenshot-watch.png +0 -0
  10. package/crosscheck.config.example.yml +214 -0
  11. package/dist/__tests__/annotation.test.d.ts +2 -0
  12. package/dist/__tests__/annotation.test.d.ts.map +1 -0
  13. package/dist/__tests__/annotation.test.js +134 -0
  14. package/dist/__tests__/annotation.test.js.map +1 -0
  15. package/dist/__tests__/backtrace.test.d.ts +2 -0
  16. package/dist/__tests__/backtrace.test.d.ts.map +1 -0
  17. package/dist/__tests__/backtrace.test.js +280 -0
  18. package/dist/__tests__/backtrace.test.js.map +1 -0
  19. package/dist/__tests__/board.test.d.ts +2 -0
  20. package/dist/__tests__/board.test.d.ts.map +1 -0
  21. package/dist/__tests__/board.test.js +149 -0
  22. package/dist/__tests__/board.test.js.map +1 -0
  23. package/dist/__tests__/codex.test.d.ts +2 -0
  24. package/dist/__tests__/codex.test.d.ts.map +1 -0
  25. package/dist/__tests__/codex.test.js +92 -0
  26. package/dist/__tests__/codex.test.js.map +1 -0
  27. package/dist/__tests__/comment-bodies.test.d.ts +2 -0
  28. package/dist/__tests__/comment-bodies.test.d.ts.map +1 -0
  29. package/dist/__tests__/comment-bodies.test.js +75 -0
  30. package/dist/__tests__/comment-bodies.test.js.map +1 -0
  31. package/dist/__tests__/conflict-resolve.test.d.ts +2 -0
  32. package/dist/__tests__/conflict-resolve.test.d.ts.map +1 -0
  33. package/dist/__tests__/conflict-resolve.test.js +123 -0
  34. package/dist/__tests__/conflict-resolve.test.js.map +1 -0
  35. package/dist/__tests__/crosscheck-commit.test.d.ts +2 -0
  36. package/dist/__tests__/crosscheck-commit.test.d.ts.map +1 -0
  37. package/dist/__tests__/crosscheck-commit.test.js +13 -0
  38. package/dist/__tests__/crosscheck-commit.test.js.map +1 -0
  39. package/dist/__tests__/detector.test.d.ts +2 -0
  40. package/dist/__tests__/detector.test.d.ts.map +1 -0
  41. package/dist/__tests__/detector.test.js +112 -0
  42. package/dist/__tests__/detector.test.js.map +1 -0
  43. package/dist/__tests__/diagnose.test.d.ts +2 -0
  44. package/dist/__tests__/diagnose.test.d.ts.map +1 -0
  45. package/dist/__tests__/diagnose.test.js +164 -0
  46. package/dist/__tests__/diagnose.test.js.map +1 -0
  47. package/dist/__tests__/diff-hash.test.d.ts +2 -0
  48. package/dist/__tests__/diff-hash.test.d.ts.map +1 -0
  49. package/dist/__tests__/diff-hash.test.js +126 -0
  50. package/dist/__tests__/diff-hash.test.js.map +1 -0
  51. package/dist/__tests__/durations.test.d.ts +2 -0
  52. package/dist/__tests__/durations.test.d.ts.map +1 -0
  53. package/dist/__tests__/durations.test.js +26 -0
  54. package/dist/__tests__/durations.test.js.map +1 -0
  55. package/dist/__tests__/event-fields.test.d.ts +2 -0
  56. package/dist/__tests__/event-fields.test.d.ts.map +1 -0
  57. package/dist/__tests__/event-fields.test.js +50 -0
  58. package/dist/__tests__/event-fields.test.js.map +1 -0
  59. package/dist/__tests__/filter.test.d.ts +2 -0
  60. package/dist/__tests__/filter.test.d.ts.map +1 -0
  61. package/dist/__tests__/filter.test.js +21 -0
  62. package/dist/__tests__/filter.test.js.map +1 -0
  63. package/dist/__tests__/fix.test.d.ts +2 -0
  64. package/dist/__tests__/fix.test.d.ts.map +1 -0
  65. package/dist/__tests__/fix.test.js +124 -0
  66. package/dist/__tests__/fix.test.js.map +1 -0
  67. package/dist/__tests__/github-client.test.d.ts +2 -0
  68. package/dist/__tests__/github-client.test.d.ts.map +1 -0
  69. package/dist/__tests__/github-client.test.js +22 -0
  70. package/dist/__tests__/github-client.test.js.map +1 -0
  71. package/dist/__tests__/github-scan-client.test.d.ts +2 -0
  72. package/dist/__tests__/github-scan-client.test.d.ts.map +1 -0
  73. package/dist/__tests__/github-scan-client.test.js +100 -0
  74. package/dist/__tests__/github-scan-client.test.js.map +1 -0
  75. package/dist/__tests__/is-fresh-review-comment.test.d.ts +2 -0
  76. package/dist/__tests__/is-fresh-review-comment.test.d.ts.map +1 -0
  77. package/dist/__tests__/is-fresh-review-comment.test.js +86 -0
  78. package/dist/__tests__/is-fresh-review-comment.test.js.map +1 -0
  79. package/dist/__tests__/issue.test.d.ts +2 -0
  80. package/dist/__tests__/issue.test.d.ts.map +1 -0
  81. package/dist/__tests__/issue.test.js +259 -0
  82. package/dist/__tests__/issue.test.js.map +1 -0
  83. package/dist/__tests__/kickass.test.d.ts +2 -0
  84. package/dist/__tests__/kickass.test.d.ts.map +1 -0
  85. package/dist/__tests__/kickass.test.js +268 -0
  86. package/dist/__tests__/kickass.test.js.map +1 -0
  87. package/dist/__tests__/loader.test.d.ts +2 -0
  88. package/dist/__tests__/loader.test.d.ts.map +1 -0
  89. package/dist/__tests__/loader.test.js +180 -0
  90. package/dist/__tests__/loader.test.js.map +1 -0
  91. package/dist/__tests__/onboard-preservation.test.d.ts +2 -0
  92. package/dist/__tests__/onboard-preservation.test.d.ts.map +1 -0
  93. package/dist/__tests__/onboard-preservation.test.js +506 -0
  94. package/dist/__tests__/onboard-preservation.test.js.map +1 -0
  95. package/dist/__tests__/optimize.test.d.ts +2 -0
  96. package/dist/__tests__/optimize.test.d.ts.map +1 -0
  97. package/dist/__tests__/optimize.test.js +101 -0
  98. package/dist/__tests__/optimize.test.js.map +1 -0
  99. package/dist/__tests__/post-review-comment.test.d.ts +2 -0
  100. package/dist/__tests__/post-review-comment.test.d.ts.map +1 -0
  101. package/dist/__tests__/post-review-comment.test.js +44 -0
  102. package/dist/__tests__/post-review-comment.test.js.map +1 -0
  103. package/dist/__tests__/pr-lock.test.d.ts +2 -0
  104. package/dist/__tests__/pr-lock.test.d.ts.map +1 -0
  105. package/dist/__tests__/pr-lock.test.js +115 -0
  106. package/dist/__tests__/pr-lock.test.js.map +1 -0
  107. package/dist/__tests__/pr-picker.test.d.ts +2 -0
  108. package/dist/__tests__/pr-picker.test.d.ts.map +1 -0
  109. package/dist/__tests__/pr-picker.test.js +57 -0
  110. package/dist/__tests__/pr-picker.test.js.map +1 -0
  111. package/dist/__tests__/pr-status-scan.test.d.ts +2 -0
  112. package/dist/__tests__/pr-status-scan.test.d.ts.map +1 -0
  113. package/dist/__tests__/pr-status-scan.test.js +92 -0
  114. package/dist/__tests__/pr-status-scan.test.js.map +1 -0
  115. package/dist/__tests__/pr-status.test.d.ts +2 -0
  116. package/dist/__tests__/pr-status.test.d.ts.map +1 -0
  117. package/dist/__tests__/pr-status.test.js +346 -0
  118. package/dist/__tests__/pr-status.test.js.map +1 -0
  119. package/dist/__tests__/repo-picker.test.d.ts +2 -0
  120. package/dist/__tests__/repo-picker.test.d.ts.map +1 -0
  121. package/dist/__tests__/repo-picker.test.js +115 -0
  122. package/dist/__tests__/repo-picker.test.js.map +1 -0
  123. package/dist/__tests__/review-comment-body.test.d.ts +2 -0
  124. package/dist/__tests__/review-comment-body.test.d.ts.map +1 -0
  125. package/dist/__tests__/review-comment-body.test.js +54 -0
  126. package/dist/__tests__/review-comment-body.test.js.map +1 -0
  127. package/dist/__tests__/review-models.test.d.ts +2 -0
  128. package/dist/__tests__/review-models.test.d.ts.map +1 -0
  129. package/dist/__tests__/review-models.test.js +39 -0
  130. package/dist/__tests__/review-models.test.js.map +1 -0
  131. package/dist/__tests__/review-status.test.d.ts +2 -0
  132. package/dist/__tests__/review-status.test.d.ts.map +1 -0
  133. package/dist/__tests__/review-status.test.js +95 -0
  134. package/dist/__tests__/review-status.test.js.map +1 -0
  135. package/dist/__tests__/runner.test.d.ts +2 -0
  136. package/dist/__tests__/runner.test.d.ts.map +1 -0
  137. package/dist/__tests__/runner.test.js +204 -0
  138. package/dist/__tests__/runner.test.js.map +1 -0
  139. package/dist/__tests__/scan-cache.test.d.ts +2 -0
  140. package/dist/__tests__/scan-cache.test.d.ts.map +1 -0
  141. package/dist/__tests__/scan-cache.test.js +59 -0
  142. package/dist/__tests__/scan-cache.test.js.map +1 -0
  143. package/dist/__tests__/scan-client.test.d.ts +2 -0
  144. package/dist/__tests__/scan-client.test.d.ts.map +1 -0
  145. package/dist/__tests__/scan-client.test.js +30 -0
  146. package/dist/__tests__/scan-client.test.js.map +1 -0
  147. package/dist/__tests__/scan.test.d.ts +2 -0
  148. package/dist/__tests__/scan.test.d.ts.map +1 -0
  149. package/dist/__tests__/scan.test.js +115 -0
  150. package/dist/__tests__/scan.test.js.map +1 -0
  151. package/dist/__tests__/scopes.test.d.ts +2 -0
  152. package/dist/__tests__/scopes.test.d.ts.map +1 -0
  153. package/dist/__tests__/scopes.test.js +101 -0
  154. package/dist/__tests__/scopes.test.js.map +1 -0
  155. package/dist/__tests__/sha-cache.test.d.ts +2 -0
  156. package/dist/__tests__/sha-cache.test.d.ts.map +1 -0
  157. package/dist/__tests__/sha-cache.test.js +40 -0
  158. package/dist/__tests__/sha-cache.test.js.map +1 -0
  159. package/dist/__tests__/smart-switch.test.d.ts +2 -0
  160. package/dist/__tests__/smart-switch.test.d.ts.map +1 -0
  161. package/dist/__tests__/smart-switch.test.js +145 -0
  162. package/dist/__tests__/smart-switch.test.js.map +1 -0
  163. package/dist/ck.d.ts +3 -0
  164. package/dist/ck.d.ts.map +1 -0
  165. package/dist/ck.js +8 -0
  166. package/dist/ck.js.map +1 -0
  167. package/dist/cli.d.ts +3 -0
  168. package/dist/cli.d.ts.map +1 -0
  169. package/dist/cli.js +132 -0
  170. package/dist/cli.js.map +1 -0
  171. package/dist/commands/diagnose.d.ts +54 -0
  172. package/dist/commands/diagnose.d.ts.map +1 -0
  173. package/dist/commands/diagnose.js +294 -0
  174. package/dist/commands/diagnose.js.map +1 -0
  175. package/dist/commands/impact.d.ts +38 -0
  176. package/dist/commands/impact.d.ts.map +1 -0
  177. package/dist/commands/impact.js +210 -0
  178. package/dist/commands/impact.js.map +1 -0
  179. package/dist/commands/init.d.ts +12 -0
  180. package/dist/commands/init.d.ts.map +1 -0
  181. package/dist/commands/init.js +183 -0
  182. package/dist/commands/init.js.map +1 -0
  183. package/dist/commands/issue.d.ts +25 -0
  184. package/dist/commands/issue.d.ts.map +1 -0
  185. package/dist/commands/issue.js +445 -0
  186. package/dist/commands/issue.js.map +1 -0
  187. package/dist/commands/kickass.d.ts +59 -0
  188. package/dist/commands/kickass.d.ts.map +1 -0
  189. package/dist/commands/kickass.js +288 -0
  190. package/dist/commands/kickass.js.map +1 -0
  191. package/dist/commands/onboard.d.ts +70 -0
  192. package/dist/commands/onboard.d.ts.map +1 -0
  193. package/dist/commands/onboard.js +883 -0
  194. package/dist/commands/onboard.js.map +1 -0
  195. package/dist/commands/optimize.d.ts +16 -0
  196. package/dist/commands/optimize.d.ts.map +1 -0
  197. package/dist/commands/optimize.js +244 -0
  198. package/dist/commands/optimize.js.map +1 -0
  199. package/dist/commands/review.d.ts +2 -0
  200. package/dist/commands/review.d.ts.map +1 -0
  201. package/dist/commands/review.js +118 -0
  202. package/dist/commands/review.js.map +1 -0
  203. package/dist/commands/run.d.ts +13 -0
  204. package/dist/commands/run.d.ts.map +1 -0
  205. package/dist/commands/run.js +243 -0
  206. package/dist/commands/run.js.map +1 -0
  207. package/dist/commands/scan.d.ts +94 -0
  208. package/dist/commands/scan.d.ts.map +1 -0
  209. package/dist/commands/scan.js +276 -0
  210. package/dist/commands/scan.js.map +1 -0
  211. package/dist/commands/serve.d.ts +9 -0
  212. package/dist/commands/serve.d.ts.map +1 -0
  213. package/dist/commands/serve.js +402 -0
  214. package/dist/commands/serve.js.map +1 -0
  215. package/dist/commands/status.d.ts +2 -0
  216. package/dist/commands/status.d.ts.map +1 -0
  217. package/dist/commands/status.js +89 -0
  218. package/dist/commands/status.js.map +1 -0
  219. package/dist/commands/watch.d.ts +9 -0
  220. package/dist/commands/watch.d.ts.map +1 -0
  221. package/dist/commands/watch.js +902 -0
  222. package/dist/commands/watch.js.map +1 -0
  223. package/dist/config/loader.d.ts +47 -0
  224. package/dist/config/loader.d.ts.map +1 -0
  225. package/dist/config/loader.js +334 -0
  226. package/dist/config/loader.js.map +1 -0
  227. package/dist/config/schema.d.ts +814 -0
  228. package/dist/config/schema.d.ts.map +1 -0
  229. package/dist/config/schema.js +152 -0
  230. package/dist/config/schema.js.map +1 -0
  231. package/dist/github/client.d.ts +139 -0
  232. package/dist/github/client.d.ts.map +1 -0
  233. package/dist/github/client.js +711 -0
  234. package/dist/github/client.js.map +1 -0
  235. package/dist/github/detector.d.ts +12 -0
  236. package/dist/github/detector.d.ts.map +1 -0
  237. package/dist/github/detector.js +120 -0
  238. package/dist/github/detector.js.map +1 -0
  239. package/dist/github/merge.d.ts +9 -0
  240. package/dist/github/merge.d.ts.map +1 -0
  241. package/dist/github/merge.js +33 -0
  242. package/dist/github/merge.js.map +1 -0
  243. package/dist/github/review-status.d.ts +6 -0
  244. package/dist/github/review-status.d.ts.map +1 -0
  245. package/dist/github/review-status.js +51 -0
  246. package/dist/github/review-status.js.map +1 -0
  247. package/dist/github/webhook.d.ts +41 -0
  248. package/dist/github/webhook.d.ts.map +1 -0
  249. package/dist/github/webhook.js +50 -0
  250. package/dist/github/webhook.js.map +1 -0
  251. package/dist/lib/annotation.d.ts +23 -0
  252. package/dist/lib/annotation.d.ts.map +1 -0
  253. package/dist/lib/annotation.js +103 -0
  254. package/dist/lib/annotation.js.map +1 -0
  255. package/dist/lib/backtrace.d.ts +40 -0
  256. package/dist/lib/backtrace.d.ts.map +1 -0
  257. package/dist/lib/backtrace.js +169 -0
  258. package/dist/lib/backtrace.js.map +1 -0
  259. package/dist/lib/board.d.ts +74 -0
  260. package/dist/lib/board.d.ts.map +1 -0
  261. package/dist/lib/board.js +640 -0
  262. package/dist/lib/board.js.map +1 -0
  263. package/dist/lib/clone.d.ts +12 -0
  264. package/dist/lib/clone.d.ts.map +1 -0
  265. package/dist/lib/clone.js +30 -0
  266. package/dist/lib/clone.js.map +1 -0
  267. package/dist/lib/comment-bodies.d.ts +17 -0
  268. package/dist/lib/comment-bodies.d.ts.map +1 -0
  269. package/dist/lib/comment-bodies.js +51 -0
  270. package/dist/lib/comment-bodies.js.map +1 -0
  271. package/dist/lib/crosscheck-commit.d.ts +2 -0
  272. package/dist/lib/crosscheck-commit.d.ts.map +1 -0
  273. package/dist/lib/crosscheck-commit.js +4 -0
  274. package/dist/lib/crosscheck-commit.js.map +1 -0
  275. package/dist/lib/diff-hash.d.ts +16 -0
  276. package/dist/lib/diff-hash.d.ts.map +1 -0
  277. package/dist/lib/diff-hash.js +71 -0
  278. package/dist/lib/diff-hash.js.map +1 -0
  279. package/dist/lib/durations.d.ts +5 -0
  280. package/dist/lib/durations.d.ts.map +1 -0
  281. package/dist/lib/durations.js +39 -0
  282. package/dist/lib/durations.js.map +1 -0
  283. package/dist/lib/event-fields.d.ts +6 -0
  284. package/dist/lib/event-fields.d.ts.map +1 -0
  285. package/dist/lib/event-fields.js +20 -0
  286. package/dist/lib/event-fields.js.map +1 -0
  287. package/dist/lib/filter.d.ts +2 -0
  288. package/dist/lib/filter.d.ts.map +1 -0
  289. package/dist/lib/filter.js +4 -0
  290. package/dist/lib/filter.js.map +1 -0
  291. package/dist/lib/fortune.d.ts +2 -0
  292. package/dist/lib/fortune.d.ts.map +1 -0
  293. package/dist/lib/fortune.js +26 -0
  294. package/dist/lib/fortune.js.map +1 -0
  295. package/dist/lib/languages.d.ts +3 -0
  296. package/dist/lib/languages.d.ts.map +1 -0
  297. package/dist/lib/languages.js +26 -0
  298. package/dist/lib/languages.js.map +1 -0
  299. package/dist/lib/log-analysis.d.ts +17 -0
  300. package/dist/lib/log-analysis.d.ts.map +1 -0
  301. package/dist/lib/log-analysis.js +72 -0
  302. package/dist/lib/log-analysis.js.map +1 -0
  303. package/dist/lib/logger.d.ts +14 -0
  304. package/dist/lib/logger.d.ts.map +1 -0
  305. package/dist/lib/logger.js +84 -0
  306. package/dist/lib/logger.js.map +1 -0
  307. package/dist/lib/port.d.ts +2 -0
  308. package/dist/lib/port.d.ts.map +1 -0
  309. package/dist/lib/port.js +21 -0
  310. package/dist/lib/port.js.map +1 -0
  311. package/dist/lib/pr-lock.d.ts +4 -0
  312. package/dist/lib/pr-lock.d.ts.map +1 -0
  313. package/dist/lib/pr-lock.js +91 -0
  314. package/dist/lib/pr-lock.js.map +1 -0
  315. package/dist/lib/pr-picker.d.ts +10 -0
  316. package/dist/lib/pr-picker.d.ts.map +1 -0
  317. package/dist/lib/pr-picker.js +80 -0
  318. package/dist/lib/pr-picker.js.map +1 -0
  319. package/dist/lib/pr-status.d.ts +206 -0
  320. package/dist/lib/pr-status.d.ts.map +1 -0
  321. package/dist/lib/pr-status.js +613 -0
  322. package/dist/lib/pr-status.js.map +1 -0
  323. package/dist/lib/repo-picker.d.ts +23 -0
  324. package/dist/lib/repo-picker.d.ts.map +1 -0
  325. package/dist/lib/repo-picker.js +411 -0
  326. package/dist/lib/repo-picker.js.map +1 -0
  327. package/dist/lib/review-models.d.ts +7 -0
  328. package/dist/lib/review-models.d.ts.map +1 -0
  329. package/dist/lib/review-models.js +32 -0
  330. package/dist/lib/review-models.js.map +1 -0
  331. package/dist/lib/runner.d.ts +65 -0
  332. package/dist/lib/runner.d.ts.map +1 -0
  333. package/dist/lib/runner.js +710 -0
  334. package/dist/lib/runner.js.map +1 -0
  335. package/dist/lib/scan-cache.d.ts +31 -0
  336. package/dist/lib/scan-cache.d.ts.map +1 -0
  337. package/dist/lib/scan-cache.js +112 -0
  338. package/dist/lib/scan-cache.js.map +1 -0
  339. package/dist/lib/scopes.d.ts +16 -0
  340. package/dist/lib/scopes.d.ts.map +1 -0
  341. package/dist/lib/scopes.js +37 -0
  342. package/dist/lib/scopes.js.map +1 -0
  343. package/dist/lib/sha-cache.d.ts +7 -0
  344. package/dist/lib/sha-cache.d.ts.map +1 -0
  345. package/dist/lib/sha-cache.js +44 -0
  346. package/dist/lib/sha-cache.js.map +1 -0
  347. package/dist/lib/smart-switch.d.ts +44 -0
  348. package/dist/lib/smart-switch.d.ts.map +1 -0
  349. package/dist/lib/smart-switch.js +145 -0
  350. package/dist/lib/smart-switch.js.map +1 -0
  351. package/dist/lib/verdict.d.ts +9 -0
  352. package/dist/lib/verdict.d.ts.map +1 -0
  353. package/dist/lib/verdict.js +52 -0
  354. package/dist/lib/verdict.js.map +1 -0
  355. package/dist/lib/workflow.d.ts +85 -0
  356. package/dist/lib/workflow.d.ts.map +1 -0
  357. package/dist/lib/workflow.js +116 -0
  358. package/dist/lib/workflow.js.map +1 -0
  359. package/dist/reviewers/address.d.ts +5 -0
  360. package/dist/reviewers/address.d.ts.map +1 -0
  361. package/dist/reviewers/address.js +87 -0
  362. package/dist/reviewers/address.js.map +1 -0
  363. package/dist/reviewers/claude.d.ts +12 -0
  364. package/dist/reviewers/claude.d.ts.map +1 -0
  365. package/dist/reviewers/claude.js +78 -0
  366. package/dist/reviewers/claude.js.map +1 -0
  367. package/dist/reviewers/codex.d.ts +9 -0
  368. package/dist/reviewers/codex.d.ts.map +1 -0
  369. package/dist/reviewers/codex.js +121 -0
  370. package/dist/reviewers/codex.js.map +1 -0
  371. package/dist/reviewers/conflict-resolve.d.ts +15 -0
  372. package/dist/reviewers/conflict-resolve.d.ts.map +1 -0
  373. package/dist/reviewers/conflict-resolve.js +219 -0
  374. package/dist/reviewers/conflict-resolve.js.map +1 -0
  375. package/dist/reviewers/fix.d.ts +7 -0
  376. package/dist/reviewers/fix.d.ts.map +1 -0
  377. package/dist/reviewers/fix.js +197 -0
  378. package/dist/reviewers/fix.js.map +1 -0
  379. package/get-started.md +1271 -0
  380. package/get-started.zh.md +1208 -0
  381. package/package.json +75 -0
package/get-started.md ADDED
@@ -0,0 +1,1271 @@
1
+ <div align="right">
2
+ <h5><a href="./get-started.zh.md">🌏 &nbsp;中文</a></h5>
3
+ </div>
4
+
5
+ # crosscheck — Get Started
6
+
7
+ ## Table of contents
8
+
9
+ - [Prerequisites](#prerequisites)
10
+ - [Install](#install)
11
+ - [Environment variables](#environment-variables)
12
+ - [Step 1 — Check your environment](#step-1--check-your-environment)
13
+ - [Step 2 — Test with a single PR](#step-2--test-with-a-single-pr)
14
+ - [Step 3 — Choose a deployment mode](#step-3--choose-a-deployment-mode)
15
+ - [Step 4 — Verify it's working](#step-4--verify-its-working)
16
+ - [Commands](#commands)
17
+ - [init](#crosscheck-init)
18
+ - [onboard](#crosscheck-onboard)
19
+ - [review](#crosscheck-review-pr-url)
20
+ - [run](#crosscheck-run-pr-url)
21
+ - [watch](#crosscheck-watch)
22
+ - [serve](#crosscheck-serve-beta)
23
+ - [status](#crosscheck-status)
24
+ - [diagnose](#crosscheck-diagnose)
25
+ - [optimize](#crosscheck-optimize)
26
+ - [impact](#crosscheck-impact)
27
+ - [issue](#crosscheck-issue)
28
+ - [Configuration](#configuration)
29
+ - [How it works](#how-it-works)
30
+ - [Post-review auto-fix](#post-review-auto-fix)
31
+ - [FAQ](#faq)
32
+
33
+ ---
34
+
35
+ ## Prerequisites
36
+
37
+ You need three CLIs installed and authenticated before crosscheck can run reviews.
38
+
39
+ ### Claude Code
40
+
41
+ ```bash
42
+ npm install -g @anthropic-ai/claude-code
43
+ claude # follow prompts to sign in to claude.ai
44
+ ```
45
+
46
+ Requires a Claude Pro or Max plan. Reviews use your subscription quota — no per-token API billing.
47
+
48
+ ### Codex
49
+
50
+ ```bash
51
+ npm install -g @openai/codex
52
+ codex login --device-auth # OAuth sign-in with your ChatGPT account
53
+ ```
54
+
55
+ Requires a ChatGPT Plus or Pro plan. When authenticated via `--device-auth`, reviews run against your subscription — no API key needed.
56
+
57
+ If you prefer to use an OpenAI API key instead:
58
+
59
+ ```bash
60
+ printenv OPENAI_API_KEY | codex login --with-api-key
61
+ ```
62
+
63
+ Then set `auth: api-key` in your config to enable model selection.
64
+
65
+ ### GitHub CLI
66
+
67
+ ```bash
68
+ brew install gh # macOS
69
+ gh auth login
70
+ ```
71
+
72
+ Used for cloning PR branches and (in watch mode) registering webhooks automatically.
73
+
74
+ ---
75
+
76
+ ## Install
77
+
78
+ **Stable (recommended):**
79
+
80
+ ```bash
81
+ npm install -g @humanbased/crosscheck
82
+ ```
83
+
84
+ **Beta (latest features, may have rough edges):**
85
+
86
+ ```bash
87
+ npm install -g @humanbased/crosscheck@beta
88
+ ```
89
+
90
+ **npx — no install:**
91
+
92
+ ```bash
93
+ npx @humanbased/crosscheck <command>
94
+ npx @humanbased/crosscheck@beta <command>
95
+ ```
96
+
97
+ **From source:**
98
+
99
+ ```bash
100
+ git clone https://github.com/humanbased-ai/crosscheck
101
+ cd crosscheck
102
+ npm install && npm run build && npm link
103
+ ```
104
+
105
+ ---
106
+
107
+ ## Environment variables
108
+
109
+ ### GitHub auth — two options (pick one)
110
+
111
+ **Option 1 — gh CLI (recommended):** authenticate once and crosscheck picks up the token automatically:
112
+
113
+ ```bash
114
+ gh auth login
115
+ ```
116
+
117
+ **Option 2 — Personal access token:** useful in CI or if you prefer an explicit token:
118
+
119
+ ```bash
120
+ export GITHUB_TOKEN=ghp_...
121
+ ```
122
+
123
+ A classic PAT needs `repo` and `admin:org_hook` scopes (org-level webhooks require `admin:org_hook`; repo-level only needs `repo`).
124
+ Generate one at [github.com/settings/tokens](https://github.com/settings/tokens).
125
+
126
+ If both are present, crosscheck prefers the `gh` keyring token (always fresh) and uses `GITHUB_TOKEN` as a fallback.
127
+
128
+ ### Webhook secret — auto-managed
129
+
130
+ `CROSSCHECK_WEBHOOK_SECRET` is **optional**. If you don't set it, crosscheck generates a random secret on first use and saves it to `~/.crosscheck/webhook-secret` (readable only by you). It's reused automatically on every subsequent run.
131
+
132
+ To retrieve it later (e.g. to register a webhook manually):
133
+
134
+ ```bash
135
+ cat ~/.crosscheck/webhook-secret
136
+ ```
137
+
138
+ To use your own secret instead, set it in your shell profile:
139
+
140
+ ```bash
141
+ export CROSSCHECK_WEBHOOK_SECRET=your-secret
142
+ ```
143
+
144
+ ---
145
+
146
+ ## Step 1 — Set up crosscheck
147
+
148
+ ```bash
149
+ crosscheck onboard
150
+ ```
151
+
152
+ `crosscheck onboard` is the recommended first step. It checks your CLIs, walks you through deployment mode, repo selection, review mode, and workflow pipeline, then writes a ready-to-use config — all in one session. See the [`crosscheck onboard`](#crosscheck-onboard) command reference for the full six-step walkthrough.
153
+
154
+ Once it completes, go straight to `crosscheck watch`. There is no separate init step required.
155
+
156
+ > If you prefer to skip the wizard and configure manually, run `crosscheck init` to generate a starter config, then edit `~/.crosscheck/config.yml` directly.
157
+
158
+ ---
159
+
160
+ ## Step 2 — Test with a single PR
161
+
162
+ Before running continuously, verify end-to-end with one PR:
163
+
164
+ ```bash
165
+ crosscheck review https://github.com/owner/repo/pull/123 --reviewer codex
166
+ ```
167
+
168
+ This clones the PR branch, runs Codex review against the base branch, and posts a comment to the PR. If it completes without error, your setup is working.
169
+
170
+ Try Claude as reviewer too:
171
+
172
+ ```bash
173
+ crosscheck review https://github.com/owner/repo/pull/123 --reviewer claude
174
+ ```
175
+
176
+ ---
177
+
178
+ ## Step 3 — Choose a deployment mode
179
+
180
+ ### Personal vs team
181
+
182
+ On first run, `crosscheck watch` (or `crosscheck serve`) will ask how you're using it:
183
+
184
+ ```
185
+ How are you using crosscheck?
186
+
187
+ [1] personal — monitor all your repos and orgs; review only PRs you author
188
+ [2] team — monitor org repos only; review all PRs from any author
189
+
190
+ Choice [1]:
191
+ ```
192
+
193
+ The choice is saved to `crosscheck.config.yml` as `deployment: personal` or `deployment: team`.
194
+
195
+ **Personal mode** (default, recommended for individuals)
196
+ - Monitors all repos under your personal GitHub account + all orgs you belong to
197
+ - Only reviews PRs you authored — ignores everyone else's
198
+ - Sets `routing.allowed_authors` to your GitHub login automatically
199
+
200
+ **Team mode** (recommended for shared machines)
201
+ - Monitors all orgs you belong to (no personal repos)
202
+ - Reviews all PRs from any author — no author filter applied
203
+
204
+ You can override the saved choice for a single session without touching the config:
205
+
206
+ ```bash
207
+ crosscheck watch --personal # personal mode this session only
208
+ crosscheck watch --team # team mode this session only
209
+ ```
210
+
211
+ To re-run the prompt and permanently change your choice:
212
+
213
+ ```bash
214
+ crosscheck watch --reconfigure
215
+ ```
216
+
217
+ ### Watch mode — for your development machine
218
+
219
+ Starts a local server and opens a tunnel via `localhost.run` (SSH, no install needed) so GitHub can reach your laptop. Registers webhooks automatically. Supports org-level coverage or per-repo. Runs while your terminal is open.
220
+
221
+ ```bash
222
+ # Monitor entire orgs (set in crosscheck.config.yml)
223
+ crosscheck watch
224
+
225
+ # Or run inside a repo — auto-detects from git remote
226
+ cd /path/to/your/repo && crosscheck watch
227
+ ```
228
+
229
+ ```
230
+ crosscheck watch
231
+
232
+ orgs humanbased-ai, codatta
233
+ mode cross-vendor
234
+ quality balanced
235
+ config ./crosscheck.config.yml ← edit to change above
236
+
237
+ ✓ tunnel ready: https://abc123.lhr.life
238
+ tunnel https://abc123.lhr.life
239
+ ✓ webhook registered for humanbased-ai
240
+
241
+ Waiting for PR events — Ctrl+C to stop.
242
+ ```
243
+
244
+ When you press `Ctrl+C`, the SSH tunnel and any registered webhooks are cleaned up automatically.
245
+
246
+ **Token scope for org webhooks:** `GITHUB_TOKEN` needs `write:org` scope for org-level coverage. For repo-level, `repo` scope is sufficient.
247
+
248
+ ### Serve mode [BETA] — for an always-on machine (mac-mini, home server)
249
+
250
+ > **Beta:** `serve` is functional but not yet battle-tested in production. Report issues at [github.com/humanbased-ai/crosscheck/issues](https://github.com/humanbased-ai/crosscheck/issues).
251
+
252
+ Listens on a fixed port. You register the webhook(s) manually once and they stay registered.
253
+
254
+ ```bash
255
+ crosscheck serve
256
+ ```
257
+
258
+ ```
259
+ crosscheck serving
260
+ ⚠ serve is in beta — report issues at github.com/humanbased-ai/crosscheck/issues
261
+
262
+ mode cross-vendor
263
+ quality balanced
264
+ port 7891
265
+ endpoint http://your-machine.local:7891/webhook
266
+
267
+ Register the endpoint above as a GitHub org webhook (content-type: application/json).
268
+ → https://github.com/organizations/humanbased-ai/settings/hooks
269
+ → https://github.com/organizations/codatta/settings/hooks
270
+ ```
271
+
272
+ **For org-level coverage** (covers all repos in the org), register at:
273
+ `https://github.com/organizations/<org>/settings/hooks`
274
+
275
+ **For repo-level coverage**, register at:
276
+ `https://github.com/<owner>/<repo>/settings/hooks`
277
+
278
+ - Payload URL: `http://your-machine:7891/webhook`
279
+ - Content type: `application/json`
280
+ - Secret: your `CROSSCHECK_WEBHOOK_SECRET` value
281
+ - Which events: **Pull requests** only
282
+
283
+ **Running as a background service (macOS launchd):**
284
+
285
+ ```xml
286
+ <!-- ~/Library/LaunchAgents/dev.crosscheck.plist -->
287
+ <?xml version="1.0" encoding="UTF-8"?>
288
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
289
+ <plist version="1.0">
290
+ <dict>
291
+ <key>Label</key><string>dev.crosscheck</string>
292
+ <key>ProgramArguments</key>
293
+ <array>
294
+ <string>/usr/local/bin/crosscheck</string>
295
+ <string>serve</string>
296
+ </array>
297
+ <key>EnvironmentVariables</key>
298
+ <dict>
299
+ <key>GITHUB_TOKEN</key><string>ghp_your_token</string>
300
+ <key>CROSSCHECK_WEBHOOK_SECRET</key><string>your_secret</string>
301
+ </dict>
302
+ <key>RunAtLoad</key><true/>
303
+ <key>KeepAlive</key><true/>
304
+ <key>StandardOutPath</key><string>/tmp/crosscheck.log</string>
305
+ <key>StandardErrorPath</key><string>/tmp/crosscheck.error.log</string>
306
+ </dict>
307
+ </plist>
308
+ ```
309
+
310
+ ```bash
311
+ launchctl load ~/Library/LaunchAgents/dev.crosscheck.plist
312
+ launchctl start dev.crosscheck
313
+ ```
314
+
315
+ **Running with pm2 (cross-platform):**
316
+
317
+ ```bash
318
+ npm install -g pm2
319
+ pm2 start crosscheck -- serve
320
+ pm2 save && pm2 startup
321
+ ```
322
+
323
+ ---
324
+
325
+ ## Step 4 — Verify it's working
326
+
327
+ Open a PR (or push to an existing one). You should see:
328
+
329
+ 1. A log line in your terminal when the event arrives
330
+ 2. A code review comment posted to the PR within ~60 seconds
331
+
332
+ If it doesn't appear, run `crosscheck status` to check auth and config, then check your GitHub webhook delivery log at `Settings → Webhooks → Recent Deliveries`.
333
+
334
+ ---
335
+
336
+ ## Commands
337
+
338
+ ### `crosscheck init`
339
+
340
+ Checks your environment and writes a starter config file.
341
+
342
+ ```bash
343
+ crosscheck init
344
+ crosscheck init --config /path/to/crosscheck.config.yml
345
+ ```
346
+
347
+ What it checks: `codex` CLI, `claude` CLI, `gh` CLI, `GITHUB_TOKEN`, `CROSSCHECK_WEBHOOK_SECRET`.
348
+
349
+ | Flag | Description |
350
+ |---|---|
351
+ | `-c, --config <path>` | Write the config file to a specific path |
352
+
353
+ ---
354
+
355
+ ### `crosscheck onboard`
356
+
357
+ The recommended first-time setup command. Walks through seven steps interactively and writes a ready-to-use config.
358
+
359
+ ```bash
360
+ crosscheck onboard
361
+ crosscheck onboard --yes # accept all defaults non-interactively
362
+ crosscheck onboard --personal # force personal mode for this session
363
+ crosscheck onboard --team # force team mode for this session
364
+ crosscheck onboard --reconfigure # re-run setup even if config already exists
365
+ ```
366
+
367
+ **The seven steps:**
368
+
369
+ **Step 1 — Environment check.** Verifies codex CLI, claude CLI, gh CLI, and GitHub token. At least one AI CLI must be authenticated; gh auth is always required. Prints ✓/✗ with fix hints.
370
+
371
+ **Step 2 — Deployment mode.** Choose how crosscheck scopes itself:
372
+ - `personal` — monitors your personal repos + all orgs you belong to; reviews only PRs you author
373
+ - `team` — monitors org repos only; reviews all PRs from any author
374
+
375
+ **Step 3 — Repo selection.** Lists accessible repos and orgs; you pick which ones to watch. Org-level selection covers all repos in the org with one webhook.
376
+
377
+ **Step 4 — Review mode.** If both CLIs are available, choose:
378
+ - `cross-vendor` — Claude reviews Codex PRs; Codex reviews Claude PRs (recommended when using both agents)
379
+ - `single-vendor` — one AI reviews all PRs (default when only one CLI is installed)
380
+
381
+ **Step 5 — Workflow pipeline.** Choose what happens after a review:
382
+
383
+ ```
384
+ [1] review only — AI posts a comment; you handle fixes
385
+ [2] review → fix — AI reviews, then auto-applies fixes (recommended)
386
+ [3] review → fix → re-check — full loop: review, fix, re-review to confirm
387
+ ```
388
+
389
+ The `review → fix → re-check` option writes a `~/.crosscheck/workflow.yml` with all three pipeline steps configured.
390
+
391
+ **Step 6 — Connection type.** Choose how GitHub webhooks reach your local server:
392
+ - `localhost.run` — zero-config SSH tunnel; reconnects automatically, no install required *(default)*
393
+ - `smee.io` — webhook relay; events queued while offline, stable channel URL (requires `npm install -g smee-client` and `tunnel.smee_channel` in config)
394
+
395
+ **Step 7 — Review and write config.** Shows a summary of all choices and writes `~/.crosscheck/config.yml` (and `workflow.yml` if re-check was selected).
396
+
397
+ ```
398
+ crosscheck onboard
399
+
400
+ Step 1 — environment check
401
+ ✓ codex CLI codex-cli 0.128.0 — authenticated
402
+ ✓ claude CLI 2.1.x (Claude Code)
403
+ ✓ gh CLI gh version 2.65.0
404
+ ✓ GITHUB_TOKEN set (gh auth login)
405
+
406
+ Step 2 — deployment mode
407
+ [1] personal [2] team
408
+ Choice [1]: 1
409
+
410
+ Step 3 — select repos to monitor
411
+ [1] humanbased-ai (org · 12 repos)
412
+ [2] codatta (org · 5 repos)
413
+ [3] your-github-login (personal · 8 repos)
414
+ Select [all]: 1,3
415
+
416
+ Step 4 — review mode
417
+ [1] cross-vendor [2] single-vendor
418
+ Choice [1]: 1
419
+
420
+ Step 5 — workflow pipeline
421
+ [1] review only [2] review → fix [3] review → fix → re-check
422
+ Choice [2]: 3
423
+
424
+ Step 6 — connection type
425
+ [1] localhost.run [2] smee.io
426
+ Choice [1]: 1
427
+
428
+ Step 7 — review and write config
429
+ deployment personal
430
+ connection localhost.run
431
+ orgs humanbased-ai
432
+ users your-github-login (8 repos)
433
+ mode cross-vendor
434
+ pipeline review-fix-recheck
435
+ config ~/.crosscheck/config.yml
436
+
437
+ ✓ config written to ~/.crosscheck/config.yml
438
+ ✓ workflow written to ~/.crosscheck/workflow.yml
439
+
440
+ Next: run crosscheck watch to start reviewing PRs.
441
+ ```
442
+
443
+ > **`crosscheck init` vs `crosscheck onboard`** — `init` is a lightweight environment check only (no repo selection, no pipeline prompt). Use it for a quick health check or in CI. `onboard` is the full first-time setup wizard.
444
+
445
+ | Flag | Description |
446
+ |---|---|
447
+ | `-c, --config <path>` | Write the config to a specific path |
448
+ | `-y, --yes` | Accept all defaults without interactive prompts |
449
+ | `--personal` | Use personal deployment mode for this session only |
450
+ | `--team` | Use team deployment mode for this session only |
451
+ | `--reconfigure` | Re-run setup even if `deployment` is already set in config |
452
+
453
+ ---
454
+
455
+ ### `crosscheck review <pr-url>`
456
+
457
+ Manually triggers a review for a single PR.
458
+
459
+ ```bash
460
+ crosscheck review https://github.com/owner/repo/pull/123
461
+ crosscheck review https://github.com/owner/repo/pull/123 --reviewer codex
462
+ crosscheck review https://github.com/owner/repo/pull/123 --reviewer claude
463
+ ```
464
+
465
+ | Flag | Description |
466
+ |---|---|
467
+ | `-r, --reviewer codex\|claude` | Skip auto-detection and force a specific reviewer |
468
+ | `-c, --config <path>` | Use a specific config file |
469
+
470
+ ---
471
+
472
+ ### `crosscheck run <pr-url>`
473
+
474
+ Executes the full configured workflow against a single PR: review → auto-fix → recheck. Where `crosscheck review` stops after posting a comment, `crosscheck run` closes the loop — if issues are found, the authoring agent opens a fix PR and crosscheck re-reviews it.
475
+
476
+ ```bash
477
+ crosscheck run https://github.com/owner/repo/pull/123
478
+ crosscheck run https://github.com/owner/repo/pull/123 --reviewer claude
479
+ crosscheck run https://github.com/owner/repo/pull/123 --steps review,fix
480
+ crosscheck run https://github.com/owner/repo/pull/123 --dry-run
481
+ crosscheck run https://github.com/owner/repo/pull/123 --expected-head-sha abc1234
482
+ ```
483
+
484
+ The workflow executed is loaded from `.crosscheck/workflow.yml` in the repo root (if present) or falls back to the built-in default pipeline (review only). Use `crosscheck run` to test your full pipeline end-to-end against a real PR.
485
+
486
+ | Flag | Description |
487
+ |---|---|
488
+ | `-r, --reviewer codex\|claude` | Force a specific reviewer; skip auto-detection |
489
+ | `--steps <list>` | Run only the listed step types, comma-separated: `review`, `fix`, `recheck` |
490
+ | `--dry-run` | Run the review but do not post a comment or apply fixes |
491
+ | `--expected-head-sha <sha>` | Skip if the PR head changed since the command was queued |
492
+ | `-c, --config <path>` | Use a specific config file |
493
+
494
+ ---
495
+
496
+ ### `crosscheck scan`
497
+
498
+ Scans monitored open PRs and shows which crosscheck workflow state each PR is in.
499
+
500
+ ```bash
501
+ crosscheck scan
502
+ crosscheck scan --tidy
503
+ crosscheck scan --force --stale-after 2h
504
+ crosscheck scan --json
505
+ ```
506
+
507
+ | Flag | Description |
508
+ |---|---|
509
+ | `--tidy` | Show only stale PRs that need attention |
510
+ | `--force` | Bypass the short-lived scan cache |
511
+ | `--stale-after <duration>` | Treat PRs as stale after a duration like `30m`, `2h`, or `1d` |
512
+ | `--json` | Emit raw scan data for scripts |
513
+
514
+ ---
515
+
516
+ ### `crosscheck kickass`
517
+
518
+ Selects stale PRs from the operator queue and advances each one with the safest next action: review, fix, recheck, or merge. The command revalidates the PR head before each mutation and prints an execution summary when it finishes.
519
+
520
+ ```bash
521
+ crosscheck kickass --dry-run
522
+ crosscheck kickass --force --stale-after 2h
523
+ ```
524
+
525
+ | Flag | Description |
526
+ |---|---|
527
+ | `--dry-run` | Print the selected actions without mutating PRs |
528
+ | `--force` | Bypass the short-lived scan cache |
529
+ | `--stale-after <duration>` | Only queue PRs stale for at least this duration |
530
+
531
+ ---
532
+
533
+ ### `crosscheck watch`
534
+
535
+ Local dev mode. Auto-creates a smee.io tunnel, registers the webhook, cleans up on exit.
536
+
537
+ ```bash
538
+ cd /path/to/your/repo
539
+ crosscheck watch
540
+ ```
541
+
542
+ Uses `localhost.run` (SSH) to open a public tunnel — SSH is pre-installed on macOS/Linux, no extra install or account needed. Requires `GITHUB_TOKEN` with `write:org` scope for org-level coverage, or `repo` scope for repo-level.
543
+
544
+ | Flag | Description |
545
+ |---|---|
546
+ | `-c, --config <path>` | Use a specific config file |
547
+
548
+ ---
549
+
550
+ ### `crosscheck serve` [BETA]
551
+
552
+ Always-on mode. Listens on a fixed port; you register webhooks once manually.
553
+
554
+ ```bash
555
+ crosscheck serve
556
+ ```
557
+
558
+ | Flag | Description |
559
+ |---|---|
560
+ | `-c, --config <path>` | Use a specific config file |
561
+
562
+ ---
563
+
564
+ ### `crosscheck status`
565
+
566
+ Shows auth state, config summary, and CLI versions.
567
+
568
+ ```bash
569
+ crosscheck status
570
+ ```
571
+
572
+ ```
573
+ crosscheck status
574
+
575
+ Auth
576
+ ✓ codex authenticated
577
+ ✓ claude 2.1.x (Claude Code)
578
+ ✓ GITHUB_TOKEN via gh auth login
579
+ ✓ WEBHOOK_SECRET auto-managed at ~/.crosscheck/webhook-secret
580
+
581
+ Config
582
+ mode cross-vendor
583
+ quality tier balanced
584
+ codex auth subscription
585
+ claude model sonnet
586
+ per-review budget $2.00/review
587
+
588
+ Impact
589
+ summary 47 reviews · ~43h saved · 19 issues caught
590
+ (run crosscheck impact for details)
591
+
592
+ Logs
593
+ path ~/.crosscheck/logs/
594
+ today 2026-05-08.ndjson (12 entries)
595
+
596
+ CLIs
597
+ codex codex-cli 0.128.0
598
+ claude 2.1.x (Claude Code)
599
+ ```
600
+
601
+ | Flag | Description |
602
+ |---|---|
603
+ | `-c, --config <path>` | Check status against a specific config file |
604
+
605
+ ---
606
+
607
+ ### `crosscheck diagnose`
608
+
609
+ Reads `~/.crosscheck/logs/` and surfaces failure patterns, reviewer performance, and improvement suggestions.
610
+
611
+ ```bash
612
+ crosscheck diagnose
613
+ crosscheck diagnose --since 2026-05-01
614
+ crosscheck diagnose --json
615
+ ```
616
+
617
+ ```
618
+ crosscheck diagnose
619
+
620
+ Period 2026-05-07 → 2026-05-08 (1 log file)
621
+
622
+ Reviews
623
+ total 6
624
+ successful 3
625
+ failed 3 (50% failure rate)
626
+
627
+ Reviewer performance
628
+ codex 1/4 success 25%
629
+ claude 2/2 success 100%
630
+
631
+ Verdict distribution
632
+ APPROVE 2 (67%)
633
+ NEEDS WORK 1 (33%)
634
+ BLOCK 0 (0%)
635
+
636
+ Error patterns
637
+ ✗ command not found: tsc ×2 (codex)
638
+ ✗ base branch missing: staging ×2
639
+
640
+ Languages detected
641
+ typescript, nodejs
642
+
643
+ Suggestions
644
+ → tsc: command not found ×2 (codex)
645
+ add to workflow.yml review step instructions: "Do not run tsc, ts-node, or tsx."
646
+ → base branch 'staging' not found ×2 — verify branch is fetched before review
647
+
648
+ Run `crosscheck optimize` to apply suggestions automatically.
649
+ ```
650
+
651
+ | Flag | Description |
652
+ |---|---|
653
+ | `--json` | Output full report as JSON (for scripting or piping to `optimize`) |
654
+ | `--since <YYYY-MM-DD>` | Limit analysis to logs from this date onward |
655
+
656
+ ---
657
+
658
+ ### `crosscheck optimize`
659
+
660
+ Runs `diagnose` internally, selects the best available AI agent, and generates improved instructions for the review step in `~/.crosscheck/workflow.yml`. Dry-run by default — shows a diff without writing.
661
+
662
+ ```bash
663
+ crosscheck optimize # show diff only
664
+ crosscheck optimize --apply # apply the changes
665
+ crosscheck optimize --agent codex --apply
666
+ ```
667
+
668
+ ```
669
+ Running diagnose...
670
+ agent claude (default — both enabled, no data)
671
+
672
+ diff /Users/you/.crosscheck/workflow.yml (review step)
673
+
674
+ +## Constraints
675
+ +
676
+ +- Do not run tsc, ts-node, or tsx.
677
+ +- Do not run npm, npx, yarn, or pnpm.
678
+ ...
679
+
680
+ Run with --apply to write changes to /Users/you/.crosscheck/workflow.yml (review step)
681
+ ```
682
+
683
+ **Which agent does `optimize` use?**
684
+
685
+ `optimize` picks the agent automatically based on your config and log history:
686
+
687
+ 1. If only one vendor is enabled → uses that one.
688
+ 2. If both are enabled → uses whichever has the higher success rate in recent logs.
689
+ 3. If rates are equal or no log data → defaults to `claude`.
690
+ 4. `--agent claude|codex` overrides all of the above.
691
+
692
+ | Flag | Description |
693
+ |---|---|
694
+ | `--apply` | Write the improved instructions to the review step in `~/.crosscheck/workflow.yml` (default is dry-run) |
695
+ | `--dry-run` | Show diff without writing (default behavior, explicit alias) |
696
+ | `--agent <claude\|codex>` | Force a specific agent regardless of config or log data |
697
+ | `--since <YYYY-MM-DD>` | Limit the diagnose window used as input |
698
+ | `-c, --config <path>` | Config file path |
699
+
700
+ ---
701
+
702
+ ### `crosscheck impact`
703
+
704
+ Reports cumulative value from review history: time saved, issues caught, and code quality trends. Reads from `~/.crosscheck/logs/` — no network calls.
705
+
706
+ ```bash
707
+ crosscheck impact
708
+ crosscheck impact --money
709
+ crosscheck impact --since 2026-01-01
710
+ crosscheck impact --json
711
+ ```
712
+
713
+ ```
714
+ crosscheck impact (all time · 47 reviews)
715
+
716
+ Time saved
717
+ ──────────────────────────────────────────────
718
+ Reviews run 47
719
+ Avg AI review time ~14 min
720
+ Assumed human time 60 min ⓘ
721
+ Total time saved ~43 h
722
+
723
+ Issues caught
724
+ ──────────────────────────────────────────────
725
+ APPROVE 28 (60%)
726
+ NEEDS WORK 14 (30%) ← actionable feedback
727
+ BLOCK 5 (11%) ← potential bugs / breaking changes
728
+ Total issues caught 19
729
+
730
+ Code quality trend (BLOCK rate, weekly)
731
+ ──────────────────────────────────────────────
732
+ May W1 ████████████████ 22%
733
+ May W2 ████████████ 17%
734
+ May W3 ████████ 11% ↓ improving
735
+
736
+ ⓘ assumes 60 min avg human review — set impact.assumed_human_review_minutes to adjust
737
+ Run crosscheck impact --money for a rough monetary estimate.
738
+ ```
739
+
740
+ | Flag | Description |
741
+ |---|---|
742
+ | `--money` | Append a monetary estimate based on `impact.hourly_rate_usd` and `impact.defect_cost_usd` |
743
+ | `--since <YYYY-MM-DD>` | Limit the analysis to logs from this date onward |
744
+ | `--json` | Output the full report as JSON |
745
+ | `-c, --config <path>` | Config file path |
746
+
747
+ The monetary estimate formula: `(hours_saved × hourly_rate_usd) + (issues_caught × defect_cost_usd)`. Defaults: `$150/hr`, `$150/issue`. Both configurable in `crosscheck.config.yml` under `impact`.
748
+
749
+ ---
750
+
751
+ ### `crosscheck issue`
752
+
753
+ Reads recent error logs, uses your best-performing AI agent to draft a GitHub issue, asks three short follow-up questions, and submits to `humanbased-ai/crosscheck` after you confirm. No manual log-digging or issue writing required.
754
+
755
+ ```bash
756
+ crosscheck issue # interactive — review draft before submitting
757
+ crosscheck issue --dry-run # print draft only, never submit
758
+ crosscheck issue --yes # submit immediately after displaying draft
759
+ crosscheck issue --since 2026-05-01
760
+ ```
761
+
762
+ ```
763
+ crosscheck issue
764
+
765
+ Scanning logs (last 3 days)...
766
+ Found error pattern: command_not_found: tsc ×4 (codex)
767
+
768
+ Can you reproduce this consistently?
769
+ [1] Every time [2] Sometimes [3] Happened once
770
+ Choice [1]: 1
771
+
772
+ Which command triggered this?
773
+ [1] watch [2] serve [3] review [4] Unknown
774
+ Choice [1]: 1
775
+
776
+ Is this blocking you?
777
+ [1] Blocked [2] Degraded [3] Cosmetic
778
+ Choice [2]: 2
779
+
780
+ Draft issue:
781
+ ────────────────────────────────────────────────────────
782
+ TITLE: codex: command not found: tsc during review in temp clone
783
+
784
+ ## Description
785
+ When crosscheck runs a Codex review, the reviewer tries to execute `tsc`
786
+ ...
787
+
788
+ Submit to humanbased-ai/crosscheck? [y/N]: y
789
+ ✓ https://github.com/humanbased-ai/crosscheck/issues/99
790
+ ```
791
+
792
+ If no errors are found in recent logs, crosscheck prints `No errors found in recent logs — nothing to report` and exits cleanly.
793
+
794
+ | Flag | Description |
795
+ |---|---|
796
+ | `--since <YYYY-MM-DD>` | Limit log scan to this date onward (default: last 3 days) |
797
+ | `--dry-run` | Print the draft without submitting |
798
+ | `-y, --yes` | Submit immediately after displaying the draft (skip confirmation) |
799
+ | `-c, --config <path>` | Config file path |
800
+
801
+ ---
802
+
803
+ ## Customization home
804
+
805
+ `~/.crosscheck/` is the persistent home for everything crosscheck learns and configures. Back it up before a machine migration and a reinstall is instant — run `crosscheck onboard` and press Enter through each step to confirm your previous settings.
806
+
807
+ ### Files in `~/.crosscheck/`
808
+
809
+ | File | Written by | Read by | Purpose |
810
+ |---|---|---|---|
811
+ | `config.yml` | `onboard`, `init`, `watch`/`serve` (first run) | all commands | Main config — deployment, repos, mode, vendors, quality, tunnel, routing, budget, branding |
812
+ | `workflow.yml` | `onboard` (first run only) | `watch`, `serve`, `run` | Global pipeline steps with per-step inline instructions. Written once on first onboard; never overwritten on re-runs — edit freely |
813
+ | `webhook-secret` | auto-generated on first use | `watch`, `serve` | HMAC secret for GitHub webhook signature verification — reused across restarts |
814
+ | `logs/YYYY-MM-DD.ndjson` | `watch`, `serve` | `diagnose`, `optimize`, `impact`, `issue` | Structured review event log, one file per day |
815
+
816
+ ### Per-project overrides (checked before the global files)
817
+
818
+ | File | Read by | Purpose |
819
+ |---|---|---|
820
+ | `.crosscheck/workflow.yml` *(in repo)* | `watch`, `serve`, `run` | Per-project pipeline — takes priority over `~/.crosscheck/workflow.yml` |
821
+ | `.crosscheck/AGENT.md` *(in repo)* | `optimize` | Per-project harness — takes priority over bundled `AGENT.md` |
822
+ | `AGENT.md` *(bundled with crosscheck)* | `optimize` | Default harness — shipped with the package, always available as fallback |
823
+
824
+ ### What `crosscheck onboard` owns vs. preserves
825
+
826
+ On re-runs, `onboard` updates only the fields it collected answers for. Everything else survives unchanged.
827
+
828
+ **Updated on every run:** `deployment`, `orgs`, `repos`, `mode`, `clone_protocol`, `vendors.*.enabled`, `vendors.*.effort`, `quality.tier`, `tunnel.*`, `post_review.auto_fix.*`
829
+
830
+ **Initialised on first run, never overwritten:** `routing.allowed_authors`, `routing.author_routes`, `routing.fallback_reviewer`
831
+
832
+ **Never touched by onboard:** `quality.focus`, `quality.custom_prompt`, `budget.*`, `branding.*`, `server.*`, `logs.*`, `backtrace.*`, `workflow.yml` (after first write), harness files
833
+
834
+ ---
835
+
836
+ ## Configuration
837
+
838
+ crosscheck stores its config in `~/.crosscheck/config.yml` by default — persistent across projects, no per-repo file needed. It also looks in these locations (first found wins):
839
+
840
+ 1. `~/.crosscheck/config.yml` ← **default location**
841
+ 2. `./crosscheck.config.yml`
842
+ 3. `./.crosscheck.yml`
843
+
844
+ Run `crosscheck init` to generate `~/.crosscheck/config.yml` with all options documented.
845
+
846
+ Logs are written to `~/.crosscheck/logs/YYYY-MM-DD.ndjson` and retained for 30 days by default.
847
+
848
+ ### Full reference
849
+
850
+ ```yaml
851
+ # ── Deployment ────────────────────────────────────────────────────────────────
852
+ # Set automatically on first run. Re-run the prompt with: crosscheck watch --reconfigure
853
+ # personal — monitor your repos + orgs; review only your PRs
854
+ # team — monitor org repos only; review all PRs from any author
855
+ # deployment: personal
856
+
857
+ # ── Mode ──────────────────────────────────────────────────────────────────────
858
+ # single-vendor: one AI reviews all PRs
859
+ # cross-vendor: Claude ↔ Codex review each other
860
+ mode: cross-vendor
861
+
862
+ # ── Clone protocol ────────────────────────────────────────────────────────────
863
+ # ssh — git@github.com:owner/repo.git (uses local SSH keys)
864
+ # https — https://github.com/owner/repo.git (uses GitHub token)
865
+ # Pick https if you have multi-account SSH setup or your default SSH key
866
+ # cannot access target repos. Independent of `gh config get git_protocol`.
867
+ clone_protocol: ssh
868
+
869
+ # ── Vendors ───────────────────────────────────────────────────────────────────
870
+ vendors:
871
+ codex:
872
+ enabled: true
873
+ auth: subscription # subscription | api-key
874
+ model: o4-mini # only used when auth: api-key
875
+
876
+ claude:
877
+ enabled: true
878
+ model: sonnet # haiku | sonnet | opus
879
+ effort: medium # low | medium | high | max
880
+
881
+ # ── Quality ───────────────────────────────────────────────────────────────────
882
+ quality:
883
+ tier: balanced # fast | balanced | thorough
884
+ focus: # narrows review scope (optional)
885
+ - security
886
+ - types
887
+ - performance
888
+ custom_prompt: | # appended to every review prompt
889
+ Be concise. Flag only issues that would block a merge.
890
+
891
+ # ── Budget ────────────────────────────────────────────────────────────────────
892
+ budget:
893
+ codex_monthly_usd: 20 # null = unlimited; only applies when auth: api-key
894
+ per_review_usd: 2.00 # passed to claude --max-budget-usd
895
+
896
+ # ── Orgs — covers all repos in each org with one webhook ─────────────────────
897
+ orgs:
898
+ - humanbased-ai
899
+ - codatta
900
+
901
+ # ── Users — monitors all repos owned by personal GitHub accounts (non-org) ───
902
+ # At startup, crosscheck enumerates each user's repos and registers webhooks.
903
+ # Useful when your AI agents open PRs across many personal repos.
904
+ # Combines with `orgs` and `repos` — all configured sources are additive.
905
+ users:
906
+ - beingzy # your personal account
907
+ # - my-agent-login # a bot account that pushes to its own repos
908
+
909
+ # ── Repos — for monitoring specific repos only ────────────────────────────────
910
+ # Omit when using `orgs`/`users`. Auto-detected from git remote if all are empty.
911
+ repos:
912
+ - owner: acme
913
+ name: specific-repo
914
+
915
+ # ── Routing ───────────────────────────────────────────────────────────────────
916
+ routing:
917
+ # Origin is detected via a four-signal chain:
918
+ # 1. PR body patterns below (fastest)
919
+ # 2. Commit message Co-Authored-By: trailers (API call, non-fatal if it fails)
920
+ # 3. Branch prefix (claude/ or codex/)
921
+ # 4. author_routes fallback (last resort)
922
+ codex_reviews_patterns:
923
+ - "Generated with \\[Claude Code\\]" # Claude Code attribution footer
924
+ - "Co-Authored-By: Claude" # commit trailer
925
+ claude_reviews_patterns:
926
+ - "Generated with \\[OpenAI Codex\\]" # Codex attribution footer
927
+ - "Co-Authored-By: codex" # commit trailer
928
+
929
+ # Branch prefix detection (signal 3). Claude Code uses claude/, Codex uses codex/.
930
+ claude_branch_prefixes:
931
+ - "claude/"
932
+ codex_branch_prefixes:
933
+ - "codex/"
934
+
935
+ # Restrict reviews to PRs opened by these GitHub logins.
936
+ # Auto-filled with your GitHub login by `crosscheck init` or first `crosscheck watch`.
937
+ # Empty = no restriction (all matching PRs reviewed).
938
+ allowed_authors:
939
+ - your-github-login # auto-detected from gh auth
940
+
941
+ # Author-based routing fallback (signal 4) — used when no pattern or prefix matches.
942
+ # Maps GitHub login → vendor origin so crosscheck routes PRs even without
943
+ # the attribution footer (e.g. when creating PRs via gh CLI directly).
944
+ author_routes:
945
+ your-github-login: claude # your PRs → treated as Claude-authored → Codex reviews
946
+
947
+ # ── Tunnel (watch mode only) ──────────────────────────────────────────────────
948
+ # localhost.run (default) — SSH tunnel, zero install, URL changes on reconnect.
949
+ # smee — stable relay via smee.io; events queued while offline.
950
+ # Setup: npm install -g smee-client, visit https://smee.io/new
951
+ tunnel:
952
+ backend: localhost.run
953
+ # backend: smee
954
+ # smee_channel: https://smee.io/your-channel-id
955
+
956
+ # ── Impact reporting ──────────────────────────────────────────────────────────
957
+ # Used by `crosscheck impact` to calculate estimated time and monetary value.
958
+ impact:
959
+ assumed_human_review_minutes: 60 # baseline for time-saved calculation
960
+ hourly_rate_usd: 150 # for --money estimate
961
+ defect_cost_usd: 150 # per issue caught, for --money estimate
962
+
963
+ # ── Post-review auto-fix ──────────────────────────────────────────────────────
964
+ # Controls HOW fixes are delivered. Step sequencing (which steps run, when,
965
+ # and with which vendor) is configured in ~/.crosscheck/workflow.yml.
966
+ post_review:
967
+ auto_fix:
968
+ delivery:
969
+ mode: pull_request # pull_request | commit | comment
970
+ # pull_request → fix PR targets original branch; human approves before merge
971
+ # commit → fixes pushed directly onto the original PR branch
972
+ # comment → suggested fixes posted as review comments only
973
+ pr_title: "fix: address CR issues in #{original_pr_title}"
974
+ label: cr-autofix # GitHub label applied to the fix PR
975
+
976
+ # ── Backtrace ─────────────────────────────────────────────────────────────────
977
+ # On startup, scan all open PRs in the monitored scope and review any that
978
+ # haven't received a [crosscheck] comment yet. Off by default.
979
+ # Enable with:
980
+ # backtrace.enabled: true (persistent — runs every startup)
981
+ # --backtrace flag (this session only)
982
+ # --no-backtrace flag (suppress even when enabled: true)
983
+ # backtrace:
984
+ # enabled: true
985
+
986
+ # ── Server ────────────────────────────────────────────────────────────────────
987
+ server:
988
+ port: 7891
989
+ webhook_path: /webhook
990
+ ```
991
+
992
+ ### Quality tiers
993
+
994
+ | Tier | Speed | Depth | Best for |
995
+ |---|---|---|---|
996
+ | `fast` | ~10s | Top issues only | High-volume repos, draft PRs |
997
+ | `balanced` | ~30s | Full review, all issues explained | Default for most teams |
998
+ | `thorough` | ~60–90s | Deep multi-pass, architecture + security | Before merging to main |
999
+
1000
+ ### Routing patterns
1001
+
1002
+ Patterns are matched against the PR body as case-insensitive regular expressions.
1003
+
1004
+ - `codex_reviews_patterns` — PRs matching these are reviewed by Codex
1005
+ - `claude_reviews_patterns` — PRs matching these are reviewed by Claude
1006
+
1007
+ To also review human PRs, add a catch-all:
1008
+
1009
+ ```yaml
1010
+ routing:
1011
+ codex_reviews_patterns:
1012
+ - "Generated with \\[Claude Code\\]"
1013
+ - ".*" # Codex reviews all PRs
1014
+ ```
1015
+
1016
+ ### Minimal config
1017
+
1018
+ ```yaml
1019
+ mode: cross-vendor
1020
+ ```
1021
+
1022
+ Everything else uses defaults.
1023
+
1024
+ ---
1025
+
1026
+ ## How it works
1027
+
1028
+ ```
1029
+ GitHub repo
1030
+ │ pull_request event (opened / synchronize)
1031
+
1032
+ crosscheck webhook server
1033
+
1034
+ ├─ verify HMAC-SHA256 signature
1035
+ ├─ detect PR origin from body patterns
1036
+ ├─ assign reviewer (opposite vendor in cross-vendor mode)
1037
+
1038
+
1039
+ clone PR branch into temp directory
1040
+
1041
+ ├─ codex review --base <branch> ← non-interactive Codex review
1042
+ │ or
1043
+ └─ claude --print --bare ... ← non-interactive Claude review
1044
+
1045
+
1046
+ post comment to PR via GitHub API
1047
+ delete temp clone
1048
+
1049
+ ▼ post_review.auto_fix (if enabled and issues found)
1050
+ authoring vendor reads review comment
1051
+
1052
+ ├─ claude --print ... (Claude authored the PR)
1053
+ │ or
1054
+ └─ codex ... (Codex authored the PR)
1055
+
1056
+
1057
+ opens fix PR → fix/cr-<pr-number>-review-issues → original branch
1058
+ (you review and merge the fix PR; original PR updates automatically)
1059
+ ```
1060
+
1061
+ ### PR origin detection
1062
+
1063
+ crosscheck uses a four-signal chain to determine whether a PR was authored by Claude Code, Codex, or a human:
1064
+
1065
+ 1. **PR body** — looks for attribution footers (e.g. `Generated with [Claude Code]`)
1066
+ 2. **Commit messages** — scans all commit messages for `Co-Authored-By:` trailers
1067
+ 3. **Branch prefix** — `claude/` → Claude origin; `codex/` → Codex origin
1068
+ 4. **`author_routes`** — per-login fallback in config
1069
+
1070
+ If none match, origin is `human` and the PR is skipped in cross-vendor mode.
1071
+
1072
+ | Default pattern | Matches |
1073
+ |---|---|
1074
+ | `Generated with \[Claude Code\]` | Claude Code attribution footer in PR body |
1075
+ | `Generated with \[OpenAI Codex\]` | Codex attribution footer in PR body |
1076
+ | `Co-Authored-By: Claude` | Commit trailers from Claude Code |
1077
+ | `Co-Authored-By: codex` | Commit trailers from Codex |
1078
+ | branch prefix `claude/` | Branch naming convention for Claude-authored PRs |
1079
+ | branch prefix `codex/` | Branch naming convention for Codex-authored PRs |
1080
+
1081
+ ### Reviewer assignment
1082
+
1083
+ | Mode | PR origin | Reviewer |
1084
+ |---|---|---|
1085
+ | `cross-vendor` | claude | Codex |
1086
+ | `cross-vendor` | codex | Claude |
1087
+ | `cross-vendor` | human | None — skipped |
1088
+ | `single-vendor` | any | First enabled vendor |
1089
+
1090
+ ### How Codex reviews run
1091
+
1092
+ ```bash
1093
+ codex review --base <base-branch> --title "<pr-title>"
1094
+ ```
1095
+
1096
+ The `--base` flag diffs current HEAD against the base branch — exactly the PR diff. With `auth: subscription`, no model flag is passed. With `auth: api-key`, the model is selected by quality tier (`fast` → `gpt-4o-mini`, `balanced` → `o4-mini`, `thorough` → `o3`).
1097
+
1098
+ ### How Claude reviews run
1099
+
1100
+ ```bash
1101
+ claude \
1102
+ --print --bare \
1103
+ --model claude-sonnet-4-6 \
1104
+ --effort medium \
1105
+ --max-budget-usd 2.00 \
1106
+ --output-last-message /tmp/review.md \
1107
+ --allowedTools "Bash(git diff),Bash(git log)" \
1108
+ "<prompt>"
1109
+ ```
1110
+
1111
+ `--bare` makes execution fast and deterministic. `--allowedTools` limits Claude to read-only git operations on the cloned repo.
1112
+
1113
+ ### Deduplication
1114
+
1115
+ **What's implemented today**
1116
+
1117
+ GitHub can fire both `opened` and `synchronize` events for the same push. crosscheck tracks `owner/repo#pr@sha` in an in-memory set and drops duplicate events for the same commit within the same running process.
1118
+
1119
+ **Known gap — concurrent sessions**
1120
+
1121
+ If `crosscheck run <pr-url>` is invoked while a `watch`/`serve` daemon is already reviewing the same PR (or two machines pick up the same webhook), both sessions will pass the current check — which only looks at already-posted comments — and both will post a review. This is a known race condition.
1122
+
1123
+ The fix (file lock for same-machine + GitHub commit status for cross-machine) is tracked as a P0 item and not yet implemented. Until it lands, avoid running `crosscheck run` manually on a PR that your `watch`/`serve` daemon is actively processing.
1124
+
1125
+ ### Watch vs serve
1126
+
1127
+ | | `watch` | `serve` [BETA] |
1128
+ |---|---|---|
1129
+ | Tunnel | `localhost.run` via SSH (no install) | None — direct port |
1130
+ | Webhook | Auto-managed, cleaned up on exit | Manual, permanent |
1131
+ | Scope | Org-level or repo-level | Org-level or repo-level |
1132
+ | Machine | Developer laptop | mac-mini / server |
1133
+ | Lifecycle | Tied to terminal | Daemon / service |
1134
+
1135
+ ### Security
1136
+
1137
+ - **Webhook signature** — every request verified with HMAC-SHA256 before parsing
1138
+ - **Temp isolation** — each PR cloned into a fresh temp dir, deleted after review
1139
+ - **Read-only tools** — Claude restricted to `git diff` and `git log` only
1140
+ - **Temp credential isolation** — with `clone_protocol: ssh` (default) no tokens touch disk; with `clone_protocol: https` a short-lived token is embedded in the temp clone's remote URL and removed when the temp dir is deleted after review
1141
+
1142
+ ---
1143
+
1144
+ ## Post-review auto-fix
1145
+
1146
+ When `post_review.auto_fix.enabled` is `true` (the default), crosscheck completes the full loop automatically after every review that finds issues:
1147
+
1148
+ ```
1149
+ agent opens PR #42 → opposite vendor reviews → issues found?
1150
+ │ yes
1151
+ authoring vendor generates fixes
1152
+
1153
+ fix PR #43 opened → feat/my-feature
1154
+
1155
+ you review and merge PR #43
1156
+
1157
+ PR #42 updates → you merge to main
1158
+ ```
1159
+
1160
+ **Key design decisions:**
1161
+
1162
+ | Setting | Default | Why |
1163
+ |---|---|---|
1164
+ | `fixer: same-as-author` | the vendor that wrote the PR also fixes it | The authoring agent knows its own code and style best |
1165
+ | `delivery: pull_request` | opens a new PR, doesn't push directly | You stay in the loop — no code lands without your approval |
1166
+ | `trigger: on_issues` | only fires when the reviewer found warnings or worse | Skips the fix step on clean PRs |
1167
+ | `min_severity: warning` | ignores info/cosmetic findings | Avoids noisy fix PRs for style-only comments |
1168
+
1169
+ **Fix PR branch naming:** `fix/cr-<original-pr-number>-review-issues`
1170
+
1171
+ **Original PR number:** never changes. The fix PR targets the original branch; once merged, its commits appear in the original PR automatically.
1172
+
1173
+ **To disable:** set `post_review.auto_fix.enabled: false` in your config, or set `trigger: never`.
1174
+
1175
+ ---
1176
+
1177
+ ## FAQ
1178
+
1179
+ ### How does crosscheck improve over time?
1180
+
1181
+ Every review — success or failure — is appended to `~/.crosscheck/logs/YYYY-MM-DD.ndjson`. Running `crosscheck diagnose` reads those logs and surfaces patterns: which commands failed, which reviewer is struggling, which language-specific tools were missing. Running `crosscheck optimize` feeds that report into your best-performing AI agent (guided by the bundled `AGENT.md`) and updates the `instructions` field of the review step in `~/.crosscheck/workflow.yml`. The improvements take effect immediately on the next PR.
1182
+
1183
+ ### Which agent does `crosscheck optimize` use?
1184
+
1185
+ It picks automatically:
1186
+ 1. If only one vendor is enabled in your config → uses that one.
1187
+ 2. Both enabled → whichever has the higher success rate in recent logs.
1188
+ 3. Equal rates or no data → defaults to `claude`.
1189
+ 4. You can always override: `crosscheck optimize --agent codex`.
1190
+
1191
+ The agent used for `optimize` is independent of which agent reviews your PRs — `optimize` is about improving the instructions, not reviewing code.
1192
+
1193
+ ### How do I customize reviewer behavior?
1194
+
1195
+ The primary place is the workflow file. Each step has an `instructions` field that is passed verbatim to the reviewer or fixer agent:
1196
+
1197
+ ```yaml
1198
+ # .crosscheck/workflow.yml
1199
+ steps:
1200
+ - name: review
1201
+ type: review
1202
+ reviewer: auto
1203
+ instructions: |
1204
+ Do not suggest TypeScript patterns — this is a Rust project.
1205
+ Focus on memory safety and error handling.
1206
+ ## Verdict
1207
+ End with: VERDICT: APPROVE | NEEDS_WORK | BLOCK
1208
+ - name: fix
1209
+ type: fix
1210
+ reviewer: origin
1211
+ when: "review.verdict != 'APPROVE'"
1212
+ instructions: "Only fix issues explicitly called out. Do not refactor unrelated code."
1213
+ ```
1214
+
1215
+ `crosscheck optimize --apply` updates the review step's `instructions` field in `~/.crosscheck/workflow.yml` to persist learned improvements across sessions.
1216
+
1217
+ To reset the review step instructions to defaults, delete `~/.crosscheck/workflow.yml` and re-run `crosscheck onboard` — it will regenerate the file with the built-in defaults.
1218
+
1219
+ ### Can I have per-project workflow?
1220
+
1221
+ Yes. Create `.crosscheck/workflow.yml` in your repo root. crosscheck loads it automatically and uses it instead of the built-in default pipeline. This is the recommended way to customize reviewer behavior — it keeps all per-project settings in one file under version control.
1222
+
1223
+ ### What is `AGENT.md`?
1224
+
1225
+ `AGENT.md` is the harness document that guides the AI during `crosscheck optimize`. It defines the input/output contract, language-detection rules, constraint-writing guidelines, and quality principles. It ships bundled with crosscheck so `optimize` works out of the box.
1226
+
1227
+ You can override it by placing an `AGENT.md` at your project root or `.crosscheck/AGENT.md`. crosscheck checks for a local override first, then falls back to the bundled version. This lets teams customize the optimization logic for their specific stack or conventions.
1228
+
1229
+ ### Why did my review fail with "command not found"?
1230
+
1231
+ The reviewer (codex or claude) tried to run a CLI tool (e.g. `tsc`, `pytest`) that isn't available in the temporary clone. The clone is a shallow `git` checkout with no `node_modules` or other installed dependencies. Run `crosscheck diagnose` to see which commands failed, then `crosscheck optimize --apply` to add the appropriate constraints to the review step in `~/.crosscheck/workflow.yml` so the reviewer stops trying.
1232
+
1233
+ ### Why did my review fail with "no such branch"?
1234
+
1235
+ crosscheck fetches the PR base branch (e.g. `staging`) into the temp clone before running the reviewer. If that fetch fails (network issue, branch deleted, insufficient token scope), the reviewer cannot diff correctly. Check:
1236
+ - The base branch exists and is accessible with your token.
1237
+ - Your `GITHUB_TOKEN` has `repo` scope.
1238
+ - The branch name in the PR matches what's on the remote.
1239
+
1240
+ ### How do I use smee.io instead of localhost.run?
1241
+
1242
+ `localhost.run` (the default) drops events if your laptop is offline when GitHub fires the webhook. [smee.io](https://smee.io) queues events and replays them when your laptop reconnects — useful when the reviewer machine isn't always on.
1243
+
1244
+ ```bash
1245
+ npm install -g smee-client
1246
+ ```
1247
+
1248
+ Visit [smee.io/new](https://smee.io/new) and copy the channel URL. Then in `~/.crosscheck/config.yml`:
1249
+
1250
+ ```yaml
1251
+ tunnel:
1252
+ backend: smee
1253
+ smee_channel: https://smee.io/your-channel-id
1254
+ ```
1255
+
1256
+ crosscheck registers the smee channel URL as your GitHub webhook automatically on first `watch` start. The channel URL never changes, so no re-registration is needed on restart. Unlike `localhost.run`, events are queued while you're offline and replayed when you reconnect.
1257
+
1258
+
1259
+ ### Can I disable the auto-fix step?
1260
+
1261
+ Yes. Set `post_review.auto_fix.enabled: false` in your config, or set `trigger: never`. You can also raise `min_severity` to `error` to limit fixes to blocking issues only.
1262
+
1263
+ To push fixes directly without a separate PR (skipping your review), switch to `delivery: commit`. To get suggested fixes as review comments without any code push, use `delivery: comment`.
1264
+
1265
+ ### Why does the fixer use the same vendor that wrote the PR?
1266
+
1267
+ The authoring agent has the most context about its own code — the same style, constraints, and intent behind the original changes. Using `fixer: same-as-author` keeps the feedback loop tight: the agent writes the code, another agent reviews it, the original agent fixes it. You can override this to `same-as-reviewer`, `codex`, or `claude` if you prefer a different arrangement.
1268
+
1269
+ ### Does optimize run automatically?
1270
+
1271
+ No — `crosscheck optimize` is always user-triggered. You run it when you want to improve instructions. There is no background daemon or scheduled job. A future version may add an optional `--schedule` mode, but the default will always be manual to keep you in control of what gets written to `~/.crosscheck/workflow.yml`.