@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,250 @@
1
+ # Autonomous execution ledger
2
+
3
+ This ledger tracks the full plan without treating a prepared scaffold as a
4
+ completed release. Work proceeds through independently testable implementations;
5
+ an unavailable runtime or external service does not count as verification.
6
+
7
+ ## M0 and M1
8
+
9
+ - Implemented: public contracts, synthetic fixtures, CLI/library/MCP engine,
10
+ trust controls, bounded execution, native Node/Python/Go checks, schemas and CI
11
+ definition. Integration evidence is recorded in `STATUS.md`.
12
+ - Verified separately: PHP syntax against PHP 8.4.23 in an isolated official Linux
13
+ container, using the actual engine integration test.
14
+ - Verified: fresh offline package installation with Claude Code health/discovery
15
+ and Codex app-server direct tool calls; see `CLIENTS.md` for the precise profiles.
16
+ - Verified: strict standard compilation of exported schemas, equivalent URL/path
17
+ boundary cases, and warning-free Claude Code discovery after correcting the
18
+ nonstandard prefix format. Original frozen evaluation artifacts remain separate.
19
+ - Remaining: hosted CI runs and broader client profiles. PHP syntax
20
+ planning still reports unavailable when PHP is absent from the consumer runtime.
21
+
22
+ ## M2
23
+
24
+ - Implemented: explicit local TypeScript and ESLint adapters with file accounting.
25
+ - Implemented: TypeScript project-reference solution validation using fresh
26
+ in-memory declarations, source accounting and normalized compiler diagnostics.
27
+ - Implemented: Vitest execution, strict evidence parsing, and native regression
28
+ cases for skipped/excluded tests, focused tests and snapshot/error bypasses.
29
+ - Implemented: Jest native execution and evidence, with conservative pending-test
30
+ handling and collection-only/snapshot/result-processor bypass tests.
31
+ - Implemented: vue-tsc with native script/template error cases, file inclusion
32
+ accounting and inherited template-check disabling rejection.
33
+ - Implemented: pytest lifecycle evidence, collection accounting, fixture and
34
+ unexpected-pass failures; verified with prepared Python 3.12 Linux tooling.
35
+ - Implemented: Ruff file/settings/JSON evidence, disabled fixes, native diagnostics,
36
+ exclusion and no-active-rule cases in prepared Linux tooling.
37
+ - Implemented: mypy source-count evidence, per-module broad suppression guard,
38
+ no stub installation/cache writes, and native Linux regression fixtures.
39
+ - Implemented: opt-in Go race validation, with native racing and atomic-update
40
+ fixtures on macOS. Native package/file and package-test participation accounting
41
+ now reports excluded source and untested packages as incomplete.
42
+ - Implemented: PHPStan per-file/debug and native JSON accounting, with return-type,
43
+ excluded-file and bad-configuration fixtures in PHP 8.5 Linux tooling.
44
+ - Implemented: PHPUnit fresh JUnit streaming, exact file/assertion accounting and
45
+ native failures/skips/empty cases in PHP 8.5 Linux tooling.
46
+ - Implemented: standalone JUnit import through CLI/library, labeled as imported
47
+ evidence, with bounded XML and aggregate-counter validation.
48
+ - Implemented: Pest fresh evidence, focused-sibling and dataset checks, explicit
49
+ TIA disabling and missing-snapshot rejection in prepared PHP Linux tooling.
50
+ - Implemented: Pint native file/fixer accounting, dry-run formatting, empty-rule
51
+ and unverified Blade integration guards, with native Linux fixtures.
52
+ - Implemented: Playwright native lifecycle/project/file evidence, focused-test and
53
+ snapshot controls, flaky failure and explicit browser prerequisites, including
54
+ real Chromium DOM assertions.
55
+ - Implemented: Staticcheck all-rule JSON analysis with surfaced suppressions,
56
+ normalized findings and native regression cases.
57
+ - Implemented: a constrained configured golangci-lint profile, explicit linter
58
+ selection, hidden-filter/fix prevention and native suppression accounting.
59
+ - Implemented: bounded native version probes and labeled package-metadata/runtime
60
+ identities in detailed reports, with incomplete results for unknown identities.
61
+ - Implemented: normalized ESLint/Ruff/PHPStan findings and SARIF 2.1.0 export
62
+ through CLI/library, with official-schema and native CLI regression evidence.
63
+ - Implemented: per-project environment requirements with operator CLI/MCP startup
64
+ permissions, value-free command metadata and environment-scoped tool identity.
65
+ - Implemented: explicit workspace dependencies and Git base selection, transitive
66
+ consumer expansion, full-plan fallback and post-run Git identity validation.
67
+ - Implemented: exact finding baselines and exceptions, owner/reason/expiry,
68
+ occurrence-count reconciliation, stale entries, explicit limits and optional
69
+ comparison against a previous baseline. CLI/library/MCP keep comparison status
70
+ separate from native validation. Partial analysis cannot be baselined.
71
+ - Remaining: broader framework scope and hosted toolchain CI evidence.
72
+
73
+ ## M3
74
+
75
+ - Implemented: schema-validated runtime inventory comparison through CLI/library/
76
+ MCP, exact registration multiplicity and ordering, explicit incomplete collection
77
+ accounting, and synthetic tests for every supported assembly category. Imported
78
+ comparison remains distinct from native framework capture.
79
+
80
+ - Implemented: reusable public JSON check profiles, pinned private/local pack
81
+ loading and additive operator-selected overlays, with post-execution policy
82
+ verification and conservative Git selection. Native framework semantics remain
83
+ separate from these check profiles.
84
+ - Implemented: captured producer/consumer JSON Schema contracts with strict
85
+ non-mutating validation, bounded workers, CLI/library/MCP and synthetic native
86
+ producer serialization. Live service integration remains separate.
87
+ - Implemented: an opt-in FastAPI flat native route collector and exact duplicate
88
+ registration rule, after lifespan startup, with Linux native broken/fixed/near-
89
+ miss fixtures and explicit unsupported-shape handling. Broader framework
90
+ semantics and other assembly categories remain separate.
91
+ - Implemented: a Django native nested URL resolver collector and exact duplicate
92
+ pattern-chain rule, with setup-time wiring, regex matching-mode preservation,
93
+ protected test settings and Linux native regression evidence.
94
+ - Implemented: Laravel testing assembly collection for routes, middleware, exact
95
+ and wildcard listeners, schedules and a defined container binding projection.
96
+ Native PHP/Linux fixtures exercise actual Artisan initialization, framework-added
97
+ routes, mutation comparisons, cold caches, dotenv exclusion and incomplete assembly.
98
+ - Verified: public synthetic FastAPI, Django and Laravel examples through their
99
+ native collectors; no private application code is needed for these regressions.
100
+ - Implemented: explicit language-agnostic dependency graph policies, exact layer
101
+ allowlists, iterative cycle detection, incomplete capture accounting and
102
+ CLI/library/MCP surfaces. Native source import graph collection remains separate.
103
+ - Verified: a real TypeScript producer tarball installed offline into a synthetic
104
+ consumer, with type and runtime checks for changed and misleading declarations;
105
+ a declared package-graph boundary check accompanies the integration fixture.
106
+ - Implemented: a native Vue Router testing assembly profile with awaited registration,
107
+ exact URL probe chains, alias/parent participation, bounded metadata projection
108
+ and incomplete-record accounting. macOS/Linux native tests and installed-package
109
+ library/CLI/MCP checks passed; see `VUE-ROUTER.md`.
110
+ - Implemented: a Nuxt SSR testing assembly using a fresh native build and in-process
111
+ requests, final runtime route capture, stable-assembly checks and complete record
112
+ participation. Native macOS/Linux fixtures and an offline read-only installed
113
+ library/CLI/MCP example passed; see `NUXT.md`.
114
+ - Pending: broader framework semantics, native assembly/import graph collectors
115
+ and live service integrations.
116
+ - Private repository results and proprietary narratives must stay out of public
117
+ source, examples, reports and history.
118
+
119
+ ## M4
120
+
121
+ - Implemented: a Rust/Cargo 1.98.1 single-package compilation profile, locked
122
+ offline dependencies, fresh build directories, native target and source
123
+ accounting, structured compiler diagnostics and Linux regression evidence.
124
+ Rust test execution, formatting, Clippy and workspace matrices remain separate.
125
+ - Implemented: MRI Ruby syntax checking for source and Ruby DSL manifests,
126
+ per-file native success accounting, disabled gem/preload behavior, synthetic
127
+ broken/fixed cases and Linux/macOS native verification. Ruby tests and framework
128
+ semantics remain separate capabilities.
129
+ - Implemented: Swift source/manifest grammar checking without SwiftPM evaluation,
130
+ native macOS compiler identity, generated .build exclusion and explicit regression
131
+ evidence distinguishing syntax from type checking. Swift build/test remain work.
132
+ - Implemented: prepared C/C++ Clang compilation-database checks with closed flag
133
+ handling, native SARIF diagnostics, fresh dependency/source accounting and native
134
+ macOS/Linux broken/fixed cases. Linking, CTest, clang-tidy and cross-target
135
+ build matrices remain separate.
136
+ - Implemented: explicit Java release/classpath compilation with checksummed JARs,
137
+ disabled annotation processing, native source/type accounting, Linux regression
138
+ evidence and fresh packaged library/CLI/MCP verification. JVM build systems,
139
+ modules, Kotlin/Scala and test runners remain separate. See `JAVA.md`.
140
+ - Implemented: explicit C# compilation through the prepared .NET SDK/Roslyn API,
141
+ pinned DLL references, native syntax/semantic accounting, source-suppression
142
+ handling and Linux regression evidence. MSBuild, restore, source generators,
143
+ analyzers, F#/VB, framework-specific builds and test runners remain separate.
144
+ See `DOTNET.md` for the precise profile and reproduction steps.
145
+ - Implemented: GitHub Actions workflow validation through actionlint with explicit
146
+ labels/variables, copied local dependencies, repository-ignore bypass and native
147
+ per-file completion evidence. Terraform, Helm and Kustomize remain unsupported.
148
+ See `ACTIONLINT.md` for profile limits and reproduction steps.
149
+ - Verified: fresh offline tarball install; public library, installed CLI and
150
+ packaged MCP stdio checks against eight synthetic JavaScript toolchain projects.
151
+ Reproduce with `node scripts/smoke-package.mjs`. This now also exercises the
152
+ Clang profile when a verified local compiler is present and records unavailable
153
+ otherwise; a verified macOS compiler passed the installed profile.
154
+ - Implemented: bounded local private pack distribution with SHA-256 pinning.
155
+ - Implemented: production npm dependency metadata/notice audit reconciled with
156
+ the installed tree and lockfile, including a pinned upstream notice for one
157
+ distribution that omitted it. Development/native/container provenance remains
158
+ separate; this is not a complete supply-chain or legal-compliance attestation.
159
+ - Implemented: bounded synthetic planning/execution performance measurement with
160
+ raw samples, source/tool/harness identities and engine-only resource accounting.
161
+ Recorded macOS/Linux snapshots and limitations are in `PERFORMANCE.md`.
162
+ - Implemented: operator-registered executable adapters with pinned manifests/files,
163
+ exact scoped-file accounting, Node/Python/PHP/native runtimes and shared cancellation
164
+ cleanup. Linux native fixtures and offline installed library/CLI/MCP checks passed;
165
+ delegated tool metadata remains adapter-reported. See `EXTERNAL-ADAPTERS.md`.
166
+ - Implemented: explicit HTTPS data-only pack distribution with independently pinned
167
+ digests, bounded TLS transfers, strict content validation and exclusive atomic
168
+ file publication. Planning and MCP never download automatically. See
169
+ `PACK-DISTRIBUTION.md`. Executable bundle distribution remains separate.
170
+ - Implemented: unpublished registry metadata with matching npm identity, a required
171
+ local root, execution disabled by default, official-schema validation and a
172
+ metadata-derived MCP startup regression. See `RELEASE.md` for concrete release
173
+ gates.
174
+ - Pending: broader runtime/OS/performance matrices and external release gates.
175
+ - Windows execution needs actual process-tree cancellation evidence before it
176
+ can be advertised. Hosted CI and a public release have not happened.
177
+ - Commits, remote creation and publication retain their existing explicit-action
178
+ requirements; local implementation and release preparation can continue.
179
+
180
+ ## M5
181
+
182
+ - Implemented: versioned public advisory guidance selected by exact check/topic
183
+ triggers, with CLI/library/MCP surfaces, bounded schemas and summary projections.
184
+ Retrieval is separate from automated findings and coverage claims.
185
+ - Implemented: targeted literal mutations for dependency-free flat Node tests,
186
+ temporary source copies, assertion-specific kill evidence, survivor/incomplete
187
+ accounting, baseline gating, cancellation and original-source preservation.
188
+ Broader language/runner profiles and automatic mutation selection remain pending.
189
+ - Implemented: paired full/Git-selected native impact measurement with original
190
+ transitive-consumer fixtures, baseline passes, exact assertion identities,
191
+ conservative fallbacks, misdeclared-graph misses and raw cost observations.
192
+ macOS/Linux evidence and limits are in `IMPACT-MEASUREMENT.md`.
193
+ - Implemented: optional local/model review exchange with bounded selected source,
194
+ operator-gated disclosure, context/source digests, exact citation checks, explicit
195
+ unreviewed-file accounting and declared model/version/token/cost metadata. Imported
196
+ claims remain advisory and never alter deterministic results; see `REVIEW-EXCHANGE.md`.
197
+ - Pending: broader impact models. Review exchange does not itself establish model
198
+ inference quality or independent evaluation.
199
+ - Implemented: a frozen post-implementation development corpus with per-family
200
+ diagnostic-specific detection, false-positive and incomplete-result accounting,
201
+ direct native-command comparisons, raw timing/tool/artifact identities and
202
+ macOS/Linux observations. See `EVALUATION.md` for interpretation limits.
203
+ - Implemented: external ESLint integration evaluation using independently authored
204
+ synthetic upstream cases and a verifier frozen before case inspection. Native
205
+ and verifier diagnostics agree on the stated macOS/Linux cohort; raw labels,
206
+ observations, artifact identities and exclusion accounting are retained in
207
+ `EXTERNAL-EVALUATION.md`. It is not independent native-rule effectiveness or
208
+ general review-quality evidence.
209
+ - Implemented: external Ruff diagnostic integration cohort with declared source
210
+ selection and a frozen verifier, paired native/macOS/Linux observations and
211
+ primary-location reconciliation. The mixed upstream files do not supply an
212
+ independent clean-case denominator; see `EXTERNAL-RUFF-EVALUATION.md`.
213
+ - Pending independent measurement: broader end-to-end review cases and rule families,
214
+ prior-workflow comparisons and representative cost/latency estimates. The
215
+ development corpus is not an independent held-out sample.
216
+ - Implemented: library-only bounded local validation task storage with atomic
217
+ transitions, exclusive process ownership, retained projected results, two-stage
218
+ cancellation and explicit interruption errors after reopening. Native macOS/Linux
219
+ crash and contention evidence is documented in `TASK-STORAGE.md`.
220
+ - Implemented: a library worker connecting durable storage to the shared engine,
221
+ with startup-only permissions, responsive polling, overlap rejection, confirmed
222
+ cancellation, parent-disconnect cleanup and retained native outcomes. See
223
+ `VALIDATION-TASKS.md` for native macOS/Linux evidence and the explicit limitation
224
+ on forcibly killing the worker itself.
225
+ - Durable MCP Tasks remains pending. The current SDK routing failure is reproduced
226
+ by `npm run probe:mcp-tasks`; storage and worker lifecycle are implemented
227
+ independently, but Tasks support must not be advertised before wire tests pass.
228
+
229
+ The dedicated Ruby and Swift CI paths now require their exact native regression
230
+ names, rather than accepting a successful suite that skipped native work. Local
231
+ Ruby/Linux/Node 22 and Swift/macOS execution pass. Runner regressions reject
232
+ missing names, wrong-file names, skips, TODOs, duplicate names, suite-only matches
233
+ and unrelated failures. Removing the missing-test rejection fails the named
234
+ regression. These profiles subsequently passed hosted CI at `52ba415`; see
235
+ `NATIVE-CI.md` for the complete workflow evidence.
236
+
237
+ The same exact-name gate now covers the prepared CI core, JavaScript, Python,
238
+ Go, PHP, framework and Rust profiles, plus the Clang, Java, C#, actionlint,
239
+ Vue Router, Nuxt, review and durable-task container suites. Local required-profile
240
+ runs passed and their accounting is retained in `NATIVE-CI.md`. Both dynamically
241
+ named cancel/close lifecycle cases are explicit requirements. Existing external
242
+ adapter per-runtime gates remain, and the PHP syntax shim now requires exactly
243
+ one successful native TAP case. Hosted CI remains a separate acceptance gate.
244
+
245
+ ## External dependencies
246
+
247
+ The installed MCP server SDK is still 2.0.0. Its standard Tasks routing failure is
248
+ documented in `MCP-COMPATIBILITY.md`. Hosted CI, publication and independent target
249
+ OS/client evidence remain separate acceptance gates. A gate is completed only
250
+ when its implementation and corresponding evidence exist.
@@ -0,0 +1,170 @@
1
+ # Trusted external adapters
2
+
3
+ An operator can register a local executable bundle without modifying the engine.
4
+ The bundle declares discovery markers, scoped checks and SHA-256 hashes for each
5
+ file it needs. Registration reads and verifies metadata without executing the
6
+ adapter. Running it requires the same trust permission as built-in checks.
7
+
8
+ This is a local extension protocol, not a plugin marketplace or sandbox. A digest
9
+ identifies bytes; it does not authenticate an author, prove an analysis correct or
10
+ pin system libraries and tools. A trusted adapter can fabricate protocol evidence.
11
+ Review its implementation, licenses and native regression cases before using it.
12
+
13
+ ## Try the original example
14
+
15
+ From a built checkout, compute the digest of the exact manifest bytes:
16
+
17
+ ```sh
18
+ adapter_manifest="$PWD/examples/external-adapter/bundle/adapter.json"
19
+ adapter_digest=$(shasum -a 256 "$adapter_manifest" | cut -d ' ' -f 1)
20
+ node dist/src/cli.js plan --root examples/external-adapter/project \
21
+ --adapter "$adapter_manifest#sha256=$adapter_digest" --detailed
22
+ node dist/src/cli.js run --root examples/external-adapter/project \
23
+ --adapter "$adapter_manifest#sha256=$adapter_digest" --trust-project --detailed
24
+ node dist/src/cli.js serve --root examples/external-adapter/project \
25
+ --adapter "$adapter_manifest#sha256=$adapter_digest" --allow-execution
26
+ ```
27
+
28
+ The example checks trailing spaces and tabs in text files. Its manifest includes
29
+ the original implementation and its MIT license. These examples are checkout
30
+ assets, not files installed by the npm package. For an independently obtained
31
+ bundle, compare its digest against a separately trusted value; computing a hash
32
+ of an unreviewed download does not establish trust.
33
+
34
+ `--adapter` can be repeated. Library callers pass
35
+ `externalAdapters: [{ path: absoluteManifestPath, sha256: expectedDigest }]` to
36
+ `createPlan` or `validate`; validation also needs `trusted: true`. MCP registration
37
+ is startup-only. A tool argument or repository configuration cannot add adapters
38
+ or grant execution permission. Project policy may select already registered check
39
+ IDs such as `external.example-lines.whitespace`. The registered manifest identities
40
+ contribute to the policy fingerprint. External registration conservatively disables
41
+ Git narrowing because the engine cannot establish an external tool's impact model.
42
+
43
+ ## Bundle contract
44
+
45
+ The generated schemas are `schemas/external-manifest.schema.json`,
46
+ `external-reference.schema.json`, `external-request.schema.json` and
47
+ `external-result.schema.json`. Runtime validation also enforces cross-field
48
+ constraints such as uniqueness, test accounting and exact scope matching.
49
+
50
+ Manifest version 1 declares:
51
+
52
+ - `id`: `external.` followed by a lowercase name; `version`: a version string.
53
+ - `runtime`: `node`, `python3`, `php` or `native`; `entry`: a listed relative file.
54
+ - `files`: normalized relative paths and lowercase SHA-256 digests.
55
+ - `markers`: exact file basenames identifying project roots.
56
+ - `checks`: unique IDs, descriptions, kind (`analysis`, `syntax`, `format`, `test`),
57
+ failure level (`error` or `warning`), and filename/suffix scope selectors.
58
+
59
+ Check IDs are the adapter ID plus `.` plus the declared check ID. Scope selectors
60
+ form a union over inventoried files assigned to the closest detected project root.
61
+ They are case-sensitive exact basenames or literal suffixes, not glob patterns.
62
+ The shared inventory exclusions apply. An empty selected scope is unavailable.
63
+
64
+ Manifest and declared files must be regular files. Bundle file paths cannot escape
65
+ the canonical bundle directory or traverse symbolic links. The manifest cannot
66
+ include itself. Only declared, verified bytes are copied into a temporary bundle;
67
+ unlisted files are neither hashed nor copied. Relative imports must refer to files
68
+ included in the bundle. Python isolated mode does not automatically put the bundle
69
+ directory on the import path; adapters needing bundled modules must load them
70
+ explicitly. Nothing prevents trusted code from reading additional external files.
71
+
72
+ ## Invocation and evidence
73
+
74
+ The adapter runs with the discovered project as its working directory. Its sole
75
+ application argument is the path to a JSON request. Node uses the current Node
76
+ executable; Python uses `python3 -I -B`; PHP uses `php -n`; native execution uses
77
+ the copied entry with executable permissions. Python's
78
+ [isolated mode](https://docs.python.org/3/using/cmdline.html#cmdoption-I) controls
79
+ startup/import behavior and is not operating-system isolation.
80
+
81
+ The request contains `protocolVersion: 1`, canonical `root`, relative `project`,
82
+ adapter `identity`, `runtime`, `checkId`, `kind`, `failOn`, project-relative `scope`
83
+ and `sourceFingerprint`. stdout must contain exactly one result JSON object:
84
+
85
+ ```json
86
+ {
87
+ "protocolVersion": 1,
88
+ "identity": {
89
+ "id": "external.example",
90
+ "version": "1.0.0",
91
+ "sha256": "<manifest digest>"
92
+ },
93
+ "checkId": "external.example.whitespace",
94
+ "sourceFingerprint": "<request fingerprint>",
95
+ "files": [{ "path": "value.txt", "status": "checked" }],
96
+ "findingsComplete": true,
97
+ "findings": [],
98
+ "tools": [{ "name": "example-checker", "version": "1.0.0" }]
99
+ }
100
+ ```
101
+
102
+ The placeholders above must be replaced with the request's actual digests. Results
103
+ must echo the identity, check ID and source fingerprint and account for every
104
+ planned file exactly once. File statuses are `checked`, `skipped` and `unavailable`.
105
+ Diagnostics have `ruleId`, `level`, `message` and optional scoped `file`/`line`.
106
+ The engine prefixes rule IDs with the full check ID and converts finding paths to
107
+ root-relative paths. Unknown fields, unplanned files, omissions, duplicates and
108
+ contradictory evidence cannot pass.
109
+
110
+ Test checks require per-file `tests: { total, passed, failed, skipped }`. Counts
111
+ must reconcile; empty, all-skipped or partly skipped files are incomplete. Other
112
+ check kinds must not include test counts. Exit 1 must agree with failed tests or
113
+ diagnostics at the declared failure level. Exit 0 must agree with their absence.
114
+ Other exits are errors. A known failure can coexist with incomplete coverage;
115
+ `findingsComplete` preserves that distinction. stderr is retained as bounded
116
+ detailed process evidence and is not itself a diagnostic protocol.
117
+
118
+ Delegated tool identities have `source: "adapter-reported"` in detailed reports.
119
+ They are not independently attested. The engine separately probes supported
120
+ interpreter versions and reads the pinned manifest version without executing the
121
+ adapter for its version probe. Default summaries omit bundle paths, delegated
122
+ metadata, raw output and source paths; check IDs and outcomes remain visible.
123
+
124
+ ## Execution limits and cleanup
125
+
126
+ Registration allows at most eight bundles. Each manifest is at most 256 KiB;
127
+ each bundle lists at most 512 files, 32 MiB per file and 128 MiB combined. A manifest
128
+ has at most 32 markers and 32 checks. A check has at most 20,000 scoped files and a
129
+ 100 KiB serialized invocation. Results have at most 2,000 findings and 32 tools;
130
+ combined child stdout/stderr is bounded to 1 MiB. Shared runner limits can make a
131
+ large encoded result incomplete before these individual maxima are reached.
132
+
133
+ The shared runner applies its timeout, output bound and POSIX process-group
134
+ cancellation. It owns the temporary directory and removes it after the child closes,
135
+ including after cancellation kills the wrapper. This does not guarantee cleanup
136
+ after an engine crash or prevent malicious processes from detaching. The engine
137
+ checks inventoried source and pinned bundle contents before and after execution.
138
+ Ignored dependencies, transient restored modifications and external services remain
139
+ outside that fingerprint. Concurrent adversarial changes require OS isolation.
140
+
141
+ External code inherits the narrow runner environment plus operator-authorized
142
+ variables. `PATH`, `NODE_OPTIONS` and the owned temporary-directory setting are
143
+ protected from project environment overrides. No dependency installation, download
144
+ or network isolation is supplied by this protocol.
145
+
146
+ ## Reproduce verification
147
+
148
+ ```sh
149
+ npm run check
150
+ docker build --file scripts/external-tools.Dockerfile \
151
+ --tag checktrail-external-test:1 scripts
152
+ node scripts/verify-external-container.mjs
153
+ ```
154
+
155
+ The helper requires Docker and an npm cache prepared by dependency installation.
156
+ Image preparation may access the network; verification containers use
157
+ `--network none` and read-only checkout/installed-package mounts. The separate
158
+ PHP image and the build stages are pinned by digest in the helper/Dockerfile.
159
+
160
+ Verified profiles are macOS Node 26.8.1, Python 3.9.6 and compiled Go 1.27.1, and
161
+ Linux arm64 Node 22.23.2, Python 3.12.13, Go 1.26.5 and PHP 8.5.6. The native fixture
162
+ is compiled from the original `examples/external-adapter/native/adapter.go`.
163
+ Tests exercise actual broken/fixed whitespace, a CRLF near miss, bundle tampering,
164
+ scope/result contradictions, trust boundaries, startup-only MCP registration and
165
+ child cancellation with cleanup. Removing the file-count reconciliation guards
166
+ was manually verified to produce a false pass caught by the accounting regression;
167
+ the guards were restored before the final passing runs. The helper also verifies a fresh offline package
168
+ through the library, CLI and MCP. These checks establish this protocol's behavior;
169
+ they do not establish arbitrary adapter correctness or Windows support. The
170
+ separate hosted Linux job passed at `52ba415`; see `NATIVE-CI.md`.
@@ -0,0 +1,155 @@
1
+ # External ESLint integration evaluation
2
+
3
+ This evaluation uses independently authored synthetic ESLint rule fixtures that
4
+ were not used to build Checktrail's adapter. The verifier runtime and lockfile
5
+ were hashed before the selected upstream case files were downloaded or inspected.
6
+ They remained unchanged during measurement. This supplies an external integration
7
+ holdout for that frozen verifier, not independent evidence about ESLint's own
8
+ rule algorithms or general code-review quality.
9
+
10
+ ## Provenance and selection
11
+
12
+ The locally declared plan is `scripts/external-evaluation-plan.json`. It selected
13
+ all literal valid/invalid cases from `eqeqeq`, `no-dupe-args` and `no-unreachable`
14
+ at ESLint tag `v10.10.0`, resolved to commit
15
+ `3f20a57c6293371b6193d3fb6746c2b7b2ac2689`. The source-file sizes and SHA-256 values,
16
+ including the upstream MIT license, are pinned in
17
+ `scripts/external-evaluation-inputs.json`. The plan digest uses its parsed JSON
18
+ serialized with two-space indentation and a trailing newline, so formatting alone
19
+ does not change its identity. This is a local declaration, not an externally
20
+ witnessed preregistration or proof of an author's prior knowledge.
21
+
22
+ The source cases and labels come from ESLint's
23
+ [rule tests](https://github.com/eslint/eslint/tree/3f20a57c6293371b6193d3fb6746c2b7b2ac2689/tests/lib/rules)
24
+ and their documented [RuleTester contract](https://eslint.org/docs/latest/integrate/nodejs-api#ruletester).
25
+ Copyright belongs to the OpenJS Foundation and other contributors under the
26
+ [pinned MIT license](https://github.com/eslint/eslint/blob/3f20a57c6293371b6193d3fb6746c2b7b2ac2689/LICENSE).
27
+ Prepared copies stay in a local input directory, include that license and are not
28
+ bundled in the npm package. Reports retain IDs, hashes, labels, diagnostic metadata
29
+ and measurements; they contain no copied case source or raw diagnostic prose.
30
+ The new extraction, measurement and regression-test code is original.
31
+
32
+ The extractor parses JavaScript syntax with the prepared Espree 11.2.0. It does
33
+ not execute the upstream test modules, invoke their hooks or evaluate fixture
34
+ expressions. It preserves literal RuleTester constructor settings, case language
35
+ settings and rule options. One recognized array transformation supplies a default
36
+ `output: null` without changing source or diagnostic labels; no arbitrary map or
37
+ filter is evaluated. Unsupported cases retain an ID, upstream label and exclusion
38
+ reason. A dynamic list whose cardinality cannot be established stops measurement.
39
+ Excluded cases remain visible in each system's classification denominator.
40
+
41
+ The baseline and verifier see the same generated files and settings. The baseline
42
+ runs the prepared ESLint 10.10.0 CLI with fixes/cache disabled, explicit configuration
43
+ and both candidate files selected. The verifier uses `javascript.eslint` through
44
+ its shared engine. The configuration file itself has a separate active rule and
45
+ is included in file accounting. Copied dependency trees and source fingerprints
46
+ are checked for changes; inputs, runtime, lockfile and harness identities are
47
+ checked before and after measurement. Nothing is installed during measurement.
48
+
49
+ ## What is checked
50
+
51
+ Upstream `valid` cases must produce no diagnostics. For an `invalid` case, detection
52
+ requires the intended rule ID, each declared message ID, the declared diagnostic
53
+ locations and the exact diagnostic count. An unrelated failure is `wrong-signal`,
54
+ not a successful detection. A passing invalid case is `missed`; a failing valid
55
+ case is `false-positive`. Incomplete results and excluded inputs are separate
56
+ columns and are not dropped. Every executable case requires one observation for
57
+ each system; missing, duplicate or malformed observations fail the harness.
58
+
59
+ This does not rerun every RuleTester assertion. Autofixes, suggestions, interpolated
60
+ message wording/data and locations not specified by the upstream case are not
61
+ assessed. It measures diagnostic preservation for the stated profile. Upstream
62
+ unit fixtures are deliberately selected and native ESLint already uses them as
63
+ regressions, so they cannot establish independent native-rule effectiveness.
64
+
65
+ ## Recorded results
66
+
67
+ The [macOS/Node 26 snapshot](measurements/external-eslint-darwin-arm64-node26.json)
68
+ and [Linux/Node 22 snapshot](measurements/external-eslint-linux-arm64-node22.json)
69
+ have the same corpus, frozen runtime, harness identity and classification matrix.
70
+
71
+ | Rule | Cases | Valid cases clean, each system | Invalid cases detected, each system |
72
+ | ---------------- | ----: | -----------------------------: | ----------------------------------: |
73
+ | `eqeqeq` | 77 | 31 | 46 |
74
+ | `no-dupe-args` | 13 | 5 | 8 |
75
+ | `no-unreachable` | 70 | 32 | 38 |
76
+
77
+ Across this fixed cohort there are no false positives, misses, wrong-signal
78
+ failures, incomplete results or exclusions. Both systems agree; this is evidence
79
+ of integration equivalence on these cases, not an improvement over native ESLint.
80
+ No comparison with a previous human/model/private review workflow was performed.
81
+
82
+ Each case was measured once per system, alternating order between cases. Wall
83
+ time includes process startup and native execution; engine time excludes the outer
84
+ worker startup. Fixture/dependency preparation and cleanup are outside the timed
85
+ operation. Raw observations are retained. These purposive, related unit fixtures
86
+ are not a random population sample, so population confidence intervals, production
87
+ false-positive estimates and representative cost/overhead claims are not justified.
88
+ No model was called; model tokens and provider cost are zero. Human and machine
89
+ costs are not measured.
90
+
91
+ Linux measurement used Node 22.23.2 in
92
+ `node:22-alpine@sha256:c610fcdfb1d5b4740dd70c284ed3cb16bb857e0f7166196e36a5501df7a3aa32`,
93
+ with networking disabled and prepared inputs/repository mounted read-only.
94
+ Temporary fixtures were writable. macOS used Node 26.8.1. Hosted CI, Windows,
95
+ other native-tool versions and additional rule/language families are separate gates.
96
+
97
+ ## Preserve and reproduce the frozen checkout
98
+
99
+ The current engine has changed since this measurement: exported guidance and
100
+ route schemas were corrected after an actual client exposed a nonstandard format.
101
+ Those changes do not retroactively update the observations above. The original
102
+ runtime, source, lockfile and original measurement harness were preserved locally
103
+ before that edit. The [preservation record](measurements/external-eslint-preservation.json)
104
+ identifies the archive and its member manifest. The archive contains original
105
+ project code and the MIT license, not upstream cases or installed dependencies.
106
+ It is a local prepared artifact, not a published download.
107
+
108
+ When the compiled checkout still matches the plan's frozen identities, this helper
109
+ creates a fresh snapshot, archives the selected files, and prepares copies of the
110
+ installed locked dependencies for local replay:
111
+
112
+ ```sh
113
+ node scripts/preserve-external-evaluation.mjs .checktrail > /tmp/frozen-evaluation.json
114
+ ```
115
+
116
+ It intentionally fails on a later runtime before creating the output snapshot.
117
+ Do not edit the freeze pins to make it accept the current engine. Reuse the
118
+ preserved artifact or obtain its original exact bytes when reproducing this
119
+ particular evaluation. A restored archive needs the original locked dependencies
120
+ prepared separately; dependency installation is not part of measurement.
121
+
122
+ From that frozen checkout, prepare the pinned upstream inputs and run:
123
+
124
+ ```sh
125
+ node scripts/prepare-external-evaluation.mjs /path/to/input-parent > /tmp/external-inputs.json
126
+ external_inputs_path="$(node -p 'JSON.parse(require("node:fs").readFileSync("/tmp/external-inputs.json", "utf8")).directory')"
127
+ node scripts/measure-external-evaluation.mjs "$external_inputs_path" > external-evaluation.json
128
+ node scripts/verify-external-evaluation-container.mjs "$external_inputs_path" > external-evaluation-linux.json
129
+ ```
130
+
131
+ Preparation explicitly downloads only the pinned public files, verifies every
132
+ byte hash before creating a fresh private directory, and retains their license.
133
+ It requires `curl` and does not modify an existing input directory. Measurement
134
+ requires the original locked development dependencies and compiled runtime; it
135
+ never fetches inputs or tools. The container helper additionally requires Docker
136
+ and the specified image already available for offline execution.
137
+
138
+ Archive extraction was checked against every recorded member digest. Rebuilding
139
+ the preserved source with the locked TypeScript compiler reproduced the original
140
+ runtime digest. The preserved harness was replayed on macOS and Linux: corpus identities, classifications,
141
+ diagnostic metadata and source fingerprints matched the original observations.
142
+ Replays are reproducibility checks, not new independent holdouts or fresh latency
143
+ comparisons. The latest engine's ordinary native regression suite is separate.
144
+
145
+ The measurement command intentionally rejects a changed verifier runtime or
146
+ lockfile. Reproducing the original observation requires the recorded frozen
147
+ artifacts. After tuning on these cases, evaluate them as known regressions rather
148
+ than claiming a new holdout; declare a new independent cohort for further claims.
149
+ The labels here do not prove semantic equivalence to a previous review process.
150
+
151
+ Synthetic harness tests cover non-execution, configuration inheritance, exact
152
+ identifiers and locations, incomplete/excluded denominators, malformed evidence,
153
+ privacy projection and independent recomputation of the recorded matrices.
154
+ Removing excluded rows from aggregation made the named denominator regression
155
+ fail; restoring the guard restored the suite.