<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Mateus Victor</title>
    <description>The latest articles on DEV Community by Mateus Victor (@mateuxcv).</description>
    <link>https://dev.to/mateuxcv</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4055202%2Fffa47a5c-6f0a-46c8-9bde-80a37cac78cb.jpg</url>
      <title>DEV Community: Mateus Victor</title>
      <link>https://dev.to/mateuxcv</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/mateuxcv"/>
    <language>en</language>
    <item>
      <title>Most Developers Don't Care About Customer Health. That Used to Be Fine.</title>
      <dc:creator>Mateus Victor</dc:creator>
      <pubDate>Tue, 04 Aug 2026 14:23:50 +0000</pubDate>
      <link>https://dev.to/mateuxcv/most-developers-dont-care-about-customer-health-that-used-to-be-fine-3g85</link>
      <guid>https://dev.to/mateuxcv/most-developers-dont-care-about-customer-health-that-used-to-be-fine-3g85</guid>
      <description>&lt;p&gt;Every SaaS company runs health checks on its servers every 30 seconds. Ask the same company how often it checks customer health, and the answer is usually:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;During the monthly QBR, if someone remembers to pull the report.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Most developers don't think about customer health at all. It's not their problem. It lives in the CRM, which lives in the CS team's browser tab, which might as well be a different universe.&lt;/p&gt;

&lt;p&gt;Servers are engineering. Customers are someone else's spreadsheet.&lt;/p&gt;

&lt;p&gt;This made sense when the CS team was a cost center that sent renewal emails. It makes less sense now, when a customer who stops using your product costs you real money before they ever talk to a human.&lt;/p&gt;

&lt;p&gt;The line between "technical health" and "customer health" has blurred. We just didn't update our tools to match.&lt;/p&gt;

&lt;h2&gt;
  
  
  Developers Built Infrastructure for Everything Except Customers
&lt;/h2&gt;

&lt;p&gt;Here's what a typical SaaS engineering team monitors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;CPU, memory, and disk I/O&lt;/li&gt;
&lt;li&gt;Request latency, error rate, and throughput&lt;/li&gt;
&lt;li&gt;Deployment success rate&lt;/li&gt;
&lt;li&gt;Database connection pools&lt;/li&gt;
&lt;li&gt;Cache hit ratios&lt;/li&gt;
&lt;li&gt;Queue depth&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here's what nobody monitors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Whether a paying customer completed onboarding&lt;/li&gt;
&lt;li&gt;Whether a customer who used the product daily for three months suddenly went silent&lt;/li&gt;
&lt;li&gt;Whether a trial user who invited three teammates is stuck because they can't connect an integration&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These aren't soft metrics. They're leading indicators of revenue.&lt;/p&gt;

&lt;p&gt;A customer who doesn't activate doesn't renew. A customer who goes silent cancels. The data already exists in your product database, billing provider, and support inbox. Nobody wired it together.&lt;/p&gt;

&lt;p&gt;The reason isn't technical. It's cultural.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why Developers Ignore Customer Health
&lt;/h2&gt;

&lt;h3&gt;
  
  
  It Was Never Framed as an Engineering Problem
&lt;/h3&gt;

&lt;p&gt;Customer Success grew out of account management. The tools reflect that: CRMs, spreadsheets, and playbooks in Google Docs.&lt;/p&gt;

&lt;p&gt;The assumption was that humans would do the evaluation, so the tools optimized for recording what humans decided, not for computing what's actually true.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dashboards Are What the Market Built, Not What the Problem Needed
&lt;/h3&gt;

&lt;p&gt;A real-time graph of "monthly active users" looks great in a demo. A deterministic state machine that computes &lt;code&gt;customer_health = "at_risk"&lt;/code&gt; does not.&lt;/p&gt;

&lt;p&gt;One is visual. The other is invisible until it fires. The market optimized for what demos well.&lt;/p&gt;

&lt;h3&gt;
  
  
  It's Uncomfortable
&lt;/h3&gt;

&lt;p&gt;Server metrics are objective. CPU usage is CPU usage.&lt;/p&gt;

&lt;p&gt;Customer health requires defining what "healthy" means. Getting three people in a room to agree on that definition is harder than wiring up a Prometheus exporter.&lt;/p&gt;

&lt;p&gt;Developers gravitated toward the clean problem and left the messy one to the CS team.&lt;/p&gt;

&lt;p&gt;But the cost keeps going up. SaaS companies with product-led growth don't have a CSM assigned to every account. Nobody is manually checking whether trial users are activating.&lt;/p&gt;

&lt;p&gt;The product itself is the only thing watching. And right now, for most companies, the product isn't watching.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Customer Infrastructure Looks Like
&lt;/h2&gt;

&lt;p&gt;Your application already emits events:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;workspace.created&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;integration.connected&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;teammate.invited&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your billing provider fires:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;payment.succeeded&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;subscription.updated&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your support tool fires:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ticket.created&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ticket.resolved&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Customer infrastructure ingests those events and continuously computes derived state.&lt;/p&gt;

&lt;p&gt;Not a dashboard. &lt;strong&gt;State.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer #42: activated

integration.connected ✓
teammate.invited ✓
first_value_event ✓ (day 3)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer #43: onboarding

workspace.created ✓
integration.connected ✓
teammate.invited ✗ (7 days, no invite)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer #44: at_risk

was: activated
inactive for 14 days
last event: login, Aug 1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The answer exists before you ask the question.&lt;/p&gt;

&lt;p&gt;And it's deterministic. Given the same events and the same definition, you get the same answer every time.&lt;/p&gt;

&lt;p&gt;No ML model that was 87% confident the customer might be at risk. No dashboard that renders differently because someone clicked a different date range.&lt;/p&gt;

&lt;p&gt;A computation and a result.&lt;/p&gt;

&lt;p&gt;Those rules live in version control. When "at risk" changes from 14 days of inactivity to 21, that's a pull request: reviewed, tested, and deployed.&lt;/p&gt;

&lt;p&gt;The same pipeline as application code. Not a Slack message to the CS team, hoping everyone adjusts their mental model by Tuesday.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where I Landed
&lt;/h2&gt;

&lt;p&gt;I spent years in Customer Success before moving closer to engineering. One thing kept bothering me:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Application logic lived in Git repositories with pull requests and CI pipelines. Customer logic lived in spreadsheets with no version history and no way to know who changed what or when.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So I built &lt;strong&gt;Kite&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;It ingests events from your existing stack and continuously computes customer state from rules you write in TypeScript.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineLifecycle&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@kitesdk/config&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineLifecycle&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;new&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

  &lt;span class="na"&gt;states&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;activated&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;enteredWhen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;journey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;onboarding&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;complete&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;

    &lt;span class="na"&gt;at_risk&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;enteredWhen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;inactiveDays&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The workflow is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kite init
kite validate
kite deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It feels closer to shipping infrastructure than configuring a dashboard.&lt;/p&gt;

&lt;p&gt;If a customer isn't activated, the engine doesn't guess why. It reports exactly which conditions were satisfied, which were missing, and which events never arrived.&lt;/p&gt;

&lt;p&gt;Whether Kite is the right answer is almost beside the point. The idea that customer health should be computed continuously, not reconstructed every time someone opens a dashboard, is what I'm arguing for.&lt;/p&gt;

&lt;h2&gt;
  
  
  A Takeaway You Can Use Today
&lt;/h2&gt;

&lt;p&gt;You don't need Kite to start thinking this way.&lt;/p&gt;

&lt;p&gt;Pick one customer state your team talks about constantly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Healthy&lt;/li&gt;
&lt;li&gt;Activated&lt;/li&gt;
&lt;li&gt;At risk&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Write it as a boolean condition.&lt;/p&gt;

&lt;p&gt;Not "they seem engaged." Not "I think they're doing well."&lt;/p&gt;

&lt;p&gt;Write:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Activated =
  created workspace
  AND invited teammate
  AND connected integration within the first 7 days
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now show that definition to three people on your team and ask:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Does this match what you meant?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If they disagree, the problem isn't your tools. It's that your team has been using the same word to mean three different things.&lt;/p&gt;

&lt;p&gt;No dashboard fixes that.&lt;/p&gt;

&lt;p&gt;Infrastructure teams stopped querying server health manually years ago. They defined the rules once and let the system compute the answers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Your customers deserve a health check too.&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>productivity</category>
      <category>typescript</category>
      <category>webdev</category>
      <category>programming</category>
    </item>
    <item>
      <title>Your servers have a runtime. Your customers don't. That's the gap</title>
      <dc:creator>Mateus Victor</dc:creator>
      <pubDate>Thu, 30 Jul 2026 17:06:10 +0000</pubDate>
      <link>https://dev.to/mateuxcv/we-built-runtimes-for-infrastructure-why-not-for-customers-4j3a</link>
      <guid>https://dev.to/mateuxcv/we-built-runtimes-for-infrastructure-why-not-for-customers-4j3a</guid>
      <description>&lt;p&gt;&lt;strong&gt;Why the query model works for analytics and fails for customer health — and what a runtime model looks like in practice.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Most dev founders I know can tell you their p99 latency from memory. Far fewer can tell you how many paying customers got stuck in onboarding this week.&lt;/p&gt;

&lt;p&gt;That isn't because they care less about customers. It's because we built infrastructure around continuous evaluation while customer operations remained stuck in the query era.&lt;/p&gt;

&lt;p&gt;Every few seconds, Prometheus evaluates alerting rules against incoming metrics. CI pipelines execute automatically for every commit. Monitoring systems don't wait for someone to ask whether a service is healthy. They continuously compute the answer and notify you when something changes.&lt;/p&gt;

&lt;p&gt;Customer state works very differently. To understand where a customer is, someone opens an analytics dashboard, checks the CRM, compares billing information, and pieces together events from multiple systems. By the time an answer exists, it's already a snapshot of the past.&lt;/p&gt;

&lt;p&gt;The gap between infrastructure monitoring and customer monitoring isn't primarily a tooling problem. It's an architectural one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Two ways to answer a question
&lt;/h2&gt;

&lt;p&gt;There are two fundamentally different ways to answer questions about a system.&lt;/p&gt;

&lt;p&gt;The first is to execute a query when someone asks a question. The system retrieves historical data, computes the result, and returns an answer. This approach is ideal for exploratory analysis. If you want to know how many signups came from Germany during Q2 or which feature grew the fastest over the last month, running a query is exactly the right solution.&lt;/p&gt;

&lt;p&gt;I'll call this the &lt;strong&gt;query model&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;The second approach is to define the important states ahead of time and continuously evaluate them as new events arrive. Instead of computing an answer only when someone asks, the system keeps the answer up to date at all times.&lt;/p&gt;

&lt;p&gt;I'll call this the &lt;strong&gt;runtime model&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;By "runtime," I don't mean a programming language runtime. I mean a system that continuously evaluates business rules and maintains derived state from an incoming stream of events. Prometheus continuously evaluates alerting rules. CI pipelines continuously evaluate every new commit. A customer runtime follows the same idea.&lt;/p&gt;

&lt;p&gt;Neither model is universally better. They solve different problems.&lt;/p&gt;

&lt;p&gt;The query model excels at answering questions you couldn't predict in advance.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How many signups came from Germany last quarter?&lt;/li&gt;
&lt;li&gt;Which feature grew the fastest this month?&lt;/li&gt;
&lt;li&gt;Which pricing plan converted best?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The runtime model excels when the question has a stable definition and the answer is operationally important.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Is the database healthy?&lt;/li&gt;
&lt;li&gt;Did the deployment succeed?&lt;/li&gt;
&lt;li&gt;Is this service available?&lt;/li&gt;
&lt;li&gt;Is this customer activated?&lt;/li&gt;
&lt;li&gt;Is this customer at risk?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Those aren't questions you want to investigate manually every hour. You define the conditions once and let the system maintain the answer continuously.&lt;/p&gt;

&lt;p&gt;I think customer state belongs in this second category.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a customer runtime looks like
&lt;/h2&gt;

&lt;p&gt;Imagine you're trying to determine whether a customer has successfully activated.&lt;/p&gt;

&lt;p&gt;Your application already emits the relevant events.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;workspace.created&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;teammate.invited&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;integration.connected&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In a query based workflow, someone periodically checks whether each customer has completed those steps. The answer only exists at the moment the query runs. Tomorrow someone needs to repeat exactly the same process.&lt;/p&gt;

&lt;p&gt;In a runtime model, the rule is defined once.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;A customer becomes Activated after all three events have occurred.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;From that point on, the system watches incoming events continuously. The moment the final condition becomes true, the customer's state transitions to &lt;strong&gt;Activated&lt;/strong&gt;. Every consumer, whether it's an API, a dashboard, or an automation, reads exactly the same current state.&lt;/p&gt;

&lt;p&gt;This isn't a new architectural pattern. It's the same principle behind state machines, monitoring systems, and CI pipelines. A finite set of inputs produces a deterministic state. New input arrives. State changes. Everyone reads the current truth.&lt;/p&gt;

&lt;p&gt;We already use this pattern throughout software infrastructure. We just haven't applied it consistently to customer operations.&lt;/p&gt;

&lt;h2&gt;
  
  
  Building a customer runtime
&lt;/h2&gt;

&lt;p&gt;If you wanted to build this yourself, the architecture is surprisingly straightforward.&lt;/p&gt;

&lt;p&gt;First, you need an event ingestion layer. Your product, CRM, billing provider, and support platform already emit events through webhooks. Receiving them isn't difficult. The real challenge is normalizing those events into a consistent schema that business rules can understand.&lt;/p&gt;

&lt;p&gt;Next comes a deterministic rules engine. Every incoming event is evaluated against the rules that depend on it. A completed onboarding step might update activation status, lifecycle stage, health score, and several other pieces of derived state at the same time.&lt;/p&gt;

&lt;p&gt;Determinism is essential. Given the same sequence of events and the same rule definitions, the engine should always compute exactly the same result. Without determinism, debugging becomes difficult, versioning becomes unreliable, and trust disappears.&lt;/p&gt;

&lt;p&gt;The output isn't another dashboard. It's computed state.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Customer 42 → Activated
Customer 43 → Onboarding
Customer 44 → At Risk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each state should include evidence showing which conditions were satisfied, which weren't, and which events produced the result.&lt;/p&gt;

&lt;p&gt;Finally, those rules need versioning. Customer definitions change over time. Maybe activation requires one more onboarding step. Maybe an at risk customer becomes inactive after 21 days instead of 14. Those changes are business logic, and business logic deserves the same lifecycle as application code. It should be reviewed, tested, deployed, and rolled back through the same engineering workflow.&lt;/p&gt;

&lt;p&gt;None of this requires inventing a new architectural pattern. It's simply event driven state computation applied to a problem that has traditionally been solved with dashboards.&lt;/p&gt;

&lt;h2&gt;
  
  
  Where I landed
&lt;/h2&gt;

&lt;p&gt;I spent years working in Customer Success before moving closer to engineering. One contrast became impossible to ignore.&lt;/p&gt;

&lt;p&gt;Application logic lived in Git repositories, pull requests, and CI pipelines.&lt;/p&gt;

&lt;p&gt;Customer logic lived in spreadsheets, drag and drop builders, and undocumented processes.&lt;/p&gt;

&lt;p&gt;Infrastructure evolved toward deterministic systems.&lt;/p&gt;

&lt;p&gt;Customer operations evolved toward dashboards.&lt;/p&gt;

&lt;p&gt;That observation led me to build Kite.&lt;/p&gt;

&lt;p&gt;Kite ingests events from existing systems and continuously computes customer state from rules written in TypeScript.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;defineLifecycle&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;@kitesdk/config&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nf"&gt;defineLifecycle&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;initialState&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;new&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

  &lt;span class="na"&gt;states&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;activated&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;enteredWhen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;journey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;onboarding&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;status&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;complete&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;

    &lt;span class="na"&gt;at_risk&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;enteredWhen&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;inactiveDays&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;14&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The workflow feels closer to shipping infrastructure than configuring a dashboard.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kite init
kite validate
kite deploy
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The engine is deterministic. If a customer isn't activated, it doesn't estimate why. It reports exactly which conditions were satisfied, which were missing, and which expected events never arrived.&lt;/p&gt;

&lt;p&gt;AI has a limited role. It helps explain missing instrumentation and surface patterns. It never invents evidence or becomes the source of truth.&lt;/p&gt;

&lt;p&gt;Whether Kite is the right implementation is almost beside the point. The architectural idea is what interests me most. Customer state feels like something that should be computed continuously instead of reconstructed every time someone opens a dashboard.&lt;/p&gt;

&lt;h2&gt;
  
  
  A takeaway you can use today
&lt;/h2&gt;

&lt;p&gt;You don't need a runtime to start thinking this way.&lt;/p&gt;

&lt;p&gt;Start by defining your customer states explicitly.&lt;/p&gt;

&lt;p&gt;Most organizations don't actually have a formal definition of concepts like &lt;strong&gt;Healthy Customer&lt;/strong&gt;, &lt;strong&gt;Activated Customer&lt;/strong&gt;, or &lt;strong&gt;At Risk Customer&lt;/strong&gt;. They have shared intuition.&lt;/p&gt;

&lt;p&gt;If three people on your team define activation differently, then activation isn't a definition. It's an opinion.&lt;/p&gt;

&lt;p&gt;Write your customer states as deterministic conditions.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Activated = &lt;code&gt;workspace.created&lt;/code&gt; AND &lt;code&gt;teammate.invited&lt;/code&gt; AND &lt;code&gt;integration.connected&lt;/code&gt; within the first seven days.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You can still evaluate that definition manually if necessary. The important change is that you've transformed an implicit idea into explicit business logic.&lt;/p&gt;

&lt;p&gt;Once the definition exists, automation becomes an implementation detail instead of a design problem.&lt;/p&gt;

&lt;p&gt;Infrastructure stopped querying server health years ago. We defined the rules once and let systems compute the answers continuously.&lt;/p&gt;

&lt;p&gt;I think customer state deserves the same treatment.&lt;/p&gt;




</description>
      <category>architecture</category>
      <category>typescript</category>
      <category>devops</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
