@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,6 +1,8 @@
1
+ import { isDraftId } from '@ontrails/core';
2
+
1
3
  import {
2
- collectNamedProvisionIds,
3
- collectProvisionDefinitionIds,
4
+ collectNamedResourceIds,
5
+ collectResourceDefinitionIds,
4
6
  extractFirstStringArg,
5
7
  findConfigProperty,
6
8
  findTrailDefinitions,
@@ -18,18 +20,18 @@ import type {
18
20
  WardenDiagnostic,
19
21
  } from './types.js';
20
22
 
21
- const isProvisionCall = (node: AstNode): boolean =>
23
+ const isResourceCall = (node: AstNode): boolean =>
22
24
  node.type === 'CallExpression' &&
23
25
  identifierName((node as unknown as { callee?: AstNode }).callee) ===
24
- 'provision';
26
+ 'resource';
25
27
 
26
- const getProvisionElements = (config: AstNode): readonly AstNode[] => {
27
- const provisionsProp = findConfigProperty(config, 'provisions');
28
- if (!provisionsProp) {
28
+ const getResourceElements = (config: AstNode): readonly AstNode[] => {
29
+ const resourcesProp = findConfigProperty(config, 'resources');
30
+ if (!resourcesProp) {
29
31
  return [];
30
32
  }
31
33
 
32
- const arrayNode = provisionsProp.value;
34
+ const arrayNode = resourcesProp.value;
33
35
  if (!arrayNode || (arrayNode as AstNode).type !== 'ArrayExpression') {
34
36
  return [];
35
37
  }
@@ -40,93 +42,93 @@ const getProvisionElements = (config: AstNode): readonly AstNode[] => {
40
42
  return elements ?? [];
41
43
  };
42
44
 
43
- const extractDeclaredProvisionId = (
45
+ const extractDeclaredResourceId = (
44
46
  element: AstNode,
45
- provisionIdsByName: ReadonlyMap<string, string>
47
+ resourceIdsByName: ReadonlyMap<string, string>
46
48
  ): string | null => {
47
49
  if (element.type === 'Identifier') {
48
50
  const name = identifierName(element);
49
- return name ? (provisionIdsByName.get(name) ?? null) : null;
51
+ return name ? (resourceIdsByName.get(name) ?? null) : null;
50
52
  }
51
53
 
52
54
  if (isStringLiteral(element)) {
53
55
  return getStringValue(element);
54
56
  }
55
57
 
56
- return isProvisionCall(element) ? extractFirstStringArg(element) : null;
58
+ return isResourceCall(element) ? extractFirstStringArg(element) : null;
57
59
  };
58
60
 
59
- const extractDeclaredProvisionIds = (
61
+ const extractDeclaredResourceIds = (
60
62
  config: AstNode,
61
- provisionIdsByName: ReadonlyMap<string, string>
63
+ resourceIdsByName: ReadonlyMap<string, string>
62
64
  ): readonly string[] => [
63
65
  ...new Set(
64
- getProvisionElements(config).flatMap((element) => {
65
- const id = extractDeclaredProvisionId(element, provisionIdsByName);
66
+ getResourceElements(config).flatMap((element) => {
67
+ const id = extractDeclaredResourceId(element, resourceIdsByName);
66
68
  return id ? [id] : [];
67
69
  })
68
70
  ),
69
71
  ];
70
72
 
71
- const buildMissingProvisionDiagnostic = (
73
+ const buildMissingResourceDiagnostic = (
72
74
  trailId: string,
73
- provisionId: string,
75
+ resourceId: string,
74
76
  filePath: string,
75
77
  line: number
76
78
  ): WardenDiagnostic => ({
77
79
  filePath,
78
80
  line,
79
- message: `Trail "${trailId}" declares provision "${provisionId}" which is not defined in the project.`,
80
- rule: 'provision-exists',
81
+ message: `Trail "${trailId}" declares resource "${resourceId}" which is not defined in the project.`,
82
+ rule: 'resource-exists',
81
83
  severity: 'error',
82
84
  });
83
85
 
84
- const reportMissingProvisions = (
86
+ const reportMissingResources = (
85
87
  def: { id: string; config: AstNode; start: number },
86
88
  sourceCode: string,
87
- provisionIdsByName: ReadonlyMap<string, string>,
89
+ resourceIdsByName: ReadonlyMap<string, string>,
88
90
  filePath: string,
89
- knownProvisionIds: ReadonlySet<string>,
91
+ knownResourceIds: ReadonlySet<string>,
90
92
  diagnostics: WardenDiagnostic[]
91
93
  ): void => {
92
94
  const line = offsetToLine(sourceCode, def.start);
93
- for (const provisionId of extractDeclaredProvisionIds(
95
+ for (const resourceId of extractDeclaredResourceIds(
94
96
  def.config,
95
- provisionIdsByName
97
+ resourceIdsByName
96
98
  )) {
97
- if (!knownProvisionIds.has(provisionId)) {
99
+ if (!knownResourceIds.has(resourceId) && !isDraftId(resourceId)) {
98
100
  diagnostics.push(
99
- buildMissingProvisionDiagnostic(def.id, provisionId, filePath, line)
101
+ buildMissingResourceDiagnostic(def.id, resourceId, filePath, line)
100
102
  );
101
103
  }
102
104
  }
103
105
  };
104
106
 
105
- const buildProvisionDiagnostics = (
107
+ const buildResourceDiagnostics = (
106
108
  ast: AstNode,
107
109
  sourceCode: string,
108
110
  filePath: string,
109
- knownProvisionIds: ReadonlySet<string>
111
+ knownResourceIds: ReadonlySet<string>
110
112
  ): readonly WardenDiagnostic[] => {
111
113
  const diagnostics: WardenDiagnostic[] = [];
112
- const provisionIdsByName = collectNamedProvisionIds(ast);
114
+ const resourceIdsByName = collectNamedResourceIds(ast);
113
115
  for (const def of findTrailDefinitions(ast)) {
114
- reportMissingProvisions(
116
+ reportMissingResources(
115
117
  def,
116
118
  sourceCode,
117
- provisionIdsByName,
119
+ resourceIdsByName,
118
120
  filePath,
119
- knownProvisionIds,
121
+ knownResourceIds,
120
122
  diagnostics
121
123
  );
122
124
  }
123
125
  return diagnostics;
124
126
  };
125
127
 
126
- const checkProvisionsExist = (
128
+ const checkResourcesExist = (
127
129
  sourceCode: string,
128
130
  filePath: string,
129
- knownProvisionIds: ReadonlySet<string>
131
+ knownResourceIds: ReadonlySet<string>
130
132
  ): readonly WardenDiagnostic[] => {
131
133
  if (isTestFile(filePath)) {
132
134
  return [];
@@ -137,27 +139,22 @@ const checkProvisionsExist = (
137
139
  return [];
138
140
  }
139
141
 
140
- return buildProvisionDiagnostics(
141
- ast,
142
- sourceCode,
143
- filePath,
144
- knownProvisionIds
145
- );
142
+ return buildResourceDiagnostics(ast, sourceCode, filePath, knownResourceIds);
146
143
  };
147
144
 
148
145
  /**
149
- * Checks that all declared provisions resolve to known provision definitions.
146
+ * Checks that all declared resources resolve to known resource definitions.
150
147
  */
151
- export const provisionExists: ProjectAwareWardenRule = {
148
+ export const resourceExists: ProjectAwareWardenRule = {
152
149
  check(sourceCode: string, filePath: string): readonly WardenDiagnostic[] {
153
150
  const ast = parse(filePath, sourceCode);
154
151
  if (!ast) {
155
152
  return [];
156
153
  }
157
- return checkProvisionsExist(
154
+ return checkResourcesExist(
158
155
  sourceCode,
159
156
  filePath,
160
- collectProvisionDefinitionIds(ast)
157
+ collectResourceDefinitionIds(ast)
161
158
  );
162
159
  },
163
160
  checkWithContext(
@@ -166,17 +163,17 @@ export const provisionExists: ProjectAwareWardenRule = {
166
163
  context: ProjectContext
167
164
  ): readonly WardenDiagnostic[] {
168
165
  const ast = parse(filePath, sourceCode);
169
- const localProvisionIds = ast
170
- ? collectProvisionDefinitionIds(ast)
166
+ const localResourceIds = ast
167
+ ? collectResourceDefinitionIds(ast)
171
168
  : new Set<string>();
172
- return checkProvisionsExist(
169
+ return checkResourcesExist(
173
170
  sourceCode,
174
171
  filePath,
175
- context.knownProvisionIds ?? localProvisionIds
172
+ context.knownResourceIds ?? localResourceIds
176
173
  );
177
174
  },
178
175
  description:
179
- 'Ensure every provision declared on a trail resolves to a known provision definition.',
180
- name: 'provision-exists',
176
+ 'Ensure every resource declared on a trail resolves to a known resource definition.',
177
+ name: 'resource-exists',
181
178
  severity: 'error',
182
179
  };
@@ -0,0 +1,65 @@
1
+ import {
2
+ extractFirstStringArg,
3
+ identifierName,
4
+ offsetToLine,
5
+ parse,
6
+ walk,
7
+ } from './ast.js';
8
+ import type { AstNode } from './ast.js';
9
+ import { isTestFile } from './scan.js';
10
+ import type { WardenDiagnostic, WardenRule } from './types.js';
11
+
12
+ const isResourceCall = (node: AstNode): boolean =>
13
+ node.type === 'CallExpression' &&
14
+ identifierName((node as unknown as { callee?: AstNode }).callee) ===
15
+ 'resource';
16
+
17
+ const buildDiagnostic = (
18
+ resourceId: string,
19
+ filePath: string,
20
+ line: number
21
+ ): WardenDiagnostic => ({
22
+ filePath,
23
+ line,
24
+ message: `Resource "${resourceId}" is invalid because resource ids may not contain ":".`,
25
+ rule: 'resource-id-grammar',
26
+ severity: 'error',
27
+ });
28
+
29
+ export const resourceIdGrammar: WardenRule = {
30
+ check(sourceCode: string, filePath: string): readonly WardenDiagnostic[] {
31
+ if (isTestFile(filePath)) {
32
+ return [];
33
+ }
34
+
35
+ const ast = parse(filePath, sourceCode);
36
+ if (!ast) {
37
+ return [];
38
+ }
39
+
40
+ const diagnostics: WardenDiagnostic[] = [];
41
+ walk(ast, (node) => {
42
+ if (!isResourceCall(node)) {
43
+ return;
44
+ }
45
+
46
+ const resourceId = extractFirstStringArg(node);
47
+ if (!resourceId || !resourceId.includes(':')) {
48
+ return;
49
+ }
50
+
51
+ diagnostics.push(
52
+ buildDiagnostic(
53
+ resourceId,
54
+ filePath,
55
+ offsetToLine(sourceCode, node.start)
56
+ )
57
+ );
58
+ });
59
+
60
+ return diagnostics;
61
+ },
62
+ description: 'Ensure resource ids do not contain the ":" scope separator.',
63
+ name: 'resource-id-grammar',
64
+ severity: 'error',
65
+ };
@@ -31,7 +31,11 @@ export interface SchemaFieldInfo {
31
31
  readonly required: boolean;
32
32
  }
33
33
 
34
- const TRAIL_LIKE_PATTERN = /\b(trail|event)\s*\(/g;
34
+ // Match `trail(...)` / `signal(...)` declaration sites, not method calls.
35
+ // The negative lookbehind excludes `foo.signal(...)`, `foo?.signal(...)`, and
36
+ // similar member-expression call sites (including optional chaining with
37
+ // whitespace) where `signal` / `trail` is a property name, not a factory.
38
+ const TRAIL_LIKE_PATTERN = /(?<![.?])\b(trail|signal)\s*\(/g;
35
39
 
36
40
  const PROPERTY_PATTERN =
37
41
  /^(?:readonly\s+)?(?:(["'`])([^"'`]+)\1|([A-Za-z_$][\w$]*))\s*:\s*([\s\S]+)$/;
@@ -1,3 +1,5 @@
1
+ import type { Topo } from '@ontrails/core';
2
+
1
3
  /**
2
4
  * Severity level for warden diagnostics.
3
5
  */
@@ -43,12 +45,39 @@ export interface WardenRule {
43
45
  * Options for cross-file rules that need knowledge of all trail IDs in a project.
44
46
  */
45
47
  export interface ProjectContext {
48
+ /** All known contour names in the project. */
49
+ readonly knownContourIds?: ReadonlySet<string>;
50
+ /** Store table IDs used with the CRUD factory across the project. */
51
+ readonly crudTableIds?: ReadonlySet<string>;
46
52
  /** All known trail IDs in the project */
47
53
  readonly knownTrailIds: ReadonlySet<string>;
48
- /** All known provision IDs in the project */
49
- readonly knownProvisionIds?: ReadonlySet<string>;
50
- /** All trail IDs referenced as detour targets across the project */
51
- readonly detourTargetTrailIds?: ReadonlySet<string>;
54
+ /** Declared contour references keyed by source contour name. */
55
+ readonly contourReferencesByName?: ReadonlyMap<string, readonly string[]>;
56
+ /** All known resource IDs in the project */
57
+ readonly knownResourceIds?: ReadonlySet<string>;
58
+ /** All known signal IDs in the project */
59
+ readonly knownSignalIds?: ReadonlySet<string>;
60
+ /** All trail IDs referenced by declared crosses arrays across the project. */
61
+ readonly crossTargetTrailIds?: ReadonlySet<string>;
62
+ /** Signal IDs referenced by trail `on` arrays across the project. */
63
+ readonly onTargetSignalIds?: ReadonlySet<string>;
64
+ /** Store table IDs used with reconcile trails across the project. */
65
+ readonly reconcileTableIds?: ReadonlySet<string>;
66
+ /** Normalized trail intents by trail ID across the project. */
67
+ readonly trailIntentsById?: ReadonlyMap<string, 'destroy' | 'read' | 'write'>;
68
+ /**
69
+ * CRUD operation coverage per entity aggregated across the project.
70
+ *
71
+ * Keys are stable entity IDs (authored contour names, `imported:<local>`
72
+ * sentinels for contours imported from another module, or store-table IDs
73
+ * produced by `deriveStoreTableId`). Values are the set of CRUD operations
74
+ * (`create`, `read`, `update`, `delete`, `list`) observed for that entity.
75
+ *
76
+ * Enables cross-file completeness evaluation so one-file-per-operation
77
+ * layouts (e.g. separate `create.ts`, `read.ts`) do not trip file-scoped
78
+ * coverage warnings.
79
+ */
80
+ readonly crudCoverageByEntity?: ReadonlyMap<string, ReadonlySet<string>>;
52
81
  }
53
82
 
54
83
  /**
@@ -62,3 +91,27 @@ export interface ProjectAwareWardenRule extends WardenRule {
62
91
  context: ProjectContext
63
92
  ) => readonly WardenDiagnostic[];
64
93
  }
94
+
95
+ /**
96
+ * A topo-aware warden rule inspects the compiled runtime trail graph —
97
+ * actual `Trail` objects with resolved types, accessor shapes, detour
98
+ * declarations, `pattern` field values, and other runtime-only data that
99
+ * is unavailable to AST-based rules.
100
+ *
101
+ * Unlike `WardenRule` and `ProjectAwareWardenRule`, which analyze source
102
+ * code on a per-file basis, a `TopoAwareWardenRule` runs once per topo
103
+ * and returns diagnostics spanning the whole graph. A rule file must
104
+ * implement exactly one of the three rule kinds.
105
+ */
106
+ export interface TopoAwareWardenRule {
107
+ /** Unique rule identifier */
108
+ readonly name: string;
109
+ /** Default severity */
110
+ readonly severity: WardenSeverity;
111
+ /** Human-readable description of what the rule enforces */
112
+ readonly description: string;
113
+ /** Run the rule against the resolved topo and return any diagnostics */
114
+ readonly checkTopo: (
115
+ topo: Topo
116
+ ) => readonly WardenDiagnostic[] | Promise<readonly WardenDiagnostic[]>;
117
+ }