Spec map

🎯 Goals

Core Architectural Idea

  • Render Contacts as a curated, non-duplicating view over the UVP rather than a parallel data store. VRM Verified
  • Surface a system-computed data-quality tier that distinguishes high-confidence contacts as the account’s actionable inventory. Dashboard
  • Give the user a politically-tailored intelligence brief on the size, growth, and composition of their list. All Contacts
  • Provide a fast, customizable, searchable contact table with subscription-aware quick and bulk actions. Contact Card
  • Present a universal UVP detail surface with layer-appropriate edit modes and a unified activity history. Tribes
  • Provide manual static and dynamic list grouping over UVPs that is reusable across modes. Import
  • Ingest CSV/Excel with AI-assisted mapping, identity-match configuration, adjudication, and reversible auditing. Fields
  • Let the account manage its custom field namespace and reference the locked global schema safely. Activity
  • Provide a filterable chronological audit feed of all contact-related events for team oversight. Duplicates
  • Surface and adjudicate likely-duplicate UVPs with a non-destructive, reversible merge workflow. Permissions
  • Apply role-based access with destructive operations gated to Admin. UVP Provenance
  • Provenance every contact change non-destructively to keep Contacts a defensible record system. Integrations Roadmap
  • Provide native and later integrated call/text/email actions that enforce channel compliance.

Mode: Relationship Mode Status: Conceptual Spec — V1 Scope Definition Companion specs: vrm-data-system (UVP, layers, field system, two-tier architecture), vrm-forms (capture inputs to Contacts), vrm-surveys (engagement inputs to Contacts), vrm-cta (acquisition inputs to Contacts), vrm-polling-engine (Campaign-Mode cousin of Tribes), politogy-vrm-brand


1. What This Product Is

Contacts is the day-to-day workbench of Relationship Mode. It is where the user actually interacts with the people in their UVP database — adds them, finds them, edits them, calls them, groups them, imports them, and manages the fields that describe them. Every other feature in Relationship Mode (Forms, Surveys, CTAs) is an input pipeline that flows into Contacts. Every output (an email campaign, a phone bank, a petition push) starts from a list built in Contacts.

Contacts is not a parallel data system. A “contact” in Relationship Mode is a Politogy Unified Voter Profile (UVP) that has been claimed by the account through an opt-in event — a Form submission, a Survey response, a CTA conversion, a manual entry, or a CSV import. Same UVP, customer-tier view. The Contacts feature is the curated lens onto the UVP architecture defined in vrm-data-system.

Product thesis: The user opens VRM in the morning and lands on Contacts. They see what’s new (opt-ins overnight), what’s known (aggregate demographic intelligence), and what needs attention (duplicates, unresolved imports, fresh leads). They click into a contact card and see everything the platform knows about that person across nine data layers — voter file truth, customer-tier truth, AI-derived signals — all in one surface, with the permissions and exposure rules quietly enforced. They take action. They send a text. They build a list. They get back to it.

Contacts is the surface that makes the UVP feel like a workbench rather than a database.


2. Mode Architecture

Contacts lives in Relationship Mode, which means the audience is opt-in (customer-claimed UVPs) rather than the full state voter file. Campaign Mode has its own analogous surface that operates over the voter file directly. The two surfaces share infrastructure, but the audience scope is fundamentally different.

ModeAudience Visible in ContactsSource of Audience
Relationship ModeOpt-in contacts the account has claimedForms, Surveys, CTAs, manual entry, CSV import
Campaign ModeVoter-roll universe within assigned geography (separate surface)State voter file
Petition ModeSigners + eligible voters in petition scopePetition Mode + Campaign Mode

This spec covers the Relationship Mode Contacts surface. Where Campaign Mode would render the same UVPs, it does so through a different feature called Voters (a separate spec).


3. The Core Architectural Idea — Contacts Is a View, Not a Table

A contact is a UVP with an account_claim relationship to the customer’s account. The claim is created at first contact (Form submitted, Survey responded to, CTA converted, manual add, etc.) and persists indefinitely.

The claim carries metadata:

  • Claim source: Form ID / Survey ID / CTA ID / “manual” / “csv_import” / “merge”
  • Claim date: When the UVP entered the account’s Contacts
  • Claim consent record: What consent was captured at claim time
  • Opt-in status per channel: Email subscribed?, SMS opted-in?, etc., each with timestamp + source

The customer-tier UI (“Contacts”) shows only UVPs the account has claimed. The underlying UVP record continues to exist in Politogy’s master database regardless of whether any account has claimed it. Voter-file UVPs may be claimed by multiple accounts (Politogy retains the full picture; each account sees only its own Relationship Data layer on that UVP). Relationship-Sourced UVPs (created via a Form/Survey/CTA submission) are claimed by the originating account at creation and may be later claimed by other accounts through their own opt-in events.

This is the rule that keeps Contacts honest: never duplicate UVP data. Always render through the UVP. The Contacts feature is a window into the data system, not a parallel store.


4. VRM Verified — The Data Quality Tier

Not every contact is created equal. VRM Verified is a designation that distinguishes high-confidence, fully-validated UVPs from raw or partially-known ones. It is a first-class signal on every contact and a key Dashboard metric.

4.1 Verification Tiers

TierCriteriaVisual Indicator
VRM VerifiedVoter-file match + explicit consent record + at least one confirmed contact channel (verified email or phone) + recent engagement (response within 12 months)Green checkmark badge
IdentifiedAt least one identifying field captured (name + email OR phone) but voter-file match incomplete or staleBlue dot
AnonymousSubmitted via a Form/Survey/CTA without identity capture, OR Visitor-ID-only with no UVP merge yetGray dot
StaleWas VRM Verified but no engagement in 18+ months; contact details may be outdatedYellow caution
InactiveVoter file marks as inactive/canceled, OR explicit opt-out across all channelsRed

4.2 Why It Matters

VRM Verified contacts are the asset. They are the validated, deliverable, addressable audience the account can rely on. Aggregate Verified counts are the headline Dashboard metric because Verified count is the practical inventory available for outreach.

The verification status is computed continuously by Politogy and pushed to the contact view in real time. The user does not manually mark a contact as Verified — the system does, based on evidence. This is intentional. Customer-driven verification creates a tagging system; system-driven verification creates a defensible data product.

4.3 Purchased VRM Verified Data

When an account purchases enrichment for a contact (or for a list), additional voter-file and third-party fields populate against the UVP. This is the Politogy-tier Enrichment layer (see vrm-data-system §3.3). The Contact Card surfaces “Verified data available — unlock” prompts where the contact has Enrichment fields gated by tier. Click to unlock at a per-contact or per-list cost, depending on the account’s pricing structure.


5. The Seven-Tab UI

Ben specified five tabs. Two additions are recommended for completeness and surface here as Tab 6 (Activity) and Tab 7 (Duplicates). The final layout:

#TabPurpose
1DashboardAccount-level intelligence and aggregate stats
2All ContactsThe contact table with search, sort, customizable columns, quick actions, Contact Card drill-in
3TribesList/group management; V1 manual + V2 AI-powered automated grouping
4ImportCSV / Excel import with AI-assisted field mapping and adjudication
5FieldsCustom field management; global field reference; field merging
6Activity (suggested)Chronological activity feed across all contact-related events
7Duplicates (suggested)Detected likely-duplicate UVPs with one-click merge adjudication

Each tab is detailed in the following sections.


6. Tab 1 — Dashboard

The Dashboard is politically-aware analytics, not generic CRM dashboard fluff. It exists to answer the three questions a campaign manager asks every morning: “How big is my list? How is it growing? What does it look like?“

6.1 Headline Strip (always visible at top)

Six metric cards in a row:

  1. Total Contacts — current count, with delta vs. last 7 days
  2. VRM Verified Contacts — count + percentage of total
  3. New Opt-Ins (7d) — count + source breakdown (Forms / Surveys / CTAs / Manual / Import)
  4. Active Subscribers (Email) — count + percentage of Verified
  5. SMS Opt-Ins — count + percentage of total
  6. Unresolved Items — count of pending imports + duplicate adjudications + unreviewed Form submissions (clickable, routes to the relevant tab)

These six metrics are the heartbeat. They tell the user the state of their list in one glance.

6.2 Demographic & Political Intelligence Panel

A panel showing aggregate demographic intelligence derived from the account’s contacts. Tailored to political work — this is not a generic e-commerce dashboard.

  • Party Affiliation Breakdown — donut chart: REP / DEM / IND / LBT / GRN / OTH / NAV / Unknown
  • Registration Status — bar: ACTIVE / INACTIVE / SUSPENDED / CANCELED / Not Matched
  • Geographic Concentration:
    • Top 10 Cities (with count)
    • Top 10 Counties (with count)
    • State breakdown (sparkline for accounts with multi-state contacts)
    • Top 10 Precincts (for hyper-local campaigns)
    • Top 10 Legislative Districts (state house, state senate, congressional)
  • Vote History Summary — % of contacts who voted in last general, last primary, midterm, off-cycle
  • Age Cohort Breakdown — 18-24 / 25-34 / 35-49 / 50-64 / 65+ / Unknown

All charts are clickable — clicking the “REP” slice filters All Contacts to Republican contacts and switches to Tab 2.

6.3 Issue & Survey Intelligence Panel

This panel pulls from the account’s Forms, Surveys, and CTAs to surface custom-data themes:

  • Top Issues — derived from Survey responses, custom field values, and CTA engagement (e.g., “Election integrity: 1,247 contacts,” “2A: 894 contacts,” “Property tax cuts: 612 contacts”)
  • Top Survey Responses — recent Survey results headline panel (e.g., “Latest ‘Issue Pulse’ Survey: 78% want property tax cap”)
  • Top Petition Signers — for accounts with Petition Mode, top petitions by signer count among Contacts (e.g., “IP37: 1,134 signers in your contacts”)
  • Form Conversion Leaderboard — top 3 Forms by submission count in the last 30 days
  • CTA Conversion Leaderboard — top 3 CTAs by conversion rate in the last 30 days

These panels make the Dashboard feel like a politically-tailored intelligence brief, not a generic widget grid. The account’s own data tells them what their list cares about.

6.4 Growth Velocity Chart

A time-series chart showing contact growth over time, with overlays for source breakdown (Forms / Surveys / CTAs / Manual / Import). Daily / weekly / monthly views. This is where the user sees if their acquisition efforts are working.

6.5 Quick Actions Strip

Persistent action shortcuts at the top-right:

  • + Add Contact (manual single-contact entry, opens a modal)
  • Import (jumps to Tab 4)
  • Build Tribe (jumps to Tab 3 with new-tribe modal open)
  • Export (exports current full Contacts list as CSV, respecting exposure rules)

6.6 Tailored Dashboard for Account Context

The Dashboard’s panel composition adapts to the account’s context:

  • Accounts with active Petition Mode see a Petition Signers panel.
  • Accounts with heavy CTA usage see the CTA Conversion Leaderboard prominently.
  • Accounts that have never run a Survey see a contextual prompt: “You haven’t run a Survey yet. Surveys help you learn what your list cares about.” (Linked to the Surveys feature.)
  • Accounts with stale lists (no new opt-ins in 30+ days) see a “Your list isn’t growing — try a CTA” prompt. (Linked to the CTA feature.)

This is the “platform that knows you” experience that makes Relationship Mode feel intelligent rather than just functional.


7. Tab 2 — All Contacts

The contact table. This is where the user spends most of their time.

7.1 The Table

A virtualized, scrollable table rendering one row per contact. Sub-second performance up to 1M+ contacts (virtualization + indexed query layer).

Default visible columns (customizable per user):

  • Verification status badge
  • Full Name
  • Email
  • Mobile Phone
  • Party
  • City
  • Subscription Status (icons per channel: Email ✓ / SMS ✓ / etc.)
  • Last Engagement Date
  • Source (where they came from: Form / Survey / CTA / Manual / Import)
  • Quick Actions (Call, Text, View Card)

7.2 Column Customization

The user can:

  • Add or remove columns from the visible set
  • Reorder columns by drag
  • Save column configurations as named views (e.g., “My Outreach View” / “My Donor View”)
  • Switch between saved views via a dropdown

Available columns include any global UVP field exposed to Relationship Mode AND any custom field the account has defined. Per-user preferences persist; per-account default view is set by Admin.

A universal search bar at the top of the table:

  • Searches Name (fuzzy), Email (exact + partial), Phone (E.164 normalized matching), Voter ID (exact), and any text custom field
  • Returns results in <500ms against full account
  • Search history persisted per user
  • Saved searches available with a star/save icon → joins the user’s saved views

7.4 Filters

A filter bar above the table. Filters stack with AND. Multiple values within a filter stack with OR.

V1 filter dimensions:

  • Verification Tier (Verified / Identified / Anonymous / Stale / Inactive)
  • Party
  • Registration Status
  • Geographic (state / county / city / precinct / district)
  • Vote History (voted in last X election: yes/no)
  • Subscription Status per channel
  • Source (which Form / Survey / CTA / Import batch)
  • Tribes (membership in a specific Tribe)
  • Custom Field Value (any custom field, any value)
  • Date Range (claim date, last engagement, last edit)
  • Age Range
  • Has Email / Has Phone / Has Address (boolean presence checks)
  • Tags

Filters can be saved as a Tribe in one click (see Section 8.3).

7.5 Sort

Sortable on any column. Multi-column sort (shift-click to add) for power users.

7.6 Quick Actions (Per Row)

Inline buttons on each row:

  • Call — opens native dialer with the contact’s primary phone (V1); routes to integrated CTI in V1.5
  • Text — opens native messaging app with the contact’s primary phone, optionally pre-populated with an account-default template (V1); routes to integrated SMS gateway in V1.5
  • Email — opens default mail client with the contact’s primary email (V1); routes to integrated email sender in V1.5
  • View Card — opens the Contact Card (see Section 9)

Quick actions respect subscription status — if a contact has opted out of SMS, the Text button is disabled with a tooltip explaining why. This prevents accidental TCPA violations.

7.7 Bulk Actions

Multi-select via checkboxes (or “select all” on filtered view). Bulk actions:

  • Add to Tribe
  • Remove from Tribe
  • Apply Tag
  • Remove Tag
  • Bulk Edit (specific fields only — see safety rules below)
  • Bulk Export (filtered selection to CSV)
  • Bulk Delete (Admin only; archives, doesn’t hard-delete UVPs — see §11.5)
  • Bulk Merge (only when exactly 2 selected and they appear to be duplicates; routes to Duplicates tab)

Bulk edit safety rules:

  • Cannot bulk-edit Identity Core fields (voter file truth, read-only at customer tier)
  • Cannot bulk-edit Vote History (system-derived)
  • CAN bulk-edit Relationship Data (tags, notes, subscription, custom fields)
  • Bulk edits create an audit log entry with the user, timestamp, count of affected records, and field changes

7.8 Row Density

Three density modes: Compact / Standard / Expanded. Compact = email-style dense list. Standard = balanced. Expanded = shows avatar + secondary metadata inline.


8. The Contact Card

The Contact Card is the universal UVP detail surface. Opens as a slide-in panel from the right (modal on mobile) when the user clicks a row in All Contacts (or anywhere a contact reference appears).

8.1 Card Structure

The card is organized into stacked sections that mirror the UVP’s nine data layers, filtered by what’s exposed at this account’s tier.

Top Strip (always visible):

  • Avatar (if available)
  • Name + Preferred Name
  • Verification badge
  • Party + registration status pill
  • Primary phone + email with quick action icons (Call, Text, Email, Copy)
  • “Last engaged: X days ago” indicator

Tabs within the Card (sub-navigation):

TabContent
OverviewIdentity Core + Contact Info + Geographic in one consolidated view
Vote HistoryVoted-in elections table with method (mail/in-person/drop-off)
EngagementActivity timeline — every Form submission, Survey response, CTA conversion, contact event, note, etc., chronological
RelationshipAccount-specific data: tags, notes, custom field values, contact log entries, Tribe memberships, subscription status per channel
Web BehaviorThe web_engagement_profile from CTAs (page visits, dismissed CTAs, referrer chains) — visible if the account uses CTAs
PetitionsSignatures on Petition Mode petitions, if any
Verified DataPolitogy-Tier Enrichment fields available for unlock at this account’s tier; or unlocked already-Verified data

8.2 Edit Modes Per Layer

Identity Core, Vote History, Geographic = read-only (voter file truth, system-derived).

Contact Info = editable inline. User edits become the primary value; voter file value demotes to alternate (per UVP priority rules in vrm-data-system §2.2). All edits audit-logged with user + timestamp.

Relationship Data (tags, notes, contact log, custom fields, subscription) = fully editable. The account owns this data on this UVP.

Enrichment = read-only display when unlocked; tier-gated lock prompt when not.

8.3 The Activity Timeline

Within the Engagement tab, every event involving this UVP renders chronologically:

  • “Submitted Form ‘Volunteer Signup’ — May 12, 2026”
  • “Opted into SMS via CTA ‘Election Integrity Banner’ — May 8, 2026”
  • “Tagged ‘Donor’ by Sarah Chen — Apr 22, 2026”
  • “Responded to Survey ‘Issue Pulse Q1’ — Apr 10, 2026”
  • “Voted in 2024 General Election (mail-in) — Nov 5, 2024” (from voter file)
  • “Signed petition IP37 — Mar 4, 2026”

The timeline is a unified history surface that makes the Contact Card feel like a real CRM, not just a record viewer. Filterable by event type.

8.4 Contact Log Entries

Within the Relationship tab, the account can record contact attempts and outcomes:

  • “Called — left voicemail” — Mar 12
  • “Texted re: rally invite — responded yes” — Mar 10
  • “Door knocked — not home” — Mar 6 (from Campaign Mode canvassing, if the contact is also a Campaign Mode voter)

Contact log is shared with Campaign Mode where applicable. A door-knock logged in Campaign Mode appears here. A phone call logged in Phone Banking appears here. One UVP, one history.

8.5 Custom Fields on the Card

All custom fields the account has on this contact render in the Relationship tab. Empty custom fields are visible-but-empty (with a placeholder) so the user can populate inline. Custom fields with data are inline-editable. The user CAN add a value to a custom field directly on the Contact Card — they don’t have to use a Form to enter custom-field data.

8.6 Quick Actions on the Card

Top-right action menu:

  • Edit Mode (toggle for editing inline)
  • Add to Tribe
  • Apply Tag
  • Log a Contact (call/text/email/note)
  • Send SMS (V1.5)
  • Open in Campaign Mode (if account has Campaign Mode and the UVP is also a voter)
  • Merge with Duplicate (if duplicates detected)
  • Archive (soft-archive only; UVP retained)
  • Print / Export

9. Tab 3 — Tribes (Lists / Groups)

Tribes is the list-management feature in Relationship Mode. In V1 it ships as a manual list builder. In V2 it becomes AI-powered automated grouping. This spec defines V1 with the data structure designed to support V2.

9.1 What a Tribe Is

A Tribe is a named, query-defined or membership-defined set of contacts. There are two kinds:

TypeMembership RuleEditability
Static TribeExplicit list of UVP IDsAdd/remove members manually
Dynamic TribeA saved filter against UVP fieldsMembership recomputed continuously; cannot manually add/remove

A Dynamic Tribe is the equivalent of a Smart Playlist. Define the filter once, membership stays current.

9.2 V1 Tribe Capabilities

Creating a Tribe:

  • From the All Contacts tab: select filtered set or manual selection → “Save as Tribe” → name it → choose Static or Dynamic
  • From the Tribes tab: ”+ New Tribe” → filter-builder modal → save as Dynamic
  • From the Contact Card: “Add to Tribe” → pick existing or create new

Tribes tab UI:

  • Table of Tribes with: name, type (Static / Dynamic), member count, creator, last modified, action menu
  • Click a Tribe → opens its contact list (essentially All Contacts pre-filtered to the Tribe’s membership)
  • Bulk-action a Tribe (export, message, add to other Tribe)
  • Edit, rename, archive, delete

Pre-built suggested Tribes (account-creation defaults):

  • “All Verified Contacts” (Dynamic, recomputed)
  • “Email Subscribers” (Dynamic)
  • “SMS Opt-Ins” (Dynamic)
  • “New This Month” (Dynamic, rolling 30 days)
  • “Volunteers” (Dynamic, filter on volunteer tag or custom field)
  • “Donors” (Dynamic, filter on donor tag or custom field)

9.3 V2 — AI-Powered Automated Tribes

This is the future-feature Ben described. The system uses AI to surface contact clusters based on what they have in common across the UVP and the account’s data:

  • “These 247 contacts all signed IP37 and have opted into SMS — call them ‘Election Security Activists’?”
  • “These 89 contacts donated AND attended the April rally AND opened the last 3 emails — call them ‘High-Engagement Donors’?”
  • “These 412 contacts live in House District 37 AND voted in the 2024 primary — call them ‘HD37 Primary Voters’?”

The AI engine clusters across:

  • Voter file dimensions (party, district, vote history, age)
  • Engagement signals (Form/Survey/CTA participation)
  • Petition Mode signatures (powerful issue signal — signing IP37 = election-security voter)
  • Survey responses (issue interests, support levels)
  • Custom fields (whatever the account has populated)
  • Behavioral data (web_engagement_profile from CTAs)

The V2 architecture:

  • AI surfaces candidate Tribes in a “Suggested Tribes” panel
  • User reviews, approves, names → it becomes a Dynamic Tribe with auto-generated membership criteria
  • Politogy’s Aggregate Intelligence model improves over time as more accounts use Tribes — the AI learns what clusters tend to be valuable

Why V2 not V1: The clustering model requires training data and tuning that can’t be done before V1 ships. V1 launches with manual Tribes; the data is being captured from day one (Tribe membership history, naming patterns, filter combinations) to fuel V2 development.

9.4 Tribes Across Modes

A Tribe defined in Relationship Mode is a set of UVPs, which means it can also be used in Campaign Mode (if the account has it) and Petition Mode. A Tribe of “Election Security Activists” defined in Relationship Mode can be a Phone Banking audience in Campaign Mode without rebuilding.

This is the cross-mode payoff. Tribes are not a Relationship Mode silo; they are an account-scoped UVP grouping that any mode can consume.


10. Tab 4 — Import

CSV / Excel import with AI-assisted field mapping. This is the second-most-architecturally-interesting tab after Fields.

10.1 The Import Flow

  1. Upload — User drops a .csv, .xlsx, or .tsv file. Max 50,000 rows in V1 (larger files in V1.5 with chunked processing).
  2. Parse — System reads headers + sample rows. Displays a preview.
  3. AI Field Mapping — System suggests a mapping of each source column to a target field (global or custom). For each column:
    • High-confidence match to a global field → auto-mapped, shown with green checkmark, user can override
    • Medium-confidence match to an existing custom field → shown with yellow “matches your existing ‘X’ — confirm?”
    • Low-confidence / no match → user prompted: create new custom field OR map to existing OR skip
  4. Adjudication — User reviews mappings, resolves ambiguities. New custom fields are previewed before creation (the user names them, picks the type, sees a sample value).
  5. Identity Matching Configuration — User picks the matching strategy for resolving rows to existing UVPs:
    • Match on Email (default for most imports)
    • Match on Phone
    • Match on Name + Address
    • Match on Voter Reg ID (for voter-file derivative lists)
    • “Strict” mode (skip ambiguous matches) vs. “Permissive” mode (best-effort match)
  6. Preview — System shows: X new contacts will be created, Y will update existing contacts, Z will be flagged for review.
  7. Confirm + Process — User clicks Import. System processes asynchronously.
  8. Report — On completion: detailed report. Rows imported successfully, rows that updated existing contacts, rows that failed (with reasons), rows flagged for adjudication (multiple-match pending).

10.2 The AI Field Mapping Model

This is the same field-promotion AI defined in vrm-data-system §11.2, applied at the per-account import level. It performs:

  • Semantic name matching against global field names (“Phone Number” → voter_phone)
  • Semantic name matching against the account’s existing custom fields (“Issue” → acct_issue_interest if the account already has that custom field)
  • Value-pattern matching when the column name is ambiguous (e.g., “ID” column — if values are voter-reg-format → voter_reg_id; if all values look like emails → voter_email)
  • Confidence scoring per suggestion

The AI does not auto-import. It auto-suggests. The user adjudicates.

10.3 Adjudication Workflow

For each ambiguous mapping:

  • Side-by-side: source column name + sample values; suggested target field + sample existing values
  • Three buttons: Accept (use suggestion) / Map to different field (dropdown of all eligible fields) / Create new custom field
  • For “Create new custom field”: modal with name + type + options (if dropdown/radio/checkbox) + description
  • Modal performs the duplicate-check from Forms (Section 6.1 of vrm-forms spec) — if the new field is semantically similar to an existing one, prompt to use existing

10.4 New Custom Field Creation From Import

When the user creates a new custom field via import:

  • The field joins the account’s custom field namespace (just like a Form-created custom field)
  • The field is immediately populated with values from the imported column
  • The field appears in the Fields tab, in the Field Library for future Forms/Surveys/CTAs, and as a column option in All Contacts

This is the central architectural point — import creates fields, not parallel data. The same field used in a Form can be populated from an import. The same custom field can be both ways.

10.5 Import History & Audit

Every import is a logged event with:

  • Filename, file size, row count
  • User who performed the import
  • Timestamp
  • Mapping decisions (which column → which field)
  • Identity match strategy used
  • Outcome (created / updated / failed / quarantined counts)
  • Audit log accessible from the Import tab → Past Imports

A failed import can be re-attempted with the same mappings (“Retry with same configuration”). A successful import can be reviewed and rolled back within 7 days (“Undo this import” — undoes the writes, removes the contacts created exclusively by it).

10.6 Multiple Match Adjudication

When an imported row matches two or more existing UVPs (e.g., the email matches one record, the phone matches another), the row is quarantined rather than auto-merged. The user resolves the conflict in the Duplicates tab (Section 13) where the candidate matches are side-by-side and the user picks which UVP gets the new data.


11. Tab 5 — Fields

The customer-tier view of the field system defined in vrm-data-system §5. This is where the account manages its custom field namespace and references the global schema.

11.1 The Field List

Two sections:

Global Fields (Politogy-controlled, locked):

  • Searchable list of every global field exposed to Relationship Mode
  • Each row shows: display label, canonical name, type, validation, usage count (how many of this account’s contacts have a value)
  • Read-only. The user can see the field but cannot rename, retype, or delete it.

My Custom Fields (account-scoped, user-editable):

  • Searchable list of every custom field the account has created
  • Each row shows: display label, internal name, type, usage count, date created, created-by user, “promotion candidate” flag if Politogy has identified this field as semantically common across accounts
  • Editable: rename label, edit options (dropdown/radio/checkbox), see audit log, merge with another custom field, delete (only if zero data — same rules as vrm-forms §11)

11.2 Custom Field Management Actions

Create a new custom field (from Fields tab — same modal as Forms builder, same duplicate detection, same rules):

  • Name, type, options, description
  • Joins the namespace immediately
  • Available in All Contacts as a column, in Forms as a field, in Surveys as a question, in CTAs as an Inline Field, and in Import as a mapping target

Edit a custom field:

  • Label always editable
  • Type immutable once data exists (same rule as Forms)
  • Options can be added freely; options with data cannot be deleted, only deactivated

Merge two custom fields:

  • User selects two custom fields, picks which is the “survivor”
  • System migrates all data from the merged field into the survivor (priority rules: survivor’s value wins on conflict; merged field’s value preserved as alternate with provenance)
  • Audit log records the merge
  • The merged field is retired; the survivor inherits all data
  • Used for cleaning up accidental duplicates (“I have ‘Issue Interest’ AND ‘Issues’ — merge into one”)

Delete a custom field:

  • Only allowed if zero contacts have data on it
  • Once data exists, deletion is permanently blocked (per the field-in-use protection rules)
  • The deletion button shows a tooltip explaining why when blocked

11.3 Promotion Candidate Notices

When Politogy’s promotion AI identifies one of the account’s custom fields as a candidate for promotion to global, a notice appears on that field’s row: “This field is similar to fields used by other accounts. Politogy is reviewing it for promotion to a global field.”

This is informational, not blocking. The account continues to use the field normally. If/when Politogy promotes the field to global, the user is notified, the field migrates, and the existing data flows into the new global field automatically.

11.4 Field Usage Audit

Click any field → see usage detail:

  • Forms / Surveys / CTAs that reference this field
  • Tribes whose membership criteria reference this field
  • Imports that mapped to this field
  • Number of contacts with a value
  • Recent edits to this field’s definition

This is the field-level audit view. Helps the user understand what depends on a field before they consider merging or modifying it.


12. Tab 6 — Activity (suggested addition)

A chronological activity feed across all contact-related events in the account. Helps managers monitor team work and spot anomalies.

12.1 The Feed

A reverse-chronological stream of events:

  • “Sarah added 12 contacts via ‘Volunteer Signup Form’” — 5m ago
  • “James imported ‘march_donors.csv’ (847 rows)” — 32m ago
  • “Maria merged Jane Smith (3 records) → kept ID 8821” — 1h ago
  • “Sarah created Tribe ‘HD37 Primary Voters’ (412 members)” — 2h ago
  • “AI flagged 8 likely duplicates” — 3h ago
  • “247 new opt-ins from ‘Election Integrity Banner’ CTA” — 6h ago

12.2 Filtering

Filter by:

  • Event type (Add / Import / Merge / Edit / Tribe / Tag / Delete / etc.)
  • User (who did it)
  • Date range
  • Affected contact (search by name → shows only events involving that contact)

12.3 Why This Tab Matters

In single-user accounts the Activity tab is nice-to-have. In multi-user accounts (campaigns with staff, organizations with delegated managers) it becomes essential. It is the audit trail surfaced for human review. It is the “what did my team do this morning?” view.

12.4 Activity as Aggregate Intelligence Feedstock

Activity events feed Politogy’s Aggregate Intelligence layer as behavioral signals about how accounts use the platform. Cross-account patterns about contact management workflows refine onboarding, surface tutorial moments, and inform future feature priorities.


13. Tab 7 — Duplicates (suggested addition)

The adjudication surface for likely-duplicate UVPs. The data system already detects duplicates (per vrm-data-system §11.2 — Data Quality & Anomaly Detection). This is where the user resolves them.

13.1 The Duplicate Detection

Politogy’s quality AI continuously scans the account’s contacts for likely duplicates:

  • Same email on multiple records
  • Similar names + same address (Robert Smith vs. Bob Smith at 123 Main St)
  • Phone number on multiple records
  • Manual flagging by user (“This looks like a duplicate”)
  • Import quarantine (Section 10.6)

Each candidate pair (or triple) gets a confidence score: High / Medium / Low.

13.2 The Adjudication UI

A table of duplicate candidates, ordered by confidence:

  • Each row shows: two (or more) UVP previews side-by-side, the matching evidence, confidence score, action buttons
  • Merge — confirms; opens a merge wizard where the user picks which value wins per conflicting field (with sensible defaults), then commits
  • Not a Duplicate — dismisses the candidate; the system remembers and won’t re-flag this pair
  • Review Later — keeps in queue
  • Bulk Merge — for high-confidence batches, one-click merge all with default-priority rules

13.3 The Merge Wizard

When the user clicks Merge on a pair:

  • Side-by-side render of all fields with values from both records
  • For each conflicting field: choose Record A’s value, Record B’s value, or enter a new value
  • Default rules pre-select (most recent value wins, voter-file-sourced wins for Identity Core, etc.)
  • Activity / engagement / contact log / Tribe membership / tags — all unioned (no choice; everything from both records merges)
  • Final preview before commit
  • Audit log records the merge with full before/after snapshots

13.4 Post-Merge Behavior

The losing record becomes a Merged state UVP with a pointer to the surviving record (per vrm-data-system §9 record lifecycle). No data is hard-deleted. Future references to the merged record route to the survivor. The merge is reversible within 14 days via the Activity log.

13.5 Cross-Account Duplicate Awareness (Politogy-tier)

When a duplicate exists in this account but the surviving UVP also exists in other accounts (because each account has its own claim), Politogy maintains the UVP linkage at the master-database level. The customer never sees other accounts’ data — the merge happens within the account’s Relationship Data layer; the underlying UVP at the Politogy level was already unified.


14. Permissions

Same role matrix as the rest of Relationship Mode (vrm-data-system §12), applied to Contacts surfaces.

RoleDashboardAll ContactsTribesImportFieldsActivityDuplicates
Account AdminAllAllCreate + editYesFullAllFull adjudication
Account ManagerAll within scopeAll within scopeCreate + edit ownYesCreate + edit customWithin scopeAdjudicate within scope
Field UserLimited (own list slice)Assigned sliceView shared TribesNoView onlyOwn actions onlyNo
ViewerRead-onlyRead-onlyRead-onlyNoView onlyRead-onlyNo

Bulk delete, custom field deletion, custom field merge, and import rollback are gated to Admin only.


15. UVP Provenance & Contact Provenance

Every change made to a contact via Contacts surfaces is provenanced per the UVP standard:

  • Source: “Manual edit by [user]”, “Import [filename]”, “Form [name]”, “Survey [name]”, “CTA [name]”, “Merge”, “Bulk edit”, etc.
  • Timestamp: When the change was committed
  • User ID: Which account user (when applicable)
  • Audit trail: Every change preserves the prior value with full provenance, never destructive

This is what makes Contacts a defensible record system. Nothing happens without a trace; nothing gets overwritten silently.


16. Integrations & Quick Actions Roadmap

The Quick Actions (Call, Text, Email) ship in V1 with native handoff (tel:, sms:, mailto:). V1.5 brings integrated channels:

16.1 V1.5 — Integrated Calling

  • Click-to-call via Telnyx (per the Phone Banking spec’s V1 click-to-call architecture)
  • Auto-logs the call to the Contact Card’s contact log
  • Captures duration, outcome (configurable), recording reference if recording is enabled

16.2 V1.5 — Integrated SMS

  • Send SMS from within the Contact Card or All Contacts row
  • Templated messages (account-saved templates)
  • TCPA-compliant: blocked if contact has opted out; explicit consent capture if first-time
  • Conversation thread visible inline on the Contact Card

16.3 V1.5 — Integrated Email

  • Send single email or bulk email to filtered selection (subject to email subscription status)
  • Templated, brand-styled
  • Tracking pixel for open/click attribution
  • CAN-SPAM compliance enforced

16.4 V2 — Calendar / Scheduling

  • “Schedule a call” → embedded scheduling widget on the Contact Card
  • Pulls from the user’s connected calendar

16.5 V2 — Mailing / Direct Mail

  • Direct mail batch export with pre-formatted address blocks
  • Integration with mailing-service providers (Lob, etc.)

17. Mobile

V1 mobile experience for Contacts is read-and-act, not full builder:

  • Dashboard, All Contacts (with simplified columns), Contact Card, Tribes (view-only), Activity all available
  • Quick actions (Call, Text, Email) prominent on mobile — this is when field staff most often use Contacts
  • Import, Fields, Duplicates are full-functionality desktop, view-only on mobile

V2: full mobile parity except for Import (which remains desktop-only due to file-handling friction on mobile).


18. V1 / V1.5 / V2 Scope

V1 — Ship

  • Seven-tab UI (Dashboard, All Contacts, Tribes, Import, Fields, Activity, Duplicates)
  • Tailored political-context Dashboard with headline strip, demographic intelligence, issue intelligence, growth velocity, quick actions
  • All Contacts table: virtualized, customizable columns, saved views, universal search, multi-filter, sort, quick actions (native call/text/email), bulk actions
  • Contact Card with 7 sub-tabs (Overview, Vote History, Engagement, Relationship, Web Behavior, Petitions, Verified Data) and activity timeline
  • Manual Tribes (Static + Dynamic), bulk Tribe membership management, pre-built suggested Tribes
  • AI-assisted Import with field mapping, adjudication, identity-match configuration, history, undo (within 7 days)
  • Fields tab with custom field CRUD, merge, audit, promotion candidate notices
  • Activity feed with filtering
  • Duplicates tab with merge wizard and bulk merge
  • Standard role-based permissions
  • Provenance on every change

V1.5 — Near-term

  • Integrated Telnyx calling (Phone Banking infrastructure)
  • Integrated SMS sending
  • Integrated email sending with templates and tracking
  • Larger import support (chunked, async, 500k+ rows)
  • Import rollback window extended (14 days)
  • Mobile parity improvements

V2 — Defer

  • AI-powered automated Tribes — the headline V2 feature, full automated clustering and suggestion
  • Cross-mode contact log unification (deeper integration with Campaign Mode canvassing and Phone Banking logs)
  • Calendar / scheduling integration on Contact Card
  • Direct mail batch export with formatted addresses
  • Advanced segmentation analytics (cohort retention, engagement decay)
  • A/B testing of Tribe definitions for performance optimization

V3+ — Aspirational

  • Predictive contact engagement scoring (AI predicts which contacts most likely to convert / volunteer / donate next)
  • Cross-account contact intelligence (Politogy Aggregate Intelligence product for Enterprise tier — “this contact has high signal across the platform”)
  • Voice assistant for hands-free contact actions (“Hey VRM, call the next volunteer on my list”)

19. Summary Mental Model

Contacts is the workbench. The UVP is the data. Forms, Surveys, CTAs, Imports, Manual Adds, and Mergers flow contacts in. Tribes, Quick Actions, and exports flow contacts out. Fields define the structure. Activity records the work. Duplicates keeps it clean. The Dashboard makes it intelligible.

Every other Relationship Mode feature exists to put a row in this table. Every Campaign Mode and Petition Mode feature draws from this table. Contacts is the gravitational center of the user’s day-to-day VRM experience.

The architectural rule: Contacts is a view, not a store. Every contact is a UVP. Every change provenance-tracked. Every field comes from the global or account-scoped namespace defined in the field system. Every list is a query over UVPs. Every action respects the two-tier IP boundary and the exposure controls.

North Star: The user opens Contacts in the morning, sees the state of their list in five seconds, finds the people they need in five clicks, takes action in five more, and trusts that everything they do strengthens the UVP underneath. Everything in this spec serves that promise.


Developer Open Questions

These are V1 architectural decisions that need a recommendation before engineering can scope.

  1. Virtualization performance threshold. At what list size do we activate aggressive virtualization vs. simple paginated rendering? Recommend virtualization always on (use Tanstack Virtual or similar); paginated rendering is a worse user experience even on small lists.

  2. Saved view sharing. Are user-saved column configurations / saved filters strictly per-user, or can they be shared across the account (“Sarah’s Donor View” usable by James)? Recommend per-user by default, with explicit “share with account” toggle.

  3. Quick action defaults — native vs. integrated. In V1, native handoff (tel:, sms:, mailto:) is the default. Should this be configurable per-account at account creation, or just per-user? Recommend per-account with per-user override, since different campaign roles use different tools.

  4. Contact Card panel vs. modal vs. drawer. Slide-in drawer (recommended), modal overlay, or dedicated route? Drawer keeps All Contacts visible behind it, useful for batch work. Recommend slide-in drawer.

  5. Manual contact addition without identity matching. When a user clicks ”+ Add Contact” and enters someone’s data, do we always run identity matching against existing UVPs, or is manual entry assumed to be net-new? Recommend always run match — manual entries are a common cause of accidental duplicates.

  6. Activity feed retention. How long is Activity history retained? Forever (storage cost) or rolling N days? Recommend forever, given that storage is cheap and the audit value is high.

  7. Bulk action confirmation thresholds. Should bulk actions over a threshold (e.g., 1000+ contacts) require typed confirmation (“Type DELETE to confirm”)? Recommend yes for destructive bulk actions; thresholds 100+ for delete, 500+ for non-reversible edits.

  8. Import field-mapping memory. When a user imports a second CSV with similar column headers, does the system remember the mappings they made last time? Recommend yes — per-user import mapping memory, suggested but overridable on subsequent imports.

  9. Contact Card edit conflicts. Two users editing the same Contact Card simultaneously — last write wins, optimistic locking, or real-time collaboration? Recommend optimistic locking with conflict warning for V1; real-time collab in V2.

  10. Dashboard panel customization. Can the user customize which panels appear on their Dashboard (drag to add/remove)? Recommend a small set of pinned/unpinnable defaults, with optional advanced panels addable from a ”+ Add Panel” menu in V1.5.

  11. Tribe membership recomputation cadence. Dynamic Tribes recompute membership when? On every UVP change (expensive), nightly batch, or on-demand-with-cache? Recommend live-on-UVP-change with a debounce window for high-traffic accounts.

  12. Tribe naming conflicts. Can two Tribes have the same name? Same name across accounts is fine; within an account: recommend block exact duplicate names, allow case-different variations.

  13. Duplicate detection sensitivity. What confidence threshold triggers a duplicate flag? Recommend three tiers: High (auto-suggest merge in Duplicates tab), Medium (show with caveat), Low (don’t surface unless user manually requests deeper scan).

  14. Custom field “in use” definition. A field is undeletable if “in use” — but what does in-use mean precisely? Any UVP with a non-null value? Or any UVP that has EVER had a value (including historical/alternate)? Recommend: any UVP that currently has a primary value OR any UVP that has an audit-logged historical value.

  15. Import row failure handling. When an import has, say, 47 failed rows out of 5,000, do we commit the 4,953 successful rows and ask the user to fix the 47, or rollback everything? Recommend partial commit with a downloadable failure report — better workflow.

  16. Verified status downgrade visibility. When a contact goes from VRM Verified → Stale, does the user see a notification? Recommend a subtle “Stale” badge appears + a roll-up in the Dashboard’s “Stale Verified” counter; no per-contact notification (would be noisy).

  17. Cross-account Tribes (V2 spec question). A campaign manages multiple sub-accounts (state organization with chapter accounts). Can a Tribe defined at the parent level distribute to sub-accounts? Recommend treating in a parent-account / sub-account spec separately; not V1.

  18. Anonymous contact handling. Visitor-ID-only “contacts” (no identity capture, just CTA behavioral data) — are they shown in All Contacts or hidden? Recommend hidden by default with a toggle to surface them (“Show anonymous visitors”) — keeps the main list focused on actionable contacts.

  19. Contact Card “Add new field” inline. Should the user be able to create a brand-new custom field directly from a Contact Card (rather than going to the Fields tab)? Recommend yes — friction-free custom field creation is one of the platform’s best workflows.

  20. The “Tribes” naming. This is your political-product name. Is it the official UI term, or do we also use “Lists” / “Segments” / “Groups” for clarity to less-political users? Recommend Tribes as the primary term with “(also called Lists)” sub-label in tooltips during onboarding.


End of Spec

This document is the V1 conceptual specification for the rebuilt VRM Contacts feature in Relationship Mode. It centers the seven-tab workbench around the UVP, the global vs. custom field architecture, and the data-quality / data-trust principles of the data system.

The North Star: the workbench that makes the UVP feel alive.