@stsepelin/checktrail 0.1.0-alpha.1

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 (385) hide show
  1. package/CONTRIBUTING.md +42 -0
  2. package/LICENSE +21 -0
  3. package/README.md +355 -0
  4. package/SECURITY.md +46 -0
  5. package/dist/src/actionlint-evidence.d.ts +2 -0
  6. package/dist/src/actionlint-evidence.js +166 -0
  7. package/dist/src/actionlint-inputs.d.ts +5 -0
  8. package/dist/src/actionlint-inputs.js +123 -0
  9. package/dist/src/actionlint-runner.d.ts +1 -0
  10. package/dist/src/actionlint-runner.js +122 -0
  11. package/dist/src/actionlint.d.ts +19 -0
  12. package/dist/src/actionlint.js +80 -0
  13. package/dist/src/adapters.d.ts +49 -0
  14. package/dist/src/adapters.js +430 -0
  15. package/dist/src/architecture.d.ts +107 -0
  16. package/dist/src/architecture.js +230 -0
  17. package/dist/src/clang-evidence.d.ts +2 -0
  18. package/dist/src/clang-evidence.js +194 -0
  19. package/dist/src/clang-protocol.d.ts +3 -0
  20. package/dist/src/clang-protocol.js +25 -0
  21. package/dist/src/clang-runner.d.ts +1 -0
  22. package/dist/src/clang-runner.js +159 -0
  23. package/dist/src/clang.d.ts +44 -0
  24. package/dist/src/clang.js +197 -0
  25. package/dist/src/cli.d.ts +2 -0
  26. package/dist/src/cli.js +338 -0
  27. package/dist/src/config.d.ts +33 -0
  28. package/dist/src/config.js +140 -0
  29. package/dist/src/contract-schema.d.ts +85 -0
  30. package/dist/src/contract-schema.js +56 -0
  31. package/dist/src/contract-worker.d.ts +1 -0
  32. package/dist/src/contract-worker.js +123 -0
  33. package/dist/src/contracts.d.ts +22 -0
  34. package/dist/src/contracts.js +123 -0
  35. package/dist/src/django-evidence.d.ts +2 -0
  36. package/dist/src/django-evidence.js +100 -0
  37. package/dist/src/django-runner.d.ts +1 -0
  38. package/dist/src/django-runner.js +80 -0
  39. package/dist/src/django.d.ts +9 -0
  40. package/dist/src/django.js +50 -0
  41. package/dist/src/dotnet-compiler.d.ts +1 -0
  42. package/dist/src/dotnet-compiler.js +87 -0
  43. package/dist/src/dotnet-evidence.d.ts +2 -0
  44. package/dist/src/dotnet-evidence.js +127 -0
  45. package/dist/src/dotnet-runner.d.ts +1 -0
  46. package/dist/src/dotnet-runner.js +167 -0
  47. package/dist/src/dotnet.d.ts +65 -0
  48. package/dist/src/dotnet.js +120 -0
  49. package/dist/src/engine.d.ts +19 -0
  50. package/dist/src/engine.js +239 -0
  51. package/dist/src/environment.d.ts +6 -0
  52. package/dist/src/environment.js +36 -0
  53. package/dist/src/eslint-evidence.d.ts +2 -0
  54. package/dist/src/eslint-evidence.js +98 -0
  55. package/dist/src/eslint-runner.d.ts +1 -0
  56. package/dist/src/eslint-runner.js +61 -0
  57. package/dist/src/eslint.d.ts +2 -0
  58. package/dist/src/eslint.js +40 -0
  59. package/dist/src/evidence.d.ts +2 -0
  60. package/dist/src/evidence.js +313 -0
  61. package/dist/src/external-adapter.d.ts +164 -0
  62. package/dist/src/external-adapter.js +265 -0
  63. package/dist/src/external-evidence.d.ts +2 -0
  64. package/dist/src/external-evidence.js +127 -0
  65. package/dist/src/external-runner.d.ts +1 -0
  66. package/dist/src/external-runner.js +122 -0
  67. package/dist/src/fastapi-evidence.d.ts +2 -0
  68. package/dist/src/fastapi-evidence.js +126 -0
  69. package/dist/src/fastapi-runner.d.ts +1 -0
  70. package/dist/src/fastapi-runner.js +84 -0
  71. package/dist/src/fastapi.d.ts +10 -0
  72. package/dist/src/fastapi.js +52 -0
  73. package/dist/src/fetch-pack.d.ts +16 -0
  74. package/dist/src/fetch-pack.js +154 -0
  75. package/dist/src/finding-policy-schema.d.ts +146 -0
  76. package/dist/src/finding-policy-schema.js +70 -0
  77. package/dist/src/finding-policy.d.ts +62 -0
  78. package/dist/src/finding-policy.js +206 -0
  79. package/dist/src/git-selection.d.ts +3 -0
  80. package/dist/src/git-selection.js +229 -0
  81. package/dist/src/go-directives.d.ts +1 -0
  82. package/dist/src/go-directives.js +32 -0
  83. package/dist/src/go-scope.d.ts +11 -0
  84. package/dist/src/go-scope.js +122 -0
  85. package/dist/src/golangci-evidence.d.ts +2 -0
  86. package/dist/src/golangci-evidence.js +92 -0
  87. package/dist/src/golangci-runner.d.ts +1 -0
  88. package/dist/src/golangci-runner.js +124 -0
  89. package/dist/src/golangci.d.ts +2 -0
  90. package/dist/src/golangci.js +35 -0
  91. package/dist/src/guidance.d.ts +98 -0
  92. package/dist/src/guidance.js +247 -0
  93. package/dist/src/index.d.ts +31 -0
  94. package/dist/src/index.js +16 -0
  95. package/dist/src/inventory.d.ts +4 -0
  96. package/dist/src/inventory.js +94 -0
  97. package/dist/src/java-compiler.d.ts +1 -0
  98. package/dist/src/java-compiler.js +110 -0
  99. package/dist/src/java-evidence.d.ts +2 -0
  100. package/dist/src/java-evidence.js +114 -0
  101. package/dist/src/java-runner.d.ts +1 -0
  102. package/dist/src/java-runner.js +79 -0
  103. package/dist/src/java.d.ts +25 -0
  104. package/dist/src/java.js +102 -0
  105. package/dist/src/jest-evidence.d.ts +2 -0
  106. package/dist/src/jest-evidence.js +117 -0
  107. package/dist/src/jest-runner.d.ts +1 -0
  108. package/dist/src/jest-runner.js +46 -0
  109. package/dist/src/jest.d.ts +2 -0
  110. package/dist/src/jest.js +36 -0
  111. package/dist/src/junit.d.ts +18 -0
  112. package/dist/src/junit.js +157 -0
  113. package/dist/src/laravel-evidence.d.ts +2 -0
  114. package/dist/src/laravel-evidence.js +175 -0
  115. package/dist/src/laravel-runner.d.ts +1 -0
  116. package/dist/src/laravel-runner.js +168 -0
  117. package/dist/src/laravel.d.ts +8 -0
  118. package/dist/src/laravel.js +50 -0
  119. package/dist/src/local-tool.d.ts +1 -0
  120. package/dist/src/local-tool.js +19 -0
  121. package/dist/src/mcp.d.ts +14 -0
  122. package/dist/src/mcp.js +362 -0
  123. package/dist/src/mutation.d.ts +118 -0
  124. package/dist/src/mutation.js +370 -0
  125. package/dist/src/mypy-evidence.d.ts +2 -0
  126. package/dist/src/mypy-evidence.js +63 -0
  127. package/dist/src/mypy.d.ts +2 -0
  128. package/dist/src/mypy.js +59 -0
  129. package/dist/src/node-reporter.d.ts +1 -0
  130. package/dist/src/node-reporter.js +28 -0
  131. package/dist/src/nuxt-evidence.d.ts +2 -0
  132. package/dist/src/nuxt-evidence.js +160 -0
  133. package/dist/src/nuxt-protocol.d.ts +52 -0
  134. package/dist/src/nuxt-protocol.js +29 -0
  135. package/dist/src/nuxt-runner.d.ts +1 -0
  136. package/dist/src/nuxt-runner.js +165 -0
  137. package/dist/src/nuxt.d.ts +24 -0
  138. package/dist/src/nuxt.js +105 -0
  139. package/dist/src/output.d.ts +3 -0
  140. package/dist/src/output.js +48 -0
  141. package/dist/src/phpstan-evidence.d.ts +2 -0
  142. package/dist/src/phpstan-evidence.js +81 -0
  143. package/dist/src/phpstan.d.ts +2 -0
  144. package/dist/src/phpstan.js +51 -0
  145. package/dist/src/phpunit-evidence.d.ts +2 -0
  146. package/dist/src/phpunit-evidence.js +53 -0
  147. package/dist/src/phpunit.d.ts +2 -0
  148. package/dist/src/phpunit.js +58 -0
  149. package/dist/src/pint-evidence.d.ts +2 -0
  150. package/dist/src/pint-evidence.js +79 -0
  151. package/dist/src/pint-runner.d.ts +1 -0
  152. package/dist/src/pint-runner.js +53 -0
  153. package/dist/src/pint.d.ts +2 -0
  154. package/dist/src/pint.js +37 -0
  155. package/dist/src/playwright-evidence.d.ts +2 -0
  156. package/dist/src/playwright-evidence.js +127 -0
  157. package/dist/src/playwright-reporter.d.ts +10 -0
  158. package/dist/src/playwright-reporter.js +37 -0
  159. package/dist/src/playwright-runner.d.ts +1 -0
  160. package/dist/src/playwright-runner.js +61 -0
  161. package/dist/src/playwright.d.ts +2 -0
  162. package/dist/src/playwright.js +35 -0
  163. package/dist/src/policy-pack.d.ts +21 -0
  164. package/dist/src/policy-pack.js +41 -0
  165. package/dist/src/pytest-evidence.d.ts +2 -0
  166. package/dist/src/pytest-evidence.js +116 -0
  167. package/dist/src/pytest-runner.d.ts +1 -0
  168. package/dist/src/pytest-runner.js +48 -0
  169. package/dist/src/pytest.d.ts +2 -0
  170. package/dist/src/pytest.js +25 -0
  171. package/dist/src/report-validation.d.ts +129 -0
  172. package/dist/src/report-validation.js +27 -0
  173. package/dist/src/review.d.ts +270 -0
  174. package/dist/src/review.js +349 -0
  175. package/dist/src/ruby.d.ts +2 -0
  176. package/dist/src/ruby.js +25 -0
  177. package/dist/src/ruff-evidence.d.ts +2 -0
  178. package/dist/src/ruff-evidence.js +99 -0
  179. package/dist/src/ruff.d.ts +2 -0
  180. package/dist/src/ruff.js +40 -0
  181. package/dist/src/runner.d.ts +8 -0
  182. package/dist/src/runner.js +117 -0
  183. package/dist/src/runtime-inventory.d.ts +112 -0
  184. package/dist/src/runtime-inventory.js +200 -0
  185. package/dist/src/rust-dep-info.d.ts +1 -0
  186. package/dist/src/rust-dep-info.js +46 -0
  187. package/dist/src/rust-evidence.d.ts +2 -0
  188. package/dist/src/rust-evidence.js +157 -0
  189. package/dist/src/rust-runner.d.ts +1 -0
  190. package/dist/src/rust-runner.js +161 -0
  191. package/dist/src/rust.d.ts +7 -0
  192. package/dist/src/rust.js +39 -0
  193. package/dist/src/sarif.d.ts +86 -0
  194. package/dist/src/sarif.js +113 -0
  195. package/dist/src/schemas.d.ts +393 -0
  196. package/dist/src/schemas.js +222 -0
  197. package/dist/src/staticcheck-evidence.d.ts +2 -0
  198. package/dist/src/staticcheck-evidence.js +75 -0
  199. package/dist/src/swift.d.ts +2 -0
  200. package/dist/src/swift.js +20 -0
  201. package/dist/src/task-store.d.ts +37 -0
  202. package/dist/src/task-store.js +349 -0
  203. package/dist/src/tool-versions.d.ts +3 -0
  204. package/dist/src/tool-versions.js +260 -0
  205. package/dist/src/types.d.ts +157 -0
  206. package/dist/src/types.js +37 -0
  207. package/dist/src/typescript-build-evidence.d.ts +2 -0
  208. package/dist/src/typescript-build-evidence.js +86 -0
  209. package/dist/src/typescript-build-runner.d.ts +1 -0
  210. package/dist/src/typescript-build-runner.js +132 -0
  211. package/dist/src/typescript-build.d.ts +2 -0
  212. package/dist/src/typescript-build.js +41 -0
  213. package/dist/src/typescript.d.ts +2 -0
  214. package/dist/src/typescript.js +54 -0
  215. package/dist/src/validation-task-worker.d.ts +1 -0
  216. package/dist/src/validation-task-worker.js +205 -0
  217. package/dist/src/validation-tasks-protocol.d.ts +69 -0
  218. package/dist/src/validation-tasks-protocol.js +57 -0
  219. package/dist/src/validation-tasks.d.ts +11 -0
  220. package/dist/src/validation-tasks.js +144 -0
  221. package/dist/src/vitest-evidence.d.ts +2 -0
  222. package/dist/src/vitest-evidence.js +112 -0
  223. package/dist/src/vitest-runner.d.ts +1 -0
  224. package/dist/src/vitest-runner.js +48 -0
  225. package/dist/src/vitest.d.ts +2 -0
  226. package/dist/src/vitest.js +36 -0
  227. package/dist/src/vue-router-capture.d.ts +42 -0
  228. package/dist/src/vue-router-capture.js +87 -0
  229. package/dist/src/vue-router-evidence.d.ts +2 -0
  230. package/dist/src/vue-router-evidence.js +126 -0
  231. package/dist/src/vue-router-protocol.d.ts +63 -0
  232. package/dist/src/vue-router-protocol.js +44 -0
  233. package/dist/src/vue-router-runner.d.ts +1 -0
  234. package/dist/src/vue-router-runner.js +88 -0
  235. package/dist/src/vue-router.d.ts +23 -0
  236. package/dist/src/vue-router.js +108 -0
  237. package/dist/src/vue-tsc-runner.d.ts +1 -0
  238. package/dist/src/vue-tsc-runner.js +24 -0
  239. package/dist/src/workspace.d.ts +7 -0
  240. package/dist/src/workspace.js +53 -0
  241. package/docs/ACCEPTANCE.md +56 -0
  242. package/docs/ACTIONLINT.md +112 -0
  243. package/docs/ARCHITECTURE-POLICY.md +82 -0
  244. package/docs/ARCHITECTURE.md +122 -0
  245. package/docs/CLANG.md +113 -0
  246. package/docs/CLIENTS.md +109 -0
  247. package/docs/CONTRACTS.md +73 -0
  248. package/docs/DEPENDENCIES.md +42 -0
  249. package/docs/DJANGO.md +70 -0
  250. package/docs/DOTNET.md +114 -0
  251. package/docs/ENVIRONMENTS.md +52 -0
  252. package/docs/ESLINT.md +68 -0
  253. package/docs/EVALUATION.md +124 -0
  254. package/docs/EXECUTION.md +250 -0
  255. package/docs/EXTERNAL-ADAPTERS.md +170 -0
  256. package/docs/EXTERNAL-EVALUATION.md +155 -0
  257. package/docs/EXTERNAL-RUFF-EVALUATION.md +85 -0
  258. package/docs/FASTAPI.md +73 -0
  259. package/docs/FINDING-POLICY.md +67 -0
  260. package/docs/GO-RACE.md +19 -0
  261. package/docs/GO-SCOPE.md +63 -0
  262. package/docs/GOLANGCI-LINT.md +64 -0
  263. package/docs/GUIDANCE.md +46 -0
  264. package/docs/IMPACT-MEASUREMENT.md +97 -0
  265. package/docs/INSTALLATION.md +102 -0
  266. package/docs/JAVA.md +79 -0
  267. package/docs/JEST.md +36 -0
  268. package/docs/JUNIT.md +31 -0
  269. package/docs/LANGUAGES.md +113 -0
  270. package/docs/LARAVEL.md +111 -0
  271. package/docs/MCP-COMPATIBILITY.md +68 -0
  272. package/docs/MUTATIONS.md +93 -0
  273. package/docs/MYPY.md +37 -0
  274. package/docs/NATIVE-CI.md +96 -0
  275. package/docs/NUXT.md +123 -0
  276. package/docs/PACK-DISTRIBUTION.md +98 -0
  277. package/docs/PERFORMANCE.md +71 -0
  278. package/docs/PEST.md +36 -0
  279. package/docs/PHPSTAN.md +48 -0
  280. package/docs/PHPUNIT.md +32 -0
  281. package/docs/PINT.md +41 -0
  282. package/docs/PLAN.md +265 -0
  283. package/docs/PLAYWRIGHT.md +73 -0
  284. package/docs/POLICY-PACKS.md +106 -0
  285. package/docs/PRIOR-WORKFLOW-EVALUATION.md +116 -0
  286. package/docs/PUBLICATION.md +28 -0
  287. package/docs/PYTEST.md +51 -0
  288. package/docs/RELEASE.md +115 -0
  289. package/docs/RENAMING.md +55 -0
  290. package/docs/REVIEW-EXCHANGE.md +136 -0
  291. package/docs/RUBY.md +50 -0
  292. package/docs/RUFF.md +39 -0
  293. package/docs/RUNTIME-INVENTORY.md +56 -0
  294. package/docs/RUST.md +74 -0
  295. package/docs/SARIF.md +64 -0
  296. package/docs/STATUS.md +530 -0
  297. package/docs/SWIFT.md +48 -0
  298. package/docs/TASK-STORAGE.md +141 -0
  299. package/docs/TOOL-IDENTITY.md +30 -0
  300. package/docs/TYPESCRIPT-BUILD.md +55 -0
  301. package/docs/VALIDATION-TASKS.md +119 -0
  302. package/docs/VITEST.md +36 -0
  303. package/docs/VUE-ROUTER.md +130 -0
  304. package/docs/VUE-TSC.md +26 -0
  305. package/docs/WORKSPACES.md +81 -0
  306. package/docs/licenses/nodable-entities-3.0.0.txt +21 -0
  307. package/docs/measurements/client-claude-before-schema-fix-darwin-arm64-node26.json +60 -0
  308. package/docs/measurements/client-claude-darwin-arm64-node26.json +55 -0
  309. package/docs/measurements/client-codex-darwin-arm64-node26.json +175 -0
  310. package/docs/measurements/evaluation-corpus-repo-verifier.json +332 -0
  311. package/docs/measurements/evaluation-darwin-arm64-node26.json +1236 -0
  312. package/docs/measurements/evaluation-linux-arm64-node22.json +1236 -0
  313. package/docs/measurements/external-eslint-darwin-arm64-node26.json +11866 -0
  314. package/docs/measurements/external-eslint-linux-arm64-node22.json +11866 -0
  315. package/docs/measurements/external-eslint-preservation.json +1527 -0
  316. package/docs/measurements/external-ruff-darwin-arm64-node26.json +1031 -0
  317. package/docs/measurements/external-ruff-linux-arm64-node22.json +1031 -0
  318. package/docs/measurements/hosted-ci-52ba415.json +1005 -0
  319. package/docs/measurements/impact-darwin-arm64-node26.json +6685 -0
  320. package/docs/measurements/impact-linux-arm64-node22.json +6690 -0
  321. package/docs/measurements/performance-darwin-arm64-node26.json +845 -0
  322. package/docs/measurements/performance-linux-arm64-node22.json +845 -0
  323. package/docs/measurements/required-native-profiles.json +500 -0
  324. package/package.json +72 -0
  325. package/packs/actionlint.json +8 -0
  326. package/packs/cpp.json +8 -0
  327. package/packs/dotnet.json +8 -0
  328. package/packs/go.json +7 -0
  329. package/packs/java.json +8 -0
  330. package/packs/javascript-node.json +7 -0
  331. package/packs/nuxt.json +7 -0
  332. package/packs/php-pest.json +7 -0
  333. package/packs/php-phpunit.json +7 -0
  334. package/packs/python-pytest.json +7 -0
  335. package/packs/ruby.json +7 -0
  336. package/packs/rust.json +7 -0
  337. package/packs/swift.json +7 -0
  338. package/packs/vue-router.json +7 -0
  339. package/packs/vue.json +11 -0
  340. package/schemas/actionlint-config.schema.json +19 -0
  341. package/schemas/architecture-policy.schema.json +51 -0
  342. package/schemas/architecture-report.schema.json +123 -0
  343. package/schemas/architecture-summary.schema.json +82 -0
  344. package/schemas/clang-database.schema.json +23 -0
  345. package/schemas/config.schema.json +69 -0
  346. package/schemas/contract-bundle.schema.json +78 -0
  347. package/schemas/contract-report.schema.json +114 -0
  348. package/schemas/contract-summary.schema.json +72 -0
  349. package/schemas/dependency-graph.schema.json +65 -0
  350. package/schemas/django-config.schema.json +16 -0
  351. package/schemas/dotnet-config.schema.json +60 -0
  352. package/schemas/external-manifest.schema.json +97 -0
  353. package/schemas/external-reference.schema.json +10 -0
  354. package/schemas/external-request.schema.json +56 -0
  355. package/schemas/external-result.schema.json +111 -0
  356. package/schemas/fastapi-config.schema.json +27 -0
  357. package/schemas/finding-baseline.schema.json +92 -0
  358. package/schemas/finding-comparison-summary.schema.json +95 -0
  359. package/schemas/finding-comparison.schema.json +121 -0
  360. package/schemas/guidance-context.schema.json +34 -0
  361. package/schemas/guidance-report.schema.json +176 -0
  362. package/schemas/guidance-summary.schema.json +68 -0
  363. package/schemas/java-config.schema.json +24 -0
  364. package/schemas/junit.schema.json +69 -0
  365. package/schemas/laravel-config.schema.json +11 -0
  366. package/schemas/mutation-recipe.schema.json +31 -0
  367. package/schemas/mutation-report.schema.json +238 -0
  368. package/schemas/mutation-summary.schema.json +98 -0
  369. package/schemas/nuxt-config.schema.json +51 -0
  370. package/schemas/plan-summary.schema.json +63 -0
  371. package/schemas/plan.schema.json +244 -0
  372. package/schemas/policy-pack.schema.json +41 -0
  373. package/schemas/report-summary.schema.json +100 -0
  374. package/schemas/report.schema.json +463 -0
  375. package/schemas/review-assessment.schema.json +133 -0
  376. package/schemas/review-context-summary.schema.json +31 -0
  377. package/schemas/review-context.schema.json +254 -0
  378. package/schemas/review-receipt-summary.schema.json +104 -0
  379. package/schemas/review-receipt.schema.json +271 -0
  380. package/schemas/review-selection.schema.json +30 -0
  381. package/schemas/runtime-comparison-summary.schema.json +68 -0
  382. package/schemas/runtime-comparison.schema.json +127 -0
  383. package/schemas/runtime-inventory.schema.json +99 -0
  384. package/schemas/vue-router-config.schema.json +67 -0
  385. package/server.json +47 -0
@@ -0,0 +1,42 @@
1
+ # Contributing
2
+
3
+ Read `docs/ARCHITECTURE.md` and `docs/LANGUAGES.md` before changing engine contracts.
4
+ Use Node 22+ and `npm ci --ignore-scripts`. Run `npm run check` and
5
+ `npm run format:check`; invoke the binaries in `node_modules/.bin` directly if a
6
+ package-manager wrapper cannot start. The local HTTPS distribution tests require
7
+ `openssl` to generate ephemeral test certificates. Report which native toolchains
8
+ were exercised. Run the corresponding [required native profile](docs/NATIVE-CI.md)
9
+ when its tools are prepared. Review the profile manifest when renaming or replacing
10
+ a required regression; skipped or missing native tests cannot satisfy CI.
11
+
12
+ ## Rules and adapters
13
+
14
+ Propose the failure mechanism, applicability and expected evidence before adding
15
+ a matcher. Include broken/fixed/near-miss fixtures. Check normalized identifiers,
16
+ boundary values and unsupported output. Never let parse failures fall back to pass.
17
+ Document tool versions and platform coverage. Do not infer semantic support from
18
+ a manifest or extension. Update the language matrix and implementation status.
19
+
20
+ Keep native commands as argument arrays and use the shared runner. Do not execute
21
+ repository code during discovery. Treat plugins as executable code, not passive
22
+ configuration. Preserve operator-controlled trust and output settings.
23
+ The executable extension protocol and original example are documented in
24
+ `docs/EXTERNAL-ADAPTERS.md`; bundled files require explicit digests and license
25
+ review. A protocol-conforming adapter still needs native regression evidence.
26
+
27
+ ## Public examples
28
+
29
+ Write small fictional examples from scratch. Do not copy private source and rename
30
+ identifiers. Do not submit credentials, internal hostnames, paths, incident reports,
31
+ customer data or proprietary repository snapshots. Verify fixture licensing and
32
+ provenance. Keep raw private test reports out of issues and pull requests.
33
+
34
+ ## Scope and review
35
+
36
+ Separate behavior changes from dependency updates. Explain what a passing result
37
+ proves and what remains unverified. A test that merely matches the implementation
38
+ is insufficient: identify the regression it prevents. Changes to result semantics,
39
+ configuration schemas or protocol behavior require migration notes and tests.
40
+
41
+ The maintainer controls releases. Do not publish packages, register remote services
42
+ or create release tags as a side effect of development automation.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 stsepelin
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,355 @@
1
+ # Checktrail
2
+
3
+ Local code validation with a CLI, MCP tools, and evidence of what actually ran.
4
+
5
+ Formerly Repo Verifier. See the [rename guide](docs/RENAMING.md) for existing source checkouts.
6
+
7
+ **Experimental preview: 0.1.0-alpha.1.** Public source is available at
8
+ [stsepelin/checktrail](https://github.com/stsepelin/checktrail).
9
+ See [implementation status](docs/STATUS.md), the [plan](docs/PLAN.md) and the
10
+ [language matrix](docs/LANGUAGES.md) before relying on an adapter.
11
+ [Installation](docs/INSTALLATION.md) covers the CLI, Claude Code and Codex.
12
+ [Release preparation](docs/RELEASE.md) records publication and verification gates. The
13
+ [milestone audit](docs/ACCEPTANCE.md) separates implemented profiles from open
14
+ acceptance work; [client checks](docs/CLIENTS.md) record actual application coverage.
15
+
16
+ The [13-job hosted matrix](https://github.com/stsepelin/checktrail/actions/runs/35573066804)
17
+ passed at `52ba415` on Linux and macOS. This identifies a verified source revision;
18
+ it does not imply that a later package version has been published.
19
+
20
+ Checktrail discovers projects, plans registered checks, invokes native tools
21
+ when explicitly trusted, and reports results without turning skipped or empty
22
+ checks into success. The same engine serves developers, CI and MCP clients.
23
+
24
+ The optional library [task store](docs/TASK-STORAGE.md) retains local validation
25
+ results across restarts. A [library worker](docs/VALIDATION-TASKS.md) adds native
26
+ execution, polling and cancellation. MCP reports still use memory; standard Tasks integration
27
+ remains pending.
28
+
29
+ ## Try the local checkout
30
+
31
+ Requires Node.js 22 or newer. Execution currently targets macOS and Linux.
32
+
33
+ ```sh
34
+ npm ci --ignore-scripts
35
+ npm run build
36
+ node dist/src/cli.js plan --root examples/javascript --detailed
37
+ node dist/src/cli.js run --root examples/javascript --trust-project --detailed
38
+ ```
39
+
40
+ `plan` and `inspect` read files without executing project code. `run` requires
41
+ `--trust-project`: tests, compiler plugins and project configuration can execute
42
+ code with your user privileges. This is not a sandbox.
43
+
44
+ Commands always return JSON except help/version. Exit codes:
45
+
46
+ | Code | Meaning |
47
+ | ---- | --------------------------------------------------------------------------------------- |
48
+ | 0 | Selected checks passed, read-only operation succeeded, or advisory experiment completed |
49
+ | 1 | At least one selected check failed |
50
+ | 2 | Required evidence is incomplete, execution is untrusted, or input is invalid |
51
+
52
+ A passing run applies to the selected checks and scope only. PHP syntax passing
53
+ does not imply its application tests passed. Unknown frameworks and empty plans
54
+ are incomplete. A source change during validation prevents an aggregate pass.
55
+
56
+ ## Initial adapters
57
+
58
+ | Ecosystem | Execution in this foundation |
59
+ | ----------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
60
+ | JavaScript | Native Node tests; explicit ESLint checking with per-file coverage evidence |
61
+ | Python | Explicit unittest/pytest tests and Ruff/mypy checks |
62
+ | Go | gofmt check, go vet, uncached go test with JSON events |
63
+ | PHP | Syntax checks and explicit PHPStan analysis; native verification in status |
64
+ | TypeScript | Explicit `javascript.typescript`: local tsc, no emit, file inclusion evidence |
65
+ | Jest | Explicit `javascript.jest`: native result accounting; pending tests are incomplete |
66
+ | Vue | Explicit `javascript.vue-tsc`: SFC and TS checking; opt-in `javascript.vue-router` route contracts |
67
+ | Vitest | Explicit `javascript.vitest`: native JSON counts and exact test-file accounting |
68
+ | Playwright | Explicit `javascript.playwright`: native test/project evidence and prepared browsers |
69
+ | Other framework test runners | Manifest discovery; execution integrations planned |
70
+ | Rust | Locked offline Cargo check with native target and source accounting; no test execution |
71
+ | Ruby | MRI syntax checking of Ruby source and DSL manifests; no gem loading or test execution |
72
+ | Swift | Native grammar checking of Swift source and Package.swift; no type checking or tests |
73
+ | C / C++ | Prepared Clang compilation databases, native diagnostics and source/header accounting; no linking or tests |
74
+ | Java | Explicit classpath compilation, pinned JARs and native source/analysis accounting; no tests |
75
+ | C# / .NET | Explicit Roslyn compilation, pinned DLL references and native syntax/semantic accounting; no build targets or tests |
76
+ | GitHub Actions | Static workflow checking with local input and per-file native evidence; no job execution |
77
+ | Kotlin, Scala, F#, Visual Basic, other infrastructure | Discovery only; execution reports unavailable |
78
+
79
+ Tools must already be installed. No dependency installation, automatic fixes,
80
+ service startup, migrations, commits or deployments are performed by the engine.
81
+ Go execution disables module proxy downloads and toolchain auto-downloads. The
82
+ [Rust profile](docs/RUST.md) uses locked offline Cargo and disables rustup auto-installation. Other
83
+ invoked tools and test code can still access the network.
84
+
85
+ ## Select checks
86
+
87
+ Without configuration, registered defaults apply to each detected project.
88
+ Node tests are selected automatically only for the exact script `node --test`.
89
+ Python needs an explicit selection because a manifest does not identify a runner.
90
+ Create `checktrail.json` in the inspected root:
91
+
92
+ ```json
93
+ {
94
+ "schemaVersion": 1,
95
+ "projects": [
96
+ { "path": "web", "checks": ["javascript.node-test", "javascript.eslint"] },
97
+ { "path": "library", "checks": ["javascript.typescript"] },
98
+ { "path": "service", "checks": ["go.format", "go.vet", "go.test"] },
99
+ { "path": "worker", "checks": ["python.unittest"] }
100
+ ]
101
+ }
102
+ ```
103
+
104
+ When present, this file selects only the listed projects/checks. Paths are exact
105
+ discovered project roots relative to `--root`; use `.` for that root itself.
106
+ Configuration cannot supply arbitrary commands or enable execution permissions.
107
+ The [schema](schemas/config.schema.json) rejects unknown fields and check IDs are
108
+ validated by the engine. Private configuration and rules need not be published.
109
+ Local public/private JSON packs and additive operator overlays are implemented;
110
+ see [policy packs](docs/POLICY-PACKS.md). An explicit
111
+ [`fetch-pack` command](docs/PACK-DISTRIBUTION.md) can download a pinned data-only
112
+ pack over HTTPS for later offline use.
113
+
114
+ Operator-registered [external adapters](docs/EXTERNAL-ADAPTERS.md) can run a pinned
115
+ local Node, Python, PHP or native executable bundle. Repository configuration can
116
+ select their registered checks; execution still requires operator trust. The
117
+ protocol checks evidence completeness, while the adapter author remains responsible
118
+ for the correctness of its analysis.
119
+
120
+ The TypeScript check requires a local `tsconfig.json` and an installed compiler
121
+ inside the configured root (project-local or hoisted to an ancestor). It disables
122
+ `noCheck`, emission and incremental state. Every inventoried `.ts`, `.tsx`, `.mts`
123
+ and `.cts` file in that project must appear in the compiler's file list. A clean
124
+ compiler exit with excluded source is incomplete. Other compiler options, including
125
+ strictness and declaration checking, come from the project config. Use `javascript.typescript-build` for
126
+ [project-reference solutions](docs/TYPESCRIPT-BUILD.md) with fresh in-memory
127
+ declarations. Vue SFC checking uses its separate adapter.
128
+ TypeScript 6.0.3 is exercised in integration tests; other versions are unverified.
129
+
130
+ `javascript.vue-router` captures a selected native testing router and verifies
131
+ complete record participation in declared URL probes; see the
132
+ [Vue Router profile](docs/VUE-ROUTER.md) for versions and projection limits.
133
+ `javascript.nuxt-runtime` builds a fresh SSR testing assembly and checks native
134
+ router capture after in-process requests; see the [Nuxt profile](docs/NUXT.md).
135
+ `python.fastapi-routes` captures a configured FastAPI application's supported flat
136
+ route table after lifespan startup and detects exact duplicate registrations.
137
+ See the [FastAPI profile](docs/FASTAPI.md) for native versions and scope limits.
138
+ `python.django-routes` captures supported nested URL resolver chains after Django
139
+ setup; see the [Django profile](docs/DJANGO.md).
140
+ `php.laravel-runtime` captures the testing assembly's routes, middleware, listeners,
141
+ schedules and container binding projection. Compare inventories to detect wiring
142
+ changes; see the [Laravel profile](docs/LARAVEL.md) for bootstrap behavior and limits.
143
+
144
+ `javascript.eslint` uses an installed ESLint and a project-local JavaScript flat
145
+ config. Ignored files, unmatched configuration and files with no enabled rules
146
+ make the check incomplete. Errors and warnings fail it. It preserves existing
147
+ lint caches and performs no fixes. See the [ESLint contract](docs/ESLINT.md) for
148
+ scope, configuration requirements and verified tool support.
149
+
150
+ `javascript.vitest` runs an installed Vitest once, requires each planned test file
151
+ in the report, and rejects empty/all-skipped results. It disables focused tests,
152
+ snapshot updates and automatic dependency installation. See the
153
+ [Vitest contract](docs/VITEST.md) for tested versions and limitations.
154
+
155
+ `javascript.playwright` reconciles native tests, projects and retry outcomes,
156
+ requires preinstalled browsers, and protects snapshots. See the
157
+ [Playwright contract](docs/PLAYWRIGHT.md).
158
+
159
+ `javascript.jest` requires native assertion and file accounting and treats pending
160
+ tests conservatively as incomplete. See the [Jest contract](docs/JEST.md).
161
+ `javascript.vue-tsc` checks Vue SFCs and TypeScript without emitting output, and
162
+ rejects disabled template checking. See the [Vue contract](docs/VUE-TSC.md).
163
+
164
+ `python.pytest` reconciles native collection and setup/call/teardown evidence.
165
+ See the [pytest contract](docs/PYTEST.md) for scope and prepared runtimes.
166
+
167
+ `python.ruff` requires exact native file selection and active-rule evidence, with
168
+ fixes disabled. See the [Ruff contract](docs/RUFF.md).
169
+
170
+ `python.mypy` checks explicit source with native source-count evidence and rejects
171
+ broad module-error suppression. See the [mypy contract](docs/MYPY.md).
172
+
173
+ `go.test-race` adds opt-in native race instrumentation with uncached test evidence.
174
+ See the [Go race contract](docs/GO-RACE.md). Go checks reconcile native package
175
+ selection with inventoried source; `go.staticcheck` adds explicit all-rule analysis
176
+ and normalized findings. See [Go scope](docs/GO-SCOPE.md). The constrained
177
+ [`go.golangci-lint` profile](docs/GOLANGCI-LINT.md) accepts explicit native linter
178
+ selection while disabling hidden issue filters and fixes.
179
+
180
+ `php.phpstan` combines per-file analysis accounting with native JSON diagnostics.
181
+ See the [PHPStan contract](docs/PHPSTAN.md).
182
+
183
+ `php.phpunit` streams fresh native JUnit evidence with file and assertion
184
+ accounting. See the [PHPUnit contract](docs/PHPUNIT.md). Existing JUnit artifacts
185
+ can also be [imported separately](docs/JUNIT.md); import does not verify current
186
+ source or execution freshness.
187
+
188
+ `php.pest` runs focused siblings in CI mode and disables cached test-impact
189
+ replay; see [Pest](docs/PEST.md). `php.pint` validates formatting with native
190
+ file and rule accounting; see [Pint](docs/PINT.md).
191
+
192
+ Detailed reports include normalized source findings for ESLint, Ruff and
193
+ PHPStan, Staticcheck, golangci-lint and TypeScript solution builds. [SARIF export](docs/SARIF.md) preserves failures and incomplete execution
194
+ without treating an empty findings list as success.
195
+
196
+ Projects can [declare environment requirements](docs/ENVIRONMENTS.md), supplied
197
+ only through operator `--allow-env NAME` permissions or explicit library options.
198
+ MCP tool calls cannot grant environment access.
199
+
200
+ Use [workspace dependencies and Git selection](docs/WORKSPACES.md) with
201
+ `--base REVISION` to validate changed projects and their declared consumers.
202
+ Uncertain impact retains the full configured plan.
203
+
204
+ ## MCP
205
+
206
+ Run the server from the built checkout:
207
+
208
+ ```sh
209
+ node dist/src/cli.js serve --root /path/to/your/repository
210
+ ```
211
+
212
+ For a client that accepts a command/arguments server definition:
213
+
214
+ ```json
215
+ {
216
+ "mcpServers": {
217
+ "checktrail": {
218
+ "command": "node",
219
+ "args": [
220
+ "/path/to/checktrail/dist/src/cli.js",
221
+ "serve",
222
+ "--root",
223
+ "/path/to/your/repository"
224
+ ]
225
+ }
226
+ }
227
+ }
228
+ ```
229
+
230
+ The available tools are `project_context`, `validation_plan`, `validation_run`,
231
+ `validation_report`, `finding_comparison`, `runtime_comparison`, `contract_validation`,
232
+ `architecture_validation`, `review_guidance`, `review_context`, `review_receipt`,
233
+ and `mutation_experiment`. The first two currently return the same project/check
234
+ inventory; advisory guidance and source review use their separate tools. Reports are kept
235
+ in memory (the latest ten) and disappear when the process exits.
236
+
237
+ Add `--allow-execution` to server arguments only for trusted project execution.
238
+ The model cannot grant that permission through a tool argument. Add `--detailed`
239
+ only if the client may receive paths, commands and raw diagnostics. The default
240
+ summary omits those fields. Data returned through an MCP client may be sent to
241
+ that client's model provider.
242
+
243
+ The implementation uses the official MCP v2 SDK. Automated tests exercise the
244
+ 2026-07-28 protocol and the SDK's legacy negotiation over stdio. This does not
245
+ establish compatibility with every editor or agent application.
246
+
247
+ Validation runs asynchronously and supports cancellation, but returns its report
248
+ on the original tool call. The optional durable Tasks extension is not implemented.
249
+ See [MCP compatibility](docs/MCP-COMPATIBILITY.md) for lifecycle tests, the reproduced
250
+ SDK routing limitation and the remaining Tasks work.
251
+
252
+ Exact finding baselines and exceptions are available through the CLI, library and
253
+ MCP. [Finding policy](docs/FINDING-POLICY.md) describes creation, expiration,
254
+ staleness and expansion checks. A successful comparison retains the separate
255
+ native validation outcome; it never changes a failed validation into a pass.
256
+
257
+ [Runtime inventory comparison](docs/RUNTIME-INVENTORY.md) checks local before/after
258
+ assembly artifacts for changed registrations, attributes, duplicates and order.
259
+ Imported artifacts retain explicit completeness and provenance limits.
260
+
261
+ [Public policy packs and private overlays](docs/POLICY-PACKS.md) compose registered
262
+ checks with pinned SHA-256 integrity. Use `--policy-overlay` at CLI invocation or
263
+ MCP startup for local additions to checked-in requirements.
264
+
265
+ [Captured contract checks](docs/CONTRACTS.md) validate producer JSON against strict
266
+ consumer schemas, with worker deadlines and separately labeled imported evidence.
267
+
268
+ ## Limits and evidence
269
+
270
+ Detailed reports include [tool identity evidence](docs/TOOL-IDENTITY.md). Native
271
+ version probes share execution limits and require operator trust; missing identity
272
+ prevents a successful check from being reported as passed.
273
+
274
+ Inventory excludes dependency/build directories, symlinks and common secret-file
275
+ names. It does not apply `.gitignore`. Optional Git selection retains these exclusions. Limits are
276
+ 20,000 entries, depth 32, 8 MiB per file and 64 MiB total file bytes. A source
277
+ fingerprint covers included contents and exclusion names, not ignored dependencies,
278
+ external configuration, tool binaries or services.
279
+
280
+ Execution has a run-wide time budget (30 seconds by default, configurable up to
281
+ 120 seconds), 1 MiB output per command and 4 MiB across a run. Timeouts, cancelled
282
+ work, truncated output and malformed test evidence are incomplete. Detailed
283
+ reports include process output; do not publish reports from private repositories.
284
+
285
+ Results are not proof against malicious project code: a trusted test can forge
286
+ output, alter other files or start detached processes. Isolation and attestation
287
+ are separate future capabilities. See [security](SECURITY.md).
288
+
289
+ ## Development
290
+
291
+ ```sh
292
+ npm run check
293
+ npm run format:check
294
+ node scripts/smoke-package.mjs
295
+ ```
296
+
297
+ Tests include real process execution, native adapter integration where tools are
298
+ available, source-change detection, output limits, schemas, CLI exit codes and
299
+ MCP calls. Missing native tools are explicitly skipped locally; CI prepares tools
300
+ and requires exact native regression names through [required profiles](docs/NATIVE-CI.md). Run `node scripts/generate-schemas.mjs` after building when
301
+ changing schema definitions; tests reject drift in the checked-in JSON schemas.
302
+
303
+ All examples and fixtures are synthetic. Contributions must include a minimal
304
+ broken case, its fix, and a valid near miss where applicable. See
305
+ [contributing](CONTRIBUTING.md). Licensed under [MIT](LICENSE).
306
+
307
+ Explicit [architecture policies](docs/ARCHITECTURE-POLICY.md) check captured project
308
+ dependencies against literal layer allowlists and optional cycle restrictions.
309
+ Imported graph completeness is declared evidence; native import discovery is not
310
+ implied. The public [built-package fixture](examples/package-contract/README.md)
311
+ exercises an installed producer through consumer type and runtime checks.
312
+
313
+ ## Advisory review assistance
314
+
315
+ Use `guidance --root PATH` for public review questions selected from planned
316
+ checks, or add an explicit `--topic`. This read-only operation makes no coverage
317
+ claim and invokes no model. See [guidance](docs/GUIDANCE.md).
318
+
319
+ Use `mutate --root examples/mutations --input mutations.json --trust-project` for
320
+ a bounded experiment in temporary source copies. Its initial profile supports
321
+ flat Node tests in dependency-free projects. Assertion kills, survivors and
322
+ inconclusive execution are separate advisory results; see [mutation experiments](docs/MUTATIONS.md).
323
+
324
+ The [C/C++ profile](docs/CLANG.md) validates prepared Clang argument arrays and
325
+ requires native dependency coverage for inventoried translation units and headers.
326
+ It does not run build systems, generate missing headers, link or execute tests.
327
+
328
+ The [Java profile](docs/JAVA.md) compiles inventoried sources with an explicit
329
+ release and pinned local dependencies. Maven/Gradle, annotation processors and
330
+ application tests are not executed.
331
+
332
+ Reproduce synthetic planning and execution costs with the
333
+ [performance harness](docs/PERFORMANCE.md). Reports retain raw measurements and
334
+ artifact identities; the documented snapshots are observations, not speed guarantees.
335
+
336
+ The [C# profile](docs/DOTNET.md) uses a prepared .NET SDK and explicit compilation
337
+ settings. Project build targets, source generators and test runners are separate
338
+ capabilities.
339
+
340
+ The [GitHub Actions profile](docs/ACTIONLINT.md) checks inventoried workflows with
341
+ explicit runner labels and variables, local dependency checks and native completion
342
+ evidence. It does not execute workflow jobs or action code.
343
+
344
+ [Development evaluation](docs/EVALUATION.md) records per-family detection,
345
+ false-positive and incomplete-result counts against direct native commands.
346
+ These small synthetic observations do not establish independent review quality.
347
+
348
+ [Impact measurements](docs/IMPACT-MEASUREMENT.md) compare full and Git-selected
349
+ validation, including missed consumer failures when dependency declarations are
350
+ wrong. Fewer selected checks alone do not establish a safe or faster run.
351
+
352
+ Optional [`review-context` and `review-receipt`](docs/REVIEW-EXCHANGE.md) exchange
353
+ bounded selected source and external reviewer assessments. Source and review prose
354
+ require `--detailed --allow-review-source`; claims and declared usage remain advisory.
355
+ The engine does not call a model or upload code.
package/SECURITY.md ADDED
@@ -0,0 +1,46 @@
1
+ # Security and data handling
2
+
3
+ Checktrail is an experimental local tool, not an execution sandbox or a security
4
+ certification. Run project checks only on source you trust or inside a separately
5
+ configured isolated environment.
6
+
7
+ ## Boundaries
8
+
9
+ - Discovery reads files within the configured root without importing project code.
10
+ - Known checks use executable/argument arrays rather than shell commands.
11
+ - Execution requires a CLI flag or a server startup flag, never a tool argument.
12
+ - Child processes receive a small environment allowlist (PATH, HOME, temporary
13
+ directory and locale variables) plus fixed adapter settings. They still have
14
+ access to the user's filesystem and any network permitted by the host.
15
+ - POSIX process groups are killed on timeout/cancellation. Malicious code can
16
+ detach from a group; process groups are not a containment boundary.
17
+ - Inventory does not follow symlinks, and resolved working directories must remain
18
+ under the configured root. Concurrent filesystem replacement can race inspection;
19
+ only operating-system isolation can contain adversarial filesystem mutation.
20
+ - External adapters are trusted executable dependencies registered by the operator.
21
+ SHA-256 pins verify declared bytes, not their author or correctness. Only listed
22
+ files are copied; imported system dependencies and invoked tools are not thereby
23
+ pinned. Adapter code retains filesystem/network privileges and can fabricate
24
+ evidence. See `docs/EXTERNAL-ADAPTERS.md`.
25
+ - Source fingerprints cover the documented inventory, not the entire build world.
26
+
27
+ ## Output
28
+
29
+ The engine contains no telemetry or upload client. The explicit `fetch-pack`
30
+ CLI/library operation sends a bounded HTTPS GET to an operator-selected endpoint;
31
+ validation and MCP never invoke it automatically. Signed endpoint URLs may carry
32
+ credentials, so avoid exposing them in shell history or shared process arguments. Invoked programs may contact
33
+ services or send data independently. Summary MCP output excludes paths, commands,
34
+ source excerpts and raw logs; it still reveals check IDs, status and test counts.
35
+ Detailed mode exposes diagnostics and may disclose source or secrets. An MCP client
36
+ may forward received output to a cloud provider.
37
+
38
+ There is no claim that secret-name exclusions identify every secret. Protect the
39
+ whole repository and report store. Public packages must contain only synthetic
40
+ examples and reviewed files. The package allowlist excludes local reports and tests.
41
+
42
+ ## Reporting
43
+
44
+ Use [GitHub private vulnerability reporting](https://github.com/stsepelin/checktrail/security/advisories/new).
45
+ The reporting channel is enabled for this repository. Do not put secrets or
46
+ exploitable private deployment details in a public issue.
@@ -0,0 +1,2 @@
1
+ import type { Check, CheckResult, ProcessResult } from "./types.js";
2
+ export declare function actionlintEvidence(check: Check, processes: ProcessResult[]): Pick<CheckResult, "status" | "reason" | "findings" | "findingsComplete">;
@@ -0,0 +1,166 @@
1
+ import path from "node:path";
2
+ import { z } from "zod";
3
+ import { actionlintInvocationSchema, workflowPath } from "./actionlint.js";
4
+ const schema = actionlintInvocationSchema.extend({
5
+ version: z.literal("1.7.12"),
6
+ preflight: z.strictObject({
7
+ findings: z
8
+ .array(z.strictObject({
9
+ ruleId: z.string().regex(/^yaml\/[A-Z_]+$/),
10
+ level: z.literal("error"),
11
+ message: z.string(),
12
+ file: z.string(),
13
+ line: z.number().int().positive(),
14
+ }))
15
+ .max(2000),
16
+ unavailable: z.string().min(1).optional(),
17
+ }),
18
+ results: z
19
+ .array(z.strictObject({
20
+ file: z.string(),
21
+ exitCode: z.number().int(),
22
+ stdout: z.string(),
23
+ stderr: z.string(),
24
+ }))
25
+ .max(128),
26
+ });
27
+ const diagnosticsSchema = z
28
+ .array(z.strictObject({
29
+ message: z.string(),
30
+ filepath: z.string(),
31
+ line: z.number().int().positive(),
32
+ column: z.number().int().positive(),
33
+ kind: z.string().regex(/^[a-z][a-z0-9-]+$/),
34
+ snippet: z.string(),
35
+ end_column: z.number().int().nonnegative(),
36
+ }))
37
+ .max(2000);
38
+ export function actionlintEvidence(check, processes) {
39
+ const incomplete = {
40
+ status: "inconclusive",
41
+ reason: "Workflow evidence is malformed or missing native per-file completion accounting",
42
+ findingsComplete: false,
43
+ };
44
+ if (processes.length !== 1)
45
+ return incomplete;
46
+ const process = processes[0];
47
+ if (process.stderr.trim())
48
+ return incomplete;
49
+ if (process.exitCode === 3) {
50
+ try {
51
+ z.strictObject({ unavailable: z.literal("actionlint-toolchain") }).parse(JSON.parse(process.stdout));
52
+ return {
53
+ status: "unavailable",
54
+ reason: "The verified actionlint release is unavailable",
55
+ };
56
+ }
57
+ catch {
58
+ return incomplete;
59
+ }
60
+ }
61
+ if (process.exitCode !== 0)
62
+ return {
63
+ status: "error",
64
+ reason: "Workflow evidence collection did not complete",
65
+ findingsComplete: false,
66
+ };
67
+ try {
68
+ const data = schema.parse(JSON.parse(process.stdout));
69
+ const planned = actionlintInvocationSchema.parse(JSON.parse(check.commands[0].args[2]));
70
+ if (JSON.stringify(data.scope) !== JSON.stringify(check.scope) ||
71
+ JSON.stringify(data.scope) !== JSON.stringify(planned.scope) ||
72
+ data.fingerprint !== planned.fingerprint ||
73
+ JSON.stringify(data.config) !== JSON.stringify(planned.config))
74
+ return incomplete;
75
+ if (data.preflight.findings.some((item) => !workflowPath(item.file) ||
76
+ path.posix.isAbsolute(item.file) ||
77
+ path.posix.normalize(item.file) !== item.file ||
78
+ item.file.startsWith("../")))
79
+ return incomplete;
80
+ const findings = data.preflight.findings.map((item) => ({
81
+ ...item,
82
+ file: path.posix.join(check.project, item.file),
83
+ }));
84
+ if (data.preflight.findings.length) {
85
+ if (data.results.length)
86
+ return incomplete;
87
+ return {
88
+ status: "failed",
89
+ reason: "Workflow or local action YAML is invalid; native analysis did not run",
90
+ findings,
91
+ findingsComplete: false,
92
+ };
93
+ }
94
+ if (data.preflight.unavailable) {
95
+ if (data.results.length)
96
+ return incomplete;
97
+ return {
98
+ status: "unavailable",
99
+ reason: data.preflight.unavailable,
100
+ findingsComplete: false,
101
+ };
102
+ }
103
+ if (data.results.length !== check.scope.length ||
104
+ new Set(data.results.map((result) => result.file)).size !==
105
+ check.scope.length)
106
+ return incomplete;
107
+ for (const result of data.results) {
108
+ if (!check.scope.includes(result.file))
109
+ return incomplete;
110
+ const diagnostics = diagnosticsSchema.parse(JSON.parse(result.stdout));
111
+ const lines = result.stderr.trimEnd().split("\n");
112
+ const counts = {};
113
+ const required = new Set([
114
+ `verbose: Linting ${result.file}`,
115
+ "verbose: Using project at <project>",
116
+ 'verbose: Rule "shellcheck" was disabled since shellcheck command name was empty',
117
+ 'verbose: Rule "pyflakes" was disabled since pyflakes command name was empty',
118
+ ]);
119
+ for (const line of lines) {
120
+ const match = /^verbose: Found (?:(total) )?(\d+) (parse )?errors in \d+ ms for (.+)$/.exec(line);
121
+ if (match && match[4] === result.file && !!match[1] !== !!match[3]) {
122
+ const key = match[1] ? "total" : "parse";
123
+ if (counts[key] !== undefined)
124
+ return incomplete;
125
+ counts[key] = Number(match[2]);
126
+ }
127
+ else if (!required.delete(line))
128
+ return incomplete;
129
+ }
130
+ if (counts.parse === undefined ||
131
+ counts.total !== diagnostics.length ||
132
+ (required.size &&
133
+ (counts.parse === 0 ||
134
+ required.size !== 2 ||
135
+ ![...required].every((line) => line.startsWith("verbose: Rule ")))) ||
136
+ diagnostics.some((item) => item.filepath !== result.file) ||
137
+ result.exitCode !== (diagnostics.length ? 1 : 0))
138
+ return incomplete;
139
+ if (!diagnostics.length && counts.parse !== 0)
140
+ return incomplete;
141
+ findings.push(...diagnostics.map((item) => ({
142
+ ruleId: `actionlint/${item.kind}`,
143
+ level: "error",
144
+ message: item.message,
145
+ file: path.posix.join(check.project, item.filepath),
146
+ line: item.line,
147
+ })));
148
+ }
149
+ return findings.length
150
+ ? {
151
+ status: "failed",
152
+ reason: "Actionlint reported workflow errors; failed analysis does not establish complete coverage",
153
+ findings,
154
+ findingsComplete: false,
155
+ }
156
+ : {
157
+ status: "passed",
158
+ reason: "Every planned workflow completed native static analysis; workflow jobs and action code were not executed",
159
+ findings,
160
+ findingsComplete: true,
161
+ };
162
+ }
163
+ catch {
164
+ return incomplete;
165
+ }
166
+ }
@@ -0,0 +1,5 @@
1
+ import type { Finding } from "./types.js";
2
+ export declare function actionlintInputs(files: Map<string, Buffer>, scope: string[]): {
3
+ findings: Finding[];
4
+ unavailable?: string;
5
+ };