primitive-admin 1.0.62 → 1.0.64

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 (344) hide show
  1. package/README.md +132 -42
  2. package/assets/skill/skills/primitive-platform/SKILL.md +142 -661
  3. package/dist/bin/primitive.js +121 -41
  4. package/dist/bin/primitive.js.map +1 -1
  5. package/dist/src/commands/admins.js +37 -50
  6. package/dist/src/commands/admins.js.map +1 -1
  7. package/dist/src/commands/analytics.js +178 -9
  8. package/dist/src/commands/analytics.js.map +1 -1
  9. package/dist/src/commands/apps.js +17 -7
  10. package/dist/src/commands/apps.js.map +1 -1
  11. package/dist/src/commands/auth-sessions.d.ts +7 -0
  12. package/dist/src/commands/auth-sessions.js +144 -0
  13. package/dist/src/commands/auth-sessions.js.map +1 -0
  14. package/dist/src/commands/auth.js +76 -116
  15. package/dist/src/commands/auth.js.map +1 -1
  16. package/dist/src/commands/blob-buckets.js +2 -1
  17. package/dist/src/commands/blob-buckets.js.map +1 -1
  18. package/dist/src/commands/catalog.js +26 -10
  19. package/dist/src/commands/catalog.js.map +1 -1
  20. package/dist/src/commands/collection-type-configs.js +3 -10
  21. package/dist/src/commands/collection-type-configs.js.map +1 -1
  22. package/dist/src/commands/collections.js +736 -19
  23. package/dist/src/commands/collections.js.map +1 -1
  24. package/dist/src/commands/config.js +13 -27
  25. package/dist/src/commands/config.js.map +1 -1
  26. package/dist/src/commands/connections.js +8 -9
  27. package/dist/src/commands/connections.js.map +1 -1
  28. package/dist/src/commands/cron-triggers.js +2 -1
  29. package/dist/src/commands/cron-triggers.js.map +1 -1
  30. package/dist/src/commands/database-type-configs.js +5 -12
  31. package/dist/src/commands/database-type-configs.js.map +1 -1
  32. package/dist/src/commands/databases.js +59 -72
  33. package/dist/src/commands/databases.js.map +1 -1
  34. package/dist/src/commands/documents.d.ts +58 -0
  35. package/dist/src/commands/documents.js +1623 -95
  36. package/dist/src/commands/documents.js.map +1 -1
  37. package/dist/src/commands/email-templates.js +5 -4
  38. package/dist/src/commands/email-templates.js.map +1 -1
  39. package/dist/src/commands/env.d.ts +1 -1
  40. package/dist/src/commands/env.js +106 -44
  41. package/dist/src/commands/env.js.map +1 -1
  42. package/dist/src/commands/feature-flags.js +2 -1
  43. package/dist/src/commands/feature-flags.js.map +1 -1
  44. package/dist/src/commands/functions.d.ts +20 -0
  45. package/dist/src/commands/functions.js +1630 -0
  46. package/dist/src/commands/functions.js.map +1 -0
  47. package/dist/src/commands/group-type-configs.js +2 -1
  48. package/dist/src/commands/group-type-configs.js.map +1 -1
  49. package/dist/src/commands/groups.js +30 -17
  50. package/dist/src/commands/groups.js.map +1 -1
  51. package/dist/src/commands/guides.js +17 -11
  52. package/dist/src/commands/guides.js.map +1 -1
  53. package/dist/src/commands/init.d.ts +24 -12
  54. package/dist/src/commands/init.js +198 -110
  55. package/dist/src/commands/init.js.map +1 -1
  56. package/dist/src/commands/integrations.js +65 -26
  57. package/dist/src/commands/integrations.js.map +1 -1
  58. package/dist/src/commands/locks.js +17 -2
  59. package/dist/src/commands/locks.js.map +1 -1
  60. package/dist/src/commands/metadata-category-configs.js +2 -1
  61. package/dist/src/commands/metadata-category-configs.js.map +1 -1
  62. package/dist/src/commands/metadata.js +8 -1
  63. package/dist/src/commands/metadata.js.map +1 -1
  64. package/dist/src/commands/prompts.js +106 -59
  65. package/dist/src/commands/prompts.js.map +1 -1
  66. package/dist/src/commands/rule-sets.js +3 -10
  67. package/dist/src/commands/rule-sets.js.map +1 -1
  68. package/dist/src/commands/scripts.d.ts +10 -0
  69. package/dist/src/commands/scripts.js +159 -25
  70. package/dist/src/commands/scripts.js.map +1 -1
  71. package/dist/src/commands/secrets.js +2 -1
  72. package/dist/src/commands/secrets.js.map +1 -1
  73. package/dist/src/commands/sessions.js +10 -9
  74. package/dist/src/commands/sessions.js.map +1 -1
  75. package/dist/src/commands/sync-app-settings.js +3 -5
  76. package/dist/src/commands/sync-app-settings.js.map +1 -1
  77. package/dist/src/commands/sync.d.ts +391 -44
  78. package/dist/src/commands/sync.js +2622 -534
  79. package/dist/src/commands/sync.js.map +1 -1
  80. package/dist/src/commands/tokens.js +2 -1
  81. package/dist/src/commands/tokens.js.map +1 -1
  82. package/dist/src/commands/users.js +19 -10
  83. package/dist/src/commands/users.js.map +1 -1
  84. package/dist/src/commands/vars.js +2 -1
  85. package/dist/src/commands/vars.js.map +1 -1
  86. package/dist/src/commands/waitlist.js +2 -1
  87. package/dist/src/commands/waitlist.js.map +1 -1
  88. package/dist/src/commands/webhooks.d.ts +29 -0
  89. package/dist/src/commands/webhooks.js +135 -64
  90. package/dist/src/commands/webhooks.js.map +1 -1
  91. package/dist/src/commands/workflows.d.ts +1 -29
  92. package/dist/src/commands/workflows.js +113 -179
  93. package/dist/src/commands/workflows.js.map +1 -1
  94. package/dist/src/lib/api-client.d.ts +628 -14
  95. package/dist/src/lib/api-client.js +776 -70
  96. package/dist/src/lib/api-client.js.map +1 -1
  97. package/dist/src/lib/app-settings-descriptor.d.ts +1 -1
  98. package/dist/src/lib/app-settings-descriptor.js +9 -1
  99. package/dist/src/lib/app-settings-descriptor.js.map +1 -1
  100. package/dist/src/lib/block-selector.d.ts +58 -0
  101. package/dist/src/lib/block-selector.js +92 -0
  102. package/dist/src/lib/block-selector.js.map +1 -0
  103. package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.d.ts +24 -54
  104. package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js +31 -153
  105. package/dist/src/lib/codegen-shared/resolveCodegenSourceDir.js.map +1 -1
  106. package/dist/src/lib/collection-export.d.ts +184 -0
  107. package/dist/src/lib/collection-export.js +252 -0
  108. package/dist/src/lib/collection-export.js.map +1 -0
  109. package/dist/src/lib/config-json-field.d.ts +28 -0
  110. package/dist/src/lib/config-json-field.js +56 -0
  111. package/dist/src/lib/config-json-field.js.map +1 -0
  112. package/dist/src/lib/config-object-descriptor.js +88 -6
  113. package/dist/src/lib/config-object-descriptor.js.map +1 -1
  114. package/dist/src/lib/config-payload.d.ts +8 -1
  115. package/dist/src/lib/config-payload.js +49 -4
  116. package/dist/src/lib/config-payload.js.map +1 -1
  117. package/dist/src/lib/config-surface.d.ts +12 -1
  118. package/dist/src/lib/config-surface.js +71 -3
  119. package/dist/src/lib/config-surface.js.map +1 -1
  120. package/dist/src/lib/config.d.ts +31 -13
  121. package/dist/src/lib/config.js +34 -70
  122. package/dist/src/lib/config.js.map +1 -1
  123. package/dist/src/lib/credentials-store.d.ts +37 -22
  124. package/dist/src/lib/credentials-store.js +103 -97
  125. package/dist/src/lib/credentials-store.js.map +1 -1
  126. package/dist/src/lib/db-codegen/dbTypeIR.js +8 -0
  127. package/dist/src/lib/db-codegen/dbTypeIR.js.map +1 -1
  128. package/dist/src/lib/deprecation.d.ts +22 -0
  129. package/dist/src/lib/deprecation.js +43 -0
  130. package/dist/src/lib/deprecation.js.map +1 -0
  131. package/dist/src/lib/document-export-permissions.d.ts +30 -0
  132. package/dist/src/lib/document-export-permissions.js +54 -0
  133. package/dist/src/lib/document-export-permissions.js.map +1 -0
  134. package/dist/src/lib/document-ingest-artifact.d.ts +120 -0
  135. package/dist/src/lib/document-ingest-artifact.js +505 -0
  136. package/dist/src/lib/document-ingest-artifact.js.map +1 -0
  137. package/dist/src/lib/document-ingest-input.d.ts +51 -0
  138. package/dist/src/lib/document-ingest-input.js +132 -0
  139. package/dist/src/lib/document-ingest-input.js.map +1 -0
  140. package/dist/src/lib/document-ingest-rows.d.ts +137 -0
  141. package/dist/src/lib/document-ingest-rows.js +181 -0
  142. package/dist/src/lib/document-ingest-rows.js.map +1 -0
  143. package/dist/src/lib/document-ingest.d.ts +101 -0
  144. package/dist/src/lib/document-ingest.js +384 -0
  145. package/dist/src/lib/document-ingest.js.map +1 -0
  146. package/dist/src/lib/env-resolver-core.d.ts +128 -17
  147. package/dist/src/lib/env-resolver-core.js +204 -22
  148. package/dist/src/lib/env-resolver-core.js.map +1 -1
  149. package/dist/src/lib/env-resolver.d.ts +18 -3
  150. package/dist/src/lib/env-resolver.js +23 -3
  151. package/dist/src/lib/env-resolver.js.map +1 -1
  152. package/dist/src/lib/function-bundle.d.ts +147 -0
  153. package/dist/src/lib/function-bundle.js +341 -0
  154. package/dist/src/lib/function-bundle.js.map +1 -0
  155. package/dist/src/lib/function-collect.d.ts +123 -0
  156. package/dist/src/lib/function-collect.js +610 -0
  157. package/dist/src/lib/function-collect.js.map +1 -0
  158. package/dist/src/lib/function-db-types.d.ts +202 -0
  159. package/dist/src/lib/function-db-types.js +870 -0
  160. package/dist/src/lib/function-db-types.js.map +1 -0
  161. package/dist/src/lib/function-document-types.d.ts +144 -0
  162. package/dist/src/lib/function-document-types.js +370 -0
  163. package/dist/src/lib/function-document-types.js.map +1 -0
  164. package/dist/src/lib/function-grants-preflight.d.ts +64 -0
  165. package/dist/src/lib/function-grants-preflight.js +105 -0
  166. package/dist/src/lib/function-grants-preflight.js.map +1 -0
  167. package/dist/src/lib/function-log-lines.d.ts +76 -0
  168. package/dist/src/lib/function-log-lines.js +160 -0
  169. package/dist/src/lib/function-log-lines.js.map +1 -0
  170. package/dist/src/lib/function-log-row.d.ts +29 -0
  171. package/dist/src/lib/function-log-row.js +73 -0
  172. package/dist/src/lib/function-log-row.js.map +1 -0
  173. package/dist/src/lib/function-log-tail.d.ts +132 -0
  174. package/dist/src/lib/function-log-tail.js +262 -0
  175. package/dist/src/lib/function-log-tail.js.map +1 -0
  176. package/dist/src/lib/function-run.d.ts +289 -0
  177. package/dist/src/lib/function-run.js +389 -0
  178. package/dist/src/lib/function-run.js.map +1 -0
  179. package/dist/src/lib/function-schema-codegen.d.ts +143 -0
  180. package/dist/src/lib/function-schema-codegen.js +420 -0
  181. package/dist/src/lib/function-schema-codegen.js.map +1 -0
  182. package/dist/src/lib/function-sync.d.ts +459 -0
  183. package/dist/src/lib/function-sync.js +1258 -0
  184. package/dist/src/lib/function-sync.js.map +1 -0
  185. package/dist/src/lib/function-trigger-listing.d.ts +27 -0
  186. package/dist/src/lib/function-trigger-listing.js +70 -0
  187. package/dist/src/lib/function-trigger-listing.js.map +1 -0
  188. package/dist/src/lib/function-typecheck.d.ts +86 -0
  189. package/dist/src/lib/function-typecheck.js +370 -0
  190. package/dist/src/lib/function-typecheck.js.map +1 -0
  191. package/dist/src/lib/function-versions.d.ts +122 -0
  192. package/dist/src/lib/function-versions.js +182 -0
  193. package/dist/src/lib/function-versions.js.map +1 -0
  194. package/dist/src/lib/generated-allowlist.js +4 -0
  195. package/dist/src/lib/generated-allowlist.js.map +1 -1
  196. package/dist/src/lib/generated-config-surfaces.d.ts +2332 -78
  197. package/dist/src/lib/generated-config-surfaces.js +6979 -468
  198. package/dist/src/lib/generated-config-surfaces.js.map +1 -1
  199. package/dist/src/lib/generated-sdk-types.d.ts +12 -0
  200. package/dist/src/lib/generated-sdk-types.js +13 -0
  201. package/dist/src/lib/generated-sdk-types.js.map +1 -0
  202. package/dist/src/lib/init-adopt.js +2 -2
  203. package/dist/src/lib/init-adopt.js.map +1 -1
  204. package/dist/src/lib/init-assets.js +3 -3
  205. package/dist/src/lib/init-client-platforms.d.ts +14 -0
  206. package/dist/src/lib/init-client-platforms.js +71 -0
  207. package/dist/src/lib/init-client-platforms.js.map +1 -0
  208. package/dist/src/lib/init-config.d.ts +1 -1
  209. package/dist/src/lib/init-email-redirect-uris.d.ts +37 -0
  210. package/dist/src/lib/init-email-redirect-uris.js +46 -0
  211. package/dist/src/lib/init-email-redirect-uris.js.map +1 -0
  212. package/dist/src/lib/init-ios-links.d.ts +41 -0
  213. package/dist/src/lib/init-ios-links.js +67 -1
  214. package/dist/src/lib/init-ios-links.js.map +1 -1
  215. package/dist/src/lib/init-plan.d.ts +1 -1
  216. package/dist/src/lib/init-plan.js +1 -1
  217. package/dist/src/lib/init-xcode.d.ts +6 -5
  218. package/dist/src/lib/init-xcode.js +34 -10
  219. package/dist/src/lib/init-xcode.js.map +1 -1
  220. package/dist/src/lib/integration-selector.d.ts +42 -0
  221. package/dist/src/lib/integration-selector.js +46 -0
  222. package/dist/src/lib/integration-selector.js.map +1 -0
  223. package/dist/src/lib/ios-app-id.d.ts +34 -0
  224. package/dist/src/lib/ios-app-id.js +69 -0
  225. package/dist/src/lib/ios-app-id.js.map +1 -0
  226. package/dist/src/lib/list-options.d.ts +68 -0
  227. package/dist/src/lib/list-options.js +89 -0
  228. package/dist/src/lib/list-options.js.map +1 -0
  229. package/dist/src/lib/local-state.d.ts +1 -1
  230. package/dist/src/lib/local-state.js +1 -1
  231. package/dist/src/lib/local-test-cases.d.ts +63 -0
  232. package/dist/src/lib/local-test-cases.js +136 -0
  233. package/dist/src/lib/local-test-cases.js.map +1 -0
  234. package/dist/src/lib/log-inspection.d.ts +152 -5
  235. package/dist/src/lib/log-inspection.js +179 -2
  236. package/dist/src/lib/log-inspection.js.map +1 -1
  237. package/dist/src/lib/logout-admin-session.d.ts +33 -0
  238. package/dist/src/lib/logout-admin-session.js +70 -0
  239. package/dist/src/lib/logout-admin-session.js.map +1 -0
  240. package/dist/src/lib/output.d.ts +15 -0
  241. package/dist/src/lib/output.js +28 -0
  242. package/dist/src/lib/output.js.map +1 -1
  243. package/dist/src/lib/paginate.d.ts +15 -0
  244. package/dist/src/lib/paginate.js +17 -0
  245. package/dist/src/lib/paginate.js.map +1 -1
  246. package/dist/src/lib/project-config.d.ts +46 -21
  247. package/dist/src/lib/project-config.js +74 -47
  248. package/dist/src/lib/project-config.js.map +1 -1
  249. package/dist/src/lib/prompt-cost-format.d.ts +11 -0
  250. package/dist/src/lib/prompt-cost-format.js +41 -0
  251. package/dist/src/lib/prompt-cost-format.js.map +1 -0
  252. package/dist/src/lib/prompt-schema-codegen.d.ts +147 -0
  253. package/dist/src/lib/prompt-schema-codegen.js +462 -0
  254. package/dist/src/lib/prompt-schema-codegen.js.map +1 -0
  255. package/dist/src/lib/refresh-admin-credentials.d.ts +9 -1
  256. package/dist/src/lib/refresh-admin-credentials.js +22 -2
  257. package/dist/src/lib/refresh-admin-credentials.js.map +1 -1
  258. package/dist/src/lib/resolve-owner.d.ts +19 -0
  259. package/dist/src/lib/resolve-owner.js +20 -0
  260. package/dist/src/lib/resolve-owner.js.map +1 -0
  261. package/dist/src/lib/skill-installer.d.ts +49 -3
  262. package/dist/src/lib/skill-installer.js +275 -100
  263. package/dist/src/lib/skill-installer.js.map +1 -1
  264. package/dist/src/lib/snapshot-audit-source.d.ts +45 -0
  265. package/dist/src/lib/snapshot-audit-source.js +58 -0
  266. package/dist/src/lib/snapshot-audit-source.js.map +1 -0
  267. package/dist/src/lib/snapshot-audit-store.d.ts +52 -0
  268. package/dist/src/lib/snapshot-audit-store.js +196 -0
  269. package/dist/src/lib/snapshot-audit-store.js.map +1 -0
  270. package/dist/src/lib/snapshot-audit.d.ts +207 -0
  271. package/dist/src/lib/snapshot-audit.js +431 -0
  272. package/dist/src/lib/snapshot-audit.js.map +1 -0
  273. package/dist/src/lib/snapshot-build-rows.d.ts +60 -0
  274. package/dist/src/lib/snapshot-build-rows.js +87 -0
  275. package/dist/src/lib/snapshot-build-rows.js.map +1 -0
  276. package/dist/src/lib/snapshot-build.d.ts +50 -0
  277. package/dist/src/lib/snapshot-build.js +111 -0
  278. package/dist/src/lib/snapshot-build.js.map +1 -0
  279. package/dist/src/lib/snapshot-manifest-layout.d.ts +61 -0
  280. package/dist/src/lib/snapshot-manifest-layout.js +70 -0
  281. package/dist/src/lib/snapshot-manifest-layout.js.map +1 -0
  282. package/dist/src/lib/snapshots.d.ts +8 -9
  283. package/dist/src/lib/snapshots.js +20 -83
  284. package/dist/src/lib/snapshots.js.map +1 -1
  285. package/dist/src/lib/step-run-table.d.ts +43 -0
  286. package/dist/src/lib/step-run-table.js +129 -0
  287. package/dist/src/lib/step-run-table.js.map +1 -0
  288. package/dist/src/lib/storage-pending-retry.d.ts +26 -0
  289. package/dist/src/lib/storage-pending-retry.js +42 -0
  290. package/dist/src/lib/storage-pending-retry.js.map +1 -0
  291. package/dist/src/lib/swift-codegen/agentGenerator.d.ts +42 -0
  292. package/dist/src/lib/swift-codegen/agentGenerator.js +118 -0
  293. package/dist/src/lib/swift-codegen/agentGenerator.js.map +1 -0
  294. package/dist/src/lib/swift-codegen/banners.d.ts +24 -0
  295. package/dist/src/lib/swift-codegen/banners.js +25 -0
  296. package/dist/src/lib/swift-codegen/banners.js.map +1 -0
  297. package/dist/src/lib/swift-codegen/dbGenerator.js +19 -7
  298. package/dist/src/lib/swift-codegen/dbGenerator.js.map +1 -1
  299. package/dist/src/lib/swift-codegen/functionGenerator.d.ts +139 -0
  300. package/dist/src/lib/swift-codegen/functionGenerator.js +462 -0
  301. package/dist/src/lib/swift-codegen/functionGenerator.js.map +1 -0
  302. package/dist/src/lib/swift-codegen/generator.d.ts +7 -1
  303. package/dist/src/lib/swift-codegen/generator.js +28 -11
  304. package/dist/src/lib/swift-codegen/generator.js.map +1 -1
  305. package/dist/src/lib/swift-codegen/schemaToSwift.d.ts +15 -0
  306. package/dist/src/lib/swift-codegen/schemaToSwift.js +21 -4
  307. package/dist/src/lib/swift-codegen/schemaToSwift.js.map +1 -1
  308. package/dist/src/lib/sync-paths.d.ts +72 -55
  309. package/dist/src/lib/sync-paths.js +97 -100
  310. package/dist/src/lib/sync-paths.js.map +1 -1
  311. package/dist/src/lib/sync-resource-types.d.ts +23 -4
  312. package/dist/src/lib/sync-resource-types.js +106 -8
  313. package/dist/src/lib/sync-resource-types.js.map +1 -1
  314. package/dist/src/lib/sync-selectors.d.ts +45 -2
  315. package/dist/src/lib/sync-selectors.js +66 -5
  316. package/dist/src/lib/sync-selectors.js.map +1 -1
  317. package/dist/src/lib/template.d.ts +2 -2
  318. package/dist/src/lib/template.js +2 -2
  319. package/dist/src/lib/test-case-file-names.d.ts +40 -0
  320. package/dist/src/lib/test-case-file-names.js +91 -0
  321. package/dist/src/lib/test-case-file-names.js.map +1 -0
  322. package/dist/src/lib/test-case-keys.d.ts +1 -1
  323. package/dist/src/lib/test-case-keys.js +1 -1
  324. package/dist/src/lib/test-case-variables.d.ts +14 -0
  325. package/dist/src/lib/test-case-variables.js +42 -0
  326. package/dist/src/lib/test-case-variables.js.map +1 -1
  327. package/dist/src/lib/toml-database-config.js +19 -2
  328. package/dist/src/lib/toml-database-config.js.map +1 -1
  329. package/dist/src/lib/web-url.d.ts +40 -0
  330. package/dist/src/lib/web-url.js +76 -0
  331. package/dist/src/lib/web-url.js.map +1 -0
  332. package/dist/src/lib/webhook-deliver.d.ts +209 -0
  333. package/dist/src/lib/webhook-deliver.js +519 -0
  334. package/dist/src/lib/webhook-deliver.js.map +1 -0
  335. package/dist/src/lib/workflow-codegen/generator.d.ts +1 -1
  336. package/dist/src/lib/workflow-codegen/generator.js +1 -1
  337. package/dist/src/lib/workflow-toml-validator.d.ts +17 -8
  338. package/dist/src/lib/workflow-toml-validator.js +25 -12
  339. package/dist/src/lib/workflow-toml-validator.js.map +1 -1
  340. package/dist/src/lib/workflow-usage.d.ts +196 -0
  341. package/dist/src/lib/workflow-usage.js +310 -0
  342. package/dist/src/lib/workflow-usage.js.map +1 -0
  343. package/dist/src/types/index.d.ts +12 -2
  344. package/package.json +5 -4
@@ -0,0 +1,519 @@
1
+ /**
2
+ * Deliver a signed preview through a webhook's real receive path (#3321).
3
+ *
4
+ * `primitive webhooks test --deliver` adds no server dispatch surface. It
5
+ * composes two capabilities that already exist:
6
+ *
7
+ * 1. the admin-gated preview `POST /admin/api/apps/{appId}/webhooks/{id}/test`,
8
+ * which signs a payload with the same rule the receiver verifies with, and
9
+ * 2. the public receive endpoint `POST /app/{appId}/webhook/{webhookKey}`,
10
+ * the unauthenticated path a provider posts to.
11
+ *
12
+ * So the delivery is a real delivery: the body cap, the availability check, the
13
+ * IP allowlist, signature verification, handshake rules, deduplication, the run
14
+ * row and the delivery log all run exactly as they do for a provider. Nobody
15
+ * gains authority they did not have — only someone who can already administer
16
+ * the app can obtain a signature — and nothing bypasses verification, because
17
+ * the signature is checked for real at the receive endpoint.
18
+ *
19
+ * ── What this module owes the caller ──────────────────────────────────────
20
+ *
21
+ * An honest report. The receive endpoint answers `{received: true}` and
22
+ * discloses nothing else (it must not: it is unauthenticated), so "did the
23
+ * function actually run?" is answered from the delivery log and the runs
24
+ * surface, and only positive evidence may be reported as a dispatch:
25
+ *
26
+ * - **Correlation is one rule.** A delivery-log row NEWER than a baseline
27
+ * snapshot taken before the POST, whose `dedupKey` equals the one the
28
+ * preview returned. That key hashes the whole signed payload including its
29
+ * timestamp prefix, so it is unique to this request rather than a
30
+ * heuristic; the baseline is what keeps a replay of the same signed bytes
31
+ * from being attributed here. There is no body-hash fallback: identical
32
+ * bodies collide, and attributing another request's row is worse than
33
+ * declining to.
34
+ * - **The key names dispatched deliveries only.** The receiver writes
35
+ * `dedupKey` on an `accepted` row that really dispatched and OMITS it
36
+ * everywhere else — on a handshake row, a duplicate, a rejection, a 202
37
+ * non-dispatch, and on the `accepted` row of a delivery whose target was
38
+ * not found (`webhook-receiver.ts`, `logEvent`). That omission is what
39
+ * keeps the `eventsByDedupKey` index holding exactly the deliveries that
40
+ * may suppress a later one, so it is load-bearing, not incidental. The
41
+ * consequence here: a delivery the receiver did not dispatch has no row
42
+ * this correlator can reach, and is reported as unconfirmed — with what
43
+ * the absence of the key means — rather than named from a row.
44
+ * - **A run is confirmed, not assumed.** An `accepted` row names a run id
45
+ * before the run finishes, and the legacy workflow branch keeps its
46
+ * `accepted` row and its HTTP 200 even when the launch is skipped or
47
+ * throws. So the named run is looked up on the authenticated runs surface
48
+ * before dispatch is claimed.
49
+ * - **Everything else is named for what it was** — a suppressed replay, a
50
+ * 410/403/401 refusal, each of which the receive endpoint reports for
51
+ * itself — or reported as "dispatch unconfirmed", which is where a
52
+ * handshake short-circuit (it can legally answer 200 `{received:true}`
53
+ * before any dispatch) and a 202 non-dispatch land, since neither records
54
+ * a correlatable row. Only a confirmed dispatch exits `0`.
55
+ */
56
+ import { fetchWithTLS } from "./fetch.js";
57
+ /** ~5 attempts over ~4 s: the accepted row is written before execution ends. */
58
+ export const DELIVER_POLL_ATTEMPTS = 5;
59
+ export const DELIVER_POLL_INTERVAL_MS = 800;
60
+ /** Cursor pages walked per attempt, so a busy log cannot outrun the poll. */
61
+ export const DELIVER_PAGE_CAP = 10;
62
+ export const DELIVER_PAGE_LIMIT = 25;
63
+ /** The same bound on the runs surface, where runs start while this one waits. */
64
+ export const DELIVER_RUN_PAGE_CAP = 5;
65
+ export const DELIVER_RUN_PAGE_LIMIT = 50;
66
+ /** Comfortably above the sync-function ceiling. */
67
+ export const DELIVER_TIMEOUT_MS = 60_000;
68
+ /**
69
+ * What the user is told before a delivery happens, in the terminal rather than
70
+ * only in the guide: a diagnostic that mutates the app has to say so where the
71
+ * user is looking (criterion 4).
72
+ */
73
+ export function deliveryNotice(scheme) {
74
+ const lines = [
75
+ "This is a real delivery: the signed body is posted to the webhook's " +
76
+ "receive endpoint, a real event row is written to the delivery log, and " +
77
+ "the signed body's dedup key is spent — delivering these exact bytes " +
78
+ "again is suppressed as a replay.",
79
+ ];
80
+ if (scheme === "github") {
81
+ lines.push("On the 'github' scheme dedup entries never expire, so this body can " +
82
+ "never be delivered to this webhook again. Vary the payload between " +
83
+ "test deliveries.");
84
+ }
85
+ return lines;
86
+ }
87
+ const defaultSleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
88
+ /**
89
+ * The one correlation rule: the newest row above `baselineEventId` whose
90
+ * `dedupKey` equals this preview's.
91
+ *
92
+ * The walk is newest-first and follows `nextCursor`, stopping at the baseline
93
+ * row (every row below it predates this delivery) or at `pageCap`. A null
94
+ * baseline means the log was empty when the snapshot was taken, so every row
95
+ * walked is a candidate.
96
+ */
97
+ export async function findDeliveryEvent(input) {
98
+ const pageCap = input.pageCap ?? DELIVER_PAGE_CAP;
99
+ const pageLimit = input.pageLimit ?? DELIVER_PAGE_LIMIT;
100
+ let cursor;
101
+ for (let page = 0; page < pageCap; page++) {
102
+ const result = await input.client.listWebhookEvents(input.appId, input.webhookId, { limit: pageLimit, ...(cursor ? { cursor } : {}) });
103
+ for (const row of result.items || []) {
104
+ if (input.baselineEventId && row.eventId === input.baselineEventId) {
105
+ return null;
106
+ }
107
+ if (row.dedupKey && row.dedupKey === input.dedupKey)
108
+ return row;
109
+ }
110
+ if (!result.nextCursor)
111
+ return null;
112
+ cursor = result.nextCursor;
113
+ }
114
+ return null;
115
+ }
116
+ /**
117
+ * Poll `findDeliveryEvent` within the budget — the row lands asynchronously.
118
+ *
119
+ * A failed read is retried rather than thrown: the delivery has already
120
+ * happened by the time this runs, so a network blip or an expired credential
121
+ * on the way to the log must not abort the command and lose the report of what
122
+ * was delivered. The last error is returned alongside an unresolved row so the
123
+ * caller can say why it is unconfirmed.
124
+ */
125
+ async function pollForDeliveryEvent(input) {
126
+ let error = null;
127
+ for (let attempt = 0; attempt < input.attempts; attempt++) {
128
+ try {
129
+ const found = await findDeliveryEvent(input);
130
+ if (found)
131
+ return { event: found, error: null };
132
+ error = null;
133
+ }
134
+ catch (err) {
135
+ error = messageOf(err);
136
+ }
137
+ if (attempt < input.attempts - 1)
138
+ await input.sleep(input.intervalMs);
139
+ }
140
+ return { event: null, error };
141
+ }
142
+ function messageOf(err) {
143
+ return err?.message ? String(err.message) : String(err);
144
+ }
145
+ /**
146
+ * Confirm the run an `accepted` row names really exists.
147
+ *
148
+ * A function-owned row is confirmed on `functions/{id}/runs`, the only surface
149
+ * that lists a function run. A legacy row is confirmed on the workflow runs
150
+ * surface, which needs the webhook's `workflowId` — a legacy row is visible to
151
+ * `webhooks get`, so that read is available (a function-owned row's is not,
152
+ * which is why the preview publishes `functionId`).
153
+ */
154
+ async function confirmRun(input) {
155
+ const { client, appId, event } = input;
156
+ const runId = (event.workflowRunId || event.workflowRunKey || null);
157
+ if (!runId) {
158
+ return {
159
+ runId: null,
160
+ confirmed: false,
161
+ surface: null,
162
+ reason: "the accepted delivery row names no run",
163
+ };
164
+ }
165
+ const matches = (row) => row?.runId === runId ||
166
+ row?.runKey === runId ||
167
+ (event.workflowRunKey && row?.runKey === event.workflowRunKey) ||
168
+ (event.workflowRunId && row?.runId === event.workflowRunId);
169
+ if (input.functionId) {
170
+ try {
171
+ const found = await findRun((params) => client.listFunctionRuns(appId, input.functionId, params), matches, input);
172
+ return {
173
+ runId,
174
+ confirmed: found,
175
+ surface: "function",
176
+ reason: found ? null : `run ${runId} is not on the function's runs`,
177
+ };
178
+ }
179
+ catch (err) {
180
+ return {
181
+ runId,
182
+ confirmed: false,
183
+ surface: "function",
184
+ reason: `the runs surface could not be read: ${messageOf(err)}`,
185
+ };
186
+ }
187
+ }
188
+ try {
189
+ const webhook = await client.getWebhook(appId, input.webhookId);
190
+ const workflowId = webhook?.workflowId;
191
+ if (!workflowId) {
192
+ return {
193
+ runId,
194
+ confirmed: false,
195
+ surface: null,
196
+ reason: "the webhook names no workflow to confirm the run against",
197
+ };
198
+ }
199
+ const found = await findRun((params) => client.listWorkflowRuns(appId, workflowId, params), matches, input);
200
+ return {
201
+ runId,
202
+ confirmed: found,
203
+ surface: "workflow",
204
+ reason: found ? null : `run ${runId} is not on the workflow's runs`,
205
+ };
206
+ }
207
+ catch (err) {
208
+ return {
209
+ runId,
210
+ confirmed: false,
211
+ surface: "workflow",
212
+ reason: `the runs surface could not be read: ${messageOf(err)}`,
213
+ };
214
+ }
215
+ }
216
+ /**
217
+ * Walk a runs listing, newest first, for the run the delivery row names.
218
+ *
219
+ * Both runs surfaces are cursor-paginated and newest-first, and a synchronous
220
+ * delivery holds this flow open while other runs start, so the newest page is
221
+ * not a safe place to stop looking: enough newer runs push this one off it and
222
+ * a real, inspectable run reads as unconfirmed. Following the cursor within a
223
+ * bounded page budget is the same shape the delivery log walk uses, and for the
224
+ * same reason.
225
+ */
226
+ async function findRun(list, matches, bounds) {
227
+ const pageCap = bounds.runPageCap ?? DELIVER_RUN_PAGE_CAP;
228
+ const pageLimit = bounds.runPageLimit ?? DELIVER_RUN_PAGE_LIMIT;
229
+ let cursor;
230
+ for (let page = 0; page < pageCap; page++) {
231
+ const result = await list({
232
+ limit: pageLimit,
233
+ ...(cursor ? { cursor } : {}),
234
+ });
235
+ if ((result.items || []).some(matches))
236
+ return true;
237
+ if (!result.nextCursor)
238
+ return false;
239
+ cursor = result.nextCursor;
240
+ }
241
+ return false;
242
+ }
243
+ const eventsHint = (webhookId) => `Read the delivery log with \`primitive webhooks events ${webhookId}\`.`;
244
+ /**
245
+ * The transport the delivery goes out on.
246
+ *
247
+ * The same one every other CLI request uses: a local dev server may speak
248
+ * HTTPS on localhost with a self-signed certificate, which `fetchWithTLS`
249
+ * accepts and bare `fetch` rejects. Sending the delivery on a different
250
+ * transport from the preview would fail exactly where this command is most
251
+ * used, and report it as "sent, dispatch unconfirmed" — the request never left.
252
+ * The receive endpoint is unauthenticated, so nothing else about the request
253
+ * changes: only the preview's bytes and its signature headers go out.
254
+ */
255
+ const deliveryFetch = (url, init) => fetchWithTLS(url, init);
256
+ /** POST the preview's bytes to the receive endpoint, verbatim. */
257
+ async function postDelivery(input) {
258
+ const attempt = {
259
+ url: input.url,
260
+ sent: true,
261
+ status: null,
262
+ body: null,
263
+ duplicate: false,
264
+ error: null,
265
+ };
266
+ const controller = typeof AbortController === "function" ? new AbortController() : null;
267
+ // Two bounds, because the localhost-HTTPS transport issues its own request
268
+ // and honours no abort signal: the signal stops a `fetch`, and losing the
269
+ // race stops the wait either way.
270
+ let timer = null;
271
+ const expiry = new Promise((_, reject) => {
272
+ timer = setTimeout(() => {
273
+ controller?.abort();
274
+ reject(new Error(`no response within ${input.timeoutMs}ms`));
275
+ }, input.timeoutMs);
276
+ });
277
+ try {
278
+ const response = await Promise.race([
279
+ input.fetchImpl(input.url, {
280
+ method: "POST",
281
+ headers: { ...input.preview.signatureHeaders },
282
+ body: input.preview.rawBody,
283
+ ...(controller ? { signal: controller.signal } : {}),
284
+ }),
285
+ expiry,
286
+ ]);
287
+ attempt.status = response?.status ?? null;
288
+ const text = typeof response?.text === "function" ? await response.text() : "";
289
+ try {
290
+ attempt.body = text ? JSON.parse(text) : null;
291
+ }
292
+ catch {
293
+ attempt.body = text || null;
294
+ }
295
+ attempt.duplicate = attempt.body?.duplicate === true;
296
+ }
297
+ catch (err) {
298
+ attempt.error = messageOf(err);
299
+ }
300
+ finally {
301
+ if (timer)
302
+ clearTimeout(timer);
303
+ }
304
+ return attempt;
305
+ }
306
+ /**
307
+ * Preview, deliver, correlate, confirm — the whole flow, as one result a caller
308
+ * renders however it likes.
309
+ */
310
+ export async function deliverWebhookTest(input, deps) {
311
+ const client = deps.client;
312
+ const fetchImpl = deps.fetchImpl ?? deliveryFetch;
313
+ const sleep = deps.sleep ?? defaultSleep;
314
+ const base = {
315
+ outcome: "unconfirmed",
316
+ headline: "",
317
+ details: [],
318
+ notice: [],
319
+ preview: null,
320
+ refusal: null,
321
+ delivery: null,
322
+ event: null,
323
+ run: null,
324
+ };
325
+ // 1. The correlation baseline, BEFORE anything is delivered. Its job is to
326
+ // scope the match to rows this delivery could have written, so a row left
327
+ // by an earlier delivery of the same signed bytes is never claimed here.
328
+ // Never the client clock: server and client clocks are not synchronized.
329
+ let baselineEventId = null;
330
+ try {
331
+ const page = await client.listWebhookEvents(input.appId, input.webhookId, {
332
+ limit: 1,
333
+ });
334
+ baselineEventId = page.items?.[0]?.eventId ?? null;
335
+ }
336
+ catch (err) {
337
+ return {
338
+ ...base,
339
+ outcome: "refused",
340
+ refusal: { message: messageOf(err), code: err?.code ?? null },
341
+ headline: "The delivery log could not be read, so a delivery could not be " +
342
+ `correlated to its event row. Nothing was delivered: ${messageOf(err)}`,
343
+ };
344
+ }
345
+ // 2. The preview, unchanged — every existing refusal propagates as it does
346
+ // without `--deliver`, and refuses before anything is delivered.
347
+ let preview;
348
+ try {
349
+ preview = (await client.testWebhook(input.appId, input.webhookId, input.payload ?? {}));
350
+ }
351
+ catch (err) {
352
+ return {
353
+ ...base,
354
+ outcome: "refused",
355
+ refusal: { message: messageOf(err), code: err?.code ?? null },
356
+ headline: `The preview was refused, so nothing was delivered: ${messageOf(err)}`,
357
+ };
358
+ }
359
+ // 3. The receive path. `webhooks get` answers 404 for a function-owned
360
+ // trigger row, so the preview is normally where the key comes from; the
361
+ // fallback is for a server that predates #3321.
362
+ let webhookKey = preview.webhookKey ?? null;
363
+ if (!webhookKey) {
364
+ try {
365
+ const webhook = await client.getWebhook(input.appId, input.webhookId);
366
+ webhookKey = webhook?.webhookKey ?? null;
367
+ }
368
+ catch {
369
+ webhookKey = null;
370
+ }
371
+ }
372
+ if (!webhookKey) {
373
+ return {
374
+ ...base,
375
+ preview,
376
+ outcome: "refused",
377
+ refusal: {
378
+ message: "this server's webhook preview does not report the receive path " +
379
+ "for this webhook, so --deliver cannot address it — upgrade the " +
380
+ "platform, or post the signed body from `--json` to " +
381
+ "`/app/{appId}/webhook/{webhookKey}` yourself",
382
+ code: "WEBHOOK_DELIVER_UNSUPPORTED",
383
+ },
384
+ headline: "Nothing was delivered: this server does not report the webhook's " +
385
+ "receive path, so --deliver cannot address it. Upgrade the platform.",
386
+ };
387
+ }
388
+ const notice = deliveryNotice(preview.verificationScheme);
389
+ deps.onBeforeDeliver?.(notice);
390
+ const url = `${input.serverUrl.replace(/\/$/, "")}/app/${input.appId}/webhook/${webhookKey}`;
391
+ const delivery = await postDelivery({
392
+ url,
393
+ preview,
394
+ fetchImpl,
395
+ timeoutMs: deps.timeoutMs ?? DELIVER_TIMEOUT_MS,
396
+ });
397
+ const resolved = { ...base, notice, preview, delivery };
398
+ // 4. The refusals the receive path reports for itself. Each is positive
399
+ // evidence that nothing was dispatched, so none of them needs the log.
400
+ const refusalHeadline = (message, details = []) => ({
401
+ ...resolved,
402
+ outcome: "refused",
403
+ headline: message,
404
+ details,
405
+ });
406
+ if (delivery.status === 410) {
407
+ return refusalHeadline("The receive endpoint refused the delivery: this webhook is not in " +
408
+ "service (410), so nothing ran.", [
409
+ `Put it back in service with \`primitive webhooks enable ${input.webhookId}\`, ` +
410
+ "or, for a function's trigger, re-push its config.",
411
+ ]);
412
+ }
413
+ if (delivery.status === 403) {
414
+ return refusalHeadline("The receive endpoint refused the delivery (403): this client's IP is " +
415
+ "not on the webhook's IP allowlist, so nothing ran.");
416
+ }
417
+ if (delivery.status === 401) {
418
+ return refusalHeadline("The receive endpoint rejected the delivery's signature (401), so " +
419
+ "nothing ran.", [eventsHint(input.webhookId)]);
420
+ }
421
+ if (delivery.duplicate) {
422
+ return refusalHeadline("The delivery was suppressed as a replay (duplicate): these signed " +
423
+ "bytes were delivered to this webhook before, so nothing ran.", preview.verificationScheme === "github"
424
+ ? [
425
+ "On the 'github' scheme dedup entries never expire, so this body " +
426
+ "can never be delivered to this webhook again — vary the payload.",
427
+ eventsHint(input.webhookId),
428
+ ]
429
+ : [eventsHint(input.webhookId)]);
430
+ }
431
+ // 5. Correlate. One rule, and it needs the preview's key: scheme `none`
432
+ // derives one only from a caller-supplied `X-Webhook-Event-Id`, so a
433
+ // `none` delivery is reported uncorrelated rather than guessed at.
434
+ const unconfirmed = (reason, details = []) => ({
435
+ ...resolved,
436
+ outcome: "unconfirmed",
437
+ headline: `The delivery was sent, but dispatch is unconfirmed: ${reason}`,
438
+ details: [...details, eventsHint(input.webhookId)],
439
+ });
440
+ const httpSummary = delivery.error
441
+ ? `the request was sent but no response was observed (${delivery.error})`
442
+ : `the receive endpoint answered ${delivery.status}`;
443
+ if (!preview.dedupKey) {
444
+ return unconfirmed(`the '${preview.verificationScheme}' scheme derives no dedup key, so ` +
445
+ `this delivery's event row cannot be identified — ${httpSummary}.`);
446
+ }
447
+ const { event, error: logError } = await pollForDeliveryEvent({
448
+ client,
449
+ appId: input.appId,
450
+ webhookId: input.webhookId,
451
+ dedupKey: preview.dedupKey,
452
+ baselineEventId,
453
+ attempts: deps.pollAttempts ?? DELIVER_POLL_ATTEMPTS,
454
+ intervalMs: deps.pollIntervalMs ?? DELIVER_POLL_INTERVAL_MS,
455
+ pageCap: deps.pageCap ?? DELIVER_PAGE_CAP,
456
+ pageLimit: deps.pageLimit ?? DELIVER_PAGE_LIMIT,
457
+ sleep,
458
+ });
459
+ if (!event) {
460
+ // The read itself failed — say that, rather than implying the receiver
461
+ // recorded nothing.
462
+ if (logError) {
463
+ return unconfirmed(`the delivery log could not be read (${logError}) — ${httpSummary}.`);
464
+ }
465
+ // The log was read and holds no row carrying this key. That is more than
466
+ // "not found": the receiver records the key ONLY on a delivery it accepted
467
+ // and dispatched, so this delivery was not dispatched — unless its row has
468
+ // yet to become visible, which is the one thing this cannot rule out.
469
+ return unconfirmed(`no dispatched-delivery row carrying this request's dedup key became ` +
470
+ `visible — ${httpSummary}.`, [
471
+ "The receiver records that key only on a delivery it accepted and " +
472
+ "dispatched, so this one was most likely short-circuited by a " +
473
+ "handshake rule, suppressed as a replay, or acknowledged without " +
474
+ "dispatch (a 202 with its reason). The delivery log names which.",
475
+ ]);
476
+ }
477
+ resolved.event = event;
478
+ // 6. Claim a dispatch only with a run behind it. A row carrying the key is
479
+ // an `accepted`, dispatched row by the receiver's own contract; the guard
480
+ // is here so a server that ever widened the key reads as unconfirmed
481
+ // rather than as a dispatch nobody checked.
482
+ if (event.status !== "accepted") {
483
+ const reason = event.rejectionReason || event.status || "no reason recorded";
484
+ return unconfirmed(`the correlated row (event ${event.eventId}) is recorded as ` +
485
+ `'${event.status}', not as a dispatched delivery: ${reason}.`);
486
+ }
487
+ const run = await confirmRun({
488
+ client,
489
+ appId: input.appId,
490
+ webhookId: input.webhookId,
491
+ functionId: preview.functionId,
492
+ event,
493
+ ...(deps.runPageCap !== undefined ? { runPageCap: deps.runPageCap } : {}),
494
+ ...(deps.runPageLimit !== undefined
495
+ ? { runPageLimit: deps.runPageLimit }
496
+ : {}),
497
+ });
498
+ resolved.run = run;
499
+ if (!run.confirmed) {
500
+ return {
501
+ ...resolved,
502
+ outcome: "unconfirmed",
503
+ headline: `The delivery was accepted (event ${event.eventId}), but dispatch is ` +
504
+ `unconfirmed: ${run.reason}.`,
505
+ details: [eventsHint(input.webhookId)],
506
+ };
507
+ }
508
+ const inspect = preview.functionId
509
+ ? `Inspect it with \`primitive functions runs ${preview.functionId}\`.`
510
+ : "Inspect it with `primitive workflows runs <workflow-id>`.";
511
+ return {
512
+ ...resolved,
513
+ outcome: "dispatched",
514
+ headline: `Delivered through the real webhook path. Event ${event.eventId} ` +
515
+ `dispatched; run ${run.runId} records the outcome.`,
516
+ details: [inspect],
517
+ };
518
+ }
519
+ //# sourceMappingURL=webhook-deliver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webhook-deliver.js","sourceRoot":"","sources":["../../../src/lib/webhook-deliver.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * `workflows codegen` orchestrator (issue #1442).
3
3
  *
4
- * Reads synced workflow TOMLs (`.primitive/sync/<env>/<appId>/workflows/*.toml`)
4
+ * Reads synced workflow TOMLs (`primitive/<env>/workflows/*.toml`)
5
5
  * and emits ONE generated file per workflow —
6
6
  * `workflows/generated/<key>.generated.ts` — each containing the workflow's
7
7
  * `<Key>Input`/`<Key>Output` types plus a typed `<key>(client)` invoker factory
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * `workflows codegen` orchestrator (issue #1442).
3
3
  *
4
- * Reads synced workflow TOMLs (`.primitive/sync/<env>/<appId>/workflows/*.toml`)
4
+ * Reads synced workflow TOMLs (`primitive/<env>/workflows/*.toml`)
5
5
  * and emits ONE generated file per workflow —
6
6
  * `workflows/generated/<key>.generated.ts` — each containing the workflow's
7
7
  * `<Key>Input`/`<Key>Output` types plus a typed `<key>(client)` invoker factory
@@ -84,14 +84,23 @@ export type WorkflowTomlError = {
84
84
  * `runAs = "system"` + a non-empty `accessRule` is dead config: a system run
85
85
  * can only be started by the system and never evaluates its accessRule, so any
86
86
  * non-empty rule is inert. The server rejects this at save time (#1258,
87
- * `src/workflows/definition-store.ts:271-280`); catching it locally keeps
88
- * `config push` all-or-nothing instead of failing mid-push and leaving partial
89
- * server state (#1418 drift).
90
- *
91
- * Mirrors the server predicate byte-for-byte: returns the sentinel error only
92
- * when `runAs === "system"` AND `typeof accessRule === "string"` AND
93
- * `accessRule.trim() !== ""`. Default/unset/empty/whitespace-only runAs or
94
- * accessRule (and a bare non-string boolean accessRule) return `null`.
87
+ * `src/workflows/config/workflow-save-rules.ts`); catching it locally puts the
88
+ * refusal in the PREFLIGHT, which aborts before the first mutating call, rather
89
+ * than mid-apply after earlier entities have been written (#1418 drift).
90
+ *
91
+ * "All-or-nothing", which this comment used to claim, was never what push
92
+ * offers and is corrected here (#3320): the preflight is all-or-nothing, and
93
+ * the apply stage that follows it is incremental and convergent with no
94
+ * rollback. See `config push --help`.
95
+ *
96
+ * Delegates the decision to the server's own predicate,
97
+ * `checkWorkflowSystemAccessRule` (#3374, vendored from
98
+ * `src/config-surface/workflow-rules.ts`): the sentinel is returned exactly
99
+ * when it reports a violation — `runAs === "system"` with a non-empty string
100
+ * `accessRule`. Default/unset/empty/whitespace-only runAs or accessRule (and a
101
+ * bare non-string boolean accessRule) return `null`. Only the HINT is this
102
+ * module's: it names the preflight remedy, where the server's sentence names
103
+ * the save-time one.
95
104
  *
96
105
  * @param workflow The workflow-metadata object — the `[workflow]` table, or
97
106
  * for commands that accept unwrapped root-level metadata, the root TOML
@@ -36,6 +36,10 @@ import { GENERATED_ALLOWLISTED_FIELDS, GENERATED_KNOWN_KINDS, } from "./generate
36
36
  // `cli/scripts/gen-template-lint.mjs`) so push-time and save-time verdicts are
37
37
  // produced by the same code rather than a hand mirror.
38
38
  import { lintWorkflowStepTemplates } from "./generated-template-lint.js";
39
+ // #3374 — the `runAs = "system"` + `accessRule` predicate is the server's own,
40
+ // vendored from `src/config-surface/workflow-rules.ts`; this module renders
41
+ // the CLI's hint from its answer rather than restating the conjunction.
42
+ import { checkWorkflowSystemAccessRule } from "./generated-config-surfaces.js";
39
43
  /**
40
44
  * Universal-and-consumed allowlist of top-level fields permitted on a step
41
45
  * (known kinds). Generated from the runners; see header.
@@ -70,14 +74,23 @@ export const KNOWN_KINDS_FOR_DRIFT_GUARD = KNOWN_KINDS;
70
74
  * `runAs = "system"` + a non-empty `accessRule` is dead config: a system run
71
75
  * can only be started by the system and never evaluates its accessRule, so any
72
76
  * non-empty rule is inert. The server rejects this at save time (#1258,
73
- * `src/workflows/definition-store.ts:271-280`); catching it locally keeps
74
- * `config push` all-or-nothing instead of failing mid-push and leaving partial
75
- * server state (#1418 drift).
77
+ * `src/workflows/config/workflow-save-rules.ts`); catching it locally puts the
78
+ * refusal in the PREFLIGHT, which aborts before the first mutating call, rather
79
+ * than mid-apply after earlier entities have been written (#1418 drift).
76
80
  *
77
- * Mirrors the server predicate byte-for-byte: returns the sentinel error only
78
- * when `runAs === "system"` AND `typeof accessRule === "string"` AND
79
- * `accessRule.trim() !== ""`. Default/unset/empty/whitespace-only runAs or
80
- * accessRule (and a bare non-string boolean accessRule) return `null`.
81
+ * "All-or-nothing", which this comment used to claim, was never what push
82
+ * offers and is corrected here (#3320): the preflight is all-or-nothing, and
83
+ * the apply stage that follows it is incremental and convergent with no
84
+ * rollback. See `config push --help`.
85
+ *
86
+ * Delegates the decision to the server's own predicate,
87
+ * `checkWorkflowSystemAccessRule` (#3374, vendored from
88
+ * `src/config-surface/workflow-rules.ts`): the sentinel is returned exactly
89
+ * when it reports a violation — `runAs === "system"` with a non-empty string
90
+ * `accessRule`. Default/unset/empty/whitespace-only runAs or accessRule (and a
91
+ * bare non-string boolean accessRule) return `null`. Only the HINT is this
92
+ * module's: it names the preflight remedy, where the server's sentence names
93
+ * the save-time one.
81
94
  *
82
95
  * @param workflow The workflow-metadata object — the `[workflow]` table, or
83
96
  * for commands that accept unwrapped root-level metadata, the root TOML
@@ -89,11 +102,11 @@ export function validateWorkflowIdentity(workflow) {
89
102
  Array.isArray(workflow)) {
90
103
  return null;
91
104
  }
92
- const runAs = workflow.runAs;
93
- const accessRule = workflow.accessRule;
94
- if (runAs === "system" &&
95
- typeof accessRule === "string" &&
96
- accessRule.trim() !== "") {
105
+ const violation = checkWorkflowSystemAccessRule({
106
+ runAs: workflow.runAs,
107
+ accessRule: workflow.accessRule,
108
+ });
109
+ if (violation) {
97
110
  return {
98
111
  stepIndex: -1,
99
112
  stepId: null,