Build notes › topic
Reliability
One failure wearing different clothes: something reporting success for work it had not done. What each one quietly cost, and the checks added so the next one fails loudly.
Covered here: self-deployed WhatsApp CRM · 7-star customer experience · AI contact enrichment · catalog_management scope · catalogue sync · Cloudflare Queues dead letter queue · consent keyword collision · consent management · conversation list polling · conversation transcript ordering
-
28 August 2026 · commerce
Building a WhatsApp catalogue that tells the truth
Meta's catalogue batch endpoint returns HTTP 200 even when every item was rejected. The script we wrote specifically to verify a token could write reported success against a catalogue that was empty and had always been empty. Eleven bugs from three weeks of building catalogue and product infrastructure, almost all of the same shape: something reporting success for work it had not done. Includes a paywall that only worked while the feature was switched off, a complete edit endpoint with no button behind 5,187 passing tests, and the two calls we got wrong ourselves.
-
19 August 2026 · updated 21 August 2026 · AI architecture & roadmap
Klaros WhatsApp Autonomous AI Agent: To-Be Architecture for a 7-Star Experience
A candid developer architectural roadmap challenging our own past design decisions, now carrying a correction. The hybrid sparse-dense retrieval this note proposed had already been written and registered ahead of every other strategy, and it had never executed once: the Cloudflare Vectorize binding it depended on does not exist on the worker, so every request took its fallback branch and re-served plain BM25 while reporting success. The audit that found it also found the real defect, which was more mundane and worse: ingest deletes the 173 question-and-answer pairs the site publishes in its own structured data, then asks a ranking function to reconstruct them from the prose. Dense retrieval is deferred in favour of contextual BM25 and reranking.
-
13 August 2026 · conversational AI
The WhatsApp auto-reply that answered a hello with a price list
A contact of five weeks typed “Hello” and received an explanation of our licensing. The model was not hallucinating: the thread query selected the oldest 40 rows of a 46-message conversation, so it was shown messages 21 to 40 and never saw the greeting it was answering. Every timestamp had been stripped too, so a pricing exchange from three weeks earlier read as the previous turn. Investigating one bad reply surfaced seven more ways the same assistant was failing to listen, including voice notes answered with total silence, “cancel my order” recorded as an unsubscribe, and a customer who asked to speak to a person and was ignored twice.
-
10 August 2026 · performance
The WhatsApp inbox skeleton that made things worse
Shimmer skeleton loaders replaced stale content during WhatsApp conversation filter switches. But
loadConversations()was a zero-argument function called from 30 sites, including the background poll that checks for new webhook deliveries. The skeleton fired on every poll, flashing every 5 seconds, but only on inboxes smaller than the page size: exactly the state a shop starts in after completing Meta's Embedded Signup. The fix was one parameter: 9 user-initiated call sites pass{ skeleton: true }; the ~20 incremental updates (resolving, assigning, sending templates) and the poll do not. -
8 August 2026 · consent
The WhatsApp opt-out that almost got a sales pitch
We sell Klaros inside a WhatsApp thread, which puts our own sales code in the same inbound path that decides whether somebody's opt-out gets recorded. The pricing intent matches
pricing; "stop sending me pricing" contains it. And because a handled sales message suppresses the consent check, losing that fight would not have meant a tactless reply. It would have meant the opt-out was never recorded at all. The guard, the same rule applied four times, and the gap we found while writing this: a politely worded opt-out is still heard by nobody. -
7 August 2026 · engineering
The WhatsApp business cards that started asking for money
Two features wanted the same short URL prefix, and the newer one was mounted first. For five days, scanning any of our free digital business cards returned "This payment link is not valid." Why neither route could move (one URL is fixed inside an approved Meta template, the other is printed on paper), the three-line fallthrough that fixed it, the passing test that was quietly asserting the bug, and the telemetry blind spot that means we can never count who saw it.
-
6 August 2026 · engineering
The WhatsApp contacts we silently stopped scoring
Our own health check found 68 dead-lettered enrichment messages, 100% one type, lined up exactly with two nights of the nightly cron. The cause was three
UPDATEstatements writing to agraph_contactscolumn that never existed. What broke, what it quietly cost every contact that should have been scored, and the regression tests we proved could catch the bug before trusting them, by reintroducing it first. -
31 July 2026 · engineering
The WhatsApp CRM billing we fixed before charging anyone
A jeweller pays for three WhatsApp lines and silently receives one. She does not complain. She decides the software is small, and six weeks later she does not renew. That was a real defect in our code, and four others sat beside it, unnoticed because no money had ever moved through the system that held them. What we found in the room where the money moves, the two forks where the flattering answer lost, and the tool that now checks what we charge against what we publish.
-
In progress
The half of a sale that nobody demos
Every platform shows you the payment landing. Almost none show you the twenty minutes afterwards: who gets told, who packs it, what the buyer hears while they wait, and what happens when it ships four days later and the messaging window has closed.
-
In progress
Where the ask ends and the shop begins
A payment request is messaging machinery. A product library is a commerce application, and the part most likely to be replaced by a real one. On finding that seam in our own code, and making it a documented extension point instead of a function that happened to sit in the middle of a file.
-
In progress
What a feature looks like when nothing consumes it
Contact limits computed on every request and enforced nowhere. A tier ladder that is marketing copy at runtime. On the difference between building a capability and shipping one, found in our own codebase.
Get the next one on WhatsApp
Message the line and type NOTES. The latest one comes straight back, in the same thread, from the number that sends everything else. Reply STOP whenever you like and it stops.
Send NOTES on WhatsAppAsk our WhatsApp number what it costs
The most honest demo we have is the purchase itself. Message the line and type pricing: you will get our live catalog as a WhatsApp list, real remaining slots, and a payment link on whatever you tap. Buy the self-deployed licence and your signed key arrives in the same thread, for infrastructure we cannot reach. You are experiencing the product before you own it.
+91 97893 77634 · you message first, so nothing reaches you without your say-so.
