VisuallyMeta

Writing

Field Notes

Working notes, experiments and thinking on AI, product and design.

  1. Superadmin Revamp

    The requirement came after a partner wanted to be a middleperson and sell the dialer to their contacts. For this we need to share superadmin access to the partner. Now obviously we can't share everything with them.
    This is also a challenge, when we set up the dialer on-premise.

    I always ask my teammates to keep suggesting improvements and difficulties from time to time. I was already keeping tracks of changes required in superadmin and how it is too complex to use. But more the complexities these were the main points that made me go for revamp:

    • Security: We needed to define the roles properly within the organization to avoid any leaks, espionage, or mistakes to a tenant account that might hamper their organization.
      • Meta Data: To keep track of all the changes done to any tenant and by whom.
      • More layers of authentications like 2-factor.
        • Root Cause Analysis (RCA): If any tenant asks, about certain system related problem, instead of searching in database, we would be able to check this screen, download the complete call trace or multiple traces, and provide the RCA to the clients.
  2. When the requirements are met but the client still wants more

    Context: A bank needed a video calling and scheduling platform for its relationship managers, connected to its existing CRM, with notifications and support for customers in India and abroad. My job was to build a full working prototype, not mockups.

    Why banks need this now

    Two shifts made video banking a priority rather than a nice-to-have:

    1. Bank calls became one-way.
    TRAI now requires banks to make service and transactional calls from the dedicated 1600 number series, so customers can tell a genuine bank call from a fraudulent one. That helps with trust, but these numbers don't take incoming calls. A customer who misses an RM's call can't simply call back. The bank needs a channel where the conversation is scheduled and two-way.

    2. Banks are competing for NRI customers.
    The RBI's special FCNR(B) deposit window in 2026 let banks offer NRIs higher rates on foreign currency deposits, and lenders began engaging more actively with NRI customers across key overseas markets. Those customers are in different time zones and countries, often unable to visit a branch, and expensive to reach by international phone call. A scheduled video call with their RM fits their situation far better. socialnews

    Regulation made outbound calls more trustworthy but harder to call back. NRI demand made distance the main obstacle. Video banking addresses both.

    What I did

    • Built the prototype end to end with Claude Code.
    • Covered every requirement in the brief.
    • Demoed it live to stakeholders as a working product rather than a slide walkthrough.

    What happened

    The prototype met their needs as written in the brief. The client still wasn't satisfied. They wanted a "cherry on top": something beyond the brief, and in some cases beyond what current technology can do.

    Meeting the requirements isn't the same as meeting the expectation. A brief records what a client can put into words, not what they imagine.

    What I'm thinking about

    • Was the gap in the brief or in the moment? A working prototype makes the possibilities feel real, so the client starts imagining further. That reaction suggests the prototype did its job.
    • Separating the impossible from the unfamiliar. Some of what sounds impossible is possible but hasn't been done in banking yet. Finding the one feasible thing in the wish list could be the real cherry.
    • Where to draw the line. Chasing features the technology can't yet deliver risks the project. The skill is saying "not yet" in a way that keeps the client excited.

    Status: Open. Let's see where it goes.

  3. The clients ignored the charts

    What happened: I showed clients the redesigned monitoring dashboard: an Overview tab full of charts, and an RTM tab with five sub-tabs (Agents, Inbound, Outbound, Campaign, OBD). The Overview tab got almost no reaction. RTM got all the questions.

    What they actually asked for:

    • Which agents are idle right now?
    • Who has been on an unusually long call?
    • Which campaigns have run out of leads?
    • Filter inbound calls by queue status.

    Supervisors didn't want to see how the day was going. They wanted to know what needed their attention right now.

    What changed:

    • A right-side drawer for each row in Agents, Inbound, Outbound and Campaigns, with live actions in it: Monitor, Whisper, Barge.
    • Advanced filters for each tab, with an estimated record count shown before the filter is applied. Supervisors can see the size of a query first, which also keeps API calls efficient.

    Workflow note: Screens were built in HTML with Claude Code first, then ported into Figma for refinement.

  4. I stopped designing the dashboard and started designing the decision

    Initial approach. The brief was the one every designer knows: research the best quality dashboards, study what the category ships, design the strongest insights page I could. So I did — benchmarked, collected patterns, had a good-looking page forming.

    Where it broke. Midway I stopped trusting the dashboard heuristics. A dashboard isn't a gallery of the best-looking charts; it's the front end of a decision. The question that mattered wasn't "what should this page show" — it was "how does a user analyse this, share it, and act on it, and how does my presentation decide which of those they can even do." Framed that way, half of my well-researched page was decoration.

    Resolution. I anchored the insights layer to an analytics lifecycle — Ask → Prepare → Process → Analyze → Share → Act — and used it as a gate, not a diagram. The rule: an insight ships only if it names a real question (Ask) and a real decision it drives (Act). If a metric changes no one's behaviour, it isn't an insight — it's decoration, and it goes to drill-down or nowhere. That one test killed most of what research had produced. Prepare and Process became the buildability gate: data has to exist with its denominator or it doesn't ship. Share stopped being a phase-three nicety and became a v1 requirement — an insight you can't export never reaches the person who acts on it.

    What I'm proudest of isn't a cleaner page, it's a mechanism. Every insight now carries the same spine — what question, whose decision, what data, what action. Most QM dashboards drown you in scoreable numbers. This one refuses to show a number that doesn't earn a decision. Fewer metrics, each load-bearing.

  5. Redesigned our real-time contact center dashboard.

    1. Spent this week redesigning the real-time dashboard for our contact center product. thought it'd be a UI job. it wasn't. the actual problem was that the customer and the engineer wanted opposite things and both of them were right, which is the worst kind of problem to have.
    1. The customer is BFSI, outbound-heavy, and every demo they'd add one more thing to the list. how many calls are live right now. how many done today. abandon rate. who's on break vs actually on a call. AHT, talk time, hold time. dispositions. the dial mode split.

    they didn't want a metric. they wanted the whole board, live. and honestly for collections that's the right instinct — the job is knowing what's happening this second.

    1. Engineer looks at the same list and goes: this will melt the DB.

    which, fair. every number is a query, the screen refreshes roughly every 28s, so it's not a page load, it's the same query storm firing on a loop forever. he wasn't being difficult, he was right too.

    1. So now I'm stuck. give the customer everything and I've handed engineering a system that falls over. give engineering the relief and I ship a dashboard so thin it answers none of the questions the customer actually cares about.

    took me a bit to realize the mistake was treating "the dashboard" like one thing that refreshes at one speed.

    1. It doesn't have to. so I sorted every number by how fresh it actually needs to be.

    the vitals up top (total, completed, abandoned, failed) are cheap reads, those stay live. the state cards — agents / outbound / inbound — only one's open at a time, not all three polling at once. and the heavy stuff at the bottom (averages, dispositions, dial mode) is aggregation over history, so it's allowed to lag a little. nobody's making a call based on whether avg talk time updated 3 seconds ago.

    1. That bottom row is where it clicked.

    "it's slow" was never actually true. "this specific aggregation is slow" was true. and once you say it that way the fight kind of disappears — because the live stuff the customer wants most is the cheap stuff, and the genuinely expensive queries are the historical rollups, which are exactly the ones that don't need to move every 28 seconds anyway. so they don't.

    1. One thing I wouldn't budge on: if I can't tell you where a number comes from, it doesn't go on the screen.

    Call duration only shows on live calls. everywhere else it's a dash. not a fake 00:00, not a padded zero. no SLA gauge, no pause-reason card, none of the stuff every competitor dashboard has that our system doesn't actually track yet. a screen that looks full but shows nothing real is the last thing you want to hand a compliance buyer.

    1. End result is the layout in the pic. customer gets the full live board they'd been asking for. engineer gets a hard ceiling on load. nobody had to lose.

    The thing I keep thinking about is that neither of them was wrong, the disagreement was just happening at the wrong altitude. the whole fix was buried inside one word everyone kept using too loosely — "slow."

  6. "Not enough data" is a state, not a blank

    Initial approach. Building the Claralens analytics layer, I defaulted to the obvious: every insight card shows a score. A number in every cell felt like completeness.

    Where it broke. On small or sparse interaction sets, a raw score misleads. Five interactions scoring 100% isn't a good agent — it's five interactions. Ranking on numbers like that manufactures false confidence, and in BFSI that confidence gets acted on.

    Resolution. I made emptiness explicit. "Not enough data" is now a first-class UI state — never a blank cell, never a zero standing in for absence. Template Health became a prerequisite gate: if the instrument isn't sound, nothing downstream is trusted. Ranking uses the Wilson lower bound with a minimum-N threshold, so a position has to be earned. Every number renders alongside its coverage and denominator, with NA checkpoints excluded from the denominator rather than counted as failures.

    The principle underneath: the dashboard's job isn't to look full. It's to say when it knows something and when it doesn't. A confident wrong number costs more than an honest gap.

  7. Correct Judgement Heuristics

    When I made "not applicable" a real checkpoint state — alongside pass and fail — it quietly broke the scoring math.

    Say a parameter has five checkpoints and one genuinely doesn't apply to this call. Score it out of 5 and you've penalized the agent for something that was never in scope. The honest denominator is 4, not 5. "Not applicable" isn't a silent zero — it's an exclusion, and exclusions change the denominator.

    So the logic changed: N/A checkpoints drop out of the denominator entirely, rather than counting as fails. The parameter scores 1 of 4. The header reads "14 of 17 scored," with the three excluded checkpoints shown explicitly — not hidden to make the number look cleaner.

    That visibility is the entire point. An agent disputing the grade can walk the exact chain: this checkpoint was N/A, here's why, that's why the parameter is out of 4, that's why your total lands where it does.

    The correction wasn't hard to make. It was hard to notice — the math looks correct right up until you realize a third state was silently doing a fail's job in the denominator.

  8. The build order flipped under me

    I'd sequenced Claralens the obvious way: start with the Evaluation Detail View. It's the heart of the product — the screen where a grade gets read, disputed, overridden. Build the heart first.

    Then I wrote the object model down as a plain dependency list and argued with it. The heart fell apart.

    You can't render a detail view without a template to score against. You can't author a template without detectors to assign into it — because a Checkpoint is a detector assigned to a template. The dependency chain runs the exact opposite of intuition:

    Detector Library → Template Editor → Evaluation Detail View.

    The most important screen in the product literally cannot exist until its foundations do. The "heart" ships last, not first.

    I only caught this because I forced the model into a table before touching wireframes. In prose it was invisible — everything sounded shippable in any order. In a dependency list it was obvious in ten seconds.

    Write the object model as a list and stress-test the order before you draw. It's a table you can rewrite in a minute or a set of wireframes you rebuild for a week.

  9. One Detector Library (Checkpoint vs Moment)

    Initial approach. The existing platform had scattered concepts — checklists, highlights, entities, signals — plus 143 live detectors.

    Where it broke. Overlapping vocabulary meant overlapping screens. Nobody could say cleanly what was scored and what was merely observed.

    Resolution. Collapsed everything into one unified Detector Library. A detector assigned to a template renders as a scored Checkpoint; an unassigned detector firing in the wild renders as an observed Moment (unscored). Detectors are typed — rule (deterministic) vs instructional (AI) — versioned, and pinned to each evaluation. Retired: checklist, highlight, entity, signal. This unification later flipped the entire build order (see §6).

    Two more locks that came out of the same work:

    • All three detector states must be authored — pass, fail, and not applicable. "Not applicable" is a first-class state that changes the scoring denominator, not an afterthought.
    • Overrides happen only at the checkpoint leaf, recomputing upward with a delta preview before commit (e.g. parameter 25 → 50 · total 62 → 68). Parent-level overrides break explainability; showing the consequence before the click turns a reflex into a considered judgment.
  10. Permissions aren't a settings page.

    In a QA tool, who-can-see-what isn't a checkbox screen you bolt on at the end. It decides what every other screen even contains.

    An auditor overrides scores. A QA manager runs calibration. An exec reads aggregates and should never touch a raw override. A tenant admin configures templates but has no business seeing an individual agent's grade. A superadmin lives in a separate shell.

    So before wireframing, I mapped every role against every surface as a matrix — full access, read-only, or none. Not for security theater. Because an exec's "detail view" and an auditor's "detail view" are different screens wearing the same name: one can flip a checkpoint and see the trail; the other can't see the button.

    Drawing that grid early kills a whole class of bug — the read-only user shown a control that errors on click, the exec accidentally exposed to data they shouldn't have. You can't design the screen honestly until you know who's standing in front of it.

    The permission matrix is a design input, not a compliance afterthought. It reshapes everything it touches.

  11. "Call" → "Interaction"

    Initial approach. The BRD's atomic unit was a "call." Every dashboard, list, and report was built around it.

    Where it broke. During stakeholder clarification the scope expanded: Claralens has to grade SMS, WhatsApp, and email too — not just voice. "Call" quietly excludes three of the four channels, and any IA built on it would need re-architecting the moment text channels arrived.

    Resolution. Renamed the atomic unit to Interaction (channel: voice | sms | whatsapp | email; actor: human | bot). Every surface became a lens over one interaction corpus. Evidence anchoring got two renderers behind one contract — timestamp for voice, message ID for text — so adding a channel never means adding an app.

  12. Analytics: Clara Dashboard

    We started on flat, comfortable ground. The scope for Analytics was strong — clean charts, solid metrics, everything a dashboard is supposed to have. We felt good. The line was steady and high.

    Then we fell into the hole.

    The problem was quiet at first, easy to miss: we had designed the whole thing from our side of the glass. We were thinking like people who build charts, not like people who live with results. And a customer who has run their Agentic AI Voice Platform for a month doesn't open Analytics to admire charts. They walk in carrying real weight — business questions:

    "Is my AI actually helping my business?"
    "Where am I losing opportunities?"
    "How can I improve my agents and campaigns?"

    Our beautiful scope had no answer to any of that. That was the bottom of the hole.

    Climbing out meant flipping the entire frame — designing for the people who'd actually use it, and more specifically, for the perspective each person brings based on their job:

    • The campaign / operations manager — "Is it working?"
    • The sales / growth owner — "Am I making money?"
    • The inbound / support lead — "Are we dropping the ball?"
    • The product / AI owner — "Does it feel good to the caller?"

    Once the questions led the design instead of the charts, everything reorganized around them. We came out of the hole standing higher than where we started — not with a prettier dashboard, but with one that actually answers for itself.

  13. Docs as a design tool, not a handoff

    I had to spec out Cloud Telephony page by page for the dev team. My first instinct was to open Figma and start annotating screens. Instead I gave Claude the codebase and asked it to write markdown specs for each page. First two files came back accurate but useless — every button, every column, every colour dutifully listed. Screenshots in prose.

    So I flipped the brief. I asked Claude to drop the CSS notes and audit each page as a designer would — flagging what should change, not just what exists. Every file since has a designer's note, 🆕 markers on improvements, and a before/after table at the bottom.

    The output is now doing two jobs at once: it's the build spec for the dev, and it's my UX proposal for the cofounder. The 🆕 tags let him decide what's in scope without me having to write two documents. What I learned: getting Claude to describe code is low leverage. Getting it to audit code with me, while I make the design calls, is where the compounding starts. The markdown is the artefact. The audit is the actual work.

  14. Reverse-engineering as a design method

    I've been reading our own codebase to write the specs, not the other way round. Dashboard through left-nav, seven markdown files, each one describing what the screen is today and what it should be — every proposed improvement flagged so a dev can scope it without guessing what's new.

    Turns out AI is genuinely good at the archaeology: crawl the code, tell me every nav item, every route, every existing state. That frees me to do the part I'm actually for — deciding what's wrong with it. It's a nice inversion. The machine reconstructs the present, I argue for the future.

  15. How can I miss this scenario?

    The customer found the bug in my design before I did. In production. In front of everyone.

    Let me back up.

    My first time designing for a dialer, I thought I'd covered everything. I mapped every log state I could think of — a call comes in as inbound, goes out as outbound, gets missed by the agent, gets missed by the customer. Right? That's everything.

    Then I went deeper. Call not connected. On mute. On hold. Completed. I designed for each one and felt pretty good about it.

    Then we shipped.

    And a customer asked, "Where's transfer and conference?"

    Damn. How do you forget transfer and conference on a dialer? And when something like that slips through, the designer wears it. I do think it was my mistake — a designer's whole job is to imagine every path a user might take and design for it.

    So, we spent two more days rebuilding: the transfer and conference widgets, and then how a transferred call should even show up in reports and data — because a new state doesn't just live on the screen, it ripples through everything downstream.

    Here's the lesson I walked away with. Can you think of every scenario up front? No. You can't. Nobody can. But you can build the flow so that any new scenario slots in without breaking the ones already there.

    Design for the paths you can see. Architect for the ones you can't.

  16. Starting with Cloud Telephony

    Doing product design for the dialer is teaching me a lot. And with the world moving and adapting to AI, I'm taking a big risk. My deadline for Cloud Telephony is 20 days, and I want to use AI and Claude Code not just to design, but to implement the frontend directly. With current AI capabilities, it feels doable — in fact, I've already tried building a dummy app entirely with Claude Code.

    The risk is clear: if I commit to the AI approach and it fails, it derails my timeline and leaves me unable to fall back on designing and delivering in Figma within the deadline.

    But I'm going to give it a shot. Let's see.

  17. Starting with Clara Design

    Now that the information architecture is done and the full flow has been shared with every stakeholder — feedback folded in, use cases refined — I've started fine-tuning the design against our brand guide.

    The setup was half the fun: I connected the Figma plugin to Claude Code and handed over my design file, which it read and turned into a clean Markdown reference for Claritel's brand colors.

    Then I fed that same design file back into Claude Code and got to work. I also brought in Wonder — an AI-first design app — and was able to generate design directly from my inputs. A few skills pulled the weight along the way: emilkowalski/skill, /impeccable init, and Leonxlnx/taste-skill.

    Hope to share the result soon.

  18. Designed the Information Architecture

    Working on a user flow is one thing. Refining its information architecture — stress-testing every button, every feature, the core flow itself against our requirements — is another entirely. There was a lot to fine-tune. It felt like designing a car, then making sure people could actually open the door, sit down, and drive.

  19. Onboarding for Clara

    Designed this onboarding screen for Clara — and the process is worth talking about more than the output. I used Claude Code to build the frontend directly, pulling inspiration and code from ReactBits. No Figma first. No handoff. Just straight from idea to working interface. The workflow is shifting, and I'm leaning into it.

  20. Working on Clara

    Sat down with the product expert to map out Clara from scratch — user flows, feature set, the full architecture of an Agentic AI Voice platform. The kind of session where you walk in with assumptions and walk out with a completely different mental model of what the product needs to be.

  21. Empty states are a product decision

    I almost treated empty states as an afterthought. But when I started listing them out for Claritel, I realized every empty state is a moment where the user either gets unstuck or gives up.

    I catalogued 20+ empty states and success states, each with specific trigger conditions, headline copy, and CTAs.

  22. The layer AI won't add unless you make it

    Our left nav was a flat list of ~14 items. Technically fine. Design-dead. Audio Library sat invisibly disconnected from IVR Design — even though it exists to feed IVRs. No badges on actionable items, no grouping, no semantic relationships.

    AI shipped the list. It won't tell you the list has no meaning. Grouping related destinations, surfacing pending callbacks, giving inactive items a reason to relate to each other — that's the thinking you have to bring. The build is cheap now. Knowing what deserves to be built is the whole game.

  23. The Lateral Thinking

    The best idea in the Claritel project came from outside SaaS entirely. We studied Formula 1 pit stops — where a two-second delay is a disaster — and gaming interfaces, where controller shortcuts eliminate friction for power users. That thinking shaped how agents navigate the dialer. The goal wasn't just usability. It was flow state. The product should work with the agent, not make them work for it.