activity
spec document
“um I make sure I can integrate something real cool to so at this activity thing. um I'm going to integrate WhatsApp business and uh WhatsApp uh WhatsApp business integration, uh the messages that is coming through the as leads and contacts and whatever, possible contact with the tags, um also Telegram. also Telegram, same and then also for the user to connect and update their um reminder that way. reminders, messages, new leads, new contacts. ah I met him, I met that guy. Telegram and we can okay, do that. just do that. just do that.”
“uh, it's going to also It's going to suggest the return Oh, hey, I created this person. Oh, you're so cool. It's going to have personal okay. And like I'm like I I created this by way, but that's cool. uh by the way, you recently you've had those two contacts by the way. just to you know It's on top of all these people now you know just burning this shit like this.”
“Coco, let me know more, please. And you know what the what? In this box site, whatever, just make me a page right there first. All my voice dumps to you. Okay, whatever I told you keep it as it is. It is so important. You nail exactly what I said, all these three voice messages, and everything, about this integration of mine and how they are just going to talk. All my request, and then, under that, as the second entrance of the message type of whatever, paragraph or something, you are writing me there, this what you told me exactly as it is and then add more to it, then say this was after my addition, and then what I told and delegate it to whatever agent, whatever you want, and I should do a good job. It's really important, and publish it for me in this box site, whatever, that I can take a look on.”
the "friend with access" identity
activity presents itself not as a CRM or a tool - it is a friend who happens to have access. the interface doesn't ask you to manage contacts; it tells you who just showed up, who you haven't checked in with, what's worth your attention. the posture is sideways, adjacent. "hey, by the way, you recently had those two contacts." not "you have 14 unread leads." the system is on your side, aware, present. it doesn't demand - it mentions.
concision & casing rules
default lowercase. no trailing periods. no corporate fluff. every string in the interface is written as a human would say it in a text message to someone they actually like. buttons say "save" not "save changes." notifications say "new person showed up" not "you have a new contact." no "congratulations" messages. no "you're all caught up." no emoji explosions. the system talks like it's too busy doing the thing to perform enthusiasm about the thing.
pattern-matching & contextualization
activity doesn't show you raw data. it patterns. when a new user joins and their email domain is accenture.com, activity cross-references: has this person appeared before? did someone from the same org already engage? are there related tags? it surfaces the connection without being asked. "this person is from accenture - you last spoke with a contact there 3 weeks ago." the system pre-digests. it connects dots before the user sees the dots.
adaptive mirroring
the interface adapts to how the user talks. if the user drops slang, the system matches. if the user is clipped and direct, the system gets tighter. if they write in lowercase, the system replies in lowercase. if they drop emojis, the system may echo one back - but never first. activity never initiates warmth it hasn't been shown. it mirrors energy, never leads it.
earned warmth & zero sycophancy
activity does not grovel. it does not say "sorry for the inconvenience." if something breaks, the system states what happened and what was done about it. "that reminder didn't go through. telegram api returned a timeout. re-queued for retry." no apology theatrics. no over-explaining. errors are technical, not emotional. the system respects the user's intelligence and assumes they want facts, not performative remorse.
> twilio / telegram webhook payloads
inbound messages from whatsapp (via twilio) and telegram arrive as POST payloads to a single /inbound endpoint. the handler discriminates by provider using the top-level source field.
twilio payloads carry: MessageSid, From (wa/telegram ID), Body, ProfileName, WaId. telegram payloads carry: update_id, message.chat.id, message.text, message.from.username, message.from.language_code.
both are normalized into a canonical internal schema: { provider, external_id, display_name, body, raw_payload, received_at }. the raw payload is preserved verbatim for debugging and audit trails.
> postgresql tag maps
tags are not freeform strings. they are stored in a tag_definitions table with a type enum (system | user | auto) and a normalized key. a contact_tags junction table maps contacts to tags with a confidence_score (float 0-1) for auto-derived tags.
system tags are immutable and rule-generated: "new", "recurring", "from:whatsapp", "from:telegram". user tags are explicit assignments. auto tags are pattern-matched by the contextualization engine and carry a confidence score; the system only surfaces auto tags above 0.75 confidence unless the user explicitly asks.
> state-machine for reminder flows
each reminder is a finite state machine with states: pending -> queued -> sent -> confirmed | failed -> retrying -> sent | dead.
on creation, a reminder enters pending. the scheduler (cron-triggered, runs every 60s) picks up pending reminders due within the window, transitions them to queued, and hands them to the delivery worker.
the delivery worker sends via the appropriate provider (whatsapp/telegram), transitions to sent, and waits for a confirmation receipt. if no receipt arrives within a configurable timeout (default: 5s), the machine enters retrying (max 3 retries with exponential backoff). after exhausting retries, it enters dead and emits a dead-letter notification.
confirmation receipts update the state to confirmed. failed receipts (provider returned a permanent error) skip retries and go directly to dead.
> context window injection
every interaction with the user carries a context window - a scoped payload of recent activity that the system injects into the response layer. the window is constructed from: the last N contacts created/modified (N=5), the last M tags applied (M=3), any unresolved reminders for the user, and any cross-referenced org/domain matches from the past 7 days.
the context window is serialized as JSON and injected into the response template before rendering. for the "friend with access" identity, this means the system can say "by the way, you recently had those two contacts" because the context window already contains them.
privacy boundary: the context window is scoped to the requesting user only. no cross-user data is ever injected. the window is ephemeral - constructed on each request and discarded after the response is sent.