THE UNIFIED PLATFORM BIBLE — ADDENDUM 07
Triple Verification — Migration Pipeline & Fixes June 2026
Version: 1.0
Date: June 16, 2026
Author: Alain Bessette, CFO/Product Owner, ABI Conglomerate
Domain: GoWeBa.com
Status: Official Strategic Addendum — Binding Specification
Constraints: ZERO data loss · ZERO force-reset · ZERO email disruption
⚠️ CRITICAL NOTICE
This addendum has the SAME authority as Part 1, Part 2, and all preceding Addendums of the Bible.
All fixes described herein are production-deployed and checkpointed.
No breaking schema changes were made.
📋 TABLE OF CONTENTS
- Context & Objective
- Phase M — Google Pull Verification
- Phase C — V10 Classification Verification
- Phase E — Email Forward/Reply Fix
- Phase A — ARCHIVED Tab & 15-Card Grid
- Bounce Address Fix
- Domain Registry — Initial Seed
- Database State
- Final Verdict & Recommendations
- Modified Files — Complete Inventory
- Checkpoint Timeline
<a id="context"></a>
SECTION 1: CONTEXT & OBJECTIVE
After several iterations on the Google → GoWeBa migration pipeline, this addendum documents the exhaustive triple verification performed on June 16, 2026, before official launch of user migrations.
The verified phases cover the entire lifecycle:
| Phase | Scope | Status |
|---|---|---|
| M | Automated migration (Google Pull API) | ✅ Verified |
| C | V10 Classification (12-layer cascade) | ✅ Verified |
| E | Email Forward/Reply (attachments + From) | ✅ Fixed & deployed |
| A | ARCHIVED tab + 15-card grid | ✅ Fixed & deployed |
| Bounce | Bounce address inbound fix | ✅ Fixed & deployed |
| Domain Registry | Initial seed of 333 domains | ✅ Executed |
<a id="phase-m"></a>
SECTION 2: PHASE M — GOOGLE PULL VERIFICATION
2.1 Retrieval Architecture
The module lib/migration/google-pull.ts handles Google data extraction via native APIs (People, Gmail, Calendar, Drive) without dependency on the googleapis package.
2.2 Verified Performance Parameters
| Parameter | Value | Justification |
|---|---|---|
QUERIES_PER_MIN | 200 | Below Gmail's 250/min limit |
MICRO_BATCH | 8 concurrent requests | Controlled parallelism |
DELAY_BETWEEN_BATCHES_MS | 2,400 ms | 8 / 2.4s ≈ 3.33 req/sec = 200/min |
MACRO_BATCH_SIZE | 2,250 | Processing in chunks |
FLUSH_SIZE | 200 | Flush to DB every 200 emails |
MAX_RETRIES | 4 | Attempts with exponential backoff |
INITIAL_BACKOFF_MS | 2,000 ms | Initial backoff (2s → 4s → 8s → 16s) |
MAX_CONSECUTIVE_ERRORS | 20 | Safety stop |
2.3 Robustness Mechanisms
- Exponential backoff: 2s → 4s → 8s → 16s + random 1s jitter
- Rate limit detection:
isRateLimitError()detects HTTP 429 and Google-specific errors - Preventive stop: After 20 consecutive errors, import stops cleanly with explicit error message
- Progressive flush: Emails are not held in memory — flushed to DB in batches of 200
- Progress logging: Log emitted every ~500 emails with elapsed time
- Time estimation: System calculates and displays estimated remaining time
2.4 Verdict
<a id="phase-c"></a>
SECTION 3: PHASE C — V10 CLASSIFICATION VERIFICATION
3.1 12-Layer Cascade
The file lib/weba/classification-cascade.ts implements the complete V10 cascade as documented in the WebaBox Classification Guide V10 (Document 2):
| Layer | Name | Confidence | Description |
|---|---|---|---|
| 1 | USER SENDER RULES | 1.00 | User rules — BLOCK→SPAM, ALLOW→skip |
| 2 | GMAIL STARRED | 0.95 | isStarred=true → URGENT |
| 3 | EXPLICIT URGENCY | 0.92 | Legal/urgency regex (FR/EN/ES) |
| 4 | DOMAIN REGISTRY | 0.90 | lookupDomain() — 333 mapped domains |
| 5 | FROM-ADDRESS PATTERNS | 0.88 | noreply→OFFICE, newsletter→JOURNAL |
| 6 | GMAIL CATEGORY LABELS | 0.85 | CATEGORY_SOCIAL→SOCIAL, etc. |
| 7 | SUBJECT LINE PATTERNS | 0.72 | Trilingual keyword matching |
| 8 | TEMPORAL ANALYSIS | 0.70 | Deadlines→URGENT/IMPORTANT |
| 9 | CONTACT GRAPH | 0.68 | Known CRM contact → IMPORTANT |
| 10 | LLM INTELLIGENCE | variable | GPT-4.1-mini + 6E few-shot |
| 11 | (part of L10) | — | Few-shot injected into LLM prompt |
| 12 | FALLBACK | 0.10 | NONE |
3.2 Batch Classification (V10 Migration)
The endpoint POST /api/weba/migration/start handles mass classification:
- Batches of 50 threads (configurable up to 100)
- Automatic self-chaining: Server calls itself via
selfChain()to process next batch - Self-chain retry: 3 attempts (localhost → external URL → fallback)
- Combined action:
action: 'both'allows classify + archive in a single operation - Cumulative counters:
_totalProcessedand_totalChangedtrack global progress
3.3 Feature Flags
All V10 flags are enabled by default (via lib/weba/feature-flags.ts):
| Flag | Function |
|---|---|
V10_WEBABOX_UI | 4×4 grid interface |
V10_NEW_CATEGORIES | TRAVEL, SOCIAL, PROMOTIONS |
V10_AUTO_ARCHIVE | Auto-archive cron 90 days |
V10_CONTACT_CLASSIFIER | Contact type classification |
V10_SECURITY_SCORER | Email security scoring |
V10_DOMAIN_REGISTRY | Domain registry (layer 4) |
V10_REALTIME_PIPELINE | Real-time cascade pipeline |
3.4 Verdict
<a id="phase-e"></a>
SECTION 4: PHASE E — EMAIL FORWARD/REPLY FIX
4.1 Identified Issues
Two bugs in WebaBox Forward/Reply:
- Attachments not transferred: When forwarding, original email attachments were not included.
- Incorrect send account: The "From" selector did not default to the thread's email account.
4.2 Fixes Applied
4.2.1 Forward Attachments
Modified files:
app/(app)/inbox/compose-modal.tsx— AddedinitialAttachmentsprop + loading logic (presigned URL → base64)app/(app)/inbox/webabox-client.tsx— Added attachments toreplyComposeStateapp/(app)/inbox/ongoing/[threadId]/ongoing-client.tsx— Same propagation for thread mode
4.2.2 Default From Account
Modified file: app/(app)/inbox/compose-modal.tsx
Bug: The useEffect that loaded email accounts systematically overwrote the initial selectedAccountId.
Fix: Added if (!initialAccountId && ...) condition to prevent overwriting an already-selected account.
4.3 Verdict
<a id="phase-a"></a>
SECTION 5: PHASE A — ARCHIVED TAB & 15-CARD GRID
5.1 UI Changes
| Before | After |
|---|---|
| "Unread" tab at top | "Archived" tab at top |
| 16 cards (4×4 with ARCHIVED) | 15 cards (3×4 + 1×3, without ARCHIVED) |
| ARCHIVED in the grid | ARCHIVED accessible via dedicated tab |
5.2 Grid Layout
| Row | Categories |
|---|---|
| 1 | Urgent · Important · Conversations · Awaiting |
| 2 | Journal · Office · Reply Later · Set Aside |
| 3 | Travel · Social · Promotions · Clips |
| 4 | Snooze · Spam · Trash |
5.3 Verdict
<a id="bounce-fix"></a>
SECTION 6: BOUNCE ADDRESS FIX
6.1 Identified Issue
Inbound emails displayed sender addresses like:
bounce+982d51.e8c12e-admin=goweba.com@m.relayfi.com
instead of the real sender address, making Reply and Forward unusable.
6.2 Root Cause
File: app/api/webhooks/sendgrid-inbound/route.ts
Function: handleRawMode()
The code correctly extracted the real address from the MIME From: header via parsed.from.address, but then overwrote it with envelope.from — the technical bounce/return-path address.
// ❌ BEFORE — Bug
const envelopeFrom = parsed.from.address; // ← Correct initially
if (envelope.from) envelopeFrom = envelope.from; // ← OVERWRITES with bounce
// ✅ AFTER — Fix
const mimeFrom = parsed.from.address; // ← Real sender (MIME From:)
let envelopeFrom = mimeFrom; // ← Copy for spam checks
if (envelope.from) envelopeFrom = envelope.from; // ← Envelope for SPF/DKIM only
// mimeFrom → stored in DB and used for contacts
// envelopeFrom → used only for checkSpamAndSpoofing()
6.3 Impact
| Context | Before | After |
|---|---|---|
fromEmail in DB | bounce+xxx@m.relayfi.com | realsender@domain.com |
| Reply function | Replies to bounce | Replies to real person |
| Forward function | Shows bounce | Shows real sender |
| Auto-created contact | Bounce contact | Real contact |
| Anti-spam/SPF | ✅ Works | ✅ Works (unchanged) |
6.4 Known Limitation
30 existing messages still have bounce addresses as fromEmail. Only new inbound emails are fixed. A retroactive migration script can be run on request.
6.5 Verdict
<a id="domain-registry"></a>
SECTION 7: DOMAIN REGISTRY — INITIAL SEED
7.1 Discovery
During the triple verification, it was found that the DomainRegistry table was empty (0 entries). Layer 4 of the V10 cascade (Domain Registry) could not function.
7.2 Corrective Action
Seed executed from lib/weba/domain-registry-seed-data.ts:
- 334 domains defined in source file
- 333 domains created in database (1 duplicate resolved by update)
- 5 categories covered: SOCIAL, TRAVEL, PROMOTIONS, JOURNAL, OFFICE
7.3 Impact on Classification
With 333 domains in the database, layer 4 (confidence 0.90) can now classify most emails from known services without calling the LLM (layer 10), improving speed, accuracy, and cost.
7.4 Verdict
<a id="db-state"></a>
SECTION 8: DATABASE STATE
8.1 Snapshot — June 16, 2026
| Metric | Value |
|---|---|
| Email threads | 884 |
| Email messages | 1,284 |
| Archived threads | 184 |
| Contacts | 1,045 |
| Classification logs | 59 |
| Domain registry entries | 333 |
| Migration projects | 9 |
8.2 Category Distribution
| Category | Threads | % |
|---|---|---|
| NONE | 781 | 88.3% |
| JOURNAL | 42 | 4.8% |
| IMPORTANT | 32 | 3.6% |
| OFFICE | 17 | 1.9% |
| URGENT | 8 | 0.9% |
| PROMOTIONS | 4 | 0.5% |
| TRAVEL | 0 | 0% |
| SOCIAL | 0 | 0% |
Note: 781 threads (88.3%) are categorized
NONEbecause V10 classification has not yet been run on existing threads. After batch classification, this distribution should approach the target documented in the V10 Guide.
8.3 Old Migration Cleanup
Both test migrations (alainbessette55@gmail.com and alainbessette.com/iwant@) were fully deleted:
- 0 residual data found in migration projects
- 0 orphaned data linked to these accounts
<a id="verdict"></a>
SECTION 9: FINAL VERDICT & RECOMMENDATIONS
9.1 Verification Summary
| Component | Verified | Status | Action Required |
|---|---|---|---|
| Google Pull (rate limits, retry, batching) | ✅ | SOLID | None |
| Import (self-chaining, stall detection) | ✅ | SOLID | None |
| V10 Classification (12-layer cascade) | ✅ | SOLID | None |
| Auto-Archive (cron, batch 2000, protected categories) | ✅ | SOLID | None |
| Feature Flags (7/7 enabled) | ✅ | ACTIVE | None |
| Inbound webhook (bounce address) | ✅ | FIXED | None |
| Domain registry (333 entries) | ✅ | SEEDED | None |
| Old migrations (cleaned) | ✅ | CLEAN | None |
| CRON_SECRET | ✅ | CONFIGURED | None |
| Google OAuth credentials | ✅ | CONFIGURED | None |
9.2 Post-Deployment Recommendations
- Run V10 classification on 781 existing threads categorized
NONEvia admin/admin/weba/migration - Run auto-archive to archive threads >90 days in eligible categories
- Verify first inbound emails after bounce fix to confirm addresses are correct
- Consider a retroactive correction script for the 30 messages with bounce addresses
- Consider adding a
replyTofield to theEmailMessagemodel (future improvement)
9.3 Conclusion
🟢 THE MIGRATION PIPELINE IS READY. All verifications passed. Critical fixes applied. Domain registry populated. The system is ready to process new migrations with confidence.
<a id="files"></a>
SECTION 10: MODIFIED FILES — COMPLETE INVENTORY
| File | Modification |
|---|---|
app/(app)/inbox/compose-modal.tsx | initialAttachments prop + presigned URL → base64 + account overwrite fix |
app/(app)/inbox/webabox-client.tsx | replyComposeState type + forward attachments + ARCHIVED tab + grid |
app/(app)/inbox/ongoing/[threadId]/ongoing-client.tsx | composeState type + forward attachments |
app/api/inbox/snapshot/route.ts | archived counter in totals |
app/api/webhooks/sendgrid-inbound/route.ts | mimeFrom vs envelopeFrom separation |
<a id="checkpoints"></a>
SECTION 11: CHECKPOINT TIMELINE
| Date | Checkpoint | Description |
|---|---|---|
| June 15, 2026 | Phase E | Forward attachments + From default fix |
| June 15, 2026 | Phase A | Archived tab + 15-card grid |
| June 16, 2026 | Bounce Fix | Fix bounce address in fromEmail for inbound emails |
End of Addendum 07 — Triple Verification Migration