@wildo-ai/saas-models 1.1.7 → 1.1.9

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 (882) hide show
  1. package/dist/esm/_inspect.d.ts.map +1 -1
  2. package/dist/esm/_inspect.js.map +1 -1
  3. package/dist/esm/applications/application-metadata.shared.resources-config.schemas.d.ts.map +1 -1
  4. package/dist/esm/applications/application-metadata.shared.resources-config.schemas.js.map +1 -1
  5. package/dist/esm/applications/application-subject.shared.schemas.d.ts.map +1 -1
  6. package/dist/esm/applications/application-subject.shared.schemas.js.map +1 -1
  7. package/dist/esm/applications/application-versions.shared.resources-config.schemas.d.ts.map +1 -1
  8. package/dist/esm/applications/application-versions.shared.resources-config.schemas.js.map +1 -1
  9. package/dist/esm/applications/applications-context.schemas.d.ts.map +1 -1
  10. package/dist/esm/applications/applications-context.schemas.js.map +1 -1
  11. package/dist/esm/applications/applications.shared.resources-config.schemas.d.ts.map +1 -1
  12. package/dist/esm/applications/applications.shared.resources-config.schemas.js.map +1 -1
  13. package/dist/esm/applications/applications.shared.schemas.d.ts.map +1 -1
  14. package/dist/esm/applications/applications.shared.schemas.js.map +1 -1
  15. package/dist/esm/billing/billing-account.shared.resources-config.schemas.d.ts.map +1 -1
  16. package/dist/esm/billing/billing-account.shared.resources-config.schemas.js.map +1 -1
  17. package/dist/esm/billing/billing-account.shared.schemas.d.ts.map +1 -1
  18. package/dist/esm/billing/billing-account.shared.schemas.js.map +1 -1
  19. package/dist/esm/billing/billing-configuration.shared.schemas.d.ts.map +1 -1
  20. package/dist/esm/billing/billing-configuration.shared.schemas.js.map +1 -1
  21. package/dist/esm/billing/billing-enums.shared.schemas.d.ts.map +1 -1
  22. package/dist/esm/billing/billing-enums.shared.schemas.js.map +1 -1
  23. package/dist/esm/billing/billing-types.shared.schemas.d.ts.map +1 -1
  24. package/dist/esm/billing/billing-types.shared.schemas.js.map +1 -1
  25. package/dist/esm/billing/credit-pool.shared.resources-config.schemas.d.ts.map +1 -1
  26. package/dist/esm/billing/credit-pool.shared.resources-config.schemas.js.map +1 -1
  27. package/dist/esm/billing/credit-pool.shared.schemas.d.ts.map +1 -1
  28. package/dist/esm/billing/credit-pool.shared.schemas.js.map +1 -1
  29. package/dist/esm/billing/invoice-ref.shared.resources-config.schemas.d.ts.map +1 -1
  30. package/dist/esm/billing/invoice-ref.shared.resources-config.schemas.js.map +1 -1
  31. package/dist/esm/billing/invoice-ref.shared.schemas.d.ts.map +1 -1
  32. package/dist/esm/billing/invoice-ref.shared.schemas.js.map +1 -1
  33. package/dist/esm/billing/price.shared.resources-config.schemas.d.ts.map +1 -1
  34. package/dist/esm/billing/price.shared.resources-config.schemas.js.map +1 -1
  35. package/dist/esm/billing/price.shared.schemas.d.ts.map +1 -1
  36. package/dist/esm/billing/price.shared.schemas.js.map +1 -1
  37. package/dist/esm/billing/product-behavior-policy.shared.schemas.d.ts.map +1 -1
  38. package/dist/esm/billing/product-behavior-policy.shared.schemas.js.map +1 -1
  39. package/dist/esm/billing/product-definition.shared.schemas.d.ts.map +1 -1
  40. package/dist/esm/billing/product-definition.shared.schemas.js.map +1 -1
  41. package/dist/esm/billing/product.shared.resources-config.schemas.d.ts.map +1 -1
  42. package/dist/esm/billing/product.shared.resources-config.schemas.js.map +1 -1
  43. package/dist/esm/billing/product.shared.schemas.d.ts.map +1 -1
  44. package/dist/esm/billing/product.shared.schemas.js.map +1 -1
  45. package/dist/esm/billing/promotions.shared.resources-config.schemas.d.ts.map +1 -1
  46. package/dist/esm/billing/promotions.shared.resources-config.schemas.js.map +1 -1
  47. package/dist/esm/billing/promotions.shared.schemas.d.ts.map +1 -1
  48. package/dist/esm/billing/promotions.shared.schemas.js.map +1 -1
  49. package/dist/esm/billing/public-pricing-catalog.shared.atoms.d.ts.map +1 -1
  50. package/dist/esm/billing/public-pricing-catalog.shared.atoms.js.map +1 -1
  51. package/dist/esm/billing/public-pricing-catalog.shared.d.ts.map +1 -1
  52. package/dist/esm/billing/public-pricing-catalog.shared.js.map +1 -1
  53. package/dist/esm/billing/referral-reward.shared.schemas.d.ts.map +1 -1
  54. package/dist/esm/billing/referral-reward.shared.schemas.js.map +1 -1
  55. package/dist/esm/billing/referral.shared.resources-config.schemas.d.ts.map +1 -1
  56. package/dist/esm/billing/referral.shared.resources-config.schemas.js.map +1 -1
  57. package/dist/esm/billing/referral.shared.schemas.d.ts.map +1 -1
  58. package/dist/esm/billing/referral.shared.schemas.js.map +1 -1
  59. package/dist/esm/billing/subscription.shared.resources-config.schemas.d.ts.map +1 -1
  60. package/dist/esm/billing/subscription.shared.resources-config.schemas.js.map +1 -1
  61. package/dist/esm/billing/subscription.shared.schemas.d.ts.map +1 -1
  62. package/dist/esm/billing/subscription.shared.schemas.js.map +1 -1
  63. package/dist/esm/billing/usage-flush-evidence.shared.schemas.d.ts.map +1 -1
  64. package/dist/esm/billing/usage-flush-evidence.shared.schemas.js.map +1 -1
  65. package/dist/esm/billing/usage-record.shared.resources-config.schemas.d.ts.map +1 -1
  66. package/dist/esm/billing/usage-record.shared.resources-config.schemas.js.map +1 -1
  67. package/dist/esm/billing/usage-record.shared.schemas.d.ts.map +1 -1
  68. package/dist/esm/billing/usage-record.shared.schemas.js.map +1 -1
  69. package/dist/esm/charts/aggregation-query.shared.schemas.d.ts.map +1 -1
  70. package/dist/esm/charts/aggregation-query.shared.schemas.js.map +1 -1
  71. package/dist/esm/charts/aggregation.shared.definitions.d.ts.map +1 -1
  72. package/dist/esm/charts/aggregation.shared.definitions.js.map +1 -1
  73. package/dist/esm/charts/chart-definition-builder.shared.d.ts.map +1 -1
  74. package/dist/esm/charts/chart-definition-builder.shared.js.map +1 -1
  75. package/dist/esm/companion/artifact-placement.shared.definitions.d.ts.map +1 -1
  76. package/dist/esm/companion/artifact-placement.shared.definitions.js.map +1 -1
  77. package/dist/esm/companion/provider-discovery.shared.schemas.d.ts +13 -0
  78. package/dist/esm/companion/provider-discovery.shared.schemas.d.ts.map +1 -1
  79. package/dist/esm/companion/provider-discovery.shared.schemas.js +13 -0
  80. package/dist/esm/companion/provider-discovery.shared.schemas.js.map +1 -1
  81. package/dist/esm/companion/shared-library-companion.shared.definitions.d.ts.map +1 -1
  82. package/dist/esm/companion/shared-library-companion.shared.definitions.js.map +1 -1
  83. package/dist/esm/companion-exports.d.ts.map +1 -1
  84. package/dist/esm/companion-exports.js.map +1 -1
  85. package/dist/esm/compliance/audit-trails/application-audit-logs.shared.resources-config.schemas.d.ts.map +1 -1
  86. package/dist/esm/compliance/audit-trails/application-audit-logs.shared.resources-config.schemas.js.map +1 -1
  87. package/dist/esm/compliance/audit-trails/audit-actor.shared.schemas.d.ts.map +1 -1
  88. package/dist/esm/compliance/audit-trails/audit-actor.shared.schemas.js.map +1 -1
  89. package/dist/esm/compliance/audit-trails/audit-export-projection.shared.schemas.d.ts.map +1 -1
  90. package/dist/esm/compliance/audit-trails/audit-export-projection.shared.schemas.js.map +1 -1
  91. package/dist/esm/compliance/audit-trails/audit-log-sink.shared.schemas.d.ts.map +1 -1
  92. package/dist/esm/compliance/audit-trails/audit-log-sink.shared.schemas.js.map +1 -1
  93. package/dist/esm/compliance/audit-trails/audit-logs.shared.resources-config.schemas.d.ts.map +1 -1
  94. package/dist/esm/compliance/audit-trails/audit-logs.shared.resources-config.schemas.js.map +1 -1
  95. package/dist/esm/compliance/audit-trails/audit-trail-config.shared.schemas.d.ts.map +1 -1
  96. package/dist/esm/compliance/audit-trails/audit-trail-config.shared.schemas.js.map +1 -1
  97. package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.d.ts.map +1 -1
  98. package/dist/esm/compliance/audit-trails/auditable-events.shared.schema.js.map +1 -1
  99. package/dist/esm/compliance/audit-trails/security-audit-event-envelope.shared.schema.d.ts.map +1 -1
  100. package/dist/esm/compliance/audit-trails/security-audit-event-envelope.shared.schema.js.map +1 -1
  101. package/dist/esm/compliance/data-classification/data-classification.shared.schemas.d.ts.map +1 -1
  102. package/dist/esm/compliance/data-classification/data-classification.shared.schemas.js.map +1 -1
  103. package/dist/esm/compliance/documents/governed-document-interactions.shared.schemas.d.ts.map +1 -1
  104. package/dist/esm/compliance/documents/governed-document-interactions.shared.schemas.js.map +1 -1
  105. package/dist/esm/compliance/documents/governed-documents.shared.schemas.d.ts.map +1 -1
  106. package/dist/esm/compliance/documents/governed-documents.shared.schemas.js.map +1 -1
  107. package/dist/esm/compliance/documents/user-governed-document-acceptances.shared.resources-config.schemas.d.ts.map +1 -1
  108. package/dist/esm/compliance/documents/user-governed-document-acceptances.shared.resources-config.schemas.js.map +1 -1
  109. package/dist/esm/compliance/documents/user-governed-document-acceptances.shared.schemas.d.ts.map +1 -1
  110. package/dist/esm/compliance/documents/user-governed-document-acceptances.shared.schemas.js.map +1 -1
  111. package/dist/esm/compliance/privacy/ai-use-posture.shared.schemas.d.ts.map +1 -1
  112. package/dist/esm/compliance/privacy/ai-use-posture.shared.schemas.js.map +1 -1
  113. package/dist/esm/compliance/privacy/capability-consent-purposes.shared.utils.d.ts.map +1 -1
  114. package/dist/esm/compliance/privacy/capability-consent-purposes.shared.utils.js.map +1 -1
  115. package/dist/esm/compliance/privacy/client-storage.shared.schemas.d.ts.map +1 -1
  116. package/dist/esm/compliance/privacy/client-storage.shared.schemas.js.map +1 -1
  117. package/dist/esm/compliance/privacy/consent-gate-vocabulary.shared.schemas.d.ts.map +1 -1
  118. package/dist/esm/compliance/privacy/consent-gate-vocabulary.shared.schemas.js.map +1 -1
  119. package/dist/esm/compliance/privacy/consent-purposes.shared.d.ts.map +1 -1
  120. package/dist/esm/compliance/privacy/consent-purposes.shared.js.map +1 -1
  121. package/dist/esm/compliance/privacy/data-subject-rights.shared.schemas.d.ts.map +1 -1
  122. package/dist/esm/compliance/privacy/data-subject-rights.shared.schemas.js.map +1 -1
  123. package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.d.ts.map +1 -1
  124. package/dist/esm/compliance/privacy/impersonalization-scrub.shared.utils.js.map +1 -1
  125. package/dist/esm/compliance/privacy/impersonalization.shared.schemas.d.ts.map +1 -1
  126. package/dist/esm/compliance/privacy/impersonalization.shared.schemas.js.map +1 -1
  127. package/dist/esm/compliance/privacy/legal-hold-subject-attribution.shared.utils.d.ts.map +1 -1
  128. package/dist/esm/compliance/privacy/legal-hold-subject-attribution.shared.utils.js.map +1 -1
  129. package/dist/esm/compliance/privacy/legal-holds.shared.resources-config.schemas.d.ts.map +1 -1
  130. package/dist/esm/compliance/privacy/legal-holds.shared.resources-config.schemas.js.map +1 -1
  131. package/dist/esm/compliance/privacy/legal-holds.shared.schemas.d.ts.map +1 -1
  132. package/dist/esm/compliance/privacy/legal-holds.shared.schemas.js.map +1 -1
  133. package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.d.ts.map +1 -1
  134. package/dist/esm/compliance/privacy/operating-jurisdictions.shared.schemas.js.map +1 -1
  135. package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.d.ts +32 -1
  136. package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.d.ts.map +1 -1
  137. package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.js +32 -0
  138. package/dist/esm/compliance/privacy/operator-compliance-identity.shared.schemas.js.map +1 -1
  139. package/dist/esm/compliance/privacy/personal-data-category.shared.schemas.d.ts.map +1 -1
  140. package/dist/esm/compliance/privacy/personal-data-category.shared.schemas.js.map +1 -1
  141. package/dist/esm/compliance/privacy/personal-data-declaration.shared.utils.d.ts.map +1 -1
  142. package/dist/esm/compliance/privacy/personal-data-declaration.shared.utils.js.map +1 -1
  143. package/dist/esm/compliance/privacy/privacy.shared.schemas.d.ts.map +1 -1
  144. package/dist/esm/compliance/privacy/privacy.shared.schemas.js.map +1 -1
  145. package/dist/esm/compliance/privacy/provider-capability-disclosure.shared.schemas.d.ts.map +1 -1
  146. package/dist/esm/compliance/privacy/provider-capability-disclosure.shared.schemas.js.map +1 -1
  147. package/dist/esm/compliance/privacy/purpose-ref.shared.schemas.d.ts.map +1 -1
  148. package/dist/esm/compliance/privacy/purpose-ref.shared.schemas.js.map +1 -1
  149. package/dist/esm/compliance/privacy/redaction.shared.schemas.d.ts.map +1 -1
  150. package/dist/esm/compliance/privacy/redaction.shared.schemas.js.map +1 -1
  151. package/dist/esm/compliance/privacy/retention-binding.shared.utils.d.ts.map +1 -1
  152. package/dist/esm/compliance/privacy/retention-binding.shared.utils.js.map +1 -1
  153. package/dist/esm/compliance/privacy/retention-enforcement-records.shared.resources-config.schemas.d.ts.map +1 -1
  154. package/dist/esm/compliance/privacy/retention-enforcement-records.shared.resources-config.schemas.js.map +1 -1
  155. package/dist/esm/compliance/privacy/retention-enforcement-records.shared.schemas.d.ts.map +1 -1
  156. package/dist/esm/compliance/privacy/retention-enforcement-records.shared.schemas.js.map +1 -1
  157. package/dist/esm/compliance/privacy/retention-schedule.shared.schemas.d.ts.map +1 -1
  158. package/dist/esm/compliance/privacy/retention-schedule.shared.schemas.js.map +1 -1
  159. package/dist/esm/compliance/privacy/retention-scope-deleted.shared.utils.d.ts.map +1 -1
  160. package/dist/esm/compliance/privacy/retention-scope-deleted.shared.utils.js.map +1 -1
  161. package/dist/esm/compliance/privacy/sharing.shared.schemas.d.ts.map +1 -1
  162. package/dist/esm/compliance/privacy/sharing.shared.schemas.js.map +1 -1
  163. package/dist/esm/compliance/privacy/subject-data-recipients.shared.schemas.d.ts.map +1 -1
  164. package/dist/esm/compliance/privacy/subject-data-recipients.shared.schemas.js.map +1 -1
  165. package/dist/esm/compliance/privacy/subject-erasure-lane-evidence.shared.schemas.d.ts.map +1 -1
  166. package/dist/esm/compliance/privacy/subject-erasure-lane-evidence.shared.schemas.js.map +1 -1
  167. package/dist/esm/compliance/privacy/subject-erasure.shared.schemas.d.ts.map +1 -1
  168. package/dist/esm/compliance/privacy/subject-erasure.shared.schemas.js.map +1 -1
  169. package/dist/esm/compliance/privacy/subject-export-render.shared.utils.d.ts.map +1 -1
  170. package/dist/esm/compliance/privacy/subject-export-render.shared.utils.js.map +1 -1
  171. package/dist/esm/compliance/privacy/subject-export.shared.schemas.d.ts.map +1 -1
  172. package/dist/esm/compliance/privacy/subject-export.shared.schemas.js.map +1 -1
  173. package/dist/esm/compliance/review-cadence.shared.schemas.d.ts.map +1 -1
  174. package/dist/esm/compliance/review-cadence.shared.schemas.js.map +1 -1
  175. package/dist/esm/compliance/risk-posture.shared.schemas.d.ts +15 -3
  176. package/dist/esm/compliance/risk-posture.shared.schemas.d.ts.map +1 -1
  177. package/dist/esm/compliance/risk-posture.shared.schemas.js +14 -2
  178. package/dist/esm/compliance/risk-posture.shared.schemas.js.map +1 -1
  179. package/dist/esm/config/analytics-value-moments.shared.schemas.d.ts.map +1 -1
  180. package/dist/esm/config/analytics-value-moments.shared.schemas.js.map +1 -1
  181. package/dist/esm/config/app-configuration-shared.shared.schemas.d.ts.map +1 -1
  182. package/dist/esm/config/app-configuration-shared.shared.schemas.js.map +1 -1
  183. package/dist/esm/config/app-frontend-type.shared.schemas.d.ts.map +1 -1
  184. package/dist/esm/config/app-frontend-type.shared.schemas.js.map +1 -1
  185. package/dist/esm/config/auth-config-resolution.shared.utils.d.ts.map +1 -1
  186. package/dist/esm/config/auth-config-resolution.shared.utils.js.map +1 -1
  187. package/dist/esm/config/brand-assets.shared.schemas.d.ts.map +1 -1
  188. package/dist/esm/config/brand-assets.shared.schemas.js.map +1 -1
  189. package/dist/esm/config/configuration-validation.shared.schemas.d.ts.map +1 -1
  190. package/dist/esm/config/configuration-validation.shared.schemas.js.map +1 -1
  191. package/dist/esm/config/entity-identity-config.shared.schemas.d.ts.map +1 -1
  192. package/dist/esm/config/entity-identity-config.shared.schemas.js.map +1 -1
  193. package/dist/esm/config/frontend/chart-definition.shared.schemas.d.ts.map +1 -1
  194. package/dist/esm/config/frontend/chart-definition.shared.schemas.js.map +1 -1
  195. package/dist/esm/config/frontend/chart-registration-alignment.shared.d.ts.map +1 -1
  196. package/dist/esm/config/frontend/chart-registration-alignment.shared.js.map +1 -1
  197. package/dist/esm/config/frontend/navigation.shared.schemas.d.ts.map +1 -1
  198. package/dist/esm/config/frontend/navigation.shared.schemas.js.map +1 -1
  199. package/dist/esm/config/frontend/onboarding.shared.schemas.d.ts.map +1 -1
  200. package/dist/esm/config/frontend/onboarding.shared.schemas.js.map +1 -1
  201. package/dist/esm/config/postgresql.shared.schemas.d.ts.map +1 -1
  202. package/dist/esm/config/postgresql.shared.schemas.js.map +1 -1
  203. package/dist/esm/config/registration-acquisition-policy.shared.utils.d.ts.map +1 -1
  204. package/dist/esm/config/registration-acquisition-policy.shared.utils.js.map +1 -1
  205. package/dist/esm/config-authoring.entry.d.ts.map +1 -1
  206. package/dist/esm/config-authoring.entry.js.map +1 -1
  207. package/dist/esm/crdt/crdt-merge.shared.utils.d.ts.map +1 -1
  208. package/dist/esm/crdt/crdt-merge.shared.utils.js.map +1 -1
  209. package/dist/esm/data-seeding/data-seeding-config.shared.schemas.d.ts.map +1 -1
  210. package/dist/esm/data-seeding/data-seeding-config.shared.schemas.js.map +1 -1
  211. package/dist/esm/errors/caught-error-description.shared.utils.d.ts.map +1 -1
  212. package/dist/esm/errors/caught-error-description.shared.utils.js.map +1 -1
  213. package/dist/esm/errors/errors.custom-message-ref.shared.definitions.d.ts.map +1 -1
  214. package/dist/esm/errors/errors.custom-message-ref.shared.definitions.js.map +1 -1
  215. package/dist/esm/errors/errors.shared.definitions.d.ts.map +1 -1
  216. package/dist/esm/errors/errors.shared.definitions.js.map +1 -1
  217. package/dist/esm/errors/errors.shared.schemas.d.ts.map +1 -1
  218. package/dist/esm/errors/errors.shared.schemas.js.map +1 -1
  219. package/dist/esm/errors/errors.shared.utils.d.ts.map +1 -1
  220. package/dist/esm/errors/errors.shared.utils.js.map +1 -1
  221. package/dist/esm/errors/resource-access-forbidden.shared.error.d.ts.map +1 -1
  222. package/dist/esm/errors/resource-access-forbidden.shared.error.js.map +1 -1
  223. package/dist/esm/errors/thrown-value-description.shared.utils.d.ts.map +1 -1
  224. package/dist/esm/errors/thrown-value-description.shared.utils.js.map +1 -1
  225. package/dist/esm/errors/zod-issue-formatting.shared.utils.d.ts.map +1 -1
  226. package/dist/esm/errors/zod-issue-formatting.shared.utils.js.map +1 -1
  227. package/dist/esm/exports/tabular-csv.shared.utils.d.ts.map +1 -1
  228. package/dist/esm/exports/tabular-csv.shared.utils.js.map +1 -1
  229. package/dist/esm/external-data/external-data-pipeline-description.shared.d.ts.map +1 -1
  230. package/dist/esm/external-data/external-data-pipeline-description.shared.js.map +1 -1
  231. package/dist/esm/external-data/external-data-pipeline-pass-mode.shared.d.ts.map +1 -1
  232. package/dist/esm/external-data/external-data-pipeline-pass-mode.shared.js.map +1 -1
  233. package/dist/esm/external-data/external-data-pipeline.shared.schemas.d.ts.map +1 -1
  234. package/dist/esm/external-data/external-data-pipeline.shared.schemas.js.map +1 -1
  235. package/dist/esm/external-data/external-data-provenance.shared.d.ts.map +1 -1
  236. package/dist/esm/external-data/external-data-provenance.shared.js.map +1 -1
  237. package/dist/esm/external-data.exports.d.ts.map +1 -1
  238. package/dist/esm/external-data.exports.js.map +1 -1
  239. package/dist/esm/external-providers/compose-provider-registry.shared.d.ts.map +1 -1
  240. package/dist/esm/external-providers/compose-provider-registry.shared.js.map +1 -1
  241. package/dist/esm/external-providers/engine-capabilities.shared.schemas.d.ts.map +1 -1
  242. package/dist/esm/external-providers/engine-capabilities.shared.schemas.js.map +1 -1
  243. package/dist/esm/external-providers/engine-capability-resolution-mode.shared.d.ts.map +1 -1
  244. package/dist/esm/external-providers/engine-capability-resolution-mode.shared.js.map +1 -1
  245. package/dist/esm/external-providers/engine-capability-surface.shared.d.ts.map +1 -1
  246. package/dist/esm/external-providers/engine-capability-surface.shared.js.map +1 -1
  247. package/dist/esm/external-providers/external-providers.shared.schemas.d.ts.map +1 -1
  248. package/dist/esm/external-providers/external-providers.shared.schemas.js.map +1 -1
  249. package/dist/esm/external-providers/frontend-bootstrap.shared.schemas.d.ts.map +1 -1
  250. package/dist/esm/external-providers/frontend-bootstrap.shared.schemas.js.map +1 -1
  251. package/dist/esm/external-providers/frontend-capability-public-config.shared.schemas.d.ts.map +1 -1
  252. package/dist/esm/external-providers/frontend-capability-public-config.shared.schemas.js.map +1 -1
  253. package/dist/esm/external-providers/frontend-capability-runtime.shared.types.d.ts.map +1 -1
  254. package/dist/esm/external-providers/frontend-capability-runtime.shared.types.js.map +1 -1
  255. package/dist/esm/external-providers/frontend-provider-entry.shared.schemas.d.ts.map +1 -1
  256. package/dist/esm/external-providers/frontend-provider-entry.shared.schemas.js.map +1 -1
  257. package/dist/esm/external-providers/frontend-provider-public-config.shared.d.ts.map +1 -1
  258. package/dist/esm/external-providers/frontend-provider-public-config.shared.js.map +1 -1
  259. package/dist/esm/external-providers/model-cost-accounting-config.shared.schemas.d.ts.map +1 -1
  260. package/dist/esm/external-providers/model-cost-accounting-config.shared.schemas.js.map +1 -1
  261. package/dist/esm/external-providers/provider-address-lookup-contract.shared.types.d.ts.map +1 -1
  262. package/dist/esm/external-providers/provider-address-lookup-contract.shared.types.js.map +1 -1
  263. package/dist/esm/external-providers/provider-augmentation-opt-ins.shared.schemas.d.ts.map +1 -1
  264. package/dist/esm/external-providers/provider-augmentation-opt-ins.shared.schemas.js.map +1 -1
  265. package/dist/esm/external-providers/provider-authentication-assurance.shared.schemas.d.ts.map +1 -1
  266. package/dist/esm/external-providers/provider-authentication-assurance.shared.schemas.js.map +1 -1
  267. package/dist/esm/external-providers/provider-browser-operations.shared.schemas.d.ts.map +1 -1
  268. package/dist/esm/external-providers/provider-browser-operations.shared.schemas.js.map +1 -1
  269. package/dist/esm/external-providers/provider-capability.shared.schemas.d.ts.map +1 -1
  270. package/dist/esm/external-providers/provider-capability.shared.schemas.js.map +1 -1
  271. package/dist/esm/external-providers/provider-compliance-profile.shared.schemas.d.ts.map +1 -1
  272. package/dist/esm/external-providers/provider-compliance-profile.shared.schemas.js.map +1 -1
  273. package/dist/esm/external-providers/provider-frontend-component-contract.shared.types.d.ts.map +1 -1
  274. package/dist/esm/external-providers/provider-frontend-component-contract.shared.types.js.map +1 -1
  275. package/dist/esm/external-providers/provider-frontend-surface.shared.schemas.d.ts.map +1 -1
  276. package/dist/esm/external-providers/provider-frontend-surface.shared.schemas.js.map +1 -1
  277. package/dist/esm/external-providers/provider-metadata.shared.schemas.d.ts.map +1 -1
  278. package/dist/esm/external-providers/provider-metadata.shared.schemas.js.map +1 -1
  279. package/dist/esm/external-providers/provider-package-allow-list.shared.schemas.d.ts.map +1 -1
  280. package/dist/esm/external-providers/provider-package-allow-list.shared.schemas.js.map +1 -1
  281. package/dist/esm/external-providers/provider-protocol.shared.schemas.d.ts.map +1 -1
  282. package/dist/esm/external-providers/provider-protocol.shared.schemas.js.map +1 -1
  283. package/dist/esm/external-providers/provider-scope-reauthorization.shared.schemas.d.ts.map +1 -1
  284. package/dist/esm/external-providers/provider-scope-reauthorization.shared.schemas.js.map +1 -1
  285. package/dist/esm/external-providers/provider-shared-connections.shared.schemas.d.ts.map +1 -1
  286. package/dist/esm/external-providers/provider-shared-connections.shared.schemas.js.map +1 -1
  287. package/dist/esm/external-providers/provider-tier-rule.shared.utils.d.ts.map +1 -1
  288. package/dist/esm/external-providers/provider-tier-rule.shared.utils.js.map +1 -1
  289. package/dist/esm/external-providers/provider-usage-cost.shared.d.ts.map +1 -1
  290. package/dist/esm/external-providers/provider-usage-cost.shared.js.map +1 -1
  291. package/dist/esm/external-providers/provider-usage-pricing.example.d.ts.map +1 -1
  292. package/dist/esm/external-providers/provider-usage-pricing.example.js.map +1 -1
  293. package/dist/esm/external-providers/provider-usage-pricing.shared.schemas.d.ts.map +1 -1
  294. package/dist/esm/external-providers/provider-usage-pricing.shared.schemas.js.map +1 -1
  295. package/dist/esm/features/application-features.shared.resources-config.schemas.d.ts.map +1 -1
  296. package/dist/esm/features/application-features.shared.resources-config.schemas.js.map +1 -1
  297. package/dist/esm/features/connected-feature.example.d.ts.map +1 -1
  298. package/dist/esm/features/connected-feature.example.js.map +1 -1
  299. package/dist/esm/features/core-feature-definitions.shared.d.ts.map +1 -1
  300. package/dist/esm/features/core-feature-definitions.shared.js.map +1 -1
  301. package/dist/esm/features/feature-builders.shared.d.ts.map +1 -1
  302. package/dist/esm/features/feature-builders.shared.js.map +1 -1
  303. package/dist/esm/features/feature-definition.shared.schemas.d.ts.map +1 -1
  304. package/dist/esm/features/feature-definition.shared.schemas.js.map +1 -1
  305. package/dist/esm/features/feature-registry.shared.d.ts.map +1 -1
  306. package/dist/esm/features/feature-registry.shared.js.map +1 -1
  307. package/dist/esm/features/feature-resolution.shared.schemas.d.ts.map +1 -1
  308. package/dist/esm/features/feature-resolution.shared.schemas.js.map +1 -1
  309. package/dist/esm/features/scope-features.shared.schemas.d.ts.map +1 -1
  310. package/dist/esm/features/scope-features.shared.schemas.js.map +1 -1
  311. package/dist/esm/features/user-features.shared.resources-config.schemas.d.ts.map +1 -1
  312. package/dist/esm/features/user-features.shared.resources-config.schemas.js.map +1 -1
  313. package/dist/esm/files/file-remote-reference-link.shared.schemas.d.ts.map +1 -1
  314. package/dist/esm/files/file-remote-reference-link.shared.schemas.js.map +1 -1
  315. package/dist/esm/files/file-upload-grant.shared.schemas.d.ts.map +1 -1
  316. package/dist/esm/files/file-upload-grant.shared.schemas.js.map +1 -1
  317. package/dist/esm/files/files.shared.resources-config.schemas.d.ts.map +1 -1
  318. package/dist/esm/files/files.shared.resources-config.schemas.js.map +1 -1
  319. package/dist/esm/files/files.shared.schemas.d.ts.map +1 -1
  320. package/dist/esm/files/files.shared.schemas.js.map +1 -1
  321. package/dist/esm/files/files.shared.utils.d.ts.map +1 -1
  322. package/dist/esm/files/files.shared.utils.js.map +1 -1
  323. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.resources-config.schemas.d.ts.map +1 -1
  324. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.resources-config.schemas.js.map +1 -1
  325. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.schemas.d.ts.map +1 -1
  326. package/dist/esm/flows-actors/a2a-push-delivery-log.shared.schemas.js.map +1 -1
  327. package/dist/esm/flows-actors/a2a-token-budget-state.shared.resources-config.schemas.d.ts.map +1 -1
  328. package/dist/esm/flows-actors/a2a-token-budget-state.shared.resources-config.schemas.js.map +1 -1
  329. package/dist/esm/flows-actors/a2a-token-budget-state.shared.schemas.d.ts.map +1 -1
  330. package/dist/esm/flows-actors/a2a-token-budget-state.shared.schemas.js.map +1 -1
  331. package/dist/esm/flows-actors/actors.shared.schemas.d.ts.map +1 -1
  332. package/dist/esm/flows-actors/actors.shared.schemas.js.map +1 -1
  333. package/dist/esm/flows-actors/agent-traceability.shared.schemas.d.ts.map +1 -1
  334. package/dist/esm/flows-actors/agent-traceability.shared.schemas.js.map +1 -1
  335. package/dist/esm/flows-actors/agent-work-decisions.shared.resources-config.schemas.d.ts.map +1 -1
  336. package/dist/esm/flows-actors/agent-work-decisions.shared.resources-config.schemas.js.map +1 -1
  337. package/dist/esm/flows-actors/agent-work-decisions.shared.schemas.d.ts.map +1 -1
  338. package/dist/esm/flows-actors/agent-work-decisions.shared.schemas.js.map +1 -1
  339. package/dist/esm/flows-actors/agents.shared.schemas.d.ts.map +1 -1
  340. package/dist/esm/flows-actors/agents.shared.schemas.js.map +1 -1
  341. package/dist/esm/flows-actors/autonomous-agents.shared.schemas.d.ts.map +1 -1
  342. package/dist/esm/flows-actors/autonomous-agents.shared.schemas.js.map +1 -1
  343. package/dist/esm/flows-actors/deliberation.shared.schemas.d.ts.map +1 -1
  344. package/dist/esm/flows-actors/deliberation.shared.schemas.js.map +1 -1
  345. package/dist/esm/flows-actors/execution-plan-readiness.shared.utils.d.ts.map +1 -1
  346. package/dist/esm/flows-actors/execution-plan-readiness.shared.utils.js.map +1 -1
  347. package/dist/esm/flows-actors/flows-actors-execution.shared.resources-config.schemas.d.ts.map +1 -1
  348. package/dist/esm/flows-actors/flows-actors-execution.shared.resources-config.schemas.js.map +1 -1
  349. package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.d.ts.map +1 -1
  350. package/dist/esm/flows-actors/flows-actors-execution.shared.schemas.js.map +1 -1
  351. package/dist/esm/flows-actors/flows-actors-task.shared.resources-config.schemas.d.ts.map +1 -1
  352. package/dist/esm/flows-actors/flows-actors-task.shared.resources-config.schemas.js.map +1 -1
  353. package/dist/esm/flows-actors/flows-actors-task.shared.schemas.d.ts.map +1 -1
  354. package/dist/esm/flows-actors/flows-actors-task.shared.schemas.js.map +1 -1
  355. package/dist/esm/flows-actors/flows-actors.commons.shared.schemas.d.ts.map +1 -1
  356. package/dist/esm/flows-actors/flows-actors.commons.shared.schemas.js.map +1 -1
  357. package/dist/esm/flows-actors/flows-actors.configuration.shared.schemas.d.ts.map +1 -1
  358. package/dist/esm/flows-actors/flows-actors.configuration.shared.schemas.js.map +1 -1
  359. package/dist/esm/flows-actors/flows-actors.frontend.shared.schemas.d.ts.map +1 -1
  360. package/dist/esm/flows-actors/flows-actors.frontend.shared.schemas.js.map +1 -1
  361. package/dist/esm/flows-actors/flows-actors.io.shared.schemas.d.ts.map +1 -1
  362. package/dist/esm/flows-actors/flows-actors.io.shared.schemas.js.map +1 -1
  363. package/dist/esm/flows-actors/flows-actors.system.shared.definitions.d.ts.map +1 -1
  364. package/dist/esm/flows-actors/flows-actors.system.shared.definitions.js.map +1 -1
  365. package/dist/esm/flows-actors/flows-actors.system.shared.schemas.d.ts.map +1 -1
  366. package/dist/esm/flows-actors/flows-actors.system.shared.schemas.js.map +1 -1
  367. package/dist/esm/flows-actors/flows.shared.schemas.d.ts.map +1 -1
  368. package/dist/esm/flows-actors/flows.shared.schemas.js.map +1 -1
  369. package/dist/esm/flows-actors/human-decision.shared.schemas.d.ts.map +1 -1
  370. package/dist/esm/flows-actors/human-decision.shared.schemas.js.map +1 -1
  371. package/dist/esm/flows-actors/mcp-servers.shared.schemas.d.ts.map +1 -1
  372. package/dist/esm/flows-actors/mcp-servers.shared.schemas.js.map +1 -1
  373. package/dist/esm/flows-actors/model-call-attributions.shared.resources-config.schemas.d.ts.map +1 -1
  374. package/dist/esm/flows-actors/model-call-attributions.shared.resources-config.schemas.js.map +1 -1
  375. package/dist/esm/flows-actors/model-call-attributions.shared.schemas.d.ts.map +1 -1
  376. package/dist/esm/flows-actors/model-call-attributions.shared.schemas.js.map +1 -1
  377. package/dist/esm/flows-actors/model-cost-period-aggregates.shared.resources-config.schemas.d.ts.map +1 -1
  378. package/dist/esm/flows-actors/model-cost-period-aggregates.shared.resources-config.schemas.js.map +1 -1
  379. package/dist/esm/flows-actors/model-cost-period-aggregates.shared.schemas.d.ts.map +1 -1
  380. package/dist/esm/flows-actors/model-cost-period-aggregates.shared.schemas.js.map +1 -1
  381. package/dist/esm/flows-actors/model-cost-summary.shared.schemas.d.ts.map +1 -1
  382. package/dist/esm/flows-actors/model-cost-summary.shared.schemas.js.map +1 -1
  383. package/dist/esm/flows-actors/prompt-ir.shared.schemas.d.ts.map +1 -1
  384. package/dist/esm/flows-actors/prompt-ir.shared.schemas.js.map +1 -1
  385. package/dist/esm/flows-actors/provider-call-records.shared.resources-config.schemas.d.ts.map +1 -1
  386. package/dist/esm/flows-actors/provider-call-records.shared.resources-config.schemas.js.map +1 -1
  387. package/dist/esm/flows-actors/provider-call-records.shared.schemas.d.ts.map +1 -1
  388. package/dist/esm/flows-actors/provider-call-records.shared.schemas.js.map +1 -1
  389. package/dist/esm/flows-actors/review-deadlines.shared.schemas.d.ts.map +1 -1
  390. package/dist/esm/flows-actors/review-deadlines.shared.schemas.js.map +1 -1
  391. package/dist/esm/flows-actors/tasks.actors.shared.schemas.d.ts.map +1 -1
  392. package/dist/esm/flows-actors/tasks.actors.shared.schemas.js.map +1 -1
  393. package/dist/esm/flows-actors/work-attribution.shared.schemas.d.ts.map +1 -1
  394. package/dist/esm/flows-actors/work-attribution.shared.schemas.js.map +1 -1
  395. package/dist/esm/frontend-definitions/frontend-notification-custom-message-ref.definitions.d.ts.map +1 -1
  396. package/dist/esm/frontend-definitions/frontend-notification-custom-message-ref.definitions.js.map +1 -1
  397. package/dist/esm/frontend-definitions/settings-destination-ref.definitions.d.ts.map +1 -1
  398. package/dist/esm/frontend-definitions/settings-destination-ref.definitions.js.map +1 -1
  399. package/dist/esm/guidance/guidance-flow.shared.schemas.d.ts.map +1 -1
  400. package/dist/esm/guidance/guidance-flow.shared.schemas.js.map +1 -1
  401. package/dist/esm/guidance/guidance-state.shared.resources-config.schemas.d.ts.map +1 -1
  402. package/dist/esm/guidance/guidance-state.shared.resources-config.schemas.js.map +1 -1
  403. package/dist/esm/guidance/guidance-state.shared.schemas.d.ts.map +1 -1
  404. package/dist/esm/guidance/guidance-state.shared.schemas.js.map +1 -1
  405. package/dist/esm/guidance/guidance-state.shared.utils.d.ts.map +1 -1
  406. package/dist/esm/guidance/guidance-state.shared.utils.js.map +1 -1
  407. package/dist/esm/guidance/lifecycle-config.shared.schemas.d.ts.map +1 -1
  408. package/dist/esm/guidance/lifecycle-config.shared.schemas.js.map +1 -1
  409. package/dist/esm/guidance/lifecycle-state.shared.resources-config.schemas.d.ts.map +1 -1
  410. package/dist/esm/guidance/lifecycle-state.shared.resources-config.schemas.js.map +1 -1
  411. package/dist/esm/guidance/lifecycle-state.shared.schemas.d.ts.map +1 -1
  412. package/dist/esm/guidance/lifecycle-state.shared.schemas.js.map +1 -1
  413. package/dist/esm/guidance/milestone-builders.shared.d.ts.map +1 -1
  414. package/dist/esm/guidance/milestone-builders.shared.js.map +1 -1
  415. package/dist/esm/guidance/milestone-definition.shared.schemas.d.ts.map +1 -1
  416. package/dist/esm/guidance/milestone-definition.shared.schemas.js.map +1 -1
  417. package/dist/esm/guidance/progression-presentation.shared.schemas.d.ts.map +1 -1
  418. package/dist/esm/guidance/progression-presentation.shared.schemas.js.map +1 -1
  419. package/dist/esm/guidance/progression-state.shared.resources-config.schemas.d.ts.map +1 -1
  420. package/dist/esm/guidance/progression-state.shared.resources-config.schemas.js.map +1 -1
  421. package/dist/esm/guidance/progression-state.shared.schemas.d.ts.map +1 -1
  422. package/dist/esm/guidance/progression-state.shared.schemas.js.map +1 -1
  423. package/dist/esm/http-api-binding/http-api-binding-id.shared.utils.d.ts.map +1 -1
  424. package/dist/esm/http-api-binding/http-api-binding-id.shared.utils.js.map +1 -1
  425. package/dist/esm/http-api-binding/http-api-binding.shared.schemas.d.ts.map +1 -1
  426. package/dist/esm/http-api-binding/http-api-binding.shared.schemas.js.map +1 -1
  427. package/dist/esm/http-api-binding/http-api-erasure-stance.shared.d.ts.map +1 -1
  428. package/dist/esm/http-api-binding/http-api-erasure-stance.shared.js.map +1 -1
  429. package/dist/esm/http-api-binding/http-api-rest-write-operations.shared.schemas.d.ts.map +1 -1
  430. package/dist/esm/http-api-binding/http-api-rest-write-operations.shared.schemas.js.map +1 -1
  431. package/dist/esm/http-api-binding/http-api-transport-dialect.shared.d.ts.map +1 -1
  432. package/dist/esm/http-api-binding/http-api-transport-dialect.shared.js.map +1 -1
  433. package/dist/esm/http-api-binding/read-through-engine-anchors.shared.d.ts.map +1 -1
  434. package/dist/esm/http-api-binding/read-through-engine-anchors.shared.js.map +1 -1
  435. package/dist/esm/i18n/application-config-vocabulary.shared.d.ts.map +1 -1
  436. package/dist/esm/i18n/application-config-vocabulary.shared.js.map +1 -1
  437. package/dist/esm/i18n/engine-open-vocabulary-values.shared.d.ts.map +1 -1
  438. package/dist/esm/i18n/engine-open-vocabulary-values.shared.js.map +1 -1
  439. package/dist/esm/i18n/engine-open-vocabulary.shared.d.ts.map +1 -1
  440. package/dist/esm/i18n/engine-open-vocabulary.shared.js.map +1 -1
  441. package/dist/esm/i18n/interpolate-label-params.shared.utils.d.ts.map +1 -1
  442. package/dist/esm/i18n/interpolate-label-params.shared.utils.js.map +1 -1
  443. package/dist/esm/i18n/labelling.dto.shared.schemas.d.ts.map +1 -1
  444. package/dist/esm/i18n/labelling.dto.shared.schemas.js.map +1 -1
  445. package/dist/esm/inbound/conversation-threads.shared.resources-config.schemas.d.ts.map +1 -1
  446. package/dist/esm/inbound/conversation-threads.shared.resources-config.schemas.js.map +1 -1
  447. package/dist/esm/inbound/conversation-threads.shared.schemas.d.ts.map +1 -1
  448. package/dist/esm/inbound/conversation-threads.shared.schemas.js.map +1 -1
  449. package/dist/esm/inbound/inbound-channels.shared.schemas.d.ts.map +1 -1
  450. package/dist/esm/inbound/inbound-channels.shared.schemas.js.map +1 -1
  451. package/dist/esm/inbound/inbound-delivery.shared.resources-config.schemas.d.ts.map +1 -1
  452. package/dist/esm/inbound/inbound-delivery.shared.resources-config.schemas.js.map +1 -1
  453. package/dist/esm/inbound/inbound-delivery.shared.schemas.d.ts.map +1 -1
  454. package/dist/esm/inbound/inbound-delivery.shared.schemas.js.map +1 -1
  455. package/dist/esm/inbound/inbound-endpoint-env.shared.d.ts.map +1 -1
  456. package/dist/esm/inbound/inbound-endpoint-env.shared.js.map +1 -1
  457. package/dist/esm/index.d.ts.map +1 -1
  458. package/dist/esm/index.js.map +1 -1
  459. package/dist/esm/meta-workflows/actions.meta-workflows.shared.schemas.d.ts.map +1 -1
  460. package/dist/esm/meta-workflows/actions.meta-workflows.shared.schemas.js.map +1 -1
  461. package/dist/esm/meta-workflows/catalog.meta-workflows.shared.schemas.d.ts.map +1 -1
  462. package/dist/esm/meta-workflows/catalog.meta-workflows.shared.schemas.js.map +1 -1
  463. package/dist/esm/meta-workflows/coding-tasks.meta-workflows.shared.schemas.d.ts.map +1 -1
  464. package/dist/esm/meta-workflows/coding-tasks.meta-workflows.shared.schemas.js.map +1 -1
  465. package/dist/esm/meta-workflows/context-selection.meta-workflows.shared.schemas.d.ts.map +1 -1
  466. package/dist/esm/meta-workflows/context-selection.meta-workflows.shared.schemas.js.map +1 -1
  467. package/dist/esm/meta-workflows/decisions.meta-workflows.shared.schemas.d.ts.map +1 -1
  468. package/dist/esm/meta-workflows/decisions.meta-workflows.shared.schemas.js.map +1 -1
  469. package/dist/esm/meta-workflows/elicitation-depth.meta-workflows.shared.schemas.d.ts +128 -0
  470. package/dist/esm/meta-workflows/elicitation-depth.meta-workflows.shared.schemas.d.ts.map +1 -0
  471. package/dist/esm/meta-workflows/elicitation-depth.meta-workflows.shared.schemas.js +136 -0
  472. package/dist/esm/meta-workflows/elicitation-depth.meta-workflows.shared.schemas.js.map +1 -0
  473. package/dist/esm/meta-workflows/orchestration.meta-workflows.shared.schemas.d.ts +32 -0
  474. package/dist/esm/meta-workflows/orchestration.meta-workflows.shared.schemas.d.ts.map +1 -1
  475. package/dist/esm/meta-workflows/orchestration.meta-workflows.shared.schemas.js +66 -1
  476. package/dist/esm/meta-workflows/orchestration.meta-workflows.shared.schemas.js.map +1 -1
  477. package/dist/esm/meta-workflows/portable-primitives.meta-workflows.shared.schemas.d.ts.map +1 -1
  478. package/dist/esm/meta-workflows/portable-primitives.meta-workflows.shared.schemas.js.map +1 -1
  479. package/dist/esm/meta-workflows.exports.d.ts +1 -0
  480. package/dist/esm/meta-workflows.exports.d.ts.map +1 -1
  481. package/dist/esm/meta-workflows.exports.js +1 -0
  482. package/dist/esm/meta-workflows.exports.js.map +1 -1
  483. package/dist/esm/monitoring/monitoring.shared.schemas.d.ts.map +1 -1
  484. package/dist/esm/monitoring/monitoring.shared.schemas.js.map +1 -1
  485. package/dist/esm/notifications/email/email-context.shared.schemas.d.ts.map +1 -1
  486. package/dist/esm/notifications/email/email-context.shared.schemas.js.map +1 -1
  487. package/dist/esm/notifications/email/email-submission.shared.enums.d.ts.map +1 -1
  488. package/dist/esm/notifications/email/email-submission.shared.enums.js.map +1 -1
  489. package/dist/esm/notifications/email/email-template-registry.shared.schemas.d.ts.map +1 -1
  490. package/dist/esm/notifications/email/email-template-registry.shared.schemas.js.map +1 -1
  491. package/dist/esm/notifications/email/email-template.shared.enums.d.ts.map +1 -1
  492. package/dist/esm/notifications/email/email-template.shared.enums.js.map +1 -1
  493. package/dist/esm/notifications/inbound-email/inbound-email.shared.resources-config.schemas.d.ts.map +1 -1
  494. package/dist/esm/notifications/inbound-email/inbound-email.shared.resources-config.schemas.js.map +1 -1
  495. package/dist/esm/notifications/inbound-email/inbound-email.shared.schemas.d.ts.map +1 -1
  496. package/dist/esm/notifications/inbound-email/inbound-email.shared.schemas.js.map +1 -1
  497. package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.d.ts.map +1 -1
  498. package/dist/esm/notifications/m2m/m2m-webhook-delivery-contract.shared.js.map +1 -1
  499. package/dist/esm/notifications/m2m/m2m-webhook-delivery-log.shared.resources-config.schemas.d.ts.map +1 -1
  500. package/dist/esm/notifications/m2m/m2m-webhook-delivery-log.shared.resources-config.schemas.js.map +1 -1
  501. package/dist/esm/notifications/m2m/m2m-webhook-delivery-log.shared.schemas.d.ts.map +1 -1
  502. package/dist/esm/notifications/m2m/m2m-webhook-delivery-log.shared.schemas.js.map +1 -1
  503. package/dist/esm/notifications/m2m/webhook-config.shared.resources-config.schemas.d.ts.map +1 -1
  504. package/dist/esm/notifications/m2m/webhook-config.shared.resources-config.schemas.js.map +1 -1
  505. package/dist/esm/notifications/m2m/webhook-config.shared.schemas.d.ts.map +1 -1
  506. package/dist/esm/notifications/m2m/webhook-config.shared.schemas.js.map +1 -1
  507. package/dist/esm/notifications/notification-badges.core.definitions.d.ts.map +1 -1
  508. package/dist/esm/notifications/notification-badges.core.definitions.js.map +1 -1
  509. package/dist/esm/notifications/notification-badges.schemas.d.ts.map +1 -1
  510. package/dist/esm/notifications/notification-badges.schemas.js.map +1 -1
  511. package/dist/esm/notifications/notification-badges.shared.resources-config.schemas.d.ts.map +1 -1
  512. package/dist/esm/notifications/notification-badges.shared.resources-config.schemas.js.map +1 -1
  513. package/dist/esm/notifications/notifications.shared.schemas.d.ts.map +1 -1
  514. package/dist/esm/notifications/notifications.shared.schemas.js.map +1 -1
  515. package/dist/esm/organizations/application-owner-organization.shared.schemas.d.ts.map +1 -1
  516. package/dist/esm/organizations/application-owner-organization.shared.schemas.js.map +1 -1
  517. package/dist/esm/organizations/organization-features.shared.resources-config.schemas.d.ts.map +1 -1
  518. package/dist/esm/organizations/organization-features.shared.resources-config.schemas.js.map +1 -1
  519. package/dist/esm/organizations/organization-features.shared.schemas.d.ts.map +1 -1
  520. package/dist/esm/organizations/organization-features.shared.schemas.js.map +1 -1
  521. package/dist/esm/organizations/organization-members.shared.resources-config.schemas.d.ts.map +1 -1
  522. package/dist/esm/organizations/organization-members.shared.resources-config.schemas.js.map +1 -1
  523. package/dist/esm/organizations/organization-members.shared.schemas.d.ts.map +1 -1
  524. package/dist/esm/organizations/organization-members.shared.schemas.js.map +1 -1
  525. package/dist/esm/organizations/organization-notifications.shared.resources-config.schemas.d.ts.map +1 -1
  526. package/dist/esm/organizations/organization-notifications.shared.resources-config.schemas.js.map +1 -1
  527. package/dist/esm/organizations/organization-notifications.shared.schemas.d.ts.map +1 -1
  528. package/dist/esm/organizations/organization-notifications.shared.schemas.js.map +1 -1
  529. package/dist/esm/organizations/organization-preferences.shared.resources-config.schemas.d.ts.map +1 -1
  530. package/dist/esm/organizations/organization-preferences.shared.resources-config.schemas.js.map +1 -1
  531. package/dist/esm/organizations/organization-preferences.shared.schemas.d.ts.map +1 -1
  532. package/dist/esm/organizations/organization-preferences.shared.schemas.js.map +1 -1
  533. package/dist/esm/organizations/organization-profile.shared.resources-config.schemas.d.ts.map +1 -1
  534. package/dist/esm/organizations/organization-profile.shared.resources-config.schemas.js.map +1 -1
  535. package/dist/esm/organizations/organization-profile.shared.schemas.d.ts.map +1 -1
  536. package/dist/esm/organizations/organization-profile.shared.schemas.js.map +1 -1
  537. package/dist/esm/organizations/organization-unit-inheritance.shared.d.ts.map +1 -1
  538. package/dist/esm/organizations/organization-unit-inheritance.shared.js.map +1 -1
  539. package/dist/esm/organizations/organization-unit-members.shared.resources-config.schemas.d.ts.map +1 -1
  540. package/dist/esm/organizations/organization-unit-members.shared.resources-config.schemas.js.map +1 -1
  541. package/dist/esm/organizations/organization-unit-members.shared.schemas.d.ts.map +1 -1
  542. package/dist/esm/organizations/organization-unit-members.shared.schemas.js.map +1 -1
  543. package/dist/esm/organizations/organization-unit-narrowing-decision.shared.d.ts.map +1 -1
  544. package/dist/esm/organizations/organization-unit-narrowing-decision.shared.js.map +1 -1
  545. package/dist/esm/organizations/organization-unit-narrowing.example.d.ts.map +1 -1
  546. package/dist/esm/organizations/organization-unit-narrowing.example.js.map +1 -1
  547. package/dist/esm/organizations/organization-unit-narrowing.shared.d.ts.map +1 -1
  548. package/dist/esm/organizations/organization-unit-narrowing.shared.js.map +1 -1
  549. package/dist/esm/organizations/organization-units.shared.path.d.ts.map +1 -1
  550. package/dist/esm/organizations/organization-units.shared.path.js.map +1 -1
  551. package/dist/esm/organizations/organization-units.shared.resources-config.schemas.d.ts.map +1 -1
  552. package/dist/esm/organizations/organization-units.shared.resources-config.schemas.js.map +1 -1
  553. package/dist/esm/organizations/organization-units.shared.schemas.d.ts.map +1 -1
  554. package/dist/esm/organizations/organization-units.shared.schemas.js.map +1 -1
  555. package/dist/esm/organizations/organizations.shared.resources-config.schemas.d.ts.map +1 -1
  556. package/dist/esm/organizations/organizations.shared.resources-config.schemas.js.map +1 -1
  557. package/dist/esm/organizations/organizations.shared.schemas.d.ts.map +1 -1
  558. package/dist/esm/organizations/organizations.shared.schemas.js.map +1 -1
  559. package/dist/esm/organizations/service-provider-activity-feed.shared.resources-config.schemas.d.ts.map +1 -1
  560. package/dist/esm/organizations/service-provider-activity-feed.shared.resources-config.schemas.js.map +1 -1
  561. package/dist/esm/organizations/service-provider-activity-feed.shared.schemas.d.ts.map +1 -1
  562. package/dist/esm/organizations/service-provider-activity-feed.shared.schemas.js.map +1 -1
  563. package/dist/esm/organizations/service-provider-capability-grants.shared.resources-config.schemas.d.ts.map +1 -1
  564. package/dist/esm/organizations/service-provider-capability-grants.shared.resources-config.schemas.js.map +1 -1
  565. package/dist/esm/organizations/service-provider-capability-grants.shared.schemas.d.ts.map +1 -1
  566. package/dist/esm/organizations/service-provider-capability-grants.shared.schemas.js.map +1 -1
  567. package/dist/esm/organizations/service-provider-client-controls.shared.schemas.d.ts.map +1 -1
  568. package/dist/esm/organizations/service-provider-client-controls.shared.schemas.js.map +1 -1
  569. package/dist/esm/organizations/service-provider-relationships.shared.resources-config.schemas.d.ts.map +1 -1
  570. package/dist/esm/organizations/service-provider-relationships.shared.resources-config.schemas.js.map +1 -1
  571. package/dist/esm/organizations/service-provider-relationships.shared.schemas.d.ts.map +1 -1
  572. package/dist/esm/organizations/service-provider-relationships.shared.schemas.js.map +1 -1
  573. package/dist/esm/organizations/tenant-teardown-config.shared.schemas.d.ts.map +1 -1
  574. package/dist/esm/organizations/tenant-teardown-config.shared.schemas.js.map +1 -1
  575. package/dist/esm/provider-registration-runtime.exports.d.ts.map +1 -1
  576. package/dist/esm/provider-registration-runtime.exports.js.map +1 -1
  577. package/dist/esm/public-runtime/index.d.ts.map +1 -1
  578. package/dist/esm/public-runtime/index.js.map +1 -1
  579. package/dist/esm/queue/jobs.shared.resources-config.schemas.d.ts.map +1 -1
  580. package/dist/esm/queue/jobs.shared.resources-config.schemas.js.map +1 -1
  581. package/dist/esm/queue/jobs.shared.schemas.d.ts +70 -1
  582. package/dist/esm/queue/jobs.shared.schemas.d.ts.map +1 -1
  583. package/dist/esm/queue/jobs.shared.schemas.js +85 -2
  584. package/dist/esm/queue/jobs.shared.schemas.js.map +1 -1
  585. package/dist/esm/queue/jobs.shared.utils.d.ts.map +1 -1
  586. package/dist/esm/queue/jobs.shared.utils.js.map +1 -1
  587. package/dist/esm/queue/queues.shared.schemas.d.ts.map +1 -1
  588. package/dist/esm/queue/queues.shared.schemas.js.map +1 -1
  589. package/dist/esm/queue/queues.shared.utils.d.ts.map +1 -1
  590. package/dist/esm/queue/queues.shared.utils.js.map +1 -1
  591. package/dist/esm/queue/rabbitmq-queue-args.shared.d.ts.map +1 -1
  592. package/dist/esm/queue/rabbitmq-queue-args.shared.js.map +1 -1
  593. package/dist/esm/rag/rag-retrieval-health.shared.d.ts.map +1 -1
  594. package/dist/esm/rag/rag-retrieval-health.shared.js.map +1 -1
  595. package/dist/esm/requests/header-keys.shared.d.ts.map +1 -1
  596. package/dist/esm/requests/header-keys.shared.js.map +1 -1
  597. package/dist/esm/requests/http-requests.shared.d.ts.map +1 -1
  598. package/dist/esm/requests/http-requests.shared.js.map +1 -1
  599. package/dist/esm/requests/idempotency-key.shared.d.ts.map +1 -1
  600. package/dist/esm/requests/idempotency-key.shared.js.map +1 -1
  601. package/dist/esm/requests/manual-controllers-routes-documentation.d.ts.map +1 -1
  602. package/dist/esm/requests/manual-controllers-routes-documentation.js.map +1 -1
  603. package/dist/esm/requests/manual-controllers-routes-urls.d.ts.map +1 -1
  604. package/dist/esm/requests/manual-controllers-routes-urls.js.map +1 -1
  605. package/dist/esm/requests/rate-limits.shared.schemas.d.ts.map +1 -1
  606. package/dist/esm/requests/rate-limits.shared.schemas.js.map +1 -1
  607. package/dist/esm/requests/websocket.shared.schemas.d.ts.map +1 -1
  608. package/dist/esm/requests/websocket.shared.schemas.js.map +1 -1
  609. package/dist/esm/resources/child-operations.shared.schemas.d.ts.map +1 -1
  610. package/dist/esm/resources/child-operations.shared.schemas.js.map +1 -1
  611. package/dist/esm/resources/collection-query-parameters.shared.d.ts.map +1 -1
  612. package/dist/esm/resources/collection-query-parameters.shared.js.map +1 -1
  613. package/dist/esm/resources/context-policy.shared.schemas.d.ts.map +1 -1
  614. package/dist/esm/resources/context-policy.shared.schemas.js.map +1 -1
  615. package/dist/esm/resources/embedded-resource-mark.shared.utils.d.ts.map +1 -1
  616. package/dist/esm/resources/embedded-resource-mark.shared.utils.js.map +1 -1
  617. package/dist/esm/resources/relationship-display.shared.schemas.d.ts.map +1 -1
  618. package/dist/esm/resources/relationship-display.shared.schemas.js.map +1 -1
  619. package/dist/esm/resources/resources-config.shared.factory.d.ts.map +1 -1
  620. package/dist/esm/resources/resources-config.shared.factory.js.map +1 -1
  621. package/dist/esm/resources/resources-config.shared.schemas.d.ts.map +1 -1
  622. package/dist/esm/resources/resources-config.shared.schemas.js.map +1 -1
  623. package/dist/esm/resources/resources-registry.shared.core.definitions.d.ts.map +1 -1
  624. package/dist/esm/resources/resources-registry.shared.core.definitions.js.map +1 -1
  625. package/dist/esm/resources/resources-relationships.shared.factory.d.ts.map +1 -1
  626. package/dist/esm/resources/resources-relationships.shared.factory.js.map +1 -1
  627. package/dist/esm/resources/resources-serialization.shared.schemas.d.ts.map +1 -1
  628. package/dist/esm/resources/resources-serialization.shared.schemas.js.map +1 -1
  629. package/dist/esm/resources/resources.shared.core.definitions.d.ts.map +1 -1
  630. package/dist/esm/resources/resources.shared.core.definitions.js.map +1 -1
  631. package/dist/esm/resources/resources.shared.schemas.d.ts.map +1 -1
  632. package/dist/esm/resources/resources.shared.schemas.js.map +1 -1
  633. package/dist/esm/resources/resources.shared.utils.d.ts.map +1 -1
  634. package/dist/esm/resources/resources.shared.utils.js.map +1 -1
  635. package/dist/esm/resources/utils/collection-export.shared.utils.d.ts.map +1 -1
  636. package/dist/esm/resources/utils/collection-export.shared.utils.js.map +1 -1
  637. package/dist/esm/resources/utils/composition-cascade-deletability.validation.d.ts.map +1 -1
  638. package/dist/esm/resources/utils/composition-cascade-deletability.validation.js.map +1 -1
  639. package/dist/esm/resources/utils/composition-seedability.validation.d.ts.map +1 -1
  640. package/dist/esm/resources/utils/composition-seedability.validation.js.map +1 -1
  641. package/dist/esm/resources/utils/context-addressed-composition-singleton.shared.utils.d.ts.map +1 -1
  642. package/dist/esm/resources/utils/context-addressed-composition-singleton.shared.utils.js.map +1 -1
  643. package/dist/esm/resources/utils/dependent-lifecycle-classification.validation.d.ts.map +1 -1
  644. package/dist/esm/resources/utils/dependent-lifecycle-classification.validation.js.map +1 -1
  645. package/dist/esm/resources/utils/duplicate-relationship-registration.validation.d.ts.map +1 -1
  646. package/dist/esm/resources/utils/duplicate-relationship-registration.validation.js.map +1 -1
  647. package/dist/esm/resources/utils/field-value-disclosure.utils.d.ts.map +1 -1
  648. package/dist/esm/resources/utils/field-value-disclosure.utils.js.map +1 -1
  649. package/dist/esm/resources/utils/http-api-write-declaration.shared.utils.d.ts.map +1 -1
  650. package/dist/esm/resources/utils/http-api-write-declaration.shared.utils.js.map +1 -1
  651. package/dist/esm/resources/utils/initiator-stamped-field-satisfiability.validation.d.ts.map +1 -1
  652. package/dist/esm/resources/utils/initiator-stamped-field-satisfiability.validation.js.map +1 -1
  653. package/dist/esm/resources/utils/no-subject-data-stance-coherence.shared.utils.d.ts.map +1 -1
  654. package/dist/esm/resources/utils/no-subject-data-stance-coherence.shared.utils.js.map +1 -1
  655. package/dist/esm/resources/utils/persistence-adapter-discrimination.shared.utils.d.ts.map +1 -1
  656. package/dist/esm/resources/utils/persistence-adapter-discrimination.shared.utils.js.map +1 -1
  657. package/dist/esm/resources/utils/populated-file-fields.shared.utils.d.ts.map +1 -1
  658. package/dist/esm/resources/utils/populated-file-fields.shared.utils.js.map +1 -1
  659. package/dist/esm/resources/utils/repository-dto-builder.utils.d.ts.map +1 -1
  660. package/dist/esm/resources/utils/repository-dto-builder.utils.js.map +1 -1
  661. package/dist/esm/resources/utils/request-schema-field-carriage.shared.utils.d.ts.map +1 -1
  662. package/dist/esm/resources/utils/request-schema-field-carriage.shared.utils.js.map +1 -1
  663. package/dist/esm/resources/utils/required-fk-fillability.validation.d.ts.map +1 -1
  664. package/dist/esm/resources/utils/required-fk-fillability.validation.js.map +1 -1
  665. package/dist/esm/resources/utils/resource-operation-type-guards.utils.d.ts.map +1 -1
  666. package/dist/esm/resources/utils/resource-operation-type-guards.utils.js.map +1 -1
  667. package/dist/esm/resources/utils/resource-polymorphism.factory.d.ts.map +1 -1
  668. package/dist/esm/resources/utils/resource-polymorphism.factory.js.map +1 -1
  669. package/dist/esm/resources/utils/resource-polymorphism.relationships.d.ts.map +1 -1
  670. package/dist/esm/resources/utils/resource-polymorphism.relationships.js.map +1 -1
  671. package/dist/esm/resources/utils/resource-polymorphism.schemas.d.ts.map +1 -1
  672. package/dist/esm/resources/utils/resource-polymorphism.schemas.js.map +1 -1
  673. package/dist/esm/resources/utils/resource-polymorphism.utils.d.ts.map +1 -1
  674. package/dist/esm/resources/utils/resource-polymorphism.utils.js.map +1 -1
  675. package/dist/esm/resources/utils/resource-subtree.utils.d.ts.map +1 -1
  676. package/dist/esm/resources/utils/resource-subtree.utils.js.map +1 -1
  677. package/dist/esm/resources/utils/resources-config-context-needs.utils.d.ts.map +1 -1
  678. package/dist/esm/resources/utils/resources-config-context-needs.utils.js.map +1 -1
  679. package/dist/esm/resources/utils/resources-config-naming.utils.d.ts.map +1 -1
  680. package/dist/esm/resources/utils/resources-config-naming.utils.js.map +1 -1
  681. package/dist/esm/resources/utils/resources-config-operations.dtos-builder.utils.d.ts +25 -0
  682. package/dist/esm/resources/utils/resources-config-operations.dtos-builder.utils.d.ts.map +1 -1
  683. package/dist/esm/resources/utils/resources-config-operations.dtos-builder.utils.js +47 -19
  684. package/dist/esm/resources/utils/resources-config-operations.dtos-builder.utils.js.map +1 -1
  685. package/dist/esm/resources/utils/resources-config-operations.path.utils.d.ts.map +1 -1
  686. package/dist/esm/resources/utils/resources-config-operations.path.utils.js.map +1 -1
  687. package/dist/esm/resources/utils/resources-config-operations.urls-builder.utils.d.ts.map +1 -1
  688. package/dist/esm/resources/utils/resources-config-operations.urls-builder.utils.js.map +1 -1
  689. package/dist/esm/resources/utils/resources-config-operations.utils.d.ts.map +1 -1
  690. package/dist/esm/resources/utils/resources-config-operations.utils.js.map +1 -1
  691. package/dist/esm/resources/utils/resources-serialization.utils.d.ts.map +1 -1
  692. package/dist/esm/resources/utils/resources-serialization.utils.js.map +1 -1
  693. package/dist/esm/resources/utils/resources-summary.utils.d.ts.map +1 -1
  694. package/dist/esm/resources/utils/resources-summary.utils.js.map +1 -1
  695. package/dist/esm/resources/utils/schema-family-builder.utils.d.ts.map +1 -1
  696. package/dist/esm/resources/utils/schema-family-builder.utils.js.map +1 -1
  697. package/dist/esm/resources/utils/schema-type-inference.utils.d.ts.map +1 -1
  698. package/dist/esm/resources/utils/schema-type-inference.utils.js.map +1 -1
  699. package/dist/esm/resources/utils/schema-type-utils.d.ts.map +1 -1
  700. package/dist/esm/resources/utils/schema-type-utils.js.map +1 -1
  701. package/dist/esm/resources/utils/schema-variant-resolver.utils.d.ts.map +1 -1
  702. package/dist/esm/resources/utils/schema-variant-resolver.utils.js.map +1 -1
  703. package/dist/esm/resources/utils/shared-persistence-collection.utils.d.ts.map +1 -1
  704. package/dist/esm/resources/utils/shared-persistence-collection.utils.js.map +1 -1
  705. package/dist/esm/resources/utils/templatable-file-fields.shared.utils.d.ts.map +1 -1
  706. package/dist/esm/resources/utils/templatable-file-fields.shared.utils.js.map +1 -1
  707. package/dist/esm/resources/work-unit.shared.schemas.d.ts.map +1 -1
  708. package/dist/esm/resources/work-unit.shared.schemas.js.map +1 -1
  709. package/dist/esm/runtime/domain-module.shared.definitions.d.ts.map +1 -1
  710. package/dist/esm/runtime/domain-module.shared.definitions.js.map +1 -1
  711. package/dist/esm/runtime/execution-context.shared.schemas.d.ts.map +1 -1
  712. package/dist/esm/runtime/execution-context.shared.schemas.js.map +1 -1
  713. package/dist/esm/runtime/runtime.shared.schemas.d.ts.map +1 -1
  714. package/dist/esm/runtime/runtime.shared.schemas.js.map +1 -1
  715. package/dist/esm/security/api-keys/api-keys-application.shared.resources-config.schemas.d.ts.map +1 -1
  716. package/dist/esm/security/api-keys/api-keys-application.shared.resources-config.schemas.js.map +1 -1
  717. package/dist/esm/security/api-keys/api-keys-organization.shared.resources-config.schemas.d.ts.map +1 -1
  718. package/dist/esm/security/api-keys/api-keys-organization.shared.resources-config.schemas.js.map +1 -1
  719. package/dist/esm/security/api-keys/api-keys.shared.schemas.d.ts.map +1 -1
  720. package/dist/esm/security/api-keys/api-keys.shared.schemas.js.map +1 -1
  721. package/dist/esm/security/authentications/anonymous-session/anonymous-session.shared.contract.d.ts.map +1 -1
  722. package/dist/esm/security/authentications/anonymous-session/anonymous-session.shared.contract.js.map +1 -1
  723. package/dist/esm/security/authentications/authentication.shared.dto.schemas.d.ts.map +1 -1
  724. package/dist/esm/security/authentications/authentication.shared.dto.schemas.js.map +1 -1
  725. package/dist/esm/security/authentications/authentication.shared.schemas.d.ts.map +1 -1
  726. package/dist/esm/security/authentications/authentication.shared.schemas.js.map +1 -1
  727. package/dist/esm/security/authentications/authentication.shared.utils.d.ts.map +1 -1
  728. package/dist/esm/security/authentications/authentication.shared.utils.js.map +1 -1
  729. package/dist/esm/security/authentications/consumable-token.shared.schemas.d.ts.map +1 -1
  730. package/dist/esm/security/authentications/consumable-token.shared.schemas.js.map +1 -1
  731. package/dist/esm/security/authentications/cross-frontend-handoff.shared.dto.schemas.d.ts.map +1 -1
  732. package/dist/esm/security/authentications/cross-frontend-handoff.shared.dto.schemas.js.map +1 -1
  733. package/dist/esm/security/authentications/mfa-backup-code-contract.shared.d.ts.map +1 -1
  734. package/dist/esm/security/authentications/mfa-backup-code-contract.shared.js.map +1 -1
  735. package/dist/esm/security/authentications/password-blocklist.shared.utils.d.ts.map +1 -1
  736. package/dist/esm/security/authentications/password-blocklist.shared.utils.js.map +1 -1
  737. package/dist/esm/security/authentications/password-reset.shared.dto.schemas.d.ts.map +1 -1
  738. package/dist/esm/security/authentications/password-reset.shared.dto.schemas.js.map +1 -1
  739. package/dist/esm/security/authentications/registration.shared.dto.schemas.d.ts.map +1 -1
  740. package/dist/esm/security/authentications/registration.shared.dto.schemas.js.map +1 -1
  741. package/dist/esm/security/authentications/same-origin-redirect-path.shared.d.ts.map +1 -1
  742. package/dist/esm/security/authentications/same-origin-redirect-path.shared.js.map +1 -1
  743. package/dist/esm/security/authentications/scim/scim-organization-unit-mapping.shared.d.ts.map +1 -1
  744. package/dist/esm/security/authentications/scim/scim-organization-unit-mapping.shared.js.map +1 -1
  745. package/dist/esm/security/authentications/scim/scim-provisioning-config.shared.resources-config.schemas.d.ts.map +1 -1
  746. package/dist/esm/security/authentications/scim/scim-provisioning-config.shared.resources-config.schemas.js.map +1 -1
  747. package/dist/esm/security/authentications/scim/scim-provisioning-config.shared.schemas.d.ts.map +1 -1
  748. package/dist/esm/security/authentications/scim/scim-provisioning-config.shared.schemas.js.map +1 -1
  749. package/dist/esm/security/authentications/scim/scim-tokens.shared.resources-config.schemas.d.ts.map +1 -1
  750. package/dist/esm/security/authentications/scim/scim-tokens.shared.resources-config.schemas.js.map +1 -1
  751. package/dist/esm/security/authentications/scim/scim-tokens.shared.schemas.d.ts.map +1 -1
  752. package/dist/esm/security/authentications/scim/scim-tokens.shared.schemas.js.map +1 -1
  753. package/dist/esm/security/authentications/service-provider-client-authentication.shared.schemas.d.ts.map +1 -1
  754. package/dist/esm/security/authentications/service-provider-client-authentication.shared.schemas.js.map +1 -1
  755. package/dist/esm/security/authentications/siem/siem-delivery-dlq.shared.resources-config.schemas.d.ts.map +1 -1
  756. package/dist/esm/security/authentications/siem/siem-delivery-dlq.shared.resources-config.schemas.js.map +1 -1
  757. package/dist/esm/security/authentications/siem/siem-delivery-dlq.shared.schemas.d.ts.map +1 -1
  758. package/dist/esm/security/authentications/siem/siem-delivery-dlq.shared.schemas.js.map +1 -1
  759. package/dist/esm/security/authentications/siem/siem-delivery-outbox.shared.resources-config.schemas.d.ts.map +1 -1
  760. package/dist/esm/security/authentications/siem/siem-delivery-outbox.shared.resources-config.schemas.js.map +1 -1
  761. package/dist/esm/security/authentications/siem/siem-delivery-outbox.shared.schemas.d.ts.map +1 -1
  762. package/dist/esm/security/authentications/siem/siem-delivery-outbox.shared.schemas.js.map +1 -1
  763. package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.d.ts.map +1 -1
  764. package/dist/esm/security/authentications/siem/siem-delivery-reliability-contract.shared.js.map +1 -1
  765. package/dist/esm/security/authentications/siem/siem-export-config.shared.resources-config.schemas.d.ts.map +1 -1
  766. package/dist/esm/security/authentications/siem/siem-export-config.shared.resources-config.schemas.js.map +1 -1
  767. package/dist/esm/security/authentications/siem/siem-export-config.shared.schemas.d.ts.map +1 -1
  768. package/dist/esm/security/authentications/siem/siem-export-config.shared.schemas.js.map +1 -1
  769. package/dist/esm/security/authentications/sso/sso-config.shared.resources-config.schemas.d.ts.map +1 -1
  770. package/dist/esm/security/authentications/sso/sso-config.shared.resources-config.schemas.js.map +1 -1
  771. package/dist/esm/security/authentications/sso/sso-config.shared.schemas.d.ts.map +1 -1
  772. package/dist/esm/security/authentications/sso/sso-config.shared.schemas.js.map +1 -1
  773. package/dist/esm/security/authentications/sso/sso-connection.shared.resources-config.schemas.d.ts.map +1 -1
  774. package/dist/esm/security/authentications/sso/sso-connection.shared.resources-config.schemas.js.map +1 -1
  775. package/dist/esm/security/authentications/sso/sso-connection.shared.schemas.d.ts.map +1 -1
  776. package/dist/esm/security/authentications/sso/sso-connection.shared.schemas.js.map +1 -1
  777. package/dist/esm/security/authorizations/administrative-continuity.shared.schemas.d.ts.map +1 -1
  778. package/dist/esm/security/authorizations/administrative-continuity.shared.schemas.js.map +1 -1
  779. package/dist/esm/security/authorizations/application-access-grants.shared.resources-config.schemas.d.ts.map +1 -1
  780. package/dist/esm/security/authorizations/application-access-grants.shared.resources-config.schemas.js.map +1 -1
  781. package/dist/esm/security/authorizations/application-access-grants.shared.schemas.d.ts.map +1 -1
  782. package/dist/esm/security/authorizations/application-access-grants.shared.schemas.js.map +1 -1
  783. package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.d.ts.map +1 -1
  784. package/dist/esm/security/authorizations/platform-access-grants.shared.resources-config.schemas.js.map +1 -1
  785. package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.d.ts.map +1 -1
  786. package/dist/esm/security/authorizations/platform-access-grants.shared.schemas.js.map +1 -1
  787. package/dist/esm/security/authorizations/roles.shared.defaults.d.ts.map +1 -1
  788. package/dist/esm/security/authorizations/roles.shared.defaults.js.map +1 -1
  789. package/dist/esm/security/authorizations/roles.shared.schemas.d.ts.map +1 -1
  790. package/dist/esm/security/authorizations/roles.shared.schemas.js.map +1 -1
  791. package/dist/esm/security/authorizations/roles.shared.utils.d.ts.map +1 -1
  792. package/dist/esm/security/authorizations/roles.shared.utils.js.map +1 -1
  793. package/dist/esm/security/connected-accounts/provider-connection-listing.shared.schemas.d.ts.map +1 -1
  794. package/dist/esm/security/connected-accounts/provider-connection-listing.shared.schemas.js.map +1 -1
  795. package/dist/esm/security/connected-accounts/provider-credentials-organization.shared.resources-config.schemas.d.ts.map +1 -1
  796. package/dist/esm/security/connected-accounts/provider-credentials-organization.shared.resources-config.schemas.js.map +1 -1
  797. package/dist/esm/security/connected-accounts/provider-credentials-user.shared.resources-config.schemas.d.ts.map +1 -1
  798. package/dist/esm/security/connected-accounts/provider-credentials-user.shared.resources-config.schemas.js.map +1 -1
  799. package/dist/esm/security/connected-accounts/provider-credentials.shared.schemas.d.ts.map +1 -1
  800. package/dist/esm/security/connected-accounts/provider-credentials.shared.schemas.js.map +1 -1
  801. package/dist/esm/security/credential-rotation-grace.shared.utils.d.ts.map +1 -1
  802. package/dist/esm/security/credential-rotation-grace.shared.utils.js.map +1 -1
  803. package/dist/esm/security/crypto-keys/crypto-keys.shared.schemas.d.ts.map +1 -1
  804. package/dist/esm/security/crypto-keys/crypto-keys.shared.schemas.js.map +1 -1
  805. package/dist/esm/security/oauth-clients/oauth-clients-application.shared.resources-config.schemas.d.ts.map +1 -1
  806. package/dist/esm/security/oauth-clients/oauth-clients-application.shared.resources-config.schemas.js.map +1 -1
  807. package/dist/esm/security/oauth-clients/oauth-clients-organization.shared.resources-config.schemas.d.ts.map +1 -1
  808. package/dist/esm/security/oauth-clients/oauth-clients-organization.shared.resources-config.schemas.js.map +1 -1
  809. package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.d.ts.map +1 -1
  810. package/dist/esm/security/oauth-clients/oauth-clients.shared.schemas.js.map +1 -1
  811. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.resources-config.schemas.d.ts.map +1 -1
  812. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.resources-config.schemas.js.map +1 -1
  813. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.d.ts.map +1 -1
  814. package/dist/esm/security/oauth-clients/oauth-consent-grants.shared.schemas.js.map +1 -1
  815. package/dist/esm/security/oauth-clients/oauth-resource-server.shared.schemas.d.ts.map +1 -1
  816. package/dist/esm/security/oauth-clients/oauth-resource-server.shared.schemas.js.map +1 -1
  817. package/dist/esm/security/outbound-target-control.shared.schemas.d.ts.map +1 -1
  818. package/dist/esm/security/outbound-target-control.shared.schemas.js.map +1 -1
  819. package/dist/esm/security/submission-challenge/submission-challenge.shared.d.ts.map +1 -1
  820. package/dist/esm/security/submission-challenge/submission-challenge.shared.js.map +1 -1
  821. package/dist/esm/systems-of-record/system-of-record-actions.shared.schemas.d.ts.map +1 -1
  822. package/dist/esm/systems-of-record/system-of-record-actions.shared.schemas.js.map +1 -1
  823. package/dist/esm/systems-of-record/system-of-record-credential-kind.shared.d.ts.map +1 -1
  824. package/dist/esm/systems-of-record/system-of-record-credential-kind.shared.js.map +1 -1
  825. package/dist/esm/systems-of-record/system-of-record-declaration.shared.schemas.d.ts.map +1 -1
  826. package/dist/esm/systems-of-record/system-of-record-declaration.shared.schemas.js.map +1 -1
  827. package/dist/esm/systems-of-record/system-of-record-env.shared.d.ts.map +1 -1
  828. package/dist/esm/systems-of-record/system-of-record-env.shared.js.map +1 -1
  829. package/dist/esm/systems-of-record/system-of-record-error-codes.shared.d.ts.map +1 -1
  830. package/dist/esm/systems-of-record/system-of-record-error-codes.shared.js.map +1 -1
  831. package/dist/esm/systems-of-record/system-of-record-facet.shared.schemas.d.ts.map +1 -1
  832. package/dist/esm/systems-of-record/system-of-record-facet.shared.schemas.js.map +1 -1
  833. package/dist/esm/systems-of-record/system-of-record-partition-assignments.shared.resources-config.schemas.d.ts.map +1 -1
  834. package/dist/esm/systems-of-record/system-of-record-partition-assignments.shared.resources-config.schemas.js.map +1 -1
  835. package/dist/esm/systems-of-record/system-of-record-partition-assignments.shared.schemas.d.ts.map +1 -1
  836. package/dist/esm/systems-of-record/system-of-record-partition-assignments.shared.schemas.js.map +1 -1
  837. package/dist/esm/testing/resource-config-builders.d.ts.map +1 -1
  838. package/dist/esm/testing/resource-config-builders.js.map +1 -1
  839. package/dist/esm/testing.d.ts.map +1 -1
  840. package/dist/esm/testing.js.map +1 -1
  841. package/dist/esm/users/anonymous-user-marketing-metadata.shared.schemas.d.ts.map +1 -1
  842. package/dist/esm/users/anonymous-user-marketing-metadata.shared.schemas.js.map +1 -1
  843. package/dist/esm/users/anonymous-users.shared.resources-config.schemas.d.ts.map +1 -1
  844. package/dist/esm/users/anonymous-users.shared.resources-config.schemas.js.map +1 -1
  845. package/dist/esm/users/anonymous-users.shared.schema.d.ts.map +1 -1
  846. package/dist/esm/users/anonymous-users.shared.schema.js.map +1 -1
  847. package/dist/esm/users/inbound-contacts.shared.resources-config.schemas.d.ts.map +1 -1
  848. package/dist/esm/users/inbound-contacts.shared.resources-config.schemas.js.map +1 -1
  849. package/dist/esm/users/inbound-contacts.shared.schemas.d.ts.map +1 -1
  850. package/dist/esm/users/inbound-contacts.shared.schemas.js.map +1 -1
  851. package/dist/esm/users/user-consent-decision.shared.utils.d.ts.map +1 -1
  852. package/dist/esm/users/user-consent-decision.shared.utils.js.map +1 -1
  853. package/dist/esm/users/user-credentials.shared.resources-config.schemas.d.ts.map +1 -1
  854. package/dist/esm/users/user-credentials.shared.resources-config.schemas.js.map +1 -1
  855. package/dist/esm/users/user-credentials.shared.schemas.d.ts.map +1 -1
  856. package/dist/esm/users/user-credentials.shared.schemas.js.map +1 -1
  857. package/dist/esm/users/user-identity-links.shared.resources-config.schemas.d.ts.map +1 -1
  858. package/dist/esm/users/user-identity-links.shared.resources-config.schemas.js.map +1 -1
  859. package/dist/esm/users/user-identity-links.shared.schemas.d.ts.map +1 -1
  860. package/dist/esm/users/user-identity-links.shared.schemas.js.map +1 -1
  861. package/dist/esm/users/user-preferences-reset.shared.utils.d.ts.map +1 -1
  862. package/dist/esm/users/user-preferences-reset.shared.utils.js.map +1 -1
  863. package/dist/esm/users/user-preferences.shared.resources-config.schemas.d.ts.map +1 -1
  864. package/dist/esm/users/user-preferences.shared.resources-config.schemas.js.map +1 -1
  865. package/dist/esm/users/user-profiles.shared.resources-config.schemas.d.ts.map +1 -1
  866. package/dist/esm/users/user-profiles.shared.resources-config.schemas.js.map +1 -1
  867. package/dist/esm/users/user-self-preferences.shared.resources-config.schemas.d.ts.map +1 -1
  868. package/dist/esm/users/user-self-preferences.shared.resources-config.schemas.js.map +1 -1
  869. package/dist/esm/users/user-self-profiles.shared.resources-config.schemas.d.ts.map +1 -1
  870. package/dist/esm/users/user-self-profiles.shared.resources-config.schemas.js.map +1 -1
  871. package/dist/esm/users/user-self.shared.resources-config.schemas.d.ts.map +1 -1
  872. package/dist/esm/users/user-self.shared.resources-config.schemas.js.map +1 -1
  873. package/dist/esm/users/users.shared.resources-config.schemas.d.ts.map +1 -1
  874. package/dist/esm/users/users.shared.resources-config.schemas.js.map +1 -1
  875. package/dist/esm/users/users.shared.schemas.d.ts.map +1 -1
  876. package/dist/esm/users/users.shared.schemas.js.map +1 -1
  877. package/package.json +4 -4
  878. package/dist/esm/__tests__/setup.d.ts +0 -2
  879. package/dist/esm/__tests__/setup.d.ts.map +0 -1
  880. package/dist/esm/__tests__/setup.js +0 -19
  881. package/dist/esm/__tests__/setup.js.map +0 -1
  882. package/dist/tsconfig.build.tsbuildinfo +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"personal-data-category.shared.schemas.js","sourceRoot":"","sources":["../../../../src/compliance/privacy/personal-data-category.shared.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["import { getDataCategories, getImpersonalizeTreatment, getPortabilityProvenance, isOtpField, isPasswordField, isWriteOnlySecretField } from '@wildo-ai/zod-decorators';\nimport { z } from 'zod';\n\nimport { resolveSubjectExportObjectShapeThroughWrappers } from './subject-export.shared.schemas';\n\n/**\n * What KIND of personal data a field holds — the vocabulary a privacy notice enumerates when it\n * answers \"which categories of personal data do you process\".\n *\n * ⚠️ NOT `Compliance_DataClassification`, and the near-miss is why this exists. That enum is a\n * four-level SENSITIVITY ladder (public / internal / confidential / restricted) applied to\n * flows-actors configuration: it answers \"how protected must this be\", not \"what kind of personal\n * data is this\". Using it as a category vocabulary produces a notice describing protection levels\n * where a reader expects data types.\n *\n * ⚠️ NOT a sensitivity, a retention class, a provenance, or a scrub treatment. A single field is\n * routinely all five at once — `CONTACT_DETAILS`, retained for 30 days, subject-provided, masked on\n * erasure. Each axis has its own declaration and they are deliberately not merged.\n *\n * **The ordinary members are coarse on purpose; the special ones are not.** Ordinary categories are\n * a framework's judgement about a useful grouping, and a granularity nobody maintains produces an\n * inventory that is precise and wrong. The special-category members are the LAW's own list, closed\n * by GDPR Art. 9(1), and they are enumerated individually because \"special category data\" alone is\n * not a disclosure — a reader is entitled to know it is health data rather than political opinion,\n * and each carries its own Art. 9(2) condition.\n *\n * @example\n * // The common case: one category, on the field that holds it.\n * email: z.email().dataCategories(PersonalDataCategory.CONTACT_DETAILS)\n * @example\n * // A field that genuinely spans two. An array never forces the author to pick a lie.\n * dietaryNotes: z.string().dataCategories([PersonalDataCategory.USER_CONTENT, PersonalDataCategory.SPECIAL_CATEGORY_HEALTH])\n *\n * @wildo_source:part:start zod.decorators.data-categories facet:layer:shared facet:family:decorator facet:kind:api facet:audience:app-developer\n */\nexport enum PersonalDataCategory {\n /** Who the person is: name, username, display name, account identifier, avatar. */\n IDENTITY = 'identity',\n /** How the person is reached: email address, telephone number, postal address. */\n CONTACT_DETAILS = 'contact-details',\n /**\n * What proves the person is who they claim: passwords, MFA secrets, API keys, session tokens.\n *\n * Rarely authored by hand — the fact producer DERIVES this category from `.isPassword()`,\n * `.isOtp()` and `.isWriteOnlySecret()`, which are declarations the application already makes.\n * Declare it explicitly only for a credential those markers do not cover.\n */\n CREDENTIALS = 'credentials',\n /** Money: payment-method references, invoices, billing details, transaction history. */\n FINANCIAL = 'financial',\n /** What the person did in the product: activity records, timestamps, device and telemetry data. */\n USAGE = 'usage',\n /** Where the person is or was: coordinates, derived region, IP-inferred location. */\n LOCATION = 'location',\n /**\n * What the person wrote or uploaded: free text, notes, attachments.\n *\n * ⚠️ Free text is the category that can silently contain any other one — a \"notes\" field may hold\n * health information nobody declared. Declaring `USER_CONTENT` states what the field is FOR; it\n * does not certify what it will contain, and no schema can. Where a free-text field is\n * FORESEEABLY used for a special category, declare that member alongside.\n */\n USER_CONTENT = 'user-content',\n /** The person's working life: employer, job title, professional relationship to the operator. */\n PROFESSIONAL = 'professional',\n\n // ── GDPR Art. 9(1), verbatim and closed. Processing needs an Art. 9(2) condition of its own,\n // over and above the Art. 6 lawful basis every other member already needs.\n /** Art. 9(1): racial or ethnic origin. */\n SPECIAL_CATEGORY_RACIAL_OR_ETHNIC_ORIGIN = 'special-category:racial-or-ethnic-origin',\n /** Art. 9(1): political opinions. */\n SPECIAL_CATEGORY_POLITICAL_OPINIONS = 'special-category:political-opinions',\n /** Art. 9(1): religious or philosophical beliefs. */\n SPECIAL_CATEGORY_RELIGIOUS_OR_PHILOSOPHICAL_BELIEFS = 'special-category:religious-or-philosophical-beliefs',\n /** Art. 9(1): trade union membership. */\n SPECIAL_CATEGORY_TRADE_UNION_MEMBERSHIP = 'special-category:trade-union-membership',\n /** Art. 9(1): genetic data. */\n SPECIAL_CATEGORY_GENETIC = 'special-category:genetic',\n /**\n * Art. 9(1): biometric data processed FOR THE PURPOSE OF uniquely identifying a natural person.\n *\n * The purpose qualifier is part of the law's definition, not a footnote: a photograph is ordinary\n * `IDENTITY` data until it is put through facial recognition, at which point it becomes this.\n */\n SPECIAL_CATEGORY_BIOMETRIC = 'special-category:biometric',\n /** Art. 9(1): data concerning health. */\n SPECIAL_CATEGORY_HEALTH = 'special-category:health',\n /** Art. 9(1): data concerning a natural person's sex life or sexual orientation. */\n SPECIAL_CATEGORY_SEX_LIFE_OR_SEXUAL_ORIENTATION = 'special-category:sex-life-or-sexual-orientation',\n\n /**\n * GDPR Art. 10: criminal convictions and offences.\n *\n * Deliberately NOT a member of {@link SPECIAL_CATEGORY_PERSONAL_DATA_CATEGORIES}. Art. 10 is a\n * separate article with a different condition — processing requires official authority or a\n * Member State law — so folding it into the Art. 9 set would attach the wrong legal test to it.\n */\n CRIMINAL_OFFENCE = 'criminal-offence',\n}\n\n/**\n * What the ENGINE deliberately does NOT declare, so its silence reads as a decision.\n *\n * Measured 2026-08-30: 48 of the 85 engine resource configurations declare at least one category. The rest are silent on\n * purpose, in four groups:\n *\n * - **System machinery is not personal data, even when the row carries a `userId`.** A queue\n * execution, an entitlement limit, an unread counter, a token-budget counter — each exists so the\n * platform can do its work, and the person's identifier on it is the LINK, not the datum. This\n * group is the one that is easiest to get wrong, because such rows legitimately appear in a\n * subject export: `systemAccessPolicy.exportSubject` means *rows here relate to a subject and\n * belong in their bundle*, which is true by linkage alone. It does not mean the row holds a datum\n * about them, and reading it that way once put `jobExecutions` in this inventory.\n *\n * - **A legal person is not a data subject.** `organizations`, `organizationUnits`,\n * `organizationProfiles`, `organizationPreferences` and their siblings describe a COMPANY. GDPR\n * Recital 14 excludes the processing of data concerning legal persons, so declaring\n * `CONTACT_DETAILS` on an organization's switchboard number would make every notice claim the\n * operator holds an individual's contact details that it does not. A small company's number is\n * often a person's — that is a fact about the customer's data, not about this field's meaning.\n * - **Configuration is not data about anyone.** SSO/SCIM/webhook configuration, API keys and OAuth\n * clients owned by an organization, products, prices, promotions, ETL cursors. An organization's\n * API key is a bearer secret whose subject is the organization; the person who minted it is not\n * recorded on the row.\n * - **A foreign key is LINKAGE, not a category.** `userId` on a usage row is what makes that usage\n * personal; the category of the row's CONTENT is what a notice enumerates. Declaring `IDENTITY`\n * on every owner FK would put \"identity data\" against resources holding no name, and tell a\n * reader nothing the linkage does not already imply. The machinery group above is this same rule\n * applied one level up, at the row rather than the field.\n *\n * The line between the first group and a real answer is not always obvious, and one pair is worth\n * keeping side by side: a metered USAGE RECORD is declared while a TOKEN-BUDGET counter is not.\n * Both count something a person consumed. The usage record is a per-event history with a timestamp —\n * a record of what they did, which an Art. 15 copy must contain. The budget counter is a single\n * mutable number that exists so a limiter can refuse the next call; nothing about the person\n * survives in it. Ask what the row is FOR, not what it counts.\n *\n * Recorded here because absence is invisible. A future reader finding `organizationProfiles`\n * undeclared should be able to see that it was considered, not assume it was missed — the same\n * discipline a justified `N/A` serves in a verification matrix.\n */\n\n/** Zod form of {@link PersonalDataCategory}. */\nexport const PersonalDataCategorySchema: z.ZodEnum<typeof PersonalDataCategory> = z.enum(PersonalDataCategory);\n\n/**\n * The GDPR Art. 9(1) members, as a set — the one place the Art. 9 line is drawn.\n *\n * Derived by PREFIX rather than hand-listed: every Art. 9 member's wire value begins\n * `special-category:`, so a member added to the enum joins this set automatically. A hand-written\n * list would be a second enumeration of a closed vocabulary, and the failure mode is silent — a new\n * Art. 9 member omitted from it reads as ordinary personal data.\n */\nexport const SPECIAL_CATEGORY_PERSONAL_DATA_CATEGORIES: ReadonlySet<PersonalDataCategory> = new Set(\n Object.values(PersonalDataCategory).filter((category) => category.startsWith('special-category:')),\n);\n\n/**\n * Does this category carry the GDPR Art. 9 condition?\n *\n * `false` for {@link PersonalDataCategory.CRIMINAL_OFFENCE} — see that member's note. Callers that\n * need \"needs a condition beyond Art. 6\" must test both.\n */\nexport function isSpecialCategoryPersonalData(category: PersonalDataCategory): boolean {\n return SPECIAL_CATEGORY_PERSONAL_DATA_CATEGORIES.has(category);\n}\n/** @wildo_source:part:end zod.decorators.data-categories */\n\n/** Every declared value that is not a {@link PersonalDataCategory} member. */\nexport function unknownPersonalDataCategories(declared: readonly string[]): readonly string[] {\n const members = new Set<string>(Object.values(PersonalDataCategory));\n return declared.filter((value) => !members.has(value));\n}\n\n/**\n * Why the fact producer believes a field holds personal data, when the field itself declares no\n * category. Each basis is a declaration the application ALREADY made for another purpose — never an\n * inference from the field's name.\n */\nexport enum PersonalDataFieldBasis {\n /** The field declares a category outright. */\n DECLARED = 'declared',\n /** `.isPassword()` / `.isOtp()` / `.isWriteOnlySecret()` — a credential by the application's own marking. */\n CREDENTIAL_MARKER = 'credential-marker',\n /** `.impersonalizeWith()` — the application declared this value must be scrubbed on erasure. */\n ERASURE_SCRUB = 'erasure-scrub',\n /** `.portabilityProvenance()` — the application declared where this value about the subject came from. */\n PORTABILITY_PROVENANCE = 'portability-provenance',\n}\n\n/** One field's category answer within a resource. */\nexport interface PersonalDataFieldCategories {\n readonly fieldName: string;\n readonly basis: PersonalDataFieldBasis;\n /** Empty exactly when `basis` is not `DECLARED` and no category could be derived. */\n readonly categories: readonly PersonalDataCategory[];\n}\n\n/** What one resource's main schema says about the categories of personal data it holds. */\nexport interface ResourcePersonalDataCategoryProfile {\n /** Fields carrying an explicit `.dataCategories()` declaration. */\n readonly declaredFields: readonly PersonalDataFieldCategories[];\n /**\n * Fields the application has ALREADY declared to be personal — through a credential marker, an\n * erasure scrub treatment, or a portability provenance — that carry no category.\n *\n * This is the actionable gap: the omission is provably an omission rather than a judgement that\n * the field is not personal, because the application said it was personal by another door.\n */\n readonly uncategorizedPersonalFields: readonly PersonalDataFieldCategories[];\n /** The union of every category the resource declares, derived credentials included. */\n readonly categories: readonly PersonalDataCategory[];\n}\n\nconst CATEGORY_ORDER: readonly PersonalDataCategory[] = Object.values(PersonalDataCategory);\n\n/**\n * Dedupe and order categories by the enum's own declaration order.\n *\n * Exported because every consumer that unions categories — across fields, across resources, across\n * an application — needs the same order, and a document that reorders its own category list between\n * runs reads as if the answer changed. One authority for the order, rather than each caller sorting\n * alphabetically (which would interleave the Art. 9 members through the ordinary ones) or by first\n * appearance (which depends on resource iteration order).\n */\nexport function sortPersonalDataCategories(categories: Iterable<PersonalDataCategory>): readonly PersonalDataCategory[] {\n return [...new Set(categories)].sort((left, right) => CATEGORY_ORDER.indexOf(left) - CATEGORY_ORDER.indexOf(right));\n}\n\n/**\n * Read a resource's declared data categories off its main schema, and report the fields the\n * application has already admitted are personal but has not categorized.\n *\n * **TOP-LEVEL fields only**, which is a real limit and is stated rather than hidden: the walk uses\n * the same shape resolver the subject-export compiler uses, and that resolver merges union options\n * without descending into a nested `ZodObject`. A category declared on `billingContact.email` is\n * therefore invisible here — exactly as an `.impersonalizeWith()` declared there is invisible to\n * the scrub writer, which is why the retention guard makes a nested treatment a BOOT ERROR. A\n * nested category is not a boot error (it breaks nothing at runtime); it simply does not reach a\n * notice, so declare categories at the top level.\n *\n * **Derivation is from DECLARATIONS, never from names.** `CREDENTIALS` is inferred from\n * `.isPassword()` / `.isOtp()` / `.isWriteOnlySecret()` because those are markers the author wrote.\n * Nothing here looks at a field being called `email`, `phone` or `dateOfBirth` — a category list\n * assembled by pattern-matching identifiers is a guess presented as an inventory, and whatever the\n * guess misses is simply not disclosed.\n */\nexport function resolveResourcePersonalDataCategories(mainSchema: unknown): ResourcePersonalDataCategoryProfile {\n const shape = resolveSubjectExportObjectShapeThroughWrappers(mainSchema);\n const declaredFields: PersonalDataFieldCategories[] = [];\n const uncategorizedPersonalFields: PersonalDataFieldCategories[] = [];\n const union = new Set<PersonalDataCategory>();\n\n for (const [fieldName, rawFieldSchema] of Object.entries(shape ?? {})) {\n const fieldSchema = rawFieldSchema as z.ZodTypeAny;\n const declared = getDataCategories(fieldSchema);\n\n if (declared !== undefined && declared.length > 0) {\n const categories = sortPersonalDataCategories(declared as readonly PersonalDataCategory[]);\n declaredFields.push({ fieldName, basis: PersonalDataFieldBasis.DECLARED, categories });\n for (const category of categories) union.add(category);\n continue;\n }\n\n if (isPasswordField(fieldSchema) || isOtpField(fieldSchema) || isWriteOnlySecretField(fieldSchema)) {\n // Derived, not guessed: the author marked this a credential. It is reported as a DECLARED-\n // equivalent answer rather than a gap, because asking for `.dataCategories(CREDENTIALS)` on a\n // field already marked `.isPassword()` is a second declaration of one fact.\n declaredFields.push({\n fieldName,\n basis: PersonalDataFieldBasis.CREDENTIAL_MARKER,\n categories: [PersonalDataCategory.CREDENTIALS],\n });\n union.add(PersonalDataCategory.CREDENTIALS);\n continue;\n }\n\n if (getImpersonalizeTreatment(fieldSchema) !== undefined) {\n uncategorizedPersonalFields.push({ fieldName, basis: PersonalDataFieldBasis.ERASURE_SCRUB, categories: [] });\n continue;\n }\n\n if (getPortabilityProvenance(fieldSchema) !== undefined) {\n uncategorizedPersonalFields.push({ fieldName, basis: PersonalDataFieldBasis.PORTABILITY_PROVENANCE, categories: [] });\n }\n }\n\n return {\n declaredFields,\n uncategorizedPersonalFields,\n categories: sortPersonalDataCategories(union),\n };\n}\n"]}
1
+ {"version":3,"file":"personal-data-category.shared.schemas.js","sourceRoot":"","sources":["../../../../../src/compliance/privacy/personal-data-category.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,yBAAyB,EAAE,wBAAwB,EAAE,UAAU,EAAE,eAAe,EAAE,sBAAsB,EAAE,MAAM,0BAA0B,CAAC;AACvK,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,8CAA8C,EAAE,MAAM,iCAAiC,CAAC;AAEjG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,CAAN,IAAY,oBA+DX;AA/DD,WAAY,oBAAoB;IAC9B,mFAAmF;IACnF,6CAAqB,CAAA;IACrB,kFAAkF;IAClF,2DAAmC,CAAA;IACnC;;;;;;OAMG;IACH,mDAA2B,CAAA;IAC3B,wFAAwF;IACxF,+CAAuB,CAAA;IACvB,mGAAmG;IACnG,uCAAe,CAAA;IACf,qFAAqF;IACrF,6CAAqB,CAAA;IACrB;;;;;;;OAOG;IACH,qDAA6B,CAAA;IAC7B,iGAAiG;IACjG,qDAA6B,CAAA;IAE7B,8FAA8F;IAC9F,8EAA8E;IAC9E,0CAA0C;IAC1C,6GAAqF,CAAA;IACrF,qCAAqC;IACrC,mGAA2E,CAAA;IAC3E,qDAAqD;IACrD,mIAA2G,CAAA;IAC3G,yCAAyC;IACzC,2GAAmF,CAAA;IACnF,+BAA+B;IAC/B,6EAAqD,CAAA;IACrD;;;;;OAKG;IACH,iFAAyD,CAAA;IACzD,yCAAyC;IACzC,2EAAmD,CAAA;IACnD,oFAAoF;IACpF,2HAAmG,CAAA;IAEnG;;;;;;OAMG;IACH,6DAAqC,CAAA;AACvC,CAAC,EA/DW,oBAAoB,KAApB,oBAAoB,QA+D/B;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAwCG;AAEH,gDAAgD;AAChD,MAAM,CAAC,MAAM,0BAA0B,GAA2C,CAAC,CAAC,IAAI,CAAC,oBAAoB,CAAC,CAAC;AAE/G;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,yCAAyC,GAAsC,IAAI,GAAG,CACjG,MAAM,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,mBAAmB,CAAC,CAAC,CACnG,CAAC;AAEF;;;;;GAKG;AACH,MAAM,UAAU,6BAA6B,CAAC,QAA8B;IAC1E,OAAO,yCAAyC,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;AACjE,CAAC;AACD,4DAA4D;AAE5D,8EAA8E;AAC9E,MAAM,UAAU,6BAA6B,CAAC,QAA2B;IACvE,MAAM,OAAO,GAAG,IAAI,GAAG,CAAS,MAAM,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,CAAC;IACrE,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;AACzD,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAN,IAAY,sBASX;AATD,WAAY,sBAAsB;IAChC,8CAA8C;IAC9C,+CAAqB,CAAA;IACrB,6GAA6G;IAC7G,iEAAuC,CAAA;IACvC,gGAAgG;IAChG,yDAA+B,CAAA;IAC/B,0GAA0G;IAC1G,2EAAiD,CAAA;AACnD,CAAC,EATW,sBAAsB,KAAtB,sBAAsB,QASjC;AA0BD,MAAM,cAAc,GAAoC,MAAM,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC;AAE5F;;;;;;;;GAQG;AACH,MAAM,UAAU,0BAA0B,CAAC,UAA0C;IACnF,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC;AACtH,CAAC;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,UAAU,qCAAqC,CAAC,UAAmB;IACvE,MAAM,KAAK,GAAG,8CAA8C,CAAC,UAAU,CAAC,CAAC;IACzE,MAAM,cAAc,GAAkC,EAAE,CAAC;IACzD,MAAM,2BAA2B,GAAkC,EAAE,CAAC;IACtE,MAAM,KAAK,GAAG,IAAI,GAAG,EAAwB,CAAC;IAE9C,KAAK,MAAM,CAAC,SAAS,EAAE,cAAc,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC,EAAE,CAAC;QACtE,MAAM,WAAW,GAAG,cAA8B,CAAC;QACnD,MAAM,QAAQ,GAAG,iBAAiB,CAAC,WAAW,CAAC,CAAC;QAEhD,IAAI,QAAQ,KAAK,SAAS,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAClD,MAAM,UAAU,GAAG,0BAA0B,CAAC,QAA2C,CAAC,CAAC;YAC3F,cAAc,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,sBAAsB,CAAC,QAAQ,EAAE,UAAU,EAAE,CAAC,CAAC;YACvF,KAAK,MAAM,QAAQ,IAAI,UAAU;gBAAE,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;YACvD,SAAS;QACX,CAAC;QAED,IAAI,eAAe,CAAC,WAAW,CAAC,IAAI,UAAU,CAAC,WAAW,CAAC,IAAI,sBAAsB,CAAC,WAAW,CAAC,EAAE,CAAC;YACnG,2FAA2F;YAC3F,8FAA8F;YAC9F,4EAA4E;YAC5E,cAAc,CAAC,IAAI,CAAC;gBAClB,SAAS;gBACT,KAAK,EAAE,sBAAsB,CAAC,iBAAiB;gBAC/C,UAAU,EAAE,CAAC,oBAAoB,CAAC,WAAW,CAAC;aAC/C,CAAC,CAAC;YACH,KAAK,CAAC,GAAG,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC;YAC5C,SAAS;QACX,CAAC;QAED,IAAI,yBAAyB,CAAC,WAAW,CAAC,KAAK,SAAS,EAAE,CAAC;YACzD,2BAA2B,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,sBAAsB,CAAC,aAAa,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;YAC7G,SAAS;QACX,CAAC;QAED,IAAI,wBAAwB,CAAC,WAAW,CAAC,KAAK,SAAS,EAAE,CAAC;YACxD,2BAA2B,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,sBAAsB,CAAC,sBAAsB,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;QACxH,CAAC;IACH,CAAC;IAED,OAAO;QACL,cAAc;QACd,2BAA2B;QAC3B,UAAU,EAAE,0BAA0B,CAAC,KAAK,CAAC;KAC9C,CAAC;AACJ,CAAC","sourcesContent":["import { getDataCategories, getImpersonalizeTreatment, getPortabilityProvenance, isOtpField, isPasswordField, isWriteOnlySecretField } from '@wildo-ai/zod-decorators';\nimport { z } from 'zod';\n\nimport { resolveSubjectExportObjectShapeThroughWrappers } from './subject-export.shared.schemas';\n\n/**\n * What KIND of personal data a field holds — the vocabulary a privacy notice enumerates when it\n * answers \"which categories of personal data do you process\".\n *\n * ⚠️ NOT `Compliance_DataClassification`, and the near-miss is why this exists. That enum is a\n * four-level SENSITIVITY ladder (public / internal / confidential / restricted) applied to\n * flows-actors configuration: it answers \"how protected must this be\", not \"what kind of personal\n * data is this\". Using it as a category vocabulary produces a notice describing protection levels\n * where a reader expects data types.\n *\n * ⚠️ NOT a sensitivity, a retention class, a provenance, or a scrub treatment. A single field is\n * routinely all five at once — `CONTACT_DETAILS`, retained for 30 days, subject-provided, masked on\n * erasure. Each axis has its own declaration and they are deliberately not merged.\n *\n * **The ordinary members are coarse on purpose; the special ones are not.** Ordinary categories are\n * a framework's judgement about a useful grouping, and a granularity nobody maintains produces an\n * inventory that is precise and wrong. The special-category members are the LAW's own list, closed\n * by GDPR Art. 9(1), and they are enumerated individually because \"special category data\" alone is\n * not a disclosure — a reader is entitled to know it is health data rather than political opinion,\n * and each carries its own Art. 9(2) condition.\n *\n * @example\n * // The common case: one category, on the field that holds it.\n * email: z.email().dataCategories(PersonalDataCategory.CONTACT_DETAILS)\n * @example\n * // A field that genuinely spans two. An array never forces the author to pick a lie.\n * dietaryNotes: z.string().dataCategories([PersonalDataCategory.USER_CONTENT, PersonalDataCategory.SPECIAL_CATEGORY_HEALTH])\n *\n * @wildo_source:part:start zod.decorators.data-categories facet:layer:shared facet:family:decorator facet:kind:api facet:audience:app-developer\n */\nexport enum PersonalDataCategory {\n /** Who the person is: name, username, display name, account identifier, avatar. */\n IDENTITY = 'identity',\n /** How the person is reached: email address, telephone number, postal address. */\n CONTACT_DETAILS = 'contact-details',\n /**\n * What proves the person is who they claim: passwords, MFA secrets, API keys, session tokens.\n *\n * Rarely authored by hand — the fact producer DERIVES this category from `.isPassword()`,\n * `.isOtp()` and `.isWriteOnlySecret()`, which are declarations the application already makes.\n * Declare it explicitly only for a credential those markers do not cover.\n */\n CREDENTIALS = 'credentials',\n /** Money: payment-method references, invoices, billing details, transaction history. */\n FINANCIAL = 'financial',\n /** What the person did in the product: activity records, timestamps, device and telemetry data. */\n USAGE = 'usage',\n /** Where the person is or was: coordinates, derived region, IP-inferred location. */\n LOCATION = 'location',\n /**\n * What the person wrote or uploaded: free text, notes, attachments.\n *\n * ⚠️ Free text is the category that can silently contain any other one — a \"notes\" field may hold\n * health information nobody declared. Declaring `USER_CONTENT` states what the field is FOR; it\n * does not certify what it will contain, and no schema can. Where a free-text field is\n * FORESEEABLY used for a special category, declare that member alongside.\n */\n USER_CONTENT = 'user-content',\n /** The person's working life: employer, job title, professional relationship to the operator. */\n PROFESSIONAL = 'professional',\n\n // ── GDPR Art. 9(1), verbatim and closed. Processing needs an Art. 9(2) condition of its own,\n // over and above the Art. 6 lawful basis every other member already needs.\n /** Art. 9(1): racial or ethnic origin. */\n SPECIAL_CATEGORY_RACIAL_OR_ETHNIC_ORIGIN = 'special-category:racial-or-ethnic-origin',\n /** Art. 9(1): political opinions. */\n SPECIAL_CATEGORY_POLITICAL_OPINIONS = 'special-category:political-opinions',\n /** Art. 9(1): religious or philosophical beliefs. */\n SPECIAL_CATEGORY_RELIGIOUS_OR_PHILOSOPHICAL_BELIEFS = 'special-category:religious-or-philosophical-beliefs',\n /** Art. 9(1): trade union membership. */\n SPECIAL_CATEGORY_TRADE_UNION_MEMBERSHIP = 'special-category:trade-union-membership',\n /** Art. 9(1): genetic data. */\n SPECIAL_CATEGORY_GENETIC = 'special-category:genetic',\n /**\n * Art. 9(1): biometric data processed FOR THE PURPOSE OF uniquely identifying a natural person.\n *\n * The purpose qualifier is part of the law's definition, not a footnote: a photograph is ordinary\n * `IDENTITY` data until it is put through facial recognition, at which point it becomes this.\n */\n SPECIAL_CATEGORY_BIOMETRIC = 'special-category:biometric',\n /** Art. 9(1): data concerning health. */\n SPECIAL_CATEGORY_HEALTH = 'special-category:health',\n /** Art. 9(1): data concerning a natural person's sex life or sexual orientation. */\n SPECIAL_CATEGORY_SEX_LIFE_OR_SEXUAL_ORIENTATION = 'special-category:sex-life-or-sexual-orientation',\n\n /**\n * GDPR Art. 10: criminal convictions and offences.\n *\n * Deliberately NOT a member of {@link SPECIAL_CATEGORY_PERSONAL_DATA_CATEGORIES}. Art. 10 is a\n * separate article with a different condition — processing requires official authority or a\n * Member State law — so folding it into the Art. 9 set would attach the wrong legal test to it.\n */\n CRIMINAL_OFFENCE = 'criminal-offence',\n}\n\n/**\n * What the ENGINE deliberately does NOT declare, so its silence reads as a decision.\n *\n * Measured 2026-08-30: 48 of the 85 engine resource configurations declare at least one category. The rest are silent on\n * purpose, in four groups:\n *\n * - **System machinery is not personal data, even when the row carries a `userId`.** A queue\n * execution, an entitlement limit, an unread counter, a token-budget counter — each exists so the\n * platform can do its work, and the person's identifier on it is the LINK, not the datum. This\n * group is the one that is easiest to get wrong, because such rows legitimately appear in a\n * subject export: `systemAccessPolicy.exportSubject` means *rows here relate to a subject and\n * belong in their bundle*, which is true by linkage alone. It does not mean the row holds a datum\n * about them, and reading it that way once put `jobExecutions` in this inventory.\n *\n * - **A legal person is not a data subject.** `organizations`, `organizationUnits`,\n * `organizationProfiles`, `organizationPreferences` and their siblings describe a COMPANY. GDPR\n * Recital 14 excludes the processing of data concerning legal persons, so declaring\n * `CONTACT_DETAILS` on an organization's switchboard number would make every notice claim the\n * operator holds an individual's contact details that it does not. A small company's number is\n * often a person's — that is a fact about the customer's data, not about this field's meaning.\n * - **Configuration is not data about anyone.** SSO/SCIM/webhook configuration, API keys and OAuth\n * clients owned by an organization, products, prices, promotions, ETL cursors. An organization's\n * API key is a bearer secret whose subject is the organization; the person who minted it is not\n * recorded on the row.\n * - **A foreign key is LINKAGE, not a category.** `userId` on a usage row is what makes that usage\n * personal; the category of the row's CONTENT is what a notice enumerates. Declaring `IDENTITY`\n * on every owner FK would put \"identity data\" against resources holding no name, and tell a\n * reader nothing the linkage does not already imply. The machinery group above is this same rule\n * applied one level up, at the row rather than the field.\n *\n * The line between the first group and a real answer is not always obvious, and one pair is worth\n * keeping side by side: a metered USAGE RECORD is declared while a TOKEN-BUDGET counter is not.\n * Both count something a person consumed. The usage record is a per-event history with a timestamp —\n * a record of what they did, which an Art. 15 copy must contain. The budget counter is a single\n * mutable number that exists so a limiter can refuse the next call; nothing about the person\n * survives in it. Ask what the row is FOR, not what it counts.\n *\n * Recorded here because absence is invisible. A future reader finding `organizationProfiles`\n * undeclared should be able to see that it was considered, not assume it was missed — the same\n * discipline a justified `N/A` serves in a verification matrix.\n */\n\n/** Zod form of {@link PersonalDataCategory}. */\nexport const PersonalDataCategorySchema: z.ZodEnum<typeof PersonalDataCategory> = z.enum(PersonalDataCategory);\n\n/**\n * The GDPR Art. 9(1) members, as a set — the one place the Art. 9 line is drawn.\n *\n * Derived by PREFIX rather than hand-listed: every Art. 9 member's wire value begins\n * `special-category:`, so a member added to the enum joins this set automatically. A hand-written\n * list would be a second enumeration of a closed vocabulary, and the failure mode is silent — a new\n * Art. 9 member omitted from it reads as ordinary personal data.\n */\nexport const SPECIAL_CATEGORY_PERSONAL_DATA_CATEGORIES: ReadonlySet<PersonalDataCategory> = new Set(\n Object.values(PersonalDataCategory).filter((category) => category.startsWith('special-category:')),\n);\n\n/**\n * Does this category carry the GDPR Art. 9 condition?\n *\n * `false` for {@link PersonalDataCategory.CRIMINAL_OFFENCE} — see that member's note. Callers that\n * need \"needs a condition beyond Art. 6\" must test both.\n */\nexport function isSpecialCategoryPersonalData(category: PersonalDataCategory): boolean {\n return SPECIAL_CATEGORY_PERSONAL_DATA_CATEGORIES.has(category);\n}\n/** @wildo_source:part:end zod.decorators.data-categories */\n\n/** Every declared value that is not a {@link PersonalDataCategory} member. */\nexport function unknownPersonalDataCategories(declared: readonly string[]): readonly string[] {\n const members = new Set<string>(Object.values(PersonalDataCategory));\n return declared.filter((value) => !members.has(value));\n}\n\n/**\n * Why the fact producer believes a field holds personal data, when the field itself declares no\n * category. Each basis is a declaration the application ALREADY made for another purpose — never an\n * inference from the field's name.\n */\nexport enum PersonalDataFieldBasis {\n /** The field declares a category outright. */\n DECLARED = 'declared',\n /** `.isPassword()` / `.isOtp()` / `.isWriteOnlySecret()` — a credential by the application's own marking. */\n CREDENTIAL_MARKER = 'credential-marker',\n /** `.impersonalizeWith()` — the application declared this value must be scrubbed on erasure. */\n ERASURE_SCRUB = 'erasure-scrub',\n /** `.portabilityProvenance()` — the application declared where this value about the subject came from. */\n PORTABILITY_PROVENANCE = 'portability-provenance',\n}\n\n/** One field's category answer within a resource. */\nexport interface PersonalDataFieldCategories {\n readonly fieldName: string;\n readonly basis: PersonalDataFieldBasis;\n /** Empty exactly when `basis` is not `DECLARED` and no category could be derived. */\n readonly categories: readonly PersonalDataCategory[];\n}\n\n/** What one resource's main schema says about the categories of personal data it holds. */\nexport interface ResourcePersonalDataCategoryProfile {\n /** Fields carrying an explicit `.dataCategories()` declaration. */\n readonly declaredFields: readonly PersonalDataFieldCategories[];\n /**\n * Fields the application has ALREADY declared to be personal — through a credential marker, an\n * erasure scrub treatment, or a portability provenance — that carry no category.\n *\n * This is the actionable gap: the omission is provably an omission rather than a judgement that\n * the field is not personal, because the application said it was personal by another door.\n */\n readonly uncategorizedPersonalFields: readonly PersonalDataFieldCategories[];\n /** The union of every category the resource declares, derived credentials included. */\n readonly categories: readonly PersonalDataCategory[];\n}\n\nconst CATEGORY_ORDER: readonly PersonalDataCategory[] = Object.values(PersonalDataCategory);\n\n/**\n * Dedupe and order categories by the enum's own declaration order.\n *\n * Exported because every consumer that unions categories — across fields, across resources, across\n * an application — needs the same order, and a document that reorders its own category list between\n * runs reads as if the answer changed. One authority for the order, rather than each caller sorting\n * alphabetically (which would interleave the Art. 9 members through the ordinary ones) or by first\n * appearance (which depends on resource iteration order).\n */\nexport function sortPersonalDataCategories(categories: Iterable<PersonalDataCategory>): readonly PersonalDataCategory[] {\n return [...new Set(categories)].sort((left, right) => CATEGORY_ORDER.indexOf(left) - CATEGORY_ORDER.indexOf(right));\n}\n\n/**\n * Read a resource's declared data categories off its main schema, and report the fields the\n * application has already admitted are personal but has not categorized.\n *\n * **TOP-LEVEL fields only**, which is a real limit and is stated rather than hidden: the walk uses\n * the same shape resolver the subject-export compiler uses, and that resolver merges union options\n * without descending into a nested `ZodObject`. A category declared on `billingContact.email` is\n * therefore invisible here — exactly as an `.impersonalizeWith()` declared there is invisible to\n * the scrub writer, which is why the retention guard makes a nested treatment a BOOT ERROR. A\n * nested category is not a boot error (it breaks nothing at runtime); it simply does not reach a\n * notice, so declare categories at the top level.\n *\n * **Derivation is from DECLARATIONS, never from names.** `CREDENTIALS` is inferred from\n * `.isPassword()` / `.isOtp()` / `.isWriteOnlySecret()` because those are markers the author wrote.\n * Nothing here looks at a field being called `email`, `phone` or `dateOfBirth` — a category list\n * assembled by pattern-matching identifiers is a guess presented as an inventory, and whatever the\n * guess misses is simply not disclosed.\n */\nexport function resolveResourcePersonalDataCategories(mainSchema: unknown): ResourcePersonalDataCategoryProfile {\n const shape = resolveSubjectExportObjectShapeThroughWrappers(mainSchema);\n const declaredFields: PersonalDataFieldCategories[] = [];\n const uncategorizedPersonalFields: PersonalDataFieldCategories[] = [];\n const union = new Set<PersonalDataCategory>();\n\n for (const [fieldName, rawFieldSchema] of Object.entries(shape ?? {})) {\n const fieldSchema = rawFieldSchema as z.ZodTypeAny;\n const declared = getDataCategories(fieldSchema);\n\n if (declared !== undefined && declared.length > 0) {\n const categories = sortPersonalDataCategories(declared as readonly PersonalDataCategory[]);\n declaredFields.push({ fieldName, basis: PersonalDataFieldBasis.DECLARED, categories });\n for (const category of categories) union.add(category);\n continue;\n }\n\n if (isPasswordField(fieldSchema) || isOtpField(fieldSchema) || isWriteOnlySecretField(fieldSchema)) {\n // Derived, not guessed: the author marked this a credential. It is reported as a DECLARED-\n // equivalent answer rather than a gap, because asking for `.dataCategories(CREDENTIALS)` on a\n // field already marked `.isPassword()` is a second declaration of one fact.\n declaredFields.push({\n fieldName,\n basis: PersonalDataFieldBasis.CREDENTIAL_MARKER,\n categories: [PersonalDataCategory.CREDENTIALS],\n });\n union.add(PersonalDataCategory.CREDENTIALS);\n continue;\n }\n\n if (getImpersonalizeTreatment(fieldSchema) !== undefined) {\n uncategorizedPersonalFields.push({ fieldName, basis: PersonalDataFieldBasis.ERASURE_SCRUB, categories: [] });\n continue;\n }\n\n if (getPortabilityProvenance(fieldSchema) !== undefined) {\n uncategorizedPersonalFields.push({ fieldName, basis: PersonalDataFieldBasis.PORTABILITY_PROVENANCE, categories: [] });\n }\n }\n\n return {\n declaredFields,\n uncategorizedPersonalFields,\n categories: sortPersonalDataCategories(union),\n };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"personal-data-declaration.shared.utils.d.ts","sourceRoot":"","sources":["../../../../src/compliance/privacy/personal-data-declaration.shared.utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,0BAA0B,EAAE,MAAM,iDAAiD,CAAC;AAGtJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,eAAe,CAAC,EAAE,uBAAuB,CAAC;IACnD,QAAQ,CAAC,iBAAiB,CAAC,EAAE,yBAAyB,CAAC;IACvD,QAAQ,CAAC,kBAAkB,CAAC,EAAE,0BAA0B,CAAC;IACzD,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,6GAA6G;AAC7G,wBAAgB,uCAAuC,CAAC,aAAa,EAAE,8BAA8B,GAAG,OAAO,CAK9G;AAED,iGAAiG;AACjG,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,mFAAmF;IACnF,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,wDAAwD,CAAC,MAAM,EAAE;IAC/E,QAAQ,CAAC,sBAAsB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,8BAA8B,CAAC,CAAC,CAAC;IAC1F,QAAQ,CAAC,wBAAwB,EAAE,SAAS,MAAM,EAAE,CAAC;CACtD,GAAG,SAAS,8BAA8B,EAAE,CAgB5C;AAED,gIAAgI;AAChI,wBAAgB,gCAAgC,CAAC,aAAa,EAAE,8BAA8B,GAAG,8BAA8B,CAE9H"}
1
+ {"version":3,"file":"personal-data-declaration.shared.utils.d.ts","sourceRoot":"","sources":["../../../../../src/compliance/privacy/personal-data-declaration.shared.utils.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,yBAAyB,EAAE,uBAAuB,EAAE,0BAA0B,EAAE,MAAM,iDAAiD,CAAC;AAGtJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAyCG;AACH,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,eAAe,CAAC,EAAE,uBAAuB,CAAC;IACnD,QAAQ,CAAC,iBAAiB,CAAC,EAAE,yBAAyB,CAAC;IACvD,QAAQ,CAAC,kBAAkB,CAAC,EAAE,0BAA0B,CAAC;IACzD,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,6GAA6G;AAC7G,wBAAgB,uCAAuC,CAAC,aAAa,EAAE,8BAA8B,GAAG,OAAO,CAK9G;AAED,iGAAiG;AACjG,MAAM,WAAW,8BAA8B;IAC7C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,mFAAmF;IACnF,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,wDAAwD,CAAC,MAAM,EAAE;IAC/E,QAAQ,CAAC,sBAAsB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,8BAA8B,CAAC,CAAC,CAAC;IAC1F,QAAQ,CAAC,wBAAwB,EAAE,SAAS,MAAM,EAAE,CAAC;CACtD,GAAG,SAAS,8BAA8B,EAAE,CAgB5C;AAED,gIAAgI;AAChI,wBAAgB,gCAAgC,CAAC,aAAa,EAAE,8BAA8B,GAAG,8BAA8B,CAE9H"}
@@ -1 +1 @@
1
- {"version":3,"file":"personal-data-declaration.shared.utils.js","sourceRoot":"","sources":["../../../../src/compliance/privacy/personal-data-declaration.shared.utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qCAAqC,EAAE,MAAM,yCAAyC,CAAC;AAmDhG,6GAA6G;AAC7G,MAAM,UAAU,uCAAuC,CAAC,aAA6C;IACnG,IAAI,aAAa,CAAC,eAAe,EAAE,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACnE,IAAI,aAAa,CAAC,iBAAiB,EAAE,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACrE,IAAI,aAAa,CAAC,kBAAkB,EAAE,aAAa,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAC/E,OAAO,qCAAqC,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;AAC/F,CAAC;AASD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,wDAAwD,CAAC,MAGxE;IACC,MAAM,UAAU,GAAqC,EAAE,CAAC;IAExD,KAAK,MAAM,YAAY,IAAI,MAAM,CAAC,wBAAwB,EAAE,CAAC;QAC3D,MAAM,aAAa,GAAG,MAAM,CAAC,sBAAsB,CAAC,YAAY,CAAC,CAAC;QAClE,IAAI,aAAa,KAAK,SAAS;YAAE,SAAS;QAC1C,IAAI,uCAAuC,CAAC,aAAa,CAAC;YAAE,SAAS;QAErE,MAAM,KAAK,GAAI,aAAa,CAAC,UAA8D,EAAE,KAAK,CAAC;QACnG,UAAU,CAAC,IAAI,CAAC;YACd,YAAY;YACZ,UAAU,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM;SAChE,CAAC,CAAC;IACL,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,gIAAgI;AAChI,MAAM,UAAU,gCAAgC,CAAC,aAA6C;IAC5F,OAAO,aAAa,CAAC;AACvB,CAAC","sourcesContent":["import type { ResourceDataSubjectPolicy, ResourceRetentionPolicy, ResourceSystemAccessPolicy } from '../../resources/resources-config.shared.schemas';\nimport { resolveResourcePersonalDataCategories } from './personal-data-category.shared.schemas';\n\n/**\n * Has this resource said ANYTHING about whether its rows are about people?\n *\n * ## The decision behind this, and what it is deliberately NOT\n *\n * Issue #93 asked whether a resource holding personal data should be REQUIRED to declare it, and the\n * evidence for requiring it was strong: measured across two applications, a declaration gets made if\n * and only if the framework refuses to start without it. `exportSubject` is fail-closed at\n * registration and was declared on 10 of 12 resources; `retentionPolicy` and `.impersonalizeWith()`\n * are not enforced and were declared on 1 and 0.\n *\n * **Paul decided against refusing.** A hard constraint on every application author, for every\n * resource, forever, is too strict — and the framework's own directive says the system must work\n * first, with protection arriving later as a judge-style guard rather than as a refusal wired into\n * the mechanism (`.claude/rules/application-creation-directive.md`).\n *\n * So this is a REPORT, and the report exists to be read by a human at startup. It never refuses, it\n * never throws, and nothing downstream branches on it. The other half of the decision — the half\n * that actually produces declarations — is the framework knowledge that teaches an author to write\n * one while they are authoring the resource, which is where a declaration is cheap.\n *\n * ## What counts as having answered\n *\n * ANY of four declarations, because they are four different questions and answering any one of them\n * means the author considered the subject:\n *\n * | declaration | the question it answers |\n * |---|---|\n * | `retentionPolicy.mode` | does an erasure keep this row, and are its fields scrubbed? |\n * | `dataSubjectPolicy.kind` | whose session does erasing this row end? |\n * | `systemAccessPolicy.exportSubject` | do these rows belong in a subject's export bundle? |\n * | a field carrying `.dataCategories()` | what KIND of personal data is held? |\n *\n * A resource declaring NONE of them has never been asked, and that is the only state this reports.\n * It is emphatically NOT a claim that the resource holds personal data — most resources do not, and\n * the report says \"unanswered\", never \"undeclared personal data\".\n *\n * ⚠️ `RETAIN_ONLY` counts as an ANSWER, and that is the point of admitting `retentionPolicy` at all:\n * its documented meaning is \"this resource holds no personal data of its own\", enforced by the\n * factory, which refuses a scrub treatment beside it. A resource that says so has answered the\n * question in the negative, deliberately, and must never appear in a gap list.\n */\nexport interface PersonalDataDeclarationSubject {\n readonly retentionPolicy?: ResourceRetentionPolicy;\n readonly dataSubjectPolicy?: ResourceDataSubjectPolicy;\n readonly systemAccessPolicy?: ResourceSystemAccessPolicy;\n readonly mainSchema?: unknown;\n}\n\n/** True when the resource declares at least one of the four — see {@link PersonalDataDeclarationSubject}. */\nexport function resourceAnsweredThePersonalDataQuestion(configuration: PersonalDataDeclarationSubject): boolean {\n if (configuration.retentionPolicy?.mode !== undefined) return true;\n if (configuration.dataSubjectPolicy?.kind !== undefined) return true;\n if (configuration.systemAccessPolicy?.exportSubject !== undefined) return true;\n return resolveResourcePersonalDataCategories(configuration.mainSchema).categories.length > 0;\n}\n\n/** One resource that has said nothing, with the size of what it holds so a reader can triage. */\nexport interface UnansweredPersonalDataResource {\n readonly resourceType: string;\n /** Top-level field count, purely to help a reader judge which to look at first. */\n readonly fieldCount: number;\n}\n\n/**\n * The APPLICATION's own resources that have said nothing about personal data.\n *\n * `applicationResourceTypes` is supplied by the caller rather than derived here, and that is the\n * whole reason this takes two arguments. The engine's ~85 resources declare their own posture and an\n * app author cannot change them, so including them would put 26 permanent entries in front of every\n * reader of a report about THEIR application — which is how a diagnostic channel stops being read.\n * The backend registry already separates the two at composition time, so the split is made once,\n * where the app and core factory maps are actually distinguishable, rather than re-derived here from\n * a key set that would then be a second enumeration of the same population.\n */\nexport function collectApplicationResourcesWithNoPersonalDataDeclaration(params: {\n readonly resourceConfigurations: Readonly<Record<string, PersonalDataDeclarationSubject>>;\n readonly applicationResourceTypes: readonly string[];\n}): readonly UnansweredPersonalDataResource[] {\n const unanswered: UnansweredPersonalDataResource[] = [];\n\n for (const resourceType of params.applicationResourceTypes) {\n const configuration = params.resourceConfigurations[resourceType];\n if (configuration === undefined) continue;\n if (resourceAnsweredThePersonalDataQuestion(configuration)) continue;\n\n const shape = (configuration.mainSchema as { shape?: Record<string, unknown> } | undefined)?.shape;\n unanswered.push({\n resourceType,\n fieldCount: shape === undefined ? 0 : Object.keys(shape).length,\n });\n }\n\n return unanswered;\n}\n\n/** Narrow a materialized configuration to the fields this report reads. Structural, so any shape carrying them satisfies it. */\nexport function asPersonalDataDeclarationSubject(configuration: PersonalDataDeclarationSubject): PersonalDataDeclarationSubject {\n return configuration;\n}\n"]}
1
+ {"version":3,"file":"personal-data-declaration.shared.utils.js","sourceRoot":"","sources":["../../../../../src/compliance/privacy/personal-data-declaration.shared.utils.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,qCAAqC,EAAE,MAAM,yCAAyC,CAAC;AAmDhG,6GAA6G;AAC7G,MAAM,UAAU,uCAAuC,CAAC,aAA6C;IACnG,IAAI,aAAa,CAAC,eAAe,EAAE,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACnE,IAAI,aAAa,CAAC,iBAAiB,EAAE,IAAI,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IACrE,IAAI,aAAa,CAAC,kBAAkB,EAAE,aAAa,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAC/E,OAAO,qCAAqC,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,CAAC;AAC/F,CAAC;AASD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,wDAAwD,CAAC,MAGxE;IACC,MAAM,UAAU,GAAqC,EAAE,CAAC;IAExD,KAAK,MAAM,YAAY,IAAI,MAAM,CAAC,wBAAwB,EAAE,CAAC;QAC3D,MAAM,aAAa,GAAG,MAAM,CAAC,sBAAsB,CAAC,YAAY,CAAC,CAAC;QAClE,IAAI,aAAa,KAAK,SAAS;YAAE,SAAS;QAC1C,IAAI,uCAAuC,CAAC,aAAa,CAAC;YAAE,SAAS;QAErE,MAAM,KAAK,GAAI,aAAa,CAAC,UAA8D,EAAE,KAAK,CAAC;QACnG,UAAU,CAAC,IAAI,CAAC;YACd,YAAY;YACZ,UAAU,EAAE,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,MAAM;SAChE,CAAC,CAAC;IACL,CAAC;IAED,OAAO,UAAU,CAAC;AACpB,CAAC;AAED,gIAAgI;AAChI,MAAM,UAAU,gCAAgC,CAAC,aAA6C;IAC5F,OAAO,aAAa,CAAC;AACvB,CAAC","sourcesContent":["import type { ResourceDataSubjectPolicy, ResourceRetentionPolicy, ResourceSystemAccessPolicy } from '../../resources/resources-config.shared.schemas';\nimport { resolveResourcePersonalDataCategories } from './personal-data-category.shared.schemas';\n\n/**\n * Has this resource said ANYTHING about whether its rows are about people?\n *\n * ## The decision behind this, and what it is deliberately NOT\n *\n * Issue #93 asked whether a resource holding personal data should be REQUIRED to declare it, and the\n * evidence for requiring it was strong: measured across two applications, a declaration gets made if\n * and only if the framework refuses to start without it. `exportSubject` is fail-closed at\n * registration and was declared on 10 of 12 resources; `retentionPolicy` and `.impersonalizeWith()`\n * are not enforced and were declared on 1 and 0.\n *\n * **Paul decided against refusing.** A hard constraint on every application author, for every\n * resource, forever, is too strict — and the framework's own directive says the system must work\n * first, with protection arriving later as a judge-style guard rather than as a refusal wired into\n * the mechanism (`.claude/rules/application-creation-directive.md`).\n *\n * So this is a REPORT, and the report exists to be read by a human at startup. It never refuses, it\n * never throws, and nothing downstream branches on it. The other half of the decision — the half\n * that actually produces declarations — is the framework knowledge that teaches an author to write\n * one while they are authoring the resource, which is where a declaration is cheap.\n *\n * ## What counts as having answered\n *\n * ANY of four declarations, because they are four different questions and answering any one of them\n * means the author considered the subject:\n *\n * | declaration | the question it answers |\n * |---|---|\n * | `retentionPolicy.mode` | does an erasure keep this row, and are its fields scrubbed? |\n * | `dataSubjectPolicy.kind` | whose session does erasing this row end? |\n * | `systemAccessPolicy.exportSubject` | do these rows belong in a subject's export bundle? |\n * | a field carrying `.dataCategories()` | what KIND of personal data is held? |\n *\n * A resource declaring NONE of them has never been asked, and that is the only state this reports.\n * It is emphatically NOT a claim that the resource holds personal data — most resources do not, and\n * the report says \"unanswered\", never \"undeclared personal data\".\n *\n * ⚠️ `RETAIN_ONLY` counts as an ANSWER, and that is the point of admitting `retentionPolicy` at all:\n * its documented meaning is \"this resource holds no personal data of its own\", enforced by the\n * factory, which refuses a scrub treatment beside it. A resource that says so has answered the\n * question in the negative, deliberately, and must never appear in a gap list.\n */\nexport interface PersonalDataDeclarationSubject {\n readonly retentionPolicy?: ResourceRetentionPolicy;\n readonly dataSubjectPolicy?: ResourceDataSubjectPolicy;\n readonly systemAccessPolicy?: ResourceSystemAccessPolicy;\n readonly mainSchema?: unknown;\n}\n\n/** True when the resource declares at least one of the four — see {@link PersonalDataDeclarationSubject}. */\nexport function resourceAnsweredThePersonalDataQuestion(configuration: PersonalDataDeclarationSubject): boolean {\n if (configuration.retentionPolicy?.mode !== undefined) return true;\n if (configuration.dataSubjectPolicy?.kind !== undefined) return true;\n if (configuration.systemAccessPolicy?.exportSubject !== undefined) return true;\n return resolveResourcePersonalDataCategories(configuration.mainSchema).categories.length > 0;\n}\n\n/** One resource that has said nothing, with the size of what it holds so a reader can triage. */\nexport interface UnansweredPersonalDataResource {\n readonly resourceType: string;\n /** Top-level field count, purely to help a reader judge which to look at first. */\n readonly fieldCount: number;\n}\n\n/**\n * The APPLICATION's own resources that have said nothing about personal data.\n *\n * `applicationResourceTypes` is supplied by the caller rather than derived here, and that is the\n * whole reason this takes two arguments. The engine's ~85 resources declare their own posture and an\n * app author cannot change them, so including them would put 26 permanent entries in front of every\n * reader of a report about THEIR application — which is how a diagnostic channel stops being read.\n * The backend registry already separates the two at composition time, so the split is made once,\n * where the app and core factory maps are actually distinguishable, rather than re-derived here from\n * a key set that would then be a second enumeration of the same population.\n */\nexport function collectApplicationResourcesWithNoPersonalDataDeclaration(params: {\n readonly resourceConfigurations: Readonly<Record<string, PersonalDataDeclarationSubject>>;\n readonly applicationResourceTypes: readonly string[];\n}): readonly UnansweredPersonalDataResource[] {\n const unanswered: UnansweredPersonalDataResource[] = [];\n\n for (const resourceType of params.applicationResourceTypes) {\n const configuration = params.resourceConfigurations[resourceType];\n if (configuration === undefined) continue;\n if (resourceAnsweredThePersonalDataQuestion(configuration)) continue;\n\n const shape = (configuration.mainSchema as { shape?: Record<string, unknown> } | undefined)?.shape;\n unanswered.push({\n resourceType,\n fieldCount: shape === undefined ? 0 : Object.keys(shape).length,\n });\n }\n\n return unanswered;\n}\n\n/** Narrow a materialized configuration to the fields this report reads. Structural, so any shape carrying them satisfies it. */\nexport function asPersonalDataDeclarationSubject(configuration: PersonalDataDeclarationSubject): PersonalDataDeclarationSubject {\n return configuration;\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"privacy.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/compliance/privacy/privacy.shared.schemas.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,0BAA0B,CAAC;AAElC,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D;;;;GAIG;AACH,oBAAY,qBAAqB;IAC/B,MAAM,WAAW,CAAE,sBAAsB;IACzC,oBAAoB,yBAAyB,CAAE,uDAAuD;IACtG,YAAY,iBAAiB,CAAE,mCAAmC;IAClE,OAAO,YAAY;CACpB;AAED,oBAAY,6BAA6B;IACvC,MAAM,WAAW,CAAE,sBAAsB;IACzC,oBAAoB,yBAAyB,CAAE,uDAAuD;IACtG,OAAO,YAAY;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH;;;;;;;;;;;;;;;GAeG;AACH,oBAAY,qBAAqB;IAC/B;;;;;OAKG;IACH,QAAQ,aAAa;IACrB;;;;OAIG;IACH,OAAO,YAAY;IACnB;;;;;;OAMG;IACH,UAAU,eAAe;CAC1B;AAoED,eAAO,MAAM,0BAA0B;;;;iBAIrC,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,2BAA2B;;;iBAGtC,CAAC;AAEH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAEhF,eAAO,MAAM,iBAAiB;;;iBAiB5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
1
+ {"version":3,"file":"privacy.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../../src/compliance/privacy/privacy.shared.schemas.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,OAAO,0BAA0B,CAAC;AAElC,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D;;;;GAIG;AACH,oBAAY,qBAAqB;IAC/B,MAAM,WAAW,CAAE,sBAAsB;IACzC,oBAAoB,yBAAyB,CAAE,uDAAuD;IACtG,YAAY,iBAAiB,CAAE,mCAAmC;IAClE,OAAO,YAAY;CACpB;AAED,oBAAY,6BAA6B;IACvC,MAAM,WAAW,CAAE,sBAAsB;IACzC,oBAAoB,yBAAyB,CAAE,uDAAuD;IACtG,OAAO,YAAY;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH;;;;;;;;;;;;;;;GAeG;AACH,oBAAY,qBAAqB;IAC/B;;;;;OAKG;IACH,QAAQ,aAAa;IACrB;;;;OAIG;IACH,OAAO,YAAY;IACnB;;;;;;OAMG;IACH,UAAU,eAAe;CAC1B;AAoED,eAAO,MAAM,0BAA0B;;;;iBAIrC,CAAC;AAEH,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;AAE9E,eAAO,MAAM,2BAA2B;;;iBAGtC,CAAC;AAEH,MAAM,MAAM,qBAAqB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,2BAA2B,CAAC,CAAC;AAEhF,eAAO,MAAM,iBAAiB;;;iBAiB5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"privacy.shared.schemas.js","sourceRoot":"","sources":["../../../../src/compliance/privacy/privacy.shared.schemas.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,6GAA6G;AAC7G,+GAA+G;AAC/G,OAAO,0BAA0B,CAAC;AAElC,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D;;;;GAIG;AACH,MAAM,CAAN,IAAY,qBAKX;AALD,WAAY,qBAAqB;IAC/B,0CAAiB,CAAA;IACjB,sEAA6C,CAAA;IAC7C,sDAA6B,CAAA;IAC7B,4CAAmB,CAAA;AACrB,CAAC,EALW,qBAAqB,KAArB,qBAAqB,QAKhC;AAED,MAAM,CAAN,IAAY,6BAIX;AAJD,WAAY,6BAA6B;IACvC,kDAAiB,CAAA;IACjB,8EAA6C,CAAA;IAC7C,oDAAmB,CAAA;AACrB,CAAC,EAJW,6BAA6B,KAA7B,6BAA6B,QAIxC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAN,IAAY,qBAsBX;AAtBD,WAAY,qBAAqB;IAC/B;;;;;OAKG;IACH,8CAAqB,CAAA;IACrB;;;;OAIG;IACH,4CAAmB,CAAA;IACnB;;;;;;OAMG;IACH,kDAAyB,CAAA;AAC3B,CAAC,EAtBW,qBAAqB,KAArB,qBAAqB,QAsBhC;AACD,0EAA0E;AAE1E;;;;;;;;;;;GAWG;AACH;;;;;;GAMG;AACH,MAAM,sBAAsB,GAAG,CAAC,OAAe,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;KACzH,QAAQ,CACP,yBAAyB,OAAO,qJAAqJ,CACtL,CAAC;AAEJ,MAAM,qBAAqB,GAAG,CAAC,OAAe,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;KACnE,QAAQ,CACP,QAAQ,OAAO,oIAAoI,CACpJ,CAAC;AAEJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,oBAAoB,GAAG,CAAC,OAAe,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;KACvH,QAAQ,CACP,2CAA2C,OAAO,sGAAsG,CACzJ,CAAC;AAEJ,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD,iBAAiB,EAAE,sBAAsB,CAAC,wBAAwB,CAAC;IACnE,eAAe,EAAE,oBAAoB,CAAC,wBAAwB,CAAC;IAC/D,gBAAgB,EAAE,qBAAqB,CAAC,wBAAwB,CAAC;CAClE,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC,MAAM,CAAC;IAClD,iBAAiB,EAAE,sBAAsB,CAAC,WAAW,CAAC;IACtD,gBAAgB,EAAE,qBAAqB,CAAC,WAAW,CAAC;CACrD,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,sGAAsG;IACtG,EAAE;IACF,sGAAsG;IACtG,qGAAqG;IACrG,wFAAwF;IACxF,EAAE;IACF,8FAA8F;IAC9F,mGAAmG;IACnG,EAAE;IACF,4FAA4F;IAC5F,gGAAgG;IAChG,oGAAoG;IACpG,4FAA4F;IAC5F,iBAAiB,EAAE,sBAAsB,CAAC,aAAa,CAAC;SACrD,eAAe,EAAE;IACpB,gBAAgB,EAAE,qBAAqB,CAAC,aAAa,CAAC;CACvD,CAAC,CAAC","sourcesContent":["/**\n * Privacy Shared Schemas\n *\n * Privacy-related schemas and enums for user data management\n */\n\nimport { z } from \"zod\";\n// Side-effect import: this module calls `.systemEnum()` at load, so the decorators must be installed first —\n// never by the importer's luck (#966). A named import used only as a type would be elided and install nothing.\nimport \"@wildo-ai/zod-decorators\";\n\nimport { ConsentPurpose } from \"./consent-purposes.shared\";\n\n/**\n * Profile Visibility Enum\n *\n * Controls who can see a user's profile information\n */\nexport enum UserProfileVisibility {\n PUBLIC = \"public\", // Visible to everyone\n APPLICATION_INTERNAL = \"application_internal\", // Visible within application, for connected users only\n ORGANIZATION = \"organization\", // Visible within organization only\n PRIVATE = \"private\", // Visible to user only\n}\n\nexport enum OrganizationProfileVisibility {\n PUBLIC = \"public\", // Visible to everyone\n APPLICATION_INTERNAL = \"application_internal\", // Visible within application, for connected users only\n PRIVATE = \"private\", // Visible to user only\n}\n\n/**\n * Whether — and with what lifetime — this application identifies the CLIENT INSTALL\n * (`clientInstanceId`, sent as `x-client-instance-id` and recorded on the audit row).\n *\n * A `clientInstanceId` answers \"which browser/device install issued this request?\", which the\n * per-request `correlationId` (server-minted, never stored on the device) and `frontendServiceName`\n * (a static per-app build constant) deliberately cannot. It is what lets an investigator group a\n * hostile actor's requests across sessions and logins — genuine security value, and exactly why it\n * needs a policy rather than a default.\n *\n * **This is a closed vocabulary with the OFF state inside it, on purpose.** Modelling it as\n * `{ enabled: boolean; scope: … }` would admit the meaningless `enabled: false, scope: PERSISTENT`\n * state; one enum makes \"off\" and \"how long it lives\" a single, always-coherent decision.\n *\n * **Why the framework refuses to choose for you (Fork D / SD9).** Storing an identifier on the\n * user's terminal equipment engages ePrivacy Directive Art 5(3), whose \"strictly necessary\"\n * exemption the EDPB reads narrowly (Guidelines 2/2023) — and *duration* is itself a\n * misclassification signal, so a long-lived id is the hardest case. GDPR Recital 49 (network and\n * information security as a legitimate interest) is a lawful basis for the PROCESSING but does not\n * remove the ePrivacy STORAGE consent question. Meanwhile NIST SP 800-53 AU-3 / AU-6(3)\n * affirmatively want this correlation capability for audit review. Those pull in opposite\n * directions, and the resolution is jurisdiction- and DPA-specific — so Wildo ships the mechanism\n * OFF and each application decides, with counsel, which member it may lawfully select.\n *\n * Not legal advice. See `.claude/plans/traceability-correlation-id.md` (SD9) for the full analysis\n * and the compliance obligations that attach to each non-`DISABLED` member.\n */\n/**\n * @wildo_source:part:start saas.models.privacy.client-instance-id-scope facet:layer:shared facet:audience:app-developer\n *\n * Whether the application identifies a browser INSTALL across visits, declared as\n * `compliance.clientInstanceIdScope`.\n *\n * It lives on `compliance` rather than beside the observability settings because it is a PRIVACY\n * decision, and on the SHARED config because both halves must obey one authored value: the frontend\n * decides whether to mint, store and send the id, and the backend independently decides whether to\n * ingest and record it. Two gates, one source — so an application that never opts in is protected\n * even if some client sends the header anyway.\n *\n * **`DISABLED` is the default**, so the privacy-preserving posture is what you get by doing nothing.\n * Choosing another member is choosing an obligation, not just a signal: start-up prints the\n * obligations each opt-in creates.\n */\nexport enum ClientInstanceIdScope {\n /**\n * DEFAULT. No client-install identifier is minted, sent, stored, or recorded — and the backend\n * additionally REFUSES an inbound `x-client-instance-id` (fail-closed, so a rogue or misconfigured\n * client cannot start populating a pseudonymous identifier in an application's retained audit\n * trail without that application ever opting in).\n */\n DISABLED = \"disabled\",\n /**\n * Minted per browsing session (`sessionStorage`) — dies when the tab closes and does NOT survive a\n * restart, so it cannot follow a user across visits. The proportionate choice when the goal is\n * correlating one session's activity; the easiest to justify as strictly necessary.\n */\n SESSION = \"session\",\n /**\n * Minted once per browser install (`localStorage`) — survives tab close, restart, logout, and\n * account switch. The strongest investigative signal (it links pre- and post-authentication\n * activity, and two accounts used from one machine) and correspondingly the most likely to require\n * consent. Select only with a recorded legitimate-interest assessment and, where required,\n * consent-gating.\n */\n PERSISTENT = \"persistent\",\n}\n/** @wildo_source:part:end saas.models.privacy.client-instance-id-scope */\n\n/**\n * The purposes a person has granted, and whether they have decided at all — the two facts every\n * consent surface reads (#534).\n *\n * `consentedPurposes` defaults to the EMPTY set, and that default is the point. It used to be\n * `.default(DataProcessingConsent.BASIC)`: every record asserted a consent its subject never gave.\n * The empty set asserts nothing.\n *\n * `consentDecidedAt` is what separates \"declined everything\" from \"was never asked\" — the two are the\n * same empty set and must not be the same fact. Absent means undecided, so a consent surface asks; set\n * means the person made an affirmative choice at that instant, whatever they chose.\n */\n/*\n * `.systemEnum('ConsentPurpose')` names the ONE vocabulary a purpose is worded by, everywhere it is stored —\n * a person's preferences, an anonymous visitor, a lead — and on the application consent gate that asks for\n * it. A purpose is a legal statement to the person deciding, so it gets one wording, authored once under\n * `system_enums.ConsentPurpose.<value>`; the labelling planner plans it there and the frontend reads it\n * there, both because this field declares it (#966).\n */\nconst consentedPurposesField = (subject: string) => z.array(z.enum(ConsentPurpose).systemEnum('ConsentPurpose')).default([])\n .describe(\n `The optional purposes ${subject} has granted, each independently. A set, not a level: granting one purpose implies nothing about another. Empty means nothing optional was granted.`,\n );\n\nconst consentDecidedAtField = (subject: string) => z.date().optional()\n .describe(\n `When ${subject} last made an affirmative consent choice. Absent means no choice was ever made, which is different from choosing to grant nothing.`,\n );\n\n/**\n * The purposes a surface actually PUT IN FRONT of the person when they decided.\n *\n * ## Why a decision is not describable by its grants alone\n *\n * A grant set says what was agreed to. It cannot say what was ASKED, and the two differ by surface:\n * a website panel offers `purposesInUse`, derived from that site's own live providers, while the\n * application's gate offers `optionalPurposes`, derived from that application's configuration. A\n * marketing site running analytics and an application that also does marketing legitimately ask\n * different questions.\n *\n * Without this field, carrying a visitor's decision to their new account records\n * `consentDecidedAt` — which every consent surface reads as *\"this person was asked and answered\"* —\n * for purposes they were never shown. The application then stops prompting, and a purpose nobody\n * displayed is stored as declined. The existing surfaces already avoid this internally (*\"Purposes\n * the panel does not offer keep their stored grant\"*); only the CARRY crossed a surface boundary, and\n * it needed to know where the boundary was.\n *\n * So a decision is `(granted ⊆ offered, at an instant)`, and the carry adopts grants for offered\n * purposes while leaving an unoffered one genuinely undecided.\n *\n * ## Why only the anonymous holder declares it\n *\n * It is the only holder whose decision is taken on one surface and read on another. A member's\n * preferences are written and read by the same application, and a lead's opt-in is never carried\n * anywhere — adding the field there would be a second thing to keep true with no reader.\n *\n * Defaults to the EMPTY set, which is the honest value for every row written before this existed and\n * for a session that has been initialized but never asked: an empty offered set means no question was\n * put, so a carry from it carries nothing, which is the same outcome those rows have today.\n */\nconst offeredPurposesField = (subject: string) => z.array(z.enum(ConsentPurpose).systemEnum('ConsentPurpose')).default([])\n .describe(\n `The optional purposes actually shown to ${subject} by the surface they decided on. What is NOT here was never asked, and must not be read as declined.`,\n );\n\nexport const AnonymousUserPrivacySchema = z.object({\n consentedPurposes: consentedPurposesField('this anonymous visitor'),\n offeredPurposes: offeredPurposesField('this anonymous visitor'),\n consentDecidedAt: consentDecidedAtField('this anonymous visitor'),\n});\n\nexport type AnonymousUserPrivacy = z.infer<typeof AnonymousUserPrivacySchema>;\n\nexport const InboundContactPrivacySchema = z.object({\n consentedPurposes: consentedPurposesField('this lead'),\n consentDecidedAt: consentDecidedAtField('this lead'),\n});\n\nexport type InboundContactPrivacy = z.infer<typeof InboundContactPrivacySchema>;\n\nexport const UserPrivacySchema = z.object({\n // `.isAuditEvidence()` on the granted purposes, and deliberately NOT on the block that contains them.\n //\n // The granted set is the subject's own privacy DECISION held as a closed vocabulary, so recording its\n // before/after values on `resource_operation_performed` is exactly the \"mark what decides authority,\n // never what identifies a person\" rule that governs the same decorator on `UserSchema`.\n //\n // Evidence is selected per leaf; the audit walker resolves the dotted path. Governed-document\n // interactions are separate immutable release-bound records and are never embedded in preferences.\n //\n // assurance-control: WILDO.PRIVACY.CONSENT_RECORD — a consent change is a security-relevant\n // decision and must leave a trail naming the previous and resulting set. Reached by the consent\n // gate and prompt, the self-service preferences RESET and self/admin UPDATE. UPDATE explicitly opts\n // into audit emission below the risk floor; only marked decision leaves enter the evidence.\n consentedPurposes: consentedPurposesField('this person')\n .isAuditEvidence(),\n consentDecidedAt: consentDecidedAtField('this person'),\n});\n\nexport type UserPrivacy = z.infer<typeof UserPrivacySchema>;\n"]}
1
+ {"version":3,"file":"privacy.shared.schemas.js","sourceRoot":"","sources":["../../../../../src/compliance/privacy/privacy.shared.schemas.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,6GAA6G;AAC7G,+GAA+G;AAC/G,OAAO,0BAA0B,CAAC;AAElC,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAE3D;;;;GAIG;AACH,MAAM,CAAN,IAAY,qBAKX;AALD,WAAY,qBAAqB;IAC/B,0CAAiB,CAAA;IACjB,sEAA6C,CAAA;IAC7C,sDAA6B,CAAA;IAC7B,4CAAmB,CAAA;AACrB,CAAC,EALW,qBAAqB,KAArB,qBAAqB,QAKhC;AAED,MAAM,CAAN,IAAY,6BAIX;AAJD,WAAY,6BAA6B;IACvC,kDAAiB,CAAA;IACjB,8EAA6C,CAAA;IAC7C,oDAAmB,CAAA;AACrB,CAAC,EAJW,6BAA6B,KAA7B,6BAA6B,QAIxC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAN,IAAY,qBAsBX;AAtBD,WAAY,qBAAqB;IAC/B;;;;;OAKG;IACH,8CAAqB,CAAA;IACrB;;;;OAIG;IACH,4CAAmB,CAAA;IACnB;;;;;;OAMG;IACH,kDAAyB,CAAA;AAC3B,CAAC,EAtBW,qBAAqB,KAArB,qBAAqB,QAsBhC;AACD,0EAA0E;AAE1E;;;;;;;;;;;GAWG;AACH;;;;;;GAMG;AACH,MAAM,sBAAsB,GAAG,CAAC,OAAe,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;KACzH,QAAQ,CACP,yBAAyB,OAAO,qJAAqJ,CACtL,CAAC;AAEJ,MAAM,qBAAqB,GAAG,CAAC,OAAe,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,QAAQ,EAAE;KACnE,QAAQ,CACP,QAAQ,OAAO,oIAAoI,CACpJ,CAAC;AAEJ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,oBAAoB,GAAG,CAAC,OAAe,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,UAAU,CAAC,gBAAgB,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,CAAC;KACvH,QAAQ,CACP,2CAA2C,OAAO,sGAAsG,CACzJ,CAAC;AAEJ,MAAM,CAAC,MAAM,0BAA0B,GAAG,CAAC,CAAC,MAAM,CAAC;IACjD,iBAAiB,EAAE,sBAAsB,CAAC,wBAAwB,CAAC;IACnE,eAAe,EAAE,oBAAoB,CAAC,wBAAwB,CAAC;IAC/D,gBAAgB,EAAE,qBAAqB,CAAC,wBAAwB,CAAC;CAClE,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC,MAAM,CAAC;IAClD,iBAAiB,EAAE,sBAAsB,CAAC,WAAW,CAAC;IACtD,gBAAgB,EAAE,qBAAqB,CAAC,WAAW,CAAC;CACrD,CAAC,CAAC;AAIH,MAAM,CAAC,MAAM,iBAAiB,GAAG,CAAC,CAAC,MAAM,CAAC;IACxC,sGAAsG;IACtG,EAAE;IACF,sGAAsG;IACtG,qGAAqG;IACrG,wFAAwF;IACxF,EAAE;IACF,8FAA8F;IAC9F,mGAAmG;IACnG,EAAE;IACF,4FAA4F;IAC5F,gGAAgG;IAChG,oGAAoG;IACpG,4FAA4F;IAC5F,iBAAiB,EAAE,sBAAsB,CAAC,aAAa,CAAC;SACrD,eAAe,EAAE;IACpB,gBAAgB,EAAE,qBAAqB,CAAC,aAAa,CAAC;CACvD,CAAC,CAAC","sourcesContent":["/**\n * Privacy Shared Schemas\n *\n * Privacy-related schemas and enums for user data management\n */\n\nimport { z } from \"zod\";\n// Side-effect import: this module calls `.systemEnum()` at load, so the decorators must be installed first —\n// never by the importer's luck (#966). A named import used only as a type would be elided and install nothing.\nimport \"@wildo-ai/zod-decorators\";\n\nimport { ConsentPurpose } from \"./consent-purposes.shared\";\n\n/**\n * Profile Visibility Enum\n *\n * Controls who can see a user's profile information\n */\nexport enum UserProfileVisibility {\n PUBLIC = \"public\", // Visible to everyone\n APPLICATION_INTERNAL = \"application_internal\", // Visible within application, for connected users only\n ORGANIZATION = \"organization\", // Visible within organization only\n PRIVATE = \"private\", // Visible to user only\n}\n\nexport enum OrganizationProfileVisibility {\n PUBLIC = \"public\", // Visible to everyone\n APPLICATION_INTERNAL = \"application_internal\", // Visible within application, for connected users only\n PRIVATE = \"private\", // Visible to user only\n}\n\n/**\n * Whether — and with what lifetime — this application identifies the CLIENT INSTALL\n * (`clientInstanceId`, sent as `x-client-instance-id` and recorded on the audit row).\n *\n * A `clientInstanceId` answers \"which browser/device install issued this request?\", which the\n * per-request `correlationId` (server-minted, never stored on the device) and `frontendServiceName`\n * (a static per-app build constant) deliberately cannot. It is what lets an investigator group a\n * hostile actor's requests across sessions and logins — genuine security value, and exactly why it\n * needs a policy rather than a default.\n *\n * **This is a closed vocabulary with the OFF state inside it, on purpose.** Modelling it as\n * `{ enabled: boolean; scope: … }` would admit the meaningless `enabled: false, scope: PERSISTENT`\n * state; one enum makes \"off\" and \"how long it lives\" a single, always-coherent decision.\n *\n * **Why the framework refuses to choose for you (Fork D / SD9).** Storing an identifier on the\n * user's terminal equipment engages ePrivacy Directive Art 5(3), whose \"strictly necessary\"\n * exemption the EDPB reads narrowly (Guidelines 2/2023) — and *duration* is itself a\n * misclassification signal, so a long-lived id is the hardest case. GDPR Recital 49 (network and\n * information security as a legitimate interest) is a lawful basis for the PROCESSING but does not\n * remove the ePrivacy STORAGE consent question. Meanwhile NIST SP 800-53 AU-3 / AU-6(3)\n * affirmatively want this correlation capability for audit review. Those pull in opposite\n * directions, and the resolution is jurisdiction- and DPA-specific — so Wildo ships the mechanism\n * OFF and each application decides, with counsel, which member it may lawfully select.\n *\n * Not legal advice. See `.claude/plans/traceability-correlation-id.md` (SD9) for the full analysis\n * and the compliance obligations that attach to each non-`DISABLED` member.\n */\n/**\n * @wildo_source:part:start saas.models.privacy.client-instance-id-scope facet:layer:shared facet:audience:app-developer\n *\n * Whether the application identifies a browser INSTALL across visits, declared as\n * `compliance.clientInstanceIdScope`.\n *\n * It lives on `compliance` rather than beside the observability settings because it is a PRIVACY\n * decision, and on the SHARED config because both halves must obey one authored value: the frontend\n * decides whether to mint, store and send the id, and the backend independently decides whether to\n * ingest and record it. Two gates, one source — so an application that never opts in is protected\n * even if some client sends the header anyway.\n *\n * **`DISABLED` is the default**, so the privacy-preserving posture is what you get by doing nothing.\n * Choosing another member is choosing an obligation, not just a signal: start-up prints the\n * obligations each opt-in creates.\n */\nexport enum ClientInstanceIdScope {\n /**\n * DEFAULT. No client-install identifier is minted, sent, stored, or recorded — and the backend\n * additionally REFUSES an inbound `x-client-instance-id` (fail-closed, so a rogue or misconfigured\n * client cannot start populating a pseudonymous identifier in an application's retained audit\n * trail without that application ever opting in).\n */\n DISABLED = \"disabled\",\n /**\n * Minted per browsing session (`sessionStorage`) — dies when the tab closes and does NOT survive a\n * restart, so it cannot follow a user across visits. The proportionate choice when the goal is\n * correlating one session's activity; the easiest to justify as strictly necessary.\n */\n SESSION = \"session\",\n /**\n * Minted once per browser install (`localStorage`) — survives tab close, restart, logout, and\n * account switch. The strongest investigative signal (it links pre- and post-authentication\n * activity, and two accounts used from one machine) and correspondingly the most likely to require\n * consent. Select only with a recorded legitimate-interest assessment and, where required,\n * consent-gating.\n */\n PERSISTENT = \"persistent\",\n}\n/** @wildo_source:part:end saas.models.privacy.client-instance-id-scope */\n\n/**\n * The purposes a person has granted, and whether they have decided at all — the two facts every\n * consent surface reads (#534).\n *\n * `consentedPurposes` defaults to the EMPTY set, and that default is the point. It used to be\n * `.default(DataProcessingConsent.BASIC)`: every record asserted a consent its subject never gave.\n * The empty set asserts nothing.\n *\n * `consentDecidedAt` is what separates \"declined everything\" from \"was never asked\" — the two are the\n * same empty set and must not be the same fact. Absent means undecided, so a consent surface asks; set\n * means the person made an affirmative choice at that instant, whatever they chose.\n */\n/*\n * `.systemEnum('ConsentPurpose')` names the ONE vocabulary a purpose is worded by, everywhere it is stored —\n * a person's preferences, an anonymous visitor, a lead — and on the application consent gate that asks for\n * it. A purpose is a legal statement to the person deciding, so it gets one wording, authored once under\n * `system_enums.ConsentPurpose.<value>`; the labelling planner plans it there and the frontend reads it\n * there, both because this field declares it (#966).\n */\nconst consentedPurposesField = (subject: string) => z.array(z.enum(ConsentPurpose).systemEnum('ConsentPurpose')).default([])\n .describe(\n `The optional purposes ${subject} has granted, each independently. A set, not a level: granting one purpose implies nothing about another. Empty means nothing optional was granted.`,\n );\n\nconst consentDecidedAtField = (subject: string) => z.date().optional()\n .describe(\n `When ${subject} last made an affirmative consent choice. Absent means no choice was ever made, which is different from choosing to grant nothing.`,\n );\n\n/**\n * The purposes a surface actually PUT IN FRONT of the person when they decided.\n *\n * ## Why a decision is not describable by its grants alone\n *\n * A grant set says what was agreed to. It cannot say what was ASKED, and the two differ by surface:\n * a website panel offers `purposesInUse`, derived from that site's own live providers, while the\n * application's gate offers `optionalPurposes`, derived from that application's configuration. A\n * marketing site running analytics and an application that also does marketing legitimately ask\n * different questions.\n *\n * Without this field, carrying a visitor's decision to their new account records\n * `consentDecidedAt` — which every consent surface reads as *\"this person was asked and answered\"* —\n * for purposes they were never shown. The application then stops prompting, and a purpose nobody\n * displayed is stored as declined. The existing surfaces already avoid this internally (*\"Purposes\n * the panel does not offer keep their stored grant\"*); only the CARRY crossed a surface boundary, and\n * it needed to know where the boundary was.\n *\n * So a decision is `(granted ⊆ offered, at an instant)`, and the carry adopts grants for offered\n * purposes while leaving an unoffered one genuinely undecided.\n *\n * ## Why only the anonymous holder declares it\n *\n * It is the only holder whose decision is taken on one surface and read on another. A member's\n * preferences are written and read by the same application, and a lead's opt-in is never carried\n * anywhere — adding the field there would be a second thing to keep true with no reader.\n *\n * Defaults to the EMPTY set, which is the honest value for every row written before this existed and\n * for a session that has been initialized but never asked: an empty offered set means no question was\n * put, so a carry from it carries nothing, which is the same outcome those rows have today.\n */\nconst offeredPurposesField = (subject: string) => z.array(z.enum(ConsentPurpose).systemEnum('ConsentPurpose')).default([])\n .describe(\n `The optional purposes actually shown to ${subject} by the surface they decided on. What is NOT here was never asked, and must not be read as declined.`,\n );\n\nexport const AnonymousUserPrivacySchema = z.object({\n consentedPurposes: consentedPurposesField('this anonymous visitor'),\n offeredPurposes: offeredPurposesField('this anonymous visitor'),\n consentDecidedAt: consentDecidedAtField('this anonymous visitor'),\n});\n\nexport type AnonymousUserPrivacy = z.infer<typeof AnonymousUserPrivacySchema>;\n\nexport const InboundContactPrivacySchema = z.object({\n consentedPurposes: consentedPurposesField('this lead'),\n consentDecidedAt: consentDecidedAtField('this lead'),\n});\n\nexport type InboundContactPrivacy = z.infer<typeof InboundContactPrivacySchema>;\n\nexport const UserPrivacySchema = z.object({\n // `.isAuditEvidence()` on the granted purposes, and deliberately NOT on the block that contains them.\n //\n // The granted set is the subject's own privacy DECISION held as a closed vocabulary, so recording its\n // before/after values on `resource_operation_performed` is exactly the \"mark what decides authority,\n // never what identifies a person\" rule that governs the same decorator on `UserSchema`.\n //\n // Evidence is selected per leaf; the audit walker resolves the dotted path. Governed-document\n // interactions are separate immutable release-bound records and are never embedded in preferences.\n //\n // assurance-control: WILDO.PRIVACY.CONSENT_RECORD — a consent change is a security-relevant\n // decision and must leave a trail naming the previous and resulting set. Reached by the consent\n // gate and prompt, the self-service preferences RESET and self/admin UPDATE. UPDATE explicitly opts\n // into audit emission below the risk floor; only marked decision leaves enter the evidence.\n consentedPurposes: consentedPurposesField('this person')\n .isAuditEvidence(),\n consentDecidedAt: consentDecidedAtField('this person'),\n});\n\nexport type UserPrivacy = z.infer<typeof UserPrivacySchema>;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"provider-capability-disclosure.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/compliance/privacy/provider-capability-disclosure.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,6DAA6D,CAAC;AAErE,OAAO,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAE/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,WAAW,4BAA4B;IAC3C,oFAAoF;IACpF,QAAQ,CAAC,UAAU,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACrD,sGAAsG;IACtG,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,+BAA+B,EAAE,QAAQ,CAAC,MAAM,CAAC,yBAAyB,EAAE,4BAA4B,GAAG,IAAI,CAAC,CAmF5H,CAAC;AACF,gFAAgF;AAEhF;;;;;;GAMG;AACH,wBAAgB,wCAAwC,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG;IACnF,QAAQ,CAAC,UAAU,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACrD,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC,CAkBA"}
1
+ {"version":3,"file":"provider-capability-disclosure.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../../src/compliance/privacy/provider-capability-disclosure.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,yBAAyB,EAC/B,MAAM,6DAA6D,CAAC;AAErE,OAAO,EAAE,oBAAoB,EAAE,MAAM,yCAAyC,CAAC;AAE/E;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,MAAM,WAAW,4BAA4B;IAC3C,oFAAoF;IACpF,QAAQ,CAAC,UAAU,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACrD,sGAAsG;IACtG,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;CAC5B;AAED,eAAO,MAAM,+BAA+B,EAAE,QAAQ,CAAC,MAAM,CAAC,yBAAyB,EAAE,4BAA4B,GAAG,IAAI,CAAC,CAmF5H,CAAC;AACF,gFAAgF;AAEhF;;;;;;GAMG;AACH,wBAAgB,wCAAwC,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,GAAG;IACnF,QAAQ,CAAC,UAAU,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACrD,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC,CAkBA"}
@@ -1 +1 @@
1
- {"version":3,"file":"provider-capability-disclosure.shared.schemas.js","sourceRoot":"","sources":["../../../../src/compliance/privacy/provider-capability-disclosure.shared.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BUILTIN_PROVIDER_CAPABILITY,\n type BuiltinProviderCapability,\n} from '../../external-providers/provider-capability.shared.schemas';\nimport { PROVIDER_CAPABILITY_TO_ENGINE_CAPABILITY } from '../../external-providers/engine-capabilities.shared.schemas';\nimport { PersonalDataCategory } from './personal-data-category.shared.schemas';\n\n/**\n * WHICH categories of personal data the ENGINE sends to a provider that serves a capability (#1709).\n *\n * ## Why a table the engine owns\n *\n * A record of processing lists the categories of personal data and the categories of recipients (GDPR Art. 30(1)(c),\n * (d)); saying which categories reach which recipient is the practice that keeps the two lists consistent. For a\n * provider reached through a CAPABILITY, the application writes no\n * field map: the ENGINE composes the request — the recipient address of an email, the customer of a billing call,\n * the prompt of a model call. So the categories are a fact about the engine's own behaviour, the same for every\n * application, and the engine states it here rather than asking each operator to narrate it\n * (`.claude/rules/derive-before-you-ask.md`).\n *\n * The provider compliance profile's header rejects restating this on each provider module, as \"a second authority\n * for one fact\": the capability is the authority, and this is where it speaks.\n *\n * ## Total over the provider-capability vocabulary\n *\n * A `Record` over every {@link BuiltinProviderCapability}, so a capability added tomorrow is a compile error here\n * until someone states what it sends. `null` is an ANSWER: the capability sends no personal data of the application's\n * users to the vendor (a build-time coding agent works on source code).\n *\n * ## Read it as a FLOOR of what reaches the vendor, never a ceiling\n *\n * `USER_CONTENT` is listed wherever free text a person wrote rides the call (a prompt, a message body, a search\n * query), and free text can carry ANY other category — see {@link PersonalDataCategory.USER_CONTENT}. A notice\n * states the listed categories and must not conclude that nothing else ever reaches the vendor.\n *\n * @wildo_source:part:start saas.models.privacy.provider-capability-disclosure facet:layer:shared facet:audience:app-developer\n */\nexport interface ProviderCapabilityDisclosure {\n /** The categories the engine sends when it calls a provider for this capability. */\n readonly categories: readonly PersonalDataCategory[];\n /** What in the call carries them — so a reader can check the claim against the engine's behaviour. */\n readonly carriedBy: string;\n}\n\nexport const PROVIDER_CAPABILITY_DISCLOSURES: Readonly<Record<BuiltinProviderCapability, ProviderCapabilityDisclosure | null>> = {\n [BUILTIN_PROVIDER_CAPABILITY.EMAIL_TRANSACTIONAL]: {\n categories: [PersonalDataCategory.CONTACT_DETAILS, PersonalDataCategory.IDENTITY, PersonalDataCategory.CREDENTIALS, PersonalDataCategory.USER_CONTENT],\n carriedBy: 'the recipient address, the recipient name the templates address, the rendered message body, and the magic-link, verification and password-reset tokens the engine\\'s own mails carry',\n },\n [BUILTIN_PROVIDER_CAPABILITY.EMAIL_MARKETING]: {\n categories: [PersonalDataCategory.CONTACT_DETAILS, PersonalDataCategory.IDENTITY],\n carriedBy: 'the subscriber address and name synchronised to the audience',\n },\n [BUILTIN_PROVIDER_CAPABILITY.EMAIL_INBOUND]: {\n categories: [PersonalDataCategory.CONTACT_DETAILS, PersonalDataCategory.USER_CONTENT],\n carriedBy: 'the sender and recipient addresses, and the message bodies and attachments the vendor receives and holds',\n },\n [BUILTIN_PROVIDER_CAPABILITY.SMS]: {\n categories: [PersonalDataCategory.CONTACT_DETAILS, PersonalDataCategory.CREDENTIALS],\n carriedBy: 'the telephone number, and the one-time verification code the message carries',\n },\n [BUILTIN_PROVIDER_CAPABILITY.BILLING]: {\n categories: [PersonalDataCategory.IDENTITY, PersonalDataCategory.CONTACT_DETAILS, PersonalDataCategory.FINANCIAL],\n carriedBy: 'the customer name and email address, and the payment, subscription and invoice records',\n },\n [BUILTIN_PROVIDER_CAPABILITY.SSO_OAUTH2]: {\n categories: [PersonalDataCategory.IDENTITY, PersonalDataCategory.CONTACT_DETAILS],\n carriedBy: 'the sign-in request, which may name the account (login hint), and the identity the vendor asserts back',\n },\n [BUILTIN_PROVIDER_CAPABILITY.SSO_SAML]: {\n categories: [PersonalDataCategory.IDENTITY, PersonalDataCategory.CONTACT_DETAILS],\n carriedBy: 'the authentication request and the asserted subject',\n },\n [BUILTIN_PROVIDER_CAPABILITY.LLM_CHAT]: {\n categories: [PersonalDataCategory.USER_CONTENT],\n carriedBy: 'the prompt and the context the application assembles into it',\n },\n [BUILTIN_PROVIDER_CAPABILITY.LLM_EMBEDDINGS]: {\n categories: [PersonalDataCategory.USER_CONTENT],\n carriedBy: 'the text of every field a resource marks as a retrieval source, sent to be embedded',\n },\n [BUILTIN_PROVIDER_CAPABILITY.DOCUMENT_TEXT_EXTRACTION]: {\n categories: [PersonalDataCategory.USER_CONTENT],\n carriedBy: 'the bytes of every uploaded document sent for text extraction',\n },\n // Build-time tooling: a coding run sends the application's SOURCE CODE and specifications, not a user's data.\n [BUILTIN_PROVIDER_CAPABILITY.CODING_AGENT]: null,\n [BUILTIN_PROVIDER_CAPABILITY.IMAGE_GENERATION]: {\n categories: [PersonalDataCategory.USER_CONTENT],\n carriedBy: 'the image prompt',\n },\n [BUILTIN_PROVIDER_CAPABILITY.FRONTEND_ERROR_MONITORING]: {\n categories: [PersonalDataCategory.USAGE, PersonalDataCategory.IDENTITY],\n carriedBy: 'the error event with its device, browser and page context, and the signed-in user identifier when the application attaches it',\n },\n [BUILTIN_PROVIDER_CAPABILITY.FRONTEND_PRODUCT_ANALYTICS]: {\n categories: [PersonalDataCategory.USAGE, PersonalDataCategory.IDENTITY],\n carriedBy: 'the product events and the identifier the application identifies the person by',\n },\n [BUILTIN_PROVIDER_CAPABILITY.FRONTEND_SEARCH]: {\n categories: [PersonalDataCategory.USER_CONTENT],\n carriedBy: 'the search query the person types',\n },\n [BUILTIN_PROVIDER_CAPABILITY.FRONTEND_FILE_PICKER]: {\n categories: [PersonalDataCategory.USER_CONTENT],\n carriedBy: 'the files the person picks from their own account at the vendor',\n },\n [BUILTIN_PROVIDER_CAPABILITY.FRONTEND_CAPTCHA]: {\n categories: [PersonalDataCategory.USAGE],\n carriedBy: 'the interaction and device signals the challenge scores',\n },\n [BUILTIN_PROVIDER_CAPABILITY.FRONTEND_ADDRESS_LOOKUP]: {\n categories: [PersonalDataCategory.CONTACT_DETAILS, PersonalDataCategory.LOCATION],\n carriedBy: 'the address text the person types and the place it resolves to',\n },\n [BUILTIN_PROVIDER_CAPABILITY.LLM_OBSERVABILITY]: {\n categories: [PersonalDataCategory.USER_CONTENT, PersonalDataCategory.USAGE],\n carriedBy: 'the traced generation — its prompt and output — and the call metadata',\n },\n [BUILTIN_PROVIDER_CAPABILITY.OBSERVABILITY_TELEMETRY]: {\n categories: [PersonalDataCategory.USAGE, PersonalDataCategory.IDENTITY],\n carriedBy: 'the traces, metrics and logs of requests, which carry request metadata and the acting user\\'s identifier on each span',\n },\n [BUILTIN_PROVIDER_CAPABILITY.COMPLIANCE_AUDIT_TRAIL]: {\n categories: [PersonalDataCategory.IDENTITY, PersonalDataCategory.USAGE],\n carriedBy: 'every audit event: the acting user, the subject, and what was done',\n },\n};\n/** @wildo_source:part:end saas.models.privacy.provider-capability-disclosure */\n\n/**\n * The categories disclosed through a set of capabilities, as the population's data paths name them — provider\n * capability tokens, and engine capabilities (each the union of the provider capabilities that fill it).\n *\n * `undeclared` lists a token this table does not know, so a caller reports it instead of dropping it. Sorted in the\n * {@link PersonalDataCategory} enum order, so one application produces one sentence.\n */\nexport function personalDataDisclosedThroughCapabilities(tokens: readonly string[]): {\n readonly categories: readonly PersonalDataCategory[];\n readonly undeclared: readonly string[];\n} {\n const found = new Set<PersonalDataCategory>();\n const undeclared: string[] = [];\n const disclosuresByProviderCapability = PROVIDER_CAPABILITY_DISCLOSURES as Readonly<Record<string, ProviderCapabilityDisclosure | null>>;\n for (const token of tokens) {\n const providerCapabilities = token in disclosuresByProviderCapability\n ? [token]\n : Object.entries(PROVIDER_CAPABILITY_TO_ENGINE_CAPABILITY).filter(([, engineCapability]) => engineCapability === token).map(([providerCapability]) => providerCapability);\n if (providerCapabilities.length === 0) {\n undeclared.push(token);\n continue;\n }\n for (const providerCapability of providerCapabilities) {\n for (const category of disclosuresByProviderCapability[providerCapability]?.categories ?? []) found.add(category);\n }\n }\n const order = Object.values(PersonalDataCategory);\n return { categories: order.filter((category) => found.has(category)), undeclared: [...new Set(undeclared)].sort() };\n}\n"]}
1
+ {"version":3,"file":"provider-capability-disclosure.shared.schemas.js","sourceRoot":"","sources":["../../../../../src/compliance/privacy/provider-capability-disclosure.shared.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n BUILTIN_PROVIDER_CAPABILITY,\n type BuiltinProviderCapability,\n} from '../../external-providers/provider-capability.shared.schemas';\nimport { PROVIDER_CAPABILITY_TO_ENGINE_CAPABILITY } from '../../external-providers/engine-capabilities.shared.schemas';\nimport { PersonalDataCategory } from './personal-data-category.shared.schemas';\n\n/**\n * WHICH categories of personal data the ENGINE sends to a provider that serves a capability (#1709).\n *\n * ## Why a table the engine owns\n *\n * A record of processing lists the categories of personal data and the categories of recipients (GDPR Art. 30(1)(c),\n * (d)); saying which categories reach which recipient is the practice that keeps the two lists consistent. For a\n * provider reached through a CAPABILITY, the application writes no\n * field map: the ENGINE composes the request — the recipient address of an email, the customer of a billing call,\n * the prompt of a model call. So the categories are a fact about the engine's own behaviour, the same for every\n * application, and the engine states it here rather than asking each operator to narrate it\n * (`.claude/rules/derive-before-you-ask.md`).\n *\n * The provider compliance profile's header rejects restating this on each provider module, as \"a second authority\n * for one fact\": the capability is the authority, and this is where it speaks.\n *\n * ## Total over the provider-capability vocabulary\n *\n * A `Record` over every {@link BuiltinProviderCapability}, so a capability added tomorrow is a compile error here\n * until someone states what it sends. `null` is an ANSWER: the capability sends no personal data of the application's\n * users to the vendor (a build-time coding agent works on source code).\n *\n * ## Read it as a FLOOR of what reaches the vendor, never a ceiling\n *\n * `USER_CONTENT` is listed wherever free text a person wrote rides the call (a prompt, a message body, a search\n * query), and free text can carry ANY other category — see {@link PersonalDataCategory.USER_CONTENT}. A notice\n * states the listed categories and must not conclude that nothing else ever reaches the vendor.\n *\n * @wildo_source:part:start saas.models.privacy.provider-capability-disclosure facet:layer:shared facet:audience:app-developer\n */\nexport interface ProviderCapabilityDisclosure {\n /** The categories the engine sends when it calls a provider for this capability. */\n readonly categories: readonly PersonalDataCategory[];\n /** What in the call carries them — so a reader can check the claim against the engine's behaviour. */\n readonly carriedBy: string;\n}\n\nexport const PROVIDER_CAPABILITY_DISCLOSURES: Readonly<Record<BuiltinProviderCapability, ProviderCapabilityDisclosure | null>> = {\n [BUILTIN_PROVIDER_CAPABILITY.EMAIL_TRANSACTIONAL]: {\n categories: [PersonalDataCategory.CONTACT_DETAILS, PersonalDataCategory.IDENTITY, PersonalDataCategory.CREDENTIALS, PersonalDataCategory.USER_CONTENT],\n carriedBy: 'the recipient address, the recipient name the templates address, the rendered message body, and the magic-link, verification and password-reset tokens the engine\\'s own mails carry',\n },\n [BUILTIN_PROVIDER_CAPABILITY.EMAIL_MARKETING]: {\n categories: [PersonalDataCategory.CONTACT_DETAILS, PersonalDataCategory.IDENTITY],\n carriedBy: 'the subscriber address and name synchronised to the audience',\n },\n [BUILTIN_PROVIDER_CAPABILITY.EMAIL_INBOUND]: {\n categories: [PersonalDataCategory.CONTACT_DETAILS, PersonalDataCategory.USER_CONTENT],\n carriedBy: 'the sender and recipient addresses, and the message bodies and attachments the vendor receives and holds',\n },\n [BUILTIN_PROVIDER_CAPABILITY.SMS]: {\n categories: [PersonalDataCategory.CONTACT_DETAILS, PersonalDataCategory.CREDENTIALS],\n carriedBy: 'the telephone number, and the one-time verification code the message carries',\n },\n [BUILTIN_PROVIDER_CAPABILITY.BILLING]: {\n categories: [PersonalDataCategory.IDENTITY, PersonalDataCategory.CONTACT_DETAILS, PersonalDataCategory.FINANCIAL],\n carriedBy: 'the customer name and email address, and the payment, subscription and invoice records',\n },\n [BUILTIN_PROVIDER_CAPABILITY.SSO_OAUTH2]: {\n categories: [PersonalDataCategory.IDENTITY, PersonalDataCategory.CONTACT_DETAILS],\n carriedBy: 'the sign-in request, which may name the account (login hint), and the identity the vendor asserts back',\n },\n [BUILTIN_PROVIDER_CAPABILITY.SSO_SAML]: {\n categories: [PersonalDataCategory.IDENTITY, PersonalDataCategory.CONTACT_DETAILS],\n carriedBy: 'the authentication request and the asserted subject',\n },\n [BUILTIN_PROVIDER_CAPABILITY.LLM_CHAT]: {\n categories: [PersonalDataCategory.USER_CONTENT],\n carriedBy: 'the prompt and the context the application assembles into it',\n },\n [BUILTIN_PROVIDER_CAPABILITY.LLM_EMBEDDINGS]: {\n categories: [PersonalDataCategory.USER_CONTENT],\n carriedBy: 'the text of every field a resource marks as a retrieval source, sent to be embedded',\n },\n [BUILTIN_PROVIDER_CAPABILITY.DOCUMENT_TEXT_EXTRACTION]: {\n categories: [PersonalDataCategory.USER_CONTENT],\n carriedBy: 'the bytes of every uploaded document sent for text extraction',\n },\n // Build-time tooling: a coding run sends the application's SOURCE CODE and specifications, not a user's data.\n [BUILTIN_PROVIDER_CAPABILITY.CODING_AGENT]: null,\n [BUILTIN_PROVIDER_CAPABILITY.IMAGE_GENERATION]: {\n categories: [PersonalDataCategory.USER_CONTENT],\n carriedBy: 'the image prompt',\n },\n [BUILTIN_PROVIDER_CAPABILITY.FRONTEND_ERROR_MONITORING]: {\n categories: [PersonalDataCategory.USAGE, PersonalDataCategory.IDENTITY],\n carriedBy: 'the error event with its device, browser and page context, and the signed-in user identifier when the application attaches it',\n },\n [BUILTIN_PROVIDER_CAPABILITY.FRONTEND_PRODUCT_ANALYTICS]: {\n categories: [PersonalDataCategory.USAGE, PersonalDataCategory.IDENTITY],\n carriedBy: 'the product events and the identifier the application identifies the person by',\n },\n [BUILTIN_PROVIDER_CAPABILITY.FRONTEND_SEARCH]: {\n categories: [PersonalDataCategory.USER_CONTENT],\n carriedBy: 'the search query the person types',\n },\n [BUILTIN_PROVIDER_CAPABILITY.FRONTEND_FILE_PICKER]: {\n categories: [PersonalDataCategory.USER_CONTENT],\n carriedBy: 'the files the person picks from their own account at the vendor',\n },\n [BUILTIN_PROVIDER_CAPABILITY.FRONTEND_CAPTCHA]: {\n categories: [PersonalDataCategory.USAGE],\n carriedBy: 'the interaction and device signals the challenge scores',\n },\n [BUILTIN_PROVIDER_CAPABILITY.FRONTEND_ADDRESS_LOOKUP]: {\n categories: [PersonalDataCategory.CONTACT_DETAILS, PersonalDataCategory.LOCATION],\n carriedBy: 'the address text the person types and the place it resolves to',\n },\n [BUILTIN_PROVIDER_CAPABILITY.LLM_OBSERVABILITY]: {\n categories: [PersonalDataCategory.USER_CONTENT, PersonalDataCategory.USAGE],\n carriedBy: 'the traced generation — its prompt and output — and the call metadata',\n },\n [BUILTIN_PROVIDER_CAPABILITY.OBSERVABILITY_TELEMETRY]: {\n categories: [PersonalDataCategory.USAGE, PersonalDataCategory.IDENTITY],\n carriedBy: 'the traces, metrics and logs of requests, which carry request metadata and the acting user\\'s identifier on each span',\n },\n [BUILTIN_PROVIDER_CAPABILITY.COMPLIANCE_AUDIT_TRAIL]: {\n categories: [PersonalDataCategory.IDENTITY, PersonalDataCategory.USAGE],\n carriedBy: 'every audit event: the acting user, the subject, and what was done',\n },\n};\n/** @wildo_source:part:end saas.models.privacy.provider-capability-disclosure */\n\n/**\n * The categories disclosed through a set of capabilities, as the population's data paths name them — provider\n * capability tokens, and engine capabilities (each the union of the provider capabilities that fill it).\n *\n * `undeclared` lists a token this table does not know, so a caller reports it instead of dropping it. Sorted in the\n * {@link PersonalDataCategory} enum order, so one application produces one sentence.\n */\nexport function personalDataDisclosedThroughCapabilities(tokens: readonly string[]): {\n readonly categories: readonly PersonalDataCategory[];\n readonly undeclared: readonly string[];\n} {\n const found = new Set<PersonalDataCategory>();\n const undeclared: string[] = [];\n const disclosuresByProviderCapability = PROVIDER_CAPABILITY_DISCLOSURES as Readonly<Record<string, ProviderCapabilityDisclosure | null>>;\n for (const token of tokens) {\n const providerCapabilities = token in disclosuresByProviderCapability\n ? [token]\n : Object.entries(PROVIDER_CAPABILITY_TO_ENGINE_CAPABILITY).filter(([, engineCapability]) => engineCapability === token).map(([providerCapability]) => providerCapability);\n if (providerCapabilities.length === 0) {\n undeclared.push(token);\n continue;\n }\n for (const providerCapability of providerCapabilities) {\n for (const category of disclosuresByProviderCapability[providerCapability]?.categories ?? []) found.add(category);\n }\n }\n const order = Object.values(PersonalDataCategory);\n return { categories: order.filter((category) => found.has(category)), undeclared: [...new Set(undeclared)].sort() };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"purpose-ref.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/compliance/privacy/purpose-ref.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,aAAoG,CAAC"}
1
+ {"version":3,"file":"purpose-ref.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../../src/compliance/privacy/purpose-ref.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;GAOG;AACH,eAAO,MAAM,2BAA2B,aAAoG,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"purpose-ref.shared.schemas.js","sourceRoot":"","sources":["../../../../src/compliance/privacy/purpose-ref.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,4BAA4B,EAAE,0CAA0C,CAAC,CAAC","sourcesContent":["import { z } from 'zod';\n\n/**\n * A stable slug naming one processing purpose (#1709) — `account-security`, `billing-records`.\n *\n * Declared on a lawful basis (`operatorComplianceIdentity.lawfulBases[].purposeRef`) and named by every recipient that\n * serves it (`providerComplianceChoices.<ref>.purposeRefs`). One schema for both ends, in an import-free atom, so the\n * compliance choice (reachable from the browser's public runtime) can validate a ref without pulling the operator\n * identity's module graph with it.\n */\nexport const LawfulBasisPurposeRefSchema = z.string().trim().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, 'a purpose ref is a lower-case kebab slug');\n"]}
1
+ {"version":3,"file":"purpose-ref.shared.schemas.js","sourceRoot":"","sources":["../../../../../src/compliance/privacy/purpose-ref.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,2BAA2B,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,4BAA4B,EAAE,0CAA0C,CAAC,CAAC","sourcesContent":["import { z } from 'zod';\n\n/**\n * A stable slug naming one processing purpose (#1709) — `account-security`, `billing-records`.\n *\n * Declared on a lawful basis (`operatorComplianceIdentity.lawfulBases[].purposeRef`) and named by every recipient that\n * serves it (`providerComplianceChoices.<ref>.purposeRefs`). One schema for both ends, in an import-free atom, so the\n * compliance choice (reachable from the browser's public runtime) can validate a ref without pulling the operator\n * identity's module graph with it.\n */\nexport const LawfulBasisPurposeRefSchema = z.string().trim().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, 'a purpose ref is a lower-case kebab slug');\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"redaction.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/compliance/privacy/redaction.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAiBxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEG;AACH,oBAAY,aAAa;IACvB,sJAAsJ;IACtJ,IAAI,SAAS;IACb,0GAA0G;IAC1G,MAAM,WAAW;IACjB,4JAA4J;IAC5J,IAAI,SAAS;IACb,iJAAiJ;IACjJ,OAAO,YAAY;IACnB,wGAAwG;IACxG,IAAI,SAAS;IACb;;;;;;;;;;;;;OAaG;IACH,KAAK,UAAU;CAChB;AACD,sEAAsE;AAGtE,eAAO,MAAM,mBAAmB;;;;;iBAK9B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
1
+ {"version":3,"file":"redaction.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../../src/compliance/privacy/redaction.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAiBxB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEG;AACH,oBAAY,aAAa;IACvB,sJAAsJ;IACtJ,IAAI,SAAS;IACb,0GAA0G;IAC1G,MAAM,WAAW;IACjB,4JAA4J;IAC5J,IAAI,SAAS;IACb,iJAAiJ;IACjJ,OAAO,YAAY;IACnB,wGAAwG;IACxG,IAAI,SAAS;IACb;;;;;;;;;;;;;OAaG;IACH,KAAK,UAAU;CAChB;AACD,sEAAsE;AAGtE,eAAO,MAAM,mBAAmB;;;;;iBAK9B,CAAC;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"redaction.shared.schemas.js","sourceRoot":"","sources":["../../../../src/compliance/privacy/redaction.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,oDAAoD,CAAC;AAEjF;;;;;;;;;;;;GAYG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEG;AACH,MAAM,CAAN,IAAY,aA0BX;AA1BD,WAAY,aAAa;IACvB,sJAAsJ;IACtJ,8BAAa,CAAA;IACb,0GAA0G;IAC1G,kCAAiB,CAAA;IACjB,4JAA4J;IAC5J,8BAAa,CAAA;IACb,iJAAiJ;IACjJ,oCAAmB,CAAA;IACnB,wGAAwG;IACxG,8BAAa,CAAA;IACb;;;;;;;;;;;;;OAaG;IACH,gCAAe,CAAA;AACjB,CAAC,EA1BW,aAAa,KAAb,aAAa,QA0BxB;AACD,sEAAsE;AAGtE,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,WAAW,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,4DAA4D;IACrG,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC;IACpC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,QAAQ,EAAE;CAC1C,CAAC,CAAC","sourcesContent":["import { z } from \"zod\";\nimport { RolesSchema } from \"../../security/authorizations/roles.shared.schemas\";\n\n/*\n * MAINTAINER NOTE — not part of the anchored, application-facing block below.\n *\n * One authority axis (D9): this vocabulary is shared by flow-actors `redactionRules` and by the\n * impersonalization `.impersonalizeWith()` treatment, deliberately, so the two cannot drift into two\n * spellings of the same idea. Adding a member is additive for both consumers — no exhaustive switch\n * reads it — EXCEPT `buildImpersonalizeScrubPatch`, whose `default` arm throws on purpose so a new\n * member fails loud in an erasure rather than being silently skipped.\n *\n * Reversible tokenization is intentionally NOT in v1 (D6 = irreversible). `ENCRYPT` stays the\n * existing reversible option for redaction, and a vault-backed `TOKENIZE` member can be added\n * additively if such a mode ships.\n */\n\n/**\n * @wildo_source:part:start saas.models.privacy.redaction-treatments facet:layer:shared facet:audience:app-developer\n *\n * How one field's value is replaced when it is redacted or scrubbed.\n *\n * Imported from `@wildo-ai/saas-models`.\n *\n * ## Two consumers, and only one of them accepts every member\n *\n * | consumer | what it does | accepts |\n * |---|---|---|\n * | flow-actors `redactionRules` | hides a value in a LOG or an API RESPONSE; the stored row is untouched | every member |\n * | `.impersonalizeWith(...)` on a schema field | ERASURE scrub: permanently rewrites the stored value when the person is erased and the row is retained | `REMOVE` · `MASK` · `RESET` · `KEEP` only |\n *\n * **`HASH` and `ENCRYPT` are accepted by the type and REFUSED at erasure time.** An erasure scrub is\n * one static write shared by every row in the batch, so `HASH` — which would have to hash each row's\n * own value — cannot be expressed and throws. `ENCRYPT` is reversible, and an erasure that can be\n * undone is not an erasure, so it is forbidden here and stays a redaction-only option. Both throw\n * when the erasure runs, not when you author the field, so choosing one leaves a resource that\n * configures cleanly and fails the first time somebody is erased.\n *\n * ## Choosing a treatment for an erasure scrub\n *\n * | the field | treatment |\n * |---|---|\n * | nullable, or `.nullish()` | `REMOVE` — writes `null`. The default choice. |\n * | a constrained string that cannot hold the default mask (`z.email()`, `z.uuid()`, `.min(n)`) | `MASK` with an explicit `maskValue` that satisfies the field's own schema |\n * | NON-nullable and carries a `.default()` — a counter, a settings object, a stage history, an array | `RESET` — writes what the schema says the field is when nobody has set it |\n * | the row's link to its tenant or its creator | nothing: the never-scrub floor already protects it |\n *\n * `RESET` is the one to reach for when the other two do not fit, and that case is common rather than\n * exotic: `REMOVE` writes `null`, which fails the strict re-parse of the row the erasure just wrote,\n * and `MASK` writes a string, which cannot express an array, a record, a number or a date.\n *\n * ⚠️ **`RESET` refuses a default that reads the clock.** `.default(() => new Date())` — or a literal\n * `.default(new Date())` evaluated when the module loads — makes the erasure write its OWN timestamp,\n * so a field such as `lastActiveAt` would record the erased person as active at the moment they were\n * erased. That fabricates information rather than removing it. Give the field a static neutral\n * default such as `new Date(0)`, which asserts \"no recorded value\", or make it nullable and use\n * `REMOVE`, which asserts \"unknown\". Those are different claims about a person; choose deliberately.\n *\n * ## The never-scrub floor\n *\n * A row's link to the organization or application it belongs to, and its `createdByUserId`, are\n * never scrubbed — even when a treatment is declared on them. They connect the retained row to the\n * tenant that must keep it, and nulling them would orphan the record the retention exists to\n * preserve. `KEEP` is the way to say the same thing explicitly about any other field.\n *\n * A field with NO `.impersonalizeWith()` is left untouched by an erasure. Declaring nothing is how a\n * legally required value — an invoice line, an amount, a date — survives the erasure of the person\n * the record names.\n *\n * @example Scrubbing a person out of a retained record\n * ```ts\n * import { RedactionType } from '@wildo-ai/saas-models';\n *\n * const contactSchema = z.object({\n * // nullable → REMOVE\n * phone: z.string().nullish().impersonalizeWith(RedactionType.REMOVE),\n * // constrained string → MASK with a value the field's own schema accepts\n * email: z.email().impersonalizeWith(RedactionType.MASK, { maskValue: 'erased@erased.invalid' }),\n * // non-nullable with a default → RESET\n * preferences: z.object({ digest: z.boolean() }).default({ digest: false })\n * .impersonalizeWith(RedactionType.RESET),\n * // no treatment → survives the erasure, deliberately\n * invoicedAmount: z.number(),\n * });\n * ```\n */\nexport enum RedactionType {\n /** Replace with a fixed mask. In an erasure scrub the value must satisfy the field's own schema — pass `maskValue` when the default mask does not. */\n MASK = 'mask',\n /** Remove / null the value. The default erasure scrub; requires a field that can actually hold `null`. */\n REMOVE = 'remove',\n /** Replace with a one-way hash. Redaction only — **throws** if an erasure scrub reaches it, because a scrub is one static write and cannot hash per row. */\n HASH = 'hash',\n /** Replace with a reversible ciphertext. Redaction only — **forbidden** for an erasure scrub, because a reversible erasure is not an erasure. */\n ENCRYPT = 'encrypt',\n /** Erasure scrub only: keep this field exactly as it is. The explicit form of the never-scrub floor. */\n KEEP = 'keep',\n /**\n * Erasure scrub only: reset the field to its OWN schema default.\n *\n * The treatment for a field that is non-nullable and carries a `.default()`, where neither of the\n * others reaches: `REMOVE` writes `null`, which fails the strict re-parse of the row the erasure\n * just wrote, and `MASK` writes a string, while these fields are arrays, records, numbers, dates\n * and objects.\n *\n * The value is read from the schema rather than authored a second time, so it cannot drift from\n * the default the field already declares — and for a person's counters and settings, \"what this is\n * when nobody has set it\" is exactly what an erasure should leave behind.\n *\n * Refused when the field declares no `.default()`, and refused when that default reads the clock.\n */\n RESET = 'reset',\n}\n/** @wildo_source:part:end saas.models.privacy.redaction-treatments */\n\n\nexport const RedationRulesSchema = z.object({\n fieldPath: z.string(),\n isRecursive: z.boolean().default(false), // default false - if true, will redaction all nested fields\n redactionType: z.enum(RedactionType),\n forRoles: z.array(RolesSchema).optional(),\n});\n\nexport type RedationRules = z.infer<typeof RedationRulesSchema>;\n"]}
1
+ {"version":3,"file":"redaction.shared.schemas.js","sourceRoot":"","sources":["../../../../../src/compliance/privacy/redaction.shared.schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,WAAW,EAAE,MAAM,oDAAoD,CAAC;AAEjF;;;;;;;;;;;;GAYG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoEG;AACH,MAAM,CAAN,IAAY,aA0BX;AA1BD,WAAY,aAAa;IACvB,sJAAsJ;IACtJ,8BAAa,CAAA;IACb,0GAA0G;IAC1G,kCAAiB,CAAA;IACjB,4JAA4J;IAC5J,8BAAa,CAAA;IACb,iJAAiJ;IACjJ,oCAAmB,CAAA;IACnB,wGAAwG;IACxG,8BAAa,CAAA;IACb;;;;;;;;;;;;;OAaG;IACH,gCAAe,CAAA;AACjB,CAAC,EA1BW,aAAa,KAAb,aAAa,QA0BxB;AACD,sEAAsE;AAGtE,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1C,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,WAAW,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,4DAA4D;IACrG,aAAa,EAAE,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC;IACpC,QAAQ,EAAE,CAAC,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC,QAAQ,EAAE;CAC1C,CAAC,CAAC","sourcesContent":["import { z } from \"zod\";\nimport { RolesSchema } from \"../../security/authorizations/roles.shared.schemas\";\n\n/*\n * MAINTAINER NOTE — not part of the anchored, application-facing block below.\n *\n * One authority axis (D9): this vocabulary is shared by flow-actors `redactionRules` and by the\n * impersonalization `.impersonalizeWith()` treatment, deliberately, so the two cannot drift into two\n * spellings of the same idea. Adding a member is additive for both consumers — no exhaustive switch\n * reads it — EXCEPT `buildImpersonalizeScrubPatch`, whose `default` arm throws on purpose so a new\n * member fails loud in an erasure rather than being silently skipped.\n *\n * Reversible tokenization is intentionally NOT in v1 (D6 = irreversible). `ENCRYPT` stays the\n * existing reversible option for redaction, and a vault-backed `TOKENIZE` member can be added\n * additively if such a mode ships.\n */\n\n/**\n * @wildo_source:part:start saas.models.privacy.redaction-treatments facet:layer:shared facet:audience:app-developer\n *\n * How one field's value is replaced when it is redacted or scrubbed.\n *\n * Imported from `@wildo-ai/saas-models`.\n *\n * ## Two consumers, and only one of them accepts every member\n *\n * | consumer | what it does | accepts |\n * |---|---|---|\n * | flow-actors `redactionRules` | hides a value in a LOG or an API RESPONSE; the stored row is untouched | every member |\n * | `.impersonalizeWith(...)` on a schema field | ERASURE scrub: permanently rewrites the stored value when the person is erased and the row is retained | `REMOVE` · `MASK` · `RESET` · `KEEP` only |\n *\n * **`HASH` and `ENCRYPT` are accepted by the type and REFUSED at erasure time.** An erasure scrub is\n * one static write shared by every row in the batch, so `HASH` — which would have to hash each row's\n * own value — cannot be expressed and throws. `ENCRYPT` is reversible, and an erasure that can be\n * undone is not an erasure, so it is forbidden here and stays a redaction-only option. Both throw\n * when the erasure runs, not when you author the field, so choosing one leaves a resource that\n * configures cleanly and fails the first time somebody is erased.\n *\n * ## Choosing a treatment for an erasure scrub\n *\n * | the field | treatment |\n * |---|---|\n * | nullable, or `.nullish()` | `REMOVE` — writes `null`. The default choice. |\n * | a constrained string that cannot hold the default mask (`z.email()`, `z.uuid()`, `.min(n)`) | `MASK` with an explicit `maskValue` that satisfies the field's own schema |\n * | NON-nullable and carries a `.default()` — a counter, a settings object, a stage history, an array | `RESET` — writes what the schema says the field is when nobody has set it |\n * | the row's link to its tenant or its creator | nothing: the never-scrub floor already protects it |\n *\n * `RESET` is the one to reach for when the other two do not fit, and that case is common rather than\n * exotic: `REMOVE` writes `null`, which fails the strict re-parse of the row the erasure just wrote,\n * and `MASK` writes a string, which cannot express an array, a record, a number or a date.\n *\n * ⚠️ **`RESET` refuses a default that reads the clock.** `.default(() => new Date())` — or a literal\n * `.default(new Date())` evaluated when the module loads — makes the erasure write its OWN timestamp,\n * so a field such as `lastActiveAt` would record the erased person as active at the moment they were\n * erased. That fabricates information rather than removing it. Give the field a static neutral\n * default such as `new Date(0)`, which asserts \"no recorded value\", or make it nullable and use\n * `REMOVE`, which asserts \"unknown\". Those are different claims about a person; choose deliberately.\n *\n * ## The never-scrub floor\n *\n * A row's link to the organization or application it belongs to, and its `createdByUserId`, are\n * never scrubbed — even when a treatment is declared on them. They connect the retained row to the\n * tenant that must keep it, and nulling them would orphan the record the retention exists to\n * preserve. `KEEP` is the way to say the same thing explicitly about any other field.\n *\n * A field with NO `.impersonalizeWith()` is left untouched by an erasure. Declaring nothing is how a\n * legally required value — an invoice line, an amount, a date — survives the erasure of the person\n * the record names.\n *\n * @example Scrubbing a person out of a retained record\n * ```ts\n * import { RedactionType } from '@wildo-ai/saas-models';\n *\n * const contactSchema = z.object({\n * // nullable → REMOVE\n * phone: z.string().nullish().impersonalizeWith(RedactionType.REMOVE),\n * // constrained string → MASK with a value the field's own schema accepts\n * email: z.email().impersonalizeWith(RedactionType.MASK, { maskValue: 'erased@erased.invalid' }),\n * // non-nullable with a default → RESET\n * preferences: z.object({ digest: z.boolean() }).default({ digest: false })\n * .impersonalizeWith(RedactionType.RESET),\n * // no treatment → survives the erasure, deliberately\n * invoicedAmount: z.number(),\n * });\n * ```\n */\nexport enum RedactionType {\n /** Replace with a fixed mask. In an erasure scrub the value must satisfy the field's own schema — pass `maskValue` when the default mask does not. */\n MASK = 'mask',\n /** Remove / null the value. The default erasure scrub; requires a field that can actually hold `null`. */\n REMOVE = 'remove',\n /** Replace with a one-way hash. Redaction only — **throws** if an erasure scrub reaches it, because a scrub is one static write and cannot hash per row. */\n HASH = 'hash',\n /** Replace with a reversible ciphertext. Redaction only — **forbidden** for an erasure scrub, because a reversible erasure is not an erasure. */\n ENCRYPT = 'encrypt',\n /** Erasure scrub only: keep this field exactly as it is. The explicit form of the never-scrub floor. */\n KEEP = 'keep',\n /**\n * Erasure scrub only: reset the field to its OWN schema default.\n *\n * The treatment for a field that is non-nullable and carries a `.default()`, where neither of the\n * others reaches: `REMOVE` writes `null`, which fails the strict re-parse of the row the erasure\n * just wrote, and `MASK` writes a string, while these fields are arrays, records, numbers, dates\n * and objects.\n *\n * The value is read from the schema rather than authored a second time, so it cannot drift from\n * the default the field already declares — and for a person's counters and settings, \"what this is\n * when nobody has set it\" is exactly what an erasure should leave behind.\n *\n * Refused when the field declares no `.default()`, and refused when that default reads the clock.\n */\n RESET = 'reset',\n}\n/** @wildo_source:part:end saas.models.privacy.redaction-treatments */\n\n\nexport const RedationRulesSchema = z.object({\n fieldPath: z.string(),\n isRecursive: z.boolean().default(false), // default false - if true, will redaction all nested fields\n redactionType: z.enum(RedactionType),\n forRoles: z.array(RolesSchema).optional(),\n});\n\nexport type RedationRules = z.infer<typeof RedationRulesSchema>;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"retention-binding.shared.utils.d.ts","sourceRoot":"","sources":["../../../../src/compliance/privacy/retention-binding.shared.utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,OAAO,EAGL,KAAK,4BAA4B,EACjC,KAAK,wBAAwB,EAC9B,MAAM,qCAAqC,CAAC;AAsB7C,wEAAwE;AACxE,eAAO,MAAM,+BAA+B,cAAc,CAAC;AAC3D,2EAA2E;AAC3E,eAAO,MAAM,+BAA+B,cAAc,CAAC;AAE3D;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,wBAAwB,GAAG,MAAM,CAexF;AAYD;;;;;;;;;;GAUG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;CACvB;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,wBAAwB,EACjC,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,IAAI,GACR,oBAAoB,CAOtB;AASD;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,OAAO,EAAE,wBAAwB,GAChC,IAAI,GAAG,SAAS,CAIlB;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,OAAO,EAAE,wBAAwB,EACjC,QAAQ,EAAE,4BAA4B,GAAG,SAAS,GACjD,IAAI,GAAG,SAAS,CAKlB;AAMD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACrC;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,CAAC,CAAC,UAAU,GAAG,YAAY,EAAE,CAgB9E;AAMD,qHAAqH;AACrH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,wBAAwB,CAAC;IACrD,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE;IAAE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAE9H;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,QAAQ,CAAC,wBAAwB,CAAC,GAAG,SAAS,MAAM,EAAE,CAO1G"}
1
+ {"version":3,"file":"retention-binding.shared.utils.d.ts","sourceRoot":"","sources":["../../../../../src/compliance/privacy/retention-binding.shared.utils.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAE7B,OAAO,EAGL,KAAK,4BAA4B,EACjC,KAAK,wBAAwB,EAC9B,MAAM,qCAAqC,CAAC;AAsB7C,wEAAwE;AACxE,eAAO,MAAM,+BAA+B,cAAc,CAAC;AAC3D,2EAA2E;AAC3E,eAAO,MAAM,+BAA+B,cAAc,CAAC;AAE3D;;;;;;;GAOG;AACH,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,wBAAwB,GAAG,MAAM,CAexF;AAYD;;;;;;;;;;GAUG;AACH,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;CACvB;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,wBAAwB,EACjC,aAAa,EAAE,MAAM,EACrB,GAAG,EAAE,IAAI,GACR,oBAAoB,CAOtB;AASD;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,OAAO,EAAE,wBAAwB,GAChC,IAAI,GAAG,SAAS,CAIlB;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC5B,OAAO,EAAE,wBAAwB,EACjC,QAAQ,EAAE,4BAA4B,GAAG,SAAS,GACjD,IAAI,GAAG,SAAS,CAKlB;AAMD;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;CACrC;AAED;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,CAAC,CAAC,UAAU,GAAG,YAAY,EAAE,CAgB9E;AAMD,qHAAqH;AACrH,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,kBAAkB,EAAE,MAAM,CAAC;IACpC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,wBAAwB,CAAC;IACrD,QAAQ,CAAC,UAAU,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE;IAAE,QAAQ,CAAC,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAE9H;AAED;;;;;;;;;GASG;AACH,wBAAgB,yBAAyB,CAAC,SAAS,EAAE,QAAQ,CAAC,wBAAwB,CAAC,GAAG,SAAS,MAAM,EAAE,CAO1G"}
@@ -1 +1 @@
1
- {"version":3,"file":"retention-binding.shared.utils.js","sourceRoot":"","sources":["../../../../src/compliance/privacy/retention-binding.shared.utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { getTtlParams, getZodObjectShape, hasTtl } from '@wildo-ai/zod-decorators';\nimport type { z } from 'zod';\n\nimport {\n RETENTION_STARTED_AT_FIELD_NAME,\n RetentionStartPoint,\n type ApplicationRetentionSchedule,\n type ResourceRetentionBinding,\n} from './retention-schedule.shared.schemas';\n\n/**\n * # Retention binding derivations — one authority for \"when does a bound row expire\"\n *\n * Every consumer of a retention binding asks one of four questions, and each is answered here once:\n *\n * | question | function | consumers |\n * |---|---|---|\n * | which field carries the start instant? | {@link resolveRetentionStartFieldName} | the sweep's query, the factory's field checks |\n * | which rows are past their period now? | {@link resolveBoundRetentionCutoff} | the sweep, the startup past-expiry report |\n * | when did THIS row's clock start / when does it end? | {@link resolveRetentionStartedAt} / {@link resolveRetentionExpiresAt} | subject erasure's `retainedUntil` (#1635), deletion evidence (#1636) |\n * | which resources hold data nobody bound? | {@link unboundRetentionResources} | compliance documents, the startup report |\n *\n * Pure and adapter-neutral: the cutoff is a single `field < instant` comparison, which MongoDB and both\n * PostgreSQL filter compilers evaluate identically — and a NULL start instant matches neither, which is\n * exactly \"a row whose start point has not occurred never expires\" (#1613 invariant 2), by construction\n * rather than by a guard somebody could forget.\n */\n\nconst MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;\n\n/** The infrastructure-owned creation instant both adapters maintain. */\nexport const RETENTION_CREATED_AT_FIELD_NAME = 'createdAt';\n/** The infrastructure-owned last-update instant both adapters maintain. */\nexport const RETENTION_UPDATED_AT_FIELD_NAME = 'updatedAt';\n\n/**\n * The field whose value is a bound row's retention start instant (or, for\n * {@link RetentionStartPoint.END_OF_CALENDAR_YEAR}, the instant the start is derived from).\n *\n * Throws for a {@link RetentionStartPoint.CLOSURE_EVENT} binding with no `closureFieldName`: the factory\n * refuses that configuration, so reaching it here means a binding bypassed the factory, and guessing a\n * field would delete rows by the wrong clock.\n */\nexport function resolveRetentionStartFieldName(binding: ResourceRetentionBinding): string {\n switch (binding.startPoint) {\n case RetentionStartPoint.CREATED:\n case RetentionStartPoint.END_OF_CALENDAR_YEAR:\n return RETENTION_CREATED_AT_FIELD_NAME;\n case RetentionStartPoint.LAST_UPDATED:\n return RETENTION_UPDATED_AT_FIELD_NAME;\n case RetentionStartPoint.SCOPE_DELETED:\n return RETENTION_STARTED_AT_FIELD_NAME;\n case RetentionStartPoint.CLOSURE_EVENT:\n if (!binding.closureFieldName) {\n throw new Error('A CLOSURE_EVENT retention binding must name its closureFieldName.');\n }\n return binding.closureFieldName;\n }\n}\n\n/** The instant 00:00:00.000 UTC on 1 January of `instant`'s UTC year. */\nfunction startOfUtcYear(instant: Date): Date {\n return new Date(Date.UTC(instant.getUTCFullYear(), 0, 1));\n}\n\n/** The last millisecond of `instant`'s UTC year: 31 December 23:59:59.999 UTC. */\nfunction endOfUtcYear(instant: Date): Date {\n return new Date(Date.UTC(instant.getUTCFullYear() + 1, 0, 1) - 1);\n}\n\n/**\n * The rows a bound resource must delete at `now`: those whose {@link BoundRetentionCutoff.fieldName} is\n * STRICTLY before {@link BoundRetentionCutoff.before}.\n *\n * A row is deleted only AFTER `start + retentionDays`, never at it: a row whose start is exactly\n * `now − retentionDays` has reached the end of its period and not passed it, so it survives this run.\n *\n * For {@link RetentionStartPoint.END_OF_CALENDAR_YEAR} the comparison is still on `createdAt`, rewritten\n * so no per-row arithmetic is needed: `endOfYear(createdAt) + days < now` holds exactly when `createdAt`\n * falls in a year BEFORE the year of `now − days`, i.e. `createdAt < 1 January (UTC) of year(now − days)`.\n */\nexport interface BoundRetentionCutoff {\n readonly fieldName: string;\n readonly before: Date;\n}\n\nexport function resolveBoundRetentionCutoff(\n binding: ResourceRetentionBinding,\n retentionDays: number,\n now: Date,\n): BoundRetentionCutoff {\n const fieldName = resolveRetentionStartFieldName(binding);\n const periodStartedBefore = new Date(now.getTime() - retentionDays * MILLISECONDS_PER_DAY);\n if (binding.startPoint === RetentionStartPoint.END_OF_CALENDAR_YEAR) {\n return { fieldName, before: startOfUtcYear(periodStartedBefore) };\n }\n return { fieldName, before: periodStartedBefore };\n}\n\nfunction readInstant(row: Record<string, unknown>, fieldName: string): Date | undefined {\n const value = row[fieldName];\n if (value === null || value === undefined) return undefined;\n const instant = value instanceof Date ? value : new Date(value as string | number);\n return Number.isNaN(instant.getTime()) ? undefined : instant;\n}\n\n/**\n * When `row`'s retention clock started, or `undefined` while its start point has not occurred (an open\n * CLOSURE_EVENT row, a SCOPE_DELETED row whose organization still exists).\n */\nexport function resolveRetentionStartedAt(\n row: Record<string, unknown>,\n binding: ResourceRetentionBinding,\n): Date | undefined {\n const instant = readInstant(row, resolveRetentionStartFieldName(binding));\n if (!instant) return undefined;\n return binding.startPoint === RetentionStartPoint.END_OF_CALENDAR_YEAR ? endOfUtcYear(instant) : instant;\n}\n\n/**\n * The instant after which `row` is deleted under the CURRENT schedule, or `undefined` when its start\n * point has not occurred or its class declares no period (undeclared is \"not decided\", never \"now\").\n */\nexport function resolveRetentionExpiresAt(\n row: Record<string, unknown>,\n binding: ResourceRetentionBinding,\n schedule: ApplicationRetentionSchedule | undefined,\n): Date | undefined {\n const period = schedule?.[binding.retentionClass];\n const startedAt = resolveRetentionStartedAt(row, binding);\n if (!period || !startedAt) return undefined;\n return new Date(startedAt.getTime() + period.retentionDays * MILLISECONDS_PER_DAY);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────────────────────────\n// Row TTL — the OTHER retention authority, kept for framework plumbing that holds no business data\n// ─────────────────────────────────────────────────────────────────────────────────────────────────\n\n/**\n * A declared `.ttl()` ROW-EXPIRY policy: rows expire `expireAfterSeconds` after `fieldName`'s value.\n *\n * `expireAfterSeconds: 0` means the field IS the absolute expiry instant (`jobPayloadStorage.expiresAt`);\n * a positive value is a window measured from the field (`jobExecutions.createdAt`). These are MongoDB's\n * `expireAfterSeconds` semantics verbatim, so one declaration cannot mean two things per adapter.\n *\n * Distinct from a {@link ResourceRetentionBinding} on purpose: `.ttl()` is a fixed number of seconds on a\n * field, for framework plumbing that holds no business or personal data, and MongoDB honours it NATIVELY\n * with no application code running. A resource holding such data binds a class instead, and a resource\n * may not declare both (one row, one retention authority).\n */\nexport interface RowTtlPolicy {\n readonly fieldName: string;\n readonly expireAfterSeconds: number;\n}\n\n/**\n * Every `.ttl()` declaration on a resource's main schema — ONE authority, read by the SQL planner, the\n * `.ttl()` sweep, the startup refusals and the resource factory.\n *\n * Tolerates a non-object schema (it declares no fields, so no TTL): this is called while enumerating\n * EVERY registered resource, and one exotic schema must not take the enumeration down.\n */\nexport function collectRowTtlPolicies(mainSchema: z.ZodTypeAny): RowTtlPolicy[] {\n let shape: Record<string, z.ZodTypeAny> | undefined;\n try {\n shape = getZodObjectShape(mainSchema as never) as Record<string, z.ZodTypeAny>;\n } catch {\n return [];\n }\n if (!shape) return [];\n const policies: RowTtlPolicy[] = [];\n for (const [fieldName, fieldSchema] of Object.entries(shape)) {\n if (!fieldSchema || !hasTtl(fieldSchema)) continue;\n const params = getTtlParams(fieldSchema);\n if (!params) continue;\n policies.push({ fieldName, expireAfterSeconds: params.expireAfterSeconds });\n }\n return policies;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────────────────────────\n// The gap report\n// ─────────────────────────────────────────────────────────────────────────────────────────────────\n\n/** The part of a resource configuration the gap report reads. Structural, so it takes a registry's configs as-is. */\nexport interface RetentionBindingGapInput {\n readonly resourceIdentifier: string;\n readonly retentionBinding?: ResourceRetentionBinding;\n readonly mainSchema?: unknown;\n}\n\n/**\n * THE rule for \"kept until erased\": a resource no retention mechanism ever deletes has no class binding\n * and no `.ttl()`. One predicate, so the startup report (which reads schemas) and the RETENTION_RULES\n * document fact (which receives `declaresRowTtl` across a JSON boundary) cannot disagree about who is in\n * the list.\n */\nexport function isKeptUntilErased(resource: { readonly retentionBinding?: unknown; readonly declaresRowTtl: boolean }): boolean {\n return !resource.retentionBinding && !resource.declaresRowTtl;\n}\n\n/**\n * The resources whose rows no retention mechanism ever deletes: no class binding and no `.ttl()`.\n *\n * Kept until erased. That is today's behaviour for every unbound resource and is not wrong in itself —\n * it is UNDECIDED, and this report is what keeps it visible next to `undeclaredRetentionClasses`, in the\n * compliance documents and in the startup log. Rejected: defaulting every unbound resource to\n * `RESOURCE_DATA`. That would silently delete data nobody decided about.\n *\n * Sorted, so two runs over the same registry produce the same list.\n */\nexport function unboundRetentionResources(resources: Iterable<RetentionBindingGapInput>): readonly string[] {\n const unbound: string[] = [];\n for (const resource of resources) {\n const declaresRowTtl = Boolean(resource.mainSchema) && collectRowTtlPolicies(resource.mainSchema as z.ZodTypeAny).length > 0;\n if (isKeptUntilErased({ retentionBinding: resource.retentionBinding, declaresRowTtl })) unbound.push(resource.resourceIdentifier);\n }\n return unbound.sort();\n}\n"]}
1
+ {"version":3,"file":"retention-binding.shared.utils.js","sourceRoot":"","sources":["../../../../../src/compliance/privacy/retention-binding.shared.utils.ts"],"names":[],"mappings":"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","sourcesContent":["import { getTtlParams, getZodObjectShape, hasTtl } from '@wildo-ai/zod-decorators';\nimport type { z } from 'zod';\n\nimport {\n RETENTION_STARTED_AT_FIELD_NAME,\n RetentionStartPoint,\n type ApplicationRetentionSchedule,\n type ResourceRetentionBinding,\n} from './retention-schedule.shared.schemas';\n\n/**\n * # Retention binding derivations — one authority for \"when does a bound row expire\"\n *\n * Every consumer of a retention binding asks one of four questions, and each is answered here once:\n *\n * | question | function | consumers |\n * |---|---|---|\n * | which field carries the start instant? | {@link resolveRetentionStartFieldName} | the sweep's query, the factory's field checks |\n * | which rows are past their period now? | {@link resolveBoundRetentionCutoff} | the sweep, the startup past-expiry report |\n * | when did THIS row's clock start / when does it end? | {@link resolveRetentionStartedAt} / {@link resolveRetentionExpiresAt} | subject erasure's `retainedUntil` (#1635), deletion evidence (#1636) |\n * | which resources hold data nobody bound? | {@link unboundRetentionResources} | compliance documents, the startup report |\n *\n * Pure and adapter-neutral: the cutoff is a single `field < instant` comparison, which MongoDB and both\n * PostgreSQL filter compilers evaluate identically — and a NULL start instant matches neither, which is\n * exactly \"a row whose start point has not occurred never expires\" (#1613 invariant 2), by construction\n * rather than by a guard somebody could forget.\n */\n\nconst MILLISECONDS_PER_DAY = 24 * 60 * 60 * 1000;\n\n/** The infrastructure-owned creation instant both adapters maintain. */\nexport const RETENTION_CREATED_AT_FIELD_NAME = 'createdAt';\n/** The infrastructure-owned last-update instant both adapters maintain. */\nexport const RETENTION_UPDATED_AT_FIELD_NAME = 'updatedAt';\n\n/**\n * The field whose value is a bound row's retention start instant (or, for\n * {@link RetentionStartPoint.END_OF_CALENDAR_YEAR}, the instant the start is derived from).\n *\n * Throws for a {@link RetentionStartPoint.CLOSURE_EVENT} binding with no `closureFieldName`: the factory\n * refuses that configuration, so reaching it here means a binding bypassed the factory, and guessing a\n * field would delete rows by the wrong clock.\n */\nexport function resolveRetentionStartFieldName(binding: ResourceRetentionBinding): string {\n switch (binding.startPoint) {\n case RetentionStartPoint.CREATED:\n case RetentionStartPoint.END_OF_CALENDAR_YEAR:\n return RETENTION_CREATED_AT_FIELD_NAME;\n case RetentionStartPoint.LAST_UPDATED:\n return RETENTION_UPDATED_AT_FIELD_NAME;\n case RetentionStartPoint.SCOPE_DELETED:\n return RETENTION_STARTED_AT_FIELD_NAME;\n case RetentionStartPoint.CLOSURE_EVENT:\n if (!binding.closureFieldName) {\n throw new Error('A CLOSURE_EVENT retention binding must name its closureFieldName.');\n }\n return binding.closureFieldName;\n }\n}\n\n/** The instant 00:00:00.000 UTC on 1 January of `instant`'s UTC year. */\nfunction startOfUtcYear(instant: Date): Date {\n return new Date(Date.UTC(instant.getUTCFullYear(), 0, 1));\n}\n\n/** The last millisecond of `instant`'s UTC year: 31 December 23:59:59.999 UTC. */\nfunction endOfUtcYear(instant: Date): Date {\n return new Date(Date.UTC(instant.getUTCFullYear() + 1, 0, 1) - 1);\n}\n\n/**\n * The rows a bound resource must delete at `now`: those whose {@link BoundRetentionCutoff.fieldName} is\n * STRICTLY before {@link BoundRetentionCutoff.before}.\n *\n * A row is deleted only AFTER `start + retentionDays`, never at it: a row whose start is exactly\n * `now − retentionDays` has reached the end of its period and not passed it, so it survives this run.\n *\n * For {@link RetentionStartPoint.END_OF_CALENDAR_YEAR} the comparison is still on `createdAt`, rewritten\n * so no per-row arithmetic is needed: `endOfYear(createdAt) + days < now` holds exactly when `createdAt`\n * falls in a year BEFORE the year of `now − days`, i.e. `createdAt < 1 January (UTC) of year(now − days)`.\n */\nexport interface BoundRetentionCutoff {\n readonly fieldName: string;\n readonly before: Date;\n}\n\nexport function resolveBoundRetentionCutoff(\n binding: ResourceRetentionBinding,\n retentionDays: number,\n now: Date,\n): BoundRetentionCutoff {\n const fieldName = resolveRetentionStartFieldName(binding);\n const periodStartedBefore = new Date(now.getTime() - retentionDays * MILLISECONDS_PER_DAY);\n if (binding.startPoint === RetentionStartPoint.END_OF_CALENDAR_YEAR) {\n return { fieldName, before: startOfUtcYear(periodStartedBefore) };\n }\n return { fieldName, before: periodStartedBefore };\n}\n\nfunction readInstant(row: Record<string, unknown>, fieldName: string): Date | undefined {\n const value = row[fieldName];\n if (value === null || value === undefined) return undefined;\n const instant = value instanceof Date ? value : new Date(value as string | number);\n return Number.isNaN(instant.getTime()) ? undefined : instant;\n}\n\n/**\n * When `row`'s retention clock started, or `undefined` while its start point has not occurred (an open\n * CLOSURE_EVENT row, a SCOPE_DELETED row whose organization still exists).\n */\nexport function resolveRetentionStartedAt(\n row: Record<string, unknown>,\n binding: ResourceRetentionBinding,\n): Date | undefined {\n const instant = readInstant(row, resolveRetentionStartFieldName(binding));\n if (!instant) return undefined;\n return binding.startPoint === RetentionStartPoint.END_OF_CALENDAR_YEAR ? endOfUtcYear(instant) : instant;\n}\n\n/**\n * The instant after which `row` is deleted under the CURRENT schedule, or `undefined` when its start\n * point has not occurred or its class declares no period (undeclared is \"not decided\", never \"now\").\n */\nexport function resolveRetentionExpiresAt(\n row: Record<string, unknown>,\n binding: ResourceRetentionBinding,\n schedule: ApplicationRetentionSchedule | undefined,\n): Date | undefined {\n const period = schedule?.[binding.retentionClass];\n const startedAt = resolveRetentionStartedAt(row, binding);\n if (!period || !startedAt) return undefined;\n return new Date(startedAt.getTime() + period.retentionDays * MILLISECONDS_PER_DAY);\n}\n\n// ─────────────────────────────────────────────────────────────────────────────────────────────────\n// Row TTL — the OTHER retention authority, kept for framework plumbing that holds no business data\n// ─────────────────────────────────────────────────────────────────────────────────────────────────\n\n/**\n * A declared `.ttl()` ROW-EXPIRY policy: rows expire `expireAfterSeconds` after `fieldName`'s value.\n *\n * `expireAfterSeconds: 0` means the field IS the absolute expiry instant (`jobPayloadStorage.expiresAt`);\n * a positive value is a window measured from the field (`jobExecutions.createdAt`). These are MongoDB's\n * `expireAfterSeconds` semantics verbatim, so one declaration cannot mean two things per adapter.\n *\n * Distinct from a {@link ResourceRetentionBinding} on purpose: `.ttl()` is a fixed number of seconds on a\n * field, for framework plumbing that holds no business or personal data, and MongoDB honours it NATIVELY\n * with no application code running. A resource holding such data binds a class instead, and a resource\n * may not declare both (one row, one retention authority).\n */\nexport interface RowTtlPolicy {\n readonly fieldName: string;\n readonly expireAfterSeconds: number;\n}\n\n/**\n * Every `.ttl()` declaration on a resource's main schema — ONE authority, read by the SQL planner, the\n * `.ttl()` sweep, the startup refusals and the resource factory.\n *\n * Tolerates a non-object schema (it declares no fields, so no TTL): this is called while enumerating\n * EVERY registered resource, and one exotic schema must not take the enumeration down.\n */\nexport function collectRowTtlPolicies(mainSchema: z.ZodTypeAny): RowTtlPolicy[] {\n let shape: Record<string, z.ZodTypeAny> | undefined;\n try {\n shape = getZodObjectShape(mainSchema as never) as Record<string, z.ZodTypeAny>;\n } catch {\n return [];\n }\n if (!shape) return [];\n const policies: RowTtlPolicy[] = [];\n for (const [fieldName, fieldSchema] of Object.entries(shape)) {\n if (!fieldSchema || !hasTtl(fieldSchema)) continue;\n const params = getTtlParams(fieldSchema);\n if (!params) continue;\n policies.push({ fieldName, expireAfterSeconds: params.expireAfterSeconds });\n }\n return policies;\n}\n\n// ─────────────────────────────────────────────────────────────────────────────────────────────────\n// The gap report\n// ─────────────────────────────────────────────────────────────────────────────────────────────────\n\n/** The part of a resource configuration the gap report reads. Structural, so it takes a registry's configs as-is. */\nexport interface RetentionBindingGapInput {\n readonly resourceIdentifier: string;\n readonly retentionBinding?: ResourceRetentionBinding;\n readonly mainSchema?: unknown;\n}\n\n/**\n * THE rule for \"kept until erased\": a resource no retention mechanism ever deletes has no class binding\n * and no `.ttl()`. One predicate, so the startup report (which reads schemas) and the RETENTION_RULES\n * document fact (which receives `declaresRowTtl` across a JSON boundary) cannot disagree about who is in\n * the list.\n */\nexport function isKeptUntilErased(resource: { readonly retentionBinding?: unknown; readonly declaresRowTtl: boolean }): boolean {\n return !resource.retentionBinding && !resource.declaresRowTtl;\n}\n\n/**\n * The resources whose rows no retention mechanism ever deletes: no class binding and no `.ttl()`.\n *\n * Kept until erased. That is today's behaviour for every unbound resource and is not wrong in itself —\n * it is UNDECIDED, and this report is what keeps it visible next to `undeclaredRetentionClasses`, in the\n * compliance documents and in the startup log. Rejected: defaulting every unbound resource to\n * `RESOURCE_DATA`. That would silently delete data nobody decided about.\n *\n * Sorted, so two runs over the same registry produce the same list.\n */\nexport function unboundRetentionResources(resources: Iterable<RetentionBindingGapInput>): readonly string[] {\n const unbound: string[] = [];\n for (const resource of resources) {\n const declaresRowTtl = Boolean(resource.mainSchema) && collectRowTtlPolicies(resource.mainSchema as z.ZodTypeAny).length > 0;\n if (isKeptUntilErased({ retentionBinding: resource.retentionBinding, declaresRowTtl })) unbound.push(resource.resourceIdentifier);\n }\n return unbound.sort();\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"retention-enforcement-records.shared.resources-config.schemas.d.ts","sourceRoot":"","sources":["../../../../src/compliance/privacy/retention-enforcement-records.shared.resources-config.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAAE,qBAAqB,EAAwD,MAAM,mDAAmD,CAAC;AAChJ,OAAO,EAA4D,oBAAoB,EAAE,MAAM,0CAA0C,CAAC;AAG1I,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC9F,OAAO,EAAE,2BAA2B,EAAoC,MAAM,gDAAgD,CAAC;AAE/H,eAAO,MAAM,sEAAsE,GACjF,wBAAwB,oBAAoB,EAAE;;;;;;;;;;;;;;;;;;;;kBAsF9C,CAAC"}
1
+ {"version":3,"file":"retention-enforcement-records.shared.resources-config.schemas.d.ts","sourceRoot":"","sources":["../../../../../src/compliance/privacy/retention-enforcement-records.shared.resources-config.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,EAAE,qBAAqB,EAAwD,MAAM,mDAAmD,CAAC;AAChJ,OAAO,EAA4D,oBAAoB,EAAE,MAAM,0CAA0C,CAAC;AAG1I,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAC9F,OAAO,EAAE,2BAA2B,EAAoC,MAAM,gDAAgD,CAAC;AAE/H,eAAO,MAAM,sEAAsE,GACjF,wBAAwB,oBAAoB,EAAE;;;;;;;;;;;;;;;;;;;;kBAsF9C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"retention-enforcement-records.shared.resources-config.schemas.js","sourceRoot":"","sources":["../../../../src/compliance/privacy/retention-enforcement-records.shared.resources-config.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Retention-enforcement records: resource configuration (#1636).\n *\n * ONE writer and two readers:\n * - the writer is the retention-class sweep, through the repository (`CREATE` is `REPOSITORY_ONLY`, so no\n * route creates a record). It uses the repository rather than the trusted-system-write primitive on\n * purpose, for the provider-call-records reason: `createAsSystem` emits a `SYSTEM_CONTEXT_WRITE` audit row\n * per call, and the run already emits ONE `RETENTION_ENFORCEMENT_RECORDED` event carrying its totals.\n * - the application administration console reads them (`READ`/`LIST` are `API_CALL`) — the operator's view\n * of whether each declared period is being enforced;\n * - the retention-enforcement evidence door reads a window of them for an assurance collector.\n *\n * APPEND-ONLY: there is no UPDATE. A run happened; a later run is a new row. `DELETE_MANY` exists only for\n * the retention-class sweep itself, which deletes records past the application's declared `AUDIT_LOGS`\n * period, and it is `INTERNAL_CALL`, so enforcing retention on the evidence creates no public deletion route.\n */\nimport { z } from 'zod';\n\nimport { createResourceConfiguration_Initialization } from '../../resources/resources-config.shared.factory';\nimport { ResourceSystemAccessMode } from '../../resources/resources-config.shared.schemas';\nimport { CoreResourceOperation, CoreResourceType, coreResourceShared_FieldIdentifier } from '../../resources/resources.shared.core.definitions';\nimport { ResourceOperationRiskLevel, ResourceOperationVariantType, ResourceRelationship } from '../../resources/resources.shared.schemas';\nimport { CORE_APP_ROLES } from '../../security/authorizations/roles.shared.schemas';\nimport { APPLICATION_AUDIT_LOG_READ_ROLES } from '../audit-trails/application-audit-logs.shared.resources-config.schemas';\nimport { DataRetentionClass, RetentionStartPoint } from './retention-schedule.shared.schemas';\nimport { RetentionEnforcementOutcome, RetentionEnforcementRecordSchema } from './retention-enforcement-records.shared.schemas';\n\nexport const retentionEnforcementRecordsResourceConfiguration_InitializationFactory = (\n resourcesRelationships: ResourceRelationship[],\n) => createResourceConfiguration_Initialization<undefined,\n CoreResourceOperation.CREATE | CoreResourceOperation.READ | CoreResourceOperation.LIST | CoreResourceOperation.DELETE_MANY,\n typeof RetentionEnforcementRecordSchema\n>({\n mainSchema: RetentionEnforcementRecordSchema,\n resourceIdentifier: CoreResourceType.RETENTION_ENFORCEMENT_RECORDS,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.RETENTION_ENFORCEMENT_RECORDS],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true,\n\n /*\n * Subject-export: FORBIDDEN, and deliberately NO `retentionPolicy`. A record holds counts and instants about\n * a resource TYPE and names no person and no row (see the schema header), so it is not data about a subject\n * and no erasure visits it. FORBIDDEN rather than undeclared so the decision is visible, the\n * provider-call-records precedent. If a field ever named a row or a person, this exemption is wrong and must\n * be revisited in the same change.\n */\n systemAccessPolicy: { exportSubject: ResourceSystemAccessMode.FORBIDDEN },\n\n /*\n * Kept for the application's declared AUDIT_LOGS period, counted from the record's creation. This is the\n * operator's defence evidence that retention was enforced, so it must outlive the data it describes: the\n * AUDIT_LOGS period is the one the audit trail itself is kept for. The sweep that writes these rows is also\n * what deletes them once that period ends, through the same service-layer path as every bound resource.\n */\n retentionBinding: {\n retentionClass: DataRetentionClass.AUDIT_LOGS,\n startPoint: RetentionStartPoint.CREATED,\n },\n\n coreOperations: [\n CoreResourceOperation.CREATE,\n CoreResourceOperation.READ,\n CoreResourceOperation.LIST,\n CoreResourceOperation.DELETE_MANY,\n ],\n operationsConfiguration: {\n [CoreResourceOperation.CREATE]: {\n variants: [{\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }],\n },\n // The audit door's audience (`APPLICATION_AUDIT_LOG_READ_ROLES`): the operator who acts on a failing\n // sweep, and an evidence reader who must read and must not act. No tenant's rows are behind this door —\n // a record names a resource type, never an organization — so no cross-tenant admission is declared.\n [CoreResourceOperation.READ]: {\n variants: [{\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [...APPLICATION_AUDIT_LOG_READ_ROLES],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }],\n },\n [CoreResourceOperation.LIST]: {\n variants: [{\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [...APPLICATION_AUDIT_LOG_READ_ROLES],\n riskLevel: ResourceOperationRiskLevel.LOW,\n filterFields: {\n retentionClass: z.enum(DataRetentionClass),\n resourceType: z.string(),\n outcome: z.enum(RetentionEnforcementOutcome),\n runRef: z.string(),\n sweptAt: z.date(),\n },\n /** `_id` last, as the keyset tie-breaker: one run writes many rows with the same `sweptAt`. */\n sortFields: ['sweptAt', 'retentionClass', 'resourceType', 'outcome', '_id'] as const,\n maxPaginatedResultPerPageLimit: 100,\n }],\n },\n // The retention-class sweep deletes expired pages through the SERVICE layer, which resolves only\n // INTERNAL_CALL (not REPOSITORY_ONLY) — and INTERNAL_CALL is route-less too.\n [CoreResourceOperation.DELETE_MANY]: {\n variants: [{\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.HIGH,\n }],\n },\n },\n});\n"]}
1
+ {"version":3,"file":"retention-enforcement-records.shared.resources-config.schemas.js","sourceRoot":"","sources":["../../../../../src/compliance/privacy/retention-enforcement-records.shared.resources-config.schemas.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Retention-enforcement records: resource configuration (#1636).\n *\n * ONE writer and two readers:\n * - the writer is the retention-class sweep, through the repository (`CREATE` is `REPOSITORY_ONLY`, so no\n * route creates a record). It uses the repository rather than the trusted-system-write primitive on\n * purpose, for the provider-call-records reason: `createAsSystem` emits a `SYSTEM_CONTEXT_WRITE` audit row\n * per call, and the run already emits ONE `RETENTION_ENFORCEMENT_RECORDED` event carrying its totals.\n * - the application administration console reads them (`READ`/`LIST` are `API_CALL`) — the operator's view\n * of whether each declared period is being enforced;\n * - the retention-enforcement evidence door reads a window of them for an assurance collector.\n *\n * APPEND-ONLY: there is no UPDATE. A run happened; a later run is a new row. `DELETE_MANY` exists only for\n * the retention-class sweep itself, which deletes records past the application's declared `AUDIT_LOGS`\n * period, and it is `INTERNAL_CALL`, so enforcing retention on the evidence creates no public deletion route.\n */\nimport { z } from 'zod';\n\nimport { createResourceConfiguration_Initialization } from '../../resources/resources-config.shared.factory';\nimport { ResourceSystemAccessMode } from '../../resources/resources-config.shared.schemas';\nimport { CoreResourceOperation, CoreResourceType, coreResourceShared_FieldIdentifier } from '../../resources/resources.shared.core.definitions';\nimport { ResourceOperationRiskLevel, ResourceOperationVariantType, ResourceRelationship } from '../../resources/resources.shared.schemas';\nimport { CORE_APP_ROLES } from '../../security/authorizations/roles.shared.schemas';\nimport { APPLICATION_AUDIT_LOG_READ_ROLES } from '../audit-trails/application-audit-logs.shared.resources-config.schemas';\nimport { DataRetentionClass, RetentionStartPoint } from './retention-schedule.shared.schemas';\nimport { RetentionEnforcementOutcome, RetentionEnforcementRecordSchema } from './retention-enforcement-records.shared.schemas';\n\nexport const retentionEnforcementRecordsResourceConfiguration_InitializationFactory = (\n resourcesRelationships: ResourceRelationship[],\n) => createResourceConfiguration_Initialization<undefined,\n CoreResourceOperation.CREATE | CoreResourceOperation.READ | CoreResourceOperation.LIST | CoreResourceOperation.DELETE_MANY,\n typeof RetentionEnforcementRecordSchema\n>({\n mainSchema: RetentionEnforcementRecordSchema,\n resourceIdentifier: CoreResourceType.RETENTION_ENFORCEMENT_RECORDS,\n resourceFieldIdentifier: coreResourceShared_FieldIdentifier[CoreResourceType.RETENTION_ENFORCEMENT_RECORDS],\n resourceRelationships: resourcesRelationships,\n isSystemResource: true,\n\n /*\n * Subject-export: FORBIDDEN, and deliberately NO `retentionPolicy`. A record holds counts and instants about\n * a resource TYPE and names no person and no row (see the schema header), so it is not data about a subject\n * and no erasure visits it. FORBIDDEN rather than undeclared so the decision is visible, the\n * provider-call-records precedent. If a field ever named a row or a person, this exemption is wrong and must\n * be revisited in the same change.\n */\n systemAccessPolicy: { exportSubject: ResourceSystemAccessMode.FORBIDDEN },\n\n /*\n * Kept for the application's declared AUDIT_LOGS period, counted from the record's creation. This is the\n * operator's defence evidence that retention was enforced, so it must outlive the data it describes: the\n * AUDIT_LOGS period is the one the audit trail itself is kept for. The sweep that writes these rows is also\n * what deletes them once that period ends, through the same service-layer path as every bound resource.\n */\n retentionBinding: {\n retentionClass: DataRetentionClass.AUDIT_LOGS,\n startPoint: RetentionStartPoint.CREATED,\n },\n\n coreOperations: [\n CoreResourceOperation.CREATE,\n CoreResourceOperation.READ,\n CoreResourceOperation.LIST,\n CoreResourceOperation.DELETE_MANY,\n ],\n operationsConfiguration: {\n [CoreResourceOperation.CREATE]: {\n variants: [{\n variantType: ResourceOperationVariantType.REPOSITORY_ONLY,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }],\n },\n // The audit door's audience (`APPLICATION_AUDIT_LOG_READ_ROLES`): the operator who acts on a failing\n // sweep, and an evidence reader who must read and must not act. No tenant's rows are behind this door —\n // a record names a resource type, never an organization — so no cross-tenant admission is declared.\n [CoreResourceOperation.READ]: {\n variants: [{\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [...APPLICATION_AUDIT_LOG_READ_ROLES],\n riskLevel: ResourceOperationRiskLevel.LOW,\n }],\n },\n [CoreResourceOperation.LIST]: {\n variants: [{\n variantType: ResourceOperationVariantType.API_CALL,\n isDefault: true,\n roles: [...APPLICATION_AUDIT_LOG_READ_ROLES],\n riskLevel: ResourceOperationRiskLevel.LOW,\n filterFields: {\n retentionClass: z.enum(DataRetentionClass),\n resourceType: z.string(),\n outcome: z.enum(RetentionEnforcementOutcome),\n runRef: z.string(),\n sweptAt: z.date(),\n },\n /** `_id` last, as the keyset tie-breaker: one run writes many rows with the same `sweptAt`. */\n sortFields: ['sweptAt', 'retentionClass', 'resourceType', 'outcome', '_id'] as const,\n maxPaginatedResultPerPageLimit: 100,\n }],\n },\n // The retention-class sweep deletes expired pages through the SERVICE layer, which resolves only\n // INTERNAL_CALL (not REPOSITORY_ONLY) — and INTERNAL_CALL is route-less too.\n [CoreResourceOperation.DELETE_MANY]: {\n variants: [{\n variantType: ResourceOperationVariantType.INTERNAL_CALL,\n isDefault: true,\n roles: [CORE_APP_ROLES.APP_ADMIN_SUPER_ADMIN],\n riskLevel: ResourceOperationRiskLevel.HIGH,\n }],\n },\n },\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"retention-enforcement-records.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../src/compliance/privacy/retention-enforcement-records.shared.schemas.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,EAAE,kBAAkB,EAAE,mBAAmB,EAAE,MAAM,qCAAqC,CAAC;AAE9F,gIAAgI;AAChI;;;GAGG;AACH,oBAAY,2BAA2B;IACrC,sGAAsG;IACtG,SAAS,cAAc;IACvB;;;;OAIG;IACH,mBAAmB,wBAAwB;IAC3C,wHAAwH;IACxH,MAAM,WAAW;IACjB,gHAAgH;IAChH,OAAO,YAAY;CACpB;AAED,uHAAuH;AACvH,oBAAY,+BAA+B;IACzC,2FAA2F;IAC3F,IAAI,SAAS;IACb,+FAA+F;IAC/F,MAAM,WAAW;IACjB,+HAA+H;IAC/H,WAAW,gBAAgB;IAC3B;;;OAGG;IACH,uBAAuB,4BAA4B;IACnD;;;;OAIG;IACH,UAAU,eAAe;CAC1B;AAED;;;GAGG;AACH,oBAAY,6BAA6B;IACvC,6GAA6G;IAC7G,gBAAgB,qBAAqB;IACrC,iGAAiG;IACjG,wBAAwB,6BAA6B;CACtD;AAED,eAAO,MAAM,gCAAgC;;;;;;;;;;;;;;;;;;;;iBAuD3C,CAAC;AACH,MAAM,MAAM,0BAA0B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,gCAAgC,CAAC,CAAC;AAC1F,8EAA8E;AAE9E;;;;GAIG;AACH,eAAO,MAAM,iCAAiC,QAAiB,CAAC;AAEhE,qIAAqI;AACrI,MAAM,WAAW,gCAAgC;IAC/C,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,cAAc,EAAE,kBAAkB,CAAC;IAC5C,QAAQ,CAAC,UAAU,EAAE,mBAAmB,CAAC;IACzC,QAAQ,CAAC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IACvC,QAAQ,CAAC,MAAM,CAAC,EAAE,IAAI,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,sBAAsB,CAAC,EAAE,IAAI,CAAC;IACvC,QAAQ,CAAC,sBAAsB,CAAC,EAAE,IAAI,CAAC;IACvC,QAAQ,CAAC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IACnC,QAAQ,CAAC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAC3C,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC,QAAQ,CAAC,YAAY,CAAC,EAAE,+BAA+B,CAAC;IACxD,QAAQ,CAAC,UAAU,CAAC,EAAE,6BAA6B,CAAC;CACrD;AAED;;;GAGG;AACH,wBAAgB,6BAA6B,CAAC,MAAM,EAAE,IAAI,CAAC,gCAAgC,EAAE,cAAc,GAAG,YAAY,GAAG,mBAAmB,CAAC,GAAG,2BAA2B,CAK9K;AAED;;;;;GAKG;AACH,wBAAgB,iCAAiC,CAC/C,MAAM,EAAE,gCAAgC,EACxC,GAAG,EAAE;IAAE,QAAQ,CAAC,aAAa,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,OAAO,EAAE,IAAI,CAAA;CAAE,GACxF,IAAI,CAAC,0BAA0B,EAAE,KAAK,GAAG,WAAW,CAAC,CAoBvD;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,wCAAwC;;;;;;;;;;;;;;;;;iBAA6F,CAAC;AACnJ,MAAM,MAAM,kCAAkC,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,wCAAwC,CAAC,CAAC;AAE1G,eAAO,MAAM,kCAAkC;;;;;;;;;;;;;;;;;;;;;;;;iBAM7C,CAAC;AACH,MAAM,MAAM,4BAA4B,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kCAAkC,CAAC,CAAC;AAI9F;;;;;GAKG;AACH,wBAAgB,qCAAqC,CAAC,KAAK,EAAE,OAAO,GAAG,4BAA4B,GAAG,SAAS,CAY9G"}
1
+ {"version":3,"file":"retention-enforcement-records.shared.schemas.d.ts","sourceRoot":"","sources":["../../../../../src/compliance/privacy/retention-enforcement-records.shared.schemas.ts"],"names":[],"mappings":"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"}