limn-review 0.1.123

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 (474) hide show
  1. package/LICENSE +110 -0
  2. package/README.md +133 -0
  3. package/dist/ai/runtime.js +535 -0
  4. package/dist/api/plugins/auth.js +169 -0
  5. package/dist/api/plugins/error-handler.js +114 -0
  6. package/dist/api/plugins/rate-limit.js +855 -0
  7. package/dist/api/plugins/security.js +321 -0
  8. package/dist/api/routes/activity.js +103 -0
  9. package/dist/api/routes/ai-runtime.js +67 -0
  10. package/dist/api/routes/auth.js +194 -0
  11. package/dist/api/routes/billing.js +209 -0
  12. package/dist/api/routes/bot-triage.js +1289 -0
  13. package/dist/api/routes/conflicts.js +730 -0
  14. package/dist/api/routes/contact.js +318 -0
  15. package/dist/api/routes/daily-brief.js +58 -0
  16. package/dist/api/routes/flow.js +71 -0
  17. package/dist/api/routes/health.js +7 -0
  18. package/dist/api/routes/insights.js +200 -0
  19. package/dist/api/routes/me.js +458 -0
  20. package/dist/api/routes/mentions.js +22 -0
  21. package/dist/api/routes/mergers.js +8 -0
  22. package/dist/api/routes/ml-labels.js +109 -0
  23. package/dist/api/routes/open-prs.js +35 -0
  24. package/dist/api/routes/prs.js +1633 -0
  25. package/dist/api/routes/reactions.js +217 -0
  26. package/dist/api/routes/repos.js +563 -0
  27. package/dist/api/routes/search.js +41 -0
  28. package/dist/api/routes/threads.js +118 -0
  29. package/dist/api/routes/timeline.js +150 -0
  30. package/dist/api/routes/users.js +67 -0
  31. package/dist/api/routes/webhooks.js +181 -0
  32. package/dist/api/routes/workspaces.js +322 -0
  33. package/dist/app.js +274 -0
  34. package/dist/ascii.js +19 -0
  35. package/dist/auth/account.js +482 -0
  36. package/dist/auth/crypto.js +46 -0
  37. package/dist/bot-triage/resolve.js +59 -0
  38. package/dist/cli.js +388 -0
  39. package/dist/coding/activity.js +80 -0
  40. package/dist/coding/agent.js +288 -0
  41. package/dist/coding/ai-fix/auto-fix.js +212 -0
  42. package/dist/coding/ai-fix/manager.js +370 -0
  43. package/dist/coding/ai-fix/persist.js +213 -0
  44. package/dist/coding/ai-fix/pr-context.js +58 -0
  45. package/dist/coding/ai-fix/prompts.js +138 -0
  46. package/dist/coding/ai-fix/review-seed.js +357 -0
  47. package/dist/coding/ai-fix/routes.js +425 -0
  48. package/dist/coding/git-ops.js +321 -0
  49. package/dist/coding/git.js +184 -0
  50. package/dist/coding/merge.js +262 -0
  51. package/dist/coding/safe-path.js +75 -0
  52. package/dist/coding/schema.js +43 -0
  53. package/dist/config.js +648 -0
  54. package/dist/conflict/diff.js +304 -0
  55. package/dist/conflict/git.js +118 -0
  56. package/dist/conflict/hash.js +73 -0
  57. package/dist/conflict/janitor.js +218 -0
  58. package/dist/conflict/land.js +675 -0
  59. package/dist/conflict/model-types.js +2 -0
  60. package/dist/conflict/model.js +1081 -0
  61. package/dist/conflict/parse.js +142 -0
  62. package/dist/conflict/seam.js +136 -0
  63. package/dist/conflict/session.js +532 -0
  64. package/dist/conflict/suggestion.js +398 -0
  65. package/dist/conflict/tokens.js +72 -0
  66. package/dist/data-dir.js +112 -0
  67. package/dist/db/actor-lanes.js +213 -0
  68. package/dist/db/automation-ids.js +97 -0
  69. package/dist/db/automation-output.js +349 -0
  70. package/dist/db/blast-radius-query.js +36 -0
  71. package/dist/db/blast-radius.js +226 -0
  72. package/dist/db/bot-dormancy.js +115 -0
  73. package/dist/db/bot-overlap.js +579 -0
  74. package/dist/db/bot-volume.js +722 -0
  75. package/dist/db/bot-window.js +35 -0
  76. package/dist/db/branch-queries.js +310 -0
  77. package/dist/db/change-shape.js +243 -0
  78. package/dist/db/changepoint.js +75 -0
  79. package/dist/db/cleanup.js +36 -0
  80. package/dist/db/client.js +102 -0
  81. package/dist/db/code-loc.js +388 -0
  82. package/dist/db/credits.js +79 -0
  83. package/dist/db/daily-brief.js +406 -0
  84. package/dist/db/dependency-cards.js +145 -0
  85. package/dist/db/erase-account.js +255 -0
  86. package/dist/db/export-account.js +189 -0
  87. package/dist/db/failing-checks.js +124 -0
  88. package/dist/db/file-coupling.js +197 -0
  89. package/dist/db/flow-detail.js +661 -0
  90. package/dist/db/flow-pointers.js +197 -0
  91. package/dist/db/flow-settings.js +67 -0
  92. package/dist/db/forecast.js +114 -0
  93. package/dist/db/line-overlap.js +81 -0
  94. package/dist/db/merge-queue.js +189 -0
  95. package/dist/db/migrate.js +17 -0
  96. package/dist/db/migrations/0000_purple_ben_grimm.sql +155 -0
  97. package/dist/db/migrations/0001_colorful_ozymandias.sql +31 -0
  98. package/dist/db/migrations/0002_famous_sersi.sql +9 -0
  99. package/dist/db/migrations/0003_clever_shinobi_shaw.sql +3 -0
  100. package/dist/db/migrations/0004_pale_scalphunter.sql +1 -0
  101. package/dist/db/migrations/0005_daffy_guardian.sql +2 -0
  102. package/dist/db/migrations/0006_cute_violations.sql +45 -0
  103. package/dist/db/migrations/0007_dark_anthem.sql +2 -0
  104. package/dist/db/migrations/0008_multitenant_accounts.sql +44 -0
  105. package/dist/db/migrations/0009_lean_bodies.sql +13 -0
  106. package/dist/db/migrations/0010_lean_bodies_nullable.sql +56 -0
  107. package/dist/db/migrations/0011_pr_diff_size.sql +10 -0
  108. package/dist/db/migrations/0012_findings_included_default.sql +7 -0
  109. package/dist/db/migrations/0013_review_routing.sql +9 -0
  110. package/dist/db/migrations/0014_account_last_active.sql +6 -0
  111. package/dist/db/migrations/0015_repos_inbox_watch.sql +9 -0
  112. package/dist/db/migrations/0016_repo_viewer_permission.sql +7 -0
  113. package/dist/db/migrations/0017_account_display_name.sql +7 -0
  114. package/dist/db/migrations/0018_finding_comment_kind.sql +7 -0
  115. package/dist/db/migrations/0019_finding_file_in_diff.sql +7 -0
  116. package/dist/db/migrations/0020_claude_review_cost_telemetry.sql +11 -0
  117. package/dist/db/migrations/0021_account_feed_last_seen.sql +7 -0
  118. package/dist/db/migrations/0022_ci_status_events.sql +21 -0
  119. package/dist/db/migrations/0023_ai_usage.sql +21 -0
  120. package/dist/db/migrations/0024_pr_head_ref_name.sql +6 -0
  121. package/dist/db/migrations/0025_account_billing.sql +7 -0
  122. package/dist/db/migrations/0026_ai_credit_allowance.sql +5 -0
  123. package/dist/db/migrations/0027_user_github_type.sql +6 -0
  124. package/dist/db/migrations/0028_bot_review_classification.sql +21 -0
  125. package/dist/db/migrations/0029_bot_mute_rules.sql +19 -0
  126. package/dist/db/migrations/0030_teams.sql +32 -0
  127. package/dist/db/migrations/0031_events_pr_idx.sql +7 -0
  128. package/dist/db/migrations/0032_benchmark_contributions.sql +29 -0
  129. package/dist/db/migrations/0033_thread_addressed_confidence.sql +9 -0
  130. package/dist/db/migrations/0034_thread_resolved_at.sql +6 -0
  131. package/dist/db/migrations/0035_pr_first_review_requested_at.sql +5 -0
  132. package/dist/db/migrations/0036_search_index.sql +25 -0
  133. package/dist/db/migrations/0037_author_indexes.sql +15 -0
  134. package/dist/db/migrations/0038_auto_merge_requests.sql +37 -0
  135. package/dist/db/migrations/0039_branch_status.sql +44 -0
  136. package/dist/db/migrations/0040_pr_review_decision.sql +10 -0
  137. package/dist/db/migrations/0041_branch_commit_detail.sql +38 -0
  138. package/dist/db/migrations/0042_repo_reviewers.sql +176 -0
  139. package/dist/db/migrations/0043_account_reviewers.sql +131 -0
  140. package/dist/db/migrations/0044_workspaces.sql +138 -0
  141. package/dist/db/migrations/0045_workspace_reviewers.sql +180 -0
  142. package/dist/db/migrations/0046_drop_inbox_watch.sql +25 -0
  143. package/dist/db/migrations/0047_ml_comment_labels.sql +40 -0
  144. package/dist/db/migrations/0048_ml_vendor_severity.sql +31 -0
  145. package/dist/db/migrations/0049_seat_pricing_repo_description.sql +21 -0
  146. package/dist/db/migrations/0050_users_app_slug.sql +12 -0
  147. package/dist/db/migrations/0051_auto_merge_queue.sql +17 -0
  148. package/dist/db/migrations/0052_trunk_ci_status_events.sql +43 -0
  149. package/dist/db/migrations/0053_automation_roles.sql +79 -0
  150. package/dist/db/migrations/0054_automation_vendor_kinds.sql +514 -0
  151. package/dist/db/migrations/0055_auto_merge_phase.sql +12 -0
  152. package/dist/db/migrations/0056_pr_mentions.sql +22 -0
  153. package/dist/db/migrations/0057_large_pr_threshold.sql +14 -0
  154. package/dist/db/migrations/0058_pending_mute.sql +53 -0
  155. package/dist/db/migrations/0059_merge_queue_state.sql +33 -0
  156. package/dist/db/migrations/0060_drop_my_turn_dismissals.sql +33 -0
  157. package/dist/db/migrations/0061_auto_merge_durable_anchors.sql +27 -0
  158. package/dist/db/migrations/0062_blast_radius_config.sql +21 -0
  159. package/dist/db/migrations/0063_repo_file_coupling.sql +33 -0
  160. package/dist/db/migrations/0064_pr_content_kind.sql +21 -0
  161. package/dist/db/migrations/0065_workspace_flow_settings.sql +13 -0
  162. package/dist/db/migrations/0066_review_request_events.sql +31 -0
  163. package/dist/db/migrations/0067_pr_security_signals.sql +86 -0
  164. package/dist/db/migrations/0068_my_turn_settings.sql +18 -0
  165. package/dist/db/migrations/0069_my_turn_dismissals.sql +41 -0
  166. package/dist/db/migrations/0070_claude_review_follow_up_ticket.sql +22 -0
  167. package/dist/db/migrations/0071_claude_review_trigger.sql +11 -0
  168. package/dist/db/migrations/0072_commit_message_headline.sql +13 -0
  169. package/dist/db/migrations/0073_claude_review_chat.sql +31 -0
  170. package/dist/db/migrations/0074_adopt_agentic_tables.sql +98 -0
  171. package/dist/db/migrations/0075_review_lens_drop_learnings.sql +15 -0
  172. package/dist/db/migrations/0076_claude_review_threads.sql +17 -0
  173. package/dist/db/migrations/0077_claude_review_ci_failures.sql +10 -0
  174. package/dist/db/migrations/0078_ai_fix_change_report.sql +17 -0
  175. package/dist/db/migrations/0079_claude_finding_story.sql +16 -0
  176. package/dist/db/migrations/meta/0000_snapshot.json +1116 -0
  177. package/dist/db/migrations/meta/0001_snapshot.json +1321 -0
  178. package/dist/db/migrations/meta/0002_snapshot.json +1375 -0
  179. package/dist/db/migrations/meta/0003_snapshot.json +1396 -0
  180. package/dist/db/migrations/meta/0004_snapshot.json +1416 -0
  181. package/dist/db/migrations/meta/0005_snapshot.json +1430 -0
  182. package/dist/db/migrations/meta/0006_snapshot.json +1745 -0
  183. package/dist/db/migrations/meta/0007_snapshot.json +1759 -0
  184. package/dist/db/migrations/meta/_journal.json +566 -0
  185. package/dist/db/migrations-pg/0000_tired_alex_power.sql +268 -0
  186. package/dist/db/migrations-pg/0001_dizzy_mockingbird.sql +3 -0
  187. package/dist/db/migrations-pg/0002_glorious_ikaris.sql +4 -0
  188. package/dist/db/migrations-pg/0003_melted_secret_warriors.sql +2 -0
  189. package/dist/db/migrations-pg/0004_numerous_triton.sql +1 -0
  190. package/dist/db/migrations-pg/0005_thick_blockbuster.sql +2 -0
  191. package/dist/db/migrations-pg/0006_majestic_dracula.sql +1 -0
  192. package/dist/db/migrations-pg/0007_same_human_torch.sql +2 -0
  193. package/dist/db/migrations-pg/0008_slimy_toxin.sql +1 -0
  194. package/dist/db/migrations-pg/0009_fuzzy_jubilee.sql +4 -0
  195. package/dist/db/migrations-pg/0010_late_hammerhead.sql +1 -0
  196. package/dist/db/migrations-pg/0011_happy_leech.sql +16 -0
  197. package/dist/db/migrations-pg/0012_woozy_captain_midlands.sql +16 -0
  198. package/dist/db/migrations-pg/0013_yielding_nicolaos.sql +1 -0
  199. package/dist/db/migrations-pg/0014_wakeful_bill_hollister.sql +2 -0
  200. package/dist/db/migrations-pg/0015_aspiring_black_tom.sql +1 -0
  201. package/dist/db/migrations-pg/0016_cute_ghost_rider.sql +30 -0
  202. package/dist/db/migrations-pg/0017_far_changeling.sql +24 -0
  203. package/dist/db/migrations-pg/0018_fancy_miss_america.sql +1 -0
  204. package/dist/db/migrations-pg/0019_benchmark_contributions.sql +22 -0
  205. package/dist/db/migrations-pg/0020_majestic_edwin_jarvis.sql +3 -0
  206. package/dist/db/migrations-pg/0021_green_salo.sql +1 -0
  207. package/dist/db/migrations-pg/0022_wise_baron_strucker.sql +1 -0
  208. package/dist/db/migrations-pg/0023_search_index.sql +19 -0
  209. package/dist/db/migrations-pg/0024_author_indexes.sql +9 -0
  210. package/dist/db/migrations-pg/0025_auto_merge_requests.sql +26 -0
  211. package/dist/db/migrations-pg/0026_branch_status.sql +32 -0
  212. package/dist/db/migrations-pg/0027_pr_review_decision.sql +5 -0
  213. package/dist/db/migrations-pg/0028_branch_commit_detail.sql +9 -0
  214. package/dist/db/migrations-pg/0029_repo_reviewers.sql +127 -0
  215. package/dist/db/migrations-pg/0030_account_reviewers.sql +77 -0
  216. package/dist/db/migrations-pg/0031_workspaces.sql +131 -0
  217. package/dist/db/migrations-pg/0032_workspace_reviewers.sql +165 -0
  218. package/dist/db/migrations-pg/0033_drop_inbox_watch.sql +14 -0
  219. package/dist/db/migrations-pg/0034_ml_comment_labels.sql +33 -0
  220. package/dist/db/migrations-pg/0035_ml_vendor_severity.sql +16 -0
  221. package/dist/db/migrations-pg/0036_seat_pricing_repo_description.sql +12 -0
  222. package/dist/db/migrations-pg/0037_users_app_slug.sql +9 -0
  223. package/dist/db/migrations-pg/0038_auto_merge_queue.sql +10 -0
  224. package/dist/db/migrations-pg/0039_trunk_ci_status_events.sql +27 -0
  225. package/dist/db/migrations-pg/0040_automation_roles.sql +63 -0
  226. package/dist/db/migrations-pg/0041_automation_vendor_kinds.sql +488 -0
  227. package/dist/db/migrations-pg/0042_auto_merge_phase.sql +8 -0
  228. package/dist/db/migrations-pg/0043_pr_mentions.sql +19 -0
  229. package/dist/db/migrations-pg/0044_large_pr_threshold.sql +6 -0
  230. package/dist/db/migrations-pg/0045_pending_mute.sql +26 -0
  231. package/dist/db/migrations-pg/0046_merge_queue_state.sql +18 -0
  232. package/dist/db/migrations-pg/0047_drop_my_turn_dismissals.sql +21 -0
  233. package/dist/db/migrations-pg/0048_auto_merge_durable_anchors.sql +27 -0
  234. package/dist/db/migrations-pg/0049_blast_radius_config.sql +8 -0
  235. package/dist/db/migrations-pg/0050_repo_file_coupling.sql +13 -0
  236. package/dist/db/migrations-pg/0051_pr_content_kind.sql +6 -0
  237. package/dist/db/migrations-pg/0052_workspace_flow_settings.sql +4 -0
  238. package/dist/db/migrations-pg/0053_review_request_events.sql +18 -0
  239. package/dist/db/migrations-pg/0054_pr_security_signals.sql +59 -0
  240. package/dist/db/migrations-pg/0055_my_turn_settings.sql +6 -0
  241. package/dist/db/migrations-pg/0056_my_turn_dismissals.sql +21 -0
  242. package/dist/db/migrations-pg/0057_claude_review_follow_up_ticket.sql +8 -0
  243. package/dist/db/migrations-pg/0058_claude_review_trigger.sql +4 -0
  244. package/dist/db/migrations-pg/0059_commit_message_headline.sql +3 -0
  245. package/dist/db/migrations-pg/0060_claude_review_chat.sql +24 -0
  246. package/dist/db/migrations-pg/0061_adopt_agentic_tables.sql +79 -0
  247. package/dist/db/migrations-pg/0062_review_lens_drop_learnings.sql +5 -0
  248. package/dist/db/migrations-pg/0063_claude_review_threads.sql +7 -0
  249. package/dist/db/migrations-pg/0064_claude_review_ci_failures.sql +4 -0
  250. package/dist/db/migrations-pg/0065_ai_fix_change_report.sql +9 -0
  251. package/dist/db/migrations-pg/0066_claude_finding_story.sql +7 -0
  252. package/dist/db/migrations-pg/meta/0000_snapshot.json +2137 -0
  253. package/dist/db/migrations-pg/meta/0001_snapshot.json +2143 -0
  254. package/dist/db/migrations-pg/meta/0002_snapshot.json +2170 -0
  255. package/dist/db/migrations-pg/meta/0003_snapshot.json +2182 -0
  256. package/dist/db/migrations-pg/meta/0004_snapshot.json +2188 -0
  257. package/dist/db/migrations-pg/meta/0005_snapshot.json +2201 -0
  258. package/dist/db/migrations-pg/meta/0006_snapshot.json +2207 -0
  259. package/dist/db/migrations-pg/meta/0007_snapshot.json +2219 -0
  260. package/dist/db/migrations-pg/meta/0008_snapshot.json +2226 -0
  261. package/dist/db/migrations-pg/meta/0009_snapshot.json +2250 -0
  262. package/dist/db/migrations-pg/meta/0010_snapshot.json +2256 -0
  263. package/dist/db/migrations-pg/meta/0011_snapshot.json +2412 -0
  264. package/dist/db/migrations-pg/meta/0012_snapshot.json +2528 -0
  265. package/dist/db/migrations-pg/meta/0013_snapshot.json +2534 -0
  266. package/dist/db/migrations-pg/meta/0014_snapshot.json +2547 -0
  267. package/dist/db/migrations-pg/meta/0015_snapshot.json +2553 -0
  268. package/dist/db/migrations-pg/meta/0016_snapshot.json +2774 -0
  269. package/dist/db/migrations-pg/meta/0017_snapshot.json +2999 -0
  270. package/dist/db/migrations-pg/meta/0018_snapshot.json +3020 -0
  271. package/dist/db/migrations-pg/meta/0020_snapshot.json +3228 -0
  272. package/dist/db/migrations-pg/meta/0021_snapshot.json +3234 -0
  273. package/dist/db/migrations-pg/meta/0022_snapshot.json +3240 -0
  274. package/dist/db/migrations-pg/meta/_journal.json +475 -0
  275. package/dist/db/ml-labels.js +1666 -0
  276. package/dist/db/my-turn-dismissals.js +343 -0
  277. package/dist/db/my-turn-settings.js +34 -0
  278. package/dist/db/pending-classify.js +46 -0
  279. package/dist/db/pending-mute.js +171 -0
  280. package/dist/db/pending-tabs.js +238 -0
  281. package/dist/db/period-metrics.js +820 -0
  282. package/dist/db/person-period.js +763 -0
  283. package/dist/db/pr-intervals.js +930 -0
  284. package/dist/db/pr-liveness.js +240 -0
  285. package/dist/db/pr-mentions.js +279 -0
  286. package/dist/db/pr-merge-queue-stamp.js +91 -0
  287. package/dist/db/queries.js +14631 -0
  288. package/dist/db/reaction-targets.js +94 -0
  289. package/dist/db/repo-activity.js +171 -0
  290. package/dist/db/retention.js +138 -0
  291. package/dist/db/review-threads-for-review.js +240 -0
  292. package/dist/db/run-migrations.js +24 -0
  293. package/dist/db/schema.pg.js +1220 -0
  294. package/dist/db/schema.sqlite.js +1801 -0
  295. package/dist/db/search.js +317 -0
  296. package/dist/db/security-alerts.js +218 -0
  297. package/dist/db/synthesis-input.js +565 -0
  298. package/dist/db/triage.js +320 -0
  299. package/dist/db/usage.js +63 -0
  300. package/dist/db/work-plan.js +1086 -0
  301. package/dist/db/working-hours.js +161 -0
  302. package/dist/feed/my-turn.js +122 -0
  303. package/dist/github/actions-logs.js +397 -0
  304. package/dist/github/auth.js +86 -0
  305. package/dist/github/branch-queries.js +229 -0
  306. package/dist/github/client.js +454 -0
  307. package/dist/github/codeowners.js +221 -0
  308. package/dist/github/commit-checks.js +105 -0
  309. package/dist/github/compare.js +110 -0
  310. package/dist/github/diff-anchor.js +227 -0
  311. package/dist/github/mutations.js +706 -0
  312. package/dist/github/pr-file-content.js +254 -0
  313. package/dist/github/pr-liveness.js +161 -0
  314. package/dist/github/queries.js +875 -0
  315. package/dist/github/rate-budget.js +129 -0
  316. package/dist/github/reactions.js +161 -0
  317. package/dist/github/reviewer-suggest.js +104 -0
  318. package/dist/github/team-reviewers.js +96 -0
  319. package/dist/index.js +184 -0
  320. package/dist/merge/auto-merge-runner.js +960 -0
  321. package/dist/ml/severity-client.js +218 -0
  322. package/dist/pr/detail-enricher.js +26 -0
  323. package/dist/pro/bind.js +302 -0
  324. package/dist/pro/contract.js +37 -0
  325. package/dist/pro/migrate.js +64 -0
  326. package/dist/review/agent-context.js +127 -0
  327. package/dist/review/agent.js +385 -0
  328. package/dist/review/agentic.js +59 -0
  329. package/dist/review/auth.js +94 -0
  330. package/dist/review/chat-agent.js +179 -0
  331. package/dist/review/claude-review/ai-ready.js +16 -0
  332. package/dist/review/claude-review/auto-settings.js +139 -0
  333. package/dist/review/claude-review/auto.js +244 -0
  334. package/dist/review/claude-review/chat.js +489 -0
  335. package/dist/review/claude-review/ci-failures.js +350 -0
  336. package/dist/review/claude-review/follow-up.js +310 -0
  337. package/dist/review/claude-review/manager.js +686 -0
  338. package/dist/review/claude-review/persist.js +996 -0
  339. package/dist/review/claude-review/prompts.js +357 -0
  340. package/dist/review/claude-review/routes.js +518 -0
  341. package/dist/review/claude-review/routing.js +61 -0
  342. package/dist/review/claude-review/specialists.js +190 -0
  343. package/dist/review/claude-review/threads.js +265 -0
  344. package/dist/review/claude-review/ticket.js +282 -0
  345. package/dist/review/clone-hygiene.js +380 -0
  346. package/dist/review/clone-manager.js +367 -0
  347. package/dist/review/llm.js +113 -0
  348. package/dist/review/model-options.js +48 -0
  349. package/dist/review/plugin-providers.js +12 -0
  350. package/dist/review/post-review.js +216 -0
  351. package/dist/review/post-seam.js +161 -0
  352. package/dist/review/prepare.js +168 -0
  353. package/dist/review/pricing.js +17 -0
  354. package/dist/review/schema.js +156 -0
  355. package/dist/review/submit-map.js +41 -0
  356. package/dist/review/usage.js +90 -0
  357. package/dist/shared/claude-review.js +335 -0
  358. package/dist/shared/conflict-fold.js +151 -0
  359. package/dist/shared/conflicts.js +30 -0
  360. package/dist/shared/flow-settings.js +191 -0
  361. package/dist/shared/index.js +8 -0
  362. package/dist/shared/my-turn-settings.js +238 -0
  363. package/dist/shared/pending-rules.js +281 -0
  364. package/dist/shared/product.js +54 -0
  365. package/dist/shared/types.js +896 -0
  366. package/dist/status.js +386 -0
  367. package/dist/sync/adaptive.js +185 -0
  368. package/dist/sync/app-attribution.js +66 -0
  369. package/dist/sync/auth-notices.js +36 -0
  370. package/dist/sync/backfill-ci-history.js +315 -0
  371. package/dist/sync/backfill-commit-headlines.js +136 -0
  372. package/dist/sync/backfill-pr-security.js +175 -0
  373. package/dist/sync/backfill-review-requests.js +97 -0
  374. package/dist/sync/benchmark-rollup.js +50 -0
  375. package/dist/sync/bot-detection.js +309 -0
  376. package/dist/sync/bot-resolution-markers.js +30 -0
  377. package/dist/sync/branch-status.js +634 -0
  378. package/dist/sync/classify-change-shape.js +150 -0
  379. package/dist/sync/commit-files.js +74 -0
  380. package/dist/sync/derive-thread-state.js +99 -0
  381. package/dist/sync/drain-review-threads.js +212 -0
  382. package/dist/sync/hydrate-detail.js +482 -0
  383. package/dist/sync/mention-scan.js +89 -0
  384. package/dist/sync/ml-enrichment.js +478 -0
  385. package/dist/sync/pr-change-signal.js +96 -0
  386. package/dist/sync/pr-liveness-sweep.js +139 -0
  387. package/dist/sync/pr-settle.js +381 -0
  388. package/dist/sync/refresh-pr.js +163 -0
  389. package/dist/sync/reparse-vendor-badges.js +495 -0
  390. package/dist/sync/resync-after-write.js +280 -0
  391. package/dist/sync/review-fingerprint.js +117 -0
  392. package/dist/sync/reviewer-behavior.js +103 -0
  393. package/dist/sync/reviewer-classify.js +503 -0
  394. package/dist/sync/routing-files.js +97 -0
  395. package/dist/sync/scheduled-jobs.js +12 -0
  396. package/dist/sync/scheduler.js +159 -0
  397. package/dist/sync/security-detect.js +521 -0
  398. package/dist/sync/sync-manager.js +750 -0
  399. package/dist/sync/sync-one-pr.js +205 -0
  400. package/dist/sync/sync-repo.js +400 -0
  401. package/dist/sync/unsettled-prs.js +506 -0
  402. package/dist/sync/upsert.js +1190 -0
  403. package/package.json +56 -0
  404. package/public/apple-touch-icon.png +0 -0
  405. package/public/assets/AiFixTab-CQP6PT5u.js +2 -0
  406. package/public/assets/ClaudeReviewTab-DQJ-58ZA.js +8 -0
  407. package/public/assets/PrBotBehaviourTab-CCnFrWbC.js +1 -0
  408. package/public/assets/archivo-latin-600-BN-JkNrl.woff2 +0 -0
  409. package/public/assets/highlight-BEHUn5zE.css +10 -0
  410. package/public/assets/highlight-CIIZLa6Z.js +12 -0
  411. package/public/assets/index-BDnYs6zg.js +73 -0
  412. package/public/assets/index-mCuI--RC.css +1 -0
  413. package/public/assets/markdown-I_JLLVAZ.js +32 -0
  414. package/public/assets/perfProbe-Da13EhTE.js +1 -0
  415. package/public/assets/tanstack-5qsxxaLe.js +17 -0
  416. package/public/assets/vis-C3BCkP5U.js +1280 -0
  417. package/public/assets/vis-ziCVehMy.css +1 -0
  418. package/public/favicon-16.png +0 -0
  419. package/public/favicon-32.png +0 -0
  420. package/public/favicon-48.png +0 -0
  421. package/public/favicon.svg +5 -0
  422. package/public/index.html +41 -0
  423. package/public-landing/apple-touch-icon.png +0 -0
  424. package/public-landing/assets/archivo-latin-500-BWmvx2Mg.woff2 +0 -0
  425. package/public-landing/assets/archivo-latin-600-BN-JkNrl.woff2 +0 -0
  426. package/public-landing/assets/index-CA3eEGXO.js +40 -0
  427. package/public-landing/assets/index-naQrQ6Fe.css +1 -0
  428. package/public-landing/assets/jetbrains-mono-latin-400-RruCX7RW.woff2 +0 -0
  429. package/public-landing/assets/newsreader-latin-400-DExrRRrN.woff2 +0 -0
  430. package/public-landing/assets/newsreader-latin-400-italic-b0I-AwbV.woff2 +0 -0
  431. package/public-landing/bots/index.html +156 -0
  432. package/public-landing/contact/index.html +156 -0
  433. package/public-landing/cookies/index.html +156 -0
  434. package/public-landing/demo/limn-walkthrough-poster.jpg +0 -0
  435. package/public-landing/demo/limn-walkthrough.cues.json +44 -0
  436. package/public-landing/demo/limn-walkthrough.mp4 +0 -0
  437. package/public-landing/favicon-16.png +0 -0
  438. package/public-landing/favicon-32.png +0 -0
  439. package/public-landing/favicon-48.png +0 -0
  440. package/public-landing/favicon.svg +5 -0
  441. package/public-landing/features/index.html +156 -0
  442. package/public-landing/for-developers/index.html +156 -0
  443. package/public-landing/for-managers/index.html +156 -0
  444. package/public-landing/how-it-works/index.html +156 -0
  445. package/public-landing/how-we-measure/index.html +156 -0
  446. package/public-landing/icon-192.png +0 -0
  447. package/public-landing/icon-512.png +0 -0
  448. package/public-landing/index.html +156 -0
  449. package/public-landing/insights/index.html +156 -0
  450. package/public-landing/og-image.png +0 -0
  451. package/public-landing/pricing/index.html +156 -0
  452. package/public-landing/privacy/index.html +156 -0
  453. package/public-landing/pro/index.html +156 -0
  454. package/public-landing/reviews/index.html +156 -0
  455. package/public-landing/robots.txt +8 -0
  456. package/public-landing/shots/benchmark.png +0 -0
  457. package/public-landing/shots/bot-roi.png +0 -0
  458. package/public-landing/shots/bot-settings.png +0 -0
  459. package/public-landing/shots/chronology.png +0 -0
  460. package/public-landing/shots/feed.png +0 -0
  461. package/public-landing/shots/flow-metrics.png +0 -0
  462. package/public-landing/shots/free-reports.png +0 -0
  463. package/public-landing/shots/pending-board.png +0 -0
  464. package/public-landing/shots/pending-card.png +0 -0
  465. package/public-landing/shots/period-report.png +0 -0
  466. package/public-landing/shots/pr-detail.png +0 -0
  467. package/public-landing/shots/pr-threads.png +0 -0
  468. package/public-landing/shots/reach.png +0 -0
  469. package/public-landing/shots/repo-rows.png +0 -0
  470. package/public-landing/shots/severity-findings.png +0 -0
  471. package/public-landing/shots/severity-strip.png +0 -0
  472. package/public-landing/site.webmanifest +14 -0
  473. package/public-landing/sitemap.xml +51 -0
  474. package/public-landing/terms/index.html +156 -0
@@ -0,0 +1,514 @@
1
+ -- Brand the automations that were stored as `in_house` — the bucket labelled "In-house AI".
2
+ --
3
+ -- WHY THIS IS NEEDED AT ALL, and why it is the same shape as `0053`. The classifier's step 2
4
+ -- fires on `githubType === 'Bot'` and assigns `fp?.tool ?? 'in_house'`, and until now there was
5
+ -- no step between it and the AI-reviewer login check. So EVERY non-reviewer integration — every
6
+ -- quality gate, dependency bot, code agent, release and housekeeping automation — was stored as
7
+ -- "In-house AI": 25 of 37 such rows on the dev corpus, holding sonarqubecloud, dependabot[bot],
8
+ -- github-actions[bot], gitguardian, socket-security, google-cla and jit-ci. They all rendered
9
+ -- with the same grey chip and the same wrong name, on the one screen that exists to classify them.
10
+ --
11
+ -- The stored `kind` wins over any derivation on read, so widening the vocabulary in code alone
12
+ -- would only ever reach an install nobody had opened the Bots tab on.
13
+ --
14
+ -- ── THE THREE CONDITIONS ARE EACH LOAD-BEARING ──────────────────────────────────────────────
15
+ --
16
+ -- `identity_source <> 'manual'` — a vendor a HUMAN named is never re-derived. Identity is
17
+ -- owned by `identity_source`, judgement by `source`; this
18
+ -- migration touches only the identity half, so a manual
19
+ -- "not a bot" verdict elsewhere on the row is unaffected.
20
+ -- `kind IN ('in_house','vendor')` — only the UNBRANDED kinds are upgraded. A row already
21
+ -- carrying a real brand is left alone even if the login
22
+ -- vocabulary would now claim it, because that brand came
23
+ -- from a stronger signal (a vendor-login or fingerprint hit)
24
+ -- and silently overwriting it is how a correction gets lost.
25
+ -- `label = NULL` — the label is a CACHE of the kind's display name, and the
26
+ -- old rows hold the literal "In-house AI" or the bare login.
27
+ -- Leaving it would show "In-house AI" beside a SonarQube
28
+ -- chip. NULL means "use the brand name", which is exactly
29
+ -- what the reader wants and what `label` is documented to do.
30
+ --
31
+ -- `[bot]`-suffix stripping is the same rule as 0053: `dependabot` and `dependabot[bot]` are
32
+ -- separate `users` rows with different node ids, and covering one spelling splits one actor.
33
+ --
34
+ -- ⚠ IT COVERS THE AI-REVIEW VENDORS TOO, not only the new families. Found while checking the
35
+ -- result on a live database: `deepsource-io` and `github-code-quality` were also sitting at
36
+ -- `in_house`, because their rows were written before those logins joined `REVIEW_BOTS`. The
37
+ -- staleness is identical and so is the fix — the stored kind wins on read, so a login joining a
38
+ -- vocabulary never reaches an actor that has already been classified.
39
+ UPDATE `workspace_reviewers`
40
+ SET `kind` = 'allcontributors', `label` = NULL
41
+ WHERE `identity_source` <> 'manual'
42
+ AND `kind` IN ('in_house', 'vendor')
43
+ AND `author_user_id` IN (
44
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('allcontributors')
45
+ );--> statement-breakpoint
46
+ UPDATE `workspace_reviewers`
47
+ SET `kind` = 'allstar', `label` = NULL
48
+ WHERE `identity_source` <> 'manual'
49
+ AND `kind` IN ('in_house', 'vendor')
50
+ AND `author_user_id` IN (
51
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('allstar')
52
+ );--> statement-breakpoint
53
+ UPDATE `workspace_reviewers`
54
+ SET `kind` = 'backport', `label` = NULL
55
+ WHERE `identity_source` <> 'manual'
56
+ AND `kind` IN ('in_house', 'vendor')
57
+ AND `author_user_id` IN (
58
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('backport', 'lumberbot-app', 'meeseeksdev')
59
+ );--> statement-breakpoint
60
+ UPDATE `workspace_reviewers`
61
+ SET `kind` = 'baz', `label` = NULL
62
+ WHERE `identity_source` <> 'manual'
63
+ AND `kind` IN ('in_house', 'vendor')
64
+ AND `author_user_id` IN (
65
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('baz-reviewer')
66
+ );--> statement-breakpoint
67
+ UPDATE `workspace_reviewers`
68
+ SET `kind` = 'bito', `label` = NULL
69
+ WHERE `identity_source` <> 'manual'
70
+ AND `kind` IN ('in_house', 'vendor')
71
+ AND `author_user_id` IN (
72
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('bito-code-review')
73
+ );--> statement-breakpoint
74
+ UPDATE `workspace_reviewers`
75
+ SET `kind` = 'bulldozer', `label` = NULL
76
+ WHERE `identity_source` <> 'manual'
77
+ AND `kind` IN ('in_house', 'vendor')
78
+ AND `author_user_id` IN (
79
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('bulldozer')
80
+ );--> statement-breakpoint
81
+ UPDATE `workspace_reviewers`
82
+ SET `kind` = 'changesets', `label` = NULL
83
+ WHERE `identity_source` <> 'manual'
84
+ AND `kind` IN ('in_house', 'vendor')
85
+ AND `author_user_id` IN (
86
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('changeset-bot', 'changesets')
87
+ );--> statement-breakpoint
88
+ UPDATE `workspace_reviewers`
89
+ SET `kind` = 'cla_assistant', `label` = NULL
90
+ WHERE `identity_source` <> 'manual'
91
+ AND `kind` IN ('in_house', 'vendor')
92
+ AND `author_user_id` IN (
93
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('cla-assistant', 'cla-bot', 'claassistant')
94
+ );--> statement-breakpoint
95
+ UPDATE `workspace_reviewers`
96
+ SET `kind` = 'codacy', `label` = NULL
97
+ WHERE `identity_source` <> 'manual'
98
+ AND `kind` IN ('in_house', 'vendor')
99
+ AND `author_user_id` IN (
100
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('codacy-bot')
101
+ );--> statement-breakpoint
102
+ UPDATE `workspace_reviewers`
103
+ SET `kind` = 'codeclimate', `label` = NULL
104
+ WHERE `identity_source` <> 'manual'
105
+ AND `kind` IN ('in_house', 'vendor')
106
+ AND `author_user_id` IN (
107
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('codeclimate')
108
+ );--> statement-breakpoint
109
+ UPDATE `workspace_reviewers`
110
+ SET `kind` = 'codecov', `label` = NULL
111
+ WHERE `identity_source` <> 'manual'
112
+ AND `kind` IN ('in_house', 'vendor')
113
+ AND `author_user_id` IN (
114
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('codecov')
115
+ );--> statement-breakpoint
116
+ UPDATE `workspace_reviewers`
117
+ SET `kind` = 'codefactor', `label` = NULL
118
+ WHERE `identity_source` <> 'manual'
119
+ AND `kind` IN ('in_house', 'vendor')
120
+ AND `author_user_id` IN (
121
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('codefactor-io')
122
+ );--> statement-breakpoint
123
+ UPDATE `workspace_reviewers`
124
+ SET `kind` = 'codegen', `label` = NULL
125
+ WHERE `identity_source` <> 'manual'
126
+ AND `kind` IN ('in_house', 'vendor')
127
+ AND `author_user_id` IN (
128
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('codegen-sh')
129
+ );--> statement-breakpoint
130
+ UPDATE `workspace_reviewers`
131
+ SET `kind` = 'coderabbit', `label` = NULL
132
+ WHERE `identity_source` <> 'manual'
133
+ AND `kind` IN ('in_house', 'vendor')
134
+ AND `author_user_id` IN (
135
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('coderabbitai')
136
+ );--> statement-breakpoint
137
+ UPDATE `workspace_reviewers`
138
+ SET `kind` = 'codesandbox', `label` = NULL
139
+ WHERE `identity_source` <> 'manual'
140
+ AND `kind` IN ('in_house', 'vendor')
141
+ AND `author_user_id` IN (
142
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('codesandbox-ci')
143
+ );--> statement-breakpoint
144
+ UPDATE `workspace_reviewers`
145
+ SET `kind` = 'codex', `label` = NULL
146
+ WHERE `identity_source` <> 'manual'
147
+ AND `kind` IN ('in_house', 'vendor')
148
+ AND `author_user_id` IN (
149
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('chatgpt-codex-connector')
150
+ );--> statement-breakpoint
151
+ UPDATE `workspace_reviewers`
152
+ SET `kind` = 'copilot', `label` = NULL
153
+ WHERE `identity_source` <> 'manual'
154
+ AND `kind` IN ('in_house', 'vendor')
155
+ AND `author_user_id` IN (
156
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('copilot-pull-request-reviewer')
157
+ );--> statement-breakpoint
158
+ UPDATE `workspace_reviewers`
159
+ SET `kind` = 'coveralls', `label` = NULL
160
+ WHERE `identity_source` <> 'manual'
161
+ AND `kind` IN ('in_house', 'vendor')
162
+ AND `author_user_id` IN (
163
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('coveralls')
164
+ );--> statement-breakpoint
165
+ UPDATE `workspace_reviewers`
166
+ SET `kind` = 'crowdin', `label` = NULL
167
+ WHERE `identity_source` <> 'manual'
168
+ AND `kind` IN ('in_house', 'vendor')
169
+ AND `author_user_id` IN (
170
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('crowdin-bot')
171
+ );--> statement-breakpoint
172
+ UPDATE `workspace_reviewers`
173
+ SET `kind` = 'cursor', `label` = NULL
174
+ WHERE `identity_source` <> 'manual'
175
+ AND `kind` IN ('in_house', 'vendor')
176
+ AND `author_user_id` IN (
177
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('cursor')
178
+ );--> statement-breakpoint
179
+ UPDATE `workspace_reviewers`
180
+ SET `kind` = 'dco', `label` = NULL
181
+ WHERE `identity_source` <> 'manual'
182
+ AND `kind` IN ('in_house', 'vendor')
183
+ AND `author_user_id` IN (
184
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('dco')
185
+ );--> statement-breakpoint
186
+ UPDATE `workspace_reviewers`
187
+ SET `kind` = 'deepsource', `label` = NULL
188
+ WHERE `identity_source` <> 'manual'
189
+ AND `kind` IN ('in_house', 'vendor')
190
+ AND `author_user_id` IN (
191
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('deepsource-io', 'deepsourcebot')
192
+ );--> statement-breakpoint
193
+ UPDATE `workspace_reviewers`
194
+ SET `kind` = 'deepsource_autofix', `label` = NULL
195
+ WHERE `identity_source` <> 'manual'
196
+ AND `kind` IN ('in_house', 'vendor')
197
+ AND `author_user_id` IN (
198
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('deepsource-autofix')
199
+ );--> statement-breakpoint
200
+ UPDATE `workspace_reviewers`
201
+ SET `kind` = 'dependabot', `label` = NULL
202
+ WHERE `identity_source` <> 'manual'
203
+ AND `kind` IN ('in_house', 'vendor')
204
+ AND `author_user_id` IN (
205
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('dependabot', 'dependabot-preview')
206
+ );--> statement-breakpoint
207
+ UPDATE `workspace_reviewers`
208
+ SET `kind` = 'depfu', `label` = NULL
209
+ WHERE `identity_source` <> 'manual'
210
+ AND `kind` IN ('in_house', 'vendor')
211
+ AND `author_user_id` IN (
212
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('depfu')
213
+ );--> statement-breakpoint
214
+ UPDATE `workspace_reviewers`
215
+ SET `kind` = 'devin', `label` = NULL
216
+ WHERE `identity_source` <> 'manual'
217
+ AND `kind` IN ('in_house', 'vendor')
218
+ AND `author_user_id` IN (
219
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('devin-ai-integration')
220
+ );--> statement-breakpoint
221
+ UPDATE `workspace_reviewers`
222
+ SET `kind` = 'ellipsis', `label` = NULL
223
+ WHERE `identity_source` <> 'manual'
224
+ AND `kind` IN ('in_house', 'vendor')
225
+ AND `author_user_id` IN (
226
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('ellipsis-dev')
227
+ );--> statement-breakpoint
228
+ UPDATE `workspace_reviewers`
229
+ SET `kind` = 'entelligence', `label` = NULL
230
+ WHERE `identity_source` <> 'manual'
231
+ AND `kind` IN ('in_house', 'vendor')
232
+ AND `author_user_id` IN (
233
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('entelligence-ai-pr-reviews')
234
+ );--> statement-breakpoint
235
+ UPDATE `workspace_reviewers`
236
+ SET `kind` = 'gitguardian', `label` = NULL
237
+ WHERE `identity_source` <> 'manual'
238
+ AND `kind` IN ('in_house', 'vendor')
239
+ AND `author_user_id` IN (
240
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('gitguardian')
241
+ );--> statement-breakpoint
242
+ UPDATE `workspace_reviewers`
243
+ SET `kind` = 'github_actions', `label` = NULL
244
+ WHERE `identity_source` <> 'manual'
245
+ AND `kind` IN ('in_house', 'vendor')
246
+ AND `author_user_id` IN (
247
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('github-actions')
248
+ );--> statement-breakpoint
249
+ UPDATE `workspace_reviewers`
250
+ SET `kind` = 'github_advanced_security', `label` = NULL
251
+ WHERE `identity_source` <> 'manual'
252
+ AND `kind` IN ('in_house', 'vendor')
253
+ AND `author_user_id` IN (
254
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('github-advanced-security')
255
+ );--> statement-breakpoint
256
+ UPDATE `workspace_reviewers`
257
+ SET `kind` = 'github_code_quality', `label` = NULL
258
+ WHERE `identity_source` <> 'manual'
259
+ AND `kind` IN ('in_house', 'vendor')
260
+ AND `author_user_id` IN (
261
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('github-code-quality')
262
+ );--> statement-breakpoint
263
+ UPDATE `workspace_reviewers`
264
+ SET `kind` = 'gitpod', `label` = NULL
265
+ WHERE `identity_source` <> 'manual'
266
+ AND `kind` IN ('in_house', 'vendor')
267
+ AND `author_user_id` IN (
268
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('gitpod-io')
269
+ );--> statement-breakpoint
270
+ UPDATE `workspace_reviewers`
271
+ SET `kind` = 'google_cla', `label` = NULL
272
+ WHERE `identity_source` <> 'manual'
273
+ AND `kind` IN ('in_house', 'vendor')
274
+ AND `author_user_id` IN (
275
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('google-cla', 'googlebot')
276
+ );--> statement-breakpoint
277
+ UPDATE `workspace_reviewers`
278
+ SET `kind` = 'graphite', `label` = NULL
279
+ WHERE `identity_source` <> 'manual'
280
+ AND `kind` IN ('in_house', 'vendor')
281
+ AND `author_user_id` IN (
282
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('graphite-app')
283
+ );--> statement-breakpoint
284
+ UPDATE `workspace_reviewers`
285
+ SET `kind` = 'greenkeeper', `label` = NULL
286
+ WHERE `identity_source` <> 'manual'
287
+ AND `kind` IN ('in_house', 'vendor')
288
+ AND `author_user_id` IN (
289
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('greenkeeper')
290
+ );--> statement-breakpoint
291
+ UPDATE `workspace_reviewers`
292
+ SET `kind` = 'greptile', `label` = NULL
293
+ WHERE `identity_source` <> 'manual'
294
+ AND `kind` IN ('in_house', 'vendor')
295
+ AND `author_user_id` IN (
296
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('greptile-apps')
297
+ );--> statement-breakpoint
298
+ UPDATE `workspace_reviewers`
299
+ SET `kind` = 'hound', `label` = NULL
300
+ WHERE `identity_source` <> 'manual'
301
+ AND `kind` IN ('in_house', 'vendor')
302
+ AND `author_user_id` IN (
303
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('houndci-bot')
304
+ );--> statement-breakpoint
305
+ UPDATE `workspace_reviewers`
306
+ SET `kind` = 'imgbot', `label` = NULL
307
+ WHERE `identity_source` <> 'manual'
308
+ AND `kind` IN ('in_house', 'vendor')
309
+ AND `author_user_id` IN (
310
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('imgbot', 'imgbotapp')
311
+ );--> statement-breakpoint
312
+ UPDATE `workspace_reviewers`
313
+ SET `kind` = 'jit', `label` = NULL
314
+ WHERE `identity_source` <> 'manual'
315
+ AND `kind` IN ('in_house', 'vendor')
316
+ AND `author_user_id` IN (
317
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('jit-ci')
318
+ );--> statement-breakpoint
319
+ UPDATE `workspace_reviewers`
320
+ SET `kind` = 'kodiak', `label` = NULL
321
+ WHERE `identity_source` <> 'manual'
322
+ AND `kind` IN ('in_house', 'vendor')
323
+ AND `author_user_id` IN (
324
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('kodiak', 'kodiakhq')
325
+ );--> statement-breakpoint
326
+ UPDATE `workspace_reviewers`
327
+ SET `kind` = 'korbit', `label` = NULL
328
+ WHERE `identity_source` <> 'manual'
329
+ AND `kind` IN ('in_house', 'vendor')
330
+ AND `author_user_id` IN (
331
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('korbit-ai')
332
+ );--> statement-breakpoint
333
+ UPDATE `workspace_reviewers`
334
+ SET `kind` = 'lock_bot', `label` = NULL
335
+ WHERE `identity_source` <> 'manual'
336
+ AND `kind` IN ('in_house', 'vendor')
337
+ AND `author_user_id` IN (
338
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('lock')
339
+ );--> statement-breakpoint
340
+ UPDATE `workspace_reviewers`
341
+ SET `kind` = 'mergify', `label` = NULL
342
+ WHERE `identity_source` <> 'manual'
343
+ AND `kind` IN ('in_house', 'vendor')
344
+ AND `author_user_id` IN (
345
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('mergify')
346
+ );--> statement-breakpoint
347
+ UPDATE `workspace_reviewers`
348
+ SET `kind` = 'meta_cla', `label` = NULL
349
+ WHERE `identity_source` <> 'manual'
350
+ AND `kind` IN ('in_house', 'vendor')
351
+ AND `author_user_id` IN (
352
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('facebook-github-bot')
353
+ );--> statement-breakpoint
354
+ UPDATE `workspace_reviewers`
355
+ SET `kind` = 'mintlify', `label` = NULL
356
+ WHERE `identity_source` <> 'manual'
357
+ AND `kind` IN ('in_house', 'vendor')
358
+ AND `author_user_id` IN (
359
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('mintlify')
360
+ );--> statement-breakpoint
361
+ UPDATE `workspace_reviewers`
362
+ SET `kind` = 'netlify', `label` = NULL
363
+ WHERE `identity_source` <> 'manual'
364
+ AND `kind` IN ('in_house', 'vendor')
365
+ AND `author_user_id` IN (
366
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('netlify')
367
+ );--> statement-breakpoint
368
+ UPDATE `workspace_reviewers`
369
+ SET `kind` = 'pre_commit_ci', `label` = NULL
370
+ WHERE `identity_source` <> 'manual'
371
+ AND `kind` IN ('in_house', 'vendor')
372
+ AND `author_user_id` IN (
373
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('pre-commit-ci')
374
+ );--> statement-breakpoint
375
+ UPDATE `workspace_reviewers`
376
+ SET `kind` = 'pyup', `label` = NULL
377
+ WHERE `identity_source` <> 'manual'
378
+ AND `kind` IN ('in_house', 'vendor')
379
+ AND `author_user_id` IN (
380
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('pyup-bot')
381
+ );--> statement-breakpoint
382
+ UPDATE `workspace_reviewers`
383
+ SET `kind` = 'qodo', `label` = NULL
384
+ WHERE `identity_source` <> 'manual'
385
+ AND `kind` IN ('in_house', 'vendor')
386
+ AND `author_user_id` IN (
387
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('codiumai-pr-agent-free', 'qodo-ai', 'qodo-merge', 'qodo-merge-for-open-source', 'qodo-merge-pro')
388
+ );--> statement-breakpoint
389
+ UPDATE `workspace_reviewers`
390
+ SET `kind` = 'release_drafter', `label` = NULL
391
+ WHERE `identity_source` <> 'manual'
392
+ AND `kind` IN ('in_house', 'vendor')
393
+ AND `author_user_id` IN (
394
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('release-drafter')
395
+ );--> statement-breakpoint
396
+ UPDATE `workspace_reviewers`
397
+ SET `kind` = 'release_please', `label` = NULL
398
+ WHERE `identity_source` <> 'manual'
399
+ AND `kind` IN ('in_house', 'vendor')
400
+ AND `author_user_id` IN (
401
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('autorelease', 'release-please', 'releaser')
402
+ );--> statement-breakpoint
403
+ UPDATE `workspace_reviewers`
404
+ SET `kind` = 'renovate', `label` = NULL
405
+ WHERE `identity_source` <> 'manual'
406
+ AND `kind` IN ('in_house', 'vendor')
407
+ AND `author_user_id` IN (
408
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('renovate', 'renovate-bot')
409
+ );--> statement-breakpoint
410
+ UPDATE `workspace_reviewers`
411
+ SET `kind` = 'restyled', `label` = NULL
412
+ WHERE `identity_source` <> 'manual'
413
+ AND `kind` IN ('in_house', 'vendor')
414
+ AND `author_user_id` IN (
415
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('restyled-io')
416
+ );--> statement-breakpoint
417
+ UPDATE `workspace_reviewers`
418
+ SET `kind` = 'semantic_pr', `label` = NULL
419
+ WHERE `identity_source` <> 'manual'
420
+ AND `kind` IN ('in_house', 'vendor')
421
+ AND `author_user_id` IN (
422
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('semantic-pull-request')
423
+ );--> statement-breakpoint
424
+ UPDATE `workspace_reviewers`
425
+ SET `kind` = 'semantic_release', `label` = NULL
426
+ WHERE `identity_source` <> 'manual'
427
+ AND `kind` IN ('in_house', 'vendor')
428
+ AND `author_user_id` IN (
429
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('semantic-release', 'semantic-release-bot')
430
+ );--> statement-breakpoint
431
+ UPDATE `workspace_reviewers`
432
+ SET `kind` = 'semgrep', `label` = NULL
433
+ WHERE `identity_source` <> 'manual'
434
+ AND `kind` IN ('in_house', 'vendor')
435
+ AND `author_user_id` IN (
436
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('semgrep-app')
437
+ );--> statement-breakpoint
438
+ UPDATE `workspace_reviewers`
439
+ SET `kind` = 'sizebot', `label` = NULL
440
+ WHERE `identity_source` <> 'manual'
441
+ AND `kind` IN ('in_house', 'vendor')
442
+ AND `author_user_id` IN (
443
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('diffray-bot', 'react-sizebot', 'sizebot')
444
+ );--> statement-breakpoint
445
+ UPDATE `workspace_reviewers`
446
+ SET `kind` = 'snyk', `label` = NULL
447
+ WHERE `identity_source` <> 'manual'
448
+ AND `kind` IN ('in_house', 'vendor')
449
+ AND `author_user_id` IN (
450
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('snyk-bot')
451
+ );--> statement-breakpoint
452
+ UPDATE `workspace_reviewers`
453
+ SET `kind` = 'socket', `label` = NULL
454
+ WHERE `identity_source` <> 'manual'
455
+ AND `kind` IN ('in_house', 'vendor')
456
+ AND `author_user_id` IN (
457
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('socket-security')
458
+ );--> statement-breakpoint
459
+ UPDATE `workspace_reviewers`
460
+ SET `kind` = 'sonarqube', `label` = NULL
461
+ WHERE `identity_source` <> 'manual'
462
+ AND `kind` IN ('in_house', 'vendor')
463
+ AND `author_user_id` IN (
464
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('sonarcloud', 'sonarqubecloud')
465
+ );--> statement-breakpoint
466
+ UPDATE `workspace_reviewers`
467
+ SET `kind` = 'sourcery', `label` = NULL
468
+ WHERE `identity_source` <> 'manual'
469
+ AND `kind` IN ('in_house', 'vendor')
470
+ AND `author_user_id` IN (
471
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('sourcery-ai')
472
+ );--> statement-breakpoint
473
+ UPDATE `workspace_reviewers`
474
+ SET `kind` = 'stale_bot', `label` = NULL
475
+ WHERE `identity_source` <> 'manual'
476
+ AND `kind` IN ('in_house', 'vendor')
477
+ AND `author_user_id` IN (
478
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('stale')
479
+ );--> statement-breakpoint
480
+ UPDATE `workspace_reviewers`
481
+ SET `kind` = 'sweep', `label` = NULL
482
+ WHERE `identity_source` <> 'manual'
483
+ AND `kind` IN ('in_house', 'vendor')
484
+ AND `author_user_id` IN (
485
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('sweep-ai')
486
+ );--> statement-breakpoint
487
+ UPDATE `workspace_reviewers`
488
+ SET `kind` = 'transifex', `label` = NULL
489
+ WHERE `identity_source` <> 'manual'
490
+ AND `kind` IN ('in_house', 'vendor')
491
+ AND `author_user_id` IN (
492
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('transifex-integration')
493
+ );--> statement-breakpoint
494
+ UPDATE `workspace_reviewers`
495
+ SET `kind` = 'trunk', `label` = NULL
496
+ WHERE `identity_source` <> 'manual'
497
+ AND `kind` IN ('in_house', 'vendor')
498
+ AND `author_user_id` IN (
499
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('trunk-io')
500
+ );--> statement-breakpoint
501
+ UPDATE `workspace_reviewers`
502
+ SET `kind` = 'vercel', `label` = NULL
503
+ WHERE `identity_source` <> 'manual'
504
+ AND `kind` IN ('in_house', 'vendor')
505
+ AND `author_user_id` IN (
506
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('vercel')
507
+ );--> statement-breakpoint
508
+ UPDATE `workspace_reviewers`
509
+ SET `kind` = 'welcome_bot', `label` = NULL
510
+ WHERE `identity_source` <> 'manual'
511
+ AND `kind` IN ('in_house', 'vendor')
512
+ AND `author_user_id` IN (
513
+ SELECT `id` FROM `users` WHERE replace(lower(`github_login`), '[bot]', '') IN ('welcome')
514
+ );
@@ -0,0 +1,12 @@
1
+ -- Auto-merge ("merge when ready") gets a MACHINE-READABLE phase. SQLite / local mode;
2
+ -- Postgres twin: migrations-pg/0042_auto_merge_phase.sql. One additive nullable column, no
3
+ -- index, no backfill — an in-flight intent picks its phase up on the watcher's very next tick,
4
+ -- and a null phase is already the "we can't characterise this wait" value.
5
+ --
6
+ -- WHY a column rather than parsing `last_reason`: the reason is PROSE written for a human
7
+ -- ('waiting: conflicts with main', 'rebased onto main — waiting for checks'), and the global
8
+ -- progress card would otherwise have to string-match a log line — which also goes NULL exactly
9
+ -- at success. `phase` is written by the same watcher call that writes the prose, so the two can
10
+ -- never disagree, and it describes a LIVE intent only: every terminal outcome is already a
11
+ -- `state` member, so the watcher nulls the phase on every resolve.
12
+ ALTER TABLE `auto_merge_requests` ADD `phase` text;
@@ -0,0 +1,22 @@
1
+ -- "@you" on a PR — the MENTION arm of My Turn's personal-relevance rule (CORE, no AI).
2
+ -- One row per (account, PR) where the account's viewer login is @mentioned in a PR comment, a
3
+ -- review body or an inline review comment. PRESENCE IS THE FACT: there is no `mentioned` flag
4
+ -- and no "scanned, found nothing" row, so every reader is a single indexed existence check.
5
+ -- Written ONLY by the background scanner (sync/mention-scan.ts), which re-derives the full set
6
+ -- per account per tick and diffs it against what is stored. Contract: docs/DATA-MODEL.md.
7
+ -- The Postgres twin is migrations-pg/0043_pr_mentions.sql.
8
+ CREATE TABLE IF NOT EXISTS `pr_mentions` (
9
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
10
+ `account_id` integer NOT NULL,
11
+ `repo_id` integer NOT NULL,
12
+ `pr_id` integer NOT NULL,
13
+ `login` text NOT NULL,
14
+ `created_at` integer DEFAULT (unixepoch()) NOT NULL,
15
+ FOREIGN KEY (`account_id`) REFERENCES `accounts`(`id`) ON UPDATE no action ON DELETE cascade,
16
+ FOREIGN KEY (`repo_id`) REFERENCES `repos`(`id`) ON UPDATE no action ON DELETE cascade,
17
+ FOREIGN KEY (`pr_id`) REFERENCES `pull_requests`(`id`) ON UPDATE no action ON DELETE cascade
18
+ );
19
+ --> statement-breakpoint
20
+ CREATE UNIQUE INDEX IF NOT EXISTS `prm_account_pr` ON `pr_mentions` (`account_id`,`pr_id`);--> statement-breakpoint
21
+ CREATE INDEX IF NOT EXISTS `prm_account_repo_idx` ON `pr_mentions` (`account_id`,`repo_id`);--> statement-breakpoint
22
+ CREATE INDEX IF NOT EXISTS `prm_pr_idx` ON `pr_mentions` (`pr_id`);
@@ -0,0 +1,14 @@
1
+ -- The LARGE-PR FLAG's threshold (CORE, free, no AI). How many lines of CODE churn — additions +
2
+ -- deletions over a PR's non-documentation, non-config files, folded by db/code-loc.ts — make a
3
+ -- pull request "large" enough to warn about.
4
+ --
5
+ -- ONE PER-ACCOUNT SETTING. Not per-workspace and not per-repo: a threshold with an inheritance
6
+ -- chain would need a resolver, and "which grain am I reading?" is the question this app spent a
7
+ -- migration pair (0044/0045) removing from the reviewer object.
8
+ --
9
+ -- NULLABLE with NO default and NO backfill: NULL means "the user has never expressed an opinion",
10
+ -- and the reader resolves it to the 1,500-line product default. Two states, so a future change to
11
+ -- the default reaches every account that never overrode it — which a backfilled 1500 would freeze.
12
+ -- Written only by POST /api/me/large-pr-threshold, which validates a positive integer or null.
13
+ -- The Postgres twin is migrations-pg/0044_large_pr_threshold.sql.
14
+ ALTER TABLE `accounts` ADD `large_pr_code_loc_threshold` integer;
@@ -0,0 +1,53 @@
1
+ -- THE PENDING MUTE (CORE, free, no AI). "Stop these Pending items claiming my turn."
2
+ --
3
+ -- WHAT A MUTE DOES, AND WHAT IT DELIBERATELY DOES NOT DO. A muted repo's "your turn"-shaped rows
4
+ -- are downgraded to `relevance: 'none'` (hence `personal: false`) inside `getMyTurn` — the ONE
5
+ -- place `personal` is folded from `relevance`. From that single write: the Pending card relabels
6
+ -- from "Your turn"/"In your repos" to the neutral "Review or reply", the browser notification
7
+ -- stops firing, the welcome-back banner / workspace badges / "N need your attention" line stop
8
+ -- counting it, and it moves into the broad "review or reply" population. The row itself, the
9
+ -- board's membership and the broad `myTurn` count are UNCHANGED. Muting routes work; it never
10
+ -- deletes it.
11
+ --
12
+ -- ⚠ THIS IS NOT THE `repos.inbox_watch` AXIS THAT MIGRATION 0046 DROPPED, and the next reader
13
+ -- will assume it is. `inbox_watch` was a SECOND VISIBILITY SCOPE sitting on top of "is this repo
14
+ -- added": it decided whether a repo's work appeared at all, which made "which of the two is this
15
+ -- screen obeying?" a live question on every surface, and collapsing to one scope (the Workspace)
16
+ -- is what 0044-0046 bought. NOTHING HERE CHANGES ANY SCREEN'S POPULATION. A muted repo is fully
17
+ -- live on Feed, Timeline, Activity, Bots and the Pending board; what changes is whether its rows
18
+ -- may CLAIM THE READER'S TURN and interrupt them. Membership is still the only visibility axis.
19
+ --
20
+ -- ⚠ TWO INDEPENDENT FACTS, OR-ed — NOT AN INHERITANCE CHAIN:
21
+ --
22
+ -- muted(repo) == its workspace's `workspaces.pending_muted` OR a `pending_muted_repos` row
23
+ --
24
+ -- Workspace-grain alone does not answer the ask (one noisy repo in a useful workspace); repo-grain
25
+ -- alone makes silencing a 20-repo workspace twenty clicks. `null`-means-inherit is a named bug
26
+ -- class in this codebase (`workspace_reviewers.monthly_cents`, the Slack target, the sprint
27
+ -- cadence) — it needs a resolver and "which grain am I reading?" then has to be answered at every
28
+ -- call site. There is no resolver: there is one union, computed once in db/pending-mute.ts, and
29
+ -- clearing either half never reveals or overwrites the other.
30
+ --
31
+ -- ⚠ `pending_muted_repos` HAS NO `workspace_id`, DELIBERATELY. A repo belongs to EXACTLY ONE
32
+ -- workspace (`workspace_repos`, UNIQUE (account_id, repo_id)); copying that onto this row would
33
+ -- give the account two answers to "which workspace is this repo in". The consequence is intended:
34
+ -- a repo moved between workspaces carries its own mute with it.
35
+ --
36
+ -- ⚠ IT IS NOT THE ORPHANED `bot_mute_rules` TABLE (migration 0029) EITHER. That backed the removed
37
+ -- Pierre-only "hide" mute plus a standing auto-resolve cron — it HID review threads and RESOLVED
38
+ -- them on a timer. This mutes nothing and resolves nothing; it changes one advisory flag.
39
+ --
40
+ -- PRESENCE IS THE FACT on the repo half: no `muted` boolean and no "considered, not muted" row, so
41
+ -- every reader is one indexed existence check. The Postgres twin is
42
+ -- migrations-pg/0045_pending_mute.sql.
43
+ ALTER TABLE `workspaces` ADD `pending_muted` integer DEFAULT 0 NOT NULL;--> statement-breakpoint
44
+ CREATE TABLE IF NOT EXISTS `pending_muted_repos` (
45
+ `id` integer PRIMARY KEY AUTOINCREMENT NOT NULL,
46
+ `account_id` integer NOT NULL,
47
+ `repo_id` integer NOT NULL,
48
+ `created_at` integer DEFAULT (unixepoch()) NOT NULL,
49
+ FOREIGN KEY (`account_id`) REFERENCES `accounts`(`id`) ON UPDATE no action ON DELETE cascade,
50
+ CONSTRAINT `pending_muted_repos_repo_account_fk` FOREIGN KEY (`repo_id`,`account_id`) REFERENCES `repos`(`id`,`account_id`) ON UPDATE no action ON DELETE cascade
51
+ );
52
+ --> statement-breakpoint
53
+ CREATE UNIQUE INDEX IF NOT EXISTS `pending_muted_repos_account_repo` ON `pending_muted_repos` (`account_id`,`repo_id`);
@@ -0,0 +1,33 @@
1
+ -- GitHub's native merge QUEUE becomes a SYNCED, STORED fact (CORE, free, no AI). Two additive
2
+ -- nullable columns on `pull_requests`, no index and no backfill — a PR picks both up on the next
3
+ -- walk that touches it. The Postgres twin is migrations-pg/0046_merge_queue_state.sql.
4
+ --
5
+ -- WHY STORE IT AT ALL, when GET /api/prs/:id/merge-options already fetches it live. GitHub's
6
+ -- MergeStateStatus enum has NO QUEUED member (github/mutations.ts records the same fact where it
7
+ -- explains why the queue verbs fork to GraphQL), so a PR sitting in the merge queue reports
8
+ -- `merge_state_status = 'blocked'` — byte-identical to one held up by unmet branch protection.
9
+ -- Every merge surface then reads "blocked" and offers a Merge button GitHub will refuse. That was
10
+ -- survivable while the only reader was the click-gated merge control, which fetches live and pays
11
+ -- ~3 GitHub calls for the answer. The Pending board is NOT allowed to fetch on mount — fifty cards
12
+ -- resolving their own state is ~150 calls to paint one screen — so a card can only know a PR is
13
+ -- queued if a column says so.
14
+ --
15
+ -- ⚠ NULL MEANS "NOT OBSERVED", NOT "NOT QUEUED", and that is why neither column takes a DEFAULT.
16
+ -- A DEFAULT 0 here would assert about every already-synced PR in the database that GitHub had told
17
+ -- us it is not in the queue, which it never did — and the merge surfaces would then render that
18
+ -- fabrication as fact until the next walk. `false` is a positive statement from GitHub; null is the
19
+ -- absence of one. sync/upsert.ts owns the three-state write (absent ⇒ omit the column, false/null ⇒
20
+ -- clear it), and the two write routes in api/routes/prs.ts stamp their own result.
21
+ --
22
+ -- WHAT IS DELIBERATELY NOT HERE: the entry's `position` and `estimatedTimeToMerge`. Both are
23
+ -- genuinely volatile — a position is wrong the moment it is written, because it changes every time
24
+ -- another PR in the queue lands — and nothing but the merge control renders either. They stay
25
+ -- live-only in merge-options. Membership and entry state are the halves that are stable enough to
26
+ -- store and useless unless stored.
27
+ ALTER TABLE `pull_requests` ADD `in_merge_queue` integer;--> statement-breakpoint
28
+ -- GitHub's MergeQueueEntryState, lowercased like every other stored enum on this table
29
+ -- (awaiting_checks | locked | mergeable | queued | unmergeable). `unmergeable` is the value that
30
+ -- earns the column: GitHub EJECTS an entry whose checks failed, so without it a PR silently
31
+ -- disappears from the queue and the reader is told nothing at all. Drizzle's `enum:` is a
32
+ -- TYPE-level constraint only, so there is no CHECK to add here.
33
+ ALTER TABLE `pull_requests` ADD `merge_queue_entry_state` text;