@ontrails/warden 1.0.0-beta.13 → 1.0.0-beta.15

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 (474) hide show
  1. package/.turbo/turbo-lint.log +1 -1
  2. package/CHANGELOG.md +30 -0
  3. package/README.md +31 -20
  4. package/dist/cli.d.ts +19 -2
  5. package/dist/cli.d.ts.map +1 -1
  6. package/dist/cli.js +261 -64
  7. package/dist/cli.js.map +1 -1
  8. package/dist/draft.d.ts +5 -0
  9. package/dist/draft.d.ts.map +1 -0
  10. package/dist/draft.js +16 -0
  11. package/dist/draft.js.map +1 -0
  12. package/dist/drift.d.ts +10 -7
  13. package/dist/drift.d.ts.map +1 -1
  14. package/dist/drift.js +50 -16
  15. package/dist/drift.js.map +1 -1
  16. package/dist/formatters.d.ts +2 -1
  17. package/dist/formatters.d.ts.map +1 -1
  18. package/dist/formatters.js +15 -4
  19. package/dist/formatters.js.map +1 -1
  20. package/dist/index.d.ts +9 -17
  21. package/dist/index.d.ts.map +1 -1
  22. package/dist/index.js +10 -17
  23. package/dist/index.js.map +1 -1
  24. package/dist/rules/ast.d.ts +412 -7
  25. package/dist/rules/ast.d.ts.map +1 -1
  26. package/dist/rules/ast.js +1847 -102
  27. package/dist/rules/ast.js.map +1 -1
  28. package/dist/rules/circular-refs.d.ts +6 -0
  29. package/dist/rules/circular-refs.d.ts.map +1 -0
  30. package/dist/rules/circular-refs.js +83 -0
  31. package/dist/rules/circular-refs.js.map +1 -0
  32. package/dist/rules/context-no-surface-types.d.ts.map +1 -1
  33. package/dist/rules/context-no-surface-types.js +59 -3
  34. package/dist/rules/context-no-surface-types.js.map +1 -1
  35. package/dist/rules/contour-exists.d.ts +7 -0
  36. package/dist/rules/contour-exists.d.ts.map +1 -0
  37. package/dist/rules/contour-exists.js +113 -0
  38. package/dist/rules/contour-exists.js.map +1 -0
  39. package/dist/rules/contour-ids.d.ts +10 -0
  40. package/dist/rules/contour-ids.d.ts.map +1 -0
  41. package/dist/rules/contour-ids.js +12 -0
  42. package/dist/rules/contour-ids.js.map +1 -0
  43. package/dist/rules/cross-declarations.d.ts.map +1 -1
  44. package/dist/rules/cross-declarations.js +171 -57
  45. package/dist/rules/cross-declarations.js.map +1 -1
  46. package/dist/rules/dead-internal-trail.d.ts +3 -0
  47. package/dist/rules/dead-internal-trail.d.ts.map +1 -0
  48. package/dist/rules/dead-internal-trail.js +80 -0
  49. package/dist/rules/dead-internal-trail.js.map +1 -0
  50. package/dist/rules/draft-file-marking.d.ts +6 -0
  51. package/dist/rules/draft-file-marking.d.ts.map +1 -0
  52. package/dist/rules/draft-file-marking.js +87 -0
  53. package/dist/rules/draft-file-marking.js.map +1 -0
  54. package/dist/rules/draft-visible-debt.d.ts +12 -0
  55. package/dist/rules/draft-visible-debt.d.ts.map +1 -0
  56. package/dist/rules/draft-visible-debt.js +50 -0
  57. package/dist/rules/draft-visible-debt.js.map +1 -0
  58. package/dist/rules/error-mapping-completeness.d.ts +13 -0
  59. package/dist/rules/error-mapping-completeness.d.ts.map +1 -0
  60. package/dist/rules/error-mapping-completeness.js +160 -0
  61. package/dist/rules/error-mapping-completeness.js.map +1 -0
  62. package/dist/rules/example-valid.d.ts +6 -0
  63. package/dist/rules/example-valid.d.ts.map +1 -0
  64. package/dist/rules/example-valid.js +203 -0
  65. package/dist/rules/example-valid.js.map +1 -0
  66. package/dist/rules/fires-declarations.d.ts +16 -0
  67. package/dist/rules/fires-declarations.d.ts.map +1 -0
  68. package/dist/rules/fires-declarations.js +444 -0
  69. package/dist/rules/fires-declarations.js.map +1 -0
  70. package/dist/rules/implementation-returns-result.d.ts +9 -0
  71. package/dist/rules/implementation-returns-result.d.ts.map +1 -1
  72. package/dist/rules/implementation-returns-result.js +638 -76
  73. package/dist/rules/implementation-returns-result.js.map +1 -1
  74. package/dist/rules/incomplete-accessor-for-standard-op.d.ts +30 -0
  75. package/dist/rules/incomplete-accessor-for-standard-op.d.ts.map +1 -0
  76. package/dist/rules/incomplete-accessor-for-standard-op.js +226 -0
  77. package/dist/rules/incomplete-accessor-for-standard-op.js.map +1 -0
  78. package/dist/rules/incomplete-crud.d.ts +21 -0
  79. package/dist/rules/incomplete-crud.d.ts.map +1 -0
  80. package/dist/rules/incomplete-crud.js +368 -0
  81. package/dist/rules/incomplete-crud.js.map +1 -0
  82. package/dist/rules/index.d.ts +40 -7
  83. package/dist/rules/index.d.ts.map +1 -1
  84. package/dist/rules/index.js +91 -15
  85. package/dist/rules/index.js.map +1 -1
  86. package/dist/rules/intent-propagation.d.ts +3 -0
  87. package/dist/rules/intent-propagation.d.ts.map +1 -0
  88. package/dist/rules/intent-propagation.js +57 -0
  89. package/dist/rules/intent-propagation.js.map +1 -0
  90. package/dist/rules/missing-reconcile.d.ts +3 -0
  91. package/dist/rules/missing-reconcile.d.ts.map +1 -0
  92. package/dist/rules/missing-reconcile.js +44 -0
  93. package/dist/rules/missing-reconcile.js.map +1 -0
  94. package/dist/rules/missing-visibility.d.ts +3 -0
  95. package/dist/rules/missing-visibility.d.ts.map +1 -0
  96. package/dist/rules/missing-visibility.js +63 -0
  97. package/dist/rules/missing-visibility.js.map +1 -0
  98. package/dist/rules/no-direct-impl-in-route.d.ts.map +1 -1
  99. package/dist/rules/no-direct-impl-in-route.js +0 -3
  100. package/dist/rules/no-direct-impl-in-route.js.map +1 -1
  101. package/dist/rules/no-direct-implementation-call.js +1 -1
  102. package/dist/rules/no-direct-implementation-call.js.map +1 -1
  103. package/dist/rules/no-sync-result-assumption.d.ts.map +1 -1
  104. package/dist/rules/no-sync-result-assumption.js +870 -61
  105. package/dist/rules/no-sync-result-assumption.js.map +1 -1
  106. package/dist/rules/no-throw-in-detour-recover.d.ts +3 -0
  107. package/dist/rules/no-throw-in-detour-recover.d.ts.map +1 -0
  108. package/dist/rules/no-throw-in-detour-recover.js +147 -0
  109. package/dist/rules/no-throw-in-detour-recover.js.map +1 -0
  110. package/dist/rules/no-throw-in-detour-target.d.ts +4 -1
  111. package/dist/rules/no-throw-in-detour-target.d.ts.map +1 -1
  112. package/dist/rules/no-throw-in-detour-target.js +6 -3
  113. package/dist/rules/no-throw-in-detour-target.js.map +1 -1
  114. package/dist/rules/no-throw-in-implementation.d.ts +4 -2
  115. package/dist/rules/no-throw-in-implementation.d.ts.map +1 -1
  116. package/dist/rules/no-throw-in-implementation.js +6 -4
  117. package/dist/rules/no-throw-in-implementation.js.map +1 -1
  118. package/dist/rules/on-references-exist.d.ts +14 -0
  119. package/dist/rules/on-references-exist.d.ts.map +1 -0
  120. package/dist/rules/on-references-exist.js +109 -0
  121. package/dist/rules/on-references-exist.js.map +1 -0
  122. package/dist/rules/orphaned-signal.d.ts +3 -0
  123. package/dist/rules/orphaned-signal.d.ts.map +1 -0
  124. package/dist/rules/orphaned-signal.js +67 -0
  125. package/dist/rules/orphaned-signal.js.map +1 -0
  126. package/dist/rules/permit-governance.d.ts +3 -0
  127. package/dist/rules/permit-governance.d.ts.map +1 -0
  128. package/dist/rules/permit-governance.js +15 -0
  129. package/dist/rules/permit-governance.js.map +1 -0
  130. package/dist/rules/reference-exists.d.ts +6 -0
  131. package/dist/rules/reference-exists.d.ts.map +1 -0
  132. package/dist/rules/reference-exists.js +47 -0
  133. package/dist/rules/reference-exists.js.map +1 -0
  134. package/dist/rules/registry-names.d.ts +8 -0
  135. package/dist/rules/registry-names.d.ts.map +1 -0
  136. package/dist/rules/registry-names.js +83 -0
  137. package/dist/rules/registry-names.js.map +1 -0
  138. package/dist/rules/resource-declarations.d.ts +14 -0
  139. package/dist/rules/resource-declarations.d.ts.map +1 -0
  140. package/dist/rules/resource-declarations.js +413 -0
  141. package/dist/rules/resource-declarations.js.map +1 -0
  142. package/dist/rules/resource-exists.d.ts +6 -0
  143. package/dist/rules/resource-exists.d.ts.map +1 -0
  144. package/dist/rules/resource-exists.js +90 -0
  145. package/dist/rules/resource-exists.js.map +1 -0
  146. package/dist/rules/resource-id-grammar.d.ts +3 -0
  147. package/dist/rules/resource-id-grammar.d.ts.map +1 -0
  148. package/dist/rules/resource-id-grammar.js +39 -0
  149. package/dist/rules/resource-id-grammar.js.map +1 -0
  150. package/dist/rules/specs.d.ts.map +1 -1
  151. package/dist/rules/specs.js +5 -1
  152. package/dist/rules/specs.js.map +1 -1
  153. package/dist/rules/types.d.ts +53 -4
  154. package/dist/rules/types.d.ts.map +1 -1
  155. package/dist/rules/unreachable-detour-shadowing.d.ts +3 -0
  156. package/dist/rules/unreachable-detour-shadowing.d.ts.map +1 -0
  157. package/dist/rules/unreachable-detour-shadowing.js +202 -0
  158. package/dist/rules/unreachable-detour-shadowing.js.map +1 -0
  159. package/dist/rules/valid-describe-refs.d.ts.map +1 -1
  160. package/dist/rules/valid-describe-refs.js +132 -16
  161. package/dist/rules/valid-describe-refs.js.map +1 -1
  162. package/dist/rules/valid-detour-contract.d.ts +3 -0
  163. package/dist/rules/valid-detour-contract.d.ts.map +1 -0
  164. package/dist/rules/valid-detour-contract.js +47 -0
  165. package/dist/rules/valid-detour-contract.js.map +1 -0
  166. package/dist/rules/valid-detour-refs.d.ts.map +1 -1
  167. package/dist/rules/valid-detour-refs.js +73 -82
  168. package/dist/rules/valid-detour-refs.js.map +1 -1
  169. package/dist/rules/warden-export-symmetry.d.ts +7 -0
  170. package/dist/rules/warden-export-symmetry.d.ts.map +1 -0
  171. package/dist/rules/warden-export-symmetry.js +352 -0
  172. package/dist/rules/warden-export-symmetry.js.map +1 -0
  173. package/dist/rules/warden-rules-use-ast.d.ts +17 -0
  174. package/dist/rules/warden-rules-use-ast.d.ts.map +1 -0
  175. package/dist/rules/warden-rules-use-ast.js +778 -0
  176. package/dist/rules/warden-rules-use-ast.js.map +1 -0
  177. package/dist/trails/circular-refs.trail.d.ts +24 -0
  178. package/dist/trails/circular-refs.trail.d.ts.map +1 -0
  179. package/dist/trails/circular-refs.trail.js +29 -0
  180. package/dist/trails/circular-refs.trail.js.map +1 -0
  181. package/dist/trails/context-no-surface-types.trail.d.ts +2 -2
  182. package/dist/trails/context-no-surface-types.trail.d.ts.map +1 -1
  183. package/dist/trails/context-no-trailhead-types.trail.d.ts +2 -2
  184. package/dist/trails/context-no-trailhead-types.trail.d.ts.map +1 -1
  185. package/dist/trails/contour-exists.trail.d.ts +24 -0
  186. package/dist/trails/contour-exists.trail.d.ts.map +1 -0
  187. package/dist/trails/contour-exists.trail.js +21 -0
  188. package/dist/trails/contour-exists.trail.js.map +1 -0
  189. package/dist/trails/cross-declarations.trail.d.ts +2 -2
  190. package/dist/trails/cross-declarations.trail.d.ts.map +1 -1
  191. package/dist/trails/dead-internal-trail.trail.d.ts +24 -0
  192. package/dist/trails/dead-internal-trail.trail.d.ts.map +1 -0
  193. package/dist/trails/dead-internal-trail.trail.js +26 -0
  194. package/dist/trails/dead-internal-trail.trail.js.map +1 -0
  195. package/dist/trails/{provision-declarations.trail.d.ts → draft-file-marking.trail.d.ts} +3 -3
  196. package/dist/trails/draft-file-marking.trail.d.ts.map +1 -0
  197. package/dist/trails/draft-file-marking.trail.js +16 -0
  198. package/dist/trails/draft-file-marking.trail.js.map +1 -0
  199. package/dist/trails/draft-visible-debt.trail.d.ts +13 -0
  200. package/dist/trails/draft-visible-debt.trail.d.ts.map +1 -0
  201. package/dist/trails/draft-visible-debt.trail.js +16 -0
  202. package/dist/trails/draft-visible-debt.trail.js.map +1 -0
  203. package/dist/trails/error-mapping-completeness.trail.d.ts +13 -0
  204. package/dist/trails/error-mapping-completeness.trail.d.ts.map +1 -0
  205. package/dist/trails/error-mapping-completeness.trail.js +29 -0
  206. package/dist/trails/error-mapping-completeness.trail.js.map +1 -0
  207. package/dist/trails/{follow-declarations.trail.d.ts → example-valid.trail.d.ts} +3 -3
  208. package/dist/trails/example-valid.trail.d.ts.map +1 -0
  209. package/dist/trails/example-valid.trail.js +25 -0
  210. package/dist/trails/example-valid.trail.js.map +1 -0
  211. package/dist/trails/fires-declarations.trail.d.ts +13 -0
  212. package/dist/trails/fires-declarations.trail.d.ts.map +1 -0
  213. package/dist/trails/fires-declarations.trail.js +22 -0
  214. package/dist/trails/fires-declarations.trail.js.map +1 -0
  215. package/dist/trails/implementation-returns-result.trail.d.ts +2 -2
  216. package/dist/trails/implementation-returns-result.trail.d.ts.map +1 -1
  217. package/dist/trails/incomplete-accessor-for-standard-op.trail.d.ts +12 -0
  218. package/dist/trails/incomplete-accessor-for-standard-op.trail.d.ts.map +1 -0
  219. package/dist/trails/incomplete-accessor-for-standard-op.trail.js +60 -0
  220. package/dist/trails/incomplete-accessor-for-standard-op.trail.js.map +1 -0
  221. package/dist/trails/incomplete-crud.trail.d.ts +24 -0
  222. package/dist/trails/incomplete-crud.trail.d.ts.map +1 -0
  223. package/dist/trails/incomplete-crud.trail.js +39 -0
  224. package/dist/trails/incomplete-crud.trail.js.map +1 -0
  225. package/dist/trails/index.d.ts +29 -7
  226. package/dist/trails/index.d.ts.map +1 -1
  227. package/dist/trails/index.js +28 -6
  228. package/dist/trails/index.js.map +1 -1
  229. package/dist/trails/intent-propagation.trail.d.ts +24 -0
  230. package/dist/trails/intent-propagation.trail.d.ts.map +1 -0
  231. package/dist/trails/intent-propagation.trail.js +30 -0
  232. package/dist/trails/intent-propagation.trail.js.map +1 -0
  233. package/dist/trails/missing-reconcile.trail.d.ts +24 -0
  234. package/dist/trails/missing-reconcile.trail.d.ts.map +1 -0
  235. package/dist/trails/missing-reconcile.trail.js +33 -0
  236. package/dist/trails/missing-reconcile.trail.js.map +1 -0
  237. package/dist/trails/missing-visibility.trail.d.ts +24 -0
  238. package/dist/trails/missing-visibility.trail.d.ts.map +1 -0
  239. package/dist/trails/missing-visibility.trail.js +22 -0
  240. package/dist/trails/missing-visibility.trail.js.map +1 -0
  241. package/dist/trails/no-direct-impl-in-route.trail.d.ts +2 -2
  242. package/dist/trails/no-direct-impl-in-route.trail.d.ts.map +1 -1
  243. package/dist/trails/no-direct-implementation-call.trail.d.ts +2 -2
  244. package/dist/trails/no-direct-implementation-call.trail.d.ts.map +1 -1
  245. package/dist/trails/no-sync-result-assumption.trail.d.ts +2 -2
  246. package/dist/trails/no-sync-result-assumption.trail.d.ts.map +1 -1
  247. package/dist/trails/no-throw-in-detour-recover.trail.d.ts +13 -0
  248. package/dist/trails/no-throw-in-detour-recover.trail.d.ts.map +1 -0
  249. package/dist/trails/no-throw-in-detour-recover.trail.js +24 -0
  250. package/dist/trails/no-throw-in-detour-recover.trail.js.map +1 -0
  251. package/dist/trails/no-throw-in-detour-target.trail.d.ts +13 -3
  252. package/dist/trails/no-throw-in-detour-target.trail.d.ts.map +1 -1
  253. package/dist/trails/no-throw-in-implementation.trail.d.ts +2 -2
  254. package/dist/trails/no-throw-in-implementation.trail.d.ts.map +1 -1
  255. package/dist/trails/on-references-exist.trail.d.ts +24 -0
  256. package/dist/trails/on-references-exist.trail.d.ts.map +1 -0
  257. package/dist/trails/on-references-exist.trail.js +21 -0
  258. package/dist/trails/on-references-exist.trail.js.map +1 -0
  259. package/dist/trails/orphaned-signal.trail.d.ts +24 -0
  260. package/dist/trails/orphaned-signal.trail.d.ts.map +1 -0
  261. package/dist/trails/orphaned-signal.trail.js +36 -0
  262. package/dist/trails/orphaned-signal.trail.js.map +1 -0
  263. package/dist/trails/permit-governance.trail.d.ts +12 -0
  264. package/dist/trails/permit-governance.trail.d.ts.map +1 -0
  265. package/dist/trails/permit-governance.trail.js +47 -0
  266. package/dist/trails/permit-governance.trail.js.map +1 -0
  267. package/dist/trails/prefer-schema-inference.trail.d.ts +2 -2
  268. package/dist/trails/prefer-schema-inference.trail.d.ts.map +1 -1
  269. package/dist/trails/reference-exists.trail.d.ts +24 -0
  270. package/dist/trails/reference-exists.trail.d.ts.map +1 -0
  271. package/dist/trails/reference-exists.trail.js +25 -0
  272. package/dist/trails/reference-exists.trail.js.map +1 -0
  273. package/dist/trails/resource-declarations.trail.d.ts +13 -0
  274. package/dist/trails/resource-declarations.trail.d.ts.map +1 -0
  275. package/dist/trails/{provision-declarations.trail.js → resource-declarations.trail.js} +7 -7
  276. package/dist/trails/resource-declarations.trail.js.map +1 -0
  277. package/dist/trails/resource-exists.trail.d.ts +24 -0
  278. package/dist/trails/resource-exists.trail.d.ts.map +1 -0
  279. package/dist/trails/{provision-exists.trail.js → resource-exists.trail.js} +8 -8
  280. package/dist/trails/resource-exists.trail.js.map +1 -0
  281. package/dist/trails/resource-id-grammar.trail.d.ts +13 -0
  282. package/dist/trails/resource-id-grammar.trail.d.ts.map +1 -0
  283. package/dist/trails/resource-id-grammar.trail.js +38 -0
  284. package/dist/trails/resource-id-grammar.trail.js.map +1 -0
  285. package/dist/trails/run.d.ts +25 -9
  286. package/dist/trails/run.d.ts.map +1 -1
  287. package/dist/trails/run.js +63 -19
  288. package/dist/trails/run.js.map +1 -1
  289. package/dist/trails/schema.d.ts +28 -3
  290. package/dist/trails/schema.d.ts.map +1 -1
  291. package/dist/trails/schema.js +57 -4
  292. package/dist/trails/schema.js.map +1 -1
  293. package/dist/trails/unreachable-detour-shadowing.trail.d.ts +13 -0
  294. package/dist/trails/unreachable-detour-shadowing.trail.d.ts.map +1 -0
  295. package/dist/trails/unreachable-detour-shadowing.trail.js +44 -0
  296. package/dist/trails/unreachable-detour-shadowing.trail.js.map +1 -0
  297. package/dist/trails/valid-describe-refs.trail.d.ts +12 -3
  298. package/dist/trails/valid-describe-refs.trail.d.ts.map +1 -1
  299. package/dist/trails/valid-detour-contract.trail.d.ts +12 -0
  300. package/dist/trails/valid-detour-contract.trail.d.ts.map +1 -0
  301. package/dist/trails/valid-detour-contract.trail.js +66 -0
  302. package/dist/trails/valid-detour-contract.trail.js.map +1 -0
  303. package/dist/trails/valid-detour-refs.trail.d.ts +13 -3
  304. package/dist/trails/valid-detour-refs.trail.d.ts.map +1 -1
  305. package/dist/trails/warden-export-symmetry.trail.d.ts +13 -0
  306. package/dist/trails/warden-export-symmetry.trail.d.ts.map +1 -0
  307. package/dist/trails/warden-export-symmetry.trail.js +16 -0
  308. package/dist/trails/warden-export-symmetry.trail.js.map +1 -0
  309. package/dist/trails/warden-rules-use-ast.trail.d.ts +13 -0
  310. package/dist/trails/warden-rules-use-ast.trail.d.ts.map +1 -0
  311. package/dist/trails/warden-rules-use-ast.trail.js +41 -0
  312. package/dist/trails/warden-rules-use-ast.trail.js.map +1 -0
  313. package/dist/trails/wrap-rule.d.ts +16 -2
  314. package/dist/trails/wrap-rule.d.ts.map +1 -1
  315. package/dist/trails/wrap-rule.js +71 -11
  316. package/dist/trails/wrap-rule.js.map +1 -1
  317. package/package.json +7 -4
  318. package/src/__tests__/ast.test.ts +613 -0
  319. package/src/__tests__/circular-refs.test.ts +121 -0
  320. package/src/__tests__/cli.test.ts +360 -32
  321. package/src/__tests__/contour-exists.test.ts +203 -0
  322. package/src/__tests__/cross-declarations.test.ts +245 -0
  323. package/src/__tests__/dead-internal-trail.test.ts +81 -0
  324. package/src/__tests__/draft-rules-context.test.ts +150 -0
  325. package/src/__tests__/drift.test.ts +75 -5
  326. package/src/__tests__/error-mapping-completeness.test.ts +56 -0
  327. package/src/__tests__/example-valid.test.ts +101 -0
  328. package/src/__tests__/fires-declarations-param-destructure.test.ts +54 -0
  329. package/src/__tests__/fires-declarations.test.ts +652 -0
  330. package/src/__tests__/formatters.test.ts +2 -2
  331. package/src/__tests__/implementation-returns-result.test.ts +1016 -2
  332. package/src/__tests__/incomplete-accessor-for-standard-op.test.ts +337 -0
  333. package/src/__tests__/incomplete-crud.test.ts +498 -0
  334. package/src/__tests__/intent-propagation.test.ts +116 -0
  335. package/src/__tests__/missing-reconcile.test.ts +154 -0
  336. package/src/__tests__/missing-visibility.test.ts +108 -0
  337. package/src/__tests__/no-sync-result-assumption.test.ts +870 -39
  338. package/src/__tests__/no-throw-in-detour-recover.test.ts +93 -0
  339. package/src/__tests__/no-throw-in-implementation.test.ts +88 -0
  340. package/src/__tests__/on-references-exist.test.ts +151 -0
  341. package/src/__tests__/orphaned-signal.test.ts +137 -0
  342. package/src/__tests__/permit-governance.test.ts +66 -0
  343. package/src/__tests__/reference-exists.test.ts +281 -0
  344. package/src/__tests__/resource-declarations.test.ts +448 -0
  345. package/src/__tests__/resource-exists.test.ts +122 -0
  346. package/src/__tests__/resource-id-grammar.test.ts +50 -0
  347. package/src/__tests__/rules.test.ts +17 -77
  348. package/src/__tests__/topo-aware-rule.test.ts +257 -0
  349. package/src/__tests__/trails.test.ts +2 -2
  350. package/src/__tests__/unreachable-detour-shadowing.test.ts +128 -0
  351. package/src/__tests__/valid-describe-refs.test.ts +183 -0
  352. package/src/__tests__/valid-detour-contract.test.ts +86 -0
  353. package/src/__tests__/warden-export-symmetry.test.ts +251 -0
  354. package/src/__tests__/warden-rules-use-ast.test.ts +468 -0
  355. package/src/__tests__/wrap-rule.test.ts +3 -3
  356. package/src/cli.ts +458 -91
  357. package/src/draft.ts +22 -0
  358. package/src/drift.ts +63 -21
  359. package/src/formatters.ts +15 -4
  360. package/src/index.ts +62 -23
  361. package/src/rules/ast.ts +2715 -119
  362. package/src/rules/circular-refs.ts +154 -0
  363. package/src/rules/{context-no-trailhead-types.ts → context-no-surface-types.ts} +72 -12
  364. package/src/rules/contour-exists.ts +251 -0
  365. package/src/rules/contour-ids.ts +15 -0
  366. package/src/rules/cross-declarations.ts +277 -69
  367. package/src/rules/dead-internal-trail.ts +141 -0
  368. package/src/rules/draft-file-marking.ts +160 -0
  369. package/src/rules/draft-visible-debt.ts +87 -0
  370. package/src/rules/error-mapping-completeness.ts +273 -0
  371. package/src/rules/example-valid.ts +401 -0
  372. package/src/rules/fires-declarations.ts +609 -0
  373. package/src/rules/implementation-returns-result.ts +1042 -122
  374. package/src/rules/incomplete-accessor-for-standard-op.ts +315 -0
  375. package/src/rules/incomplete-crud.ts +579 -0
  376. package/src/rules/index.ts +95 -16
  377. package/src/rules/intent-propagation.ts +142 -0
  378. package/src/rules/missing-reconcile.ts +98 -0
  379. package/src/rules/missing-visibility.ts +110 -0
  380. package/src/rules/no-direct-impl-in-route.ts +0 -4
  381. package/src/rules/no-direct-implementation-call.ts +1 -1
  382. package/src/rules/no-sync-result-assumption.ts +1134 -96
  383. package/src/rules/no-throw-in-detour-recover.ts +225 -0
  384. package/src/rules/no-throw-in-implementation.ts +6 -4
  385. package/src/rules/on-references-exist.ts +194 -0
  386. package/src/rules/orphaned-signal.ts +150 -0
  387. package/src/rules/permit-governance.ts +25 -0
  388. package/src/rules/reference-exists.ts +98 -0
  389. package/src/rules/registry-names.ts +83 -0
  390. package/src/rules/{provision-declarations.ts → resource-declarations.ts} +208 -138
  391. package/src/rules/{provision-exists.ts → resource-exists.ts} +48 -51
  392. package/src/rules/resource-id-grammar.ts +65 -0
  393. package/src/rules/specs.ts +5 -1
  394. package/src/rules/types.ts +57 -4
  395. package/src/rules/unreachable-detour-shadowing.ts +375 -0
  396. package/src/rules/valid-describe-refs.ts +160 -32
  397. package/src/rules/valid-detour-contract.ts +78 -0
  398. package/src/rules/warden-export-symmetry.ts +533 -0
  399. package/src/rules/warden-rules-use-ast.ts +996 -0
  400. package/src/trails/circular-refs.trail.ts +29 -0
  401. package/src/trails/{context-no-trailhead-types.trail.ts → context-no-surface-types.trail.ts} +4 -4
  402. package/src/trails/contour-exists.trail.ts +21 -0
  403. package/src/trails/dead-internal-trail.trail.ts +26 -0
  404. package/src/trails/draft-file-marking.trail.ts +16 -0
  405. package/src/trails/draft-visible-debt.trail.ts +16 -0
  406. package/src/trails/error-mapping-completeness.trail.ts +29 -0
  407. package/src/trails/example-valid.trail.ts +25 -0
  408. package/src/trails/fires-declarations.trail.ts +22 -0
  409. package/src/trails/incomplete-accessor-for-standard-op.trail.ts +76 -0
  410. package/src/trails/incomplete-crud.trail.ts +39 -0
  411. package/src/trails/index.ts +40 -7
  412. package/src/trails/intent-propagation.trail.ts +30 -0
  413. package/src/trails/missing-reconcile.trail.ts +33 -0
  414. package/src/trails/missing-visibility.trail.ts +22 -0
  415. package/src/trails/no-throw-in-detour-recover.trail.ts +24 -0
  416. package/src/trails/on-references-exist.trail.ts +21 -0
  417. package/src/trails/orphaned-signal.trail.ts +36 -0
  418. package/src/trails/permit-governance.trail.ts +51 -0
  419. package/src/trails/reference-exists.trail.ts +25 -0
  420. package/src/trails/{provision-declarations.trail.ts → resource-declarations.trail.ts} +6 -6
  421. package/src/trails/{provision-exists.trail.ts → resource-exists.trail.ts} +7 -7
  422. package/src/trails/resource-id-grammar.trail.ts +39 -0
  423. package/src/trails/run.ts +121 -24
  424. package/src/trails/schema.ts +66 -4
  425. package/src/trails/unreachable-detour-shadowing.trail.ts +45 -0
  426. package/src/trails/valid-detour-contract.trail.ts +71 -0
  427. package/src/trails/warden-export-symmetry.trail.ts +16 -0
  428. package/src/trails/warden-rules-use-ast.trail.ts +45 -0
  429. package/src/trails/wrap-rule.ts +104 -12
  430. package/tsconfig.tests.json +10 -0
  431. package/tsconfig.tsbuildinfo +1 -1
  432. package/dist/rules/follow-declarations.d.ts +0 -13
  433. package/dist/rules/follow-declarations.d.ts.map +0 -1
  434. package/dist/rules/follow-declarations.js +0 -264
  435. package/dist/rules/follow-declarations.js.map +0 -1
  436. package/dist/rules/provision-declarations.d.ts +0 -14
  437. package/dist/rules/provision-declarations.d.ts.map +0 -1
  438. package/dist/rules/provision-declarations.js +0 -344
  439. package/dist/rules/provision-declarations.js.map +0 -1
  440. package/dist/rules/provision-exists.d.ts +0 -6
  441. package/dist/rules/provision-exists.d.ts.map +0 -1
  442. package/dist/rules/provision-exists.js +0 -89
  443. package/dist/rules/provision-exists.js.map +0 -1
  444. package/dist/rules/service-declarations.d.ts +0 -16
  445. package/dist/rules/service-declarations.d.ts.map +0 -1
  446. package/dist/rules/service-declarations.js +0 -346
  447. package/dist/rules/service-declarations.js.map +0 -1
  448. package/dist/rules/service-exists.d.ts +0 -8
  449. package/dist/rules/service-exists.d.ts.map +0 -1
  450. package/dist/rules/service-exists.js +0 -91
  451. package/dist/rules/service-exists.js.map +0 -1
  452. package/dist/trails/follow-declarations.trail.d.ts.map +0 -1
  453. package/dist/trails/follow-declarations.trail.js +0 -22
  454. package/dist/trails/follow-declarations.trail.js.map +0 -1
  455. package/dist/trails/provision-declarations.trail.d.ts.map +0 -1
  456. package/dist/trails/provision-declarations.trail.js.map +0 -1
  457. package/dist/trails/provision-exists.trail.d.ts +0 -15
  458. package/dist/trails/provision-exists.trail.d.ts.map +0 -1
  459. package/dist/trails/provision-exists.trail.js.map +0 -1
  460. package/dist/trails/service-declarations.trail.d.ts +0 -26
  461. package/dist/trails/service-declarations.trail.d.ts.map +0 -1
  462. package/dist/trails/service-declarations.trail.js +0 -27
  463. package/dist/trails/service-declarations.trail.js.map +0 -1
  464. package/dist/trails/service-exists.trail.d.ts +0 -32
  465. package/dist/trails/service-exists.trail.d.ts.map +0 -1
  466. package/dist/trails/service-exists.trail.js +0 -29
  467. package/dist/trails/service-exists.trail.js.map +0 -1
  468. package/src/__tests__/no-throw-in-detour-target.test.ts +0 -78
  469. package/src/__tests__/provision-declarations.test.ts +0 -318
  470. package/src/__tests__/provision-exists.test.ts +0 -122
  471. package/src/rules/no-throw-in-detour-target.ts +0 -150
  472. package/src/rules/valid-detour-refs.ts +0 -187
  473. package/src/trails/no-throw-in-detour-target.trail.ts +0 -20
  474. package/src/trails/valid-detour-refs.trail.ts +0 -24
@@ -1,14 +1,14 @@
1
1
  /**
2
- * Validates that provision access matches the declared `provisions` array.
2
+ * Validates that resource access matches the declared `resources` array.
3
3
  *
4
4
  * Statically analyzes trail `blaze` functions to find `db.from(ctx)` and
5
- * `ctx.provision('db.main')` calls and compares them against the declared
6
- * `provisions: [...]` array in the trail config. Reports errors for undeclared
5
+ * `ctx.resource('db.main')` calls and compares them against the declared
6
+ * `resources: [...]` array in the trail config. Reports errors for undeclared
7
7
  * access and warnings for unused declarations.
8
8
  */
9
9
 
10
10
  import {
11
- collectNamedProvisionIds,
11
+ collectNamedResourceIds,
12
12
  extractFirstStringArg,
13
13
  findConfigProperty,
14
14
  findBlazeBodies,
@@ -25,15 +25,15 @@ import { isTestFile } from './scan.js';
25
25
  import type { WardenDiagnostic, WardenRule } from './types.js';
26
26
 
27
27
  // ---------------------------------------------------------------------------
28
- // Provision declaration extraction
28
+ // Resource declaration extraction
29
29
  // ---------------------------------------------------------------------------
30
30
 
31
- interface DeclaredProvision {
31
+ interface DeclaredResource {
32
32
  readonly id: string | null;
33
33
  readonly name: string | null;
34
34
  }
35
35
 
36
- interface CalledProvisions {
36
+ interface CalledResources {
37
37
  readonly fromNames: ReadonlySet<string>;
38
38
  readonly lookupIds: ReadonlySet<string>;
39
39
  readonly lookupNames: ReadonlySet<string>;
@@ -59,25 +59,25 @@ const extractMemberPair = (
59
59
  return objName && propName ? { objName, propName } : null;
60
60
  };
61
61
 
62
- /** Check if a node is an inline `provision('id', ...)` call. */
63
- const isInlineProvisionCall = (node: AstNode): boolean => {
62
+ /** Check if a node is an inline `resource('id', ...)` call. */
63
+ const isInlineResourceCall = (node: AstNode): boolean => {
64
64
  if (node.type !== 'CallExpression') {
65
65
  return false;
66
66
  }
67
67
  return (
68
68
  identifierName((node as unknown as { callee?: AstNode }).callee) ===
69
- 'provision'
69
+ 'resource'
70
70
  );
71
71
  };
72
72
 
73
- /** Get `provisions` array elements from a trail config. */
74
- const getProvisionElements = (config: AstNode): readonly AstNode[] => {
75
- const provisionsProp = findConfigProperty(config, 'provisions');
76
- if (!provisionsProp) {
73
+ /** Get `resources` array elements from a trail config. */
74
+ const getResourceElements = (config: AstNode): readonly AstNode[] => {
75
+ const resourcesProp = findConfigProperty(config, 'resources');
76
+ if (!resourcesProp) {
77
77
  return [];
78
78
  }
79
79
 
80
- const arrayNode = provisionsProp.value;
80
+ const arrayNode = resourcesProp.value;
81
81
  if (!arrayNode || (arrayNode as AstNode).type !== 'ArrayExpression') {
82
82
  return [];
83
83
  }
@@ -88,15 +88,15 @@ const getProvisionElements = (config: AstNode): readonly AstNode[] => {
88
88
  return elements ?? [];
89
89
  };
90
90
 
91
- /** Extract one declared provision from a `provisions` array element. */
92
- const extractDeclaredProvision = (
91
+ /** Extract one declared resource from a `resources` array element. */
92
+ const extractDeclaredResource = (
93
93
  element: AstNode,
94
- provisionIdsByName: ReadonlyMap<string, string>
95
- ): DeclaredProvision | null => {
94
+ resourceIdsByName: ReadonlyMap<string, string>
95
+ ): DeclaredResource | null => {
96
96
  if (element.type === 'Identifier') {
97
97
  const name = identifierName(element);
98
98
  return {
99
- id: name ? (provisionIdsByName.get(name) ?? null) : null,
99
+ id: name ? (resourceIdsByName.get(name) ?? null) : null,
100
100
  name,
101
101
  };
102
102
  }
@@ -105,39 +105,113 @@ const extractDeclaredProvision = (
105
105
  return { id: getStringValue(element), name: null };
106
106
  }
107
107
 
108
- if (isInlineProvisionCall(element)) {
108
+ if (isInlineResourceCall(element)) {
109
109
  return { id: extractFirstStringArg(element), name: null };
110
110
  }
111
111
 
112
112
  return null;
113
113
  };
114
114
 
115
- /** Extract declared provisions from a trail config's `provisions` array. */
116
- const extractDeclaredProvisions = (
115
+ /** Extract declared resources from a trail config's `resources` array. */
116
+ const extractDeclaredResources = (
117
117
  config: AstNode,
118
- provisionIdsByName: ReadonlyMap<string, string>
119
- ): readonly DeclaredProvision[] =>
120
- getProvisionElements(config).flatMap((element) => {
121
- const provision = extractDeclaredProvision(element, provisionIdsByName);
122
- return provision ? [provision] : [];
118
+ resourceIdsByName: ReadonlyMap<string, string>
119
+ ): readonly DeclaredResource[] =>
120
+ getResourceElements(config).flatMap((element) => {
121
+ const resource = extractDeclaredResource(element, resourceIdsByName);
122
+ return resource ? [resource] : [];
123
123
  });
124
124
 
125
125
  // ---------------------------------------------------------------------------
126
- // Called service extraction
126
+ // Called resource extraction
127
127
  // ---------------------------------------------------------------------------
128
128
 
129
- /** Extract the second parameter name from a blaze function node. */
130
- const extractContextParamName = (blazeBody: AstNode): string | null => {
129
+ /** Extract the raw second parameter node from a blaze function. */
130
+ const extractContextParamNode = (blazeBody: AstNode): AstNode | null => {
131
131
  const params = blazeBody['params'] as readonly AstNode[] | undefined;
132
132
  if (!params || params.length < 2) {
133
133
  return null;
134
134
  }
135
- return identifierName(params[1]);
135
+ return params[1] ?? null;
136
+ };
137
+
138
+ /**
139
+ * Extract the second parameter name from a blaze function node.
140
+ *
141
+ * Returns null when the parameter is not a plain Identifier (e.g. when the
142
+ * author destructures `{ resource }` in the parameter list). Parameter-level
143
+ * destructuring is handled separately by `collectParamResourceAliases`.
144
+ *
145
+ * Also handles defaulted parameters like `(input, ctx = fallback) => ...`
146
+ * (AssignmentPattern whose `.left` is the Identifier). Without this, valid
147
+ * signatures would silently drop out of ctx-access analysis.
148
+ */
149
+ const extractContextParamName = (blazeBody: AstNode): string | null => {
150
+ const param = extractContextParamNode(blazeBody);
151
+ if (!param) {
152
+ return null;
153
+ }
154
+ if (param.type === 'AssignmentPattern') {
155
+ const { left } = param as unknown as { left?: AstNode };
156
+ return identifierName(left);
157
+ }
158
+ return identifierName(param);
159
+ };
160
+
161
+ /** Extract the alias name from a Property node whose key is `resource`. */
162
+ const extractResourceAlias = (property: AstNode): string | null => {
163
+ if (property.type !== 'Property') {
164
+ return null;
165
+ }
166
+ const keyName = identifierName(
167
+ (property as unknown as { key?: AstNode }).key
168
+ );
169
+ if (keyName !== 'resource') {
170
+ return null;
171
+ }
172
+ return (
173
+ identifierName((property as unknown as { value?: AstNode }).value) ??
174
+ keyName
175
+ );
136
176
  };
137
177
 
138
- /** Build the set of context parameter names to match against. */
178
+ /**
179
+ * Collect `resource` aliases bound via parameter-level destructuring.
180
+ *
181
+ * Recognizes `(input, { resource }) => ...` and `(input, { resource: r }) => ...`.
182
+ * When the blaze author destructures in the parameter list, there is no
183
+ * enclosing `ctx` identifier to track — we seed the resource alias set directly
184
+ * from the ObjectPattern in `params[1]`.
185
+ */
186
+ const collectParamResourceAliases = (body: AstNode): ReadonlySet<string> => {
187
+ const param = extractContextParamNode(body);
188
+ if (!param || param.type !== 'ObjectPattern') {
189
+ return new Set();
190
+ }
191
+ const aliases = new Set<string>();
192
+ const properties = param['properties'] as readonly AstNode[] | undefined;
193
+ for (const property of properties ?? []) {
194
+ const alias = extractResourceAlias(property);
195
+ if (alias) {
196
+ aliases.add(alias);
197
+ }
198
+ }
199
+ return aliases;
200
+ };
201
+
202
+ /**
203
+ * Build the set of context parameter names to match against.
204
+ *
205
+ * Returns ONLY the actual second-parameter name from the blaze signature.
206
+ * No seeded defaults: if the blaze has no second parameter, the returned set
207
+ * is empty and no `ctx.resource(...)` / `context.resource(...)` calls are
208
+ * tracked for that blaze. An unrelated closure-scoped `ctx` identifier is not
209
+ * the trail context and must not be treated as one.
210
+ *
211
+ * Mirrors `fires-declarations.ts` `buildCtxNames` for the same reason.
212
+ */
139
213
  const buildCtxNames = (body: AstNode): ReadonlySet<string> => {
140
- const ctxNames = new Set(['ctx', 'context']);
214
+ const ctxNames = new Set<string>();
141
215
  const paramName = extractContextParamName(body);
142
216
  if (paramName) {
143
217
  ctxNames.add(paramName);
@@ -189,63 +263,63 @@ const extractFromCallName = (
189
263
  : null;
190
264
  };
191
265
 
192
- /** Check if a callee is a member-style `ctx.provision(...)` call. */
193
- const isMemberProvisionCall = (
266
+ /** Check if a callee is a member-style `ctx.resource(...)` call. */
267
+ const isMemberResourceCall = (
194
268
  callee: AstNode,
195
269
  ctxNames: ReadonlySet<string>
196
270
  ): boolean => {
197
271
  const pair = extractMemberPair(callee);
198
- return !!pair && ctxNames.has(pair.objName) && pair.propName === 'provision';
272
+ return !!pair && ctxNames.has(pair.objName) && pair.propName === 'resource';
199
273
  };
200
274
 
201
- /** Extract `ctx.provision(db)` and destructured `provision(db)` lookup names. */
202
- const extractLookupProvisionName = (
275
+ /** Extract `ctx.resource(db)` and destructured `resource(db)` lookup names. */
276
+ const extractLookupResourceName = (
203
277
  node: AstNode,
204
278
  ctxNames: ReadonlySet<string>,
205
- provisionAliases: ReadonlySet<string>
279
+ resourceAliases: ReadonlySet<string>
206
280
  ): string | null => {
207
281
  const callee = extractCallCallee(node);
208
282
  if (!callee) {
209
283
  return null;
210
284
  }
211
285
 
212
- if (isMemberProvisionCall(callee, ctxNames)) {
286
+ if (isMemberResourceCall(callee, ctxNames)) {
213
287
  return extractFirstIdentifierArg(node);
214
288
  }
215
289
 
216
- if (provisionAliases.has(identifierName(callee) ?? '')) {
290
+ if (resourceAliases.has(identifierName(callee) ?? '')) {
217
291
  return extractFirstIdentifierArg(node);
218
292
  }
219
293
 
220
294
  return null;
221
295
  };
222
296
 
223
- /** Extract `ctx.provision('id')` and destructured `provision('id')` lookup IDs. */
224
- const extractLookupProvisionId = (
297
+ /** Extract `ctx.resource('id')` and destructured `resource('id')` lookup IDs. */
298
+ const extractLookupResourceId = (
225
299
  node: AstNode,
226
300
  ctxNames: ReadonlySet<string>,
227
- provisionAliases: ReadonlySet<string>
301
+ resourceAliases: ReadonlySet<string>
228
302
  ): string | null => {
229
303
  const callee = extractCallCallee(node);
230
304
  if (!callee) {
231
305
  return null;
232
306
  }
233
307
 
234
- if (isMemberProvisionCall(callee, ctxNames)) {
308
+ if (isMemberResourceCall(callee, ctxNames)) {
235
309
  return extractFirstStringArg(node);
236
310
  }
237
311
 
238
312
  const calleeName = identifierName(callee);
239
313
  const args = node['arguments'] as readonly AstNode[] | undefined;
240
- if (calleeName && provisionAliases.has(calleeName) && args?.length === 1) {
314
+ if (calleeName && resourceAliases.has(calleeName) && args?.length === 1) {
241
315
  return extractFirstStringArg(node);
242
316
  }
243
317
 
244
318
  return null;
245
319
  };
246
320
 
247
- /** Collect local aliases for the provision accessor (e.g. `const { provision } = ctx`). */
248
- const collectProvisionAliases = (
321
+ /** Collect local aliases for the resource accessor (e.g. `const { resource } = ctx`). */
322
+ const collectResourceAliases = (
249
323
  body: AstNode,
250
324
  ctxNames: ReadonlySet<string>
251
325
  ): ReadonlySet<string> => {
@@ -267,7 +341,7 @@ const collectProvisionAliases = (
267
341
  const keyName = identifierName(
268
342
  (property as unknown as { key?: AstNode }).key
269
343
  );
270
- if (keyName !== 'provision') {
344
+ if (keyName !== 'resource') {
271
345
  return [];
272
346
  }
273
347
 
@@ -300,15 +374,17 @@ const collectProvisionAliases = (
300
374
  return aliases;
301
375
  };
302
376
 
303
- /** Walk blaze bodies and collect provision access that can be resolved statically. */
304
- const extractCalledProvisions = (config: AstNode): CalledProvisions => {
377
+ /** Walk blaze bodies and collect resource access that can be resolved statically. */
378
+ const extractCalledResources = (config: AstNode): CalledResources => {
305
379
  const fromNames = new Set<string>();
306
380
  const lookupIds = new Set<string>();
307
381
  const lookupNames = new Set<string>();
308
382
 
309
383
  for (const body of findBlazeBodies(config)) {
310
384
  const ctxNames = buildCtxNames(body);
311
- const provisionAliases = collectProvisionAliases(body, ctxNames);
385
+ const paramAliases = collectParamResourceAliases(body);
386
+ const bodyAliases = collectResourceAliases(body, ctxNames);
387
+ const resourceAliases = new Set([...paramAliases, ...bodyAliases]);
312
388
 
313
389
  walkScope(body, (node) => {
314
390
  const fromName = extractFromCallName(node, ctxNames);
@@ -316,19 +392,15 @@ const extractCalledProvisions = (config: AstNode): CalledProvisions => {
316
392
  fromNames.add(fromName);
317
393
  }
318
394
 
319
- const lookupId = extractLookupProvisionId(
320
- node,
321
- ctxNames,
322
- provisionAliases
323
- );
395
+ const lookupId = extractLookupResourceId(node, ctxNames, resourceAliases);
324
396
  if (lookupId) {
325
397
  lookupIds.add(lookupId);
326
398
  }
327
399
 
328
- const lookupName = extractLookupProvisionName(
400
+ const lookupName = extractLookupResourceName(
329
401
  node,
330
402
  ctxNames,
331
- provisionAliases
403
+ resourceAliases
332
404
  );
333
405
  if (lookupName) {
334
406
  lookupNames.add(lookupName);
@@ -343,58 +415,58 @@ const extractCalledProvisions = (config: AstNode): CalledProvisions => {
343
415
  // Diagnostics
344
416
  // ---------------------------------------------------------------------------
345
417
 
346
- const renderDeclaredProvision = (provision: DeclaredProvision): string =>
347
- provision.name ?? provision.id ?? '<unknown>';
418
+ const renderDeclaredResource = (resource: DeclaredResource): string =>
419
+ resource.name ?? resource.id ?? '<unknown>';
348
420
 
349
421
  const buildUndeclaredFromDiagnostic = (
350
422
  trailId: string,
351
- provisionName: string,
423
+ resourceName: string,
352
424
  filePath: string,
353
425
  line: number
354
426
  ): WardenDiagnostic => ({
355
427
  filePath,
356
428
  line,
357
- message: `Trail "${trailId}": ${provisionName}.from(ctx) called but '${provisionName}' is not declared in provisions`,
358
- rule: 'provision-declarations',
429
+ message: `Trail "${trailId}": ${resourceName}.from(ctx) called but '${resourceName}' is not declared in resources`,
430
+ rule: 'resource-declarations',
359
431
  severity: 'error',
360
432
  });
361
433
 
362
434
  const buildUndeclaredLookupDiagnostic = (
363
435
  trailId: string,
364
- provisionId: string,
436
+ resourceId: string,
365
437
  filePath: string,
366
438
  line: number
367
439
  ): WardenDiagnostic => ({
368
440
  filePath,
369
441
  line,
370
- message: `Trail "${trailId}": ctx.provision('${provisionId}') called but '${provisionId}' is not declared in provisions`,
371
- rule: 'provision-declarations',
442
+ message: `Trail "${trailId}": ctx.resource('${resourceId}') called but '${resourceId}' is not declared in resources`,
443
+ rule: 'resource-declarations',
372
444
  severity: 'error',
373
445
  });
374
446
 
375
447
  const buildUndeclaredLookupNameDiagnostic = (
376
448
  trailId: string,
377
- provisionName: string,
449
+ resourceName: string,
378
450
  filePath: string,
379
451
  line: number
380
452
  ): WardenDiagnostic => ({
381
453
  filePath,
382
454
  line,
383
- message: `Trail "${trailId}": ctx.provision(${provisionName}) called but '${provisionName}' is not declared in provisions`,
384
- rule: 'provision-declarations',
455
+ message: `Trail "${trailId}": ctx.resource(${resourceName}) called but '${resourceName}' is not declared in resources`,
456
+ rule: 'resource-declarations',
385
457
  severity: 'error',
386
458
  });
387
459
 
388
460
  const buildUnusedDiagnostic = (
389
461
  trailId: string,
390
- declaredProvision: DeclaredProvision,
462
+ declaredResource: DeclaredResource,
391
463
  filePath: string,
392
464
  line: number
393
465
  ): WardenDiagnostic => ({
394
466
  filePath,
395
467
  line,
396
- message: `Trail "${trailId}": '${renderDeclaredProvision(declaredProvision)}' declared in provisions but never used`,
397
- rule: 'provision-declarations',
468
+ message: `Trail "${trailId}": '${renderDeclaredResource(declaredResource)}' declared in resources but never used`,
469
+ rule: 'resource-declarations',
398
470
  severity: 'warn',
399
471
  });
400
472
 
@@ -402,21 +474,21 @@ const buildUnusedDiagnostic = (
402
474
  // Comparison
403
475
  // ---------------------------------------------------------------------------
404
476
 
405
- const provisionWasUsed = (
406
- declaredProvision: DeclaredProvision,
407
- calledProvisions: CalledProvisions
477
+ const resourceWasUsed = (
478
+ declaredResource: DeclaredResource,
479
+ calledResources: CalledResources
408
480
  ): boolean => {
409
481
  if (
410
- declaredProvision.name &&
411
- (calledProvisions.fromNames.has(declaredProvision.name) ||
412
- calledProvisions.lookupNames.has(declaredProvision.name))
482
+ declaredResource.name &&
483
+ (calledResources.fromNames.has(declaredResource.name) ||
484
+ calledResources.lookupNames.has(declaredResource.name))
413
485
  ) {
414
486
  return true;
415
487
  }
416
488
 
417
489
  if (
418
- declaredProvision.id &&
419
- calledProvisions.lookupIds.has(declaredProvision.id)
490
+ declaredResource.id &&
491
+ calledResources.lookupIds.has(declaredResource.id)
420
492
  ) {
421
493
  return true;
422
494
  }
@@ -425,35 +497,33 @@ const provisionWasUsed = (
425
497
  };
426
498
 
427
499
  const buildDeclaredNames = (
428
- declaredProvisions: readonly DeclaredProvision[]
500
+ declaredResources: readonly DeclaredResource[]
429
501
  ): ReadonlySet<string> =>
430
502
  new Set(
431
- declaredProvisions.flatMap((provision) =>
432
- provision.name ? [provision.name] : []
503
+ declaredResources.flatMap((resource) =>
504
+ resource.name ? [resource.name] : []
433
505
  )
434
506
  );
435
507
 
436
508
  const buildDeclaredIds = (
437
- declaredProvisions: readonly DeclaredProvision[]
509
+ declaredResources: readonly DeclaredResource[]
438
510
  ): ReadonlySet<string> =>
439
511
  new Set(
440
- declaredProvisions.flatMap((provision) =>
441
- provision.id ? [provision.id] : []
442
- )
512
+ declaredResources.flatMap((resource) => (resource.id ? [resource.id] : []))
443
513
  );
444
514
 
445
515
  const reportUndeclaredFromCalls = (
446
516
  trailId: string,
447
517
  filePath: string,
448
518
  line: number,
449
- calledProvisions: CalledProvisions,
519
+ calledResources: CalledResources,
450
520
  declaredNames: ReadonlySet<string>,
451
521
  diagnostics: WardenDiagnostic[]
452
522
  ): void => {
453
- for (const provisionName of calledProvisions.fromNames) {
454
- if (!declaredNames.has(provisionName)) {
523
+ for (const resourceName of calledResources.fromNames) {
524
+ if (!declaredNames.has(resourceName)) {
455
525
  diagnostics.push(
456
- buildUndeclaredFromDiagnostic(trailId, provisionName, filePath, line)
526
+ buildUndeclaredFromDiagnostic(trailId, resourceName, filePath, line)
457
527
  );
458
528
  }
459
529
  }
@@ -463,19 +533,19 @@ const reportUndeclaredLookupCalls = (
463
533
  trailId: string,
464
534
  filePath: string,
465
535
  line: number,
466
- calledProvisions: CalledProvisions,
536
+ calledResources: CalledResources,
467
537
  declaredIds: ReadonlySet<string>,
468
538
  declaredNames: ReadonlySet<string>,
469
539
  diagnostics: WardenDiagnostic[]
470
540
  ): void => {
471
- for (const provisionName of calledProvisions.lookupNames) {
472
- // Name-based lookup checks remain reliable even when an imported provision ID
541
+ for (const resourceName of calledResources.lookupNames) {
542
+ // Name-based lookup checks remain reliable even when an imported resource ID
473
543
  // cannot be resolved locally.
474
- if (!declaredNames.has(provisionName)) {
544
+ if (!declaredNames.has(resourceName)) {
475
545
  diagnostics.push(
476
546
  buildUndeclaredLookupNameDiagnostic(
477
547
  trailId,
478
- provisionName,
548
+ resourceName,
479
549
  filePath,
480
550
  line
481
551
  )
@@ -483,10 +553,10 @@ const reportUndeclaredLookupCalls = (
483
553
  }
484
554
  }
485
555
 
486
- for (const provisionId of calledProvisions.lookupIds) {
487
- if (!declaredIds.has(provisionId)) {
556
+ for (const resourceId of calledResources.lookupIds) {
557
+ if (!declaredIds.has(resourceId)) {
488
558
  diagnostics.push(
489
- buildUndeclaredLookupDiagnostic(trailId, provisionId, filePath, line)
559
+ buildUndeclaredLookupDiagnostic(trailId, resourceId, filePath, line)
490
560
  );
491
561
  }
492
562
  }
@@ -496,54 +566,54 @@ const reportUnusedDeclarations = (
496
566
  trailId: string,
497
567
  filePath: string,
498
568
  line: number,
499
- declaredProvisions: readonly DeclaredProvision[],
500
- calledProvisions: CalledProvisions,
569
+ declaredResources: readonly DeclaredResource[],
570
+ calledResources: CalledResources,
501
571
  diagnostics: WardenDiagnostic[]
502
572
  ): void => {
503
- for (const declaredProvision of declaredProvisions) {
504
- if (provisionWasUsed(declaredProvision, calledProvisions)) {
573
+ for (const declaredResource of declaredResources) {
574
+ if (resourceWasUsed(declaredResource, calledResources)) {
505
575
  continue;
506
576
  }
507
577
 
508
- if (declaredProvision.name && declaredProvision.id === null) {
578
+ if (declaredResource.name && declaredResource.id === null) {
509
579
  continue;
510
580
  }
511
581
 
512
582
  diagnostics.push(
513
- buildUnusedDiagnostic(trailId, declaredProvision, filePath, line)
583
+ buildUnusedDiagnostic(trailId, declaredResource, filePath, line)
514
584
  );
515
585
  }
516
586
  };
517
587
 
518
- const hasNoProvisionActivity = (
519
- declaredProvisions: readonly DeclaredProvision[],
520
- calledProvisions: CalledProvisions
588
+ const hasNoResourceActivity = (
589
+ declaredResources: readonly DeclaredResource[],
590
+ calledResources: CalledResources
521
591
  ): boolean =>
522
- declaredProvisions.length === 0 &&
523
- calledProvisions.fromNames.size === 0 &&
524
- calledProvisions.lookupIds.size === 0 &&
525
- calledProvisions.lookupNames.size === 0;
592
+ declaredResources.length === 0 &&
593
+ calledResources.fromNames.size === 0 &&
594
+ calledResources.lookupIds.size === 0 &&
595
+ calledResources.lookupNames.size === 0;
526
596
 
527
597
  const analyzeTrailServices = (
528
598
  def: { config: AstNode; start: number },
529
599
  sourceCode: string,
530
- provisionIdsByName: ReadonlyMap<string, string>
600
+ resourceIdsByName: ReadonlyMap<string, string>
531
601
  ): {
532
- readonly calledProvisions: CalledProvisions;
602
+ readonly calledResources: CalledResources;
533
603
  readonly declaredIds: ReadonlySet<string>;
534
604
  readonly declaredNames: ReadonlySet<string>;
535
- readonly declaredProvisions: readonly DeclaredProvision[];
605
+ readonly declaredResources: readonly DeclaredResource[];
536
606
  readonly line: number;
537
607
  } => {
538
- const declaredProvisions = extractDeclaredProvisions(
608
+ const declaredResources = extractDeclaredResources(
539
609
  def.config,
540
- provisionIdsByName
610
+ resourceIdsByName
541
611
  );
542
612
  return {
543
- calledProvisions: extractCalledProvisions(def.config),
544
- declaredIds: buildDeclaredIds(declaredProvisions),
545
- declaredNames: buildDeclaredNames(declaredProvisions),
546
- declaredProvisions,
613
+ calledResources: extractCalledResources(def.config),
614
+ declaredIds: buildDeclaredIds(declaredResources),
615
+ declaredNames: buildDeclaredNames(declaredResources),
616
+ declaredResources,
547
617
  line: offsetToLine(sourceCode, def.start),
548
618
  };
549
619
  };
@@ -552,18 +622,18 @@ const checkTrailDefinition = (
552
622
  def: { id: string; config: AstNode; start: number },
553
623
  filePath: string,
554
624
  sourceCode: string,
555
- provisionIdsByName: ReadonlyMap<string, string>,
625
+ resourceIdsByName: ReadonlyMap<string, string>,
556
626
  diagnostics: WardenDiagnostic[]
557
627
  ): void => {
558
628
  const {
559
- calledProvisions,
629
+ calledResources,
560
630
  declaredIds,
561
631
  declaredNames,
562
- declaredProvisions,
632
+ declaredResources,
563
633
  line,
564
- } = analyzeTrailServices(def, sourceCode, provisionIdsByName);
634
+ } = analyzeTrailServices(def, sourceCode, resourceIdsByName);
565
635
 
566
- if (hasNoProvisionActivity(declaredProvisions, calledProvisions)) {
636
+ if (hasNoResourceActivity(declaredResources, calledResources)) {
567
637
  return;
568
638
  }
569
639
 
@@ -571,7 +641,7 @@ const checkTrailDefinition = (
571
641
  def.id,
572
642
  filePath,
573
643
  line,
574
- calledProvisions,
644
+ calledResources,
575
645
  declaredNames,
576
646
  diagnostics
577
647
  );
@@ -579,7 +649,7 @@ const checkTrailDefinition = (
579
649
  def.id,
580
650
  filePath,
581
651
  line,
582
- calledProvisions,
652
+ calledResources,
583
653
  declaredIds,
584
654
  declaredNames,
585
655
  diagnostics
@@ -588,8 +658,8 @@ const checkTrailDefinition = (
588
658
  def.id,
589
659
  filePath,
590
660
  line,
591
- declaredProvisions,
592
- calledProvisions,
661
+ declaredResources,
662
+ calledResources,
593
663
  diagnostics
594
664
  );
595
665
  };
@@ -599,9 +669,9 @@ const checkTrailDefinition = (
599
669
  // ---------------------------------------------------------------------------
600
670
 
601
671
  /**
602
- * Validates that provision access aligns with declared `provisions` arrays.
672
+ * Validates that resource access aligns with declared `resources` arrays.
603
673
  */
604
- export const provisionDeclarations: WardenRule = {
674
+ export const resourceDeclarations: WardenRule = {
605
675
  check(sourceCode: string, filePath: string): readonly WardenDiagnostic[] {
606
676
  if (isTestFile(filePath)) {
607
677
  return [];
@@ -613,14 +683,14 @@ export const provisionDeclarations: WardenRule = {
613
683
  }
614
684
 
615
685
  const diagnostics: WardenDiagnostic[] = [];
616
- const provisionIdsByName = collectNamedProvisionIds(ast);
686
+ const resourceIdsByName = collectNamedResourceIds(ast);
617
687
 
618
688
  for (const def of findTrailDefinitions(ast)) {
619
689
  checkTrailDefinition(
620
690
  def,
621
691
  filePath,
622
692
  sourceCode,
623
- provisionIdsByName,
693
+ resourceIdsByName,
624
694
  diagnostics
625
695
  );
626
696
  }
@@ -628,7 +698,7 @@ export const provisionDeclarations: WardenRule = {
628
698
  return diagnostics;
629
699
  },
630
700
  description:
631
- 'Ensure provision.from(ctx) and ctx.provision() calls match the declared provisions array in trail definitions.',
632
- name: 'provision-declarations',
701
+ 'Ensure resource.from(ctx) and ctx.resource() calls match the declared resources array in trail definitions.',
702
+ name: 'resource-declarations',
633
703
  severity: 'error',
634
704
  };