@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,80 @@
1
+ export const djangoRunner = String.raw `
2
+ import contextlib, hashlib, json, sys
3
+ from datetime import datetime, timezone
4
+ from importlib.metadata import version, PackageNotFoundError
5
+
6
+ def identity(value):
7
+ module = getattr(value, '__module__', None)
8
+ name = getattr(value, '__qualname__', None)
9
+ if not isinstance(module, str) or not isinstance(name, str):
10
+ raise ValueError('Unsupported callable identity')
11
+ return module + '.' + name
12
+
13
+ def capture():
14
+ import django
15
+ django.setup()
16
+ from django.urls import get_resolver
17
+ from django.urls.resolvers import URLPattern, URLResolver, RoutePattern, RegexPattern
18
+ from django.urls.converters import IntConverter, StringConverter, UUIDConverter, SlugConverter, PathConverter
19
+ supported_converters = (IntConverter, StringConverter, UUIDConverter, SlugConverter, PathConverter)
20
+ entries = []
21
+ visited = 0
22
+ unsupported = 0
23
+ def walk(routes, patterns, namespaces, defaults, depth):
24
+ nonlocal visited, unsupported
25
+ if depth > 32:
26
+ raise ValueError('URL resolver depth limit exceeded')
27
+ for route in routes:
28
+ visited += 1
29
+ if visited > 20000:
30
+ raise ValueError('URL inventory entry limit exceeded')
31
+ if type(route) not in (URLPattern, URLResolver) or type(route.pattern) not in (RoutePattern, RegexPattern):
32
+ unsupported += 1
33
+ continue
34
+ pattern = route.pattern
35
+ if type(pattern) is RoutePattern and type(pattern._route) is not str:
36
+ unsupported += 1
37
+ continue
38
+ if any(type(converter) not in supported_converters for converter in pattern.converters.values()):
39
+ unsupported += 1
40
+ continue
41
+ signature = json.dumps([type(pattern).__name__, pattern.regex.pattern, pattern.regex.flags, pattern._is_endpoint], separators=(',', ':'), ensure_ascii=False)
42
+ fragments = patterns + [signature]
43
+ values = {**defaults, **(route.default_kwargs if type(route) is URLResolver else route.default_args)}
44
+ if type(route) is URLResolver:
45
+ walk(route.url_patterns, fragments, namespaces + ([route.namespace] if route.namespace else []), values, depth + 1)
46
+ else:
47
+ values_json = json.dumps(values, sort_keys=True, separators=(',', ':'), allow_nan=False)
48
+ handler = getattr(route.callback, 'view_class', route.callback)
49
+ entries.append({
50
+ 'key': json.dumps(fragments, separators=(',', ':'), ensure_ascii=False),
51
+ 'attributes': {'patterns': fragments, 'namespaces': namespaces, 'handler': identity(handler),
52
+ 'name': route.name, 'defaultsHash': hashlib.sha256(values_json.encode()).hexdigest()}
53
+ })
54
+ walk(get_resolver().url_patterns, [], [], {}, 0)
55
+ return entries, visited, unsupported
56
+
57
+ try:
58
+ try:
59
+ installed = version('Django')
60
+ except PackageNotFoundError:
61
+ json.dump({'unavailable': 'django-runtime', 'reason': 'missing-package'}, sys.stdout)
62
+ sys.exit(3)
63
+ if installed != '6.1.1':
64
+ json.dump({'unavailable': 'django-runtime', 'reason': 'unsupported-version'}, sys.stdout)
65
+ sys.exit(3)
66
+ config = json.loads(sys.argv[1])
67
+ with contextlib.redirect_stdout(sys.stderr):
68
+ entries, visited, unsupported = capture()
69
+ json.dump({
70
+ 'version': 1, 'djangoVersion': installed, 'visitedNodes': visited, 'unsupportedNodes': unsupported,
71
+ 'runtime': {'schemaVersion': 1, 'format': 'runtime-inventory',
72
+ 'producer': {'name': 'checktrail.django-routes', 'version': '1.0.0'},
73
+ 'assembly': {'name': config['assembly'], 'environment': config['environment']},
74
+ 'sourceFingerprint': sys.argv[2], 'capturedAt': datetime.now(timezone.utc).isoformat().replace('+00:00', 'Z'),
75
+ 'collections': [{'kind': 'routes', 'complete': unsupported == 0, 'ordered': True, 'entries': entries}]}
76
+ }, sys.stdout)
77
+ except Exception as error:
78
+ print(type(error).__name__ + ': ' + str(error), file=sys.stderr)
79
+ sys.exit(2)
80
+ `;
@@ -0,0 +1,9 @@
1
+ import { z } from "zod";
2
+ import type { Check, Inventory, Project } from "./types.js";
3
+ export declare const djangoConfigSchema: z.ZodObject<{
4
+ schemaVersion: z.ZodLiteral<1>;
5
+ settings: z.ZodString;
6
+ assembly: z.ZodString;
7
+ environment: z.ZodString;
8
+ }, z.core.$strict>;
9
+ export declare function djangoCheck(source: Inventory, project: Project): Promise<Check>;
@@ -0,0 +1,50 @@
1
+ import path from "node:path";
2
+ import { z } from "zod";
3
+ import { readProjectFile } from "./inventory.js";
4
+ import { djangoRunner } from "./django-runner.js";
5
+ export const djangoConfigSchema = z.strictObject({
6
+ schemaVersion: z.literal(1),
7
+ settings: z
8
+ .string()
9
+ .regex(/^[A-Za-z_]\w*(?:\.[A-Za-z_]\w*)*$/)
10
+ .max(256),
11
+ assembly: z.string().min(1).max(256),
12
+ environment: z.string().min(1).max(256),
13
+ });
14
+ export async function djangoCheck(source, project) {
15
+ const check = {
16
+ id: "python.django-routes",
17
+ adapter: project.adapter,
18
+ project: project.path,
19
+ scope: [],
20
+ commands: [],
21
+ kind: "analysis",
22
+ parser: "django-json",
23
+ reason: "Load explicit Django test settings, run native application setup, and inventory supported URL patterns including nested resolvers.",
24
+ };
25
+ if (!project.files.includes("checktrail.django.json")) {
26
+ check.unavailableReason =
27
+ "Django route validation requires an explicit checktrail.django.json profile.";
28
+ return check;
29
+ }
30
+ const config = djangoConfigSchema.parse(JSON.parse(await readProjectFile(source.root, path.posix.join(project.path, "checktrail.django.json"))));
31
+ const modulePath = config.settings.replaceAll(".", "/");
32
+ check.scope = [`${modulePath}.py`, `${modulePath}/__init__.py`].filter((file) => project.files.includes(file));
33
+ if (check.scope.length !== 1) {
34
+ check.unavailableReason =
35
+ "Django settings must resolve to one inventoried local Python module or package.";
36
+ return check;
37
+ }
38
+ check.commands = [
39
+ {
40
+ executable: "python3",
41
+ args: ["-c", djangoRunner, JSON.stringify(config), source.fingerprint],
42
+ cwd: project.path,
43
+ env: {
44
+ PYTHONDONTWRITEBYTECODE: "1",
45
+ DJANGO_SETTINGS_MODULE: config.settings,
46
+ },
47
+ },
48
+ ];
49
+ return check;
50
+ }
@@ -0,0 +1 @@
1
+ export declare const dotnetCompilerSource: string;
@@ -0,0 +1,87 @@
1
+ export const dotnetCompilerSource = String.raw `
2
+ using System;
3
+ using System.Collections.Generic;
4
+ using System.IO;
5
+ using System.Linq;
6
+ using System.Reflection.Metadata;
7
+ using System.Reflection.PortableExecutable;
8
+ using System.Text;
9
+ using System.Text.Json;
10
+ using Microsoft.CodeAnalysis;
11
+ using Microsoft.CodeAnalysis.CSharp;
12
+ using Microsoft.CodeAnalysis.Text;
13
+
14
+ sealed class BoundedOutput : MemoryStream {
15
+ const int Limit = 32 * 1024 * 1024;
16
+ void Check(long length) { if (length > Limit) throw new IOException("Compiler output limit exceeded"); }
17
+ public override void Write(byte[] buffer, int offset, int count) { Check(Position + count); base.Write(buffer, offset, count); }
18
+ public override void Write(ReadOnlySpan<byte> buffer) { Check(Position + buffer.Length); base.Write(buffer); }
19
+ public override void WriteByte(byte value) { Check(Position + 1); base.WriteByte(value); }
20
+ public override void SetLength(long value) { Check(value); base.SetLength(value); }
21
+ }
22
+
23
+ class VerifierCompiler {
24
+ static void Main(string[] args) {
25
+ using var input = JsonDocument.Parse(File.ReadAllText(args[0], Encoding.UTF8));
26
+ var root = input.RootElement;
27
+ var config = root.GetProperty("config");
28
+ var language = config.GetProperty("languageVersion").GetString() switch {
29
+ "12" => LanguageVersion.CSharp12, "13" => LanguageVersion.CSharp13, "14" => LanguageVersion.CSharp14,
30
+ _ => throw new InvalidOperationException("Unsupported language version")
31
+ };
32
+ var nullable = config.GetProperty("nullable").GetString() switch {
33
+ "enable" => NullableContextOptions.Enable, "disable" => NullableContextOptions.Disable,
34
+ "warnings" => NullableContextOptions.Warnings, "annotations" => NullableContextOptions.Annotations,
35
+ _ => throw new InvalidOperationException("Unsupported nullable context")
36
+ };
37
+ var parseOptions = new CSharpParseOptions(language, DocumentationMode.Parse, SourceCodeKind.Regular,
38
+ config.GetProperty("defines").EnumerateArray().Select(item => item.GetString()!));
39
+ var trees = new List<SyntaxTree>();
40
+ foreach (var file in root.GetProperty("sources").EnumerateArray()) {
41
+ var name = file.GetString()!;
42
+ var text = File.ReadAllText(name, new UTF8Encoding(false, true));
43
+ trees.Add(CSharpSyntaxTree.ParseText(SourceText.From(text, Encoding.UTF8, SourceHashAlgorithm.Sha256), parseOptions, name));
44
+ }
45
+ var implicitUsings = config.GetProperty("implicitUsings").GetBoolean();
46
+ if (implicitUsings) trees.Add(CSharpSyntaxTree.ParseText("global using System; global using System.Collections.Generic; global using System.IO; global using System.Linq; global using System.Net.Http; global using System.Threading; global using System.Threading.Tasks;", parseOptions, "checktrail://implicit-usings", Encoding.UTF8));
47
+ var references = root.GetProperty("references").EnumerateArray().Select(item => {
48
+ var file = item.GetString()!;
49
+ using var stream = File.OpenRead(file);
50
+ using var image = new PEReader(stream);
51
+ if (!image.HasMetadata) throw new InvalidOperationException("Reference is not a managed assembly");
52
+ var metadata = image.GetMetadataReader();
53
+ if (!metadata.IsAssembly || metadata.AssemblyFiles.Count != 0)
54
+ throw new InvalidOperationException("Multi-file assembly references are unsupported");
55
+ return MetadataReference.CreateFromFile(file);
56
+ }).ToArray();
57
+ var options = new CSharpCompilationOptions(
58
+ config.GetProperty("outputKind").GetString() == "console" ? OutputKind.ConsoleApplication : OutputKind.DynamicallyLinkedLibrary,
59
+ optimizationLevel: OptimizationLevel.Release, checkOverflow: config.GetProperty("checkedArithmetic").GetBoolean(),
60
+ allowUnsafe: config.GetProperty("allowUnsafe").GetBoolean(), warningLevel: 9999,
61
+ generalDiagnosticOption: config.GetProperty("warningsAsErrors").GetBoolean() ? ReportDiagnostic.Error : ReportDiagnostic.Default,
62
+ concurrentBuild: false, deterministic: true, nullableContextOptions: nullable, reportSuppressedDiagnostics: true);
63
+ var compilation = CSharpCompilation.Create(config.GetProperty("assemblyName").GetString()!, trees, references, options);
64
+ var sources = new List<object>();
65
+ foreach (var tree in trees.Where(tree => tree.FilePath != "checktrail://implicit-usings")) {
66
+ var syntax = tree.GetRoot();
67
+ var model = compilation.GetSemanticModel(tree);
68
+ var diagnostics = model.GetDiagnostics();
69
+ if (diagnostics.Length > 2000) throw new InvalidOperationException("Diagnostic limit exceeded");
70
+ sources.Add(new {file = tree.FilePath, syntaxLength = syntax.FullSpan.Length, textLength = tree.GetText().Length,
71
+ semantic = model.SyntaxTree == tree, semanticDiagnosticCount = diagnostics.Length});
72
+ }
73
+ using var output = new BoundedOutput();
74
+ var result = compilation.Emit(output);
75
+ if (result.Diagnostics.Length > 2000) throw new InvalidOperationException("Diagnostic limit exceeded");
76
+ var messages = result.Diagnostics.Select(item => {
77
+ var line = item.Location.IsInSource ? item.Location.GetLineSpan() : default;
78
+ return new {code = item.Id, severity = item.Severity.ToString(), message = item.GetMessage(System.Globalization.CultureInfo.InvariantCulture),
79
+ suppressed = item.IsSuppressed, file = item.Location.IsInSource ? item.Location.SourceTree?.FilePath : null,
80
+ line = item.Location.IsInSource ? line.StartLinePosition.Line + 1 : 0};
81
+ }).ToArray();
82
+ Console.Write(JsonSerializer.Serialize(new {version = 1, compiler = typeof(CSharpCompilation).Assembly.GetName().Version!.ToString(),
83
+ runtime = Environment.Version.ToString(), success = result.Success, outputBytes = output.Length,
84
+ ownedTreeCount = implicitUsings ? 1 : 0, referenceCount = references.Length, settings = config, sources, diagnostics = messages}));
85
+ }
86
+ }
87
+ `;
@@ -0,0 +1,2 @@
1
+ import type { Check, CheckResult, ProcessResult } from "./types.js";
2
+ export declare function dotnetEvidence(check: Check, processes: ProcessResult[], root: string | undefined): Pick<CheckResult, "status" | "reason" | "findings" | "findingsComplete">;
@@ -0,0 +1,127 @@
1
+ import path from "node:path";
2
+ import { z } from "zod";
3
+ import { dotnetConfigSchema, dotnetInvocationSchema } from "./dotnet.js";
4
+ const schema = z.strictObject({
5
+ sdkVersion: z.literal("10.0.401"),
6
+ runtimeReferenceVersion: z.literal("10.0.12"),
7
+ referenceFiles: z.number().int().min(2).max(509),
8
+ compilerAndReferencesSha256: z.string().regex(/^[a-f0-9]{64}$/),
9
+ compilation: z.strictObject({
10
+ version: z.literal(1),
11
+ compiler: z.literal("5.9.0.0"),
12
+ runtime: z.literal("10.0.12"),
13
+ success: z.boolean(),
14
+ outputBytes: z
15
+ .number()
16
+ .int()
17
+ .nonnegative()
18
+ .max(32 * 1024 * 1024),
19
+ ownedTreeCount: z.number().int().min(0).max(1),
20
+ referenceCount: z.number().int().positive(),
21
+ settings: dotnetConfigSchema,
22
+ sources: z
23
+ .array(z.strictObject({
24
+ file: z.string(),
25
+ syntaxLength: z.number().int().nonnegative(),
26
+ textLength: z.number().int().nonnegative(),
27
+ semantic: z.boolean(),
28
+ semanticDiagnosticCount: z.number().int().nonnegative().max(2000),
29
+ }))
30
+ .max(20_000),
31
+ diagnostics: z
32
+ .array(z.strictObject({
33
+ code: z.string().regex(/^CS\d+$/),
34
+ severity: z.enum(["Error", "Warning", "Info", "Hidden"]),
35
+ message: z.string(),
36
+ suppressed: z.boolean(),
37
+ file: z.string().nullable(),
38
+ line: z.number().int().nonnegative(),
39
+ }))
40
+ .max(2000),
41
+ }),
42
+ });
43
+ export function dotnetEvidence(check, processes, root) {
44
+ const incomplete = {
45
+ status: "inconclusive",
46
+ reason: ".NET evidence is malformed, suppressed or missing native compilation/source accounting",
47
+ findingsComplete: false,
48
+ };
49
+ if (!root || processes.length !== 1)
50
+ return incomplete;
51
+ const process = processes[0];
52
+ if (process.exitCode === 3) {
53
+ try {
54
+ z.strictObject({ unavailable: z.literal("dotnet-toolchain") }).parse(JSON.parse(process.stdout));
55
+ return {
56
+ status: "unavailable",
57
+ reason: "The verified .NET SDK and Roslyn compiler are unavailable",
58
+ };
59
+ }
60
+ catch {
61
+ return incomplete;
62
+ }
63
+ }
64
+ if (process.exitCode !== 0)
65
+ return {
66
+ status: "error",
67
+ reason: ".NET evidence collection did not complete normally",
68
+ findingsComplete: false,
69
+ };
70
+ try {
71
+ const data = schema.parse(JSON.parse(process.stdout));
72
+ const result = data.compilation;
73
+ const planned = dotnetInvocationSchema.parse(JSON.parse(check.commands[0].args[2]));
74
+ if (JSON.stringify(planned.scope) !== JSON.stringify(check.scope) ||
75
+ JSON.stringify(planned.config) !== JSON.stringify(result.settings) ||
76
+ result.ownedTreeCount !== Number(planned.config.implicitUsings) ||
77
+ result.referenceCount !==
78
+ data.referenceFiles + planned.config.references.length)
79
+ return incomplete;
80
+ const expected = new Set(check.scope.map((file) => path.resolve(root, check.project, file)));
81
+ const findings = result.diagnostics
82
+ .filter((item) => !item.suppressed)
83
+ .map((item) => ({
84
+ ruleId: `csharp/${item.code}`,
85
+ level: item.severity === "Error"
86
+ ? "error"
87
+ : item.severity === "Warning"
88
+ ? "warning"
89
+ : "note",
90
+ message: item.message,
91
+ ...(item.file && expected.has(item.file) && item.line > 0
92
+ ? {
93
+ file: path.relative(root, item.file).split(path.sep).join("/"),
94
+ line: item.line,
95
+ }
96
+ : {}),
97
+ }));
98
+ const errors = result.diagnostics.some((item) => item.severity === "Error" && !item.suppressed);
99
+ if (errors && !result.success)
100
+ return {
101
+ status: "failed",
102
+ reason: "Roslyn reported compiler errors; failed compilation does not establish complete analysis",
103
+ findings,
104
+ findingsComplete: false,
105
+ };
106
+ if (errors ||
107
+ !result.success ||
108
+ !result.outputBytes ||
109
+ result.diagnostics.some((item) => item.suppressed) ||
110
+ !expected.size ||
111
+ result.sources.length !== expected.size ||
112
+ new Set(result.sources.map((item) => item.file)).size !== expected.size ||
113
+ result.sources.some((item) => !expected.has(item.file) ||
114
+ !item.semantic ||
115
+ item.syntaxLength !== item.textLength))
116
+ return { ...incomplete, findings };
117
+ return {
118
+ status: "passed",
119
+ reason: "Configured C# sources compiled with native syntax and semantic accounting; no application code, build targets or tests were executed",
120
+ findings,
121
+ findingsComplete: true,
122
+ };
123
+ }
124
+ catch {
125
+ return incomplete;
126
+ }
127
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,167 @@
1
+ import { spawnSync } from "node:child_process";
2
+ import { createHash } from "node:crypto";
3
+ import { copyFile, mkdtemp, readFile, readdir, realpath, rm, stat, writeFile, } from "node:fs/promises";
4
+ import { tmpdir } from "node:os";
5
+ import path from "node:path";
6
+ import { dotnetCompilerSource } from "./dotnet-compiler.js";
7
+ import { dotnetInvocationSchema, dotnetReferences } from "./dotnet.js";
8
+ import { withinRoot } from "./inventory.js";
9
+ const sdkVersion = "10.0.401";
10
+ const runtimeVersion = "10.0.12";
11
+ const compilerVersion = "5.9.0-1.26423.113 (e34a38d2ae1fc26406a317517196e55c68ff83ab)";
12
+ const env = {
13
+ PATH: process.env.PATH ?? "",
14
+ DOTNET_CLI_TELEMETRY_OPTOUT: "1",
15
+ DOTNET_NOLOGO: "1",
16
+ DOTNET_SKIP_FIRST_TIME_EXPERIENCE: "1",
17
+ DOTNET_SYSTEM_GLOBALIZATION_INVARIANT: "1",
18
+ DOTNET_EnableDiagnostics: "0",
19
+ DOTNET_GCHeapHardLimit: "10000000",
20
+ };
21
+ let nativeBytes = 0;
22
+ function invoke(args, cwd) {
23
+ const result = spawnSync("dotnet", args, {
24
+ cwd,
25
+ env,
26
+ encoding: "utf8",
27
+ maxBuffer: 1024 * 1024,
28
+ });
29
+ nativeBytes +=
30
+ Buffer.byteLength(result.stdout ?? "") +
31
+ Buffer.byteLength(result.stderr ?? "");
32
+ if (result.error ||
33
+ result.signal ||
34
+ result.status === null ||
35
+ nativeBytes > 4 * 1024 * 1024)
36
+ throw new Error(".NET invocation did not complete within evidence limits");
37
+ return result;
38
+ }
39
+ async function fingerprint(files) {
40
+ const hash = createHash("sha256");
41
+ let total = 0;
42
+ if (files.length > 512)
43
+ throw new Error(".NET reference pack exceeds file limits");
44
+ for (const file of files) {
45
+ const info = await stat(file);
46
+ total += info.size;
47
+ if (!info.isFile() ||
48
+ info.size > 32 * 1024 * 1024 ||
49
+ total > 128 * 1024 * 1024)
50
+ throw new Error(".NET reference pack exceeds byte limits");
51
+ hash
52
+ .update(path.basename(file))
53
+ .update("\0")
54
+ .update(createHash("sha256")
55
+ .update(await readFile(file))
56
+ .digest("hex"))
57
+ .update("\0");
58
+ }
59
+ return hash.digest("hex");
60
+ }
61
+ async function main() {
62
+ const temporary = await mkdtemp(path.join(tmpdir(), "checktrail-dotnet-"));
63
+ try {
64
+ let sdk;
65
+ try {
66
+ const list = invoke(["--list-sdks"], temporary);
67
+ const matches = list.stdout
68
+ .split(/\r?\n/)
69
+ .flatMap((line) => /^10\.0\.401 \[([^\r\n]+)\]$/.exec(line)?.[1] ?? []);
70
+ if (list.status !== 0 || list.stderr || matches.length !== 1)
71
+ throw new Error("Missing verified SDK");
72
+ sdk = await realpath(path.join(matches[0], sdkVersion));
73
+ const version = invoke(["exec", path.join(sdk, "Roslyn/bincore/csc.dll"), "-version"], temporary);
74
+ if (version.status !== 0 ||
75
+ version.stderr ||
76
+ version.stdout.trim() !== compilerVersion)
77
+ throw new Error("Unverified Roslyn compiler");
78
+ }
79
+ catch {
80
+ process.stdout.write(JSON.stringify({ unavailable: "dotnet-toolchain" }));
81
+ process.exitCode = 3;
82
+ return;
83
+ }
84
+ if (process.argv[2] === "--version") {
85
+ process.stdout.write(`${sdkVersion}\n`);
86
+ return;
87
+ }
88
+ const installation = path.resolve(sdk, "../..");
89
+ const referencePack = path.join(installation, "packs/Microsoft.NETCore.App.Ref", runtimeVersion, "ref/net10.0");
90
+ const builtins = (await readdir(referencePack))
91
+ .filter((file) => file.endsWith(".dll"))
92
+ .sort()
93
+ .map((file) => path.join(referencePack, file));
94
+ if (!["System.Runtime.dll", "mscorlib.dll"].every((file) => builtins.includes(path.join(referencePack, file))))
95
+ throw new Error("Incomplete .NET reference pack");
96
+ const compiler = path.join(sdk, "Roslyn/bincore");
97
+ const compilerLibraries = [
98
+ "Microsoft.CodeAnalysis.dll",
99
+ "Microsoft.CodeAnalysis.CSharp.dll",
100
+ ].map((file) => path.join(compiler, file));
101
+ const toolFiles = [
102
+ ...builtins,
103
+ ...compilerLibraries,
104
+ path.join(compiler, "csc.dll"),
105
+ ];
106
+ const before = await fingerprint(toolFiles);
107
+ const root = await realpath(process.argv[2]);
108
+ const project = path.relative(root, await realpath(process.cwd())) || ".";
109
+ const invocation = dotnetInvocationSchema.parse(JSON.parse(process.argv[3]));
110
+ const references = await dotnetReferences(root, project, invocation.config);
111
+ const sources = await Promise.all(invocation.scope.map((file) => withinRoot(root, path.join(project, file))));
112
+ const helper = path.join(temporary, "VerifierCompiler.cs");
113
+ const output = path.join(temporary, "VerifierCompiler.dll");
114
+ await writeFile(helper, dotnetCompilerSource);
115
+ const bootstrap = invoke([
116
+ "exec",
117
+ path.join(compiler, "csc.dll"),
118
+ "-nologo",
119
+ "-noconfig",
120
+ "-nostdlib+",
121
+ "-langversion:14",
122
+ "-nullable:enable",
123
+ "-warnaserror+",
124
+ "-target:exe",
125
+ `-out:${output}`,
126
+ ...[...builtins, ...compilerLibraries].map((file) => `-r:${file}`),
127
+ helper,
128
+ ], temporary);
129
+ if (bootstrap.status !== 0 || bootstrap.stderr || bootstrap.stdout.trim())
130
+ throw new Error("Owned .NET compiler helper could not be prepared");
131
+ for (const file of compilerLibraries)
132
+ await copyFile(file, path.join(temporary, path.basename(file)));
133
+ await writeFile(path.join(temporary, "VerifierCompiler.runtimeconfig.json"), JSON.stringify({
134
+ runtimeOptions: {
135
+ tfm: "net10.0",
136
+ framework: { name: "Microsoft.NETCore.App", version: runtimeVersion },
137
+ rollForward: "Disable",
138
+ },
139
+ }));
140
+ const input = path.join(temporary, "invocation.json");
141
+ await writeFile(input, JSON.stringify({
142
+ config: invocation.config,
143
+ sources,
144
+ references: [...builtins, ...references],
145
+ }));
146
+ const result = invoke(["exec", output, input], temporary);
147
+ if (result.status !== 0 || result.stderr.trim())
148
+ throw new Error(".NET compiler did not complete evidence collection");
149
+ await dotnetReferences(root, project, invocation.config);
150
+ if ((await fingerprint(toolFiles)) !== before)
151
+ throw new Error(".NET reference pack or compiler changed during compilation");
152
+ process.stdout.write(JSON.stringify({
153
+ sdkVersion,
154
+ runtimeReferenceVersion: runtimeVersion,
155
+ referenceFiles: builtins.length,
156
+ compilerAndReferencesSha256: before,
157
+ compilation: JSON.parse(result.stdout),
158
+ }));
159
+ }
160
+ finally {
161
+ await rm(temporary, { recursive: true, force: true });
162
+ }
163
+ }
164
+ main().catch(() => {
165
+ process.stderr.write(".NET evidence collection could not complete\n");
166
+ process.exitCode = 2;
167
+ });
@@ -0,0 +1,65 @@
1
+ import { z } from "zod";
2
+ import type { Check, Inventory, Project } from "./types.js";
3
+ export declare const dotnetConfigSchema: z.ZodObject<{
4
+ schemaVersion: z.ZodLiteral<1>;
5
+ targetFramework: z.ZodLiteral<"net10.0">;
6
+ assemblyName: z.ZodString;
7
+ languageVersion: z.ZodEnum<{
8
+ 12: "12";
9
+ 13: "13";
10
+ 14: "14";
11
+ }>;
12
+ outputKind: z.ZodEnum<{
13
+ library: "library";
14
+ console: "console";
15
+ }>;
16
+ nullable: z.ZodEnum<{
17
+ enable: "enable";
18
+ disable: "disable";
19
+ warnings: "warnings";
20
+ annotations: "annotations";
21
+ }>;
22
+ warningsAsErrors: z.ZodBoolean;
23
+ allowUnsafe: z.ZodBoolean;
24
+ checkedArithmetic: z.ZodBoolean;
25
+ implicitUsings: z.ZodBoolean;
26
+ defines: z.ZodArray<z.ZodString>;
27
+ references: z.ZodArray<z.ZodObject<{
28
+ path: z.ZodString;
29
+ sha256: z.ZodString;
30
+ }, z.core.$strict>>;
31
+ }, z.core.$strict>;
32
+ export declare const dotnetInvocationSchema: z.ZodObject<{
33
+ config: z.ZodObject<{
34
+ schemaVersion: z.ZodLiteral<1>;
35
+ targetFramework: z.ZodLiteral<"net10.0">;
36
+ assemblyName: z.ZodString;
37
+ languageVersion: z.ZodEnum<{
38
+ 12: "12";
39
+ 13: "13";
40
+ 14: "14";
41
+ }>;
42
+ outputKind: z.ZodEnum<{
43
+ library: "library";
44
+ console: "console";
45
+ }>;
46
+ nullable: z.ZodEnum<{
47
+ enable: "enable";
48
+ disable: "disable";
49
+ warnings: "warnings";
50
+ annotations: "annotations";
51
+ }>;
52
+ warningsAsErrors: z.ZodBoolean;
53
+ allowUnsafe: z.ZodBoolean;
54
+ checkedArithmetic: z.ZodBoolean;
55
+ implicitUsings: z.ZodBoolean;
56
+ defines: z.ZodArray<z.ZodString>;
57
+ references: z.ZodArray<z.ZodObject<{
58
+ path: z.ZodString;
59
+ sha256: z.ZodString;
60
+ }, z.core.$strict>>;
61
+ }, z.core.$strict>;
62
+ scope: z.ZodArray<z.ZodString>;
63
+ }, z.core.$strict>;
64
+ export declare function dotnetReferences(root: string, project: string, config: z.infer<typeof dotnetConfigSchema>): Promise<string[]>;
65
+ export declare function dotnetCheck(source: Inventory, project: Project): Promise<Check>;