Signal-to-Fix Engine — Design Notes

How one platform serves three stages of AI adoption, shown through the support-to-product loop.

The Signal-to-Fix loop

Goal: shorten the time from the first affected conversation to every rep giving the right answer.

CUSTOMERS SUPPORT PLATFORM ENTERPRISE Customers report a product issue spike ↑ Phase 1 · Triage Spots the pattern, confirms it's a product issue, reports it with evidence Phase 2 · Investigate & inform Product team investigates Finds the cause; asks reps to get more info from customers if needed Reps get the right guidance Human and AI reps answer correctly from the next conversation on Customer reports subside ↓ conversations report guidance provide requested info right answers loop closes ↻ Signal-to-Fix Engine
Show architecture ▾
One platform. Three tiers.

Every enterprise runs on the same Signal-to-Fix Engine and the same data model. Each picks the tooling that matches how it works today, and can move up a tier without re-integrating.

SUPPORT PLATFORM Signal-to-Fix Engine Same data model, every tier: • Issue • Case • Evidence • InfoRequest • Guidance CORE APIs ← Support Platform Enterprise → Dashboard + Tickets Human-led Mechanic: people go and look Heritage Mercantile Traditional retailer; small tech team, works in tickets Dashboard ~100 conversations without the right guidance Webhook + MCP Mixed Mechanic: information is pushed and queried Northwind Outfitters Modern retailer; engineers already work with AI assistants Webhook MCP ~70 conversations without the right guidance A2A Agent-led Mechanic: agents hand off to agents Autonomix AI-native; runs its own agents for releases, engineering, and KB Release Agent Engineering Agent KB Agent ~3 conversations without the right guidance More automation, less waiting between people

Why each tier is faster

TierWhat changes, and why it removes waitingEffect
Human-led
baseline
  • Signal Agent clusters, CX Lead reviews: conversations are scored and grouped automatically; the CX Lead reviews by exception (low-fit conversations are flagged) and reports. Confident at ~38 conversations.
  • Manual alert: the CX Lead writes and files a ticket; it waits in the product team's queue until someone reads and prioritizes it.
  • Dashboard: the engineer clicks through conversations in the support platform's dashboard, outside their own tools.
~100 conversations without the right guidance
Mixed
  • Webhook: the report lands in the product team's queue in one click, with summary and evidence attached, so there's no ticket to write. Helps most during working hours.
  • MCP: the engineer's AI assistant queries conversations in plain language, next to the engineer's own logs and code in the same session. Investigation drops from ~2h to ~30m.
~70
Agent-led
  • Release Agent: correlates clusters with what recently changed ("missing apartment deliveries" ↔ "last release changed shipping labels"). A known change plus matching complaints reaches confidence at ~10 conversations instead of ~38, hours earlier.
  • Engineering Agent: Picks up the report immediately and routes it to the owning engineer, hands over the support platform's evidence plus the correlated change, relays the engineer's info request, and pushes answers back the moment they're ready.
  • KB Agent: applies the enterprise's policies and language, publishes rep-facing guidance immediately, and routes customer-facing messages to the CX Lead.
  • Why agents, not just better tools: MCP only works while an engineer has a session open. An A2A task stays open between human steps, so nothing waits for someone to look, relay, or remember.
Guidance ~4h after first report → ~3

Metrics — how I'd know it's working

North star metric — did customers get the right answer sooner? Economic buyer · VP CS / CX

MetricDirection
North starAvg conversations without the right guidance, per issue↓
GuardrailPoor-outcome rate after guidance goes live↓ must drop vs. before guidance

Triage — spot the pattern, confirm the likely root cause, report it CX Lead

MetricDirection
Primary metricAvg conversations needed to report a product issue with confidence↓
GuardrailReports rejected by product; conversations removed by the CX Lead↔ flat

Investigate & inform — find the cause, get the right guidance to reps and customers Enterprise engineer

MetricDirection
Primary metricDeveloper satisfaction: how much effort the engineer says the investigation took, rated after each resolved issue↑
Secondary metricAvg time from report → investigation complete (root cause found or info requested)↓
GuardrailGuidance retraction rate (corrected or withdrawn within 24h)↔ flat

Every speed metric is paired with a guardrail that catches it going wrong.

Quality signals

Quality of experiencequality of the customer's experience
Frustration at startHow upset the customer is when they arrive, before support has done anything.low · medium · high

Why it matters: separates what the customer brought in from what support did. Without it, reps get blamed for customers who arrived angry, and incident severity is understated: high entry frustration means customers already hit the problem, maybe more than once.

Used for: incident severity; normalizing the trajectory signal.

Sentiment trajectoryHow the customer's sentiment changed from the start of the conversation to the end.improved · flat · worsened

Why it matters: the part of the experience support actually controls. A customer who arrives furious and leaves calm is a good conversation; a raw sentiment score would call it bad.

Used for: measuring whether guidance is working; a worsened trajectory feeds the "ended poorly" outcome.

Resolved in conversationWhether the customer's problem was solved before the conversation ended.yes · no · escalated

Why it matters: the outcome that drives cost (repeat contacts, escalations) and CSAT. During an incident it's the clearest sign reps don't have the right answer.

Used for: the "ended poorly" outcome on the impact chart.

Triagewhere the conversation belongs and who can act on it
Likely root causeThe most probable reason the customer contacted support, with a confidence score.product issue · policy · knowledge gap · external

Why it matters: different causes need different owners. Only product issues go to the product team; knowledge gaps go to support training; external causes (theft, carrier) go nowhere. Routing everything everywhere is how teams learn to ignore alerts.

Used for: deciding whether a cluster is reported to the product team.

Cluster fitHow closely a conversation matches the rest of its cluster.0–1

Why it matters: lets the CX Lead review by exception instead of reading every conversation. Low-fit conversations (e.g., porch theft inside a "delivered but not received" cluster) are flagged as unsure. The CX Lead's removals and additions become labeled data for cluster precision and recall.

Used for: human review of the cluster before it's reported.

Deliberately not included · how I'd validate the signals
Not included
  • Empathy / agent tone scores — useful for rep coaching, not incident detection. Different loop, different buyer.
  • CSAT prediction — would duplicate the three experience signals without adding an action.
How I'd validate the signals
  • Agreement with human QA labels on a sample of ~200 conversations, per signal.
  • CX Lead removals and additions → precision and recall of clusters over time.
  • Resolved-in-conversation vs. actual repeat contacts within 7 days.

Integration specs

InterfaceShaped aroundConsumer
Conversation dashboardViews — screens over the same objectsPeople (CX Lead, engineers)
Core APIResources — one endpoint per objectCode (including the dashboard)
WebhookEvents — "something happened to an Issue"Systems
MCPIntents — "help me do this task"A model working with a human
A2ATasks — "own this outcome"Another agent
Interfaces
Internal

Core data model

ObjectKey attributes
Casecase_id, started_at, channel, signals: frustration_at_start, trajectory, resolved, likely_root_cause {type, confidence}; issues: [{issue_id, cluster_fit, added_by}]
Issueissue_id, title, summary, likely_root_cause {type, confidence}, case_count, first_seen, state
Evidenceissue_id, case_id, turn, quote, request_id (set when the quote answers an InfoRequest)
InfoRequestrequest_id, issue_id, question, answers_needed, answers {count, breakdown}, each answer linked to Evidence
Guidanceguidance_id, issue_id, audience (rep / customer), text, approval (auto / pending / approved), status (draft / live / retired)

Issue lifecycle: reported → investigating → needs_info → resolved

Relationships: a Case can belong to more than one Issue, so membership lives on the Case, with cluster_fit relative to that Issue and added_by (system / cx_lead) recording the CX Lead's review. Evidence always points to the Issue it supports, and to the InfoRequest when it's an answer.

{
  "issue_id": "ISS-1042",
  "title": "Delivered but not received",
  "likely_root_cause": { "type": "product_issue", "confidence": 0.91 },
  "case_count": 37,
  "first_seen": "Mon 12:48",
  "state": "needs_info"
}

Ingestion API

Batch in, scored cases out. This is where every Case comes from.

POST /v1/conversations:batch

// request
{ "conversations": [ { "conversation_id": "C-40811", "started_at": "Mon 13:12",
    "channel": "chat",
    "turns": [ { "speaker": "customer", "text": "Tracking says delivered but nothing at my door." } ] } ] }

// response
{ "scored": 212,
  "cases": [ { "case_id": "C-40811",
    "signals": { "frustration_at_start": "high", "trajectory": "worsened", "resolved": "no",
                 "likely_root_cause": { "type": "product_issue", "confidence": 0.94 } } } ] }

Core API

Resource-shaped: one endpoint per object, for code and for the support platform's own dashboard. Every other interface is built on it.

EndpointPurpose
GET /v1/issues · GET /v1/issues/{id}List and read Issues
GET /v1/issues/{id}/casesCases in an Issue, with signals
GET /v1/cases/{id}/evidenceEvidence for a Case
POST /v1/issues/{id}/info-requests · GET /v1/info-requests/{id}Create and read InfoRequests
POST /v1/guidance · PATCH /v1/guidance/{id}Draft, approve, retire Guidance
PATCH /v1/issues/{id}Update Issue state

Webhook

Event-shaped: pushes an Issue into the enterprise's tracker the moment the CX Lead reports it. The payload carries enough to triage without logging into the support platform.

issue.reported

{
  "event": "issue.reported",
  "event_id": "evt_8f2c",
  "issue": { "issue_id": "ISS-1042", "title": "Delivered but not received",
             "likely_root_cause": { "type": "product_issue", "confidence": 0.91 },
             "case_count": 37, "first_seen": "Mon 12:48" },
  "evidence": [ { "issue_id": "ISS-1042", "case_id": "C-40811", "turn": 1,
                  "quote": "Tracking says delivered but nothing at my door." } ],
  "investigate_via": { "mcp_server": "signal-mcp", "issue_id": "ISS-1042" }
}

Signed (HMAC); event_id makes delivery idempotent.

MCP server signal-mcp

Intents → tools

Engineer's intentToolReplaces (Core API)Returns
"What's going on?"investigate_issue(issue_id)GET /issues/{id} + GET /issues/{id}/cases + aggregationSummary, trend, likely root cause, what cases have in common (and don't), representative evidence
"Show me cases that mention X"find_evidence(issue_id, query)GET /cases?filter=… + reading transcriptsMatching quotes with case and turn references
"Ask affected customers something"ask_customers(issue_id, question, answers_needed)POST /info-requests + POST /guidance + approvalRequest status and what happens next
"What did they say?"get_customer_answers(issue_id)GET /info-requests/{id} + answersBreakdown, whether the target was reached, sample answers linked to evidence
"It's fixed"mark_resolved(issue_id, root_cause, customer_impact)PATCH /issues/{id} + POST /guidanceConfirmation and what happens next

Deliberate escape hatch: intent-shaped tools are opinionated. find_evidence stays flexible for questions nobody anticipated.

One tool in full: ask_customers

{
  "name": "ask_customers",
  "description": "Ask customers affected by an issue a diagnostic question. Use when the cause
    can't be found from existing conversations and customers likely know something your
    systems don't (their setup, what they saw, what they did). The support platform drafts rep guidance so
    reps ask the question in new conversations; answers are extracted automatically.
    Never ask for payment details, passwords, or other sensitive data.",
  "input": {
    "issue_id": "string",
    "question": "string — one question a rep can ask in plain language",
    "answers_needed": "integer — answers to collect before notifying (default 20)"
  }
}

// response
{
  "request_id": "RQ-77",
  "issue_state": "needs_info",
  "next": "Rep guidance drafted; reps start asking once the CX Lead approves.
           Answers will be available via get_customer_answers."
}

A2A

Task-shaped: the support platform's agent hands outcomes to the enterprise agent that owns each system. Follows A2A concepts (Agent Card, Task, task states); field names abbreviated.

Agent cards — skills are intent-shaped, like the MCP tools

AgentOwnerSkills
Signal AgentSupport Platformfind_evidence, ask_customers
Release AgentEnterprisecorrelate_changes
Engineering AgentEnterpriseinvestigate_issue
KB AgentEnterprisepublish_guidance, retire_guidance
{
  "name": "Signal Agent",
  "description": "Surfaces product issues from customer conversations and collects
                  answers from affected customers.",
  "capabilities": { "streaming": true, "pushNotifications": true },
  "skills": [
    { "id": "find_evidence", "description": "Find customer quotes about an issue that match a question." },
    { "id": "ask_customers", "description": "Collect answers to a diagnostic question from affected customers." }
  ]
}

The Issue lifecycle maps onto A2A task states

the support platform sends investigate_issue to the Engineering Agent. The task's state is the Issue's state:

A2A task stateIssue stateWhat's happening
submittedreportedThe support platform hands over the Issue with evidence and correlated changes
workinginvestigatingEngineering Agent routes to the owning engineer
input-requiredneeds_infoEngineering Agent needs customer answers; The support platform asks customers and replies on the task
completedresolvedFix verified; resolution returned as a task artifact
// Engineering Agent → Signal Agent: task needs input
{
  "task_id": "T-311",
  "skill": "investigate_issue",
  "status": { "state": "input-required",
    "message": "Can't reproduce. Ask affected customers: 'Do you live in an apartment or
                building with a mailroom or parcel locker?' Need 20 answers." },
  "context": { "issue_id": "ISS-1042" }
}

The same holds for the other agents: correlate_changes completes with the matching changes as an artifact; publish_guidance completes when guidance is live — immediately for rep-facing guidance, after CX Lead approval for customer-facing.

Tradeoffs

What I'd change for production

  • Version the data model and every interface. Issue and Case carry a schema version, and the Core API, webhook events, and MCP tools are versioned separately. Enterprises can then move up a tier, or stay put, without anything breaking underneath them.
  • Offline evals for classification and clustering. Build a labeled set of conversations, and measure each signal's agreement with human labels plus cluster precision and recall. No model or prompt change ships unless it holds or improves those numbers.

What I'd measure

  • The metrics in the Metrics tab: the north star and each stage's primary metric, each with its guardrail.
  • Tier adoption and migration friction: how many enterprises are on each tier, and what it costs to move up (time to onboard, integration issues along the way). If moving up is hard, "no re-integration" isn't true yet.
  • MCP usage: which tools engineers call, how often, and whether a session ends in an action (ask_customers, mark_resolved). Tools nobody calls mean I guessed the wrong intents.

What I'm unsure about

  • Webhooks. I don't know yet whether product teams want issues pushed into their tracker, or a different channel such as Slack, on-call paging, or a digest. I'd validate with a handful of product teams before building more than one channel.
  • A2A. I don't know whether enterprises will run their own release, engineering, and KB agents, or whether A2A is the protocol they'll adopt. I'd build it with one or two design partners before generalizing.