Fionn
AI-Powered Renewal Management System — Architecture Document
1. System Overview
Fionn is an AI-based software renewal management system that automates the end-to-end renewal lifecycle — from initial customer outreach through final contract closure. It operates across multiple integrated platforms to identify upcoming renewals, engage customers via intelligent email conversations, track renewal stages, and provide real-time operational visibility through a management dashboard.
Fionn replaces manual renewal management with an autonomous AI agent that handles outreach, follow-ups, sentiment analysis, pricing, quoting, and stage progression — all while maintaining strict communication discipline and contract rules.
Core Principles
- Fully autonomous — Fionn handles outreach, replies, reminders, and escalations without human intervention in standard cases
- Asynchronous communication only — all customer engagement happens via email; no calls, no meetings
- Contract discipline — pricing, terms, and contract structures are enforced programmatically
- Stage-driven progression — every opportunity follows a defined renewal pipeline with clear transition rules
- Real-time visibility — a dedicated dashboard surfaces pipeline health, AI assessments, and email activity
2. High-Level Architecture
graph TB
subgraph Fionn System
SF["Salesforce<br/>(Trilogy Sales + No Software Speed)"]
CC["CuChulainn<br/>AI Engine<br/>4 Packages · 14 Skills · 1 Agent"]
DASH["Fionn Dashboard<br/>Frontend · Backend · Storage"]
end
subgraph External Systems
KLAIR["Klair<br/>NetSuite Data"]
KAYAKO["Kayako<br/>Support Tickets"]
OPENAI["OpenAI<br/>GPT-5.3-instant"]
GAS["Google Apps Script<br/>Email Routing"]
end
SF <--> CC
CC <--> DASH
SF <--> DASH
CC --> KLAIR
CC --> KAYAKO
CC --> OPENAI
GAS --> CC
OPENAI --> DASH
CUSTOMER["Customer<br/>Email Inbox"] <--> GAS
CC --> CUSTOMER
3. Component Architecture
3.1 CuChulainn — AI Execution Engine
CuChulainn is the core AI platform that powers Fionn's autonomous operations. It provides the runtime for AI packages, each containing workflows, skills, and agents.
graph LR
subgraph CuChulainn Platform
GO["GeneralOutbound<br/>First contact with customer"]
GI["GeneralInbound<br/>Reply to every inbound email"]
RP["ReminderPackage<br/>Follow-up + find more users"]
EI["EmailInvestigator<br/>Find alternate emails"]
SA["SalesforceAgent<br/>6 Salesforce skills"]
SK["14 Shared Skills<br/>API endpoints"]
end
GO --> SK
GI --> SK
RP --> SK
EI --> SK
GO --> SA
GI --> SA
RP --> SA
EI --> SA
3.2 Fionn Dashboard — Operational Visibility Layer
The dashboard provides real-time pipeline visibility, AI health assessments, and operational controls.
| Component | Technology | Purpose |
|---|---|---|
| Frontend | S3 + CloudFront | Static HTML/JS/CSS dashboard |
| API Backend | AWS Lambda (fionn-dashboard-api) | REST API for dashboard operations |
| Sync Engine | AWS Lambda (fionn-dashboard-sync) | Daily Salesforce data sync + AI refresh |
| Auto-Trigger | AWS Lambda (fionn-auto-trigger) | Scheduled outbound triggers + smart reminders |
| Primary Store | DynamoDB (FionnDashboard) | Opportunity data, AI status, flags, notes, defer state |
| Email Logs | DynamoDB (FionnEmailLogs) | Email conversation history |
| Product Config | DynamoDB (FionnProductConfig) | Product-to-project mappings and aliases |
| CDN | CloudFront (E22HOIROU34E4P) | Global content delivery + API routing |
| API Gateway | HTTP API (o61t89e1x1) | REST endpoint routing |
3.3 Scheduled Processes
Three scheduled processes run via AWS EventBridge:
| Schedule | Lambda | Cron | Purpose |
|---|---|---|---|
| Daily Sync | fionn-dashboard-sync | cron(0 6 * * ? *) (6 AM UTC) | Salesforce data sync + AI status refresh |
| Auto-Trigger | fionn-auto-trigger | cron(0 14 * * ? *) (2 PM GMT) | Auto-trigger Fionn at ≤180 days, auto-reminders for stale Pending opps |
4. CuChulainn Packages — Detailed Flows
4.1 GeneralOutbound
Purpose: First contact with the customer when a renewal is approaching.
Trigger: Dashboard trigger (manual or auto-trigger at ≤180 days to renewal).
Package ID: PACKAGE-d3a9354c-3d3e-4edd-9494-c55898403852 (common for all products)
flowchart LR
T["Trigger<br/>(Manual or Auto)"] --> FETCH["Fetch Opportunity<br/>from Salesforce"]
FETCH --> KLAIR["Get NetSuite<br/>Contract Data"]
KLAIR --> COMPOSE["AI Composes<br/>Outreach Email"]
COMPOSE --> SEND["Send Email<br/>to Customer"]
SEND --> LOG["Log to<br/>FionnEmailLogs"]
LOG --> UPDATE["Update Opp Stage<br/>→ Outreach"]
Key behaviors
- Retrieves full contract context from NetSuite via Klair before composing
- Email is AI-generated, warm, professional, and product-aware
- Never mentions pricing, internal IDs, or meeting requests in first outreach
- Marks opportunity as
FionnTriggered = Yesin DynamoDB
4.2 GeneralInbound
Purpose: Process and respond to every inbound customer email related to a renewal.
Trigger: Google Apps Script routes inbound email to CuChulainn.
flowchart LR
IN["Inbound Email<br/>via Apps Script"] --> PARSE["Parse Email<br/>+ Thread Context"]
PARSE --> ANALYZE["AI Sentiment<br/>Analysis"]
ANALYZE --> DECIDE["Determine<br/>Response Strategy"]
DECIDE --> REPLY["AI Composes<br/>Reply"]
REPLY --> SEND["Send Reply<br/>to Customer"]
SEND --> STAGE["Update Stage<br/>if Needed"]
Key behaviors
- Maintains full thread context for coherent conversations
- Detects customer sentiment and adjusts tone accordingly
- Escalates to human when customer explicitly requests it
- Progresses stage automatically when conversation milestones are reached
4.3 ReminderPackage
Purpose: Follow up when no customer response has been received. Discovers and adds additional contacts to widen the outreach net.
Trigger: Auto-trigger (daily at 2 PM GMT for Pending opps with no reply in 5+ days) or manual dashboard trigger.
Package ID: PACKAGE-9dc9897a-3d92-4dc1-b7c6-ddd3591a74e8
flowchart LR
CHECK["Check Last<br/>Mail Date"] --> DEFER{"Defer Signal<br/>Detected?"}
DEFER -->|Yes| PAUSE["Pause Until<br/>Follow-up Date"]
DEFER -->|No| CONTACTS["Find Additional<br/>Contacts"]
CONTACTS --> COMPOSE["AI Composes<br/>Follow-up"]
COMPOSE --> SEND["Send Reminder<br/>Email"]
SEND --> LOG["Log + Update<br/>Reminder Count"]
Key Differentiator: Actively searches for additional contacts beyond Salesforce, broadening reach when the original contact is unresponsive.
4.4 EmailInvestigator
Purpose: Find alternate email addresses when delivery fails or the primary contact is unreachable.
Trigger: Called by other packages when email bounces or no response after multiple reminders.
flowchart LR
BOUNCE["Delivery Failure<br/>or No Response"] --> SEARCH["Search Kayako<br/>+ Other Systems"]
SEARCH --> VALIDATE["Validate Found<br/>Addresses"]
VALIDATE --> UPDATE["Update Contact<br/>in Salesforce"]
UPDATE --> RETRY["Retry Outreach<br/>with New Address"]
5. Automated Trigger & Reminder System
The system runs autonomously at 2:00 PM GMT daily via the fionn-auto-trigger Lambda.
5.1 Auto-Trigger Rules
| Rule | Condition | Action |
|---|---|---|
| Auto-Trigger Outbound | ≤180 days to renewal AND not yet triggered AND not closed/finalizing | Calls Fionn outbound API, marks FionnTriggered = Yes, AutoTriggered = true |
| Auto-Send Reminder | Stage is "Pending" AND already triggered AND last mail direction is outbound AND 5+ days since last mail | Analyzes emails for defer → if no defer, sends reminder |
5.2 Smart Defer Detection
Before sending any auto-reminder, the system analyzes the last 5 emails using GPT-5.3-instant to detect defer signals from the customer.
Detected signals include
- "It's too early, let's discuss later"
- "We will follow up in June"
- "Let's reconnect after Q2"
- "Can we discuss this on March 25?"
- "We're not ready yet, please reach out in 3 months"
When a defer is detected
- GPT extracts the follow-up date (converts relative dates like "in 2 weeks" to actual dates)
ReminderPausedUntilis stored in DynamoDB with the extracted dateDeferReasoncaptures the customer's statement- Reminders are suppressed until the follow-up date
- When the date arrives, reminders automatically resume
flowchart TB
AUTO["Auto-Trigger<br/>2 PM GMT Daily"] --> SCAN["Scan All<br/>Open Opportunities"]
SCAN --> TRIGGER{"≤180 Days<br/>& Not Triggered?"}
TRIGGER -->|Yes| OUTBOUND["Call Fionn<br/>Outbound API"]
TRIGGER -->|No| PENDING{"Pending Stage<br/>& 5+ Days Stale?"}
PENDING -->|Yes| PAUSED{"Reminder<br/>Paused?"}
PAUSED -->|Yes, Future| SKIP["Skip — Wait for<br/>Follow-up Date"]
PAUSED -->|No or Expired| ANALYZE["AI Analyzes<br/>Recent Emails"]
ANALYZE --> DEFER{"Defer Signal<br/>Found?"}
DEFER -->|Yes| STORE["Store Pause Date<br/>+ Reason"]
DEFER -->|No| REMIND["Send Reminder<br/>via ReminderPackage"]
PENDING -->|No| NEXT["Next Opportunity"]
5.3 Manual Pause/Resume
The dashboard provides manual controls to pause or resume reminders:
- Pause — Set a specific follow-up date and reason from the dashboard
- Resume — Clear any existing pause immediately
- API endpoint:
POST /reminder-pausewith{action: 'pause'|'resume', opportunityId, pauseUntil?, reason?}
6. Skills Reference
All skills are shared across packages. Each skill is an API endpoint performing one atomic task.
| # | Skill Name | Description |
|---|---|---|
| 1 | send_email_fionn | Send email from Fionn mailbox to customer |
| 2 | get_sf_details | Get full opportunity details from Salesforce |
| 3 | update_sf_stage | Update opportunity stage in Salesforce |
| 4 | get_klair_contract | Fetch NetSuite contract data via Klair |
| 5 | get_klair_pricing | Fetch pricing and subscription details |
| 6 | search_kayako_tickets | Search Kayako for support history |
| 7 | get_kayako_contacts | Find alternate contacts from Kayako |
| 8 | pull_andon_cord_fionn | Emergency stop — halts all processing |
| 9 | get_sf_contact_roles | Get contact roles for an opportunity |
| 10 | update_sf_contact | Update contact information in Salesforce |
| 11 | search_sf_accounts | Search Salesforce accounts by criteria |
| 12 | get_email_thread | Retrieve full email thread history |
| 13 | validate_email | Validate email address deliverability |
| 14 | log_activity | Log activity to FionnEmailLogs DynamoDB table |
7. Agents Reference
| Agent | Skills Used | Purpose |
|---|---|---|
| SalesforceAgent | get_sf_details, update_sf_stage, get_sf_contact_roles, update_sf_contact, search_sf_accounts, log_activity | Manages all Salesforce interactions with AI intelligence to decide which data to fetch/update |
8. Renewal Pipeline — Stage Progression
The renewal lifecycle follows a strict sequential pipeline. Fionn manages transitions automatically based on conversation state.
flowchart LR
P["Pending"] --> O["Outreach"]
O --> E["Engaged"]
E --> PR["Proposal"]
PR --> QF["Quote Follow Up"]
QF --> F["Finalizing"]
F --> CW["Closed Won"]
F --> CL["Closed Lost"]
Stage Definitions
| Stage | Meaning | Typical Timeline |
|---|---|---|
| Pending | Renewal identified, no outreach yet | >180 days |
| Outreach | Initial email sent, awaiting response | 180–145 days |
| Engaged | Customer is actively responding | 145–90 days |
| Proposal | Quote or proposal shared | 90–60 days |
| Quote Follow Up | Awaiting customer decision on quote | 60–30 days |
| Finalizing | Contract in final closing stage (treated as closed) | 30–0 days |
| Closed Won | Renewal completed successfully | — |
| Closed Lost | Customer chose not to renew | — |
Stage Treatment
- Finalizing is treated as a closed stage — it is excluded from "open" counts, does not trigger reminders, and receives a deterministic GREEN AI signal
- Finalizing can result in either Closed Won or Closed Lost
9. Data Flow — End to End
graph TB
subgraph External Data Sources
SF_TS["Salesforce: Trilogy Sales<br/>Fionn AI owned opportunities"]
SF_NS["Salesforce: No Software Speed<br/>Renewal data · ARR · Stages"]
end
subgraph AI Services
OAI["OpenAI GPT-5.3-instant<br/>AI status · Summaries · Defer analysis"]
end
subgraph Fionn Core
CC["CuChulainn<br/>4 Packages"]
LAMBDA_SYNC["Lambda: Sync<br/>Daily 6 AM UTC"]
LAMBDA_API["Lambda: API<br/>Dashboard backend"]
LAMBDA_AUTO["Lambda: Auto-Trigger<br/>Daily 2 PM GMT"]
DDB["DynamoDB<br/>Opportunities · Emails · Config"]
DASH["Dashboard UI<br/>S3 + CloudFront"]
end
SF_TS --> LAMBDA_SYNC
SF_NS --> LAMBDA_SYNC
LAMBDA_SYNC --> DDB
LAMBDA_SYNC --> OAI
DDB --> DASH
DASH --> LAMBDA_API
LAMBDA_API --> CC
LAMBDA_AUTO --> CC
LAMBDA_AUTO --> OAI
LAMBDA_AUTO --> DDB
Data Sync Process (Daily + On-Demand)
- Trilogy Sales query — Fetch all Fionn AI-owned opportunity IDs via SOAP API
- No Software Speed query — Fetch renewal data (ARR, stage, dates) for those IDs via REST API
- Email log merge — Fetch from FionnEmailLogs DynamoDB + legacy mail tracking API
- Safe upsert — Write to DynamoDB preserving protected fields (triggers, reminders, flags, notes, AI status, defer state)
- Stale cleanup — Remove records no longer in Salesforce
- AI refresh — Generate/update AI health status for all open opportunities
- DaysSinceLastMail — Recalculated in real-time on every API response (not stored stale)
10. Dashboard Features
10.1 Hierarchical Table View
Opportunities are organized in a collapsible hierarchy:
All groups are collapsed by default. Expand All / Collapse All toggle is available. A second "Flat View" tab shows all opportunities without grouping.
10.2 Per-Opportunity AI Status
Each opportunity has an AI-generated health assessment powered by GPT-5.3-instant:
| Signal | Meaning | Criteria |
|---|---|---|
| 🟢 GREEN | On Track | Stage matches or ahead of timeline, active communication |
| 🟡 YELLOW | Attention | Stage slightly behind, or communication stalled >14 days |
| 🔴 RED | At Risk | Stage significantly behind, no outreach when overdue, or customer expressed intent to cancel |
AI status is refreshed:
- Daily — automatically after sync
- On demand (single) — click refresh icon next to any opportunity
- On demand (bulk) — click "Refresh All AI" in toolbar (with progress polling)
10.3 AI Status Click-to-Expand
Clicking an AI signal expands an inline detail panel below that opportunity showing:
- Color-coded signal badge (On Track / Attention / At Risk)
- Full AI-generated summary text
- Last updated timestamp
10.4 Smart Reminder Controls
Each opportunity's reminder column shows contextual controls:
- Active — "Remind" button + pause (⏸) button to manually set a follow-up date
- Deferred (AI-detected) — Green badge with follow-up date + resume (▶) button
- Deferred (Manual) — Blue badge with follow-up date + resume (▶) button
- Expired pause — "Remind" button reappears + clear (✕) button
10.5 KPI Cards & Running Totals
| Metric | Description |
|---|---|
| Urgent (<30d) | Open opportunities within 30 days of renewal |
| Upcoming (30-90d) | Open opportunities 30-90 days from renewal |
| Fionn Triggered | Total opportunities with outbound initiated |
| Emails Sent | Total email count across all opportunities |
| Deferred | Opportunities with paused reminders (AI or manual) |
| Running ARR | Dynamic ARR total in toolbar, updates with filters |
10.6 Additional Features
- Sync Health — Trilogy Sales count vs Dashboard count, missing opportunity tracking
- Email History — Full conversation thread per opportunity with HTML rendering, quoted replies, signatures; external images stripped for tracking pixel protection
- Notes — Internal notes per opportunity with timeline view and delete
- Flags — Flag at-risk opportunities for visibility
- PDF Reports — Filtered renewal reports with AI executive summary, cover page with stage breakdown, timeline, legend; loading indicator prevents double-clicks
- CSV Export — Configurable column selection, grouping by BU/Product
- Product Configuration — Manage product settings with Ephor Project IDs; product alias mapping for Salesforce name variations
- Searchable Multi-Select Filters — Product, Stage, Fionn Status, Open/Closed (with separate Finalizing option), Renewal Window
- Support Link — Direct link to fionn-renewals.kayako.com
- Architecture Page — This document, accessible from the sidebar
11. Integration Map
graph TB
subgraph External Data Sources
SF_TS["Salesforce: Trilogy Sales<br/>Fionn AI owned opportunities"]
SF_NS["Salesforce: No Software Speed<br/>Renewal data · ARR · Stages"]
KLAIR["Klair<br/>NetSuite contract data · Pricing"]
KAYAKO["Kayako<br/>Support tickets · Alternate contacts"]
end
subgraph AI Services
OAI_CC["OpenAI GPT-4o<br/>CuChulainn email generation<br/>Sentiment analysis"]
OAI_DASH["OpenAI GPT-5.3-instant<br/>Dashboard AI status<br/>Executive summaries<br/>Defer detection"]
end
subgraph Fionn Core
CC["CuChulainn<br/>4 Packages"]
LAMBDA["AWS Lambda<br/>API + Sync + Auto-Trigger"]
DDB["DynamoDB<br/>3 Tables"]
DASH["Dashboard UI<br/>S3 + CloudFront"]
end
subgraph Communication
GAS["Google Apps Script<br/>Email processing + routing"]
CUST["Customer<br/>Email inbox"]
end
SF_TS --> LAMBDA
SF_NS --> LAMBDA
LAMBDA --> DDB
DDB --> DASH
LAMBDA --> OAI_DASH
CC --> KLAIR
CC --> KAYAKO
CC --> OAI_CC
CC --> SF_NS
DASH --> LAMBDA
LAMBDA --> CC
GAS --> CC
CC --> CUST
CUST --> GAS
12. Security Architecture
| Layer | Measure |
|---|---|
| API Keys | Stored as Lambda environment variables, never in frontend code |
| CORS | Origin whitelist (CloudFront domain + localhost dev) — no wildcard |
| Input Validation | Salesforce ID regex validation (^[a-zA-Z0-9]{15,18}$) on all ID parameters |
| XSS Protection | All user-supplied content escaped via escapeHtml() before DOM insertion |
| Email Sanitization | HTML emails sanitized via DOMParser — scripts, iframes, forms stripped; event handlers removed; external images blocked (tracking pixel protection) |
| CDN Integrity | SRI attributes on external script tags (jsPDF, AutoTable) |
| Sensitive Logging | Request logging excludes full event payload — only method + path logged |
| DynamoDB | Protected fields preserved during sync (triggers, flags, notes, AI, defer state never overwritten) |
13. Communication Guardrails
Fionn operates under strict communication rules enforced at the package level:
Forbidden in All Outbound Communication
- Pricing, contract terms, or deadlines (first outreach only)
- Meeting or call invitations
- Phone numbers, Calendly links, scheduling URLs
- Internal identifiers (NetSuite ID, Opportunity ID, ARR)
- Urgency or pressure language
- Assumptions about customer knowledge of renewal processes
Required in All Communication
- HTML formatted emails
- Professional, warm, non-aggressive tone
- Product name referenced (not internal codes)
- Signed as "Fionn" (no placeholders)
- Single email per workflow execution
- Thread history preserved in replies
Contract Rules
- Allowed terms: 1 year, 3 year, 5 year only
- No monthly contracts, no 2-year contracts
- No custom pricing outside approved structure
- Platinum Success Tier positioned first in upgrade discussions
14. Deployment Architecture
flowchart LR
DEV["Developer<br/>Machine"] --> FE["S3 Upload<br/>index.html · app.js<br/>styles.css · logo.png<br/>architecture.html"]
DEV --> BE["Lambda Deploy<br/>lambda_handler.py<br/>→ API + Sync + Auto-Trigger"]
DEV --> RT["API Gateway<br/>Route creation"]
DEV --> EB["EventBridge<br/>Schedule rules"]
FE --> CF["CloudFront<br/>Cache Invalidation"]
CF --> LIVE["Live Dashboard"]
style LIVE fill:#EDFAF3,stroke:#1A7F4B,color:#1A1A18
| Item | Value |
|---|---|
| AWS Account | 582049328161 |
| Region | us-east-1 |
| S3 Bucket | fionn-dashboard-frontend-582049328161 |
| CloudFront Distribution | E22HOIROU34E4P |
| API Lambda | fionn-dashboard-api |
| Sync Lambda | fionn-dashboard-sync |
| Auto-Trigger Lambda | fionn-auto-trigger |
| API Gateway | o61t89e1x1 (HTTP API) |
| DynamoDB Tables | FionnDashboard, FionnEmailLogs, FionnProductConfig |
| Daily Sync Schedule | cron(0 6 * * ? *) — 6:00 AM UTC |
| Auto-Trigger Schedule | cron(0 14 * * ? *) — 2:00 PM GMT |
| AI Model | GPT-5.3-instant (via OpenAI API) |
15. Product Portfolio
Products are organized by Business Unit. Each product has an Ephor Project ID for CuChulainn integration and may have Salesforce name aliases for normalization.
| Business Unit | Products |
|---|---|
| JigTree | Tivian, BroadVision, Influitive, MessageOne, Artemis, Bonzai, ACRM, Pivotal, Aurea Platform, Stratifyd, Playbooks, Saratoga, Jigsaw Platform, Onyx, CRMagic, Engine Yard, CallStream |
| IgniteTech | DNN, NorthPlains, Jive, Tradebeam, Verdiem, Gensym, Everest, ObjectStore, Autotrol, StreetSmart, Gomembers, Infobright, TAKE, Coretrac, Nuview, AnswerHub, Smart Routines, Acorn, Computron, Prysm, SupportSoft, Aurea Social, EPM Live, Myalerts, ScaleArc, AtHand, Prologic, Knova, Pricer, NextDocs, Config, Fog Bugz, Eloquens, Sococo, Olive Software, Suuchi, School Loop |
| Skyvera | NewNet, STL, Mobilogy, Service Gateway, ResponseTek, VoltDelta, Cloudsense, Kandy, PeerApp |
| Canopy | Contently, Kayako, CloudFix |
| Aurea E-Commerce | Aurea SAS, SLI, Spiral, Quantum Retail, Finserv(AIS) |
| Ignite SMB | Kerio, GFI, Exinda |