@endora-commerce/cli 0.100.0

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 (356) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +37 -0
  3. package/dist/bin/endora.d.ts +28 -0
  4. package/dist/bin/endora.d.ts.map +1 -0
  5. package/dist/bin/endora.js +926 -0
  6. package/dist/bin/endora.js.map +1 -0
  7. package/dist/check/estate.d.ts +189 -0
  8. package/dist/check/estate.d.ts.map +1 -0
  9. package/dist/check/estate.js +1037 -0
  10. package/dist/check/estate.js.map +1 -0
  11. package/dist/check/hosts.d.ts +25 -0
  12. package/dist/check/hosts.d.ts.map +1 -0
  13. package/dist/check/hosts.js +1347 -0
  14. package/dist/check/hosts.js.map +1 -0
  15. package/dist/check/index.d.ts +60 -0
  16. package/dist/check/index.d.ts.map +1 -0
  17. package/dist/check/index.js +111 -0
  18. package/dist/check/index.js.map +1 -0
  19. package/dist/check/layout.d.ts +136 -0
  20. package/dist/check/layout.d.ts.map +1 -0
  21. package/dist/check/layout.js +262 -0
  22. package/dist/check/layout.js.map +1 -0
  23. package/dist/check/ledger.d.ts +98 -0
  24. package/dist/check/ledger.d.ts.map +1 -0
  25. package/dist/check/ledger.js +173 -0
  26. package/dist/check/ledger.js.map +1 -0
  27. package/dist/check/peer-owners.d.ts +116 -0
  28. package/dist/check/peer-owners.d.ts.map +1 -0
  29. package/dist/check/peer-owners.js +225 -0
  30. package/dist/check/peer-owners.js.map +1 -0
  31. package/dist/check/report.d.ts +33 -0
  32. package/dist/check/report.d.ts.map +1 -0
  33. package/dist/check/report.js +107 -0
  34. package/dist/check/report.js.map +1 -0
  35. package/dist/check/run.d.ts +147 -0
  36. package/dist/check/run.d.ts.map +1 -0
  37. package/dist/check/run.js +111 -0
  38. package/dist/check/run.js.map +1 -0
  39. package/dist/checks.d.ts +17 -0
  40. package/dist/checks.d.ts.map +1 -0
  41. package/dist/checks.js +17 -0
  42. package/dist/checks.js.map +1 -0
  43. package/dist/dev/index.d.ts +83 -0
  44. package/dist/dev/index.d.ts.map +1 -0
  45. package/dist/dev/index.js +298 -0
  46. package/dist/dev/index.js.map +1 -0
  47. package/dist/generate/divergence.d.ts +38 -0
  48. package/dist/generate/divergence.d.ts.map +1 -0
  49. package/dist/generate/divergence.js +237 -0
  50. package/dist/generate/divergence.js.map +1 -0
  51. package/dist/generate/index.d.ts +90 -0
  52. package/dist/generate/index.d.ts.map +1 -0
  53. package/dist/generate/index.js +369 -0
  54. package/dist/generate/index.js.map +1 -0
  55. package/dist/index.d.ts +23 -0
  56. package/dist/index.d.ts.map +1 -0
  57. package/dist/index.js +35 -0
  58. package/dist/index.js.map +1 -0
  59. package/dist/inputs/declaration.d.ts +18 -0
  60. package/dist/inputs/declaration.d.ts.map +1 -0
  61. package/dist/inputs/declaration.js +64 -0
  62. package/dist/inputs/declaration.js.map +1 -0
  63. package/dist/inputs/env-file.d.ts +73 -0
  64. package/dist/inputs/env-file.d.ts.map +1 -0
  65. package/dist/inputs/env-file.js +134 -0
  66. package/dist/inputs/env-file.js.map +1 -0
  67. package/dist/inputs/prompt.d.ts +21 -0
  68. package/dist/inputs/prompt.d.ts.map +1 -0
  69. package/dist/inputs/prompt.js +59 -0
  70. package/dist/inputs/prompt.js.map +1 -0
  71. package/dist/inputs/resolve.d.ts +163 -0
  72. package/dist/inputs/resolve.d.ts.map +1 -0
  73. package/dist/inputs/resolve.js +290 -0
  74. package/dist/inputs/resolve.js.map +1 -0
  75. package/dist/install/host.d.ts +27 -0
  76. package/dist/install/host.d.ts.map +1 -0
  77. package/dist/install/host.js +90 -0
  78. package/dist/install/host.js.map +1 -0
  79. package/dist/install/index.d.ts +173 -0
  80. package/dist/install/index.d.ts.map +1 -0
  81. package/dist/install/index.js +793 -0
  82. package/dist/install/index.js.map +1 -0
  83. package/dist/install/wizard.d.ts +144 -0
  84. package/dist/install/wizard.d.ts.map +1 -0
  85. package/dist/install/wizard.js +362 -0
  86. package/dist/install/wizard.js.map +1 -0
  87. package/dist/lib/admin-artefacts.d.ts +70 -0
  88. package/dist/lib/admin-artefacts.d.ts.map +1 -0
  89. package/dist/lib/admin-artefacts.js +354 -0
  90. package/dist/lib/admin-artefacts.js.map +1 -0
  91. package/dist/lib/admin-surfaces.d.ts +298 -0
  92. package/dist/lib/admin-surfaces.d.ts.map +1 -0
  93. package/dist/lib/admin-surfaces.js +669 -0
  94. package/dist/lib/admin-surfaces.js.map +1 -0
  95. package/dist/lib/delegated-composer.d.ts +85 -0
  96. package/dist/lib/delegated-composer.d.ts.map +1 -0
  97. package/dist/lib/delegated-composer.js +241 -0
  98. package/dist/lib/delegated-composer.js.map +1 -0
  99. package/dist/lib/divergence-artefacts.d.ts +305 -0
  100. package/dist/lib/divergence-artefacts.d.ts.map +1 -0
  101. package/dist/lib/divergence-artefacts.js +828 -0
  102. package/dist/lib/divergence-artefacts.js.map +1 -0
  103. package/dist/lib/divergence.d.ts +337 -0
  104. package/dist/lib/divergence.d.ts.map +1 -0
  105. package/dist/lib/divergence.js +1005 -0
  106. package/dist/lib/divergence.js.map +1 -0
  107. package/dist/lib/docs-artefacts.d.ts +395 -0
  108. package/dist/lib/docs-artefacts.d.ts.map +1 -0
  109. package/dist/lib/docs-artefacts.js +781 -0
  110. package/dist/lib/docs-artefacts.js.map +1 -0
  111. package/dist/lib/emitted-exports.d.ts +21 -0
  112. package/dist/lib/emitted-exports.d.ts.map +1 -0
  113. package/dist/lib/emitted-exports.js +96 -0
  114. package/dist/lib/emitted-exports.js.map +1 -0
  115. package/dist/lib/emitted-freshness.d.ts +112 -0
  116. package/dist/lib/emitted-freshness.d.ts.map +1 -0
  117. package/dist/lib/emitted-freshness.js +288 -0
  118. package/dist/lib/emitted-freshness.js.map +1 -0
  119. package/dist/lib/entity-index-artefact.d.ts +95 -0
  120. package/dist/lib/entity-index-artefact.d.ts.map +1 -0
  121. package/dist/lib/entity-index-artefact.js +210 -0
  122. package/dist/lib/entity-index-artefact.js.map +1 -0
  123. package/dist/lib/instance-build-inputs.d.ts +108 -0
  124. package/dist/lib/instance-build-inputs.d.ts.map +1 -0
  125. package/dist/lib/instance-build-inputs.js +165 -0
  126. package/dist/lib/instance-build-inputs.js.map +1 -0
  127. package/dist/lib/module-docs.d.ts +473 -0
  128. package/dist/lib/module-docs.d.ts.map +1 -0
  129. package/dist/lib/module-docs.js +711 -0
  130. package/dist/lib/module-docs.js.map +1 -0
  131. package/dist/lib/module-package-subpaths.d.ts +56 -0
  132. package/dist/lib/module-package-subpaths.d.ts.map +1 -0
  133. package/dist/lib/module-package-subpaths.js +223 -0
  134. package/dist/lib/module-package-subpaths.js.map +1 -0
  135. package/dist/lib/module-packages.d.ts +200 -0
  136. package/dist/lib/module-packages.d.ts.map +1 -0
  137. package/dist/lib/module-packages.js +580 -0
  138. package/dist/lib/module-packages.js.map +1 -0
  139. package/dist/lib/module-population.d.ts +129 -0
  140. package/dist/lib/module-population.d.ts.map +1 -0
  141. package/dist/lib/module-population.js +172 -0
  142. package/dist/lib/module-population.js.map +1 -0
  143. package/dist/lib/module-roots.d.ts +337 -0
  144. package/dist/lib/module-roots.d.ts.map +1 -0
  145. package/dist/lib/module-roots.js +586 -0
  146. package/dist/lib/module-roots.js.map +1 -0
  147. package/dist/lib/nested-checkouts.d.ts +33 -0
  148. package/dist/lib/nested-checkouts.d.ts.map +1 -0
  149. package/dist/lib/nested-checkouts.js +160 -0
  150. package/dist/lib/nested-checkouts.js.map +1 -0
  151. package/dist/lib/platform-root.d.ts +43 -0
  152. package/dist/lib/platform-root.d.ts.map +1 -0
  153. package/dist/lib/platform-root.js +134 -0
  154. package/dist/lib/platform-root.js.map +1 -0
  155. package/dist/lib/platform-surface.d.ts +235 -0
  156. package/dist/lib/platform-surface.d.ts.map +1 -0
  157. package/dist/lib/platform-surface.js +393 -0
  158. package/dist/lib/platform-surface.js.map +1 -0
  159. package/dist/lib/port-registrations.d.ts +223 -0
  160. package/dist/lib/port-registrations.d.ts.map +1 -0
  161. package/dist/lib/port-registrations.js +532 -0
  162. package/dist/lib/port-registrations.js.map +1 -0
  163. package/dist/lib/read-size.d.ts +154 -0
  164. package/dist/lib/read-size.d.ts.map +1 -0
  165. package/dist/lib/read-size.js +182 -0
  166. package/dist/lib/read-size.js.map +1 -0
  167. package/dist/lib/registration-owners.d.ts +79 -0
  168. package/dist/lib/registration-owners.d.ts.map +1 -0
  169. package/dist/lib/registration-owners.js +77 -0
  170. package/dist/lib/registration-owners.js.map +1 -0
  171. package/dist/lib/release-index.d.ts +53 -0
  172. package/dist/lib/release-index.d.ts.map +1 -0
  173. package/dist/lib/release-index.js +162 -0
  174. package/dist/lib/release-index.js.map +1 -0
  175. package/dist/lib/repeating-timers.d.ts +79 -0
  176. package/dist/lib/repeating-timers.d.ts.map +1 -0
  177. package/dist/lib/repeating-timers.js +189 -0
  178. package/dist/lib/repeating-timers.js.map +1 -0
  179. package/dist/lib/source-text.d.ts +34 -0
  180. package/dist/lib/source-text.d.ts.map +1 -0
  181. package/dist/lib/source-text.js +80 -0
  182. package/dist/lib/source-text.js.map +1 -0
  183. package/dist/lib/specifiers.d.ts +20 -0
  184. package/dist/lib/specifiers.d.ts.map +1 -0
  185. package/dist/lib/specifiers.js +130 -0
  186. package/dist/lib/specifiers.js.map +1 -0
  187. package/dist/lib/sql-tables.d.ts +166 -0
  188. package/dist/lib/sql-tables.d.ts.map +1 -0
  189. package/dist/lib/sql-tables.js +464 -0
  190. package/dist/lib/sql-tables.js.map +1 -0
  191. package/dist/lib/switchable-modules.d.ts +54 -0
  192. package/dist/lib/switchable-modules.d.ts.map +1 -0
  193. package/dist/lib/switchable-modules.js +104 -0
  194. package/dist/lib/switchable-modules.js.map +1 -0
  195. package/dist/lib/tailwind-sources.d.ts +136 -0
  196. package/dist/lib/tailwind-sources.d.ts.map +1 -0
  197. package/dist/lib/tailwind-sources.js +307 -0
  198. package/dist/lib/tailwind-sources.js.map +1 -0
  199. package/dist/lib/ui-layer.d.ts +54 -0
  200. package/dist/lib/ui-layer.d.ts.map +1 -0
  201. package/dist/lib/ui-layer.js +57 -0
  202. package/dist/lib/ui-layer.js.map +1 -0
  203. package/dist/lib/workspace-packages.d.ts +186 -0
  204. package/dist/lib/workspace-packages.d.ts.map +1 -0
  205. package/dist/lib/workspace-packages.js +351 -0
  206. package/dist/lib/workspace-packages.js.map +1 -0
  207. package/dist/new-instance/deploy.d.ts +211 -0
  208. package/dist/new-instance/deploy.d.ts.map +1 -0
  209. package/dist/new-instance/deploy.js +1381 -0
  210. package/dist/new-instance/deploy.js.map +1 -0
  211. package/dist/new-instance/docs-toolchain.d.ts +66 -0
  212. package/dist/new-instance/docs-toolchain.d.ts.map +1 -0
  213. package/dist/new-instance/docs-toolchain.js +69 -0
  214. package/dist/new-instance/docs-toolchain.js.map +1 -0
  215. package/dist/new-instance/host.d.ts +124 -0
  216. package/dist/new-instance/host.d.ts.map +1 -0
  217. package/dist/new-instance/host.js +276 -0
  218. package/dist/new-instance/host.js.map +1 -0
  219. package/dist/new-instance/index.d.ts +118 -0
  220. package/dist/new-instance/index.d.ts.map +1 -0
  221. package/dist/new-instance/index.js +567 -0
  222. package/dist/new-instance/index.js.map +1 -0
  223. package/dist/new-instance/modules.d.ts +188 -0
  224. package/dist/new-instance/modules.d.ts.map +1 -0
  225. package/dist/new-instance/modules.js +392 -0
  226. package/dist/new-instance/modules.js.map +1 -0
  227. package/dist/new-instance/template.d.ts +505 -0
  228. package/dist/new-instance/template.d.ts.map +1 -0
  229. package/dist/new-instance/template.js +1886 -0
  230. package/dist/new-instance/template.js.map +1 -0
  231. package/dist/new-module/emit.d.ts +67 -0
  232. package/dist/new-module/emit.d.ts.map +1 -0
  233. package/dist/new-module/emit.js +1393 -0
  234. package/dist/new-module/emit.js.map +1 -0
  235. package/dist/new-module/host.d.ts +67 -0
  236. package/dist/new-module/host.d.ts.map +1 -0
  237. package/dist/new-module/host.js +224 -0
  238. package/dist/new-module/host.js.map +1 -0
  239. package/dist/new-module/index.d.ts +32 -0
  240. package/dist/new-module/index.d.ts.map +1 -0
  241. package/dist/new-module/index.js +193 -0
  242. package/dist/new-module/index.js.map +1 -0
  243. package/dist/new-module/spec.d.ts +188 -0
  244. package/dist/new-module/spec.d.ts.map +1 -0
  245. package/dist/new-module/spec.js +404 -0
  246. package/dist/new-module/spec.js.map +1 -0
  247. package/dist/new-module/text.d.ts +15 -0
  248. package/dist/new-module/text.d.ts.map +1 -0
  249. package/dist/new-module/text.js +22 -0
  250. package/dist/new-module/text.js.map +1 -0
  251. package/dist/new-storefront/dockerfile.d.ts +20 -0
  252. package/dist/new-storefront/dockerfile.d.ts.map +1 -0
  253. package/dist/new-storefront/dockerfile.js +131 -0
  254. package/dist/new-storefront/dockerfile.js.map +1 -0
  255. package/dist/new-storefront/gitignore.d.ts +23 -0
  256. package/dist/new-storefront/gitignore.d.ts.map +1 -0
  257. package/dist/new-storefront/gitignore.js +39 -0
  258. package/dist/new-storefront/gitignore.js.map +1 -0
  259. package/dist/new-storefront/index.d.ts +93 -0
  260. package/dist/new-storefront/index.d.ts.map +1 -0
  261. package/dist/new-storefront/index.js +329 -0
  262. package/dist/new-storefront/index.js.map +1 -0
  263. package/dist/new-storefront/npmrc.d.ts +98 -0
  264. package/dist/new-storefront/npmrc.d.ts.map +1 -0
  265. package/dist/new-storefront/npmrc.js +217 -0
  266. package/dist/new-storefront/npmrc.js.map +1 -0
  267. package/dist/new-storefront/reference.d.ts +189 -0
  268. package/dist/new-storefront/reference.d.ts.map +1 -0
  269. package/dist/new-storefront/reference.js +430 -0
  270. package/dist/new-storefront/reference.js.map +1 -0
  271. package/dist/new-storefront/rewrite.d.ts +171 -0
  272. package/dist/new-storefront/rewrite.d.ts.map +1 -0
  273. package/dist/new-storefront/rewrite.js +701 -0
  274. package/dist/new-storefront/rewrite.js.map +1 -0
  275. package/dist/release-index.json +284 -0
  276. package/dist/rules/action-route-permissions.d.ts +141 -0
  277. package/dist/rules/action-route-permissions.d.ts.map +1 -0
  278. package/dist/rules/action-route-permissions.js +556 -0
  279. package/dist/rules/action-route-permissions.js.map +1 -0
  280. package/dist/rules/bundle-pairing.d.ts +74 -0
  281. package/dist/rules/bundle-pairing.d.ts.map +1 -0
  282. package/dist/rules/bundle-pairing.js +281 -0
  283. package/dist/rules/bundle-pairing.js.map +1 -0
  284. package/dist/rules/channel-resolution.d.ts +17 -0
  285. package/dist/rules/channel-resolution.d.ts.map +1 -0
  286. package/dist/rules/channel-resolution.js +382 -0
  287. package/dist/rules/channel-resolution.js.map +1 -0
  288. package/dist/rules/command-coverage.d.ts +210 -0
  289. package/dist/rules/command-coverage.d.ts.map +1 -0
  290. package/dist/rules/command-coverage.js +714 -0
  291. package/dist/rules/command-coverage.js.map +1 -0
  292. package/dist/rules/container-imports.d.ts +60 -0
  293. package/dist/rules/container-imports.d.ts.map +1 -0
  294. package/dist/rules/container-imports.js +158 -0
  295. package/dist/rules/container-imports.js.map +1 -0
  296. package/dist/rules/default-language-prose.d.ts +212 -0
  297. package/dist/rules/default-language-prose.d.ts.map +1 -0
  298. package/dist/rules/default-language-prose.js +710 -0
  299. package/dist/rules/default-language-prose.js.map +1 -0
  300. package/dist/rules/diacritic-folds.d.ts +238 -0
  301. package/dist/rules/diacritic-folds.d.ts.map +1 -0
  302. package/dist/rules/diacritic-folds.js +681 -0
  303. package/dist/rules/diacritic-folds.js.map +1 -0
  304. package/dist/rules/entity-tenant-classification.d.ts +171 -0
  305. package/dist/rules/entity-tenant-classification.d.ts.map +1 -0
  306. package/dist/rules/entity-tenant-classification.js +323 -0
  307. package/dist/rules/entity-tenant-classification.js.map +1 -0
  308. package/dist/rules/entry-presence.d.ts +142 -0
  309. package/dist/rules/entry-presence.d.ts.map +1 -0
  310. package/dist/rules/entry-presence.js +339 -0
  311. package/dist/rules/entry-presence.js.map +1 -0
  312. package/dist/rules/entry-scope.d.ts +91 -0
  313. package/dist/rules/entry-scope.d.ts.map +1 -0
  314. package/dist/rules/entry-scope.js +404 -0
  315. package/dist/rules/entry-scope.js.map +1 -0
  316. package/dist/rules/env-inputs.d.ts +222 -0
  317. package/dist/rules/env-inputs.d.ts.map +1 -0
  318. package/dist/rules/env-inputs.js +951 -0
  319. package/dist/rules/env-inputs.js.map +1 -0
  320. package/dist/rules/kernel-boundary.d.ts +37 -0
  321. package/dist/rules/kernel-boundary.d.ts.map +1 -0
  322. package/dist/rules/kernel-boundary.js +195 -0
  323. package/dist/rules/kernel-boundary.js.map +1 -0
  324. package/dist/rules/nul-bytes.d.ts +233 -0
  325. package/dist/rules/nul-bytes.d.ts.map +1 -0
  326. package/dist/rules/nul-bytes.js +332 -0
  327. package/dist/rules/nul-bytes.js.map +1 -0
  328. package/dist/rules/platform-surface.d.ts +479 -0
  329. package/dist/rules/platform-surface.d.ts.map +1 -0
  330. package/dist/rules/platform-surface.js +749 -0
  331. package/dist/rules/platform-surface.js.map +1 -0
  332. package/dist/rules/port-catches.d.ts +225 -0
  333. package/dist/rules/port-catches.d.ts.map +1 -0
  334. package/dist/rules/port-catches.js +1374 -0
  335. package/dist/rules/port-catches.js.map +1 -0
  336. package/dist/rules/port-shape.d.ts +213 -0
  337. package/dist/rules/port-shape.d.ts.map +1 -0
  338. package/dist/rules/port-shape.js +670 -0
  339. package/dist/rules/port-shape.js.map +1 -0
  340. package/dist/rules/queue-names.d.ts +108 -0
  341. package/dist/rules/queue-names.d.ts.map +1 -0
  342. package/dist/rules/queue-names.js +395 -0
  343. package/dist/rules/queue-names.js.map +1 -0
  344. package/dist/rules/singleton-identity.d.ts +205 -0
  345. package/dist/rules/singleton-identity.d.ts.map +1 -0
  346. package/dist/rules/singleton-identity.js +830 -0
  347. package/dist/rules/singleton-identity.js.map +1 -0
  348. package/dist/rules/subscribe-seam.d.ts +121 -0
  349. package/dist/rules/subscribe-seam.d.ts.map +1 -0
  350. package/dist/rules/subscribe-seam.js +594 -0
  351. package/dist/rules/subscribe-seam.js.map +1 -0
  352. package/dist/rules/transaction-context.d.ts +40 -0
  353. package/dist/rules/transaction-context.d.ts.map +1 -0
  354. package/dist/rules/transaction-context.js +294 -0
  355. package/dist/rules/transaction-context.js.map +1 -0
  356. package/package.json +59 -0
@@ -0,0 +1,116 @@
1
+ /**
2
+ * What a package's **peers** own — the one input Phase 3's owner-map rules share
3
+ * (`specs/101-endora-check/contracts/package-scope-layout.md` §2, the `owner
4
+ * maps` row, and §5's Tier B).
5
+ *
6
+ * ## The measurement that made this file necessary
7
+ *
8
+ * `check:port-catches` was assessed as needing no peer input at all, on the
9
+ * reasoning that its alias table is *"a fixpoint over port-carrying values"*
10
+ * seeded on a resolution — and a consuming package writes its own resolutions.
11
+ * That reasoning is wrong, and the code says where: the seed is
12
+ * `lazyPort(ctx, '<name>')` **whose name is already in `portOwners`**, and
13
+ * `portOwners` is built from `di.providePort` in a file that declares
14
+ * `registerModule` — the **owner's** file, not the consumer's. A package that
15
+ * only consumes ports has an empty seed.
16
+ *
17
+ * Measured over this repository's module packages, because the hazard is worth
18
+ * having as evidence rather than as an assertion: the whole-tree run attributes
19
+ * **226** guarded-port sites to 41 packages; the same analysis run over each
20
+ * package **in isolation** finds **19**, in 10 packages. **31 of the 41 lose
21
+ * every site**, and they include all four PIM connectors (17–19 sites each) and
22
+ * `product_feeds` (24) — which is to say the integration-heavy modules a
23
+ * package-scope host exists to judge, the ones whose ports are almost all
24
+ * somebody else's. A package-scope host without this input would have printed
25
+ * `violations=0` over exactly the packages it was built to judge.
26
+ *
27
+ * The reasoning that produced the wrong assessment is worth naming too, since it
28
+ * is not specific to this rule: it came from **the rule's header comment**, which
29
+ * describes the alias table as a fixpoint over port-carrying values and is
30
+ * accurate — and says nothing about the seed. The predicate is six lines of
31
+ * `isProxyCall`. A written statement trusted in place of the thing it describes is
32
+ * the failure this whole estate exists against, and it reaches the people
33
+ * building the estate too.
34
+ *
35
+ * ## Both discovery halves are needed, and a reader will not notice deleting one
36
+ *
37
+ * Stated here because neither tree alone shows it: the **installed** walk finds
38
+ * nothing in this repository, because every module package is a workspace member
39
+ * symlinked into `node_modules` and the walk correctly rejects a candidate whose
40
+ * real path leaves the `node_modules` it was reached through. The **workspace**
41
+ * walk finds nothing in a client instance, which has no workspace. So a reader
42
+ * who deletes either half sees a green run in whichever tree they are standing
43
+ * in, and the other tree's hosts go quietly blind.
44
+ *
45
+ * ## Why this is synchronous, takes no new dependency, and duplicates nothing
46
+ *
47
+ * The obvious route — resolve `@endora-commerce/platform/packages` out of the
48
+ * subject's tree and call `scanNodeModulesRoots` — is async, and
49
+ * {@link PackageRuleHost} is synchronous by Phase 1's design. It is also
50
+ * unnecessary: `lib/module-packages.ts` already carries an **installed** walk
51
+ * beside its workspace one, with its own recorded reason for being separate from
52
+ * the platform's boot walk and an explicit agreement on the three rules that
53
+ * decide an answer. So the discovery exists, in this package, and this file adds
54
+ * none of its own.
55
+ *
56
+ * What it adds is the *reading*: a peer's registrations come out of its emitted
57
+ * `./backend`-ish artefact as **text through the compiler API**, using the same
58
+ * `providedPortNames` / `registeredNames` the repository hosts use over source.
59
+ * No import of a stranger's composition, no platform, no ORM, no `await`.
60
+ *
61
+ * ## Two sources, because a peer can be either
62
+ *
63
+ * A peer is a workspace member (this checkout, and a stranger's monorepo) **or**
64
+ * a package installed under a `node_modules` (a stranger's instance). That is
65
+ * `module-roots.ts`' own two-sourced derivation with the population narrowed, and
66
+ * both halves are needed: in *this* repository every module package is a
67
+ * workspace member symlinked into `node_modules`, which the installed walk
68
+ * correctly rejects as `links-out-of-node-modules`, so the installed half alone
69
+ * would find nothing here and the workspace half alone would find nothing in a
70
+ * client instance.
71
+ *
72
+ * ## It never answers "nobody owns it"
73
+ *
74
+ * A name no peer provides is **not attributed to nobody** — it is *unattributed*,
75
+ * and the count of those is what a rule turns into `sources=owners:<n>/<m>` on
76
+ * its own `read:` line and, when `n` is zero, into `unreadable`. That is the
77
+ * whole of §5's *"a port whose owner module is not installed is `unreadable` for
78
+ * that edge, never `unowned`"*, expressed in the idiom the estate already prints
79
+ * rather than in a sentence a reader has to trust.
80
+ */
81
+ import { type ModulePackage } from '../lib/module-packages.js';
82
+ import type { PackageLayout } from './layout.js';
83
+ /** A peer whose declarations could not be read, named with the reason. */
84
+ export interface UnreadablePeer {
85
+ readonly name: string;
86
+ readonly moduleId: string;
87
+ /** In the words the rule's own line uses. */
88
+ readonly reason: string;
89
+ }
90
+ export interface PeerOwners {
91
+ /** Peer module packages found, the subject excluded. */
92
+ readonly peers: readonly ModulePackage[];
93
+ /** Gated port name → the module id whose artefact provides it. */
94
+ readonly portOwners: ReadonlyMap<string, string>;
95
+ /** Container registration name → the module id whose artefact registers it. */
96
+ readonly containerOwners: ReadonlyMap<string, string>;
97
+ /** Emitted artefacts opened — the `files=` contribution. */
98
+ readonly filesRead: number;
99
+ /** Peers that claimed to be modules and could not be read. Never a silent zero. */
100
+ readonly unreadable: readonly UnreadablePeer[];
101
+ /** Which half, or halves, the peers came from. Printed, so a zero is legible. */
102
+ readonly discovery: 'installed' | 'workspace' | 'both' | 'none';
103
+ }
104
+ /** The empty answer — a package standing alone, with nothing installed beside it. */
105
+ export declare const NO_PEER_OWNERS: PeerOwners;
106
+ /**
107
+ * Read what the subject's peers own.
108
+ *
109
+ * Every failure is named. A peer that publishes no composing artefact is
110
+ * *readable and empty* — it registers nothing, by its own `exports` map — while a
111
+ * peer whose artefact is absent is **unreadable**, because a package that was
112
+ * never built is a package whose registrations this run cannot see and must not
113
+ * credit with none.
114
+ */
115
+ export declare function readPeerOwners(layout: PackageLayout): PeerOwners;
116
+ //# sourceMappingURL=peer-owners.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peer-owners.d.ts","sourceRoot":"","sources":["../../src/check/peer-owners.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+EG;AAKH,OAAO,EAGL,KAAK,aAAa,EACnB,MAAM,2BAA2B,CAAC;AAInC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,0EAA0E;AAC1E,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,6CAA6C;IAC7C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,UAAU;IACzB,wDAAwD;IACxD,QAAQ,CAAC,KAAK,EAAE,SAAS,aAAa,EAAE,CAAC;IACzC,kEAAkE;IAClE,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACjD,+EAA+E;IAC/E,QAAQ,CAAC,eAAe,EAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtD,4DAA4D;IAC5D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,mFAAmF;IACnF,QAAQ,CAAC,UAAU,EAAE,SAAS,cAAc,EAAE,CAAC;IAC/C,iFAAiF;IACjF,QAAQ,CAAC,SAAS,EAAE,WAAW,GAAG,WAAW,GAAG,MAAM,GAAG,MAAM,CAAC;CACjE;AAED,qFAAqF;AACrF,eAAO,MAAM,cAAc,EAAE,UAO5B,CAAC;AA6CF;;;;;;;;GAQG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,aAAa,GAAG,UAAU,CAiFhE"}
@@ -0,0 +1,225 @@
1
+ /**
2
+ * What a package's **peers** own — the one input Phase 3's owner-map rules share
3
+ * (`specs/101-endora-check/contracts/package-scope-layout.md` §2, the `owner
4
+ * maps` row, and §5's Tier B).
5
+ *
6
+ * ## The measurement that made this file necessary
7
+ *
8
+ * `check:port-catches` was assessed as needing no peer input at all, on the
9
+ * reasoning that its alias table is *"a fixpoint over port-carrying values"*
10
+ * seeded on a resolution — and a consuming package writes its own resolutions.
11
+ * That reasoning is wrong, and the code says where: the seed is
12
+ * `lazyPort(ctx, '<name>')` **whose name is already in `portOwners`**, and
13
+ * `portOwners` is built from `di.providePort` in a file that declares
14
+ * `registerModule` — the **owner's** file, not the consumer's. A package that
15
+ * only consumes ports has an empty seed.
16
+ *
17
+ * Measured over this repository's module packages, because the hazard is worth
18
+ * having as evidence rather than as an assertion: the whole-tree run attributes
19
+ * **226** guarded-port sites to 41 packages; the same analysis run over each
20
+ * package **in isolation** finds **19**, in 10 packages. **31 of the 41 lose
21
+ * every site**, and they include all four PIM connectors (17–19 sites each) and
22
+ * `product_feeds` (24) — which is to say the integration-heavy modules a
23
+ * package-scope host exists to judge, the ones whose ports are almost all
24
+ * somebody else's. A package-scope host without this input would have printed
25
+ * `violations=0` over exactly the packages it was built to judge.
26
+ *
27
+ * The reasoning that produced the wrong assessment is worth naming too, since it
28
+ * is not specific to this rule: it came from **the rule's header comment**, which
29
+ * describes the alias table as a fixpoint over port-carrying values and is
30
+ * accurate — and says nothing about the seed. The predicate is six lines of
31
+ * `isProxyCall`. A written statement trusted in place of the thing it describes is
32
+ * the failure this whole estate exists against, and it reaches the people
33
+ * building the estate too.
34
+ *
35
+ * ## Both discovery halves are needed, and a reader will not notice deleting one
36
+ *
37
+ * Stated here because neither tree alone shows it: the **installed** walk finds
38
+ * nothing in this repository, because every module package is a workspace member
39
+ * symlinked into `node_modules` and the walk correctly rejects a candidate whose
40
+ * real path leaves the `node_modules` it was reached through. The **workspace**
41
+ * walk finds nothing in a client instance, which has no workspace. So a reader
42
+ * who deletes either half sees a green run in whichever tree they are standing
43
+ * in, and the other tree's hosts go quietly blind.
44
+ *
45
+ * ## Why this is synchronous, takes no new dependency, and duplicates nothing
46
+ *
47
+ * The obvious route — resolve `@endora-commerce/platform/packages` out of the
48
+ * subject's tree and call `scanNodeModulesRoots` — is async, and
49
+ * {@link PackageRuleHost} is synchronous by Phase 1's design. It is also
50
+ * unnecessary: `lib/module-packages.ts` already carries an **installed** walk
51
+ * beside its workspace one, with its own recorded reason for being separate from
52
+ * the platform's boot walk and an explicit agreement on the three rules that
53
+ * decide an answer. So the discovery exists, in this package, and this file adds
54
+ * none of its own.
55
+ *
56
+ * What it adds is the *reading*: a peer's registrations come out of its emitted
57
+ * `./backend`-ish artefact as **text through the compiler API**, using the same
58
+ * `providedPortNames` / `registeredNames` the repository hosts use over source.
59
+ * No import of a stranger's composition, no platform, no ORM, no `await`.
60
+ *
61
+ * ## Two sources, because a peer can be either
62
+ *
63
+ * A peer is a workspace member (this checkout, and a stranger's monorepo) **or**
64
+ * a package installed under a `node_modules` (a stranger's instance). That is
65
+ * `module-roots.ts`' own two-sourced derivation with the population narrowed, and
66
+ * both halves are needed: in *this* repository every module package is a
67
+ * workspace member symlinked into `node_modules`, which the installed walk
68
+ * correctly rejects as `links-out-of-node-modules`, so the installed half alone
69
+ * would find nothing here and the workspace half alone would find nothing in a
70
+ * client instance.
71
+ *
72
+ * ## It never answers "nobody owns it"
73
+ *
74
+ * A name no peer provides is **not attributed to nobody** — it is *unattributed*,
75
+ * and the count of those is what a rule turns into `sources=owners:<n>/<m>` on
76
+ * its own `read:` line and, when `n` is zero, into `unreadable`. That is the
77
+ * whole of §5's *"a port whose owner module is not installed is `unreadable` for
78
+ * that edge, never `unowned`"*, expressed in the idiom the estate already prints
79
+ * rather than in a sentence a reader has to trust.
80
+ */
81
+ import { existsSync, readFileSync } from 'node:fs';
82
+ import { dirname, join, resolve } from 'node:path';
83
+ import { discoverModulePackages, scanInstalledModulePackages, } from '../lib/module-packages.js';
84
+ import { declaresRegisterModule } from '../lib/module-roots.js';
85
+ import { providedPortNames, registeredNames } from '../lib/port-registrations.js';
86
+ /** The empty answer — a package standing alone, with nothing installed beside it. */
87
+ export const NO_PEER_OWNERS = {
88
+ peers: [],
89
+ portOwners: new Map(),
90
+ containerOwners: new Map(),
91
+ filesRead: 0,
92
+ unreadable: [],
93
+ discovery: 'none',
94
+ };
95
+ /**
96
+ * Every ancestor of the package that could hold peers, nearest first.
97
+ *
98
+ * "Could hold peers" is *has a `node_modules`* or *declares a workspace* — both
99
+ * questions about the tree rather than about a path anybody spells. The walk
100
+ * stops at the filesystem root; a package in a temp directory yields none, which
101
+ * is the honest answer and the one the fixtures rely on.
102
+ */
103
+ function candidateRoots(packageRoot) {
104
+ const roots = [];
105
+ let dir = resolve(packageRoot);
106
+ for (;;) {
107
+ if (existsSync(join(dir, 'node_modules')) || existsSync(join(dir, 'pnpm-workspace.yaml'))) {
108
+ roots.push(dir);
109
+ }
110
+ const parent = dirname(dir);
111
+ if (parent === dir)
112
+ return roots;
113
+ dir = parent;
114
+ }
115
+ }
116
+ /**
117
+ * The subpath whose artefact **composes** the peer, derived rather than spelled.
118
+ *
119
+ * `declaresRegisterModule` is `generate-composer.ts`'s own marker, so the
120
+ * composer, the repository hosts and this file cannot disagree about which file
121
+ * composes a module. Nothing here names `./backend` (D-100): the composing
122
+ * artefact is whichever declared target says so about itself.
123
+ */
124
+ function composingArtefact(pkg) {
125
+ for (const target of pkg.exports.values()) {
126
+ const path = join(pkg.dir, ...target.replace(/^\.\//, '').split('/'));
127
+ let text;
128
+ try {
129
+ text = readFileSync(path, 'utf8');
130
+ }
131
+ catch {
132
+ continue;
133
+ }
134
+ if (declaresRegisterModule(text))
135
+ return { path, text };
136
+ }
137
+ return null;
138
+ }
139
+ /**
140
+ * Read what the subject's peers own.
141
+ *
142
+ * Every failure is named. A peer that publishes no composing artefact is
143
+ * *readable and empty* — it registers nothing, by its own `exports` map — while a
144
+ * peer whose artefact is absent is **unreadable**, because a package that was
145
+ * never built is a package whose registrations this run cannot see and must not
146
+ * credit with none.
147
+ */
148
+ export function readPeerOwners(layout) {
149
+ const byId = new Map();
150
+ let installed = false;
151
+ let workspace = false;
152
+ const unreadable = [];
153
+ for (const root of candidateRoots(layout.packageRoot)) {
154
+ const scan = scanInstalledModulePackages(root);
155
+ for (const pkg of scan.packages) {
156
+ if (pkg.moduleId === layout.moduleId)
157
+ continue;
158
+ if (!byId.has(pkg.moduleId)) {
159
+ byId.set(pkg.moduleId, pkg);
160
+ installed = true;
161
+ }
162
+ }
163
+ try {
164
+ for (const pkg of discoverModulePackages(root)) {
165
+ if (pkg.moduleId === layout.moduleId)
166
+ continue;
167
+ if (!byId.has(pkg.moduleId)) {
168
+ byId.set(pkg.moduleId, pkg);
169
+ workspace = true;
170
+ }
171
+ }
172
+ }
173
+ catch (error) {
174
+ // Two workspace members claiming one module id. It is a real defect and it
175
+ // is not the subject's, so it is reported as an unreadable peer set rather
176
+ // than thrown: a stranger's malformed workspace must not abort their run,
177
+ // and crediting it with no peers would be the silence this file exists
178
+ // against.
179
+ unreadable.push({
180
+ name: root,
181
+ moduleId: '(workspace)',
182
+ reason: `its workspace could not be enumerated (${error instanceof Error ? error.message : String(error)})`,
183
+ });
184
+ }
185
+ }
186
+ const portOwners = new Map();
187
+ const containerOwners = new Map();
188
+ let filesRead = 0;
189
+ for (const pkg of [...byId.values()].sort((a, b) => a.moduleId.localeCompare(b.moduleId))) {
190
+ const artefact = composingArtefact(pkg);
191
+ if (artefact === null) {
192
+ // Readable and empty vs unreadable, decided by the package's own map: a
193
+ // peer that declares subpaths whose targets are not on disk was never
194
+ // built, and its registrations are unread rather than absent.
195
+ const declaresTargets = [...pkg.exports.values()].some((target) => existsSync(join(pkg.dir, ...target.replace(/^\.\//, '').split('/'))));
196
+ if (pkg.exports.size > 0 && !declaresTargets) {
197
+ unreadable.push({
198
+ name: pkg.name,
199
+ moduleId: pkg.moduleId,
200
+ reason: 'none of the targets its `exports` map declares is on disk, so the ports and ' +
201
+ 'container names it registers cannot be read — it was never built',
202
+ });
203
+ }
204
+ continue;
205
+ }
206
+ filesRead += 1;
207
+ for (const name of providedPortNames(artefact.text, artefact.path)) {
208
+ if (!portOwners.has(name))
209
+ portOwners.set(name, pkg.moduleId);
210
+ }
211
+ for (const name of registeredNames(artefact.text, artefact.path)) {
212
+ if (!containerOwners.has(name))
213
+ containerOwners.set(name, pkg.moduleId);
214
+ }
215
+ }
216
+ return {
217
+ peers: [...byId.values()],
218
+ portOwners,
219
+ containerOwners,
220
+ filesRead,
221
+ unreadable,
222
+ discovery: installed && workspace ? 'both' : installed ? 'installed' : workspace ? 'workspace' : 'none',
223
+ };
224
+ }
225
+ //# sourceMappingURL=peer-owners.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peer-owners.js","sourceRoot":"","sources":["../../src/check/peer-owners.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * The report — one line per rule, then the arithmetic
3
+ * (`specs/101-endora-check/contracts/exit-reduction.md` §3).
4
+ *
5
+ * Formatting only. Every decision is made in `run.ts` and every verdict in
6
+ * `hosts.ts`; a reporter that could change either would be a second place the
7
+ * exit code is decided.
8
+ *
9
+ * Two properties are contract rather than presentation:
10
+ *
11
+ * * **every rule appears**, whatever the aggregate found. That is what makes
12
+ * the reduction's `max` honest — the information a masked finding is about
13
+ * is on its own line, not something a reader infers from a scroll;
14
+ * * **`findings=<n>` is printed even when the exit code is 2** (FR-014). It is
15
+ * the whole of §4.4's answer to the masking objection, and it is normative.
16
+ */
17
+ import { coverageToken } from '../lib/read-size.js';
18
+ import type { LedgerRead } from './ledger.js';
19
+ import type { RunReport } from './run.js';
20
+ /**
21
+ * The arithmetic line, last.
22
+ *
23
+ * A narrowed run prints `selected=<n>/<estate>` **in place of** `estate=<n>`, so
24
+ * it cannot be mistaken for a full run's (§6). That is the only difference.
25
+ */
26
+ export declare function arithmeticLine(report: RunReport): string;
27
+ /** The sentence after the counts — why the run exited as it did. */
28
+ export declare function verdictSentence(report: RunReport): string;
29
+ /** The whole report, as the lines the command writes to stdout. */
30
+ export declare function formatReport(report: RunReport, ledger: LedgerRead): readonly string[];
31
+ /** The `sources=` token, re-exported so a caller need not reach past this file. */
32
+ export { coverageToken };
33
+ //# sourceMappingURL=report.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/check/report.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,EAAE,aAAa,EAAgB,MAAM,qBAAqB,CAAC;AAElE,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAE9C,OAAO,KAAK,EAAE,SAAS,EAAc,MAAM,UAAU,CAAC;AAuCtD;;;;;GAKG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CAWxD;AAED,oEAAoE;AACpE,wBAAgB,eAAe,CAAC,MAAM,EAAE,SAAS,GAAG,MAAM,CA0BzD;AAED,mEAAmE;AACnE,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,GAAG,SAAS,MAAM,EAAE,CAYrF;AAED,mFAAmF;AACnF,OAAO,EAAE,aAAa,EAAE,CAAC"}
@@ -0,0 +1,107 @@
1
+ /**
2
+ * The report — one line per rule, then the arithmetic
3
+ * (`specs/101-endora-check/contracts/exit-reduction.md` §3).
4
+ *
5
+ * Formatting only. Every decision is made in `run.ts` and every verdict in
6
+ * `hosts.ts`; a reporter that could change either would be a second place the
7
+ * exit code is decided.
8
+ *
9
+ * Two properties are contract rather than presentation:
10
+ *
11
+ * * **every rule appears**, whatever the aggregate found. That is what makes
12
+ * the reduction's `max` honest — the information a masked finding is about
13
+ * is on its own line, not something a reader infers from a scroll;
14
+ * * **`findings=<n>` is printed even when the exit code is 2** (FR-014). It is
15
+ * the whole of §4.4's answer to the masking objection, and it is normative.
16
+ */
17
+ import { coverageToken, readSizeLine } from '../lib/read-size.js';
18
+ import { reasonFor } from './ledger.js';
19
+ const VERDICT_WIDTH = 15;
20
+ const ID_WIDTH = 34;
21
+ function pad(text, width) {
22
+ return text.length >= width ? text : text + ' '.repeat(width - text.length);
23
+ }
24
+ /** `ran` splits into the two sub-states a reader cares about. */
25
+ function verdictWord(result) {
26
+ if (result.verdict !== 'ran')
27
+ return result.verdict;
28
+ return result.findings.length === 0 ? 'clean' : `findings=${result.findings.length}`;
29
+ }
30
+ function ruleLines(result, ledger) {
31
+ const lines = [];
32
+ const head = ` ${pad(result.id, ID_WIDTH)} ${pad(verdictWord(result), VERDICT_WIDTH)}`;
33
+ lines.push(result.readSize === null ? `${head}${result.explanation}` : `${head}${readSizeLine(result.readSize)}`);
34
+ if (result.readSize !== null && result.explanation.length > 0) {
35
+ lines.push(` ${result.explanation}`);
36
+ }
37
+ for (const signal of result.unevaluatedSignals) {
38
+ lines.push(` not evaluated — ${signal.signal}: ${signal.reason}`);
39
+ }
40
+ for (const finding of result.findings) {
41
+ lines.push(` ${finding.location ?? result.id} ${finding.message}`);
42
+ }
43
+ for (const finding of result.acknowledged) {
44
+ lines.push(` acknowledged ${finding.location ?? result.id} ${finding.message}`);
45
+ lines.push(` reason: ${reasonFor(ledger, finding)}`);
46
+ }
47
+ return lines;
48
+ }
49
+ /**
50
+ * The arithmetic line, last.
51
+ *
52
+ * A narrowed run prints `selected=<n>/<estate>` **in place of** `estate=<n>`, so
53
+ * it cannot be mistaken for a full run's (§6). That is the only difference.
54
+ */
55
+ export function arithmeticLine(report) {
56
+ const counts = report.counts;
57
+ const scope = report.selected === null
58
+ ? `estate=${counts.estate}`
59
+ : `selected=${report.selected.selected}/${report.selected.estate}`;
60
+ return (`endora check: ${scope} ran=${counts.ran} clean=${counts.clean} ` +
61
+ `findings=${counts.findings} not-applicable=${counts.notApplicable} ` +
62
+ `unreadable=${counts.unreadable} pending=${counts.pending}`);
63
+ }
64
+ /** The sentence after the counts — why the run exited as it did. */
65
+ export function verdictSentence(report) {
66
+ const counts = report.counts;
67
+ if (report.arithmeticFailures.length > 0) {
68
+ return ` → 2 ${report.arithmeticFailures.join(' ')}`;
69
+ }
70
+ const causes = [];
71
+ if (counts.pending > 0) {
72
+ const phases = [
73
+ ...new Set(report.results
74
+ .filter((result) => result.verdict === 'pending')
75
+ .map((result) => result.explanation)),
76
+ ];
77
+ causes.push(`${counts.pending} rule(s) have no package-scope host in this build (${phases.join('; ')})`);
78
+ }
79
+ if (counts.unreadable > 0) {
80
+ causes.push(`${counts.unreadable} rule(s) could not read an input this package must supply`);
81
+ }
82
+ if (causes.length > 0)
83
+ return ` → 2 ${causes.join('; ')}`;
84
+ if (counts.findings > 0 || report.ledgerFindings.length > 0) {
85
+ return ` → 1 ${counts.findings} rule(s) reported a finding`;
86
+ }
87
+ return ' → 0 the estate was completely evaluated and found nothing';
88
+ }
89
+ /** The whole report, as the lines the command writes to stdout. */
90
+ export function formatReport(report, ledger) {
91
+ const lines = [
92
+ `endora check: ${report.packageName}@${report.packageVersion}`,
93
+ '',
94
+ ];
95
+ for (const result of report.results)
96
+ lines.push(...ruleLines(result, ledger));
97
+ if (report.ledgerFindings.length > 0) {
98
+ lines.push('');
99
+ for (const finding of report.ledgerFindings)
100
+ lines.push(` ledger: ${finding}`);
101
+ }
102
+ lines.push('', arithmeticLine(report), verdictSentence(report));
103
+ return lines;
104
+ }
105
+ /** The `sources=` token, re-exported so a caller need not reach past this file. */
106
+ export { coverageToken };
107
+ //# sourceMappingURL=report.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/check/report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,147 @@
1
+ /**
2
+ * The verdicts, the arithmetic and the reduction
3
+ * (`specs/101-endora-check/contracts/exit-reduction.md` §1, §3, §4).
4
+ *
5
+ * ## The reduction is `max`, and that is not a new decision
6
+ *
7
+ * `0` and `1` are statements about the **tree**; `2` is a statement about the
8
+ * **run**. So the aggregate's job is to make each code a *complete* statement:
9
+ *
10
+ * * **2** — the picture is incomplete. There may or may not be findings under
11
+ * it; repair the picture.
12
+ * * **1** — the picture is complete and there are findings.
13
+ * * **0** — the picture is complete and there are none.
14
+ *
15
+ * Every member of this estate already reduces this way internally, over many
16
+ * signals and many files: `check:module-boundary` exits 2 on an owner map that
17
+ * resolved zero tables even when its walk found real unledgered reaches. An
18
+ * aggregate reducing differently would be a second derivation of one convention.
19
+ *
20
+ * The masking objection — *"one unreadable input hides every real finding"* — is
21
+ * answered where it lives: it masks them **in the exit code and nowhere else**.
22
+ * Every rule prints its own line regardless, and {@link countsOf}'s `findings`
23
+ * is printed on the arithmetic line **even when the code is 2**. That is
24
+ * normative (FR-014), not cosmetic.
25
+ *
26
+ * ## The identities have to be able to fail
27
+ *
28
+ * {@link countsOf} takes the estate's size as an argument rather than deriving it
29
+ * from the results it was handed. A count computed by summing the results a run
30
+ * happens to hold can never detect a lost rule — it is a tautology, and the
31
+ * whole point of §3's first identity is that losing a rule is the failure this
32
+ * command exists to make impossible. The second identity fails on a malformed
33
+ * host: a result that is not `ran` and still carries a finding.
34
+ */
35
+ import type { ReadSizeInput } from '../lib/read-size.js';
36
+ import type { PartialSignal } from './estate.js';
37
+ /** One thing a rule found. */
38
+ export interface Finding {
39
+ /** The estate id of the rule that found it. */
40
+ readonly rule: string;
41
+ /**
42
+ * The rule's own key shape for this finding — what a package ledger entry
43
+ * names. Never a line number where the rule's repository-side ledger keys on
44
+ * a digest: a line-keyed entry reds on any insertion above the site.
45
+ */
46
+ readonly key: string;
47
+ /** The sentence the author reads. */
48
+ readonly message: string;
49
+ /** Package-relative, or `null` where the finding is about the package. */
50
+ readonly location: string | null;
51
+ }
52
+ export type Verdict = 'ran' | 'not-applicable' | 'unreadable' | 'pending';
53
+ export interface RuleResult {
54
+ /** Matches {@link EstateEntry.id}. */
55
+ readonly id: string;
56
+ readonly verdict: Verdict;
57
+ /** Empty for every verdict but `ran`. */
58
+ readonly findings: readonly Finding[];
59
+ /**
60
+ * Findings a package ledger entry matched. Excluded from the author's exit
61
+ * code, included under `--as-platform` (`contracts/package-ledger.md` §4).
62
+ */
63
+ readonly acknowledged: readonly Finding[];
64
+ /** `null` only for `not-applicable` and `pending`. */
65
+ readonly readSize: ReadSizeInput | null;
66
+ /**
67
+ * Required for every verdict but `ran`, and that requirement **is** the
68
+ * design: a rule that did not run and cannot say why is the silent skip.
69
+ * Making the field non-optional is the cheapest place to make that
70
+ * unreachable.
71
+ */
72
+ readonly explanation: string;
73
+ /** Printed on the rule's own line. */
74
+ readonly unevaluatedSignals: readonly PartialSignal[];
75
+ }
76
+ export interface RunCounts {
77
+ readonly estate: number;
78
+ readonly ran: number;
79
+ readonly clean: number;
80
+ readonly findings: number;
81
+ readonly notApplicable: number;
82
+ readonly unreadable: number;
83
+ readonly pending: number;
84
+ }
85
+ /** `null` for a full run; the pair for a `--rule` run. */
86
+ export interface Selection {
87
+ readonly selected: number;
88
+ readonly estate: number;
89
+ }
90
+ export interface RunReport {
91
+ /** As read from the package's own manifest. */
92
+ readonly packageName: string;
93
+ readonly packageVersion: string;
94
+ readonly results: readonly RuleResult[];
95
+ readonly selected: Selection | null;
96
+ readonly counts: RunCounts;
97
+ /**
98
+ * Ledger entries that describe no finding this run produced, that carry no
99
+ * reason, or that are expressed as a count. Each makes the run exit 1; none
100
+ * of them is an estate member, so none disturbs §3's arithmetic.
101
+ */
102
+ readonly ledgerFindings: readonly string[];
103
+ /** Why §3's identities do not hold, or empty. */
104
+ readonly arithmeticFailures: readonly string[];
105
+ /** Computed by {@link reduce} and by nothing else. */
106
+ readonly exitCode: number;
107
+ }
108
+ /** Which findings count against the exit code, for this reader. */
109
+ export declare function effectiveFindings(result: RuleResult, asPlatform: boolean): readonly Finding[];
110
+ /**
111
+ * The counts, over the results and an **independently supplied** estate size.
112
+ *
113
+ * `estateSize` is a parameter rather than `results.length` on purpose — see the
114
+ * header. `clean` and `findings` are each counted directly rather than one being
115
+ * derived from the other, so §3's second identity is a real comparison.
116
+ */
117
+ export declare function countsOf(results: readonly RuleResult[], estateSize: number, asPlatform?: boolean): RunCounts;
118
+ /**
119
+ * Why §3's identities do not hold, or an empty list.
120
+ *
121
+ * A narrowed run suppresses the first — it is meaningless over a subset — and
122
+ * keeps the second, which is about the results themselves.
123
+ */
124
+ export declare function arithmeticFailures(counts: RunCounts, narrowed: boolean): readonly string[];
125
+ /**
126
+ * The exit code. `max` over the members' own codes, with `pending` folded into 2.
127
+ *
128
+ * ```
129
+ * exit 2 if unreadable > 0 or pending > 0 or either identity fails
130
+ * exit 1 else if findings > 0 or a ledger entry is stale
131
+ * exit 0 else
132
+ * ```
133
+ */
134
+ export declare function reduce(counts: RunCounts, failures: readonly string[], ledgerFindings: readonly string[]): number;
135
+ export interface RunReportInput {
136
+ readonly packageName: string;
137
+ readonly packageVersion: string;
138
+ readonly results: readonly RuleResult[];
139
+ /** The estate's size — never `results.length` (see the header). */
140
+ readonly estateSize: number;
141
+ /** `null` for a full run. */
142
+ readonly selected: Selection | null;
143
+ readonly ledgerFindings?: readonly string[];
144
+ readonly asPlatform?: boolean;
145
+ }
146
+ export declare function buildRunReport(input: RunReportInput): RunReport;
147
+ //# sourceMappingURL=run.d.ts.map