@almadar/std 16.252.0 → 16.254.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (453) hide show
  1. package/behaviors/lolo/agent/atoms/std-agent-pool.lolo +355 -0
  2. package/behaviors/lolo/agent/atoms/std-agent-suggestions.lolo +16 -2
  3. package/behaviors/lolo/agent/evals/eval-agent-builder.lolo +152 -0
  4. package/behaviors/lolo/agent/organisms/std-agent-builder.lolo +320 -26
  5. package/behaviors/lolo/ui/learning/atoms/std-learn-generate.lolo +6 -4
  6. package/behaviors/lolo-behavior-contracts.json +1 -1
  7. package/behaviors/registry/agent/atoms/std-agent-context.orb +1 -1
  8. package/behaviors/registry/agent/atoms/std-agent-fix-loop.orb +1 -1
  9. package/behaviors/registry/agent/atoms/std-agent-planner.orb +1 -1
  10. package/behaviors/registry/agent/atoms/std-agent-pool.orb +1 -0
  11. package/behaviors/registry/agent/atoms/std-agent-proposal.orb +1 -1
  12. package/behaviors/registry/agent/atoms/std-agent-session.orb +1 -1
  13. package/behaviors/registry/agent/atoms/std-agent-suggestions.orb +1 -1
  14. package/behaviors/registry/agent/atoms/std-agent-tool-call.orb +1 -1
  15. package/behaviors/registry/agent/atoms/std-agent-tool-loop.orb +1 -1
  16. package/behaviors/registry/agent/atoms/std-agent-trace.orb +1 -1
  17. package/behaviors/registry/agent/evals/eval-agent-builder.orb +1 -0
  18. package/behaviors/registry/agent/organisms/std-agent-assistant.orb +1 -1
  19. package/behaviors/registry/agent/organisms/std-agent-builder.orb +1 -1
  20. package/behaviors/registry/infra/atoms/std-analytics.orb +1 -1
  21. package/behaviors/registry/infra/atoms/std-approval-gate.orb +1 -1
  22. package/behaviors/registry/infra/atoms/std-cache-aside.orb +1 -1
  23. package/behaviors/registry/infra/atoms/std-calendar-sync.orb +1 -1
  24. package/behaviors/registry/infra/atoms/std-cascade-on-delete.orb +1 -1
  25. package/behaviors/registry/infra/atoms/std-circuit-breaker.orb +1 -1
  26. package/behaviors/registry/infra/atoms/std-data-erasure.orb +1 -1
  27. package/behaviors/registry/infra/atoms/std-data-import.orb +1 -1
  28. package/behaviors/registry/infra/atoms/std-global-search.orb +1 -1
  29. package/behaviors/registry/infra/atoms/std-knowledge-loop.orb +1 -1
  30. package/behaviors/registry/infra/atoms/std-lifecycle.orb +1 -1
  31. package/behaviors/registry/infra/atoms/std-migration-job.orb +1 -1
  32. package/behaviors/registry/infra/atoms/std-mod-queue.orb +1 -1
  33. package/behaviors/registry/infra/atoms/std-notification-center.orb +1 -1
  34. package/behaviors/registry/infra/atoms/std-notification-preferences.orb +1 -1
  35. package/behaviors/registry/infra/atoms/std-notify-on-event.orb +1 -1
  36. package/behaviors/registry/infra/atoms/std-page-search.orb +1 -1
  37. package/behaviors/registry/infra/atoms/std-page-watch.orb +1 -1
  38. package/behaviors/registry/infra/atoms/std-permission-matrix.orb +1 -1
  39. package/behaviors/registry/infra/atoms/std-rate-limiter.orb +1 -1
  40. package/behaviors/registry/infra/atoms/std-reminder-scheduler.orb +1 -1
  41. package/behaviors/registry/infra/atoms/std-review-cycle.orb +1 -1
  42. package/behaviors/registry/infra/atoms/std-row-access-control.orb +1 -1
  43. package/behaviors/registry/infra/atoms/std-status-lifecycle.orb +1 -1
  44. package/behaviors/registry/infra/organisms/std-status-lifecycle-control.orb +1 -1
  45. package/behaviors/registry/ml/atoms/std-data-collector.orb +1 -1
  46. package/behaviors/registry/ml/atoms/std-graph-builder.orb +1 -1
  47. package/behaviors/registry/ml/atoms/std-ml-classify.orb +1 -1
  48. package/behaviors/registry/ml/atoms/std-ml-infer.orb +1 -1
  49. package/behaviors/registry/ml/atoms/std-ml-lookup.orb +1 -1
  50. package/behaviors/registry/ml/atoms/std-ml-posterior.orb +1 -1
  51. package/behaviors/registry/ml/atoms/std-ml-similarity.orb +1 -1
  52. package/behaviors/registry/ml/atoms/std-tokenizer.orb +1 -1
  53. package/behaviors/registry/ml/atoms/std-weight-validator.orb +1 -1
  54. package/behaviors/registry/ml/organisms/std-escalating-decision.orb +1 -1
  55. package/behaviors/registry/ml/organisms/std-knowledge-tracing.orb +1 -1
  56. package/behaviors/registry/ui/avl/atoms/std-avl-cosmic-zoom.orb +1 -1
  57. package/behaviors/registry/ui/avl/atoms/ui-avl-glyph.orb +1 -1
  58. package/behaviors/registry/ui/avl/atoms/ui-avl-state-machine.orb +1 -1
  59. package/behaviors/registry/ui/avl/atoms/ui-avl-transition-detail.orb +1 -1
  60. package/behaviors/registry/ui/avl/atoms/ui-avl-transition-explainer.orb +1 -1
  61. package/behaviors/registry/ui/avl/atoms/ui-behavior-view.orb +1 -1
  62. package/behaviors/registry/ui/avl/atoms/ui-module-card.orb +1 -1
  63. package/behaviors/registry/ui/avl/organisms/ui-flow-canvas.orb +1 -1
  64. package/behaviors/registry/ui/avl/organisms/ui-layers-panel.orb +1 -1
  65. package/behaviors/registry/ui/avl/organisms/ui-orb-inspector.orb +1 -1
  66. package/behaviors/registry/ui/core/atoms/std-app-layout.orb +1 -1
  67. package/behaviors/registry/ui/core/atoms/std-app-search.orb +1 -1
  68. package/behaviors/registry/ui/core/atoms/std-behavior-catalog.orb +1 -1
  69. package/behaviors/registry/ui/core/atoms/std-behavior-tour.orb +1 -1
  70. package/behaviors/registry/ui/core/atoms/std-billable-hour.orb +1 -1
  71. package/behaviors/registry/ui/core/atoms/std-board.orb +1 -1
  72. package/behaviors/registry/ui/core/atoms/std-book-reader.orb +1 -1
  73. package/behaviors/registry/ui/core/atoms/std-browse.orb +1 -1
  74. package/behaviors/registry/ui/core/atoms/std-calendar.orb +1 -1
  75. package/behaviors/registry/ui/core/atoms/std-card-grid.orb +1 -1
  76. package/behaviors/registry/ui/core/atoms/std-confirmation.orb +1 -1
  77. package/behaviors/registry/ui/core/atoms/std-dashboard-grid-embedded.orb +1 -1
  78. package/behaviors/registry/ui/core/atoms/std-date-range.orb +1 -1
  79. package/behaviors/registry/ui/core/atoms/std-doc-page.orb +1 -1
  80. package/behaviors/registry/ui/core/atoms/std-esign-flow.orb +1 -1
  81. package/behaviors/registry/ui/core/atoms/std-esign-request.orb +1 -1
  82. package/behaviors/registry/ui/core/atoms/std-event-log.orb +1 -1
  83. package/behaviors/registry/ui/core/atoms/std-export.orb +1 -1
  84. package/behaviors/registry/ui/core/atoms/std-file-store.orb +1 -1
  85. package/behaviors/registry/ui/core/atoms/std-filter.orb +1 -1
  86. package/behaviors/registry/ui/core/atoms/std-form-advanced.orb +1 -1
  87. package/behaviors/registry/ui/core/atoms/std-gallery.orb +1 -1
  88. package/behaviors/registry/ui/core/atoms/std-gantt-schedule.orb +1 -1
  89. package/behaviors/registry/ui/core/atoms/std-graphs.orb +1 -1
  90. package/behaviors/registry/ui/core/atoms/std-hero.orb +1 -1
  91. package/behaviors/registry/ui/core/atoms/std-home.orb +1 -1
  92. package/behaviors/registry/ui/core/atoms/std-image-upload-multi.orb +1 -1
  93. package/behaviors/registry/ui/core/atoms/std-import.orb +1 -1
  94. package/behaviors/registry/ui/core/atoms/std-language-picker.orb +1 -1
  95. package/behaviors/registry/ui/core/atoms/std-media-section.orb +1 -1
  96. package/behaviors/registry/ui/core/atoms/std-modal-editor.orb +1 -1
  97. package/behaviors/registry/ui/core/atoms/std-modal.orb +1 -1
  98. package/behaviors/registry/ui/core/atoms/std-multi-party-flow.orb +1 -1
  99. package/behaviors/registry/ui/core/atoms/std-notification-panel.orb +1 -1
  100. package/behaviors/registry/ui/core/atoms/std-panel-launcher.orb +1 -1
  101. package/behaviors/registry/ui/core/atoms/std-pricing.orb +1 -1
  102. package/behaviors/registry/ui/core/atoms/std-proof.orb +1 -1
  103. package/behaviors/registry/ui/core/atoms/std-prose.orb +1 -1
  104. package/behaviors/registry/ui/core/atoms/std-rating-review.orb +1 -1
  105. package/behaviors/registry/ui/core/atoms/std-record-detail.orb +1 -1
  106. package/behaviors/registry/ui/core/atoms/std-recurrence.orb +1 -1
  107. package/behaviors/registry/ui/core/atoms/std-related.orb +1 -1
  108. package/behaviors/registry/ui/core/atoms/std-role-gate.orb +1 -1
  109. package/behaviors/registry/ui/core/atoms/std-saved-search.orb +1 -1
  110. package/behaviors/registry/ui/core/atoms/std-scatter.orb +1 -1
  111. package/behaviors/registry/ui/core/atoms/std-scoped-list.orb +1 -1
  112. package/behaviors/registry/ui/core/atoms/std-selection.orb +1 -1
  113. package/behaviors/registry/ui/core/atoms/std-site-footer.orb +1 -1
  114. package/behaviors/registry/ui/core/atoms/std-site-header.orb +1 -1
  115. package/behaviors/registry/ui/core/atoms/std-slide-deck.orb +1 -1
  116. package/behaviors/registry/ui/core/atoms/std-stat-band.orb +1 -1
  117. package/behaviors/registry/ui/core/atoms/std-stats.orb +1 -1
  118. package/behaviors/registry/ui/core/atoms/std-step-flow.orb +1 -1
  119. package/behaviors/registry/ui/core/atoms/std-steps.orb +1 -1
  120. package/behaviors/registry/ui/core/atoms/std-tabs.orb +1 -1
  121. package/behaviors/registry/ui/core/atoms/std-tag-strip.orb +1 -1
  122. package/behaviors/registry/ui/core/atoms/std-tag-taxonomy.orb +1 -1
  123. package/behaviors/registry/ui/core/atoms/std-thread.orb +1 -1
  124. package/behaviors/registry/ui/core/atoms/std-tree.orb +1 -1
  125. package/behaviors/registry/ui/core/atoms/std-version-history.orb +1 -1
  126. package/behaviors/registry/ui/core/atoms/std-wizard.orb +1 -1
  127. package/behaviors/registry/ui/core/atoms/std-workspace-layout.orb +1 -1
  128. package/behaviors/registry/ui/core/atoms/ui-animated-graphic.orb +1 -1
  129. package/behaviors/registry/ui/core/atoms/ui-animated-reveal.orb +1 -1
  130. package/behaviors/registry/ui/core/atoms/ui-aside.orb +1 -1
  131. package/behaviors/registry/ui/core/atoms/ui-atlas-image.orb +1 -1
  132. package/behaviors/registry/ui/core/atoms/ui-atlas-panel.orb +1 -1
  133. package/behaviors/registry/ui/core/atoms/ui-avatar.orb +1 -1
  134. package/behaviors/registry/ui/core/atoms/ui-badge.orb +1 -1
  135. package/behaviors/registry/ui/core/atoms/ui-box.orb +1 -1
  136. package/behaviors/registry/ui/core/atoms/ui-button.orb +1 -1
  137. package/behaviors/registry/ui/core/atoms/ui-card.orb +1 -1
  138. package/behaviors/registry/ui/core/atoms/ui-center.orb +1 -1
  139. package/behaviors/registry/ui/core/atoms/ui-checkbox.orb +1 -1
  140. package/behaviors/registry/ui/core/atoms/ui-conditional-wrapper.orb +1 -1
  141. package/behaviors/registry/ui/core/atoms/ui-confetti-effect.orb +1 -1
  142. package/behaviors/registry/ui/core/atoms/ui-day-cell.orb +1 -1
  143. package/behaviors/registry/ui/core/atoms/ui-dialog.orb +1 -1
  144. package/behaviors/registry/ui/core/atoms/ui-divider.orb +1 -1
  145. package/behaviors/registry/ui/core/atoms/ui-filter-pill.orb +1 -1
  146. package/behaviors/registry/ui/core/atoms/ui-flip-container.orb +1 -1
  147. package/behaviors/registry/ui/core/atoms/ui-game-icon.orb +1 -1
  148. package/behaviors/registry/ui/core/atoms/ui-hstack.orb +1 -1
  149. package/behaviors/registry/ui/core/atoms/ui-icon.orb +1 -1
  150. package/behaviors/registry/ui/core/atoms/ui-image.orb +1 -1
  151. package/behaviors/registry/ui/core/atoms/ui-infinite-scroll-sentinel.orb +1 -1
  152. package/behaviors/registry/ui/core/atoms/ui-input.orb +1 -1
  153. package/behaviors/registry/ui/core/atoms/ui-label.orb +1 -1
  154. package/behaviors/registry/ui/core/atoms/ui-law-reference-tooltip.orb +1 -1
  155. package/behaviors/registry/ui/core/atoms/ui-overlay.orb +1 -1
  156. package/behaviors/registry/ui/core/atoms/ui-pattern-tile.orb +1 -1
  157. package/behaviors/registry/ui/core/atoms/ui-presence.orb +1 -1
  158. package/behaviors/registry/ui/core/atoms/ui-progress-bar.orb +1 -1
  159. package/behaviors/registry/ui/core/atoms/ui-radio.orb +1 -1
  160. package/behaviors/registry/ui/core/atoms/ui-range-slider.orb +1 -1
  161. package/behaviors/registry/ui/core/atoms/ui-section-header.orb +1 -1
  162. package/behaviors/registry/ui/core/atoms/ui-select.orb +1 -1
  163. package/behaviors/registry/ui/core/atoms/ui-spacer.orb +1 -1
  164. package/behaviors/registry/ui/core/atoms/ui-sparkline.orb +1 -1
  165. package/behaviors/registry/ui/core/atoms/ui-spinner.orb +1 -1
  166. package/behaviors/registry/ui/core/atoms/ui-stack.orb +1 -1
  167. package/behaviors/registry/ui/core/atoms/ui-status-dot.orb +1 -1
  168. package/behaviors/registry/ui/core/atoms/ui-svg-branch.orb +1 -1
  169. package/behaviors/registry/ui/core/atoms/ui-svg-connection.orb +1 -1
  170. package/behaviors/registry/ui/core/atoms/ui-svg-flow.orb +1 -1
  171. package/behaviors/registry/ui/core/atoms/ui-svg-grid.orb +1 -1
  172. package/behaviors/registry/ui/core/atoms/ui-svg-lobe.orb +1 -1
  173. package/behaviors/registry/ui/core/atoms/ui-svg-mesh.orb +1 -1
  174. package/behaviors/registry/ui/core/atoms/ui-svg-morph.orb +1 -1
  175. package/behaviors/registry/ui/core/atoms/ui-svg-node.orb +1 -1
  176. package/behaviors/registry/ui/core/atoms/ui-svg-pulse.orb +1 -1
  177. package/behaviors/registry/ui/core/atoms/ui-svg-ring.orb +1 -1
  178. package/behaviors/registry/ui/core/atoms/ui-svg-shield.orb +1 -1
  179. package/behaviors/registry/ui/core/atoms/ui-svg-stack.orb +1 -1
  180. package/behaviors/registry/ui/core/atoms/ui-switch.orb +1 -1
  181. package/behaviors/registry/ui/core/atoms/ui-text-highlight.orb +1 -1
  182. package/behaviors/registry/ui/core/atoms/ui-textarea.orb +1 -1
  183. package/behaviors/registry/ui/core/atoms/ui-theme-toggle.orb +1 -1
  184. package/behaviors/registry/ui/core/atoms/ui-time-slot-cell.orb +1 -1
  185. package/behaviors/registry/ui/core/atoms/ui-trend-indicator.orb +1 -1
  186. package/behaviors/registry/ui/core/atoms/ui-typewriter-text.orb +1 -1
  187. package/behaviors/registry/ui/core/atoms/ui-typography.orb +1 -1
  188. package/behaviors/registry/ui/core/atoms/ui-video-embed.orb +1 -1
  189. package/behaviors/registry/ui/core/atoms/ui-vstack.orb +1 -1
  190. package/behaviors/registry/ui/core/molecules/std-stat-rows.orb +1 -1
  191. package/behaviors/registry/ui/core/molecules/ui-accordion.orb +1 -1
  192. package/behaviors/registry/ui/core/molecules/ui-activation-block.orb +1 -1
  193. package/behaviors/registry/ui/core/molecules/ui-activity-rail.orb +1 -1
  194. package/behaviors/registry/ui/core/molecules/ui-agent-activity-feed.orb +1 -1
  195. package/behaviors/registry/ui/core/molecules/ui-agent-activity-row.orb +1 -1
  196. package/behaviors/registry/ui/core/molecules/ui-agent-chat-feed.orb +1 -1
  197. package/behaviors/registry/ui/core/molecules/ui-alert.orb +1 -1
  198. package/behaviors/registry/ui/core/molecules/ui-animated-counter.orb +1 -1
  199. package/behaviors/registry/ui/core/molecules/ui-bloom-quiz-block.orb +1 -1
  200. package/behaviors/registry/ui/core/molecules/ui-branching-logic-builder.orb +1 -1
  201. package/behaviors/registry/ui/core/molecules/ui-breadcrumb.orb +1 -1
  202. package/behaviors/registry/ui/core/molecules/ui-calendar-grid.orb +1 -1
  203. package/behaviors/registry/ui/core/molecules/ui-carousel.orb +1 -1
  204. package/behaviors/registry/ui/core/molecules/ui-change-list.orb +1 -1
  205. package/behaviors/registry/ui/core/molecules/ui-chart-legend.orb +1 -1
  206. package/behaviors/registry/ui/core/molecules/ui-chart.orb +1 -1
  207. package/behaviors/registry/ui/core/molecules/ui-code-block.orb +1 -1
  208. package/behaviors/registry/ui/core/molecules/ui-command-palette.orb +1 -1
  209. package/behaviors/registry/ui/core/molecules/ui-commit-row.orb +1 -1
  210. package/behaviors/registry/ui/core/molecules/ui-confirm-dialog.orb +1 -1
  211. package/behaviors/registry/ui/core/molecules/ui-connection-block.orb +1 -1
  212. package/behaviors/registry/ui/core/molecules/ui-container.orb +1 -1
  213. package/behaviors/registry/ui/core/molecules/ui-content-renderer.orb +1 -1
  214. package/behaviors/registry/ui/core/molecules/ui-data-grid.orb +1 -1
  215. package/behaviors/registry/ui/core/molecules/ui-data-list.orb +1 -1
  216. package/behaviors/registry/ui/core/molecules/ui-date-range-picker.orb +1 -1
  217. package/behaviors/registry/ui/core/molecules/ui-date-range-selector.orb +1 -1
  218. package/behaviors/registry/ui/core/molecules/ui-doc-breadcrumb.orb +1 -1
  219. package/behaviors/registry/ui/core/molecules/ui-doc-pagination.orb +1 -1
  220. package/behaviors/registry/ui/core/molecules/ui-doc-search.orb +1 -1
  221. package/behaviors/registry/ui/core/molecules/ui-doc-sidebar.orb +1 -1
  222. package/behaviors/registry/ui/core/molecules/ui-doc-toc.orb +1 -1
  223. package/behaviors/registry/ui/core/molecules/ui-document-details.orb +1 -1
  224. package/behaviors/registry/ui/core/molecules/ui-document-panel.orb +1 -1
  225. package/behaviors/registry/ui/core/molecules/ui-document-viewer.orb +1 -1
  226. package/behaviors/registry/ui/core/molecules/ui-drawer.orb +1 -1
  227. package/behaviors/registry/ui/core/molecules/ui-edge-decoration.orb +1 -1
  228. package/behaviors/registry/ui/core/molecules/ui-emoji-picker.orb +1 -1
  229. package/behaviors/registry/ui/core/molecules/ui-empty-state.orb +1 -1
  230. package/behaviors/registry/ui/core/molecules/ui-error-boundary.orb +1 -1
  231. package/behaviors/registry/ui/core/molecules/ui-error-state.orb +1 -1
  232. package/behaviors/registry/ui/core/molecules/ui-feature-card.orb +1 -1
  233. package/behaviors/registry/ui/core/molecules/ui-feature-grid.orb +1 -1
  234. package/behaviors/registry/ui/core/molecules/ui-file-tree.orb +1 -1
  235. package/behaviors/registry/ui/core/molecules/ui-filter-group.orb +1 -1
  236. package/behaviors/registry/ui/core/molecules/ui-flex.orb +1 -1
  237. package/behaviors/registry/ui/core/molecules/ui-flip-card.orb +1 -1
  238. package/behaviors/registry/ui/core/molecules/ui-floating-action-button.orb +1 -1
  239. package/behaviors/registry/ui/core/molecules/ui-floating-toolbar.orb +1 -1
  240. package/behaviors/registry/ui/core/molecules/ui-form-actions.orb +1 -1
  241. package/behaviors/registry/ui/core/molecules/ui-form-field.orb +1 -1
  242. package/behaviors/registry/ui/core/molecules/ui-form-layout.orb +1 -1
  243. package/behaviors/registry/ui/core/molecules/ui-form-section-header.orb +1 -1
  244. package/behaviors/registry/ui/core/molecules/ui-fx-overlay.orb +1 -1
  245. package/behaviors/registry/ui/core/molecules/ui-gantt.orb +1 -1
  246. package/behaviors/registry/ui/core/molecules/ui-geometric-pattern.orb +1 -1
  247. package/behaviors/registry/ui/core/molecules/ui-gradient-divider.orb +1 -1
  248. package/behaviors/registry/ui/core/molecules/ui-graph-canvas.orb +1 -1
  249. package/behaviors/registry/ui/core/molecules/ui-graph-view.orb +1 -1
  250. package/behaviors/registry/ui/core/molecules/ui-grid.orb +1 -1
  251. package/behaviors/registry/ui/core/molecules/ui-header.orb +1 -1
  252. package/behaviors/registry/ui/core/molecules/ui-icon-button.orb +1 -1
  253. package/behaviors/registry/ui/core/molecules/ui-import-preview-tree.orb +1 -1
  254. package/behaviors/registry/ui/core/molecules/ui-import-progress.orb +1 -1
  255. package/behaviors/registry/ui/core/molecules/ui-import-source-picker.orb +1 -1
  256. package/behaviors/registry/ui/core/molecules/ui-input-group.orb +1 -1
  257. package/behaviors/registry/ui/core/molecules/ui-jazari-state-machine.orb +1 -1
  258. package/behaviors/registry/ui/core/molecules/ui-lightbox.orb +1 -1
  259. package/behaviors/registry/ui/core/molecules/ui-likert-scale.orb +1 -1
  260. package/behaviors/registry/ui/core/molecules/ui-line-chart.orb +1 -1
  261. package/behaviors/registry/ui/core/molecules/ui-loading-state.orb +1 -1
  262. package/behaviors/registry/ui/core/molecules/ui-map-view.orb +1 -1
  263. package/behaviors/registry/ui/core/molecules/ui-markdown-content.orb +1 -1
  264. package/behaviors/registry/ui/core/molecules/ui-matrix-question.orb +1 -1
  265. package/behaviors/registry/ui/core/molecules/ui-menu.orb +1 -1
  266. package/behaviors/registry/ui/core/molecules/ui-meter.orb +1 -1
  267. package/behaviors/registry/ui/core/molecules/ui-modal.orb +1 -1
  268. package/behaviors/registry/ui/core/molecules/ui-navigation.orb +1 -1
  269. package/behaviors/registry/ui/core/molecules/ui-notification.orb +1 -1
  270. package/behaviors/registry/ui/core/molecules/ui-number-stepper.orb +1 -1
  271. package/behaviors/registry/ui/core/molecules/ui-option-constraint-group.orb +1 -1
  272. package/behaviors/registry/ui/core/molecules/ui-orbital-visualization.orb +1 -1
  273. package/behaviors/registry/ui/core/molecules/ui-page-header.orb +1 -1
  274. package/behaviors/registry/ui/core/molecules/ui-page-transition.orb +1 -1
  275. package/behaviors/registry/ui/core/molecules/ui-pagination.orb +1 -1
  276. package/behaviors/registry/ui/core/molecules/ui-popover.orb +1 -1
  277. package/behaviors/registry/ui/core/molecules/ui-positioned-canvas.orb +1 -1
  278. package/behaviors/registry/ui/core/molecules/ui-progress-dots.orb +1 -1
  279. package/behaviors/registry/ui/core/molecules/ui-pull-to-refresh.orb +1 -1
  280. package/behaviors/registry/ui/core/molecules/ui-qr-scanner.orb +1 -1
  281. package/behaviors/registry/ui/core/molecules/ui-quiz-block.orb +1 -1
  282. package/behaviors/registry/ui/core/molecules/ui-reflection-block.orb +1 -1
  283. package/behaviors/registry/ui/core/molecules/ui-relation-select.orb +1 -1
  284. package/behaviors/registry/ui/core/molecules/ui-repeatable-form-section.orb +1 -1
  285. package/behaviors/registry/ui/core/molecules/ui-reply-tree.orb +1 -1
  286. package/behaviors/registry/ui/core/molecules/ui-rich-text-editor.orb +1 -1
  287. package/behaviors/registry/ui/core/molecules/ui-scaled-diagram.orb +1 -1
  288. package/behaviors/registry/ui/core/molecules/ui-search-input.orb +1 -1
  289. package/behaviors/registry/ui/core/molecules/ui-section.orb +1 -1
  290. package/behaviors/registry/ui/core/molecules/ui-side-panel.orb +1 -1
  291. package/behaviors/registry/ui/core/molecules/ui-sidebar.orb +1 -1
  292. package/behaviors/registry/ui/core/molecules/ui-signature-pad.orb +1 -1
  293. package/behaviors/registry/ui/core/molecules/ui-simple-grid.orb +1 -1
  294. package/behaviors/registry/ui/core/molecules/ui-skeleton.orb +1 -1
  295. package/behaviors/registry/ui/core/molecules/ui-social-proof.orb +1 -1
  296. package/behaviors/registry/ui/core/molecules/ui-sortable-list.orb +1 -1
  297. package/behaviors/registry/ui/core/molecules/ui-split.orb +1 -1
  298. package/behaviors/registry/ui/core/molecules/ui-star-rating.orb +1 -1
  299. package/behaviors/registry/ui/core/molecules/ui-stat-display.orb +1 -1
  300. package/behaviors/registry/ui/core/molecules/ui-swipeable-row.orb +1 -1
  301. package/behaviors/registry/ui/core/molecules/ui-table-view.orb +1 -1
  302. package/behaviors/registry/ui/core/molecules/ui-tabs.orb +1 -1
  303. package/behaviors/registry/ui/core/molecules/ui-tag-input.orb +1 -1
  304. package/behaviors/registry/ui/core/molecules/ui-tooltip.orb +1 -1
  305. package/behaviors/registry/ui/core/molecules/ui-top-nav-item.orb +1 -1
  306. package/behaviors/registry/ui/core/molecules/ui-upload-drop-zone.orb +1 -1
  307. package/behaviors/registry/ui/core/molecules/ui-version-diff.orb +1 -1
  308. package/behaviors/registry/ui/core/molecules/ui-violation-alert.orb +1 -1
  309. package/behaviors/registry/ui/core/molecules/ui-vote-stack.orb +1 -1
  310. package/behaviors/registry/ui/core/molecules/ui-wizard-container.orb +1 -1
  311. package/behaviors/registry/ui/core/molecules/ui-wizard-navigation.orb +1 -1
  312. package/behaviors/registry/ui/core/molecules/ui-wizard-progress.orb +1 -1
  313. package/behaviors/registry/ui/core/organisms/ui-chat-bar.orb +1 -1
  314. package/behaviors/registry/ui/core/organisms/ui-code-runner-panel.orb +1 -1
  315. package/behaviors/registry/ui/core/organisms/ui-dashboard-grid.orb +1 -1
  316. package/behaviors/registry/ui/core/organisms/ui-detail-panel.orb +1 -1
  317. package/behaviors/registry/ui/core/organisms/ui-dock-layout.orb +1 -1
  318. package/behaviors/registry/ui/core/organisms/ui-drawer-slot.orb +1 -1
  319. package/behaviors/registry/ui/core/organisms/ui-form-section.orb +1 -1
  320. package/behaviors/registry/ui/core/organisms/ui-form.orb +1 -1
  321. package/behaviors/registry/ui/core/organisms/ui-master-detail-layout.orb +1 -1
  322. package/behaviors/registry/ui/core/organisms/ui-media-gallery.orb +1 -1
  323. package/behaviors/registry/ui/core/organisms/ui-modal-slot.orb +1 -1
  324. package/behaviors/registry/ui/core/organisms/ui-runtime-debugger.orb +1 -1
  325. package/behaviors/registry/ui/core/organisms/ui-segment-renderer.orb +1 -1
  326. package/behaviors/registry/ui/core/organisms/ui-split-pane.orb +1 -1
  327. package/behaviors/registry/ui/core/organisms/ui-stat-card.orb +1 -1
  328. package/behaviors/registry/ui/core/organisms/ui-state-machine-view.orb +1 -1
  329. package/behaviors/registry/ui/core/organisms/ui-subagent-trace-panel.orb +1 -1
  330. package/behaviors/registry/ui/core/organisms/ui-tabbed-container.orb +1 -1
  331. package/behaviors/registry/ui/core/organisms/ui-timeline.orb +1 -1
  332. package/behaviors/registry/ui/core/organisms/ui-toast-slot.orb +1 -1
  333. package/behaviors/registry/ui/core/templates/ui-auth-layout.orb +1 -1
  334. package/behaviors/registry/ui/core/templates/ui-counter-template.orb +1 -1
  335. package/behaviors/registry/ui/core/templates/ui-dashboard-layout.orb +1 -1
  336. package/behaviors/registry/ui/core/templates/ui-generic-app-template.orb +1 -1
  337. package/behaviors/registry/ui/game/atoms/std-arcade-play.orb +1 -1
  338. package/behaviors/registry/ui/game/atoms/std-area-fill.orb +1 -1
  339. package/behaviors/registry/ui/game/atoms/std-audio-cue.orb +1 -1
  340. package/behaviors/registry/ui/game/atoms/std-camera-rig.orb +1 -1
  341. package/behaviors/registry/ui/game/atoms/std-chase-ai.orb +1 -1
  342. package/behaviors/registry/ui/game/atoms/std-choice-gate.orb +1 -1
  343. package/behaviors/registry/ui/game/atoms/std-coef-pad.orb +1 -1
  344. package/behaviors/registry/ui/game/atoms/std-curve-fog.orb +1 -1
  345. package/behaviors/registry/ui/game/atoms/std-dungeon-combat.orb +1 -1
  346. package/behaviors/registry/ui/game/atoms/std-fx-narrative.orb +1 -1
  347. package/behaviors/registry/ui/game/atoms/std-fx-particles.orb +1 -1
  348. package/behaviors/registry/ui/game/atoms/std-fx-trail.orb +1 -1
  349. package/behaviors/registry/ui/game/atoms/std-gate-lock.orb +1 -1
  350. package/behaviors/registry/ui/game/atoms/std-gather.orb +1 -1
  351. package/behaviors/registry/ui/game/atoms/std-gold.orb +1 -1
  352. package/behaviors/registry/ui/game/atoms/std-grid-tactics.orb +1 -1
  353. package/behaviors/registry/ui/game/atoms/std-hero-nav.orb +1 -1
  354. package/behaviors/registry/ui/game/atoms/std-lives.orb +1 -1
  355. package/behaviors/registry/ui/game/atoms/std-loop-lock.orb +1 -1
  356. package/behaviors/registry/ui/game/atoms/std-market-flow.orb +1 -1
  357. package/behaviors/registry/ui/game/atoms/std-motion-body.orb +1 -1
  358. package/behaviors/registry/ui/game/atoms/std-objective-reach.orb +1 -1
  359. package/behaviors/registry/ui/game/atoms/std-pad-lock.orb +1 -1
  360. package/behaviors/registry/ui/game/atoms/std-patience.orb +1 -1
  361. package/behaviors/registry/ui/game/atoms/std-patrol-hazard.orb +1 -1
  362. package/behaviors/registry/ui/game/atoms/std-pickup.orb +1 -1
  363. package/behaviors/registry/ui/game/atoms/std-platformer-body.orb +1 -1
  364. package/behaviors/registry/ui/game/atoms/std-production.orb +1 -1
  365. package/behaviors/registry/ui/game/atoms/std-score.orb +1 -1
  366. package/behaviors/registry/ui/game/atoms/std-tutorial-autodemo.orb +1 -1
  367. package/behaviors/registry/ui/game/atoms/std-tutorial-overlay.orb +1 -1
  368. package/behaviors/registry/ui/game/atoms/std-velocity-gate.orb +1 -1
  369. package/behaviors/registry/ui/game/atoms/std-xp.orb +1 -1
  370. package/behaviors/registry/ui/game/atoms/std-zone-card.orb +1 -1
  371. package/behaviors/registry/ui/game/atoms/ui-action-palette.orb +1 -1
  372. package/behaviors/registry/ui/game/atoms/ui-action-tile.orb +1 -1
  373. package/behaviors/registry/ui/game/atoms/ui-canvas-2d.orb +1 -1
  374. package/behaviors/registry/ui/game/atoms/ui-canvas.orb +1 -1
  375. package/behaviors/registry/ui/game/atoms/ui-choice-button.orb +1 -1
  376. package/behaviors/registry/ui/game/atoms/ui-control-button.orb +1 -1
  377. package/behaviors/registry/ui/game/atoms/ui-control-grid.orb +1 -1
  378. package/behaviors/registry/ui/game/atoms/ui-dialogue-bubble.orb +1 -1
  379. package/behaviors/registry/ui/game/atoms/ui-draw-fx-layer.orb +1 -1
  380. package/behaviors/registry/ui/game/atoms/ui-draw-group.orb +1 -1
  381. package/behaviors/registry/ui/game/atoms/ui-draw-mesh.orb +1 -1
  382. package/behaviors/registry/ui/game/atoms/ui-draw-shape-layer.orb +1 -1
  383. package/behaviors/registry/ui/game/atoms/ui-draw-shape.orb +1 -1
  384. package/behaviors/registry/ui/game/atoms/ui-draw-skinned-mesh.orb +1 -1
  385. package/behaviors/registry/ui/game/atoms/ui-draw-sprite-layer.orb +1 -1
  386. package/behaviors/registry/ui/game/atoms/ui-draw-sprite.orb +1 -1
  387. package/behaviors/registry/ui/game/atoms/ui-draw-text-layer.orb +1 -1
  388. package/behaviors/registry/ui/game/atoms/ui-draw-text.orb +1 -1
  389. package/behaviors/registry/ui/game/atoms/ui-game-audio-cue.orb +1 -1
  390. package/behaviors/registry/ui/game/atoms/ui-game-audio-toggle.orb +1 -1
  391. package/behaviors/registry/ui/game/atoms/ui-game-hud.orb +1 -1
  392. package/behaviors/registry/ui/game/atoms/ui-game-menu.orb +1 -1
  393. package/behaviors/registry/ui/game/atoms/ui-health-bar.orb +1 -1
  394. package/behaviors/registry/ui/game/atoms/ui-score-display.orb +1 -1
  395. package/behaviors/registry/ui/game/atoms/ui-sequence-bar.orb +1 -1
  396. package/behaviors/registry/ui/game/atoms/ui-stat-badge.orb +1 -1
  397. package/behaviors/registry/ui/game/atoms/ui-state-graph.orb +1 -1
  398. package/behaviors/registry/ui/game/atoms/ui-state-json-view.orb +1 -1
  399. package/behaviors/registry/ui/game/atoms/ui-timer-display.orb +1 -1
  400. package/behaviors/registry/ui/game/atoms/ui-trait-slot.orb +1 -1
  401. package/behaviors/registry/ui/game/organisms/std-arcade-board-3d.orb +1 -1
  402. package/behaviors/registry/ui/game/organisms/std-crew-board-2d.orb +1 -1
  403. package/behaviors/registry/ui/game/organisms/std-dungeon-board-2d.orb +1 -1
  404. package/behaviors/registry/ui/game/organisms/std-market-board-3d.orb +1 -1
  405. package/behaviors/registry/ui/game/organisms/std-objective-board-3d.orb +1 -1
  406. package/behaviors/registry/ui/game/organisms/std-platformer-board-2d.orb +1 -1
  407. package/behaviors/registry/ui/game/organisms/std-platformer-puzzle.orb +1 -1
  408. package/behaviors/registry/ui/game/organisms/std-survival-board-3d.orb +1 -1
  409. package/behaviors/registry/ui/game/organisms/std-tactics-board-2d.orb +1 -1
  410. package/behaviors/registry/ui/game/organisms/std-tactics-board-3d.orb +1 -1
  411. package/behaviors/registry/ui/game/organisms/std-worldmap-board-2d.orb +1 -1
  412. package/behaviors/registry/ui/game/templates/ui-game-shell.orb +1 -1
  413. package/behaviors/registry/ui/learning/atoms/std-learn-arrangement.orb +1 -1
  414. package/behaviors/registry/ui/learning/atoms/std-learn-classify.orb +1 -1
  415. package/behaviors/registry/ui/learning/atoms/std-learn-compare.orb +1 -1
  416. package/behaviors/registry/ui/learning/atoms/std-learn-coupled-sim.orb +1 -1
  417. package/behaviors/registry/ui/learning/atoms/std-learn-derivation.orb +1 -1
  418. package/behaviors/registry/ui/learning/atoms/std-learn-diagram.orb +1 -1
  419. package/behaviors/registry/ui/learning/atoms/std-learn-doser.orb +1 -1
  420. package/behaviors/registry/ui/learning/atoms/std-learn-estimate.orb +1 -1
  421. package/behaviors/registry/ui/learning/atoms/std-learn-fx-cues.orb +1 -1
  422. package/behaviors/registry/ui/learning/atoms/std-learn-generate.orb +1 -1
  423. package/behaviors/registry/ui/learning/atoms/std-learn-goal-seek.orb +1 -1
  424. package/behaviors/registry/ui/learning/atoms/std-learn-grid-sim.orb +1 -1
  425. package/behaviors/registry/ui/learning/atoms/std-learn-hotspot.orb +1 -1
  426. package/behaviors/registry/ui/learning/atoms/std-learn-live-sim.orb +1 -1
  427. package/behaviors/registry/ui/learning/atoms/std-learn-measure.orb +1 -1
  428. package/behaviors/registry/ui/learning/atoms/std-learn-param-explorer.orb +1 -1
  429. package/behaviors/registry/ui/learning/atoms/std-learn-perturb.orb +1 -1
  430. package/behaviors/registry/ui/learning/atoms/std-learn-predict.orb +1 -1
  431. package/behaviors/registry/ui/learning/atoms/std-learn-sample-accumulator.orb +1 -1
  432. package/behaviors/registry/ui/learning/atoms/std-learn-sandbox.orb +1 -1
  433. package/behaviors/registry/ui/learning/atoms/std-learn-scatter-fit.orb +1 -1
  434. package/behaviors/registry/ui/learning/atoms/std-learn-scenario.orb +1 -1
  435. package/behaviors/registry/ui/learning/atoms/std-learn-sim-3d.orb +1 -1
  436. package/behaviors/registry/ui/learning/atoms/std-learn-slope-probe.orb +1 -1
  437. package/behaviors/registry/ui/learning/atoms/std-learn-speed-drill.orb +1 -1
  438. package/behaviors/registry/ui/learning/atoms/std-learn-stepper.orb +1 -1
  439. package/behaviors/registry/ui/learning/atoms/std-learn-tour-3d.orb +1 -1
  440. package/behaviors/registry/ui/learning/atoms/std-learn-trace-player.orb +1 -1
  441. package/behaviors/registry/ui/learning/atoms/std-learn-transport.orb +1 -1
  442. package/behaviors/registry/ui/learning/atoms/std-learn-tree.orb +1 -1
  443. package/behaviors/registry/ui/learning/atoms/ui-algo-graph-canvas.orb +1 -1
  444. package/behaviors/registry/ui/learning/atoms/ui-algorithm-canvas.orb +1 -1
  445. package/behaviors/registry/ui/learning/atoms/ui-biology-canvas.orb +1 -1
  446. package/behaviors/registry/ui/learning/atoms/ui-chemistry-canvas.orb +1 -1
  447. package/behaviors/registry/ui/learning/atoms/ui-learning-canvas.orb +1 -1
  448. package/behaviors/registry/ui/learning/atoms/ui-math-canvas.orb +1 -1
  449. package/behaviors/registry/ui/learning/atoms/ui-physics-canvas.orb +1 -1
  450. package/dist/behaviors-embeddings.hash.json +2 -2
  451. package/dist/behaviors-embeddings.json +1 -1
  452. package/dist/knob-embeddings.hash.json +2 -2
  453. package/package.json +2 -2
@@ -1 +1 @@
1
- {"name":"std-notification-center","version":"1.0.0","description":"std-notification-center — per-user notification preferences, web-push subscriptions, and the digest drain for suppressed notifications. Owns the two owner-scoped stores std-notify-on-event consults at dispatch time: NotificationPreference rows (per event key: mode instant/digest/off, channel override, per-user quiet hours) and PushSubscription rows (captured via the browser/push-subscribe flow — the shared service worker + PushManager subscription, persisted as flat endpoint/p256dh/auth credentials). The DigestDrain trait is the delivery half of every suppression std-notify-on-event records: an hourly cron tick scans NotificationRecord audit rows left undispatched for digest/quiet-hours reasons and at least `minAgeHours` old, delivers each by email (the digest channel), and marks it dispatched — the reminder-scheduler self-driving scan loop verbatim. Compose alongside std-notify-on-event: the listener suppresses and records, this atom captures subscriptions, edits preferences, and drains.","orbitals":[{"name":"NotificationCenterOrbital","id":"orb_VQBZ2YWY5WF2Y8S3JJE6BQNW4C","uses":[{"from":"std/behaviors/ui-button","as":"Button"}],"entity":{"name":"NotificationPreference","id":"ent_9SFC0KCE6M73AB0CQWSWX8NTYX","collection":"notificationPreferences","persistence":"persistent","fields":[{"name":"id","type":"string","required":true},{"name":"personId","type":"string","required":true,"description":"Owner of this preference row — rows are meant to be private to their owner. Access predicates need an [identity] roster, so the binding organism (which declares one) owns the @read/@update scoping; the generic atom cannot.","synonyms":"user, owner, account"},{"name":"eventKey","type":"string","default":"","description":"Event key this preference applies to (matches a listener's eventKey); blank = all events.","synonyms":"event, trigger, subscription, topic"},{"name":"channel","type":"string","default":"in_app","values":["in_app","email","push","slack","sms","webhook"],"description":"Channel override for this user.","synonyms":"preferred channel, delivery method"},{"name":"mode","type":"string","default":"instant","values":["instant","digest","off"],"description":"Delivery mode: instant (default), digest (deferred to the drain cycle), or off (muted).","synonyms":"delivery mode, frequency, cadence, mute, defer"},{"name":"quietHours","type":"string","default":"","description":"Per-user quiet-hours window as \"HH:MM-HH:MM\" (e.g. 22:00-07:00); blank = disabled.","synonyms":"do not disturb, quiet window, night mode"},{"name":"createdAt","type":"number","default":0,"description":"Timestamp indicating when this preference row was created.","synonyms":"creation time, created"},{"name":"updatedAt","type":"number","default":0,"description":"Timestamp indicating when this preference row was last updated.","synonyms":"modified, last updated"}]},"auxiliaryEntities":[{"name":"PushSubscription","id":"ent_KEFWKMB0F6G7KDEHSF7QYPNGR0","collection":"pushSubscriptions","persistence":"persistent","fields":[{"name":"id","type":"string","required":true},{"name":"userId","type":"string","default":"","description":"Owner of this browser push subscription. Owner-scoped access predicates belong to the binding organism's [identity] roster, as with NotificationPreference.","synonyms":"user, owner, account"},{"name":"endpoint","type":"string","default":"","description":"Push service endpoint URL for this subscription.","synonyms":"push url, subscription endpoint"},{"name":"p256dh","type":"string","default":"","description":"Client public key (p256dh) of the subscription.","synonyms":"public key"},{"name":"auth","type":"string","default":"","description":"Auth secret of the subscription.","synonyms":"auth secret"},{"name":"createdAt","type":"number","default":0,"description":"When this subscription was captured.","synonyms":"subscribed at, created"},{"name":"lastError","type":"string","default":"","description":"Scratch: last subscribe-flow failure shown to the user; blank = none.","synonyms":"subscribe error, failure reason"}]},{"name":"NotificationRecord","id":"ent_FMK1JWJGPW8BE3XNDTRY5SPCFA","collection":"notifications","persistence":"persistent","fields":[{"name":"id","type":"string","required":true},{"name":"recipient","type":"string","default":"","description":"The identifier of the entity receiving the notification.","synonyms":"user, target, receiver, destination"},{"name":"channel","type":"string","default":"in-app","description":"The delivery method for the notification (e.g., email, SMS, in-app).","synonyms":"delivery, medium, type"},{"name":"message","type":"string","default":"","description":"The content of the notification message.","synonyms":"text, content, body"},{"name":"severity","type":"string","default":"info","description":"Indicates the importance or urgency level of the notification.","synonyms":"priority, level, importance"},{"name":"dispatched","type":"boolean","default":false,"description":"Indicates whether the notification has been successfully sent.","synonyms":"sent, delivered, status"},{"name":"error","type":"string","default":"","description":"Suppression reason or delivery failure detail when dispatched is false.","synonyms":"error message, failure reason, dispatch error"},{"name":"recordedAt","type":"number","default":0,"description":"Timestamp indicating when the notification record was created.","synonyms":"creation time, timestamp, date, when"}]},{"name":"DigestRunView","id":"ent_DBFXWY8RGDC86T95F4RG0HDD8R","persistence":"runtime","fields":[{"name":"id","type":"string","required":true},{"name":"headId","type":"string","default":"","description":"Scratch: id of the audit row the drain loop is currently delivering.","synonyms":"current id, cursor"},{"name":"headRecipient","type":"string","default":"","description":"Scratch: recipient of the row being delivered.","synonyms":"current recipient"},{"name":"headMessage","type":"string","default":"","description":"Scratch: message of the row being delivered.","synonyms":"current message"},{"name":"drainedCount","type":"number","default":0,"description":"Number of rows delivered in the current drain cycle.","synonyms":"delivered count, processed"},{"name":"lastError","type":"string","default":"","description":"Last drain failure; blank = none.","synonyms":"drain error, failure"}]}],"traits":[{"name":"PushSubscriber","id":"trt_FSVH6CVH0HRG8Z80X8JNESK8C6","effectRow":[{"kind":"browser/push-subscribe"},{"kind":"persist","resource":"PushSubscription"},{"kind":"render-ui","resource":"toast"},{"kind":"set","resource":"@entity.lastError"}],"category":"lifecycle","linkedEntity":"PushSubscription","linkedEntityId":"ent_KEFWKMB0F6G7KDEHSF7QYPNGR0","entityRefIds":{"PushSubscription":"ent_KEFWKMB0F6G7KDEHSF7QYPNGR0"},"emits":[{"event":"PUSH_SUBSCRIBED","eventId":"evt_XBWMRCYPTFBD7W3E14AEKGW7RB","description":"browser/push-subscribe resolved; the subscription credentials arrive flat on the payload","tier":"secondary","payloadSchema":[{"name":"endpoint","type":"string"},{"name":"p256dh","type":"string"},{"name":"auth","type":"string"}]},{"event":"PUSH_SUBSCRIBE_FAILED","eventId":"evt_BJHQT1N5MTJTDAZERH3GP9SWF9","description":"Push API unavailable, permission denied, or the host has no VAPID key","tier":"secondary","payloadSchema":[{"name":"error","type":"string","required":true}]},{"event":"PUSH_SAVED","eventId":"evt_02FYV6VPY8VF42SDDY7XMTT2Z7","description":"Subscription row persisted for the current user","tier":"secondary","payloadSchema":[{"name":"id","type":"string","required":true}]},{"event":"PUSH_SAVE_FAILED","eventId":"evt_XMPZH31MBKT5SW1GT8EX0REXJK","description":"Persisting the subscription row failed","tier":"secondary","payloadSchema":[{"name":"error","type":"string","required":true}]}],"stateMachine":{"states":[{"name":"idle","isInitial":true}],"events":[{"key":"SUBSCRIBE_PUSH","id":"evt_B4FRJE2Z2KFH9YW4SGYQ8TAKYN","name":"Subscribe Push","listened":true},{"key":"PUSH_SUBSCRIBED","id":"evt_XBWMRCYPTFBD7W3E14AEKGW7RB","name":"Push Subscribed","description":"browser/push-subscribe resolved; the subscription credentials arrive flat on the payload","tier":"secondary","payloadSchema":[{"name":"endpoint","type":"string"},{"name":"p256dh","type":"string"},{"name":"auth","type":"string"}]},{"key":"PUSH_SAVED","id":"evt_02FYV6VPY8VF42SDDY7XMTT2Z7","name":"Push Saved","description":"Subscription row persisted for the current user","tier":"secondary","payloadSchema":[{"name":"id","type":"string","required":true}]},{"key":"PUSH_SUBSCRIBE_FAILED","id":"evt_BJHQT1N5MTJTDAZERH3GP9SWF9","name":"Push Subscribe Failed","description":"Push API unavailable, permission denied, or the host has no VAPID key","tier":"secondary","payloadSchema":[{"name":"error","type":"string","required":true}]},{"key":"PUSH_SAVE_FAILED","id":"evt_XMPZH31MBKT5SW1GT8EX0REXJK","name":"Push Save Failed","description":"Persisting the subscription row failed","tier":"secondary","payloadSchema":[{"name":"error","type":"string","required":true}]}],"transitions":[{"from":"idle","to":"idle","event":"SUBSCRIBE_PUSH","eventId":"evt_B4FRJE2Z2KFH9YW4SGYQ8TAKYN","effects":[["browser/push-subscribe",{"emit":{"failure":"PUSH_SUBSCRIBE_FAILED","success":"PUSH_SUBSCRIBED"}}]]},{"from":"idle","to":"idle","event":"PUSH_SUBSCRIBED","eventId":"evt_XBWMRCYPTFBD7W3E14AEKGW7RB","effects":[["set","@entity.lastError",""],["persist","create","PushSubscription",{"auth":"@payload.auth","createdAt":"@now","endpoint":"@payload.endpoint","p256dh":"@payload.p256dh","userId":"@user.id"},{"emit":{"failure":"PUSH_SAVE_FAILED","success":"PUSH_SAVED"}}]]},{"from":"idle","to":"idle","event":"PUSH_SAVED","eventId":"evt_02FYV6VPY8VF42SDDY7XMTT2Z7","effects":[["render-ui","toast",{"type":"alert","variant":"success","message":"Push notifications enabled on this browser","dismissible":true}]]},{"from":"idle","to":"idle","event":"PUSH_SUBSCRIBE_FAILED","eventId":"evt_BJHQT1N5MTJTDAZERH3GP9SWF9","effects":[["set","@entity.lastError","@payload.error"],["render-ui","toast",{"type":"alert","variant":"warning","message":"Could not enable push notifications","dismissible":true}]]},{"from":"idle","to":"idle","event":"PUSH_SAVE_FAILED","eventId":"evt_XMPZH31MBKT5SW1GT8EX0REXJK","effects":[["set","@entity.lastError","@payload.error"],["render-ui","toast",{"type":"alert","variant":"warning","message":"Could not save the push subscription","dismissible":true}]]}]},"scope":"instance"},{"ref":"Button.traits.ButtonRender","id":"trt_ECT5YP16VDKDPSJVZKHG7RAGJJ","name":"PreferenceEditorButtonSubscribe","linkedEntity":"NotificationPreference","linkedEntityId":"ent_9SFC0KCE6M73AB0CQWSWX8NTYX","config":{"action":{"type":"unknown","default":"OPEN_SUBSCRIBE"},"label":{"type":"unknown","default":"Enable push notifications"}}},{"ref":"Button.traits.ButtonRender","id":"trt_NASW4TMBG95R4P7MF2KSWDSDGS","name":"PreferenceEditorButtonDigest","linkedEntity":"NotificationPreference","linkedEntityId":"ent_9SFC0KCE6M73AB0CQWSWX8NTYX","config":{"label":{"type":"unknown","default":"View notification digest"},"action":{"type":"unknown","default":"OPEN_DIGEST"}}},{"name":"PreferenceEditor","id":"trt_WE0GEX3SSNWWTQZARWCHC54WG1","effectRow":[{"kind":"fetch","resource":"NotificationPreference"},{"kind":"navigate","resource":"/notifications/digest"},{"kind":"navigate","resource":"/notifications/subscribe"},{"kind":"persist","resource":"NotificationPreference"},{"kind":"render-ui","resource":"main"},{"kind":"render-ui","resource":"toast"}],"category":"lifecycle","linkedEntity":"NotificationPreference","linkedEntityId":"ent_9SFC0KCE6M73AB0CQWSWX8NTYX","entityRefIds":{"NotificationPreference":"ent_9SFC0KCE6M73AB0CQWSWX8NTYX"},"traitEmbedIds":{"PreferenceEditorButtonSubscribe":"trt_ECT5YP16VDKDPSJVZKHG7RAGJJ","PreferenceEditorButtonDigest":"trt_NASW4TMBG95R4P7MF2KSWDSDGS"},"emits":[{"event":"PREFERENCE_SAVED","eventId":"evt_EABFA0HMM4TA2DWFVK5HDGYNHD","description":"Preference row persisted","tier":"secondary","payloadSchema":[{"name":"id","type":"string","required":true}]},{"event":"PREFERENCE_DELETED","eventId":"evt_ETABRCXEVGQDR46ND53X4K9N8V","description":"Preference row removed","tier":"secondary","payloadSchema":[{"name":"id","type":"string","required":true}]},{"event":"PREFERENCE_SAVE_FAILED","eventId":"evt_G1MQDDFQ94VMJCY9XEG4AJZ332","description":"Preference persist failed","tier":"secondary","payloadSchema":[{"name":"error","type":"string","required":true}]}],"stateMachine":{"states":[{"name":"idle","isInitial":true}],"events":[{"key":"INIT","id":"evt_KSEC1W3JF2S7H05MM1PXSEQMTB","name":"Initialize"},{"key":"OPEN_SUBSCRIBE","id":"evt_YN990M6AX75EKMP7T414N16ZH9","name":"Open Subscribe"},{"key":"OPEN_DIGEST","id":"evt_6V616VEXANENAZRHZV49765EKV","name":"Open Digest"},{"key":"SAVE_PREFERENCE","id":"evt_3EQG1K8SQ2CVH7FEBBNR3EKG1Y","name":"Save Preference","payloadSchema":[{"name":"eventKey","type":"string"},{"name":"mode","type":"string"},{"name":"channel","type":"string"},{"name":"quietHours","type":"string"}],"listened":true},{"key":"UPDATE_PREFERENCE","id":"evt_JS6T49PD376HKJAX6S5QZNNJ2X","name":"Update Preference","payloadSchema":[{"name":"id","type":"string"},{"name":"eventKey","type":"string"},{"name":"mode","type":"string"},{"name":"channel","type":"string"},{"name":"quietHours","type":"string"}],"listened":true},{"key":"DELETE_PREFERENCE","id":"evt_JZGRDCWK4H9J8T6R3A0Z6TCP01","name":"Delete Preference","payloadSchema":[{"name":"id","type":"string"}],"listened":true},{"key":"PREFERENCE_SAVED","id":"evt_EABFA0HMM4TA2DWFVK5HDGYNHD","name":"Preference Saved","description":"Preference row persisted","tier":"secondary","payloadSchema":[{"name":"id","type":"string","required":true}]},{"key":"PREFERENCE_DELETED","id":"evt_ETABRCXEVGQDR46ND53X4K9N8V","name":"Preference Deleted","description":"Preference row removed","tier":"secondary","payloadSchema":[{"name":"id","type":"string","required":true}]},{"key":"PREFERENCE_SAVE_FAILED","id":"evt_G1MQDDFQ94VMJCY9XEG4AJZ332","name":"Preference Save Failed","description":"Preference persist failed","tier":"secondary","payloadSchema":[{"name":"error","type":"string","required":true}]}],"transitions":[{"from":"idle","to":"idle","event":"INIT","eventId":"evt_KSEC1W3JF2S7H05MM1PXSEQMTB","effects":[["fetch","NotificationPreference"],["render-ui","main",{"type":"stack","direction":"vertical","gap":"md","children":["@trait.PreferenceEditorButtonSubscribe","@trait.PreferenceEditorButtonDigest"]}]]},{"from":"idle","to":"idle","event":"OPEN_SUBSCRIBE","eventId":"evt_YN990M6AX75EKMP7T414N16ZH9","effects":[["navigate","/notifications/subscribe"]]},{"from":"idle","to":"idle","event":"OPEN_DIGEST","eventId":"evt_6V616VEXANENAZRHZV49765EKV","effects":[["navigate","/notifications/digest"]]},{"from":"idle","to":"idle","event":"SAVE_PREFERENCE","eventId":"evt_3EQG1K8SQ2CVH7FEBBNR3EKG1Y","effects":[["persist","create","NotificationPreference",{"channel":"@payload.channel","createdAt":"@now","eventKey":"@payload.eventKey","mode":"@payload.mode","personId":"@user.id","quietHours":"@payload.quietHours","updatedAt":"@now"},{"emit":{"failure":"PREFERENCE_SAVE_FAILED","success":"PREFERENCE_SAVED"}}]]},{"from":"idle","to":"idle","event":"UPDATE_PREFERENCE","eventId":"evt_JS6T49PD376HKJAX6S5QZNNJ2X","effects":[["persist","update","NotificationPreference",{"id":"@payload.id","channel":"@payload.channel","eventKey":"@payload.eventKey","mode":"@payload.mode","quietHours":"@payload.quietHours","updatedAt":"@now"},{"emit":{"failure":"PREFERENCE_SAVE_FAILED","success":"PREFERENCE_SAVED"}}]]},{"from":"idle","to":"idle","event":"DELETE_PREFERENCE","eventId":"evt_JZGRDCWK4H9J8T6R3A0Z6TCP01","effects":[["persist","delete","NotificationPreference","@payload.id",{"emit":{"failure":"PREFERENCE_SAVE_FAILED","success":"PREFERENCE_DELETED"}}]]},{"from":"idle","to":"idle","event":"PREFERENCE_SAVED","eventId":"evt_EABFA0HMM4TA2DWFVK5HDGYNHD","effects":[["render-ui","toast",{"type":"alert","variant":"success","message":"Notification preference saved","dismissible":true}]]},{"from":"idle","to":"idle","event":"PREFERENCE_DELETED","eventId":"evt_ETABRCXEVGQDR46ND53X4K9N8V","effects":[["render-ui","toast",{"type":"alert","variant":"info","message":"Notification preference removed","dismissible":true}]]},{"from":"idle","to":"idle","event":"PREFERENCE_SAVE_FAILED","eventId":"evt_G1MQDDFQ94VMJCY9XEG4AJZ332","effects":[["render-ui","toast",{"type":"alert","variant":"warning","message":"Could not save the notification preference","dismissible":true}]]}]},"scope":"instance"},{"name":"DigestDrain","id":"trt_5X2W3SXQXCVYP32AHS6JS0YEE9","effectRow":[{"kind":"call-service","resource":"email.send"},{"kind":"fetch","resource":"NotificationRecord"},{"kind":"fetch","resource":"NotificationRecord","site":"tick"},{"kind":"persist","resource":"NotificationRecord"},{"kind":"render-ui","resource":"toast"},{"kind":"set","resource":"@entity.drainedCount"},{"kind":"set","resource":"@entity.headId"},{"kind":"set","resource":"@entity.headMessage"},{"kind":"set","resource":"@entity.headRecipient"},{"kind":"set","resource":"@entity.lastError"},{"kind":"ticks","site":"tick"}],"category":"lifecycle","linkedEntity":"DigestRunView","linkedEntityId":"ent_DBFXWY8RGDC86T95F4RG0HDD8R","entityRefIds":{"DigestRunView":"ent_DBFXWY8RGDC86T95F4RG0HDD8R","NotificationRecord":"ent_FMK1JWJGPW8BE3XNDTRY5SPCFA"},"emits":[{"event":"DIGEST_ROWS_LOADED","eventId":"evt_0S7GWCNVT7XX3NNBX64XYAG6AT","description":"Undispatched digest/quiet-hours audit rows past minAgeHours, oldest batch first","tier":"secondary","payloadSchema":[{"name":"data","type":"[object]","properties":[{"name":"id","type":"string"},{"name":"recipient","type":"string"},{"name":"channel","type":"string"},{"name":"message","type":"string"},{"name":"severity","type":"string"},{"name":"dispatched","type":"boolean"},{"name":"error","type":"string"},{"name":"recordedAt","type":"number"}],"entity":"NotifRow"}]},{"event":"DIGEST_ITEM_SENT","eventId":"evt_ZWA78MWCPN6BAJJJP53M8CZPMD","description":"email.send result for the current digest row","tier":"secondary","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"status","type":"string","required":true}]},{"event":"DIGEST_STEPPED","eventId":"evt_0DFRN2S936MHK8TVVWE6X0GCGS","description":"Current row marked dispatched; drives the next loop pass","tier":"secondary","payloadSchema":[{"name":"id","type":"string","required":true}]},{"event":"DIGEST_FAILED","eventId":"evt_9A59DJKXNSYTWVG1WZ84NX5CWK","description":"Digest scan / delivery / persist failed — the cycle stops until the next tick","tier":"secondary","payloadSchema":[{"name":"error","type":"string","required":true}]}],"stateMachine":{"states":[{"name":"idle","isInitial":true},{"name":"draining"}],"events":[{"key":"DIGEST_ROWS_LOADED","id":"evt_0S7GWCNVT7XX3NNBX64XYAG6AT","name":"Digest Rows Loaded","description":"Undispatched digest/quiet-hours audit rows past minAgeHours, oldest batch first","tier":"secondary","payloadSchema":[{"name":"data","type":"[object]","properties":[{"name":"id","type":"string"},{"name":"recipient","type":"string"},{"name":"channel","type":"string"},{"name":"message","type":"string"},{"name":"severity","type":"string"},{"name":"dispatched","type":"boolean"},{"name":"error","type":"string"},{"name":"recordedAt","type":"number"}]}],"listened":true},{"key":"DIGEST_FAILED","id":"evt_9A59DJKXNSYTWVG1WZ84NX5CWK","name":"Digest Failed","description":"Digest scan / delivery / persist failed — the cycle stops until the next tick","tier":"secondary","payloadSchema":[{"name":"error","type":"string","required":true}],"listened":true},{"key":"DIGEST_ITEM_SENT","id":"evt_ZWA78MWCPN6BAJJJP53M8CZPMD","name":"Digest Item Sent","description":"email.send result for the current digest row","tier":"secondary","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"status","type":"string","required":true}],"listened":true},{"key":"DIGEST_STEPPED","id":"evt_0DFRN2S936MHK8TVVWE6X0GCGS","name":"Digest Stepped","description":"Current row marked dispatched; drives the next loop pass","tier":"secondary","payloadSchema":[{"name":"id","type":"string","required":true}],"listened":true}],"transitions":[{"from":"idle","to":"draining","event":"DIGEST_ROWS_LOADED","eventId":"evt_0S7GWCNVT7XX3NNBX64XYAG6AT","guard":["and","@config.digestEnabled",[">",["array/len","@payload.data"],0]],"effects":[["set","@entity.headId",["object/get",["array/first","@payload.data"],"id"]],["set","@entity.headRecipient",["object/get",["array/first","@payload.data"],"recipient"]],["set","@entity.headMessage",["object/get",["array/first","@payload.data"],"message"]],["call-service","email","send",{"body":"@entity.headMessage","from":"","subject":"@config.digestSubject","to":"@entity.headRecipient"},{"emit":{"failure":"DIGEST_FAILED","success":"DIGEST_ITEM_SENT"}}]]},{"from":"idle","to":"idle","event":"DIGEST_ROWS_LOADED","eventId":"evt_0S7GWCNVT7XX3NNBX64XYAG6AT","guard":["=",["array/len","@payload.data"],0]},{"from":"idle","to":"idle","event":"DIGEST_FAILED","eventId":"evt_9A59DJKXNSYTWVG1WZ84NX5CWK","effects":[["set","@entity.lastError","@payload.error"],["render-ui","toast",{"type":"alert","variant":"error","message":["str/concat","Couldn't send the notification digest — ","@payload.error"],"dismissible":true}]]},{"from":"draining","to":"draining","event":"DIGEST_ITEM_SENT","eventId":"evt_ZWA78MWCPN6BAJJJP53M8CZPMD","effects":[["set","@entity.drainedCount",["+","@entity.drainedCount",1]],["persist","update","NotificationRecord",{"id":"@entity.headId","dispatched":true},{"emit":{"failure":"DIGEST_FAILED","success":"DIGEST_STEPPED"}}]]},{"from":"draining","to":"draining","event":"DIGEST_STEPPED","eventId":"evt_0DFRN2S936MHK8TVVWE6X0GCGS","effects":[["fetch","NotificationRecord",{"emit":{"failure":"DIGEST_FAILED","success":"DIGEST_ROWS_LOADED"},"filter":["and",["=",["object/get","@entity","dispatched"],false],["or",["=",["object/get","@entity","error"],"digest-deferred"],["=",["object/get","@entity","error"],"quiet-hours"]],["<",["object/get","@entity","recordedAt"],["-","@now",["*","@config.minAgeHours",3600000]]]]}]]},{"from":"draining","to":"draining","event":"DIGEST_ROWS_LOADED","eventId":"evt_0S7GWCNVT7XX3NNBX64XYAG6AT","guard":[">",["array/len","@payload.data"],0],"effects":[["set","@entity.headId",["object/get",["array/first","@payload.data"],"id"]],["set","@entity.headRecipient",["object/get",["array/first","@payload.data"],"recipient"]],["set","@entity.headMessage",["object/get",["array/first","@payload.data"],"message"]],["call-service","email","send",{"body":"@entity.headMessage","from":"","subject":"@config.digestSubject","to":"@entity.headRecipient"},{"emit":{"failure":"DIGEST_FAILED","success":"DIGEST_ITEM_SENT"}}]]},{"from":"draining","to":"idle","event":"DIGEST_ROWS_LOADED","eventId":"evt_0S7GWCNVT7XX3NNBX64XYAG6AT","guard":["=",["array/len","@payload.data"],0]},{"from":"draining","to":"idle","event":"DIGEST_FAILED","eventId":"evt_9A59DJKXNSYTWVG1WZ84NX5CWK","effects":[["set","@entity.lastError","@payload.error"],["render-ui","toast",{"type":"alert","variant":"error","message":["str/concat","Couldn't send the notification digest — ","@payload.error"],"dismissible":true}]]}]},"ticks":[{"name":"digestCycle","interval":"0 * * * *","effects":[["fetch","NotificationRecord",{"emit":{"failure":"DIGEST_FAILED","success":"DIGEST_ROWS_LOADED"},"filter":["and",["=",["object/get","@entity","dispatched"],false],["or",["=",["object/get","@entity","error"],"digest-deferred"],["=",["object/get","@entity","error"],"quiet-hours"]],["<",["object/get","@entity","recordedAt"],["-","@now",["*","@config.minAgeHours",3600000]]]]}]],"runsInBackground":true}],"config":{"minAgeHours":{"type":"number","default":1,"label":"Minimum age (hours)","description":"Only drain audit rows at least this many hours old, so quiet-hours suppressions are not redelivered inside their window.","synonyms":"delay, drain delay, hold for, batch window","tier":"infra"},"digestSubject":{"type":"string","default":"Notification digest","label":"Digest email subject","description":"Subject line for drained digest deliveries.","synonyms":"digest title, summary subject, email subject","tier":"presentation"},"digestEnabled":{"type":"boolean","default":false,"label":"Deliver digests","description":"Drain suppressed notifications (digest-deferred and quiet-hours audit rows) on the hourly cycle. Off by default.","synonyms":"enable digest, digest mode, batch notifications, daily summary, drain suppressed","tier":"infra"}},"scope":"instance"}],"pages":[{"name":"NotificationPreferencesPage","id":"pag_VKQFW1D1GPGRB94S1T6VV0V8VN","path":"/notifications/preferences","traits":[{"ref":"PreferenceEditor","refId":"trt_WE0GEX3SSNWWTQZARWCHC54WG1"},{"ref":"PreferenceEditorButtonSubscribe","refId":"trt_ECT5YP16VDKDPSJVZKHG7RAGJJ"},{"ref":"PreferenceEditorButtonDigest","refId":"trt_NASW4TMBG95R4P7MF2KSWDSDGS"}]},{"name":"PushSubscribePage","id":"pag_ZC96H4NF3MQHTF08P3AGC73TNK","path":"/notifications/subscribe","traits":[{"ref":"PushSubscriber","refId":"trt_FSVH6CVH0HRG8Z80X8JNESK8C6"}]},{"name":"NotificationDigestPage","id":"pag_CKB79DYPGWB8E36MH5PB83EEK1","path":"/notifications/digest","traits":[{"ref":"DigestDrain","refId":"trt_5X2W3SXQXCVYP32AHS6JS0YEE9"}]}],"types":{"NotifRow":[{"name":"id","type":"string"},{"name":"recipient","type":"string"},{"name":"channel","type":"string"},{"name":"message","type":"string"},{"name":"severity","type":"string"},{"name":"dispatched","type":"boolean"},{"name":"error","type":"string"},{"name":"recordedAt","type":"number"}],"PushCreds":[{"name":"endpoint","type":"string"},{"name":"p256dh","type":"string"},{"name":"auth","type":"string"}]}}],"schemaVersion":1,"ledger":{"schemaVersion":1,"entries":{"ent_9SFC0KCE6M73AB0CQWSWX8NTYX":{"id":"ent_9SFC0KCE6M73AB0CQWSWX8NTYX","kind":"entity","bakedName":"NotificationPreference","curName":"NotificationPreference","renames":[],"owner":"workspace"},"ent_DBFXWY8RGDC86T95F4RG0HDD8R":{"id":"ent_DBFXWY8RGDC86T95F4RG0HDD8R","kind":"entity","bakedName":"DigestRunView","curName":"DigestRunView","renames":[],"owner":"workspace"},"ent_FMK1JWJGPW8BE3XNDTRY5SPCFA":{"id":"ent_FMK1JWJGPW8BE3XNDTRY5SPCFA","kind":"entity","bakedName":"NotificationRecord","curName":"NotificationRecord","renames":[],"owner":"workspace"},"ent_KEFWKMB0F6G7KDEHSF7QYPNGR0":{"id":"ent_KEFWKMB0F6G7KDEHSF7QYPNGR0","kind":"entity","bakedName":"PushSubscription","curName":"PushSubscription","renames":[],"owner":"workspace"},"evt_02FYV6VPY8VF42SDDY7XMTT2Z7":{"id":"evt_02FYV6VPY8VF42SDDY7XMTT2Z7","kind":"event","bakedName":"PUSH_SAVED","curName":"PUSH_SAVED","renames":[],"owner":"workspace","parent":"trt_FSVH6CVH0HRG8Z80X8JNESK8C6"},"evt_0DFRN2S936MHK8TVVWE6X0GCGS":{"id":"evt_0DFRN2S936MHK8TVVWE6X0GCGS","kind":"event","bakedName":"DIGEST_STEPPED","curName":"DIGEST_STEPPED","renames":[],"owner":"workspace","parent":"trt_5X2W3SXQXCVYP32AHS6JS0YEE9"},"evt_0S7GWCNVT7XX3NNBX64XYAG6AT":{"id":"evt_0S7GWCNVT7XX3NNBX64XYAG6AT","kind":"event","bakedName":"DIGEST_ROWS_LOADED","curName":"DIGEST_ROWS_LOADED","renames":[],"owner":"workspace","parent":"trt_5X2W3SXQXCVYP32AHS6JS0YEE9"},"evt_3EQG1K8SQ2CVH7FEBBNR3EKG1Y":{"id":"evt_3EQG1K8SQ2CVH7FEBBNR3EKG1Y","kind":"event","bakedName":"SAVE_PREFERENCE","curName":"SAVE_PREFERENCE","renames":[],"owner":"workspace","parent":"trt_WE0GEX3SSNWWTQZARWCHC54WG1"},"evt_6V616VEXANENAZRHZV49765EKV":{"id":"evt_6V616VEXANENAZRHZV49765EKV","kind":"event","bakedName":"OPEN_DIGEST","curName":"OPEN_DIGEST","renames":[],"owner":"workspace","parent":"trt_WE0GEX3SSNWWTQZARWCHC54WG1"},"evt_9A59DJKXNSYTWVG1WZ84NX5CWK":{"id":"evt_9A59DJKXNSYTWVG1WZ84NX5CWK","kind":"event","bakedName":"DIGEST_FAILED","curName":"DIGEST_FAILED","renames":[],"owner":"workspace","parent":"trt_5X2W3SXQXCVYP32AHS6JS0YEE9"},"evt_B4FRJE2Z2KFH9YW4SGYQ8TAKYN":{"id":"evt_B4FRJE2Z2KFH9YW4SGYQ8TAKYN","kind":"event","bakedName":"SUBSCRIBE_PUSH","curName":"SUBSCRIBE_PUSH","renames":[],"owner":"workspace","parent":"trt_FSVH6CVH0HRG8Z80X8JNESK8C6"},"evt_BJHQT1N5MTJTDAZERH3GP9SWF9":{"id":"evt_BJHQT1N5MTJTDAZERH3GP9SWF9","kind":"event","bakedName":"PUSH_SUBSCRIBE_FAILED","curName":"PUSH_SUBSCRIBE_FAILED","renames":[],"owner":"workspace","parent":"trt_FSVH6CVH0HRG8Z80X8JNESK8C6"},"evt_EABFA0HMM4TA2DWFVK5HDGYNHD":{"id":"evt_EABFA0HMM4TA2DWFVK5HDGYNHD","kind":"event","bakedName":"PREFERENCE_SAVED","curName":"PREFERENCE_SAVED","renames":[],"owner":"workspace","parent":"trt_WE0GEX3SSNWWTQZARWCHC54WG1"},"evt_ETABRCXEVGQDR46ND53X4K9N8V":{"id":"evt_ETABRCXEVGQDR46ND53X4K9N8V","kind":"event","bakedName":"PREFERENCE_DELETED","curName":"PREFERENCE_DELETED","renames":[],"owner":"workspace","parent":"trt_WE0GEX3SSNWWTQZARWCHC54WG1"},"evt_G1MQDDFQ94VMJCY9XEG4AJZ332":{"id":"evt_G1MQDDFQ94VMJCY9XEG4AJZ332","kind":"event","bakedName":"PREFERENCE_SAVE_FAILED","curName":"PREFERENCE_SAVE_FAILED","renames":[],"owner":"workspace","parent":"trt_WE0GEX3SSNWWTQZARWCHC54WG1"},"evt_JS6T49PD376HKJAX6S5QZNNJ2X":{"id":"evt_JS6T49PD376HKJAX6S5QZNNJ2X","kind":"event","bakedName":"UPDATE_PREFERENCE","curName":"UPDATE_PREFERENCE","renames":[],"owner":"workspace","parent":"trt_WE0GEX3SSNWWTQZARWCHC54WG1"},"evt_JZGRDCWK4H9J8T6R3A0Z6TCP01":{"id":"evt_JZGRDCWK4H9J8T6R3A0Z6TCP01","kind":"event","bakedName":"DELETE_PREFERENCE","curName":"DELETE_PREFERENCE","renames":[],"owner":"workspace","parent":"trt_WE0GEX3SSNWWTQZARWCHC54WG1"},"evt_KSEC1W3JF2S7H05MM1PXSEQMTB":{"id":"evt_KSEC1W3JF2S7H05MM1PXSEQMTB","kind":"event","bakedName":"INIT","curName":"INIT","renames":[],"owner":"workspace","parent":"trt_WE0GEX3SSNWWTQZARWCHC54WG1"},"evt_XBWMRCYPTFBD7W3E14AEKGW7RB":{"id":"evt_XBWMRCYPTFBD7W3E14AEKGW7RB","kind":"event","bakedName":"PUSH_SUBSCRIBED","curName":"PUSH_SUBSCRIBED","renames":[],"owner":"workspace","parent":"trt_FSVH6CVH0HRG8Z80X8JNESK8C6"},"evt_XMPZH31MBKT5SW1GT8EX0REXJK":{"id":"evt_XMPZH31MBKT5SW1GT8EX0REXJK","kind":"event","bakedName":"PUSH_SAVE_FAILED","curName":"PUSH_SAVE_FAILED","renames":[],"owner":"workspace","parent":"trt_FSVH6CVH0HRG8Z80X8JNESK8C6"},"evt_YN990M6AX75EKMP7T414N16ZH9":{"id":"evt_YN990M6AX75EKMP7T414N16ZH9","kind":"event","bakedName":"OPEN_SUBSCRIBE","curName":"OPEN_SUBSCRIBE","renames":[],"owner":"workspace","parent":"trt_WE0GEX3SSNWWTQZARWCHC54WG1"},"evt_ZWA78MWCPN6BAJJJP53M8CZPMD":{"id":"evt_ZWA78MWCPN6BAJJJP53M8CZPMD","kind":"event","bakedName":"DIGEST_ITEM_SENT","curName":"DIGEST_ITEM_SENT","renames":[],"owner":"workspace","parent":"trt_5X2W3SXQXCVYP32AHS6JS0YEE9"},"orb_VQBZ2YWY5WF2Y8S3JJE6BQNW4C":{"id":"orb_VQBZ2YWY5WF2Y8S3JJE6BQNW4C","kind":"orbital","bakedName":"NotificationCenterOrbital","curName":"NotificationCenterOrbital","renames":[],"owner":"workspace"},"pag_CKB79DYPGWB8E36MH5PB83EEK1":{"id":"pag_CKB79DYPGWB8E36MH5PB83EEK1","kind":"page","bakedName":"NotificationDigestPage","curName":"NotificationDigestPage","renames":[],"owner":"workspace"},"pag_VKQFW1D1GPGRB94S1T6VV0V8VN":{"id":"pag_VKQFW1D1GPGRB94S1T6VV0V8VN","kind":"page","bakedName":"NotificationPreferencesPage","curName":"NotificationPreferencesPage","renames":[],"owner":"workspace"},"pag_ZC96H4NF3MQHTF08P3AGC73TNK":{"id":"pag_ZC96H4NF3MQHTF08P3AGC73TNK","kind":"page","bakedName":"PushSubscribePage","curName":"PushSubscribePage","renames":[],"owner":"workspace"},"trt_5X2W3SXQXCVYP32AHS6JS0YEE9":{"id":"trt_5X2W3SXQXCVYP32AHS6JS0YEE9","kind":"trait","bakedName":"DigestDrain","curName":"DigestDrain","renames":[],"owner":"workspace"},"trt_ECT5YP16VDKDPSJVZKHG7RAGJJ":{"id":"trt_ECT5YP16VDKDPSJVZKHG7RAGJJ","kind":"trait","bakedName":"PreferenceEditorButtonSubscribe","curName":"PreferenceEditorButtonSubscribe","renames":[],"owner":"workspace"},"trt_FSVH6CVH0HRG8Z80X8JNESK8C6":{"id":"trt_FSVH6CVH0HRG8Z80X8JNESK8C6","kind":"trait","bakedName":"PushSubscriber","curName":"PushSubscriber","renames":[],"owner":"workspace"},"trt_NASW4TMBG95R4P7MF2KSWDSDGS":{"id":"trt_NASW4TMBG95R4P7MF2KSWDSDGS","kind":"trait","bakedName":"PreferenceEditorButtonDigest","curName":"PreferenceEditorButtonDigest","renames":[],"owner":"workspace"},"trt_WE0GEX3SSNWWTQZARWCHC54WG1":{"id":"trt_WE0GEX3SSNWWTQZARWCHC54WG1","kind":"trait","bakedName":"PreferenceEditor","curName":"PreferenceEditor","renames":[],"owner":"workspace"}}}}
1
+ {"name":"std-notification-center","version":"1.0.0","description":"std-notification-center — per-user notification preferences, web-push subscriptions, and the digest drain for suppressed notifications. Owns the two owner-scoped stores std-notify-on-event consults at dispatch time: NotificationPreference rows (per event key: mode instant/digest/off, channel override, per-user quiet hours) and PushSubscription rows (captured via the browser/push-subscribe flow — the shared service worker + PushManager subscription, persisted as flat endpoint/p256dh/auth credentials). The DigestDrain trait is the delivery half of every suppression std-notify-on-event records: an hourly cron tick scans NotificationRecord audit rows left undispatched for digest/quiet-hours reasons and at least `minAgeHours` old, delivers each by email (the digest channel), and marks it dispatched — the reminder-scheduler self-driving scan loop verbatim. Compose alongside std-notify-on-event: the listener suppresses and records, this atom captures subscriptions, edits preferences, and drains.","orbitals":[{"name":"NotificationCenterOrbital","id":"orb_VQBZ2YWY5WF2Y8S3JJE6BQNW4C","uses":[{"from":"std/behaviors/ui-button","as":"Button"}],"entity":{"name":"NotificationPreference","id":"ent_9SFC0KCE6M73AB0CQWSWX8NTYX","collection":"notificationPreferences","persistence":"persistent","fields":[{"name":"id","type":"string","required":true},{"name":"personId","type":"string","required":true,"description":"Owner of this preference row — rows are meant to be private to their owner. Access predicates need an [identity] roster, so the binding organism (which declares one) owns the @read/@update scoping; the generic atom cannot.","synonyms":"user, owner, account"},{"name":"eventKey","type":"string","default":"","description":"Event key this preference applies to (matches a listener's eventKey); blank = all events.","synonyms":"event, trigger, subscription, topic"},{"name":"channel","type":"string","default":"in_app","values":["in_app","email","push","slack","sms","webhook"],"description":"Channel override for this user.","synonyms":"preferred channel, delivery method"},{"name":"mode","type":"string","default":"instant","values":["instant","digest","off"],"description":"Delivery mode: instant (default), digest (deferred to the drain cycle), or off (muted).","synonyms":"delivery mode, frequency, cadence, mute, defer"},{"name":"quietHours","type":"string","default":"","description":"Per-user quiet-hours window as \"HH:MM-HH:MM\" (e.g. 22:00-07:00); blank = disabled.","synonyms":"do not disturb, quiet window, night mode"},{"name":"createdAt","type":"number","default":0,"description":"Timestamp indicating when this preference row was created.","synonyms":"creation time, created"},{"name":"updatedAt","type":"number","default":0,"description":"Timestamp indicating when this preference row was last updated.","synonyms":"modified, last updated"}]},"auxiliaryEntities":[{"name":"PushSubscription","id":"ent_KEFWKMB0F6G7KDEHSF7QYPNGR0","collection":"pushSubscriptions","persistence":"persistent","fields":[{"name":"id","type":"string","required":true},{"name":"userId","type":"string","default":"","description":"Owner of this browser push subscription. Owner-scoped access predicates belong to the binding organism's [identity] roster, as with NotificationPreference.","synonyms":"user, owner, account"},{"name":"endpoint","type":"string","default":"","description":"Push service endpoint URL for this subscription.","synonyms":"push url, subscription endpoint"},{"name":"p256dh","type":"string","default":"","description":"Client public key (p256dh) of the subscription.","synonyms":"public key"},{"name":"auth","type":"string","default":"","description":"Auth secret of the subscription.","synonyms":"auth secret"},{"name":"createdAt","type":"number","default":0,"description":"When this subscription was captured.","synonyms":"subscribed at, created"},{"name":"lastError","type":"string","default":"","description":"Scratch: last subscribe-flow failure shown to the user; blank = none.","synonyms":"subscribe error, failure reason"}]},{"name":"NotificationRecord","id":"ent_FMK1JWJGPW8BE3XNDTRY5SPCFA","collection":"notifications","persistence":"persistent","fields":[{"name":"id","type":"string","required":true},{"name":"recipient","type":"string","default":"","description":"The identifier of the entity receiving the notification.","synonyms":"user, target, receiver, destination"},{"name":"channel","type":"string","default":"in-app","description":"The delivery method for the notification (e.g., email, SMS, in-app).","synonyms":"delivery, medium, type"},{"name":"message","type":"string","default":"","description":"The content of the notification message.","synonyms":"text, content, body"},{"name":"severity","type":"string","default":"info","description":"Indicates the importance or urgency level of the notification.","synonyms":"priority, level, importance"},{"name":"dispatched","type":"boolean","default":false,"description":"Indicates whether the notification has been successfully sent.","synonyms":"sent, delivered, status"},{"name":"error","type":"string","default":"","description":"Suppression reason or delivery failure detail when dispatched is false.","synonyms":"error message, failure reason, dispatch error"},{"name":"recordedAt","type":"number","default":0,"description":"Timestamp indicating when the notification record was created.","synonyms":"creation time, timestamp, date, when"}]},{"name":"DigestRunView","id":"ent_DBFXWY8RGDC86T95F4RG0HDD8R","persistence":"runtime","fields":[{"name":"id","type":"string","required":true},{"name":"headId","type":"string","default":"","description":"Scratch: id of the audit row the drain loop is currently delivering.","synonyms":"current id, cursor"},{"name":"headRecipient","type":"string","default":"","description":"Scratch: recipient of the row being delivered.","synonyms":"current recipient"},{"name":"headMessage","type":"string","default":"","description":"Scratch: message of the row being delivered.","synonyms":"current message"},{"name":"drainedCount","type":"number","default":0,"description":"Number of rows delivered in the current drain cycle.","synonyms":"delivered count, processed"},{"name":"lastError","type":"string","default":"","description":"Last drain failure; blank = none.","synonyms":"drain error, failure"}]}],"traits":[{"name":"PushSubscriber","id":"trt_FSVH6CVH0HRG8Z80X8JNESK8C6","effectRow":[{"kind":"browser/push-subscribe"},{"kind":"persist","resource":"PushSubscription"},{"kind":"render-ui","resource":"toast"},{"kind":"set","resource":"@entity.lastError"}],"category":"lifecycle","linkedEntity":"PushSubscription","linkedEntityId":"ent_KEFWKMB0F6G7KDEHSF7QYPNGR0","entityRefIds":{"PushSubscription":"ent_KEFWKMB0F6G7KDEHSF7QYPNGR0"},"emits":[{"event":"PUSH_SUBSCRIBED","eventId":"evt_XBWMRCYPTFBD7W3E14AEKGW7RB","description":"browser/push-subscribe resolved; the subscription credentials arrive flat on the payload","tier":"secondary","payloadSchema":[{"name":"endpoint","type":"string"},{"name":"p256dh","type":"string"},{"name":"auth","type":"string"}]},{"event":"PUSH_SUBSCRIBE_FAILED","eventId":"evt_BJHQT1N5MTJTDAZERH3GP9SWF9","description":"Push API unavailable, permission denied, or the host has no VAPID key","tier":"secondary","payloadSchema":[{"name":"error","type":"string","required":true}]},{"event":"PUSH_SAVED","eventId":"evt_02FYV6VPY8VF42SDDY7XMTT2Z7","description":"Subscription row persisted for the current user","tier":"secondary","payloadSchema":[{"name":"id","type":"string","required":true}]},{"event":"PUSH_SAVE_FAILED","eventId":"evt_XMPZH31MBKT5SW1GT8EX0REXJK","description":"Persisting the subscription row failed","tier":"secondary","payloadSchema":[{"name":"error","type":"string","required":true}]}],"stateMachine":{"states":[{"name":"idle","isInitial":true}],"events":[{"key":"SUBSCRIBE_PUSH","id":"evt_B4FRJE2Z2KFH9YW4SGYQ8TAKYN","name":"Subscribe Push","listened":true},{"key":"PUSH_SUBSCRIBED","id":"evt_XBWMRCYPTFBD7W3E14AEKGW7RB","name":"Push Subscribed","description":"browser/push-subscribe resolved; the subscription credentials arrive flat on the payload","tier":"secondary","payloadSchema":[{"name":"endpoint","type":"string"},{"name":"p256dh","type":"string"},{"name":"auth","type":"string"}]},{"key":"PUSH_SAVED","id":"evt_02FYV6VPY8VF42SDDY7XMTT2Z7","name":"Push Saved","description":"Subscription row persisted for the current user","tier":"secondary","payloadSchema":[{"name":"id","type":"string","required":true}]},{"key":"PUSH_SUBSCRIBE_FAILED","id":"evt_BJHQT1N5MTJTDAZERH3GP9SWF9","name":"Push Subscribe Failed","description":"Push API unavailable, permission denied, or the host has no VAPID key","tier":"secondary","payloadSchema":[{"name":"error","type":"string","required":true}]},{"key":"PUSH_SAVE_FAILED","id":"evt_XMPZH31MBKT5SW1GT8EX0REXJK","name":"Push Save Failed","description":"Persisting the subscription row failed","tier":"secondary","payloadSchema":[{"name":"error","type":"string","required":true}]}],"transitions":[{"from":"idle","to":"idle","event":"SUBSCRIBE_PUSH","eventId":"evt_B4FRJE2Z2KFH9YW4SGYQ8TAKYN","effects":[["browser/push-subscribe",{"emit":{"failure":"PUSH_SUBSCRIBE_FAILED","success":"PUSH_SUBSCRIBED"}}]]},{"from":"idle","to":"idle","event":"PUSH_SUBSCRIBED","eventId":"evt_XBWMRCYPTFBD7W3E14AEKGW7RB","effects":[["set","@entity.lastError",""],["persist","create","PushSubscription",{"auth":"@payload.auth","createdAt":"@now","endpoint":"@payload.endpoint","p256dh":"@payload.p256dh","userId":"@user.id"},{"emit":{"failure":"PUSH_SAVE_FAILED","success":"PUSH_SAVED"}}]]},{"from":"idle","to":"idle","event":"PUSH_SAVED","eventId":"evt_02FYV6VPY8VF42SDDY7XMTT2Z7","effects":[["render-ui","toast",{"type":"alert","variant":"success","message":"Push notifications enabled on this browser","dismissible":true}]]},{"from":"idle","to":"idle","event":"PUSH_SUBSCRIBE_FAILED","eventId":"evt_BJHQT1N5MTJTDAZERH3GP9SWF9","effects":[["set","@entity.lastError","@payload.error"],["render-ui","toast",{"type":"alert","variant":"warning","message":"Could not enable push notifications","dismissible":true}]]},{"from":"idle","to":"idle","event":"PUSH_SAVE_FAILED","eventId":"evt_XMPZH31MBKT5SW1GT8EX0REXJK","effects":[["set","@entity.lastError","@payload.error"],["render-ui","toast",{"type":"alert","variant":"warning","message":"Could not save the push subscription","dismissible":true}]]}]},"scope":"instance"},{"ref":"Button.traits.ButtonRender","id":"trt_ECT5YP16VDKDPSJVZKHG7RAGJJ","name":"PreferenceEditorButtonSubscribe","linkedEntity":"NotificationPreference","linkedEntityId":"ent_9SFC0KCE6M73AB0CQWSWX8NTYX","config":{"action":{"type":"unknown","default":"OPEN_SUBSCRIBE"},"label":{"type":"unknown","default":"Enable push notifications"}}},{"ref":"Button.traits.ButtonRender","id":"trt_NASW4TMBG95R4P7MF2KSWDSDGS","name":"PreferenceEditorButtonDigest","linkedEntity":"NotificationPreference","linkedEntityId":"ent_9SFC0KCE6M73AB0CQWSWX8NTYX","config":{"label":{"type":"unknown","default":"View notification digest"},"action":{"type":"unknown","default":"OPEN_DIGEST"}}},{"name":"PreferenceEditor","id":"trt_WE0GEX3SSNWWTQZARWCHC54WG1","effectRow":[{"kind":"fetch","resource":"NotificationPreference"},{"kind":"navigate","resource":"/notifications/digest"},{"kind":"navigate","resource":"/notifications/subscribe"},{"kind":"persist","resource":"NotificationPreference"},{"kind":"render-ui","resource":"main"},{"kind":"render-ui","resource":"toast"}],"category":"lifecycle","linkedEntity":"NotificationPreference","linkedEntityId":"ent_9SFC0KCE6M73AB0CQWSWX8NTYX","entityRefIds":{"NotificationPreference":"ent_9SFC0KCE6M73AB0CQWSWX8NTYX"},"traitEmbedIds":{"PreferenceEditorButtonSubscribe":"trt_ECT5YP16VDKDPSJVZKHG7RAGJJ","PreferenceEditorButtonDigest":"trt_NASW4TMBG95R4P7MF2KSWDSDGS"},"emits":[{"event":"PREFERENCE_SAVED","eventId":"evt_EABFA0HMM4TA2DWFVK5HDGYNHD","description":"Preference row persisted","tier":"secondary","payloadSchema":[{"name":"id","type":"string","required":true}]},{"event":"PREFERENCE_DELETED","eventId":"evt_ETABRCXEVGQDR46ND53X4K9N8V","description":"Preference row removed","tier":"secondary","payloadSchema":[{"name":"id","type":"string","required":true}]},{"event":"PREFERENCE_SAVE_FAILED","eventId":"evt_G1MQDDFQ94VMJCY9XEG4AJZ332","description":"Preference persist failed","tier":"secondary","payloadSchema":[{"name":"error","type":"string","required":true}]}],"stateMachine":{"states":[{"name":"idle","isInitial":true}],"events":[{"key":"INIT","id":"evt_KSEC1W3JF2S7H05MM1PXSEQMTB","name":"Initialize"},{"key":"OPEN_SUBSCRIBE","id":"evt_YN990M6AX75EKMP7T414N16ZH9","name":"Open Subscribe"},{"key":"OPEN_DIGEST","id":"evt_6V616VEXANENAZRHZV49765EKV","name":"Open Digest"},{"key":"SAVE_PREFERENCE","id":"evt_3EQG1K8SQ2CVH7FEBBNR3EKG1Y","name":"Save Preference","payloadSchema":[{"name":"eventKey","type":"string"},{"name":"mode","type":"string"},{"name":"channel","type":"string"},{"name":"quietHours","type":"string"}],"listened":true},{"key":"UPDATE_PREFERENCE","id":"evt_JS6T49PD376HKJAX6S5QZNNJ2X","name":"Update Preference","payloadSchema":[{"name":"id","type":"string"},{"name":"eventKey","type":"string"},{"name":"mode","type":"string"},{"name":"channel","type":"string"},{"name":"quietHours","type":"string"}],"listened":true},{"key":"DELETE_PREFERENCE","id":"evt_JZGRDCWK4H9J8T6R3A0Z6TCP01","name":"Delete Preference","payloadSchema":[{"name":"id","type":"string"}],"listened":true},{"key":"PREFERENCE_SAVED","id":"evt_EABFA0HMM4TA2DWFVK5HDGYNHD","name":"Preference Saved","description":"Preference row persisted","tier":"secondary","payloadSchema":[{"name":"id","type":"string","required":true}]},{"key":"PREFERENCE_DELETED","id":"evt_ETABRCXEVGQDR46ND53X4K9N8V","name":"Preference Deleted","description":"Preference row removed","tier":"secondary","payloadSchema":[{"name":"id","type":"string","required":true}]},{"key":"PREFERENCE_SAVE_FAILED","id":"evt_G1MQDDFQ94VMJCY9XEG4AJZ332","name":"Preference Save Failed","description":"Preference persist failed","tier":"secondary","payloadSchema":[{"name":"error","type":"string","required":true}]}],"transitions":[{"from":"idle","to":"idle","event":"INIT","eventId":"evt_KSEC1W3JF2S7H05MM1PXSEQMTB","effects":[["fetch","NotificationPreference"],["render-ui","main",{"type":"stack","direction":"vertical","gap":"md","children":["@trait.PreferenceEditorButtonSubscribe","@trait.PreferenceEditorButtonDigest"]}]]},{"from":"idle","to":"idle","event":"OPEN_SUBSCRIBE","eventId":"evt_YN990M6AX75EKMP7T414N16ZH9","effects":[["navigate","/notifications/subscribe"]]},{"from":"idle","to":"idle","event":"OPEN_DIGEST","eventId":"evt_6V616VEXANENAZRHZV49765EKV","effects":[["navigate","/notifications/digest"]]},{"from":"idle","to":"idle","event":"SAVE_PREFERENCE","eventId":"evt_3EQG1K8SQ2CVH7FEBBNR3EKG1Y","effects":[["persist","create","NotificationPreference",{"channel":"@payload.channel","createdAt":"@now","eventKey":"@payload.eventKey","mode":"@payload.mode","personId":"@user.id","quietHours":"@payload.quietHours","updatedAt":"@now"},{"emit":{"failure":"PREFERENCE_SAVE_FAILED","success":"PREFERENCE_SAVED"}}]]},{"from":"idle","to":"idle","event":"UPDATE_PREFERENCE","eventId":"evt_JS6T49PD376HKJAX6S5QZNNJ2X","effects":[["persist","update","NotificationPreference",{"id":"@payload.id","channel":"@payload.channel","eventKey":"@payload.eventKey","mode":"@payload.mode","quietHours":"@payload.quietHours","updatedAt":"@now"},{"emit":{"failure":"PREFERENCE_SAVE_FAILED","success":"PREFERENCE_SAVED"}}]]},{"from":"idle","to":"idle","event":"DELETE_PREFERENCE","eventId":"evt_JZGRDCWK4H9J8T6R3A0Z6TCP01","effects":[["persist","delete","NotificationPreference","@payload.id",{"emit":{"failure":"PREFERENCE_SAVE_FAILED","success":"PREFERENCE_DELETED"}}]]},{"from":"idle","to":"idle","event":"PREFERENCE_SAVED","eventId":"evt_EABFA0HMM4TA2DWFVK5HDGYNHD","effects":[["render-ui","toast",{"type":"alert","variant":"success","message":"Notification preference saved","dismissible":true}]]},{"from":"idle","to":"idle","event":"PREFERENCE_DELETED","eventId":"evt_ETABRCXEVGQDR46ND53X4K9N8V","effects":[["render-ui","toast",{"type":"alert","variant":"info","message":"Notification preference removed","dismissible":true}]]},{"from":"idle","to":"idle","event":"PREFERENCE_SAVE_FAILED","eventId":"evt_G1MQDDFQ94VMJCY9XEG4AJZ332","effects":[["render-ui","toast",{"type":"alert","variant":"warning","message":"Could not save the notification preference","dismissible":true}]]}]},"scope":"instance"},{"name":"DigestDrain","id":"trt_5X2W3SXQXCVYP32AHS6JS0YEE9","effectRow":[{"kind":"call-service","resource":"email.send"},{"kind":"fetch","resource":"NotificationRecord"},{"kind":"fetch","resource":"NotificationRecord","site":"tick"},{"kind":"persist","resource":"NotificationRecord"},{"kind":"render-ui","resource":"toast"},{"kind":"set","resource":"@entity.drainedCount"},{"kind":"set","resource":"@entity.headId"},{"kind":"set","resource":"@entity.headMessage"},{"kind":"set","resource":"@entity.headRecipient"},{"kind":"set","resource":"@entity.lastError"},{"kind":"ticks","site":"tick"}],"category":"lifecycle","linkedEntity":"DigestRunView","linkedEntityId":"ent_DBFXWY8RGDC86T95F4RG0HDD8R","entityRefIds":{"NotificationRecord":"ent_FMK1JWJGPW8BE3XNDTRY5SPCFA","DigestRunView":"ent_DBFXWY8RGDC86T95F4RG0HDD8R"},"emits":[{"event":"DIGEST_ROWS_LOADED","eventId":"evt_0S7GWCNVT7XX3NNBX64XYAG6AT","description":"Undispatched digest/quiet-hours audit rows past minAgeHours, oldest batch first","tier":"secondary","payloadSchema":[{"name":"data","type":"[object]","properties":[{"name":"id","type":"string"},{"name":"recipient","type":"string"},{"name":"channel","type":"string"},{"name":"message","type":"string"},{"name":"severity","type":"string"},{"name":"dispatched","type":"boolean"},{"name":"error","type":"string"},{"name":"recordedAt","type":"number"}],"entity":"NotifRow"}]},{"event":"DIGEST_ITEM_SENT","eventId":"evt_ZWA78MWCPN6BAJJJP53M8CZPMD","description":"email.send result for the current digest row","tier":"secondary","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"status","type":"string","required":true}]},{"event":"DIGEST_STEPPED","eventId":"evt_0DFRN2S936MHK8TVVWE6X0GCGS","description":"Current row marked dispatched; drives the next loop pass","tier":"secondary","payloadSchema":[{"name":"id","type":"string","required":true}]},{"event":"DIGEST_FAILED","eventId":"evt_9A59DJKXNSYTWVG1WZ84NX5CWK","description":"Digest scan / delivery / persist failed — the cycle stops until the next tick","tier":"secondary","payloadSchema":[{"name":"error","type":"string","required":true}]}],"stateMachine":{"states":[{"name":"idle","isInitial":true},{"name":"draining"}],"events":[{"key":"DIGEST_ROWS_LOADED","id":"evt_0S7GWCNVT7XX3NNBX64XYAG6AT","name":"Digest Rows Loaded","description":"Undispatched digest/quiet-hours audit rows past minAgeHours, oldest batch first","tier":"secondary","payloadSchema":[{"name":"data","type":"[object]","properties":[{"name":"id","type":"string"},{"name":"recipient","type":"string"},{"name":"channel","type":"string"},{"name":"message","type":"string"},{"name":"severity","type":"string"},{"name":"dispatched","type":"boolean"},{"name":"error","type":"string"},{"name":"recordedAt","type":"number"}]}],"listened":true},{"key":"DIGEST_FAILED","id":"evt_9A59DJKXNSYTWVG1WZ84NX5CWK","name":"Digest Failed","description":"Digest scan / delivery / persist failed — the cycle stops until the next tick","tier":"secondary","payloadSchema":[{"name":"error","type":"string","required":true}],"listened":true},{"key":"DIGEST_ITEM_SENT","id":"evt_ZWA78MWCPN6BAJJJP53M8CZPMD","name":"Digest Item Sent","description":"email.send result for the current digest row","tier":"secondary","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"status","type":"string","required":true}],"listened":true},{"key":"DIGEST_STEPPED","id":"evt_0DFRN2S936MHK8TVVWE6X0GCGS","name":"Digest Stepped","description":"Current row marked dispatched; drives the next loop pass","tier":"secondary","payloadSchema":[{"name":"id","type":"string","required":true}],"listened":true}],"transitions":[{"from":"idle","to":"draining","event":"DIGEST_ROWS_LOADED","eventId":"evt_0S7GWCNVT7XX3NNBX64XYAG6AT","guard":["and","@config.digestEnabled",[">",["array/len","@payload.data"],0]],"effects":[["set","@entity.headId",["object/get",["array/first","@payload.data"],"id"]],["set","@entity.headRecipient",["object/get",["array/first","@payload.data"],"recipient"]],["set","@entity.headMessage",["object/get",["array/first","@payload.data"],"message"]],["call-service","email","send",{"body":"@entity.headMessage","from":"","subject":"@config.digestSubject","to":"@entity.headRecipient"},{"emit":{"failure":"DIGEST_FAILED","success":"DIGEST_ITEM_SENT"}}]]},{"from":"idle","to":"idle","event":"DIGEST_ROWS_LOADED","eventId":"evt_0S7GWCNVT7XX3NNBX64XYAG6AT","guard":["=",["array/len","@payload.data"],0]},{"from":"idle","to":"idle","event":"DIGEST_FAILED","eventId":"evt_9A59DJKXNSYTWVG1WZ84NX5CWK","effects":[["set","@entity.lastError","@payload.error"],["render-ui","toast",{"type":"alert","variant":"error","message":["str/concat","Couldn't send the notification digest — ","@payload.error"],"dismissible":true}]]},{"from":"draining","to":"draining","event":"DIGEST_ITEM_SENT","eventId":"evt_ZWA78MWCPN6BAJJJP53M8CZPMD","effects":[["set","@entity.drainedCount",["+","@entity.drainedCount",1]],["persist","update","NotificationRecord",{"id":"@entity.headId","dispatched":true},{"emit":{"failure":"DIGEST_FAILED","success":"DIGEST_STEPPED"}}]]},{"from":"draining","to":"draining","event":"DIGEST_STEPPED","eventId":"evt_0DFRN2S936MHK8TVVWE6X0GCGS","effects":[["fetch","NotificationRecord",{"emit":{"failure":"DIGEST_FAILED","success":"DIGEST_ROWS_LOADED"},"filter":["and",["=",["object/get","@entity","dispatched"],false],["or",["=",["object/get","@entity","error"],"digest-deferred"],["=",["object/get","@entity","error"],"quiet-hours"]],["<",["object/get","@entity","recordedAt"],["-","@now",["*","@config.minAgeHours",3600000]]]]}]]},{"from":"draining","to":"draining","event":"DIGEST_ROWS_LOADED","eventId":"evt_0S7GWCNVT7XX3NNBX64XYAG6AT","guard":[">",["array/len","@payload.data"],0],"effects":[["set","@entity.headId",["object/get",["array/first","@payload.data"],"id"]],["set","@entity.headRecipient",["object/get",["array/first","@payload.data"],"recipient"]],["set","@entity.headMessage",["object/get",["array/first","@payload.data"],"message"]],["call-service","email","send",{"body":"@entity.headMessage","from":"","subject":"@config.digestSubject","to":"@entity.headRecipient"},{"emit":{"failure":"DIGEST_FAILED","success":"DIGEST_ITEM_SENT"}}]]},{"from":"draining","to":"idle","event":"DIGEST_ROWS_LOADED","eventId":"evt_0S7GWCNVT7XX3NNBX64XYAG6AT","guard":["=",["array/len","@payload.data"],0]},{"from":"draining","to":"idle","event":"DIGEST_FAILED","eventId":"evt_9A59DJKXNSYTWVG1WZ84NX5CWK","effects":[["set","@entity.lastError","@payload.error"],["render-ui","toast",{"type":"alert","variant":"error","message":["str/concat","Couldn't send the notification digest — ","@payload.error"],"dismissible":true}]]}]},"ticks":[{"name":"digestCycle","interval":"0 * * * *","effects":[["fetch","NotificationRecord",{"emit":{"failure":"DIGEST_FAILED","success":"DIGEST_ROWS_LOADED"},"filter":["and",["=",["object/get","@entity","dispatched"],false],["or",["=",["object/get","@entity","error"],"digest-deferred"],["=",["object/get","@entity","error"],"quiet-hours"]],["<",["object/get","@entity","recordedAt"],["-","@now",["*","@config.minAgeHours",3600000]]]]}]],"runsInBackground":true}],"config":{"digestSubject":{"type":"string","default":"Notification digest","label":"Digest email subject","description":"Subject line for drained digest deliveries.","synonyms":"digest title, summary subject, email subject","tier":"presentation"},"minAgeHours":{"type":"number","default":1,"label":"Minimum age (hours)","description":"Only drain audit rows at least this many hours old, so quiet-hours suppressions are not redelivered inside their window.","synonyms":"delay, drain delay, hold for, batch window","tier":"infra"},"digestEnabled":{"type":"boolean","default":false,"label":"Deliver digests","description":"Drain suppressed notifications (digest-deferred and quiet-hours audit rows) on the hourly cycle. Off by default.","synonyms":"enable digest, digest mode, batch notifications, daily summary, drain suppressed","tier":"infra"}},"scope":"instance"}],"pages":[{"name":"NotificationPreferencesPage","id":"pag_VKQFW1D1GPGRB94S1T6VV0V8VN","path":"/notifications/preferences","traits":[{"ref":"PreferenceEditor","refId":"trt_WE0GEX3SSNWWTQZARWCHC54WG1"},{"ref":"PreferenceEditorButtonSubscribe","refId":"trt_ECT5YP16VDKDPSJVZKHG7RAGJJ"},{"ref":"PreferenceEditorButtonDigest","refId":"trt_NASW4TMBG95R4P7MF2KSWDSDGS"}]},{"name":"PushSubscribePage","id":"pag_ZC96H4NF3MQHTF08P3AGC73TNK","path":"/notifications/subscribe","traits":[{"ref":"PushSubscriber","refId":"trt_FSVH6CVH0HRG8Z80X8JNESK8C6"}]},{"name":"NotificationDigestPage","id":"pag_CKB79DYPGWB8E36MH5PB83EEK1","path":"/notifications/digest","traits":[{"ref":"DigestDrain","refId":"trt_5X2W3SXQXCVYP32AHS6JS0YEE9"}]}],"types":{"NotifRow":[{"name":"id","type":"string"},{"name":"recipient","type":"string"},{"name":"channel","type":"string"},{"name":"message","type":"string"},{"name":"severity","type":"string"},{"name":"dispatched","type":"boolean"},{"name":"error","type":"string"},{"name":"recordedAt","type":"number"}],"PushCreds":[{"name":"endpoint","type":"string"},{"name":"p256dh","type":"string"},{"name":"auth","type":"string"}]}}],"schemaVersion":1,"ledger":{"schemaVersion":1,"entries":{"ent_9SFC0KCE6M73AB0CQWSWX8NTYX":{"id":"ent_9SFC0KCE6M73AB0CQWSWX8NTYX","kind":"entity","bakedName":"NotificationPreference","curName":"NotificationPreference","renames":[],"owner":"workspace"},"ent_DBFXWY8RGDC86T95F4RG0HDD8R":{"id":"ent_DBFXWY8RGDC86T95F4RG0HDD8R","kind":"entity","bakedName":"DigestRunView","curName":"DigestRunView","renames":[],"owner":"workspace"},"ent_FMK1JWJGPW8BE3XNDTRY5SPCFA":{"id":"ent_FMK1JWJGPW8BE3XNDTRY5SPCFA","kind":"entity","bakedName":"NotificationRecord","curName":"NotificationRecord","renames":[],"owner":"workspace"},"ent_KEFWKMB0F6G7KDEHSF7QYPNGR0":{"id":"ent_KEFWKMB0F6G7KDEHSF7QYPNGR0","kind":"entity","bakedName":"PushSubscription","curName":"PushSubscription","renames":[],"owner":"workspace"},"evt_02FYV6VPY8VF42SDDY7XMTT2Z7":{"id":"evt_02FYV6VPY8VF42SDDY7XMTT2Z7","kind":"event","bakedName":"PUSH_SAVED","curName":"PUSH_SAVED","renames":[],"owner":"workspace","parent":"trt_FSVH6CVH0HRG8Z80X8JNESK8C6"},"evt_0DFRN2S936MHK8TVVWE6X0GCGS":{"id":"evt_0DFRN2S936MHK8TVVWE6X0GCGS","kind":"event","bakedName":"DIGEST_STEPPED","curName":"DIGEST_STEPPED","renames":[],"owner":"workspace","parent":"trt_5X2W3SXQXCVYP32AHS6JS0YEE9"},"evt_0S7GWCNVT7XX3NNBX64XYAG6AT":{"id":"evt_0S7GWCNVT7XX3NNBX64XYAG6AT","kind":"event","bakedName":"DIGEST_ROWS_LOADED","curName":"DIGEST_ROWS_LOADED","renames":[],"owner":"workspace","parent":"trt_5X2W3SXQXCVYP32AHS6JS0YEE9"},"evt_3EQG1K8SQ2CVH7FEBBNR3EKG1Y":{"id":"evt_3EQG1K8SQ2CVH7FEBBNR3EKG1Y","kind":"event","bakedName":"SAVE_PREFERENCE","curName":"SAVE_PREFERENCE","renames":[],"owner":"workspace","parent":"trt_WE0GEX3SSNWWTQZARWCHC54WG1"},"evt_6V616VEXANENAZRHZV49765EKV":{"id":"evt_6V616VEXANENAZRHZV49765EKV","kind":"event","bakedName":"OPEN_DIGEST","curName":"OPEN_DIGEST","renames":[],"owner":"workspace","parent":"trt_WE0GEX3SSNWWTQZARWCHC54WG1"},"evt_9A59DJKXNSYTWVG1WZ84NX5CWK":{"id":"evt_9A59DJKXNSYTWVG1WZ84NX5CWK","kind":"event","bakedName":"DIGEST_FAILED","curName":"DIGEST_FAILED","renames":[],"owner":"workspace","parent":"trt_5X2W3SXQXCVYP32AHS6JS0YEE9"},"evt_B4FRJE2Z2KFH9YW4SGYQ8TAKYN":{"id":"evt_B4FRJE2Z2KFH9YW4SGYQ8TAKYN","kind":"event","bakedName":"SUBSCRIBE_PUSH","curName":"SUBSCRIBE_PUSH","renames":[],"owner":"workspace","parent":"trt_FSVH6CVH0HRG8Z80X8JNESK8C6"},"evt_BJHQT1N5MTJTDAZERH3GP9SWF9":{"id":"evt_BJHQT1N5MTJTDAZERH3GP9SWF9","kind":"event","bakedName":"PUSH_SUBSCRIBE_FAILED","curName":"PUSH_SUBSCRIBE_FAILED","renames":[],"owner":"workspace","parent":"trt_FSVH6CVH0HRG8Z80X8JNESK8C6"},"evt_EABFA0HMM4TA2DWFVK5HDGYNHD":{"id":"evt_EABFA0HMM4TA2DWFVK5HDGYNHD","kind":"event","bakedName":"PREFERENCE_SAVED","curName":"PREFERENCE_SAVED","renames":[],"owner":"workspace","parent":"trt_WE0GEX3SSNWWTQZARWCHC54WG1"},"evt_ETABRCXEVGQDR46ND53X4K9N8V":{"id":"evt_ETABRCXEVGQDR46ND53X4K9N8V","kind":"event","bakedName":"PREFERENCE_DELETED","curName":"PREFERENCE_DELETED","renames":[],"owner":"workspace","parent":"trt_WE0GEX3SSNWWTQZARWCHC54WG1"},"evt_G1MQDDFQ94VMJCY9XEG4AJZ332":{"id":"evt_G1MQDDFQ94VMJCY9XEG4AJZ332","kind":"event","bakedName":"PREFERENCE_SAVE_FAILED","curName":"PREFERENCE_SAVE_FAILED","renames":[],"owner":"workspace","parent":"trt_WE0GEX3SSNWWTQZARWCHC54WG1"},"evt_JS6T49PD376HKJAX6S5QZNNJ2X":{"id":"evt_JS6T49PD376HKJAX6S5QZNNJ2X","kind":"event","bakedName":"UPDATE_PREFERENCE","curName":"UPDATE_PREFERENCE","renames":[],"owner":"workspace","parent":"trt_WE0GEX3SSNWWTQZARWCHC54WG1"},"evt_JZGRDCWK4H9J8T6R3A0Z6TCP01":{"id":"evt_JZGRDCWK4H9J8T6R3A0Z6TCP01","kind":"event","bakedName":"DELETE_PREFERENCE","curName":"DELETE_PREFERENCE","renames":[],"owner":"workspace","parent":"trt_WE0GEX3SSNWWTQZARWCHC54WG1"},"evt_KSEC1W3JF2S7H05MM1PXSEQMTB":{"id":"evt_KSEC1W3JF2S7H05MM1PXSEQMTB","kind":"event","bakedName":"INIT","curName":"INIT","renames":[],"owner":"workspace","parent":"trt_WE0GEX3SSNWWTQZARWCHC54WG1"},"evt_XBWMRCYPTFBD7W3E14AEKGW7RB":{"id":"evt_XBWMRCYPTFBD7W3E14AEKGW7RB","kind":"event","bakedName":"PUSH_SUBSCRIBED","curName":"PUSH_SUBSCRIBED","renames":[],"owner":"workspace","parent":"trt_FSVH6CVH0HRG8Z80X8JNESK8C6"},"evt_XMPZH31MBKT5SW1GT8EX0REXJK":{"id":"evt_XMPZH31MBKT5SW1GT8EX0REXJK","kind":"event","bakedName":"PUSH_SAVE_FAILED","curName":"PUSH_SAVE_FAILED","renames":[],"owner":"workspace","parent":"trt_FSVH6CVH0HRG8Z80X8JNESK8C6"},"evt_YN990M6AX75EKMP7T414N16ZH9":{"id":"evt_YN990M6AX75EKMP7T414N16ZH9","kind":"event","bakedName":"OPEN_SUBSCRIBE","curName":"OPEN_SUBSCRIBE","renames":[],"owner":"workspace","parent":"trt_WE0GEX3SSNWWTQZARWCHC54WG1"},"evt_ZWA78MWCPN6BAJJJP53M8CZPMD":{"id":"evt_ZWA78MWCPN6BAJJJP53M8CZPMD","kind":"event","bakedName":"DIGEST_ITEM_SENT","curName":"DIGEST_ITEM_SENT","renames":[],"owner":"workspace","parent":"trt_5X2W3SXQXCVYP32AHS6JS0YEE9"},"orb_VQBZ2YWY5WF2Y8S3JJE6BQNW4C":{"id":"orb_VQBZ2YWY5WF2Y8S3JJE6BQNW4C","kind":"orbital","bakedName":"NotificationCenterOrbital","curName":"NotificationCenterOrbital","renames":[],"owner":"workspace"},"pag_CKB79DYPGWB8E36MH5PB83EEK1":{"id":"pag_CKB79DYPGWB8E36MH5PB83EEK1","kind":"page","bakedName":"NotificationDigestPage","curName":"NotificationDigestPage","renames":[],"owner":"workspace"},"pag_VKQFW1D1GPGRB94S1T6VV0V8VN":{"id":"pag_VKQFW1D1GPGRB94S1T6VV0V8VN","kind":"page","bakedName":"NotificationPreferencesPage","curName":"NotificationPreferencesPage","renames":[],"owner":"workspace"},"pag_ZC96H4NF3MQHTF08P3AGC73TNK":{"id":"pag_ZC96H4NF3MQHTF08P3AGC73TNK","kind":"page","bakedName":"PushSubscribePage","curName":"PushSubscribePage","renames":[],"owner":"workspace"},"trt_5X2W3SXQXCVYP32AHS6JS0YEE9":{"id":"trt_5X2W3SXQXCVYP32AHS6JS0YEE9","kind":"trait","bakedName":"DigestDrain","curName":"DigestDrain","renames":[],"owner":"workspace"},"trt_ECT5YP16VDKDPSJVZKHG7RAGJJ":{"id":"trt_ECT5YP16VDKDPSJVZKHG7RAGJJ","kind":"trait","bakedName":"PreferenceEditorButtonSubscribe","curName":"PreferenceEditorButtonSubscribe","renames":[],"owner":"workspace"},"trt_FSVH6CVH0HRG8Z80X8JNESK8C6":{"id":"trt_FSVH6CVH0HRG8Z80X8JNESK8C6","kind":"trait","bakedName":"PushSubscriber","curName":"PushSubscriber","renames":[],"owner":"workspace"},"trt_NASW4TMBG95R4P7MF2KSWDSDGS":{"id":"trt_NASW4TMBG95R4P7MF2KSWDSDGS","kind":"trait","bakedName":"PreferenceEditorButtonDigest","curName":"PreferenceEditorButtonDigest","renames":[],"owner":"workspace"},"trt_WE0GEX3SSNWWTQZARWCHC54WG1":{"id":"trt_WE0GEX3SSNWWTQZARWCHC54WG1","kind":"trait","bakedName":"PreferenceEditor","curName":"PreferenceEditor","renames":[],"owner":"workspace"}}}}
@@ -1 +1 @@
1
- {"name":"std-notification-preferences","version":"1.0.0","description":"std-notification-preferences — per-person notification preference store plus a consultable gate. Owns NotificationPreference rows (one per person + event key: channel override in_app/email/push/slack/sms/webhook, mode instant/digest/off, quiet-hours window 'HH:MM-HH:MM' such as 22:00-07:00). The PreferencesManage trait is standard CRUD over the store (list / create / update / delete, persisted, success/failure cascade arms): a data-grid browse plus ModalRecordModal create/edit forms whose SAVE carries the full row payload (std-list daisy-chain idiom). The PreferenceGate trait is the consult half other notify traits call: emit CHECK_PREFERENCE { personId, eventKey } and the gate fetches the matching row (a row whose eventKey is blank applies to every event) and answers PREFERENCE_RESOLVED { personId, eventKey, channel, mode, suppressed } — suppressed is true only when the row's quietHours window covers the current hour; mode 'digest' rides on the verdict for the caller to defer. Default policy: no matching row — or a failed lookup — resolves fail-open to { channel: in_app, mode: instant, suppressed: false }; the absence of a preference never silences a notification.","orbitals":[{"name":"NotificationPreferencesOrbital","id":"orb_NY862D5QC2VP19PHB5CKGQH8F5","uses":[{"from":"std/behaviors/std-modal","as":"Modal"}],"entity":{"name":"NotificationPreference","id":"ent_9XXV1AFA93N4HQM643KWYXGVCQ","collection":"notificationPreferences","persistence":"persistent","fields":[{"name":"id","type":"string","required":true},{"name":"personId","type":"string","required":true,"description":"The person this preference row belongs to.","synonyms":"user, recipient, owner, account"},{"name":"eventKey","type":"string","default":"","description":"Event key this preference applies to (matches a notify listener's eventKey); blank = all events.","synonyms":"event, trigger, topic, subscription"},{"name":"channel","type":"string","default":"in_app","values":["in_app","email","push","slack","sms","webhook"],"description":"Delivery channel override for this person.","synonyms":"preferred channel, delivery method"},{"name":"mode","type":"string","default":"instant","values":["instant","digest","off"],"description":"Delivery mode: instant (default), digest (deferred to a batch cycle), or off (muted).","synonyms":"delivery mode, frequency, cadence, mute, defer"},{"name":"quietHours","type":"string","default":"","description":"Quiet-hours window as \"HH:MM-HH:MM\" (e.g. 22:00-07:00); blank or equal start/end = disabled.","synonyms":"do not disturb, quiet window, night mode"},{"name":"createdAt","type":"number","default":0,"description":"Timestamp indicating when this preference row was created.","synonyms":"creation time, created"},{"name":"updatedAt","type":"number","default":0,"description":"Timestamp indicating when this preference row was last updated.","synonyms":"modified, last updated"}]},"auxiliaryEntities":[{"name":"GateView","id":"ent_1C83HNBAWSNECQZAW3M95G502V","persistence":"runtime","fields":[{"name":"id","type":"string","required":true},{"name":"personId","type":"string","default":"","description":"Scratch: personId of the consult currently in flight.","synonyms":"current person"},{"name":"eventKey","type":"string","default":"","description":"Scratch: effective event key of the consult currently in flight (payload eventKey, or the configured eventKey when the payload is blank).","synonyms":"current event key"},{"name":"channel","type":"string","default":"","description":"Scratch: resolved channel for the current consult.","synonyms":"resolved channel"},{"name":"mode","type":"string","default":"","description":"Scratch: resolved delivery mode for the current consult.","synonyms":"resolved mode"},{"name":"quietHours","type":"string","default":"","description":"Scratch: quiet-hours window of the matched row for the current consult; blank = none.","synonyms":"resolved quiet hours"}]}],"traits":[{"name":"PreferencesManage","id":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6","effectRow":[{"kind":"fetch","resource":"NotificationPreference"},{"kind":"persist","resource":"NotificationPreference"},{"kind":"render-ui","resource":"main"},{"kind":"render-ui","resource":"toast"}],"category":"interaction","linkedEntity":"NotificationPreference","linkedEntityId":"ent_9XXV1AFA93N4HQM643KWYXGVCQ","entityRefIds":{"NotificationPreference":"ent_9XXV1AFA93N4HQM643KWYXGVCQ"},"emits":[{"event":"CREATE","eventId":"evt_QW6JNB276X3KEQ4BNT5WB754A3","description":"Opens the blank preference modal.","synonyms":"add, new, insert","tier":"domain"},{"event":"EDIT","eventId":"evt_DAJMYWXBYANZ57Z1W1J5C3BM4V","description":"Opens a preference row in the edit modal.","synonyms":"modify, update, change","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"row","type":"object","properties":[{"name":"id","type":"string","required":true},{"name":"personId","type":"string","required":true},{"name":"eventKey","type":"string"},{"name":"channel","type":"string","values":["in_app","email","push","slack","sms","webhook"]},{"name":"mode","type":"string","values":["instant","digest","off"]},{"name":"quietHours","type":"string"},{"name":"createdAt","type":"number"},{"name":"updatedAt","type":"number"}],"entity":"NotificationPreference"}]},{"event":"DELETE","eventId":"evt_HF6KA8J0V10DGX5HMWW7WAEPC9","description":"Removes a preference row.","synonyms":"remove, discard, clear","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"row","type":"object","properties":[{"name":"id","type":"string","required":true},{"name":"personId","type":"string","required":true},{"name":"eventKey","type":"string"},{"name":"channel","type":"string","values":["in_app","email","push","slack","sms","webhook"]},{"name":"mode","type":"string","values":["instant","digest","off"]},{"name":"quietHours","type":"string"},{"name":"createdAt","type":"number"},{"name":"updatedAt","type":"number"}],"entity":"NotificationPreference"}]},{"event":"PreferencesLoaded","eventId":"evt_XF6P2M2MMWAAE0R2MZVSP9WJE4","description":"The preference collection finished loading.","synonyms":"loaded, fetched, retrieved","tier":"internal","payloadSchema":[{"name":"data","type":"[object]","properties":[{"name":"id","type":"string","required":true},{"name":"personId","type":"string","required":true},{"name":"eventKey","type":"string"},{"name":"channel","type":"string","values":["in_app","email","push","slack","sms","webhook"]},{"name":"mode","type":"string","values":["instant","digest","off"]},{"name":"quietHours","type":"string"},{"name":"createdAt","type":"number"},{"name":"updatedAt","type":"number"}],"entity":"NotificationPreference"}]},{"event":"PreferencesLoadFailed","eventId":"evt_KBVBFG78TZMDFW4K2SBYR69RTY","description":"The preference collection failed to load.","synonyms":"error, failure, load error","tier":"internal","payloadSchema":[{"name":"error","type":"string"},{"name":"code","type":"string"}]},{"event":"PreferenceSaved","eventId":"evt_93DE8SY3YA1Z57W1PEPZ7HP8MM","description":"A preference row persisted (create or update).","synonyms":"created, updated, persisted","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true}]},{"event":"PreferenceSaveFailed","eventId":"evt_5GXQHQDMT4TD288ZZFRRZBXRA0","description":"A preference persist failed.","synonyms":"failed, error, unsuccessful","tier":"internal","payloadSchema":[{"name":"error","type":"string"},{"name":"code","type":"string"}]},{"event":"PreferenceDeleted","eventId":"evt_GTAPK71SV3WXHT3H6FKF9BHRM7","description":"A preference row was deleted.","synonyms":"removed, purged, discarded","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true}]}],"listens":[{"event":"PREFERENCE_CREATED","triggers":"DO_CREATE","triggersId":"evt_ACVDGSM8CA465B22X38EKHR52A","source":{"kind":"trait","trait":"PreferenceCreate","traitId":"trt_DDXED3J0X50EJSSVHE251PQMSF"}},{"event":"PREFERENCE_UPDATED","triggers":"DO_UPDATE","triggersId":"evt_P1ASTZKBS8NWMCEFB5PAY3Y362","source":{"kind":"trait","trait":"PreferenceEdit","traitId":"trt_FKR1971TV5XDJX6VJN4KBC9ST9"}}],"stateMachine":{"states":[{"name":"loading","isInitial":true},{"name":"browsing"},{"name":"error"}],"events":[{"key":"INIT","id":"evt_7R59HX8RR1CC0XEY97RGY3NQ3C","name":"Initialize"},{"key":"PreferencesLoaded","id":"evt_XF6P2M2MMWAAE0R2MZVSP9WJE4","name":"Preferences loaded","description":"The preference collection finished loading.","synonyms":"loaded, fetched, retrieved","tier":"internal","payloadSchema":[{"name":"data","type":"[object]","properties":[{"name":"id","type":"string","required":true},{"name":"personId","type":"string","required":true},{"name":"eventKey","type":"string"},{"name":"channel","type":"string","values":["in_app","email","push","slack","sms","webhook"]},{"name":"mode","type":"string","values":["instant","digest","off"]},{"name":"quietHours","type":"string"},{"name":"createdAt","type":"number"},{"name":"updatedAt","type":"number"}],"entity":"NotificationPreference"}],"listened":true},{"key":"PreferencesLoadFailed","id":"evt_KBVBFG78TZMDFW4K2SBYR69RTY","name":"Preferences load failed","description":"The preference collection failed to load.","synonyms":"error, failure, load error","tier":"internal","payloadSchema":[{"name":"error","type":"string"},{"name":"code","type":"string"}],"listened":true},{"key":"DELETE","id":"evt_HF6KA8J0V10DGX5HMWW7WAEPC9","name":"Delete","description":"Removes a preference row.","synonyms":"remove, discard, clear","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"row","type":"object","properties":[{"name":"id","type":"string","required":true},{"name":"personId","type":"string","required":true},{"name":"eventKey","type":"string"},{"name":"channel","type":"string","values":["in_app","email","push","slack","sms","webhook"]},{"name":"mode","type":"string","values":["instant","digest","off"]},{"name":"quietHours","type":"string"},{"name":"createdAt","type":"number"},{"name":"updatedAt","type":"number"}],"entity":"NotificationPreference"}],"listened":true},{"key":"DO_CREATE","id":"evt_ACVDGSM8CA465B22X38EKHR52A","name":"Do Create","description":"Create persist requested; the modal's SAVE payload carries the full form row.","synonyms":"add, new, insert","tier":"internal","payloadSchema":[{"name":"data","type":"object","required":true,"properties":[{"name":"id","type":"string","required":true},{"name":"personId","type":"string","required":true},{"name":"eventKey","type":"string"},{"name":"channel","type":"string","values":["in_app","email","push","slack","sms","webhook"]},{"name":"mode","type":"string","values":["instant","digest","off"]},{"name":"quietHours","type":"string"},{"name":"createdAt","type":"number"},{"name":"updatedAt","type":"number"}],"entity":"NotificationPreference"}],"listened":true},{"key":"DO_UPDATE","id":"evt_P1ASTZKBS8NWMCEFB5PAY3Y362","name":"Do Update","description":"Update persist requested; the modal's SAVE payload carries the full form row.","synonyms":"modified, changed, refreshed","tier":"internal","payloadSchema":[{"name":"data","type":"object","required":true,"properties":[{"name":"id","type":"string","required":true},{"name":"personId","type":"string","required":true},{"name":"eventKey","type":"string"},{"name":"channel","type":"string","values":["in_app","email","push","slack","sms","webhook"]},{"name":"mode","type":"string","values":["instant","digest","off"]},{"name":"quietHours","type":"string"},{"name":"createdAt","type":"number"},{"name":"updatedAt","type":"number"}],"entity":"NotificationPreference"}],"listened":true},{"key":"PreferenceSaved","id":"evt_93DE8SY3YA1Z57W1PEPZ7HP8MM","name":"Preference saved","description":"A preference row persisted (create or update).","synonyms":"created, updated, persisted","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true}],"listened":true},{"key":"PreferenceDeleted","id":"evt_GTAPK71SV3WXHT3H6FKF9BHRM7","name":"Preference deleted","description":"A preference row was deleted.","synonyms":"removed, purged, discarded","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true}],"listened":true},{"key":"PreferenceSaveFailed","id":"evt_5GXQHQDMT4TD288ZZFRRZBXRA0","name":"Preference save failed","description":"A preference persist failed.","synonyms":"failed, error, unsuccessful","tier":"internal","payloadSchema":[{"name":"error","type":"string"},{"name":"code","type":"string"}],"listened":true},{"key":"RETRY","id":"evt_9AJYN9CVH8DRMEPKPB0PVPF6F1","name":"Retry","description":"Retries loading the preference collection after a failure.","synonyms":"try again, reload","tier":"presentation","listened":true},{"key":"CREATE","id":"evt_QW6JNB276X3KEQ4BNT5WB754A3","name":"Create","description":"Opens the blank preference modal.","synonyms":"add, new, insert","tier":"domain"},{"key":"EDIT","id":"evt_DAJMYWXBYANZ57Z1W1J5C3BM4V","name":"Edit","description":"Opens a preference row in the edit modal.","synonyms":"modify, update, change","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"row","type":"object","properties":[{"name":"id","type":"string","required":true},{"name":"personId","type":"string","required":true},{"name":"eventKey","type":"string"},{"name":"channel","type":"string","values":["in_app","email","push","slack","sms","webhook"]},{"name":"mode","type":"string","values":["instant","digest","off"]},{"name":"quietHours","type":"string"},{"name":"createdAt","type":"number"},{"name":"updatedAt","type":"number"}],"entity":"NotificationPreference"}]}],"transitions":[{"from":"loading","to":"loading","event":"INIT","eventId":"evt_7R59HX8RR1CC0XEY97RGY3NQ3C","effects":[["fetch","NotificationPreference",{"emit":{"failure":"PreferencesLoadFailed","success":"PreferencesLoaded"}}],["render-ui","main",{"type":"stack","direction":"vertical","gap":"lg","children":[{"type":"skeleton","variant":"header"},{"type":"skeleton","variant":"grid","rows":6}]}]]},{"from":"loading","to":"browsing","event":"PreferencesLoaded","eventId":"evt_XF6P2M2MMWAAE0R2MZVSP9WJE4","effects":[["render-ui","main",{"children":[{"children":[{"children":[{"name":"bell","size":"lg","type":"icon"},{"content":"@config.title","type":"typography","variant":"h3"}],"direction":"horizontal","gap":"sm","type":"stack"},{"action":"CREATE","icon":"plus","label":"New preference","type":"button","variant":"primary"}],"direction":"horizontal","gap":"sm","justify":"between","type":"stack"},{"type":"divider"},{"cols":1,"entity":"@payload.data","fields":[{"label":"Person","name":"personId","variant":"h4"},{"label":"Event","name":"eventKey","variant":"caption"},{"label":"Channel","name":"channel","variant":"badge"},{"label":"Mode","name":"mode","variant":"badge"},{"label":"Quiet hours","name":"quietHours","variant":"caption"}],"gap":"sm","itemClickEvent":"@config.itemClickEvent","itemActions":["array/filter","@config.itemActions",["fn","action",["or",["=",["array/len",["object/get","@action","roles",[]]],0],["array/includes",["object/get","@action","roles",[]],"@config.viewerRole"]]]],"look":"@config.tableLook","type":"data-grid"}],"direction":"vertical","gap":"md","type":"stack"}]]},{"from":"loading","to":"error","event":"PreferencesLoadFailed","eventId":"evt_KBVBFG78TZMDFW4K2SBYR69RTY","effects":[["render-ui","main",{"align":"center","children":[{"message":"@payload.error","type":"alert","variant":"error"},{"action":"RETRY","icon":"rotate-ccw","label":"Retry","type":"button","variant":"primary"}],"className":"py-12","direction":"vertical","gap":"md","type":"stack"}]]},{"from":"browsing","to":"loading","event":"INIT","eventId":"evt_7R59HX8RR1CC0XEY97RGY3NQ3C","effects":[["fetch","NotificationPreference",{"emit":{"failure":"PreferencesLoadFailed","success":"PreferencesLoaded"}}],["render-ui","main",{"type":"stack","direction":"vertical","gap":"lg","children":[{"type":"skeleton","variant":"header"},{"type":"skeleton","variant":"grid","rows":6}]}]]},{"from":"browsing","to":"browsing","event":"DELETE","eventId":"evt_HF6KA8J0V10DGX5HMWW7WAEPC9","effects":[["persist","delete","NotificationPreference","@payload.id",{"emit":{"failure":"PreferenceSaveFailed","success":"PreferenceDeleted"}}]]},{"from":"browsing","to":"browsing","event":"DO_CREATE","eventId":"evt_ACVDGSM8CA465B22X38EKHR52A","effects":[["persist","create","NotificationPreference","@payload.data",{"emit":{"failure":"PreferenceSaveFailed","success":"PreferenceSaved"}}]]},{"from":"browsing","to":"browsing","event":"DO_UPDATE","eventId":"evt_P1ASTZKBS8NWMCEFB5PAY3Y362","effects":[["persist","update","NotificationPreference","@payload.data",{"emit":{"failure":"PreferenceSaveFailed","success":"PreferenceSaved"}}]]},{"from":"browsing","to":"loading","event":"PreferenceSaved","eventId":"evt_93DE8SY3YA1Z57W1PEPZ7HP8MM","effects":[["render-ui","toast",{"type":"alert","variant":"success","message":"Notification preference saved","dismissible":true}],["fetch","NotificationPreference",{"emit":{"failure":"PreferencesLoadFailed","success":"PreferencesLoaded"}}]]},{"from":"browsing","to":"loading","event":"PreferenceDeleted","eventId":"evt_GTAPK71SV3WXHT3H6FKF9BHRM7","effects":[["render-ui","toast",{"type":"alert","variant":"info","message":"Notification preference removed","dismissible":true}],["fetch","NotificationPreference",{"emit":{"failure":"PreferencesLoadFailed","success":"PreferencesLoaded"}}]]},{"from":"browsing","to":"browsing","event":"PreferenceSaveFailed","eventId":"evt_5GXQHQDMT4TD288ZZFRRZBXRA0","effects":[["render-ui","toast",{"type":"alert","variant":"warning","message":"Could not save the notification preference","dismissible":true}]]},{"from":"browsing","to":"error","event":"PreferencesLoadFailed","eventId":"evt_KBVBFG78TZMDFW4K2SBYR69RTY","effects":[["render-ui","main",{"align":"center","children":[{"message":"@payload.error","type":"alert","variant":"error"},{"action":"RETRY","icon":"rotate-ccw","label":"Retry","type":"button","variant":"primary"}],"className":"py-12","direction":"vertical","gap":"md","type":"stack"}]]},{"from":"error","to":"loading","event":"INIT","eventId":"evt_7R59HX8RR1CC0XEY97RGY3NQ3C","effects":[["fetch","NotificationPreference",{"emit":{"failure":"PreferencesLoadFailed","success":"PreferencesLoaded"}}],["render-ui","main",{"type":"stack","direction":"vertical","gap":"lg","children":[{"type":"skeleton","variant":"header"},{"type":"skeleton","variant":"grid","rows":6}]}]]},{"from":"error","to":"loading","event":"RETRY","eventId":"evt_9AJYN9CVH8DRMEPKPB0PVPF6F1","effects":[["fetch","NotificationPreference",{"emit":{"failure":"PreferencesLoadFailed","success":"PreferencesLoaded"}}],["render-ui","main",{"type":"stack","direction":"vertical","gap":"lg","children":[{"type":"skeleton","variant":"header"},{"type":"skeleton","variant":"grid","rows":6}]}]]}]},"config":{"viewerRole":{"type":"string","default":"","label":"Viewer's role","description":"The signed-in viewer's role that each action's `roles` is checked against. Bind it explicitly at the call site (e.g. `viewerRole: @user.role`) in an app whose identity carries a role; left empty, only actions with no `roles` show.","tier":"policy"},"itemClickEvent":{"type":"event","default":"EDIT","label":"Row click","description":"Event emitted when a row is clicked; opens the preference for editing. Empty disables the row click.","tier":"presentation","refId":"evt_DAJMYWXBYANZ57Z1W1J5C3BM4V"},"itemActions":{"type":"[ItemAction]","default":[{"event":"EDIT","icon":"pencil","label":"Edit","variant":"secondary"},{"event":"DELETE","icon":"trash-2","label":"Delete","variant":"danger"}],"label":"Row actions","description":"Actions offered on each row; give an item `roles` to show it only to those viewer roles.","tier":"presentation","items":{"type":"object","properties":{"label":{"name":"label","type":"string","required":true},"event":{"name":"event","type":"event","required":false},"roles":{"name":"roles","type":"array","required":false,"items":{"type":"string"}},"icon":{"name":"icon","type":"string","required":false},"variant":{"name":"variant","type":"string","required":false},"when":{"name":"when","type":"SExpr","required":false}}}},"tableLook":{"type":"string","default":"dense","label":"Table look","description":"Layer 2 visual treatment for the preference data table rendered by this atom.","tier":"presentation","values":["dense","spacious","striped","borderless","card-rows"]},"title":{"type":"string","default":"Notification preferences","label":"Section title","description":"Heading shown above the preference list","tier":"presentation"}},"scope":"collection"},{"ref":"Modal.traits.ModalRecordModal","id":"trt_DDXED3J0X50EJSSVHE251PQMSF","name":"PreferenceCreate","linkedEntity":"NotificationPreference","linkedEntityId":"ent_9XXV1AFA93N4HQM643KWYXGVCQ","config":{"fields":{"type":"unknown","default":["personId","eventKey","channel","mode","quietHours"]},"title":{"type":"unknown","default":"New notification preference"},"mode":{"type":"unknown","default":"create"},"icon":{"type":"unknown","default":"plus-circle"}},"events":{"SAVE":"PREFERENCE_CREATED","OPEN":"CREATE"},"listens":[{"event":"CREATE","triggers":"CREATE","source":{"kind":"trait","trait":"PreferencesManage"}}]},{"ref":"Modal.traits.ModalRecordModal","id":"trt_FKR1971TV5XDJX6VJN4KBC9ST9","name":"PreferenceEdit","linkedEntity":"NotificationPreference","linkedEntityId":"ent_9XXV1AFA93N4HQM643KWYXGVCQ","config":{"mode":{"type":"unknown","default":"edit"},"fields":{"type":"unknown","default":["personId","eventKey","channel","mode","quietHours"]},"title":{"type":"unknown","default":"Edit notification preference"},"icon":{"type":"unknown","default":"pencil"}},"events":{"OPEN":"EDIT","SAVE":"PREFERENCE_UPDATED"},"listens":[{"event":"EDIT","triggers":"EDIT","source":{"kind":"trait","trait":"PreferencesManage"}}]},{"name":"PreferenceGate","id":"trt_PXP894680X40EPGEPPTV82D4NA","effectRow":[{"kind":"emit","resource":"PREFERENCE_RESOLVED"},{"kind":"fetch","resource":"NotificationPreference"},{"kind":"render-ui","resource":"toast"},{"kind":"set","resource":"@entity.channel"},{"kind":"set","resource":"@entity.eventKey"},{"kind":"set","resource":"@entity.mode"},{"kind":"set","resource":"@entity.personId"},{"kind":"set","resource":"@entity.quietHours"}],"category":"lifecycle","linkedEntity":"GateView","linkedEntityId":"ent_1C83HNBAWSNECQZAW3M95G502V","entityRefIds":{"NotificationPreference":"ent_9XXV1AFA93N4HQM643KWYXGVCQ","GateView":"ent_1C83HNBAWSNECQZAW3M95G502V"},"emits":[{"event":"PREFERENCE_RESOLVED","eventId":"evt_MFSTF3R5AZ2NFQKR132ZRQMHG9","description":"The gate's verdict for a CHECK_PREFERENCE consult: resolved channel and mode, and whether quiet hours suppress delivery right now. Fail-open: no row or failed lookup = { channel: in_app, mode: instant, suppressed: false }.","synonyms":"verdict, preference answer, gate result, resolved preference","tier":"domain","scope":"external","payloadSchema":[{"name":"personId","type":"string"},{"name":"eventKey","type":"string"},{"name":"channel","type":"string"},{"name":"mode","type":"string"},{"name":"suppressed","type":"boolean"}]},{"event":"PREFERENCE_ROWS_LOADED","eventId":"evt_FKJ2ZZ927TH3X0HYSYJRARQFJV","description":"NotificationPreference rows loaded; the arm filters to the (personId, eventKey) match and resolves the verdict","tier":"internal","payloadSchema":[{"name":"data","type":"[object]","properties":[{"name":"id","type":"string","required":true},{"name":"personId","type":"string","required":true},{"name":"eventKey","type":"string"},{"name":"channel","type":"string","values":["in_app","email","push","slack","sms","webhook"]},{"name":"mode","type":"string","values":["instant","digest","off"]},{"name":"quietHours","type":"string"},{"name":"createdAt","type":"number"},{"name":"updatedAt","type":"number"}],"entity":"NotificationPreference"}]},{"event":"PREFERENCE_CHECK_FAILED","eventId":"evt_2ZG8HA6ACP56BDNCZJTQ751VMZ","description":"The preference fetch failed — the arm emits the fail-open verdict","tier":"internal","payloadSchema":[{"name":"error","type":"string","required":true}]}],"stateMachine":{"states":[{"name":"idle","isInitial":true}],"events":[{"key":"CHECK_PREFERENCE","id":"evt_6CC20NBAWGNE84TH4SHSE7F8QF","name":"Check Preference","description":"Consult the gate for a person's effective notification preference.","synonyms":"check preference, resolve preference, should notify, gate notification","tier":"domain","payloadSchema":[{"name":"personId","type":"string"},{"name":"eventKey","type":"string"}],"listened":true},{"key":"PREFERENCE_ROWS_LOADED","id":"evt_FKJ2ZZ927TH3X0HYSYJRARQFJV","name":"Preference Rows Loaded","description":"NotificationPreference rows loaded; the arm filters to the (personId, eventKey) match and resolves the verdict","tier":"internal","payloadSchema":[{"name":"data","type":"[object]","properties":[{"name":"id","type":"string","required":true},{"name":"personId","type":"string","required":true},{"name":"eventKey","type":"string"},{"name":"channel","type":"string","values":["in_app","email","push","slack","sms","webhook"]},{"name":"mode","type":"string","values":["instant","digest","off"]},{"name":"quietHours","type":"string"},{"name":"createdAt","type":"number"},{"name":"updatedAt","type":"number"}],"entity":"NotificationPreference"}],"listened":true},{"key":"PREFERENCE_CHECK_FAILED","id":"evt_2ZG8HA6ACP56BDNCZJTQ751VMZ","name":"Preference Check Failed","description":"The preference fetch failed — the arm emits the fail-open verdict","tier":"internal","payloadSchema":[{"name":"error","type":"string","required":true}],"listened":true},{"key":"PREFERENCE_RESOLVED","id":"evt_MFSTF3R5AZ2NFQKR132ZRQMHG9","name":"Preference Resolved","description":"The gate's verdict for a CHECK_PREFERENCE consult: resolved channel and mode, and whether quiet hours suppress delivery right now. Fail-open: no row or failed lookup = { channel: in_app, mode: instant, suppressed: false }.","synonyms":"verdict, preference answer, gate result, resolved preference","tier":"domain","payloadSchema":[{"name":"personId","type":"string"},{"name":"eventKey","type":"string"},{"name":"channel","type":"string"},{"name":"mode","type":"string"},{"name":"suppressed","type":"boolean"}]}],"transitions":[{"from":"idle","to":"idle","event":"CHECK_PREFERENCE","eventId":"evt_6CC20NBAWGNE84TH4SHSE7F8QF","effects":[["set","@entity.personId","@payload.personId"],["set","@entity.eventKey",["if",["=","@payload.eventKey",""],"@config.eventKey","@payload.eventKey"]],["fetch","NotificationPreference",{"emit":{"failure":"PREFERENCE_CHECK_FAILED","success":"PREFERENCE_ROWS_LOADED"}}]]},{"from":"idle","to":"idle","event":"PREFERENCE_ROWS_LOADED","eventId":"evt_FKJ2ZZ927TH3X0HYSYJRARQFJV","effects":[["set","@entity.channel",["if",["=",["array/len",["array/filter","@payload.data",["fn","p",["and",["=",["object/get","@p","personId"],"@entity.personId"],["or",["=",["object/get","@p","eventKey"],""],["=",["object/get","@p","eventKey"],"@entity.eventKey"]]]]]],0],"in_app",["object/get",["array/first",["array/filter","@payload.data",["fn","p",["and",["=",["object/get","@p","personId"],"@entity.personId"],["or",["=",["object/get","@p","eventKey"],""],["=",["object/get","@p","eventKey"],"@entity.eventKey"]]]]]],"channel"]]],["set","@entity.mode",["if",["=",["array/len",["array/filter","@payload.data",["fn","p",["and",["=",["object/get","@p","personId"],"@entity.personId"],["or",["=",["object/get","@p","eventKey"],""],["=",["object/get","@p","eventKey"],"@entity.eventKey"]]]]]],0],"instant",["object/get",["array/first",["array/filter","@payload.data",["fn","p",["and",["=",["object/get","@p","personId"],"@entity.personId"],["or",["=",["object/get","@p","eventKey"],""],["=",["object/get","@p","eventKey"],"@entity.eventKey"]]]]]],"mode"]]],["set","@entity.quietHours",["if",["=",["array/len",["array/filter","@payload.data",["fn","p",["and",["=",["object/get","@p","personId"],"@entity.personId"],["or",["=",["object/get","@p","eventKey"],""],["=",["object/get","@p","eventKey"],"@entity.eventKey"]]]]]],0],"",["object/get",["array/first",["array/filter","@payload.data",["fn","p",["and",["=",["object/get","@p","personId"],"@entity.personId"],["or",["=",["object/get","@p","eventKey"],""],["=",["object/get","@p","eventKey"],"@entity.eventKey"]]]]]],"quietHours"]]],["emit","PREFERENCE_RESOLVED",{"channel":"@entity.channel","eventKey":"@entity.eventKey","mode":"@entity.mode","personId":"@entity.personId","suppressed":["and",["str/includes","@entity.quietHours","-"],["!=",["str/slice",["array/first",["str/split","@entity.quietHours","-"]],0,2],["str/slice",["array/nth",["str/split","@entity.quietHours","-"],1],0,2]],["if",["<",["str/slice",["array/first",["str/split","@entity.quietHours","-"]],0,2],["str/slice",["array/nth",["str/split","@entity.quietHours","-"],1],0,2]],["and",[">=",["str/padStart",["str/concat","",["time/hour","@now"]],2,"0"],["str/slice",["array/first",["str/split","@entity.quietHours","-"]],0,2]],["<",["str/padStart",["str/concat","",["time/hour","@now"]],2,"0"],["str/slice",["array/nth",["str/split","@entity.quietHours","-"],1],0,2]]],["or",[">=",["str/padStart",["str/concat","",["time/hour","@now"]],2,"0"],["str/slice",["array/first",["str/split","@entity.quietHours","-"]],0,2]],["<",["str/padStart",["str/concat","",["time/hour","@now"]],2,"0"],["str/slice",["array/nth",["str/split","@entity.quietHours","-"],1],0,2]]]]]}]]},{"from":"idle","to":"idle","event":"PREFERENCE_CHECK_FAILED","eventId":"evt_2ZG8HA6ACP56BDNCZJTQ751VMZ","effects":[["emit","PREFERENCE_RESOLVED",{"channel":"in_app","eventKey":"@entity.eventKey","mode":"instant","personId":"@entity.personId","suppressed":false}],["render-ui","toast",{"message":"@payload.error","type":"alert","variant":"error"}]]}]},"config":{"eventKey":{"type":"string","default":"","label":"Event key","description":"Stable key naming the event this gate checks preferences for (e.g. 'BudgetThreshold' — the std-finance-tracker NotifyOnEventListener convention). A blank CHECK_PREFERENCE payload eventKey falls back to this value. Preference rows whose eventKey is blank apply to every event.","synonyms":"preference key, event name, subscription key, notification topic","tier":"policy"}},"scope":"instance"}],"pages":[{"name":"NotificationPreferencesPage","id":"pag_6W0NNSR5Q52VJS8XT54FA9ZZQ7","path":"/notification-preferences","traits":[{"ref":"PreferencesManage","refId":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6"},{"ref":"PreferenceCreate","refId":"trt_DDXED3J0X50EJSSVHE251PQMSF"},{"ref":"PreferenceEdit","refId":"trt_FKR1971TV5XDJX6VJN4KBC9ST9"},{"ref":"PreferenceGate","refId":"trt_PXP894680X40EPGEPPTV82D4NA"}]}],"types":{"ItemAction":[{"name":"label","type":"string","required":true},{"name":"event","type":"event"},{"name":"variant","type":"string"},{"name":"icon","type":"string"},{"name":"roles","type":"[string]"},{"name":"when","type":"SExpr"}]}}],"schemaVersion":1,"ledger":{"schemaVersion":1,"entries":{"ent_1C83HNBAWSNECQZAW3M95G502V":{"id":"ent_1C83HNBAWSNECQZAW3M95G502V","kind":"entity","bakedName":"GateView","curName":"GateView","renames":[],"owner":"workspace"},"ent_9XXV1AFA93N4HQM643KWYXGVCQ":{"id":"ent_9XXV1AFA93N4HQM643KWYXGVCQ","kind":"entity","bakedName":"NotificationPreference","curName":"NotificationPreference","renames":[],"owner":"workspace"},"evt_2ZG8HA6ACP56BDNCZJTQ751VMZ":{"id":"evt_2ZG8HA6ACP56BDNCZJTQ751VMZ","kind":"event","bakedName":"PREFERENCE_CHECK_FAILED","curName":"PREFERENCE_CHECK_FAILED","renames":[],"owner":"workspace","parent":"trt_PXP894680X40EPGEPPTV82D4NA"},"evt_5GXQHQDMT4TD288ZZFRRZBXRA0":{"id":"evt_5GXQHQDMT4TD288ZZFRRZBXRA0","kind":"event","bakedName":"PreferenceSaveFailed","curName":"PreferenceSaveFailed","renames":[],"owner":"workspace","parent":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6"},"evt_6CC20NBAWGNE84TH4SHSE7F8QF":{"id":"evt_6CC20NBAWGNE84TH4SHSE7F8QF","kind":"event","bakedName":"CHECK_PREFERENCE","curName":"CHECK_PREFERENCE","renames":[],"owner":"workspace","parent":"trt_PXP894680X40EPGEPPTV82D4NA"},"evt_7R59HX8RR1CC0XEY97RGY3NQ3C":{"id":"evt_7R59HX8RR1CC0XEY97RGY3NQ3C","kind":"event","bakedName":"INIT","curName":"INIT","renames":[],"owner":"workspace","parent":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6"},"evt_93DE8SY3YA1Z57W1PEPZ7HP8MM":{"id":"evt_93DE8SY3YA1Z57W1PEPZ7HP8MM","kind":"event","bakedName":"PreferenceSaved","curName":"PreferenceSaved","renames":[],"owner":"workspace","parent":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6"},"evt_9AJYN9CVH8DRMEPKPB0PVPF6F1":{"id":"evt_9AJYN9CVH8DRMEPKPB0PVPF6F1","kind":"event","bakedName":"RETRY","curName":"RETRY","renames":[],"owner":"workspace","parent":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6"},"evt_ACVDGSM8CA465B22X38EKHR52A":{"id":"evt_ACVDGSM8CA465B22X38EKHR52A","kind":"event","bakedName":"DO_CREATE","curName":"DO_CREATE","renames":[],"owner":"workspace","parent":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6"},"evt_DAJMYWXBYANZ57Z1W1J5C3BM4V":{"id":"evt_DAJMYWXBYANZ57Z1W1J5C3BM4V","kind":"event","bakedName":"EDIT","curName":"EDIT","renames":[],"owner":"workspace","parent":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6"},"evt_FKJ2ZZ927TH3X0HYSYJRARQFJV":{"id":"evt_FKJ2ZZ927TH3X0HYSYJRARQFJV","kind":"event","bakedName":"PREFERENCE_ROWS_LOADED","curName":"PREFERENCE_ROWS_LOADED","renames":[],"owner":"workspace","parent":"trt_PXP894680X40EPGEPPTV82D4NA"},"evt_GTAPK71SV3WXHT3H6FKF9BHRM7":{"id":"evt_GTAPK71SV3WXHT3H6FKF9BHRM7","kind":"event","bakedName":"PreferenceDeleted","curName":"PreferenceDeleted","renames":[],"owner":"workspace","parent":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6"},"evt_HF6KA8J0V10DGX5HMWW7WAEPC9":{"id":"evt_HF6KA8J0V10DGX5HMWW7WAEPC9","kind":"event","bakedName":"DELETE","curName":"DELETE","renames":[],"owner":"workspace","parent":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6"},"evt_KBVBFG78TZMDFW4K2SBYR69RTY":{"id":"evt_KBVBFG78TZMDFW4K2SBYR69RTY","kind":"event","bakedName":"PreferencesLoadFailed","curName":"PreferencesLoadFailed","renames":[],"owner":"workspace","parent":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6"},"evt_MFSTF3R5AZ2NFQKR132ZRQMHG9":{"id":"evt_MFSTF3R5AZ2NFQKR132ZRQMHG9","kind":"event","bakedName":"PREFERENCE_RESOLVED","curName":"PREFERENCE_RESOLVED","renames":[],"owner":"workspace","parent":"trt_PXP894680X40EPGEPPTV82D4NA"},"evt_P1ASTZKBS8NWMCEFB5PAY3Y362":{"id":"evt_P1ASTZKBS8NWMCEFB5PAY3Y362","kind":"event","bakedName":"DO_UPDATE","curName":"DO_UPDATE","renames":[],"owner":"workspace","parent":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6"},"evt_QW6JNB276X3KEQ4BNT5WB754A3":{"id":"evt_QW6JNB276X3KEQ4BNT5WB754A3","kind":"event","bakedName":"CREATE","curName":"CREATE","renames":[],"owner":"workspace","parent":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6"},"evt_XF6P2M2MMWAAE0R2MZVSP9WJE4":{"id":"evt_XF6P2M2MMWAAE0R2MZVSP9WJE4","kind":"event","bakedName":"PreferencesLoaded","curName":"PreferencesLoaded","renames":[],"owner":"workspace","parent":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6"},"orb_NY862D5QC2VP19PHB5CKGQH8F5":{"id":"orb_NY862D5QC2VP19PHB5CKGQH8F5","kind":"orbital","bakedName":"NotificationPreferencesOrbital","curName":"NotificationPreferencesOrbital","renames":[],"owner":"workspace"},"pag_6W0NNSR5Q52VJS8XT54FA9ZZQ7":{"id":"pag_6W0NNSR5Q52VJS8XT54FA9ZZQ7","kind":"page","bakedName":"NotificationPreferencesPage","curName":"NotificationPreferencesPage","renames":[],"owner":"workspace"},"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6":{"id":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6","kind":"trait","bakedName":"PreferencesManage","curName":"PreferencesManage","renames":[],"owner":"workspace"},"trt_DDXED3J0X50EJSSVHE251PQMSF":{"id":"trt_DDXED3J0X50EJSSVHE251PQMSF","kind":"trait","bakedName":"PreferenceCreate","curName":"PreferenceCreate","renames":[],"owner":"workspace"},"trt_FKR1971TV5XDJX6VJN4KBC9ST9":{"id":"trt_FKR1971TV5XDJX6VJN4KBC9ST9","kind":"trait","bakedName":"PreferenceEdit","curName":"PreferenceEdit","renames":[],"owner":"workspace"},"trt_PXP894680X40EPGEPPTV82D4NA":{"id":"trt_PXP894680X40EPGEPPTV82D4NA","kind":"trait","bakedName":"PreferenceGate","curName":"PreferenceGate","renames":[],"owner":"workspace"}}}}
1
+ {"name":"std-notification-preferences","version":"1.0.0","description":"std-notification-preferences — per-person notification preference store plus a consultable gate. Owns NotificationPreference rows (one per person + event key: channel override in_app/email/push/slack/sms/webhook, mode instant/digest/off, quiet-hours window 'HH:MM-HH:MM' such as 22:00-07:00). The PreferencesManage trait is standard CRUD over the store (list / create / update / delete, persisted, success/failure cascade arms): a data-grid browse plus ModalRecordModal create/edit forms whose SAVE carries the full row payload (std-list daisy-chain idiom). The PreferenceGate trait is the consult half other notify traits call: emit CHECK_PREFERENCE { personId, eventKey } and the gate fetches the matching row (a row whose eventKey is blank applies to every event) and answers PREFERENCE_RESOLVED { personId, eventKey, channel, mode, suppressed } — suppressed is true only when the row's quietHours window covers the current hour; mode 'digest' rides on the verdict for the caller to defer. Default policy: no matching row — or a failed lookup — resolves fail-open to { channel: in_app, mode: instant, suppressed: false }; the absence of a preference never silences a notification.","orbitals":[{"name":"NotificationPreferencesOrbital","id":"orb_NY862D5QC2VP19PHB5CKGQH8F5","uses":[{"from":"std/behaviors/std-modal","as":"Modal"}],"entity":{"name":"NotificationPreference","id":"ent_9XXV1AFA93N4HQM643KWYXGVCQ","collection":"notificationPreferences","persistence":"persistent","fields":[{"name":"id","type":"string","required":true},{"name":"personId","type":"string","required":true,"description":"The person this preference row belongs to.","synonyms":"user, recipient, owner, account"},{"name":"eventKey","type":"string","default":"","description":"Event key this preference applies to (matches a notify listener's eventKey); blank = all events.","synonyms":"event, trigger, topic, subscription"},{"name":"channel","type":"string","default":"in_app","values":["in_app","email","push","slack","sms","webhook"],"description":"Delivery channel override for this person.","synonyms":"preferred channel, delivery method"},{"name":"mode","type":"string","default":"instant","values":["instant","digest","off"],"description":"Delivery mode: instant (default), digest (deferred to a batch cycle), or off (muted).","synonyms":"delivery mode, frequency, cadence, mute, defer"},{"name":"quietHours","type":"string","default":"","description":"Quiet-hours window as \"HH:MM-HH:MM\" (e.g. 22:00-07:00); blank or equal start/end = disabled.","synonyms":"do not disturb, quiet window, night mode"},{"name":"createdAt","type":"number","default":0,"description":"Timestamp indicating when this preference row was created.","synonyms":"creation time, created"},{"name":"updatedAt","type":"number","default":0,"description":"Timestamp indicating when this preference row was last updated.","synonyms":"modified, last updated"}]},"auxiliaryEntities":[{"name":"GateView","id":"ent_1C83HNBAWSNECQZAW3M95G502V","persistence":"runtime","fields":[{"name":"id","type":"string","required":true},{"name":"personId","type":"string","default":"","description":"Scratch: personId of the consult currently in flight.","synonyms":"current person"},{"name":"eventKey","type":"string","default":"","description":"Scratch: effective event key of the consult currently in flight (payload eventKey, or the configured eventKey when the payload is blank).","synonyms":"current event key"},{"name":"channel","type":"string","default":"","description":"Scratch: resolved channel for the current consult.","synonyms":"resolved channel"},{"name":"mode","type":"string","default":"","description":"Scratch: resolved delivery mode for the current consult.","synonyms":"resolved mode"},{"name":"quietHours","type":"string","default":"","description":"Scratch: quiet-hours window of the matched row for the current consult; blank = none.","synonyms":"resolved quiet hours"}]}],"traits":[{"name":"PreferencesManage","id":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6","effectRow":[{"kind":"fetch","resource":"NotificationPreference"},{"kind":"persist","resource":"NotificationPreference"},{"kind":"render-ui","resource":"main"},{"kind":"render-ui","resource":"toast"}],"category":"interaction","linkedEntity":"NotificationPreference","linkedEntityId":"ent_9XXV1AFA93N4HQM643KWYXGVCQ","entityRefIds":{"NotificationPreference":"ent_9XXV1AFA93N4HQM643KWYXGVCQ"},"emits":[{"event":"CREATE","eventId":"evt_QW6JNB276X3KEQ4BNT5WB754A3","description":"Opens the blank preference modal.","synonyms":"add, new, insert","tier":"domain"},{"event":"EDIT","eventId":"evt_DAJMYWXBYANZ57Z1W1J5C3BM4V","description":"Opens a preference row in the edit modal.","synonyms":"modify, update, change","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"row","type":"object","properties":[{"name":"id","type":"string","required":true},{"name":"personId","type":"string","required":true},{"name":"eventKey","type":"string"},{"name":"channel","type":"string","values":["in_app","email","push","slack","sms","webhook"]},{"name":"mode","type":"string","values":["instant","digest","off"]},{"name":"quietHours","type":"string"},{"name":"createdAt","type":"number"},{"name":"updatedAt","type":"number"}],"entity":"NotificationPreference"}]},{"event":"DELETE","eventId":"evt_HF6KA8J0V10DGX5HMWW7WAEPC9","description":"Removes a preference row.","synonyms":"remove, discard, clear","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"row","type":"object","properties":[{"name":"id","type":"string","required":true},{"name":"personId","type":"string","required":true},{"name":"eventKey","type":"string"},{"name":"channel","type":"string","values":["in_app","email","push","slack","sms","webhook"]},{"name":"mode","type":"string","values":["instant","digest","off"]},{"name":"quietHours","type":"string"},{"name":"createdAt","type":"number"},{"name":"updatedAt","type":"number"}],"entity":"NotificationPreference"}]},{"event":"PreferencesLoaded","eventId":"evt_XF6P2M2MMWAAE0R2MZVSP9WJE4","description":"The preference collection finished loading.","synonyms":"loaded, fetched, retrieved","tier":"internal","payloadSchema":[{"name":"data","type":"[object]","properties":[{"name":"id","type":"string","required":true},{"name":"personId","type":"string","required":true},{"name":"eventKey","type":"string"},{"name":"channel","type":"string","values":["in_app","email","push","slack","sms","webhook"]},{"name":"mode","type":"string","values":["instant","digest","off"]},{"name":"quietHours","type":"string"},{"name":"createdAt","type":"number"},{"name":"updatedAt","type":"number"}],"entity":"NotificationPreference"}]},{"event":"PreferencesLoadFailed","eventId":"evt_KBVBFG78TZMDFW4K2SBYR69RTY","description":"The preference collection failed to load.","synonyms":"error, failure, load error","tier":"internal","payloadSchema":[{"name":"error","type":"string"},{"name":"code","type":"string"}]},{"event":"PreferenceSaved","eventId":"evt_93DE8SY3YA1Z57W1PEPZ7HP8MM","description":"A preference row persisted (create or update).","synonyms":"created, updated, persisted","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true}]},{"event":"PreferenceSaveFailed","eventId":"evt_5GXQHQDMT4TD288ZZFRRZBXRA0","description":"A preference persist failed.","synonyms":"failed, error, unsuccessful","tier":"internal","payloadSchema":[{"name":"error","type":"string"},{"name":"code","type":"string"}]},{"event":"PreferenceDeleted","eventId":"evt_GTAPK71SV3WXHT3H6FKF9BHRM7","description":"A preference row was deleted.","synonyms":"removed, purged, discarded","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true}]}],"listens":[{"event":"PREFERENCE_CREATED","triggers":"DO_CREATE","triggersId":"evt_ACVDGSM8CA465B22X38EKHR52A","source":{"kind":"trait","trait":"PreferenceCreate","traitId":"trt_DDXED3J0X50EJSSVHE251PQMSF"}},{"event":"PREFERENCE_UPDATED","triggers":"DO_UPDATE","triggersId":"evt_P1ASTZKBS8NWMCEFB5PAY3Y362","source":{"kind":"trait","trait":"PreferenceEdit","traitId":"trt_FKR1971TV5XDJX6VJN4KBC9ST9"}}],"stateMachine":{"states":[{"name":"loading","isInitial":true},{"name":"browsing"},{"name":"error"}],"events":[{"key":"INIT","id":"evt_7R59HX8RR1CC0XEY97RGY3NQ3C","name":"Initialize"},{"key":"PreferencesLoaded","id":"evt_XF6P2M2MMWAAE0R2MZVSP9WJE4","name":"Preferences loaded","description":"The preference collection finished loading.","synonyms":"loaded, fetched, retrieved","tier":"internal","payloadSchema":[{"name":"data","type":"[object]","properties":[{"name":"id","type":"string","required":true},{"name":"personId","type":"string","required":true},{"name":"eventKey","type":"string"},{"name":"channel","type":"string","values":["in_app","email","push","slack","sms","webhook"]},{"name":"mode","type":"string","values":["instant","digest","off"]},{"name":"quietHours","type":"string"},{"name":"createdAt","type":"number"},{"name":"updatedAt","type":"number"}],"entity":"NotificationPreference"}],"listened":true},{"key":"PreferencesLoadFailed","id":"evt_KBVBFG78TZMDFW4K2SBYR69RTY","name":"Preferences load failed","description":"The preference collection failed to load.","synonyms":"error, failure, load error","tier":"internal","payloadSchema":[{"name":"error","type":"string"},{"name":"code","type":"string"}],"listened":true},{"key":"DELETE","id":"evt_HF6KA8J0V10DGX5HMWW7WAEPC9","name":"Delete","description":"Removes a preference row.","synonyms":"remove, discard, clear","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"row","type":"object","properties":[{"name":"id","type":"string","required":true},{"name":"personId","type":"string","required":true},{"name":"eventKey","type":"string"},{"name":"channel","type":"string","values":["in_app","email","push","slack","sms","webhook"]},{"name":"mode","type":"string","values":["instant","digest","off"]},{"name":"quietHours","type":"string"},{"name":"createdAt","type":"number"},{"name":"updatedAt","type":"number"}],"entity":"NotificationPreference"}],"listened":true},{"key":"DO_CREATE","id":"evt_ACVDGSM8CA465B22X38EKHR52A","name":"Do Create","description":"Create persist requested; the modal's SAVE payload carries the full form row.","synonyms":"add, new, insert","tier":"internal","payloadSchema":[{"name":"data","type":"object","required":true,"properties":[{"name":"id","type":"string","required":true},{"name":"personId","type":"string","required":true},{"name":"eventKey","type":"string"},{"name":"channel","type":"string","values":["in_app","email","push","slack","sms","webhook"]},{"name":"mode","type":"string","values":["instant","digest","off"]},{"name":"quietHours","type":"string"},{"name":"createdAt","type":"number"},{"name":"updatedAt","type":"number"}],"entity":"NotificationPreference"}],"listened":true},{"key":"DO_UPDATE","id":"evt_P1ASTZKBS8NWMCEFB5PAY3Y362","name":"Do Update","description":"Update persist requested; the modal's SAVE payload carries the full form row.","synonyms":"modified, changed, refreshed","tier":"internal","payloadSchema":[{"name":"data","type":"object","required":true,"properties":[{"name":"id","type":"string","required":true},{"name":"personId","type":"string","required":true},{"name":"eventKey","type":"string"},{"name":"channel","type":"string","values":["in_app","email","push","slack","sms","webhook"]},{"name":"mode","type":"string","values":["instant","digest","off"]},{"name":"quietHours","type":"string"},{"name":"createdAt","type":"number"},{"name":"updatedAt","type":"number"}],"entity":"NotificationPreference"}],"listened":true},{"key":"PreferenceSaved","id":"evt_93DE8SY3YA1Z57W1PEPZ7HP8MM","name":"Preference saved","description":"A preference row persisted (create or update).","synonyms":"created, updated, persisted","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true}],"listened":true},{"key":"PreferenceDeleted","id":"evt_GTAPK71SV3WXHT3H6FKF9BHRM7","name":"Preference deleted","description":"A preference row was deleted.","synonyms":"removed, purged, discarded","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true}],"listened":true},{"key":"PreferenceSaveFailed","id":"evt_5GXQHQDMT4TD288ZZFRRZBXRA0","name":"Preference save failed","description":"A preference persist failed.","synonyms":"failed, error, unsuccessful","tier":"internal","payloadSchema":[{"name":"error","type":"string"},{"name":"code","type":"string"}],"listened":true},{"key":"RETRY","id":"evt_9AJYN9CVH8DRMEPKPB0PVPF6F1","name":"Retry","description":"Retries loading the preference collection after a failure.","synonyms":"try again, reload","tier":"presentation","listened":true},{"key":"CREATE","id":"evt_QW6JNB276X3KEQ4BNT5WB754A3","name":"Create","description":"Opens the blank preference modal.","synonyms":"add, new, insert","tier":"domain"},{"key":"EDIT","id":"evt_DAJMYWXBYANZ57Z1W1J5C3BM4V","name":"Edit","description":"Opens a preference row in the edit modal.","synonyms":"modify, update, change","tier":"domain","payloadSchema":[{"name":"id","type":"string","required":true},{"name":"row","type":"object","properties":[{"name":"id","type":"string","required":true},{"name":"personId","type":"string","required":true},{"name":"eventKey","type":"string"},{"name":"channel","type":"string","values":["in_app","email","push","slack","sms","webhook"]},{"name":"mode","type":"string","values":["instant","digest","off"]},{"name":"quietHours","type":"string"},{"name":"createdAt","type":"number"},{"name":"updatedAt","type":"number"}],"entity":"NotificationPreference"}]}],"transitions":[{"from":"loading","to":"loading","event":"INIT","eventId":"evt_7R59HX8RR1CC0XEY97RGY3NQ3C","effects":[["fetch","NotificationPreference",{"emit":{"failure":"PreferencesLoadFailed","success":"PreferencesLoaded"}}],["render-ui","main",{"type":"stack","direction":"vertical","gap":"lg","children":[{"type":"skeleton","variant":"header"},{"type":"skeleton","variant":"grid","rows":6}]}]]},{"from":"loading","to":"browsing","event":"PreferencesLoaded","eventId":"evt_XF6P2M2MMWAAE0R2MZVSP9WJE4","effects":[["render-ui","main",{"children":[{"children":[{"children":[{"name":"bell","size":"lg","type":"icon"},{"content":"@config.title","type":"typography","variant":"h3"}],"direction":"horizontal","gap":"sm","type":"stack"},{"action":"CREATE","icon":"plus","label":"New preference","type":"button","variant":"primary"}],"direction":"horizontal","gap":"sm","justify":"between","type":"stack"},{"type":"divider"},{"cols":1,"entity":"@payload.data","fields":[{"label":"Person","name":"personId","variant":"h4"},{"label":"Event","name":"eventKey","variant":"caption"},{"label":"Channel","name":"channel","variant":"badge"},{"label":"Mode","name":"mode","variant":"badge"},{"label":"Quiet hours","name":"quietHours","variant":"caption"}],"gap":"sm","itemClickEvent":"@config.itemClickEvent","itemActions":["array/filter","@config.itemActions",["fn","action",["or",["=",["array/len",["object/get","@action","roles",[]]],0],["array/includes",["object/get","@action","roles",[]],"@config.viewerRole"]]]],"look":"@config.tableLook","type":"data-grid"}],"direction":"vertical","gap":"md","type":"stack"}]]},{"from":"loading","to":"error","event":"PreferencesLoadFailed","eventId":"evt_KBVBFG78TZMDFW4K2SBYR69RTY","effects":[["render-ui","main",{"align":"center","children":[{"message":"@payload.error","type":"alert","variant":"error"},{"action":"RETRY","icon":"rotate-ccw","label":"Retry","type":"button","variant":"primary"}],"className":"py-12","direction":"vertical","gap":"md","type":"stack"}]]},{"from":"browsing","to":"loading","event":"INIT","eventId":"evt_7R59HX8RR1CC0XEY97RGY3NQ3C","effects":[["fetch","NotificationPreference",{"emit":{"failure":"PreferencesLoadFailed","success":"PreferencesLoaded"}}],["render-ui","main",{"type":"stack","direction":"vertical","gap":"lg","children":[{"type":"skeleton","variant":"header"},{"type":"skeleton","variant":"grid","rows":6}]}]]},{"from":"browsing","to":"browsing","event":"DELETE","eventId":"evt_HF6KA8J0V10DGX5HMWW7WAEPC9","effects":[["persist","delete","NotificationPreference","@payload.id",{"emit":{"failure":"PreferenceSaveFailed","success":"PreferenceDeleted"}}]]},{"from":"browsing","to":"browsing","event":"DO_CREATE","eventId":"evt_ACVDGSM8CA465B22X38EKHR52A","effects":[["persist","create","NotificationPreference","@payload.data",{"emit":{"failure":"PreferenceSaveFailed","success":"PreferenceSaved"}}]]},{"from":"browsing","to":"browsing","event":"DO_UPDATE","eventId":"evt_P1ASTZKBS8NWMCEFB5PAY3Y362","effects":[["persist","update","NotificationPreference","@payload.data",{"emit":{"failure":"PreferenceSaveFailed","success":"PreferenceSaved"}}]]},{"from":"browsing","to":"loading","event":"PreferenceSaved","eventId":"evt_93DE8SY3YA1Z57W1PEPZ7HP8MM","effects":[["render-ui","toast",{"type":"alert","variant":"success","message":"Notification preference saved","dismissible":true}],["fetch","NotificationPreference",{"emit":{"failure":"PreferencesLoadFailed","success":"PreferencesLoaded"}}]]},{"from":"browsing","to":"loading","event":"PreferenceDeleted","eventId":"evt_GTAPK71SV3WXHT3H6FKF9BHRM7","effects":[["render-ui","toast",{"type":"alert","variant":"info","message":"Notification preference removed","dismissible":true}],["fetch","NotificationPreference",{"emit":{"failure":"PreferencesLoadFailed","success":"PreferencesLoaded"}}]]},{"from":"browsing","to":"browsing","event":"PreferenceSaveFailed","eventId":"evt_5GXQHQDMT4TD288ZZFRRZBXRA0","effects":[["render-ui","toast",{"type":"alert","variant":"warning","message":"Could not save the notification preference","dismissible":true}]]},{"from":"browsing","to":"error","event":"PreferencesLoadFailed","eventId":"evt_KBVBFG78TZMDFW4K2SBYR69RTY","effects":[["render-ui","main",{"align":"center","children":[{"message":"@payload.error","type":"alert","variant":"error"},{"action":"RETRY","icon":"rotate-ccw","label":"Retry","type":"button","variant":"primary"}],"className":"py-12","direction":"vertical","gap":"md","type":"stack"}]]},{"from":"error","to":"loading","event":"INIT","eventId":"evt_7R59HX8RR1CC0XEY97RGY3NQ3C","effects":[["fetch","NotificationPreference",{"emit":{"failure":"PreferencesLoadFailed","success":"PreferencesLoaded"}}],["render-ui","main",{"type":"stack","direction":"vertical","gap":"lg","children":[{"type":"skeleton","variant":"header"},{"type":"skeleton","variant":"grid","rows":6}]}]]},{"from":"error","to":"loading","event":"RETRY","eventId":"evt_9AJYN9CVH8DRMEPKPB0PVPF6F1","effects":[["fetch","NotificationPreference",{"emit":{"failure":"PreferencesLoadFailed","success":"PreferencesLoaded"}}],["render-ui","main",{"type":"stack","direction":"vertical","gap":"lg","children":[{"type":"skeleton","variant":"header"},{"type":"skeleton","variant":"grid","rows":6}]}]]}]},"config":{"itemActions":{"type":"[ItemAction]","default":[{"event":"EDIT","icon":"pencil","label":"Edit","variant":"secondary"},{"event":"DELETE","icon":"trash-2","label":"Delete","variant":"danger"}],"label":"Row actions","description":"Actions offered on each row; give an item `roles` to show it only to those viewer roles.","tier":"presentation","items":{"type":"object","properties":{"event":{"name":"event","type":"event","required":false},"icon":{"name":"icon","type":"string","required":false},"when":{"name":"when","type":"SExpr","required":false},"roles":{"name":"roles","type":"array","required":false,"items":{"type":"string"}},"label":{"name":"label","type":"string","required":true},"variant":{"name":"variant","type":"string","required":false}}}},"itemClickEvent":{"type":"event","default":"EDIT","label":"Row click","description":"Event emitted when a row is clicked; opens the preference for editing. Empty disables the row click.","tier":"presentation","refId":"evt_DAJMYWXBYANZ57Z1W1J5C3BM4V"},"viewerRole":{"type":"string","default":"","label":"Viewer's role","description":"The signed-in viewer's role that each action's `roles` is checked against. Bind it explicitly at the call site (e.g. `viewerRole: @user.role`) in an app whose identity carries a role; left empty, only actions with no `roles` show.","tier":"policy"},"title":{"type":"string","default":"Notification preferences","label":"Section title","description":"Heading shown above the preference list","tier":"presentation"},"tableLook":{"type":"string","default":"dense","label":"Table look","description":"Layer 2 visual treatment for the preference data table rendered by this atom.","tier":"presentation","values":["dense","spacious","striped","borderless","card-rows"]}},"scope":"collection"},{"ref":"Modal.traits.ModalRecordModal","id":"trt_DDXED3J0X50EJSSVHE251PQMSF","name":"PreferenceCreate","linkedEntity":"NotificationPreference","linkedEntityId":"ent_9XXV1AFA93N4HQM643KWYXGVCQ","config":{"icon":{"type":"unknown","default":"plus-circle"},"fields":{"type":"unknown","default":["personId","eventKey","channel","mode","quietHours"]},"title":{"type":"unknown","default":"New notification preference"},"mode":{"type":"unknown","default":"create"}},"events":{"SAVE":"PREFERENCE_CREATED","OPEN":"CREATE"},"listens":[{"event":"CREATE","triggers":"CREATE","source":{"kind":"trait","trait":"PreferencesManage"}}]},{"ref":"Modal.traits.ModalRecordModal","id":"trt_FKR1971TV5XDJX6VJN4KBC9ST9","name":"PreferenceEdit","linkedEntity":"NotificationPreference","linkedEntityId":"ent_9XXV1AFA93N4HQM643KWYXGVCQ","config":{"title":{"type":"unknown","default":"Edit notification preference"},"icon":{"type":"unknown","default":"pencil"},"fields":{"type":"unknown","default":["personId","eventKey","channel","mode","quietHours"]},"mode":{"type":"unknown","default":"edit"}},"events":{"SAVE":"PREFERENCE_UPDATED","OPEN":"EDIT"},"listens":[{"event":"EDIT","triggers":"EDIT","source":{"kind":"trait","trait":"PreferencesManage"}}]},{"name":"PreferenceGate","id":"trt_PXP894680X40EPGEPPTV82D4NA","effectRow":[{"kind":"emit","resource":"PREFERENCE_RESOLVED"},{"kind":"fetch","resource":"NotificationPreference"},{"kind":"render-ui","resource":"toast"},{"kind":"set","resource":"@entity.channel"},{"kind":"set","resource":"@entity.eventKey"},{"kind":"set","resource":"@entity.mode"},{"kind":"set","resource":"@entity.personId"},{"kind":"set","resource":"@entity.quietHours"}],"category":"lifecycle","linkedEntity":"GateView","linkedEntityId":"ent_1C83HNBAWSNECQZAW3M95G502V","entityRefIds":{"GateView":"ent_1C83HNBAWSNECQZAW3M95G502V","NotificationPreference":"ent_9XXV1AFA93N4HQM643KWYXGVCQ"},"emits":[{"event":"PREFERENCE_RESOLVED","eventId":"evt_MFSTF3R5AZ2NFQKR132ZRQMHG9","description":"The gate's verdict for a CHECK_PREFERENCE consult: resolved channel and mode, and whether quiet hours suppress delivery right now. Fail-open: no row or failed lookup = { channel: in_app, mode: instant, suppressed: false }.","synonyms":"verdict, preference answer, gate result, resolved preference","tier":"domain","scope":"external","payloadSchema":[{"name":"personId","type":"string"},{"name":"eventKey","type":"string"},{"name":"channel","type":"string"},{"name":"mode","type":"string"},{"name":"suppressed","type":"boolean"}]},{"event":"PREFERENCE_ROWS_LOADED","eventId":"evt_FKJ2ZZ927TH3X0HYSYJRARQFJV","description":"NotificationPreference rows loaded; the arm filters to the (personId, eventKey) match and resolves the verdict","tier":"internal","payloadSchema":[{"name":"data","type":"[object]","properties":[{"name":"id","type":"string","required":true},{"name":"personId","type":"string","required":true},{"name":"eventKey","type":"string"},{"name":"channel","type":"string","values":["in_app","email","push","slack","sms","webhook"]},{"name":"mode","type":"string","values":["instant","digest","off"]},{"name":"quietHours","type":"string"},{"name":"createdAt","type":"number"},{"name":"updatedAt","type":"number"}],"entity":"NotificationPreference"}]},{"event":"PREFERENCE_CHECK_FAILED","eventId":"evt_2ZG8HA6ACP56BDNCZJTQ751VMZ","description":"The preference fetch failed — the arm emits the fail-open verdict","tier":"internal","payloadSchema":[{"name":"error","type":"string","required":true}]}],"stateMachine":{"states":[{"name":"idle","isInitial":true}],"events":[{"key":"CHECK_PREFERENCE","id":"evt_6CC20NBAWGNE84TH4SHSE7F8QF","name":"Check Preference","description":"Consult the gate for a person's effective notification preference.","synonyms":"check preference, resolve preference, should notify, gate notification","tier":"domain","payloadSchema":[{"name":"personId","type":"string"},{"name":"eventKey","type":"string"}],"listened":true},{"key":"PREFERENCE_ROWS_LOADED","id":"evt_FKJ2ZZ927TH3X0HYSYJRARQFJV","name":"Preference Rows Loaded","description":"NotificationPreference rows loaded; the arm filters to the (personId, eventKey) match and resolves the verdict","tier":"internal","payloadSchema":[{"name":"data","type":"[object]","properties":[{"name":"id","type":"string","required":true},{"name":"personId","type":"string","required":true},{"name":"eventKey","type":"string"},{"name":"channel","type":"string","values":["in_app","email","push","slack","sms","webhook"]},{"name":"mode","type":"string","values":["instant","digest","off"]},{"name":"quietHours","type":"string"},{"name":"createdAt","type":"number"},{"name":"updatedAt","type":"number"}],"entity":"NotificationPreference"}],"listened":true},{"key":"PREFERENCE_CHECK_FAILED","id":"evt_2ZG8HA6ACP56BDNCZJTQ751VMZ","name":"Preference Check Failed","description":"The preference fetch failed — the arm emits the fail-open verdict","tier":"internal","payloadSchema":[{"name":"error","type":"string","required":true}],"listened":true},{"key":"PREFERENCE_RESOLVED","id":"evt_MFSTF3R5AZ2NFQKR132ZRQMHG9","name":"Preference Resolved","description":"The gate's verdict for a CHECK_PREFERENCE consult: resolved channel and mode, and whether quiet hours suppress delivery right now. Fail-open: no row or failed lookup = { channel: in_app, mode: instant, suppressed: false }.","synonyms":"verdict, preference answer, gate result, resolved preference","tier":"domain","payloadSchema":[{"name":"personId","type":"string"},{"name":"eventKey","type":"string"},{"name":"channel","type":"string"},{"name":"mode","type":"string"},{"name":"suppressed","type":"boolean"}]}],"transitions":[{"from":"idle","to":"idle","event":"CHECK_PREFERENCE","eventId":"evt_6CC20NBAWGNE84TH4SHSE7F8QF","effects":[["set","@entity.personId","@payload.personId"],["set","@entity.eventKey",["if",["=","@payload.eventKey",""],"@config.eventKey","@payload.eventKey"]],["fetch","NotificationPreference",{"emit":{"failure":"PREFERENCE_CHECK_FAILED","success":"PREFERENCE_ROWS_LOADED"}}]]},{"from":"idle","to":"idle","event":"PREFERENCE_ROWS_LOADED","eventId":"evt_FKJ2ZZ927TH3X0HYSYJRARQFJV","effects":[["set","@entity.channel",["if",["=",["array/len",["array/filter","@payload.data",["fn","p",["and",["=",["object/get","@p","personId"],"@entity.personId"],["or",["=",["object/get","@p","eventKey"],""],["=",["object/get","@p","eventKey"],"@entity.eventKey"]]]]]],0],"in_app",["object/get",["array/first",["array/filter","@payload.data",["fn","p",["and",["=",["object/get","@p","personId"],"@entity.personId"],["or",["=",["object/get","@p","eventKey"],""],["=",["object/get","@p","eventKey"],"@entity.eventKey"]]]]]],"channel"]]],["set","@entity.mode",["if",["=",["array/len",["array/filter","@payload.data",["fn","p",["and",["=",["object/get","@p","personId"],"@entity.personId"],["or",["=",["object/get","@p","eventKey"],""],["=",["object/get","@p","eventKey"],"@entity.eventKey"]]]]]],0],"instant",["object/get",["array/first",["array/filter","@payload.data",["fn","p",["and",["=",["object/get","@p","personId"],"@entity.personId"],["or",["=",["object/get","@p","eventKey"],""],["=",["object/get","@p","eventKey"],"@entity.eventKey"]]]]]],"mode"]]],["set","@entity.quietHours",["if",["=",["array/len",["array/filter","@payload.data",["fn","p",["and",["=",["object/get","@p","personId"],"@entity.personId"],["or",["=",["object/get","@p","eventKey"],""],["=",["object/get","@p","eventKey"],"@entity.eventKey"]]]]]],0],"",["object/get",["array/first",["array/filter","@payload.data",["fn","p",["and",["=",["object/get","@p","personId"],"@entity.personId"],["or",["=",["object/get","@p","eventKey"],""],["=",["object/get","@p","eventKey"],"@entity.eventKey"]]]]]],"quietHours"]]],["emit","PREFERENCE_RESOLVED",{"channel":"@entity.channel","eventKey":"@entity.eventKey","mode":"@entity.mode","personId":"@entity.personId","suppressed":["and",["str/includes","@entity.quietHours","-"],["!=",["str/slice",["array/first",["str/split","@entity.quietHours","-"]],0,2],["str/slice",["array/nth",["str/split","@entity.quietHours","-"],1],0,2]],["if",["<",["str/slice",["array/first",["str/split","@entity.quietHours","-"]],0,2],["str/slice",["array/nth",["str/split","@entity.quietHours","-"],1],0,2]],["and",[">=",["str/padStart",["str/concat","",["time/hour","@now"]],2,"0"],["str/slice",["array/first",["str/split","@entity.quietHours","-"]],0,2]],["<",["str/padStart",["str/concat","",["time/hour","@now"]],2,"0"],["str/slice",["array/nth",["str/split","@entity.quietHours","-"],1],0,2]]],["or",[">=",["str/padStart",["str/concat","",["time/hour","@now"]],2,"0"],["str/slice",["array/first",["str/split","@entity.quietHours","-"]],0,2]],["<",["str/padStart",["str/concat","",["time/hour","@now"]],2,"0"],["str/slice",["array/nth",["str/split","@entity.quietHours","-"],1],0,2]]]]]}]]},{"from":"idle","to":"idle","event":"PREFERENCE_CHECK_FAILED","eventId":"evt_2ZG8HA6ACP56BDNCZJTQ751VMZ","effects":[["emit","PREFERENCE_RESOLVED",{"channel":"in_app","eventKey":"@entity.eventKey","mode":"instant","personId":"@entity.personId","suppressed":false}],["render-ui","toast",{"message":"@payload.error","type":"alert","variant":"error"}]]}]},"config":{"eventKey":{"type":"string","default":"","label":"Event key","description":"Stable key naming the event this gate checks preferences for (e.g. 'BudgetThreshold' — the std-finance-tracker NotifyOnEventListener convention). A blank CHECK_PREFERENCE payload eventKey falls back to this value. Preference rows whose eventKey is blank apply to every event.","synonyms":"preference key, event name, subscription key, notification topic","tier":"policy"}},"scope":"instance"}],"pages":[{"name":"NotificationPreferencesPage","id":"pag_6W0NNSR5Q52VJS8XT54FA9ZZQ7","path":"/notification-preferences","traits":[{"ref":"PreferencesManage","refId":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6"},{"ref":"PreferenceCreate","refId":"trt_DDXED3J0X50EJSSVHE251PQMSF"},{"ref":"PreferenceEdit","refId":"trt_FKR1971TV5XDJX6VJN4KBC9ST9"},{"ref":"PreferenceGate","refId":"trt_PXP894680X40EPGEPPTV82D4NA"}]}],"types":{"ItemAction":[{"name":"label","type":"string","required":true},{"name":"event","type":"event"},{"name":"variant","type":"string"},{"name":"icon","type":"string"},{"name":"roles","type":"[string]"},{"name":"when","type":"SExpr"}]}}],"schemaVersion":1,"ledger":{"schemaVersion":1,"entries":{"ent_1C83HNBAWSNECQZAW3M95G502V":{"id":"ent_1C83HNBAWSNECQZAW3M95G502V","kind":"entity","bakedName":"GateView","curName":"GateView","renames":[],"owner":"workspace"},"ent_9XXV1AFA93N4HQM643KWYXGVCQ":{"id":"ent_9XXV1AFA93N4HQM643KWYXGVCQ","kind":"entity","bakedName":"NotificationPreference","curName":"NotificationPreference","renames":[],"owner":"workspace"},"evt_2ZG8HA6ACP56BDNCZJTQ751VMZ":{"id":"evt_2ZG8HA6ACP56BDNCZJTQ751VMZ","kind":"event","bakedName":"PREFERENCE_CHECK_FAILED","curName":"PREFERENCE_CHECK_FAILED","renames":[],"owner":"workspace","parent":"trt_PXP894680X40EPGEPPTV82D4NA"},"evt_5GXQHQDMT4TD288ZZFRRZBXRA0":{"id":"evt_5GXQHQDMT4TD288ZZFRRZBXRA0","kind":"event","bakedName":"PreferenceSaveFailed","curName":"PreferenceSaveFailed","renames":[],"owner":"workspace","parent":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6"},"evt_6CC20NBAWGNE84TH4SHSE7F8QF":{"id":"evt_6CC20NBAWGNE84TH4SHSE7F8QF","kind":"event","bakedName":"CHECK_PREFERENCE","curName":"CHECK_PREFERENCE","renames":[],"owner":"workspace","parent":"trt_PXP894680X40EPGEPPTV82D4NA"},"evt_7R59HX8RR1CC0XEY97RGY3NQ3C":{"id":"evt_7R59HX8RR1CC0XEY97RGY3NQ3C","kind":"event","bakedName":"INIT","curName":"INIT","renames":[],"owner":"workspace","parent":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6"},"evt_93DE8SY3YA1Z57W1PEPZ7HP8MM":{"id":"evt_93DE8SY3YA1Z57W1PEPZ7HP8MM","kind":"event","bakedName":"PreferenceSaved","curName":"PreferenceSaved","renames":[],"owner":"workspace","parent":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6"},"evt_9AJYN9CVH8DRMEPKPB0PVPF6F1":{"id":"evt_9AJYN9CVH8DRMEPKPB0PVPF6F1","kind":"event","bakedName":"RETRY","curName":"RETRY","renames":[],"owner":"workspace","parent":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6"},"evt_ACVDGSM8CA465B22X38EKHR52A":{"id":"evt_ACVDGSM8CA465B22X38EKHR52A","kind":"event","bakedName":"DO_CREATE","curName":"DO_CREATE","renames":[],"owner":"workspace","parent":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6"},"evt_DAJMYWXBYANZ57Z1W1J5C3BM4V":{"id":"evt_DAJMYWXBYANZ57Z1W1J5C3BM4V","kind":"event","bakedName":"EDIT","curName":"EDIT","renames":[],"owner":"workspace","parent":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6"},"evt_FKJ2ZZ927TH3X0HYSYJRARQFJV":{"id":"evt_FKJ2ZZ927TH3X0HYSYJRARQFJV","kind":"event","bakedName":"PREFERENCE_ROWS_LOADED","curName":"PREFERENCE_ROWS_LOADED","renames":[],"owner":"workspace","parent":"trt_PXP894680X40EPGEPPTV82D4NA"},"evt_GTAPK71SV3WXHT3H6FKF9BHRM7":{"id":"evt_GTAPK71SV3WXHT3H6FKF9BHRM7","kind":"event","bakedName":"PreferenceDeleted","curName":"PreferenceDeleted","renames":[],"owner":"workspace","parent":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6"},"evt_HF6KA8J0V10DGX5HMWW7WAEPC9":{"id":"evt_HF6KA8J0V10DGX5HMWW7WAEPC9","kind":"event","bakedName":"DELETE","curName":"DELETE","renames":[],"owner":"workspace","parent":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6"},"evt_KBVBFG78TZMDFW4K2SBYR69RTY":{"id":"evt_KBVBFG78TZMDFW4K2SBYR69RTY","kind":"event","bakedName":"PreferencesLoadFailed","curName":"PreferencesLoadFailed","renames":[],"owner":"workspace","parent":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6"},"evt_MFSTF3R5AZ2NFQKR132ZRQMHG9":{"id":"evt_MFSTF3R5AZ2NFQKR132ZRQMHG9","kind":"event","bakedName":"PREFERENCE_RESOLVED","curName":"PREFERENCE_RESOLVED","renames":[],"owner":"workspace","parent":"trt_PXP894680X40EPGEPPTV82D4NA"},"evt_P1ASTZKBS8NWMCEFB5PAY3Y362":{"id":"evt_P1ASTZKBS8NWMCEFB5PAY3Y362","kind":"event","bakedName":"DO_UPDATE","curName":"DO_UPDATE","renames":[],"owner":"workspace","parent":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6"},"evt_QW6JNB276X3KEQ4BNT5WB754A3":{"id":"evt_QW6JNB276X3KEQ4BNT5WB754A3","kind":"event","bakedName":"CREATE","curName":"CREATE","renames":[],"owner":"workspace","parent":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6"},"evt_XF6P2M2MMWAAE0R2MZVSP9WJE4":{"id":"evt_XF6P2M2MMWAAE0R2MZVSP9WJE4","kind":"event","bakedName":"PreferencesLoaded","curName":"PreferencesLoaded","renames":[],"owner":"workspace","parent":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6"},"orb_NY862D5QC2VP19PHB5CKGQH8F5":{"id":"orb_NY862D5QC2VP19PHB5CKGQH8F5","kind":"orbital","bakedName":"NotificationPreferencesOrbital","curName":"NotificationPreferencesOrbital","renames":[],"owner":"workspace"},"pag_6W0NNSR5Q52VJS8XT54FA9ZZQ7":{"id":"pag_6W0NNSR5Q52VJS8XT54FA9ZZQ7","kind":"page","bakedName":"NotificationPreferencesPage","curName":"NotificationPreferencesPage","renames":[],"owner":"workspace"},"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6":{"id":"trt_ABWPDWTZQAFVN7YT5KG1QP24Y6","kind":"trait","bakedName":"PreferencesManage","curName":"PreferencesManage","renames":[],"owner":"workspace"},"trt_DDXED3J0X50EJSSVHE251PQMSF":{"id":"trt_DDXED3J0X50EJSSVHE251PQMSF","kind":"trait","bakedName":"PreferenceCreate","curName":"PreferenceCreate","renames":[],"owner":"workspace"},"trt_FKR1971TV5XDJX6VJN4KBC9ST9":{"id":"trt_FKR1971TV5XDJX6VJN4KBC9ST9","kind":"trait","bakedName":"PreferenceEdit","curName":"PreferenceEdit","renames":[],"owner":"workspace"},"trt_PXP894680X40EPGEPPTV82D4NA":{"id":"trt_PXP894680X40EPGEPPTV82D4NA","kind":"trait","bakedName":"PreferenceGate","curName":"PreferenceGate","renames":[],"owner":"workspace"}}}}