open-loam 0.1.0 → 0.2.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 (273) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +48 -8
  3. data/LICENSE +1 -1
  4. data/README.md +24 -24
  5. data/app/jobs/{loam → open_loam}/custom_field_reindex_job.rb +6 -6
  6. data/app/jobs/{loam → open_loam}/event_delivery_job.rb +8 -8
  7. data/app/jobs/{loam → open_loam}/event_redelivery_sweep_job.rb +4 -4
  8. data/app/jobs/{loam → open_loam}/webhook_delivery_job.rb +7 -7
  9. data/app/models/{loam → open_loam}/api_token.rb +7 -7
  10. data/app/models/{loam → open_loam}/audit_record.rb +3 -3
  11. data/app/models/{loam → open_loam}/auth_attempt.rb +5 -5
  12. data/app/models/{loam → open_loam}/business_rule.rb +10 -10
  13. data/app/models/{loam → open_loam}/business_rule_run.rb +5 -5
  14. data/app/models/{loam → open_loam}/comment.rb +9 -9
  15. data/app/models/{loam → open_loam}/config.rb +7 -7
  16. data/app/models/{loam → open_loam}/custom_field_value.rb +5 -5
  17. data/app/models/{loam → open_loam}/dashboard_widget.rb +5 -5
  18. data/app/models/open_loam/dictionary.rb +20 -0
  19. data/app/models/{loam → open_loam}/dictionary_entry.rb +7 -7
  20. data/app/models/{loam → open_loam}/event_delivery.rb +4 -4
  21. data/app/models/{loam → open_loam}/field_definition.rb +8 -8
  22. data/app/models/{loam → open_loam}/inbound_webhook_delivery.rb +4 -4
  23. data/app/models/{loam → open_loam}/inbound_webhook_source.rb +13 -13
  24. data/app/models/{loam → open_loam}/membership.rb +6 -6
  25. data/app/models/{loam → open_loam}/mfa_credential.rb +8 -8
  26. data/app/models/{loam → open_loam}/notification.rb +10 -10
  27. data/app/models/{loam → open_loam}/pending_action.rb +23 -23
  28. data/app/models/{loam → open_loam}/perspective.rb +5 -5
  29. data/app/models/{loam → open_loam}/progress_job.rb +7 -7
  30. data/app/models/{loam → open_loam}/record_lock.rb +5 -5
  31. data/app/models/{loam → open_loam}/scheduled_job.rb +7 -7
  32. data/app/models/open_loam/search_token.rb +9 -0
  33. data/app/models/{loam → open_loam}/sso_identity.rb +4 -4
  34. data/app/models/{loam → open_loam}/sso_provider.rb +8 -8
  35. data/app/models/open_loam/tenant.rb +20 -0
  36. data/app/models/{loam → open_loam}/translation.rb +5 -5
  37. data/app/models/{loam → open_loam}/webhook_endpoint.rb +6 -6
  38. data/app/views/{loam → open_loam}/attachments/_attachments.html.erb +1 -1
  39. data/app/views/{loam → open_loam}/comments/_comments.html.erb +1 -1
  40. data/app/views/{loam → open_loam}/custom_fields/_fields.html.erb +2 -2
  41. data/lib/generators/{loam → open_loam}/entity/entity_generator.rb +9 -9
  42. data/lib/generators/{loam → open_loam}/entity/templates/api_controller.rb +1 -1
  43. data/lib/generators/{loam → open_loam}/entity/templates/controller.rb +21 -21
  44. data/lib/generators/{loam → open_loam}/entity/templates/entity_test.rb +12 -12
  45. data/lib/generators/{loam → open_loam}/entity/templates/migration.rb +5 -5
  46. data/lib/generators/{loam → open_loam}/entity/templates/model.rb +10 -10
  47. data/lib/generators/{loam → open_loam}/entity/templates/policy.rb +1 -1
  48. data/lib/generators/{loam → open_loam}/entity/templates/views/_form.html.erb +4 -4
  49. data/lib/generators/{loam → open_loam}/entity/templates/views/deleted.html.erb +7 -7
  50. data/lib/generators/open_loam/entity/templates/views/edit.html.erb +3 -0
  51. data/lib/generators/open_loam/entity/templates/views/index.html.erb +90 -0
  52. data/lib/generators/open_loam/entity/templates/views/new.html.erb +3 -0
  53. data/lib/generators/open_loam/entity/templates/views/show.html.erb +36 -0
  54. data/lib/generators/{loam → open_loam}/install/install_generator.rb +47 -47
  55. data/lib/generators/open_loam/install/templates/AGENTS.md +341 -0
  56. data/lib/generators/{loam → open_loam}/install/templates/admin/api_docs_controller.rb +2 -2
  57. data/lib/generators/{loam → open_loam}/install/templates/admin/api_docs_index.html.erb +1 -1
  58. data/lib/generators/{loam → open_loam}/install/templates/admin/api_tokens_controller.rb +1 -1
  59. data/lib/generators/{loam → open_loam}/install/templates/admin/base_controller.rb +38 -38
  60. data/lib/generators/{loam → open_loam}/install/templates/admin/business_rules_controller.rb +7 -7
  61. data/lib/generators/{loam → open_loam}/install/templates/admin/business_rules_form.html.erb +2 -2
  62. data/lib/generators/{loam → open_loam}/install/templates/admin/comments_controller.rb +4 -4
  63. data/lib/generators/{loam → open_loam}/install/templates/admin/configs_controller.rb +9 -9
  64. data/lib/generators/open_loam/install/templates/admin/dashboard_controller.rb +10 -0
  65. data/lib/generators/{loam → open_loam}/install/templates/admin/dashboard_widgets_controller.rb +5 -5
  66. data/lib/generators/{loam → open_loam}/install/templates/admin/dictionaries_controller.rb +5 -5
  67. data/lib/generators/{loam → open_loam}/install/templates/admin/dictionaries_form.html.erb +1 -1
  68. data/lib/generators/{loam → open_loam}/install/templates/admin/dictionary_entries_controller.rb +2 -2
  69. data/lib/generators/{loam → open_loam}/install/templates/admin/event_deliveries_controller.rb +5 -5
  70. data/lib/generators/{loam → open_loam}/install/templates/admin/event_deliveries_index.html.erb +1 -1
  71. data/lib/generators/{loam → open_loam}/install/templates/admin/events_controller.rb +5 -5
  72. data/lib/generators/{loam → open_loam}/install/templates/admin/features_controller.rb +9 -9
  73. data/lib/generators/{loam → open_loam}/install/templates/admin/field_definitions_controller.rb +5 -5
  74. data/lib/generators/{loam → open_loam}/install/templates/admin/field_definitions_new.html.erb +2 -2
  75. data/lib/generators/{loam → open_loam}/install/templates/admin/history_controller.rb +7 -7
  76. data/lib/generators/{loam → open_loam}/install/templates/admin/history_index.html.erb +1 -1
  77. data/lib/generators/{loam → open_loam}/install/templates/admin/imports_controller.rb +12 -12
  78. data/lib/generators/{loam → open_loam}/install/templates/admin/inbound_webhook_sources_controller.rb +6 -6
  79. data/lib/generators/{loam → open_loam}/install/templates/admin/inbound_webhook_sources_new.html.erb +2 -2
  80. data/lib/generators/open_loam/install/templates/admin/layout.html.erb +76 -0
  81. data/lib/generators/{loam → open_loam}/install/templates/admin/mfa_controller.rb +6 -6
  82. data/lib/generators/{loam → open_loam}/install/templates/admin/notifications_controller.rb +3 -3
  83. data/lib/generators/{loam → open_loam}/install/templates/admin/overrides_controller.rb +3 -3
  84. data/lib/generators/{loam → open_loam}/install/templates/admin/overrides_index.html.erb +2 -2
  85. data/lib/generators/{loam → open_loam}/install/templates/admin/pending_actions_controller.rb +3 -3
  86. data/lib/generators/{loam → open_loam}/install/templates/admin/perspectives_controller.rb +7 -7
  87. data/lib/generators/{loam → open_loam}/install/templates/admin/perspectives_index.html.erb +1 -1
  88. data/lib/generators/open_loam/install/templates/admin/progress_jobs_controller.rb +19 -0
  89. data/lib/generators/{loam → open_loam}/install/templates/admin/progress_jobs_index.html.erb +1 -1
  90. data/lib/generators/{loam → open_loam}/install/templates/admin/record_locks_controller.rb +4 -4
  91. data/lib/generators/{loam → open_loam}/install/templates/admin/scheduled_jobs_controller.rb +7 -7
  92. data/lib/generators/{loam → open_loam}/install/templates/admin/scheduled_jobs_form.html.erb +1 -1
  93. data/lib/generators/{loam → open_loam}/install/templates/admin/scheduled_jobs_index.html.erb +1 -1
  94. data/lib/generators/{loam → open_loam}/install/templates/admin/search_controller.rb +5 -5
  95. data/lib/generators/{loam → open_loam}/install/templates/admin/sessions_controller.rb +32 -32
  96. data/lib/generators/{loam → open_loam}/install/templates/admin/sso_providers_controller.rb +6 -6
  97. data/lib/generators/{loam → open_loam}/install/templates/admin/sso_providers_form.html.erb +2 -2
  98. data/lib/generators/{loam → open_loam}/install/templates/admin/sudo_controller.rb +5 -5
  99. data/lib/generators/{loam → open_loam}/install/templates/admin/sudo_new.html.erb +1 -1
  100. data/lib/generators/{loam → open_loam}/install/templates/admin/translations_controller.rb +7 -7
  101. data/lib/generators/{loam → open_loam}/install/templates/admin/translations_index.html.erb +3 -3
  102. data/lib/generators/{loam → open_loam}/install/templates/admin/webhook_endpoints_controller.rb +4 -4
  103. data/lib/generators/{loam → open_loam}/install/templates/admin/webhook_endpoints_index.html.erb +1 -1
  104. data/lib/generators/{loam → open_loam}/install/templates/admin.css +1 -1
  105. data/lib/generators/{loam → open_loam}/install/templates/api_base_controller.rb +15 -15
  106. data/lib/generators/{loam → open_loam}/install/templates/guardrails_test.rb +17 -17
  107. data/lib/generators/{loam → open_loam}/install/templates/import_job.rb +7 -7
  108. data/lib/generators/{loam → open_loam}/install/templates/inbound_webhooks_controller.rb +4 -4
  109. data/lib/generators/{loam → open_loam}/install/templates/initializer.rb +74 -74
  110. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_api_tokens.rb +15 -0
  111. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_audit_records.rb +14 -0
  112. data/lib/generators/{loam/install/templates/migrations/create_loam_auth_attempts.rb → open_loam/install/templates/migrations/create_open_loam_auth_attempts.rb} +3 -3
  113. data/lib/generators/{loam/install/templates/migrations/create_loam_business_rules.rb → open_loam/install/templates/migrations/create_open_loam_business_rules.rb} +10 -10
  114. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_comments.rb +13 -0
  115. data/lib/generators/{loam/install/templates/migrations/create_loam_configs.rb → open_loam/install/templates/migrations/create_open_loam_configs.rb} +7 -7
  116. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_custom_field_values.rb +19 -0
  117. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_dashboard_widgets.rb +12 -0
  118. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_dictionaries.rb +11 -0
  119. data/lib/generators/{loam/install/templates/migrations/create_loam_dictionary_entries.rb → open_loam/install/templates/migrations/create_open_loam_dictionary_entries.rb} +6 -6
  120. data/lib/generators/{loam/install/templates/migrations/create_loam_event_deliveries.rb → open_loam/install/templates/migrations/create_open_loam_event_deliveries.rb} +5 -5
  121. data/lib/generators/{loam/install/templates/migrations/create_loam_field_definitions.rb → open_loam/install/templates/migrations/create_open_loam_field_definitions.rb} +4 -4
  122. data/lib/generators/{loam/install/templates/migrations/create_loam_inbound_webhooks.rb → open_loam/install/templates/migrations/create_open_loam_inbound_webhooks.rb} +9 -9
  123. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_memberships.rb +11 -0
  124. data/lib/generators/{loam/install/templates/migrations/create_loam_mfa_credentials.rb → open_loam/install/templates/migrations/create_open_loam_mfa_credentials.rb} +4 -4
  125. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_notifications.rb +15 -0
  126. data/lib/generators/{loam/install/templates/migrations/create_loam_pending_actions.rb → open_loam/install/templates/migrations/create_open_loam_pending_actions.rb} +9 -9
  127. data/lib/generators/{loam/install/templates/migrations/create_loam_perspectives.rb → open_loam/install/templates/migrations/create_open_loam_perspectives.rb} +5 -5
  128. data/lib/generators/{loam/install/templates/migrations/create_loam_progress_jobs.rb → open_loam/install/templates/migrations/create_open_loam_progress_jobs.rb} +5 -5
  129. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_record_locks.rb +16 -0
  130. data/lib/generators/{loam/install/templates/migrations/create_loam_scheduled_jobs.rb → open_loam/install/templates/migrations/create_open_loam_scheduled_jobs.rb} +5 -5
  131. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_search_tokens.rb +18 -0
  132. data/lib/generators/{loam/install/templates/migrations/create_loam_sso_providers.rb → open_loam/install/templates/migrations/create_open_loam_sso_providers.rb} +12 -12
  133. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_tenants.rb +9 -0
  134. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_translations.rb +15 -0
  135. data/lib/generators/open_loam/install/templates/migrations/create_open_loam_webhook_endpoints.rb +13 -0
  136. data/lib/generators/{loam → open_loam}/install/templates/migrations/create_users.rb +1 -1
  137. data/lib/generators/{loam → open_loam}/install/templates/user.rb +5 -5
  138. data/lib/generators/{loam → open_loam}/primary_key_options.rb +23 -23
  139. data/lib/open-loam.rb +2 -2
  140. data/lib/{loam → open_loam}/attachable.rb +4 -4
  141. data/lib/{loam → open_loam}/auditable.rb +23 -23
  142. data/lib/{loam → open_loam}/auth_throttle.rb +10 -10
  143. data/lib/{loam → open_loam}/base32.rb +1 -1
  144. data/lib/{loam → open_loam}/bulk.rb +7 -7
  145. data/lib/{loam → open_loam}/business_rules/actions.rb +7 -7
  146. data/lib/{loam → open_loam}/business_rules/condition.rb +5 -5
  147. data/lib/{loam → open_loam}/business_rules.rb +19 -19
  148. data/lib/{loam → open_loam}/commentable.rb +6 -6
  149. data/lib/{loam → open_loam}/configs.rb +19 -19
  150. data/lib/{loam → open_loam}/cron.rb +2 -2
  151. data/lib/{loam → open_loam}/csv.rb +2 -2
  152. data/lib/{loam → open_loam}/current.rb +5 -5
  153. data/lib/{loam → open_loam}/custom_field_index.rb +23 -23
  154. data/lib/{loam → open_loam}/custom_fields.rb +17 -17
  155. data/lib/{loam → open_loam}/dashboard.rb +5 -5
  156. data/lib/{loam → open_loam}/dictionaries.rb +12 -12
  157. data/lib/{loam → open_loam}/durable_events.rb +19 -19
  158. data/lib/{loam → open_loam}/encryptable.rb +33 -33
  159. data/lib/{loam → open_loam}/encryption/cipher.rb +3 -3
  160. data/lib/{loam → open_loam}/encryption/key_provider.rb +3 -3
  161. data/lib/{loam → open_loam}/encryption.rb +11 -11
  162. data/lib/open_loam/engine.rb +57 -0
  163. data/lib/{loam → open_loam}/enrichers.rb +5 -5
  164. data/lib/{loam → open_loam}/errors.rb +10 -10
  165. data/lib/{loam → open_loam}/eval.rb +2 -2
  166. data/lib/{loam → open_loam}/event_stream.rb +14 -14
  167. data/lib/{loam → open_loam}/eventful.rb +12 -12
  168. data/lib/{loam → open_loam}/events.rb +5 -5
  169. data/lib/{loam → open_loam}/export.rb +8 -8
  170. data/lib/{loam → open_loam}/features.rb +15 -15
  171. data/lib/{loam → open_loam}/generated_key.rb +6 -6
  172. data/lib/{loam → open_loam}/import.rb +12 -12
  173. data/lib/{loam → open_loam}/inbound_webhooks.rb +7 -7
  174. data/lib/{loam → open_loam}/lifecycle.rb +25 -25
  175. data/lib/{loam/locales/loam.en.yml → open_loam/locales/open_loam.en.yml} +5 -5
  176. data/lib/{loam → open_loam}/mcp/server.rb +9 -9
  177. data/lib/{loam → open_loam}/mcp.rb +21 -21
  178. data/lib/{loam → open_loam}/notifications.rb +5 -5
  179. data/lib/{loam → open_loam}/open_api.rb +16 -16
  180. data/lib/{loam → open_loam}/overrides.rb +10 -10
  181. data/lib/{loam → open_loam}/pending_actions.rb +9 -9
  182. data/lib/{loam → open_loam}/permissions.rb +8 -8
  183. data/lib/{loam → open_loam}/perspectives.rb +9 -9
  184. data/lib/{loam → open_loam}/policy.rb +6 -6
  185. data/lib/{loam → open_loam}/progress.rb +6 -6
  186. data/lib/{loam → open_loam}/record_locks.rb +9 -9
  187. data/lib/{loam → open_loam}/scheduler.rb +20 -20
  188. data/lib/{loam → open_loam}/search/driver.rb +3 -3
  189. data/lib/{loam → open_loam}/search/like_driver.rb +5 -5
  190. data/lib/{loam → open_loam}/search/token_driver.rb +15 -15
  191. data/lib/{loam → open_loam}/search.rb +5 -5
  192. data/lib/{loam → open_loam}/searchable.rb +22 -22
  193. data/lib/{loam → open_loam}/soft_deletable.rb +10 -10
  194. data/lib/{loam → open_loam}/sso/claims.rb +1 -1
  195. data/lib/{loam → open_loam}/sso/fake_provider.rb +1 -1
  196. data/lib/{loam → open_loam}/sso/http_client.rb +3 -3
  197. data/lib/{loam → open_loam}/sso/oidc_provider.rb +2 -2
  198. data/lib/{loam → open_loam}/sso.rb +17 -17
  199. data/lib/{loam → open_loam}/telemetry.rb +6 -6
  200. data/lib/{loam → open_loam}/tenant_record.rb +10 -10
  201. data/lib/{loam → open_loam}/test_helpers.rb +4 -4
  202. data/lib/{loam → open_loam}/totp.rb +3 -3
  203. data/lib/{loam → open_loam}/translatable.rb +24 -24
  204. data/lib/{loam → open_loam}/undo.rb +11 -11
  205. data/lib/open_loam/version.rb +3 -0
  206. data/lib/{loam → open_loam}/webhooks.rb +4 -4
  207. data/lib/{loam → open_loam}/widgets.rb +9 -9
  208. data/lib/{loam → open_loam}/workflow.rb +45 -45
  209. data/lib/open_loam.rb +122 -0
  210. data/lib/tasks/{loam.rake → open_loam.rake} +43 -43
  211. data/lib/tasks/{loam_eval.rake → open_loam_eval.rake} +7 -7
  212. data/lib/tasks/open_loam_mcp.rake +20 -0
  213. metadata +242 -242
  214. data/app/models/loam/dictionary.rb +0 -20
  215. data/app/models/loam/search_token.rb +0 -9
  216. data/app/models/loam/tenant.rb +0 -20
  217. data/lib/generators/loam/entity/templates/views/edit.html.erb +0 -3
  218. data/lib/generators/loam/entity/templates/views/index.html.erb +0 -90
  219. data/lib/generators/loam/entity/templates/views/new.html.erb +0 -3
  220. data/lib/generators/loam/entity/templates/views/show.html.erb +0 -36
  221. data/lib/generators/loam/install/templates/AGENTS.md +0 -341
  222. data/lib/generators/loam/install/templates/admin/dashboard_controller.rb +0 -10
  223. data/lib/generators/loam/install/templates/admin/layout.html.erb +0 -76
  224. data/lib/generators/loam/install/templates/admin/progress_jobs_controller.rb +0 -19
  225. data/lib/generators/loam/install/templates/migrations/create_loam_api_tokens.rb +0 -15
  226. data/lib/generators/loam/install/templates/migrations/create_loam_audit_records.rb +0 -14
  227. data/lib/generators/loam/install/templates/migrations/create_loam_comments.rb +0 -13
  228. data/lib/generators/loam/install/templates/migrations/create_loam_custom_field_values.rb +0 -19
  229. data/lib/generators/loam/install/templates/migrations/create_loam_dashboard_widgets.rb +0 -12
  230. data/lib/generators/loam/install/templates/migrations/create_loam_dictionaries.rb +0 -11
  231. data/lib/generators/loam/install/templates/migrations/create_loam_memberships.rb +0 -11
  232. data/lib/generators/loam/install/templates/migrations/create_loam_notifications.rb +0 -15
  233. data/lib/generators/loam/install/templates/migrations/create_loam_record_locks.rb +0 -16
  234. data/lib/generators/loam/install/templates/migrations/create_loam_search_tokens.rb +0 -18
  235. data/lib/generators/loam/install/templates/migrations/create_loam_tenants.rb +0 -9
  236. data/lib/generators/loam/install/templates/migrations/create_loam_translations.rb +0 -15
  237. data/lib/generators/loam/install/templates/migrations/create_loam_webhook_endpoints.rb +0 -13
  238. data/lib/loam/engine.rb +0 -57
  239. data/lib/loam/version.rb +0 -3
  240. data/lib/loam.rb +0 -122
  241. data/lib/tasks/loam_mcp.rake +0 -20
  242. /data/lib/generators/{loam → open_loam}/install/templates/admin/api_tokens_index.html.erb +0 -0
  243. /data/lib/generators/{loam → open_loam}/install/templates/admin/business_rules_edit.html.erb +0 -0
  244. /data/lib/generators/{loam → open_loam}/install/templates/admin/business_rules_index.html.erb +0 -0
  245. /data/lib/generators/{loam → open_loam}/install/templates/admin/business_rules_new.html.erb +0 -0
  246. /data/lib/generators/{loam → open_loam}/install/templates/admin/configs_edit.html.erb +0 -0
  247. /data/lib/generators/{loam → open_loam}/install/templates/admin/configs_index.html.erb +0 -0
  248. /data/lib/generators/{loam → open_loam}/install/templates/admin/dashboard_index.html.erb +0 -0
  249. /data/lib/generators/{loam → open_loam}/install/templates/admin/dashboard_widgets_index.html.erb +0 -0
  250. /data/lib/generators/{loam → open_loam}/install/templates/admin/dictionaries_edit.html.erb +0 -0
  251. /data/lib/generators/{loam → open_loam}/install/templates/admin/dictionaries_index.html.erb +0 -0
  252. /data/lib/generators/{loam → open_loam}/install/templates/admin/dictionaries_new.html.erb +0 -0
  253. /data/lib/generators/{loam → open_loam}/install/templates/admin/features_index.html.erb +0 -0
  254. /data/lib/generators/{loam → open_loam}/install/templates/admin/field_definitions_index.html.erb +0 -0
  255. /data/lib/generators/{loam → open_loam}/install/templates/admin/imports_new.html.erb +0 -0
  256. /data/lib/generators/{loam → open_loam}/install/templates/admin/imports_preview.html.erb +0 -0
  257. /data/lib/generators/{loam → open_loam}/install/templates/admin/imports_summary.html.erb +0 -0
  258. /data/lib/generators/{loam → open_loam}/install/templates/admin/inbound_webhook_sources_index.html.erb +0 -0
  259. /data/lib/generators/{loam → open_loam}/install/templates/admin/mfa_activated.html.erb +0 -0
  260. /data/lib/generators/{loam → open_loam}/install/templates/admin/mfa_new.html.erb +0 -0
  261. /data/lib/generators/{loam → open_loam}/install/templates/admin/mfa_show.html.erb +0 -0
  262. /data/lib/generators/{loam → open_loam}/install/templates/admin/notifications_index.html.erb +0 -0
  263. /data/lib/generators/{loam → open_loam}/install/templates/admin/pagination.rb +0 -0
  264. /data/lib/generators/{loam → open_loam}/install/templates/admin/pending_actions_index.html.erb +0 -0
  265. /data/lib/generators/{loam → open_loam}/install/templates/admin/scheduled_jobs_edit.html.erb +0 -0
  266. /data/lib/generators/{loam → open_loam}/install/templates/admin/scheduled_jobs_new.html.erb +0 -0
  267. /data/lib/generators/{loam → open_loam}/install/templates/admin/search_index.html.erb +0 -0
  268. /data/lib/generators/{loam → open_loam}/install/templates/admin/sessions_mfa_challenge.html.erb +0 -0
  269. /data/lib/generators/{loam → open_loam}/install/templates/admin/sessions_new.html.erb +0 -0
  270. /data/lib/generators/{loam → open_loam}/install/templates/admin/sso_providers_edit.html.erb +0 -0
  271. /data/lib/generators/{loam → open_loam}/install/templates/admin/sso_providers_index.html.erb +0 -0
  272. /data/lib/generators/{loam → open_loam}/install/templates/admin/sso_providers_new.html.erb +0 -0
  273. /data/lib/generators/{loam → open_loam}/install/templates/admin/webhook_endpoints_new.html.erb +0 -0
data/lib/open_loam.rb ADDED
@@ -0,0 +1,122 @@
1
+ require "open_loam/version"
2
+ require "open_loam/errors"
3
+ require "open_loam/current"
4
+ require "open_loam/events"
5
+ require "open_loam/policy"
6
+ require "open_loam/lifecycle"
7
+ require "open_loam/configs"
8
+ require "open_loam/features"
9
+ require "open_loam/auth_throttle"
10
+ require "open_loam/dictionaries"
11
+ require "open_loam/custom_field_index"
12
+ require "open_loam/undo"
13
+ require "open_loam/permissions"
14
+ require "open_loam/telemetry"
15
+ require "open_loam/eval"
16
+ require "open_loam/mcp"
17
+ require "open_loam/mcp/server"
18
+ require "open_loam/progress"
19
+ require "open_loam/cron"
20
+ require "open_loam/scheduler"
21
+ require "open_loam/csv"
22
+ require "open_loam/export"
23
+ require "open_loam/import"
24
+ require "open_loam/bulk"
25
+ require "open_loam/widgets"
26
+ require "open_loam/dashboard"
27
+ require "open_loam/overrides"
28
+ require "open_loam/open_api"
29
+ require "open_loam/encryption"
30
+ require "open_loam/base32"
31
+ require "open_loam/totp"
32
+ require "open_loam/pending_actions"
33
+ require "open_loam/perspectives"
34
+ require "open_loam/record_locks"
35
+ require "open_loam/event_stream"
36
+ require "open_loam/enrichers"
37
+ require "open_loam/search"
38
+ require "open_loam/search/driver"
39
+ require "open_loam/search/like_driver"
40
+ require "open_loam/search/token_driver"
41
+ require "open_loam/notifications"
42
+ require "open_loam/sso"
43
+ require "open_loam/business_rules"
44
+ require "open_loam/webhooks"
45
+ require "open_loam/inbound_webhooks"
46
+ require "open_loam/durable_events"
47
+ require "open_loam/engine" if defined?(Rails::Engine)
48
+
49
+ module OpenLoam
50
+ # The current tenant, or a loud failure. This is THE guardrail: tenant-scoped
51
+ # code paths call this, so a missing tenant context can never silently widen
52
+ # a query to all tenants.
53
+ def self.tenant!
54
+ Current.tenant or raise MissingTenantError
55
+ end
56
+
57
+ def self.tenant
58
+ Current.tenant
59
+ end
60
+
61
+ def self.actor
62
+ Current.actor
63
+ end
64
+
65
+ # Feature-string permission check for the current actor's role (see
66
+ # OpenLoam::Permissions) — deny-by-default, wildcard-aware. `role:` overrides the
67
+ # actor's role. Returns false with no actor/role.
68
+ def self.can?(permission, role: nil)
69
+ role ||= Current.actor && OpenLoam::Membership.find_by(user_id: Current.actor.id)&.role
70
+ OpenLoam::Permissions.allow?(role, permission)
71
+ end
72
+
73
+ # The approval-gate seam. When a caller runs under :confirm (an MCP tool acting
74
+ # for an AI agent), a write should be STAGED for human approval via
75
+ # OpenLoam::PendingActions.stage instead of committed. OpenLoam does not intercept
76
+ # Active Record globally — this is the documented hook a write path checks.
77
+ def self.mutation_mode
78
+ Current.mutation_mode || :direct
79
+ end
80
+
81
+ def self.require_confirmation?
82
+ mutation_mode == :confirm
83
+ end
84
+
85
+ # Run a block with writes gated for approval. The one blessed way to enter
86
+ # confirm-mode; restores the previous mode afterwards.
87
+ def self.with_confirmation
88
+ previous = Current.mutation_mode
89
+ Current.mutation_mode = :confirm
90
+ yield
91
+ ensure
92
+ Current.mutation_mode = previous
93
+ end
94
+
95
+ # Run a block inside a tenant (and optional actor) context, restoring the
96
+ # previous context afterwards. The one blessed way to switch tenants.
97
+ def self.as_tenant(tenant, actor: nil)
98
+ previous_tenant = Current.tenant
99
+ previous_actor = Current.actor
100
+ Current.tenant = tenant
101
+ Current.actor = actor if actor
102
+ yield
103
+ ensure
104
+ Current.tenant = previous_tenant
105
+ Current.actor = previous_actor
106
+ end
107
+ end
108
+
109
+ ActiveSupport.on_load(:active_record) do
110
+ require "open_loam/generated_key"
111
+ require "open_loam/tenant_record"
112
+ require "open_loam/auditable"
113
+ require "open_loam/soft_deletable"
114
+ require "open_loam/eventful"
115
+ require "open_loam/custom_fields"
116
+ require "open_loam/workflow"
117
+ require "open_loam/searchable"
118
+ require "open_loam/encryptable"
119
+ require "open_loam/translatable"
120
+ require "open_loam/commentable"
121
+ require "open_loam/attachable"
122
+ end
@@ -1,75 +1,75 @@
1
- namespace :loam do
2
- desc "Re-run every Loam.on_tenant_created callback for every existing tenant (idempotent)"
1
+ namespace :open_loam do
2
+ desc "Re-run every OpenLoam.on_tenant_created callback for every existing tenant (idempotent)"
3
3
  task sync: :environment do
4
- synced = Loam.sync_tenants!
5
- puts "loam:sync — ran #{Loam.tenant_created_callbacks.size} tenant callback(s) across #{synced} tenant(s)."
4
+ synced = OpenLoam.sync_tenants!
5
+ puts "open_loam:sync — ran #{OpenLoam.tenant_created_callbacks.size} tenant callback(s) across #{synced} tenant(s)."
6
6
  end
7
7
 
8
8
  namespace :openapi do
9
9
  # Write the OpenAPI 3.1 document + a Markdown rendering to disk, for CI or
10
10
  # publishing. Introspection only — no server, no network.
11
11
  #
12
- # bin/rails loam:openapi:export
12
+ # bin/rails open_loam:openapi:export
13
13
  desc "Export the API's OpenAPI JSON + Markdown to doc/"
14
14
  task export: :environment do
15
15
  require "json"
16
16
  dir = ENV["DIR"].presence || "doc"
17
17
  FileUtils.mkdir_p(dir)
18
- File.write(File.join(dir, "openapi.json"), JSON.pretty_generate(Loam::OpenApi.document))
19
- File.write(File.join(dir, "openapi.md"), Loam::OpenApi.markdown)
20
- puts "loam:openapi:export — wrote #{dir}/openapi.json and #{dir}/openapi.md."
18
+ File.write(File.join(dir, "openapi.json"), JSON.pretty_generate(OpenLoam::OpenApi.document))
19
+ File.write(File.join(dir, "openapi.md"), OpenLoam::OpenApi.markdown)
20
+ puts "open_loam:openapi:export — wrote #{dir}/openapi.json and #{dir}/openapi.md."
21
21
  end
22
22
  end
23
23
 
24
24
  namespace :scheduler do
25
25
  # Fire every due recurring job once. Wire to system cron, every minute:
26
- # * * * * * cd /app && bin/rails loam:scheduler:tick
26
+ # * * * * * cd /app && bin/rails open_loam:scheduler:tick
27
27
  # The claim is atomic, so running this from several hosts never double-fires
28
28
  # a job (Postgres SKIP LOCKED; SQLite serializes the single-process claim).
29
- desc "Enqueue every due Loam::ScheduledJob (run from cron)"
29
+ desc "Enqueue every due OpenLoam::ScheduledJob (run from cron)"
30
30
  task tick: :environment do
31
- fired = Loam::Scheduler.tick
32
- puts "loam:scheduler:tick — fired #{fired} scheduled job(s)."
31
+ fired = OpenLoam::Scheduler.tick
32
+ puts "open_loam:scheduler:tick — fired #{fired} scheduled job(s)."
33
33
  end
34
34
  end
35
35
 
36
36
  namespace :index do
37
- # Rebuild the custom-field read-model index (Loam::CustomFieldIndex) for every
37
+ # Rebuild the custom-field read-model index (OpenLoam::CustomFieldIndex) for every
38
38
  # entity with custom fields, in every tenant. Run once after enabling it so
39
39
  # existing rows are projected; new/updated records index themselves on save.
40
40
  #
41
- # bin/rails loam:index:reindex
41
+ # bin/rails open_loam:index:reindex
42
42
  desc "Rebuild the custom-field read-model index for every model in every tenant"
43
43
  task reindex: :environment do
44
44
  Rails.application.eager_load!
45
- models = Loam::TenantRecord.descendants.select do |model|
45
+ models = OpenLoam::TenantRecord.descendants.select do |model|
46
46
  model.name.present? && model.respond_to?(:custom_field_definitions)
47
47
  end
48
48
 
49
49
  tenants = 0
50
- Loam::Tenant.find_each do |tenant|
51
- Loam.as_tenant(tenant) { models.each { |model| Loam::CustomFieldIndex.reindex(model) } }
50
+ OpenLoam::Tenant.find_each do |tenant|
51
+ OpenLoam.as_tenant(tenant) { models.each { |model| OpenLoam::CustomFieldIndex.reindex(model) } }
52
52
  tenants += 1
53
53
  end
54
- puts "loam:index:reindex — rebuilt #{models.size} model(s) across #{tenants} tenant(s)."
54
+ puts "open_loam:index:reindex — rebuilt #{models.size} model(s) across #{tenants} tenant(s)."
55
55
  end
56
56
 
57
57
  # Report custom-field index coverage (indexed vs expected) per model/field
58
58
  # per tenant — the trust signal for whether the index is complete or drifting.
59
59
  #
60
- # bin/rails loam:index:coverage
60
+ # bin/rails open_loam:index:coverage
61
61
  desc "Report custom-field index coverage per model/field per tenant"
62
62
  task coverage: :environment do
63
63
  Rails.application.eager_load!
64
- models = Loam::TenantRecord.descendants.select do |model|
64
+ models = OpenLoam::TenantRecord.descendants.select do |model|
65
65
  model.name.present? && model.respond_to?(:custom_field_definitions)
66
66
  end
67
67
 
68
- Loam::Tenant.find_each do |tenant|
69
- Loam.as_tenant(tenant) do
68
+ OpenLoam::Tenant.find_each do |tenant|
69
+ OpenLoam.as_tenant(tenant) do
70
70
  models.each do |model|
71
71
  model.custom_field_definitions.find_each do |definition|
72
- c = Loam::CustomFieldIndex.coverage(model, definition.name)
72
+ c = OpenLoam::CustomFieldIndex.coverage(model, definition.name)
73
73
  flag = c[:complete] ? "ok" : "GAP"
74
74
  puts " [#{flag}] #{tenant.slug} #{model.name}.#{definition.name}: #{c[:indexed]}/#{c[:expected]} indexed"
75
75
  end
@@ -82,24 +82,24 @@ namespace :loam do
82
82
  namespace :search do
83
83
  # Rebuild the active driver's search index for every searchable model in
84
84
  # every tenant. Needed once after switching to a driver that keeps an index
85
- # (Loam::Search::TokenDriver): existing rows have no tokens until reindexed,
85
+ # (OpenLoam::Search::TokenDriver): existing rows have no tokens until reindexed,
86
86
  # while new and updated records index themselves on save. A no-op under the
87
87
  # default LikeDriver (its reindex does nothing), so it is always safe to run.
88
88
  #
89
- # bin/rails loam:search:reindex
89
+ # bin/rails open_loam:search:reindex
90
90
  desc "Rebuild the search index for every searchable model in every tenant"
91
91
  task reindex: :environment do
92
92
  Rails.application.eager_load!
93
- models = Loam::TenantRecord.descendants.select do |model|
94
- model.name.present? && model.respond_to?(:loam_searchable?) && model.loam_searchable?
93
+ models = OpenLoam::TenantRecord.descendants.select do |model|
94
+ model.name.present? && model.respond_to?(:open_loam_searchable?) && model.open_loam_searchable?
95
95
  end
96
96
 
97
97
  tenants = 0
98
- Loam::Tenant.find_each do |tenant|
99
- Loam.as_tenant(tenant) { models.each { |model| Loam::Search.reindex(model) } }
98
+ OpenLoam::Tenant.find_each do |tenant|
99
+ OpenLoam.as_tenant(tenant) { models.each { |model| OpenLoam::Search.reindex(model) } }
100
100
  tenants += 1
101
101
  end
102
- puts "loam:search:reindex — rebuilt #{models.size} model(s) across #{tenants} tenant(s) using #{Loam::Search.driver}."
102
+ puts "open_loam:search:reindex — rebuilt #{models.size} model(s) across #{tenants} tenant(s) using #{OpenLoam::Search.driver}."
103
103
  end
104
104
  end
105
105
 
@@ -110,20 +110,20 @@ namespace :loam do
110
110
  # coexist, so this can run incrementally without downtime. Each record is an
111
111
  # ordinary audited "[encrypted]" update.
112
112
  #
113
- # bin/rails loam:encryption:rotate[Customer,42]
113
+ # bin/rails open_loam:encryption:rotate[Customer,42]
114
114
  desc "Re-encrypt a model's encrypted fields for one tenant (rotation step)"
115
115
  task :rotate, %i[model tenant_id] => :environment do |_task, args|
116
116
  model = fetch_encryptable_model(args[:model])
117
- tenant = Loam::Tenant.find(args[:tenant_id])
117
+ tenant = OpenLoam::Tenant.find(args[:tenant_id])
118
118
 
119
119
  count = 0
120
- Loam.as_tenant(tenant) do
120
+ OpenLoam.as_tenant(tenant) do
121
121
  each_record(model) do |record|
122
- record.loam_reencrypt!
122
+ record.open_loam_reencrypt!
123
123
  count += 1
124
124
  end
125
125
  end
126
- puts "loam:encryption:rotate — re-encrypted #{count} #{model.name} record(s) in tenant #{tenant.slug}."
126
+ puts "open_loam:encryption:rotate — re-encrypted #{count} #{model.name} record(s) in tenant #{tenant.slug}."
127
127
  end
128
128
 
129
129
  # Decrypt and print one tenant's encrypted fields, e.g. for a GDPR data
@@ -132,15 +132,15 @@ namespace :loam do
132
132
  # a shell history that syncs), and only for a tenant you are authorized to
133
133
  # export.
134
134
  #
135
- # bin/rails loam:encryption:decrypt_dump[Customer,42]
135
+ # bin/rails open_loam:encryption:decrypt_dump[Customer,42]
136
136
  desc "Print decrypted encrypted-field values for one tenant (GDPR export; handle with care)"
137
137
  task :decrypt_dump, %i[model tenant_id] => :environment do |_task, args|
138
138
  require "json"
139
139
  model = fetch_encryptable_model(args[:model])
140
- tenant = Loam::Tenant.find(args[:tenant_id])
141
- fields = model.loam_encrypted_attributes
140
+ tenant = OpenLoam::Tenant.find(args[:tenant_id])
141
+ fields = model.open_loam_encrypted_attributes
142
142
 
143
- Loam.as_tenant(tenant) do
143
+ OpenLoam.as_tenant(tenant) do
144
144
  each_record(model) do |record|
145
145
  row = { id: record.id }.merge(fields.index_with { |field| record.public_send(field) })
146
146
  puts row.to_json
@@ -150,15 +150,15 @@ namespace :loam do
150
150
  end
151
151
  end
152
152
 
153
- # Resolve a model name to a class that actually uses Loam::Encryptable — a typo
153
+ # Resolve a model name to a class that actually uses OpenLoam::Encryptable — a typo
154
154
  # or a plain model should fail loudly, not silently dump/rotate nothing.
155
155
  def fetch_encryptable_model(name)
156
- # Force the app's classes (and Loam::TenantRecord, required lazily via the
156
+ # Force the app's classes (and OpenLoam::TenantRecord, required lazily via the
157
157
  # active_record on_load hook) to load before we constantize a model name.
158
158
  Rails.application.eager_load!
159
159
  model = name.to_s.constantize
160
- unless model.respond_to?(:loam_encrypted_attributes) && model.loam_encrypted_attributes.any?
161
- abort "#{name} does not `include Loam::Encryptable` with any `encrypts` fields."
160
+ unless model.respond_to?(:open_loam_encrypted_attributes) && model.open_loam_encrypted_attributes.any?
161
+ abort "#{name} does not `include OpenLoam::Encryptable` with any `encrypts` fields."
162
162
  end
163
163
  model
164
164
  end
@@ -1,23 +1,23 @@
1
1
  require "json"
2
2
  require "fileutils"
3
3
 
4
- namespace :loam do
4
+ namespace :open_loam do
5
5
  # Score the app's current test suite as a golden-task eval result and record it
6
- # under ai/benchmark_runs/ (L-303). Run this in a Loam app AFTER an agent (or
6
+ # under ai/benchmark_runs/ (L-303). Run this in a OpenLoam app AFTER an agent (or
7
7
  # you) has implemented a golden task:
8
8
  #
9
- # bin/rails "loam:eval[2]" # task 2, tests only
10
- # bin/rails "loam:eval[2,tenancy_leak:unscoped]" # note an invariant breach
9
+ # bin/rails "open_loam:eval[2]" # task 2, tests only
10
+ # bin/rails "open_loam:eval[2,tenancy_leak:unscoped]" # note an invariant breach
11
11
  #
12
12
  # Exits non-zero if the task did not pass, so it drops straight into CI.
13
- desc "Score the current test suite as a golden-task eval result (loam:eval[task,violation,violation,...])"
13
+ desc "Score the current test suite as a golden-task eval result (open_loam:eval[task,violation,violation,...])"
14
14
  task :eval, [ :task ] => :environment do |_task, args|
15
15
  task_id = args[:task] || "unspecified"
16
16
  violations = args.extras # any positional args after the task id are violations
17
17
 
18
18
  output = `bin/rails test 2>&1`
19
- summary = Loam::Eval.parse_summary(output)
20
- card = Loam::Eval.scorecard(task: task_id, summary: summary, violations: violations)
19
+ summary = OpenLoam::Eval.parse_summary(output)
20
+ card = OpenLoam::Eval.scorecard(task: task_id, summary: summary, violations: violations)
21
21
 
22
22
  dir = Rails.root.join("ai", "benchmark_runs")
23
23
  FileUtils.mkdir_p(dir)
@@ -0,0 +1,20 @@
1
+ require "logger"
2
+
3
+ namespace :open_loam do
4
+ namespace :mcp do
5
+ # Serve the OpenLoam MCP server over stdio. Point an MCP client (Claude Code,
6
+ # Cursor, Codex) at `bin/rails open_loam:mcp:serve` with OPEN_LOAM_MCP_TOKEN set to a
7
+ # OpenLoam API token — the agent then acts as that token's user, in that tenant.
8
+ #
9
+ # stdout carries JSON-RPC only; every log is sent to stderr so it can't
10
+ # corrupt the stream.
11
+ desc "Serve the OpenLoam MCP server over stdio (auth via OPEN_LOAM_MCP_TOKEN)"
12
+ task serve: :environment do
13
+ Rails.logger = Logger.new($stderr)
14
+ ActiveRecord::Base.logger = Rails.logger
15
+ $stdout.sync = true
16
+
17
+ OpenLoam::Mcp::Server.new.run
18
+ end
19
+ end
20
+ end