# Anomaly Detection Agent - Implementation Tasks

## Overview

Implementation of a **generic** anomaly detection agent system. The system is fully domain-agnostic: all domain knowledge (what database to query, what KPIs to monitor, what thresholds to use) comes from plain text prompts stored in `MonitorSpec.SystemPrompt`. The agent uses MCP tools (`mysql_query` via `benborla/mcp-server-mysql`) to access data and formulates its own SQL queries based on the prompt instructions.

**Architecture:**
- **MonitorSpec** - plain text instructions (system prompt) describing what to monitor
- **Agent** - single generic `AnomalyDetectorAgent` using `IChatClient` (LLM) + MCP tools
- **MCP Tools** - `McpToolProvider` connects to MySQL via stdio transport, exposes tools to the agent
- **emit_conclusion** - custom tool the agent calls to report structured findings
- **Orchestrator** - loads spec, runs agent, emits alerts, records history

**Tech Stack:**
- .NET 10, Aspire-based solution
- AWS Bedrock (Claude) via `IChatClient` (registered in `Kds.Ai.AgentsCommon`)
- `Microsoft.Extensions.AI` / `Microsoft.Agents.AI` v1.0.0-preview
- MySQL via `benborla/mcp-server-mysql` MCP server (stdio transport)
- EF Core with MySQL for internal state (MonitorSpec, MonitorRun, AlertEvent)

---

## Task Checklist

### Phase 1: Infrastructure & Data Layer

- [x] [TASK1.1](./TASK1.1.md) - Create MonitorSpec entity (sealed, MonitorState enum, no StoreGuid/MonitorType)
- [x] [TASK1.2](./TASK1.2.md) - Create MonitorRun entity (sealed, ICollection\<AlertEvent\> via many-to-many join table)
- [x] [TASK1.3](./TASK1.3.md) - Create EF migration (via Add-Migration.ps1, auto-applies at AppHost startup)
- [x] [TASK1.4](./TASK1.4.md) - Create McpToolProvider using official MCP C# SDK (StdioClientTransport)

### Phase 2: Agent Core

- [x] [TASK 2.1](./TASK2.1.md) - Create IAnomalyDetectorAgent interface and result types (generic, no domain DTOs)
- [x] [TASK 2.2](./TASK2.2.md) - Create AnomalyDetectorAgent implementation (agentic loop + emit_conclusion tool)

### Phase 3: MonitorSpec System

- [x] [TASK 3.1](./TASK3.1.md) - Create IMonitorSpecRepository interface (name-based, MonitorState)
- [x] [TASK 3.2](./TASK3.2.md) - Implement EfMonitorSpecRepository (sealed, ExecuteUpdateAsync)
- [x] [TASK 3.3](./TASK3.3.md) - Create MonitorSpecSeeder + ExamplePrompts (generic, no factory)

### Phase 4: Runtime Orchestration

- [x] [TASK 4.1](./TASK4.1.md) - Create IMonitorRunOrchestrator interface (no ExecuteAllActiveAsync, no store/type)
- [x] [TASK 4.2](./TASK4.2.md) - Implement MonitorRunOrchestrator (sealed, single agent, AlertEvents collection)
- [x] [TASK 4.3](./TASK4.3.md) - Create AlertEmitter (sealed, name-based dedup, generic findings)
- [x] [TASK 4.4](./TASK4.4.md) - Create MonitorRunRepository (sealed, no GetByStore, no alertEventId param)

### Phase 5: CLI Integration

- [ ] [TASK 5.1](./TASK5.1.md) - Create RunAnomalyDetectorCommand (--name/--spec-id, set-state, no --store)
- [ ] [TASK 5.2](./TASK5.2.md) - Wire up DI (McpToolProvider, AnomalyDetectorAgent, no deleted services)
- [ ] [TASK 5.3](./TASK5.3.md) - Add enhanced CLI options (history, stats, json output)

### Phase 6: Testing & Validation

- [ ] [TASK 6.1](./TASK6.1.md) - Create mock testing infrastructure (FakeChatClient, FakeMcpToolProvider, ScriptedAgentScenarios)
- [ ] [TASK 6.2](./TASK6.2.md) - Add integration and unit tests using fakes
- [ ] [TASK 6.3](./TASK6.3.md) - Test against real KDSDev with sample data

---

## Deleted Tasks (for reference)

The following tasks existed in the **original** numbering scheme (before renumbering) and were **deleted** because the system is generic. These numbers no longer correspond to any current files:

- ~~Old TASK 2.1~~ IKdsDataAccessService - deleted (agent uses MCP tools directly)
- ~~Old TASK 2.2~~ McpKdsDataAccessService - deleted (no typed data access layer)
- ~~Old TASK 2.3~~ PrepTimeQueryBuilder - deleted (agent formulates its own SQL)
- ~~Old TASK 2.4~~ KDSDev connection config - deleted (MCP config is in TASK 1.4)
- ~~Old TASK 3.3~~ Hardcoded prep-time system prompt - deleted (prompts are plain text in MonitorSpec)
- ~~Old TASK 3.4~~ Hardcoded tool definitions wrapping IKdsDataAccessService - deleted (agent uses MCP tools)
- ~~Old TASK 3.5~~ PrepTimeFeaturePanel DTOs - deleted (no typed domain models)

---

## Dependency Graph

```
Phase 1 (Infrastructure)
    |-- 1.1 MonitorSpec Entity
    |-- 1.2 MonitorRun Entity  
    |-- 1.3 Migration <-- (depends on 1.1, 1.2)
    +-- 1.4 McpToolProvider

Phase 2 (Agent Core) <-- depends on 1.1, 1.4
    |-- 2.1 IAnomalyDetectorAgent + Result Types
    +-- 2.2 AnomalyDetectorAgent <-- (depends on 2.1, 1.4)

Phase 3 (MonitorSpec) <-- depends on 1.1
    |-- 3.1 IMonitorSpecRepository
    |-- 3.2 EfMonitorSpecRepository <-- (depends on 3.1)
    +-- 3.3 MonitorSpecSeeder + ExamplePrompts <-- (depends on 3.1)

Phase 4 (Orchestration) <-- depends on Phase 2, Phase 3
    |-- 4.1 IMonitorRunOrchestrator
    |-- 4.2 MonitorRunOrchestrator <-- (depends on 4.1, 2.1, 3.1, 4.3, 4.4)
    |-- 4.3 AlertEmitter
    +-- 4.4 MonitorRunRepository

Phase 5 (CLI) <-- depends on Phase 4
    |-- 5.1 RunAnomalyDetectorCommand <-- (depends on 4.1, 3.1, 3.3)
    |-- 5.2 DI Wiring
    +-- 5.3 Enhanced CLI Options

Phase 6 (Testing) <-- depends on all
    |-- 6.1 Fakes (FakeChatClient, FakeMcpToolProvider)
    |-- 6.2 Integration + Unit Tests <-- (depends on 6.1)
    +-- 6.3 Real Testing
```

---

## Recommended Session Order

| Session | Tasks | Description |
|---------|-------|-------------|
| 1 | 1.1, 1.2, 1.3 | Data entities + migration |
| 2 | 1.4 | McpToolProvider setup |
| 3 | 2.1, 2.2 | Agent interface + implementation |
| 4 | 3.1, 3.2, 3.3 | MonitorSpec repository + seeder |
| 5 | 4.1, 4.2, 4.3, 4.4 | Orchestration layer |
| 6 | 5.1, 5.2, 5.3 | CLI integration |
| 7 | 6.1, 6.2, 6.3 | Testing |

---

## Key Design Decisions

### Generic System (No Domain Models in Code)

The system contains **zero** domain-specific code:
- No `PrepTimeHourlyStats`, `OrderTypeBreakdown`, or other typed DTOs
- No `IKdsDataAccessService` or `PrepTimeQueryBuilder`
- No `IAnomalyDetectorAgentFactory` or `MonitorType` discriminator
- All domain knowledge lives in `MonitorSpec.SystemPrompt` as plain text

### Single Agent, No Factory

There is one `AnomalyDetectorAgent` class. Different monitors are distinguished by their `MonitorSpec.SystemPrompt`, not by different agent classes. No factory pattern.

### MCP-Driven Data Access

The agent accesses data through MCP tools provided by `McpToolProvider`. The LLM formulates SQL queries based on the system prompt instructions. No code-level query building.

### MonitorState Enum (Not Boolean)

`MonitorSpec.State` uses a 4-value enum (`Draft`, `Active`, `Paused`, `Archived`) instead of `bool IsEnabled`.

### Many-to-Many Alert Relationship

`MonitorRun` has `ICollection<AlertEvent> AlertEvents` via a join table, not a single `Guid? AlertEventId` FK. One run can detect multiple anomalies resulting in multiple alerts.

---

## Reference: KDSDev Orders Table Schema

```sql
create table orders
(
    guid                   varchar(36)       not null primary key,
    store_guid             varchar(36)       not null,
    destination            varchar(255)      null,
    external_id            varchar(199)      not null,
    guest_table            varchar(199)      null,
    is_priority            tinyint default 0 not null,
    items_count            int     default 0 not null,
    order_type             varchar(199)      null,
    pos_terminal           varchar(199)      null,
    preparation_time       int               null,
    server_name            varchar(199)      null,
    user_info              varchar(199)      null,
    done                   tinyint default 0 not null,
    create_time            int               not null,
    update_time            int               not null,
    upload_time            int     default 1 null,
    is_deleted             tinyint default 0 not null,
    update_device          varchar(36)       null,
    phone                  tinytext          null,
    create_local_time      int     default 0 null,
    is_hidden              tinyint default 0 not null,
    customer_guid          varchar(36)       null,
    smart_order_start_time int     default 0 null,
    order_messages         varchar(255)      not null,
    customer_name          varchar(60)       null,
    seat                   int               null,
    order_status           int               null
)
```

**Note:** This schema is provided as reference for writing example prompts. The agent code does not reference these columns - only the MonitorSpec's plain text prompt does.
