excludes: semantic/vector retrieval, product-signal webhook verification, model routing/fallback,
cost dashboards, localization, idle-session timeout (see spec.md Assumptions).
## Constitution Check
*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.*
| Principle / Section | Check | Result |
|---|---|---|
| I. SaaS Is the Sole Identity & Access Authority | Sessions/diagnoses/actions reference `Ticket`/`Product` (SupportHub's own domain) only; no SaaS identity data is duplicated. | PASS |
| II. Configuration Over Hardcoding | Confidence thresholds are DB-configurable per product/category (`AIConfidencePolicy`, FR-005); the model name and reasoning effort are env-configurable (research.md), not inline string literals. | PASS |
| III. Layered Architecture With Enforced Module Boundaries | Four new submodules follow the standard shape; `troubleshooting` reaches `knowledge`'s `Runbook` data only through `knowledge`'s public `index.ts`, never a deep import. | PASS |
| IV. AI Recommends, Deterministic Policy Decides | This is the central principle this feature exists to implement: `evaluateToolProposal` (research.md) is the one shared, model-output-blind gate every tool call passes through; confidence-band policy is applied to the diagnosis's numeric score by application code, never by asking the model what it thinks should happen next. | PASS |
| V. Evidence-Based Verification | `resolved` status is guarded on a structured `AIActionResult` from `verifyProductResolution`, never on interaction/message content (research.md "Verification and resolution"). | PASS |
| VI. Durable Audit & History | Every `AIDiagnosis` is append-only (never overwritten); every `AIAction` records its evaluation outcome even when nothing executes; `AIKnowledgeReference` records exactly what knowledge the AI was shown. | PASS |
| VII. Concurrency-Safe, Durable Job Handling | The first-turn job runs through the existing durable BullMQ `queueManager` (survives a process restart — not an in-memory timer); "one active session per ticket" (FR-001) is enforced as a repository-level check analogous to 003's optimistic-concurrency pattern. | PASS |
| VIII. Problem and Ticket Are Separate, Related Entities | `AISupportSession` attaches to `Ticket` (per doc 06), and reads `Problem` for diagnosis context — doesn't collapse the two. | PASS |
| Technology & Platform Constraints | Adds exactly one new dependency, `@anthropic-ai/sdk` — the one genuinely new capability this phase requires; no other new runtime dependency. | PASS |
| Testing gate — AI tool-permission tests | Directly required by the constitution's Testing section, not just this feature's own FRs — see quickstart Scenario 3 and tasks.md. | Addressed in Phase 3 (US3) tests |
| Testing gate — two standing E2E scenarios (AI-resolves, AI-escalates) | Both were impossible before this feature (no AI session existed anywhere in the codebase) — added here as the constitution requires. | Addressed in Phase 6 (Polish) |
No violations requiring Complexity Tracking justification. The one deliberately-incomplete piece
(`overrideTicketPriority` staying `pending_approval` forever, with no approval UI yet) is an
explicitly documented known limitation, not a silent gap — same class as `fastify.authenticate`.
## Post-Design Constitution Re-check
All gates above remain PASS after Phase 1 design (research.md, data-model.md, contracts/,
quickstart.md). Worth calling out explicitly against Principle IV: the two-call design
(classify+diagnose, then separately reason/act — research.md) means the confidence-band policy
sits in application code *between* two model calls, not inside a prompt instruction hoping the
model applies its own policy correctly — this is what makes Principle IV a mechanical guarantee
here rather than a hope.
## Project Structure
### Documentation (this feature)
```text
specs/005-ai-support/
├── plan.md # This file
├── research.md # Phase 0 output
├── data-model.md # Phase 1 output
├── quickstart.md # Phase 1 output
├── contracts/ # Phase 1 output
└── tasks.md # Phase 2 output (/speckit-tasks — not created here)