collab-email GitHub Enterprise org (62 repos), applying the Product Technical Intelligence Playbook to the customer pain themes documented in the Editor Brief. Every claim below is backed by a specific repo finding: file LOC, dep version, schema versions, contributor concentration, PR cycle time, test ratios.nuni-core-ui consumes @collab-email/nuni-core@1.49.0 while the actual library is at 1.74.5 — schema/UI drift gates Universal Content (P2.1).nuni-core-ui, React 18.3 in builder-platform, React 19 in nuni-core. Three layers, three runtimes, one product.nuni-core-ui (the actual editor UI). Library layer is at 111–137%. Quality gates are below the layer customers touch.nuni-core/edit/edit.ts: "Pure function. Zero React deps. Zero state. Zero side effects." Block-typed JSON tree + command pattern + 31 semantic block schemas. Conversational AI in canvas (P4.2.1) is technically achievable today.The Strategy Memo’s +$25–30M FY27 anchor depends on three Q2-Q5 ships — Universal Content (P2.1), NEB Code Mode (P2.2.3), and conversational in-canvas AI (P4.2.1). Two are structurally ready in the codebase today (semantic block schemas, command-pattern edit API). One is structurally blocked by version drift between nuni-core (the schema library, v1.74.5) and nuni-core-ui (the actual editor, pinned at v1.49.0). The single highest-leverage engineering ask in this analysis is closing that 25-version gap before Universal Content ships — not because Universal Content can’t be built, but because shipping it on a stale schema layer guarantees the same fragmentation pattern that produced the Classic-vs-NEB split (Strategy memo Cost-of-Bifurcation: $1–2M ARR risk).
The image labels collab-email/emails-nuni-editor as "Frontend editor (primary)". That repo was last pushed November 12, 2024 — 18 months untouched. The actual primary editor frontend is nuni-core-ui (last push: today, May 13, 2026). emails-nuni-editor is a fork/predecessor; its directory structure, scaffolds (cypress/integration/examples/McappWidget.spec.js) and config files are byte-identical patterns to the early nuni-core-ui. Not in the diagram: mc-omni-mcp (Python MCP server, the agentic surface) and mc-omni-agent-ui (4956KB TS, more active than nuni-core-ui itself). Update the architecture map before the next exec review.
Last 6 months commit count: mc-omni-agent-ui ≈ 691 commits across 5 active engineers vs nuni-core-ui ≈ 83 commits across 2 hero contributors. The Strategy Memo’s Guiding Principle #2 explicitly says "AI cannot compensate for broken editor trust"; the commit ratio shows the team is building the agent layer 8× faster than the foundation it sits on. This matches the playbook’s "Engineering Preference" failure mode (the new shiny thing gets the senior contributors). Expect AI demos to land before bulk Established users (888,706/mo) feel the change.
nuni-core/src/document/operations.ts ships a JSON-tree document model with typed parent/children/properties; nuni-core/src/edit/edit.ts exposes a single edit(doc, edits, config) → EditCandidate command-pattern API. There are 31 semantic block schemas (ButtonBlockSchema, ProductBlockSchema, PromoCodeBlockSchema, EmailFooterBlockSchema...) and 3 schema versions already shipped this year (v20260113, v20260225, v20260316). Universal Content is not an architectural greenfield — it is a primitive that maps to existing edit operations + a registry layer. The blocker is propagation, not invention.
nuni-core-ui/package.json declares "pusher-js": "4.3.1" as a top-level production dependency. Pusher (WebSocket pub-sub) is in the editor today. What’s missing is the collab CRDT/OT layer on top — there are no yjs, @tiptap/extension-collaboration, hocuspocus, or liveblocks deps. The Q5 credibility moment ("Real-time multi-author co-edit + comments", P5.3) is a library-add + integration spike, not a wire-up-WebSockets-from-scratch effort. The TipTap rich-text engine (3.20.1) supports the collab extensions natively.
Grep across nuni-core-ui/src and builder-platform/src for featureFlag|launchDarkly|optimizely|isExperiment: zero hits. The platform-level flag service (Mailchimp’s internal flag infra) is presumably called from nuni-api or higher up the shell, but at the editor level every deploy is all-or-nothing for 888K monthly Established users. This is the playbook’s Layer 7 red flag: "Can they ship incrementally? Or is every deploy all-or-nothing?" The Q2 Universal Content rollout, the Brand Kit data correctness fix (P1.2.1, in the strategy memo’s Q1 list), and the Write with AI ungate (Q4) all assume incremental rollout to a cohort. Confirm the flag harness exists at the editor layer before committing to those quarterly milestones.
Per Layer 5 (commit concentration, last 12 months):
nuni-core: top 2 contributors (sprioleau 147, jhunsucker 106) own ~76% of commits.nuni-core-ui: top 2 (sprioleau 34, ccovell 28) own ~75%.builder-platform: ccovell alone has 181 commits — ~47% single-author share.nuni-api: smoore16 67 commits = ~56%.The playbook calls this bus factor = 1–2 across the entire NUNI core. sprioleau appears as the top contributor in 3 of 4 active repos. This is the most-cited person in the codebase. Resignation, vacation, or reassignment is a P0 risk to the FY27 commit.
| Strategy memo bet (Q-by-Q) | Code-readiness verdict | What has to happen first |
|---|---|---|
| Q1 (May–Jul ’26) · Brand Kit incident closure + SMS TCPA $57K guardrails (P1.2.1, P5.2.3) | CONDITIONAL Bug fixes are tractable. Incremental rollout of Brand Kit data fix needs the missing flag system. | Confirm nuni-api emits flag-gated routes; if not, scope a 2-week flag harness spike before the 50% ramp Austin Milt confirmed in HVC Theme 8. |
| Q2 ★ (Aug–Oct ’26) · Universal Content MVP (P2.1) | PARTIALLY READY Schema + edit API exist; UI consumes a 25-version-old schema lib. | Bump @collab-email/nuni-core in nuni-core-ui from 1.49.0 to ≥1.74. Add the Universal Content FragmentBlockSchema registry path (already exists at the schema layer). Estimate: 4–6 week spike, not 4–6 month rebuild. |
| Q3 (Nov ’26–Jan ’27) · NEB Code Mode (P2.2.3) | UNDER-RESOURCED The html-to-nuni-parser repo (Java, 122 source files, 202 prod-test HTML fixtures) is the inverse capability — Code Mode is the symmetric path. | Define ownership: is Code Mode going into nuni-core-ui (TS) or as a parser microservice (Java, mirroring the existing parser)? Today there is no repo that owns it. This is the highest-risk Q in the roadmap. |
| Q4 ★ (Feb–Apr ’27) · Write with AI global ungate + Free uplift (P4.1.1, P3.4.1) | POLICY-GATED No code blocker; the mc-omni-mcp + mc-omni-agent-ui agentic stack is shippable. | Decouple model-availability flags from rendering paths. Confirm nuni-api can route AI calls per-region/per-tenant. |
| Q5 (May–Jul ’27) · Conversational AI + Real-time co-edit + Shared blocks (P4.2.1, P5.3, P5.1) | FOUNDATION READY TipTap 3.20 + Pusher 4.3 + command-pattern edit() API + JSON-tree state. | Add @tiptap/extension-collaboration + a CRDT (yjs or hocuspocus); wire the existing Pusher channel to collab-doc events. Q5 is the cleanest engineering story in the entire roadmap. |
| Q6 (Aug–Oct ’27) · Brand-style transfer + Prompt-first mode + SMB governance (P4.2.2, P4.2.3, P5.4) | DEPENDENT Requires Q2 + Q5 to land first. | Sequence locked. |
nuni-core-ui from @collab-email/nuni-core@1.49.0 to @^1.74. Either with a single bump and regression sweep, or via a phased migration (one schema version per sprint). This unblocks Universal Content and removes the structural cause of bifurcation drift.sprioleau, ccovell, and smoore16 with a designated co-owner in nuni-core, builder-platform, and nuni-api. The bus-factor risk is invisible until it’s decisive.Method: All numerical findings derived from collab-email/* on github.intuit.com via shallow clone + gh api queries against /repos, /commits, /pulls, and direct file reads. Every claim is reproducible: see Method & Sources tab. Framework applied: Product Technical Intelligence Playbook (May 2026 internal reference, 20 pages, 7-layer forensic + AI readiness + org failure modes).
CUSTOMER (browser · Mailchimp.com / new email builder)
│
│ HTTPS · React 17 SPA · loaded via Mailchimp shell
▼
┌─[1] PRESENTATION (the editor UI)
│ nuni-core-ui · TS · React 17 · 965 KB · push: today
│ ├─ store.ts (966 LOC) ◄── god file: state · save · presence
│ ├─ TipTap 3.20 ── rich-text editor
│ ├─ Atlassian Pragmatic DnD 1.7 ── block drag-drop
│ ├─ Zustand 4.5 + Immer 11 ── state management
│ ├─ pusher-js 4.3 ── WebSocket bus (PRESENT but UNUSED)
│ └─ Bugsnag + browser-perf ── observability
│
│ builder-platform · TS · React 18.3 · 1.8 MB · push: today
│ └─ blocks/ Spacer · Image · Table · Divider · Text
│ (each with renderers/ + migrations/)
│
│ uses (peer dep)
▼
┌─[2] SCHEMA + EDIT (the strategic moat — AI readiness 7/7)
│ nuni-core · TS lib · 1.84 MB · @1.74.5 · push: today
│ ├─ edit/edit.ts ◄── PURE FUNCTION command pattern
│ │ "(doc, edits, config) → EditCandidate"
│ │ Zero React deps · zero state · transactional
│ ├─ document/operations.ts (addBlock · moveBlock · …)
│ ├─ 31 typed BlockSchemas
│ │ (Button · Image · Text · Product · Promo · Footer …)
│ ├─ validate/v20260113 · v20260225 · v20260316
│ └─ renderers/email/ ── per-block HTML output
│
│ ⚠ DRIFT: nuni-core-ui imports @1.49.0 (25 versions behind 1.74)
│ (gates Q2 Universal Content + 3 of 7 VoC hate themes)
│
│ HTTPS · REST/GraphQL
▼
┌─[3] API
│ nuni-api · TS · Hono (NOT Express) · 657 KB · push: today
│ ├─ Pino structured logging
│ ├─ Intuit IAM ticket auth via JSK
│ └─ Pre-push hook: build + test:ci
│
▼
┌─[4] PERSISTENCE (in-flight migration: Kotlin → TS)
│ nuni-document-store · Kotlin · 202 KB · stale 4 mo
│ ─── OR ─── (parallel today)
│ document-data-store · TS · 615 KB · push: today ── NEW
│
─── ASSET LAYER (loaded on demand) ─────────────────────────────────
nuni-template-sources (JS · 18 MB JSON catalog)
nuni-brand (TS · Brand Kit data)
nuni-thumbnails (JS · preview images)
─── RENDER PIPELINE (on send) ──────────────────────────────────────
email-render-pipeline (TS · Vitest + jsdom · push: today)
▸ calibration · scoring · screenshot diff · golden-data PNGs
▸ NOT YET wired into nuni-core-ui CI gate (the unrealized win)
server-side-rendering (JS · 9 MB · push: today)
─→ [Mailchimp send pipeline · OUTSIDE this org]
─── AI SURFACE (parallel · NOT in your repo diagram) ───────────────
mc-omni-agent-ui (TS · 4.9 MB · push: today)
↕ MCP protocol
mc-omni-mcp (Python · 546 KB · push 9 days ago)
▸ agents_and_tools.yaml ◄── MCP tool registry
▸ exposes nuni-core/edit/edit() AS A TOOL
▸ AI-generated edits → preValidate → mutation → postValidate
─── MIGRATION (Classic → NEB · winding down) ──────────────────────
html-to-nuni-parser (Java · Maven · Lombok · 122 src files)
editor-migration-workbench (HTML)
editor-migration-release (Go · stale 10 mo)
nuni-core-ui — a React 17 SPA. TipTap handles rich-text editing; Atlassian Pragmatic DnD handles block drag-and-drop; Zustand + Immer manage state. pusher-js is in the dependency list but currently unused (the unused real-time foundation that Q5 collab will activate).nuni-core-ui imports nuni-core@1.49.0, the schema/edit library that defines what blocks exist (31 typed schemas) and how to mutate documents (edit() pure function, operations.ts CRUD primitives). This is the architectural moat — and the version drift bites: the library is at v1.74.5; the UI consumes v1.49.0. Closing this drift is the single highest-leverage Q1 action.nuni-core/edit/edit({type: 'addBlock', ...}), which returns an EditCandidate. The candidate runs preValidate → mutation → postValidate; if valid, the new doc replaces the old in the Zustand store; React re-renders via builder-platform's per-block renderers.store.ts in nuni-core-ui. This is the playbook's "god file" and the architectural choke point that gates Q5 real-time collaboration.nuni-api — a Hono service (not Express), authenticated via Intuit IAM. The API writes to either nuni-document-store (Kotlin, currently stale 4 months) or document-data-store (TypeScript, the new replacement, pushed today). Persistence is mid-migration from Kotlin to TS.nuni-brand for Brand Kit (colors, fonts, logos); nuni-template-sources for the 18 MB template catalog; nuni-thumbnails for preview images.nuni-core/renderers/email/. The deeper visual-regression check uses email-render-pipeline (jsdom + golden-data PNGs + scoring) but isn't yet wired into the nuni-core-ui CI gate — this is the "70%-built rig sitting unused" finding.server-side-rendering to final HTML, then handed off to the Mailchimp send pipeline (outside this org tree).mc-omni-agent-ui (TS) talks to mc-omni-mcp (Python MCP server), which exposes nuni-core/edit/edit() as an MCP tool. AI agents make valid edits without going through the UI — and because edit() runs the same preValidate/postValidate, AI-generated mutations cannot corrupt the document state. This is the rare case where AI safety is provided by the architecture, not by guardrails bolted on.Architecture lens: 5-layer model (Presentation, Schema+Edit, API, Persistence, Render Pipeline) + 3 satellites (Asset Layer, AI Surface, Migration). Per-repo evidence from shallow clones + gh api as of May 13 2026; consistent with the 7-Layer Forensic tab and Repo Map.
| # | What the customer does | What happens in code | Repos involved |
|---|---|---|---|
| 1 | Click "Create campaign" in Mailchimp | Mailchimp shell routes the browser to the New Email Builder URL. Authentication is already established via the broader Mailchimp session. | (legacy MC monolith routing) |
| 2 | Pick a template from the gallery | Gallery view fetches templates via nuni-api, which reads from the nuni-template-sources JSON catalog and applies the user’s plan/segment filter. | nuni-api · nuni-template-sources |
| 3 | Editor opens with the template loaded | nuni-core-ui hydrates the document tree from the API response; builder-platform renders each typed block via its per-block renderer; nuni-core schemas validate the document on hydrate. | nuni-core-ui · builder-platform · nuni-core |
| 4 | Drag a Text block onto the canvas | DnD event captured by Atlassian Pragmatic DnD → calls nuni-core/edit/edit({type:'addBlock', ...}) → preValidate → mutation → postValidate → new doc replaces old in Zustand store → React re-renders. | nuni-core-ui · nuni-core/edit/ · builder-platform/blocks/Text/ |
| 5 | Edit text in the block | TipTap captures keystrokes → debounced save trigger → edit({type:'updateProperties'}) → typed validation against TextBlockSchema → state mutation. | nuni-core-ui (TipTap) · nuni-core (schema) |
| 6 | Apply Brand Kit | nuni-brand serves the customer’s brand colors, fonts, and logo via nuni-api; the per-block renderers in builder-platform apply brand tokens. | nuni-brand · builder-platform/blocks/*/renderers/ |
| 7 | Mobile preview | Client-side render via nuni-core/renderers/email/; preview is rendered into an iframe inside the editor. | nuni-core/renderers/email/ |
| 8 | Save | nuni-api POST → currently writes to both nuni-document-store (Kotlin, legacy) and document-data-store (TS, new) during the migration; eventually only TS. | nuni-api · document-data-store · nuni-document-store |
| 9 | Click "Send" | Final document validated via nuni-core-cross-validate; server-side-rendering produces final HTML; document handed off to the Mailchimp send pipeline. | nuni-core-cross-validate · server-side-rendering → [send pipeline] |
| 10 | (AI) Type "make the hero block friendlier" | mc-omni-agent-ui sends prompt → mc-omni-mcp resolves intent → calls edit() as MCP tool → preValidate + postValidate guarantee a valid edit lands; UI re-renders. | mc-omni-agent-ui · mc-omni-mcp · nuni-core/edit/ |
FragmentBlockSchema; the missing piece is the UI consuming the new schema version.preValidate/postValidate as a human edit. The architecture provides safety; humans don't have to.nuni-brand data flows through every renderer that consumes it.email-render-pipeline's visual-regression rig isn't wired into nuni-core-ui CI. HVC #3 ($1,820/mo cited).store.ts doesn't model presence; HVC #4 ($340/mo cited).nuni-core-ui consumes a 25-version-old schema; bifurcation pain (VoC #1).nuni-api routing layer (Standard customers in EMEA get nothing).The NUNI architecture is genuinely well-designed at the schema + edit layer — pure-function command pattern, typed block schemas, validated mutations. That layer is a strategic moat. The customer-facing UI layer consumes a 25-version-old version of that moat, leaks five customer contracts because of it, and has a 966-LOC god file that gates the Q5 collab story. Every customer pain in the Editor Brief traces back to the gap between layer 2 (excellent) and layer 1 (drifted). Closing the drift, decomposing the god file, and wiring the visual-regression rig are the three architectural moves that make every roadmap commitment cheaper.
Cross-references: See Pain → Code Map for HVC theme → repo traceability · 7-Layer Forensic for layer-by-layer evidence · AI Readiness for the 7/7 scorecard · Arch Review · SWOT for strengths/weaknesses/threats/opportunities.
| Customer complaint | Why this happens (architectural root cause) | The solution (what we should do) | Business metric to move |
|---|---|---|---|
| VOC #1 · Bifurcation "Two builders that don’t talk to each other — I rebuilt the same welcome email three times." G2 cluster · HVC Themes 1–2 · $834/mo cited |
Templates customers built in the old Classic Builder over the years can’t move automatically to the New Builder. The Java conversion service (html-to-nuni-parser) that was supposed to be the bridge has been quiet for 10+ months — the migration tooling was wound down before the bridge was complete. So mid-migration users rebuild from scratch. |
Restart the migration tooling investment. Build a "1-click migrate ALL my templates" tool using the 202 production HTML test fixtures already in the parser repo as the regression suite. Pair with funded migration assistance for Premium accounts (12-month grace period). Until this ships, every Classic-to-NEB migration produces churn. | Bulk Established 888K → 915–935K (+$10.4M L1) Premium/agency Classic ARR retained ($1–2M risk per Strategy R1) |
| VOC #6 · No Universal Content "Klaviyo just shipped Universal Content. Edit once, propagates. I’m migrating before BFCM." Reddit r/Klaviyo Spring ’26 · HVC Theme 1 · $330/mo cited |
The "edit once, propagates everywhere" capability has actually been built in Mailchimp’s schema library — it’s called FragmentBlockSchema and lives in nuni-core@1.74. But the editor UI is consuming an old version of that library (@1.49, 25 versions behind). It’s like the kitchen made a new dish but never sent it to the dining room. |
Ship a "schema bump" — upgrade the editor UI’s consumed library version from 1.49 to 1.74. This is 4–6 weeks of regression testing, no new feature code, just integration. Highest-leverage Q1 action in the brief — closes Universal Content + 2 other customer hate themes simultaneously. | Universal Content adoption 50–70% of NEB users Block reuse +25–40% per campaign +$4–7M FY27 (Strategy P2) |
| HVC #3 · Rendering bugs "Forwarded mail looks not good at all"; mobile line-breaks; Ctrl+K broken on Firefox/Chrome. $1,820/mo cited (4 named users incl. $949 Premium) |
When a code change breaks how an email renders in Gmail / Outlook / mobile, nothing automated catches it — the team finds out from support tickets. Mailchimp does have a screenshot-comparison tool already built (email-render-pipeline) with golden-data PNG fixtures, but only 2 tests use it and it’s not wired into the editor’s pre-merge CI gate. Every release has a chance to ship a regression. |
Wire the existing screenshot-diff tool into the editor’s CI pipeline. Every PR runs it; broken rendering blocks the merge. The infrastructure is 70% built — this is a 1–2 week integration job, not a build. Cheapest retention save in the brief. | Bulk churn 40.0% → 36.5–37.5% Mobile preview tickets −35% +$3–5M FY27 L5 retention save |
| HVC #4 · Multi-author save conflicts "Just get a message saying there is a problem with the saved version … no indication that someone else is currently editing." UR Bet #4 · Jack/Kyle/Bianka cluster · $340/mo cited |
When two team members edit the same email, one’s changes get silently overwritten. The editor doesn’t track who has the document open — only what the document looks like. The state-management code (store.ts, a single 966-line file) tangles save logic, conflict detection, and rendering state together. Adding multi-user awareness requires breaking up that file first. |
Decompose store.ts into three smaller files: state, save/persistence, presence. Then add presence-awareness using the pusher-js dependency that’s already in package.json but unused. After that, real-time co-edit (the Q5 strategy moment) becomes a follow-on, not a rebuild. |
Save-conflict tickets eliminated Foundation for P5.3 real-time co-edit (Q5 ★ credibility moment) |
| HVC #5 · Block-ordering bugs "Editor often confuses order of blocks or won’t let you move them without a refresh." $410/mo Premium |
The block-mutation code (operations.ts in the schema library) does the right thing — but the editor UI consumes an older version of the library while running on React 17, while the library itself expects React 19. Timing mismatches between what the library says ("the block is now at position 2") and what the UI renders cause race conditions that look like bugs to the customer. |
Same root cause as Row 2 — the schema bump fixes it. Until the editor consumes the current library, every block-mutation bug has version drift as a contributing factor. After the bump, run integration tests focused on block-reordering scenarios specifically. | Block-ordering tickets cleared ($410/mo) Pre-condition for P5.3 collaborative edit (must trust single-author state first) |
| HVC #6 · Templates don’t appear in wizard "My campaign tab is not showing the templates built in the new builder." $1,950/mo cited (Premium account) |
Templates are stored in one place (nuni-template-sources catalog), served by another (nuni-api), and read by a third (the campaign wizard’s filter logic in the editor UI). When the wizard’s query parameters don’t match what the API expects, new templates get filtered out invisibly. The customer thinks their templates didn’t save. |
Audit the contract between the API’s template-listing endpoint and the campaign wizard’s consumer code. Add an integration test that creates a New Builder template and verifies it appears in the wizard within 30 seconds. 1–2 week fix. | Direct $1,950/mo Premium-account exposure cleared Activation rate (P3.1.4 AI Setup Agent depends on the same registry) |
| HVC #7–10 · Brand Kit reliability Stale colors; logo present but no colors; "DIN 2014 not recognized by Creative Assistant"; no multi-brand kits. $6,465/mo cumulative |
Customers spend hours setting up Brand Kit (logo, colors, fonts) and expect it to flow through every email, landing page, form, and AI design suggestion automatically. But Brand Kit data lives in nuni-brand, while consumers (editor, landing pages, Creative Assistant, signup forms) each fetch and cache it separately. When data updates, not all consumers see the update. Multi-brand isn’t supported because the data model assumes one kit per account. |
Treat Brand Kit as a contract, not a data store. Define one source-of-truth in nuni-brand; make every consumer read from it on every request (no caching divergence). Add a multi-brand data model — one account → multiple kits with one default. 4–6 weeks of platform work; closes 4 cited HVC themes. |
P1.2 sub-pillar (4 initiatives, FY27 $3–5M) Brand Kit auto-extract on signup unblocked |
| HVC #13 · Canva sync silent failure "Sent an email without the synced graphic even though the graphic showed in the editor." $2,500+/mo cited |
When a customer drags a Canva design into a Mailchimp email, the editor stores a reference (URL) to Canva’s content — not the image itself. At send-time, Mailchimp tries to fetch the image from Canva. If Canva says "no" for any reason (deleted, permissions changed, server hiccup), the email ships without the image. There’s no error handling for "Canva said yes a minute ago but says no now." | Two fixes: (1) cache Canva content in Mailchimp’s CDN at drag-time so the send is decoupled from Canva availability; (2) show "image not synced" warning before send if the cached version differs from Canva’s current. Cross-team work — the Canva integration likely lives in a different team’s repo, so this needs escalation contacts. | Direct $2,500+/mo named exposure P1.3.1 (Strategy memo Q1 deliverable) |
| HVC #16 · SMS TCPA $57K incident C3 Festivals duplicate opt-out shipped in live SMS campaign — legal exposure. Largest single named exposure in the brief |
The SMS engine auto-appended a compliance footer to every message AND the customer’s template already included one. So recipients got two opt-out instructions — technically a TCPA violation. The send pipeline has no validation step that checks "this message already has compliance text, skip auto-append." | Add a pre-send compliance-check Executor: scan the SMS body for existing opt-out language; if present, skip the auto-append. Simple boolean check, not a complex feature. Cross-team — SMS pipeline isn’t in the editor org tree, requires escalation to the partner team owning the send pipeline. | $57K/mo named MRR risk eliminated SMS churn 53% → 46–48% |
| UR Discovery · Multi-year undiscovered features 5 named customers used 10–20% of editor features for years (Bianka, Jack, Jeffrey, Clint, Wes). UR Bet #2 |
There’s no surface in the editor that tells customers about new features at the moment they’d care. Bianka didn’t know A/B testing existed for years; Jack used a 4–6 year old template because he didn’t realize the New Builder was a thing; Clint left a welcome automation in DRAFT for over a year. The help docs that document the features go unread. | Build an in-product discovery surface inside the editor: weekly product-update sidebar; contextual prompts ("you’ve used X, try Y"); "draft resurrect" nudges for incomplete journeys. From-zero build in nuni-core-ui — 4–6 weeks. Closes the silent-churn pattern of "I’m not getting enough value." |
Capability utilization 10–20% → 35–50% L3 + L4 levers (~$1.5M ARR) |
| VOC #5 · No real-time collaboration "Single editor at a time; no Google-Docs-style co-edit; teams workaround via screenshots." −48 net sentiment · UR Bet #4 |
Modern marketing teams of 2–5 expect Google-Docs-style co-editing. Mailchimp doesn’t support it because: (a) no real-time sync engine is wired in (though pusher-js is in deps, unused); (b) the rich-text editor (TipTap) supports collab as an opt-in extension that’s not added; (c) the state god file (store.ts, 966 LOC) doesn’t model multiple users. |
This is a 4-week PoC, not a rewrite. Add @tiptap/extension-collaboration + a CRDT (yjs is the natural choice) + wire Pusher (already in deps) as the transport + decompose store.ts (Row 4 dependency). Real-time co-edit becomes the Q5 ★ "Mailchimp is back, modern" credibility moment. |
Q5 credibility moment L6 ARPU lift on multi-author teams |
| HVC AI / Health · Write with AI geo-gate "I am in the Netherlands. I get to pay for AI I cannot use." Explore −73.7% YoY · churn 77.2% (worst in family) |
Write with AI is gated to US/UK/AU/CA only — but the Standard plan is sold globally. International customers pay the same price and can’t use the headline AI feature. The geo-gate is enforced UI-side, not API-side, so even if the model is technically available, the UI won’t show it. | Move the geo-gate decision from the UI to the API gateway (nuni-api). Then run a parallel policy track to either (a) ungate Write with AI globally, or (b) repackage as a paid AI add-on globally. Technical work < 2 weeks; policy/legal work 1–2 quarters. |
P4 entire pillar (15 initiatives, FY27 $4–6M) Reverses Health Crisis Pillar (Strategy R3) |
Once you map every customer pain to the code that causes it, four patterns emerge. Each is a leverage point: fix one structural issue and multiple customer complaints clear simultaneously. Each pattern below is structured the same way: why it’s a problem · why it keeps happening · the solution.
Why this is a problem. The editor is built in two halves that talk through a versioned contract. The "library" half (nuni-core) is where new features get built first — it’s currently at version 1.74. The "editor UI" half that customers see is consuming version 1.49, which is 25 versions behind. It’s like a restaurant where the kitchen has a new menu but the waiters are still working from a printed copy from five months ago. Three of the seven customer hate themes (the two-builder split, no Universal Content, no HTML escape hatch) all happen because new capabilities exist in the kitchen but never reach the customer’s table.
Why it keeps happening. Bumping the version requires a regression sweep — testing every editor screen against the new library to make sure nothing breaks. It’s not glamorous work, no new feature ships from it, so it gets deprioritized. But every quarter, the gap grows and the regression sweep gets harder.
The solution. Schedule a 4–6 week "schema bump" as a single Q1 commit — one engineer, zero new features, just close the gap. Once it lands, three customer hate themes become solvable simultaneously, and Q2 Universal Content (the Strategy Memo’s biggest competitive ship) is automatically unblocked. Highest-leverage Q1 action in the entire brief.
store.ts is the choke point for collab + reliabilityWhy this is a problem. The editor has one giant 966-line code file (store.ts) that handles everything: tracking what the document looks like, saving it, managing undo/redo, and (eventually) tracking who else is editing. When one file does too many things, every change risks breaking something else — engineers get scared to touch it, bugs accumulate, and any new feature that needs to interact with state has to wedge itself in.
Why this is the bottleneck. Three customer pains all live in this one file:
The solution. Split store.ts into three smaller files with single responsibilities: one for document state, one for save/persistence, one for presence. This 2–3 week refactor unblocks two cited bugs and the entire Q5 collaboration roadmap — three quarters of strategy depend on this single file getting decomposed.
Why this is a problem. Mailchimp’s #3 cited customer complaint is "the email looked right in the editor, but the recipient saw something broken" — particularly forwarded mail, mobile preview, and Outlook web view. $1,820/mo of named-customer pain on this single theme. The standard way to catch these regressions is automated screenshot tests: snapshot the email rendered today, compare it to a known-good version, fail the build if they differ.
The twist. Mailchimp already has this infrastructure built in a repo called email-render-pipeline — calibration, screenshot diff, scoring, golden-data PNG fixtures. It’s all there. It’s just not connected to the editor’s test pipeline. Today only 2 tests use it. So when an engineer changes the renderer, the screenshot tool isn’t checking; the regression ships; the customer files a ticket. Classic "infrastructure-without-an-owner" pattern — the team that built the visual-regression rig is presumably different from the team shipping editor changes; nobody owns wiring them together.
The solution. Wire the existing screenshot-diff tool into the editor’s CI pipeline. Every PR runs it; broken rendering blocks the merge. This is a 1–2 week integration job using infrastructure that’s 70% complete. Once wired, it closes the entire Theme 3 customer-pain pattern. Cheapest retention save in the brief.
Why this is a problem. Looking at code-change activity over the last 6 months, the AI agent layer (mc-omni-agent-ui + mc-omni-mcp) has had ~5× the activity of the actual editor UI (nuni-core-ui). The team is investing more engineering energy in AI features bolted on top of the editor than in fixing the editor itself.
Why this matters — and why it keeps happening. The Strategy Memo has an explicit guiding principle: "AI cannot compensate for broken editor trust." The brief documents $95K/mo in customer pain on the editor side, and the team’s commit pattern ships AI demos faster than foundation fixes. Risk: a customer tries the new conversational AI, asks it to do something, the underlying editor breaks because of an existing rendering bug, and the customer concludes "AI is broken" — when it was actually the foundation underneath. Why does it persist? New AI work attracts senior engineers; bug-fixing the existing editor doesn’t.
The solution. This isn’t a code question — it’s a leadership question. Before Q3, the exec team should decide what % of capacity goes to fixing the editor foundation (target: ≥ 60%) vs. building new AI features (target: ≤ 25%) for the rest of FY27. The codebase shows the priority; the leadership decision aligns it.
Sources: All repo facts from github.intuit.com/collab-email/* via shallow clone (depth=1) on main/master tips as of May 13 2026. Customer-pain references from HVC Risk Map ($95K/mo cited across 17 themes), Voice of Customer (7 hate themes), User Research (5 bets, Discovery table). Framework: Product Technical Intelligence Playbook §4 "Customer Pain → Code Mapping."
github.intuit.com/collab-email/* as of May 13 2026. 62 repos in the org; 8 are core-active; the diagram covers only 6 of them and includes one that’s been quiet for 18 months.The image groups NUNI repos into 9 functional layers. Cross-checked against gh api orgs/collab-email/repos (62 repos):
| Diagram layer | Repo (per diagram) | Live size | Last push | Reality check |
|---|---|---|---|---|
| Frontend editor (primary) | collab-email/emails-nuni-editor | 182 KB | Nov 12 2024 | This is the wrong repo. Hasn’t been pushed in 18 months. The byte-identical scaffolding (cypress/integration/examples/McappWidget.spec.js) shows it’s an ancestor of nuni-core-ui. Actual primary is nuni-core-ui (last push today, 965 KB, all editor UI work happens here). |
| Builder platform shell | collab-email/builder-platform | 1,799 KB | May 13 2026 | Correct + active. TS, React 18.3, 8 forks, 11 watchers (highest in the org). blocks/Text|Image|Spacer|Table|Divider shows it’s the block-rendering shell. |
| Schema / validation lib | collab-email/nuni-core + nuni-core-cross-validate | 1,840 + 242 KB | May 12 2026 | Correct. nuni-core@1.74.5 is the source-of-truth schema package; consumers in editor + API + render pipeline. nuni-core-cross-validate is the cross-document validator (e.g. fragment graph integrity). |
| API service | collab-email/nuni-api (+ -config, -deployment, -test) | 657 KB | May 12 2026 | Correct + active. Surprise: Hono framework (not Express). CLAUDE.md in repo — team is using Claude Code for development. |
| Document store | collab-email/nuni-document-store (Kotlin) | 202 KB | Jan 15 2026 (4mo stale) | Correct but concerning. The Kotlin doc store hasn’t been pushed in 4 months. Meanwhile document-data-store (TS, 615 KB, last push today) appears to be a parallel/replacement service. Diagram doesn’t mention document-data-store. |
| Templates / brand / docs | nuni-template-sources, nuni-brand, nuni-doc-library, nuni-screenshot-app | 18,739 + 454 + 5,360 + 63,651 KB | Mixed | Correct list. Note: nuni-screenshot-app at 63 MB — likely contains golden-data screenshots. nuni-doc-library is doc generation (nuni-thumbnails at 55 KB is the image-thumb companion). |
| HTML→Nuni migration | html-to-nuni-parser, editor-migration-workbench, editor-migration-review-ui, editor-migration-release | 546,139 + 3,208 + 309 + 109 KB | Mostly winding down | Correct list. html-to-nuni-parser is Java + Maven + Lombok (122 source files, 202 prod-test HTML fixtures) — a JVM service, not the Kotlin store. Migration release tooling last touched Jul 2025 (10 months) — investment is winding down. Implication: Classic-to-NEB migration is no longer being actively built; either it’s "done" or stalled. |
| Playground / cross-checks | collab-email/nuni-playground | 517 KB | Apr 3 2026 (5wk) | Correct. Internal sandbox — useful for spike scoping but not on customer path. |
| Render pipeline / SSR | email-render-pipeline, server-side-rendering | 297 + 9,087 KB | May 12, May 4 2026 | Correct + active. email-render-pipeline uses Vitest + jsdom + nuni-renderer-jsdom with calibration/comparison/screenshot infrastructure — the visual-regression scaffolding for the rendering parity story. |
Last push: today (May 13 2026, 18:02 UTC). Most recently pushed repo in the entire org. Contains AGENTS.md and CLAUDE.md at root — agent-architecture documentation in-repo. Active contributors last 6mo: jarama 233, sprioleau 124, jlittle4 123, ccovell 107 — 691 commits across 4 active humans + a service bot.
This is where conversational journey editing (P4.2.1, the Q5 ★ Strategy moment) is being built. Cross-references with the editor by sharing 3 of the 4 top engineers (sprioleau, ccovell, jlittle4) — same hero pool, two products.
Last push May 4 2026. Contains agents_and_tools.yaml (MCP tool registry), JenkinsfileAgenticStage.snippet (CI agent stage), .cursorrules + .windsurfrules (in-tree IDE rules). This is the Model Context Protocol server — the agent backend for the omni surface above.
Top contributors: jdudley1 36, amilt (Austin Milt — same engineer who shipped the Brand Kit fix in HVC Theme 8) 32, jlittle4 17. Austin Milt is splitting time between Brand Kit reliability and the agent backend — Layer 5 hero-engineer concentration extends to AI infra.
Last push today. Newer parallel/successor to the Kotlin nuni-document-store (which hasn’t shipped since Jan). Likely the read/write path the active TS stack uses. Migration from Kotlin → TS data store is in progress; not labeled in the diagram.
Risk: Two document stores in parallel echoes the Classic-vs-NEB editor split. If the Kotlin store still serves any production traffic, it’s a bifurcation in the persistence layer.
Last push Oct 29 2025 (6+ months stale). Possibly a thin wrapper / consumer of the platform — the name suggests it’s the campaign-side host. Status unclear from metadata alone; needs ownership clarification.
Adjacent repos in same state: email-nea (197 KB, Sep 2025), forms-builder (268 KB, Sep 2025), sms-registration-ui (198 KB, Oct 2025) — a small constellation of TS UIs all 6+ months stale.
Active (last push today). Larger than nuni-core-ui. Top-of-org by recent push order. Possibly a parallel builder for the proposal/sales-doc product sharing the platform shell. Worth confirming whether it consumes builder-platform as a consumer or has forked logic.
Active. Likely the transactional-email builder — Mailchimp Transactional (formerly Mandrill). Strategy memo’s Health Tab notes Transactional Established −10.5% YoY; this is the repo where retention work would land.
| Repo | Language | Framework | Tests | State mgmt | Build |
|---|---|---|---|---|---|
nuni-core | TypeScript 5.6 | None (lib) · React 19 peer | Jest + 75 unit; 14,731 test LOC ≈ 111% of source | immer 11 + zod 3.25 | tsc · auto for releases |
nuni-core-ui | TypeScript 4.8 | React 17.0.2 · TipTap 3.20 · styled-components 4.4 | Jest + 16 unit (3,438 LOC ≈ 17% of source); Cypress folder = 1 scaffold spec | zustand 4.5 + immer 11 | @appfabric/plugin-cli (Intuit internal) |
builder-platform | TypeScript | React 18.3 · drag-drop: @atlaskit/pragmatic-drag-and-drop 1.7 | Jest + 64 unit (11,315 LOC ≈ 137%) | (consumer of host store) | tsc |
nuni-api | TypeScript | Hono 4 · Pino logging | Jest + 13 unit | (stateless service) | tsc + Docker · pre-push CI hook |
email-render-pipeline | TypeScript | jsdom + custom nuni-renderer-jsdom + screenshot diff | Vitest + 2 (calibration, scoring) | (stateless) | tsc |
html-to-nuni-parser | Java 17 | Maven · Lombok · 122 source files | JUnit (count not enumerated; 202 prod-test HTML fixtures) | (stateless service) | Maven + Docker |
nuni-document-store | Kotlin | Gradle Kotlin DSL · Spring (likely) | Gradle test (count not enumerated) | (JPA / data layer) | Gradle + Docker |
document-data-store | TypeScript | (NEW · supersedes Kotlin store) | — | — | — |
mc-omni-agent-ui | TypeScript | (unscanned in this pass) | — | — | — |
mc-omni-mcp | Python | MCP server | (unscanned) | — | Docker · Jenkins agentic stage |
The NUNI surface ships in 6 languages: TypeScript, JavaScript, Kotlin, Java, Go, Python. Each language carries its own dependency tree, security audit cadence, CI lane, and on-call training cost. The migration tooling alone (Go for editor-migration-release + editor-migration-workbench-runner; Java for the parser; Kotlin for the legacy doc store) is three runtimes. This is not unusual for a 4-year-old platform, but it is operational tax that compounds with the React-version drift.
Three React versions across three layers consumed by the same product (React 17 in nuni-core-ui, React 18.3 in builder-platform, React 19 peer in nuni-core) is the playbook’s Layer 2 dependency-debt red flag in its purest form. It works today via React’s backwards-compat guarantees, but the moment nuni-core uses a React-19-only API (e.g. use(), async transitions), nuni-core-ui breaks unless it bumps too.
Sources: gh api orgs/collab-email/repos --paginate (62 repos enumerated). Per-repo package.json, build.gradle.kts, pom.xml read from shallow clones. Last-push timestamps from GitHub repo metadata. Contributor counts from gh api repos/<repo>/commits?since=2025-05-01T00:00:00Z --paginate. Cross-referenced with diagram in user-supplied image (Mailchimp New Builder (NUNI), dated May 13 2026).
What we found:
nuni-core/src/ splits into document/, edit/, define/, render/, renderers/email/, channel/email/, validate/, load/ — each a distinct concern, each importable independently via package exports map. This is what the playbook calls "Strong" (modular components / rendering-engine / template-parser / preview-service).blocks/Spacer|Image|Table|Divider|Text/{renderers,migrations} shows per-block ownership of rendering + migration paths. Migration paths inside the block dir is a forward-thinking architectural choice — schema versions ship beside the block.src/js/widgets/editor/NuniCoreEditor/platform/store.ts at 966 LOC — over the playbook’s 800 LOC threshold. This file is the high-fan-in choke point for state, save, conflict, and presence. Multi-author (HVC #4) and block-ordering (HVC #5) bugs both flow through it.nuni-core/src/validate/v20260113/, v20260225/, v20260316/ — three schema versions shipped this year alone (Jan, Feb, March). The validate.ts dispatches by version. Forward compatibility is being engineered, not bolted on.edit(), semantic block types. The library half of NUNI is well-architected.store.ts; three React versions in the live chain (17 / 18.3 / 19); Kotlin doc-store running in parallel with new TS doc store (persistence-layer bifurcation echoes the editor bifurcation customers hate).What we found:
renovate.json extends Intuit’s AppFabric/renovate-config). Auto-update bot runs as svc-uxinfra-bot (12 commits in nuni-core-ui last 6mo, 104 in mc-omni-agent-ui) — the harness is healthy.nuni-core-ui/package.json declares "@collab-email/nuni-core": "1.49.0" exactly (no caret), preventing Renovate from upgrading. Either there’s a known incompatibility, or the team is afraid of the schema bump. This needs a decision.nuni-core@1.74.5 declares "react": "^19.2.4" in dev/peer; builder-platform declares "react": "~18.3.1"; nuni-core-ui declares "react": "17.0.2" exactly. Three majors live concurrently in the production consumer chain.react-intl@2.9.0 (current major: 7.x), styled-components@4.4.1 (current: 6.x), tabbable@4.0.0, focus-trap@7.6.5, TypeScript 4.8 (current: 5.7). These work, but they bloat bundle and gate UI library upgrades."engines": { "node": ">= 18.0.0 < 19.0.0" } — Node 18 only. Node 18 entered maintenance LTS Oct 2024 and is end-of-life April 2025. This pin will break before Q3 FY27 if not bumped.@design-systems/icons (Intuit), @mcds/components (Mailchimp), and @ids-ts/* (Intuit TypeScript). Three component libraries inside the same editor — Brand consistency UX paradox.pusher-js@4.3.1 as a top-level dep. No yjs, @tiptap/extension-collaboration, liveblocks. Pusher 4.x is itself a stale major (current: 8.x).auto for releases is configured; secret-detection ESLint plugin (eslint-plugin-no-secrets) is enabled in the editor.What we found:
| Repo | Source LOC | Test LOC | Ratio | Verdict |
|---|---|---|---|---|
nuni-core | 13,223 | 14,731 | 111.4% | EXCELLENT |
builder-platform | 8,238 | 11,315 | 137.4% | EXCELLENT |
nuni-core-ui (the actual editor) | 20,604 | 3,438 | 16.7% | FEAR-DRIVEN |
nuni-api | (not enumerated) | 13 test files | — | LIGHT |
email-render-pipeline | (not enumerated) | 2 test files | — | SCAFFOLD ONLY |
ImageBlockSchema.test.ts (854 LOC), formatErrors.test.ts (837 LOC), ButtonRenderer.test.tsx (684 LOC) — substantive integration-flavored unit tests, not happy-path-only.nuni-core-ui/cypress/integration/examples/HelloWidget.spec.ts — 1 file, scaffold name, looks like template default.emails-nuni-editor/cypress/integration/examples/McappWidget.spec.js — 1 file, scaffold (and the repo is dead).email-render-pipeline ships calibration/, compare/, scoring/, screenshot/ with PNG fixture sets and a generate.ts for golden data. The infra is 70% built. It’s gated by 2 unit tests and isn’t wired into nuni-core-ui CI. Cheapest L5 retention save in the brief: finish wiring this in.app/src/test/resources/prod-test-nuni-html-data/, prod-tool-test-nea-html-data/) — golden-data discipline exists on the JVM side. Mirror it on the TS side.yarn clean && yarn build && yarn test:ci (per CLAUDE.md) — strong gate.email-render-pipeline is largely built. Pre-push hook on the API.nuni-core-ui/store.ts, nuni-core/document/operations.ts, renderers/email/SocialFollowRenderer.tsxLargest source files (Layer 4 thresholds: >800 LOC = god-class candidate; >500 LOC = complexity hotspot):
| File | LOC | Repo | Concern |
|---|---|---|---|
src/js/widgets/editor/NuniCoreEditor/platform/store.ts | 966 | nuni-core-ui | God-class candidate. State/save/conflict/presence concentration. Touched by HVC #4 + #5. Decompose to unblock Q5 collab. |
src/channel/email/schemas/ImageBlockSchema.test.ts | 854 | nuni-core | Test file; complexity reflects schema breadth, not anti-pattern. |
src/channel/email/functions/formatErrors.test.ts | 837 | nuni-core | Test file (good). |
__tests__/StaticRenderer.test.tsx | 739 | builder-platform | Test file (good). |
src/js/widgets/email-editor/EmailEditor/services/schemaConverter.ts | 687 | nuni-core-ui | Production code over 600 LOC. Bridges old "email-editor" widget to NEB schema. The schema-conversion path — direct candidate for the 25-version-drift bump-and-rewrite work. |
src/renderers/email/ButtonRenderer.test.tsx | 684 | nuni-core | Test file (good — Button is highest-fan-in block). |
src/channel/email/schemas/schemas.ts | 664 | nuni-core | Schema registry. Production code; not a problem if cohesive (schema declarations). |
src/document/operations.ts | 641 | nuni-core | Production code. Contains addBlock / moveBlock / moveToColumnPosition / duplicateBlock. Heavy churn likely (HVC #5 cluster lives here). |
src/renderers/email/SocialFollowRenderer.tsx | 626 | nuni-core | Production code. Single-block renderer at 626 LOC = block-specific complexity. Likely Outlook/Gmail/AOL conditional rendering. |
controls/RichTextToolbar.tsx | 611 | builder-platform | Production code. Toolbar = high-fan-in surface; refactor candidate. |
The four production hotspots (>600 LOC, non-test): store.ts, schemaConverter.ts, operations.ts, RichTextToolbar.tsx. Three of them are in the editor consumer chain (nuni-core-ui + builder-platform); the fourth (operations.ts) is in the schema lib but is mutating-API code and likely high-churn. Per the playbook’s Layer 4 superpower lens — "complexity × churn = real choke points" — these four files are where the FY27 customer-pain dollars concentrate.
store.ts at 966 is over the god-class threshold and gates the Q5 collab moment.| Repo | Top contributor concentration (last 12mo) | PR median | PR p95 | Verdict |
|---|---|---|---|---|
nuni-core | sprioleau 147 + jhunsucker 106 = 76% of commits between 2 humans | 17.6h | 75.0h | HERO 2-of-N |
nuni-core-ui | sprioleau 34 + ccovell 28 = 75% across 2 humans (low total: ~83 commits in 12mo) | 7.1h | 692.6h (29 days) | REVIEW BOTTLENECK |
builder-platform | ccovell alone 181 commits = 47%; second contrib at 59 | 2.8h | 98.0h | SINGLE HERO |
nuni-api | smoore16 67 = 56% single-author | 3.4h | 64.6h | SINGLE HERO |
mc-omni-agent-ui | jarama 233 + sprioleau 124 + jlittle4 123 + ccovell 107 — 4 active humans + service bot | — | — | DISTRIBUTED |
sprioleau appears as #1 or #2 in nuni-core, nuni-core-ui, mc-omni-agent-ui — three of the four most-critical surfaces. ccovell appears as #1 in builder-platform AND #2 in nuni-core-ui AND #4 in mc-omni-agent-ui. Two engineers carry the floor of the FY27 commit. Per playbook §1.1 this is the "Hero engineer dependency" failure mode in pure form.mc-omni-agent-ui alone has shipped roughly 8× more commits in the last 6 months than nuni-core-ui. The team is shipping AI features faster than the editor that hosts them.auto-it/git-tag plugin configured) suggests semver discipline; weekly-or-better release cadence implied by the 25-version delta over ~10 months.auto; Renovate bot is healthy; PR median time-to-merge is healthy across the org (median < 24h on every active repo).nuni-core-ui p95 PR time = 29 days = unstuck-after-month review path. AI surface is shipping at 8× the rate of the editor that hosts it.What we found:
@bugsnag/js@8.8.1, @bugsnag/browser-performance@3.4.1, @bugsnag/plugin-react@8.8.0 — Bugsnag + Browser Performance + React error boundary integration. No Sentry, no Datadog RUM detected. Single-vendor observability.nuni-core-ui/webpack.config.js is bare (per the comment block, plugin-cli handles the build) — no webpack-bundle-analyzer, no source-map explorer, no preload hints visible at this level. Bundle size is unlikely to be measured per-PR.outlook|gmail|MSO|
L7
Layer 7 · Feature Flag & Configuration Debt
No detectable feature-flag system inside the editor. Every deploy is all-or-nothing for 888K Established users.
What we found:
- Grep across
nuni-core-ui/src + builder-platform/src for featureFlag|FeatureFlag|launchDarkly|optimizely|isExperiment|experimentKey|flagService: zero matches.
- It’s plausible that flag resolution happens at the platform-shell or
nuni-api level (Mailchimp’s internal flag service is presumably called server-side and decisions are baked into the bootstrap response). But at the editor surface, every customer gets the same code on every deploy.
- This is the playbook’s Layer 7 red flag in pure form. The Strategy memo’s Q1 Brand Kit fix, Q2 Universal Content MVP, Q4 Write with AI ungate, and Q5 collab moment ALL assume cohort rollouts. Without an editor-layer flag harness:
- Universal Content can’t be A/B tested for adoption velocity — ship-or-don’t.
- The Brand Kit data fix (50% ramp confirmed by Austin Milt in HVC #8) — confirm this ramp is happening at
nuni-api, not in the UI.
- The Write with AI geo-ungate has to be a routing decision in
nuni-api, not a UI flag.
- Stale config detection: No top-level magic-URL strings in
nuni-core-ui/src per spot-check; config.json at root contains build-time config (region/locale defaults). The team uses plugin-cli for build, which likely injects environment via NODE_ENV at compile time.
- language-config.json at repo root is the i18n entrypoint — pairs with the (stale) react-intl 2.9 stack. International rollout of Write with AI requires the i18n stack to actually work.
Strengths: Build-time config is centralized in config.json + language-config.json; no obvious magic-URL hardcoding visible.
Risks: No detectable editor-layer feature flag system. Every roadmap milestone in Q1–Q5 assumes incremental cohort rollout. Confirm the harness exists, or scope a 2-week harness spike before Q1 ships.
Method: Each layer applied per the Product Technical Intelligence Playbook §3 (Days 3–7 deep dive). Evidence collected via shallow-clone + find/grep/wc/jq against the latest tip of main/master. Contributor and PR data from github.intuit.com REST API on May 13 2026. All findings are reproducible — see Method & Sources tab for the exact queries.
Signals:
sprioleau = top contributor in nuni-core (147 commits = 53%), top in nuni-core-ui (34 = 41%), #2 in mc-omni-agent-ui (124 commits). One person, three of the four most-critical surfaces.ccovell = top contributor in builder-platform (181 commits, 47%), #2 in nuni-core-ui (28), #4 in mc-omni-agent-ui (107). One person, also three of the four critical surfaces.nuni-core-ui p95 PR time = 692 hours (29 days) — long-tail PRs sit waiting on the same approver pool.Diagnostic question (per playbook): "What happens if this person is on vacation?"
Mitigation (within 30 days): Name a designated co-owner on each top-3 critical-path repo. Pair-program on the next two PRs. Rotate one Q1 ship lead away from sprioleau / ccovell.
nuni-core-ui is the codebase-level signalSignals:
nuni-core: 111% test/source ratio. builder-platform: 137%. nuni-core-ui: 17%.store.ts 966-LOC god file, the 687-LOC schemaConverter.ts bridging dead-repo to live-repo, and the unused email-render-pipeline rig together describe a system where the safest code-paths are the ones nobody touches.Diagnostic question (per playbook): "What systems create the most anxiety? What code does nobody want to touch?"
mc-omni-agent-ui and nuni-core-ui.Mitigation: Wire email-render-pipeline golden-data screenshots into the nuni-core-ui CI gate. Add 4 cypress tests covering the HVC #3, #4, #5 bug clusters before any new editor feature. Treat test-first as a precondition for the Q2 Universal Content ship.
Signals:
mc-omni-agent-ui, mc-omni-mcp) is running 8× faster than the editor — and the Strategy memo’s explicit Guiding Principle #2 says "AI cannot compensate for broken editor trust."Diagnostic question (per playbook): "Modernization for customer value or engineer preference? What’s the customer-facing benefit?"
Signals:
amilt — Austin Milt — confirmed the 50% ramp). System works when prioritized.nuni-core-ui.Diagnostic question (per playbook): "Who owns quality? What happens when a bug is found?"
email-render-pipeline is the institutional answer waiting to be wired in.collab-email orgSignals:
collab-email is sms-registration-ui (198 KB, last push Oct 28 2025 — 6+ months stale). The actual SMS send pipeline (where the $57K TCPA incident lives) is in a different org. Strategy P5.2.3 (TCPA guardrails) is a cross-org dependency.collab-email. The mc-omni-mcp + mc-omni-agent-ui repos are the integration surface, not the model. Strategy P4.1.1 (geo-ungate) is policy-cross-org-gated.@design-systems/* Intuit, @mcds/* Mailchimp, @ids-ts/* Intuit-TS) means three external teams gating component upgrades.Diagnostic question (per playbook): "How many teams need to coordinate for a single feature release?"
Mitigation: For the 3 cross-org Q1–Q5 dependencies (SMS pipeline, Canva integration, Write-with-AI policy), name a Senior PM-level escalation contact in the partner org now. Don’t wait for the dependency to slip.
Signals:
nuni-core ships FragmentBlockSchema.ts, v20260316 validation, full edit() command pattern. The primitive for Universal Content is done at the schema layer.nuni-core-ui consumes nuni-core@1.49.0 — locked to a version 25 minor releases behind. The UI doesn’t see the new primitives.nuni-core explicitly says: "We strongly recommend that you use the validation endpoints on Nuni API instead of directly depending on this library. This helps us minimize version drift across the ecosystem" — and the editor itself is the violator.Diagnostic question (per playbook): "What’s the definition of done? Who validates end-to-end experience?"
nuni-core ships a primitive; that’s done. nuni-core-ui hasn’t bumped to consume it; that’s a different team’s "done." The customer doesn’t see Universal Content until both sides ship.Mitigation: Q2 ship-readiness criterion = "schema lib and editor consumer are on aligned majors." Make the version bump a precondition, not a parallel track.
| Readiness dimension | Ready signal (per playbook) | Repo evidence | Verdict |
|---|---|---|---|
| Editor state structure | JSON block tree with typed nodes | nuni-core/src/document/types.ts defines Doc = Record<string, DocBlock> with typed nodes (id, type, parent, children, properties). operations.ts implements parent/child walks via findAncestorOfType(), getDescendants(). This is exactly the playbook’s "Ready Signal" definition. |
READY |
| Component semantics | Semantic block types with metadata | 31 typed block schemas: ButtonBlockSchema, ImageBlockSchema, TextBlockSchema, ColumnBlockSchema, EmailFooterBlockSchema, EmailImageGallerySectionBlockSchema, ProductBlockSchema, ProductRecsBlockSchema, PromoCodeBlockSchema, SocialFollowBlockSchema, SurveyButtonBlockSchema, VideoBlockSchema, FreddieBadgeBlockSchema, etc. Every block carries semantic type + Zod-validated property metadata. |
READY |
| Content modularity | Block-level CRUD operations | operations.ts exports addBlock, deleteBlock, updateProperties, moveBlock, duplicateBlock, moveToColumnPosition. Independent block-level CRUD. FragmentBlockSchema exists for cross-document blocks (Universal Content primitive). |
READY |
| Workflow observability | Event bus or action log exists | nuni-core/src/edit/log-collector.ts + edit/log/ directory. edit() returns an EditCandidate with logs. The action log is structurally present. Less clear is whether it’s emitted to a downstream bus (e.g. for AI training data) — but the structured log exists. |
READY |
| Machine-callable actions | Clean API or command pattern | edit/edit.ts header comment: "The single internal API for all document mutations. Pure function: (doc, edits, config) → EditCandidate. Zero React deps. Zero state. Zero side effects." Plus preValidate(), postValidate(), resolveEditTarget(). This is a textbook command pattern with pre/post hooks. An AI agent can call edit() directly without going through the UI. |
READY |
| Prompt / context access | Metadata accessible at edit time | Brand Kit lives in nuni-brand; document metadata in nuni-document-store; product catalog connectors are an integration surface. The EditConfig argument to edit() can carry context. mc-omni-mcp/agents_and_tools.yaml declares the tool registry. Brand Kit + audience + goal context can be assembled at the agent layer. |
READY |
| Safe state modification | Command pattern with undo stack | edit/types.ts: EditCandidate + EditResult + BlockValidationIssue; edit() takes validation: "strict" and mode: "transactional" options. document/intelligence.ts exports diff and snapshot (the undo-stack primitives). Pure functions + transactional mode = safe AI modification. |
READY |
The NUNI schema and edit layers are already more AI-ready than most code I’ve seen. Block-typed JSON tree + 31 semantic blocks + pure-function command-pattern edit() + transactional validation + structured action log = every "Ready Signal" the playbook checks for. Conversational journey editing in canvas (Strategy P4.2.1, Q5 ★) is technically achievable today. The blockers are not the code — they’re (1) the schema/UI version drift gating which schemas the AI can act on, (2) the agent-layer prompt + RAG context that connects Brand Kit + audience to the edit() call, (3) safety / brand-tone guardrails. None of those are 18-month builds; they’re 4–8 week scoped efforts.
| AI feature (Strategy memo P4 mapping) | Structural deps (per playbook) | Customer signal | Repo readiness | Estimated complexity |
|---|---|---|---|---|
| P4.1 Write with AI funnel recovery (geo-ungate + brand-tone fix) | Prompt access · brand metadata · safe state mod | HIGH · Health Crisis (Explore −73.7%, churn 77.2%) | READY at edit-API · Policy-gated at nuni-api routing | Medium — policy + routing, not a rebuild |
| P4.2.1 Conversational in-canvas editing | Machine-callable actions · component semantics · safe state mod · prompt/context | FLAGSHIP · Q5 ★ "Mailchimp is back, modern" moment | READY — every dep is in nuni-core | Medium — agent layer + UI sidebar + tool routing |
| P4.2.2 AI brand-style transfer between campaigns | Editor state structure · content modularity | LEAPFROG · No competitor ships this | READY at schema · UI work = mostly net-new | Medium-High — transfer-learning model + UI |
| P4.2.3 Prompt-first email mode (toggle) | Component semantics · machine-callable actions | EMERGING · Mailmodo wins SMB | READY — full primitive coverage | Medium — generation pipeline + scaffold UI |
| P4.3 Generative SMS in composer | Channel agnostic edit API · prompt access | HIGH · SMS +73.5% adoption / 53% churn | READY at nuni-core/channel/email + (planned) channel/sms | Medium — needs SMS channel in nuni-core |
| P4.4.1 AI image gen tied to product catalog | Prompt access · 300+ ecom integrations · Brand Kit | UNIQUE COMBO — only Mailchimp has all 4 inputs | Cross-product surface (catalog connectors) | High — model + catalog integration + UX |
| P4.4.4 In-canvas revenue per recipient (Klaviyo countermove) | Prompt access · workflow observability | Klaviyo capability gap closure | READY — log-collector + analytics tap | Low-Medium — analytics surface in editor |
| I-3.1.4 AI Email Setup Agent (URL → campaign in 3 clicks, Klaviyo Marketing Agent counter) | Prompt access · safe state mod · 260+ template registry | HIGH · Klaviyo Marketing Agent (Spring ’25 GA) parity | READY · nuni-template-sources is the corpus | Medium — orchestration + brand auto-extract |
Code blocker: Schema/UI version drift. The agent will call edit(doc, edits, config) on the library’s schema (1.74), but the editor renders against the UI’s pinned version (1.49). New primitives won’t round-trip until the bump lands.
Non-code blockers: Tool registry definition in mc-omni-mcp; conversational sidebar UX in nuni-core-ui; Brand-Kit-aware prompt template; eval harness for "did this AI edit produce a valid send?"
Code blocker: Geo-policy routing in nuni-api. Today the geo-gate is reportedly enforced UI-side (a Standard customer in NL doesn’t see the feature). Move the decision to the API layer to enable per-region rollout.
Non-code blockers: Intuit-level model availability + DPA/GDPR review for EU. This is the policy-cross-org dependency; technical work is < 2 weeks.
Code blocker: Add @tiptap/extension-collaboration + a CRDT (yjs is the natural choice for TipTap). Wire the existing pusher-js channel as the transport. Decompose store.ts (966 LOC) so presence + cursors don’t merge into the main edit reducer.
Non-code blockers: Pusher 4.x → 8.x upgrade likely needed for modern presence APIs. Cleanest engineering story in the FY27 roadmap.
edit/ module is a moatAcross the 5 active core repos analyzed, the most strategically valuable artifact is nuni-core/src/edit/edit.ts. Why:
preValidate runs before the mutation; postValidate runs after; "strict" mode rolls back invalid edits.This is not what most email-builder codebases look like. It’s what Klaviyo and Stensul are trying to build (their roadmaps reference "stable headless edit APIs" and "AI-callable block ops"). Mailchimp’s NUNI has it. The next 18 months are about exposing it correctly — through mc-omni-mcp as an MCP server, through a conversational sidebar, and through the schema bump in the editor. The capability is built; the productization is not.
Method: Each readiness dimension scored against the playbook’s §7.1 checklist using direct file reads from nuni-core/src/document/types.ts, nuni-core/src/document/operations.ts, nuni-core/src/edit/edit.ts, nuni-core/src/edit/types.ts, nuni-core/src/channel/email/schemas/ (31 schemas enumerated). Opportunity map cross-references Initiative Canvas P4 sub-pillar.
nuni-core/edit/edit.ts is a pure-function command-pattern API — "Pure function. Zero React deps. Zero state. Zero side effects." Klaviyo and Stensul are still trying to build this.pusher-js@4.3.1 + TipTap 3.20 (collab-ready) + command-pattern edit(). CRDT add is a 4-week PoC, not a rebuild.email-render-pipeline ships calibration + screenshot diff + scoring + golden-data PNG fixtures. Just unused in CI.v20260113, v20260225, v20260316); per-block migration paths in builder-platform/src/blocks/*/migrations/. Forward-compat is engineered.nuni-core, 137% on builder-platform. Substantive integration-flavored tests.nuni-core@1.74.5 vs nuni-core-ui consumes 1.49.0. The single architectural defect that gates Q2 Universal Content + Q5 unified canvas.nuni-core.store.ts god file. High-fan-in choke point for state, save, conflict, and presence. Gates Q5 collab story.react-intl@2.9 (current 7.x), styled-components@4.4 (6.x), Node 18 EOL April 2025, pusher-js@4 (current 8.x). The i18n stack alone gates the international Write with AI ungate.nuni-core-ui to nuni-core@^1.74 simultaneously enables Q2 Universal Content, Q5 unified email+SMS canvas, and Q6 fragment-graph governance.edit() as an MCP tool registry. Makes Mailchimp’s editor more AI-callable than Klaviyo’s. First-mover on conversational journey editing — Q5 ★ "Mailchimp is back" credibility moment becomes a 4–8 week effort.store.ts as the highest-leverage refactor. Unlocks HVC #4 multi-author save + HVC #5 block-ordering + Q5 real-time collab simultaneously.email-render-pipeline into nuni-core-ui CI. Cheapest L5 retention save in the brief — closes HVC #3 ($1,820/mo cited) regression pattern with infrastructure already 70% built.edit() in place. Cleanest engineering story in the FY27 roadmap.sprioleau + ccovell carry top-3 commit share on 3 of 4 critical surfaces. FY27 commit dependent on continuity.mc-omni-agent-ui ≈ 691 commits/6mo vs nuni-core-ui ≈ 83. Strategy Memo’s "AI cannot compensate for broken editor trust" is being violated structurally.nuni-core uses any React-19-only API (e.g. use(), async transitions), the editor breaks unless it bumps too.nuni-core-ui/package.json still pins "node": ">= 18.0.0 < 19.0.0". Will break under future security patches.10 standard architecture quality attributes scored 1–5 against repo evidence. Aggregate 3.0/5 hides the bimodal split: library/platform layers score 4–5; the customer-facing editor UI scores 1–3.
| Attribute | Score | Visualization | Repo evidence |
|---|---|---|---|
| Modularity | 4 / 5 | nuni-core splits into document/, edit/, render/, renderers/, channel/, validate/; builder-platform per-block renderers/migrations/. | |
| AI readiness | 5 / 5 | 7/7 playbook signals. Pure-function edit() + 31 semantic blocks + transactional validation + structured action log. | |
| Time-to-market for new blocks | 4 / 5 | Block schema + per-block migration pattern is established; new schema versions ship every ~6 weeks. | |
| Testability | 3 / 5 | Library/platform 111–137%; editor UI 16.7%. Bimodal — score reflects the gap. | |
| Observability | 3 / 5 | @bugsnag/js + @bugsnag/browser-performance + @bugsnag/plugin-react integrated. Single-vendor; no Datadog RUM. | |
| Security posture | 3 / 5 | Renovate active; eslint-plugin-no-secrets enabled; Node 18 EOL near; 3 design systems = 3 supply-chain surfaces. | |
| Reliability gates | 2 / 5 | No E2E on a visual builder; vis-reg rig built but unwired; 16.7% test ratio on the customer surface. | |
| Maintainability | 2 / 5 | 3 React versions; 25-version schema drift; god-class store.ts; 3 design systems. | |
| Dependency currency | 2 / 5 | react-intl 5 majors behind; styled-components 2 majors behind; Pusher 4 majors behind; Node 18 EOL. | |
| Cost / op complexity | 2 / 5 | 6 languages in the org (TS, JS, Kotlin, Java, Go, Python); migration tooling alone is 3 runtimes. | |
| Aggregate | 3.0 / 5 | Library/edit-API layer scores 4–5 (strategic asset). Customer-facing UI layer scores 1–3 (consumer-side debt). The gap is the architectural defect. | |
Method: SWOT framework + ISO/IEC 25010 software-quality attributes scored against the same repo evidence used in the 7-Layer Forensic and AI Readiness tabs. Each score is reproducible from the queries in Method & Sources.
The Editor Brief documents $95K/mo in cited HVC MRR across 17 themes, 7 VoC hate themes, bulk-email Established users −9.4% YoY, and Write with AI Explore funnel collapsed −73.7% YoY. The customer pain decomposes into three categories: trust (NEB rendering bugs, multi-author save conflicts, Brand Kit reliability), competitiveness (Klaviyo Spring ’26 Universal Content, no real-time co-edit, geo-gated AI), and unification (NEB+Classic split, email+SMS surface split). The Strategy Memo commits the editor to +$25–30M FY27 ARR via 5 customer-benefit pillars over 6 quarters; mid scenario worked at ~$26.2M. Every Q1–Q5 commitment in the strategy is achievable on the foundation that exists today; timing is at risk because the consumer surface is undermaintained relative to the library.
nuni-core’s pure-function edit() is a moat; nuni-core-ui is the bottleneck. The 25-version drift is the architectural symbol of this — engineering investment is concentrated where it should be (the schema), but customer experience lives where it shouldn’t (the consumer surface).nuni-core-ui not consuming current schema lib. One fix → three story closures.nuni-core-ui to nuni-core@^1.74Single highest-leverage action in the brief. Unblocks Universal Content (Q2), shared blocks (Q5), and removes the structural cause of 3 of 7 VoC hate themes. Estimate: 4–6 week spike + regression sweep. Cost: low. Strategic value: highest.
nuni-core-ui CICheapest L5 retention save. email-render-pipeline’s calibration + screenshot diff + scoring infrastructure is 70% built. Closes HVC #3 ($1,820/mo cited) regression pattern. Estimate: 2-week spike + ramp.
store.ts (966 LOC)Critical-path refactor. Unblocks HVC #4 multi-author save fix + HVC #5 block-ordering fix + Q5 real-time collab moment. Decompose into presence + edit reducer + persistence; lay foundation for CRDT integration.
edit()Validates Strategy Memo Q5 ★ credibility moment. Expose edit(doc, edits, config) via mc-omni-mcp as an MCP tool; agent UI sends "make the hero block 20% smaller in a friendlier tone." Output: feasibility report + safety incident count.
Bus-factor mitigation. Pair sprioleau, ccovell, jhunsucker, and smoore16 with a designated co-owner on the next two PRs. Rotate one Q1 ship lead away from the hero pool. Cost: zero. Insurance value: highest non-technical lever in the brief.
The NUNI architecture is a story of two halves. The schema and edit-API layer is among the best automation/editor primitives in the SMB tier — modular, AI-ready, command-pattern, version-disciplined. The customer-facing UI layer is on stale React, undertested, version-drifted, hero-dependent. The FY27 +$25–30M commit is achievable because the foundation is right; the timing is at risk because the consumer surface is undermaintained. The single most important architectural action for Mailchimp leadership is closing the 25-version schema drift — every other Q1–Q5 strategy bet either depends on it directly or is made cheaper by it. Everything else flows from there.
Cross-references: Executive Summary for the 6 headline findings · Pain → Code Map for HVC theme → repo traceability · 7-Layer Forensic for evidence detail · AI Readiness for the 7/7 scorecard · Leverage Cheat Sheet for engineering-sync questions · Method & Sources for reproducibility.
nuni-core is at v1.74.5 with FragmentBlockSchema already shipped, but nuni-core-ui consumes @collab-email/nuni-core@1.49.0 — a 25-version-old pin. What’s the plan to bump the schema lib in the editor before Q2? Is there a known incompatibility, or is the team scope-blocked on a regression sweep?"nuni-core-ui already declares pusher-js@4.3.1 as a top-level dep, and TipTap 3.20 supports @tiptap/extension-collaboration + yjs natively. The edit() command pattern in nuni-core/edit/edit.ts is pure-function and would round-trip through CRDT. What does a 4-week PoC look like — wiring the existing Pusher channel as transport for collab cursors and presence, decomposing the 966-LOC store.ts so presence doesn’t merge with the edit reducer?"email-render-pipeline ships a calibration + screenshot + scoring rig with PNG fixture sets and a generate.ts for golden data. It’s gated by 2 unit tests and isn’t wired into the nuni-core-ui CI gate. The HVC #3 rendering theme cites $1,820/mo across 4 named accounts — these are the exact regressions the rig was built for. What’s blocking us from making the visual-regression rig a CI requirement on nuni-core-ui?"edit/edit.ts module is documented as ‘Pure function. Zero React deps. Zero state. Zero side effects.’ with pre/post validation and transactional mode. nuni-core defines 31 semantic block schemas. The document/operations.ts CRUD primitives are already block-level. What’s blocking us from exposing edit() through mc-omni-mcp as the MCP server’s primary tool? Is the agent-side blocker prompt design, brand-context retrieval, or eval harness?"nuni-core-ui test ratio is 16.7% vs 111% / 137% on the library and platform layers. Can we size a quarterly cleanup sprint and tie each item to the customer bug it would prevent — e.g. styled-components 4 → 6 for bundle size, react-intl 2 → 7 for the international Write with AI ungate?"mc-omni-agent-ui shipped ~691 commits in the last 6 months across 4 active engineers; nuni-core-ui shipped ~83 across 2. The Strategy memo’s Guiding Principle #2 says ‘AI cannot compensate for broken editor trust.’ Are we shipping in the right priority order, given the cited HVC bug exposure on the editor side? What does a balanced 60/25/10/5 portfolio look like (per the playbook §6.2) for the next two quarters?"amilt) closed the HVC #8 Brand Kit incident with a 50% ramp; the same engineer is now top-3 contributor in mc-omni-mcp. What’s the on-call rotation that means HVC #8 doesn’t recur when Austin is heads-down on the agent backend? Where is the regression test that prevents the ‘stale Brand Kit / no colors’ pattern from coming back?"Per playbook §6.2, the 60 / 25 / 10 / 5 split. Applied to the NUNI roadmap as documented in the Initiative Canvas:
| Allocation | NUNI-specific work for Q1 (May–Jul ’26) | Success metric |
|---|---|---|
| 60% · Customer-facing | HVC #3 rendering parity (4 cited accts) · HVC #8 Brand Kit incident closure (P1.2.1) · HVC #13 Canva sync (P1.3.1) · HVC #16 SMS TCPA $57K (P5.2.3, cross-org) · HVC #4/#5 (P1.1.2/3) | Cited HVC MRR cleared this quarter; bulk churn 40.0% → 38.5% leading indicator |
| 25% · Tech debt payoff | Bump nuni-core-ui from nuni-core@1.49 → @^1.74 (Q2 ship gate) · Decompose store.ts (966 LOC) into presence + edit reducer + persistence · Wire email-render-pipeline into nuni-core-ui CI | Editor test/source ratio 17% → 35%; Q2 Universal Content ship is on its critical path |
| 10% · Strategic AI | P4.1.1 Write with AI policy track (geo-ungate scope) · P4.2.1 conversational sidebar PoC against edit() · MCP tool registry definition in mc-omni-mcp | Spike report on conversational AI feasibility delivered Q1; Q4 ungate decision unblocked |
| 5% · Exploration | Feature-flag harness audit (does it exist editor-side or only API-side?) · Pusher 4 → 8 upgrade spike for collab readiness · Node 18 → 20 migration scoping | Decision document: editor-layer flag harness yes/no; if no, scope a Q2 spike |
Spike 1 · 2-week schema bump dry-run. "Can we run a 2-week PoC to validate whether bumping nuni-core-ui from @collab-email/nuni-core@1.49.0 to @^1.74 breaks the editor on the top-3 customer journeys (campaign create, save, send)? Output: pass/fail + regression list."
Spike 2 · 2-week conversational AI PoC. "Can we run a 2-week PoC where mc-omni-mcp exposes edit() as a tool, the agent UI sends ‘Make the hero block 20% smaller, in a friendlier tone’, and we measure round-trip time + edit validity rate against the existing postValidate pipeline? Output: feasibility report + safety incident count."
Spike 3 · 2-week visual-regression CI integration. "Can we run a 2-week PoC wiring email-render-pipeline’s screenshot/calibration/scoring rig into nuni-core-ui CI, with the HVC #3 cited customer email patterns as the golden data set? Output: regression-rate baseline + ship/no-ship gate proposal."
github.intuit.com/collab-email as of May 13 2026.Product Technical Intelligence Playbook — May 2026, 20-page internal reference. Specifically used:
nuni-core-ui and nuni-core/src/document/.GH_HOST=github.intuit.com gh api orgs/collab-email/repos --paginate \ -q '.[] | "\(.name)|\(.language // "N/A")|\(.size)|\(.pushed_at)|\(.archived)|\(.default_branch)"' # 62 repos returned
for repo in nuni-core nuni-core-ui builder-platform nuni-api email-render-pipeline \
html-to-nuni-parser nuni-document-store emails-nuni-editor; do
GH_HOST=github.intuit.com gh api repos/collab-email/$repo --jq \
'{name, language, size, pushed_at, default_branch, open_issues_count, forks, watchers_count, subscribers_count}'
done
for repo in nuni-core nuni-core-ui builder-platform nuni-api email-render-pipeline \
html-to-nuni-parser nuni-document-store emails-nuni-editor; do
GH_HOST=github.intuit.com gh repo clone collab-email/$repo $repo -- --depth=1 --quiet
done
find $repo/src -type f \( -name "*.ts" -o -name "*.tsx" -o -name "*.js" -o -name "*.jsx" \) \
-exec wc -l {} \; | awk '$1 >= 600' | sort -rn | head -25
src_loc=$(find $repo/src -type f \( -name "*.ts" -o -name "*.tsx" \) \
! -name "*.test.*" ! -name "*.spec.*" -exec cat {} \; | wc -l)
test_loc=$(find $repo -type f \( -name "*.test.ts" -o -name "*.test.tsx" -o -name "*.spec.ts" \) \
-exec cat {} \; | wc -l)
echo "$repo: src=$src_loc test=$test_loc ratio=$((test_loc * 100 / src_loc))%"
GH_HOST=github.intuit.com gh api \ "repos/collab-email/$repo/commits?since=2025-05-01T00:00:00Z&per_page=100" --paginate \ -q '.[].author.login // .[].commit.author.name // "unknown"' | sort | uniq -c | sort -rn | head -8
GH_HOST=github.intuit.com gh api "repos/collab-email/$repo/pulls?state=closed&per_page=30" \ | python3 -c "import json,sys,datetime; ..." # see exec script for median + p95
| Type | Source | Used for |
|---|---|---|
| Framework | Product Technical Intelligence Playbook (Deepak — Product Management; May 2026 internal reference; 20 pages) | Every section’s structural framework |
| Customer evidence | Mailchimp Email/SMS Unified Editor & Builder Brief — 11 tabs (Executive, VOC, Klaviyo Brief, Klaviyo VoC, HVC Risk, User Research, Product Health, Growth Model, Loss Attribution, Initiative Canvas, Strategy Memo) | VOC themes, HVC cited MRR, UR bets, BigQuery health metrics, FY27 commit math |
| Repo data | github.intuit.com/collab-email/* via gh api + shallow clones | All numerical findings: file LOC, dep versions, test ratios, contributor counts, PR cycle times |
| Architecture diagram | User-supplied image (Mailchimp New Builder (NUNI), dated May 13 2026, 9 functional layers) | Reality-vs-diagram reconciliation in Repo Map tab |
collab-email.Per the playbook’s "Continuous Intelligence" mode (§9 timeline, "Ongoing"): this analysis should be re-run quarterly. Suggested cadence:
edit().
Confidentiality. The repo-level findings in this analysis are derived from github.intuit.com/collab-email/*, accessible to authorized Intuit employees. The Product Technical Intelligence Playbook is marked CONFIDENTIAL — Internal Reference Only. The customer-evidence sources (HVC, VOC, BigQuery) are summarized in the public-to-this-domain Editor Brief; named-customer MRR figures are cited only at theme-aggregate level. This brief is intended for executive review within the Mailchimp authoring-surface leadership audience; it should not be shared externally without redaction of the github.intuit.com URLs and named-engineer references.