Business logic
This module is the answer to "why did the system do that?". Every page describes rules that are implemented in code, with the thresholds, formulas, and suppression conditions spelled out and the implementing file named.
The proposition
Payability advances marketplace sellers their revenue ahead of the platform’s payout cycle. A seller who is growing, holds a lot of inventory, and waits two weeks for Amazon to pay feels that gap acutely. Morpheus exists to find those sellers, prove they are worth a call, and put them in front of a human at the moment a call is most likely to land.
Three judgements drive everything:
-
Is this seller in the ideal customer profile? — revenue band, category, marketplace. Decided at discovery.
-
How acutely do they feel payout pain? — the payout-pain score, 0–100. Decided by an AI pass over structured seller data and enrichment notes.
-
Is now the right moment to call? — re-engagement segmentation and priority. Decided every few hours from CRM engagement data.
Rule pages
| Page | What it decides |
|---|---|
The end-to-end lifecycle from marketplace row to booked demo, and which component owns each transition |
|
Which sellers enter the pipeline: ICP bounds, pagination, the kill switch |
|
How contact intelligence is gathered and written back, and what is skipped |
|
The eight signals and weights behind |
|
How sellers become HubSpot Companies and contacts become HubSpot Contacts, and the search priority for matching |
|
The five segments that surface a contact for another call, with each priority formula |
|
How today’s list is assembled, prioritised, and materialised in HubSpot |
|
Task creation, HubSpot mirroring, the three-stage Slack escalation ladder |
|
Reply categorisation, engagement events, opt-outs and suppression |
|
Line-type classification, risk tiers, and automatic blocking |
|
AI dialer and Five9 call sync, disposition mapping, lifecycle promotion |
|
Who a contact gets assigned to, and when ownership is overridden |
Cross-cutting rules
These hold everywhere and are not repeated on each page.
- Single tenant, explicitly checked
-
Production runs one subscription,
b191a905-5d19-4fa0-941b-d8eb81c0c477. Handlers that receive asubscription_idon the event compare it to their configured value and drop mismatches.email-agentinstead derives the tenant from the row it loaded. See tenant isolation. - Idempotence over exactness
-
Every write is designed to be safely repeatable —
ON CONFLICT DO UPDATEupserts on natural keys, find-or-create for contacts, "already done" guards onenrichedAtandpayoutPainScore. A handler that runs twice must not double anything that matters. - Suppression beats enrolment
-
When a suppression rule and an enrolment rule both apply, suppression wins. Blocked dispositions, do-not-contact reasons, open deals, and "called today" checks all remove a contact from a segment before any priority is computed.
- US Eastern is the business day
-
"Today" for call lists means the calendar date in US Eastern, approximated as UTC−4 in code. The daily list refresh runs at 6 AM ET, an hour at which EDT and EST agree on the date, so the fixed offset is safe there. Handlers that run around midnight UTC can disagree with a true
America/New_Yorkdate by an hour during EST. - Ownership is sticky, except when it is not real
-
A contact keeps its owner. Reassignment happens only when there is no owner, the owner is the AI fallback owner (
86817215), or the owner is not an activesales_repsrow. See Ownership and round-robin. - AI output is validated, never trusted raw
-
Every agent that produces data uses Strands structured output with a Pydantic model. Nothing parses JSON out of free-form model text.