Files
support_backend/specs/009-problem-resolution/spec.md
T
saqib mirandClaude Sonnet 5 14c6793460 docs: spec for problem resolution feature (009)
Investigation -> Root Cause -> Solution -> Implementation ->
Verification -> Resolution, plus customer confirmation and reopen,
matching doc04 SS3-9's workflow narrative and doc06's "Domain: Problem
Resolution" schema exactly. Explicitly closes a loop 008's own spec left
open (reopen never restarts an SLA run); verification-failure escalation
reuses 003/007's existing HUMAN_ESCALATION transition rather than adding
an eleventh escalation-rule trigger type to 008's system.

Also documents a real scope-boundary finding: src/modules/problem-management/problems
is a dead, unwired duplicate scaffold for Problem (the real one has lived
in ticketing/tickets since 003) and is not touched by this feature -- only
the five investigation/root-causes/solutions/resolutions/verification
stub directories are.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-03 14:33:55 +05:30

19 KiB

Feature Specification: Problem Resolution

Feature Branch: 009-problem-resolution

Created: 2026-09-03

Status: Draft

Input: User description: "Phase 9 of docs/10-implementation-roadmap.md: Investigation/ RootCause/Solution/SolutionImplementation/SolutionVerification/Resolution models and workflows, customer confirmation + reopen flow. Per docs/04-ticketing-and-problem-management.md §3-9 and docs/06-database-schema.md 'Domain: Problem Resolution'."

User Scenarios & Testing (mandatory)

User Story 1 - An agent records structured investigation findings (Priority: P1)

An agent investigating a problem records findings, evidence, and internal notes as a structured record — not a free-text blob buried in a message — with its own status (open/complete). A problem can have more than one investigation attempt over its lifetime, each preserved, not overwritten.

Why this priority: Everything downstream (root cause, solution, verification) reads from or references an investigation; nothing else in this feature can start without one existing first.

Independent Test: Record an investigation with findings and evidence for a problem; confirm it's retrievable exactly as given, with its own investigator and timestamp.

Acceptance Scenarios:

  1. Given an agent records an investigation with findings, When it's saved, Then it's retrievable with investigator, findings, evidence, internalNotes, and status exactly as given.
  2. Given a problem already has a completed investigation, When a new investigation is started for the same problem (e.g., after a failed verification, User Story 4), Then the prior investigation's record is preserved unchanged — a new investigation is its own row, never an overwrite of the earlier one.
  3. Given internalNotes on an investigation, When any customer-facing view is composed, Then that data is never included — internal notes are agent/admin-only, same "never shown to customers" discipline as ticketing's INTERNAL_NOTE message type (004 §10).

User Story 2 - An agent records a root cause, separate from the investigation (Priority: P1)

Once findings point to a cause, the agent records a root cause as its own record — distinct from the investigation that surfaced it — typed as technical, configuration, external-dependency, business, or a contributing factor.

Why this priority: A solution (User Story 3) is a response to a specific, recorded cause — without one, "solving" a problem has nothing to be checked against.

Independent Test: Record a root cause of a given type for a problem with an investigation already on file; confirm it's retrievable and distinct from the investigation record.

Acceptance Scenarios:

  1. Given a problem with an investigation on file, When an agent records a root cause with a type and description, Then it's retrievable as its own record, never merged into the investigation's own fields.
  2. Given a root cause type outside the five documented values, When it's submitted, Then it's rejected — the type is a closed, validated set, not free text.

User Story 3 - An agent proposes, approves, and implements a solution, each as its own state (Priority: P1)

A solution moves through distinct states — proposed, approved, implemented — never collapsed into one mutable blob. Implementation is its own record: who implemented it, when, and any notes, kept separate from the proposal itself.

Why this priority: Verification (User Story 4) and resolution (User Story 5) both need a concrete, dated implementation record to verify and resolve against.

Independent Test: Propose a solution, approve it, then record its implementation; confirm all three states are independently visible on the same solution record/its implementation relation.

Acceptance Scenarios:

  1. Given a root cause on file, When an agent proposes a solution, Then it's stored with approved: false by default.
  2. Given a proposed solution, When it's approved, Then approved becomes true — approval is a distinct, explicit action, never implied by implementation happening.
  3. Given an approved solution, When an agent records its implementation (notes, implementer, timestamp), Then a SolutionImplementation record is created, one-to-one with the solution — attempting a second implementation record for the same solution is rejected, not silently overwritten.
  4. Given a solution that has not been approved, When an implementation is attempted, Then it's rejected — implementation without approval is never allowed.

User Story 4 - A solution is verified; failure re-opens investigation or escalates (Priority: P2)

After implementation, the solution is verified by one of several methods (automated check, technical test, customer confirmation, agent confirmation). A successful verification clears the way to resolution (User Story 5). A failed verification either re-opens investigation (a fresh investigation record for the same problem) or escalates the ticket — an agent's explicit choice, not an automatic guess.

Why this priority: Depends on User Story 3 (something implemented to verify). Recording a resolution without ever having verified anything would misrepresent what was actually confirmed.

Independent Test: Verify an implemented solution as failed; confirm no Resolution can be recorded from it, and that either a fresh investigation exists or the ticket has been escalated, per the agent's chosen path.

Acceptance Scenarios:

  1. Given an implemented solution, When it's verified with result: success, Then a SolutionVerification record is created (method, result, evidence, timestamp), one-to-one with the solution.
  2. Given an implemented solution, When it's verified with result: failed, Then no resolution can reference this solution's verification as successful — a failed verification is a real, recorded outcome, not silently discarded.
  3. Given a failed verification and the agent chooses re-investigation, When that choice is made, Then a new Investigation record is created for the same problem (User Story 1's own "each attempt is its own row" rule).
  4. Given a failed verification and the agent chooses escalation instead, When that choice is made, Then the ticket transitions to HUMAN_ESCALATION through 003-ticketing's existing state machine — 007's orchestration re-runs automatically from that transition alone, exactly as it already does for any other route into HUMAN_ESCALATION; this feature does not invent a second escalation mechanism alongside 008's.

User Story 5 - A resolution is recorded, with configurable customer confirmation or auto-close (Priority: P1)

Once a solution is verified successful, a Resolution record captures the final outcome for the ticket. Depending on configuration, the ticket either waits for explicit customer confirmation before closing, or auto-closes after a configured waiting period with no response.

Why this priority: This is the feature's actual deliverable from the customer's point of view — everything before this is agent-facing work product.

Independent Test: Record a resolution for a ticket with a successfully verified solution; confirm the ticket reaches RESOLUTION_PENDING_CUSTOMER, then either an explicit confirmation or the configured waiting period elapsing moves it to RESOLVED.

Acceptance Scenarios:

  1. Given a solution with a successful verification, When an agent records a resolution, Then a Resolution record is created (outcome, resolvedBy) and the ticket transitions to RESOLUTION_PENDING_CUSTOMER.
  2. Given a ticket in RESOLUTION_PENDING_CUSTOMER, When the customer explicitly confirms, Then the ticket transitions to RESOLVED.
  3. Given a ticket in RESOLUTION_PENDING_CUSTOMER with no customer response, When the configured auto-close waiting period elapses, Then the ticket transitions to RESOLVED automatically — durably, via a background job, never an in-memory timer (Constitution Principle VII, same discipline 008's breach-detection job already established).
  4. Given a Resolution is attempted without a successfully verified solution on file, When it's attempted, Then it's rejected — a resolution must be backed by real, recorded verification, never asserted on its own.

User Story 6 - A resolved or closed ticket can be reopened (Priority: P2)

A customer or agent can reopen a RESOLVED or CLOSED ticket, which re-enters the appropriate point in the lifecycle rather than starting over from NEW.

Why this priority: Depends on User Story 5 (a ticket has to have reached a closeable state before reopening it means anything). Closes the loop 008 explicitly left open ("reopening... may need its own SLA-run-restart decision").

Independent Test: Reopen a RESOLVED ticket; confirm it transitions to REOPENED and then into an active lifecycle state, and that the prior resolution record remains on file, unaltered.

Acceptance Scenarios:

  1. Given a RESOLVED or CLOSED ticket, When the customer or an agent reopens it, Then the ticket transitions to REOPENED and then to IN_PROGRESS (003's existing REOPENED → IN_PROGRESS transition) — never back to NEW.
  2. Given a ticket is reopened, When the prior Resolution record is checked, Then it remains on file exactly as it was — reopening never deletes or mutates history.
  3. Given a ticket already has an SLA run (008) from its original assignment, When it's reopened, Then no new SLA run is created and the existing one is left exactly as it was (008's own Assumptions: "SLA runs are 1:1 with a ticket's first successful assignment only") — this feature does not retroactively expand that boundary.

Edge Cases

  • What happens if an agent tries to record a root cause before any investigation exists for the problem? Rejected — a root cause without a preceding investigation has nothing to be grounded in (FR-006).
  • What happens if a solution is proposed for a problem with no root cause on file? Rejected, same reasoning as above (FR-009).
  • What happens if two verification attempts are recorded for the same solution? Rejected — like SolutionImplementation, SolutionVerification is one-to-one with its solution (doc 06's own @unique on solutionId); a second verification attempt on an already-verified solution is out of scope for this feature (re-verification of a previously-verified solution is not a flow doc 04 describes).
  • What happens to a ticket's messages/attachments/assignment history when it's reopened? Nothing — reopening only affects Ticket.status; every other record (007's Assignment, 008's SLARun, this feature's own Investigation/RootCause/Solution/Resolution records) is untouched by the reopen transition itself.
  • What happens if the configured auto-close waiting period is set to zero or is unconfigured? Zero is a valid configuration (auto-close as soon as the sweep next runs); unconfigured falls back to a system default (Constitution Principle II — configuration over hardcoding, but a default value must exist so the sweep job always has something to compare against).
  • What happens if a ticket is reopened more than once? Each reopen is its own REOPENED → IN_PROGRESS transition — no cap on how many times a ticket can be reopened is introduced by this feature (counting reopens toward an escalation trigger remains 008's already-documented, deliberately deferred repeated_reopen trigger type — this feature does not wire it up).

Requirements (mandatory)

Functional Requirements

  • FR-001: The system MUST let an agent record an investigation (investigator, findings, evidence, internal notes, status) for a problem.
  • FR-002: Each investigation MUST be its own durable record — a new investigation for the same problem (e.g., after a failed verification) MUST NOT overwrite a prior one.
  • FR-003: Internal notes on an investigation MUST NEVER be exposed through any customer-facing read path.
  • FR-004: The system MUST let an agent record a root cause (type, description) for a problem, as a record distinct from any investigation.
  • FR-005: A root cause's type MUST be validated against the five documented values (technical, configuration, external_dependency, business, contributing_factor) — never free text.
  • FR-006: Recording a root cause for a problem with no investigation on file MUST be rejected.
  • FR-007: The system MUST let an agent propose a solution for a problem (approved: false by default), approve it explicitly, and record its implementation (notes, implementer, timestamp) as a separate, one-to-one record.
  • FR-008: Recording an implementation for a solution that has not been approved MUST be rejected.
  • FR-009: Proposing a solution for a problem with no root cause on file MUST be rejected.
  • FR-010: The system MUST let an agent record a verification (method, result, evidence) for an implemented solution, as a one-to-one record.
  • FR-011: A verification's method MUST be validated against the four documented values (automated, technical_test, customer_confirmation, agent_confirmation).
  • FR-012: A failed verification MUST NOT permit a Resolution to be recorded against that solution.
  • FR-013: On a failed verification, the system MUST support either starting a fresh investigation for the same problem (FR-002) or transitioning the ticket to HUMAN_ESCALATION (003's existing state machine, triggering 007's existing orchestration subscriber automatically) — the choice between the two is the recording agent's, not automatic.
  • FR-014: The system MUST let an agent record a Resolution (outcome, resolvedBy) for a ticket, only when a successfully verified solution exists for its problem — this transitions the ticket to RESOLUTION_PENDING_CUSTOMER.
  • FR-015: The system MUST let a customer explicitly confirm a pending resolution, transitioning the ticket to RESOLVED.
  • FR-016: The system MUST auto-transition a ticket from RESOLUTION_PENDING_CUSTOMER to RESOLVED after a configured waiting period with no explicit customer confirmation — detected by a durable background job, never an in-memory timer (Constitution Principle VII).
  • FR-017: The system MUST let a customer or agent reopen a RESOLVED or CLOSED ticket, transitioning it to REOPENED and then IN_PROGRESS — never back to NEW, and never mutating any prior investigation/root-cause/solution/verification/resolution record.
  • FR-018: Reopening a ticket MUST NOT create a new SLA run (008's existing 1:1-with-first- assignment boundary is unchanged by this feature).

Key Entities

  • Investigation: A structured, per-attempt record of what an agent found while investigating a problem — findings, evidence, internal notes — never free text buried in a message; a problem can have more than one, each preserved.
  • Root Cause: Why the problem happened, typed and recorded separately from what was found (the investigation).
  • Solution: What's proposed to fix the root cause, moving through proposed → approved states explicitly.
  • Solution Implementation: The one-to-one record of a solution actually being carried out — who, when, and any notes — distinct from the proposal.
  • Solution Verification: The one-to-one record of whether the implementation actually worked, by which method.
  • Resolution: The final, ticket-level outcome — distinct from the solution (what was done) and the verification (whether it worked).

Success Criteria (mandatory)

Measurable Outcomes

  • SC-001: 100% of investigation/root-cause/solution/implementation/verification/resolution records, once created, remain retrievable exactly as given — no field silently dropped or overwritten by a later action in the same problem's lifecycle.
  • SC-002: 100% of internal-notes fields are absent from every customer-facing response, verified by a direct comparison of the agent-facing and customer-facing read paths for the same investigation.
  • SC-003: 100% of resolutions recorded without a successfully verified solution on file are rejected.
  • SC-004: 100% of tickets reaching RESOLUTION_PENDING_CUSTOMER with no explicit customer confirmation reach RESOLVED within one auto-close job cycle of their configured waiting period elapsing.
  • SC-005: 100% of reopened tickets leave every prior investigation/root-cause/solution/ verification/resolution record and SLA run untouched.

Assumptions

  • This feature does not build a customer-facing confirmation UI — "explicit customer confirmation" (FR-015) is an API action a caller (a future customer portal, or 008/010's own future UI work) can invoke; this feature's own scope is the backend transition and the auto-close fallback, not a rendered confirmation page (010 — Agent/Admin UI — is a separate, later roadmap phase).
  • Verification-failure escalation reuses 003-ticketing's existing HUMAN_ESCALATION state transition and 007's already-automatic orchestration subscriber directly — it does not create a new EscalationEvent through 008's rule-based mechanism, since "solution verification failed" is not one of doc 05 §6's ten escalation trigger types 008 modeled; inventing an eleventh type for a single feature's own internal flow was judged unnecessary scope, not an oversight. Re-escalation through the plain ticket-status transition is exactly what 007 was already built to react to — no new coupling is introduced.
  • The auto-close waiting period is a single, system-wide configuration value (Principle II — configuration over hardcoding), not scoped per product/category the way 008's SLA policies are; doc 04 §9 describes it as "a configured waiting period," not a per-context policy table, and nothing in doc 06's schema defines a per-scope auto-close entity to resolve against.
  • repeated_reopen (008's already-inert escalation trigger type) is still not wired up by this feature — reopening increments no counter and triggers no escalation rule; this remains future work exactly as 008's own Assumptions already documented, not something this feature silently expands into.
  • A second verification attempt on an already-verified solution is out of scope — doc 06's SolutionVerification.solutionId is @unique, meaning at most one verification record per solution; if a first verification fails and the agent chooses re-investigation (FR-013), any new solution that comes out of that fresh investigation cycle gets its own new Solution row (User Story 3) with its own verification slot — never a second write to the original one.