staging vs main

origin/main @ 38b9b850  vs  origin/staging @ b4eecfd6
Merge base fa30c70a (PR #975, 2026-06-10). Verified by file presence, not commit subjects.

Measurestagingmain
Commits the other branch lacks669577
Merge units (PRs)29124
Files the other branch lacks331126
New Prisma models / enums365
Next.js version16.2.616.3.0
Files differing on both sides583
Staging commits already patch-equivalent in main41
0 / 13 merged

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.

Group A

Entirely absent from main

No counterpart on main at all. Clean adds. Each brings its own Prisma models.

1Evals + Test Lab14,360 ins / 61 new

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-schedule
  • routers/evals, routers/testlab-copilot (prompt + tools)
  • Routes: test-lab/page.tsx + 11 components, api/evals/{run,scheduled-run,score-dataset}, api/v1/evals/run, api/test-lab/copilot/stream
  • Schema: eval-suite, eval-case, eval-case-result, eval-run, eval-criterion, eval-dataset, eval.enum
  • 18 unit tests
2Live Calls supervisor / monitor7,819 ins / 55 new

Only 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)
  • Hooks: use-live-call-stream, use-call-presence, use-live-calls-floor, use-supervisor-leg
  • routers/supervisor-settings, services/live-calls-query.ts, lib/supervisor-config.ts
  • api/live-calls/{stream,workspace-stream}, api/webhooks/orchestration/live-turn
  • call-center/monitor/_components/* (10)
  • Schema: live-call-turn, live-call-bookmark, live-call-supervisor-action
  • Handoff docs ship with it: docs/LIVE-MONITOR-PROD-HANDOFF.md, -PRODUCTION-CHECKLIST.md, -WORKLOG.md
3Data Tables6,700 ins / 17 new
  • Routes tables/page.tsx, tables/[tableId]/page.tsx, _components/* (8), _lib/* (4)
  • routers/tables + tables/access.ts
  • Schema: data-table, data-field, data-record, data-view
4Outbound Campaigns6,656 ins / 14 new
  • Routes campaigns/page.tsx, campaigns/[campaignId]/page.tsx, _components/* (7)
  • routers/campaign
  • Schema: campaign, campaign-assistant, campaign-contact, campaign.enum
Overlaps A2P. Merge after item 5.
5A2P 10DLC registration4,339 ins / 14 new
  • routers/a2p + validation
  • services/a2p-billing | a2p-charge | a2p-teardown.service.ts
  • lib/a2p/billing.ts, lib/a2p/constants.ts
  • api/workflow/a2p-campaign-billing/route.ts
  • Schema: a2p-brand, a2p-campaign, a2p-submission-batch, a2p.enum
Billing-touching. Land main's Stripe payment-links API first (main item 7).
6MCP server + OAuth2,567 ins / 15 new
  • server/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.md
Collides with main item 15. Staging drops routers/mcp-server.ts; main still registers it and added an MCP servers UI section. Pick a winner first.
7Blacklist / blocklist2,016 ins / 8 new
  • routers/blacklist, services/blocklist.service.ts
  • settings/blacklist/_components/* (4)
  • Schema: blocklist.model.prisma, blocklist.enum.prisma
8Workflow forms1,075 ins / 5 new
  • routers/forms, public forms/[formId]/page.tsx, api/forms/[formId]/submit
  • lib/workflow/ form-fields, form-brand, form-text, recaptcha, respond, ssrf
  • Schema: workflow-form, workflow-data-store
Depends on item 9 for the node side.
9Monitor health + notifications1,239 ins / 6 new
  • services/monitor-health.service.ts, settings/monitoring/page.tsx
  • routers/notification, services/notification.service.ts
Group B

Partly on main already, merge the remainder

Main has some of this. Diff before you cherry-pick, or you will re-land work that is already live.

10Automations / workflow engine23,835 ins / 55 new + 121 mod

Largest remaining bucket by a wide margin. PR #1449, #1490.

  • server/workflow-engine/ event-dispatch, prune, run-scope
  • lib/workflow/ node-registry, templates, approval-token
  • api/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-copilot
  • 8 workflow-engine + 6 lib/workflow unit tests
  • docs/AUTOMATIONS-HARDENING-FOLLOWUPS.md
121 modified files. Staging deleted add-node-drawer.tsx and ai-chat-panel.tsx; main still has them and added direct-unavailable-panel.tsx.
Prior art: 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.
11Observation + continual learning4,704 ins / 17 new + 12 mod

PR #1487. Suggest → validate → apply loop.

  • services/observation/ runner, alerts, alert-window, condition-evaluator, detection-schema, voice-quality
  • lib/observation/enqueue.ts, services/suggested-fix.service.ts, services/issue-clustering.service.ts
  • observation/_components/* (5), api/observation/eval
  • Schema: continual-learning-config, suggested-fix, regression-case, issue; observation-result + enum modified
Main added contact-linked observation tools (#1466 / #1468 / #1469) into the same models.
12CRM settings pages3,852 ins / 10 new + 63 mod
  • settings/custom-fields, settings/pipelines, settings/tags pages
  • contacts/_components/* and crm-* / contact-pipeline models modified
63 modified files and staging replaced columns.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.
13Docs brain: KB corrections2,384 ins / 12 new + 16 mod

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.ts
  • api/internal/docs-chat/correction, api/internal/docs-chat/retrieve
  • Schema: doc-correction.model.prisma + prisma/sql/create-doc-correction.sql
  • docs/support-agent.md; stage + approve gate (#1510), Assistable Way personality (#1506), Sonnet 5 default (#1511, #1512)
Needs env: CORRECTION_APPROVE_SECRET, DOCS_ANSWER_MODEL.
Group C

Not merge candidates

Verified already on main, or main is ahead. These need a main → staging sync, not a merge into main.

AreaStatusstg-onlymain-only
Telnyx LLM inference rolloutllm/telnyx-provider.ts landed on main in 0120dd20. Remainder is subaccount resolution, webhook signature, credentials service (6 files)970163
Gleap inbox mirror + staff replygleap-inbox-mirror.ts and gleap-reply-outbox.ts are on main. Only the imported-conversation model remains262141
Voice drawer / selector sandboxAll 12 sandbox files present on main. Main is ahead (Fish Audio, overhaul, desync fixes)9962,951
Flowbuilder runtimeEditor work is on main. Only the 4 fb-* models remain. Main is ahead54222
Command CenterZero new files on staging. Mutual drift across 45 files, main slightly ahead1,5742,340

Leftovers not in any bucket

27 new + 288 modified files, ~13.7k insertions. Mostly drift, but three real additions:

Staging-only, never merge

A

Large features staging has no equivalent of

1Assistable Direct31 router files

PR #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.ts
  • routers/subaccount/direct.ts, create-direct-subaccount-modal.tsx
  • contacts/_components/direct-call-button.tsx, workflow-editor/components/direct-unavailable-panel.tsx
  • tests/unit/direct-router.test.ts
Staging deletes the direct import from root.ts. The single biggest reason not to merge staging wholesale.
2Voice: Fish Audio + drawer overhaul2,951 lines ahead

53 voice + 18 voice-drawer commits. PRs #1477, #1564, #1497, #1498, #1529–#1534, #985. Main leads staging 2,951 to 996 here.

  • Fish Audio voices: S2.1 Pro / S2 Pro / S1 (#1564)
  • Voice drawer overhaul (#1477); hydration + autosave fix; spurious-unpublish noop guards
  • 8 model-switch desync fixes, ABA-race stale sibling rejection, partial-template flagging
  • api/internal/sync-telnyx-voices (#1497), ElevenLabs model + provider filter (#1498)
  • lib/voice-language.ts, utils/voice-config-compare.ts, prompt-language-options.ts
3Command Center (main's line of work)2,340 lines ahead

PR #1559 kumar/cc-ui, #1577 remove Assistable branding.

  • Rebranded model picker; refactor(command-center) User / session FK relations
  • lib/command-center/artifact-href.ts
  • tests/unit/server/command-center/ artifact-href, routine-schedule
  • Also carried the Telnyx inference plumbing into main (0120dd20), which is why that looked staging-only
4Agent FlowsPRs #1486, #1492, #1493, #1496
  • Autopilot flows and enrollment; open beta, beta badge, portal-sidebar hiding
  • #1579 autopilot stop-on-negative-sentiment flag
Not the collision I first claimed. Main also leads on the flow editor; staging's only remaining flow delta is the 4 fb-* models.
5Widget v2 enterprise builder37 widget commits

PR #1443, #1336, #1453, #1472, #1474, #1016, #1017, #1011, #1481, #1463, #1412, #1581 plus bundle rebuilds (#1470, #1471, #1483, #1485).

  • Enterprise widget builder, editor redesign + polish, help-center templates
  • Office-hours editor, tab content builder, help import
  • GHL sync toggle, default-on for new widgets, form GHL destination
  • Orb floating / fixed, voice mic recall, pipeline-trace accordion, teaser toggle
  • Fix: editor deleting fields it does not own; tool select, favourites, webhook events
  • Schema: widget-feedback, widget-form-submission, widget-roadmap-vote
B

Billing, money and provisioning

6Billing + Stripe cluster35 commits / ~14 PRs
  • Cancel-subscription UI (#1032, #1034), reactivation identity reset, replay-safe deletion
  • Agency billing: filter transactions by subaccount (#1420), workspace-transaction-filters.ts
  • Wallet: event button (#1479), source header hotfix (#1524), subaccount-id column (#1522)
  • Rebilling: rebill-billing.ts, rebilling-defaults.ts, snapshot-billing.ts
  • Stripe: customer-id generation (#1516), subscription webhook PM null (#1519), non-subscription price wiping limits (#1517), next invoice date (#982), autopay attach self-heal (#1309), card fallback
  • utils/stripe-currency.ts, utils/provision-tier-overrides.ts
  • 6 billing unit tests staging lacks
7Internal Stripe payment links API4 files

PR #1563.

  • api/internal/stripe-links/ route.ts, [linkId]/route.ts, _auth.ts, README.md
  • services/stripe-link.service.ts; currency rules, retry handling
Land before staging's A2P billing (staging item 5).
8Account lifecycle events5 files

PR #1566.

  • api/internal/lifecycle-events/retry, services/lifecycle-event-retry.service.ts
  • Retry-safe capture, replay identity preservation, verified against a real database
Already on staging too (5bae0afb, patch-equivalent). Do not merge twice.
C

Smaller features and subsystems

9Bot training playground5 files

PR #1480, #1491.

  • (auth)/bot-playground/page.tsx, routers/bot-playground
  • api/bot-playground/draft-rule/route.ts, services/bot-rules.ts
  • Schema: bot-response-rule
Staging deletes the botPlayground import from root.ts.
10SMS analytics9 files

PR #1329, #1541, #1542, #1543.

  • components/analytics/sms-analytics-report-view.tsx, combined-analytics-report-view.tsx, ui/sms-volume-card.tsx
  • hooks/use-sms-analytics.ts, routers/message-analytics.shared.ts
  • AI-only filter, Prisma grouping hotfix, fallback path, message-analytics.test.ts
11Inbox improvements17 files
  • AI-responding indicator (#1549): inbox-typing-indicator.tsx, utils/ai-responding.ts
  • Per-chat sleep mode (#1536): utils/conversation-sleep.ts; sleep badge freshness (#1553)
  • Webchat channel filter case (#1537), needs-reply filter wrap (#1445)
  • Inbox trace read from ClickHouse (#1525); composer no longer flips channel
  • inbox-channels.test.ts, conversation-sleep.test.ts
12Tickets / support desk4 files

PR #1336.

  • portal/[subaccountId]/tickets/page.tsx, components/tickets/tickets-view.tsx
  • Show human support requests, not just bug reports
  • Schema: support-ticket (a conversation can hold more than one ticket)
13Knowledge-base importers6 files
  • shopify-import.service.ts, knowledge/help-center-import.service.ts, help-articles-import.service.ts, news-feed-import.service.ts
  • lib/faq-csv.ts + undefined-index hotfix (#1460), widgets/_components/help-import.ts
  • #1418 stop generating answers from a deleted KB
14Calls: history, spend, web calls10 files
  • lib/call-history-helpers.ts, lib/call-spend.ts, services/web-calls.service.ts
  • Search call IDs, identify owning subaccount (#1521); analytics export hotfix (#1419)
  • Web voice orb login_failed (#1528), v3 calls scope registration (#1028)
15MCP servers UI + message history4 files
  • routers/mcp-server.ts, integrations/_components/mcp-servers-section.tsx, integration-badges.tsx
  • services/integration/resolve-provider.ts, routers/message-history.ts
Collides with staging item 6. Staging replaces this with server/mcp + OAuth and deletes both imports.
16Whitelabel + domains5 files
  • lib/platform-host.ts; host-only DNS (#1413), signup policy links (#1411)
  • HTTPS readiness trust (#1337), whitelabel model selector (#1495)
17Auth, access and staff toolingsmall but load-bearing
  • CHIPS cookie-jar mirror (#1387): lib/auth-cookie-mirror.ts. Fixes the login loop where better-auth's customSession drops Partitioned on refresh
  • utils/assistable-staff.ts: staff triage access bypass (#1538)
  • Subaccount access errors (#1448, #1465), workspace fixes (#1520)
  • Reseller onboarding API-key auth (#1052), launchpad reseller gate (#838), rate-limiter fail-open (#1407)
Do not lose the cookie mirror. Production login-loop fix, easy to drop in a conflict resolution.
18Platform, deps and schema indexesinfra
  • Next 16.2.6 → 16.3.0 (staging is on 16.2.6, so this is a patch bump, not a major)
  • Deps security sweep (#1582), pnpm 10 pin, security scan on node 22
  • Backend cache invalidation (#1069) + authenticated call (#1583)
  • Kimi K2 (#1332); prompt-language gate (#1518)
  • Tools: library audit (#1386, #1395), copy-tools (#1546), toolkit count / visibility (#1405), remove-tool error (#1459), dialog reset (#1514), reveal API key (#1009)
  • Phone numbers: health tool (#1406), numbers 500 (#1404), unguarded release (#1482)
  • Indexes staging lacks: Appointment.conversationId, conversation.visitorId, conversation.ghlContactId, active_tag.assistant_id, self-schedule parity (#1335)

The four router imports staging deletes

RouterOn mainOn staging
direct31 filesabsent
mcpServerpresentreplaced by server/mcp
botPlaygroundpresentabsent
messageHistorypresentabsent

Recommended process

  1. Sync 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.
  2. Cut feature branches off main, cherry-pick the file set per bucket, open a normal PR. Never merge staging into main directly.
  3. Diff before cherry-picking any Group B item. Main already has part of each one, so a blind cherry-pick re-lands work that is already live.
  4. Schema in its own PR per feature, ahead of the code. 36 new models land on the shared prod Neon DB via 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.
  5. Settle the four router identities: direct, mcpServer, botPlayground, messageHistory. Only mcpServer is a real contest; the other three are main-only additions staging simply has not seen.
  6. Order: Group A items 7, 8, 9 (small, clean) → 3, 4, 5 (new surfaces, watch the A2P / campaigns / Stripe-links ordering) → 6 (after the MCP decision) → 1, 2 (large but clean) → Group B last, largest first, since Automations at 23.8k dominates everything else.

Prior art already in the repo

Commands used

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.