@humanbased/crosscheck 1.2.0 → 1.3.0-beta.100

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 (438) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +183 -375
  3. package/README.zh.md +1 -1
  4. package/assets/icon-256.png +0 -0
  5. package/assets/linear-comment.svg +18 -0
  6. package/assets/linear-onboard.svg +30 -0
  7. package/assets/linear-status.svg +23 -0
  8. package/assets/linear-test.svg +34 -0
  9. package/assets/skills/code-review/.crosscheck-skill.json +9 -0
  10. package/assets/skills/code-review/LICENSE +21 -0
  11. package/assets/skills/code-review/SKILL.md +89 -0
  12. package/assets/skills/code-review/agents/openai.yaml +3 -0
  13. package/assets/skills/code-review-skill/.crosscheck-skill.json +9 -0
  14. package/assets/skills/code-review-skill/LICENSE +21 -0
  15. package/assets/skills/code-review-skill/SKILL.md +231 -0
  16. package/assets/skills/code-review-skill/assets/pr-review-template.md +137 -0
  17. package/assets/skills/code-review-skill/assets/review-checklist.md +123 -0
  18. package/assets/skills/code-review-skill/reference/angular.md +768 -0
  19. package/assets/skills/code-review-skill/reference/architecture-review-guide.md +472 -0
  20. package/assets/skills/code-review-skill/reference/c.md +890 -0
  21. package/assets/skills/code-review-skill/reference/code-quality-universal.md +488 -0
  22. package/assets/skills/code-review-skill/reference/code-review-best-practices.md +136 -0
  23. package/assets/skills/code-review-skill/reference/common-bugs-checklist.md +286 -0
  24. package/assets/skills/code-review-skill/reference/cpp.md +893 -0
  25. package/assets/skills/code-review-skill/reference/cross-cutting/async-concurrency-patterns.md +515 -0
  26. package/assets/skills/code-review-skill/reference/cross-cutting/error-handling-principles.md +492 -0
  27. package/assets/skills/code-review-skill/reference/cross-cutting/n-plus-one-queries.md +309 -0
  28. package/assets/skills/code-review-skill/reference/cross-cutting/sql-injection-prevention.md +308 -0
  29. package/assets/skills/code-review-skill/reference/cross-cutting/xss-prevention.md +264 -0
  30. package/assets/skills/code-review-skill/reference/csharp.md +525 -0
  31. package/assets/skills/code-review-skill/reference/css-less-sass.md +661 -0
  32. package/assets/skills/code-review-skill/reference/django.md +985 -0
  33. package/assets/skills/code-review-skill/reference/fastapi.md +580 -0
  34. package/assets/skills/code-review-skill/reference/go.md +993 -0
  35. package/assets/skills/code-review-skill/reference/java.md +409 -0
  36. package/assets/skills/code-review-skill/reference/java8.md +586 -0
  37. package/assets/skills/code-review-skill/reference/kotlin.md +1018 -0
  38. package/assets/skills/code-review-skill/reference/nestjs.md +593 -0
  39. package/assets/skills/code-review-skill/reference/performance-review-guide.md +816 -0
  40. package/assets/skills/code-review-skill/reference/php.md +684 -0
  41. package/assets/skills/code-review-skill/reference/python.md +1073 -0
  42. package/assets/skills/code-review-skill/reference/qt.md +757 -0
  43. package/assets/skills/code-review-skill/reference/react.md +871 -0
  44. package/assets/skills/code-review-skill/reference/ruby.md +964 -0
  45. package/assets/skills/code-review-skill/reference/rust.md +846 -0
  46. package/assets/skills/code-review-skill/reference/security-review-guide.md +494 -0
  47. package/assets/skills/code-review-skill/reference/svelte.md +1064 -0
  48. package/assets/skills/code-review-skill/reference/swift.md +936 -0
  49. package/assets/skills/code-review-skill/reference/typescript.md +1016 -0
  50. package/assets/skills/code-review-skill/reference/vue.md +924 -0
  51. package/assets/skills/code-review-skill/reference/zig.md +440 -0
  52. package/assets/skills/code-review-skill/scripts/pr-analyzer.py +435 -0
  53. package/assets/skills/code-review-skill/scripts/test_pr_analyzer.py +380 -0
  54. package/assets/skills/codebase-design/.crosscheck-skill.json +9 -0
  55. package/assets/skills/codebase-design/DEEPENING.md +37 -0
  56. package/assets/skills/codebase-design/DESIGN-IT-TWICE.md +44 -0
  57. package/assets/skills/codebase-design/LICENSE +21 -0
  58. package/assets/skills/codebase-design/SKILL.md +114 -0
  59. package/assets/skills/codebase-design/agents/openai.yaml +3 -0
  60. package/assets/skills/diagnosing-bugs/.crosscheck-skill.json +9 -0
  61. package/assets/skills/diagnosing-bugs/LICENSE +21 -0
  62. package/assets/skills/diagnosing-bugs/SKILL.md +134 -0
  63. package/assets/skills/diagnosing-bugs/agents/openai.yaml +3 -0
  64. package/assets/skills/diagnosing-bugs/scripts/hitl-loop.template.sh +41 -0
  65. package/crosscheck.config.example.yml +124 -11
  66. package/dist/__tests__/adoption.test.d.ts +2 -0
  67. package/dist/__tests__/adoption.test.d.ts.map +1 -0
  68. package/dist/__tests__/adoption.test.js +175 -0
  69. package/dist/__tests__/adoption.test.js.map +1 -0
  70. package/dist/__tests__/auto-fix-branch.test.d.ts +2 -0
  71. package/dist/__tests__/auto-fix-branch.test.d.ts.map +1 -0
  72. package/dist/__tests__/auto-fix-branch.test.js +143 -0
  73. package/dist/__tests__/auto-fix-branch.test.js.map +1 -0
  74. package/dist/__tests__/board.test.js +13 -0
  75. package/dist/__tests__/board.test.js.map +1 -1
  76. package/dist/__tests__/can-write-verdict.test.d.ts +2 -0
  77. package/dist/__tests__/can-write-verdict.test.d.ts.map +1 -0
  78. package/dist/__tests__/can-write-verdict.test.js +31 -0
  79. package/dist/__tests__/can-write-verdict.test.js.map +1 -0
  80. package/dist/__tests__/codex-env.test.d.ts +2 -0
  81. package/dist/__tests__/codex-env.test.d.ts.map +1 -0
  82. package/dist/__tests__/codex-env.test.js +70 -0
  83. package/dist/__tests__/codex-env.test.js.map +1 -0
  84. package/dist/__tests__/codex.test.js +100 -25
  85. package/dist/__tests__/codex.test.js.map +1 -1
  86. package/dist/__tests__/comment-bodies.test.js +49 -1
  87. package/dist/__tests__/comment-bodies.test.js.map +1 -1
  88. package/dist/__tests__/commit-subject.test.d.ts +2 -0
  89. package/dist/__tests__/commit-subject.test.d.ts.map +1 -0
  90. package/dist/__tests__/commit-subject.test.js +72 -0
  91. package/dist/__tests__/commit-subject.test.js.map +1 -0
  92. package/dist/__tests__/conflict-resolve.test.js +44 -1
  93. package/dist/__tests__/conflict-resolve.test.js.map +1 -1
  94. package/dist/__tests__/credential-free-origin.test.d.ts +2 -0
  95. package/dist/__tests__/credential-free-origin.test.d.ts.map +1 -0
  96. package/dist/__tests__/credential-free-origin.test.js +59 -0
  97. package/dist/__tests__/credential-free-origin.test.js.map +1 -0
  98. package/dist/__tests__/detector.test.js +87 -1
  99. package/dist/__tests__/detector.test.js.map +1 -1
  100. package/dist/__tests__/error-classification.test.js +34 -0
  101. package/dist/__tests__/error-classification.test.js.map +1 -1
  102. package/dist/__tests__/fix.test.js +69 -0
  103. package/dist/__tests__/fix.test.js.map +1 -1
  104. package/dist/__tests__/harness-section.test.d.ts +2 -0
  105. package/dist/__tests__/harness-section.test.d.ts.map +1 -0
  106. package/dist/__tests__/harness-section.test.js +46 -0
  107. package/dist/__tests__/harness-section.test.js.map +1 -0
  108. package/dist/__tests__/kickass.test.js +31 -0
  109. package/dist/__tests__/kickass.test.js.map +1 -1
  110. package/dist/__tests__/linear-branding.test.d.ts +2 -0
  111. package/dist/__tests__/linear-branding.test.d.ts.map +1 -0
  112. package/dist/__tests__/linear-branding.test.js +156 -0
  113. package/dist/__tests__/linear-branding.test.js.map +1 -0
  114. package/dist/__tests__/linear-client.test.d.ts +2 -0
  115. package/dist/__tests__/linear-client.test.d.ts.map +1 -0
  116. package/dist/__tests__/linear-client.test.js +120 -0
  117. package/dist/__tests__/linear-client.test.js.map +1 -0
  118. package/dist/__tests__/linear-comment.test.d.ts +2 -0
  119. package/dist/__tests__/linear-comment.test.d.ts.map +1 -0
  120. package/dist/__tests__/linear-comment.test.js +151 -0
  121. package/dist/__tests__/linear-comment.test.js.map +1 -0
  122. package/dist/__tests__/linear-identity.test.d.ts +2 -0
  123. package/dist/__tests__/linear-identity.test.d.ts.map +1 -0
  124. package/dist/__tests__/linear-identity.test.js +253 -0
  125. package/dist/__tests__/linear-identity.test.js.map +1 -0
  126. package/dist/__tests__/linear-notify.test.d.ts +2 -0
  127. package/dist/__tests__/linear-notify.test.d.ts.map +1 -0
  128. package/dist/__tests__/linear-notify.test.js +144 -0
  129. package/dist/__tests__/linear-notify.test.js.map +1 -0
  130. package/dist/__tests__/linear-ref.test.d.ts +2 -0
  131. package/dist/__tests__/linear-ref.test.d.ts.map +1 -0
  132. package/dist/__tests__/linear-ref.test.js +261 -0
  133. package/dist/__tests__/linear-ref.test.js.map +1 -0
  134. package/dist/__tests__/linear-test-ref.test.d.ts +2 -0
  135. package/dist/__tests__/linear-test-ref.test.d.ts.map +1 -0
  136. package/dist/__tests__/linear-test-ref.test.js +81 -0
  137. package/dist/__tests__/linear-test-ref.test.js.map +1 -0
  138. package/dist/__tests__/linear-verify.test.d.ts +2 -0
  139. package/dist/__tests__/linear-verify.test.d.ts.map +1 -0
  140. package/dist/__tests__/linear-verify.test.js +132 -0
  141. package/dist/__tests__/linear-verify.test.js.map +1 -0
  142. package/dist/__tests__/linear-worker.test.d.ts +2 -0
  143. package/dist/__tests__/linear-worker.test.d.ts.map +1 -0
  144. package/dist/__tests__/linear-worker.test.js +83 -0
  145. package/dist/__tests__/linear-worker.test.js.map +1 -0
  146. package/dist/__tests__/linear-write-possible.test.d.ts +2 -0
  147. package/dist/__tests__/linear-write-possible.test.d.ts.map +1 -0
  148. package/dist/__tests__/linear-write-possible.test.js +30 -0
  149. package/dist/__tests__/linear-write-possible.test.js.map +1 -0
  150. package/dist/__tests__/loader.test.js +2 -2
  151. package/dist/__tests__/loader.test.js.map +1 -1
  152. package/dist/__tests__/onboard-preservation.test.js +59 -4
  153. package/dist/__tests__/onboard-preservation.test.js.map +1 -1
  154. package/dist/__tests__/optimize.test.js +2 -0
  155. package/dist/__tests__/optimize.test.js.map +1 -1
  156. package/dist/__tests__/pr-status.test.js +213 -3
  157. package/dist/__tests__/pr-status.test.js.map +1 -1
  158. package/dist/__tests__/pr-workflow-state.test.js +247 -7
  159. package/dist/__tests__/pr-workflow-state.test.js.map +1 -1
  160. package/dist/__tests__/repo-picker.test.js +7 -1
  161. package/dist/__tests__/repo-picker.test.js.map +1 -1
  162. package/dist/__tests__/repository-guidance.test.d.ts +2 -0
  163. package/dist/__tests__/repository-guidance.test.d.ts.map +1 -0
  164. package/dist/__tests__/repository-guidance.test.js +107 -0
  165. package/dist/__tests__/repository-guidance.test.js.map +1 -0
  166. package/dist/__tests__/review-comment-body.test.js +35 -0
  167. package/dist/__tests__/review-comment-body.test.js.map +1 -1
  168. package/dist/__tests__/review-models.test.js +19 -3
  169. package/dist/__tests__/review-models.test.js.map +1 -1
  170. package/dist/__tests__/review-strategy.test.d.ts +2 -0
  171. package/dist/__tests__/review-strategy.test.d.ts.map +1 -0
  172. package/dist/__tests__/review-strategy.test.js +397 -0
  173. package/dist/__tests__/review-strategy.test.js.map +1 -0
  174. package/dist/__tests__/reviewed-sha.test.d.ts +2 -0
  175. package/dist/__tests__/reviewed-sha.test.d.ts.map +1 -0
  176. package/dist/__tests__/reviewed-sha.test.js +116 -0
  177. package/dist/__tests__/reviewed-sha.test.js.map +1 -0
  178. package/dist/__tests__/runner.test.js +206 -2
  179. package/dist/__tests__/runner.test.js.map +1 -1
  180. package/dist/__tests__/skill-attribution.test.d.ts +2 -0
  181. package/dist/__tests__/skill-attribution.test.d.ts.map +1 -0
  182. package/dist/__tests__/skill-attribution.test.js +53 -0
  183. package/dist/__tests__/skill-attribution.test.js.map +1 -0
  184. package/dist/__tests__/skill-broker.test.d.ts +2 -0
  185. package/dist/__tests__/skill-broker.test.d.ts.map +1 -0
  186. package/dist/__tests__/skill-broker.test.js +186 -0
  187. package/dist/__tests__/skill-broker.test.js.map +1 -0
  188. package/dist/__tests__/skill-catalog.test.d.ts +2 -0
  189. package/dist/__tests__/skill-catalog.test.d.ts.map +1 -0
  190. package/dist/__tests__/skill-catalog.test.js +40 -0
  191. package/dist/__tests__/skill-catalog.test.js.map +1 -0
  192. package/dist/__tests__/skill-installer.test.d.ts +2 -0
  193. package/dist/__tests__/skill-installer.test.d.ts.map +1 -0
  194. package/dist/__tests__/skill-installer.test.js +96 -0
  195. package/dist/__tests__/skill-installer.test.js.map +1 -0
  196. package/dist/__tests__/skills-config.test.d.ts +2 -0
  197. package/dist/__tests__/skills-config.test.d.ts.map +1 -0
  198. package/dist/__tests__/skills-config.test.js +12 -0
  199. package/dist/__tests__/skills-config.test.js.map +1 -0
  200. package/dist/__tests__/superseded-fix-pr.test.d.ts +2 -0
  201. package/dist/__tests__/superseded-fix-pr.test.d.ts.map +1 -0
  202. package/dist/__tests__/superseded-fix-pr.test.js +225 -0
  203. package/dist/__tests__/superseded-fix-pr.test.js.map +1 -0
  204. package/dist/__tests__/webhook.test.js +60 -0
  205. package/dist/__tests__/webhook.test.js.map +1 -1
  206. package/dist/cli.js +37 -0
  207. package/dist/cli.js.map +1 -1
  208. package/dist/commands/adoption.d.ts +6 -0
  209. package/dist/commands/adoption.d.ts.map +1 -0
  210. package/dist/commands/adoption.js +132 -0
  211. package/dist/commands/adoption.js.map +1 -0
  212. package/dist/commands/detect-step.d.ts.map +1 -1
  213. package/dist/commands/detect-step.js +5 -1
  214. package/dist/commands/detect-step.js.map +1 -1
  215. package/dist/commands/diagnose.d.ts.map +1 -1
  216. package/dist/commands/diagnose.js +2 -2
  217. package/dist/commands/diagnose.js.map +1 -1
  218. package/dist/commands/init.d.ts.map +1 -1
  219. package/dist/commands/init.js +1 -2
  220. package/dist/commands/init.js.map +1 -1
  221. package/dist/commands/issue.js +1 -1
  222. package/dist/commands/issue.js.map +1 -1
  223. package/dist/commands/kickass.d.ts +1 -1
  224. package/dist/commands/kickass.d.ts.map +1 -1
  225. package/dist/commands/kickass.js +36 -22
  226. package/dist/commands/kickass.js.map +1 -1
  227. package/dist/commands/linear-test.d.ts +18 -0
  228. package/dist/commands/linear-test.d.ts.map +1 -0
  229. package/dist/commands/linear-test.js +130 -0
  230. package/dist/commands/linear-test.js.map +1 -0
  231. package/dist/commands/onboard.d.ts +36 -3
  232. package/dist/commands/onboard.d.ts.map +1 -1
  233. package/dist/commands/onboard.js +263 -45
  234. package/dist/commands/onboard.js.map +1 -1
  235. package/dist/commands/optimize.d.ts.map +1 -1
  236. package/dist/commands/optimize.js +1 -0
  237. package/dist/commands/optimize.js.map +1 -1
  238. package/dist/commands/review.d.ts.map +1 -1
  239. package/dist/commands/review.js +65 -6
  240. package/dist/commands/review.js.map +1 -1
  241. package/dist/commands/run.d.ts.map +1 -1
  242. package/dist/commands/run.js +85 -11
  243. package/dist/commands/run.js.map +1 -1
  244. package/dist/commands/scan.d.ts.map +1 -1
  245. package/dist/commands/scan.js +6 -0
  246. package/dist/commands/scan.js.map +1 -1
  247. package/dist/commands/skill.d.ts +2 -0
  248. package/dist/commands/skill.d.ts.map +1 -0
  249. package/dist/commands/skill.js +16 -0
  250. package/dist/commands/skill.js.map +1 -0
  251. package/dist/commands/status.d.ts.map +1 -1
  252. package/dist/commands/status.js +53 -1
  253. package/dist/commands/status.js.map +1 -1
  254. package/dist/commands/watch.d.ts.map +1 -1
  255. package/dist/commands/watch.js +215 -66
  256. package/dist/commands/watch.js.map +1 -1
  257. package/dist/config/loader.d.ts +3 -1
  258. package/dist/config/loader.d.ts.map +1 -1
  259. package/dist/config/loader.js +19 -6
  260. package/dist/config/loader.js.map +1 -1
  261. package/dist/config/review-model-tiers.json +3 -3
  262. package/dist/config/review-strategy.json +204 -0
  263. package/dist/config/schema.d.ts +269 -15
  264. package/dist/config/schema.d.ts.map +1 -1
  265. package/dist/config/schema.js +109 -10
  266. package/dist/config/schema.js.map +1 -1
  267. package/dist/github/client.d.ts +21 -1
  268. package/dist/github/client.d.ts.map +1 -1
  269. package/dist/github/client.js +46 -7
  270. package/dist/github/client.js.map +1 -1
  271. package/dist/github/detector.d.ts.map +1 -1
  272. package/dist/github/detector.js +28 -1
  273. package/dist/github/detector.js.map +1 -1
  274. package/dist/github/merge.d.ts +0 -5
  275. package/dist/github/merge.d.ts.map +1 -1
  276. package/dist/github/merge.js +0 -9
  277. package/dist/github/merge.js.map +1 -1
  278. package/dist/github/reviewed-sha.d.ts +13 -0
  279. package/dist/github/reviewed-sha.d.ts.map +1 -0
  280. package/dist/github/reviewed-sha.js +62 -0
  281. package/dist/github/reviewed-sha.js.map +1 -0
  282. package/dist/github/superseded-fix-pr.d.ts +19 -0
  283. package/dist/github/superseded-fix-pr.d.ts.map +1 -0
  284. package/dist/github/superseded-fix-pr.js +97 -0
  285. package/dist/github/superseded-fix-pr.js.map +1 -0
  286. package/dist/github/webhook.d.ts +8 -1
  287. package/dist/github/webhook.d.ts.map +1 -1
  288. package/dist/github/webhook.js +8 -1
  289. package/dist/github/webhook.js.map +1 -1
  290. package/dist/issues/ticket-ref.d.ts.map +1 -1
  291. package/dist/issues/ticket-ref.js +6 -5
  292. package/dist/issues/ticket-ref.js.map +1 -1
  293. package/dist/lib/adoption.d.ts +64 -0
  294. package/dist/lib/adoption.d.ts.map +1 -0
  295. package/dist/lib/adoption.js +165 -0
  296. package/dist/lib/adoption.js.map +1 -0
  297. package/dist/lib/annotation.d.ts +7 -0
  298. package/dist/lib/annotation.d.ts.map +1 -1
  299. package/dist/lib/annotation.js +11 -8
  300. package/dist/lib/annotation.js.map +1 -1
  301. package/dist/lib/auto-fix-branch.d.ts +35 -0
  302. package/dist/lib/auto-fix-branch.d.ts.map +1 -0
  303. package/dist/lib/auto-fix-branch.js +88 -0
  304. package/dist/lib/auto-fix-branch.js.map +1 -0
  305. package/dist/lib/board.d.ts +3 -0
  306. package/dist/lib/board.d.ts.map +1 -1
  307. package/dist/lib/board.js +4 -2
  308. package/dist/lib/board.js.map +1 -1
  309. package/dist/lib/clone.d.ts +2 -0
  310. package/dist/lib/clone.d.ts.map +1 -1
  311. package/dist/lib/clone.js +69 -10
  312. package/dist/lib/clone.js.map +1 -1
  313. package/dist/lib/comment-bodies.d.ts +37 -0
  314. package/dist/lib/comment-bodies.d.ts.map +1 -1
  315. package/dist/lib/comment-bodies.js +50 -9
  316. package/dist/lib/comment-bodies.js.map +1 -1
  317. package/dist/lib/logger.d.ts.map +1 -1
  318. package/dist/lib/logger.js +17 -1
  319. package/dist/lib/logger.js.map +1 -1
  320. package/dist/lib/pr-picker.d.ts +1 -1
  321. package/dist/lib/pr-picker.d.ts.map +1 -1
  322. package/dist/lib/pr-picker.js +10 -5
  323. package/dist/lib/pr-picker.js.map +1 -1
  324. package/dist/lib/pr-status.d.ts +2 -1
  325. package/dist/lib/pr-status.d.ts.map +1 -1
  326. package/dist/lib/pr-status.js +70 -6
  327. package/dist/lib/pr-status.js.map +1 -1
  328. package/dist/lib/pr-workflow-state.d.ts +17 -1
  329. package/dist/lib/pr-workflow-state.d.ts.map +1 -1
  330. package/dist/lib/pr-workflow-state.js +110 -5
  331. package/dist/lib/pr-workflow-state.js.map +1 -1
  332. package/dist/lib/repo-picker.d.ts +3 -0
  333. package/dist/lib/repo-picker.d.ts.map +1 -1
  334. package/dist/lib/repo-picker.js +45 -10
  335. package/dist/lib/repo-picker.js.map +1 -1
  336. package/dist/lib/repository-guidance.d.ts +2 -0
  337. package/dist/lib/repository-guidance.d.ts.map +1 -0
  338. package/dist/lib/repository-guidance.js +55 -0
  339. package/dist/lib/repository-guidance.js.map +1 -0
  340. package/dist/lib/review-models.d.ts +15 -2
  341. package/dist/lib/review-models.d.ts.map +1 -1
  342. package/dist/lib/review-models.js +26 -6
  343. package/dist/lib/review-models.js.map +1 -1
  344. package/dist/lib/review-strategy.d.ts +92 -0
  345. package/dist/lib/review-strategy.d.ts.map +1 -0
  346. package/dist/lib/review-strategy.js +282 -0
  347. package/dist/lib/review-strategy.js.map +1 -0
  348. package/dist/lib/runner.d.ts +123 -1
  349. package/dist/lib/runner.d.ts.map +1 -1
  350. package/dist/lib/runner.js +919 -101
  351. package/dist/lib/runner.js.map +1 -1
  352. package/dist/lib/vendor.d.ts +1 -0
  353. package/dist/lib/vendor.d.ts.map +1 -1
  354. package/dist/lib/vendor.js +6 -0
  355. package/dist/lib/vendor.js.map +1 -1
  356. package/dist/lib/workflow.d.ts +13 -0
  357. package/dist/lib/workflow.d.ts.map +1 -1
  358. package/dist/lib/workflow.js +24 -1
  359. package/dist/lib/workflow.js.map +1 -1
  360. package/dist/linear/client.d.ts +18 -0
  361. package/dist/linear/client.d.ts.map +1 -0
  362. package/dist/linear/client.js +67 -0
  363. package/dist/linear/client.js.map +1 -0
  364. package/dist/linear/comment.d.ts +20 -0
  365. package/dist/linear/comment.d.ts.map +1 -0
  366. package/dist/linear/comment.js +57 -0
  367. package/dist/linear/comment.js.map +1 -0
  368. package/dist/linear/identity.d.ts +59 -0
  369. package/dist/linear/identity.d.ts.map +1 -0
  370. package/dist/linear/identity.js +187 -0
  371. package/dist/linear/identity.js.map +1 -0
  372. package/dist/linear/notify.d.ts +35 -0
  373. package/dist/linear/notify.d.ts.map +1 -0
  374. package/dist/linear/notify.js +76 -0
  375. package/dist/linear/notify.js.map +1 -0
  376. package/dist/linear/ref.d.ts +13 -0
  377. package/dist/linear/ref.d.ts.map +1 -0
  378. package/dist/linear/ref.js +90 -0
  379. package/dist/linear/ref.js.map +1 -0
  380. package/dist/linear/verify.d.ts +26 -0
  381. package/dist/linear/verify.d.ts.map +1 -0
  382. package/dist/linear/verify.js +67 -0
  383. package/dist/linear/verify.js.map +1 -0
  384. package/dist/reviewers/address.d.ts +1 -1
  385. package/dist/reviewers/address.d.ts.map +1 -1
  386. package/dist/reviewers/address.js +1 -1
  387. package/dist/reviewers/address.js.map +1 -1
  388. package/dist/reviewers/claude.d.ts +4 -1
  389. package/dist/reviewers/claude.d.ts.map +1 -1
  390. package/dist/reviewers/claude.js +39 -7
  391. package/dist/reviewers/claude.js.map +1 -1
  392. package/dist/reviewers/codex-env.d.ts +12 -0
  393. package/dist/reviewers/codex-env.d.ts.map +1 -0
  394. package/dist/reviewers/codex-env.js +54 -0
  395. package/dist/reviewers/codex-env.js.map +1 -0
  396. package/dist/reviewers/codex.d.ts +18 -1
  397. package/dist/reviewers/codex.d.ts.map +1 -1
  398. package/dist/reviewers/codex.js +164 -81
  399. package/dist/reviewers/codex.js.map +1 -1
  400. package/dist/reviewers/conflict-resolve.d.ts +3 -1
  401. package/dist/reviewers/conflict-resolve.d.ts.map +1 -1
  402. package/dist/reviewers/conflict-resolve.js +21 -6
  403. package/dist/reviewers/conflict-resolve.js.map +1 -1
  404. package/dist/reviewers/fix.d.ts +5 -2
  405. package/dist/reviewers/fix.d.ts.map +1 -1
  406. package/dist/reviewers/fix.js +38 -12
  407. package/dist/reviewers/fix.js.map +1 -1
  408. package/dist/skills/attribution.d.ts +4 -0
  409. package/dist/skills/attribution.d.ts.map +1 -0
  410. package/dist/skills/attribution.js +14 -0
  411. package/dist/skills/attribution.js.map +1 -0
  412. package/dist/skills/broker-server.d.ts +2 -0
  413. package/dist/skills/broker-server.d.ts.map +1 -0
  414. package/dist/skills/broker-server.js +17 -0
  415. package/dist/skills/broker-server.js.map +1 -0
  416. package/dist/skills/broker.d.ts +43 -0
  417. package/dist/skills/broker.d.ts.map +1 -0
  418. package/dist/skills/broker.js +311 -0
  419. package/dist/skills/broker.js.map +1 -0
  420. package/dist/skills/catalog.d.ts +28 -0
  421. package/dist/skills/catalog.d.ts.map +1 -0
  422. package/dist/skills/catalog.js +104 -0
  423. package/dist/skills/catalog.js.map +1 -0
  424. package/dist/skills/installer.d.ts +10 -0
  425. package/dist/skills/installer.d.ts.map +1 -0
  426. package/dist/skills/installer.js +138 -0
  427. package/dist/skills/installer.js.map +1 -0
  428. package/dist/skills/integrity.d.ts +4 -0
  429. package/dist/skills/integrity.d.ts.map +1 -0
  430. package/dist/skills/integrity.js +36 -0
  431. package/dist/skills/integrity.js.map +1 -0
  432. package/docs/dynamic-thoroughness.md +738 -0
  433. package/docs/linear-identity-contract.md +139 -0
  434. package/docs/linear-identity.md +293 -0
  435. package/docs/metrics.md +115 -0
  436. package/docs/trust.md +159 -0
  437. package/get-started.md +322 -16
  438. package/package.json +6 -3
package/get-started.md CHANGED
@@ -22,9 +22,11 @@
22
22
  - [Multi-PR syntax](#multi-pr-syntax)
23
23
  - [watch](#crosscheck-watch)
24
24
  - [status](#crosscheck-status)
25
+ - [skill install](#crosscheck-skill-install-source)
25
26
  - [diagnose](#crosscheck-diagnose)
26
27
  - [optimize](#crosscheck-optimize)
27
28
  - [impact](#crosscheck-impact)
29
+ - [adoption](#crosscheck-adoption)
28
30
  - [issue](#crosscheck-issue)
29
31
  - [Configuration](#configuration)
30
32
  - [How it works](#how-it-works)
@@ -156,6 +158,52 @@ export LINEAR_API_KEY=lin_api_...
156
158
  If it's unset while enrichment is on, crosscheck just skips enrichment and
157
159
  reviews the diff as usual — it never errors.
158
160
 
161
+ ### Linear identity — for writing back to Linear (optional)
162
+
163
+ Separate from enrichment above, which only *reads*. When `linear.enabled: true`,
164
+ crosscheck mirrors each review verdict onto the PR's Linear issue.
165
+
166
+ `crosscheck onboard` asks which rung of the attribution ladder you want and writes
167
+ the config for you.
168
+
169
+ **Start with `api_key`.** It reuses `LINEAR_API_KEY`, works immediately, and posts
170
+ the comment — the feature is fully functional. Comments attribute to your Linear
171
+ account, led by a `🤖 crosscheck · <model>` signature line.
172
+
173
+ Climb to `client_credentials` when more than one thing writes to your workspace and
174
+ you need them told apart. It uses an OAuth app — one per workspace, not per user —
175
+ so comments post as crosscheck itself with its own icon:
176
+
177
+ ```bash
178
+ export LINEAR_CLIENT_ID=...
179
+ export LINEAR_CLIENT_SECRET=...
180
+ ```
181
+
182
+ A failed T1 token mint aborts the run rather than falling back to `api_key` —
183
+ a silent downgrade would put agent writes back under a human's name.
184
+
185
+ `crosscheck onboard` walks you through the choice:
186
+
187
+ <p align="center">
188
+ <img src="./assets/linear-onboard.svg" alt="crosscheck onboard — choosing a Linear attribution rung" width="700" />
189
+ </p>
190
+
191
+ Before opening a PR, `crosscheck linear-test` exercises the whole path and posts nothing —
192
+ identity, issue lookup, verdict filter, and the exact comment body:
193
+
194
+ <p align="center">
195
+ <img src="./assets/linear-test.svg" alt="crosscheck linear-test — dry-run verification" width="700" />
196
+ </p>
197
+
198
+ `crosscheck status` shows which rung is active whenever `linear.enabled` is true:
199
+
200
+ <p align="center">
201
+ <img src="./assets/linear-status.svg" alt="crosscheck status — the Linear identity section" width="620" />
202
+ </p>
203
+
204
+ Full walkthrough, including the two Linear UI gotchas that trip people up:
205
+ [docs/linear-identity.md](docs/linear-identity.md).
206
+
159
207
  ---
160
208
 
161
209
  ## Step 1 — Check your setup
@@ -188,6 +236,8 @@ crosscheck review https://github.com/owner/repo/pull/123 --reviewer codex
188
236
 
189
237
  If this step fails, fix the specific auth, clone, reviewer, or comment-posting error before enabling `watch`.
190
238
 
239
+ If you'd rather nothing be written to the PR on a first run, use `crosscheck run <pr-url> --dry-run` instead: it clones, reviews, and prints the comment it would post without touching GitHub. (`--dry-run` lives on `run`, `fix`, `recheck`, and `resolve` — not on `review`, which always posts.) [docs/trust.md](./docs/trust.md) covers what leaves your machine at each step, which permissions each command needs, and exactly what `watch` can change.
240
+
191
241
  ## Step 3 — Choose a deployment mode
192
242
 
193
243
  After one-shot review works, run the guided setup:
@@ -345,6 +395,8 @@ crosscheck onboard --reconfigure # re-run setup even if config already exists
345
395
 
346
396
  **Step 6 — Review quality.** Choose the speed/thoroughness tier for review prompts and reviewer timeouts.
347
397
 
398
+ **Step 6.5 — Agent skills.** Choose which preloaded or custom-installed skills are enabled for coding agents. New setups preselect `code-review-skill (by @awesome-skills, MIT)` and `diagnosing-bugs (by @mattpocock, MIT)`. Matt Pocock's `code-review` and `codebase-design` are available but off by default. Re-running onboard preserves your selection. Skills are made available across workflow operations, and each skill's description plus the coding agent decides when it applies.
399
+
348
400
  **Step 7 — Workflow pipeline.** Choose what happens after a review:
349
401
 
350
402
  ```
@@ -398,6 +450,12 @@ crosscheck onboard
398
450
  [1] fast [2] balanced [3] thorough
399
451
  Choice [2]: 2
400
452
 
453
+ Step 6.5 — agent skills
454
+ [ ] code-review (by @mattpocock, MIT)
455
+ [x] code-review-skill (by @awesome-skills, MIT)
456
+ [x] codebase-design (by @mattpocock, MIT)
457
+ [x] diagnosing-bugs (by @mattpocock, MIT)
458
+
401
459
  Step 7 — workflow pipeline
402
460
  [1] review only [2] review → fix [3] review → fix → re-check
403
461
  Choice [2]: 3
@@ -473,6 +531,8 @@ crosscheck alter humanbased-ai/xny-monorepo --reset # remove th
473
531
 
474
532
  The depths differ in what happens after the initial review:
475
533
 
534
+ In every depth, an `APPROVE` stops all work on the commit it covers, and a later push re-opens the PR — see [What happens after a PR is approved?](#what-happens-after-a-pr-is-approved).
535
+
476
536
  - **`review`** — review each new SHA; never modify code.
477
537
  - **`review,fix`** — crosscheck auto-applies fixes when the verdict isn't `APPROVE`, and stops there; its own fix commit is not re-reviewed.
478
538
  - **`review,fix,recheck`** — same, then rechecks its own fix commit. `max_rounds` in `~/.crosscheck/workflow.yml` bounds that fix→recheck cycle.
@@ -624,7 +684,7 @@ crosscheck scan --json
624
684
 
625
685
  ### `crosscheck kickass`
626
686
 
627
- Selects all actionable PRs (any PR where a next step is needed: review, fix, recheck) and advances each one. Stale PRs are shown first. APPROVE PRs appear as a read-only "needs merge (manual)" section — visible so you know what's ready, but not dispatched automatically. The command revalidates the PR head before each mutation and prints an execution summary when it finishes.
687
+ Selects all actionable PRs (any PR where a next step is needed: resolve, review, fix, recheck) and advances each one. A PR with merge conflicts is dispatched as a `resolve` leg first — conflicts block everything downstream, and a base-branch move that conflicts a PR fires no webhook, so a scan is the only thing that notices. Stale PRs are shown first. APPROVE PRs appear as a read-only "needs merge (manual)" section — visible so you know what's ready, but not dispatched automatically. The command revalidates the PR head before each mutation and prints an execution summary when it finishes.
628
688
 
629
689
  Each PR dispatch uses `detect-step` to read live PR comment history and advances **exactly the next needed step** — kickass drives one step per PR, then `watch` picks up continuation via the webhooks that step produces.
630
690
 
@@ -721,6 +781,8 @@ crosscheck status
721
781
  Config
722
782
  mode cross-vendor
723
783
  quality tier balanced
784
+ installed skills code-review (by @mattpocock, MIT), code-review-skill (by @awesome-skills, MIT), codebase-design (by @mattpocock, MIT), diagnosing-bugs (by @mattpocock, MIT)
785
+ enabled skills code-review-skill (by @awesome-skills, MIT), diagnosing-bugs (by @mattpocock, MIT)
724
786
  codex auth subscription
725
787
  claude model sonnet
726
788
  per-review budget $2.00/review
@@ -744,6 +806,41 @@ crosscheck status
744
806
 
745
807
  ---
746
808
 
809
+ ### `crosscheck skill install <source>`
810
+
811
+ Installs an Agent Skill from a Git URL or local directory into `~/.crosscheck/skills`. Crosscheck validates `SKILL.md`, rejects unsafe names and symbolic links, and records source, revision, author, license, and package integrity. Installation does not enable a skill automatically.
812
+
813
+ Crosscheck itself ships with this preloaded catalog:
814
+
815
+ | Skill | Onboarding default | Best fit |
816
+ |---|---:|---|
817
+ | [`code-review-skill`](https://github.com/awesome-skills/code-review-skill) (by `@awesome-skills`, MIT) | On | General default: broad language, correctness, security, performance, and architecture coverage |
818
+ | [`codebase-design`](https://github.com/mattpocock/skills/tree/main/skills/engineering/codebase-design) (by `@mattpocock`, MIT) | On | Architecture-heavy changes: deep modules, small interfaces, clean seams, and testability |
819
+ | [`diagnosing-bugs`](https://github.com/mattpocock/skills/tree/main/skills/engineering/diagnosing-bugs) (by `@mattpocock`, MIT) | On | Hard bugs and regressions: reproducible signals, ranked hypotheses, and regression evidence |
820
+ | [`code-review`](https://github.com/mattpocock/skills/tree/main/skills/engineering/code-review) (by `@mattpocock`, MIT) | Off | Evidence-rich repositories: separately checks documented standards and issue/PRD fidelity |
821
+
822
+ `code-review` and `code-review-skill` are competing review baselines. The onboarding picker highlights the conflict and will not enable one until the selected counterpart is deselected; the runtime broker also rejects activation of a second baseline. The other bundled skills are complementary.
823
+
824
+ ```bash
825
+ crosscheck skill install https://github.com/owner/my-skill.git
826
+ crosscheck skill install /path/to/my-skill
827
+ crosscheck onboard # enable installed skills
828
+ ```
829
+
830
+ The Git repository or local directory must have `SKILL.md` at its root. For a skill nested in a monorepo, clone it and pass the nested local directory.
831
+
832
+ `crosscheck status` distinguishes the full installed catalog from the enabled selection and renders attributed identities as `skill-name (by @author, license)`.
833
+
834
+ At runtime, Crosscheck distinguishes three states: **installed** skills are in the catalog, **enabled** skills are available to agents, and **activated** skills were actually loaded for one workflow step. A skill becomes activated only when the agent successfully calls the Crosscheck broker's `activate_skill` tool for an enabled skill and receives its `SKILL.md` instructions. Listing enabled skills, seeing a skill description, or merely enabling a skill does not count.
835
+
836
+ Activation is scoped to one step session, such as review, fix, recheck, or conflict resolution. Repeated activation in that session is idempotent, and the receipt survives retries or a reviewer fallback within the same step. Every later step gets a separate empty session, and Crosscheck deletes all step sessions when the workflow run ends. The terminal, logs, and PR comment preserve the completed step's attribution as historical evidence; they do not pre-activate future sessions. For example: `code-review-skill (by @awesome-skills, MIT)`.
837
+
838
+ Upgrading from an earlier Crosscheck release is opt-in: existing configs default to `skills.enabled: []`. Re-run `crosscheck onboard` to choose the recommended bundle or any additional installed skills.
839
+
840
+ Review and recheck also honor repository practices in `AGENTS.md` and `CLAUDE.md`. These repository-defined practices take precedence over bundled skill advice. Crosscheck reads the root files plus any nested files whose directory contains a changed path, orders them from broadest to most specific, and lets nested guidance override root guidance. It reads these files from the PR's base branch and disables vendor-native discovery for the run, so guidance added or modified by the PR cannot influence its own review.
841
+
842
+ ---
843
+
747
844
  ### `crosscheck diagnose`
748
845
 
749
846
  Reads `~/.crosscheck/logs/` and surfaces failure patterns, reviewer performance, and improvement suggestions.
@@ -884,6 +981,65 @@ crosscheck impact (all time · 47 reviews)
884
981
  | `--json` | Output the full report as JSON |
885
982
  | `-c, --config <path>` | Config file path |
886
983
 
984
+ ---
985
+
986
+ ### `crosscheck adoption`
987
+
988
+ Reports whether crosscheck is actually being used, and how long a PR waits for a verdict. Where `impact` prices reviews that happened, `adoption` measures activation and reach. Reads from `~/.crosscheck/logs/` — no network calls, nothing transmitted.
989
+
990
+ ```bash
991
+ crosscheck adoption
992
+ crosscheck adoption --since 2026-07-01
993
+ crosscheck adoption --json
994
+ ```
995
+
996
+ ```
997
+ crosscheck adoption (2026-06-15 → 2026-07-14)
998
+
999
+ Activation
1000
+ ──────────────────────────────────────────────
1001
+ onboard started 3
1002
+ onboard completed 2
1003
+ abandoned 1
1004
+
1005
+ Usage
1006
+ ──────────────────────────────────────────────
1007
+ reviews started 51
1008
+ reviews completed 47
1009
+ rechecks completed 12
1010
+ blocking findings posted 19
1011
+ fixes applied 11
1012
+ active repos 6
1013
+
1014
+ Weekly active repos
1015
+ ──────────────────────────────────────────────
1016
+ 2026-06-22 ████████ 3 repos 14 reviews
1017
+ 2026-06-29 ████████████ 4 repos 18 reviews
1018
+ 2026-07-06 ████████████████ 6 repos 15 reviews
1019
+
1020
+ PR open → verdict
1021
+ ──────────────────────────────────────────────
1022
+ median 22m
1023
+ p90 1.8h
1024
+ slowest 2d
1025
+ measured on 41 verdicts
1026
+ ⓘ 6 verdicts had no PR open time in the event — excluded
1027
+
1028
+ First-run failures (sessions that never reached a verdict)
1029
+ ──────────────────────────────────────────────
1030
+ auth 2
1031
+
1032
+ ⓘ derived from local logs only (30d retention) — nothing is transmitted. See docs/metrics.md
1033
+ ```
1034
+
1035
+ | Flag | Description |
1036
+ |---|---|
1037
+ | `--since <YYYY-MM-DD>` | Limit the analysis to logs from this date onward |
1038
+ | `--json` | Output the full report as JSON |
1039
+ | `-c, --config <path>` | Config file path |
1040
+
1041
+ Every field these numbers are derived from is inventoried in **[docs/metrics.md](./docs/metrics.md)**, including what is deliberately never written to disk.
1042
+
887
1043
  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`.
888
1044
 
889
1045
  ---
@@ -965,7 +1121,7 @@ If no errors are found in recent logs, crosscheck prints `No errors found in rec
965
1121
 
966
1122
  On re-runs, `onboard` updates only the fields it collected answers for. Everything else survives unchanged.
967
1123
 
968
- **Updated on every run:** `deployment`, `orgs`, `repos`, `mode`, `clone_protocol`, `vendors.*.enabled`, `vendors.*.effort`, `quality.tier`, `tunnel.*`, `post_review.auto_fix.*`
1124
+ **Updated on every run:** `deployment`, `orgs`, `repos`, `mode`, `clone_protocol`, `vendors.*.enabled`, `vendors.*.effort`, `quality.tier`, `skills.enabled`, `tunnel.*`, `post_review.auto_fix.*`
969
1125
 
970
1126
  **Never touched by onboard:** per-repo overrides in `~/.crosscheck/workflows/` (owned by `crosscheck alter`), and `~/.crosscheck/workflow.yml` after its first write
971
1127
 
@@ -1015,7 +1171,8 @@ vendors:
1015
1171
  codex:
1016
1172
  enabled: true
1017
1173
  auth: subscription # subscription | api-key
1018
- model: gpt-5.6-terra # only used when auth: api-key
1174
+ model: gpt-5.6-terra # pins the review model; unset = tier model (api-key) / CLI default (subscription)
1175
+ effort: medium # low | medium | high | xhigh | max | ultra (ultra: terra/sol only)
1019
1176
  # timeout_sec: 1200 # max seconds per CLI call; unset = tier-based (300/600/1200)
1020
1177
 
1021
1178
  claude:
@@ -1026,7 +1183,8 @@ vendors:
1026
1183
 
1027
1184
  # ── Quality ───────────────────────────────────────────────────────────────────
1028
1185
  quality:
1029
- tier: balanced # fast | balanced | thorough
1186
+ mode: smart # smart (default) | fixed see Review thoroughness
1187
+ tier: balanced # fast | balanced | thorough (fallback under smart)
1030
1188
  focus: # narrows review scope (optional)
1031
1189
  - security
1032
1190
  - types
@@ -1034,6 +1192,27 @@ quality:
1034
1192
  custom_prompt: | # appended to every review prompt
1035
1193
  Be concise. Flag only issues that would block a merge.
1036
1194
 
1195
+ # ── Agent skills ──────────────────────────────────────────────────────────────
1196
+ # Enabled means available to every coding-agent operation. The skill description
1197
+ # and agent decide whether to activate it for a particular step.
1198
+ skills:
1199
+ enabled:
1200
+ - code-review-skill # recommended · @awesome-skills, MIT
1201
+ - diagnosing-bugs # recommended · @mattpocock, MIT
1202
+ # - code-review # preloaded, opt-in · @mattpocock, MIT
1203
+ # - codebase-design # preloaded, opt-in · @mattpocock, MIT
1204
+
1205
+ # Codex only. Codex reaches the skill broker (an MCP server) only when its
1206
+ # sandbox is disabled: under -s read-only, -s workspace-write, -a never and
1207
+ # --full-auto alike it cancels every tool call, so skills silently do nothing.
1208
+ # Turning this on lets codex run unsandboxed against the PR checkout — which is
1209
+ # untrusted code — in exchange for skills actually working. Crosscheck removes
1210
+ # the git credential from the checkout and passes codex an allowlisted
1211
+ # environment (no GITHUB_TOKEN) either way, but a prompt injection can still
1212
+ # read the working tree and reach the network. Claude needs none of this: its
1213
+ # broker works sandboxed.
1214
+ codex_full_access: false
1215
+
1037
1216
  # ── Budget ────────────────────────────────────────────────────────────────────
1038
1217
  budget:
1039
1218
  codex_monthly_usd: 20 # null = unlimited; only applies when auth: api-key
@@ -1070,6 +1249,13 @@ routing:
1070
1249
  # 2. Commit message Co-Authored-By: trailers (API call, non-fatal if it fails)
1071
1250
  # 3. Branch prefix (claude/ or codex/)
1072
1251
  # 4. author_routes fallback (last resort)
1252
+ # These say who WROTE the code, not who reviewed it.
1253
+ #
1254
+ # Crosscheck's own attribution — its fix-PR footer and `Crosscheck-Reviewer`
1255
+ # commit trailers — is recognised ALWAYS, whatever you put here. Setting either
1256
+ # list replaces the defaults, so if these markers lived in the list a pinned
1257
+ # config would misread crosscheck's own fix PRs as human-authored. Your patterns
1258
+ # are checked first and still win.
1073
1259
  codex_reviews_patterns:
1074
1260
  - "Generated with \\[Claude Code\\]" # Claude Code attribution footer
1075
1261
  - "Co-Authored-By: Claude" # commit trailer
@@ -1118,8 +1304,9 @@ post_review:
1118
1304
  auto_fix:
1119
1305
  delivery:
1120
1306
  mode: pull_request # pull_request | commit | comment
1121
- # pull_request → fix PR targets original branch; human approves before merge
1122
- # commit → fixes pushed directly onto the original PR branch
1307
+ # pull_request → fixes land on the original PR branch; a separate fix PR is
1308
+ # opened only if that push can't land (branch merged/deleted/protected)
1309
+ # commit → fixes pushed directly onto the original PR branch (no fallback)
1123
1310
  # comment → suggested fixes posted as review comments only
1124
1311
  pr_title: "fix: address CR issues in #{original_pr_title}"
1125
1312
  label: cr-autofix # GitHub label applied to the fix PR
@@ -1144,15 +1331,93 @@ post_review:
1144
1331
  server:
1145
1332
  port: 7891
1146
1333
  webhook_path: /webhook
1147
- ```
1334
+
1335
+ linear: # write review verdicts back to a Linear issue (opt-in)
1336
+ enabled: false
1337
+ auth:
1338
+ mode: api_key # api_key | client_credentials
1339
+ api_key_env: LINEAR_API_KEY
1340
+ client_id_env: LINEAR_CLIENT_ID
1341
+ client_secret_env: LINEAR_CLIENT_SECRET
1342
+ scopes: "read,write" # comma-separated; initiative:* are separate scopes
1343
+ identity:
1344
+ actor: crosscheck
1345
+ signature: "🤖 {actor} · {model}" # {actor} {product} {model} {reviewer} {icon}
1346
+ icon_url: "" # rendered where {icon} appears; app avatar is preferred
1347
+ per_step_actor: true # crosscheck/review vs crosscheck/fix in Linear
1348
+ comment_on: # verdicts mirrored to the issue (default omits APPROVE)
1349
+ - NEEDS_WORK
1350
+ - BLOCK
1351
+ team_keys: [] # e.g. [IN] — required to match bare refs like IN-42
1352
+ ```
1353
+
1354
+ ### Review thoroughness
1355
+
1356
+ **`quality.mode: smart` is the default.** Crosscheck classifies each PR from its
1357
+ changed-file list and adjusts model and effort to match, rather than applying one
1358
+ tier to everything. Classification runs on the already-cloned working copy, so it
1359
+ costs one `git diff` and no API call. Set `mode: fixed` to opt out.
1360
+
1361
+ | # | PR class | Detected by | Tier | Steps |
1362
+ |---|---|---|---|---|
1363
+ | 1 | Generated / vendored | every file is a lockfile or build output | — | **PR skipped** |
1364
+ | 2 | Security / data-critical | auth, crypto, payment, migration paths; `risk:T3`; hotfix→default | `thorough` | full loop |
1365
+ | 3 | Deletion-only | ≤ 5 additions with ≥ 20 deletions | `fast` | review |
1366
+ | 4 | Docs / spec | ≥ 50% Markdown | `balanced` | review |
1367
+ | 5 | Test-only | every file is a test | `fast` | review, fix |
1368
+ | 6 | Config / infra | ≥ 50% config, no source | `balanced` | full loop |
1369
+ | 7 | Trivial | ≤ 3 files, ≤ 150 lines | `fast` | review, fix |
1370
+ | 8 | Standard | everything else | `balanced` | full loop |
1371
+
1372
+ First match wins, and security sits second so it dominates every cheapening rule
1373
+ below it — a deletion that removes auth code, or a two-file migration, is never
1374
+ routed to `fast`.
1375
+
1376
+ The class's step set narrows the configured pipeline and never widens it, so a
1377
+ repo pinned to review-only with `crosscheck alter` stays review-only. Rounds past
1378
+ the first escalate on measured non-convergence: effort rises where the model
1379
+ supports it, the tier is promoted where it does not.
1380
+
1381
+ Note that classes 3 and 4 narrow to `review` alone, which also drops
1382
+ `conflict-resolve` — review-only never touches code, and auto-conflict-resolve
1383
+ is code modification. That rule normally follows an operator's explicit
1384
+ `crosscheck alter --review-only`; under smart mode the *classifier* can reach it
1385
+ too, so a docs-only or deletion-only PR with a merge conflict is reviewed but not
1386
+ auto-resolved. Set `mode: fixed` if you want auto-conflict-resolve on every PR.
1387
+
1388
+ Every comment cites the policy that produced it:
1389
+
1390
+ ```
1391
+ <!-- crosscheck: … verdict=BLOCK strategy=1.1.0 class=risky tier=thorough … -->
1392
+ ```
1393
+
1394
+ > **Leave `vendors.*.model` unset under smart mode.** An explicit model outranks
1395
+ > the strategy, so pinning one makes per-PR selection a no-op. When that happens
1396
+ > crosscheck **withholds** the tier from the comment rather than citing one that
1397
+ > did not run. `crosscheck onboard` clears the pin — and prints what it cleared —
1398
+ > when you choose smart.
1399
+
1400
+ Verify the policy is current with `npm run verify:strategy`. Full rationale:
1401
+ [docs/dynamic-thoroughness.md](./docs/dynamic-thoroughness.md).
1148
1402
 
1149
1403
  ### Quality tiers
1150
1404
 
1151
- | Tier | Speed | Depth | Best for |
1152
- |---|---|---|---|
1153
- | `fast` | ~10s | Top issues only | High-volume repos, draft PRs |
1154
- | `balanced` | ~30s | Full review, all issues explained | Default for most teams |
1155
- | `thorough` | ~60–90s | Deep multi-pass, architecture + security | Before merging to main |
1405
+ Under `fixed`, the tier applies to every call. Under `smart`, it is the fallback
1406
+ when a PR's file list cannot be read.
1407
+
1408
+ | Tier | Claude | Codex | Cost per review | Best for |
1409
+ |---|---|---|---|---|
1410
+ | `fast` | Haiku 4.5 | GPT-5.6 Luna | $0.24 · $0.06 | High-volume repos, draft PRs |
1411
+ | `balanced` | Sonnet 5 | GPT-5.6 Terra | $0.72 · $0.58 | Default for most teams |
1412
+ | `thorough` | Opus 5 | GPT-5.6 Sol | $1.20 · $1.44 | Before merging to main |
1413
+
1414
+ Cost is output-token cost at 48k output tokens, the measured median for one
1415
+ review. A review is an agentic session, not a single call — expect 10–16 minutes
1416
+ of wall clock (median 643s, p90 984s across 43 logged runs). Tier changes depth
1417
+ and the subprocess timeout, not seconds-scale latency.
1418
+
1419
+ `claude-fable-5` is banned from review: 2× Opus 5's price for a lower coding
1420
+ benchmark score.
1156
1421
 
1157
1422
  ### Issue enrichment
1158
1423
 
@@ -1274,7 +1539,9 @@ If none match, origin is `human` and the PR is skipped in cross-vendor mode.
1274
1539
  codex review --base <base-branch> --title "<pr-title>"
1275
1540
  ```
1276
1541
 
1277
- 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-5.6-luna`, `balanced` → `gpt-5.6-terra`, `thorough` → `gpt-5.6-sol`).
1542
+ The `--base` flag diffs current HEAD against the base branch — exactly the PR diff. An explicit `vendors.codex.model` (or matching `model_tiers` entry) is passed as `-c model=...` under either auth mode. When unset: `auth: subscription` passes no model flag (the Codex CLI picks its default), while `auth: api-key` selects the model by quality tier (`fast` → `gpt-5.6-luna`, `balanced` → `gpt-5.6-terra`, `thorough` → `gpt-5.6-sol`).
1543
+
1544
+ Reasoning effort comes from `vendors.codex.effort` and is always passed through as `-c model_reasoning_effort=...` — for the review step and for the auto-fix step (`codex exec`) alike. The values match the codex CLI tiers 1:1 — `low` (Light), `medium`, `high`, `xhigh` (Extra High), `max`, `ultra`. Not every model supports every tier: `ultra` is terra/sol only, and pre-5.6 models stop at `xhigh` — the CLI rejects unsupported combinations. Higher tiers can multiply review wall-clock time; pair them with `timeout_sec`.
1278
1545
 
1279
1546
  ### How Claude reviews run
1280
1547
 
@@ -1289,7 +1556,16 @@ claude \
1289
1556
  "<prompt>"
1290
1557
  ```
1291
1558
 
1292
- `--bare` makes execution fast and deterministic. `--allowedTools` limits Claude to read-only git operations on the cloned repo.
1559
+ `--bare` makes execution fast and deterministic. `--allowedTools` limits Claude to read-only git operations on the cloned repo. `vendors.claude.effort` drives `--effort` for every Claude step — review, recheck, auto-fix and conflict-resolve.
1560
+
1561
+ Every comment crosscheck posts closes with the model and effort the step actually ran with, plus any skills the agent activated:
1562
+
1563
+ ```
1564
+ ---
1565
+ _Reviewed with Claude Code via Crosscheck_ _(Opus 5 · high effort)_
1566
+
1567
+ _Skills: code-review-skill (by @awesome-skills, MIT)_
1568
+ ```
1293
1569
 
1294
1570
  ### Deduplication
1295
1571
 
@@ -1309,6 +1585,9 @@ The fix (file lock for same-machine + GitHub commit status for cross-machine) is
1309
1585
  - **Temp isolation** — each PR cloned into a fresh temp dir, deleted after review
1310
1586
  - **Read-only tools** — Claude restricted to `git diff` and `git log` only
1311
1587
  - **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
1588
+ - **Skill package validation** — installs reject unsafe names, attribution injection, symbolic links, packages over 1,000 files or 10 MiB, and collisions; Git sources record their checked-out commit
1589
+ - **Skill integrity** — Crosscheck verifies every installed package against its SHA-256 receipt before exposing it to agents; modified or malformed packages fail closed and appear as unavailable in `crosscheck status`
1590
+ - **Skill execution boundary** — the activation broker exposes instructions and referenced files but never executes bundled scripts itself. Skills are third-party instructions: inspect their source and license before enabling them; the selected coding agent still operates under its normal sandbox and permissions
1312
1591
 
1313
1592
  ---
1314
1593
 
@@ -1333,7 +1612,7 @@ agent opens PR #42 → opposite vendor reviews → issues found?
1333
1612
  | Setting | Default | Why |
1334
1613
  |---|---|---|
1335
1614
  | `fixer: same-as-author` | the vendor that wrote the PR also fixes it | The authoring agent knows its own code and style best |
1336
- | `delivery: pull_request` | opens a new PR, doesn't push directly | You stay in the loop no code lands without your approval |
1615
+ | `delivery: pull_request` | pushes the fix onto the PR's own branch, so the fix, recheck, and approval stay on one PR; opens a separate fix PR only when that push can't land | Keeps everything on the original PR while still covering merged/protected branches |
1337
1616
  | `trigger: on_issues` | only fires when the reviewer found warnings or worse | Skips the fix step on clean PRs |
1338
1617
  | `min_severity: warning` | ignores info/cosmetic findings | Avoids noisy fix PRs for style-only comments |
1339
1618
 
@@ -1448,11 +1727,38 @@ Each cycle is one `[crosscheck]` fix commit followed by one recheck. The loop st
1448
1727
 
1449
1728
  `max_rounds` is respected by both `crosscheck watch` and `crosscheck run`. `watch` re-triggers on each pushed fix commit; `run` loops inline within the same session.
1450
1729
 
1730
+ ### My PR became conflicted — will crosscheck resolve it?
1731
+
1732
+ Yes, if your workflow has a `conflict-resolve` step (the `onboard` default does). Conflicts are handled independently of the review ladder, because a PR usually conflicts when the **base branch** moves — which changes nothing about the code that was reviewed.
1733
+
1734
+ The catch is that a base-branch move fires no webhook on your PR, so `watch` never hears about it. `crosscheck scan` and `crosscheck kickass` are what notice: a conflicted PR shows `next=resolve` and is dispatched ahead of review, fix, and recheck. An approved PR that can no longer merge is resolved too — the merge commit then moves HEAD off the approved SHA, so the merged code gets a fresh review.
1735
+
1736
+ ```bash
1737
+ crosscheck kickass # picks up conflicted PRs along with everything else
1738
+ crosscheck resolve <pr-url> # or force just the conflict-resolve step
1739
+ ```
1740
+
1741
+ Fork PRs are skipped, same as with auto-fix — crosscheck cannot push to them. Repos narrowed to `review` or `review,recheck` never resolve conflicts either, since that would modify code.
1742
+
1743
+ ### What happens after a PR is approved?
1744
+
1745
+ Crosscheck stops working on that commit. Once the newest verdict is `APPROVE` and it covers the PR's current HEAD, no further step runs — not a recheck, not a re-review. `watch` skips further events on that SHA, `crosscheck run` prints `this commit is already approved — nothing to do until new commits land`, and `kickass` lists the PR under "needs merge (manual)" instead of dispatching it.
1746
+
1747
+ **A push re-opens it.** New commits materially change what was approved, so the approval no longer applies: the next event runs a fresh review (round *n*+1) on the new code, and the full fix/recheck loop resumes from there. An `APPROVE` posted before the annotation carried a `sha=` field can't prove which commit it covers, so it is treated the same way — one review re-establishes it.
1748
+
1749
+ To force another pass on the approved commit itself, name the steps explicitly — that bypasses history detection:
1750
+
1751
+ ```bash
1752
+ crosscheck run https://github.com/owner/repo/pull/123 --steps review
1753
+ ```
1754
+
1755
+ `crosscheck detect-step <pr-url>` shows the stop reason for any PR.
1756
+
1451
1757
  ### Can I disable the auto-fix step?
1452
1758
 
1453
1759
  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.
1454
1760
 
1455
- 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`.
1761
+ Both `delivery: pull_request` (the default) and `delivery: commit` push the fix directly onto the PR's own branch. The only difference is the fallback: `pull_request` opens a separate fix PR if that push can't land (branch merged, deleted, or protected), whereas `commit` surfaces the push failure instead. To get suggested fixes as review comments without any code push, use `delivery: comment`.
1456
1762
 
1457
1763
  ### Why does the fixer use the same vendor that wrote the PR?
1458
1764
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@humanbased/crosscheck",
3
- "version": "1.2.0",
3
+ "version": "1.3.0-beta.100",
4
4
  "description": "AI code review pipeline that turns agent-written PRs into merge-ready patches",
5
5
  "bin": {
6
6
  "crosscheck": "dist/cli.js",
@@ -23,12 +23,13 @@
23
23
  "node": ">=18"
24
24
  },
25
25
  "scripts": {
26
- "build": "tsc && rm -rf dist/harness && cp -r src/harness dist/harness && cp src/config/review-model-tiers.json dist/config/review-model-tiers.json && chmod +x dist/cli.js dist/ck.js",
26
+ "build": "tsc && rm -rf dist/harness && cp -r src/harness dist/harness && cp src/config/review-model-tiers.json dist/config/review-model-tiers.json && cp src/config/review-strategy.json dist/config/review-strategy.json && chmod +x dist/cli.js dist/ck.js",
27
27
  "dev": "tsx src/cli.ts",
28
28
  "typecheck": "tsc --noEmit",
29
29
  "test": "vitest run",
30
30
  "lint": "eslint src --ext .ts",
31
- "prepublishOnly": "npm run typecheck && npm run build"
31
+ "prepublishOnly": "npm run typecheck && npm run build",
32
+ "verify:strategy": "node scripts/verify-review-strategy.mjs"
32
33
  },
33
34
  "dependencies": {
34
35
  "chalk": "^5.3.0",
@@ -42,8 +43,10 @@
42
43
  "devDependencies": {
43
44
  "@types/js-yaml": "^4.0.9",
44
45
  "@types/node": "^22.0.0",
46
+ "eslint": "^9.39.5",
45
47
  "tsx": "^4.16.0",
46
48
  "typescript": "^5.5.0",
49
+ "typescript-eslint": "^8.67.0",
47
50
  "vitest": "^3.2.4"
48
51
  },
49
52
  "keywords": [