SOP CS-01: AI Customer Service Triage (v2.4)¶
Automated AI-powered customer service intake with policy gates, Claude Sonnet classification, and comprehensive health monitoring.
Document ID: SOP-CS-01-v2.4
Version: 2.4
Status: ✅ Production Ready
Last Updated: 2026-04-08
Owner: Protocol Raw Operations
Replaces: SOP-CS-01-v2.3
Review Date: 2026-07-08
Key Changes in v2.4¶
- ✅ Subject line generation: When customer provides no subject, AI generates a
suggested_subject(max 8 words, plain language). Fallback chain: customer subject → AIsuggested_subject→ category-based fallback ("Your {category}"). Subject stored without[Support]prefix — prefix applied at send time only bysend-support-email. - ✅ Customer context enrichment:
is_existing_customerflag passed to Claude. When customer lookup returns no match, AI receivesCUSTOMER STATUS: No matching customer found. This person is likely a prospective customer.When match found, full customer context (name, subscription, box size) is passed. - ✅ Sign-off stripping: Belt-and-braces regex strips trailing sign-off patterns (persona names, "Best regards", "[Name]", etc.) from AI drafts before storing on the ticket. Only examines the last few lines — does not affect the greeting or body. Persona sign-off is appended later by
send-support-email. - ✅ AI response schema updated: Structured response from Claude now includes
suggested_subjectandcustomer_namealongsidecategory,confidence,draft_response,action,escalation_reason. - ✅ Customer name extraction: AI extracts customer name from email sign-off when no name in customer context. Stored on
support_tickets.customer_namecolumn (new). - ✅ Placeholder subject normalisation: Literal strings like "(no subject)", "(none)", "(empty)" are treated as blank, triggering AI subject generation.
Key Changes in v2.3¶
- ✅ Email intake migrated from Make.com Gmail watch to Cloudflare Email Routing →
email-ingestCloudflare Worker - ✅ Slack notification for #cust-ops moved inside cs-agent-triage Edge Function (fires when escalate=true OR confidence<0.85)
- ✅ MX records for protocolraw.co.uk now point to Cloudflare Email Routing; SPF updated to include both Google and Cloudflare
- ✅ Make.com CS-01 scenario disabled (not deleted)
- ✅
send-support-emailEdge Function created to replace deprecatedsupport-send-response, with CORS support for ops.protocolraw.co.uk - ✅ Module Configuration section replaced with Worker + Edge Function descriptions
Key Changes in v2.2¶
- ✅ RLS enabled on all four support tables (
support_tickets,ticket_messages,cs_agent_decisions,csat_responses) — no policies, service role bypasses, anon blocked - ✅ Replaced broken
monitor-support-queuecron job withfn_check_support_health_v2via MON-01 pattern - ✅ Added intake silence detection: alert if no new tickets in 8 hours during business hours (M–F 08:00–20:00 UTC)
- ✅ Added triage quality monitoring: policy gate rate and low confidence rate alerts
- ✅ Corrected documented ticket statuses to match production schema (
new,pending,in_progress,escalated,resolved,closed) - ✅ Fixed monitoring to use
created_at(noupdated_atcolumn exists onsupport_tickets) - ❌ Removed stale "Queue Monitoring Alerts — Not yet implemented" section (now implemented)
Purpose¶
Provide fast, consistent, auditable customer service triage for all inbound email to hello@protocolraw.co.uk. Every email is either caught by a code-enforced policy gate (zero tokens, ~150ms) or classified by Claude Sonnet with a draft response in Protocol Raw's brand voice. All tickets route to human review via the Support Workstation.
Scope¶
This SOP covers:
- Email intake via Cloudflare Email Routing → email-ingest Worker → cs-agent-triage Edge Function
- Policy gate logic (code-enforced escalation rules)
- AI classification and draft response generation (cs-agent-triage Edge Function)
- Ticket creation and decision audit trail
- Human review workflow (Support Workstation in Ops Portal)
- Draft usage tracking and accuracy analytics
- Support health monitoring (MON-01 pattern)
- Row-Level Security posture on support tables
Related SOPs: - SOP CS-00: Customer Operations System (master design) - SOP CS-02: Live Chat System - SOP CS-03: Autonomous Support Agent (future: auto-execute) - SOP AI-KB-01: AI Knowledge Base (prompt content management) - SOP MON-01: Monitoring Architecture
Architecture¶
System Flow¶
┌─────────────────────────────────┐
│ Cloudflare Email Routing │ ← MX records for protocolraw.co.uk
│ │ hello@ → email-ingest Worker
│ │ catch-all → Gmail forwarding
└──────────┬──────────────────────┘
│
▼
┌─────────────────────────────────┐
│ email-ingest Worker │ ← Cloudflare Worker (MIME-to-HTTP adapter)
│ │ 1. Parse raw MIME (postal-mime)
│ │ 2. Extract sender, subject, body, Message-ID
│ │ 3. POST to cs-agent-triage
└──────────┬──────────────────────┘
│
▼
┌─────────────────────────────────┐
│ cs-agent-triage Edge Function │ ← Supabase Edge Function
│ │ 1. Check policy gates (code)
│ │ 2. Fetch AI prompt from KB
│ │ 3. Call Claude Sonnet
│ │ 4. Create ticket
│ │ 5. Store decision in cs_agent_decisions
│ │ 6. Slack notification if escalated/low confidence
└──────────┬──────────────────────┘
│
▼
┌─────────────────────────────────┐
│ Support Workstation │ ← Unified review interface
│ (Ops Portal) │ Shows: message + context + AI draft + policy gate
└─────────────────────────────────┘
Monitoring Flow (v2.2 NEW)¶
pg_cron: monitor-cs-01-support-health (*/15 * * * *)
↓
pg_net → run-monitor Edge Function
↓ {"check": "support_health"}
fn_check_support_health_v2()
↓
monitoring_runs (logged)
↓ (if threshold breached)
ops-alerter → Slack (#ops-alerts or #ops-urgent)
Policy Gates¶
Code-enforced rules that trigger immediate escalation WITHOUT calling Claude. Zero tokens, ~150ms response.
Policy Gate Keywords¶
| Gate Code | Trigger Keywords | Escalation Reason |
|---|---|---|
| health_vomiting | vomit/vomiting/vomited/throwing up/puking + sick/ill/unwell | Dog health concern — potential food reaction |
| health_diarrhea | diarrhea/diarrhoea/loose stool/runny poo | Dog health concern — potential food reaction |
| health_blood | blood in stool/bloody stool/blood in poo | Dog health concern — blood in stool |
| health_lethargy | lethargic/lethargy/won't eat/not eating/refusing food | Dog health concern — lethargy or appetite loss |
| legal_threat | lawyer/solicitor/trading standards/legal action/sue | Legal threat mentioned |
| media_threat | newspaper/journalist/social media/going public | Media/reputation threat |
| complaint_formal | formal complaint/complaint/disgusted/outraged/furious | Formal complaint or severe dissatisfaction |
| allergy_reaction | allergic/allergy/reaction/swelling/hives | Potential allergic reaction |
| foreign_object | plastic/metal/glass/foreign object/found something | Foreign object concern |
| social_media_threat | post/share + facebook/twitter/instagram/review | Social media threat |
| b2b_inquiry | wholesale, retail partner, breeder program, bulk order | B2B inquiry |
| repeat_contacter | Customer contacted 3+ times in 7 days | Repeat contacter |
| double_credit_request | Has recent credit AND asking for more | Double credit request |
Policy Gate Outcomes¶
| Outcome | model_used | confidence_score | Claude Called? |
|---|---|---|---|
| Policy gate triggered | policy_gate |
0.00 | No |
| AI classification | claude-sonnet-4-20250514 |
0.00–1.00 | Yes |
Benefit: Health/safety escalations in ~150ms vs ~4000ms for Claude. Zero tokens spent.
Human Review Workflow¶
Unified Support Workstation¶
All tickets appear in the Support Workstation queue. Each ticket card displays:
- Customer Message — Full email content
- Customer Context — Subscription status, box size, order history, shipment status
- AI Triage Panel — Category, confidence score, recommended action
- Policy Gate Warning — If triggered, prominently displayed with gate code
- AI Draft Response — Pre-filled in editable textarea
- Action Buttons — Send Response, Send + Replacement, Close Without Sending
Operator Workflow¶
1. Open Support Workstation
2. Select ticket from queue (sorted by priority)
3. Review customer message + context
4. Review AI draft response
5. Either:
a. Send as-is (AI was correct)
b. Edit and send (AI needed adjustment)
c. Replace entirely (AI was wrong)
d. Close without sending (no response needed)
6. System tracks draft_usage for analytics
Priority Calculation¶
| Condition | Priority | Sort Order |
|---|---|---|
| Policy gate triggered OR escalation_reason set | 1 (High) | First |
| Confidence < 0.70 | 2 (Medium) | Second |
| Normal AI classification | 3 (Normal) | Third |
| Outbound/awaiting reply | 4 (Awaiting) | Last |
Draft Usage Tracking¶
The system tracks how operators use AI-drafted responses:
| draft_usage | Meaning | Indicates |
|---|---|---|
sent_as_is |
Response sent without changes | AI was correct |
minor_edits |
>70% word overlap with original | AI mostly correct |
major_rewrite |
<70% word overlap | AI needed significant changes |
replaced |
Completely different response | AI was wrong |
no_draft |
No AI draft was provided | Policy gate escalation |
Calculation Logic¶
if (responseText === originalDraft) {
draftUsage = 'sent_as_is';
} else {
const similarity = matchingWords / originalWords.length;
draftUsage = similarity > 0.7 ? 'minor_edits' : 'major_rewrite';
}
Analytics Queries¶
-- AI accuracy rate (last 30 days)
SELECT
draft_usage,
COUNT(*) as count,
ROUND(COUNT(*) * 100.0 / SUM(COUNT(*)) OVER (), 1) as percentage
FROM raw_ops.support_tickets
WHERE resolved_at > NOW() - INTERVAL '30 days'
AND draft_usage IS NOT NULL
GROUP BY draft_usage
ORDER BY count DESC;
-- Accuracy by category
SELECT
ai_category,
COUNT(*) FILTER (WHERE draft_usage = 'sent_as_is') as sent_as_is,
COUNT(*) FILTER (WHERE draft_usage IN ('minor_edits', 'major_rewrite', 'replaced')) as edited,
ROUND(
COUNT(*) FILTER (WHERE draft_usage = 'sent_as_is') * 100.0 / COUNT(*), 1
) as accuracy_pct
FROM raw_ops.support_tickets
WHERE resolved_at > NOW() - INTERVAL '30 days'
AND draft_usage IS NOT NULL
GROUP BY ai_category
ORDER BY accuracy_pct DESC;
Database Schema¶
Table: support_tickets¶
Core ticket storage with AI fields.
| Column | Type | Description |
|---|---|---|
| id | UUID | Primary key |
| customer_email | TEXT | Customer's email |
| subject | TEXT | Email subject |
| body | TEXT | Full email body |
| status | TEXT | new, pending, in_progress, escalated, resolved, closed |
| ai_category | TEXT | AI classification |
| ai_confidence | NUMERIC(3,2) | 0.00–1.00 |
| ai_draft_response | TEXT | AI-drafted response |
| ai_recommended_action | TEXT | Suggested action |
| ai_escalation_reason | TEXT | Why escalated (or null) |
| draft_usage | TEXT | How draft was used |
| customer_name | TEXT | Customer name (AI-extracted from email sign-off or customer context) |
| email_message_id | TEXT | Original email Message-ID for threading |
| created_at | TIMESTAMPTZ | Ticket creation time |
RLS: Enabled. No policies (service role bypasses, anon blocked).
Table: ticket_messages¶
Individual messages within a ticket thread.
RLS: Enabled. No policies (service role bypasses, anon blocked).
Table: cs_agent_decisions¶
Stores AI decisions separately for audit trail and analytics.
| Column | Type | Description |
|---|---|---|
| id | UUID | Primary key |
| ticket_id | UUID | FK to support_tickets |
| category | TEXT | Classification result |
| confidence_score | NUMERIC(3,2) | 0.00–1.00 |
| draft_response | TEXT | AI-drafted response |
| escalation_reason | TEXT | Why escalated |
| policy_gate_triggered | BOOLEAN | Whether policy gate fired |
| policy_gate_code | TEXT | Machine code for analytics |
| model_used | TEXT | claude-sonnet-4-20250514 or policy_gate |
| execution_duration_ms | INTEGER | Processing time |
| dedupe_key | TEXT | Idempotency key |
| created_at | TIMESTAMPTZ | When processed |
RLS: Enabled. No policies (service role bypasses, anon blocked).
Table: csat_responses¶
Customer satisfaction survey responses linked to tickets.
RLS: Enabled. No policies (service role bypasses, anon blocked).
View: v_support_queue¶
Unified queue view for Support Workstation:
SELECT
t.*,
c.id AS customer_id,
c.first_name,
c.last_name,
s.status AS subscription_status,
s.box_size,
s.frequency_weeks,
s.seal_subscription_id,
s.next_billing_date,
d.policy_gate_triggered,
d.policy_gate_code,
d.id AS decision_id,
CASE
WHEN t.is_outbound THEN 4
WHEN t.ai_escalation_reason IS NOT NULL THEN 1
WHEN t.ai_confidence < 0.7 THEN 2
ELSE 3
END AS priority
FROM raw_ops.support_tickets t
LEFT JOIN raw_ops.customers c ON c.email = t.customer_email
LEFT JOIN raw_ops.subscriptions s ON s.customer_id = c.id
LEFT JOIN raw_ops.cs_agent_decisions d ON d.ticket_id = t.id
WHERE t.status NOT IN ('resolved', 'closed');
Row-Level Security Summary¶
| Table | RLS Enabled | Policies | Access Model |
|---|---|---|---|
| support_tickets | Yes | None | Service role bypasses, anon blocked |
| ticket_messages | Yes | None | Service role bypasses, anon blocked |
| cs_agent_decisions | Yes | None | Service role bypasses, anon blocked |
| csat_responses | Yes | None | Service role bypasses, anon blocked |
This is the standard Protocol Raw RLS posture: explicit enablement with no policies means only the service role (used by Edge Functions and server-side operations) can access these tables. The anon role is blocked by default.
Monitoring¶
Support Health Monitor (v2.2 NEW)¶
Follows the SOP-MON-01 canonical monitoring pattern.
Function: raw_ops.fn_check_support_health_v2()
Cron Job: monitor-cs-01-support-health (every 15 minutes)
Dispatch Key: support_health in run-monitor Edge Function
Active Checks and Thresholds¶
| Check | Threshold | Severity | Slack Channel |
|---|---|---|---|
| Open tickets > 20 | warning | warning | #ops-alerts |
| Oldest pending ticket > 24h | warning | warning | #ops-alerts |
| Oldest pending ticket > 48h | critical | critical | #ops-urgent |
| Policy gate rate > 20% (min 5 tickets/hr) | warning | warning | #ops-alerts |
| Low confidence rate > 30% (min 5 tickets/hr) | warning | warning | #ops-alerts |
| No new tickets in 8h (business hours M–F 08:00–20:00 UTC) | critical | critical | #ops-urgent |
Notes on thresholds:
- Queue depth (20 tickets) and age (24h/48h) will need recalibration once ticket volume establishes a baseline.
- Intake silence detection uses created_at on support_tickets (no updated_at column exists). The 8-hour window is business-hours-only to avoid false alerts overnight and at weekends.
- Policy gate rate and low confidence rate require a minimum of 5 tickets in the preceding hour before alerting. This prevents noise during low-volume periods.
What Was Replaced¶
The previous monitor-support-queue cron job was sending {"check": "support_queue"} to run-monitor, but support_queue was never registered in the dispatch map. Every 15-minute invocation was returning HTTP 400. The underlying function fn_check_support_queue_v2 existed but was unreachable, and only checked escalation queue depth via v_support_needs_review.
The replacement fn_check_support_health_v2 covers all original checks plus intake silence detection and triage quality metrics, and is properly registered in the run-monitor dispatch map.
Rollback¶
Original fn_check_support_queue_v2 definition saved at rollback/cs-01-rollback.sql.
Component Configuration¶
email-ingest Worker (Cloudflare)¶
Type: Cloudflare Email Worker
Location: email-ingest/src/index.ts
Receives: Raw MIME email via Cloudflare Email Routing
Parser: postal-mime (lightweight MIME parser for Workers)
Behaviour:
- Only processes emails addressed to hello@protocolraw.co.uk
- Emails to other addresses are forwarded to Gmail untouched
- Empty body emails (calendar invites, read receipts) are forwarded but not triaged
- Extracts: sender email, subject, text body (HTML stripped as fallback), Message-ID
- POSTs to cs-agent-triage with x-internal-secret auth header
- Message-ID is passed as both email_message_id and dedupe_key
cs-agent-triage Edge Function (Supabase)¶
Type: Supabase Edge Function
URL: https://znfjpllsiuyezqlneqzr.supabase.co/functions/v1/cs-agent-triage
Callers: email-ingest Worker (email), chat Edge Function (chat escalation)
Auth: x-internal-secret header matching AGENT_INTERNAL_SECRET
Response Fields:
| Field | Type | Description |
|---|---|---|
| ticket_id | UUID | Created ticket ID |
| decision_id | UUID | AI decision ID |
| category | string | delivery / quality / feeding / subscription / escalation / other |
| confidence | number | 0.00–1.00 (0 for policy gate) |
| draft_response | string | AI-drafted response (empty if escalated). Sign-off patterns stripped before storage. |
| escalate | boolean | Whether human review required |
| escalation_reason | string | Why escalated (or null) |
| policy_gate_triggered | boolean | Whether policy gate fired |
| policy_gate_code | string | Machine code for analytics |
| suggested_subject | string | AI-generated subject for blank-subject emails (v2.4) |
| customer_name | string | Customer name extracted from email sign-off or context (v2.4) |
Slack Notification (inside cs-agent-triage)¶
Channel: #cust-ops
Webhook: SLACK_CUST_OPS_WEBHOOK (falls back to SLACK_CHAT_ESCALATION_WEBHOOK)
Fires when (OR logic):
- escalate = true
- confidence < 0.85
Behaviour: Fire-and-forget (does not block triage response). Policy gate tickets show the gate code in the Slack message.
send-support-email Edge Function (Supabase)¶
Type: Supabase Edge Function
URL: https://znfjpllsiuyezqlneqzr.supabase.co/functions/v1/send-support-email
Callers: Ops Portal Support Workstation, CS-03 Autonomous Agent
CORS: Allows ops.protocolraw.co.uk
Customer.io Template: support_response (transactional)
Behaviour: Sends support response emails with threading headers (In-Reply-To, References) using plain object format. Picks deterministic persona (Sophie/Tom/Lucy) based on customer email hash and replaces [Name] placeholder in draft with persona name. Appends persona sign-off ("{persona}\nProtocol Raw") to the message body. Applies [Support] prefix to subject if missing. Adds Re: prefix only when prior outbound messages exist on the ticket. Normalises placeholder subjects ("(no subject)", "(pending)") to category-based fallback. Logs to ticket_messages. Updates ticket status to resolved.
Operations Guide¶
Daily Monitoring¶
- Check #cust-ops Slack channel for escalated tickets
- Open Ops Portal → Support Workstation tab
- Process tickets by priority (high priority at top)
- Review AI draft, edit if needed, send response
- Check #ops-alerts and #ops-urgent for support health alerts
Metrics to Track (Metabase)¶
| Metric | Query |
|---|---|
| Policy gate triggers by code | GROUP BY policy_gate_code |
| Average confidence score | AVG(confidence_score) WHERE model_used != 'policy_gate' |
| Draft acceptance rate | COUNT(*) WHERE draft_usage = 'sent_as_is' / COUNT(*) |
| Escalation rate | COUNT(*) WHERE escalate = true / COUNT(*) |
| Queue depth trend | COUNT(*) WHERE status NOT IN ('resolved', 'closed') GROUP BY date |
| CSAT by category | Join csat_responses to support_tickets on ticket_id |
| Policy gate rate | COUNT(*) WHERE policy_gate_triggered / COUNT(*) per hour |
| Confidence distribution | Histogram of confidence_score WHERE model_used != 'policy_gate' |
| Average resolution time | AVG(resolved_at - created_at) |
Troubleshooting¶
Edge Function returning 401:
- Check x-internal-secret header matches AGENT_INTERNAL_SECRET
Edge Function returning 500: - Check Supabase Edge Function logs - Common cause: ANTHROPIC_API_KEY not set
Policy gate not triggering:
- Verify keywords match patterns in runPolicyGate() function
- Check email body is being passed correctly
Duplicate tickets created:
- Ensure dedupe_key is unique per email (uses MIME Message-ID header)
- Check idempotency logic in Edge Function
Support health alerts not firing:
- Verify cron job monitor-cs-01-support-health is active: SELECT * FROM cron.job WHERE jobname = 'monitor-cs-01-support-health';
- Verify dispatch registration: check support_health key exists in run-monitor's MONITOR_FUNCTIONS map
- Check recent runs: SELECT * FROM raw_ops.monitoring_runs WHERE check_name = 'support_health' ORDER BY run_at DESC LIMIT 5;
Intake silence alert firing unexpectedly: - This is expected if no tickets have been received in 8+ hours during business hours - Check Cloudflare Workers → email-ingest → Logs for errors or dropped emails - Verify Cloudflare Email Routing is active and hello@ rule points to email-ingest Worker - Check MX records for protocolraw.co.uk resolve to Cloudflare
Credentials and Access¶
Cloudflare Email Routing¶
- Domain: protocolraw.co.uk
- Rule: hello@protocolraw.co.uk → email-ingest Worker
- Catch-all: Forward to anton@protocolraw.co.uk (Gmail)
email-ingest Worker (Cloudflare)¶
- Location: Cloudflare Workers dashboard
- Secrets:
AGENT_INTERNAL_SECRET(must match cs-agent-triage) - Env vars:
TRIAGE_URL,GMAIL_FORWARD_ADDRESS(hardcoded fallbacks in code)
Make.com (disabled)¶
- Scenario: CS-01 Support Intake — disabled 2026-04-06, not deleted
- Location: Protocol Raw workspace
Anthropic (Claude)¶
- Model: claude-sonnet-4-20250514
- API Key: Stored in Supabase Edge Function secrets
Supabase¶
- Project: znfjpllsiuyezqlneqzr
- Schema: raw_ops
- Edge Function: cs-agent-triage
Slack¶
- Workspace: protocolraw.slack.com
- Channels: #cust-ops (ticket notifications), #ops-alerts (health warnings), #ops-urgent (critical alerts)
Future Enhancements (Not Yet Built)¶
Autonomous Mode¶
Currently all tickets require human review (shadow mode). Future autonomous mode will:
- Auto-send responses when confidence >= threshold (85%? 90%?)
- Require human review only for:
- Policy gate triggers
- Low confidence (< threshold)
- Categories marked for mandatory review
Requirements before enabling:
- [ ] Define confidence threshold (recommend 90%)
- [ ] Test email delivery end-to-end
- [ ] Achieve >80% draft acceptance rate in shadow mode
- [ ] draft_usage data reaches statistical significance
~~Gmail Intake Migration~~ ✅ Complete (v2.3)¶
Migrated from Make.com Gmail watch to Cloudflare Email Routing → email-ingest Worker. Make.com CS-01 scenario disabled.
Duplicate Thread Anomaly Monitoring¶
Track sudden spikes in duplicate tickets per customer, tickets without matched customer, or policy-gated escalations by category. Add after volume reaches statistical significance to calibrate baselines.
Metabase Dashboard¶
Dedicated CS-01 dashboard combining: queue depth trend, CSAT by category, policy gate rate, confidence distribution, draft acceptance rate, average resolution time. Build once 1–2 weeks of live ticket data exists.
Version History¶
| Version | Date | Changes | Author |
|---|---|---|---|
| 2.4 | 2026-04-08 | Email quality fixes: AI subject generation for blank-subject emails (suggested_subject). Customer context enrichment (prospect vs customer detection). Sign-off stripping belt-and-braces. Customer name extraction from email sign-off. Placeholder subject normalisation. AI response schema extended with suggested_subject and customer_name. send-support-email: persona sign-off appended to body, conditional Re: prefix, placeholder subject handling, [Support] prefix. | Anton |
| 2.3 | 2026-04-06 | Email intake migration: Replaced Make.com Gmail watch with Cloudflare Email Routing → email-ingest Worker. Slack notification moved inside cs-agent-triage (fire-and-forget). Make.com CS-01 scenario disabled. Created send-support-email Edge Function with CORS. MX/SPF updated for Cloudflare. | Anton |
| 2.2 | 2026-03-19 | RLS enabled on 4 support tables. Replaced broken monitor-support-queue with fn_check_support_health_v2 via MON-01 pattern. Added intake silence detection and triage quality monitoring. Corrected ticket statuses to match production. | Anton |
| 2.1 | 2026-01-19 | Removed separate Agent Review tab. Unified review in Support Workstation. Added draft_usage tracking. Policy gate info visible in Support Workstation. | Anton |
| 2.0 | 2026-01-19 | Migrated from OpenAI GPT-4o to Claude Sonnet. Consolidated all business logic into single Edge Function. Added policy gates. Simplified Make.com to pure orchestration. Added idempotency via dedupe_key. Separated AI decisions into cs_agent_decisions table. | Anton |
| 1.2 | 2026-01-12 | Added Module 15 for prompt fetching from AI Knowledge Base. | Anton |
| 1.1 | 2025-12-15 | Added Module 11 for finding open tickets (thread detection). | Anton |
| 1.0 | 2025-12-03 | Initial production release. Gmail trigger, OpenAI GPT-4o, Supabase storage, Slack notifications. | Anton |
Related Documentation¶
- SOP AI-KB-01 v1.9: AI Knowledge Base (prompt content management)
- SOP CS-00 v1.6: Customer Operations System (master design)
- SOP CS-02 v2.0: Live Chat System
- SOP CS-03 v1.5: Autonomous Support Agent (future: auto-execute)
- SOP CS-04 v1.2: Refund Resolution Operations
- SOP CS-05 v1.0: CSAT Survey System
- SOP MON-01 v1.0: Monitoring and Alerting Architecture
- Ops Portal Documentation v3.8: Support Workstation reference
Document Owner: Protocol Raw Technical Team
Last Reviewed: 2026-04-08
Next Review: 2026-07-08
Version: 2.4
Status: Production Ready ✅