plumbbob 0.9.3 → 0.10.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 (320) hide show
  1. package/.claude-plugin/plugin.json +1 -1
  2. package/README.md +92 -89
  3. package/dist/cli-core.js +25 -8
  4. package/dist/cli.js +1 -1
  5. package/dist/lib/agents.js +26 -26
  6. package/dist/lib/buildlog.js +11 -11
  7. package/dist/lib/buildlogsync.js +8 -8
  8. package/dist/lib/check.js +55 -22
  9. package/dist/lib/commitbody.js +72 -0
  10. package/dist/lib/commitmsg.js +7 -7
  11. package/dist/lib/git.js +44 -15
  12. package/dist/lib/intent.js +21 -20
  13. package/dist/lib/latch.js +19 -19
  14. package/dist/lib/orient.js +36 -17
  15. package/dist/lib/reentry.js +70 -0
  16. package/dist/lib/settings.js +16 -16
  17. package/dist/lib/sidecar.js +54 -54
  18. package/dist/lib/templates.js +1 -1
  19. package/dist/verbs/agent.js +27 -27
  20. package/dist/verbs/build.js +9 -9
  21. package/dist/verbs/check.js +6 -6
  22. package/dist/verbs/checkpoint.js +48 -47
  23. package/dist/verbs/doctor.js +31 -30
  24. package/dist/verbs/finish.js +28 -41
  25. package/dist/verbs/handoff.js +9 -8
  26. package/dist/verbs/init.js +9 -9
  27. package/dist/verbs/park.js +3 -3
  28. package/dist/verbs/recover.js +297 -0
  29. package/dist/verbs/revert.js +13 -13
  30. package/dist/verbs/spike.js +25 -19
  31. package/dist/verbs/start.js +49 -19
  32. package/dist/verbs/status.js +8 -8
  33. package/dist/verbs/turn.js +16 -16
  34. package/dist/verbs/use.js +4 -4
  35. package/hooks/post-edit.sh +4 -4
  36. package/hooks/pre-bash-commit.sh +3 -3
  37. package/node_modules/checkride/.claude-plugin/plugin.json +11 -0
  38. package/node_modules/checkride/CHANGELOG.md +1404 -0
  39. package/node_modules/checkride/LICENSE +201 -21
  40. package/node_modules/checkride/README.md +197 -38
  41. package/node_modules/checkride/dist/__tests__/fixtures/released-stanzas.d.ts +15 -0
  42. package/node_modules/checkride/dist/__tests__/fixtures/released-stanzas.d.ts.map +1 -0
  43. package/node_modules/checkride/dist/__tests__/fixtures/released-stanzas.js +17 -0
  44. package/node_modules/checkride/dist/__tests__/fixtures/released-stanzas.js.map +1 -0
  45. package/node_modules/checkride/dist/adapters.d.ts +30 -10
  46. package/node_modules/checkride/dist/adapters.d.ts.map +1 -1
  47. package/node_modules/checkride/dist/adapters.js +62 -23
  48. package/node_modules/checkride/dist/adapters.js.map +1 -1
  49. package/node_modules/checkride/dist/agent-setup/claude.d.ts +88 -0
  50. package/node_modules/checkride/dist/agent-setup/claude.d.ts.map +1 -0
  51. package/node_modules/checkride/dist/agent-setup/claude.js +305 -0
  52. package/node_modules/checkride/dist/agent-setup/claude.js.map +1 -0
  53. package/node_modules/checkride/dist/agent-setup/command.d.ts +43 -0
  54. package/node_modules/checkride/dist/agent-setup/command.d.ts.map +1 -0
  55. package/node_modules/checkride/dist/agent-setup/command.js +77 -0
  56. package/node_modules/checkride/dist/agent-setup/command.js.map +1 -0
  57. package/node_modules/checkride/dist/agent-setup/cursor.d.ts +69 -0
  58. package/node_modules/checkride/dist/agent-setup/cursor.d.ts.map +1 -0
  59. package/node_modules/checkride/dist/agent-setup/cursor.js +247 -0
  60. package/node_modules/checkride/dist/agent-setup/cursor.js.map +1 -0
  61. package/node_modules/checkride/dist/agent-setup/files.d.ts +50 -0
  62. package/node_modules/checkride/dist/agent-setup/files.d.ts.map +1 -0
  63. package/node_modules/checkride/dist/agent-setup/files.js +80 -0
  64. package/node_modules/checkride/dist/agent-setup/files.js.map +1 -0
  65. package/node_modules/checkride/dist/agent-setup/harness.d.ts +101 -0
  66. package/node_modules/checkride/dist/agent-setup/harness.d.ts.map +1 -0
  67. package/node_modules/checkride/dist/agent-setup/harness.js +93 -0
  68. package/node_modules/checkride/dist/agent-setup/harness.js.map +1 -0
  69. package/node_modules/checkride/dist/agent-setup/hook.d.ts +45 -52
  70. package/node_modules/checkride/dist/agent-setup/hook.d.ts.map +1 -1
  71. package/node_modules/checkride/dist/agent-setup/hook.js +64 -95
  72. package/node_modules/checkride/dist/agent-setup/hook.js.map +1 -1
  73. package/node_modules/checkride/dist/agent-setup/index.d.ts +10 -4
  74. package/node_modules/checkride/dist/agent-setup/index.d.ts.map +1 -1
  75. package/node_modules/checkride/dist/agent-setup/index.js +9 -4
  76. package/node_modules/checkride/dist/agent-setup/index.js.map +1 -1
  77. package/node_modules/checkride/dist/agent-setup/scripts.d.ts +81 -0
  78. package/node_modules/checkride/dist/agent-setup/scripts.d.ts.map +1 -0
  79. package/node_modules/checkride/dist/agent-setup/scripts.js +604 -0
  80. package/node_modules/checkride/dist/agent-setup/scripts.js.map +1 -0
  81. package/node_modules/checkride/dist/agent-setup/skills.d.ts +31 -0
  82. package/node_modules/checkride/dist/agent-setup/skills.d.ts.map +1 -0
  83. package/node_modules/checkride/dist/agent-setup/skills.js +56 -0
  84. package/node_modules/checkride/dist/agent-setup/skills.js.map +1 -0
  85. package/node_modules/checkride/dist/artifacts/configured.d.ts +30 -0
  86. package/node_modules/checkride/dist/artifacts/configured.d.ts.map +1 -0
  87. package/node_modules/checkride/dist/artifacts/configured.js +45 -0
  88. package/node_modules/checkride/dist/artifacts/configured.js.map +1 -0
  89. package/node_modules/checkride/dist/artifacts/format.d.ts +33 -0
  90. package/node_modules/checkride/dist/artifacts/format.d.ts.map +1 -0
  91. package/node_modules/checkride/dist/artifacts/format.js +56 -0
  92. package/node_modules/checkride/dist/artifacts/format.js.map +1 -0
  93. package/node_modules/checkride/dist/artifacts/freshness.d.ts +32 -0
  94. package/node_modules/checkride/dist/artifacts/freshness.d.ts.map +1 -0
  95. package/node_modules/checkride/dist/artifacts/freshness.js +37 -0
  96. package/node_modules/checkride/dist/artifacts/freshness.js.map +1 -0
  97. package/node_modules/checkride/dist/artifacts/index.d.ts +22 -0
  98. package/node_modules/checkride/dist/artifacts/index.d.ts.map +1 -0
  99. package/node_modules/checkride/dist/artifacts/index.js +19 -0
  100. package/node_modules/checkride/dist/artifacts/index.js.map +1 -0
  101. package/node_modules/checkride/dist/artifacts/json.d.ts +31 -0
  102. package/node_modules/checkride/dist/artifacts/json.d.ts.map +1 -0
  103. package/node_modules/checkride/dist/artifacts/json.js +47 -0
  104. package/node_modules/checkride/dist/artifacts/json.js.map +1 -0
  105. package/node_modules/checkride/dist/artifacts/raw.d.ts +60 -0
  106. package/node_modules/checkride/dist/artifacts/raw.d.ts.map +1 -0
  107. package/node_modules/checkride/dist/artifacts/raw.js +91 -0
  108. package/node_modules/checkride/dist/artifacts/raw.js.map +1 -0
  109. package/node_modules/checkride/dist/artifacts/summary.d.ts +69 -0
  110. package/node_modules/checkride/dist/artifacts/summary.d.ts.map +1 -0
  111. package/node_modules/checkride/dist/artifacts/summary.js +108 -0
  112. package/node_modules/checkride/dist/artifacts/summary.js.map +1 -0
  113. package/node_modules/checkride/dist/atomic.d.ts +16 -1
  114. package/node_modules/checkride/dist/atomic.d.ts.map +1 -1
  115. package/node_modules/checkride/dist/atomic.js +25 -3
  116. package/node_modules/checkride/dist/atomic.js.map +1 -1
  117. package/node_modules/checkride/dist/baseline/fallow.d.ts +9 -5
  118. package/node_modules/checkride/dist/baseline/fallow.d.ts.map +1 -1
  119. package/node_modules/checkride/dist/baseline/fallow.js +163 -60
  120. package/node_modules/checkride/dist/baseline/fallow.js.map +1 -1
  121. package/node_modules/checkride/dist/baseline/fingerprint.d.ts +20 -11
  122. package/node_modules/checkride/dist/baseline/fingerprint.d.ts.map +1 -1
  123. package/node_modules/checkride/dist/baseline/fingerprint.js +73 -23
  124. package/node_modules/checkride/dist/baseline/fingerprint.js.map +1 -1
  125. package/node_modules/checkride/dist/baseline/history.d.ts +98 -0
  126. package/node_modules/checkride/dist/baseline/history.d.ts.map +1 -0
  127. package/node_modules/checkride/dist/baseline/history.js +232 -0
  128. package/node_modules/checkride/dist/baseline/history.js.map +1 -0
  129. package/node_modules/checkride/dist/baseline/index.d.ts +7 -5
  130. package/node_modules/checkride/dist/baseline/index.d.ts.map +1 -1
  131. package/node_modules/checkride/dist/baseline/index.js +5 -4
  132. package/node_modules/checkride/dist/baseline/index.js.map +1 -1
  133. package/node_modules/checkride/dist/baseline/store.d.ts +41 -10
  134. package/node_modules/checkride/dist/baseline/store.d.ts.map +1 -1
  135. package/node_modules/checkride/dist/baseline/store.js +65 -24
  136. package/node_modules/checkride/dist/baseline/store.js.map +1 -1
  137. package/node_modules/checkride/dist/baseline-command.d.ts +5 -5
  138. package/node_modules/checkride/dist/baseline-command.js +7 -7
  139. package/node_modules/checkride/dist/baseline-command.js.map +1 -1
  140. package/node_modules/checkride/dist/cli.d.ts +21 -4
  141. package/node_modules/checkride/dist/cli.d.ts.map +1 -1
  142. package/node_modules/checkride/dist/cli.js +350 -36
  143. package/node_modules/checkride/dist/cli.js.map +1 -1
  144. package/node_modules/checkride/dist/config.d.ts +114 -9
  145. package/node_modules/checkride/dist/config.d.ts.map +1 -1
  146. package/node_modules/checkride/dist/config.js +142 -23
  147. package/node_modules/checkride/dist/config.js.map +1 -1
  148. package/node_modules/checkride/dist/digest/digest.d.ts +5 -5
  149. package/node_modules/checkride/dist/digest/digest.js +6 -6
  150. package/node_modules/checkride/dist/digest/index.d.ts +2 -2
  151. package/node_modules/checkride/dist/digest/index.js +2 -2
  152. package/node_modules/checkride/dist/doctor.d.ts +27 -6
  153. package/node_modules/checkride/dist/doctor.d.ts.map +1 -1
  154. package/node_modules/checkride/dist/doctor.js +231 -27
  155. package/node_modules/checkride/dist/doctor.js.map +1 -1
  156. package/node_modules/checkride/dist/gate.d.ts +180 -0
  157. package/node_modules/checkride/dist/gate.d.ts.map +1 -0
  158. package/node_modules/checkride/dist/gate.js +617 -0
  159. package/node_modules/checkride/dist/gate.js.map +1 -0
  160. package/node_modules/checkride/dist/init.d.ts +79 -12
  161. package/node_modules/checkride/dist/init.d.ts.map +1 -1
  162. package/node_modules/checkride/dist/init.js +385 -81
  163. package/node_modules/checkride/dist/init.js.map +1 -1
  164. package/node_modules/checkride/dist/json.d.ts +21 -0
  165. package/node_modules/checkride/dist/json.d.ts.map +1 -0
  166. package/node_modules/checkride/dist/json.js +21 -0
  167. package/node_modules/checkride/dist/json.js.map +1 -0
  168. package/node_modules/checkride/dist/links.d.ts +31 -5
  169. package/node_modules/checkride/dist/links.d.ts.map +1 -1
  170. package/node_modules/checkride/dist/links.js +141 -32
  171. package/node_modules/checkride/dist/links.js.map +1 -1
  172. package/node_modules/checkride/dist/node-pin.d.ts +129 -0
  173. package/node_modules/checkride/dist/node-pin.d.ts.map +1 -0
  174. package/node_modules/checkride/dist/node-pin.js +211 -0
  175. package/node_modules/checkride/dist/node-pin.js.map +1 -0
  176. package/node_modules/checkride/dist/orchestrator.d.ts +53 -10
  177. package/node_modules/checkride/dist/orchestrator.d.ts.map +1 -1
  178. package/node_modules/checkride/dist/orchestrator.js +312 -113
  179. package/node_modules/checkride/dist/orchestrator.js.map +1 -1
  180. package/node_modules/checkride/dist/pack.d.ts +8 -9
  181. package/node_modules/checkride/dist/pack.d.ts.map +1 -1
  182. package/node_modules/checkride/dist/pack.js +53 -17
  183. package/node_modules/checkride/dist/pack.js.map +1 -1
  184. package/node_modules/checkride/dist/pm/detect.d.ts +6 -1
  185. package/node_modules/checkride/dist/pm/detect.d.ts.map +1 -1
  186. package/node_modules/checkride/dist/pm/detect.js +6 -1
  187. package/node_modules/checkride/dist/pm/detect.js.map +1 -1
  188. package/node_modules/checkride/dist/pm/index.d.ts +7 -2
  189. package/node_modules/checkride/dist/pm/index.d.ts.map +1 -1
  190. package/node_modules/checkride/dist/pm/index.js +6 -2
  191. package/node_modules/checkride/dist/pm/index.js.map +1 -1
  192. package/node_modules/checkride/dist/pm/launch.d.ts +72 -0
  193. package/node_modules/checkride/dist/pm/launch.d.ts.map +1 -0
  194. package/node_modules/checkride/dist/pm/launch.js +108 -0
  195. package/node_modules/checkride/dist/pm/launch.js.map +1 -0
  196. package/node_modules/checkride/dist/pm/tools.d.ts +73 -0
  197. package/node_modules/checkride/dist/pm/tools.d.ts.map +1 -0
  198. package/node_modules/checkride/dist/pm/tools.js +124 -0
  199. package/node_modules/checkride/dist/pm/tools.js.map +1 -0
  200. package/node_modules/checkride/dist/pm/translate.d.ts +35 -9
  201. package/node_modules/checkride/dist/pm/translate.d.ts.map +1 -1
  202. package/node_modules/checkride/dist/pm/translate.js +78 -18
  203. package/node_modules/checkride/dist/pm/translate.js.map +1 -1
  204. package/node_modules/checkride/dist/proc.d.ts +30 -0
  205. package/node_modules/checkride/dist/proc.d.ts.map +1 -0
  206. package/node_modules/checkride/dist/proc.js +42 -0
  207. package/node_modules/checkride/dist/proc.js.map +1 -0
  208. package/node_modules/checkride/dist/qa/cli.d.ts +20 -0
  209. package/node_modules/checkride/dist/qa/cli.d.ts.map +1 -0
  210. package/node_modules/checkride/dist/qa/cli.js +24 -0
  211. package/node_modules/checkride/dist/qa/cli.js.map +1 -0
  212. package/node_modules/checkride/dist/qa/dead.d.ts +39 -0
  213. package/node_modules/checkride/dist/qa/dead.d.ts.map +1 -0
  214. package/node_modules/checkride/dist/qa/dead.js +88 -0
  215. package/node_modules/checkride/dist/qa/dead.js.map +1 -0
  216. package/node_modules/checkride/dist/qa/dupes.d.ts +45 -0
  217. package/node_modules/checkride/dist/qa/dupes.d.ts.map +1 -0
  218. package/node_modules/checkride/dist/qa/dupes.js +62 -0
  219. package/node_modules/checkride/dist/qa/dupes.js.map +1 -0
  220. package/node_modules/checkride/dist/qa/health.d.ts +85 -0
  221. package/node_modules/checkride/dist/qa/health.d.ts.map +1 -0
  222. package/node_modules/checkride/dist/qa/health.js +109 -0
  223. package/node_modules/checkride/dist/qa/health.js.map +1 -0
  224. package/node_modules/checkride/dist/qa/index.d.ts +23 -0
  225. package/node_modules/checkride/dist/qa/index.d.ts.map +1 -0
  226. package/node_modules/checkride/dist/qa/index.js +22 -0
  227. package/node_modules/checkride/dist/qa/index.js.map +1 -0
  228. package/node_modules/checkride/dist/qa/mutation.d.ts +80 -0
  229. package/node_modules/checkride/dist/qa/mutation.d.ts.map +1 -0
  230. package/node_modules/checkride/dist/qa/mutation.js +195 -0
  231. package/node_modules/checkride/dist/qa/mutation.js.map +1 -0
  232. package/node_modules/checkride/dist/qa/qa.d.ts +71 -0
  233. package/node_modules/checkride/dist/qa/qa.d.ts.map +1 -0
  234. package/node_modules/checkride/dist/qa/qa.js +158 -0
  235. package/node_modules/checkride/dist/qa/qa.js.map +1 -0
  236. package/node_modules/checkride/dist/qa/read.d.ts +40 -0
  237. package/node_modules/checkride/dist/qa/read.d.ts.map +1 -0
  238. package/node_modules/checkride/dist/qa/read.js +47 -0
  239. package/node_modules/checkride/dist/qa/read.js.map +1 -0
  240. package/node_modules/checkride/dist/qa/render.d.ts +26 -0
  241. package/node_modules/checkride/dist/qa/render.d.ts.map +1 -0
  242. package/node_modules/checkride/dist/qa/render.js +310 -0
  243. package/node_modules/checkride/dist/qa/render.js.map +1 -0
  244. package/node_modules/checkride/dist/recover.d.ts +48 -0
  245. package/node_modules/checkride/dist/recover.d.ts.map +1 -0
  246. package/node_modules/checkride/dist/recover.js +220 -0
  247. package/node_modules/checkride/dist/recover.js.map +1 -0
  248. package/node_modules/checkride/dist/security.d.ts +45 -0
  249. package/node_modules/checkride/dist/security.d.ts.map +1 -0
  250. package/node_modules/checkride/dist/security.js +86 -0
  251. package/node_modules/checkride/dist/security.js.map +1 -0
  252. package/node_modules/checkride/dist/smoke.d.ts +6 -6
  253. package/node_modules/checkride/dist/smoke.js +6 -6
  254. package/node_modules/checkride/dist/snippets.d.ts +27 -30
  255. package/node_modules/checkride/dist/snippets.d.ts.map +1 -1
  256. package/node_modules/checkride/dist/snippets.js +26 -30
  257. package/node_modules/checkride/dist/snippets.js.map +1 -1
  258. package/node_modules/checkride/dist/tool-json.d.ts +33 -0
  259. package/node_modules/checkride/dist/tool-json.d.ts.map +1 -0
  260. package/node_modules/checkride/dist/tool-json.js +58 -0
  261. package/node_modules/checkride/dist/tool-json.js.map +1 -0
  262. package/node_modules/checkride/dist/triage/cli.d.ts +21 -0
  263. package/node_modules/checkride/dist/triage/cli.d.ts.map +1 -0
  264. package/node_modules/checkride/dist/triage/cli.js +26 -0
  265. package/node_modules/checkride/dist/triage/cli.js.map +1 -0
  266. package/node_modules/checkride/dist/triage/doctor-fold.d.ts +51 -0
  267. package/node_modules/checkride/dist/triage/doctor-fold.d.ts.map +1 -0
  268. package/node_modules/checkride/dist/triage/doctor-fold.js +88 -0
  269. package/node_modules/checkride/dist/triage/doctor-fold.js.map +1 -0
  270. package/node_modules/checkride/dist/triage/env.d.ts +54 -0
  271. package/node_modules/checkride/dist/triage/env.d.ts.map +1 -0
  272. package/node_modules/checkride/dist/triage/env.js +81 -0
  273. package/node_modules/checkride/dist/triage/env.js.map +1 -0
  274. package/node_modules/checkride/dist/triage/gate.d.ts +61 -0
  275. package/node_modules/checkride/dist/triage/gate.d.ts.map +1 -0
  276. package/node_modules/checkride/dist/triage/gate.js +121 -0
  277. package/node_modules/checkride/dist/triage/gate.js.map +1 -0
  278. package/node_modules/checkride/dist/triage/index.d.ts +22 -0
  279. package/node_modules/checkride/dist/triage/index.d.ts.map +1 -0
  280. package/node_modules/checkride/dist/triage/index.js +20 -0
  281. package/node_modules/checkride/dist/triage/index.js.map +1 -0
  282. package/node_modules/checkride/dist/triage/render.d.ts +19 -0
  283. package/node_modules/checkride/dist/triage/render.d.ts.map +1 -0
  284. package/node_modules/checkride/dist/triage/render.js +419 -0
  285. package/node_modules/checkride/dist/triage/render.js.map +1 -0
  286. package/node_modules/checkride/dist/triage/triage.d.ts +83 -0
  287. package/node_modules/checkride/dist/triage/triage.d.ts.map +1 -0
  288. package/node_modules/checkride/dist/triage/triage.js +131 -0
  289. package/node_modules/checkride/dist/triage/triage.js.map +1 -0
  290. package/node_modules/checkride/package.json +18 -15
  291. package/node_modules/checkride/schema/checkride.config.schema.json +70 -5
  292. package/node_modules/checkride/schema/checkride.summary.schema.json +1 -1
  293. package/node_modules/checkride/skills/check/SKILL.md +265 -0
  294. package/node_modules/checkride/skills/qa/SKILL.md +231 -0
  295. package/node_modules/checkride/templates/shared/cspell.json +1 -0
  296. package/node_modules/checkride/templates/shared/oxlintrc.json +1 -1
  297. package/node_modules/checkride/templates/shared/styles/Repo/Drift.yml +41 -0
  298. package/node_modules/checkride/templates/shared/styles/Repo/Latin.yml +14 -0
  299. package/node_modules/checkride/templates/shared/styles/Repo/LyHyphen.yml +28 -0
  300. package/node_modules/checkride/templates/shared/styles/Repo/Minted.yml +33 -0
  301. package/node_modules/checkride/templates/shared/styles/Repo/ThereIs.yml +16 -0
  302. package/node_modules/checkride/templates/shared/styles/Repo/Weasel.yml +26 -0
  303. package/node_modules/checkride/templates/shared/vale.ini +34 -0
  304. package/package.json +10 -9
  305. package/skills/build/SKILL.md +85 -76
  306. package/skills/doctor/SKILL.md +11 -11
  307. package/skills/finish/SKILL.md +21 -18
  308. package/skills/harvest/SKILL.md +13 -11
  309. package/skills/park/SKILL.md +10 -10
  310. package/skills/plan/SKILL.md +69 -59
  311. package/skills/recover/SKILL.md +28 -0
  312. package/skills/refine/SKILL.md +21 -18
  313. package/skills/revert/SKILL.md +6 -6
  314. package/skills/spike/SKILL.md +9 -9
  315. package/skills/status/SKILL.md +5 -5
  316. package/skills/step/SKILL.md +20 -15
  317. package/skills/verify/SKILL.md +56 -46
  318. package/templates/build-log.md +7 -7
  319. package/templates/intent.md +52 -41
  320. package/templates/spike-report.md +10 -10
@@ -0,0 +1,231 @@
1
+ ---
2
+ name: qa
3
+ description: Read checkride's quality artifacts — surviving mutants, dead code, duplication and the health score — and say what the test suite actually proves. Use when asked how healthy the codebase is, whether the tests are any good, where the risk or the tech debt is, what mutation testing found, or which files need better coverage. Reads a bounded report instead of megabytes of `.check/` artifacts, runs nothing, and reports which quality dimensions were never measured rather than guessing at them.
4
+ argument-hint: "[repo-path]"
5
+ allowed-tools: Read, Grep, Glob, Bash(node *), Bash(pnpm *), Bash(npx checkride*), Bash(yarn *), Bash(bunx *), Bash(wc *), Bash(git log *)
6
+ ---
7
+
8
+ # checkride: read the quality signal
9
+
10
+ checkride's gate answers one question — is the work done? — and answers it
11
+ pass/fail. These four artifacts answer a different one: **is the suite actually
12
+ testing anything, and where is the risk?** Nothing here is red or green. No
13
+ threshold fires. That is exactly why this is the easiest report in the repo to
14
+ hallucinate: with no failure to anchor to, a plausible-sounding list of eight
15
+ issues costs nothing to write and means nothing.
16
+
17
+ So the discipline is inverted from triage. The triage skill starts from a
18
+ failure and narrows to one cause. This skill starts from evidence and stops when
19
+ the evidence stops — which is sometimes after one finding, and sometimes after
20
+ none.
21
+
22
+ For a red gate, use the triage skill instead (`/checkride:check` under the
23
+ plugin, `/checkride-check` in Cursor, or `checkride triage` directly). This skill
24
+ reads what a *past* run left behind and never runs the gate itself.
25
+
26
+ ## 1. Run the reader
27
+
28
+ ```bash
29
+ pnpm exec checkride qa
30
+ ```
31
+
32
+ Substitute the repo's package manager (`npx checkride`, `yarn checkride`, `bunx
33
+ checkride`). Pass a repo path as the one optional argument to read somewhere
34
+ other than the current directory.
35
+
36
+ If checkride is not a dependency of the target repo, run the copy the plugin
37
+ ships instead: `node "${CLAUDE_PLUGIN_ROOT}/dist/qa/cli.js"`. Both entry points
38
+ render the identical report.
39
+
40
+ It **runs nothing** — no stryker, no fallow, not the gate. It opens `.check/`,
41
+ folds each artifact to a ranked short list, and renders under 8 KB (the same
42
+ ceiling `--digest` uses). In checkride's own repo that is 2.3 MB of
43
+ `mutation.json` reduced to a page, which is the only reason a mutation finding
44
+ is affordable at all.
45
+
46
+ **Do not open any `.check/` file before this report names one.** Every count
47
+ below comes from a full pass over the artifact; the lists are ranked, not
48
+ truncated at random.
49
+
50
+ ## 2. The ledger is the answer, not the preamble
51
+
52
+ Because the reader runs nothing, its first job is to say what it is actually
53
+ holding. Two head lines, then a table — and in a default consumer repo that is
54
+ very nearly the *whole* report.
55
+
56
+ ```text
57
+ - summary: `.check/summary.json` — `schema_version` 1, 1.5m ago, 1.5s
58
+ - covered: 3 slot(s) ran — links, docs, spell
59
+ ```
60
+
61
+ - **`summary`** — what the artifacts beside it belong to, and how long ago. If it
62
+ reads `` `schema_version` is 2, not 1; STOP ``, then **stop**: the reader is
63
+ pinned to schema 1, and guessing across a version is how you invent a finding.
64
+ - **`covered`** — the slots that run actually touched. Three of seventeen means
65
+ the artifacts on disk mostly belong to *some other* run, and the ledger's
66
+ staleness column is the only thing standing between you and reporting them as
67
+ current. `covered: nothing` means there is no readable summary at all, so no
68
+ artifact here can be dated and none of them is evidence.
69
+
70
+ **Open your report with that covered count and the run's age**, the same way
71
+ the triage skill does. A quality claim without its coverage is an assertion
72
+ about the whole repo built from a fraction of it.
73
+
74
+ | state | what it means | what it licenses you to say |
75
+ | --- | --- | --- |
76
+ | `read` | fresh — written by the run whose summary sits beside it | evidence, present tense |
77
+ | `STALE` | on disk, but older than that run's start | a fact about the past, with the age always attached |
78
+ | `not opted in` | the slot is absent from `checkride.config.json`, so no run produces it | **nothing about this dimension** — name the remedy instead |
79
+ | `absent` | opted in, but no file — the slot has not run, or produced nothing | nothing; name the command |
80
+ | `too-large` / `unreadable` / `unrecognized` | the bytes are there but not usable | nothing; say which, because each has a different cause |
81
+
82
+ Two rules follow, and they are the ones that make this skill honest.
83
+
84
+ **A gap is a finding, not an edge case.** Three of the four artifacts come from
85
+ opt-in slots, and checkride's own gate never runs `mutation` at all. In a fresh
86
+ consumer repo you will find `dead.json` and nothing else. The honest report
87
+ there is the ledger plus the two commands that would produce data — *not* a page
88
+ of quality assessment extrapolated from one artifact. The reader already prints
89
+ the exact command or config entry for each gap; quote it rather than inventing
90
+ one.
91
+
92
+ **Never launder a stale number into a present-tense claim.** "Mutation score is
93
+ 71%" is wrong when the file is 7.6 days old. "As of a stryker run 7.6 days ago,
94
+ 71%" is right, and it carries its own warning. When a stale artifact is
95
+ load-bearing for a finding, check whether the code moved under it:
96
+
97
+ ```bash
98
+ git log -1 --format=%cr -- src/init.ts
99
+ ```
100
+
101
+ If the file changed more recently than the artifact, the artifact describes code
102
+ that no longer exists. Say so and stop — do not report its findings as current.
103
+
104
+ ## 3. Read in evidence order — strongest proof first
105
+
106
+ The reader emits its sections in the order you should reason about them, and
107
+ that order is not arbitrary. It ranks by **how much of the claim the artifact
108
+ already proved for you**:
109
+
110
+ 1. **Surviving mutants** — the strongest evidence in the repo. Stryker *changed
111
+ the code* and the suite still passed. That is a demonstrated hole, not an
112
+ opinion, and no amount of coverage percentage can contradict it.
113
+ 2. **Dead code** — a static claim about reachability. Usually right; wrong
114
+ exactly where entry points are dynamic, which is why `fallow.toml`'s `entry`
115
+ list exists.
116
+ 3. **Structure** (`dupes`, `health`) — measurements against thresholds somebody
117
+ configured. A hotspot is a place to look, not a defect.
118
+ 4. **Your own reading of the source** — last, and only when it names a file and
119
+ a line.
120
+
121
+ Work down that list and stop where the evidence stops. That is the whole
122
+ anti-hallucination device: findings are sorted by proof, so a short report is a
123
+ *strong* one.
124
+
125
+ ### Mutation: survived and no-coverage want different fixes
126
+
127
+ The two undetected states look alike in a table and mean opposite things.
128
+
129
+ - **No-coverage** — no test reaches the line at all. The fix is a test that
130
+ executes it.
131
+ - **Survived** — a test *does* reach it and asserts nothing that would notice
132
+ the change. The fix is a stronger assertion in the test that already runs.
133
+ Adding another test that also does not look is the standard wrong answer, and
134
+ it raises line coverage while changing nothing.
135
+
136
+ The mutator name tells you what kind of hole it is:
137
+
138
+ | mutator | what its survival proves |
139
+ | --- | --- |
140
+ | `ConditionalExpression` | a branch condition can be forced true or false and nothing notices — usually one side of the branch is decorative. The most common survivor almost everywhere (359 of them in checkride's own repo) and the most informative |
141
+ | `BlockStatement` | an entire function body was emptied and the suite passed. The loudest signal in the table |
142
+ | `EqualityOperator` | a comparison flipped undetected — a boundary case nothing exercises |
143
+ | `LogicalOperator` | one arm of an `&&` / `\|\|` is never the deciding one in any test |
144
+ | `ArrayDeclaration`, `ObjectLiteral` | a literal was emptied unnoticed — the *contents* of that data are unasserted. Common on config tables, and often low-value (see below) |
145
+ | `Regex`, `StringLiteral` | the pattern or text is unasserted; frequently a message nobody should assert on |
146
+
147
+ **Not every survivor is worth killing.** Equivalent mutants — ones with no
148
+ observable behavior difference — are real and common: log text, a default
149
+ immediately overwritten, a `??` on a value that is never null. A suite driven to
150
+ 100% mutation score is a suite full of assertions on things nobody cares about.
151
+ Rank survivors by **what the mutant proves about a path a user can reach**, and
152
+ say when you are dismissing one and why.
153
+
154
+ **Rank is not priority.** The reader ranks files by undetected count, which
155
+ tracks file *size* at least as much as risk — `src/init.ts` tops checkride's own
156
+ table largely because it is the biggest file with the most mutants. Read what
157
+ the survivors are before treating the top row as the most important work.
158
+
159
+ ## 4. Ground the finding, or drop it
160
+
161
+ A finding must be able to name three things: **the artifact it came from, the
162
+ file and line, and — for a mutation finding — the test that should have caught
163
+ it and did not.** If you cannot name the test file you would edit, you have a
164
+ metric, not a finding.
165
+
166
+ So for the one or two survivors that look genuinely load-bearing:
167
+
168
+ 1. Open the source at the sample line the report gave you (`Read` with an
169
+ `offset`, not the whole file).
170
+ 2. Find the test that covers it — `src/__tests__/<name>.test.ts`, or `Grep` for
171
+ the function name.
172
+ 3. Read what that test asserts. The finding is the sentence that comes out:
173
+ *"`resolveOrder` is called in three tests and all three assert only the
174
+ length of the result, so flipping its `<=` to `<` changes nothing they
175
+ check."*
176
+
177
+ "Coverage could be improved here" is not that sentence.
178
+
179
+ **Open at most two or three files.** If the report ranks eight, read the top one
180
+ properly rather than all eight badly — the same economy the triage skill uses
181
+ when it opens exactly one artifact.
182
+
183
+ ## 5. Report
184
+
185
+ - **Evidence** — the covered-slot count, the run's age, then the ledger in a
186
+ line or two: what is fresh, what is stale and by how much, what was never
187
+ produced. Always first. A report that opens with a finding is a report that hid
188
+ its own uncertainty.
189
+ - **What the artifacts prove** — findings in evidence order, each grounded per
190
+ step 4. As many as the evidence supports, and no more.
191
+ - **What would produce the missing evidence** — the reader's own command or
192
+ config line for each gap. This is often the single most useful thing you can
193
+ say.
194
+ - **Judgment** — clearly labelled as yours, last, and only where it names a
195
+ file.
196
+
197
+ ### The failure mode this skill exists to prevent
198
+
199
+ **Produce no fixed-size list.** Not "top 5 issues", not eight findings, not one
200
+ per artifact. The count is whatever the evidence supports, and **zero is a
201
+ legitimate answer** — a repo with a fresh, empty `dead.json` and three
202
+ unmeasured dimensions has exactly one honest thing to report: that three of four
203
+ quality dimensions are unmeasured. Padding that to five means inventing four.
204
+
205
+ Three specific ways it goes wrong:
206
+
207
+ - **Restating the metric as a finding.** "Health score is 80.9/B" is the ledger.
208
+ A finding names which function costs the points and why.
209
+ - **Grading the grade.** No number in `health.json` is a defect; the thresholds
210
+ are a configured opinion, and the score is 100 minus the penalties. When
211
+ nothing is over any threshold and the whole penalty is hotspots and unit size,
212
+ say that — do not manufacture violations to explain a B.
213
+ - **Turning a ranked list into a to-do list.** The tables are ranked so you know
214
+ where to *look*. Copying the top five rows into "recommendations" is
215
+ transcription wearing analysis's clothes.
216
+
217
+ ## What this skill does not do
218
+
219
+ - **It runs nothing.** Not stryker (minutes to hours, and it rewrites your
220
+ source while it works), not fallow, not the gate. Naming the command is the
221
+ deliverable; running it is the human's call.
222
+ - **It does not gate.** None of these four dimensions has a pass/fail line, and
223
+ inventing one — "mutation score should be above 80" — turns a measurement into
224
+ a target, which is how it stops being a measurement.
225
+ - **It does not write tests.** Naming the unasserted branch is the deliverable.
226
+ Writing the test is the next request, and it should start from the named
227
+ mutant.
228
+ - **It does not triage a red gate.** That is the triage skill, which runs the
229
+ gate and reads different artifacts entirely.
230
+ - **It does not touch the baseline.** `checkride baseline` hides findings
231
+ permanently; that is never a reading step.
@@ -10,6 +10,7 @@
10
10
  "package.json",
11
11
  "CHANGELOG.md"
12
12
  ],
13
+ "ignoreRegExpList": ["/v1[0-9a-f]{16}/g"],
13
14
  "words": [
14
15
  "checkride",
15
16
  "baselined",
@@ -29,5 +29,5 @@
29
29
  }
30
30
  }
31
31
  ],
32
- "ignorePatterns": ["dist/**", ".check/**", ".claude/**", "node_modules/**"]
32
+ "ignorePatterns": ["dist/**", ".check/**", ".claude/**", ".cursor/**", "node_modules/**"]
33
33
  }
@@ -0,0 +1,41 @@
1
+ # The lexical fingerprints of model-generated prose: vocabulary that runs at
2
+ # many times its human base rate in machine-written text (`delve` is the
3
+ # canonical case), and the stock frames readers have learned to skim past.
4
+ # Model output feeds the next session's context, so every fingerprint that
5
+ # lands becomes the example the next generation copies — this rule breaks that
6
+ # loop while the copy count is still one.
7
+ #
8
+ # The list is deliberately short and high-precision: words a careful writer
9
+ # almost never reaches for, so a hit is close to proof of provenance. Words
10
+ # that are merely overused (`robust`, `crucial`, `comprehensive`) stay off it —
11
+ # flagging those turns the rule into noise. Add your own repo's tells as they
12
+ # emerge; cut anything you would defend in your own voice.
13
+ #
14
+ # Case classes instead of `ignorecase`, because the last token — the
15
+ # `It's not just X — it's Y` frame — is anchored to its sentence-initial
16
+ # capital, and one flag governs every token in the rule.
17
+ extends: existence
18
+ message: "'%s' is a fingerprint of generated prose — say the plain thing instead."
19
+ level: error
20
+ ignorecase: false
21
+ # The tokens are full regexes with their own anchors, so word boundaries must
22
+ # not be wrapped around them.
23
+ nonword: true
24
+ tokens:
25
+ - '\b[Dd]elv(?:e[sd]?|ing)\b'
26
+ - '\b[Cc]ommendable\b'
27
+ - '\b[Mm]eticulous(?:ly)?\b'
28
+ - '\b[Ii]ntricate(?:ly)?\b'
29
+ - '\b[Ii]ntricac(?:y|ies)\b'
30
+ - '\b[Tt]estament to\b'
31
+ - '\b[Tt]apestry\b'
32
+ - '\b[Gg]ame-chang(?:er|ers|ing)\b'
33
+ - '\b[Ee]ver-evolving\b'
34
+ - "\\b[Ii]n today['’]s\\b"
35
+ - '\b[Ss]eamless(?:ly)?\b'
36
+ - '\b[Ss]upercharg(?:e[sd]?|ing)\b'
37
+ - '\b[Uu]nlock(?:s|ed|ing)? the (?:full )?(?:power|potential)\b'
38
+ - "\\b[Ii]t(?: is|['’]s) (?:important to note|worth noting)\\b"
39
+ - '\b[Ii]n conclusion\b'
40
+ - '\b[Bb]oasts\b'
41
+ - "It(?:['’]s| is) not just (?:about )?[^.,;:—–]{1,60}[—–,;] ?it(?:['’]s| is)\\b"
@@ -0,0 +1,14 @@
1
+ # Latin abbreviations read as shorthand and land as a stumble: `i.e.` and `e.g.`
2
+ # are confused for each other often enough that the plain English is simply
3
+ # clearer. Mechanical, not a matter of voice — the substitution is always
4
+ # available and always says the same thing.
5
+ extends: substitution
6
+ message: "Use '%s' instead of '%s'."
7
+ level: error
8
+ ignorecase: false
9
+ # The tokens carry periods, so word boundaries cannot wrap them.
10
+ nonword: true
11
+ swap:
12
+ '\b(?:eg|e\.g\.)[\s,]': for example
13
+ '\b(?:ie|i\.e\.)[\s,]': that is
14
+ '\betc\.': and so on
@@ -0,0 +1,28 @@
1
+ # An adverb ending in `-ly` cannot modify anything but the word that follows
2
+ # it, so the hyphen adds nothing: `newly created`, not `newly-created`. This is
3
+ # a rule about punctuation, not about how the sentence should read.
4
+ #
5
+ # The exceptions are words that end in `-ly` without being adverbs — `supply
6
+ # chain`, `family friendly`, `early return`. They are the rule's whole
7
+ # false-positive surface, and the list below is a starting point: add to it
8
+ # rather than reaching for a suppression.
9
+ extends: existence
10
+ message: "'%s': an adverb ending in '-ly' takes no hyphen."
11
+ level: error
12
+ ignorecase: true
13
+ # The token spans a hyphen, which word boundaries would cut in half.
14
+ nonword: true
15
+ tokens:
16
+ - '\b[^\s-]+ly-\w+\b'
17
+ exceptions:
18
+ - anomaly
19
+ - apply
20
+ - assembly
21
+ - comply
22
+ - early
23
+ - family
24
+ - imply
25
+ - multiply
26
+ - only
27
+ - reply
28
+ - supply
@@ -0,0 +1,33 @@
1
+ # The minted dialect: verbs pressed into service as nouns (`the ask`), nouns
2
+ # conscripted as verbs (`to action`), and the corporate register's syllable
3
+ # inflations (`utilize`, three syllables where one does the work). Generated
4
+ # prose leans into this dialect and then copies its own lean, so each swap here
5
+ # is one the next pass never gets to imitate. Mechanical, not a matter of
6
+ # voice — the plain word is always available and always says the same thing.
7
+ #
8
+ # Only unambiguous forms are listed. The noun `leverage` (mechanical advantage,
9
+ # `open-source leverage`) is legitimate English, so only the verb forms match;
10
+ # `the build` stays off the list entirely because in a repository it names the
11
+ # compiled artifact far more often than it apes the dialect.
12
+ extends: substitution
13
+ message: "Use '%s' instead of '%s'."
14
+ level: error
15
+ ignorecase: false
16
+ # The patterns carry their own case classes and boundaries.
17
+ nonword: true
18
+ swap:
19
+ '\b[Tt]he ask\b': the request
20
+ '\b[Ll]earnings\b': lessons
21
+ '\b[Aa]ctioned\b': handled
22
+ '\b[Aa]ctioning\b': handling
23
+ '\b[Ss]olutioning\b': designing
24
+ '\b[Tt]o leverage\b': to use
25
+ '\b[Ll]everages\b': uses
26
+ '\b[Ll]everaged\b': used
27
+ '\b[Ll]everaging\b': using
28
+ '\b[Uu]tilize\b': use
29
+ '\b[Uu]tilizes\b': uses
30
+ '\b[Uu]tilized\b': used
31
+ '\b[Uu]tilizing\b': using
32
+ '\b[Uu]tilization\b': use
33
+ '\b[Tt]he lift\b': the effort
@@ -0,0 +1,16 @@
1
+ # `There is a flag that controls X` spends its subject position on a word that
2
+ # names nothing, then makes the reader wait for the real subject. Naming the
3
+ # thing first is shorter every time: `A flag controls X`.
4
+ #
5
+ # Deliberately case-sensitive: only the sentence-initial pattern is the
6
+ # stumble. A mid-clause existential — `when there is nothing to fix` — is
7
+ # idiomatic English with no cleaner rewrite, and flagging it turns careful
8
+ # prose into a wall of contortions. Sentence-initial `There` is always
9
+ # capitalized, so the capital T is the whole test.
10
+ extends: existence
11
+ message: "'%s' postpones the subject — name the thing that acts, then act."
12
+ level: error
13
+ ignorecase: false
14
+ tokens:
15
+ - 'There (is|are|was|were)'
16
+ - "There'?s"
@@ -0,0 +1,26 @@
1
+ # Weasel words claim an intensity the sentence never earns: `very fast` is not
2
+ # a measurement, and `simply call the function` is a claim about the reader.
3
+ # Cutting one almost never costs meaning.
4
+ #
5
+ # This is the one rule in the set that is taste rather than mechanics, so the
6
+ # scaffolded .vale.ini ships it OFF (`Repo.Weasel = NO`). Careful prose uses
7
+ # some of these deliberately — `just` as "only", `clearly` as a genuine signal —
8
+ # and a rule the author disagrees with becomes a wall of suppressions. Read the
9
+ # list, cut what you would defend, then turn it on.
10
+ extends: existence
11
+ message: "'%s' is a weasel word — cut it, or say the specific thing."
12
+ level: error
13
+ ignorecase: true
14
+ tokens:
15
+ - actually
16
+ - basically
17
+ - clearly
18
+ - fairly
19
+ - just
20
+ - obviously
21
+ - quite
22
+ - rather
23
+ - really
24
+ - simply
25
+ - somewhat
26
+ - very
@@ -0,0 +1,34 @@
1
+ # Vale — the `prose` slot. Written by `checkride init --add prose`; yours now.
2
+ #
3
+ # The styles under .vale/styles/Repo are plain YAML in this repo: no download,
4
+ # no `vale sync` on the default path, nothing to keep in step with an upstream.
5
+ # Disagree with a rule and the answer is to edit or delete it, not to suppress
6
+ # it line by line — a style full of suppressions is ceremony.
7
+
8
+ StylesPath = .vale/styles
9
+
10
+ # Report everything; only errors decide the check. Vale exits non-zero for
11
+ # error-severity alerts alone, so demoting a rule to `warning` keeps it visible
12
+ # here while making it advisory — which is why this stays at `suggestion`.
13
+ # Raise it and you stop seeing the advisory half rather than silencing it.
14
+ MinAlertLevel = suggestion
15
+
16
+ # Vale has no TypeScript format of its own. Mapping it to JavaScript lints doc
17
+ # comments and string-free prose, and leaves the code alone.
18
+ [formats]
19
+ ts = js
20
+
21
+ [*.{md,ts}]
22
+ BasedOnStyles = Vale, Repo
23
+
24
+ # One spell checker, one wordlist. The `spell` slot (cspell) owns spelling and
25
+ # knows the technical vocabulary a plain en_US dictionary flags as errors.
26
+ Vale.Spelling = NO
27
+
28
+ # A vocabulary file is that second wordlist through another door — same reason.
29
+ Vale.Terms = NO
30
+
31
+ # The subjective half. Every other rule here is mechanical; this one is taste,
32
+ # and taste belongs to whoever writes the docs. Read
33
+ # .vale/styles/Repo/Weasel.yml and flip this to YES if you agree with it.
34
+ Repo.Weasel = NO
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "plumbbob",
3
- "version": "0.9.3",
3
+ "version": "0.10.0",
4
4
  "description": "Attention-first build process: 12 skills + a CLI that keep you the decider — guidance on the work, a latch on the record.",
5
5
  "keywords": [
6
6
  "claude-code",
@@ -45,21 +45,22 @@
45
45
  "eval:report": "node test/evals/run.ts --report"
46
46
  },
47
47
  "devDependencies": {
48
- "@ast-grep/cli": "0.43.0",
48
+ "@ast-grep/cli": "0.45.1",
49
49
  "@stryker-mutator/api": "9.6.1",
50
50
  "@stryker-mutator/core": "9.6.1",
51
51
  "@stryker-mutator/vitest-runner": "9.6.1",
52
- "@types/node": "24.13.1",
53
- "@vitest/coverage-v8": "4.1.9",
54
- "fallow": "2.103.0",
52
+ "@types/node": "26.2.0",
53
+ "@vitest/coverage-v8": "4.1.10",
54
+ "@vvago/vale": "3.17.1",
55
+ "fallow": "3.14.0",
55
56
  "fascicle": "0.8.16",
56
- "markdownlint-cli2": "0.22.1",
57
- "oxlint": "1.69.0",
57
+ "markdownlint-cli2": "0.23.2",
58
+ "oxlint": "1.78.0",
58
59
  "typescript": "6.0.3",
59
- "vitest": "4.1.9"
60
+ "vitest": "4.1.10"
60
61
  },
61
62
  "dependencies": {
62
- "checkride": "0.5.2"
63
+ "checkride": "0.12.2"
63
64
  },
64
65
  "bundleDependencies": [
65
66
  "checkride"