railwatch 0.9.4 → 1.1.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 (452) hide show
  1. checksums.yaml +4 -4
  2. data/AGENTS.md +37 -33
  3. data/CHANGELOG.md +63 -0
  4. data/README.md +51 -60
  5. data/config/routes.rb +0 -59
  6. data/docs/ai-and-mcp.md +9 -8
  7. data/docs/configuration.md +35 -66
  8. data/docs/faq.md +17 -25
  9. data/docs/getting-started.md +105 -117
  10. data/docs/replacing-nightwatch.md +8 -7
  11. data/docs/replacing-sentry.md +12 -16
  12. data/docs/security.md +14 -20
  13. data/docs/self-hosting.md +24 -22
  14. data/docs/testing.md +6 -14
  15. data/docs/troubleshooting.md +12 -46
  16. data/lib/generators/railwatch/install/install_generator.rb +12 -240
  17. data/lib/generators/railwatch/install/templates/initializer.rb.tt +10 -40
  18. data/lib/generators/railwatch/install/templates/post-deploy +0 -7
  19. data/lib/railwatch/authentication.rb +6 -5
  20. data/lib/railwatch/configuration.rb +18 -152
  21. data/lib/railwatch/engine.rb +9 -118
  22. data/lib/railwatch/patches.rb +0 -11
  23. data/lib/railwatch/reporter.rb +13 -20
  24. data/lib/railwatch/subscribers/process_info.rb +1 -2
  25. data/lib/railwatch/version.rb +1 -1
  26. data/lib/railwatch.rb +4 -62
  27. data/lib/tasks/railwatch_tasks.rake +3 -325
  28. data/llms.txt +23 -25
  29. metadata +3 -453
  30. data/app/channels/railwatch/environment_channel.rb +0 -62
  31. data/app/controllers/concerns/railwatch/telemetry_identity.rb +0 -25
  32. data/app/controllers/railwatch/alerts_controller.rb +0 -48
  33. data/app/controllers/railwatch/anomaly_rules_controller.rb +0 -31
  34. data/app/controllers/railwatch/attachments_controller.rb +0 -22
  35. data/app/controllers/railwatch/broadcasts_controller.rb +0 -15
  36. data/app/controllers/railwatch/cache_events_controller.rb +0 -30
  37. data/app/controllers/railwatch/commands_controller.rb +0 -16
  38. data/app/controllers/railwatch/comments_controller.rb +0 -11
  39. data/app/controllers/railwatch/dashboard_controller.rb +0 -70
  40. data/app/controllers/railwatch/deploys_controller.rb +0 -34
  41. data/app/controllers/railwatch/deprecations_controller.rb +0 -54
  42. data/app/controllers/railwatch/environment_scoped.rb +0 -81
  43. data/app/controllers/railwatch/exceptions_controller.rb +0 -52
  44. data/app/controllers/railwatch/executions_controller.rb +0 -13
  45. data/app/controllers/railwatch/issues_controller.rb +0 -258
  46. data/app/controllers/railwatch/jobs_controller.rb +0 -63
  47. data/app/controllers/railwatch/llm_calls_controller.rb +0 -124
  48. data/app/controllers/railwatch/logs_controller.rb +0 -40
  49. data/app/controllers/railwatch/mails_controller.rb +0 -19
  50. data/app/controllers/railwatch/notifications_controller.rb +0 -11
  51. data/app/controllers/railwatch/outgoing_requests_controller.rb +0 -19
  52. data/app/controllers/railwatch/overview_controller.rb +0 -38
  53. data/app/controllers/railwatch/people_controller.rb +0 -25
  54. data/app/controllers/railwatch/processes_controller.rb +0 -33
  55. data/app/controllers/railwatch/profiles_controller.rb +0 -65
  56. data/app/controllers/railwatch/queries_controller.rb +0 -59
  57. data/app/controllers/railwatch/releases_controller.rb +0 -75
  58. data/app/controllers/railwatch/requests_controller.rb +0 -37
  59. data/app/controllers/railwatch/saved_views_controller.rb +0 -53
  60. data/app/controllers/railwatch/scheduled_tasks_controller.rb +0 -45
  61. data/app/controllers/railwatch/spans_controller.rb +0 -47
  62. data/app/controllers/railwatch/storage_ops_controller.rb +0 -15
  63. data/app/controllers/railwatch/tenants_controller.rb +0 -44
  64. data/app/controllers/railwatch/thresholds_controller.rb +0 -47
  65. data/app/controllers/railwatch/traces_controller.rb +0 -72
  66. data/app/controllers/railwatch/transactions_controller.rb +0 -21
  67. data/app/controllers/railwatch/view_renders_controller.rb +0 -28
  68. data/app/controllers/railwatch/visits_controller.rb +0 -53
  69. data/app/frontend/components/app-content.tsx +0 -26
  70. data/app/frontend/components/app-logo-icon.tsx +0 -23
  71. data/app/frontend/components/app-logo.tsx +0 -14
  72. data/app/frontend/components/app-shell.tsx +0 -38
  73. data/app/frontend/components/app-sidebar-header.tsx +0 -54
  74. data/app/frontend/components/app-sidebar.tsx +0 -94
  75. data/app/frontend/components/app-wordmark.tsx +0 -29
  76. data/app/frontend/components/breadcrumbs.tsx +0 -46
  77. data/app/frontend/components/icon.tsx +0 -16
  78. data/app/frontend/components/input-error.tsx +0 -18
  79. data/app/frontend/components/nav-footer.tsx +0 -46
  80. data/app/frontend/components/nav-main.tsx +0 -41
  81. data/app/frontend/components/nav-user.tsx +0 -50
  82. data/app/frontend/components/railwatch/chart-hover.tsx +0 -34
  83. data/app/frontend/components/railwatch/chart-panel.tsx +0 -170
  84. data/app/frontend/components/railwatch/code.tsx +0 -28
  85. data/app/frontend/components/railwatch/command-palette.tsx +0 -132
  86. data/app/frontend/components/railwatch/copy-block.tsx +0 -52
  87. data/app/frontend/components/railwatch/copy-id.tsx +0 -49
  88. data/app/frontend/components/railwatch/cursor-load-more.tsx +0 -39
  89. data/app/frontend/components/railwatch/data-table.tsx +0 -195
  90. data/app/frontend/components/railwatch/digit-roll.tsx +0 -312
  91. data/app/frontend/components/railwatch/empty-state.tsx +0 -159
  92. data/app/frontend/components/railwatch/env-nav.tsx +0 -130
  93. data/app/frontend/components/railwatch/env-switcher.tsx +0 -145
  94. data/app/frontend/components/railwatch/filter-bar.tsx +0 -153
  95. data/app/frontend/components/railwatch/flamegraph.tsx +0 -324
  96. data/app/frontend/components/railwatch/frames.tsx +0 -295
  97. data/app/frontend/components/railwatch/json-viewer.tsx +0 -159
  98. data/app/frontend/components/railwatch/live-dot.tsx +0 -78
  99. data/app/frontend/components/railwatch/live-toggle.tsx +0 -76
  100. data/app/frontend/components/railwatch/metric-chart.tsx +0 -112
  101. data/app/frontend/components/railwatch/mobile-page-switcher.tsx +0 -89
  102. data/app/frontend/components/railwatch/onboarding.tsx +0 -91
  103. data/app/frontend/components/railwatch/origin-identity.tsx +0 -84
  104. data/app/frontend/components/railwatch/page-header.tsx +0 -42
  105. data/app/frontend/components/railwatch/percentile-picker.tsx +0 -18
  106. data/app/frontend/components/railwatch/relative-time.tsx +0 -18
  107. data/app/frontend/components/railwatch/saved-views.tsx +0 -232
  108. data/app/frontend/components/railwatch/segmented.tsx +0 -64
  109. data/app/frontend/components/railwatch/series-chart.tsx +0 -400
  110. data/app/frontend/components/railwatch/shortcuts-dialog.tsx +0 -89
  111. data/app/frontend/components/railwatch/signal-toast.tsx +0 -121
  112. data/app/frontend/components/railwatch/sort-header.tsx +0 -37
  113. data/app/frontend/components/railwatch/source-link.tsx +0 -57
  114. data/app/frontend/components/railwatch/sparkline-cell.tsx +0 -14
  115. data/app/frontend/components/railwatch/sql-block.tsx +0 -116
  116. data/app/frontend/components/railwatch/stat.tsx +0 -185
  117. data/app/frontend/components/railwatch/status-badge.tsx +0 -79
  118. data/app/frontend/components/railwatch/step-picker.tsx +0 -57
  119. data/app/frontend/components/railwatch/timeline.tsx +0 -405
  120. data/app/frontend/components/railwatch/utilisation-bar.tsx +0 -44
  121. data/app/frontend/components/railwatch/window-picker.tsx +0 -147
  122. data/app/frontend/components/ui/avatar.tsx +0 -51
  123. data/app/frontend/components/ui/badge.tsx +0 -46
  124. data/app/frontend/components/ui/breadcrumb.tsx +0 -109
  125. data/app/frontend/components/ui/button.tsx +0 -60
  126. data/app/frontend/components/ui/card.tsx +0 -92
  127. data/app/frontend/components/ui/chart.tsx +0 -374
  128. data/app/frontend/components/ui/checkbox.tsx +0 -32
  129. data/app/frontend/components/ui/collapsible.tsx +0 -31
  130. data/app/frontend/components/ui/command.tsx +0 -182
  131. data/app/frontend/components/ui/dialog.tsx +0 -158
  132. data/app/frontend/components/ui/dropdown-menu.tsx +0 -255
  133. data/app/frontend/components/ui/hover-card.tsx +0 -42
  134. data/app/frontend/components/ui/input.tsx +0 -21
  135. data/app/frontend/components/ui/label.tsx +0 -24
  136. data/app/frontend/components/ui/popover.tsx +0 -87
  137. data/app/frontend/components/ui/select.tsx +0 -185
  138. data/app/frontend/components/ui/separator.tsx +0 -28
  139. data/app/frontend/components/ui/sheet.tsx +0 -137
  140. data/app/frontend/components/ui/sidebar.tsx +0 -726
  141. data/app/frontend/components/ui/skeleton.tsx +0 -13
  142. data/app/frontend/components/ui/sonner.tsx +0 -41
  143. data/app/frontend/components/ui/table.tsx +0 -114
  144. data/app/frontend/components/ui/tabs.tsx +0 -91
  145. data/app/frontend/components/ui/textarea.tsx +0 -18
  146. data/app/frontend/components/ui/tooltip.tsx +0 -61
  147. data/app/frontend/components/user-info.tsx +0 -32
  148. data/app/frontend/components/user-menu-content.tsx +0 -94
  149. data/app/frontend/entrypoints/application.css +0 -244
  150. data/app/frontend/entrypoints/inertia.tsx +0 -92
  151. data/app/frontend/fonts/CommitMono-Bold.woff2 +0 -0
  152. data/app/frontend/fonts/CommitMono-Regular.woff2 +0 -0
  153. data/app/frontend/fonts/Roboto-Black.woff2 +0 -0
  154. data/app/frontend/fonts/Roboto-Bold.woff2 +0 -0
  155. data/app/frontend/fonts/Roboto-Medium.woff2 +0 -0
  156. data/app/frontend/fonts/Roboto-Regular.woff2 +0 -0
  157. data/app/frontend/hooks/use-appearance.tsx +0 -67
  158. data/app/frontend/hooks/use-clipboard.ts +0 -32
  159. data/app/frontend/hooks/use-flash.tsx +0 -23
  160. data/app/frontend/hooks/use-hotkeys.ts +0 -63
  161. data/app/frontend/hooks/use-initials.tsx +0 -15
  162. data/app/frontend/hooks/use-live.ts +0 -205
  163. data/app/frontend/hooks/use-mobile-navigation.ts +0 -8
  164. data/app/frontend/hooks/use-mobile.ts +0 -21
  165. data/app/frontend/hooks/use-percentile.ts +0 -24
  166. data/app/frontend/hooks/use-reduced-motion.ts +0 -25
  167. data/app/frontend/hooks/use-row-nav.ts +0 -106
  168. data/app/frontend/hooks/use-step.ts +0 -27
  169. data/app/frontend/hooks/use-ticker.ts +0 -12
  170. data/app/frontend/hooks/use-window.ts +0 -58
  171. data/app/frontend/layouts/app/app-sidebar-layout.tsx +0 -107
  172. data/app/frontend/layouts/app-layout.tsx +0 -21
  173. data/app/frontend/layouts/env-layout.tsx +0 -53
  174. data/app/frontend/layouts/persistent-layout.tsx +0 -18
  175. data/app/frontend/lib/cable.ts +0 -10
  176. data/app/frontend/lib/env-pages.ts +0 -236
  177. data/app/frontend/lib/execution-path.ts +0 -55
  178. data/app/frontend/lib/explain.ts +0 -50
  179. data/app/frontend/lib/filter.ts +0 -25
  180. data/app/frontend/lib/flamegraph.ts +0 -155
  181. data/app/frontend/lib/format.ts +0 -71
  182. data/app/frontend/lib/keyboard.ts +0 -18
  183. data/app/frontend/lib/mount.ts +0 -23
  184. data/app/frontend/lib/source-link.ts +0 -217
  185. data/app/frontend/lib/utils.ts +0 -6
  186. data/app/frontend/pages/alerts/index.tsx +0 -171
  187. data/app/frontend/pages/broadcasts/index.tsx +0 -171
  188. data/app/frontend/pages/cache_events/index.tsx +0 -127
  189. data/app/frontend/pages/commands/index.tsx +0 -143
  190. data/app/frontend/pages/deploys/index.tsx +0 -94
  191. data/app/frontend/pages/deploys/show.tsx +0 -309
  192. data/app/frontend/pages/deprecations/index.tsx +0 -176
  193. data/app/frontend/pages/exceptions/index.tsx +0 -271
  194. data/app/frontend/pages/executions/show.tsx +0 -821
  195. data/app/frontend/pages/issues/index.tsx +0 -399
  196. data/app/frontend/pages/issues/show.tsx +0 -1367
  197. data/app/frontend/pages/jobs/index.tsx +0 -381
  198. data/app/frontend/pages/jobs/klass.tsx +0 -215
  199. data/app/frontend/pages/llm_calls/index.tsx +0 -664
  200. data/app/frontend/pages/logs/index.tsx +0 -303
  201. data/app/frontend/pages/mails/index.tsx +0 -218
  202. data/app/frontend/pages/notifications/index.tsx +0 -161
  203. data/app/frontend/pages/outgoing_requests/index.tsx +0 -309
  204. data/app/frontend/pages/overview/show.tsx +0 -333
  205. data/app/frontend/pages/people/index.tsx +0 -102
  206. data/app/frontend/pages/people/show.tsx +0 -149
  207. data/app/frontend/pages/processes/index.tsx +0 -335
  208. data/app/frontend/pages/profiles/index.tsx +0 -110
  209. data/app/frontend/pages/profiles/show.tsx +0 -105
  210. data/app/frontend/pages/queries/index.tsx +0 -492
  211. data/app/frontend/pages/queries/show.tsx +0 -276
  212. data/app/frontend/pages/releases/index.tsx +0 -190
  213. data/app/frontend/pages/releases/release-health.tsx +0 -68
  214. data/app/frontend/pages/releases/release-path.ts +0 -25
  215. data/app/frontend/pages/releases/show.tsx +0 -262
  216. data/app/frontend/pages/requests/index.tsx +0 -235
  217. data/app/frontend/pages/requests/route.tsx +0 -159
  218. data/app/frontend/pages/scheduled_tasks/index.tsx +0 -220
  219. data/app/frontend/pages/spans/index.tsx +0 -229
  220. data/app/frontend/pages/spans/show.tsx +0 -220
  221. data/app/frontend/pages/storage_ops/index.tsx +0 -150
  222. data/app/frontend/pages/tenants/index.tsx +0 -236
  223. data/app/frontend/pages/tenants/show.tsx +0 -477
  224. data/app/frontend/pages/tenants/tenant-path.ts +0 -26
  225. data/app/frontend/pages/thresholds/index.tsx +0 -414
  226. data/app/frontend/pages/traces/show.tsx +0 -208
  227. data/app/frontend/pages/transactions/index.tsx +0 -220
  228. data/app/frontend/pages/view_renders/index.tsx +0 -241
  229. data/app/frontend/pages/visits/index.tsx +0 -321
  230. data/app/frontend/public/icon.png +0 -0
  231. data/app/frontend/public/icon.svg +0 -5
  232. data/app/frontend/routes/index.d.ts +0 -2136
  233. data/app/frontend/routes/index.js +0 -2112
  234. data/app/frontend/types/globals.d.ts +0 -9
  235. data/app/frontend/types/index.ts +0 -288
  236. data/app/frontend/types/vite-env.d.ts +0 -9
  237. data/app/helpers/railwatch/assets_helper.rb +0 -52
  238. data/app/jobs/railwatch/anomaly_scan_job.rb +0 -11
  239. data/app/jobs/railwatch/application_job.rb +0 -7
  240. data/app/jobs/railwatch/auto_resolve_issues_job.rb +0 -19
  241. data/app/jobs/railwatch/check_scheduled_tasks_job.rb +0 -113
  242. data/app/jobs/railwatch/detect_anomalies_job.rb +0 -171
  243. data/app/jobs/railwatch/detect_performance_issues_job.rb +0 -95
  244. data/app/jobs/railwatch/group_exceptions_job.rb +0 -91
  245. data/app/jobs/railwatch/optimize_telemetry_job.rb +0 -23
  246. data/app/jobs/railwatch/performance_scan_job.rb +0 -11
  247. data/app/jobs/railwatch/prune_telemetry_job.rb +0 -129
  248. data/app/jobs/railwatch/release_health_rollup_job.rb +0 -64
  249. data/app/jobs/railwatch/rollup_catchup_job.rb +0 -21
  250. data/app/jobs/railwatch/rollup_job.rb +0 -132
  251. data/app/jobs/railwatch/scheduled_task_scan_job.rb +0 -11
  252. data/app/models/concerns/railwatch/detection_snapshotting.rb +0 -20
  253. data/app/models/railwatch/alert.rb +0 -229
  254. data/app/models/railwatch/alert_rule.rb +0 -121
  255. data/app/models/railwatch/anomaly_rule.rb +0 -51
  256. data/app/models/railwatch/application.rb +0 -44
  257. data/app/models/railwatch/application_record.rb +0 -33
  258. data/app/models/railwatch/comment.rb +0 -36
  259. data/app/models/railwatch/deploy.rb +0 -67
  260. data/app/models/railwatch/environment.rb +0 -68
  261. data/app/models/railwatch/execution_presenter.rb +0 -185
  262. data/app/models/railwatch/filter_query.rb +0 -184
  263. data/app/models/railwatch/followup_receipt.rb +0 -27
  264. data/app/models/railwatch/ingest/batch.rb +0 -355
  265. data/app/models/railwatch/ingest/mapper.rb +0 -585
  266. data/app/models/railwatch/ingest/payload.rb +0 -96
  267. data/app/models/railwatch/ingest/rollup_absorber.rb +0 -170
  268. data/app/models/railwatch/ingest/writer.rb +0 -137
  269. data/app/models/railwatch/issue.rb +0 -277
  270. data/app/models/railwatch/issue_activity.rb +0 -23
  271. data/app/models/railwatch/issue_detection_presenter.rb +0 -309
  272. data/app/models/railwatch/issue_detection_snapshot.rb +0 -77
  273. data/app/models/railwatch/maintenance_task.rb +0 -53
  274. data/app/models/railwatch/saved_view.rb +0 -63
  275. data/app/models/railwatch/telemetry/aggregations.rb +0 -251
  276. data/app/models/railwatch/telemetry/attachment.rb +0 -31
  277. data/app/models/railwatch/telemetry/bounded_gzip.rb +0 -101
  278. data/app/models/railwatch/telemetry/broadcast.rb +0 -13
  279. data/app/models/railwatch/telemetry/cache_event.rb +0 -16
  280. data/app/models/railwatch/telemetry/child.rb +0 -53
  281. data/app/models/railwatch/telemetry/cursor_page.rb +0 -99
  282. data/app/models/railwatch/telemetry/deprecation.rb +0 -13
  283. data/app/models/railwatch/telemetry/enqueued_job.rb +0 -13
  284. data/app/models/railwatch/telemetry/exception.rb +0 -28
  285. data/app/models/railwatch/telemetry/execution.rb +0 -152
  286. data/app/models/railwatch/telemetry/export_delivery.rb +0 -32
  287. data/app/models/railwatch/telemetry/export_destination.rb +0 -66
  288. data/app/models/railwatch/telemetry/health_sample.rb +0 -72
  289. data/app/models/railwatch/telemetry/ingest_batch.rb +0 -31
  290. data/app/models/railwatch/telemetry/llm_call.rb +0 -37
  291. data/app/models/railwatch/telemetry/log.rb +0 -91
  292. data/app/models/railwatch/telemetry/mail.rb +0 -13
  293. data/app/models/railwatch/telemetry/n_plus_one.rb +0 -92
  294. data/app/models/railwatch/telemetry/notification.rb +0 -13
  295. data/app/models/railwatch/telemetry/outgoing_request.rb +0 -13
  296. data/app/models/railwatch/telemetry/person.rb +0 -50
  297. data/app/models/railwatch/telemetry/process.rb +0 -10
  298. data/app/models/railwatch/telemetry/profile.rb +0 -37
  299. data/app/models/railwatch/telemetry/query.rb +0 -57
  300. data/app/models/railwatch/telemetry/query_shape.rb +0 -45
  301. data/app/models/railwatch/telemetry/release_health.rb +0 -69
  302. data/app/models/railwatch/telemetry/rollup.rb +0 -157
  303. data/app/models/railwatch/telemetry/session.rb +0 -24
  304. data/app/models/railwatch/telemetry/span.rb +0 -19
  305. data/app/models/railwatch/telemetry/storage_op.rb +0 -13
  306. data/app/models/railwatch/telemetry/tenant.rb +0 -240
  307. data/app/models/railwatch/telemetry/transaction.rb +0 -13
  308. data/app/models/railwatch/telemetry/view_render.rb +0 -13
  309. data/app/models/railwatch/telemetry/visit.rb +0 -24
  310. data/app/models/railwatch/telemetry_record.rb +0 -107
  311. data/app/models/railwatch/threshold.rb +0 -66
  312. data/app/models/railwatch/user.rb +0 -47
  313. data/app/models/railwatch/viewer.rb +0 -13
  314. data/app/models/railwatch/window.rb +0 -66
  315. data/app/views/layouts/railwatch/dashboard.html.erb +0 -25
  316. data/db/railwatch_migrate/20260916000000_create_railwatch_tables.rb +0 -151
  317. data/db/railwatch_migrate/20260917000000_create_railwatch_maintenance_tasks.rb +0 -18
  318. data/db/railwatch_migrate/20260917120000_create_railwatch_followup_receipts.rb +0 -20
  319. data/db/railwatch_migrate/20260918120000_widen_host_user_ids.rb +0 -71
  320. data/db/railwatch_telemetry_migrate/20260903000000_enable_incremental_vacuum.rb +0 -62
  321. data/db/railwatch_telemetry_migrate/20260903000001_create_telemetry.rb +0 -481
  322. data/db/railwatch_telemetry_migrate/20260903000002_rename_tenant_to_app_tenant.rb +0 -14
  323. data/db/railwatch_telemetry_migrate/20260903000003_add_statement_count_to_transactions.rb +0 -9
  324. data/db/railwatch_telemetry_migrate/20260903000004_add_role_and_channel.rb +0 -10
  325. data/db/railwatch_telemetry_migrate/20260903000005_add_locals_to_exceptions.rb +0 -9
  326. data/db/railwatch_telemetry_migrate/20260903000006_add_spans_health_vitals_and_fts.rb +0 -82
  327. data/db/railwatch_telemetry_migrate/20260903000007_rename_span_attributes_to_payload.rb +0 -10
  328. data/db/railwatch_telemetry_migrate/20260903000008_add_profiles_and_attachments.rb +0 -60
  329. data/db/railwatch_telemetry_migrate/20260903000009_add_truncated_to_attachments.rb +0 -9
  330. data/db/railwatch_telemetry_migrate/20260903000010_create_sessions_and_release_health.rb +0 -51
  331. data/db/railwatch_telemetry_migrate/20260903000011_add_fingerprint_to_exceptions.rb +0 -11
  332. data/db/railwatch_telemetry_migrate/20260904000012_add_failed_to_broadcasts.rb +0 -10
  333. data/db/railwatch_telemetry_migrate/20260904010000_add_filter_cursor_indexes.rb +0 -37
  334. data/db/railwatch_telemetry_migrate/20260904020000_add_n_plus_ones_execution_id_index.rb +0 -11
  335. data/db/railwatch_telemetry_migrate/20260904120000_create_query_shapes.rb +0 -15
  336. data/db/railwatch_telemetry_migrate/20260906120000_add_backpressure_factor_to_ingest_batches.rb +0 -9
  337. data/db/railwatch_telemetry_migrate/20260907000000_rename_lantern_version_on_processes.rb +0 -10
  338. data/db/railwatch_telemetry_migrate/20260913000000_rename_nightrail_version_on_processes.rb +0 -9
  339. data/db/railwatch_telemetry_migrate/20260914000000_drop_orphan_durable_ingest_tables.rb +0 -18
  340. data/db/railwatch_telemetry_migrate/20260914010000_drop_orphan_durable_ingest_columns.rb +0 -25
  341. data/db/railwatch_telemetry_migrate/20260915000000_create_llm_calls.rb +0 -55
  342. data/db/railwatch_telemetry_migrate/20260915120000_add_detail_to_llm_calls.rb +0 -21
  343. data/db/railwatch_telemetry_migrate/20260915200000_add_explained_index_to_queries.rb +0 -16
  344. data/db/railwatch_telemetry_migrate/20260915210000_add_slowest_index_to_queries.rb +0 -18
  345. data/db/railwatch_telemetry_migrate/20260917010000_add_batch_ledger_to_ingest_batches.rb +0 -16
  346. data/db/railwatch_telemetry_migrate/20260919000100_create_export_queue.rb +0 -146
  347. data/db/railwatch_telemetry_migrate/20260922000000_add_covering_indexes_for_dashboard_aggregates.rb +0 -34
  348. data/db/railwatch_telemetry_migrate/20260923000000_add_people_index.rb +0 -15
  349. data/db/railwatch_telemetry_migrate/20260925000000_add_tenant_summary_index.rb +0 -17
  350. data/db/railwatch_telemetry_migrate/20261008000000_add_in_transaction_to_outgoing_requests.rb +0 -10
  351. data/docs/embedded.md +0 -503
  352. data/lib/puma/plugin/railwatch.rb +0 -215
  353. data/lib/railwatch/dashboard_assets.rb +0 -45
  354. data/lib/railwatch/embedded.rb +0 -50
  355. data/lib/railwatch/export/client.rb +0 -124
  356. data/lib/railwatch/export/lease.rb +0 -56
  357. data/lib/railwatch/export/outbox.rb +0 -361
  358. data/lib/railwatch/export/policy.rb +0 -79
  359. data/lib/railwatch/export/sender.rb +0 -130
  360. data/lib/railwatch/ingest_request_body_limit.rb +0 -10
  361. data/lib/railwatch/maintenance.rb +0 -194
  362. data/lib/railwatch/patches/migration_busy_timeout.rb +0 -73
  363. data/lib/railwatch/transport/local.rb +0 -78
  364. data/lib/railwatch/transport/socket.rb +0 -183
  365. data/lib/railwatch/writer.rb +0 -370
  366. data/public/railwatch/assets/CommitMono-Bold-D6h61ieg.woff2 +0 -0
  367. data/public/railwatch/assets/CommitMono-Regular-zr8w7Obm.woff2 +0 -0
  368. data/public/railwatch/assets/Roboto-Black-auA4GeOK.woff2 +0 -0
  369. data/public/railwatch/assets/Roboto-Bold-CJLnO8j1.woff2 +0 -0
  370. data/public/railwatch/assets/Roboto-Medium-Cm2bwKpj.woff2 +0 -0
  371. data/public/railwatch/assets/Roboto-Regular-Chaq1-PV.woff2 +0 -0
  372. data/public/railwatch/assets/app-layout-by7G3sa1.js +0 -41
  373. data/public/railwatch/assets/application-Cc5v_Vk9.css +0 -1
  374. data/public/railwatch/assets/arrow-up-DCZ7emux.js +0 -1
  375. data/public/railwatch/assets/braces-CykT5_5u.js +0 -1
  376. data/public/railwatch/assets/card-C-PPSA0g.js +0 -1
  377. data/public/railwatch/assets/chart-Cov79YC5.js +0 -39
  378. data/public/railwatch/assets/chart-hover-DdK4E-2h.js +0 -1
  379. data/public/railwatch/assets/chart-panel-BPaYRXJB.js +0 -1
  380. data/public/railwatch/assets/code-BYjC4YZ_.js +0 -1
  381. data/public/railwatch/assets/copy-id-LPfoj9cC.js +0 -1
  382. data/public/railwatch/assets/cursor-load-more-DSdhgpGl.js +0 -1
  383. data/public/railwatch/assets/data-table-CQ_YRWQs.js +0 -1
  384. data/public/railwatch/assets/env-layout-CdMWbUkm.js +0 -1
  385. data/public/railwatch/assets/execution-path-7MYt-Qbn.js +0 -1
  386. data/public/railwatch/assets/filter-bar-CrzpQ_vD.js +0 -1
  387. data/public/railwatch/assets/flamegraph-BIFEdTAg.js +0 -2
  388. data/public/railwatch/assets/format-B9SDkrWj.js +0 -1
  389. data/public/railwatch/assets/frames-C5t-x4f0.js +0 -1
  390. data/public/railwatch/assets/index--NQ7us-L.js +0 -1
  391. data/public/railwatch/assets/index-2kgYe_99.js +0 -1
  392. data/public/railwatch/assets/index-4YEPHxtO.js +0 -1
  393. data/public/railwatch/assets/index-AOCC1GDJ.js +0 -1
  394. data/public/railwatch/assets/index-BEo-u0eO.js +0 -1
  395. data/public/railwatch/assets/index-BJ1V3w2N.js +0 -1
  396. data/public/railwatch/assets/index-BPoHsBKb.js +0 -1
  397. data/public/railwatch/assets/index-BZzyGUM3.js +0 -1
  398. data/public/railwatch/assets/index-BgVq7yKL.js +0 -1
  399. data/public/railwatch/assets/index-BqFGEZvW.js +0 -1
  400. data/public/railwatch/assets/index-ByuHJ1CH.js +0 -1
  401. data/public/railwatch/assets/index-C2j50AL2.js +0 -1
  402. data/public/railwatch/assets/index-CLEdTkvW.js +0 -1
  403. data/public/railwatch/assets/index-CWgq8qBu.js +0 -1
  404. data/public/railwatch/assets/index-CXQ7_oVj.js +0 -2
  405. data/public/railwatch/assets/index-CmyYrjS2.js +0 -1
  406. data/public/railwatch/assets/index-Cn9_HjDo.js +0 -1
  407. data/public/railwatch/assets/index-CsMAm9UK.js +0 -1
  408. data/public/railwatch/assets/index-D0Kk_oGY.js +0 -1
  409. data/public/railwatch/assets/index-DC9ZptJh.js +0 -1
  410. data/public/railwatch/assets/index-DNzg7jmV.js +0 -1
  411. data/public/railwatch/assets/index-DQ8uJO5f.js +0 -1
  412. data/public/railwatch/assets/index-Deq14BxB.js +0 -1
  413. data/public/railwatch/assets/index-IaV3Blzp.js +0 -1
  414. data/public/railwatch/assets/index-TYNWcJQs.js +0 -1
  415. data/public/railwatch/assets/index-WonH2fcZ.js +0 -1
  416. data/public/railwatch/assets/index-WxWUaH_d.js +0 -1
  417. data/public/railwatch/assets/index-mUNrl4ky.js +0 -1
  418. data/public/railwatch/assets/inertia-DfNRARuA.js +0 -97
  419. data/public/railwatch/assets/json-viewer-DMsF5glp.js +0 -1
  420. data/public/railwatch/assets/klass-CmHYk5rz.js +0 -1
  421. data/public/railwatch/assets/origin-identity-1R3bqa3R.js +0 -1
  422. data/public/railwatch/assets/percentile-picker-73z5PAps.js +0 -1
  423. data/public/railwatch/assets/relative-time-Dsc_cCdX.js +0 -1
  424. data/public/railwatch/assets/release-health-BV5OaOWd.js +0 -1
  425. data/public/railwatch/assets/route-CWh58C7K.js +0 -1
  426. data/public/railwatch/assets/segmented-DB4zh-Am.js +0 -1
  427. data/public/railwatch/assets/select-DBKjFlOX.js +0 -1
  428. data/public/railwatch/assets/series-chart-BaiDG795.js +0 -1
  429. data/public/railwatch/assets/show-B4ICCFGh.js +0 -1
  430. data/public/railwatch/assets/show-B5lOU9Gv.js +0 -1
  431. data/public/railwatch/assets/show-BYPB74t4.js +0 -2
  432. data/public/railwatch/assets/show-C7A0m2M8.js +0 -1
  433. data/public/railwatch/assets/show-DT5X1zqE.js +0 -1
  434. data/public/railwatch/assets/show-D_NBdXsn.js +0 -2
  435. data/public/railwatch/assets/show-DgPCnRg8.js +0 -1
  436. data/public/railwatch/assets/show-Yl69HF0x.js +0 -1
  437. data/public/railwatch/assets/show-_QxuUQCm.js +0 -3
  438. data/public/railwatch/assets/show-g__jnN36.js +0 -1
  439. data/public/railwatch/assets/show-l4ztfjl9.js +0 -1
  440. data/public/railwatch/assets/sort-header-BcG8ulEH.js +0 -1
  441. data/public/railwatch/assets/source-link-B2183i2-.js +0 -1
  442. data/public/railwatch/assets/sparkline-cell-B47ipscB.js +0 -1
  443. data/public/railwatch/assets/stat-DT2hhsqS.js +0 -1
  444. data/public/railwatch/assets/status-badge-CmbRKlY7.js +0 -1
  445. data/public/railwatch/assets/tenant-path-C4rNGauE.js +0 -1
  446. data/public/railwatch/assets/use-clipboard-oTNeP4ax.js +0 -1
  447. data/public/railwatch/assets/use-live-CLZZj245.js +0 -1
  448. data/public/railwatch/icon.png +0 -0
  449. data/public/railwatch/icon.svg +0 -5
  450. data/public/railwatch/manifest.json +0 -1245
  451. data/public/railwatch/rails-vite.json +0 -1
  452. /data/{app/frontend/lib → lib/generators/railwatch/install/templates}/railwatch.ts +0 -0
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bfbb6b3ab550297baaa042889c6e98fe0b5fc1528acf6696fa343631b05936bd
4
- data.tar.gz: 37b7b7bce05a1e0b19ed8051f9dcc7cd09f3ca0c8d638404c9fa55bb227c44c4
3
+ metadata.gz: 3620348235aae6e5733728931b85a9c0edd0ac31367a4fd143eceee1de28cbc0
4
+ data.tar.gz: 273a578b3059f4390854d7452df971d8223c9e4f6c8c6a9e7e8d9f46a27ef1f3
5
5
  SHA512:
6
- metadata.gz: dc66f26f906bdab5b2be01c151c81e40767004508f94c1c7860d0a590272daa7469ec3a1a66cb8d5992e1f8ff7f080d6280049afe932b0582859b693c2801655
7
- data.tar.gz: 9296b26cf0c6c0eb837fdc85f7b69cd4f589c2ebfe5579e30401d3b16819e653dd86ad52764cff5d2ab6e768bf72c5b505ec4255d128a0f3334bfcefe0c41b72
6
+ metadata.gz: 82640c29a57b4c99d890b40ef75179d635b53308879516ba4973aaed0cfa1179696e0ee14e6660be2eb59c935611eb395e9f508e583c2604fbe8a7e57da0f8ad
7
+ data.tar.gz: 53ff388054d12658c7d0cb99c3d0c3dd01be8579ac2227efbb07d65f008a766851761655904b081c8f344aa5db6f3ad9d2cb1e25a349bf30b943e85cb74489bc
data/AGENTS.md CHANGED
@@ -4,9 +4,11 @@ About *using* the `railwatch` gem from a Rails application; copy
4
4
  this into that application's repository. Index of everything else:
5
5
  [`llms.txt`](llms.txt).
6
6
 
7
- Railwatch instruments a Rails app end to end and stores linked telemetry in
8
- two SQLite databases of the app's own (embedded, the default) or sends it to
9
- Railwatch Cloud. Every request, job attempt, scheduled task run, and command is
7
+ Railwatch instruments a Rails app end to end and sends linked telemetry over
8
+ HTTPS to a Railwatch server: Railwatch Cloud (`https://railwatch.rebulk.com`,
9
+ the default), a self-hosted [railwatch-rs](https://github.com/Rebulk/railwatch-rs),
10
+ or the one the [`railwatch-server`](https://github.com/Rebulk/railwatch-server)
11
+ gem runs next to Puma. Every request, job attempt, scheduled task run, and command is
10
12
  an **execution**; every query, cache read, log line, outgoing HTTP call, LLM
11
13
  call, view render, exception, and span is a child of one, linked by
12
14
  `execution_id`/`trace_id`. It never writes to the app's primary database.
@@ -15,40 +17,41 @@ call, view render, exception, and span is a child of one, linked by
15
17
 
16
18
  ```sh
17
19
  bundle add railwatch
18
- bin/rails generate railwatch:install # embedded: dashboard at /railwatch
19
- bin/rails generate railwatch:install --prompt-token --kamal-secrets # or: Railwatch Cloud
20
+ bin/rails generate railwatch:install --prompt-token --kamal-secrets # Railwatch Cloud
21
+ bin/rails generate railwatch:install --url=https://telemetry.example.com # self-hosted railwatch-rs
20
22
  ```
21
23
 
22
- With no flags the install is embedded (see [Embedded mode](docs/embedded.md)):
23
- telemetry stays in two SQLite databases the app owns (`railwatch`,
24
- `railwatch_telemetry`, added to `config/database.yml`), Puma forks one writer
25
- for them (`plugin :railwatch` in `config/puma.rb`), and the dashboard is served
26
- at `/railwatch`. It is open in development and answers 401 elsewhere until
27
- `RAILS_ENV=production bin/rails railwatch:authentication:configure` sets a
28
- password. An exported `RAILWATCH_TOKEN` alone does not change the mode.
29
- `--cloud`, or any of `--prompt-token`, `--token-stdin`, `--url`,
30
- `--kamal-secrets`, sends telemetry to Railwatch Cloud instead.
31
-
32
- Both modes write `config/initializers/railwatch.rb`, mount `Railwatch::Engine`
33
- at `/railwatch`, add the Kamal `post-deploy` hook and the Inertia browser client
34
- where the app has them, and require `railwatch/rspec` (or `railwatch/minitest`)
35
- in the test helper; the cloud install then runs `railwatch:doctor`. A
24
+ The generator writes `config/initializers/railwatch.rb`, mounts
25
+ `Railwatch::Engine` at `/railwatch` (it serves only the browser beacon), adds
26
+ the Kamal `post-deploy` hook and the Inertia browser client where the app has
27
+ them, requires `railwatch/rspec` (or `railwatch/minitest`) in the test helper,
28
+ and runs `railwatch:doctor` (`--no-doctor` skips it). A
36
29
  prompted/stdin/environment token goes into `.env` only when Git confirms that
37
- file is ignored; token values are never printed. Configuration lives only in
38
- that initializer; every option also has a `RAILWATCH_*` environment variable.
39
- An embedded install mirrors to Railwatch Cloud as well with a token and
40
- `c.export_enabled = true`.
30
+ file is ignored; token values are never printed. Without a token the gem is
31
+ inert. Configuration lives only in that initializer; every option also has a
32
+ `RAILWATCH_*` environment variable.
33
+
34
+ Embedded (the dashboard inside the app, no token to manage): add
35
+ `gem "railwatch-server"` to the Gemfile and `plugin :railwatch_server` to
36
+ `config/puma.rb`. It provisions `storage/railwatch/<env>` on first boot and
37
+ points this agent at it. Its dashboard at `/railwatch` is gated by this gem's
38
+ `http_basic_auth_*` settings (open in development, 401 elsewhere until
39
+ `RAILS_ENV=production bin/rails railwatch:authentication:configure` sets a
40
+ password) or, with Basic off, by `c.base_controller_class`.
41
+
42
+ Railwatch 0.x's in-gem embedded mode (`c.transport = :local`, `plugin :railwatch`,
43
+ the `railwatch`/`railwatch_telemetry` databases) is gone in 1.0; remove all three
44
+ and add railwatch-server. Its old SQLite files are not migrated.
41
45
 
42
46
  ## Rake tasks
43
47
 
44
48
  | Task | Does |
45
49
  |---|---|
46
- | `bin/rails railwatch:doctor` | ✓/✗ per check. Embedded: databases, migrations, writer process, last write, maintenance, dashboard access, export. Cloud: token, token storage, ingest URL, reachability. Both: middleware, engine mount, deploy, sample rates, ignored types, Kamal hook, browser client and whether an entrypoint calls it, profiler backend, test matchers. Exits non-zero on a missing database, pending migrations, broken export, a missing or tracked token, or an unreachable host. **Run this first when telemetry is missing.** |
47
- | `bin/rails railwatch:authentication:configure` | Sets the embedded dashboard's HTTP Basic credentials for the current `RAILS_ENV`. |
48
- | `bin/rails railwatch:export:status` | What the export queue holds and whether it can send. |
49
- | `bin/rails railwatch:token` | Where to create a Railwatch Cloud ingest token for this app. |
50
- | `bin/rails railwatch:mcp` | Paste-ready MCP client configuration for this app's Railwatch Cloud. |
51
- | `bin/rails railwatch:deploy[ref,name,url]` | Records a deploy marker (in the embedded database, or on the cloud). Use as a release step when not deploying with Kamal. |
50
+ | `bin/rails railwatch:doctor` | ✓/✗ per check: token, token storage, ingest URL, reachability, middleware, engine mount, deploy, sample rates, ignored types, Kamal hook, browser client and whether an entrypoint calls it, profiler backend, test matchers. Exits non-zero on a missing or tracked token, or an unreachable host. **Run this first when telemetry is missing.** |
51
+ | `bin/rails railwatch:authentication:configure` | Sets the HTTP Basic credentials that gate railwatch-server's dashboard, for the current `RAILS_ENV`. |
52
+ | `bin/rails railwatch:token` | Where to create an ingest token for this app on the server `ingest_url` points at. |
53
+ | `bin/rails railwatch:mcp` | Paste-ready MCP client configuration for that server. |
54
+ | `bin/rails railwatch:deploy[ref,name,url]` | Records a deploy marker on the server. Use as a release step when not deploying with Kamal. |
52
55
  | `bin/rails 'railwatch:sourcemaps[public,true]'` | Uploads Vite source maps for the configured deploy, then deletes acknowledged files. Run after building and before publishing assets. Omit `true` to retain files. See [Source maps](docs/source-maps.md). |
53
56
 
54
57
  ## Facade
@@ -89,9 +92,9 @@ Per action, in a controller class body: `railwatch_sample 0.01, only: :index`,
89
92
  ## Specs
90
93
 
91
94
  `require "railwatch/rspec"` in `spec/rails_helper.rb` (or `"railwatch/minitest"` in
92
- `test/test_helper.rb`). Railwatch must be enabled in the test env: an embedded
93
- install is, and needs `RAILS_ENV=test bin/rails db:prepare` once so its test
94
- databases exist; a cloud install needs any non-blank `RAILWATCH_TOKEN`. Records
95
+ `test/test_helper.rb`). Railwatch must be enabled in the test env, which
96
+ needs any non-blank `RAILWATCH_TOKEN` there (railwatch-server is off in test
97
+ and does not set one). Records
95
98
  go to an in-memory transport, never over the wire. All matchers are block
96
99
  matchers.
97
100
 
@@ -117,7 +120,8 @@ melt in production.
117
120
 
118
121
  ## MCP
119
122
 
120
- Railwatch Cloud (not embedded mode) is an MCP server at `<ingest host>/mcp`.
123
+ Railwatch Cloud and railwatch-rs are MCP servers at `<ingest host>/mcp`
124
+ (with railwatch-server: the app's host plus `/railwatch/mcp`).
121
125
  Generate a personal token at Settings → Profile → "API & MCP token", then:
122
126
 
123
127
  ```sh
data/CHANGELOG.md CHANGED
@@ -6,6 +6,69 @@
6
6
  filled in by the release commit, which is also the only commit that
7
7
  touches lib/railwatch/version.rb and Gemfile.lock. See CONTRIBUTING.md. -->
8
8
 
9
+ ## 1.1.0 (2026-10-22)
10
+
11
+ - A receiver that refuses the connection (nothing listening: a Railwatch
12
+ server restarting, or a deploy handing over to the next container) no
13
+ longer counts as backpressure. The retry ladder it starts used to double
14
+ the sampling divisor every flush tick, so the app's first requests after
15
+ the server came back were sampled out: a fresh app recorded 23-29 of 30
16
+ requests sent right after its embedded server was killed and restarted,
17
+ in every one of 10 runs. A timeout, a 5xx and a full buffer are still
18
+ pressure.
19
+ - `Configuration#local?` is gone. It was kept in 1.0.0 only for
20
+ railwatch-server 0.1.0; railwatch-server 0.1.1 no longer calls it.
21
+
22
+ ## 1.0.0 (2026-10-22)
23
+
24
+ - **Breaking: `railwatch` is the agent only.** It instruments the app and
25
+ sends to an ingest URL: Railwatch Cloud (the default,
26
+ `https://railwatch.rebulk.com`) or a self-hosted
27
+ [railwatch-rs](https://github.com/Rebulk/railwatch-rs) server
28
+ (`RAILWATCH_INGEST_URL`, `RAILWATCH_TOKEN`). Embedded mode is gone from
29
+ this gem: `transport :local` / `RAILWATCH_TRANSPORT`, the two SQLite
30
+ databases (`railwatch`, `railwatch_telemetry`) and their migrations, the
31
+ Puma writer (`plugin :railwatch`), the maintenance clock, export to the
32
+ cloud, the dashboard pages, its live channel and its compiled bundle.
33
+ The dashboard is part of the server now, and the gem has no runtime
34
+ dependency on `inertia_rails` or `tdigest`.
35
+ - The dashboard inside the app is the separate
36
+ [railwatch-server](https://github.com/Rebulk/railwatch-server) gem. It
37
+ runs the railwatch-rs server next to Puma and points this agent at it.
38
+ - Removed settings: `transport`, `issue_prefix`, `repository_url`,
39
+ `retention_days`, `dashboard_user`, `dashboard_open`, `writer_socket`,
40
+ `migration_busy_timeout`, and every `export_*`, with their
41
+ `RAILWATCH_*` variables. Removed rake tasks: `railwatch:vacuum`,
42
+ `railwatch:vacuum:status`, `railwatch:export:status`, `:rebind` and
43
+ `:discard`. Removed: `Railwatch.migrations_path`,
44
+ `Railwatch.url_helpers`, `Railwatch.frontend_path`.
45
+ - `http_basic_auth_enabled`, `http_basic_auth_user`,
46
+ `http_basic_auth_password`, `base_controller_class` and
47
+ `bin/rails railwatch:authentication:configure` stay. They are the gate
48
+ railwatch-server puts in front of its dashboard, and do nothing without
49
+ it.
50
+ - `bin/rails generate railwatch:install` sets up the agent only: token,
51
+ ingest URL (`--url` for a self-hosted server), the beacon mount, the
52
+ Kamal hook, the browser client and the test helpers. It no longer
53
+ writes `config/database.yml` or `config/puma.rb`, and `--cloud` is gone
54
+ because there is no other mode.
55
+ - The browser client moved to
56
+ `lib/generators/railwatch/install/templates/railwatch.ts`
57
+ (`Railwatch.browser_client_path`). Apps that already copied it keep
58
+ their copy at `app/frontend/lib/railwatch.ts`.
59
+ - Upgrading an embedded 0.x install: delete `c.transport = :local` (or
60
+ `RAILWATCH_TRANSPORT=local`), delete `plugin :railwatch` from
61
+ `config/puma.rb` (Puma refuses to boot with a plugin it cannot find),
62
+ and delete the `railwatch` and `railwatch_telemetry` entries from
63
+ `config/database.yml`. Then add `gem "railwatch-server"` and
64
+ `plugin :railwatch_server`. The old data in
65
+ `storage/<env>_railwatch.sqlite3` and
66
+ `storage/<env>_railwatch_telemetry.sqlite3` is not migrated: railwatch-rs
67
+ has no import for these files (`railwatch import-rails` reads a
68
+ Railwatch Cloud install, not this gem's embedded databases), so the new
69
+ dashboard starts empty. Keep the old files only if you want them; they
70
+ can be deleted.
71
+
9
72
  ## 0.9.4 (2026-10-22)
10
73
 
11
74
  - Sampling recovers as soon as ingest does. A receiver refusing with a
data/README.md CHANGED
@@ -6,37 +6,26 @@ outgoing HTTP, storage, views, and logs, and links them into one trace
6
6
  per execution, for about half a millisecond per request plus tens of
7
7
  microseconds per query, with zero writes to your database.
8
8
 
9
- By default all of it stays inside the app:
10
- [embedded mode](docs/embedded.md) serves the full dashboard at
11
- `/railwatch` out of two SQLite files your app owns, with no token, no
12
- Node, no Redis and no job worker. Railwatch Cloud is optional: it
13
- delivers alerts to Slack, email, webhooks or Linear (including when the
14
- app is down), serves MCP to your AI assistant, and puts many apps and
15
- servers in one place.
9
+ The gem is the agent. It sends what it records over HTTPS to a
10
+ Railwatch server, which stores it, groups exceptions into issues, sends
11
+ alerts, and serves the dashboard and an MCP server:
16
12
 
17
- ## Install
18
-
19
- ```sh
20
- bundle add railwatch # 1. add the public gem
21
- bin/rails generate railwatch:install # 2. embedded: databases, Puma writer, dashboard at /railwatch
22
- ```
23
-
24
- Restart and open `/railwatch`. It is open in development; before you
25
- deploy, give it a password with
26
- `RAILS_ENV=production bin/rails railwatch:authentication:configure`
27
- (it answers 401 in production until you do). On a PostgreSQL or MySQL
28
- app without the `sqlite3` gem, the generator adds it to the Gemfile;
29
- run `bundle install` and `bin/rails db:prepare` to finish.
13
+ - **Railwatch Cloud** at <https://railwatch.rebulk.com>, the default.
14
+ - **Self-hosted [railwatch-rs](https://github.com/Rebulk/railwatch-rs)**,
15
+ one static binary for many apps ([Self-hosting](docs/self-hosting.md)).
16
+ - **Embedded**: the [`railwatch-server`](https://github.com/Rebulk/railwatch-server)
17
+ gem runs that server next to Puma for one app and serves the dashboard
18
+ at `/railwatch`, with nothing else to run.
30
19
 
31
- To send everything to Railwatch Cloud instead, pass `--cloud` or a token
32
- option:
20
+ ## Install
33
21
 
34
22
  ```sh
35
- bundle add railwatch
36
- bin/rails generate railwatch:install --prompt-token # hidden token input plus app wiring
23
+ bundle add railwatch # 1. add the public gem
24
+ bin/rails generate railwatch:install --prompt-token # 2. hidden token input plus app wiring
37
25
  bin/rails railwatch:doctor # check every piece is wired up after restart
38
26
  ```
39
27
 
28
+ For a self-hosted server, add `--url=https://telemetry.example.com`.
40
29
  The generator's flags, getting a token, and deploying with Kamal,
41
30
  Docker, Heroku, or Render are covered in
42
31
  [Getting started](docs/getting-started.md). For an unreleased revision,
@@ -46,6 +35,36 @@ use the Git source instead:
46
35
  gem "railwatch", github: "Rebulk/railwatch"
47
36
  ```
48
37
 
38
+ ### Embedded
39
+
40
+ To keep everything inside the app, add `railwatch-server` next to this
41
+ gem:
42
+
43
+ ```ruby
44
+ # Gemfile
45
+ gem "railwatch"
46
+ gem "railwatch-server"
47
+ ```
48
+
49
+ ```ruby
50
+ # config/puma.rb
51
+ plugin :railwatch_server
52
+ ```
53
+
54
+ It provisions its data under `storage/railwatch/<env>` on first boot and
55
+ points this gem at it, so there is no token to manage. The dashboard at
56
+ `/railwatch` is open in development and answers 401 elsewhere until you
57
+ give it a password with
58
+ `RAILS_ENV=production bin/rails railwatch:authentication:configure`, or
59
+ put it behind your own admin authentication
60
+ ([Configuration](docs/configuration.md#dashboard-gate-railwatch-server)).
61
+ Everything else is in the
62
+ [railwatch-server README](https://github.com/Rebulk/railwatch-server#readme).
63
+
64
+ Railwatch 0.x kept embedded telemetry in two SQLite databases written by
65
+ `plugin :railwatch`. 1.0 removes that mode; see
66
+ [Coming from 0.x embedded mode](docs/getting-started.md#coming-from-0x-embedded-mode).
67
+
49
68
  ## What you get
50
69
 
51
70
  - Requests, jobs, scheduled tasks, commands, queries, exceptions, and
@@ -63,8 +82,8 @@ gem "railwatch", github: "Rebulk/railwatch"
63
82
  and browser errors ([Getting started](docs/getting-started.md)).
64
83
  - RSpec and Minitest matchers that turn a query budget into a CI gate
65
84
  ([Testing](docs/testing.md)).
66
- - With Railwatch Cloud, an MCP server so Claude Code, Cursor, VS Code, or
67
- Zed can read your production data
85
+ - An MCP server on the Railwatch server, so Claude Code, Cursor, VS Code,
86
+ or Zed can read your production data
68
87
  ([AI assistants and MCP](docs/ai-and-mcp.md)).
69
88
 
70
89
  Configuration lives in `config/initializers/railwatch.rb`; most options
@@ -85,36 +104,12 @@ expect { get "/widgets" }.to have_railwatch_queries(at_most: 6)
85
104
  expect { get "/widgets" }.not_to have_railwatch_n_plus_one
86
105
  ```
87
106
 
88
- ## Embedded mode
89
-
90
- Telemetry goes to two SQLite files the app owns -- `railwatch` for
91
- issues, comments and saved views, `railwatch_telemetry` for what the app
92
- reports -- and the dashboard is served at `/railwatch` from a bundle
93
- shipped inside the gem. Nothing leaves the machine unless you turn on
94
- export to Railwatch Cloud, and there is nothing else to run.
95
-
96
- Puma forks a single writer process (`plugin :railwatch`, which the
97
- installer adds) that owns both files. The web workers hand it batches
98
- over a Unix socket instead of writing SQLite on their own threads, and it
99
- runs the maintenance clock too, so exception grouping, rollups, retention
100
- and threshold scans happen without a queue.
101
-
102
- That dashboard reads every query, log line and exception the app
103
- produced, so it is gated the way Mission Control Jobs is: HTTP Basic is
104
- on, and with no credentials every request is 401 until you set them
105
- with `bin/rails railwatch:authentication:configure`. Development is the
106
- exception: with no credentials set there, it is open. Apps that would
107
- rather use their own authentication turn Basic off and gate the pages
108
- with `base_controller_class` or a routes constraint around the mount; a
109
- `dashboard_user` resolver then names the operator and authorizes live
110
- updates, but does not gate pages. [Embedded mode](docs/embedded.md)
111
- covers all of it, including upgrades and what it costs to store.
112
-
113
107
  ## Documentation
114
108
 
115
- - [Getting started](docs/getting-started.md) — the embedded install, the
116
- Railwatch Cloud install and its token, the three optional lines, and
117
- deploying with Kamal, Docker, Heroku, Render, or none of them.
109
+ - [Getting started](docs/getting-started.md) — the install and its token,
110
+ embedded with railwatch-server, moving from 0.x embedded mode, the three
111
+ optional lines, and deploying with Kamal, Docker, Heroku, Render, or none
112
+ of them.
118
113
  - [Configuration](docs/configuration.md) — every option and `RAILWATCH_*`
119
114
  variable, field by field.
120
115
  - [Record types](docs/records.md) — every record Railwatch ships and every
@@ -122,17 +117,13 @@ covers all of it, including upgrades and what it costs to store.
122
117
  - [Testing](docs/testing.md) — the RSpec and Minitest matchers, and a CI
123
118
  performance gate.
124
119
  - [AI assistants and MCP](docs/ai-and-mcp.md) — connecting Claude Code,
125
- Cursor, VS Code, or Zed to your production data through Railwatch
126
- Cloud.
120
+ Cursor, VS Code, or Zed to your production data.
127
121
  - [Replacing Sentry](docs/replacing-sentry.md) — a step-by-step migration,
128
122
  option by option and call site by call site.
129
123
  - [Coming from Laravel Nightwatch](docs/replacing-nightwatch.md) — the
130
124
  record-type mapping and the sampling model, for Laravel people.
131
- - [Embedded mode](docs/embedded.md) — the default: the whole dashboard
132
- inside your app, telemetry in your own SQLite files, and optional
133
- export to Railwatch Cloud.
134
125
  - [Self-hosting](docs/self-hosting.md) — pointing the gem at your own
135
- Railwatch Cloud.
126
+ railwatch-rs server.
136
127
  - [Troubleshooting](docs/troubleshooting.md) — every failure mode, paired
137
128
  with the `railwatch:doctor` line it shows up as.
138
129
  - [FAQ](docs/faq.md) — overhead numbers, retention, PII posture, SQLite.
data/config/routes.rb CHANGED
@@ -2,63 +2,4 @@
2
2
 
3
3
  Railwatch::Engine.routes.draw do
4
4
  post "beacon", to: "beacon#create"
5
-
6
- # The embedded dashboard. Same URL shape as the hosted platform so the
7
- # prebuilt bundle's route helpers resolve unchanged once js-routes knows
8
- # the mount point; a singleton install always answers for app 1, env 1.
9
- root to: redirect { |_p, req| "#{req.script_name}/apps/1/envs/1" }
10
- get "dashboard", to: redirect { |_p, req| "#{req.script_name}/apps/1/envs/1" }
11
- get "docs", to: redirect("https://railwatch.rebulk.com/docs")
12
-
13
- scope "apps/:application_id", as: :application do
14
- get "/", to: redirect { |p, req| "#{req.script_name}/apps/#{p[:application_id]}/envs/1" }
15
- scope "envs/:environment_id", as: :environment do
16
- get "/", to: "overview#show", as: :overview
17
- resources :requests, only: [ :index, :show ] do
18
- get "routes/:group_hash", to: "requests#route", on: :collection, as: :route
19
- end
20
- resources :jobs, only: [ :index, :show ] do
21
- get "classes/:group_hash", to: "jobs#klass", on: :collection, as: :klass
22
- end
23
- resources :scheduled_tasks, only: [ :index, :show ]
24
- resources :commands, only: [ :index, :show ]
25
- resources :executions, only: [ :show ]
26
- resources :queries, only: [ :index, :show ]
27
- resources :spans, only: [ :index, :show ]
28
- resources :profiles, only: [ :index, :show ]
29
- resources :attachments, only: [ :show ]
30
- get "traces/:trace_id", to: "traces#show", as: :trace
31
- resources :view_renders, path: "views", only: [ :index ]
32
- resources :transactions, only: [ :index ]
33
- resources :deprecations, only: [ :index ]
34
- resources :exceptions, only: [ :index ]
35
- resources :cache_events, path: "cache", only: [ :index ]
36
- resources :mails, path: "mail", only: [ :index ]
37
- resources :notifications, only: [ :index ]
38
- resources :broadcasts, only: [ :index ]
39
- resources :outgoing_requests, only: [ :index ]
40
- resources :llm_calls, path: "llm", only: [ :index ]
41
- resources :storage_ops, path: "storage", only: [ :index ]
42
- resources :logs, only: [ :index ]
43
- resources :people, path: "users", only: [ :index, :show ]
44
- resources :deploys, only: [ :index, :show ]
45
- resources :releases, only: [ :index, :show ]
46
- resources :visits, only: [ :index ]
47
- resources :processes, only: [ :index ]
48
- resources :tenants, only: [ :index, :show ]
49
- resources :saved_views, only: [ :create, :update, :destroy ]
50
- resources :thresholds, only: [ :index, :create, :update, :destroy ]
51
- resources :anomaly_rules, only: [ :create, :update, :destroy ]
52
- resources :alerts, only: [ :index ]
53
- end
54
- end
55
-
56
- resources :issues, only: [ :index, :show, :update ] do
57
- resources :comments, only: [ :create ]
58
- post :bulk, on: :collection
59
- get :merge_candidates, on: :member
60
- end
61
- resources :alerts, only: [ :index ] do
62
- post :retry, on: :member
63
- end
64
5
  end
data/docs/ai-and-mcp.md CHANGED
@@ -1,6 +1,7 @@
1
1
  # AI assistants and MCP
2
2
 
3
- Railwatch Cloud is an [MCP](https://modelcontextprotocol.io) server. Point
3
+ Railwatch Cloud, and any railwatch-rs server, is an
4
+ [MCP](https://modelcontextprotocol.io) server. Point
4
5
  Claude Code, Claude Desktop, Cursor, VS Code, or Zed at it and the assistant
5
6
  sitting in your editor can read the same production data your dashboards
6
7
  show: issues and their stack traces, slow routes, the queries and N+1s
@@ -9,13 +10,13 @@ crash-free rates per release. It can also write — resolve an issue, set a
9
10
  priority, leave a comment — and every write is signed with your user and the
10
11
  agent's name in the issue's activity feed.
11
12
 
12
- MCP is a Railwatch Cloud feature. The embedded dashboard at `/railwatch`
13
- does not serve it; an embedded install gets it by
14
- [exporting to the cloud](embedded.md#three-ways-to-run-it).
15
-
16
13
  The endpoint is `<your ingest host>/mcp`. For the hosted platform that's
17
14
  `https://railwatch.rebulk.com/mcp`; if you self-host, it is your own host (see
18
- [`self-hosting.md`](self-hosting.md)). The gem knows which one you're on:
15
+ [`self-hosting.md`](self-hosting.md)). With the `railwatch-server` gem the
16
+ server runs under the app's dashboard path, so the endpoint is the app's own
17
+ host plus `/railwatch/mcp`; see the
18
+ [railwatch-server README](https://github.com/Rebulk/railwatch-server#readme).
19
+ For Railwatch Cloud and a self-hosted server the gem knows which one you're on:
19
20
 
20
21
  ```sh
21
22
  bin/rails railwatch:mcp
@@ -225,9 +226,9 @@ Copy either into your own app's repo to give its agent the same context.
225
226
 
226
227
  ## See also
227
228
 
228
- - [`getting-started.md`](getting-started.md) — install, the cloud token,
229
+ - [`getting-started.md`](getting-started.md) — install, the token,
229
230
  first request.
230
231
  - [`self-hosting.md`](self-hosting.md) — pointing the gem, and this endpoint,
231
- at your own platform.
232
+ at your own server.
232
233
  - [`troubleshooting.md`](troubleshooting.md) — when something isn't
233
234
  reporting.
@@ -11,9 +11,9 @@ values set in the initializer always win over the env var.
11
11
 
12
12
  | Attribute | Env var | Default | Meaning |
13
13
  |---|---|---|---|
14
- | `enabled` | `RAILWATCH_ENABLED` | `true` | Master switch. With `transport = :http`, `Railwatch.enabled?` is also `false` whenever `token` is blank, so setting only `RAILWATCH_TOKEN` is enough to turn a cloud install on. An embedded install needs no token. |
15
- | `token` | `RAILWATCH_TOKEN` | nil | Bearer token for `/ingest`. Required with `transport = :http` and for [export](#export-to-railwatch-cloud). |
16
- | `ingest_url` | `RAILWATCH_INGEST_URL` | `https://railwatch.rebulk.com` | Platform base URL. Point at a self-hosted instance to override. |
14
+ | `enabled` | `RAILWATCH_ENABLED` | `true` | Master switch. `Railwatch.enabled?` is also `false` whenever `token` is blank, so setting only `RAILWATCH_TOKEN` is enough to turn an install on. |
15
+ | `token` | `RAILWATCH_TOKEN` | nil | Bearer token for `/ingest`. Required; with railwatch-server installed it is set for you. |
16
+ | `ingest_url` | `RAILWATCH_INGEST_URL` | `https://railwatch.rebulk.com` | Server base URL. Point at a self-hosted railwatch-rs to override. |
17
17
  | `allow_http` | `RAILWATCH_ALLOW_HTTP` | `false` | Permit a non-loopback plain HTTP ingest URL. HTTPS is required by default; `localhost`, `127.0.0.1`, and `::1` remain available for local self-hosted development. |
18
18
  | `deploy` | `RAILWATCH_DEPLOY` | auto-detected (order below), then nil | Version tag stamped on every record and used by `railwatch:deploy`. Full 40-character SHAs are shortened to 12 characters. |
19
19
  | `detect_deploy` | `RAILWATCH_DETECT_DEPLOY` | `true` | Detect deploys beyond `RAILWATCH_DEPLOY` and `KAMAL_VERSION`. Set false when the app deliberately reports no inferred deploy. |
@@ -25,7 +25,7 @@ values set in the initializer always win over the env var.
25
25
  | `beacon_rate_limit` | `RAILWATCH_BEACON_RATE_LIMIT` | `120` | Beacon POSTs accepted per client IP per minute before `POST /railwatch/beacon` answers 429. The beacon is unauthenticated and keeps every browser error it is sent, so this is what stops a script from spending the app's event quota. Counted in the app's cache store; `0` turns it off. |
26
26
 
27
27
  `Railwatch.enabled?` delegates to `config.enabled?`, which is `@enabled &&
28
- (local? || token.present?)`. There is no separate "is configured" check
28
+ token.present?`. There is no separate "is configured" check
29
29
  elsewhere.
30
30
 
31
31
  Deploy detection stops at the first value found: `RAILWATCH_DEPLOY`,
@@ -585,7 +585,7 @@ Rake tasks and Solid Queue jobs are never interactive.
585
585
 
586
586
  | Attribute | Env var | Default | Meaning |
587
587
  |---|---|---|---|
588
- | `capture_exception_source` | `RAILWATCH_CAPTURE_EXCEPTION_SOURCE_CODE` | `true` | Record source snippet lines surrounding each in-application exception frame (sent to Railwatch Cloud when the install reports there or exports). This is on by default for crash context; disable it when source disclosure is outside the application's telemetry policy. |
588
+ | `capture_exception_source` | `RAILWATCH_CAPTURE_EXCEPTION_SOURCE_CODE` | `true` | Record source snippet lines surrounding each in-application exception frame (sent to whichever server the app reports to). This is on by default for crash context; disable it when source disclosure is outside the application's telemetry policy. |
589
589
  | `capture_exception_locals` | `RAILWATCH_CAPTURE_EXCEPTION_LOCALS` | `false` | Snapshot the raising frame's local variables (up to 25, values truncated to 200 chars, run through the same filter as request params) onto each exception, like Sentry's locals panel. Installs a `TracePoint(:raise)`; opt in per environment. |
590
590
  | `capture_request_payload` | `RAILWATCH_CAPTURE_REQUEST_PAYLOAD` | `false` | Capture (redacted) request params — only for a request that raised, never otherwise. |
591
591
  | `capture_job_arguments` | `RAILWATCH_CAPTURE_JOB_ARGUMENTS` | `false` | Add the job's real arguments (`job.serialize["arguments"]`) to each `job_attempt`/`scheduled_task` record, capped at 8 KiB of JSON. Hash arguments run through the same filter as request params. Off by default because job arguments routinely carry PII; `arguments_preview` (argument *shapes* only) is always on regardless. |
@@ -900,72 +900,50 @@ in `lib/railwatch.rb`, unless noted:
900
900
  `instrument_outgoing`, `flush`, `debug { }`. `pause`/`resume` are the
901
901
  ignore block's building blocks, and are nestable.
902
902
 
903
- ## Embedded mode
903
+ ## Dashboard gate (railwatch-server)
904
+
905
+ These settings do nothing on their own. They gate the dashboard that the
906
+ [`railwatch-server`](https://github.com/Rebulk/railwatch-server) gem
907
+ serves at `/railwatch` inside the app, so one setting covers it whichever
908
+ way it is installed.
904
909
 
905
910
  ```ruby
906
- c.transport = :local # RAILWATCH_TRANSPORT; runtime default "http", but the installer writes :local
907
- c.issue_prefix = "SHOP" # RAILWATCH_ISSUE_PREFIX; default from the app name
908
- c.repository_url = "..." # RAILWATCH_REPOSITORY_URL
909
- c.retention_days = 7 # RAILWATCH_RETENTION_DAYS
910
911
  c.http_basic_auth_enabled = true # RAILWATCH_HTTP_BASIC_AUTH_ENABLED; on, and closed outside development until credentials exist
911
912
  c.http_basic_auth_user = "ops" # RAILWATCH_HTTP_BASIC_AUTH_USER, or credentials railwatch.http_basic_auth_user
912
913
  c.http_basic_auth_password = "..." # RAILWATCH_HTTP_BASIC_AUTH_PASSWORD, or credentials railwatch.http_basic_auth_password
913
914
  c.base_controller_class = "AdminController" # RAILWATCH_BASE_CONTROLLER_CLASS; default ActionController::Base
914
- c.dashboard_open = false # RAILWATCH_DASHBOARD_OPEN; default false, true makes it public on purpose
915
- c.dashboard_user = ->(request) { { id:, name:, email: } or nil }
916
- c.writer_socket = "tmp/sockets/railwatch-writer.sock" # RAILWATCH_WRITER_SOCKET
917
915
  ```
918
916
 
919
- With `transport = :local` the reporter writes each batch into the app's
920
- own `railwatch_telemetry` database instead of POSTing it, and the engine
921
- serves the dashboard at its mount. `enabled?` no longer needs a token.
922
- The others only matter in that mode. The dashboard is behind HTTP Basic
923
- by default and, outside development, answers 401 until `bin/rails
924
- railwatch:authentication:configure` has written credentials; a host with
925
- its own admin auth turns Basic off and sets `base_controller_class` or a
926
- routes constraint. Full walkthrough: [Embedded mode](embedded.md).
927
-
928
- ### Export to Railwatch Cloud
929
-
930
- An embedded install can also mirror every record to Railwatch Cloud.
931
- Off unless `export_enabled` is set; a configured token alone sends
932
- nothing. Only meaningful with `transport = :local`.
933
-
934
- | Attribute | Env var | Default | Meaning |
935
- |---|---|---|---|
936
- | `export_enabled` | `RAILWATCH_EXPORT_ENABLED` | `false` | Mirror every record to the cloud as well as storing it locally. |
937
- | `export_token` | `RAILWATCH_EXPORT_TOKEN` | `token` | Cloud environment token to send with. |
938
- | `export_url` | `RAILWATCH_EXPORT_URL` | `{ingest_url}/ingest` | Where to send. |
939
- | `export_max_bytes` | `RAILWATCH_EXPORT_MAX_BYTES` | `268435456` (256 MiB) | Queue ceiling in bytes. At capacity new work is refused and counted, not swapped for old. |
940
- | `export_max_deliveries` | `RAILWATCH_EXPORT_MAX_DELIVERIES` | `100000` | Queue ceiling in deliveries. |
941
- | `export_max_age` | `RAILWATCH_EXPORT_MAX_AGE_SECONDS` | `86400` | How long a queued delivery is kept. At most seven days, past which the receiver no longer recognises it. |
917
+ HTTP Basic is on by default and, outside development, answers 401 until
918
+ credentials exist: `bin/rails railwatch:authentication:configure` writes
919
+ them to the current environment's Rails credentials, or set the env vars.
920
+ In development with no credentials configured, it is open. An initializer
921
+ or env var that sets them wins over credentials.
942
922
 
943
- `railwatch:doctor` fails when export is enabled and cannot work, and
944
- `railwatch:export:status` shows the queue. See
945
- [Embedded mode](embedded.md#three-ways-to-run-it).
923
+ An app with its own admin authentication turns Basic off and names a
924
+ base controller. railwatch-server's proxy controller inherits from
925
+ `base_controller_class`, so the app's own `before_action`s (require an
926
+ admin, redirect to sign-in) run in front of every dashboard request.
946
927
 
947
928
  ## Rake tasks
948
929
 
949
930
  Ship with the gem via Rails::Engine's default `lib/tasks` convention, in
950
931
  `lib/tasks/railwatch_tasks.rake`:
951
932
 
952
- - **`railwatch:status`** embedded: prints that telemetry is stored in the
953
- app. Cloud: pings `{ingest_url}/ingest/ping` with the configured token,
954
- and aborts if `RAILWATCH_TOKEN` is unset or the ping fails.
933
+ - **`railwatch:status`** pings `{ingest_url}/ingest/ping` with the
934
+ configured token, and aborts if `RAILWATCH_TOKEN` is unset or the ping
935
+ fails.
955
936
  - **`railwatch:doctor`** prints a ✓/✗ checklist of the whole install.
956
- Embedded, it checks both databases and their migrations, telemetry
957
- disk mode, the maintenance clock, the writer process, dashboard access,
958
- and export when enabled. Cloud, it checks the token, where the token is
959
- stored, the ingest URL and its transport security, and
960
- `GET /ingest/ping`. Then, either way: `Railwatch::Middleware::Request`
937
+ It checks the token, where the token is stored, the ingest URL and its
938
+ transport security, and `GET /ingest/ping`. Then
939
+ `Railwatch::Middleware::Request`
961
940
  in the middleware stack, the mounted engine's beacon route,
962
941
  `config.deploy` and its source, sample rates, ignored record types, the
963
942
  Kamal `post-deploy` hook, the browser client and whether an entrypoint
964
943
  calls it, the profiler backend, and the test matchers. It exits
965
944
  non-zero only on the lines marked fatal in
966
945
  [Troubleshooting](troubleshooting.md).
967
- - **`railwatch:deploy[ref,name,url]`** embedded: writes the deploy marker
968
- to the app's `railwatch` database. Cloud: POSTs `{deploy, ref, name,
946
+ - **`railwatch:deploy[ref,name,url]`** POSTs `{deploy, ref, name,
969
947
  url, server, timestamp, performer, destination, service, commits}` to
970
948
  `{ingest_url}/ingest/deploys`. `deploy` comes from `config.deploy`. It
971
949
  aborts if that's unset. `ref` defaults to `git rev-parse HEAD` when not
@@ -974,29 +952,20 @@ Ship with the gem via Rails::Engine's default `lib/tasks` convention, in
974
952
  `{sha, author, message, at}` objects, newest first, from `git log`. It
975
953
  is empty inside an app container, which has no `.git`. That is why the
976
954
  hook below posts from the deployer instead.
977
- - **`railwatch:authentication:configure`** writes the embedded
978
- dashboard's HTTP Basic credentials to the current environment's Rails
979
- credentials.
980
- - **`railwatch:export:status`**, **`railwatch:export:rebind`**,
981
- **`railwatch:export:discard`** show the export queue, clear a
982
- credential block (abandoning work queued under the old token), and
983
- abandon everything queued.
984
- - **`railwatch:vacuum:status`** and **`railwatch:vacuum`** report and
985
- reclaim the telemetry database's disk
986
- ([Embedded mode](embedded.md#giving-the-disk-back)).
987
- - **`railwatch:token`** and **`railwatch:mcp`** print where to create a
988
- cloud ingest token and paste-ready MCP client configuration.
955
+ - **`railwatch:authentication:configure`** writes the
956
+ [dashboard gate](#dashboard-gate-railwatch-server)'s HTTP Basic
957
+ credentials to the current environment's Rails credentials.
958
+ - **`railwatch:token`** and **`railwatch:mcp`** print where to create an
959
+ ingest token and paste-ready MCP client configuration for the server
960
+ `ingest_url` points at.
989
961
  - **`railwatch:sourcemaps[directory,delete]`** uploads browser source
990
962
  maps ([Source maps](source-maps.md)).
991
963
 
992
964
  ## Kamal integration
993
965
 
994
966
  `bin/rails generate railwatch:install` writes `.kamal/hooks/post-deploy`,
995
- but only if `config/deploy.yml` already exists. With
996
- `RAILWATCH_TRANSPORT=local` in the deployer's environment it runs
997
- `bin/rails railwatch:deploy[$KAMAL_VERSION]` in the primary container,
998
- which records the marker in the embedded database, and stops. Otherwise
999
- it no-ops when `RAILWATCH_TOKEN` isn't set. It never fails a deploy.
967
+ but only if `config/deploy.yml` already exists. It no-ops when
968
+ `RAILWATCH_TOKEN` isn't set. It never fails a deploy.
1000
969
  Every network call ends in `|| true`.
1001
970
 
1002
971
  The hook runs on the **deployer machine**, not in a container, which is