Smart Tags: A Segmentation Engine That Never Goes Stale
Advisors were tagging households by hand into labels that were true the day they were applied and wrong a few months later. I designed and built Smart Tags — a rule-based tagging engine — solo, end to end, and won Savvy Wealth's company-wide hackathon, Big Bang 2026, with it.
The problem: tags that lied
Applied once, by hand. Never re-checked — six months later the client is 41 and still wearing a tag that's now a lie.
Backed by a rule. Re-evaluates on every data change — the day the client turns 41, the tag removes itself.
Same tag, same household — the difference is what happens after it's applied. Reconstructed from the shipped rule engine, not a literal screenshot.
Tags shipped as static labels in December 2025. Advisors could apply a tag to a household, but nothing about it was true for long — client attributes like age, income, and last-contact date change constantly, and a label frozen at the moment it was applied starts rotting immediately.
"People aged 30 to 40. Well, your age changes, so eventually that tag is irrelevant. That's a filter, not a tag."
— Ed Wildermuth, Financial Advisor"You go into each household, tag it, go to the next household, tag it — it's not good."
— Advisor feedback on bulk taggingTwo separate advisors, independently, named the same two failure modes: tags went stale, and applying them one household at a time didn't scale to a real book of business. That gave me a crisp brief — turn the existing Tags surface into a tagging and segmentation primitive, not a bigger pile of manual labels.
Why this, why now
- Closed every "Done when" item already scoped in the backlog (Linear SV-888)
- Shipped directly against advisors' top-requested Canny item — "Easier access to client tags" (score 8, ~45 addressable votes)
- Became the segmentation primitive two other roadmap items were waiting on — Multi-Household Tasks and the Service Calendar could now reuse the same rule-based grouping instead of building their own
A rule you can trust, on both ends
Building a Smart Tag end to end — the rule, the overlap warning against an existing tag, and the tag re-evaluating live the moment a household's data changes.
A smart tag isn't just a label — it can be a rule: age, income, AUM, state, employment status, last-contacted date, and stage, combined with AND/OR logic in a visual builder I designed so advisors could write conditions without ever seeing a query language. The real design problem wasn't the builder's UI, though — it was trust. The live preview an advisor sees while building a rule had to match, exactly, what the system would actually do to their households afterward, or the feature would feel like a lie the first time it didn't. So I wrote the spec for how a rule evaluates once, then paired with Claude Code to implement it twice against that same contract — TypeScript for instant preview, Ruby as the source of truth — and tested both until they never disagreed.
When you save a rule, it applies right away across every household in the org instead of waiting on some overnight job — I wanted the effect to feel immediate, not theoretical. After that, any change to a household automatically re-checks its tags, and checking twice never causes problems: if nothing's changed, nothing happens.
Turning "one household at a time" into one action
The other half of the bulk-tagging problem was advisors switching from Redtail or Wealthbox with years of tags already applied. Re-creating that by hand was the exact pain the advisor quote above was describing — so import needed to survive messy, inconsistent real-world exports without guessing wrong in either direction.
Classify
- Scores every column header and a sample of its cell contents — advisors never rename columns to match our schema
- Each role (name, email, phone, tag) claims its best-scoring unclaimed column, so nothing double-assigns
- Parses "Last, First" and "First Last" formats, drops suffixes like Jr./Sr./III
Preview
- Matches CSV rows to existing households on email, phone, and name, in tiers
- A conflicting email/phone match is surfaced, not hidden — resolved in favor of email but flagged
- Falls back to name matching only when no reliable contact info is on the row
Confirm
- Near-duplicate tag names auto-merge ("Stage is a Lead" ≡ "Stage is Lead")
- An advisor's explicit rename always overrides the auto-merge
- Smart tags can never be force-applied by an import — membership stays rule-governed
The full wizard, end to end — upload, classify, resolve the one ambiguous row, and land on 23 of 24 clients matched automatically.
A phone number can match the right household but the wrong person in it — a household's line might ring to Sophia, but the CSV row with that number is actually for Helen. If the name on the row doesn't align with the name behind the matched contact info, the row is pushed to a reviewable "ambiguous" queue with that household's other members offered as candidates — instead of silently tagging the wrong person because their sibling's phone number happened to match.
Shipping fast didn't mean skipping the polish pass
Hackathon timelines compress everything except the instinct to check your own work. Running a design-review pass against the finished build caught a consistency issue before submission — small on its own, but exactly the kind of thing that makes a feature feel unfinished.
The Zap icon that marks a smart tag was rendering the same way everywhere, regardless of which category the tag actually belonged to. Fixed to always inherit the tag's own category color, so the icon and the category agree everywhere it shows up.
Automating trust, not just tagging
The hard part of this feature was never the rule builder UI — it was earning the right to let a system add and remove tags on its own without an advisor feeling like they need to double-check it. A few decisions did most of that work:
- Smart tags are inviolable. Never manually removable, never a merge destination, never force-applied by an import — a rule-governed tag stays rule-governed, full stop.
- Manual tags are never touched by automation. The system only ever changes what it created; an advisor's own tagging is never silently modified.
- Ambiguity gets surfaced, not resolved quietly. A conflicting match is flagged and shown, not hidden behind a best guess.
- AI refuses rather than hallucinates. The Claude-generated tag descriptions return empty on an ambiguous or nonsense tag name instead of inventing a plausible-sounding one.
Advisors using tags for client segmentation
An empty tags list is a hard sell, so launch didn't wait for advisors to build their first rule from scratch. A handful of high-need smart tags were created automatically for every advisor, existing and new, so the feature arrived with a few already working instead of a blank slate. Two mattered most: RMD Eligible, because a required minimum distribution deadline is one advisors genuinely can't afford to miss, and High Net Worth, because AUM is how advisors decide which households get their attention first.