Files
support_backend/specs/005-ai-support/spec.md
T
saqib mirandClaude Sonnet 5 9586b872b7 docs: spec for AI support agent feature (005)
Phase 4 of the roadmap: AI session/diagnosis, confidence-band policy,
permission/risk-gated tool system, runbook execution, and evidence-based
verification. Per explicit decision, reasoning integrates a real LLM
provider (Anthropic Claude) rather than a mock.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-02 16:43:51 +05:30

22 KiB

Feature Specification: AI Support Agent

Feature Branch: 005-ai-support

Created: 2026-09-02

Status: Draft

Input: User description: "Phase 4 of docs/10-implementation-roadmap.md: AI session/diagnosis/ interaction models, classification, RAG-backed reasoning, confidence thresholds (configurable), tool system with permission/risk gating, runbook engine, verification logic. Per docs/03-ai-support-architecture.md and docs/06-database-schema.md. The AI reasoning calls a real LLM provider (not a mock), per explicit decision."

User Scenarios & Testing (mandatory)

User Story 1 - The AI diagnoses a new ticket and confidence decides what happens next (Priority: P1)

When a ticket is created, an AI support session starts for it. The AI reads the customer's problem, produces a structured diagnosis (product, feature, problem type, severity, and a confidence score) grounded in the product's knowledge base, and a configurable confidence-band policy decides what happens next: proceed automatically toward a solution, ask the customer a clarifying question, or escalate straight to a human.

Why this priority: Nothing else in this feature has anything to act on until a ticket has been diagnosed. Automatic, knowledge-grounded triage — even before tool execution or guided troubleshooting exist — already reduces how much every ticket depends on a human reading it first.

Independent Test: Create a ticket, confirm an AI session starts and produces a diagnosis with a confidence score; configure a low threshold and confirm a low-confidence diagnosis escalates instead of proceeding; configure a high threshold and confirm a high-confidence diagnosis proceeds without escalating.

Acceptance Scenarios:

  1. Given a newly created ticket, When its AI session runs, Then a diagnosis is recorded with a product, problem type, severity, confidence score, and possible causes, and the diagnosis is grounded in knowledge actually retrieved for that product — never invented.
  2. Given a diagnosis whose confidence is at or above the configured "high" threshold for that product/category, When the policy is applied, Then the session proceeds automatically toward a solution without waiting for a human.
  3. Given a diagnosis whose confidence falls in the configured "medium" band, When the policy is applied, Then the AI asks the customer a clarifying question rather than guessing.
  4. Given a diagnosis whose confidence is below the configured "low" threshold, When the policy is applied, Then the session escalates to a human immediately, with the diagnosis attached as context.
  5. Given no knowledge exists for the ticket's product at all, When the AI session runs, Then it escalates rather than fabricating a diagnosis from nothing.
  6. Given an admin changes the confidence thresholds for a product, When the next ticket for that product is diagnosed, Then the new thresholds apply — with no deploy required.

User Story 2 - The AI asks a clarifying question and re-diagnoses from the answer (Priority: P2)

When confidence is in the "ask" band, the AI's clarifying question is delivered to the customer as a normal ticket message. When the customer replies, the AI reconsiders its diagnosis using the full conversation so far, and the confidence-band policy is applied again to the new diagnosis.

Why this priority: Depends on User Story 1's diagnosis and policy existing. Without this, the "ask" band is a dead end — a question with nowhere for the answer to go. This is what turns a single triage decision into an actual conversation.

Independent Test: Trigger a medium-confidence diagnosis, confirm the AI's question appears as a customer-visible message; reply as the customer, confirm a new diagnosis is recorded using the reply, and confirm the policy is re-applied to it (which may proceed, ask again, or escalate).

Acceptance Scenarios:

  1. Given a session in the "ask" state, When the AI's question is recorded, Then it appears as a customer-visible message on the ticket, indistinguishable in visibility from an agent's message.
  2. Given a customer reply to an AI session's question, When it's submitted, Then the AI produces a new diagnosis that accounts for the reply, not a repeat of the first one.
  3. Given a session has already asked a configured maximum number of clarifying questions without reaching high or low confidence, When another "medium" result occurs, Then the session escalates instead of asking indefinitely.

User Story 3 - The AI proposes tool calls; the application decides whether to run them (Priority: P2)

Once a session is proceeding toward a solution, the AI may request a tool call (e.g., looking up structured status information relevant to the ticket) to ground its next step in real system state instead of assumption. The AI's request is a proposal only — a deterministic policy layer checks the tool's permission and risk level before anything executes, low-risk tool calls run automatically, and every proposal, decision, and result is durably recorded.

Why this priority: Depends on User Story 1's session/diagnosis existing, but delivers standalone value once it does — the AI can consult real data rather than reasoning from the conversation text alone, without ever getting unmediated access to the system.

Independent Test: Trigger a session that proceeds toward a solution, confirm a tool call the AI proposes is checked against its declared permission and risk level before running, confirm a low-risk tool executes and its result is recorded, and confirm a tool call outside the session's product scope or the caller's permission is refused rather than run.

Acceptance Scenarios:

  1. Given the AI proposes a tool call, When the policy layer evaluates it, Then the evaluation checks the tool's declared permission, risk level, and whether the tool is enabled for the session's product — regardless of what the AI's own message claims justifies it.
  2. Given a tool call passes evaluation and is low-risk, When it's approved, Then it executes and its result (success or failure) is recorded and available to the AI's next turn.
  3. Given a tool call is high-risk, When it's proposed, Then it is never auto-executed — it requires the stronger control path (policy-and/or-human-approval) defined for that risk level before it can run.
  4. Given a tool execution fails, When the failure is recorded, Then it counts toward this session's escalation triggers rather than being silently retried forever.
  5. Given a proposed tool is not permitted for the session's product or is unknown, When it is evaluated, Then it is refused without executing, and the refusal is recorded.

User Story 4 - A matching runbook drives guided troubleshooting, not the AI's own improvisation (Priority: P3)

When a diagnosis matches a known problem type with a defined runbook, the session enters guided troubleshooting: the runbook engine — not the AI — determines which step is next, in the exact order the runbook was authored. The AI presents each step to the customer conversationally and interprets the customer's response, but it cannot skip, reorder, or invent a step the runbook doesn't define. If every step is exhausted without resolving the problem, the session escalates.

Why this priority: Depends on User Story 1 (diagnosis) and benefits from User Story 3 (a runbook step may itself require a tool call), but is a distinct, independently valuable behavior: consistent, product-approved troubleshooting sequences instead of ad hoc AI reasoning about what to try next.

Independent Test: Diagnose a problem type with a known runbook, confirm the session enters troubleshooting and presents the runbook's first step; confirm the AI cannot advance to a step out of order; exhaust every step without success and confirm the session escalates.

Acceptance Scenarios:

  1. Given a diagnosis matches a runbook's key for the ticket's product, When the session enters troubleshooting, Then the first step presented is the runbook's first authored step, never a step the AI selects on its own.
  2. Given the customer completes a step, When the session advances, Then the next step presented is exactly the next one in the runbook's authored order.
  3. Given all of a runbook's steps have been presented without resolving the problem, When the last step's outcome is recorded, Then the session escalates with every attempted step included in the hand-off summary.
  4. Given no runbook matches the diagnosed problem type, When the session would otherwise enter troubleshooting, Then it proceeds using the AI's knowledge-grounded reasoning alone (User Story 1/2 behavior) rather than failing.

User Story 5 - A ticket is only marked AI-resolved when there's real evidence, not a customer's claim alone (Priority: P3)

Before an AI session can close a ticket as resolved, it needs verification evidence — the result of an approved tool call confirming the expected outcome — not just the customer saying "it worked." Customer confirmation is recorded, but only as a secondary signal alongside the primary evidence, never as the sole basis for marking a ticket AI-resolved.

Why this priority: Depends on prior stories producing an attempted solution to verify. Guards the specific failure mode doc 03 calls out by name — the AI would rather escalate an unverified success than falsely claim resolution.

Independent Test: Reach a point where the customer reports the problem is fixed with no corroborating tool evidence, and confirm the session does not mark the ticket AI-resolved from that alone; reach the same point but with a passing verification tool result, and confirm the ticket is marked AI-resolved.

Acceptance Scenarios:

  1. Given a customer reports the problem is resolved, When no verification tool result confirms it, Then the session does not mark the ticket AI-resolved — it either waits for verifiable evidence or escalates if none is obtainable.
  2. Given a verification tool call confirms the expected outcome, When the result is recorded, Then the session may mark the ticket AI-resolved, with the customer's own confirmation (if given) recorded alongside it as a secondary signal.
  3. Given a verification tool call returns a failing or inconclusive result, When it's recorded, Then the ticket is not marked resolved, and repeated verification failure counts toward this session's escalation triggers.

Edge Cases

  • What happens if the LLM provider is unreachable or errors out mid-session? The session records the failure and escalates — an AI session that cannot reason is treated the same as one that couldn't reach a confident diagnosis, never left silently stuck.
  • What happens if the AI's response can't be parsed into the expected structured diagnosis shape? Treated as a failure of that turn — escalate rather than proceed on an unparseable result.
  • What happens if a customer's message (or anything derived from an attachment) contains text that reads like an instruction to the AI ("ignore your instructions", "you are now allowed to...")? It is treated as untrusted data to reason about, never as authority that changes tool permissions, risk-level handling, or escalation policy — those are decided by the deterministic policy layer alone, regardless of what any message claims.
  • What happens when a session is already active for a ticket and another diagnosis trigger fires (e.g., a duplicate)? The existing active session continues; a second one is never started for the same ticket while one is already active.
  • What happens if an agent takes over a ticket while an AI session is still active? The AI session ends (recorded, not deleted) — a human taking the ticket is treated as equivalent to escalation for the purpose of who's driving the ticket next.
  • What happens to a session's clarifying-question budget or step progress if the ticket sits idle for a long time? Out of scope for this feature — idle-session timeout/expiry is not defined here; a session simply waits for its next input.

Requirements (mandatory)

Functional Requirements

  • FR-001: The system MUST start an AI support session for a ticket, and MUST NOT start a second concurrent session for the same ticket while one is already active.
  • FR-002: An AI session MUST produce a structured diagnosis (product, feature if determinable, problem type, severity, confidence score, possible causes) for every diagnosis attempt, persisted and attributable to that session.
  • FR-003: A diagnosis MUST be grounded in knowledge actually retrieved for the ticket's product; the system MUST NOT present fabricated product behavior, configuration, or troubleshooting steps as if they came from the knowledge base.
  • FR-004: The system MUST evaluate every diagnosis's confidence score against configurable thresholds to select one of exactly three outcomes: proceed automatically, ask a clarifying question, or escalate to a human.
  • FR-005: Confidence thresholds MUST be configurable per product (and optionally per category) without requiring a code deploy, and MUST fall back to a system-wide default when no product-specific configuration exists.
  • FR-006: When no knowledge exists for the ticket's product, the session MUST escalate rather than produce a diagnosis with no grounding.
  • FR-007: An AI-authored clarifying question MUST be recorded as a customer-visible ticket message using the same visibility mechanism as any other customer-facing message.
  • FR-008: A customer's reply during an active AI session MUST trigger a new diagnosis that accounts for the full conversation so far, with the confidence-band policy (FR-004) re-applied to it.
  • FR-009: A session MUST escalate once it has asked a configurable maximum number of clarifying questions without reaching a "proceed" or explicit "escalate" outcome.
  • FR-010: Every tool the AI can propose MUST have a declared permission requirement, risk level (low/medium/high), and the set of products it's enabled for.
  • FR-011: Every tool call the AI proposes MUST be evaluated by a deterministic policy layer against its declared permission, risk level, and product scope before any execution — the content of the AI's own request MUST NEVER be sufficient justification on its own.
  • FR-012: A low-risk tool call that passes evaluation MAY execute automatically; a high-risk tool call MUST NOT execute automatically — it requires the stronger control path defined for that risk level.
  • FR-013: Every tool proposal, its policy evaluation outcome, and its execution result (if run) MUST be durably recorded and attributable to the session that proposed it.
  • FR-014: A tool execution failure MUST count toward the session's escalation triggers.
  • FR-015: When a diagnosis matches a runbook defined for the ticket's product, the session MUST present that runbook's steps in exactly the authored order; the AI MUST NOT be able to skip, reorder, or invent a step outside the runbook's defined sequence.
  • FR-016: When a runbook's steps are exhausted without resolving the problem, the session MUST escalate, and the hand-off MUST include every step that was attempted.
  • FR-017: When no runbook matches, the session MUST proceed using knowledge-grounded reasoning (FR-002/FR-003) rather than failing or escalating solely for that reason.
  • FR-018: The system MUST NOT mark a ticket as AI-resolved based on customer confirmation alone — resolution requires verification evidence from an approved tool call confirming the expected outcome.
  • FR-019: Customer confirmation of a fix, when given, MUST be recorded as a secondary signal alongside — never instead of — verification evidence.
  • FR-020: The system MUST escalate a session when any of: confidence is below the configured low threshold, no knowledge exists for the product, a runbook is exhausted without success, a required tool execution fails, the clarifying-question budget is exhausted, the customer explicitly asks for a human, or the reasoning provider itself fails or returns an unusable result.
  • FR-021: An escalation MUST hand off to a human-workable ticket state with a structured summary attached — problem, diagnosis, steps attempted (tool calls and/or runbook steps), and the AI's own confidence at the time of escalation.
  • FR-022: An escalation MUST end the session's active reasoning (recorded, not deleted); the ticket becomes human-owned from that point.
  • FR-023: If a human agent takes ownership of a ticket while its AI session is still active, the system MUST end that session the same way an escalation does.
  • FR-024: Content from a customer message, or derived from an attachment, MUST be treated as data for the AI to reason about, never as instructions capable of altering tool permissions, risk-level handling, or escalation policy.

Key Entities

  • AI Support Session: The unit of AI involvement in one ticket — one active session per ticket, with a status reflecting where it is in the flow (analyzing, troubleshooting, verifying, resolved, escalated), and the diagnoses/interactions/tool actions/knowledge references it produced.
  • Diagnosis: A structured, confidence-scored classification of the customer's problem produced at a point in time; a session accumulates one per reasoning attempt, never overwriting a prior one.
  • Interaction: A single turn of the conversation between the customer and the AI within a session (the customer's message, or the AI's response), preserved in order.
  • Tool Proposal / Action: A request from the AI to invoke a specific tool with specific input, together with the policy layer's evaluation and, if executed, its result — the complete, auditable record of every action the AI attempted, whether or not it ran.
  • Confidence Policy Configuration: The per-product (optionally per-category) thresholds and clarifying-question limit that determine when a diagnosis proceeds, asks, or escalates — editable by an admin without a deploy.
  • Escalation: The recorded hand-off from an AI session to a human, carrying the structured summary a human agent needs to pick up where the AI left off.

Success Criteria (mandatory)

Measurable Outcomes

  • SC-001: Every new ticket receives an AI diagnosis attempt without any human having to trigger it manually.
  • SC-002: 100% of diagnoses below the configured low-confidence threshold result in escalation, never a guessed proceed-automatically outcome.
  • SC-003: 100% of high-risk tool proposals are blocked from automatic execution, verified across every risk level in the tool registry.
  • SC-004: 100% of tickets marked AI-resolved have at least one passing verification tool result attached — zero marked resolved from customer confirmation alone.
  • SC-005: An admin can change a product's confidence thresholds and see the new thresholds apply to the very next diagnosis for that product — no deploy, no restart.
  • SC-006: Every escalation carries a structured summary a human agent can act on without re-reading the entire raw conversation first.
  • SC-007: When a runbook matches, 100% of presented steps follow the runbook's authored order — zero cases of a step being skipped, reordered, or improvised.

Assumptions

  • The AI reasoning calls a real LLM provider (Anthropic Claude, via the official SDK), per explicit product decision — this is not a mock or a pluggable-interface placeholder. A real API credential must be supplied via environment variable to run this feature at all; without it, the feature cannot function (there is no offline fallback path in scope).
  • Retrieval feeds the AI from GET /knowledge/retrieve (built in 004-product-knowledge) as structured, filtered, validation-aware context — this feature does not add a semantic/embedding/vector retrieval layer. Per docs/11-...md §B1, real semantic retrieval is a significant, separable infrastructure decision (embedding model, vector store, chunking, re-ranking); layering it under the same retrieval contract later does not require reworking this feature's reasoning flow.
  • The tool catalog in this feature is generic to the platform, not per-integrated-product. Doc 03's example tools (retryConversion, enableFallbackParser, etc.) are illustrative of a specific hypothetical product (DocuQube) this codebase has no integration with. This feature builds the tool system (registry, permission/risk gating, execution, audit) plus a small set of real tools backed by data this platform actually has (ticket/problem state, knowledge lookup, escalation) — not fictional product-specific actions. A specific SaaS product's own tools (e.g., DocuQube's real retry endpoint) would be registered later through the same system, out of scope here.
  • Per-session token/cost governance (doc 11 §B2: token budget, step-count cap on the reasoning loop) is implemented as a hard cap on reasoning turns and tool-call iterations per session, to prevent a runaway loop — full cost-per-ticket reporting/dashboards are out of scope for this feature (later observability work, doc 09).
  • Product-signal verification (a webhook/event from the integrated product confirming success) is out of scope — ProductIntegration has no outbound callback mechanism yet (doc 11 §A2 is a separate, not-yet-built gap). This feature's verification evidence comes from an approved tool call's result, consistent with doc 03 §8's "automated verification (poll a status endpoint via an approved tool)" mode.
  • Runbook execution consumes the Runbook records already built in 004-product-knowledge (ordered steps JSON, looked up by key/product, active/inactive) — this feature adds the engine that walks those steps during a live session; it does not change how runbooks are authored or versioned.
  • Model routing (a smaller/faster model for one call, a stronger one for another, per doc 11 §B2) is not implemented — a single configurable model applies to all reasoning calls in this feature; which specific model is a plan-stage decision, not a spec-level one.
  • Localization (doc 11 §B7) is out of scope — the AI reasons and responds in whatever language the conversation is already in, with no explicit translation layer.