@starci/hfs 4.11.21 → 4.12.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 (1088) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/README.md +31 -31
  3. package/ci/cli.d.mts +15 -0
  4. package/ci/cli.mjs +71 -52
  5. package/ci/github.d.mts +43 -0
  6. package/ci/github.mjs +33 -28
  7. package/ci/local.d.mts +12 -0
  8. package/ci/local.mjs +145 -108
  9. package/ci/secret.d.mts +15 -0
  10. package/ci/secret.mjs +31 -21
  11. package/ci/vars.d.mts +17 -0
  12. package/ci/vars.mjs +47 -33
  13. package/ci/verify.d.mts +18 -0
  14. package/ci/verify.mjs +52 -40
  15. package/codemod/button-intent.d.mts +63 -0
  16. package/codemod/button-intent.mjs +338 -285
  17. package/coverage/cli.d.mts +28 -0
  18. package/coverage/cli.mjs +65 -51
  19. package/db/backup-receipt.d.mts +28 -0
  20. package/db/backup-receipt.mjs +78 -58
  21. package/db/drift.d.mts +86 -0
  22. package/db/drift.mjs +213 -180
  23. package/db/dump.d.mts +52 -0
  24. package/db/dump.mjs +63 -56
  25. package/db/entity-list.d.mts +4 -0
  26. package/db/entity-list.mjs +0 -2
  27. package/db/image.d.mts +8 -0
  28. package/db/image.mjs +1 -2
  29. package/db/migrate.d.mts +104 -0
  30. package/db/migrate.mjs +207 -167
  31. package/db/new.d.mts +11 -0
  32. package/db/new.mjs +25 -25
  33. package/db/post-cutover.d.mts +5 -0
  34. package/db/post-cutover.mjs +89 -82
  35. package/db/postgres.d.mts +71 -0
  36. package/db/postgres.mjs +62 -61
  37. package/emit/compiler.d.mts +3 -0
  38. package/emit/compiler.mjs +25 -27
  39. package/emit/contracts.d.mts +35 -0
  40. package/emit/contracts.mjs +46 -50
  41. package/emit/events.d.mts +9 -0
  42. package/emit/events.mjs +19 -20
  43. package/emit/form-bounds.d.mts +83 -0
  44. package/emit/form-bounds.mjs +133 -117
  45. package/emit/graphql-input-bounds.d.mts +63 -0
  46. package/emit/graphql-input-bounds.mjs +90 -79
  47. package/emit/input-bounds.d.mts +30 -0
  48. package/emit/input-bounds.mjs +29 -27
  49. package/emit/operation-schemas.d.mts +24 -0
  50. package/emit/operation-schemas.mjs +136 -116
  51. package/emit/operations-worker.d.mts +1 -0
  52. package/emit/operations-worker.mjs +9 -7
  53. package/emit/operations.d.mts +47 -0
  54. package/emit/operations.mjs +124 -133
  55. package/emit/schema-worker.d.mts +1 -0
  56. package/emit/schema-worker.mjs +57 -50
  57. package/emit/static-graph.d.mts +48 -0
  58. package/emit/static-graph.mjs +766 -640
  59. package/emit/type-schema.d.mts +29 -0
  60. package/emit/type-schema.mjs +153 -140
  61. package/lint/bound-sys.cjs +27 -33
  62. package/lint/chunk.d.mts +17 -0
  63. package/lint/chunk.mjs +41 -31
  64. package/lint/run.d.mts +120 -0
  65. package/lint/run.mjs +415 -322
  66. package/package.json +21 -4
  67. package/release/candidate-ci.d.mts +46 -0
  68. package/release/candidate-ci.mjs +76 -70
  69. package/release/gate.d.mts +120 -0
  70. package/release/gate.mjs +358 -330
  71. package/release/index.d.mts +68 -0
  72. package/release/index.mjs +95 -73
  73. package/release/lint-report.d.mts +14 -0
  74. package/release/lint-report.mjs +33 -32
  75. package/release/push.d.mts +32 -0
  76. package/release/push.mjs +92 -79
  77. package/release/records.d.mts +18 -0
  78. package/release/records.mjs +22 -21
  79. package/release/sonar-quality-gate.d.mts +18 -0
  80. package/release/sonar-quality-gate.mjs +60 -52
  81. package/release/urgent.d.mts +20 -0
  82. package/release/urgent.mjs +76 -74
  83. package/report/order.d.mts +1 -0
  84. package/report/sonar.d.mts +73 -0
  85. package/report/sonar.mjs +82 -89
  86. package/runtime/engine/admission.d.mts +209 -0
  87. package/runtime/engine/admission.mjs +225 -204
  88. package/runtime/engine/by-code-unit.d.mts +5 -0
  89. package/runtime/engine/by-code-unit.mjs +6 -6
  90. package/runtime/engine/config.d.mts +333 -0
  91. package/runtime/engine/config.mjs +486 -328
  92. package/runtime/engine/db/blob.d.mts +83 -0
  93. package/runtime/engine/db/blob.mjs +344 -268
  94. package/runtime/engine/db/event-compact.d.mts +21 -0
  95. package/runtime/engine/db/event-compact.mjs +34 -38
  96. package/runtime/engine/db/machine-connection.d.mts +68 -0
  97. package/runtime/engine/db/machine-connection.mjs +166 -119
  98. package/runtime/engine/db/machine-open.d.mts +26 -0
  99. package/runtime/engine/db/machine-open.mjs +59 -45
  100. package/runtime/engine/db/machine-schema.d.mts +34 -0
  101. package/runtime/engine/db/machine-schema.mjs +102 -83
  102. package/runtime/engine/db/machine.d.mts +1746 -0
  103. package/runtime/engine/db/machine.mjs +1040 -734
  104. package/runtime/engine/db/provider-reservations.d.mts +169 -0
  105. package/runtime/engine/db/provider-reservations.mjs +141 -119
  106. package/runtime/engine/db/provision-lock.d.mts +23 -0
  107. package/runtime/engine/db/provision-lock.mjs +14 -14
  108. package/runtime/engine/db/ref-value.d.mts +19 -0
  109. package/runtime/engine/db/ref-value.mjs +36 -35
  110. package/runtime/engine/db/sqlite-types.d.mts +28 -0
  111. package/runtime/engine/db/sqlite-types.mjs +4 -0
  112. package/runtime/engine/digest.d.mts +4 -0
  113. package/runtime/engine/digest.mjs +16 -7
  114. package/runtime/engine/invalid-config.d.mts +13 -0
  115. package/runtime/engine/invalid-config.mjs +17 -11
  116. package/runtime/engine/model-config.d.mts +91 -0
  117. package/runtime/engine/model-config.mjs +98 -76
  118. package/runtime/engine/orca-config.d.mts +26 -0
  119. package/runtime/engine/orca-config.mjs +22 -17
  120. package/runtime/engine/plain-object.d.mts +2 -0
  121. package/runtime/engine/refuse.d.mts +9 -0
  122. package/runtime/engine/refuse.mjs +3 -6
  123. package/runtime/engine/release-config.d.mts +19 -0
  124. package/runtime/engine/release-config.mjs +22 -18
  125. package/runtime/engine/removed-vocabulary.d.mts +12 -0
  126. package/runtime/engine/removed-vocabulary.mjs +21 -20
  127. package/runtime/engine/resources-config.d.mts +34 -0
  128. package/runtime/engine/resources-config.mjs +42 -35
  129. package/runtime/engine/runtime-root.d.mts +28 -0
  130. package/runtime/engine/runtime-root.mjs +11 -13
  131. package/runtime/engine/secrets.d.mts +41 -0
  132. package/runtime/engine/secrets.mjs +170 -102
  133. package/runtime/engine/sonar-config.d.mts +10 -0
  134. package/runtime/engine/sonar-config.mjs +16 -13
  135. package/runtime/engine/temp-root.d.mts +17 -0
  136. package/runtime/engine/temp-root.mjs +3 -9
  137. package/runtime/engine/yaml.d.mts +9 -0
  138. package/runtime/knowledge/hfs/canon-pins.yaml +10 -10
  139. package/runtime/knowledge/hfs/ci-standard.yaml +2 -2
  140. package/runtime/knowledge/hfs/rules.yaml +72 -6
  141. package/runtime/knowledge/hfs/slots.yaml +3 -3
  142. package/runtime/knowledge/sonar-gate.yaml +1 -1
  143. package/runtime/modules/kernel/failure-codes.yaml +43 -32
  144. package/runtime/modules/schemas/application-stacks.schema.yaml +3 -3
  145. package/runtime/packages/cli/src/catalog.generated.d.mts +13 -0
  146. package/runtime/packages/cli/src/catalog.generated.mjs +1853 -14824
  147. package/runtime/packages/cli/src/validate-args.d.mts +74 -0
  148. package/runtime/packages/cli/src/validate-args.mjs +183 -171
  149. package/runtime/packages/jest-preset/sonar-exclusions.cjs +5 -5
  150. package/runtime/scripts/api/fs/claim-file.d.mts +12 -0
  151. package/runtime/scripts/api/fs/claim-file.mjs +31 -17
  152. package/runtime/scripts/api/fs/ensure-temp-root.d.mts +4 -0
  153. package/runtime/scripts/api/fs/ensure-temp-root.mjs +15 -14
  154. package/runtime/scripts/api/fs/forbidden-root.d.mts +15 -0
  155. package/runtime/scripts/api/fs/forbidden-root.mjs +31 -23
  156. package/runtime/scripts/api/fs/is-link-like.d.mts +10 -0
  157. package/runtime/scripts/api/fs/is-link-like.mjs +25 -11
  158. package/runtime/scripts/api/fs/lib.d.mts +12 -0
  159. package/runtime/scripts/api/fs/lib.mjs +28 -8
  160. package/runtime/scripts/api/fs/make-temp-dir.d.mts +5 -0
  161. package/runtime/scripts/api/fs/make-temp-dir.mjs +3 -4
  162. package/runtime/scripts/api/fs/rename-over.d.mts +13 -0
  163. package/runtime/scripts/api/fs/rename-over.mjs +16 -10
  164. package/runtime/scripts/api/fs/safe-remove.d.mts +25 -0
  165. package/runtime/scripts/api/fs/safe-remove.mjs +129 -71
  166. package/runtime/scripts/api/git/add.d.mts +3 -0
  167. package/runtime/scripts/api/git/add.mjs +0 -1
  168. package/runtime/scripts/api/git/cat-file.d.mts +3 -0
  169. package/runtime/scripts/api/git/cat-file.mjs +0 -1
  170. package/runtime/scripts/api/git/check-ignore.d.mts +3 -0
  171. package/runtime/scripts/api/git/check-ignore.mjs +0 -1
  172. package/runtime/scripts/api/git/commit-tree.d.mts +3 -0
  173. package/runtime/scripts/api/git/commit-tree.mjs +0 -1
  174. package/runtime/scripts/api/git/config-get.d.mts +10 -0
  175. package/runtime/scripts/api/git/config-get.mjs +1 -2
  176. package/runtime/scripts/api/git/diff.d.mts +3 -0
  177. package/runtime/scripts/api/git/diff.mjs +0 -1
  178. package/runtime/scripts/api/git/init.d.mts +7 -0
  179. package/runtime/scripts/api/git/init.mjs +1 -2
  180. package/runtime/scripts/api/git/is-ancestor.d.mts +5 -0
  181. package/runtime/scripts/api/git/is-ancestor.mjs +0 -1
  182. package/runtime/scripts/api/git/lib.d.mts +67 -0
  183. package/runtime/scripts/api/git/lib.mjs +32 -32
  184. package/runtime/scripts/api/git/ls-files.d.mts +3 -0
  185. package/runtime/scripts/api/git/ls-files.mjs +0 -1
  186. package/runtime/scripts/api/git/ls-tree.d.mts +3 -0
  187. package/runtime/scripts/api/git/ls-tree.mjs +0 -1
  188. package/runtime/scripts/api/git/merge-base.d.mts +5 -0
  189. package/runtime/scripts/api/git/merge-base.mjs +2 -3
  190. package/runtime/scripts/api/git/remote.d.mts +3 -0
  191. package/runtime/scripts/api/git/remote.mjs +0 -1
  192. package/runtime/scripts/api/git/rev-parse-query.d.mts +3 -0
  193. package/runtime/scripts/api/git/rev-parse-query.mjs +0 -1
  194. package/runtime/scripts/api/git/show.d.mts +3 -0
  195. package/runtime/scripts/api/git/show.mjs +0 -1
  196. package/runtime/scripts/api/git/tag.d.mts +3 -0
  197. package/runtime/scripts/api/git/tag.mjs +0 -1
  198. package/runtime/scripts/api/git/update-ref.d.mts +7 -0
  199. package/runtime/scripts/api/git/update-ref.mjs +1 -2
  200. package/runtime/scripts/api/git/write-tree.d.mts +3 -0
  201. package/runtime/scripts/api/git/write-tree.mjs +0 -1
  202. package/runtime/scripts/api/node/lib.d.mts +7 -0
  203. package/runtime/scripts/api/node/lib.mjs +17 -7
  204. package/runtime/scripts/api/node/run-node.d.mts +3 -0
  205. package/runtime/scripts/api/node/run-node.mjs +0 -3
  206. package/runtime/scripts/api/process/resolve-real-tool.d.mts +12 -0
  207. package/runtime/scripts/api/process/resolve-real-tool.mjs +46 -38
  208. package/runtime/scripts/api/process/run-program.d.mts +3 -0
  209. package/runtime/scripts/api/process/run-program.mjs +5 -2
  210. package/runtime/scripts/api/sops/decrypt.d.mts +9 -0
  211. package/runtime/scripts/api/sops/decrypt.mjs +1 -2
  212. package/runtime/scripts/api/sops/lib.d.mts +149 -0
  213. package/runtime/scripts/api/sops/lib.mjs +417 -318
  214. package/runtime/scripts/api/sops/resolve-sops.d.mts +3 -0
  215. package/runtime/scripts/api/sops/resolve-sops.mjs +1 -2
  216. package/runtime/scripts/api/sops/seal.d.mts +19 -0
  217. package/runtime/scripts/api/sops/seal.mjs +14 -10
  218. package/runtime/scripts/api/sops/selected-age-recipient.d.mts +3 -0
  219. package/runtime/scripts/api/sops/selected-age-recipient.mjs +1 -2
  220. package/runtime/scripts/api/sops/update-keys.d.mts +16 -0
  221. package/runtime/scripts/api/sops/update-keys.mjs +11 -8
  222. package/runtime/scripts/cli/gen-catalog.d.mts +42 -0
  223. package/runtime/scripts/cli/gen-catalog.mjs +72 -0
  224. package/runtime/scripts/gates/runtime-host.d.mts +23 -0
  225. package/runtime/scripts/gates/runtime-host.mjs +48 -41
  226. package/runtime/scripts/gates/sonar-gate.d.mts +219 -0
  227. package/runtime/scripts/gates/sonar-gate.mjs +166 -153
  228. package/runtime/scripts/gates/starcistacks-ci.d.mts +35 -0
  229. package/runtime/scripts/gates/starcistacks-ci.mjs +47 -39
  230. package/runtime/scripts/gates/starcistacks-form.d.mts +80 -0
  231. package/runtime/scripts/gates/starcistacks-form.mjs +16 -14
  232. package/runtime/scripts/gates/starcistacks-runtime.d.mts +1 -0
  233. package/runtime/scripts/gates/starcistacks-value-file.d.mts +2 -0
  234. package/runtime/scripts/gates/starcistacks-value-file.mjs +14 -11
  235. package/runtime/scripts/gates/starcistacks.d.mts +141 -0
  236. package/runtime/scripts/gates/starcistacks.mjs +470 -355
  237. package/runtime/scripts/guards/git-pathspec.d.mts +48 -0
  238. package/runtime/scripts/guards/git-pathspec.mjs +215 -130
  239. package/runtime/scripts/guards/git-policy.d.mts +30 -0
  240. package/runtime/scripts/guards/git-policy.mjs +278 -235
  241. package/runtime/scripts/guards/hook-io.d.mts +22 -0
  242. package/runtime/scripts/guards/hook-io.mjs +77 -63
  243. package/runtime/scripts/guards/push-scan.d.mts +31 -0
  244. package/runtime/scripts/guards/push-scan.mjs +93 -80
  245. package/runtime/scripts/guards/release-push-gate.d.mts +22 -0
  246. package/runtime/scripts/guards/release-push-gate.mjs +40 -38
  247. package/runtime/scripts/hfs/allows.d.mts +24 -0
  248. package/runtime/scripts/hfs/allows.mjs +37 -38
  249. package/runtime/scripts/hfs/app-wiring.d.mts +72 -0
  250. package/runtime/scripts/hfs/app-wiring.mjs +197 -167
  251. package/runtime/scripts/hfs/architecture/ast-walks.d.mts +89 -0
  252. package/runtime/scripts/hfs/architecture/ast-walks.mjs +180 -163
  253. package/runtime/scripts/hfs/architecture/automatic-gates.d.mts +21 -0
  254. package/runtime/scripts/hfs/architecture/automatic-gates.mjs +80 -73
  255. package/runtime/scripts/hfs/architecture/backend-app-files.d.mts +10 -0
  256. package/runtime/scripts/hfs/architecture/backend-app-files.mjs +88 -77
  257. package/runtime/scripts/hfs/architecture/backend.d.mts +5 -0
  258. package/runtime/scripts/hfs/architecture/backend.mjs +378 -357
  259. package/runtime/scripts/hfs/architecture/background-unowned.d.mts +25 -0
  260. package/runtime/scripts/hfs/architecture/background-unowned.mjs +201 -187
  261. package/runtime/scripts/hfs/architecture/canon-clones.d.mts +8 -0
  262. package/runtime/scripts/hfs/architecture/canon-clones.mjs +260 -209
  263. package/runtime/scripts/hfs/architecture/canon-jsx-clones.d.mts +5 -0
  264. package/runtime/scripts/hfs/architecture/canon-jsx-clones.mjs +149 -116
  265. package/runtime/scripts/hfs/architecture/client-reaches-server.d.mts +28 -0
  266. package/runtime/scripts/hfs/architecture/client-reaches-server.mjs +72 -68
  267. package/runtime/scripts/hfs/architecture/clones.d.mts +54 -0
  268. package/runtime/scripts/hfs/architecture/clones.mjs +212 -217
  269. package/runtime/scripts/hfs/architecture/config-unread.d.mts +14 -0
  270. package/runtime/scripts/hfs/architecture/config-unread.mjs +7 -9
  271. package/runtime/scripts/hfs/architecture/config.d.mts +74 -0
  272. package/runtime/scripts/hfs/architecture/config.mjs +302 -268
  273. package/runtime/scripts/hfs/architecture/connection-map.d.mts +33 -0
  274. package/runtime/scripts/hfs/architecture/connection-map.mjs +258 -225
  275. package/runtime/scripts/hfs/architecture/constructor-deps.d.mts +57 -0
  276. package/runtime/scripts/hfs/architecture/constructor-deps.mjs +80 -71
  277. package/runtime/scripts/hfs/architecture/context-coupling.d.mts +21 -0
  278. package/runtime/scripts/hfs/architecture/context-coupling.mjs +82 -77
  279. package/runtime/scripts/hfs/architecture/context-map.d.mts +102 -0
  280. package/runtime/scripts/hfs/architecture/context-map.mjs +267 -234
  281. package/runtime/scripts/hfs/architecture/context-owner.d.mts +15 -0
  282. package/runtime/scripts/hfs/architecture/context-owner.mjs +73 -61
  283. package/runtime/scripts/hfs/architecture/context-platform-tables.d.mts +18 -0
  284. package/runtime/scripts/hfs/architecture/context-platform-tables.mjs +47 -43
  285. package/runtime/scripts/hfs/architecture/context-transaction.d.mts +20 -0
  286. package/runtime/scripts/hfs/architecture/context-transaction.mjs +54 -52
  287. package/runtime/scripts/hfs/architecture/contract-fixture-guard.d.mts +37 -0
  288. package/runtime/scripts/hfs/architecture/contract-fixture-guard.mjs +113 -104
  289. package/runtime/scripts/hfs/architecture/contracts-readonly.d.mts +32 -0
  290. package/runtime/scripts/hfs/architecture/contracts-readonly.mjs +288 -270
  291. package/runtime/scripts/hfs/architecture/contracts.d.mts +30 -0
  292. package/runtime/scripts/hfs/architecture/contracts.mjs +408 -393
  293. package/runtime/scripts/hfs/architecture/cross-app-duplicate.d.mts +27 -0
  294. package/runtime/scripts/hfs/architecture/cross-app-duplicate.mjs +50 -51
  295. package/runtime/scripts/hfs/architecture/dead-exports-bindings.d.mts +21 -0
  296. package/runtime/scripts/hfs/architecture/dead-exports-bindings.mjs +143 -119
  297. package/runtime/scripts/hfs/architecture/dead-exports.d.mts +32 -0
  298. package/runtime/scripts/hfs/architecture/dead-exports.mjs +286 -228
  299. package/runtime/scripts/hfs/architecture/default-deny.d.mts +21 -0
  300. package/runtime/scripts/hfs/architecture/default-deny.mjs +129 -110
  301. package/runtime/scripts/hfs/architecture/doc-language.d.mts +17 -0
  302. package/runtime/scripts/hfs/architecture/doc-language.mjs +24 -19
  303. package/runtime/scripts/hfs/architecture/entity-registry.d.mts +49 -0
  304. package/runtime/scripts/hfs/architecture/entity-registry.mjs +20 -22
  305. package/runtime/scripts/hfs/architecture/entrypoint.d.mts +13 -0
  306. package/runtime/scripts/hfs/architecture/entrypoint.mjs +47 -45
  307. package/runtime/scripts/hfs/architecture/error-codes.d.mts +16 -0
  308. package/runtime/scripts/hfs/architecture/error-codes.mjs +37 -35
  309. package/runtime/scripts/hfs/architecture/error-masked.d.mts +16 -0
  310. package/runtime/scripts/hfs/architecture/error-masked.mjs +55 -59
  311. package/runtime/scripts/hfs/architecture/fe-slot-allows.d.mts +38 -0
  312. package/runtime/scripts/hfs/architecture/fe-slot-allows.mjs +24 -23
  313. package/runtime/scripts/hfs/architecture/feature-shape.d.mts +26 -0
  314. package/runtime/scripts/hfs/architecture/feature-shape.mjs +40 -38
  315. package/runtime/scripts/hfs/architecture/framework-pinned.d.mts +3 -0
  316. package/runtime/scripts/hfs/architecture/framework-pinned.mjs +21 -21
  317. package/runtime/scripts/hfs/architecture/frontend-block-render.d.mts +26 -0
  318. package/runtime/scripts/hfs/architecture/frontend-block-render.mjs +106 -98
  319. package/runtime/scripts/hfs/architecture/frontend-grammar.d.mts +7 -0
  320. package/runtime/scripts/hfs/architecture/frontend-grammar.mjs +153 -150
  321. package/runtime/scripts/hfs/architecture/frontend-routing.d.mts +23 -0
  322. package/runtime/scripts/hfs/architecture/frontend-routing.mjs +161 -149
  323. package/runtime/scripts/hfs/architecture/frontend-world-render.d.mts +72 -0
  324. package/runtime/scripts/hfs/architecture/frontend-world-render.mjs +343 -305
  325. package/runtime/scripts/hfs/architecture/frontend-world.d.mts +94 -0
  326. package/runtime/scripts/hfs/architecture/frontend-world.mjs +340 -294
  327. package/runtime/scripts/hfs/architecture/frontend.d.mts +31 -0
  328. package/runtime/scripts/hfs/architecture/frontend.mjs +174 -184
  329. package/runtime/scripts/hfs/architecture/function-spec-providers.d.mts +27 -0
  330. package/runtime/scripts/hfs/architecture/function-spec-providers.mjs +124 -106
  331. package/runtime/scripts/hfs/architecture/hfs-graph.d.mts +78 -0
  332. package/runtime/scripts/hfs/architecture/hfs-graph.mjs +52 -48
  333. package/runtime/scripts/hfs/architecture/hfs.d.mts +135 -0
  334. package/runtime/scripts/hfs/architecture/hfs.mjs +328 -282
  335. package/runtime/scripts/hfs/architecture/hooks-are-hooks.d.mts +24 -0
  336. package/runtime/scripts/hfs/architecture/hooks-are-hooks.mjs +81 -71
  337. package/runtime/scripts/hfs/architecture/i18n-keys.d.mts +31 -0
  338. package/runtime/scripts/hfs/architecture/i18n-keys.mjs +155 -141
  339. package/runtime/scripts/hfs/architecture/identity.d.mts +7 -0
  340. package/runtime/scripts/hfs/architecture/identity.mjs +141 -125
  341. package/runtime/scripts/hfs/architecture/index.d.mts +101 -0
  342. package/runtime/scripts/hfs/architecture/index.mjs +272 -272
  343. package/runtime/scripts/hfs/architecture/injection-token-exported.d.mts +21 -0
  344. package/runtime/scripts/hfs/architecture/injection-token-exported.mjs +45 -43
  345. package/runtime/scripts/hfs/architecture/jwt-ast.d.mts +16 -0
  346. package/runtime/scripts/hfs/architecture/jwt-ast.mjs +195 -176
  347. package/runtime/scripts/hfs/architecture/machine-ast.d.mts +88 -0
  348. package/runtime/scripts/hfs/architecture/machine-ast.mjs +163 -155
  349. package/runtime/scripts/hfs/architecture/managed-scripts.d.mts +2 -0
  350. package/runtime/scripts/hfs/architecture/managed-scripts.mjs +19 -20
  351. package/runtime/scripts/hfs/architecture/module-per-transport.d.mts +35 -0
  352. package/runtime/scripts/hfs/architecture/module-per-transport.mjs +177 -172
  353. package/runtime/scripts/hfs/architecture/next-data-contract.d.mts +35 -0
  354. package/runtime/scripts/hfs/architecture/next-data-contract.mjs +100 -78
  355. package/runtime/scripts/hfs/architecture/next-data-inference.d.mts +39 -0
  356. package/runtime/scripts/hfs/architecture/next-data-inference.mjs +170 -154
  357. package/runtime/scripts/hfs/architecture/next-data-key.d.mts +50 -0
  358. package/runtime/scripts/hfs/architecture/next-data-key.mjs +311 -275
  359. package/runtime/scripts/hfs/architecture/next-data-symbols.d.mts +5 -0
  360. package/runtime/scripts/hfs/architecture/next-data-symbols.mjs +17 -17
  361. package/runtime/scripts/hfs/architecture/next-data.d.mts +36 -0
  362. package/runtime/scripts/hfs/architecture/next-data.mjs +351 -334
  363. package/runtime/scripts/hfs/architecture/operation-contract-roots.d.mts +10 -0
  364. package/runtime/scripts/hfs/architecture/operation-contract-roots.mjs +39 -37
  365. package/runtime/scripts/hfs/architecture/owners.d.mts +5 -0
  366. package/runtime/scripts/hfs/architecture/owners.mjs +97 -98
  367. package/runtime/scripts/hfs/architecture/package-shape.d.mts +26 -0
  368. package/runtime/scripts/hfs/architecture/package-shape.mjs +56 -55
  369. package/runtime/scripts/hfs/architecture/presentation.d.mts +24 -0
  370. package/runtime/scripts/hfs/architecture/presentation.mjs +138 -130
  371. package/runtime/scripts/hfs/architecture/reachability.d.mts +25 -0
  372. package/runtime/scripts/hfs/architecture/reachability.mjs +258 -241
  373. package/runtime/scripts/hfs/architecture/register-once.d.mts +18 -0
  374. package/runtime/scripts/hfs/architecture/register-once.mjs +152 -139
  375. package/runtime/scripts/hfs/architecture/registration.d.mts +15 -0
  376. package/runtime/scripts/hfs/architecture/registration.mjs +301 -267
  377. package/runtime/scripts/hfs/architecture/required-files.d.mts +64 -0
  378. package/runtime/scripts/hfs/architecture/required-files.mjs +172 -167
  379. package/runtime/scripts/hfs/architecture/route-files-thin.d.mts +23 -0
  380. package/runtime/scripts/hfs/architecture/route-files-thin.mjs +85 -77
  381. package/runtime/scripts/hfs/architecture/schema-owner.d.mts +34 -0
  382. package/runtime/scripts/hfs/architecture/schema-owner.mjs +206 -181
  383. package/runtime/scripts/hfs/architecture/server-action.d.mts +22 -0
  384. package/runtime/scripts/hfs/architecture/server-action.mjs +48 -48
  385. package/runtime/scripts/hfs/architecture/side-boundary.d.mts +3 -0
  386. package/runtime/scripts/hfs/architecture/side-boundary.mjs +2 -5
  387. package/runtime/scripts/hfs/architecture/source-names-shape.d.mts +85 -0
  388. package/runtime/scripts/hfs/architecture/source-names-shape.mjs +261 -259
  389. package/runtime/scripts/hfs/architecture/source-names.d.mts +7 -0
  390. package/runtime/scripts/hfs/architecture/source-names.mjs +304 -278
  391. package/runtime/scripts/hfs/architecture/sql-keys.d.mts +5 -0
  392. package/runtime/scripts/hfs/architecture/sql-keys.mjs +277 -194
  393. package/runtime/scripts/hfs/architecture/sql-owner.d.mts +30 -0
  394. package/runtime/scripts/hfs/architecture/sql-owner.mjs +236 -194
  395. package/runtime/scripts/hfs/architecture/sql-returning.d.mts +22 -0
  396. package/runtime/scripts/hfs/architecture/sql-returning.mjs +46 -45
  397. package/runtime/scripts/hfs/architecture/sql-token-forms.d.mts +21 -0
  398. package/runtime/scripts/hfs/architecture/sql-token-forms.mjs +86 -74
  399. package/runtime/scripts/hfs/architecture/sql-tokens.d.mts +32 -0
  400. package/runtime/scripts/hfs/architecture/sql-tokens.mjs +456 -341
  401. package/runtime/scripts/hfs/architecture/staged-consumers.d.mts +7 -0
  402. package/runtime/scripts/hfs/architecture/staged-consumers.mjs +35 -30
  403. package/runtime/scripts/hfs/architecture/surface.d.mts +26 -0
  404. package/runtime/scripts/hfs/architecture/surface.mjs +64 -74
  405. package/runtime/scripts/hfs/architecture/symbols.d.mts +11 -0
  406. package/runtime/scripts/hfs/architecture/symbols.mjs +209 -216
  407. package/runtime/scripts/hfs/architecture/test-world-files.d.mts +45 -0
  408. package/runtime/scripts/hfs/architecture/test-world-files.mjs +165 -155
  409. package/runtime/scripts/hfs/architecture/tiers.d.mts +29 -0
  410. package/runtime/scripts/hfs/architecture/tiers.mjs +161 -154
  411. package/runtime/scripts/hfs/architecture/transport-owner.d.mts +37 -0
  412. package/runtime/scripts/hfs/architecture/transport-owner.mjs +155 -149
  413. package/runtime/scripts/hfs/architecture/type-context.d.mts +60 -0
  414. package/runtime/scripts/hfs/architecture/type-context.mjs +255 -250
  415. package/runtime/scripts/hfs/architecture/typescript.d.mts +94 -0
  416. package/runtime/scripts/hfs/architecture/typescript.mjs +358 -318
  417. package/runtime/scripts/hfs/architecture/unit-spec-providers.d.mts +34 -0
  418. package/runtime/scripts/hfs/architecture/unit-spec-providers.mjs +110 -92
  419. package/runtime/scripts/hfs/architecture.d.mts +13 -0
  420. package/runtime/scripts/hfs/architecture.mjs +39 -29
  421. package/runtime/scripts/hfs/canon-pins.d.mts +26 -0
  422. package/runtime/scripts/hfs/canon-pins.mjs +5 -8
  423. package/runtime/scripts/hfs/catalog-once.d.mts +2 -0
  424. package/runtime/scripts/hfs/catalog-once.mjs +8 -9
  425. package/runtime/scripts/hfs/check-results.d.mts +29 -0
  426. package/runtime/scripts/hfs/check-results.mjs +14 -18
  427. package/runtime/scripts/hfs/check.d.mts +144 -0
  428. package/runtime/scripts/hfs/check.mjs +309 -329
  429. package/runtime/scripts/hfs/ci-declaration.d.mts +77 -0
  430. package/runtime/scripts/hfs/ci-declaration.mjs +99 -87
  431. package/runtime/scripts/hfs/coverage-from.d.mts +22 -0
  432. package/runtime/scripts/hfs/coverage-from.mjs +52 -49
  433. package/runtime/scripts/hfs/coverage-scope.d.mts +87 -0
  434. package/runtime/scripts/hfs/coverage-scope.mjs +139 -142
  435. package/runtime/scripts/hfs/db-baseline-verb.d.mts +84 -0
  436. package/runtime/scripts/hfs/db-baseline-verb.mjs +327 -266
  437. package/runtime/scripts/hfs/db-errors.d.mts +2 -0
  438. package/runtime/scripts/hfs/db-errors.mjs +2 -1
  439. package/runtime/scripts/hfs/db-plan-verb.d.mts +33 -0
  440. package/runtime/scripts/hfs/db-plan-verb.mjs +174 -128
  441. package/runtime/scripts/hfs/db-restamp-verb.d.mts +5 -0
  442. package/runtime/scripts/hfs/db-restamp-verb.mjs +94 -70
  443. package/runtime/scripts/hfs/db-squash.d.mts +117 -0
  444. package/runtime/scripts/hfs/db-squash.mjs +414 -351
  445. package/runtime/scripts/hfs/declaration-shape.d.mts +3 -0
  446. package/runtime/scripts/hfs/declaration-shape.mjs +140 -103
  447. package/runtime/scripts/hfs/declaration-slots.d.mts +18 -0
  448. package/runtime/scripts/hfs/declaration-slots.mjs +64 -61
  449. package/runtime/scripts/hfs/doc-commands.d.mts +71 -0
  450. package/runtime/scripts/hfs/doc-commands.mjs +257 -250
  451. package/runtime/scripts/hfs/edition-slots.d.mts +37 -0
  452. package/runtime/scripts/hfs/edition-slots.mjs +43 -40
  453. package/runtime/scripts/hfs/example-secrets.d.mts +18 -0
  454. package/runtime/scripts/hfs/example-secrets.mjs +173 -154
  455. package/runtime/scripts/hfs/gate-threshold.d.mts +20 -0
  456. package/runtime/scripts/hfs/gate-threshold.mjs +28 -0
  457. package/runtime/scripts/hfs/grammar-presentation.d.mts +74 -0
  458. package/runtime/scripts/hfs/grammar-presentation.mjs +109 -106
  459. package/runtime/scripts/hfs/linear-text.d.mts +6 -0
  460. package/runtime/scripts/hfs/linear-text.mjs +20 -20
  461. package/runtime/scripts/hfs/manifest-shape.d.mts +216 -0
  462. package/runtime/scripts/hfs/manifest-shape.mjs +399 -324
  463. package/runtime/scripts/hfs/param-names.d.mts +3 -0
  464. package/runtime/scripts/hfs/param-names.mjs +6 -11
  465. package/runtime/scripts/hfs/path-findings.d.mts +22 -0
  466. package/runtime/scripts/hfs/path-findings.mjs +120 -100
  467. package/runtime/scripts/hfs/pin-findings.d.mts +19 -0
  468. package/runtime/scripts/hfs/pin-findings.mjs +26 -21
  469. package/runtime/scripts/hfs/refusal-codes.d.mts +1 -0
  470. package/runtime/scripts/hfs/refusal-codes.mjs +2 -2
  471. package/runtime/scripts/hfs/repo-identity.d.mts +15 -0
  472. package/runtime/scripts/hfs/repo-identity.mjs +55 -42
  473. package/runtime/scripts/hfs/rule-catalog.d.mts +77 -0
  474. package/runtime/scripts/hfs/rule-catalog.mjs +353 -257
  475. package/runtime/scripts/hfs/rule-params-shape.d.mts +10 -0
  476. package/runtime/scripts/hfs/rule-params-shape.mjs +60 -47
  477. package/runtime/scripts/hfs/rules/a15-findings.d.mts +18 -0
  478. package/runtime/scripts/hfs/rules/a15-findings.mjs +59 -55
  479. package/runtime/scripts/hfs/rules/app-env-required.d.mts +9 -0
  480. package/runtime/scripts/hfs/rules/app-env-required.mjs +13 -13
  481. package/runtime/scripts/hfs/rules/app-root.d.mts +15 -0
  482. package/runtime/scripts/hfs/rules/app-root.mjs +20 -21
  483. package/runtime/scripts/hfs/rules/app-workflow-findings.d.mts +12 -0
  484. package/runtime/scripts/hfs/rules/app-workflow-findings.mjs +4 -4
  485. package/runtime/scripts/hfs/rules/assets.d.mts +13 -0
  486. package/runtime/scripts/hfs/rules/assets.mjs +58 -46
  487. package/runtime/scripts/hfs/rules/boot-proof.d.mts +11 -0
  488. package/runtime/scripts/hfs/rules/boot-proof.mjs +7 -8
  489. package/runtime/scripts/hfs/rules/bypass-markers.d.mts +9 -0
  490. package/runtime/scripts/hfs/rules/bypass-markers.mjs +7 -12
  491. package/runtime/scripts/hfs/rules/canon-copy-drift.d.mts +10 -0
  492. package/runtime/scripts/hfs/rules/canon-copy-drift.mjs +70 -68
  493. package/runtime/scripts/hfs/rules/ci-custody.d.mts +7 -0
  494. package/runtime/scripts/hfs/rules/ci-custody.mjs +72 -73
  495. package/runtime/scripts/hfs/rules/ci-standard.d.mts +12 -0
  496. package/runtime/scripts/hfs/rules/ci-standard.mjs +149 -142
  497. package/runtime/scripts/hfs/rules/cli.d.mts +7 -0
  498. package/runtime/scripts/hfs/rules/cli.mjs +24 -23
  499. package/runtime/scripts/hfs/rules/contract-compat.d.mts +11 -0
  500. package/runtime/scripts/hfs/rules/contract-compat.mjs +64 -53
  501. package/runtime/scripts/hfs/rules/contract.d.mts +26 -0
  502. package/runtime/scripts/hfs/rules/contract.mjs +126 -111
  503. package/runtime/scripts/hfs/rules/coverage-below.d.mts +17 -0
  504. package/runtime/scripts/hfs/rules/coverage-below.mjs +200 -167
  505. package/runtime/scripts/hfs/rules/database-access.d.mts +12 -0
  506. package/runtime/scripts/hfs/rules/database-access.mjs +231 -202
  507. package/runtime/scripts/hfs/rules/database-baseline.d.mts +22 -0
  508. package/runtime/scripts/hfs/rules/database-baseline.mjs +104 -104
  509. package/runtime/scripts/hfs/rules/database-config.d.mts +11 -0
  510. package/runtime/scripts/hfs/rules/database-config.mjs +101 -135
  511. package/runtime/scripts/hfs/rules/database-constants.d.mts +36 -0
  512. package/runtime/scripts/hfs/rules/database-constants.mjs +7 -7
  513. package/runtime/scripts/hfs/rules/database-migrations.d.mts +41 -0
  514. package/runtime/scripts/hfs/rules/database-migrations.mjs +428 -388
  515. package/runtime/scripts/hfs/rules/database-plpgsql.d.mts +5 -0
  516. package/runtime/scripts/hfs/rules/database-plpgsql.mjs +278 -259
  517. package/runtime/scripts/hfs/rules/database-queue-sources.d.mts +4 -0
  518. package/runtime/scripts/hfs/rules/database-queue-sources.mjs +48 -43
  519. package/runtime/scripts/hfs/rules/database-queues.d.mts +15 -0
  520. package/runtime/scripts/hfs/rules/database-queues.mjs +211 -182
  521. package/runtime/scripts/hfs/rules/database-sql.d.mts +16 -0
  522. package/runtime/scripts/hfs/rules/database-sql.mjs +394 -394
  523. package/runtime/scripts/hfs/rules/database-transaction.d.mts +3 -0
  524. package/runtime/scripts/hfs/rules/database-transaction.mjs +25 -27
  525. package/runtime/scripts/hfs/rules/database.d.mts +22 -0
  526. package/runtime/scripts/hfs/rules/database.mjs +42 -58
  527. package/runtime/scripts/hfs/rules/deploy-scan.d.mts +10 -0
  528. package/runtime/scripts/hfs/rules/deploy-scan.mjs +177 -168
  529. package/runtime/scripts/hfs/rules/deploy-workflow.d.mts +3 -0
  530. package/runtime/scripts/hfs/rules/deploy-workflow.mjs +194 -171
  531. package/runtime/scripts/hfs/rules/deps.d.mts +6 -0
  532. package/runtime/scripts/hfs/rules/deps.mjs +61 -60
  533. package/runtime/scripts/hfs/rules/doc-fresh.d.mts +11 -0
  534. package/runtime/scripts/hfs/rules/doc-fresh.mjs +242 -223
  535. package/runtime/scripts/hfs/rules/docker-health.d.mts +9 -0
  536. package/runtime/scripts/hfs/rules/docker-health.mjs +222 -196
  537. package/runtime/scripts/hfs/rules/docker.d.mts +13 -0
  538. package/runtime/scripts/hfs/rules/docker.mjs +234 -208
  539. package/runtime/scripts/hfs/rules/edition.d.mts +18 -0
  540. package/runtime/scripts/hfs/rules/edition.mjs +103 -101
  541. package/runtime/scripts/hfs/rules/env-parity.d.mts +25 -0
  542. package/runtime/scripts/hfs/rules/env-parity.mjs +278 -252
  543. package/runtime/scripts/hfs/rules/env-value-shape.d.mts +21 -0
  544. package/runtime/scripts/hfs/rules/env-value-shape.mjs +82 -67
  545. package/runtime/scripts/hfs/rules/event-bus.d.mts +17 -0
  546. package/runtime/scripts/hfs/rules/event-bus.mjs +145 -133
  547. package/runtime/scripts/hfs/rules/event-tables.d.mts +7 -0
  548. package/runtime/scripts/hfs/rules/event-tables.mjs +77 -75
  549. package/runtime/scripts/hfs/rules/fe-build-args.d.mts +10 -0
  550. package/runtime/scripts/hfs/rules/fe-build-args.mjs +116 -99
  551. package/runtime/scripts/hfs/rules/fe-contract-documents.d.mts +7 -0
  552. package/runtime/scripts/hfs/rules/fe-contract-documents.mjs +121 -111
  553. package/runtime/scripts/hfs/rules/fe-no-tests.d.mts +9 -0
  554. package/runtime/scripts/hfs/rules/fe-no-tests.mjs +37 -36
  555. package/runtime/scripts/hfs/rules/fe-stack.d.mts +23 -0
  556. package/runtime/scripts/hfs/rules/fe-stack.mjs +108 -105
  557. package/runtime/scripts/hfs/rules/feature-files.d.mts +10 -0
  558. package/runtime/scripts/hfs/rules/feature-files.mjs +14 -19
  559. package/runtime/scripts/hfs/rules/frontend-tree.d.mts +18 -0
  560. package/runtime/scripts/hfs/rules/frontend-tree.mjs +105 -91
  561. package/runtime/scripts/hfs/rules/integration-specs.d.mts +7 -0
  562. package/runtime/scripts/hfs/rules/integration-specs.mjs +190 -177
  563. package/runtime/scripts/hfs/rules/kinds.d.mts +6 -0
  564. package/runtime/scripts/hfs/rules/kinds.mjs +88 -81
  565. package/runtime/scripts/hfs/rules/lexicon.d.mts +9 -0
  566. package/runtime/scripts/hfs/rules/lexicon.mjs +43 -40
  567. package/runtime/scripts/hfs/rules/lint-suppression.d.mts +5 -0
  568. package/runtime/scripts/hfs/rules/lint-suppression.mjs +22 -20
  569. package/runtime/scripts/hfs/rules/lite-proof-lane.d.mts +9 -0
  570. package/runtime/scripts/hfs/rules/lite-proof-lane.mjs +59 -58
  571. package/runtime/scripts/hfs/rules/lite-secrets.d.mts +12 -0
  572. package/runtime/scripts/hfs/rules/lite-secrets.mjs +60 -63
  573. package/runtime/scripts/hfs/rules/mcp-tools.d.mts +7 -0
  574. package/runtime/scripts/hfs/rules/mcp-tools.mjs +56 -41
  575. package/runtime/scripts/hfs/rules/monorepo.d.mts +17 -0
  576. package/runtime/scripts/hfs/rules/monorepo.mjs +153 -138
  577. package/runtime/scripts/hfs/rules/peer-integrations.d.mts +7 -0
  578. package/runtime/scripts/hfs/rules/peer-integrations.mjs +39 -36
  579. package/runtime/scripts/hfs/rules/pipeline.d.mts +7 -0
  580. package/runtime/scripts/hfs/rules/pipeline.mjs +53 -53
  581. package/runtime/scripts/hfs/rules/proof-commands.d.mts +14 -0
  582. package/runtime/scripts/hfs/rules/proof-commands.mjs +52 -41
  583. package/runtime/scripts/hfs/rules/read.d.mts +7 -0
  584. package/runtime/scripts/hfs/rules/read.mjs +19 -15
  585. package/runtime/scripts/hfs/rules/release-provenance.d.mts +12 -0
  586. package/runtime/scripts/hfs/rules/release-provenance.mjs +196 -159
  587. package/runtime/scripts/hfs/rules/repo-local-checks.d.mts +5 -0
  588. package/runtime/scripts/hfs/rules/repo-local-checks.mjs +19 -17
  589. package/runtime/scripts/hfs/rules/rule-types.d.mts +40 -0
  590. package/runtime/scripts/hfs/rules/rule-types.mjs +4 -0
  591. package/runtime/scripts/hfs/rules/saga-delivery.d.mts +2 -0
  592. package/runtime/scripts/hfs/rules/saga-delivery.mjs +58 -50
  593. package/runtime/scripts/hfs/rules/saga.d.mts +7 -0
  594. package/runtime/scripts/hfs/rules/saga.mjs +151 -145
  595. package/runtime/scripts/hfs/rules/script-hygiene.d.mts +11 -0
  596. package/runtime/scripts/hfs/rules/script-hygiene.mjs +112 -95
  597. package/runtime/scripts/hfs/rules/secret-custody-only.d.mts +7 -0
  598. package/runtime/scripts/hfs/rules/secret-custody-only.mjs +29 -35
  599. package/runtime/scripts/hfs/rules/secrets.d.mts +29 -0
  600. package/runtime/scripts/hfs/rules/secrets.mjs +45 -44
  601. package/runtime/scripts/hfs/rules/services.d.mts +7 -0
  602. package/runtime/scripts/hfs/rules/services.mjs +148 -148
  603. package/runtime/scripts/hfs/rules/spec-placement.d.mts +8 -0
  604. package/runtime/scripts/hfs/rules/spec-placement.mjs +12 -13
  605. package/runtime/scripts/hfs/rules/stack-tooling.d.mts +11 -0
  606. package/runtime/scripts/hfs/rules/stack-tooling.mjs +45 -52
  607. package/runtime/scripts/hfs/rules/stacks-auth-cookie-domain.d.mts +30 -0
  608. package/runtime/scripts/hfs/rules/stacks-auth-cookie-domain.mjs +149 -0
  609. package/runtime/scripts/hfs/rules/stacks-deploy.d.mts +7 -0
  610. package/runtime/scripts/hfs/rules/stacks-deploy.mjs +32 -42
  611. package/runtime/scripts/hfs/rules/stacks-ingress.d.mts +16 -0
  612. package/runtime/scripts/hfs/rules/stacks-ingress.mjs +62 -64
  613. package/runtime/scripts/hfs/rules/stacks-lite-backing.d.mts +17 -0
  614. package/runtime/scripts/hfs/rules/stacks-lite-backing.mjs +111 -116
  615. package/runtime/scripts/hfs/rules/stacks-release.d.mts +26 -0
  616. package/runtime/scripts/hfs/rules/stacks-release.mjs +335 -309
  617. package/runtime/scripts/hfs/rules/stacks-runtime.d.mts +31 -0
  618. package/runtime/scripts/hfs/rules/stacks-runtime.mjs +130 -124
  619. package/runtime/scripts/hfs/rules/stacks-swarm.d.mts +5 -0
  620. package/runtime/scripts/hfs/rules/stacks-swarm.mjs +366 -344
  621. package/runtime/scripts/hfs/rules/stacks.d.mts +7 -0
  622. package/runtime/scripts/hfs/rules/stacks.mjs +37 -38
  623. package/runtime/scripts/hfs/rules/staged-specs.d.mts +10 -0
  624. package/runtime/scripts/hfs/rules/staged-specs.mjs +14 -18
  625. package/runtime/scripts/hfs/rules/supply-chain.d.mts +10 -0
  626. package/runtime/scripts/hfs/rules/supply-chain.mjs +143 -150
  627. package/runtime/scripts/hfs/rules/test-topology.d.mts +5 -0
  628. package/runtime/scripts/hfs/rules/test-topology.mjs +23 -21
  629. package/runtime/scripts/hfs/rules/text-integrity.d.mts +9 -0
  630. package/runtime/scripts/hfs/rules/text-integrity.mjs +47 -43
  631. package/runtime/scripts/hfs/rules/unused-symbol-flow.d.mts +22 -0
  632. package/runtime/scripts/hfs/rules/unused-symbol-flow.mjs +226 -204
  633. package/runtime/scripts/hfs/rules/unused-symbol-ledger.d.mts +7 -0
  634. package/runtime/scripts/hfs/rules/unused-symbol-ledger.mjs +70 -49
  635. package/runtime/scripts/hfs/rules/unused-symbol-properties.d.mts +12 -0
  636. package/runtime/scripts/hfs/rules/unused-symbol-properties.mjs +141 -126
  637. package/runtime/scripts/hfs/rules/unused-symbol-translators.d.mts +8 -0
  638. package/runtime/scripts/hfs/rules/unused-symbol-translators.mjs +160 -140
  639. package/runtime/scripts/hfs/rules/unused-symbol-values.d.mts +9 -0
  640. package/runtime/scripts/hfs/rules/unused-symbol-values.mjs +138 -125
  641. package/runtime/scripts/hfs/rules/unused-symbol.d.mts +11 -0
  642. package/runtime/scripts/hfs/rules/unused-symbol.mjs +283 -253
  643. package/runtime/scripts/hfs/rules/workflow-contexts.d.mts +8 -0
  644. package/runtime/scripts/hfs/rules/workflow-contexts.mjs +79 -67
  645. package/runtime/scripts/hfs/runtime-rules/git-triggers.d.mts +6 -0
  646. package/runtime/scripts/hfs/runtime-rules/git-triggers.mjs +36 -35
  647. package/runtime/scripts/hfs/runtime-rules/hook-shape.d.mts +10 -0
  648. package/runtime/scripts/hfs/runtime-rules/hook-shape.mjs +45 -42
  649. package/runtime/scripts/hfs/runtime-rules/source-ast.d.mts +39 -0
  650. package/runtime/scripts/hfs/runtime-rules/source-ast.mjs +130 -116
  651. package/runtime/scripts/hfs/runtime-rules/workflow-source.d.mts +5 -0
  652. package/runtime/scripts/hfs/runtime-rules/workflow-source.mjs +8 -7
  653. package/runtime/scripts/hfs/sealed-members.d.mts +22 -0
  654. package/runtime/scripts/hfs/sealed-members.mjs +79 -75
  655. package/runtime/scripts/hfs/secret-bootstrap-crypto.d.mts +12 -0
  656. package/runtime/scripts/hfs/secret-bootstrap-crypto.mjs +151 -167
  657. package/runtime/scripts/hfs/secret-document.d.mts +16 -0
  658. package/runtime/scripts/hfs/secret-document.mjs +59 -75
  659. package/runtime/scripts/hfs/secret-edit.d.mts +14 -0
  660. package/runtime/scripts/hfs/secret-edit.mjs +115 -135
  661. package/runtime/scripts/hfs/secret-errors.d.mts +4 -0
  662. package/runtime/scripts/hfs/secret-errors.mjs +19 -16
  663. package/runtime/scripts/hfs/secret-files.d.mts +20 -0
  664. package/runtime/scripts/hfs/secret-files.mjs +103 -112
  665. package/runtime/scripts/hfs/secret-init.d.mts +108 -0
  666. package/runtime/scripts/hfs/secret-init.mjs +304 -346
  667. package/runtime/scripts/hfs/secret-output.d.mts +18 -0
  668. package/runtime/scripts/hfs/secret-output.mjs +52 -80
  669. package/runtime/scripts/hfs/secret-prompt.d.mts +39 -0
  670. package/runtime/scripts/hfs/secret-prompt.mjs +108 -93
  671. package/runtime/scripts/hfs/secret-sops.d.mts +29 -0
  672. package/runtime/scripts/hfs/secret-sops.mjs +161 -199
  673. package/runtime/scripts/hfs/secret-standard.d.mts +89 -0
  674. package/runtime/scripts/hfs/secret-standard.mjs +300 -264
  675. package/runtime/scripts/hfs/secret-store.d.mts +36 -0
  676. package/runtime/scripts/hfs/secret-store.mjs +120 -136
  677. package/runtime/scripts/hfs/secret.d.mts +40 -0
  678. package/runtime/scripts/hfs/secret.mjs +254 -222
  679. package/runtime/scripts/hfs/slot-app-view.d.mts +11 -0
  680. package/runtime/scripts/hfs/slot-app-view.mjs +69 -74
  681. package/runtime/scripts/hfs/slot-classify.d.mts +75 -0
  682. package/runtime/scripts/hfs/slot-classify.mjs +42 -38
  683. package/runtime/scripts/hfs/slot-errors.d.mts +6 -0
  684. package/runtime/scripts/hfs/slot-errors.mjs +8 -7
  685. package/runtime/scripts/hfs/slot-imports.d.mts +8 -0
  686. package/runtime/scripts/hfs/slot-imports.mjs +70 -63
  687. package/runtime/scripts/hfs/slot-manifest-shape.d.mts +9 -0
  688. package/runtime/scripts/hfs/slot-manifest-shape.mjs +74 -52
  689. package/runtime/scripts/hfs/slot-match.d.mts +50 -0
  690. package/runtime/scripts/hfs/slot-match.mjs +122 -111
  691. package/runtime/scripts/hfs/slot-path.d.mts +1 -0
  692. package/runtime/scripts/hfs/slot-path.mjs +0 -2
  693. package/runtime/scripts/hfs/slot-required.d.mts +11 -0
  694. package/runtime/scripts/hfs/slot-required.mjs +65 -59
  695. package/runtime/scripts/hfs/slot-semantic-problems.d.mts +9 -0
  696. package/runtime/scripts/hfs/slot-semantic-problems.mjs +138 -112
  697. package/runtime/scripts/hfs/slot-side-problems.d.mts +3 -0
  698. package/runtime/scripts/hfs/slot-side-problems.mjs +23 -19
  699. package/runtime/scripts/hfs/slots.d.mts +188 -0
  700. package/runtime/scripts/hfs/slots.mjs +175 -152
  701. package/runtime/scripts/hfs/sql/pg-parse.d.mts +9 -0
  702. package/runtime/scripts/hfs/sql/pg-parse.mjs +25 -25
  703. package/runtime/scripts/hfs/stack-config-kit.d.mts +22 -0
  704. package/runtime/scripts/hfs/stack-config-kit.mjs +21 -17
  705. package/runtime/scripts/hfs/stack-deploy-config.d.mts +155 -0
  706. package/runtime/scripts/hfs/stack-deploy-config.mjs +345 -273
  707. package/runtime/scripts/hfs/stack-ingress-config.d.mts +74 -0
  708. package/runtime/scripts/hfs/stack-ingress-config.mjs +211 -177
  709. package/runtime/scripts/hfs/stacks-gate.d.mts +52 -0
  710. package/runtime/scripts/hfs/stacks-gate.mjs +557 -397
  711. package/runtime/scripts/hfs/starcistacks-runtime.d.mts +7 -0
  712. package/runtime/scripts/hfs/starcistacks-runtime.mjs +51 -40
  713. package/runtime/scripts/hfs/test-world-slot.d.mts +2 -0
  714. package/runtime/scripts/hfs/test-world-slot.mjs +0 -1
  715. package/runtime/scripts/hfs/trailing-slashes.d.mts +2 -0
  716. package/runtime/scripts/hfs/trailing-slashes.mjs +4 -4
  717. package/runtime/scripts/hfs/tree-findings.d.mts +9 -0
  718. package/runtime/scripts/hfs/tree-findings.mjs +18 -17
  719. package/runtime/scripts/hfs/tree.d.mts +35 -0
  720. package/runtime/scripts/hfs/tree.mjs +56 -46
  721. package/runtime/scripts/hfs/typescript-programs.d.mts +36 -0
  722. package/runtime/scripts/hfs/typescript-programs.mjs +66 -69
  723. package/runtime/scripts/hfs/view.d.mts +45 -0
  724. package/runtime/scripts/hfs/view.mjs +38 -40
  725. package/runtime/scripts/lib/bypass-markers.d.mts +15 -0
  726. package/runtime/scripts/lib/bypass-markers.mjs +210 -197
  727. package/runtime/scripts/lib/cli-arg.d.mts +67 -0
  728. package/runtime/scripts/lib/cli-arg.mjs +59 -63
  729. package/runtime/scripts/lib/command-tokens.d.mts +11 -0
  730. package/runtime/scripts/lib/command-tokens.mjs +77 -78
  731. package/runtime/scripts/lib/compose-values.d.mts +6 -0
  732. package/runtime/scripts/lib/compose-values.mjs +7 -7
  733. package/runtime/scripts/lib/css-rules.d.mts +36 -0
  734. package/runtime/scripts/lib/css-rules.mjs +181 -171
  735. package/runtime/scripts/lib/deployment-findings.d.mts +9 -0
  736. package/runtime/scripts/lib/deployment-findings.mjs +4 -4
  737. package/runtime/scripts/lib/dockerfile.d.mts +39 -0
  738. package/runtime/scripts/lib/dockerfile.mjs +131 -114
  739. package/runtime/scripts/lib/dom-tree.d.mts +7 -0
  740. package/runtime/scripts/lib/dom-tree.mjs +3 -3
  741. package/runtime/scripts/lib/env.d.mts +12 -0
  742. package/runtime/scripts/lib/env.mjs +3 -6
  743. package/runtime/scripts/lib/escape.d.mts +6 -0
  744. package/runtime/scripts/lib/escape.mjs +2 -6
  745. package/runtime/scripts/lib/event-contract.d.mts +21 -0
  746. package/runtime/scripts/lib/event-contract.mjs +73 -78
  747. package/runtime/scripts/lib/event-items.d.mts +20 -0
  748. package/runtime/scripts/lib/event-items.mjs +27 -15
  749. package/runtime/scripts/lib/example-refs.d.mts +69 -0
  750. package/runtime/scripts/lib/example-refs.mjs +145 -129
  751. package/runtime/scripts/lib/fs-kind.d.mts +12 -0
  752. package/runtime/scripts/lib/fs-kind.mjs +20 -10
  753. package/runtime/scripts/lib/git-hooks-dir.d.mts +15 -0
  754. package/runtime/scripts/lib/git-hooks-dir.mjs +16 -16
  755. package/runtime/scripts/lib/git.d.mts +24 -0
  756. package/runtime/scripts/lib/git.mjs +15 -16
  757. package/runtime/scripts/lib/glob.d.mts +4 -0
  758. package/runtime/scripts/lib/glob.mjs +23 -14
  759. package/runtime/scripts/lib/grammar-lint.d.mts +47 -0
  760. package/runtime/scripts/lib/grammar-lint.mjs +33 -37
  761. package/runtime/scripts/lib/grammar-vendor-parity-jsx.d.mts +40 -0
  762. package/runtime/scripts/lib/grammar-vendor-parity-jsx.mjs +285 -266
  763. package/runtime/scripts/lib/grammar-vendor-parity.d.mts +61 -0
  764. package/runtime/scripts/lib/grammar-vendor-parity.mjs +209 -216
  765. package/runtime/scripts/lib/graphql-contract.d.mts +53 -0
  766. package/runtime/scripts/lib/graphql-contract.mjs +201 -198
  767. package/runtime/scripts/lib/graphql-sdl.d.mts +66 -0
  768. package/runtime/scripts/lib/graphql-sdl.mjs +230 -205
  769. package/runtime/scripts/lib/hook-limits.d.mts +11 -0
  770. package/runtime/scripts/lib/hook-limits.mjs +0 -1
  771. package/runtime/scripts/lib/i18n.d.mts +48 -0
  772. package/runtime/scripts/lib/i18n.mjs +32 -35
  773. package/runtime/scripts/lib/in-order.d.mts +12 -0
  774. package/runtime/scripts/lib/in-order.mjs +57 -38
  775. package/runtime/scripts/lib/is-main.d.mts +6 -0
  776. package/runtime/scripts/lib/is-main.mjs +11 -4
  777. package/runtime/scripts/lib/js-lex.d.mts +32 -0
  778. package/runtime/scripts/lib/js-lex.mjs +196 -162
  779. package/runtime/scripts/lib/json-clone.d.mts +11 -0
  780. package/runtime/scripts/lib/json-clone.mjs +45 -36
  781. package/runtime/scripts/lib/json-schema.d.mts +2 -0
  782. package/runtime/scripts/lib/json-schema.mjs +127 -90
  783. package/runtime/scripts/lib/json.d.mts +16 -0
  784. package/runtime/scripts/lib/json.mjs +26 -14
  785. package/runtime/scripts/lib/language.d.mts +44 -0
  786. package/runtime/scripts/lib/language.mjs +133 -129
  787. package/runtime/scripts/lib/list.d.mts +17 -0
  788. package/runtime/scripts/lib/list.mjs +9 -14
  789. package/runtime/scripts/lib/loosening-budgets.d.mts +12 -0
  790. package/runtime/scripts/lib/loosening-budgets.mjs +35 -29
  791. package/runtime/scripts/lib/loosening-config.d.mts +64 -0
  792. package/runtime/scripts/lib/loosening-config.mjs +267 -236
  793. package/runtime/scripts/lib/loosening-state.d.mts +77 -0
  794. package/runtime/scripts/lib/loosening-state.mjs +134 -128
  795. package/runtime/scripts/lib/mutation-fence.d.mts +11 -0
  796. package/runtime/scripts/lib/mutation-fence.mjs +10 -5
  797. package/runtime/scripts/lib/normalize.d.mts +12 -0
  798. package/runtime/scripts/lib/normalize.mjs +11 -11
  799. package/runtime/scripts/lib/numeric-match.d.mts +2 -0
  800. package/runtime/scripts/lib/numeric-match.mjs +2 -2
  801. package/runtime/scripts/lib/package-at.d.mts +24 -0
  802. package/runtime/scripts/lib/package-at.mjs +34 -31
  803. package/runtime/scripts/lib/path-key.d.mts +76 -0
  804. package/runtime/scripts/lib/path-key.mjs +53 -38
  805. package/runtime/scripts/lib/pid-alive.d.mts +2 -0
  806. package/runtime/scripts/lib/pid-alive.mjs +10 -3
  807. package/runtime/scripts/lib/properties.d.mts +2 -0
  808. package/runtime/scripts/lib/properties.mjs +17 -11
  809. package/runtime/scripts/lib/provision-operation-schema.d.mts +4 -0
  810. package/runtime/scripts/lib/provision-operation-schema.mjs +4 -5
  811. package/runtime/scripts/lib/read-text.d.mts +12 -0
  812. package/runtime/scripts/lib/read-text.mjs +30 -17
  813. package/runtime/scripts/lib/redact.d.mts +52 -0
  814. package/runtime/scripts/lib/redact.mjs +135 -121
  815. package/runtime/scripts/lib/regex.d.mts +2 -0
  816. package/runtime/scripts/lib/regex.mjs +1 -2
  817. package/runtime/scripts/lib/roots.d.mts +32 -0
  818. package/runtime/scripts/lib/roots.mjs +5 -15
  819. package/runtime/scripts/lib/runtime-example.d.mts +1 -0
  820. package/runtime/scripts/lib/runtime-example.mjs +10 -8
  821. package/runtime/scripts/lib/same-text.d.mts +2 -0
  822. package/runtime/scripts/lib/same-text.mjs +0 -1
  823. package/runtime/scripts/lib/sealed-member.d.mts +16 -0
  824. package/runtime/scripts/lib/sealed-member.mjs +8 -13
  825. package/runtime/scripts/lib/secret-patterns.d.mts +30 -0
  826. package/runtime/scripts/lib/secret-patterns.mjs +175 -163
  827. package/runtime/scripts/lib/shell-source.d.mts +2 -0
  828. package/runtime/scripts/lib/shell-source.mjs +0 -1
  829. package/runtime/scripts/lib/sleep-sync.d.mts +2 -0
  830. package/runtime/scripts/lib/sleep-sync.mjs +5 -6
  831. package/runtime/scripts/lib/sops-envelope.d.mts +34 -0
  832. package/runtime/scripts/lib/sops-envelope.mjs +148 -120
  833. package/runtime/scripts/lib/source-phrases.d.mts +4 -0
  834. package/runtime/scripts/lib/source-phrases.mjs +13 -13
  835. package/runtime/scripts/lib/sql-ast.d.mts +13 -0
  836. package/runtime/scripts/lib/sql-ast.mjs +19 -18
  837. package/runtime/scripts/lib/sqlite.d.mts +21 -0
  838. package/runtime/scripts/lib/sqlite.mjs +3 -9
  839. package/runtime/scripts/lib/stack-declaration.d.mts +51 -0
  840. package/runtime/scripts/lib/stack-declaration.mjs +27 -20
  841. package/runtime/scripts/lib/stack-services.d.mts +73 -0
  842. package/runtime/scripts/lib/stack-services.mjs +128 -129
  843. package/runtime/scripts/lib/starciwork-boundary.d.mts +10 -0
  844. package/runtime/scripts/lib/starciwork-boundary.mjs +98 -92
  845. package/runtime/scripts/lib/swarm-stack.d.mts +24 -0
  846. package/runtime/scripts/lib/swarm-stack.mjs +112 -100
  847. package/runtime/scripts/lib/trim-end.d.mts +2 -0
  848. package/runtime/scripts/lib/trim-end.mjs +4 -4
  849. package/runtime/scripts/lib/ts-analysis.d.mts +24 -0
  850. package/runtime/scripts/lib/ts-analysis.mjs +28 -26
  851. package/runtime/scripts/lib/ts-ast.d.mts +36 -0
  852. package/runtime/scripts/lib/ts-ast.mjs +36 -42
  853. package/runtime/scripts/lib/walk.d.mts +19 -0
  854. package/runtime/scripts/lib/walk.mjs +33 -27
  855. package/runtime/scripts/lib/work-edition.d.mts +10 -0
  856. package/runtime/scripts/lib/work-edition.mjs +29 -21
  857. package/runtime/scripts/lib/workflow-events.d.mts +2 -0
  858. package/runtime/scripts/lib/workflow-events.mjs +5 -4
  859. package/runtime/scripts/lib/worktree-exclude.d.mts +16 -0
  860. package/runtime/scripts/lib/worktree-exclude.mjs +6 -8
  861. package/runtime/scripts/lib/yaml-cached.d.mts +2 -0
  862. package/runtime/scripts/lib/yaml-cached.mjs +4 -4
  863. package/runtime/scripts/machine/artifact-hold.d.mts +26 -0
  864. package/runtime/scripts/machine/artifact-hold.mjs +22 -23
  865. package/runtime/scripts/work/asset-slot.d.mts +96 -0
  866. package/runtime/scripts/work/asset-slot.mjs +201 -175
  867. package/runtime/scripts/work/draw/draw-dna-anatomy.d.mts +30 -0
  868. package/runtime/scripts/work/draw/draw-dna-anatomy.mjs +40 -36
  869. package/runtime/scripts/work/draw/draw-dna-findings.d.mts +12 -0
  870. package/runtime/scripts/work/draw/draw-dna-findings.mjs +240 -206
  871. package/runtime/scripts/work/draw/draw-dna-selector.d.mts +7 -0
  872. package/runtime/scripts/work/draw/draw-dna-selector.mjs +28 -28
  873. package/runtime/scripts/work/draw/draw-dna.d.mts +191 -0
  874. package/runtime/scripts/work/draw/draw-dna.mjs +283 -249
  875. package/runtime/scripts/work/grammar-proposal.d.mts +83 -0
  876. package/runtime/scripts/work/grammar-proposal.mjs +215 -178
  877. package/runtime/scripts/work/work-io.d.mts +62 -0
  878. package/runtime/scripts/work/work-io.mjs +82 -63
  879. package/scaffold/add-app.d.mts +15 -0
  880. package/scaffold/add-app.mjs +111 -163
  881. package/scaffold/add-cli-lite.d.mts +8 -0
  882. package/scaffold/add-cli-lite.mjs +173 -207
  883. package/scaffold/add-compose.d.mts +44 -0
  884. package/scaffold/add-compose.mjs +62 -62
  885. package/scaffold/add-database-lite.d.mts +2 -0
  886. package/scaffold/add-database-lite.mjs +10 -10
  887. package/scaffold/add-fe-layout.d.mts +16 -0
  888. package/scaffold/add-fe-layout.mjs +23 -23
  889. package/scaffold/add-fe-overlay.d.mts +17 -0
  890. package/scaffold/add-fe-overlay.mjs +76 -78
  891. package/scaffold/add-fe-page.d.mts +41 -0
  892. package/scaffold/add-fe-page.mjs +84 -89
  893. package/scaffold/add-fe-unit.d.mts +59 -0
  894. package/scaffold/add-fe-unit.mjs +205 -197
  895. package/scaffold/add-inbox-lite.d.mts +17 -0
  896. package/scaffold/add-inbox-lite.mjs +209 -264
  897. package/scaffold/add-plan.d.mts +68 -0
  898. package/scaffold/add-plan.mjs +164 -149
  899. package/scaffold/add-queue-lite.d.mts +34 -0
  900. package/scaffold/add-queue-lite.mjs +267 -267
  901. package/scaffold/add-table.d.mts +16 -0
  902. package/scaffold/add-table.mjs +405 -442
  903. package/scaffold/add.d.mts +34 -0
  904. package/scaffold/add.mjs +260 -246
  905. package/scaffold/app.d.mts +198 -0
  906. package/scaffold/app.mjs +413 -391
  907. package/scaffold/edition-gate.d.mts +49 -0
  908. package/scaffold/edition-gate.mjs +19 -29
  909. package/scaffold/image.d.mts +4 -0
  910. package/scaffold/image.mjs +12 -12
  911. package/scaffold/lite-exports.d.mts +15 -0
  912. package/scaffold/lite-exports.mjs +262 -255
  913. package/scaffold/pattern-file-slots.d.mts +7 -0
  914. package/scaffold/pattern-file-slots.mjs +29 -24
  915. package/scaffold/service.d.mts +60 -0
  916. package/scaffold/service.mjs +297 -279
  917. package/scaffold/test-world.d.mts +31 -0
  918. package/scaffold/test-world.mjs +71 -78
  919. package/scaffold/yaml-block-edit.d.mts +23 -0
  920. package/scaffold/yaml-block-edit.mjs +95 -87
  921. package/scripts/sync-bundles.d.mts +31 -0
  922. package/src/fixtures/bypass-index.d.mts +4 -0
  923. package/src/fixtures/hfs-stack-tooling/passing.d.mts +8 -0
  924. package/src/fixtures/hfs-stack-tooling/violating.d.mts +19 -0
  925. package/src/fixtures/hfs-stacks-full/model-unavailable.d.mts +10 -0
  926. package/src/fixtures/hfs-stacks-full/passing.d.mts +19 -0
  927. package/src/fixtures/hfs-stacks-full/violating.d.mts +10 -0
  928. package/src/fixtures/loosening/adversarial.d.mts +4 -0
  929. package/src/fixtures/loosening/forms.d.mts +16 -0
  930. package/src/fixtures/loosening/swallows.d.mts +5 -0
  931. package/src/helpers/hfs-arch-fixture.d.mts +47 -0
  932. package/src/helpers/hfs-cli-fixture.d.mts +65 -0
  933. package/src/helpers/hfs-hfs-docker-rules-fixture.d.mts +5 -0
  934. package/src/helpers/hfs-secret-fixture.d.mts +19 -0
  935. package/src/helpers/pre-push-fixture.d.mts +21 -0
  936. package/src/helpers/stack-compose.d.mts +6 -0
  937. package/src/helpers/swarm-stack-fixture.d.mts +18 -0
  938. package/src/helpers/tmpdir.d.mts +2 -0
  939. package/src/main.d.mts +58 -0
  940. package/src/main.mjs +494 -346
  941. package/stack/age-install.d.mts +13 -0
  942. package/stack/age-install.mjs +28 -25
  943. package/stack/backup.d.mts +11 -0
  944. package/stack/backup.mjs +76 -69
  945. package/stack/build-args.d.mts +7 -0
  946. package/stack/build-args.mjs +22 -23
  947. package/stack/build.d.mts +8 -0
  948. package/stack/build.mjs +138 -119
  949. package/stack/cli.d.mts +55 -0
  950. package/stack/cli.mjs +187 -130
  951. package/stack/config.d.mts +197 -0
  952. package/stack/config.mjs +47 -33
  953. package/stack/context.d.mts +122 -0
  954. package/stack/context.mjs +63 -65
  955. package/stack/converge.d.mts +13 -0
  956. package/stack/converge.mjs +73 -69
  957. package/stack/deploy.d.mts +88 -0
  958. package/stack/deploy.mjs +272 -224
  959. package/stack/digest.d.mts +8 -0
  960. package/stack/digest.mjs +1 -6
  961. package/stack/docker-transport.d.mts +5 -0
  962. package/stack/docker-transport.mjs +101 -93
  963. package/stack/edge-alias.d.mts +42 -0
  964. package/stack/edge-alias.mjs +62 -60
  965. package/stack/errors.d.mts +18 -0
  966. package/stack/errors.mjs +8 -10
  967. package/stack/image-scan.d.mts +20 -0
  968. package/stack/image-scan.mjs +114 -101
  969. package/stack/ingress-create.d.mts +4 -0
  970. package/stack/ingress-create.mjs +82 -86
  971. package/stack/ingress-publish.d.mts +6 -0
  972. package/stack/ingress-publish.mjs +194 -182
  973. package/stack/ingress.d.mts +55 -0
  974. package/stack/ingress.mjs +534 -524
  975. package/stack/jobs.d.mts +12 -0
  976. package/stack/jobs.mjs +35 -34
  977. package/stack/live-restore.d.mts +35 -0
  978. package/stack/live-restore.mjs +120 -125
  979. package/stack/post-deploy.d.mts +8 -0
  980. package/stack/post-deploy.mjs +25 -25
  981. package/stack/prepare.d.mts +24 -0
  982. package/stack/prepare.mjs +213 -200
  983. package/stack/private-file.d.mts +5 -0
  984. package/stack/private-file.mjs +9 -9
  985. package/stack/provision.d.mts +25 -0
  986. package/stack/provision.mjs +64 -63
  987. package/stack/prune.d.mts +11 -0
  988. package/stack/prune.mjs +38 -27
  989. package/stack/release-store.d.mts +28 -0
  990. package/stack/release-store.mjs +68 -67
  991. package/stack/remote.d.mts +83 -0
  992. package/stack/remote.mjs +176 -162
  993. package/stack/render.d.mts +14 -0
  994. package/stack/render.mjs +132 -124
  995. package/stack/retire.d.mts +9 -0
  996. package/stack/retire.mjs +31 -34
  997. package/stack/sealed.d.mts +46 -0
  998. package/stack/sealed.mjs +78 -82
  999. package/stack/server-key.d.mts +67 -0
  1000. package/stack/server-key.mjs +217 -203
  1001. package/stack/ssh-session.d.mts +29 -0
  1002. package/stack/ssh-session.mjs +133 -123
  1003. package/stack/target-binding.d.mts +21 -0
  1004. package/stack/target-binding.mjs +68 -44
  1005. package/stack/task.d.mts +12 -0
  1006. package/stack/task.mjs +26 -31
  1007. package/stack/urgent-floor.d.mts +106 -0
  1008. package/stack/urgent-floor.mjs +211 -160
  1009. package/stack/urgent-release.d.mts +38 -0
  1010. package/stack/urgent-release.mjs +26 -22
  1011. package/stack/verify.d.mts +14 -0
  1012. package/stack/verify.mjs +75 -65
  1013. package/sync/ci-commands.d.mts +26 -0
  1014. package/sync/ci-commands.mjs +181 -182
  1015. package/sync/cli.d.mts +8 -0
  1016. package/sync/cli.mjs +9 -9
  1017. package/sync/format.d.mts +38 -0
  1018. package/sync/format.mjs +30 -24
  1019. package/sync/hygiene.d.mts +23 -0
  1020. package/sync/hygiene.mjs +113 -99
  1021. package/sync/index.d.mts +237 -0
  1022. package/sync/index.mjs +457 -436
  1023. package/sync/managed.d.mts +23 -0
  1024. package/sync/managed.mjs +104 -94
  1025. package/sync/quality-services.d.mts +35 -0
  1026. package/sync/quality-services.mjs +48 -41
  1027. package/sync/readme-badges.d.mts +13 -0
  1028. package/sync/readme-badges.mjs +45 -44
  1029. package/sync/sonar-key.d.mts +31 -0
  1030. package/sync/sonar-key.mjs +29 -28
  1031. package/sync/stack-images.d.mts +36 -0
  1032. package/sync/stack-images.mjs +85 -95
  1033. package/sync/ts-strict.d.mts +14 -0
  1034. package/sync/ts-strict.mjs +43 -34
  1035. package/templates/app/ci-workflows/github/workflows/ci.yml +1 -1
  1036. package/templates/app/ci-workflows/github/workflows/images.yml +1 -1
  1037. package/templates/app/ci-workflows/github/workflows/stack-deploy.yml +2 -2
  1038. package/templates/app/ci-workflows/github/workflows/stack-key-restore.yml +1 -1
  1039. package/templates/app/ci-workflows-lite/github/workflows/ci.yml +1 -1
  1040. package/templates/app/ci-workflows-lite/github/workflows/db-deploy.yml +3 -3
  1041. package/templates/app/ci-workflows-lite/github/workflows/images.yml +1 -1
  1042. package/templates/app/ci-workflows-lite/github/workflows/stack-deploy.yml +2 -2
  1043. package/templates/app/ci-workflows-lite/github/workflows/stack-key-restore.yml +1 -1
  1044. package/templates/app/codegen-lite/scripts/codegen.mjs +1 -1
  1045. package/templates/app/db-bootstrap/db/bootstrap.sql +1 -1
  1046. package/templates/app/db-image/starcistacks/images/db/Dockerfile +1 -1
  1047. package/templates/app/hooks/husky/pre-commit +2 -2
  1048. package/templates/app/package-scripts/db.json +3 -3
  1049. package/templates/app/package-scripts/package.json +1 -1
  1050. package/templates/app/quality-config/sonar-project.properties +1 -1
  1051. package/templates/app/skeleton/.starcistacks/application-stacks.yaml +2 -2
  1052. package/templates/app/skeleton/.starcistacks/production/README.md +4 -4
  1053. package/templates/app/skeleton/.starcistacks/production/infra/swarm/stack.yaml +8 -3
  1054. package/templates/app/skeleton/README.md +1 -1
  1055. package/templates/app/skeleton-lite/.starcistacks/application-stacks.yaml +2 -2
  1056. package/templates/app/skeleton-lite/.starcistacks/dev/README.md +1 -1
  1057. package/templates/app/skeleton-lite/.starcistacks/dev/infra/swarm/stack.yaml +6 -2
  1058. package/templates/app/skeleton-lite/.starcistacks/dev/runtime/env/KEYS.md +3 -2
  1059. package/templates/app/skeleton-lite/.starcistacks/production/README.md +5 -5
  1060. package/templates/app/skeleton-lite/.starcistacks/production/infra/swarm/stack.yaml +7 -2
  1061. package/templates/app/skeleton-lite/.starcistacks/production/runtime/env/KEYS.md +3 -2
  1062. package/templates/app/skeleton-lite/README.md +2 -2
  1063. package/templates/be/skeleton/apps/cli/src/compose/platform.ts +1 -1
  1064. package/templates/be/skeleton/apps/cli/src/main.ts +6 -4
  1065. package/templates/be/skeleton/src/modules/platform/config/env-source.config.ts +12 -0
  1066. package/templates/be/skeleton/src/modules/platform/database/abstract.entity.ts +19 -0
  1067. package/templates/be/skeleton/src/modules/platform/database/database.module.ts +7 -1
  1068. package/templates/be/skeleton/src/modules/platform/logging/json-logger.service.spec.ts +19 -0
  1069. package/templates/be/skeleton/src/modules/platform/logging/json-logger.service.ts +4 -3
  1070. package/templates/be/skeleton/src/modules/platform/logging/logging.module.ts +1 -1
  1071. package/templates/be/skeleton/src/modules/platform/logging/logging.options.ts +5 -2
  1072. package/templates/be/skeleton-lite/apps/cli/src/compose/platform.ts +1 -1
  1073. package/templates/be/skeleton-lite/src/modules/integrations/passport/passport.config.spec.ts +40 -0
  1074. package/templates/be/skeleton-lite/src/modules/integrations/passport/passport.config.ts +1 -0
  1075. package/templates/be/skeleton-lite/src/modules/integrations/passport/passport.cookie.spec.ts +48 -1
  1076. package/templates/be/skeleton-lite/src/modules/integrations/passport/passport.cookie.ts +5 -0
  1077. package/templates/be/skeleton-lite/src/modules/integrations/passport/passport.options.ts +5 -0
  1078. package/templates/be/skeleton-lite/src/modules/integrations/passport/strategies/google.strategy.ts +1 -1
  1079. package/templates/be/skeleton-lite/src/modules/integrations/passport/strategies/oauth-state.store.ts +7 -3
  1080. package/templates/be/skeleton-lite/src/modules/platform/database/database.module.ts +7 -1
  1081. package/templates/be/table/entity.ts.tpl +4 -15
  1082. package/upgrade/check.d.mts +9 -0
  1083. package/upgrade/check.mjs +8 -8
  1084. package/upgrade/file-state.d.mts +6 -0
  1085. package/upgrade/file-state.mjs +32 -40
  1086. package/upgrade/index.d.mts +13 -0
  1087. package/upgrade/index.mjs +122 -151
  1088. package/vendor-types.d.mts +8 -0
@@ -11,9 +11,8 @@ import { parseSource, ts } from '../runtime-rules/source-ast.mjs';
11
11
  import { readText } from './read.mjs';
12
12
  import { externalIngressStack } from './stacks-ingress.mjs';
13
13
  import { stacksDeploymentFindings } from './stacks-runtime.mjs';
14
-
15
- const mapping = value => plain(value) ? value : {};
16
- const present = value => typeof value === 'string' && Boolean(value.trim());
14
+ const mapping = (value) => plain(value) ? value : {};
15
+ const present = (value) => typeof value === 'string' && Boolean(value.trim());
17
16
  const VERSION = /^[1-9]\d*$/;
18
17
  const VERSIONED_SECRET = /-v[1-9]\d*$/;
19
18
  const SENSITIVE_KEY = /password|passwd|secret|token|credential|private[_-]?key|api[_-]?key|service[_-]?role|(?:(?:^|_)key$)/i;
@@ -21,408 +20,431 @@ const SOURCE = /^be\/(?:apps|src)\/.*\.[cm]?[jt]sx?$/;
21
20
  const TEST_SOURCE = /(?:\.(?:spec|test)|-spec)\.[cm]?[jt]sx?$|\/tests\//;
22
21
  const REALTIME_SOURCE = /^be\/src\/features\/realtime\/[^/]+\//;
23
22
  const HOST = /^(?:[a-z0-9-]+\.)+[a-z0-9-]+$/i;
24
-
25
23
  function secretVersionMatches(declaration, secret) {
26
- const version = String(declaration.version ?? '');
27
- return VERSION.test(version) && present(declaration.runtimeName)
28
- && declaration.runtimeName.endsWith(`-v${version}`) && secret.name === declaration.runtimeName;
24
+ const version = String(declaration.version ?? '');
25
+ return VERSION.test(version) && present(declaration.runtimeName)
26
+ && declaration.runtimeName.endsWith(`-v${version}`) && secret.name === declaration.runtimeName;
29
27
  }
30
-
31
28
  function secretCustodyIssues(spec, model, add) {
32
- const secrets = mapping(model.secrets);
33
- const declarations = new Map(list(spec.secrets).map(entry => [entry?.name, entry]));
34
- const names = new Set([...Object.keys(secrets), ...declarations.keys()]);
35
- for (const name of names) {
36
- const secret = mapping(secrets[name]), declaration = mapping(declarations.get(name));
37
- const at = `secrets.${name}`;
38
- if (secret.external !== true || ['file', 'environment', 'content', 'value'].some(key => secret[key] !== undefined))
39
- add('STACKS_SECRET_NOT_EXTERNAL', at, 'Swarm secrets must be external engine secrets without an embedded source');
40
- if (!present(secret.name) || !VERSIONED_SECRET.test(secret.name) || !secretVersionMatches(declaration, secret))
41
- add('STACKS_SECRET_UNVERSIONED', at, 'Declare runtimeName and a positive version matching the immutable rendered secret name <logical>-v<N>');
42
- }
43
- }
44
-
29
+ const secrets = mapping(model.secrets);
30
+ const declarations = new Map(list(spec.secrets).map((entry) => [entry?.name, entry]));
31
+ const names = new Set([...Object.keys(secrets), ...declarations.keys()]);
32
+ for (const name of names) {
33
+ const secret = mapping(secrets[name]), declaration = mapping(declarations.get(name));
34
+ const at = `secrets.${name}`;
35
+ if (secret.external !== true || ['file', 'environment', 'content', 'value'].some(key => secret[key] !== undefined))
36
+ add('STACKS_SECRET_NOT_EXTERNAL', at, 'Swarm secrets must be external engine secrets without an embedded source');
37
+ if (!present(secret.name) || !VERSIONED_SECRET.test(secret.name) || !secretVersionMatches(declaration, secret))
38
+ add('STACKS_SECRET_UNVERSIONED', at, 'Declare runtimeName and a positive version matching the immutable rendered secret name <logical>-v<N>');
39
+ }
40
+ }
45
41
  function grantedSecretTargets(service, secrets) {
46
- const targets = new Set();
47
- for (const entry of list(service.secrets)) {
48
- const source = plain(entry) ? entry.source : entry;
49
- if (!Object.hasOwn(secrets, source)) continue;
50
- const target = plain(entry) ? entry.target ?? source : source;
51
- if (present(target) && !target.includes('/') && !target.includes('..')) targets.add(`/run/secrets/${target}`);
52
- }
53
- return targets;
54
- }
55
-
42
+ const targets = new Set();
43
+ for (const entry of list(service.secrets)) {
44
+ const source = plain(entry) ? entry.source : entry;
45
+ if (!Object.hasOwn(secrets, source))
46
+ continue;
47
+ const target = plain(entry) ? entry.target ?? source : source;
48
+ if (present(target) && !target.includes('/') && !target.includes('..'))
49
+ targets.add(`/run/secrets/${target}`);
50
+ }
51
+ return targets;
52
+ }
56
53
  function sensitiveEnvironmentKey(key, declarations) {
57
- const normalized = key.toUpperCase().replaceAll('-', '_');
58
- return SENSITIVE_KEY.test(key) || declarations.some(entry => entry?.name?.toUpperCase().replaceAll('-', '_') === normalized);
54
+ const normalized = key.toUpperCase().replaceAll('-', '_');
55
+ return SENSITIVE_KEY.test(key) || declarations.some((entry) => entry?.name?.toUpperCase().replaceAll('-', '_') === normalized);
59
56
  }
60
-
61
57
  function credentialUri(value) {
62
- if (!present(value)) return false;
63
- try {
64
- const uri = new URL(value);
65
- return Boolean(uri.password);
66
- } catch { return false; }
58
+ if (!present(value))
59
+ return false;
60
+ try {
61
+ const uri = new URL(value);
62
+ return Boolean(uri.password);
63
+ }
64
+ catch {
65
+ return false;
66
+ }
67
67
  }
68
-
69
68
  function environmentSecretIssues(id, service, spec, model, add) {
70
- const targets = grantedSecretTargets(service, mapping(model.secrets));
71
- for (const [key, value] of composeEntries(service.environment, { missingValue: null })) {
72
- if (key.endsWith('_FILE')) {
73
- const secretFile = sensitiveEnvironmentKey(key.slice(0, -5), list(spec.secrets)) || String(value).startsWith('/run/secrets/') || credentialUri(value);
74
- if (secretFile && !targets.has(value)) add('STACKS_SECRET_ENV_LITERAL', `services.${id}.environment.${key}`, 'A secret file binding must name the exact /run/secrets target granted to this service');
75
- continue;
69
+ const targets = grantedSecretTargets(service, mapping(model.secrets));
70
+ for (const [key, value] of composeEntries(service.environment, { missingValue: null })) {
71
+ if (key.endsWith('_FILE')) {
72
+ const secretFile = sensitiveEnvironmentKey(key.slice(0, -5), list(spec.secrets)) || String(value).startsWith('/run/secrets/') || credentialUri(value);
73
+ if (secretFile && !targets.has(value))
74
+ add('STACKS_SECRET_ENV_LITERAL', `services.${id}.environment.${key}`, 'A secret file binding must name the exact /run/secrets target granted to this service');
75
+ continue;
76
+ }
77
+ if (sensitiveEnvironmentKey(key, list(spec.secrets)) || credentialUri(value))
78
+ add('STACKS_SECRET_ENV_LITERAL', `services.${id}.environment.${key}`, 'Sensitive environment bindings must use a granted Swarm secret file; secret values must never be embedded');
79
+ }
80
+ for (const entry of list(service.secrets)) {
81
+ const source = plain(entry) ? entry.source : entry;
82
+ if (!Object.hasOwn(mapping(model.secrets), source))
83
+ add('STACKS_SECRET_NOT_EXTERNAL', `services.${id}.secrets`, 'A service grant must reference a declared external engine secret');
76
84
  }
77
- if (sensitiveEnvironmentKey(key, list(spec.secrets)) || credentialUri(value))
78
- add('STACKS_SECRET_ENV_LITERAL', `services.${id}.environment.${key}`, 'Sensitive environment bindings must use a granted Swarm secret file; secret values must never be embedded');
79
- }
80
- for (const entry of list(service.secrets)) {
81
- const source = plain(entry) ? entry.source : entry;
82
- if (!Object.hasOwn(mapping(model.secrets), source))
83
- add('STACKS_SECRET_NOT_EXTERNAL', `services.${id}.secrets`, 'A service grant must reference a declared external engine secret');
84
- }
85
- }
86
-
85
+ }
87
86
  function allowedPort(entry) {
88
- if (plain(entry)) return [undefined, 'ingress'].includes(entry.mode) && [80, 443].includes(Number(entry.published));
89
- if (typeof entry !== 'string') return false;
90
- const parts = String(entry).split('/')[0].split(':');
91
- return parts.length > 1 && [80, 443].includes(Number(parts.at(-2)));
87
+ if (plain(entry))
88
+ return [undefined, 'ingress'].includes(entry.mode) && [80, 443].includes(Number(entry.published));
89
+ if (typeof entry !== 'string')
90
+ return false;
91
+ const parts = String(entry).split('/')[0].split(':');
92
+ return parts.length > 1 && [80, 443].includes(Number(parts.at(-2)));
92
93
  }
93
-
94
94
  function publishedPortIssues(id, service, spec, add) {
95
- if (service.ports === undefined || (Array.isArray(service.ports) && !service.ports.length)) return;
96
- if (id !== spec.ingress?.component || !Array.isArray(service.ports) || !service.ports.every(allowedPort))
97
- add('STACKS_PORT_PUBLISHED', `services.${id}.ports`, 'Only the declared ingress may publish ports, using ingress mode and published ports 80 or 443');
95
+ if (service.ports === undefined || (Array.isArray(service.ports) && !service.ports.length))
96
+ return;
97
+ if (id !== spec.ingress?.component || !Array.isArray(service.ports) || !service.ports.every(allowedPort))
98
+ add('STACKS_PORT_PUBLISHED', `services.${id}.ports`, 'Only the declared ingress may publish ports, using ingress mode and published ports 80 or 443');
98
99
  }
99
-
100
100
  function hostOf(value) {
101
- if (!present(value)) return null;
102
- let candidate = value.trim().replace(/^https?:\/\//i, '').split('/')[0].split(':')[0];
103
- candidate = candidate.toLowerCase().replace(/\.$/, '');
104
- return HOST.test(candidate) ? candidate : null;
101
+ if (!present(value))
102
+ return null;
103
+ let candidate = value.trim().replace(/^https?:\/\//i, '').split('/')[0].split(':')[0]; // split always yields one element
104
+ candidate = candidate.toLowerCase().replace(/\.$/, '');
105
+ return HOST.test(candidate) ? candidate : null;
105
106
  }
106
-
107
107
  function traefikHosts(rule) {
108
- const hosts = [], text = String(rule);
109
- for (const match of text.matchAll(/\bHost\s*\(/g)) {
110
- if (!positiveHostCall(text.slice(0, match.index))) continue;
111
- const part = text.slice(match.index + match[0].length);
112
- const argumentsText = part.split(')')[0];
113
- for (const argument of argumentsText.split(',')) {
114
- const quoted = argument.trim();
115
- if (!['`', '"', "'"].includes(quoted[0]) || quoted.at(-1) !== quoted[0]) continue;
116
- const domain = quoted.slice(1, -1).toLowerCase();
117
- const host = HOST.test(domain) ? domain : null;
118
- if (host) hosts.push(host);
108
+ const hosts = [], text = String(rule);
109
+ for (const match of text.matchAll(/\bHost\s*\(/g)) {
110
+ if (!positiveHostCall(text.slice(0, match.index)))
111
+ continue;
112
+ const part = text.slice(match.index + match[0].length);
113
+ const argumentsText = part.split(')')[0];
114
+ for (const argument of argumentsText.split(',')) {
115
+ const quoted = argument.trim();
116
+ if (!['`', '"', "'"].includes(quoted[0]) || quoted.at(-1) !== quoted[0])
117
+ continue;
118
+ const domain = quoted.slice(1, -1).toLowerCase();
119
+ const host = HOST.test(domain) ? domain : null;
120
+ if (host)
121
+ hosts.push(host);
122
+ }
119
123
  }
120
- }
121
- return hosts;
124
+ return hosts;
122
125
  }
123
-
124
126
  function positiveHostCall(prefix) {
125
- const scopes = [false];
126
- let pending = false;
127
- for (const token of prefix.match(/"[^"]*"|'[^']*'|`[^`]*`|[()!]|[A-Za-z_]\w*|\S/g) ?? []) {
128
- if (token === '!') { pending = !pending; continue; }
129
- if (token === '(') scopes.push(scopes.at(-1) !== pending);
130
- if (token === ')' && scopes.length > 1) scopes.pop();
131
- pending = false;
132
- }
133
- return !scopes.at(-1) && !pending;
134
- }
135
-
127
+ const scopes = [false];
128
+ let pending = false;
129
+ for (const token of prefix.match(/"[^"]*"|'[^']*'|`[^`]*`|[()!]|[A-Za-z_]\w*|\S/g) ?? []) {
130
+ if (token === '!') {
131
+ pending = !pending;
132
+ continue;
133
+ }
134
+ if (token === '(')
135
+ scopes.push(scopes.at(-1) !== pending);
136
+ if (token === ')' && scopes.length > 1)
137
+ scopes.pop();
138
+ pending = false;
139
+ }
140
+ return !scopes.at(-1) && !pending;
141
+ }
136
142
  function labelHosts(service, family) {
137
- const hosts = [];
138
- const labels = [...composeEntries(service.labels, { missingValue: null }), ...composeEntries(service.deploy?.labels, { missingValue: null })];
139
- if (family === 'traefik' && labels.some(([key, value]) => key === 'traefik.enable' && String(value) === 'false')) return hosts;
140
- for (const [key, value] of labels) {
141
- if (family === 'traefik' && key.startsWith('traefik.http.routers.') && key.endsWith('.rule')) hosts.push(...traefikHosts(value));
142
- if (family === 'caddy-docker-proxy' && /^caddy(?:_\d+)?$/.test(key)) hosts.push(...String(value).split(/[\s,]+/).map(hostOf).filter(Boolean));
143
- }
144
- return hosts;
145
- }
146
-
143
+ const hosts = [];
144
+ const labels = [...composeEntries(service.labels, { missingValue: null }), ...composeEntries(service.deploy?.labels, { missingValue: null })];
145
+ if (family === 'traefik' && labels.some(([key, value]) => key === 'traefik.enable' && String(value) === 'false'))
146
+ return hosts;
147
+ for (const [key, value] of labels) {
148
+ if (family === 'traefik' && key.startsWith('traefik.http.routers.') && key.endsWith('.rule'))
149
+ hosts.push(...traefikHosts(value));
150
+ if (family === 'caddy-docker-proxy' && /^caddy(?:_\d+)?$/.test(key))
151
+ hosts.push(...String(value).split(/[\s,]+/).map(hostOf).filter(Boolean));
152
+ }
153
+ return hosts;
154
+ }
147
155
  function safeRegularFile(repoRoot, file) {
148
- const base = path.resolve(repoRoot), target = path.resolve(base, file);
149
- if (!isInside(base, target)) return false;
150
- try {
151
- if (!fs.lstatSync(target).isFile()) return false;
152
- let cursor = target;
153
- while (cursor !== base) {
154
- if (fs.lstatSync(cursor).isSymbolicLink()) return false;
155
- cursor = path.dirname(cursor);
156
+ const base = path.resolve(repoRoot), target = path.resolve(base, file);
157
+ if (!isInside(base, target))
158
+ return false;
159
+ try {
160
+ if (!fs.lstatSync(target).isFile())
161
+ return false;
162
+ let cursor = target;
163
+ while (cursor !== base) {
164
+ if (fs.lstatSync(cursor).isSymbolicLink())
165
+ return false;
166
+ cursor = path.dirname(cursor);
167
+ }
168
+ return true;
169
+ }
170
+ catch {
171
+ return false;
156
172
  }
157
- return true;
158
- } catch {
159
- return false;
160
- }
161
173
  }
162
-
163
174
  function trackedConfigText(input, relative) {
164
- if (!present(relative) || /\.enc(?:\.yaml)?$/.test(relative) || path.isAbsolute(relative)) return null;
165
- const directory = `.starcistacks/${input.environment}/`;
166
- const stack = input.spec.renderedModel ?? input.spec.composeFiles?.[0] ?? 'infra/swarm/stack.yaml';
167
- const file = path.posix.normalize(path.posix.join(directory, path.posix.dirname(stack), relative));
168
- const allowed = file.startsWith(`${directory}infra/`) || file.startsWith(`${directory}runtime/config/`);
169
- if (!allowed || file.includes('/secrets/') || !list(input.files).includes(file) || !input.repoRoot) return null;
170
- if (!safeRegularFile(input.repoRoot, file)) return null;
171
- return readText(input.repoRoot, file);
172
- }
173
-
175
+ if (!present(relative) || /\.enc(?:\.yaml)?$/.test(relative) || path.isAbsolute(relative))
176
+ return null;
177
+ const directory = `.starcistacks/${input.environment}/`;
178
+ const stack = input.spec.renderedModel ?? input.spec.composeFiles?.[0] ?? 'infra/swarm/stack.yaml';
179
+ const file = path.posix.normalize(path.posix.join(directory, path.posix.dirname(stack), relative));
180
+ const allowed = file.startsWith(`${directory}infra/`) || file.startsWith(`${directory}runtime/config/`);
181
+ if (!allowed || file.includes('/secrets/') || !list(input.files).includes(file) || !input.repoRoot)
182
+ return null;
183
+ if (!safeRegularFile(input.repoRoot, file))
184
+ return null;
185
+ return readText(input.repoRoot, file);
186
+ }
174
187
  function caddyConfigSources(service, model) {
175
- const sources = [];
176
- for (const entry of list(service.configs)) {
177
- const source = plain(entry) ? entry.source : entry;
178
- const config = mapping(model.configs)[source];
179
- if (present(config?.file)) sources.push(config.file);
180
- }
181
- for (const entry of list(service.volumes)) {
182
- if (plain(entry) && entry.type === 'bind' && String(entry.target).endsWith('/Caddyfile')) sources.push(entry.source);
183
- if (typeof entry === 'string') {
184
- const [source, target] = entry.split(':');
185
- if (target?.endsWith('/Caddyfile')) sources.push(source);
188
+ const sources = [];
189
+ for (const entry of list(service.configs)) {
190
+ const source = plain(entry) ? entry.source : entry;
191
+ const config = mapping(model.configs)[source];
192
+ if (present(config?.file))
193
+ sources.push(config.file);
186
194
  }
187
- }
188
- return sources;
195
+ for (const entry of list(service.volumes)) {
196
+ if (plain(entry) && entry.type === 'bind' && String(entry.target).endsWith('/Caddyfile'))
197
+ sources.push(entry.source);
198
+ if (typeof entry === 'string') {
199
+ const [source, target] = entry.split(':');
200
+ if (target?.endsWith('/Caddyfile'))
201
+ sources.push(source);
202
+ }
203
+ }
204
+ return sources;
189
205
  }
190
-
191
206
  function caddyfileHosts(text) {
192
- const hosts = [];
193
- let depth = 0;
194
- for (const line of String(text ?? '').split(/\r?\n/)) {
195
- const clean = line.split('#')[0].trim();
196
- if (depth === 0 && clean.includes('{')) {
197
- const header = clean.split('{')[0];
198
- hosts.push(...header.split(/[\s,]+/).map(hostOf).filter(Boolean));
207
+ const hosts = [];
208
+ let depth = 0;
209
+ for (const line of String(text ?? '').split(/\r?\n/)) {
210
+ const clean = line.split('#')[0].trim();
211
+ if (depth === 0 && clean.includes('{')) {
212
+ const header = clean.split('{')[0];
213
+ hosts.push(...header.split(/[\s,]+/).map(hostOf).filter(Boolean));
214
+ }
215
+ depth += clean.split('{').length - clean.split('}').length;
216
+ depth = Math.max(0, depth);
199
217
  }
200
- depth += clean.split('{').length - clean.split('}').length;
201
- depth = Math.max(0, depth);
202
- }
203
- return hosts;
218
+ return hosts;
204
219
  }
205
-
206
220
  function routedHosts(input) {
207
- const hosts = new Set();
208
- const ingress = mapping(input.model.services)[input.spec.ingress?.component];
209
- const family = repositoryOf(String(ingress?.image ?? '')).toLowerCase();
210
- for (const service of Object.values(mapping(input.model.services))) {
211
- for (const host of labelHosts(service, family)) hosts.add(host);
212
- }
213
- if (!family.startsWith('caddy')) return hosts;
214
- for (const source of caddyConfigSources(mapping(ingress), input.model)) {
215
- for (const host of caddyfileHosts(trackedConfigText(input, source))) hosts.add(host);
216
- }
217
- return hosts;
218
- }
219
-
221
+ const hosts = new Set();
222
+ const ingress = mapping(input.model.services)[input.spec.ingress?.component];
223
+ const family = repositoryOf(String(ingress?.image ?? '')).toLowerCase();
224
+ for (const service of Object.values(mapping(input.model.services))) {
225
+ for (const host of labelHosts(service, family))
226
+ hosts.add(host);
227
+ }
228
+ if (!family.startsWith('caddy'))
229
+ return hosts;
230
+ for (const source of caddyConfigSources(mapping(ingress), input.model)) {
231
+ for (const host of caddyfileHosts(trackedConfigText(input, source)))
232
+ hosts.add(host);
233
+ }
234
+ return hosts;
235
+ }
220
236
  function publicRoutingIssues(input, add) {
221
- const { spec } = input, routed = routedHosts(input);
222
- const declared = new Set(list(spec.ingress?.hosts).map(hostOf).filter(Boolean));
223
- const dns = list(spec.dns);
224
- for (const host of new Set([...declared, ...routed])) {
225
- if (!dns.some(entry => hostOf(entry?.host) === host && present(entry.owner) && present(entry.receipt)))
226
- add('STACKS_DNS_UNDECLARED', `environments.${input.environment}.dns`, 'Each public host must declare its DNS owner and receipt');
227
- // An external shared ingress routes the hosts from its own dynamic files (published by `starci app stack ingress publish`), not from labels here.
228
- if (!declared.has(host) || (externalIngressStack(spec) === null && !routed.has(host)))
229
- add('STACKS_HOST_UNROUTED', `environments.${input.environment}.ingress.hosts`, 'Each public host must be declared and bound by an actual ingress route');
230
- }
231
- const ingress = mapping(input.model.services)[spec.ingress?.component];
232
- const publicIngress = declared.size || routed.size || list(ingress?.ports).length;
233
- if (publicIngress && (!present(spec.tls?.owner) || !present(spec.tls?.receipt)))
234
- add('STACKS_TLS_UNDECLARED', `environments.${input.environment}.tls`, 'Public ingress must declare its TLS owner and issuance/persistence receipt');
235
- }
236
-
237
+ const { spec } = input, routed = routedHosts(input);
238
+ const declared = new Set(list(spec.ingress?.hosts).map(hostOf).filter(Boolean));
239
+ const dns = list(spec.dns);
240
+ for (const host of new Set([...declared, ...routed])) {
241
+ if (!dns.some((entry) => hostOf(entry?.host) === host && present(entry.owner) && present(entry.receipt)))
242
+ add('STACKS_DNS_UNDECLARED', `environments.${input.environment}.dns`, 'Each public host must declare its DNS owner and receipt');
243
+ // An external shared ingress routes the hosts from its own dynamic files (published by `starci app stack ingress publish`), not from labels here.
244
+ if (!declared.has(host) || (externalIngressStack(spec) === null && !routed.has(host)))
245
+ add('STACKS_HOST_UNROUTED', `environments.${input.environment}.ingress.hosts`, 'Each public host must be declared and bound by an actual ingress route');
246
+ }
247
+ const ingress = mapping(input.model.services)[spec.ingress?.component];
248
+ const publicIngress = declared.size || routed.size || list(ingress?.ports).length;
249
+ if (publicIngress && (!present(spec.tls?.owner) || !present(spec.tls?.receipt)))
250
+ add('STACKS_TLS_UNDECLARED', `environments.${input.environment}.tls`, 'Public ingress must declare its TLS owner and issuance/persistence receipt');
251
+ }
237
252
  function usesPersistentVolume(service) {
238
- return list(service.volumes).some(entry => {
239
- if (plain(entry)) return entry.type === 'volume' || (present(entry.source) && !entry.source.startsWith('/'));
240
- if (typeof entry !== 'string' || !entry.includes(':')) return false;
241
- const source = entry.split(':')[0];
242
- return present(source) && !source.startsWith('.') && !source.startsWith('/') && !source.includes(String.fromCodePoint(92));
243
- });
244
- }
245
-
253
+ return list(service.volumes).some((entry) => {
254
+ if (plain(entry))
255
+ return entry.type === 'volume' || (present(entry.source) && !entry.source.startsWith('/'));
256
+ if (typeof entry !== 'string' || !entry.includes(':'))
257
+ return false;
258
+ const source = entry.split(':')[0];
259
+ return present(source) && !source.startsWith('.') && !source.startsWith('/') && !source.includes(String.fromCodePoint(92));
260
+ });
261
+ }
246
262
  function placementIssues(id, component, service, add) {
247
- const stateful = component.stateful === true || component.role === 'stateful' || present(component.database?.provider)
248
- || list(component.volumes).length > 0 || usesPersistentVolume(service);
249
- if (!stateful) return;
250
- const constraints = list(service.deploy?.placement?.constraints);
251
- if (!constraints.length || !constraints.every(present))
252
- add('STACKS_PLACEMENT_MISSING', `services.${id}.deploy.placement`, 'Stateful services and persistent volumes must declare node placement constraints');
253
- }
254
-
263
+ const stateful = component.stateful === true || component.role === 'stateful' || present(component.database?.provider)
264
+ || list(component.volumes).length > 0 || usesPersistentVolume(service);
265
+ if (!stateful)
266
+ return;
267
+ const constraints = list(service.deploy?.placement?.constraints);
268
+ if (!constraints.length || !constraints.every(present))
269
+ add('STACKS_PLACEMENT_MISSING', `services.${id}.deploy.placement`, 'Stateful services and persistent volumes must declare node placement constraints');
270
+ }
255
271
  function healthCommand(test) {
256
- if (present(test)) return test.trim();
257
- if (!Array.isArray(test) || !['CMD', 'CMD-SHELL'].includes(test[0]) || !test.slice(1).every(present)) return null;
258
- return test.slice(1).join(' ').trim();
272
+ if (present(test))
273
+ return test.trim();
274
+ if (!Array.isArray(test) || !['CMD', 'CMD-SHELL'].includes(test[0]) || !test.slice(1).every(present))
275
+ return null;
276
+ return test.slice(1).join(' ').trim();
259
277
  }
260
-
261
278
  function nontrivialHealthcheck(healthcheck) {
262
- const command = healthCommand(healthcheck.test);
263
- if (healthcheck.disable === true || !command || command === 'NONE') return false;
264
- const unwrapped = command.replace(/^(?:\/bin\/)?(?:ba)?sh\s+-c\s+/, '').replace(/^["']|["']$/g, '').trim();
265
- const executable = unwrapped.split(/\s/)[0].split('/').at(-1);
266
- return !['true', ':', 'echo'].includes(executable) && !/^exit\s+0(?:\s|$)/.test(unwrapped)
267
- && !/\|\|\s*(?:true|exit\s+0)(?:\s|$)/.test(unwrapped)
268
- && !endsWithSuccessfulCommand(unwrapped)
269
- && !/process\.exit\(\s*0\s*\)/.test(unwrapped);
270
- }
271
-
279
+ const command = healthCommand(healthcheck.test);
280
+ if (healthcheck.disable === true || !command || command === 'NONE')
281
+ return false;
282
+ const unwrapped = command.replace(/^(?:\/bin\/)?(?:ba)?sh\s+-c\s+/, '').replace(/^["']|["']$/g, '').trim();
283
+ const executable = unwrapped.split(/\s/)[0].split('/').at(-1); // split yields at least one element
284
+ return !['true', ':', 'echo'].includes(executable) && !/^exit\s+0(?:\s|$)/.test(unwrapped)
285
+ && !/\|\|\s*(?:true|exit\s+0)(?:\s|$)/.test(unwrapped)
286
+ && !endsWithSuccessfulCommand(unwrapped)
287
+ && !/process\.exit\(\s*0\s*\)/.test(unwrapped);
288
+ }
272
289
  function endsWithSuccessfulCommand(command) {
273
- const commands = command.split(/[;\n]/);
274
- if (commands.length < 2) return false;
275
- const last = commands.at(-1).trim();
276
- return last === 'true' || /^exit\s+0$/.test(last);
290
+ const commands = command.split(/[;\n]/);
291
+ if (commands.length < 2)
292
+ return false;
293
+ const last = commands.at(-1).trim();
294
+ return last === 'true' || /^exit\s+0$/.test(last);
277
295
  }
278
-
279
296
  function positiveMonitor(value) {
280
- if (typeof value === 'number') return Number.isFinite(value) && value > 0;
281
- if (!present(value)) return false;
282
- const units = value.match(/[a-z]+/g) ?? [], quantities = value.split(/[a-z]+/);
283
- if (quantities.pop() !== '' || !units.length) return false;
284
- return units.every(unit => ['ns', 'us', 'ms', 's', 'm', 'h'].includes(unit))
285
- && quantities.every(quantity => /^\d+(?:\.\d+)?$/.test(quantity)) && /[1-9]/.test(value);
286
- }
287
-
297
+ if (typeof value === 'number')
298
+ return Number.isFinite(value) && value > 0;
299
+ if (!present(value))
300
+ return false;
301
+ const units = value.match(/[a-z]+/g) ?? [], quantities = value.split(/[a-z]+/);
302
+ if (quantities.pop() !== '' || !units.length)
303
+ return false;
304
+ return units.every((unit) => ['ns', 'us', 'ms', 's', 'm', 'h'].includes(unit))
305
+ && quantities.every((quantity) => /^\d+(?:\.\d+)?$/.test(quantity)) && /[1-9]/.test(value);
306
+ }
288
307
  function updatePolicyIssues(id, service, add) {
289
- const deploy = mapping(service.deploy), update = mapping(deploy.update_config);
290
- const updateValid = ['start-first', 'stop-first'].includes(update.order) && update.failure_action === 'rollback' && positiveMonitor(update.monitor);
291
- const rollbackValid = Object.keys(mapping(deploy.rollback_config)).length > 0;
292
- const restartValid = ['none', 'any', 'on-failure'].includes(deploy.restart_policy?.condition);
293
- if (!updateValid || !rollbackValid || !restartValid)
294
- add('STACKS_UPDATE_POLICY_MISSING', `services.${id}.deploy`, 'Declare update order, failure_action: rollback, a positive monitor, rollback_config and restart_policy');
295
- }
296
-
308
+ const deploy = mapping(service.deploy), update = mapping(deploy.update_config);
309
+ const updateValid = ['start-first', 'stop-first'].includes(update.order) && update.failure_action === 'rollback' && positiveMonitor(update.monitor);
310
+ const rollbackValid = Object.keys(mapping(deploy.rollback_config)).length > 0;
311
+ const restartValid = ['none', 'any', 'on-failure'].includes(deploy.restart_policy?.condition);
312
+ if (!updateValid || !rollbackValid || !restartValid)
313
+ add('STACKS_UPDATE_POLICY_MISSING', `services.${id}.deploy`, 'Declare update order, failure_action: rollback, a positive monitor, rollback_config and restart_policy');
314
+ }
297
315
  function runtimeStaticReference(t, node) {
298
- if (!node.moduleSpecifier || !t.isStringLiteralLike(node.moduleSpecifier) || node.isTypeOnly) return null;
299
- if (t.isImportDeclaration(node)) {
300
- const clause = node.importClause;
301
- if (clause?.isTypeOnly) return null;
302
- const named = clause?.namedBindings;
303
- if (named && t.isNamedImports(named) && !clause.name && named.elements.every(entry => entry.isTypeOnly)) return null;
304
- }
305
- if (t.isExportDeclaration(node) && node.exportClause && t.isNamedExports(node.exportClause)
306
- && node.exportClause.elements.every(entry => entry.isTypeOnly)) return null;
307
- return node.moduleSpecifier.text;
308
- }
309
-
316
+ if (!node.moduleSpecifier || !t.isStringLiteralLike(node.moduleSpecifier) || node.isTypeOnly)
317
+ return null;
318
+ if (t.isImportDeclaration(node)) {
319
+ const clause = node.importClause;
320
+ if (clause?.isTypeOnly)
321
+ return null;
322
+ const named = clause?.namedBindings;
323
+ if (named && t.isNamedImports(named) && !clause.name && named.elements.every((entry) => entry.isTypeOnly))
324
+ return null;
325
+ }
326
+ if (t.isExportDeclaration(node) && node.exportClause && t.isNamedExports(node.exportClause)
327
+ && node.exportClause.elements.every((entry) => entry.isTypeOnly))
328
+ return null;
329
+ return node.moduleSpecifier.text;
330
+ }
310
331
  function runtimeReference(t, node) {
311
- if (t.isImportDeclaration(node) || t.isExportDeclaration(node)) return runtimeStaticReference(t, node);
312
- if (t.isImportEqualsDeclaration(node) && !node.isTypeOnly && t.isExternalModuleReference(node.moduleReference)) {
313
- const reference = node.moduleReference.expression;
314
- return reference && t.isStringLiteralLike(reference) ? reference.text : null;
315
- }
316
- if (!t.isCallExpression(node) || !node.arguments.length || !t.isStringLiteralLike(node.arguments[0])) return null;
317
- const expression = node.expression;
318
- if (expression.kind === t.SyntaxKind.ImportKeyword || (t.isIdentifier(expression) && expression.text === 'require')) return node.arguments[0].text;
319
- return null;
320
- }
321
-
332
+ if (t.isImportDeclaration(node) || t.isExportDeclaration(node))
333
+ return runtimeStaticReference(t, node);
334
+ if (t.isImportEqualsDeclaration(node) && !node.isTypeOnly && t.isExternalModuleReference(node.moduleReference)) {
335
+ const reference = node.moduleReference.expression;
336
+ return reference && t.isStringLiteralLike(reference) ? reference.text : null;
337
+ }
338
+ if (!t.isCallExpression(node) || !node.arguments.length || !t.isStringLiteralLike(node.arguments[0]))
339
+ return null;
340
+ const expression = node.expression;
341
+ if (expression.kind === t.SyntaxKind.ImportKeyword || (t.isIdentifier(expression) && expression.text === 'require'))
342
+ return node.arguments[0].text;
343
+ return null;
344
+ }
322
345
  function runtimeImports(source) {
323
- const compiler = ts(), imports = [];
324
- const visit = node => {
325
- const reference = runtimeReference(compiler, node);
326
- if (reference) imports.push(reference);
327
- compiler.forEachChild(node, visit);
328
- };
329
- visit(source);
330
- return imports;
331
- }
332
-
346
+ const compiler = ts(), imports = [];
347
+ const visit = (node) => {
348
+ const reference = runtimeReference(compiler, node);
349
+ if (reference)
350
+ imports.push(reference);
351
+ compiler.forEachChild(node, visit);
352
+ };
353
+ visit(source);
354
+ return imports;
355
+ }
333
356
  function trackedCompilerHost(repoRoot, files) {
334
- const relativeOf = absolute => path.relative(repoRoot, absolute).split(path.sep).join('/');
335
- const readable = absolute => {
336
- const relative = relativeOf(absolute);
337
- return files.has(relative) && relative.startsWith('be/') && !relative.includes('/secrets/')
338
- && (SOURCE.test(relative) || relative.endsWith('.json')) && safeRegularFile(repoRoot, relative);
339
- };
340
- return { ...ts().sys,
341
- readFile: absolute => readable(absolute) ? readText(repoRoot, relativeOf(absolute)) ?? undefined : undefined,
342
- fileExists: readable,
343
- };
344
- }
345
-
357
+ const relativeOf = (absolute) => path.relative(repoRoot, absolute).split(path.sep).join('/');
358
+ const readable = (absolute) => {
359
+ const relative = relativeOf(absolute);
360
+ return files.has(relative) && relative.startsWith('be/') && !relative.includes('/secrets/')
361
+ && (SOURCE.test(relative) || relative.endsWith('.json')) && safeRegularFile(repoRoot, relative);
362
+ };
363
+ return { ...ts().sys,
364
+ readFile: (absolute) => readable(absolute) ? readText(repoRoot, relativeOf(absolute)) ?? undefined : undefined,
365
+ fileExists: readable, };
366
+ }
346
367
  function compilerOptions(repoRoot, app, files, host) {
347
- for (const file of [`be/apps/${app}/tsconfig.json`, 'be/tsconfig.json']) {
348
- if (!files.has(file)) continue;
349
- const project = readTypeScriptProject(ts(), path.join(repoRoot, file), host.readFile);
350
- if (project.parsed) return project.parsed.options;
351
- }
352
- return { baseUrl: path.join(repoRoot, 'be'), paths: { '@features/*': ['src/features/*'], '@modules/*': ['src/modules/*'] } };
353
- }
354
-
368
+ for (const file of [`be/apps/${app}/tsconfig.json`, 'be/tsconfig.json']) {
369
+ if (!files.has(file))
370
+ continue;
371
+ const project = readTypeScriptProject(ts(), path.join(repoRoot, file), host.readFile);
372
+ if (project.parsed)
373
+ return project.parsed.options;
374
+ }
375
+ return { baseUrl: path.join(repoRoot, 'be'), paths: { '@features/*': ['src/features/*'], '@modules/*': ['src/modules/*'] } };
376
+ }
355
377
  function sourceTarget(repoRoot, file, specifier, options, files, host) {
356
- const absolute = resolveTypeScriptModule(ts(), specifier, path.join(repoRoot, file), options, host);
357
- if (!absolute) return null;
358
- const relative = path.relative(repoRoot, absolute).split(path.sep).join('/');
359
- return files.has(relative) && SOURCE.test(relative) && !TEST_SOURCE.test(relative) && !relative.includes('/secrets/') ? relative : null;
378
+ const absolute = resolveTypeScriptModule(ts(), specifier, path.join(repoRoot, file), options, host);
379
+ if (!absolute)
380
+ return null;
381
+ const relative = path.relative(repoRoot, absolute).split(path.sep).join('/');
382
+ return files.has(relative) && SOURCE.test(relative) && !TEST_SOURCE.test(relative) && !relative.includes('/secrets/') ? relative : null;
360
383
  }
361
-
362
384
  function appComposesRealtime(repoRoot, app, files) {
363
- if (!repoRoot) return false;
364
- const tracked = new Set(files), host = trackedCompilerHost(repoRoot, tracked);
365
- const options = compilerOptions(repoRoot, app, tracked, host);
366
- const entry = `be/apps/${app}/src/main.ts`;
367
- const queue = tracked.has(entry) ? [entry] : [];
368
- const seen = new Set();
369
- while (queue.length) {
370
- const file = queue.shift();
371
- if (seen.has(file)) continue;
372
- seen.add(file);
373
- if (REALTIME_SOURCE.test(file)) return true;
374
- if (!safeRegularFile(repoRoot, file)) continue;
375
- const source = parseSource(readText(repoRoot, file) ?? '', file);
376
- for (const specifier of runtimeImports(source)) {
377
- const target = sourceTarget(repoRoot, file, specifier, options, tracked, host);
378
- if (target) queue.push(target);
385
+ if (!repoRoot)
386
+ return false;
387
+ const tracked = new Set(files), host = trackedCompilerHost(repoRoot, tracked);
388
+ const options = compilerOptions(repoRoot, app, tracked, host);
389
+ const entry = `be/apps/${app}/src/main.ts`;
390
+ const queue = tracked.has(entry) ? [entry] : [];
391
+ const seen = new Set();
392
+ while (queue.length) {
393
+ const file = queue.shift();
394
+ if (seen.has(file))
395
+ continue;
396
+ seen.add(file);
397
+ if (REALTIME_SOURCE.test(file))
398
+ return true;
399
+ if (!safeRegularFile(repoRoot, file))
400
+ continue;
401
+ const source = parseSource(readText(repoRoot, file) ?? '', file);
402
+ for (const specifier of runtimeImports(source)) {
403
+ const target = sourceTarget(repoRoot, file, specifier, options, tracked, host);
404
+ if (target)
405
+ queue.push(target);
406
+ }
379
407
  }
380
- }
381
- return false;
408
+ return false;
382
409
  }
383
-
384
410
  const SHARED_HUBS = new Set(['postgres', 'redis']);
385
-
386
411
  /** The hub a service selects with REALTIME_HUB, or null when it declares none. */
387
412
  function realtimeHub(service) {
388
- const entry = composeEntries(service.environment, { missingValue: null }).find(([key]) => key === 'REALTIME_HUB');
389
- return entry && present(entry[1]) ? String(entry[1]).trim() : null;
413
+ const entry = composeEntries(service.environment, { missingValue: null }).find(([key]) => key === 'REALTIME_HUB');
414
+ return entry && present(entry[1]) ? String(entry[1]).trim() : null;
390
415
  }
391
-
392
416
  /** A service runs on several nodes: more than one replica, or the global mode (one task per node). */
393
- const scaledOut = service => service.deploy?.mode === 'global' || Number(service.deploy?.replicas ?? 1) > 1;
394
-
417
+ const scaledOut = (service) => service.deploy?.mode === 'global' || Number(service.deploy?.replicas ?? 1) > 1;
395
418
  /** Realtime scale (knowledge/patterns/be/realtime.yaml BE-REALTIME-7): an API with several replicas selects a shared hub. */
396
419
  function realtimeIssues(input, add) {
397
- const apis = new Set(list(input.repo?.sides?.be?.apps).filter(app => app.kind === 'api').map(app => app.name));
398
- for (const [id, service] of Object.entries(mapping(input.model.services))) {
399
- const component = mapping(input.doc.components)[id], app = component?.app ?? id;
400
- if (!apis.has(app) || !scaledOut(service) || !appComposesRealtime(input.repoRoot, app, list(input.files))) continue;
401
- if (!SHARED_HUBS.has(realtimeHub(service) ?? ''))
402
- add('STACKS_REALTIME_SCALED', `services.${id}.environment.REALTIME_HUB`, 'A realtime API with more than one replica must select a shared hub (REALTIME_HUB postgres or redis): the memory hub serves one process only');
403
- }
404
- }
405
-
420
+ const apis = new Set(list(input.repo?.sides?.be?.apps).filter((app) => app.kind === 'api').map((app) => app.name));
421
+ for (const [id, service] of Object.entries(mapping(input.model.services))) {
422
+ const component = mapping(input.doc.components)[id], app = component?.app ?? id;
423
+ if (!apis.has(app) || !scaledOut(service) || !appComposesRealtime(input.repoRoot, app, list(input.files)))
424
+ continue;
425
+ if (!SHARED_HUBS.has(realtimeHub(service) ?? ''))
426
+ add('STACKS_REALTIME_SCALED', `services.${id}.environment.REALTIME_HUB`, 'A realtime API with more than one replica must select a shared hub (REALTIME_HUB postgres or redis): the memory hub serves one process only');
427
+ }
428
+ }
406
429
  /** Machine issues shared by the HFS finder and the rendered-model gate; no secret contents are read or returned. */
407
430
  export function swarmHardeningIssues(input) {
408
- const normalized = { ...input, doc: mapping(input.doc), spec: mapping(input.spec), model: mapping(input.model) };
409
- const issues = [], add = (code, at, message) => issues.push({ code, at, message });
410
- secretCustodyIssues(normalized.spec, normalized.model, add);
411
- for (const [id, value] of Object.entries(mapping(normalized.model.services))) {
412
- const service = mapping(value), component = mapping(normalized.doc.components)[id] ?? {};
413
- environmentSecretIssues(id, service, normalized.spec, normalized.model, add);
414
- publishedPortIssues(id, service, normalized.spec, add);
415
- placementIssues(id, component, service, add);
416
- if (!nontrivialHealthcheck(mapping(service.healthcheck)))
417
- add('STACKS_HEALTHCHECK_MISSING', `services.${id}.healthcheck`, 'Every Swarm service needs an enabled healthcheck that can fail when its process is unhealthy');
418
- updatePolicyIssues(id, service, add);
419
- }
420
- publicRoutingIssues(normalized, add);
421
- realtimeIssues(normalized, add);
422
- return issues;
423
- }
424
-
431
+ const normalized = { ...input, doc: mapping(input.doc), spec: mapping(input.spec), model: mapping(input.model) };
432
+ const issues = [], add = (code, at, message) => issues.push({ code, at, message });
433
+ secretCustodyIssues(normalized.spec, normalized.model, add);
434
+ for (const [id, value] of Object.entries(mapping(normalized.model.services))) {
435
+ const service = mapping(value), component = mapping(normalized.doc.components)[id] ?? {};
436
+ environmentSecretIssues(id, service, normalized.spec, normalized.model, add);
437
+ publishedPortIssues(id, service, normalized.spec, add);
438
+ placementIssues(id, component, service, add);
439
+ if (!nontrivialHealthcheck(mapping(service.healthcheck)))
440
+ add('STACKS_HEALTHCHECK_MISSING', `services.${id}.healthcheck`, 'Every Swarm service needs an enabled healthcheck that can fail when its process is unhealthy');
441
+ updatePolicyIssues(id, service, add);
442
+ }
443
+ publicRoutingIssues(normalized, add);
444
+ realtimeIssues(normalized, add);
445
+ return issues;
446
+ }
425
447
  /** R266 findings at the app root, over each available tracked rendered Swarm model. */
426
448
  export function stacksSwarmFindings(context) {
427
- return stacksDeploymentFindings(context, swarmHardeningIssues);
449
+ return stacksDeploymentFindings(context, swarmHardeningIssues);
428
450
  }