origin/main @ 38b9b850 vs origin/staging @ b4eecfd6
Merge base fa30c70a (PR #975, 2026-06-10). Verified by file presence, not commit subjects.
| Measure | staging | main |
|---|---|---|
| Commits the other branch lacks | 669 | 577 |
| Merge units (PRs) | 29 | 124 |
| Files the other branch lacks | 331 | 126 |
| New Prisma models / enums | 36 | 5 |
| Next.js version | 16.2.6 | 16.3.0 |
| Files differing on both sides | 583 | |
| Staging commits already patch-equivalent in main | 41 | |
Sizes are net insertions from a two-dot diff: lines that exist on staging and not on main. That is the actual merge payload, not how much staging changed since the base.
No counterpart on main at all. Clean adds. Each brings its own Prisma models.
Biggest genuinely-new subsystem. Verified: zero eval files on main.
services/evals/* (23 files: suite / case / run generation, personas, replay, scoring, safety criteria, benchmarking, stats, baselines, redaction, run-diff)lib/evals/ cost, run-gate, run-schedulerouters/evals, routers/testlab-copilot (prompt + tools)test-lab/page.tsx + 11 components, api/evals/{run,scheduled-run,score-dataset}, api/v1/evals/run, api/test-lab/copilot/streameval-suite, eval-case, eval-case-result, eval-run, eval-criterion, eval-dataset, eval.enumOnly 3 modified files, so almost pure addition. Main has liveCallsRouter but none of this.
lib/live-calls/* (18: SSE, ingest, presence, takeover, QA score, sentiment, SLA, alerts, leaderboard, metrics, CSV, floor prefs / version, connect latency, row nav)use-live-call-stream, use-call-presence, use-live-calls-floor, use-supervisor-legrouters/supervisor-settings, services/live-calls-query.ts, lib/supervisor-config.tsapi/live-calls/{stream,workspace-stream}, api/webhooks/orchestration/live-turncall-center/monitor/_components/* (10)live-call-turn, live-call-bookmark, live-call-supervisor-actiondocs/LIVE-MONITOR-PROD-HANDOFF.md, -PRODUCTION-CHECKLIST.md, -WORKLOG.mdtables/page.tsx, tables/[tableId]/page.tsx, _components/* (8), _lib/* (4)routers/tables + tables/access.tsdata-table, data-field, data-record, data-viewcampaigns/page.tsx, campaigns/[campaignId]/page.tsx, _components/* (7)routers/campaigncampaign, campaign-assistant, campaign-contact, campaign.enumrouters/a2p + validationservices/a2p-billing | a2p-charge | a2p-teardown.service.tslib/a2p/billing.ts, lib/a2p/constants.tsapi/workflow/a2p-campaign-billing/route.tsa2p-brand, a2p-campaign, a2p-submission-batch, a2p.enumserver/mcp/ handler, caller, registry, registry-write; server/mcp/oauth/* (4)api/mcp/route.ts, api/mcp/oauth/{authorize,register,token}.well-known/oauth-authorization-server, .well-known/oauth-protected-resource(auth)/oauth/mcp/authorize/page.tsx, docs/mcp-server.mdrouters/mcp-server.ts; main still registers it and added an MCP servers UI section. Pick a winner first.routers/blacklist, services/blocklist.service.tssettings/blacklist/_components/* (4)blocklist.model.prisma, blocklist.enum.prismarouters/forms, public forms/[formId]/page.tsx, api/forms/[formId]/submitlib/workflow/ form-fields, form-brand, form-text, recaptcha, respond, ssrfworkflow-form, workflow-data-storeservices/monitor-health.service.ts, settings/monitoring/page.tsxrouters/notification, services/notification.service.tsMain has some of this. Diff before you cherry-pick, or you will re-land work that is already live.
Largest remaining bucket by a wide margin. PR #1449, #1490.
server/workflow-engine/ event-dispatch, prune, run-scopelib/workflow/ node-registry, templates, approval-tokenapi/workflows/approval/[runId]/[nodeId], api/workflows/webhook-wait/[runId]/[nodeId]automations/_components/workflow-editor/{nodes,panels,components} (16 new)api/automations/copilot/stream, routers/automations-copilotdocs/AUTOMATIONS-HARDENING-FOLLOWUPS.mdadd-node-drawer.tsx and ai-chat-panel.tsx; main still has them and added direct-unavailable-panel.tsx.docs/AUTOMATIONS-STAGING-TO-MAIN-HANDOFF.md on main (ASSIST-640, 2026-06-19) plans exactly this bucket: backend coupling near zero, two pre-existing BE endpoints, schema delta entirely additive. Status recorded there is "planning complete, execution NOT started". Read it first.PR #1487. Suggest → validate → apply loop.
services/observation/ runner, alerts, alert-window, condition-evaluator, detection-schema, voice-qualitylib/observation/enqueue.ts, services/suggested-fix.service.ts, services/issue-clustering.service.tsobservation/_components/* (5), api/observation/evalcontinual-learning-config, suggested-fix, regression-case, issue; observation-result + enum modifiedsettings/custom-fields, settings/pipelines, settings/tags pagescontacts/_components/* and crm-* / contact-pipeline models modifiedcolumns.tsx, contact-edit-sheet.tsx, filters-dialog.tsx, contacts-table-floating-bar.tsx, which main still has. Main also added direct-call-button.tsx in that folder.Much smaller than first reported. Main already has account-scope.ts, docs-actions.ts, docs-rag.service.ts, docs-tools.ts via #1509 promote/support-agent-to-prod.
Genuinely remaining:
services/docs/correction.service.ts, services/docs/docs-models.tsapi/internal/docs-chat/correction, api/internal/docs-chat/retrievedoc-correction.model.prisma + prisma/sql/create-doc-correction.sqldocs/support-agent.md; stage + approve gate (#1510), Assistable Way personality (#1506), Sonnet 5 default (#1511, #1512)CORRECTION_APPROVE_SECRET, DOCS_ANSWER_MODEL.Verified already on main, or main is ahead. These need a main → staging sync, not a merge into main.
| Area | Status | stg-only | main-only |
|---|---|---|---|
| Telnyx LLM inference rollout | llm/telnyx-provider.ts landed on main in 0120dd20. Remainder is subaccount resolution, webhook signature, credentials service (6 files) | 970 | 163 |
| Gleap inbox mirror + staff reply | gleap-inbox-mirror.ts and gleap-reply-outbox.ts are on main. Only the imported-conversation model remains | 262 | 141 |
| Voice drawer / selector sandbox | All 12 sandbox files present on main. Main is ahead (Fish Audio, overhaul, desync fixes) | 996 | 2,951 |
| Flowbuilder runtime | Editor work is on main. Only the 4 fb-* models remain. Main is ahead | 54 | 222 |
| Command Center | Zero new files on staging. Mutual drift across 45 files, main slightly ahead | 1,574 | 2,340 |
27 new + 288 modified files, ~13.7k insertions. Mostly drift, but three real additions:
services/validation.service.ts (449 lines)assistants/_components/ai-builder-panel.tsx (310)services/assistant-version.service.ts (125), scripts/sync-platform-tools-from-prod.ts (380)pnpm-lock.yaml (2,168), widget page drift, routers/assistant, sidebar, STYLE-GUIDE.md, the UI consistency passchore/staging-backend-url-env, fix/ghl-app-credentials-by-env (staging env config)chore(staging): redeploy ... no-op commitsMerge branch 'main' into staging and the PR #748 integration merges5bae0afb) is already patch-equivalent in main via PR #1566PR #1030 feat/assistable-direct, #1550, #1539. Largest main-only feature. Verified 31 files on main, 0 on staging.
routers/direct/*: assistants, contacts, crm, calls, call-history, live-calls, inbox, inbox-assistant, knowledge, tool, voice, widget, phone-number, number-pool, pipeline, tag, folder, import, bulk-actions, observation, appointment, artifact, autopilot, autopilot-flow, flowbuilder, mcp, message-history, replacement, data-analysis, _shared.ts, index.tsrouters/subaccount/direct.ts, create-direct-subaccount-modal.tsxcontacts/_components/direct-call-button.tsx, workflow-editor/components/direct-unavailable-panel.tsxtests/unit/direct-router.test.tsdirect import from root.ts. The single biggest reason not to merge staging wholesale.53 voice + 18 voice-drawer commits. PRs #1477, #1564, #1497, #1498, #1529–#1534, #985. Main leads staging 2,951 to 996 here.
api/internal/sync-telnyx-voices (#1497), ElevenLabs model + provider filter (#1498)lib/voice-language.ts, utils/voice-config-compare.ts, prompt-language-options.tsPR #1559 kumar/cc-ui, #1577 remove Assistable branding.
refactor(command-center) User / session FK relationslib/command-center/artifact-href.tstests/unit/server/command-center/ artifact-href, routine-schedule0120dd20), which is why that looked staging-onlyfb-* models.PR #1443, #1336, #1453, #1472, #1474, #1016, #1017, #1011, #1481, #1463, #1412, #1581 plus bundle rebuilds (#1470, #1471, #1483, #1485).
widget-feedback, widget-form-submission, widget-roadmap-voteworkspace-transaction-filters.tsrebill-billing.ts, rebilling-defaults.ts, snapshot-billing.tsutils/stripe-currency.ts, utils/provision-tier-overrides.tsPR #1563.
api/internal/stripe-links/ route.ts, [linkId]/route.ts, _auth.ts, README.mdservices/stripe-link.service.ts; currency rules, retry handlingPR #1566.
api/internal/lifecycle-events/retry, services/lifecycle-event-retry.service.ts5bae0afb, patch-equivalent). Do not merge twice.PR #1480, #1491.
(auth)/bot-playground/page.tsx, routers/bot-playgroundapi/bot-playground/draft-rule/route.ts, services/bot-rules.tsbot-response-rulebotPlayground import from root.ts.PR #1329, #1541, #1542, #1543.
components/analytics/sms-analytics-report-view.tsx, combined-analytics-report-view.tsx, ui/sms-volume-card.tsxhooks/use-sms-analytics.ts, routers/message-analytics.shared.tsmessage-analytics.test.tsinbox-typing-indicator.tsx, utils/ai-responding.tsutils/conversation-sleep.ts; sleep badge freshness (#1553)inbox-channels.test.ts, conversation-sleep.test.tsPR #1336.
portal/[subaccountId]/tickets/page.tsx, components/tickets/tickets-view.tsxsupport-ticket (a conversation can hold more than one ticket)shopify-import.service.ts, knowledge/help-center-import.service.ts, help-articles-import.service.ts, news-feed-import.service.tslib/faq-csv.ts + undefined-index hotfix (#1460), widgets/_components/help-import.tslib/call-history-helpers.ts, lib/call-spend.ts, services/web-calls.service.tslogin_failed (#1528), v3 calls scope registration (#1028)routers/mcp-server.ts, integrations/_components/mcp-servers-section.tsx, integration-badges.tsxservices/integration/resolve-provider.ts, routers/message-history.tsserver/mcp + OAuth and deletes both imports.lib/platform-host.ts; host-only DNS (#1413), signup policy links (#1411)lib/auth-cookie-mirror.ts. Fixes the login loop where better-auth's customSession drops Partitioned on refreshutils/assistable-staff.ts: staff triage access bypass (#1538)Appointment.conversationId, conversation.visitorId, conversation.ghlContactId, active_tag.assistant_id, self-schedule parity (#1335)| Router | On main | On staging |
|---|---|---|
direct | 31 files | absent |
mcpServer | present | replaced by server/mcp |
botPlayground | present | absent |
messageHistory | present | absent |
main → staging once and resolve there, so every feature PR is cut from a base
that already contains main. Otherwise all 13 PRs re-fight the same root.ts and schema
conflicts. This also pulls staging up on voice and flowbuilder, where main leads.prisma db push on the Vercel build, and the backend repo needs mirrored
declarations or the parity CI gate trips. Never use --accept-data-loss.direct, mcpServer,
botPlayground, messageHistory. Only mcpServer is a real
contest; the other three are main-only additions staging simply has not seen.git rev-list --count origin/main..origin/staging # 669
git rev-list --count origin/staging..origin/main # 577
git diff --name-status origin/main..origin/staging # 331 A / 126 D / 583 M
git diff --numstat origin/main..origin/staging # true merge payload
git cherry origin/main origin/staging # 584 new / 41 already applied
git ls-tree -r --name-only origin/main # presence checks
Group A rows are verified absent from main by file presence. Group B rows are verified partial: the listed remainder is what the two-dot diff still shows. Line counts are insertions from the two-dot diff, so a heavily-reworked shared file still inflates its bucket somewhat. Bucket boundaries between Automations, workflow-forms and the observation loop may overlap; verify before cutting those branches.