@wildo-ai/saas-models 1.1.0 → 1.1.2

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 (292) hide show
  1. package/dist/esm/applications/applications-context.schemas.d.ts +2 -0
  2. package/dist/esm/applications/applications-context.schemas.d.ts.map +1 -1
  3. package/dist/esm/billing/billing-account.shared.resources-config.schemas.d.ts +1 -1
  4. package/dist/esm/billing/billing-account.shared.resources-config.schemas.d.ts.map +1 -1
  5. package/dist/esm/billing/billing-account.shared.resources-config.schemas.js +36 -0
  6. package/dist/esm/billing/billing-account.shared.resources-config.schemas.js.map +1 -1
  7. package/dist/esm/billing/billing-account.shared.schemas.d.ts.map +1 -1
  8. package/dist/esm/billing/billing-account.shared.schemas.js +8 -1
  9. package/dist/esm/billing/billing-account.shared.schemas.js.map +1 -1
  10. package/dist/esm/billing/billing-types.shared.schemas.d.ts +2 -2
  11. package/dist/esm/billing/credit-pool.shared.resources-config.schemas.d.ts +1 -1
  12. package/dist/esm/billing/credit-pool.shared.resources-config.schemas.d.ts.map +1 -1
  13. package/dist/esm/billing/credit-pool.shared.resources-config.schemas.js +39 -0
  14. package/dist/esm/billing/credit-pool.shared.resources-config.schemas.js.map +1 -1
  15. package/dist/esm/billing/credit-pool.shared.schemas.d.ts +6 -6
  16. package/dist/esm/billing/credit-pool.shared.schemas.d.ts.map +1 -1
  17. package/dist/esm/billing/credit-pool.shared.schemas.js +8 -4
  18. package/dist/esm/billing/credit-pool.shared.schemas.js.map +1 -1
  19. package/dist/esm/billing/invoice-ref.shared.resources-config.schemas.d.ts +1 -1
  20. package/dist/esm/billing/invoice-ref.shared.resources-config.schemas.d.ts.map +1 -1
  21. package/dist/esm/billing/invoice-ref.shared.resources-config.schemas.js +35 -0
  22. package/dist/esm/billing/invoice-ref.shared.resources-config.schemas.js.map +1 -1
  23. package/dist/esm/billing/invoice-ref.shared.schemas.d.ts.map +1 -1
  24. package/dist/esm/billing/invoice-ref.shared.schemas.js +8 -3
  25. package/dist/esm/billing/invoice-ref.shared.schemas.js.map +1 -1
  26. package/dist/esm/billing/subscription.shared.resources-config.schemas.d.ts +1 -1
  27. package/dist/esm/billing/subscription.shared.resources-config.schemas.d.ts.map +1 -1
  28. package/dist/esm/billing/subscription.shared.resources-config.schemas.js +39 -0
  29. package/dist/esm/billing/subscription.shared.resources-config.schemas.js.map +1 -1
  30. package/dist/esm/billing/subscription.shared.schemas.d.ts +4 -4
  31. package/dist/esm/billing/subscription.shared.schemas.d.ts.map +1 -1
  32. package/dist/esm/billing/subscription.shared.schemas.js +6 -2
  33. package/dist/esm/billing/subscription.shared.schemas.js.map +1 -1
  34. package/dist/esm/billing/usage-record.shared.resources-config.schemas.d.ts +1 -1
  35. package/dist/esm/billing/usage-record.shared.resources-config.schemas.d.ts.map +1 -1
  36. package/dist/esm/billing/usage-record.shared.resources-config.schemas.js +39 -0
  37. package/dist/esm/billing/usage-record.shared.resources-config.schemas.js.map +1 -1
  38. package/dist/esm/billing/usage-record.shared.schemas.d.ts +4 -4
  39. package/dist/esm/billing/usage-record.shared.schemas.d.ts.map +1 -1
  40. package/dist/esm/billing/usage-record.shared.schemas.js +7 -3
  41. package/dist/esm/billing/usage-record.shared.schemas.js.map +1 -1
  42. package/dist/esm/compliance/audit-trails/audit-logs.shared.resources-config.schemas.d.ts.map +1 -1
  43. package/dist/esm/compliance/audit-trails/audit-logs.shared.resources-config.schemas.js +35 -2
  44. package/dist/esm/compliance/audit-trails/audit-logs.shared.resources-config.schemas.js.map +1 -1
  45. package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.d.ts +61 -0
  46. package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.d.ts.map +1 -1
  47. package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.js +58 -0
  48. package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.js.map +1 -1
  49. package/dist/esm/compliance/audit-trails/security-audit-event-envelope.shared.schema.d.ts.map +1 -1
  50. package/dist/esm/compliance/audit-trails/security-audit-event-envelope.shared.schema.js +14 -0
  51. package/dist/esm/compliance/audit-trails/security-audit-event-envelope.shared.schema.js.map +1 -1
  52. package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.d.ts +49 -0
  53. package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.d.ts.map +1 -1
  54. package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.js +124 -1
  55. package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.js.map +1 -1
  56. package/dist/esm/compliance/privacy/impersonalization.shared.schemas.d.ts +11 -3
  57. package/dist/esm/compliance/privacy/impersonalization.shared.schemas.d.ts.map +1 -1
  58. package/dist/esm/compliance/privacy/impersonalization.shared.schemas.js +11 -3
  59. package/dist/esm/compliance/privacy/impersonalization.shared.schemas.js.map +1 -1
  60. package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.d.ts +93 -0
  61. package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.d.ts.map +1 -0
  62. package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.js +116 -0
  63. package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.js.map +1 -0
  64. package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.d.ts +67 -12
  65. package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.d.ts.map +1 -1
  66. package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.js +95 -8
  67. package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.js.map +1 -1
  68. package/dist/esm/compliance/privacy/redaction.shared.schemas.d.ts +21 -1
  69. package/dist/esm/compliance/privacy/redaction.shared.schemas.d.ts.map +1 -1
  70. package/dist/esm/compliance/privacy/redaction.shared.schemas.js +20 -0
  71. package/dist/esm/compliance/privacy/redaction.shared.schemas.js.map +1 -1
  72. package/dist/esm/config/app-configuration-shared.shared.schemas.d.ts +2 -0
  73. package/dist/esm/config/app-configuration-shared.shared.schemas.d.ts.map +1 -1
  74. package/dist/esm/config/app-configuration-shared.shared.schemas.js +29 -0
  75. package/dist/esm/config/app-configuration-shared.shared.schemas.js.map +1 -1
  76. package/dist/esm/config/frontend/navigation.shared.schemas.d.ts +33 -0
  77. package/dist/esm/config/frontend/navigation.shared.schemas.d.ts.map +1 -1
  78. package/dist/esm/config/frontend/navigation.shared.schemas.js +32 -0
  79. package/dist/esm/config/frontend/navigation.shared.schemas.js.map +1 -1
  80. package/dist/esm/errors/errors.custom-message-ref.shared.definitions.d.ts +12 -1
  81. package/dist/esm/errors/errors.custom-message-ref.shared.definitions.d.ts.map +1 -1
  82. package/dist/esm/errors/errors.custom-message-ref.shared.definitions.js +12 -1
  83. package/dist/esm/errors/errors.custom-message-ref.shared.definitions.js.map +1 -1
  84. package/dist/esm/external-data/external-data-pipeline.shared.schemas.d.ts +13 -0
  85. package/dist/esm/external-data/external-data-pipeline.shared.schemas.d.ts.map +1 -1
  86. package/dist/esm/external-data/external-data-pipeline.shared.schemas.js.map +1 -1
  87. package/dist/esm/external-providers/engine-capabilities.shared.schemas.d.ts +6 -6
  88. package/dist/esm/external-providers/engine-capabilities.shared.schemas.d.ts.map +1 -1
  89. package/dist/esm/external-providers/engine-capabilities.shared.schemas.js +26 -6
  90. package/dist/esm/external-providers/engine-capabilities.shared.schemas.js.map +1 -1
  91. package/dist/esm/external-providers/engine-capability-resolution-mode.shared.d.ts.map +1 -1
  92. package/dist/esm/external-providers/engine-capability-resolution-mode.shared.js +0 -2
  93. package/dist/esm/external-providers/engine-capability-resolution-mode.shared.js.map +1 -1
  94. package/dist/esm/external-providers/frontend-bootstrap.shared.schemas.d.ts +1 -0
  95. package/dist/esm/external-providers/frontend-bootstrap.shared.schemas.d.ts.map +1 -1
  96. package/dist/esm/external-providers/provider-capability.shared.schemas.d.ts +4 -3
  97. package/dist/esm/external-providers/provider-capability.shared.schemas.d.ts.map +1 -1
  98. package/dist/esm/external-providers/provider-capability.shared.schemas.js +4 -3
  99. package/dist/esm/external-providers/provider-capability.shared.schemas.js.map +1 -1
  100. package/dist/esm/features/user-features.shared.resources-config.schemas.d.ts +1 -1
  101. package/dist/esm/features/user-features.shared.resources-config.schemas.d.ts.map +1 -1
  102. package/dist/esm/features/user-features.shared.resources-config.schemas.js +48 -0
  103. package/dist/esm/features/user-features.shared.resources-config.schemas.js.map +1 -1
  104. package/dist/esm/files/file-upload-grant.shared.schemas.d.ts +144 -0
  105. package/dist/esm/files/file-upload-grant.shared.schemas.d.ts.map +1 -0
  106. package/dist/esm/files/file-upload-grant.shared.schemas.js +136 -0
  107. package/dist/esm/files/file-upload-grant.shared.schemas.js.map +1 -0
  108. package/dist/esm/files/files.shared.schemas.d.ts +45 -4
  109. package/dist/esm/files/files.shared.schemas.d.ts.map +1 -1
  110. package/dist/esm/files/files.shared.schemas.js +48 -4
  111. package/dist/esm/files/files.shared.schemas.js.map +1 -1
  112. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.resources-config.schemas.d.ts +1 -1
  113. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.resources-config.schemas.d.ts.map +1 -1
  114. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.resources-config.schemas.js +33 -0
  115. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.resources-config.schemas.js.map +1 -1
  116. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.schemas.d.ts.map +1 -1
  117. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.schemas.js +6 -2
  118. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.schemas.js.map +1 -1
  119. package/dist/esm/flows-actors/a2a-token-budget-state.shared.resources-config.schemas.d.ts +1 -1
  120. package/dist/esm/flows-actors/a2a-token-budget-state.shared.resources-config.schemas.d.ts.map +1 -1
  121. package/dist/esm/flows-actors/a2a-token-budget-state.shared.resources-config.schemas.js +53 -0
  122. package/dist/esm/flows-actors/a2a-token-budget-state.shared.resources-config.schemas.js.map +1 -1
  123. package/dist/esm/flows-actors/flows-actors-execution.shared.resources-config.schemas.d.ts +1 -1
  124. package/dist/esm/flows-actors/flows-actors-execution.shared.resources-config.schemas.d.ts.map +1 -1
  125. package/dist/esm/flows-actors/flows-actors-execution.shared.resources-config.schemas.js +43 -0
  126. package/dist/esm/flows-actors/flows-actors-execution.shared.resources-config.schemas.js.map +1 -1
  127. package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.d.ts.map +1 -1
  128. package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.js +8 -3
  129. package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.js.map +1 -1
  130. package/dist/esm/flows-actors/flows-actors-task.shared.resources-config.schemas.d.ts +1 -1
  131. package/dist/esm/flows-actors/flows-actors-task.shared.resources-config.schemas.d.ts.map +1 -1
  132. package/dist/esm/flows-actors/flows-actors-task.shared.resources-config.schemas.js +41 -0
  133. package/dist/esm/flows-actors/flows-actors-task.shared.resources-config.schemas.js.map +1 -1
  134. package/dist/esm/flows-actors/flows-actors-task.shared.schemas.d.ts +0 -7
  135. package/dist/esm/flows-actors/flows-actors-task.shared.schemas.d.ts.map +1 -1
  136. package/dist/esm/flows-actors/flows-actors-task.shared.schemas.js +23 -13
  137. package/dist/esm/flows-actors/flows-actors-task.shared.schemas.js.map +1 -1
  138. package/dist/esm/guidance/guidance-state.shared.resources-config.schemas.d.ts +1 -1
  139. package/dist/esm/guidance/guidance-state.shared.resources-config.schemas.d.ts.map +1 -1
  140. package/dist/esm/guidance/guidance-state.shared.resources-config.schemas.js +51 -0
  141. package/dist/esm/guidance/guidance-state.shared.resources-config.schemas.js.map +1 -1
  142. package/dist/esm/guidance/guidance-state.shared.schemas.d.ts.map +1 -1
  143. package/dist/esm/guidance/guidance-state.shared.schemas.js +8 -2
  144. package/dist/esm/guidance/guidance-state.shared.schemas.js.map +1 -1
  145. package/dist/esm/guidance/lifecycle-state.shared.resources-config.schemas.d.ts +1 -1
  146. package/dist/esm/guidance/lifecycle-state.shared.resources-config.schemas.d.ts.map +1 -1
  147. package/dist/esm/guidance/lifecycle-state.shared.resources-config.schemas.js +51 -0
  148. package/dist/esm/guidance/lifecycle-state.shared.resources-config.schemas.js.map +1 -1
  149. package/dist/esm/guidance/lifecycle-state.shared.schemas.d.ts.map +1 -1
  150. package/dist/esm/guidance/lifecycle-state.shared.schemas.js +28 -3
  151. package/dist/esm/guidance/lifecycle-state.shared.schemas.js.map +1 -1
  152. package/dist/esm/guidance/progression-state.shared.resources-config.schemas.d.ts +1 -1
  153. package/dist/esm/guidance/progression-state.shared.resources-config.schemas.d.ts.map +1 -1
  154. package/dist/esm/guidance/progression-state.shared.resources-config.schemas.js +51 -0
  155. package/dist/esm/guidance/progression-state.shared.resources-config.schemas.js.map +1 -1
  156. package/dist/esm/guidance/progression-state.shared.schemas.d.ts.map +1 -1
  157. package/dist/esm/guidance/progression-state.shared.schemas.js +18 -4
  158. package/dist/esm/guidance/progression-state.shared.schemas.js.map +1 -1
  159. package/dist/esm/http-api-binding/http-api-binding.shared.schemas.d.ts +37 -3
  160. package/dist/esm/http-api-binding/http-api-binding.shared.schemas.d.ts.map +1 -1
  161. package/dist/esm/http-api-binding/http-api-binding.shared.schemas.js +29 -3
  162. package/dist/esm/http-api-binding/http-api-binding.shared.schemas.js.map +1 -1
  163. package/dist/esm/index.d.ts +6 -0
  164. package/dist/esm/index.d.ts.map +1 -1
  165. package/dist/esm/index.js +6 -0
  166. package/dist/esm/index.js.map +1 -1
  167. package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.d.ts +70 -0
  168. package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.d.ts.map +1 -0
  169. package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.js +71 -0
  170. package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.js.map +1 -0
  171. package/dist/esm/notifications/notification-badges.shared.resources-config.schemas.d.ts +1 -1
  172. package/dist/esm/notifications/notification-badges.shared.resources-config.schemas.d.ts.map +1 -1
  173. package/dist/esm/notifications/notification-badges.shared.resources-config.schemas.js +36 -0
  174. package/dist/esm/notifications/notification-badges.shared.resources-config.schemas.js.map +1 -1
  175. package/dist/esm/organizations/organization-members.shared.resources-config.schemas.d.ts +1 -1
  176. package/dist/esm/organizations/organization-members.shared.resources-config.schemas.d.ts.map +1 -1
  177. package/dist/esm/organizations/organization-members.shared.resources-config.schemas.js +44 -0
  178. package/dist/esm/organizations/organization-members.shared.resources-config.schemas.js.map +1 -1
  179. package/dist/esm/organizations/organization-members.shared.schemas.d.ts.map +1 -1
  180. package/dist/esm/organizations/organization-members.shared.schemas.js +15 -4
  181. package/dist/esm/organizations/organization-members.shared.schemas.js.map +1 -1
  182. package/dist/esm/organizations/organizations.shared.resources-config.schemas.d.ts.map +1 -1
  183. package/dist/esm/organizations/organizations.shared.resources-config.schemas.js +18 -10
  184. package/dist/esm/organizations/organizations.shared.resources-config.schemas.js.map +1 -1
  185. package/dist/esm/queue/jobs.shared.resources-config.schemas.d.ts.map +1 -1
  186. package/dist/esm/queue/jobs.shared.resources-config.schemas.js +17 -0
  187. package/dist/esm/queue/jobs.shared.resources-config.schemas.js.map +1 -1
  188. package/dist/esm/requests/websocket.shared.schemas.d.ts +59 -0
  189. package/dist/esm/requests/websocket.shared.schemas.d.ts.map +1 -1
  190. package/dist/esm/requests/websocket.shared.schemas.js +103 -0
  191. package/dist/esm/requests/websocket.shared.schemas.js.map +1 -1
  192. package/dist/esm/resources/collection-query-parameters.shared.d.ts +22 -0
  193. package/dist/esm/resources/collection-query-parameters.shared.d.ts.map +1 -0
  194. package/dist/esm/resources/collection-query-parameters.shared.js +22 -0
  195. package/dist/esm/resources/collection-query-parameters.shared.js.map +1 -0
  196. package/dist/esm/resources/resources-config.shared.factory.d.ts.map +1 -1
  197. package/dist/esm/resources/resources-config.shared.factory.js +86 -13
  198. package/dist/esm/resources/resources-config.shared.factory.js.map +1 -1
  199. package/dist/esm/resources/resources-config.shared.schemas.d.ts +162 -41
  200. package/dist/esm/resources/resources-config.shared.schemas.d.ts.map +1 -1
  201. package/dist/esm/resources/resources-config.shared.schemas.js +109 -20
  202. package/dist/esm/resources/resources-config.shared.schemas.js.map +1 -1
  203. package/dist/esm/resources/utils/resources-config-operations.dtos-builder.utils.d.ts.map +1 -1
  204. package/dist/esm/resources/utils/resources-config-operations.dtos-builder.utils.js +21 -6
  205. package/dist/esm/resources/utils/resources-config-operations.dtos-builder.utils.js.map +1 -1
  206. package/dist/esm/security/authentications/authentication.shared.schemas.d.ts +57 -0
  207. package/dist/esm/security/authentications/authentication.shared.schemas.d.ts.map +1 -1
  208. package/dist/esm/security/authentications/authentication.shared.schemas.js +64 -0
  209. package/dist/esm/security/authentications/authentication.shared.schemas.js.map +1 -1
  210. package/dist/esm/security/authentications/consumable-token.shared.schemas.d.ts +17 -1
  211. package/dist/esm/security/authentications/consumable-token.shared.schemas.d.ts.map +1 -1
  212. package/dist/esm/security/authentications/consumable-token.shared.schemas.js +16 -0
  213. package/dist/esm/security/authentications/consumable-token.shared.schemas.js.map +1 -1
  214. package/dist/esm/security/authentications/mfa-backup-code-contract.shared.d.ts +28 -0
  215. package/dist/esm/security/authentications/mfa-backup-code-contract.shared.d.ts.map +1 -0
  216. package/dist/esm/security/authentications/mfa-backup-code-contract.shared.js +28 -0
  217. package/dist/esm/security/authentications/mfa-backup-code-contract.shared.js.map +1 -0
  218. package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.d.ts +21 -0
  219. package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.d.ts.map +1 -0
  220. package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.js +21 -0
  221. package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.js.map +1 -0
  222. package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.d.ts +1 -1
  223. package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.d.ts.map +1 -1
  224. package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.js +43 -0
  225. package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.js.map +1 -1
  226. package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.d.ts +0 -8
  227. package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.d.ts.map +1 -1
  228. package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.js +13 -4
  229. package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.js.map +1 -1
  230. package/dist/esm/security/authorizations/roles.shared.schemas.d.ts +16 -1
  231. package/dist/esm/security/authorizations/roles.shared.schemas.d.ts.map +1 -1
  232. package/dist/esm/security/authorizations/roles.shared.schemas.js +16 -1
  233. package/dist/esm/security/authorizations/roles.shared.schemas.js.map +1 -1
  234. package/dist/esm/security/authorizations/roles.shared.utils.d.ts +54 -0
  235. package/dist/esm/security/authorizations/roles.shared.utils.d.ts.map +1 -1
  236. package/dist/esm/security/authorizations/roles.shared.utils.js +59 -0
  237. package/dist/esm/security/authorizations/roles.shared.utils.js.map +1 -1
  238. package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.d.ts +61 -0
  239. package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.d.ts.map +1 -1
  240. package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.js +13 -1
  241. package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.js.map +1 -1
  242. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.resources-config.schemas.d.ts +1 -1
  243. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.resources-config.schemas.d.ts.map +1 -1
  244. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.resources-config.schemas.js +35 -0
  245. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.resources-config.schemas.js.map +1 -1
  246. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.d.ts.map +1 -1
  247. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.js +7 -1
  248. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.js.map +1 -1
  249. package/dist/esm/users/inbound-contacts.shared.resources-config.schemas.d.ts +1 -1
  250. package/dist/esm/users/inbound-contacts.shared.resources-config.schemas.d.ts.map +1 -1
  251. package/dist/esm/users/inbound-contacts.shared.resources-config.schemas.js +34 -0
  252. package/dist/esm/users/inbound-contacts.shared.resources-config.schemas.js.map +1 -1
  253. package/dist/esm/users/inbound-contacts.shared.schemas.d.ts.map +1 -1
  254. package/dist/esm/users/inbound-contacts.shared.schemas.js +7 -4
  255. package/dist/esm/users/inbound-contacts.shared.schemas.js.map +1 -1
  256. package/dist/esm/users/user-credentials.shared.resources-config.schemas.d.ts +1 -1
  257. package/dist/esm/users/user-credentials.shared.resources-config.schemas.d.ts.map +1 -1
  258. package/dist/esm/users/user-credentials.shared.resources-config.schemas.js +37 -0
  259. package/dist/esm/users/user-credentials.shared.resources-config.schemas.js.map +1 -1
  260. package/dist/esm/users/user-credentials.shared.schemas.d.ts.map +1 -1
  261. package/dist/esm/users/user-credentials.shared.schemas.js +17 -2
  262. package/dist/esm/users/user-credentials.shared.schemas.js.map +1 -1
  263. package/dist/esm/users/user-identity-links.shared.resources-config.schemas.d.ts +1 -1
  264. package/dist/esm/users/user-identity-links.shared.resources-config.schemas.d.ts.map +1 -1
  265. package/dist/esm/users/user-identity-links.shared.resources-config.schemas.js +36 -0
  266. package/dist/esm/users/user-identity-links.shared.resources-config.schemas.js.map +1 -1
  267. package/dist/esm/users/user-identity-links.shared.schemas.d.ts.map +1 -1
  268. package/dist/esm/users/user-identity-links.shared.schemas.js +15 -5
  269. package/dist/esm/users/user-identity-links.shared.schemas.js.map +1 -1
  270. package/dist/esm/users/user-preferences.shared.resources-config.schemas.d.ts +1 -1
  271. package/dist/esm/users/user-preferences.shared.resources-config.schemas.d.ts.map +1 -1
  272. package/dist/esm/users/user-preferences.shared.resources-config.schemas.js +53 -0
  273. package/dist/esm/users/user-preferences.shared.resources-config.schemas.js.map +1 -1
  274. package/dist/esm/users/user-profiles.shared.resources-config.schemas.d.ts +1 -1
  275. package/dist/esm/users/user-profiles.shared.resources-config.schemas.d.ts.map +1 -1
  276. package/dist/esm/users/user-profiles.shared.resources-config.schemas.js +62 -0
  277. package/dist/esm/users/user-profiles.shared.resources-config.schemas.js.map +1 -1
  278. package/dist/esm/users/user-self-preferences.shared.resources-config.schemas.d.ts +1 -1
  279. package/dist/esm/users/user-self-preferences.shared.resources-config.schemas.d.ts.map +1 -1
  280. package/dist/esm/users/user-self-preferences.shared.resources-config.schemas.js +53 -0
  281. package/dist/esm/users/user-self-preferences.shared.resources-config.schemas.js.map +1 -1
  282. package/dist/esm/users/user-self-profiles.shared.resources-config.schemas.d.ts +1 -1
  283. package/dist/esm/users/user-self-profiles.shared.resources-config.schemas.d.ts.map +1 -1
  284. package/dist/esm/users/user-self-profiles.shared.resources-config.schemas.js +62 -0
  285. package/dist/esm/users/user-self-profiles.shared.resources-config.schemas.js.map +1 -1
  286. package/dist/esm/users/users.shared.schemas.d.ts +19 -0
  287. package/dist/esm/users/users.shared.schemas.d.ts.map +1 -1
  288. package/dist/esm/users/users.shared.schemas.js +41 -16
  289. package/dist/esm/users/users.shared.schemas.js.map +1 -1
  290. package/dist/tsconfig.build.tsbuildinfo +1 -1
  291. package/package.json +5 -6
  292. package/dist/esm/.builder.pid +0 -9
@@ -338,6 +338,19 @@ export declare const ExternalDataPipelineDeclarationSchema: z.ZodObject<{
338
338
  }, z.core.$strip>;
339
339
  /** @wildo_source:part:end saas.models.external-data-pipeline */
340
340
  export type ExternalDataPipelineDeclaration = z.infer<typeof ExternalDataPipelineDeclarationSchema>;
341
+ /**
342
+ * What an APPLICATION AUTHOR writes — the schema's INPUT shape, so every field carrying a
343
+ * `.default()` is optional to type. Consumers read the parsed shape above, where those same fields
344
+ * are guaranteed present.
345
+ *
346
+ * The distinction is not cosmetic, and the first dogfood proved it: typing the resource-config
347
+ * field with the PARSED shape forced an author to spell out `verifyMetadataAtBoot`,
348
+ * `identityMode`, and a `coercion` + `required` on every mapping entry — values the schema exists
349
+ * to supply. `DataSeedDefinitionAuthored` records the identical lesson for seeds ("authors may omit
350
+ * this field and the dispatcher still reads a guaranteed `string[]`"); this is the same split, and
351
+ * it was missed here because nothing had authored a pipeline by hand yet.
352
+ */
353
+ export type ExternalDataPipelineDeclarationAuthored = z.input<typeof ExternalDataPipelineDeclarationSchema>;
341
354
  /**
342
355
  * Schema-INDEPENDENT coherence of a parsed declaration — the mainSchema-dependent half lives in
343
356
  * the resource-configuration factory (it needs the shape). Throws with the offending path named,
@@ -1 +1 @@
1
- {"version":3,"file":"external-data-pipeline.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/external-data/external-data-pipeline.shared.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAEL,oBAAoB,EACpB,uBAAuB,EACxB,MAAM,qDAAqD,CAAC;AAE7D;;;;;GAKG;AACH,kHAAkH;AAClH,oBAAY,6BAA6B;IACvC,OAAO,YAAY;CACpB;AAED;;;;;;GAMG;AACH,oBAAY,iCAAiC;IAC3C;;;;OAIG;IACH,MAAM,WAAW;IACjB;;;;;OAKG;IACH,IAAI,SAAS;CACd;AAED;;;;;;;;;GASG;AACH,oBAAY,wBAAwB;IAClC,uGAAuG;IACvG,MAAM,WAAW;IACjB,mGAAmG;IACnG,SAAS,cAAc;IACvB,uFAAuF;IACvF,MAAM,WAAW;CAClB;AAED,kGAAkG;AAClG,oBAAY,4BAA4B;IACtC,+DAA+D;IAC/D,YAAY,iBAAiB;IAC7B,yGAAyG;IACzG,QAAQ,aAAa;CACtB;AAED;;;;GAIG;AACH,oBAAY,yBAAyB;IACnC,+EAA+E;IAC/E,IAAI,SAAS;IACb;;;;OAIG;IACH,kBAAkB,uBAAuB;IACzC,mFAAmF;IACnF,kBAAkB,uBAAuB;CAC1C;AAED,+FAA+F;AAC/F,eAAO,MAAM,mCAAmC;;;;;;;;;;2BAkB9C,CAAC;AAEH,gEAAgE;AAChE,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mCAAmC,CAAC,CAAC;AAKhG;;;;;;;GAOG;AACH,kHAAkH;AAClH,eAAO,MAAM,qCAAqC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAoDhD,CAAC;AAEH,gEAAgE;AAChE,MAAM,MAAM,+BAA+B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qCAAqC,CAAC,CAAC;AAEpG;;;;GAIG;AACH,wBAAgB,8CAA8C,CAAC,WAAW,EAAE,+BAA+B,GAAG,IAAI,CAyCjH"}
1
+ {"version":3,"file":"external-data-pipeline.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/external-data/external-data-pipeline.shared.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAEL,oBAAoB,EACpB,uBAAuB,EACxB,MAAM,qDAAqD,CAAC;AAE7D;;;;;GAKG;AACH,kHAAkH;AAClH,oBAAY,6BAA6B;IACvC,OAAO,YAAY;CACpB;AAED;;;;;;GAMG;AACH,oBAAY,iCAAiC;IAC3C;;;;OAIG;IACH,MAAM,WAAW;IACjB;;;;;OAKG;IACH,IAAI,SAAS;CACd;AAED;;;;;;;;;GASG;AACH,oBAAY,wBAAwB;IAClC,uGAAuG;IACvG,MAAM,WAAW;IACjB,mGAAmG;IACnG,SAAS,cAAc;IACvB,uFAAuF;IACvF,MAAM,WAAW;CAClB;AAED,kGAAkG;AAClG,oBAAY,4BAA4B;IACtC,+DAA+D;IAC/D,YAAY,iBAAiB;IAC7B,yGAAyG;IACzG,QAAQ,aAAa;CACtB;AAED;;;;GAIG;AACH,oBAAY,yBAAyB;IACnC,+EAA+E;IAC/E,IAAI,SAAS;IACb;;;;OAIG;IACH,kBAAkB,uBAAuB;IACzC,mFAAmF;IACnF,kBAAkB,uBAAuB;CAC1C;AAED,+FAA+F;AAC/F,eAAO,MAAM,mCAAmC;;;;;;;;;;2BAkB9C,CAAC;AAEH,gEAAgE;AAChE,MAAM,MAAM,6BAA6B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mCAAmC,CAAC,CAAC;AAKhG;;;;;;;GAOG;AACH,kHAAkH;AAClH,eAAO,MAAM,qCAAqC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAoDhD,CAAC;AAEH,gEAAgE;AAChE,MAAM,MAAM,+BAA+B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qCAAqC,CAAC,CAAC;AAEpG;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,uCAAuC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,qCAAqC,CAAC,CAAC;AAE5G;;;;GAIG;AACH,wBAAgB,8CAA8C,CAAC,WAAW,EAAE,+BAA+B,GAAG,IAAI,CAyCjH"}
@@ -1 +1 @@
1
- {"version":3,"file":"external-data-pipeline.shared.schemas.js","sourceRoot":"","sources":["../../../../src/external-data/external-data-pipeline.shared.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The ETL PIPELINE declaration (`externalDataPipeline`) — partial-resource coverage, model v3\n * (`.claude/plans/etl-partial-resource-coverage.md`, PR-3/PR-19; decisions D-P1…D-P10).\n *\n * \"Some resources local, some remote, ETL between them\": an ordinary LOCAL resource may declare\n * ONE inbound pipeline from a remote HTTP-API entity. The declaration reuses the whole\n * {@link HttpApiResourceBindingSchema} as its source half (provider, entity, dialect, key\n * fields, remote-call semantics — the E is the same adapter plumbing the VIRTUAL mode runs on),\n * adds the T (a declared field mapping) and the L/refresh contract (population posture, orphan\n * policy, schedule, run bounds). The destination stays a FULL local resource — files, RAG,\n * retention/erasure, charts and the read-only UI chain are all inherited, never re-built.\n *\n * Everything here is a CLOSED vocabulary with one named source; the runtime seams (P-2) consume\n * these members, and the paper's ledger rows (PR-…) are cited per surface.\n */\n\nimport { z } from 'zod';\n\nimport {\n HttpApiResourceBindingSchema,\n HttpApiTenancyStance,\n HttpApiTransportDialect,\n} from '../http-api-binding/http-api-binding.shared.schemas';\n\n/**\n * Pipeline direction (PR-19). A SINGLE-member enum on purpose: reverse ETL (local→remote) and\n * bidirectional sync belong to the outbound-writes gate (ETL plan Step 5, concurrency contract),\n * but the DECLARATION is direction-extensible NOW so those arrive as new members instead of a\n * schema reshape — the immutability-needs-a-paired-path lesson applied to a vocabulary.\n */\n/** @wildo_source:part:start saas.models.external-data-pipeline facet:layer:shared facet:audience:app-developer */\nexport enum ExternalDataPipelineDirection {\n INBOUND = 'inbound',\n}\n\n/**\n * Who owns the destination's row population (D-P8, v3.1 §1).\n *\n * The declared answer to the question the orphan sweep MUST have: \"is a row the pipeline did not\n * create a USER row, or a VANISHED remote row?\" — undeclared mixed populations are how an orphan\n * pass deletes user data.\n */\nexport enum ExternalDataDestinationPopulation {\n /**\n * Every row comes from the pipeline. Caller CREATE is refused at declaration time, and orphan\n * detection may consider the whole population. The default: safest, and the honest description\n * of a synced master-data table.\n */\n CLOSED = 'closed',\n /**\n * Mixed rows: users may create rows the pipeline does not own. Pipeline rows are identified by\n * the remote-key field being present, and orphan detection is CONFINED to that population. A\n * user row that later matches an incoming remote key is ADOPTED by the upsert (documented\n * collision semantics, not an accident).\n */\n OPEN = 'open',\n}\n\n/**\n * What happens to a destination row whose remote counterpart disappeared (D-P9).\n *\n * MIRRORS `DataSeedSyncOrphanPolicy` (saas-backend-lib, data-seeding) member-for-member, and the\n * P-2 pipeline→SYNC seam maps the two 1:1. A separate enum EXISTS ONLY because of dependency\n * direction: this declaration lives in saas-models, the data-seeding models live in\n * saas-backend-lib, and models cannot import backend. If the data-seeding vocabulary ever moves\n * down to saas-models, collapse this enum into it — do not let the two drift meanwhile (the\n * seam's mapping is exhaustive and compile-forced, so a new member on either side reddens P-2).\n */\nexport enum ExternalDataOrphanPolicy {\n /** Hard-delete the orphan row — flows through ordinary lifecycle (cascades, file teardown). Opt-in. */\n DELETE = 'delete',\n /** Mark the row deprecated and keep it; a re-appearing remote key REVIVES it (v3.1 §4). Opt-in. */\n DEPRECATE = 'deprecate',\n /** Touch nothing; surface the diff in the run ledger. The DEFAULT — least surprise. */\n REPORT = 'report',\n}\n\n/** The two shapes a mapping entry can take — a closed discriminator, never inferred from keys. */\nexport enum ExternalDataMappingEntryKind {\n /** Copy (and coerce) one remote field into one local field. */\n REMOTE_FIELD = 'remote-field',\n /** Fill one local field with a declared constant (destination-required fields with no remote source). */\n CONSTANT = 'constant',\n}\n\n/**\n * Built-in, closed coercion vocabulary for REMOTE_FIELD entries (v3.1 §3 / PR-8). Slice 1 ships\n * exactly the coercions the two generic dialects force; arbitrary transforms are the recorded\n * widenings (W-FK resolution, W-AGENT authored transforms) — never an open function slot here.\n */\nexport enum ExternalDataFieldCoercion {\n /** Value lands as extracted (after the destination schema's own Zod parse). */\n NONE = 'none',\n /**\n * Odoo spells an ABSENT value as boolean `false` — a mapped string field would otherwise store\n * literal `false`. Applied by DEFAULT for ODOO_JSONRPC sources; declaring it on another dialect\n * is refused (the name is Odoo's semantics, not a generic null-coalesce).\n */\n ODOO_FALSE_AS_NULL = 'odoo-false-as-null',\n /** Parse a strict-ISO datetime string into a Date for a date-typed local field. */\n ISO_STRING_TO_DATE = 'iso-string-to-date',\n}\n\n/** One declared T-step: remote field → local field with a built-in coercion, or a constant. */\nexport const ExternalDataFieldMappingEntrySchema = z.discriminatedUnion('kind', [\n z.object({\n kind: z.literal(ExternalDataMappingEntryKind.REMOTE_FIELD),\n remoteField: z.string().trim().min(1),\n localField: z.string().trim().min(1),\n coercion: z.enum(ExternalDataFieldCoercion).default(ExternalDataFieldCoercion.NONE),\n /**\n * `true`: a row whose extracted value is ABSENT is REJECTED (reported per row in the run\n * ledger; its previous local version survives). `false` (default): absent lands as null,\n * which the declaration coherence requires the local field to accept.\n */\n required: z.boolean().default(false),\n }),\n z.object({\n kind: z.literal(ExternalDataMappingEntryKind.CONSTANT),\n localField: z.string().trim().min(1),\n constant: z.union([z.string(), z.number(), z.boolean()]),\n }),\n]);\n\n/** @wildo_source:part:end saas.models.external-data-pipeline */\nexport type ExternalDataFieldMappingEntry = z.infer<typeof ExternalDataFieldMappingEntrySchema>;\n\n/** Scalar values admissible in the declared source filter (T-set equality conjunctions only). */\nconst externalDataPipelineFilterScalarSchema = z.union([z.string(), z.number(), z.boolean()]);\n\n/**\n * The inbound pipeline declaration an ordinary LOCAL resource carries as `externalDataPipeline`.\n *\n * NOT legal on an HTTP_API-adapter resource (a virtual resource IS the remote side); the\n * resource-configuration factory enforces that plus every mainSchema-dependent coherence rule —\n * see `validateExternalDataPipelineDeclarationAgainstSchema` there. This module owns only the\n * schema-independent shape and coherence.\n */\n/** @wildo_source:part:start saas.models.external-data-pipeline facet:layer:shared facet:audience:app-developer */\nexport const ExternalDataPipelineDeclarationSchema = z.object({\n direction: z.enum(ExternalDataPipelineDirection).default(ExternalDataPipelineDirection.INBOUND),\n\n /**\n * The source half — the SAME binding declaration the VIRTUAL mode uses (provider, entity,\n * dialect, key fields + codecs, remote-call semantics, erasure stance, tenancy). Slice 1\n * confines pipelines to SINGLE_TENANT_BINDING sources (W-TENANCY records the widening — a\n * wrong remote-scope→org mapping is a cross-tenant leak, so it is designed, not improvised).\n *\n * ⚠ OPERATIONAL HAZARD (PR-16): changing `keyFields` or a component CODEC after rows exist\n * re-keys EVERY business key — the whole destination population orphans and re-creates on the\n * next full pass, detaching local annotations (extension fields, files, chunks) from the rows\n * that replace them. Treat a key/codec change as a MIGRATION EVENT, never a config tweak. Not\n * mechanically detectable at authoring (no row access here). Relatedly: a remote system that\n * RECYCLES ids hands the recycled row the OLD row's local annotations — the upsert cannot tell\n * a revived entity from a new one wearing its key.\n */\n binding: HttpApiResourceBindingSchema,\n\n /**\n * The LOCAL field holding the row's remote identity — the synthesized id (paper A codec) as a\n * plain STRING business key. The factory requires it declared `.isBusinessKey()` +\n * `excludeFromCreate/Update`: SYNC's idempotent upsert keys on it, and no caller may mint or\n * move it.\n */\n remoteKeyLocalField: z.string().trim().min(1),\n\n /** The declared T — at least one entry; targets validated against `mainSchema` by the factory. */\n mapping: z.array(ExternalDataFieldMappingEntrySchema).min(1),\n\n /**\n * Optional remote-side subset (v3.1 §2): equality conjunctions over REMOTE fields, exactly the\n * T-set's T3 shape — anything richer is a widening, not an improvisation.\n */\n sourceFilter: z.record(z.string().trim().min(1), externalDataPipelineFilterScalarSchema).optional(),\n\n population: z.enum(ExternalDataDestinationPopulation).default(ExternalDataDestinationPopulation.CLOSED),\n\n orphanPolicy: z.enum(ExternalDataOrphanPolicy).default(ExternalDataOrphanPolicy.REPORT),\n\n /**\n * Cron expression for the scheduled refresh (crontabs machinery). Absent = on-demand only —\n * legal, and honest for a manually-driven backfill.\n */\n scheduleCron: z.string().trim().min(1).optional(),\n\n /**\n * Extraction bound per run (v3.1 §2): a big backfill progresses across runs via the ledger's\n * resumable cursor instead of owning one unbounded run. The default matches the rate-budget\n * era's \"bounded by construction\" posture.\n */\n maxRowsPerRun: z.number().int().positive().default(10_000),\n});\n\n/** @wildo_source:part:end saas.models.external-data-pipeline */\nexport type ExternalDataPipelineDeclaration = z.infer<typeof ExternalDataPipelineDeclarationSchema>;\n\n/**\n * Schema-INDEPENDENT coherence of a parsed declaration — the mainSchema-dependent half lives in\n * the resource-configuration factory (it needs the shape). Throws with the offending path named,\n * mirroring `assertHttpApiBindingDialectCoherence`'s contract.\n */\nexport function assertExternalDataPipelineDeclarationCoherence(declaration: ExternalDataPipelineDeclaration): void {\n // S1 tenancy confinement (v3.1 §2 / W-TENANCY).\n if (declaration.binding.tenancy.stance !== HttpApiTenancyStance.SINGLE_TENANT_BINDING) {\n throw new Error(\n \"binding.tenancy: slice 1 confines pipelines to SINGLE_TENANT_BINDING sources — a pushdown-tenancy source needs the declared remote-scope→organization mapping (widening W-TENANCY), because a wrong org assignment is a cross-tenant leak.\",\n );\n }\n\n // D-P10: extraction uses drift-safe paging ONLY (`@odata.nextLink` / the Odoo id-keyset\n // cursor). REST_JSON declares offset paging, which skips or doubles rows whenever the remote\n // set shifts mid-run — so a REST_JSON pipeline SOURCE is refused until a declared cursor\n // contract exists for the dialect (a recorded widening beside W-DELTA, not an improvisation).\n if (declaration.binding.dialect === HttpApiTransportDialect.REST_JSON) {\n throw new Error(\n 'binding.dialect: REST_JSON pipeline sources are refused in slice 1 — the dialect declares offset paging, which drifts under concurrent remote change (rows skipped or doubled). ODATA (@odata.nextLink) and ODOO_JSONRPC (id cursor) sources are drift-safe; a declared REST cursor contract is the recorded widening.',\n );\n }\n\n const localTargets = new Set<string>();\n for (const entry of declaration.mapping) {\n if (localTargets.has(entry.localField)) {\n throw new Error(`mapping: local field '${entry.localField}' is targeted by more than one entry — one writer per field.`);\n }\n localTargets.add(entry.localField);\n\n if (entry.localField === declaration.remoteKeyLocalField) {\n throw new Error(\n `mapping: local field '${entry.localField}' is the remoteKeyLocalField — the remote identity is written by the pipeline's L from the synthesized id, never by a mapping entry.`,\n );\n }\n\n if (\n entry.kind === ExternalDataMappingEntryKind.REMOTE_FIELD\n && entry.coercion === ExternalDataFieldCoercion.ODOO_FALSE_AS_NULL\n && declaration.binding.dialect !== HttpApiTransportDialect.ODOO_JSONRPC\n ) {\n throw new Error(\n `mapping('${entry.localField}').coercion: '${ExternalDataFieldCoercion.ODOO_FALSE_AS_NULL}' names Odoo's absent-as-false semantics and is refused on a ${declaration.binding.dialect} source.`,\n );\n }\n }\n}\n"]}
1
+ {"version":3,"file":"external-data-pipeline.shared.schemas.js","sourceRoot":"","sources":["../../../../src/external-data/external-data-pipeline.shared.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The ETL PIPELINE declaration (`externalDataPipeline`) — partial-resource coverage, model v3\n * (`.claude/plans/etl-partial-resource-coverage.md`, PR-3/PR-19; decisions D-P1…D-P10).\n *\n * \"Some resources local, some remote, ETL between them\": an ordinary LOCAL resource may declare\n * ONE inbound pipeline from a remote HTTP-API entity. The declaration reuses the whole\n * {@link HttpApiResourceBindingSchema} as its source half (provider, entity, dialect, key\n * fields, remote-call semantics — the E is the same adapter plumbing the VIRTUAL mode runs on),\n * adds the T (a declared field mapping) and the L/refresh contract (population posture, orphan\n * policy, schedule, run bounds). The destination stays a FULL local resource — files, RAG,\n * retention/erasure, charts and the read-only UI chain are all inherited, never re-built.\n *\n * Everything here is a CLOSED vocabulary with one named source; the runtime seams (P-2) consume\n * these members, and the paper's ledger rows (PR-…) are cited per surface.\n */\n\nimport { z } from 'zod';\n\nimport {\n HttpApiResourceBindingSchema,\n HttpApiTenancyStance,\n HttpApiTransportDialect,\n} from '../http-api-binding/http-api-binding.shared.schemas';\n\n/**\n * Pipeline direction (PR-19). A SINGLE-member enum on purpose: reverse ETL (local→remote) and\n * bidirectional sync belong to the outbound-writes gate (ETL plan Step 5, concurrency contract),\n * but the DECLARATION is direction-extensible NOW so those arrive as new members instead of a\n * schema reshape — the immutability-needs-a-paired-path lesson applied to a vocabulary.\n */\n/** @wildo_source:part:start saas.models.external-data-pipeline facet:layer:shared facet:audience:app-developer */\nexport enum ExternalDataPipelineDirection {\n INBOUND = 'inbound',\n}\n\n/**\n * Who owns the destination's row population (D-P8, v3.1 §1).\n *\n * The declared answer to the question the orphan sweep MUST have: \"is a row the pipeline did not\n * create a USER row, or a VANISHED remote row?\" — undeclared mixed populations are how an orphan\n * pass deletes user data.\n */\nexport enum ExternalDataDestinationPopulation {\n /**\n * Every row comes from the pipeline. Caller CREATE is refused at declaration time, and orphan\n * detection may consider the whole population. The default: safest, and the honest description\n * of a synced master-data table.\n */\n CLOSED = 'closed',\n /**\n * Mixed rows: users may create rows the pipeline does not own. Pipeline rows are identified by\n * the remote-key field being present, and orphan detection is CONFINED to that population. A\n * user row that later matches an incoming remote key is ADOPTED by the upsert (documented\n * collision semantics, not an accident).\n */\n OPEN = 'open',\n}\n\n/**\n * What happens to a destination row whose remote counterpart disappeared (D-P9).\n *\n * MIRRORS `DataSeedSyncOrphanPolicy` (saas-backend-lib, data-seeding) member-for-member, and the\n * P-2 pipeline→SYNC seam maps the two 1:1. A separate enum EXISTS ONLY because of dependency\n * direction: this declaration lives in saas-models, the data-seeding models live in\n * saas-backend-lib, and models cannot import backend. If the data-seeding vocabulary ever moves\n * down to saas-models, collapse this enum into it — do not let the two drift meanwhile (the\n * seam's mapping is exhaustive and compile-forced, so a new member on either side reddens P-2).\n */\nexport enum ExternalDataOrphanPolicy {\n /** Hard-delete the orphan row — flows through ordinary lifecycle (cascades, file teardown). Opt-in. */\n DELETE = 'delete',\n /** Mark the row deprecated and keep it; a re-appearing remote key REVIVES it (v3.1 §4). Opt-in. */\n DEPRECATE = 'deprecate',\n /** Touch nothing; surface the diff in the run ledger. The DEFAULT — least surprise. */\n REPORT = 'report',\n}\n\n/** The two shapes a mapping entry can take — a closed discriminator, never inferred from keys. */\nexport enum ExternalDataMappingEntryKind {\n /** Copy (and coerce) one remote field into one local field. */\n REMOTE_FIELD = 'remote-field',\n /** Fill one local field with a declared constant (destination-required fields with no remote source). */\n CONSTANT = 'constant',\n}\n\n/**\n * Built-in, closed coercion vocabulary for REMOTE_FIELD entries (v3.1 §3 / PR-8). Slice 1 ships\n * exactly the coercions the two generic dialects force; arbitrary transforms are the recorded\n * widenings (W-FK resolution, W-AGENT authored transforms) — never an open function slot here.\n */\nexport enum ExternalDataFieldCoercion {\n /** Value lands as extracted (after the destination schema's own Zod parse). */\n NONE = 'none',\n /**\n * Odoo spells an ABSENT value as boolean `false` — a mapped string field would otherwise store\n * literal `false`. Applied by DEFAULT for ODOO_JSONRPC sources; declaring it on another dialect\n * is refused (the name is Odoo's semantics, not a generic null-coalesce).\n */\n ODOO_FALSE_AS_NULL = 'odoo-false-as-null',\n /** Parse a strict-ISO datetime string into a Date for a date-typed local field. */\n ISO_STRING_TO_DATE = 'iso-string-to-date',\n}\n\n/** One declared T-step: remote field → local field with a built-in coercion, or a constant. */\nexport const ExternalDataFieldMappingEntrySchema = z.discriminatedUnion('kind', [\n z.object({\n kind: z.literal(ExternalDataMappingEntryKind.REMOTE_FIELD),\n remoteField: z.string().trim().min(1),\n localField: z.string().trim().min(1),\n coercion: z.enum(ExternalDataFieldCoercion).default(ExternalDataFieldCoercion.NONE),\n /**\n * `true`: a row whose extracted value is ABSENT is REJECTED (reported per row in the run\n * ledger; its previous local version survives). `false` (default): absent lands as null,\n * which the declaration coherence requires the local field to accept.\n */\n required: z.boolean().default(false),\n }),\n z.object({\n kind: z.literal(ExternalDataMappingEntryKind.CONSTANT),\n localField: z.string().trim().min(1),\n constant: z.union([z.string(), z.number(), z.boolean()]),\n }),\n]);\n\n/** @wildo_source:part:end saas.models.external-data-pipeline */\nexport type ExternalDataFieldMappingEntry = z.infer<typeof ExternalDataFieldMappingEntrySchema>;\n\n/** Scalar values admissible in the declared source filter (T-set equality conjunctions only). */\nconst externalDataPipelineFilterScalarSchema = z.union([z.string(), z.number(), z.boolean()]);\n\n/**\n * The inbound pipeline declaration an ordinary LOCAL resource carries as `externalDataPipeline`.\n *\n * NOT legal on an HTTP_API-adapter resource (a virtual resource IS the remote side); the\n * resource-configuration factory enforces that plus every mainSchema-dependent coherence rule —\n * see `validateExternalDataPipelineDeclarationAgainstSchema` there. This module owns only the\n * schema-independent shape and coherence.\n */\n/** @wildo_source:part:start saas.models.external-data-pipeline facet:layer:shared facet:audience:app-developer */\nexport const ExternalDataPipelineDeclarationSchema = z.object({\n direction: z.enum(ExternalDataPipelineDirection).default(ExternalDataPipelineDirection.INBOUND),\n\n /**\n * The source half — the SAME binding declaration the VIRTUAL mode uses (provider, entity,\n * dialect, key fields + codecs, remote-call semantics, erasure stance, tenancy). Slice 1\n * confines pipelines to SINGLE_TENANT_BINDING sources (W-TENANCY records the widening — a\n * wrong remote-scope→org mapping is a cross-tenant leak, so it is designed, not improvised).\n *\n * ⚠ OPERATIONAL HAZARD (PR-16): changing `keyFields` or a component CODEC after rows exist\n * re-keys EVERY business key — the whole destination population orphans and re-creates on the\n * next full pass, detaching local annotations (extension fields, files, chunks) from the rows\n * that replace them. Treat a key/codec change as a MIGRATION EVENT, never a config tweak. Not\n * mechanically detectable at authoring (no row access here). Relatedly: a remote system that\n * RECYCLES ids hands the recycled row the OLD row's local annotations — the upsert cannot tell\n * a revived entity from a new one wearing its key.\n */\n binding: HttpApiResourceBindingSchema,\n\n /**\n * The LOCAL field holding the row's remote identity — the synthesized id (paper A codec) as a\n * plain STRING business key. The factory requires it declared `.isBusinessKey()` +\n * `excludeFromCreate/Update`: SYNC's idempotent upsert keys on it, and no caller may mint or\n * move it.\n */\n remoteKeyLocalField: z.string().trim().min(1),\n\n /** The declared T — at least one entry; targets validated against `mainSchema` by the factory. */\n mapping: z.array(ExternalDataFieldMappingEntrySchema).min(1),\n\n /**\n * Optional remote-side subset (v3.1 §2): equality conjunctions over REMOTE fields, exactly the\n * T-set's T3 shape — anything richer is a widening, not an improvisation.\n */\n sourceFilter: z.record(z.string().trim().min(1), externalDataPipelineFilterScalarSchema).optional(),\n\n population: z.enum(ExternalDataDestinationPopulation).default(ExternalDataDestinationPopulation.CLOSED),\n\n orphanPolicy: z.enum(ExternalDataOrphanPolicy).default(ExternalDataOrphanPolicy.REPORT),\n\n /**\n * Cron expression for the scheduled refresh (crontabs machinery). Absent = on-demand only —\n * legal, and honest for a manually-driven backfill.\n */\n scheduleCron: z.string().trim().min(1).optional(),\n\n /**\n * Extraction bound per run (v3.1 §2): a big backfill progresses across runs via the ledger's\n * resumable cursor instead of owning one unbounded run. The default matches the rate-budget\n * era's \"bounded by construction\" posture.\n */\n maxRowsPerRun: z.number().int().positive().default(10_000),\n});\n\n/** @wildo_source:part:end saas.models.external-data-pipeline */\nexport type ExternalDataPipelineDeclaration = z.infer<typeof ExternalDataPipelineDeclarationSchema>;\n\n/**\n * What an APPLICATION AUTHOR writes — the schema's INPUT shape, so every field carrying a\n * `.default()` is optional to type. Consumers read the parsed shape above, where those same fields\n * are guaranteed present.\n *\n * The distinction is not cosmetic, and the first dogfood proved it: typing the resource-config\n * field with the PARSED shape forced an author to spell out `verifyMetadataAtBoot`,\n * `identityMode`, and a `coercion` + `required` on every mapping entry — values the schema exists\n * to supply. `DataSeedDefinitionAuthored` records the identical lesson for seeds (\"authors may omit\n * this field and the dispatcher still reads a guaranteed `string[]`\"); this is the same split, and\n * it was missed here because nothing had authored a pipeline by hand yet.\n */\nexport type ExternalDataPipelineDeclarationAuthored = z.input<typeof ExternalDataPipelineDeclarationSchema>;\n\n/**\n * Schema-INDEPENDENT coherence of a parsed declaration — the mainSchema-dependent half lives in\n * the resource-configuration factory (it needs the shape). Throws with the offending path named,\n * mirroring `assertHttpApiBindingDialectCoherence`'s contract.\n */\nexport function assertExternalDataPipelineDeclarationCoherence(declaration: ExternalDataPipelineDeclaration): void {\n // S1 tenancy confinement (v3.1 §2 / W-TENANCY).\n if (declaration.binding.tenancy.stance !== HttpApiTenancyStance.SINGLE_TENANT_BINDING) {\n throw new Error(\n \"binding.tenancy: slice 1 confines pipelines to SINGLE_TENANT_BINDING sources — a pushdown-tenancy source needs the declared remote-scope→organization mapping (widening W-TENANCY), because a wrong org assignment is a cross-tenant leak.\",\n );\n }\n\n // D-P10: extraction uses drift-safe paging ONLY (`@odata.nextLink` / the Odoo id-keyset\n // cursor). REST_JSON declares offset paging, which skips or doubles rows whenever the remote\n // set shifts mid-run — so a REST_JSON pipeline SOURCE is refused until a declared cursor\n // contract exists for the dialect (a recorded widening beside W-DELTA, not an improvisation).\n if (declaration.binding.dialect === HttpApiTransportDialect.REST_JSON) {\n throw new Error(\n 'binding.dialect: REST_JSON pipeline sources are refused in slice 1 — the dialect declares offset paging, which drifts under concurrent remote change (rows skipped or doubled). ODATA (@odata.nextLink) and ODOO_JSONRPC (id cursor) sources are drift-safe; a declared REST cursor contract is the recorded widening.',\n );\n }\n\n const localTargets = new Set<string>();\n for (const entry of declaration.mapping) {\n if (localTargets.has(entry.localField)) {\n throw new Error(`mapping: local field '${entry.localField}' is targeted by more than one entry — one writer per field.`);\n }\n localTargets.add(entry.localField);\n\n if (entry.localField === declaration.remoteKeyLocalField) {\n throw new Error(\n `mapping: local field '${entry.localField}' is the remoteKeyLocalField — the remote identity is written by the pipeline's L from the synthesized id, never by a mapping entry.`,\n );\n }\n\n if (\n entry.kind === ExternalDataMappingEntryKind.REMOTE_FIELD\n && entry.coercion === ExternalDataFieldCoercion.ODOO_FALSE_AS_NULL\n && declaration.binding.dialect !== HttpApiTransportDialect.ODOO_JSONRPC\n ) {\n throw new Error(\n `mapping('${entry.localField}').coercion: '${ExternalDataFieldCoercion.ODOO_FALSE_AS_NULL}' names Odoo's absent-as-false semantics and is refused on a ${declaration.binding.dialect} source.`,\n );\n }\n }\n}\n"]}
@@ -44,11 +44,13 @@ export declare enum EngineCapability {
44
44
  * extraction into `AI_LLM` would have made one `selection[AI_LLM].primary` decide all three,
45
45
  * which is exactly the defect that split `AI_EMBEDDINGS` out of `AI_LLM`.
46
46
  *
47
- * ## Not to be confused with `DOCUMENT_GENERATION`
47
+ * ## Not to be confused with PDF GENERATION
48
48
  *
49
- * `DOCUMENT_GENERATION` is PDF *generation* — templates and data become bytes. This is the
50
- * opposite direction: bytes become text. The names are adjacent and the capabilities are
51
- * unrelated; nothing routes between them.
49
+ * PDF generation — templates and data become bytes is the `pdfTemplates` surface, done
50
+ * in-process and with no provider slot of its own. This is the opposite direction: bytes become
51
+ * text. The two are unrelated and nothing routes between them. (There WAS an
52
+ * `EngineCapability.DOCUMENT_GENERATION` that this paragraph used to name; it was withdrawn
53
+ * because no provider capability could ever fill it.)
52
54
  *
53
55
  * ## Absence is benign, and that is load-bearing
54
56
  *
@@ -74,8 +76,6 @@ export declare enum EngineCapability {
74
76
  * authorisation decision. They deserve separate, deliberate answers.
75
77
  */
76
78
  AI_CODING_AGENT = "AI_CODING_AGENT",
77
- DOCUMENT_GENERATION = "DOCUMENT_GENERATION",
78
- ANTIVIRUS_SCANNING = "ANTIVIRUS_SCANNING",
79
79
  FRONTEND_ERROR_MONITORING = "FRONTEND_ERROR_MONITORING",
80
80
  FRONTEND_PRODUCT_ANALYTICS = "FRONTEND_PRODUCT_ANALYTICS",
81
81
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"engine-capabilities.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/external-providers/engine-capabilities.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AAEnH;;;;;;;;;;;GAWG;AACH,oBAAY,gBAAgB;IAC1B,aAAa,kBAAkB;IAC/B,OAAO,YAAY;IACnB,gBAAgB,qBAAqB;IACrC,cAAc,mBAAmB;IACjC,sBAAsB,2BAA2B;IAEjD,mBAAmB,wBAAwB;IAC3C,eAAe,oBAAoB;IACnC,GAAG,QAAQ;IAEX,MAAM,WAAW;IACjB,mBAAmB,wBAAwB;IAC3C;;;;;;;;OAQG;IACH,aAAa,kBAAkB;IAC/B;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,sBAAsB,2BAA2B;IACjD;;;;;;;;;;;;;;OAcG;IACH,eAAe,oBAAoB;IAEnC,mBAAmB,wBAAwB;IAC3C,kBAAkB,uBAAuB;IAEzC,yBAAyB,8BAA8B;IACvD,0BAA0B,+BAA+B;IAEzD;;;;;OAKG;IACH,iBAAiB,sBAAsB;IAEvC;;;;;;;;OAQG;IACH,uBAAuB,4BAA4B;CACpD;AACD,6DAA6D;AAE7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AACH,eAAO,MAAM,wCAAwC,EAAE,OAAO,CAC5D,MAAM,CAAC,yBAAyB,EAAE,gBAAgB,CAAC,CA8BpD,CAAC"}
1
+ {"version":3,"file":"engine-capabilities.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/external-providers/engine-capabilities.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAA+B,KAAK,yBAAyB,EAAE,MAAM,sCAAsC,CAAC;AAEnH;;;;;;;;;;;GAWG;AACH,oBAAY,gBAAgB;IAC1B,aAAa,kBAAkB;IAC/B,OAAO,YAAY;IACnB,gBAAgB,qBAAqB;IACrC,cAAc,mBAAmB;IACjC,sBAAsB,2BAA2B;IAEjD,mBAAmB,wBAAwB;IAC3C,eAAe,oBAAoB;IACnC,GAAG,QAAQ;IAEX,MAAM,WAAW;IACjB,mBAAmB,wBAAwB;IAC3C;;;;;;;;OAQG;IACH,aAAa,kBAAkB;IAC/B;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,sBAAsB,2BAA2B;IACjD;;;;;;;;;;;;;;OAcG;IACH,eAAe,oBAAoB;IAuBnC,yBAAyB,8BAA8B;IACvD,0BAA0B,+BAA+B;IAEzD;;;;;OAKG;IACH,iBAAiB,sBAAsB;IAEvC;;;;;;;;OAQG;IACH,uBAAuB,4BAA4B;CACpD;AACD,6DAA6D;AAE7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AACH,eAAO,MAAM,wCAAwC,EAAE,OAAO,CAC5D,MAAM,CAAC,yBAAyB,EAAE,gBAAgB,CAAC,CA8BpD,CAAC"}
@@ -45,11 +45,13 @@ export var EngineCapability;
45
45
  * extraction into `AI_LLM` would have made one `selection[AI_LLM].primary` decide all three,
46
46
  * which is exactly the defect that split `AI_EMBEDDINGS` out of `AI_LLM`.
47
47
  *
48
- * ## Not to be confused with `DOCUMENT_GENERATION`
48
+ * ## Not to be confused with PDF GENERATION
49
49
  *
50
- * `DOCUMENT_GENERATION` is PDF *generation* — templates and data become bytes. This is the
51
- * opposite direction: bytes become text. The names are adjacent and the capabilities are
52
- * unrelated; nothing routes between them.
50
+ * PDF generation — templates and data become bytes is the `pdfTemplates` surface, done
51
+ * in-process and with no provider slot of its own. This is the opposite direction: bytes become
52
+ * text. The two are unrelated and nothing routes between them. (There WAS an
53
+ * `EngineCapability.DOCUMENT_GENERATION` that this paragraph used to name; it was withdrawn
54
+ * because no provider capability could ever fill it.)
53
55
  *
54
56
  * ## Absence is benign, and that is load-bearing
55
57
  *
@@ -75,8 +77,26 @@ export var EngineCapability;
75
77
  * authorisation decision. They deserve separate, deliberate answers.
76
78
  */
77
79
  EngineCapability["AI_CODING_AGENT"] = "AI_CODING_AGENT";
78
- EngineCapability["DOCUMENT_GENERATION"] = "DOCUMENT_GENERATION";
79
- EngineCapability["ANTIVIRUS_SCANNING"] = "ANTIVIRUS_SCANNING";
80
+ /*
81
+ * WITHDRAWN 2026-09-03: `DOCUMENT_GENERATION` and `ANTIVIRUS_SCANNING` were members here and are
82
+ * not any more. Neither could ever be filled — `PROVIDER_CAPABILITY_TO_ENGINE_CAPABILITY` had no
83
+ * entry pointing at either, so no provider capability token could claim the slot — while both were
84
+ * classified `SELECT_ONE`, which asserts that exactly one provider must be selected. Selecting one
85
+ * of zero candidates is not a resolution mode.
86
+ *
87
+ * Both capabilities are real and both are delivered elsewhere, which is why withdrawing the slots
88
+ * costs nothing: antivirus scanning is `InfraCapability.ANTIVIRUS_SCANNING`, fulfilled by ClamAV
89
+ * and consumed by `FileScanningBackendService`; PDF generation is the in-process `pdfTemplates`
90
+ * surface, with `InfraCapability.DOCUMENT_RENDERING` (Gotenberg) provisioned beside it. Neither
91
+ * has an external provider, and neither is planned to.
92
+ *
93
+ * Removing `ANTIVIRUS_SCANNING` also removes a collision: the identical spelling named an engine
94
+ * slot nothing could fill AND a live infra capability, in two packages, so a reader grepping the
95
+ * word landed in whichever they searched first.
96
+ *
97
+ * If a hosted AV or document-rendering vendor is ever adopted, the member comes back WITH its
98
+ * `PROVIDER_CAPABILITY_TO_ENGINE_CAPABILITY` entry and its own JSDoc in the same change.
99
+ */
80
100
  EngineCapability["FRONTEND_ERROR_MONITORING"] = "FRONTEND_ERROR_MONITORING";
81
101
  EngineCapability["FRONTEND_PRODUCT_ANALYTICS"] = "FRONTEND_PRODUCT_ANALYTICS";
82
102
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"engine-capabilities.shared.schemas.js","sourceRoot":"","sources":["../../../../src/external-providers/engine-capabilities.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAkC,MAAM,sCAAsC,CAAC;AAEnH;;;;;;;;;;;GAWG;AACH,MAAM,CAAN,IAAY,gBA0FX;AA1FD,WAAY,gBAAgB;IAC1B,mDAA+B,CAAA;IAC/B,uCAAmB,CAAA;IACnB,yDAAqC,CAAA;IACrC,qDAAiC,CAAA;IACjC,qEAAiD,CAAA;IAEjD,+DAA2C,CAAA;IAC3C,uDAAmC,CAAA;IACnC,+BAAW,CAAA;IAEX,qCAAiB,CAAA;IACjB,+DAA2C,CAAA;IAC3C;;;;;;;;OAQG;IACH,mDAA+B,CAAA;IAC/B;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,qEAAiD,CAAA;IACjD;;;;;;;;;;;;;;OAcG;IACH,uDAAmC,CAAA;IAEnC,+DAA2C,CAAA;IAC3C,6DAAyC,CAAA;IAEzC,2EAAuD,CAAA;IACvD,6EAAyD,CAAA;IAEzD;;;;;OAKG;IACH,2DAAuC,CAAA;IAEvC;;;;;;;;OAQG;IACH,uEAAmD,CAAA;AACrD,CAAC,EA1FW,gBAAgB,KAAhB,gBAAgB,QA0F3B;AACD,6DAA6D;AAE7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AACH,MAAM,CAAC,MAAM,wCAAwC,GAEjD;IACF,CAAC,2BAA2B,CAAC,mBAAmB,CAAC,EAAE,gBAAgB,CAAC,mBAAmB;IACvF,CAAC,2BAA2B,CAAC,eAAe,CAAC,EAAE,gBAAgB,CAAC,eAAe;IAC/E,CAAC,2BAA2B,CAAC,GAAG,CAAC,EAAE,gBAAgB,CAAC,GAAG;IACvD,CAAC,2BAA2B,CAAC,OAAO,CAAC,EAAE,gBAAgB,CAAC,OAAO;IAC/D,CAAC,2BAA2B,CAAC,QAAQ,CAAC,EAAE,gBAAgB,CAAC,MAAM;IAC/D;;;;;;OAMG;IACH,CAAC,2BAA2B,CAAC,cAAc,CAAC,EAAE,gBAAgB,CAAC,aAAa;IAC5E;;;;;;OAMG;IACH,CAAC,2BAA2B,CAAC,wBAAwB,CAAC,EAAE,gBAAgB,CAAC,sBAAsB;IAC/F,CAAC,2BAA2B,CAAC,YAAY,CAAC,EAAE,gBAAgB,CAAC,eAAe;IAC5E,CAAC,2BAA2B,CAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC,mBAAmB;IACpF,CAAC,2BAA2B,CAAC,yBAAyB,CAAC,EAAE,gBAAgB,CAAC,yBAAyB;IACnG,CAAC,2BAA2B,CAAC,0BAA0B,CAAC,EAAE,gBAAgB,CAAC,0BAA0B;IACrG,CAAC,2BAA2B,CAAC,iBAAiB,CAAC,EAAE,gBAAgB,CAAC,iBAAiB;IACnF,CAAC,2BAA2B,CAAC,uBAAuB,CAAC,EAAE,gBAAgB,CAAC,uBAAuB;IAC/F,CAAC,2BAA2B,CAAC,sBAAsB,CAAC,EAAE,gBAAgB,CAAC,sBAAsB;CAC9F,CAAC","sourcesContent":["import { BUILTIN_PROVIDER_CAPABILITY, type BuiltinProviderCapability } from './provider-capability.shared.schemas';\n\n/** @wildo_source:part:start saas.models.engine-capabilities facet:kind:api facet:audience:app-developer\n *\n * Closed application capability vocabulary used to declare what the\n * application needs from its configured providers.\n *\n * `EngineCapability` no longer means \"feature gate id\" and no longer\n * carries provider routing by itself. Provider-backed fulfillment is selected\n * by the application's provider configuration; entitlement/billing features\n * remain application feature decisions. Import this enum from\n * `@wildo-ai/saas-models` and declare only capabilities the application\n * actually intends to configure and operate.\n */\nexport enum EngineCapability {\n ORGANIZATIONS = 'ORGANIZATIONS',\n BILLING = 'BILLING',\n BILLING_PAYMENTS = 'BILLING_PAYMENTS',\n MULTI_LANGUAGE = 'MULTI_LANGUAGE',\n COMPLIANCE_AUDIT_TRAIL = 'COMPLIANCE_AUDIT_TRAIL',\n\n EMAIL_TRANSACTIONAL = 'EMAIL_TRANSACTIONAL',\n EMAIL_MARKETING = 'EMAIL_MARKETING',\n SMS = 'SMS',\n\n AI_LLM = 'AI_LLM',\n AI_IMAGE_GENERATION = 'AI_IMAGE_GENERATION',\n /**\n * Text → vector embeddings (the RAG derived-data tier: `.ragSource()` corpus embedding by the\n * `rag:embedding-drain` worker, and query-time embedding in retrieval). A slot of its OWN,\n * deliberately separate from `AI_LLM` (RAG plan DL2/H4): while `LLM_EMBEDDINGS` mapped into the\n * `AI_LLM` slot, an application structurally could not pick Anthropic for chat and a different\n * provider for embeddings — one `selection[AI_LLM].primary` decided both. Embeddings resolve\n * through `EMBEDDINGS_PROVIDER` protocol bindings and are selected by applicability class\n * (`Embeddings_Applicability`), never by a concrete model id at a call site.\n */\n AI_EMBEDDINGS = 'AI_EMBEDDINGS',\n /**\n * Document bytes → text: provider-backed extraction (OCR) for uploaded documents, serving\n * `FileTextExtractionBackendService` and, through it, `.ragSource()` corpus ingestion.\n *\n * ## Why a slot of its own\n *\n * Three unrelated procurement decisions were otherwise fused. A deployment may well want one\n * vendor for chat, another for embeddings, and a third for OCR — vendors are not equally good\n * at all three, and their pricing models do not even share a unit (tokens vs. pages). Mapping\n * extraction into `AI_LLM` would have made one `selection[AI_LLM].primary` decide all three,\n * which is exactly the defect that split `AI_EMBEDDINGS` out of `AI_LLM`.\n *\n * ## Not to be confused with `DOCUMENT_GENERATION`\n *\n * `DOCUMENT_GENERATION` is PDF *generation* — templates and data become bytes. This is the\n * opposite direction: bytes become text. The names are adjacent and the capabilities are\n * unrelated; nothing routes between them.\n *\n * ## Absence is benign, and that is load-bearing\n *\n * With no provider selected, extraction falls back to the local `pdfjs-dist` text-layer read.\n * That is a real answer for a born-digital PDF and returns nothing for a SCAN — so this\n * capability is what makes scanned documents answerable, never what makes extraction work at\n * all. An application that ingests only born-digital documents may leave it unset deliberately.\n */\n AI_DOCUMENT_EXTRACTION = 'AI_DOCUMENT_EXTRACTION',\n /**\n * An autonomous coding agent that mutates the application workspace.\n *\n * Its own slot rather than `AI_LLM`, for exactly the reason `AI_EMBEDDINGS`\n * was split out of it: one `selection[AI_LLM].primary` decides every provider\n * mapped into that slot. While the coding transport mapped to `AI_LLM`, an\n * application structurally could NOT choose one vendor's coding agent and a\n * different vendor for chat — picking a chat provider silently picked the\n * agent that would be allowed to edit its source.\n *\n * The stakes differ too, which is why fusing them was wrong beyond the\n * ergonomics: selecting a chat model is a quality and cost decision, while\n * selecting the agent that writes your code is those things AND an\n * authorisation decision. They deserve separate, deliberate answers.\n */\n AI_CODING_AGENT = 'AI_CODING_AGENT',\n\n DOCUMENT_GENERATION = 'DOCUMENT_GENERATION',\n ANTIVIRUS_SCANNING = 'ANTIVIRUS_SCANNING',\n\n FRONTEND_ERROR_MONITORING = 'FRONTEND_ERROR_MONITORING',\n FRONTEND_PRODUCT_ANALYTICS = 'FRONTEND_PRODUCT_ANALYTICS',\n\n /**\n * Backend LLM-call observability (model/tokens/cost/latency per `invokeAgent`),\n * platform-scoped. This enables model-call observability when the selected\n * provider configuration supplies that capability; it does not itself\n * configure a provider or make telemetry operational.\n */\n LLM_OBSERVABILITY = 'LLM_OBSERVABILITY',\n\n /**\n * Operational telemetry (traces/metrics/logs) shipped via the OpenTelemetry\n * SDK over OTLP to a provider (for example, BetterStack). Unlike\n * `LLM_OBSERVABILITY`, the connection is preloaded from\n * `OTEL_*` env vars (the CLI translates the saas-config selection + per-env\n * infra config into them) BEFORE app config — not resolved through the runtime\n * registry. Author the corresponding infrastructure/provider settings in\n * the application environment before relying on telemetry.\n */\n OBSERVABILITY_TELEMETRY = 'OBSERVABILITY_TELEMETRY',\n}\n/** @wildo_source:part:end saas.models.engine-capabilities */\n\n/**\n * Canonical, single-source-of-truth mapping from the open\n * `ProviderCapability` vocabulary (the built-in subset) to the closed\n * `EngineCapability` slots the engine actually fulfills.\n *\n * A provider declares which `providerCapabilities` it satisfies (e.g.\n * Stripe → `BILLING`, Resend → `EMAIL_TRANSACTIONAL`, Anthropic →\n * `LLM_CHAT`/`CODING_AGENT`). This map projects each built-in\n * capability onto the engine slot it fills, so a provider's\n * `engineCapabilities` set can be derived mechanically. Multiple\n * provider capabilities may share one engine slot (every `LLM_*`\n * capability maps to `AI_LLM`); de-duplicate after projecting.\n *\n * **Why this lives here (one map, three consumers).** The projection\n * used to be hand-copied in three places that silently drifted:\n * 1. The runtime registry projection in `saas-backend-lib`\n * (`ExternalProvidersRegistryBackendService.buildRuntimeRegistryFromProviderModules`),\n * which decides which provider answers `getProvidersForEngineCapability`.\n * 2. The backend companion-discovery export in\n * `@wildo-ai/external-connectors-private` (feeds the generated\n * `provider-catalog.types.ts` autocomplete via `wildo config sync`).\n * 3. The frontend companion-discovery export in\n * `@wildo-ai/external-connectors-public` (same, for browser-bound\n * provider modules).\n * A missing/wrong entry in any copy silently breaks a different surface\n * (a registry resolution, or the catalog autocomplete). It is co-located\n * with the `EngineCapability` enum it projects onto, and every consumer\n * imports it from the `@wildo-ai/saas-models` package root barrel.\n *\n * **Bundle boundary — why here and not beside `BUILTIN_PROVIDER_CAPABILITY`.**\n * This map references `EngineCapability`, which is deliberately kept off\n * the browser-safe `@wildo-ai/saas-models/public-runtime` seam. So it must\n * live in a full-only module. `engine-capabilities.shared.schemas.ts` is\n * exactly that (exported from the root barrel, never from\n * `public-runtime/index.ts`), whereas `provider-capability.shared.schemas.ts`\n * — the other natural home — IS on the public seam and would drag\n * `EngineCapability` into the browser bundle. The frontend discovery\n * consumer (#3) imports this map through its Node-only `./companion`\n * subpath, which already pulls the full root barrel; the browser-shipped\n * `./app`/`./techdoc`/`./website` subpaths never reach it.\n *\n * **BILLING → BILLING (not BILLING_PAYMENTS).** A billing provider\n * (Stripe) declares `BUILTIN_PROVIDER_CAPABILITY.BILLING` and fills the\n * `EngineCapability.BILLING` slot — the SAME slot apps enable in\n * `defineSaaSProviders`/`engineCapabilities` activation config and that\n * `getProvidersForEngineCapability` gates resolution on. Mapping it to\n * the distinct `EngineCapability.BILLING_PAYMENTS` slot (as the runtime\n * copy historically did) registered Stripe under a slot no activation\n * config enables and no consumer queries, making it unreachable through\n * the registry. `BILLING_PAYMENTS` currently has no producer or consumer\n * other than that former bug; it is left in the enum as a reserved slot.\n *\n * **Intentionally unmapped.** `SSO_OAUTH2`, `SSO_SAML`, `FRONTEND_SEARCH`,\n * `FRONTEND_FILE_PICKER`, and `FRONTEND_CAPTCHA` have no closed engine\n * slot today — they are fulfilled by provider protocols / app wiring, not\n * by an `EngineCapability`. Their absence here is by construction, not an\n * oversight: a `Partial<Record<…>>` lookup returns `undefined` and the\n * capability contributes nothing to a provider's `engineCapabilities`.\n *\n * App-extended (kebab-case) provider capabilities never appear here:\n * they live in the open `AppCustomProviderCapabilities` namespace and\n * have no engine slot by definition.\n */\nexport const PROVIDER_CAPABILITY_TO_ENGINE_CAPABILITY: Partial<\n Record<BuiltinProviderCapability, EngineCapability>\n> = {\n [BUILTIN_PROVIDER_CAPABILITY.EMAIL_TRANSACTIONAL]: EngineCapability.EMAIL_TRANSACTIONAL,\n [BUILTIN_PROVIDER_CAPABILITY.EMAIL_MARKETING]: EngineCapability.EMAIL_MARKETING,\n [BUILTIN_PROVIDER_CAPABILITY.SMS]: EngineCapability.SMS,\n [BUILTIN_PROVIDER_CAPABILITY.BILLING]: EngineCapability.BILLING,\n [BUILTIN_PROVIDER_CAPABILITY.LLM_CHAT]: EngineCapability.AI_LLM,\n /**\n * REPOINTED 2026-08-27 (RAG plan DL2/H4): `LLM_EMBEDDINGS` used to map into `AI_LLM`, which\n * fused the chat and embeddings provider selections into one slot. The TOKEN keeps its name —\n * it correctly says \"this provider can produce embeddings\", and it sits inside the anchored\n * `saas.models.provider-capabilities` block compiled into shipped skills — only the slot it\n * fills changed. Exactly one token claims the embeddings slot.\n */\n [BUILTIN_PROVIDER_CAPABILITY.LLM_EMBEDDINGS]: EngineCapability.AI_EMBEDDINGS,\n /**\n * EXACTLY ONE token claims the document-extraction slot, and it is a new one. Checked rather\n * than assumed before adding it: `IMAGE_GENERATION` maps to `AI_IMAGE_GENERATION` (output),\n * `LLM_CHAT` to `AI_LLM`, `LLM_EMBEDDINGS` to `AI_EMBEDDINGS`, and no built-in token mapped\n * anywhere near document INPUT. Repointing an existing token — the move that kept\n * `LLM_EMBEDDINGS` alive — was not available here because none of them meant this.\n */\n [BUILTIN_PROVIDER_CAPABILITY.DOCUMENT_TEXT_EXTRACTION]: EngineCapability.AI_DOCUMENT_EXTRACTION,\n [BUILTIN_PROVIDER_CAPABILITY.CODING_AGENT]: EngineCapability.AI_CODING_AGENT,\n [BUILTIN_PROVIDER_CAPABILITY.IMAGE_GENERATION]: EngineCapability.AI_IMAGE_GENERATION,\n [BUILTIN_PROVIDER_CAPABILITY.FRONTEND_ERROR_MONITORING]: EngineCapability.FRONTEND_ERROR_MONITORING,\n [BUILTIN_PROVIDER_CAPABILITY.FRONTEND_PRODUCT_ANALYTICS]: EngineCapability.FRONTEND_PRODUCT_ANALYTICS,\n [BUILTIN_PROVIDER_CAPABILITY.LLM_OBSERVABILITY]: EngineCapability.LLM_OBSERVABILITY,\n [BUILTIN_PROVIDER_CAPABILITY.OBSERVABILITY_TELEMETRY]: EngineCapability.OBSERVABILITY_TELEMETRY,\n [BUILTIN_PROVIDER_CAPABILITY.COMPLIANCE_AUDIT_TRAIL]: EngineCapability.COMPLIANCE_AUDIT_TRAIL,\n};\n"]}
1
+ {"version":3,"file":"engine-capabilities.shared.schemas.js","sourceRoot":"","sources":["../../../../src/external-providers/engine-capabilities.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,2BAA2B,EAAkC,MAAM,sCAAsC,CAAC;AAEnH;;;;;;;;;;;GAWG;AACH,MAAM,CAAN,IAAY,gBA8GX;AA9GD,WAAY,gBAAgB;IAC1B,mDAA+B,CAAA;IAC/B,uCAAmB,CAAA;IACnB,yDAAqC,CAAA;IACrC,qDAAiC,CAAA;IACjC,qEAAiD,CAAA;IAEjD,+DAA2C,CAAA;IAC3C,uDAAmC,CAAA;IACnC,+BAAW,CAAA;IAEX,qCAAiB,CAAA;IACjB,+DAA2C,CAAA;IAC3C;;;;;;;;OAQG;IACH,mDAA+B,CAAA;IAC/B;;;;;;;;;;;;;;;;;;;;;;;;;;OA0BG;IACH,qEAAiD,CAAA;IACjD;;;;;;;;;;;;;;OAcG;IACH,uDAAmC,CAAA;IAEnC;;;;;;;;;;;;;;;;;;;OAmBG;IAEH,2EAAuD,CAAA;IACvD,6EAAyD,CAAA;IAEzD;;;;;OAKG;IACH,2DAAuC,CAAA;IAEvC;;;;;;;;OAQG;IACH,uEAAmD,CAAA;AACrD,CAAC,EA9GW,gBAAgB,KAAhB,gBAAgB,QA8G3B;AACD,6DAA6D;AAE7D;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8DG;AACH,MAAM,CAAC,MAAM,wCAAwC,GAEjD;IACF,CAAC,2BAA2B,CAAC,mBAAmB,CAAC,EAAE,gBAAgB,CAAC,mBAAmB;IACvF,CAAC,2BAA2B,CAAC,eAAe,CAAC,EAAE,gBAAgB,CAAC,eAAe;IAC/E,CAAC,2BAA2B,CAAC,GAAG,CAAC,EAAE,gBAAgB,CAAC,GAAG;IACvD,CAAC,2BAA2B,CAAC,OAAO,CAAC,EAAE,gBAAgB,CAAC,OAAO;IAC/D,CAAC,2BAA2B,CAAC,QAAQ,CAAC,EAAE,gBAAgB,CAAC,MAAM;IAC/D;;;;;;OAMG;IACH,CAAC,2BAA2B,CAAC,cAAc,CAAC,EAAE,gBAAgB,CAAC,aAAa;IAC5E;;;;;;OAMG;IACH,CAAC,2BAA2B,CAAC,wBAAwB,CAAC,EAAE,gBAAgB,CAAC,sBAAsB;IAC/F,CAAC,2BAA2B,CAAC,YAAY,CAAC,EAAE,gBAAgB,CAAC,eAAe;IAC5E,CAAC,2BAA2B,CAAC,gBAAgB,CAAC,EAAE,gBAAgB,CAAC,mBAAmB;IACpF,CAAC,2BAA2B,CAAC,yBAAyB,CAAC,EAAE,gBAAgB,CAAC,yBAAyB;IACnG,CAAC,2BAA2B,CAAC,0BAA0B,CAAC,EAAE,gBAAgB,CAAC,0BAA0B;IACrG,CAAC,2BAA2B,CAAC,iBAAiB,CAAC,EAAE,gBAAgB,CAAC,iBAAiB;IACnF,CAAC,2BAA2B,CAAC,uBAAuB,CAAC,EAAE,gBAAgB,CAAC,uBAAuB;IAC/F,CAAC,2BAA2B,CAAC,sBAAsB,CAAC,EAAE,gBAAgB,CAAC,sBAAsB;CAC9F,CAAC","sourcesContent":["import { BUILTIN_PROVIDER_CAPABILITY, type BuiltinProviderCapability } from './provider-capability.shared.schemas';\n\n/** @wildo_source:part:start saas.models.engine-capabilities facet:kind:api facet:audience:app-developer\n *\n * Closed application capability vocabulary used to declare what the\n * application needs from its configured providers.\n *\n * `EngineCapability` no longer means \"feature gate id\" and no longer\n * carries provider routing by itself. Provider-backed fulfillment is selected\n * by the application's provider configuration; entitlement/billing features\n * remain application feature decisions. Import this enum from\n * `@wildo-ai/saas-models` and declare only capabilities the application\n * actually intends to configure and operate.\n */\nexport enum EngineCapability {\n ORGANIZATIONS = 'ORGANIZATIONS',\n BILLING = 'BILLING',\n BILLING_PAYMENTS = 'BILLING_PAYMENTS',\n MULTI_LANGUAGE = 'MULTI_LANGUAGE',\n COMPLIANCE_AUDIT_TRAIL = 'COMPLIANCE_AUDIT_TRAIL',\n\n EMAIL_TRANSACTIONAL = 'EMAIL_TRANSACTIONAL',\n EMAIL_MARKETING = 'EMAIL_MARKETING',\n SMS = 'SMS',\n\n AI_LLM = 'AI_LLM',\n AI_IMAGE_GENERATION = 'AI_IMAGE_GENERATION',\n /**\n * Text → vector embeddings (the RAG derived-data tier: `.ragSource()` corpus embedding by the\n * `rag:embedding-drain` worker, and query-time embedding in retrieval). A slot of its OWN,\n * deliberately separate from `AI_LLM` (RAG plan DL2/H4): while `LLM_EMBEDDINGS` mapped into the\n * `AI_LLM` slot, an application structurally could not pick Anthropic for chat and a different\n * provider for embeddings — one `selection[AI_LLM].primary` decided both. Embeddings resolve\n * through `EMBEDDINGS_PROVIDER` protocol bindings and are selected by applicability class\n * (`Embeddings_Applicability`), never by a concrete model id at a call site.\n */\n AI_EMBEDDINGS = 'AI_EMBEDDINGS',\n /**\n * Document bytes → text: provider-backed extraction (OCR) for uploaded documents, serving\n * `FileTextExtractionBackendService` and, through it, `.ragSource()` corpus ingestion.\n *\n * ## Why a slot of its own\n *\n * Three unrelated procurement decisions were otherwise fused. A deployment may well want one\n * vendor for chat, another for embeddings, and a third for OCR — vendors are not equally good\n * at all three, and their pricing models do not even share a unit (tokens vs. pages). Mapping\n * extraction into `AI_LLM` would have made one `selection[AI_LLM].primary` decide all three,\n * which is exactly the defect that split `AI_EMBEDDINGS` out of `AI_LLM`.\n *\n * ## Not to be confused with PDF GENERATION\n *\n * PDF generation — templates and data become bytes — is the `pdfTemplates` surface, done\n * in-process and with no provider slot of its own. This is the opposite direction: bytes become\n * text. The two are unrelated and nothing routes between them. (There WAS an\n * `EngineCapability.DOCUMENT_GENERATION` that this paragraph used to name; it was withdrawn\n * because no provider capability could ever fill it.)\n *\n * ## Absence is benign, and that is load-bearing\n *\n * With no provider selected, extraction falls back to the local `pdfjs-dist` text-layer read.\n * That is a real answer for a born-digital PDF and returns nothing for a SCAN — so this\n * capability is what makes scanned documents answerable, never what makes extraction work at\n * all. An application that ingests only born-digital documents may leave it unset deliberately.\n */\n AI_DOCUMENT_EXTRACTION = 'AI_DOCUMENT_EXTRACTION',\n /**\n * An autonomous coding agent that mutates the application workspace.\n *\n * Its own slot rather than `AI_LLM`, for exactly the reason `AI_EMBEDDINGS`\n * was split out of it: one `selection[AI_LLM].primary` decides every provider\n * mapped into that slot. While the coding transport mapped to `AI_LLM`, an\n * application structurally could NOT choose one vendor's coding agent and a\n * different vendor for chat — picking a chat provider silently picked the\n * agent that would be allowed to edit its source.\n *\n * The stakes differ too, which is why fusing them was wrong beyond the\n * ergonomics: selecting a chat model is a quality and cost decision, while\n * selecting the agent that writes your code is those things AND an\n * authorisation decision. They deserve separate, deliberate answers.\n */\n AI_CODING_AGENT = 'AI_CODING_AGENT',\n\n /*\n * WITHDRAWN 2026-09-03: `DOCUMENT_GENERATION` and `ANTIVIRUS_SCANNING` were members here and are\n * not any more. Neither could ever be filled — `PROVIDER_CAPABILITY_TO_ENGINE_CAPABILITY` had no\n * entry pointing at either, so no provider capability token could claim the slot — while both were\n * classified `SELECT_ONE`, which asserts that exactly one provider must be selected. Selecting one\n * of zero candidates is not a resolution mode.\n *\n * Both capabilities are real and both are delivered elsewhere, which is why withdrawing the slots\n * costs nothing: antivirus scanning is `InfraCapability.ANTIVIRUS_SCANNING`, fulfilled by ClamAV\n * and consumed by `FileScanningBackendService`; PDF generation is the in-process `pdfTemplates`\n * surface, with `InfraCapability.DOCUMENT_RENDERING` (Gotenberg) provisioned beside it. Neither\n * has an external provider, and neither is planned to.\n *\n * Removing `ANTIVIRUS_SCANNING` also removes a collision: the identical spelling named an engine\n * slot nothing could fill AND a live infra capability, in two packages, so a reader grepping the\n * word landed in whichever they searched first.\n *\n * If a hosted AV or document-rendering vendor is ever adopted, the member comes back WITH its\n * `PROVIDER_CAPABILITY_TO_ENGINE_CAPABILITY` entry and its own JSDoc in the same change.\n */\n\n FRONTEND_ERROR_MONITORING = 'FRONTEND_ERROR_MONITORING',\n FRONTEND_PRODUCT_ANALYTICS = 'FRONTEND_PRODUCT_ANALYTICS',\n\n /**\n * Backend LLM-call observability (model/tokens/cost/latency per `invokeAgent`),\n * platform-scoped. This enables model-call observability when the selected\n * provider configuration supplies that capability; it does not itself\n * configure a provider or make telemetry operational.\n */\n LLM_OBSERVABILITY = 'LLM_OBSERVABILITY',\n\n /**\n * Operational telemetry (traces/metrics/logs) shipped via the OpenTelemetry\n * SDK over OTLP to a provider (for example, BetterStack). Unlike\n * `LLM_OBSERVABILITY`, the connection is preloaded from\n * `OTEL_*` env vars (the CLI translates the saas-config selection + per-env\n * infra config into them) BEFORE app config — not resolved through the runtime\n * registry. Author the corresponding infrastructure/provider settings in\n * the application environment before relying on telemetry.\n */\n OBSERVABILITY_TELEMETRY = 'OBSERVABILITY_TELEMETRY',\n}\n/** @wildo_source:part:end saas.models.engine-capabilities */\n\n/**\n * Canonical, single-source-of-truth mapping from the open\n * `ProviderCapability` vocabulary (the built-in subset) to the closed\n * `EngineCapability` slots the engine actually fulfills.\n *\n * A provider declares which `providerCapabilities` it satisfies (e.g.\n * Stripe → `BILLING`, Resend → `EMAIL_TRANSACTIONAL`, Anthropic →\n * `LLM_CHAT`/`CODING_AGENT`). This map projects each built-in\n * capability onto the engine slot it fills, so a provider's\n * `engineCapabilities` set can be derived mechanically. Multiple\n * provider capabilities may share one engine slot (every `LLM_*`\n * capability maps to `AI_LLM`); de-duplicate after projecting.\n *\n * **Why this lives here (one map, three consumers).** The projection\n * used to be hand-copied in three places that silently drifted:\n * 1. The runtime registry projection in `saas-backend-lib`\n * (`ExternalProvidersRegistryBackendService.buildRuntimeRegistryFromProviderModules`),\n * which decides which provider answers `getProvidersForEngineCapability`.\n * 2. The backend companion-discovery export in\n * `@wildo-ai/external-connectors-private` (feeds the generated\n * `provider-catalog.types.ts` autocomplete via `wildo config sync`).\n * 3. The frontend companion-discovery export in\n * `@wildo-ai/external-connectors-public` (same, for browser-bound\n * provider modules).\n * A missing/wrong entry in any copy silently breaks a different surface\n * (a registry resolution, or the catalog autocomplete). It is co-located\n * with the `EngineCapability` enum it projects onto, and every consumer\n * imports it from the `@wildo-ai/saas-models` package root barrel.\n *\n * **Bundle boundary — why here and not beside `BUILTIN_PROVIDER_CAPABILITY`.**\n * This map references `EngineCapability`, which is deliberately kept off\n * the browser-safe `@wildo-ai/saas-models/public-runtime` seam. So it must\n * live in a full-only module. `engine-capabilities.shared.schemas.ts` is\n * exactly that (exported from the root barrel, never from\n * `public-runtime/index.ts`), whereas `provider-capability.shared.schemas.ts`\n * — the other natural home — IS on the public seam and would drag\n * `EngineCapability` into the browser bundle. The frontend discovery\n * consumer (#3) imports this map through its Node-only `./companion`\n * subpath, which already pulls the full root barrel; the browser-shipped\n * `./app`/`./techdoc`/`./website` subpaths never reach it.\n *\n * **BILLING → BILLING (not BILLING_PAYMENTS).** A billing provider\n * (Stripe) declares `BUILTIN_PROVIDER_CAPABILITY.BILLING` and fills the\n * `EngineCapability.BILLING` slot — the SAME slot apps enable in\n * `defineSaaSProviders`/`engineCapabilities` activation config and that\n * `getProvidersForEngineCapability` gates resolution on. Mapping it to\n * the distinct `EngineCapability.BILLING_PAYMENTS` slot (as the runtime\n * copy historically did) registered Stripe under a slot no activation\n * config enables and no consumer queries, making it unreachable through\n * the registry. `BILLING_PAYMENTS` currently has no producer or consumer\n * other than that former bug; it is left in the enum as a reserved slot.\n *\n * **Intentionally unmapped.** `SSO_OAUTH2`, `SSO_SAML`, `FRONTEND_SEARCH`,\n * `FRONTEND_FILE_PICKER`, and `FRONTEND_CAPTCHA` have no closed engine\n * slot today — they are fulfilled by provider protocols / app wiring, not\n * by an `EngineCapability`. Their absence here is by construction, not an\n * oversight: a `Partial<Record<…>>` lookup returns `undefined` and the\n * capability contributes nothing to a provider's `engineCapabilities`.\n *\n * App-extended (kebab-case) provider capabilities never appear here:\n * they live in the open `AppCustomProviderCapabilities` namespace and\n * have no engine slot by definition.\n */\nexport const PROVIDER_CAPABILITY_TO_ENGINE_CAPABILITY: Partial<\n Record<BuiltinProviderCapability, EngineCapability>\n> = {\n [BUILTIN_PROVIDER_CAPABILITY.EMAIL_TRANSACTIONAL]: EngineCapability.EMAIL_TRANSACTIONAL,\n [BUILTIN_PROVIDER_CAPABILITY.EMAIL_MARKETING]: EngineCapability.EMAIL_MARKETING,\n [BUILTIN_PROVIDER_CAPABILITY.SMS]: EngineCapability.SMS,\n [BUILTIN_PROVIDER_CAPABILITY.BILLING]: EngineCapability.BILLING,\n [BUILTIN_PROVIDER_CAPABILITY.LLM_CHAT]: EngineCapability.AI_LLM,\n /**\n * REPOINTED 2026-08-27 (RAG plan DL2/H4): `LLM_EMBEDDINGS` used to map into `AI_LLM`, which\n * fused the chat and embeddings provider selections into one slot. The TOKEN keeps its name —\n * it correctly says \"this provider can produce embeddings\", and it sits inside the anchored\n * `saas.models.provider-capabilities` block compiled into shipped skills — only the slot it\n * fills changed. Exactly one token claims the embeddings slot.\n */\n [BUILTIN_PROVIDER_CAPABILITY.LLM_EMBEDDINGS]: EngineCapability.AI_EMBEDDINGS,\n /**\n * EXACTLY ONE token claims the document-extraction slot, and it is a new one. Checked rather\n * than assumed before adding it: `IMAGE_GENERATION` maps to `AI_IMAGE_GENERATION` (output),\n * `LLM_CHAT` to `AI_LLM`, `LLM_EMBEDDINGS` to `AI_EMBEDDINGS`, and no built-in token mapped\n * anywhere near document INPUT. Repointing an existing token — the move that kept\n * `LLM_EMBEDDINGS` alive — was not available here because none of them meant this.\n */\n [BUILTIN_PROVIDER_CAPABILITY.DOCUMENT_TEXT_EXTRACTION]: EngineCapability.AI_DOCUMENT_EXTRACTION,\n [BUILTIN_PROVIDER_CAPABILITY.CODING_AGENT]: EngineCapability.AI_CODING_AGENT,\n [BUILTIN_PROVIDER_CAPABILITY.IMAGE_GENERATION]: EngineCapability.AI_IMAGE_GENERATION,\n [BUILTIN_PROVIDER_CAPABILITY.FRONTEND_ERROR_MONITORING]: EngineCapability.FRONTEND_ERROR_MONITORING,\n [BUILTIN_PROVIDER_CAPABILITY.FRONTEND_PRODUCT_ANALYTICS]: EngineCapability.FRONTEND_PRODUCT_ANALYTICS,\n [BUILTIN_PROVIDER_CAPABILITY.LLM_OBSERVABILITY]: EngineCapability.LLM_OBSERVABILITY,\n [BUILTIN_PROVIDER_CAPABILITY.OBSERVABILITY_TELEMETRY]: EngineCapability.OBSERVABILITY_TELEMETRY,\n [BUILTIN_PROVIDER_CAPABILITY.COMPLIANCE_AUDIT_TRAIL]: EngineCapability.COMPLIANCE_AUDIT_TRAIL,\n};\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"engine-capability-resolution-mode.shared.d.ts","sourceRoot":"","sources":["../../../../src/external-providers/engine-capability-resolution-mode.shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAExE;;;;;;;;;;GAUG;AACH,oBAAY,8BAA8B;IACxC;;;;OAIG;IACH,UAAU,eAAe;IACzB;;;;;OAKG;IACH,OAAO,YAAY;CACpB;AA+CD;;;;;;;;;GASG;AACH,wBAAgB,iCAAiC,CAC/C,UAAU,EAAE,gBAAgB,GAC3B,8BAA8B,CAEhC"}
1
+ {"version":3,"file":"engine-capability-resolution-mode.shared.d.ts","sourceRoot":"","sources":["../../../../src/external-providers/engine-capability-resolution-mode.shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAExE;;;;;;;;;;GAUG;AACH,oBAAY,8BAA8B;IACxC;;;;OAIG;IACH,UAAU,eAAe;IACzB;;;;;OAKG;IACH,OAAO,YAAY;CACpB;AA6CD;;;;;;;;;GASG;AACH,wBAAgB,iCAAiC,CAC/C,UAAU,EAAE,gBAAgB,GAC3B,8BAA8B,CAEhC"}
@@ -62,8 +62,6 @@ const ENGINE_CAPABILITY_RESOLUTION_MODE = {
62
62
  // asked for — and the change attribution that follows a run could no longer say which agent
63
63
  // wrote which file.
64
64
  [EngineCapability.AI_CODING_AGENT]: EngineCapabilityResolutionMode.SELECT_ONE,
65
- [EngineCapability.DOCUMENT_GENERATION]: EngineCapabilityResolutionMode.SELECT_ONE,
66
- [EngineCapability.ANTIVIRUS_SCANNING]: EngineCapabilityResolutionMode.SELECT_ONE,
67
65
  [EngineCapability.FRONTEND_ERROR_MONITORING]: EngineCapabilityResolutionMode.SELECT_ONE,
68
66
  [EngineCapability.FRONTEND_PRODUCT_ANALYTICS]: EngineCapabilityResolutionMode.SELECT_ONE,
69
67
  [EngineCapability.LLM_OBSERVABILITY]: EngineCapabilityResolutionMode.SELECT_ONE,
@@ -1 +1 @@
1
- {"version":3,"file":"engine-capability-resolution-mode.shared.js","sourceRoot":"","sources":["../../../../src/external-providers/engine-capability-resolution-mode.shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAExE;;;;;;;;;;GAUG;AACH,MAAM,CAAN,IAAY,8BAcX;AAdD,WAAY,8BAA8B;IACxC;;;;OAIG;IACH,2DAAyB,CAAA;IACzB;;;;;OAKG;IACH,qDAAmB,CAAA;AACrB,CAAC,EAdW,8BAA8B,KAA9B,8BAA8B,QAczC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,iCAAiC,GAA6D;IAClG,CAAC,gBAAgB,CAAC,sBAAsB,CAAC,EAAE,8BAA8B,CAAC,OAAO;IAEjF,CAAC,gBAAgB,CAAC,aAAa,CAAC,EAAE,8BAA8B,CAAC,UAAU;IAC3E,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,8BAA8B,CAAC,UAAU;IACrE,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,EAAE,8BAA8B,CAAC,UAAU;IAC9E,CAAC,gBAAgB,CAAC,cAAc,CAAC,EAAE,8BAA8B,CAAC,UAAU;IAC5E,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,EAAE,8BAA8B,CAAC,UAAU;IACjF,CAAC,gBAAgB,CAAC,eAAe,CAAC,EAAE,8BAA8B,CAAC,UAAU;IAC7E,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,8BAA8B,CAAC,UAAU;IACjE,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,8BAA8B,CAAC,UAAU;IACpE,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,EAAE,8BAA8B,CAAC,UAAU;IACjF,8FAA8F;IAC9F,8FAA8F;IAC9F,CAAC,gBAAgB,CAAC,aAAa,CAAC,EAAE,8BAA8B,CAAC,UAAU;IAC3E,4FAA4F;IAC5F,6FAA6F;IAC7F,2FAA2F;IAC3F,CAAC,gBAAgB,CAAC,sBAAsB,CAAC,EAAE,8BAA8B,CAAC,UAAU;IACpF,0FAA0F;IAC1F,4FAA4F;IAC5F,4FAA4F;IAC5F,oBAAoB;IACpB,CAAC,gBAAgB,CAAC,eAAe,CAAC,EAAE,8BAA8B,CAAC,UAAU;IAC7E,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,EAAE,8BAA8B,CAAC,UAAU;IACjF,CAAC,gBAAgB,CAAC,kBAAkB,CAAC,EAAE,8BAA8B,CAAC,UAAU;IAChF,CAAC,gBAAgB,CAAC,yBAAyB,CAAC,EAAE,8BAA8B,CAAC,UAAU;IACvF,CAAC,gBAAgB,CAAC,0BAA0B,CAAC,EAAE,8BAA8B,CAAC,UAAU;IACxF,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,EAAE,8BAA8B,CAAC,UAAU;IAC/E,CAAC,gBAAgB,CAAC,uBAAuB,CAAC,EAAE,8BAA8B,CAAC,UAAU;CACtF,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,UAAU,iCAAiC,CAC/C,UAA4B;IAE5B,OAAO,iCAAiC,CAAC,UAAU,CAAC,CAAC;AACvD,CAAC","sourcesContent":["import { EngineCapability } from './engine-capabilities.shared.schemas';\n\n/**\n * How the engine resolves the provider(s) fulfilling an `EngineCapability`\n * when more than one is declared for the same scope.\n *\n * This is a FIRST-CLASS, declared property of a capability — NOT an implicit\n * per-consumer convention. A reader can tell whether a capability picks one\n * provider or writes to all of them; a new capability author declares it\n * here; and both the runtime registry resolver and the `defineSaaSProviders`\n * config validators branch on it (so a `FAN_OUT` capability is validated by\n * DECLARATION and never keyed off `selection`).\n */\nexport enum EngineCapabilityResolutionMode {\n /**\n * Exactly one active provider — `selection.<capability>.primary`, with\n * `fallbacks` tried only on failure. The default for every capability\n * (billing, email, observability, …): a request is served by one provider.\n */\n SELECT_ONE = 'SELECT_ONE',\n /**\n * ALL declared providers are active simultaneously — every one receives\n * every emission (no primary, no failover). For sinks whose nature is\n * additive rather than substitutable: `COMPLIANCE_AUDIT_TRAIL` writes each\n * audit event to every configured destination.\n */\n FAN_OUT = 'FAN_OUT',\n}\n\n/**\n * The DECLARED resolution mode for EVERY engine capability. Exhaustive by\n * construction: because this is a `Record<EngineCapability, …>`, adding a new\n * member to the `EngineCapability` enum WITHOUT classifying it here is a COMPILE\n * error. That is deliberate — a bare \"default to SELECT_ONE\" would let a future\n * additive/fan-out capability silently collapse to single-provider resolution\n * (dropping emissions to every non-primary destination) just because its author\n * forgot a one-line edit. The compiler now forces the decision.\n *\n * Only `COMPLIANCE_AUDIT_TRAIL` is `FAN_OUT` today (audit events are additive —\n * every declared destination receives every event). Everything else is\n * `SELECT_ONE` (the failover norm — one active provider, fallbacks on failure).\n */\nconst ENGINE_CAPABILITY_RESOLUTION_MODE: Record<EngineCapability, EngineCapabilityResolutionMode> = {\n [EngineCapability.COMPLIANCE_AUDIT_TRAIL]: EngineCapabilityResolutionMode.FAN_OUT,\n\n [EngineCapability.ORGANIZATIONS]: EngineCapabilityResolutionMode.SELECT_ONE,\n [EngineCapability.BILLING]: EngineCapabilityResolutionMode.SELECT_ONE,\n [EngineCapability.BILLING_PAYMENTS]: EngineCapabilityResolutionMode.SELECT_ONE,\n [EngineCapability.MULTI_LANGUAGE]: EngineCapabilityResolutionMode.SELECT_ONE,\n [EngineCapability.EMAIL_TRANSACTIONAL]: EngineCapabilityResolutionMode.SELECT_ONE,\n [EngineCapability.EMAIL_MARKETING]: EngineCapabilityResolutionMode.SELECT_ONE,\n [EngineCapability.SMS]: EngineCapabilityResolutionMode.SELECT_ONE,\n [EngineCapability.AI_LLM]: EngineCapabilityResolutionMode.SELECT_ONE,\n [EngineCapability.AI_IMAGE_GENERATION]: EngineCapabilityResolutionMode.SELECT_ONE,\n // Embeddings are substitutable, not additive: one provider serves a vector space, and writing\n // the same chunk through two providers would produce two incompatible spaces, not redundancy.\n [EngineCapability.AI_EMBEDDINGS]: EngineCapabilityResolutionMode.SELECT_ONE,\n // Extraction is substitutable, not additive: one provider reads a document, and running the\n // same bytes through two OCR services would produce two divergent transcriptions of one page\n // with no principled way to merge them — plus a second egress of the same private content.\n [EngineCapability.AI_DOCUMENT_EXTRACTION]: EngineCapabilityResolutionMode.SELECT_ONE,\n // One agent per task, and emphatically not fan-out: two coding agents given the same task\n // against the same worktree do not produce redundancy, they produce a merge conflict nobody\n // asked for — and the change attribution that follows a run could no longer say which agent\n // wrote which file.\n [EngineCapability.AI_CODING_AGENT]: EngineCapabilityResolutionMode.SELECT_ONE,\n [EngineCapability.DOCUMENT_GENERATION]: EngineCapabilityResolutionMode.SELECT_ONE,\n [EngineCapability.ANTIVIRUS_SCANNING]: EngineCapabilityResolutionMode.SELECT_ONE,\n [EngineCapability.FRONTEND_ERROR_MONITORING]: EngineCapabilityResolutionMode.SELECT_ONE,\n [EngineCapability.FRONTEND_PRODUCT_ANALYTICS]: EngineCapabilityResolutionMode.SELECT_ONE,\n [EngineCapability.LLM_OBSERVABILITY]: EngineCapabilityResolutionMode.SELECT_ONE,\n [EngineCapability.OBSERVABILITY_TELEMETRY]: EngineCapabilityResolutionMode.SELECT_ONE,\n};\n\n/**\n * The declared resolution mode for an engine capability. A TOTAL lookup — every\n * capability is explicitly classified in `ENGINE_CAPABILITY_RESOLUTION_MODE`\n * (no silent default).\n *\n * Consumers: the runtime registry (`ExternalProvidersRegistryBackendService`\n * — `FAN_OUT` uses the full provider list, `SELECT_ONE` uses the primary) and\n * the `defineSaaSProviders` validators (a `FAN_OUT` capability is validated by\n * declaration and rejects a `selection` entry).\n */\nexport function getEngineCapabilityResolutionMode(\n capability: EngineCapability,\n): EngineCapabilityResolutionMode {\n return ENGINE_CAPABILITY_RESOLUTION_MODE[capability];\n}\n"]}
1
+ {"version":3,"file":"engine-capability-resolution-mode.shared.js","sourceRoot":"","sources":["../../../../src/external-providers/engine-capability-resolution-mode.shared.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,sCAAsC,CAAC;AAExE;;;;;;;;;;GAUG;AACH,MAAM,CAAN,IAAY,8BAcX;AAdD,WAAY,8BAA8B;IACxC;;;;OAIG;IACH,2DAAyB,CAAA;IACzB;;;;;OAKG;IACH,qDAAmB,CAAA;AACrB,CAAC,EAdW,8BAA8B,KAA9B,8BAA8B,QAczC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,iCAAiC,GAA6D;IAClG,CAAC,gBAAgB,CAAC,sBAAsB,CAAC,EAAE,8BAA8B,CAAC,OAAO;IAEjF,CAAC,gBAAgB,CAAC,aAAa,CAAC,EAAE,8BAA8B,CAAC,UAAU;IAC3E,CAAC,gBAAgB,CAAC,OAAO,CAAC,EAAE,8BAA8B,CAAC,UAAU;IACrE,CAAC,gBAAgB,CAAC,gBAAgB,CAAC,EAAE,8BAA8B,CAAC,UAAU;IAC9E,CAAC,gBAAgB,CAAC,cAAc,CAAC,EAAE,8BAA8B,CAAC,UAAU;IAC5E,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,EAAE,8BAA8B,CAAC,UAAU;IACjF,CAAC,gBAAgB,CAAC,eAAe,CAAC,EAAE,8BAA8B,CAAC,UAAU;IAC7E,CAAC,gBAAgB,CAAC,GAAG,CAAC,EAAE,8BAA8B,CAAC,UAAU;IACjE,CAAC,gBAAgB,CAAC,MAAM,CAAC,EAAE,8BAA8B,CAAC,UAAU;IACpE,CAAC,gBAAgB,CAAC,mBAAmB,CAAC,EAAE,8BAA8B,CAAC,UAAU;IACjF,8FAA8F;IAC9F,8FAA8F;IAC9F,CAAC,gBAAgB,CAAC,aAAa,CAAC,EAAE,8BAA8B,CAAC,UAAU;IAC3E,4FAA4F;IAC5F,6FAA6F;IAC7F,2FAA2F;IAC3F,CAAC,gBAAgB,CAAC,sBAAsB,CAAC,EAAE,8BAA8B,CAAC,UAAU;IACpF,0FAA0F;IAC1F,4FAA4F;IAC5F,4FAA4F;IAC5F,oBAAoB;IACpB,CAAC,gBAAgB,CAAC,eAAe,CAAC,EAAE,8BAA8B,CAAC,UAAU;IAC7E,CAAC,gBAAgB,CAAC,yBAAyB,CAAC,EAAE,8BAA8B,CAAC,UAAU;IACvF,CAAC,gBAAgB,CAAC,0BAA0B,CAAC,EAAE,8BAA8B,CAAC,UAAU;IACxF,CAAC,gBAAgB,CAAC,iBAAiB,CAAC,EAAE,8BAA8B,CAAC,UAAU;IAC/E,CAAC,gBAAgB,CAAC,uBAAuB,CAAC,EAAE,8BAA8B,CAAC,UAAU;CACtF,CAAC;AAEF;;;;;;;;;GASG;AACH,MAAM,UAAU,iCAAiC,CAC/C,UAA4B;IAE5B,OAAO,iCAAiC,CAAC,UAAU,CAAC,CAAC;AACvD,CAAC","sourcesContent":["import { EngineCapability } from './engine-capabilities.shared.schemas';\n\n/**\n * How the engine resolves the provider(s) fulfilling an `EngineCapability`\n * when more than one is declared for the same scope.\n *\n * This is a FIRST-CLASS, declared property of a capability — NOT an implicit\n * per-consumer convention. A reader can tell whether a capability picks one\n * provider or writes to all of them; a new capability author declares it\n * here; and both the runtime registry resolver and the `defineSaaSProviders`\n * config validators branch on it (so a `FAN_OUT` capability is validated by\n * DECLARATION and never keyed off `selection`).\n */\nexport enum EngineCapabilityResolutionMode {\n /**\n * Exactly one active provider — `selection.<capability>.primary`, with\n * `fallbacks` tried only on failure. The default for every capability\n * (billing, email, observability, …): a request is served by one provider.\n */\n SELECT_ONE = 'SELECT_ONE',\n /**\n * ALL declared providers are active simultaneously — every one receives\n * every emission (no primary, no failover). For sinks whose nature is\n * additive rather than substitutable: `COMPLIANCE_AUDIT_TRAIL` writes each\n * audit event to every configured destination.\n */\n FAN_OUT = 'FAN_OUT',\n}\n\n/**\n * The DECLARED resolution mode for EVERY engine capability. Exhaustive by\n * construction: because this is a `Record<EngineCapability, …>`, adding a new\n * member to the `EngineCapability` enum WITHOUT classifying it here is a COMPILE\n * error. That is deliberate — a bare \"default to SELECT_ONE\" would let a future\n * additive/fan-out capability silently collapse to single-provider resolution\n * (dropping emissions to every non-primary destination) just because its author\n * forgot a one-line edit. The compiler now forces the decision.\n *\n * Only `COMPLIANCE_AUDIT_TRAIL` is `FAN_OUT` today (audit events are additive —\n * every declared destination receives every event). Everything else is\n * `SELECT_ONE` (the failover norm — one active provider, fallbacks on failure).\n */\nconst ENGINE_CAPABILITY_RESOLUTION_MODE: Record<EngineCapability, EngineCapabilityResolutionMode> = {\n [EngineCapability.COMPLIANCE_AUDIT_TRAIL]: EngineCapabilityResolutionMode.FAN_OUT,\n\n [EngineCapability.ORGANIZATIONS]: EngineCapabilityResolutionMode.SELECT_ONE,\n [EngineCapability.BILLING]: EngineCapabilityResolutionMode.SELECT_ONE,\n [EngineCapability.BILLING_PAYMENTS]: EngineCapabilityResolutionMode.SELECT_ONE,\n [EngineCapability.MULTI_LANGUAGE]: EngineCapabilityResolutionMode.SELECT_ONE,\n [EngineCapability.EMAIL_TRANSACTIONAL]: EngineCapabilityResolutionMode.SELECT_ONE,\n [EngineCapability.EMAIL_MARKETING]: EngineCapabilityResolutionMode.SELECT_ONE,\n [EngineCapability.SMS]: EngineCapabilityResolutionMode.SELECT_ONE,\n [EngineCapability.AI_LLM]: EngineCapabilityResolutionMode.SELECT_ONE,\n [EngineCapability.AI_IMAGE_GENERATION]: EngineCapabilityResolutionMode.SELECT_ONE,\n // Embeddings are substitutable, not additive: one provider serves a vector space, and writing\n // the same chunk through two providers would produce two incompatible spaces, not redundancy.\n [EngineCapability.AI_EMBEDDINGS]: EngineCapabilityResolutionMode.SELECT_ONE,\n // Extraction is substitutable, not additive: one provider reads a document, and running the\n // same bytes through two OCR services would produce two divergent transcriptions of one page\n // with no principled way to merge them — plus a second egress of the same private content.\n [EngineCapability.AI_DOCUMENT_EXTRACTION]: EngineCapabilityResolutionMode.SELECT_ONE,\n // One agent per task, and emphatically not fan-out: two coding agents given the same task\n // against the same worktree do not produce redundancy, they produce a merge conflict nobody\n // asked for — and the change attribution that follows a run could no longer say which agent\n // wrote which file.\n [EngineCapability.AI_CODING_AGENT]: EngineCapabilityResolutionMode.SELECT_ONE,\n [EngineCapability.FRONTEND_ERROR_MONITORING]: EngineCapabilityResolutionMode.SELECT_ONE,\n [EngineCapability.FRONTEND_PRODUCT_ANALYTICS]: EngineCapabilityResolutionMode.SELECT_ONE,\n [EngineCapability.LLM_OBSERVABILITY]: EngineCapabilityResolutionMode.SELECT_ONE,\n [EngineCapability.OBSERVABILITY_TELEMETRY]: EngineCapabilityResolutionMode.SELECT_ONE,\n};\n\n/**\n * The declared resolution mode for an engine capability. A TOTAL lookup — every\n * capability is explicitly classified in `ENGINE_CAPABILITY_RESOLUTION_MODE`\n * (no silent default).\n *\n * Consumers: the runtime registry (`ExternalProvidersRegistryBackendService`\n * — `FAN_OUT` uses the full provider list, `SELECT_ONE` uses the primary) and\n * the `defineSaaSProviders` validators (a `FAN_OUT` capability is validated by\n * declaration and rejects a `selection` entry).\n */\nexport function getEngineCapabilityResolutionMode(\n capability: EngineCapability,\n): EngineCapabilityResolutionMode {\n return ENGINE_CAPABILITY_RESOLUTION_MODE[capability];\n}\n"]}
@@ -28,6 +28,7 @@ export declare const AppConfiguration_FrontendBootstrapResponse_Schema: z.ZodObj
28
28
  displayName: z.ZodOptional<z.ZodString>;
29
29
  description: z.ZodOptional<z.ZodString>;
30
30
  version: z.ZodString;
31
+ applicationId: z.ZodOptional<z.ZodString>;
31
32
  }, z.core.$strip>;
32
33
  brandAssets: z.ZodOptional<z.ZodArray<z.ZodObject<{
33
34
  composition: z.ZodEnum<typeof import("..").BrandAssetComposition>;
@@ -1 +1 @@
1
- {"version":3,"file":"frontend-bootstrap.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/external-providers/frontend-bootstrap.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EACL,2BAA2B,EAC3B,4BAA4B,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,GAC5B,MAAM,0CAA0C,CAAC;AAGlD,eAAO,MAAM,iCAAiC;;;;;;;;;;;;;;iBAE5C,CAAC;AACH,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iCAAiC,CAAC,CAAC;AAE5F;;;;;GAKG;AACH,eAAO,MAAM,iDAAiD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAG1D,CAAC;AACL,MAAM,MAAM,0CAA0C,GAAG,CAAC,CAAC,KAAK,CAC9D,OAAO,iDAAiD,CACzD,CAAC"}
1
+ {"version":3,"file":"frontend-bootstrap.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/external-providers/frontend-bootstrap.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EACL,2BAA2B,EAC3B,4BAA4B,EAC5B,KAAK,qBAAqB,EAC1B,KAAK,sBAAsB,GAC5B,MAAM,0CAA0C,CAAC;AAGlD,eAAO,MAAM,iCAAiC;;;;;;;;;;;;;;iBAE5C,CAAC;AACH,MAAM,MAAM,2BAA2B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iCAAiC,CAAC,CAAC;AAE5F;;;;;GAKG;AACH,eAAO,MAAM,iDAAiD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBAG1D,CAAC;AACL,MAAM,MAAM,0CAA0C,GAAG,CAAC,CAAC,KAAK,CAC9D,OAAO,iDAAiD,CACzD,CAAC"}
@@ -47,9 +47,10 @@ export declare const BUILTIN_PROVIDER_CAPABILITY: {
47
47
  * a read of a PDF's existing text layer. Maps to `EngineCapability.AI_DOCUMENT_EXTRACTION`.
48
48
  *
49
49
  * A NEW token was genuinely required rather than convenient: `IMAGE_GENERATION` is an OUTPUT
50
- * capability (text → image), and `EngineCapability.DOCUMENT_GENERATION` is PDF *generation*,
51
- * which is this capability's exact opposite. Nothing in the existing vocabulary claimed the
52
- * document-INPUT slot.
50
+ * capability (text → image), and PDF *generation* — the `pdfTemplates` surface — is this
51
+ * capability's exact opposite. Nothing in the existing vocabulary claimed the document-INPUT
52
+ * slot. (This paragraph used to name `EngineCapability.DOCUMENT_GENERATION`; that member was
53
+ * withdrawn because no provider capability could fill it.)
53
54
  *
54
55
  * Distinct from `LLM_CHAT` even where a vendor serves both from one API key: the work is
55
56
  * different (a page-layout model, billed per page, with no sampling parameters), and fusing
@@ -1 +1 @@
1
- {"version":3,"file":"provider-capability.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/external-providers/provider-capability.shared.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;;;GASG;AACH,eAAO,MAAM,2BAA2B;;;;IAItC;;;;;;;;OAQG;;;IAGH,sEAAsE;;;;IAItE;;;;;;;;;;;;;OAaG;;IAEH;;;;;;;;;;OAUG;;;;;;;;IAQH;;;;;OAKG;;IAEH;;;;;OAKG;;IAEH;;;;;;;OAOG;;CAEK,CAAC;AACX,+DAA+D;AAE/D,MAAM,MAAM,yBAAyB,GACnC,CAAC,OAAO,2BAA2B,CAAC,CAAC,MAAM,OAAO,2BAA2B,CAAC,CAAC;AAEjF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,6BAA6B;CAAG;AAEjD;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAC1B,yBAAyB,GACzB,MAAM,6BAA6B,CAAC"}
1
+ {"version":3,"file":"provider-capability.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/external-providers/provider-capability.shared.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;;;GASG;AACH,eAAO,MAAM,2BAA2B;;;;IAItC;;;;;;;;OAQG;;;IAGH,sEAAsE;;;;IAItE;;;;;;;;;;;;;;OAcG;;IAEH;;;;;;;;;;OAUG;;;;;;;;IAQH;;;;;OAKG;;IAEH;;;;;OAKG;;IAEH;;;;;;;OAOG;;CAEK,CAAC;AACX,+DAA+D;AAE/D,MAAM,MAAM,yBAAyB,GACnC,CAAC,OAAO,2BAA2B,CAAC,CAAC,MAAM,OAAO,2BAA2B,CAAC,CAAC;AAEjF;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,MAAM,WAAW,6BAA6B;CAAG;AAEjD;;;;GAIG;AACH,MAAM,MAAM,kBAAkB,GAC1B,yBAAyB,GACzB,MAAM,6BAA6B,CAAC"}
@@ -47,9 +47,10 @@ export const BUILTIN_PROVIDER_CAPABILITY = {
47
47
  * a read of a PDF's existing text layer. Maps to `EngineCapability.AI_DOCUMENT_EXTRACTION`.
48
48
  *
49
49
  * A NEW token was genuinely required rather than convenient: `IMAGE_GENERATION` is an OUTPUT
50
- * capability (text → image), and `EngineCapability.DOCUMENT_GENERATION` is PDF *generation*,
51
- * which is this capability's exact opposite. Nothing in the existing vocabulary claimed the
52
- * document-INPUT slot.
50
+ * capability (text → image), and PDF *generation* — the `pdfTemplates` surface — is this
51
+ * capability's exact opposite. Nothing in the existing vocabulary claimed the document-INPUT
52
+ * slot. (This paragraph used to name `EngineCapability.DOCUMENT_GENERATION`; that member was
53
+ * withdrawn because no provider capability could fill it.)
53
54
  *
54
55
  * Distinct from `LLM_CHAT` even where a vendor serves both from one API key: the work is
55
56
  * different (a page-layout model, billed per page, with no sampling parameters), and fusing
@@ -1 +1 @@
1
- {"version":3,"file":"provider-capability.shared.schemas.js","sourceRoot":"","sources":["../../../../src/external-providers/provider-capability.shared.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG;IACzC,mBAAmB,EAAE,qBAAqB;IAC1C,eAAe,EAAE,iBAAiB;IAClC,GAAG,EAAE,KAAK;IACV;;;;;;;;OAQG;IACH,OAAO,EAAE,SAAS;IAClB,UAAU,EAAE,YAAY;IACxB,sEAAsE;IACtE,QAAQ,EAAE,UAAU;IACpB,QAAQ,EAAE,UAAU;IACpB,cAAc,EAAE,gBAAgB;IAChC;;;;;;;;;;;;;OAaG;IACH,wBAAwB,EAAE,0BAA0B;IACpD;;;;;;;;;;OAUG;IACH,YAAY,EAAE,cAAc;IAC5B,gBAAgB,EAAE,kBAAkB;IACpC,yBAAyB,EAAE,2BAA2B;IACtD,0BAA0B,EAAE,4BAA4B;IACxD,eAAe,EAAE,iBAAiB;IAClC,oBAAoB,EAAE,sBAAsB;IAC5C,gBAAgB,EAAE,kBAAkB;IACpC;;;;;OAKG;IACH,iBAAiB,EAAE,mBAAmB;IACtC;;;;;OAKG;IACH,uBAAuB,EAAE,yBAAyB;IAClD;;;;;;;OAOG;IACH,sBAAsB,EAAE,wBAAwB;CACxC,CAAC","sourcesContent":["/**\n * `ProviderCapability` — open, app-extensible enum of standardized\n * behaviors that providers implement.\n *\n * Distinct from `EngineCapability` (closed, engine-defined slots that\n * may require fulfillment). See the analysis glossary in\n * `.cursor/plans/provider-registration-refactor-draft-analysis.md` §14\n * for the full naming rationale; this file is the canonical Phase-0\n * authoring surface called out in §Phase 0.2 of the implementation\n * plan.\n *\n * Built-in values use SCREAMING_SNAKE_CASE; app-augmented values SHOULD\n * use kebab-case + domain prefix (e.g. `'live-chat-handoff'`,\n * `'search-index'`). The two namespaces never collide by construction.\n */\n\n/** @wildo_source:part:start saas.models.provider-capabilities facet:kind:api facet:audience:app-developer\n *\n * Built-in provider capabilities shipped by the framework.\n *\n * Authoring rule: keep this list narrow and stable. Adding a new\n * built-in capability is a framework-level decision (it implies the\n * engine knows how to consume the capability via a transformer or a\n * platform binding); apps that need a one-off capability MUST extend\n * via `AppCustomProviderCapabilities` instead.\n */\nexport const BUILTIN_PROVIDER_CAPABILITY = {\n EMAIL_TRANSACTIONAL: 'EMAIL_TRANSACTIONAL',\n EMAIL_MARKETING: 'EMAIL_MARKETING',\n SMS: 'SMS',\n /**\n * Single billing-engagement capability covering everything from\n * Checkout-style hosted flows to first-party PaymentIntent flows.\n * Webhook delivery is NOT a separate capability — it is modelled at\n * the protocol layer (e.g. Stripe declares both a `BILLING_PROVIDER`\n * and a `WEBHOOK_ORIGINATOR` protocol but a single `BILLING`\n * capability). This 1:1 matches the billing slot from the older\n * external connector transformer vocabulary.\n */\n BILLING: 'BILLING',\n SSO_OAUTH2: 'SSO_OAUTH2',\n /** Reserved for future SAML-based SSO providers (none ship today). */\n SSO_SAML: 'SSO_SAML',\n LLM_CHAT: 'LLM_CHAT',\n LLM_EMBEDDINGS: 'LLM_EMBEDDINGS',\n /**\n * Provider turns DOCUMENT BYTES into text — OCR over scans and photographs of pages, not merely\n * a read of a PDF's existing text layer. Maps to `EngineCapability.AI_DOCUMENT_EXTRACTION`.\n *\n * A NEW token was genuinely required rather than convenient: `IMAGE_GENERATION` is an OUTPUT\n * capability (text → image), and `EngineCapability.DOCUMENT_GENERATION` is PDF *generation*,\n * which is this capability's exact opposite. Nothing in the existing vocabulary claimed the\n * document-INPUT slot.\n *\n * Distinct from `LLM_CHAT` even where a vendor serves both from one API key: the work is\n * different (a page-layout model, billed per page, with no sampling parameters), and fusing\n * them would make the OCR provider unselectable independently of the chat provider — the exact\n * defect that splitting `AI_EMBEDDINGS` out of `AI_LLM` existed to fix.\n */\n DOCUMENT_TEXT_EXTRACTION: 'DOCUMENT_TEXT_EXTRACTION',\n /**\n * Provider ships an autonomous CODING AGENT: a process that reads and writes\n * a workspace, runs commands, and requests authorisation, reachable over the\n * Agent Client Protocol.\n *\n * Distinct from `LLM_CHAT` because the WORK is\n * different, not merely its transport. A chat model returns text for a caller\n * to act on; a coding agent acts, and the resulting obligations — permission\n * decisions, mutation scope, change attribution, verification — have no\n * counterpart in a completion call.\n */\n CODING_AGENT: 'CODING_AGENT',\n IMAGE_GENERATION: 'IMAGE_GENERATION',\n FRONTEND_ERROR_MONITORING: 'FRONTEND_ERROR_MONITORING',\n FRONTEND_PRODUCT_ANALYTICS: 'FRONTEND_PRODUCT_ANALYTICS',\n FRONTEND_SEARCH: 'FRONTEND_SEARCH',\n FRONTEND_FILE_PICKER: 'FRONTEND_FILE_PICKER',\n FRONTEND_CAPTCHA: 'FRONTEND_CAPTCHA',\n /**\n * Backend LLM-call observability — a provider that ingests per-`invokeAgent`\n * generation traces (model / tokens / cost / latency), e.g. PostHog\n * `$ai_generation`. Maps to `EngineCapability.LLM_OBSERVABILITY`. The engine\n * consumes it via the `AgentCallTraceSink` (not a request/response transformer).\n */\n LLM_OBSERVABILITY: 'LLM_OBSERVABILITY',\n /**\n * Operational-telemetry sink — a provider that ingests OpenTelemetry traces,\n * metrics, and logs over OTLP (e.g. BetterStack). Maps to\n * `EngineCapability.OBSERVABILITY_TELEMETRY`. Consumed by the OTel SDK preload\n * (env-var-driven), NOT a request/response transformer or a DI sink.\n */\n OBSERVABILITY_TELEMETRY: 'OBSERVABILITY_TELEMETRY',\n /**\n * Audit-log sink — a provider that stores or forwards compliance audit\n * events (who-did-what-when), e.g. immudb (tamper-evident) or a SIEM\n * webhook. Maps to `EngineCapability.COMPLIANCE_AUDIT_TRAIL`, a FAN_OUT\n * capability: every declared audit provider receives every event (see\n * `getEngineCapabilityResolutionMode`). The engine consumes it via the\n * `AuditLogSink` DI fan-out, layered on the always-on database audit store.\n */\n COMPLIANCE_AUDIT_TRAIL: 'COMPLIANCE_AUDIT_TRAIL',\n} as const;\n/** @wildo_source:part:end saas.models.provider-capabilities */\n\nexport type BuiltinProviderCapability =\n (typeof BUILTIN_PROVIDER_CAPABILITY)[keyof typeof BUILTIN_PROVIDER_CAPABILITY];\n\n/**\n * Open extension point — apps augment via TypeScript module augmentation\n * inside their `wildo.saas.config.ts`. See analysis §10 Q2 for the\n * design decision (no `app.d.ts` file; declaration merging happens\n * inline in the saas config so the surface is co-located with the\n * authored configuration).\n *\n * Example app-side augmentation:\n *\n * ```ts\n * declare module '@wildo-ai/saas-models' {\n * interface AppCustomProviderCapabilities {\n * 'live-chat-handoff': true;\n * 'search-index': true;\n * }\n * }\n * ```\n *\n * Phase 3.d (per the implementation plan) wires this augmentation point\n * into `BackendProviderRegistry.getProvidersByProviderCapability()` so\n * apps can register and resolve custom capabilities in a fully\n * type-checked way. In Phase 0 the interface is intentionally empty.\n */\nexport interface AppCustomProviderCapabilities {}\n\n/**\n * Union of every possible provider capability — the closed built-in set\n * plus any app-side augmentations. Consumers (registries, transformers,\n * lock-file digests) accept this union.\n */\nexport type ProviderCapability =\n | BuiltinProviderCapability\n | keyof AppCustomProviderCapabilities;\n"]}
1
+ {"version":3,"file":"provider-capability.shared.schemas.js","sourceRoot":"","sources":["../../../../src/external-providers/provider-capability.shared.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG;IACzC,mBAAmB,EAAE,qBAAqB;IAC1C,eAAe,EAAE,iBAAiB;IAClC,GAAG,EAAE,KAAK;IACV;;;;;;;;OAQG;IACH,OAAO,EAAE,SAAS;IAClB,UAAU,EAAE,YAAY;IACxB,sEAAsE;IACtE,QAAQ,EAAE,UAAU;IACpB,QAAQ,EAAE,UAAU;IACpB,cAAc,EAAE,gBAAgB;IAChC;;;;;;;;;;;;;;OAcG;IACH,wBAAwB,EAAE,0BAA0B;IACpD;;;;;;;;;;OAUG;IACH,YAAY,EAAE,cAAc;IAC5B,gBAAgB,EAAE,kBAAkB;IACpC,yBAAyB,EAAE,2BAA2B;IACtD,0BAA0B,EAAE,4BAA4B;IACxD,eAAe,EAAE,iBAAiB;IAClC,oBAAoB,EAAE,sBAAsB;IAC5C,gBAAgB,EAAE,kBAAkB;IACpC;;;;;OAKG;IACH,iBAAiB,EAAE,mBAAmB;IACtC;;;;;OAKG;IACH,uBAAuB,EAAE,yBAAyB;IAClD;;;;;;;OAOG;IACH,sBAAsB,EAAE,wBAAwB;CACxC,CAAC","sourcesContent":["/**\n * `ProviderCapability` — open, app-extensible enum of standardized\n * behaviors that providers implement.\n *\n * Distinct from `EngineCapability` (closed, engine-defined slots that\n * may require fulfillment). See the analysis glossary in\n * `.cursor/plans/provider-registration-refactor-draft-analysis.md` §14\n * for the full naming rationale; this file is the canonical Phase-0\n * authoring surface called out in §Phase 0.2 of the implementation\n * plan.\n *\n * Built-in values use SCREAMING_SNAKE_CASE; app-augmented values SHOULD\n * use kebab-case + domain prefix (e.g. `'live-chat-handoff'`,\n * `'search-index'`). The two namespaces never collide by construction.\n */\n\n/** @wildo_source:part:start saas.models.provider-capabilities facet:kind:api facet:audience:app-developer\n *\n * Built-in provider capabilities shipped by the framework.\n *\n * Authoring rule: keep this list narrow and stable. Adding a new\n * built-in capability is a framework-level decision (it implies the\n * engine knows how to consume the capability via a transformer or a\n * platform binding); apps that need a one-off capability MUST extend\n * via `AppCustomProviderCapabilities` instead.\n */\nexport const BUILTIN_PROVIDER_CAPABILITY = {\n EMAIL_TRANSACTIONAL: 'EMAIL_TRANSACTIONAL',\n EMAIL_MARKETING: 'EMAIL_MARKETING',\n SMS: 'SMS',\n /**\n * Single billing-engagement capability covering everything from\n * Checkout-style hosted flows to first-party PaymentIntent flows.\n * Webhook delivery is NOT a separate capability — it is modelled at\n * the protocol layer (e.g. Stripe declares both a `BILLING_PROVIDER`\n * and a `WEBHOOK_ORIGINATOR` protocol but a single `BILLING`\n * capability). This 1:1 matches the billing slot from the older\n * external connector transformer vocabulary.\n */\n BILLING: 'BILLING',\n SSO_OAUTH2: 'SSO_OAUTH2',\n /** Reserved for future SAML-based SSO providers (none ship today). */\n SSO_SAML: 'SSO_SAML',\n LLM_CHAT: 'LLM_CHAT',\n LLM_EMBEDDINGS: 'LLM_EMBEDDINGS',\n /**\n * Provider turns DOCUMENT BYTES into text — OCR over scans and photographs of pages, not merely\n * a read of a PDF's existing text layer. Maps to `EngineCapability.AI_DOCUMENT_EXTRACTION`.\n *\n * A NEW token was genuinely required rather than convenient: `IMAGE_GENERATION` is an OUTPUT\n * capability (text → image), and PDF *generation* the `pdfTemplates` surface — is this\n * capability's exact opposite. Nothing in the existing vocabulary claimed the document-INPUT\n * slot. (This paragraph used to name `EngineCapability.DOCUMENT_GENERATION`; that member was\n * withdrawn because no provider capability could fill it.)\n *\n * Distinct from `LLM_CHAT` even where a vendor serves both from one API key: the work is\n * different (a page-layout model, billed per page, with no sampling parameters), and fusing\n * them would make the OCR provider unselectable independently of the chat provider — the exact\n * defect that splitting `AI_EMBEDDINGS` out of `AI_LLM` existed to fix.\n */\n DOCUMENT_TEXT_EXTRACTION: 'DOCUMENT_TEXT_EXTRACTION',\n /**\n * Provider ships an autonomous CODING AGENT: a process that reads and writes\n * a workspace, runs commands, and requests authorisation, reachable over the\n * Agent Client Protocol.\n *\n * Distinct from `LLM_CHAT` because the WORK is\n * different, not merely its transport. A chat model returns text for a caller\n * to act on; a coding agent acts, and the resulting obligations — permission\n * decisions, mutation scope, change attribution, verification — have no\n * counterpart in a completion call.\n */\n CODING_AGENT: 'CODING_AGENT',\n IMAGE_GENERATION: 'IMAGE_GENERATION',\n FRONTEND_ERROR_MONITORING: 'FRONTEND_ERROR_MONITORING',\n FRONTEND_PRODUCT_ANALYTICS: 'FRONTEND_PRODUCT_ANALYTICS',\n FRONTEND_SEARCH: 'FRONTEND_SEARCH',\n FRONTEND_FILE_PICKER: 'FRONTEND_FILE_PICKER',\n FRONTEND_CAPTCHA: 'FRONTEND_CAPTCHA',\n /**\n * Backend LLM-call observability — a provider that ingests per-`invokeAgent`\n * generation traces (model / tokens / cost / latency), e.g. PostHog\n * `$ai_generation`. Maps to `EngineCapability.LLM_OBSERVABILITY`. The engine\n * consumes it via the `AgentCallTraceSink` (not a request/response transformer).\n */\n LLM_OBSERVABILITY: 'LLM_OBSERVABILITY',\n /**\n * Operational-telemetry sink — a provider that ingests OpenTelemetry traces,\n * metrics, and logs over OTLP (e.g. BetterStack). Maps to\n * `EngineCapability.OBSERVABILITY_TELEMETRY`. Consumed by the OTel SDK preload\n * (env-var-driven), NOT a request/response transformer or a DI sink.\n */\n OBSERVABILITY_TELEMETRY: 'OBSERVABILITY_TELEMETRY',\n /**\n * Audit-log sink — a provider that stores or forwards compliance audit\n * events (who-did-what-when), e.g. immudb (tamper-evident) or a SIEM\n * webhook. Maps to `EngineCapability.COMPLIANCE_AUDIT_TRAIL`, a FAN_OUT\n * capability: every declared audit provider receives every event (see\n * `getEngineCapabilityResolutionMode`). The engine consumes it via the\n * `AuditLogSink` DI fan-out, layered on the always-on database audit store.\n */\n COMPLIANCE_AUDIT_TRAIL: 'COMPLIANCE_AUDIT_TRAIL',\n} as const;\n/** @wildo_source:part:end saas.models.provider-capabilities */\n\nexport type BuiltinProviderCapability =\n (typeof BUILTIN_PROVIDER_CAPABILITY)[keyof typeof BUILTIN_PROVIDER_CAPABILITY];\n\n/**\n * Open extension point — apps augment via TypeScript module augmentation\n * inside their `wildo.saas.config.ts`. See analysis §10 Q2 for the\n * design decision (no `app.d.ts` file; declaration merging happens\n * inline in the saas config so the surface is co-located with the\n * authored configuration).\n *\n * Example app-side augmentation:\n *\n * ```ts\n * declare module '@wildo-ai/saas-models' {\n * interface AppCustomProviderCapabilities {\n * 'live-chat-handoff': true;\n * 'search-index': true;\n * }\n * }\n * ```\n *\n * Phase 3.d (per the implementation plan) wires this augmentation point\n * into `BackendProviderRegistry.getProvidersByProviderCapability()` so\n * apps can register and resolve custom capabilities in a fully\n * type-checked way. In Phase 0 the interface is intentionally empty.\n */\nexport interface AppCustomProviderCapabilities {}\n\n/**\n * Union of every possible provider capability — the closed built-in set\n * plus any app-side augmentations. Consumers (registries, transformers,\n * lock-file digests) accept this union.\n */\nexport type ProviderCapability =\n | BuiltinProviderCapability\n | keyof AppCustomProviderCapabilities;\n"]}
@@ -7,7 +7,7 @@
7
7
  */
8
8
  import { CoreResourceOperation } from '../resources/resources.shared.core.definitions';
9
9
  import { ResourceRelationship } from '../resources/resources.shared.schemas';
10
- type UserFeaturesCoreOperations = CoreResourceOperation.CREATE | CoreResourceOperation.READ | CoreResourceOperation.SEARCH | CoreResourceOperation.UPDATE | CoreResourceOperation.DELETE;
10
+ type UserFeaturesCoreOperations = CoreResourceOperation.CREATE | CoreResourceOperation.READ | CoreResourceOperation.LIST | CoreResourceOperation.UPDATE_MANY | CoreResourceOperation.SEARCH | CoreResourceOperation.UPDATE | CoreResourceOperation.DELETE;
11
11
  export declare const userFeaturesResourceConfiguration_InitializationFactory: (resourcesRelationships: ResourceRelationship[]) => import("..").ResourceConfiguration<Record<string, never>, UserFeaturesCoreOperations, import("zod").ZodObject<{
12
12
  features: import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<import("zod").ZodDefault<import("zod").ZodArray<import("zod").ZodUnion<readonly [import("zod").ZodEnum<typeof import("..").CoreFeature>, import("zod").ZodString]>>>>>;
13
13
  limits: import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<import("@wildo-ai/zod-decorators").DecoratedPrimitiveZodType<import("zod").ZodDefault<import("zod").ZodRecord<import("zod").ZodString, import("zod").ZodNumber>>>>;
@@ -1 +1 @@
1
- {"version":3,"file":"user-features.shared.resources-config.schemas.d.ts","sourceRoot":"","sources":["../../../../src/features/user-features.shared.resources-config.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAAE,qBAAqB,EAAE,MAAM,gDAAgD,CAAC;AACvF,OAAO,EAA8B,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAQzG,KAAK,0BAA0B,GAC3B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,IAAI,GAC1B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,CAAC;AAEjC,eAAO,MAAM,uDAAuD,GAAI,wBAAwB,oBAAoB,EAAE;;;;;;;;iCA6FpH,CAAC"}
1
+ {"version":3,"file":"user-features.shared.resources-config.schemas.d.ts","sourceRoot":"","sources":["../../../../src/features/user-features.shared.resources-config.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAAE,qBAAqB,EAAE,MAAM,gDAAgD,CAAC;AACvF,OAAO,EAA8B,oBAAoB,EAAE,MAAM,uCAAuC,CAAC;AAQzG,KAAK,0BAA0B,GAC3B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,IAAI,GAC1B,qBAAqB,CAAC,IAAI,GAC1B,qBAAqB,CAAC,WAAW,GACjC,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,GAC5B,qBAAqB,CAAC,MAAM,CAAC;AAEjC,eAAO,MAAM,uDAAuD,GAAI,wBAAwB,oBAAoB,EAAE;;;;;;;;iCA+IpH,CAAC"}
@@ -6,6 +6,7 @@
6
6
  * Uses ScopeFeaturesWithOverridesSchema as mainSchema (same pattern as org features).
7
7
  */
8
8
  import { ScopeFeaturesWithOverridesSchema } from './scope-features.shared.schemas.js';
9
+ import { ErasureRetentionMode, ResourceDataSubjectKind } from '../compliance/privacy/impersonalization.shared.schemas.js';
9
10
  import { CoreResourceOperation } from '../resources/resources.shared.core.definitions.js';
10
11
  import { ResourceOperationRiskLevel } from '../resources/resources.shared.schemas.js';
11
12
  import { CoreResourceType, coreResourceShared_FieldIdentifier } from '../resources/resources.shared.core.definitions.js';
@@ -23,11 +24,31 @@ export const userFeaturesResourceConfiguration_InitializationFactory = (resource
23
24
  /** Subject-export disclosure. The subject's own data. Secrets and backend-only values are withheld by the export's security floor regardless of this grant. */
24
25
  systemAccessPolicy: { exportSubject: ResourceSystemAccessMode.ALLOWED },
25
26
  portabilityPolicy: { defaultProvenance: DataPortabilityProvenance.DERIVED },
27
+ /**
28
+ * Subject erasure RETAINS this row and scrubs nothing, because there is nothing here to scrub.
29
+ *
30
+ * `RETAIN_ONLY` is a positive assertion, not a default: this resource holds feature toggles, added
31
+ * and removed feature keys, and numeric limit overrides. Its only link to a person is the scope
32
+ * foreign key, which the never-scrub floor protects in every mode. Declaring the mode is what lets a
33
+ * notice say what erasure does to these rows instead of reporting them as undeclared.
34
+ *
35
+ * The assertion is CHECKED: the factory refuses `RETAIN_ONLY` if any field declares an impersonalize
36
+ * treatment, because a treatment that would never run is a config claiming something the runtime
37
+ * would not honour.
38
+ */
39
+ retentionPolicy: {
40
+ mode: ErasureRetentionMode.RETAIN_ONLY,
41
+ },
42
+ /** The subject is the person whose features these are, reached through the scope key. */
43
+ dataSubjectPolicy: { kind: ResourceDataSubjectKind.SELF_PRINCIPAL },
26
44
  coreOperations: [
27
45
  CoreResourceOperation.CREATE,
28
46
  CoreResourceOperation.READ,
29
47
  CoreResourceOperation.SEARCH,
30
48
  CoreResourceOperation.UPDATE,
49
+ // Route-less; `retentionPolicy` requires READ + LIST + UPDATE_MANY (see the variants).
50
+ CoreResourceOperation.LIST,
51
+ CoreResourceOperation.UPDATE_MANY,
31
52
  // DELETE is REPOSITORY_ONLY (no HTTP route): the scope-features ledger is not
32
53
  // API-deletable, but the composition `onParentDelete` cascade must physically
33
54
  // delete the row when its owning user is deleted. Without a DELETE op the cascade
@@ -37,6 +58,33 @@ export const userFeaturesResourceConfiguration_InitializationFactory = (resource
37
58
  ],
38
59
  customOperation: {},
39
60
  operationsConfiguration: {
61
+ /*
62
+ * Route-less retention plumbing — INTERNAL_CALL registers no route. Not REPOSITORY_ONLY: the
63
+ * retention primitives resolve through `getServiceOperationPathDefault`, which excludes it, so
64
+ * that spelling passes the boot guard and fails when an erasure runs. LIST is LOW because a
65
+ * read-shaped operation may not claim the HIGH/CRITICAL band — that band carries an audit-emission
66
+ * obligation, checked over the real engine catalogue.
67
+ */
68
+ [CoreResourceOperation.LIST]: {
69
+ variants: [
70
+ {
71
+ variantType: ResourceOperationVariantType.INTERNAL_CALL,
72
+ isDefault: true,
73
+ roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],
74
+ riskLevel: ResourceOperationRiskLevel.LOW,
75
+ },
76
+ ],
77
+ },
78
+ [CoreResourceOperation.UPDATE_MANY]: {
79
+ variants: [
80
+ {
81
+ variantType: ResourceOperationVariantType.INTERNAL_CALL,
82
+ isDefault: true,
83
+ roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],
84
+ riskLevel: ResourceOperationRiskLevel.CRITICAL,
85
+ },
86
+ ],
87
+ },
40
88
  [CoreResourceOperation.CREATE]: {
41
89
  variants: [
42
90
  {
@@ -1 +1 @@
1
- {"version":3,"file":"user-features.shared.resources-config.schemas.js","sourceRoot":"","sources":["../../../../src/features/user-features.shared.resources-config.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * User Features Shared Resource Configuration\n *\n * Resource configuration for user-level feature management.\n * Controls which features are available to individual users (overrides/additions).\n * Uses ScopeFeaturesWithOverridesSchema as mainSchema (same pattern as org features).\n */\n\nimport { ScopeFeaturesWithOverridesSchema } from './scope-features.shared.schemas';\n\nimport { CoreResourceOperation } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationRiskLevel, ResourceRelationship } from '../resources/resources.shared.schemas';\nimport { CoreResourceType, coreResourceShared_FieldIdentifier } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationVariantType } from '../resources/resources.shared.schemas';\nimport { createResourceConfiguration_Initialization } from '../resources/resources-config.shared.factory';\nimport { CORE_APP_ROLES, CORE_ORG_ROLES } from '../security/authorizations/roles.shared.schemas';\nimport { ResourceSystemAccessMode } from '../resources/resources-config.shared.schemas';\nimport { DataPortabilityProvenance } from '../compliance/privacy/subject-export.shared.schemas';\n\ntype UserFeaturesCoreOperations =\n | CoreResourceOperation.CREATE\n | CoreResourceOperation.READ\n | CoreResourceOperation.SEARCH\n | CoreResourceOperation.UPDATE\n | CoreResourceOperation.DELETE;\n\nexport const userFeaturesResourceConfiguration_InitializationFactory = (resourcesRelationships: ResourceRelationship[]) => createResourceConfiguration_Initialization<\n Record<string, never>,\n UserFeaturesCoreOperations,\n typeof ScopeFeaturesWithOverridesSchema\n>({\n mainSchema: ScopeFeaturesWithOverridesSchema,\n resourceIdentifier: CoreResourceType.USER_FEATURES,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.USER_FEATURES],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true,\n\n /** Subject-export disclosure. The subject's own data. Secrets and backend-only values are withheld by the export's security floor regardless of this grant. */\n systemAccessPolicy: { exportSubject: ResourceSystemAccessMode.ALLOWED },\n portabilityPolicy: { defaultProvenance: DataPortabilityProvenance.DERIVED },\n\n coreOperations: [\n CoreResourceOperation.CREATE,\n CoreResourceOperation.READ,\n CoreResourceOperation.SEARCH,\n CoreResourceOperation.UPDATE,\n // DELETE is REPOSITORY_ONLY (no HTTP route): the scope-features ledger is not\n // API-deletable, but the composition `onParentDelete` cascade must physically\n // delete the row when its owning user is deleted. Without a DELETE op the cascade\n // (`deleteChildrenImmediate`) throws ErrorType.CONFIGURATION on any user that has a\n // features row. See .claude/plans/composition-oncreate-lifecycle.md (FEATURES wave).\n CoreResourceOperation.DELETE,\n ],\n\n customOperation: {} as Record<string, never>,\n\n operationsConfiguration: {\n [CoreResourceOperation.CREATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n }\n ],\n },\n\n [CoreResourceOperation.READ]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ]\n },\n\n [CoreResourceOperation.SEARCH]: {\n variants: [{\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n isSearchable: false,\n searchableFields: [],\n searchableOptions: { caseSensitive: false, fullMatchOnly: false },\n filterFields: {},\n sortFields: [],\n maxPaginatedResultPerPageLimit: 50,\n }],\n },\n\n [CoreResourceOperation.UPDATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.HIGH,\n requestDto: ScopeFeaturesWithOverridesSchema.partial(),\n }\n ],\n },\n\n // Internal-only (REPOSITORY_ONLY): powers the composition onParentDelete cascade,\n // not a public API surface — the ledger is reset, never DELETEd, over HTTP.\n [CoreResourceOperation.DELETE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.HIGH,\n }\n ],\n },\n },\n});\n"]}
1
+ {"version":3,"file":"user-features.shared.resources-config.schemas.js","sourceRoot":"","sources":["../../../../src/features/user-features.shared.resources-config.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * User Features Shared Resource Configuration\n *\n * Resource configuration for user-level feature management.\n * Controls which features are available to individual users (overrides/additions).\n * Uses ScopeFeaturesWithOverridesSchema as mainSchema (same pattern as org features).\n */\n\nimport { ScopeFeaturesWithOverridesSchema } from './scope-features.shared.schemas';\nimport { ErasureRetentionMode, ResourceDataSubjectKind } from '../compliance/privacy/impersonalization.shared.schemas';\n\nimport { CoreResourceOperation } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationRiskLevel, ResourceRelationship } from '../resources/resources.shared.schemas';\nimport { CoreResourceType, coreResourceShared_FieldIdentifier } from '../resources/resources.shared.core.definitions';\nimport { ResourceOperationVariantType } from '../resources/resources.shared.schemas';\nimport { createResourceConfiguration_Initialization } from '../resources/resources-config.shared.factory';\nimport { CORE_APP_ROLES, CORE_ORG_ROLES } from '../security/authorizations/roles.shared.schemas';\nimport { ResourceSystemAccessMode } from '../resources/resources-config.shared.schemas';\nimport { DataPortabilityProvenance } from '../compliance/privacy/subject-export.shared.schemas';\n\ntype UserFeaturesCoreOperations =\n | CoreResourceOperation.CREATE\n | CoreResourceOperation.READ\n | CoreResourceOperation.LIST\n | CoreResourceOperation.UPDATE_MANY\n | CoreResourceOperation.SEARCH\n | CoreResourceOperation.UPDATE\n | CoreResourceOperation.DELETE;\n\nexport const userFeaturesResourceConfiguration_InitializationFactory = (resourcesRelationships: ResourceRelationship[]) => createResourceConfiguration_Initialization<\n Record<string, never>,\n UserFeaturesCoreOperations,\n typeof ScopeFeaturesWithOverridesSchema\n>({\n mainSchema: ScopeFeaturesWithOverridesSchema,\n resourceIdentifier: CoreResourceType.USER_FEATURES,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.USER_FEATURES],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true,\n\n /** Subject-export disclosure. The subject's own data. Secrets and backend-only values are withheld by the export's security floor regardless of this grant. */\n systemAccessPolicy: { exportSubject: ResourceSystemAccessMode.ALLOWED },\n portabilityPolicy: { defaultProvenance: DataPortabilityProvenance.DERIVED },\n\n\n /**\n * Subject erasure RETAINS this row and scrubs nothing, because there is nothing here to scrub.\n *\n * `RETAIN_ONLY` is a positive assertion, not a default: this resource holds feature toggles, added\n * and removed feature keys, and numeric limit overrides. Its only link to a person is the scope\n * foreign key, which the never-scrub floor protects in every mode. Declaring the mode is what lets a\n * notice say what erasure does to these rows instead of reporting them as undeclared.\n *\n * The assertion is CHECKED: the factory refuses `RETAIN_ONLY` if any field declares an impersonalize\n * treatment, because a treatment that would never run is a config claiming something the runtime\n * would not honour.\n */\n retentionPolicy: {\n mode: ErasureRetentionMode.RETAIN_ONLY,\n },\n\n /** The subject is the person whose features these are, reached through the scope key. */\n dataSubjectPolicy: { kind: ResourceDataSubjectKind.SELF_PRINCIPAL },\n\n coreOperations: [\n CoreResourceOperation.CREATE,\n CoreResourceOperation.READ,\n CoreResourceOperation.SEARCH,\n CoreResourceOperation.UPDATE,\n // Route-less; `retentionPolicy` requires READ + LIST + UPDATE_MANY (see the variants).\n CoreResourceOperation.LIST,\n CoreResourceOperation.UPDATE_MANY,\n // DELETE is REPOSITORY_ONLY (no HTTP route): the scope-features ledger is not\n // API-deletable, but the composition `onParentDelete` cascade must physically\n // delete the row when its owning user is deleted. Without a DELETE op the cascade\n // (`deleteChildrenImmediate`) throws ErrorType.CONFIGURATION on any user that has a\n // features row. See .claude/plans/composition-oncreate-lifecycle.md (FEATURES wave).\n CoreResourceOperation.DELETE,\n ],\n\n customOperation: {} as Record<string, never>,\n\n operationsConfiguration: {\n /*\n * Route-less retention plumbing — INTERNAL_CALL registers no route. Not REPOSITORY_ONLY: the\n * retention primitives resolve through `getServiceOperationPathDefault`, which excludes it, so\n * that spelling passes the boot guard and fails when an erasure runs. LIST is LOW because a\n * read-shaped operation may not claim the HIGH/CRITICAL band — that band carries an audit-emission\n * obligation, checked over the real engine catalogue.\n */\n [CoreResourceOperation.LIST]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.LOW,\n },\n ],\n },\n [CoreResourceOperation.UPDATE_MANY]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.CRITICAL,\n },\n ],\n },\n [CoreResourceOperation.CREATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.MEDIUM,\n }\n ],\n },\n\n [CoreResourceOperation.READ]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }\n ]\n },\n\n [CoreResourceOperation.SEARCH]: {\n variants: [{\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_ORG_ROLES.ORG_MEMBER],\n riskLevel: ResourceOperationRiskLevel.LOW,\n isSearchable: false,\n searchableFields: [],\n searchableOptions: { caseSensitive: false, fullMatchOnly: false },\n filterFields: {},\n sortFields: [],\n maxPaginatedResultPerPageLimit: 50,\n }],\n },\n\n [CoreResourceOperation.UPDATE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.HIGH,\n requestDto: ScopeFeaturesWithOverridesSchema.partial(),\n }\n ],\n },\n\n // Internal-only (REPOSITORY_ONLY): powers the composition onParentDelete cascade,\n // not a public API surface — the ledger is reset, never DELETEd, over HTTP.\n [CoreResourceOperation.DELETE]: {\n variants: [\n {\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.HIGH,\n }\n ],\n },\n },\n});\n"]}