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>
This commit is contained in:
saqib mir
2026-09-03 14:33:55 +05:30
co-authored by Claude Sonnet 5
parent 7e3d2ae29f
commit 14c6793460
2 changed files with 367 additions and 0 deletions
@@ -0,0 +1,52 @@
# Specification Quality Checklist: Problem Resolution
**Purpose**: Validate specification completeness and quality before proceeding to planning
**Created**: 2026-09-03
**Feature**: [spec.md](../spec.md)
## Content Quality
- [x] No implementation details (languages, frameworks, APIs)
- [x] Focused on user value and business needs
- [x] Written for non-technical stakeholders
- [x] All mandatory sections completed
## Requirement Completeness
- [x] No [NEEDS CLARIFICATION] markers remain
- [x] Requirements are testable and unambiguous
- [x] Success criteria are measurable
- [x] Success criteria are technology-agnostic (no implementation details)
- [x] All acceptance scenarios are defined
- [x] Edge cases are identified
- [x] Scope is clearly bounded
- [x] Dependencies and assumptions identified
## Feature Readiness
- [x] All functional requirements have clear acceptance criteria
- [x] User scenarios cover primary flows
- [x] Feature meets measurable outcomes defined in Success Criteria
- [x] No implementation details leak into specification
## Notes
- Scope is Phase 9 per `docs/10-implementation-roadmap.md`: Investigation → Root Cause →
Solution → Solution Implementation → Solution Verification → Resolution, plus customer
confirmation and reopen — the full doc 04 §3-9 workflow narrative, matching doc 06's "Domain:
Problem Resolution" schema exactly (no new fields invented beyond what's already documented).
- `src/modules/problem-management/{investigation,root-causes,solutions,resolutions,verification}`
are the five real target stub directories for this feature (each currently a one-file stub
returning a hardcoded placeholder). `src/modules/problem-management/problems` was found to be a
**dead, unwired duplicate scaffold** for `Problem` — the real, actively-used `Problem` model and
repository already live in `ticketing/tickets` since 003 — this feature does not touch
`problem-management/problems`, matching this session's established discipline of only replacing
stubs a documented phase's roadmap item actually calls for.
- This feature explicitly closes a loop 008-sla-escalation's own spec.md left open in its Edge
Cases: "reopening... may need its own SLA-run-restart decision" — resolved here as "no new SLA
run on reopen" (FR-018), keeping 008's already-shipped 1:1-with-first-assignment boundary
unchanged rather than reopening (no pun intended) that feature's own scope.
- Verification-failure escalation deliberately reuses 003/007's existing `HUMAN_ESCALATION`
transition rather than inventing a new escalation-rule trigger type in 008's system — flagged
explicitly in Assumptions as a scope decision, not an oversight.
- All items pass; no revision iterations were needed.
+315
View File
@@ -0,0 +1,315 @@
# 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.