# Implementation Plan

## Validation Checklist

- [x] All specification file paths are correct and exist
- [x] Context priming section is complete
- [x] All implementation phases are defined
- [x] Each phase follows TDD: Prime → Test → Implement → Validate
- [x] Dependencies between phases are clear (no circular dependencies)
- [x] Parallel work is properly tagged with `[parallel: true]`
- [x] Activity hints provided for specialist selection `[activity: type]`
- [x] Every phase references relevant SDD sections
- [x] Every test references PRD acceptance criteria
- [x] Integration & E2E tests defined in final phase
- [x] Project commands match actual project setup
- [x] A developer could follow this plan independently

---

## Specification Compliance Guidelines

### How to Ensure Specification Adherence

1. **Before Each Phase**: Complete the Pre-Implementation Specification Gate
2. **During Implementation**: Reference specific SDD sections in each task
3. **After Each Task**: Run Specification Compliance checks
4. **Phase Completion**: Verify all specification requirements are met

### Deviation Protocol

If implementation cannot follow specification exactly:
1. Document the deviation and reason
2. Get approval before proceeding
3. Update SDD if the deviation is an improvement
4. Never deviate without documentation

## Metadata Reference

- `[parallel: true]` - Tasks that can run concurrently
- `[component: component-name]` - For multi-component features
- `[ref: document/section; lines: 1, 2-3]` - Links to specifications, patterns, or interfaces and (if applicable) line(s)
- `[activity: type]` - Activity hint for specialist agent selection

---

## Context Priming

*GATE: You MUST fully read all files mentioned in this section before starting any implementation.*

**Specification**:

- `docs/specs/015-task-engine/product-requirements.md` - Product Requirements (PRD)
- `docs/specs/015-task-engine/solution-design.md` - Solution Design (SDD)

**Key Design Decisions**:

- **ADR-1**: Queue Backend = Redis-compatible (Valkey preferred) with BRPOPLPUSH reserve/ack pattern for at-least-once delivery
- **ADR-2**: Job Storage = MySQL for definitions/history (durability), Redis for queue only (speed)
- **ADR-3**: Worker Process Model = One process per worker (isolation, PCNTL signal handling)
- **ADR-4**: Job Scope Model = Global + Per-Store with single scheduler
- **ADR-5**: Admin Dashboard Scope = Store-scoped + Global for super-admins

**Implementation Context**:

- Commands to run:
  - `./test.sh` - Run all tests
  - `./test.sh --testsuite unit` - Run unit tests only
  - `./test.sh --testsuite integration` - Run integration tests only
  - `cd userfrosting && ./vendor/bin/phpstan analyse` - Static analysis
  - `php userfrosting/conductor run` - Run database migrations

- Patterns to follow:
  - `docs/patterns/controller-patterns.md` - BaseController pattern
  - `docs/patterns/namespace-structure.md` - PSR-4 namespace conventions
  - `docs/patterns/architecture-overview.md` - Multi-store architecture

- Interfaces to implement:
  - `BuyerKiosk\TaskEngine\Domain\Job\JobInterface` - Job contract
  - `BuyerKiosk\TaskEngine\Infrastructure\Queue\QueueInterface` - Queue abstraction

---

## Implementation Phases

### T1: Foundation - Database Schema & Base Infrastructure ✅ COMPLETED

**Goal**: Establish database schema and core interfaces that all other components depend on.

**Completed**: 2025-12-17 | **Tests**: 128 passing, 276 assertions | **PHPStan**: 0 errors

- [x] T1.1 Prime Context
    - [x] T1.1.1 Read database schema specification `[ref: solution-design.md; lines: 409-480]`
    - [x] T1.1.2 Read data model definitions `[ref: solution-design.md; lines: 629-700]`
    - [x] T1.1.3 Review existing migration patterns `[ref: userfrosting/migrations/]`
    - [x] T1.1.4 Review existing configuration/.env patterns for `TASK_ENGINE_*` variables

- [x] T1.2 Write Tests
    - [x] T1.2.1 Test JobDefinition entity hydration and behaviors `[activity: test-implementation]`
    - [x] T1.2.2 Test Execution entity state transitions `[activity: test-implementation]`
    - [x] T1.2.3 Test Worker entity heartbeat logic `[activity: test-implementation]`
    - [x] T1.2.4 Test JobDefinitionRepository CRUD operations `[activity: test-implementation]`
    - [x] T1.2.5 Test ExecutionRepository query methods `[activity: test-implementation]`
    - [x] T1.2.6 Test WorkerRepository registration and heartbeat `[activity: test-implementation]`

- [x] T1.3 Implement Database Migration
    - [x] T1.3.1 Create migration JSON for `task_job_definitions` table `[activity: database-implementation]`
    - [x] T1.3.2 Create migration JSON for `task_executions` table `[activity: database-implementation]`
    - [x] T1.3.3 Create migration JSON for `task_execution_logs` table `[activity: database-implementation]`
    - [x] T1.3.4 Create migration JSON for `task_workers` table `[activity: database-implementation]`
    - [x] T1.3.5 Create migration JSON for task-engine permissions (`uri_task_engine`, `uri_task_engine_global`) `[activity: database-implementation]`
    - [x] T1.3.6 Run migrations and verify schema `[activity: database-implementation]`

- [x] T1.4 Implement Domain Entities
    - [x] T1.4.1 Create `JobInterface.php` contract `[ref: solution-design.md; lines: 344]` `[activity: domain-implementation]`
    - [x] T1.4.2 Create `JobResult.php` value object `[activity: domain-implementation]`
    - [x] T1.4.3 Create `JobContext.php` execution context `[activity: domain-implementation]`
    - [x] T1.4.4 Create `WorkerStatus.php` enum `[activity: domain-implementation]`
    - [x] T1.4.5 Create `ExecutionStatus.php` enum `[activity: domain-implementation]`
    - [x] T1.4.6 Wire `TASK_ENGINE_*` env vars into config with defaults `[ref: solution-design.md; lines: 1134-1136]` `[activity: domain-implementation]`

- [x] T1.5 Implement Repository Layer
    - [x] T1.5.1 Create `JobDefinitionRepository.php` `[activity: repository-implementation]`
    - [x] T1.5.2 Create `ExecutionRepository.php` `[activity: repository-implementation]`
    - [x] T1.5.3 Create `WorkerRepository.php` `[activity: repository-implementation]`
    - [x] T1.5.4 Create `ExecutionLogRepository.php` `[activity: repository-implementation]`

- [x] T1.6 Validate
    - [x] T1.6.1 Run unit tests for entities and repositories `[activity: run-tests]`
    - [x] T1.6.2 Run PHPStan analysis `[activity: lint-code]`
    - [x] T1.6.3 Verify migration executes cleanly `[activity: database-validation]`

**Artifacts Created**:
- `userfrosting/migrations/input/20251217_001_task_engine_tables.json` (4 tables)
- `userfrosting/migrations/input/20251217_002_task_engine_permissions.json` (2 permissions)
- `userfrosting/src/BuyerKiosk/TaskEngine/Domain/Job/` (6 files)
- `userfrosting/src/BuyerKiosk/TaskEngine/Domain/Worker/` (2 files)
- `userfrosting/src/BuyerKiosk/TaskEngine/Infrastructure/Persistence/` (4 repos)
- `userfrosting/tests/Unit/TaskEngine/` (9 test files)

---

### T2: Queue Infrastructure - Redis Adapter & Job Dispatcher ✅ COMPLETED

**Goal**: Implement Redis queue abstraction and job dispatch mechanism.

**Completed**: 2025-12-17 | **Tests**: 168 passing, 509 assertions | **PHPStan**: 0 errors

- [x] T2.1 Prime Context
    - [x] T2.1.1 Read queue interface specification `[ref: solution-design.md; lines: 358-367]`
    - [x] T2.1.2 Read queue semantics (at-least-once) `[ref: solution-design.md; lines: 1193-1197]`
    - [x] T2.1.3 Read idempotency requirements `[ref: solution-design.md; lines: 1199-1204]`
    - [x] T2.1.4 Review existing Redis usage patterns `[ref: userfrosting/src/BuyerKiosk/Auth/Services/RateLimiter.php]`

- [x] T2.2 Write Tests
    - [x] T2.2.1 Test RedisQueueAdapter push operation `[activity: test-implementation]`
    - [x] T2.2.2 Test RedisQueueAdapter reserve (BRPOPLPUSH) operation `[activity: test-implementation]`
    - [x] T2.2.3 Test RedisQueueAdapter ack operation `[activity: test-implementation]`
    - [x] T2.2.4 Test RedisQueueAdapter delayed queue (ZADD/ZRANGEBYSCORE) `[activity: test-implementation]`
    - [x] T2.2.5 Test JobDispatcher creates execution and pushes to queue `[activity: test-implementation]`
    - [x] T2.2.6 Test JobDispatcher idempotency key prevents duplicates `[activity: test-implementation]`
    - [x] T2.2.7 Test JobDispatcher generates deterministic idempotency keys and handles uniqueness conflicts `[activity: test-implementation]`

- [x] T2.3 Implement Queue Adapter
    - [x] T2.3.1 Create `QueueInterface.php` `[activity: infrastructure-implementation]`
    - [x] T2.3.2 Create `RedisQueueAdapter.php` with push/reserve/ack `[ref: solution-design.md; lines: 1193-1197]` `[activity: infrastructure-implementation]`
    - [x] T2.3.3 Implement delayed queue support (ZADD sorted set) `[activity: infrastructure-implementation]`
    - [x] T2.3.4 Implement queue depth monitoring methods `[activity: infrastructure-implementation]`

- [x] T2.4 Implement Job Dispatcher
    - [x] T2.4.1 Create `JobDispatcher.php` `[activity: application-implementation]`
    - [x] T2.4.2 Implement execution creation with idempotency key `[activity: application-implementation]`
    - [x] T2.4.3 Implement per-store dispatch (creates N executions) `[activity: application-implementation]`
    - [x] T2.4.4 Generate default idempotency key for manual dispatch when not provided `[activity: application-implementation]`
    - [x] T2.4.5 On idempotency UNIQUE conflict, return existing execution and skip enqueue `[activity: application-implementation]`

- [x] T2.5 Validate
    - [x] T2.5.1 Run unit tests with RedisMock `[activity: run-tests]`
    - [x] T2.5.2 Run integration tests with real Redis-compatible server (Valkey/Redis OSS) `[activity: run-tests]`
    - [x] T2.5.3 Run PHPStan analysis `[activity: lint-code]`

**Artifacts Created**:
- `userfrosting/src/BuyerKiosk/TaskEngine/Infrastructure/Queue/QueueInterface.php` - Queue contract
- `userfrosting/src/BuyerKiosk/TaskEngine/Infrastructure/Queue/RedisQueueAdapter.php` - Redis implementation
- `userfrosting/src/BuyerKiosk/TaskEngine/Application/JobDispatcher.php` - Job dispatch service
- `userfrosting/tests/Unit/TaskEngine/Infrastructure/RedisQueueAdapterTest.php` - 22 tests, 45 assertions
- `userfrosting/tests/Unit/TaskEngine/Application/JobDispatcherTest.php` - 17 tests, 43 assertions
- `userfrosting/tests/Mocks/RedisMock.php` - Enhanced with sorted sets (ZADD/ZRANGEBYSCORE) + BRPOPLPUSH

---

### T3: Scheduler - Cron Expression & Schedule Evaluation ✅ COMPLETED

**Goal**: Implement scheduler that evaluates cron expressions and dispatches due jobs.

**Completed**: 2025-12-17 | **Tests**: 168+ passing | **PHPStan**: 0 errors

- [x] T3.1 Prime Context
    - [x] T3.1.1 Read scheduler specification `[ref: solution-design.md; lines: 347-352]`
    - [x] T3.1.2 Read scheduler runtime flow `[ref: solution-design.md; lines: 988-1037]`
    - [x] T3.1.3 Read scheduler locking mechanism `[ref: solution-design.md; lines: 1001-1003]`
    - [x] T3.1.4 Read catch-up behavior `[ref: solution-design.md; lines: 1003-1004]`

- [x] T3.2 Write Tests
    - [x] T3.2.1 Test CronExpression parsing (standard expressions) `[activity: test-implementation]`
    - [x] T3.2.2 Test CronExpression `isDue()` evaluation `[activity: test-implementation]`
    - [x] T3.2.3 Test CronExpression `getNextRunTime()` `[activity: test-implementation]`
    - [x] T3.2.4 Test ScheduleEvaluator identifies due jobs `[activity: test-implementation]`
    - [x] T3.2.5 Test Scheduler acquires Redis lock `[activity: test-implementation]`
    - [x] T3.2.6 Test Scheduler dispatches due jobs `[activity: test-implementation]`
    - [x] T3.2.7 Test Scheduler catch-up for missed schedules `[activity: test-implementation]`
    - [x] T3.2.8 Test Scheduler promotes delayed retries `[activity: test-implementation]`
    - [x] T3.2.9 Test Scheduler requeues stale processing-list reservations (visibility timeout) `[activity: test-implementation]`
    - [x] T3.2.10 Test Scheduler builds idempotency keys for scheduled runs `[activity: test-implementation]`

- [x] T3.3 Implement Cron Expression Parser
    - [x] T3.3.1 Create `CronExpression.php` with parsing logic `[activity: domain-implementation]`
    - [x] T3.3.2 Implement `isDue(DateTime $now)` method `[activity: domain-implementation]`
    - [x] T3.3.3 Implement `getNextRunTime(DateTime $from)` method `[activity: domain-implementation]`

- [x] T3.4 Implement Schedule Evaluator
    - [x] T3.4.1 Create `ScheduleEvaluator.php` `[activity: domain-implementation]`
    - [x] T3.4.2 Implement due job identification logic `[activity: domain-implementation]`
    - [x] T3.4.3 Implement catch-up window logic (default 10 minutes) `[activity: domain-implementation]`

- [x] T3.5 Implement Scheduler
    - [x] T3.5.1 Create `Scheduler.php` `[ref: solution-design.md; lines: 347-352]` `[activity: domain-implementation]`
    - [x] T3.5.2 Implement Redis lock acquisition/release `[activity: domain-implementation]`
    - [x] T3.5.3 Implement delayed retry promotion (ZRANGEBYSCORE → RPUSH) `[activity: domain-implementation]`
    - [x] T3.5.4 Implement job dispatch loop `[activity: domain-implementation]`
    - [x] T3.5.5 Implement orphan job detection `[ref: solution-design.md; lines: 1091-1114]` `[activity: domain-implementation]`
    - [x] T3.5.6 Implement processing-list stale reservation requeue (processing:<queue> → queue:<queue>, configurable visibility timeout) `[ref: solution-design.md; lines: 1193-1197]` `[activity: domain-implementation]`

- [x] T3.6 Validate
    - [x] T3.6.1 Run unit tests for cron expression parsing `[activity: run-tests]`
    - [x] T3.6.2 Run unit tests for scheduler logic `[activity: run-tests]`
    - [x] T3.6.3 Run PHPStan analysis `[activity: lint-code]`
    - [x] T3.6.4 Verify PRD F1 acceptance criteria `[ref: product-requirements.md; lines: 116-123]` `[activity: business-acceptance]`

**Artifacts Created**:
- `userfrosting/src/BuyerKiosk/TaskEngine/Domain/Scheduler/CronExpression.php` - Cron expression parser
- `userfrosting/src/BuyerKiosk/TaskEngine/Domain/Scheduler/ScheduleEvaluator.php` - Due job identification
- `userfrosting/src/BuyerKiosk/TaskEngine/Domain/Scheduler/Scheduler.php` - Main scheduler service
- `userfrosting/src/BuyerKiosk/TaskEngine/Infrastructure/Persistence/ExecutionRepository.php` - Added getLastScheduledFireAt()
- `userfrosting/tests/Unit/TaskEngine/Domain/CronExpressionTest.php` - 40 tests, 73 assertions
- `userfrosting/tests/Unit/TaskEngine/Domain/ScheduleEvaluatorTest.php` - 12 tests, 25 assertions
- `userfrosting/tests/Unit/TaskEngine/Domain/SchedulerTest.php` - 18 tests, 45 assertions
- `userfrosting/tests/Mocks/RedisMock.php` - Enhanced with SET NX EX options

---

### T4: Worker System - Worker Process & Manager ✅ COMPLETED

**Goal**: Implement worker process that pulls and executes jobs with signal handling.

**Completed**: 2025-12-18 | **Tests**: 327 passing, 873 assertions | **PHPStan**: 0 errors

- [x] T4.1 Prime Context
    - [x] T4.1.1 Read worker specification `[ref: solution-design.md; lines: 354-357]`
    - [x] T4.1.2 Read worker process loop example `[ref: solution-design.md; lines: 899-979]`
    - [x] T4.1.3 Read worker runtime flow `[ref: solution-design.md; lines: 1005-1012]`
    - [x] T4.1.4 Read error handling strategies `[ref: solution-design.md; lines: 1046-1056]`

- [x] T4.2 Write Tests
    - [x] T4.2.1 Test Worker registers heartbeat on startup `[activity: test-implementation]`
    - [x] T4.2.2 Test Worker reserves job from queue `[activity: test-implementation]`
    - [x] T4.2.3 Test Worker executes job lifecycle (before/handle/after) `[activity: test-implementation]`
    - [x] T4.2.4 Test Worker handles job exception and marks failed `[activity: test-implementation]`
    - [x] T4.2.5 Test Worker ACKs job after completion `[activity: test-implementation]`
    - [x] T4.2.6 Test Worker responds to shutdown request gracefully `[activity: test-implementation]`
    - [x] T4.2.7 Test WorkerManager target worker count math `[activity: test-implementation]`
    - [x] T4.2.8 Test WorkerManager stale worker detection `[activity: test-implementation]`
    - [x] T4.2.9 Test ExecutionLogger writes per-execution logs `[activity: test-implementation]`
    - [x] T4.2.10 Test WorkerProcess recycles after N jobs `[activity: test-implementation]`

- [x] T4.3 Implement BaseJob
    - [x] T4.3.1 Create `BaseJob.php` abstract class `[ref: solution-design.md; lines: 750-826]` `[activity: domain-implementation]`
    - [x] T4.3.2 Implement lifecycle hook methods (beforeHandle, afterHandle, failed) `[activity: domain-implementation]`
    - [x] T4.3.3 Implement progress reporting method `[activity: domain-implementation]`
    - [x] T4.3.4 Implement logging helper methods `[activity: domain-implementation]`
    - [x] T4.3.5 Implement store context helpers via `JobContext` (getStore, getStoreDb) `[activity: domain-implementation]`
    - [x] T4.3.6 Create minimal `ExecutionLogger.php` (core) that persists to `task_execution_logs` `[activity: logging-implementation]`

- [x] T4.4 Implement Job Registry
    - [x] T4.4.1 Create `JobRegistry.php` `[ref: solution-design.md; lines: 372-373]` `[activity: domain-implementation]`
    - [x] T4.4.2 Implement job name to class mapping `[activity: domain-implementation]`
    - [x] T4.4.3 Implement job instantiation with context injection (context set by worker) `[activity: domain-implementation]`

- [x] T4.5 Implement Worker
    - [x] T4.5.1 Create `WorkerProcess.php` `[ref: solution-design.md; lines: 899-979]` `[activity: domain-implementation]`
    - [x] T4.5.2 Implement signal handler registration (SIGTERM, SIGINT) `[activity: domain-implementation]`
    - [x] T4.5.3 Implement heartbeat loop `[activity: domain-implementation]`
    - [x] T4.5.4 Implement job processing loop (with timeout support via SIGALRM) `[activity: domain-implementation]`
    - [x] T4.5.5 Implement graceful shutdown `[activity: domain-implementation]`

- [x] T4.6 Implement Worker Manager
    - [x] T4.6.1 Create `WorkerManager.php` `[ref: solution-design.md; lines: 355]` `[activity: domain-implementation]`
    - [x] T4.6.2 Implement spawn command generation `[activity: domain-implementation]`
    - [x] T4.6.3 Implement worker health monitoring `[activity: domain-implementation]`
    - [x] T4.6.4 Implement stale worker cleanup `[activity: domain-implementation]`
    - [x] T4.6.5 Implement worker recycling after N jobs (configurable) `[activity: domain-implementation]`

- [x] T4.7 Validate
    - [x] T4.7.1 Run unit tests for Worker and WorkerManager `[activity: run-tests]`
    - [x] T4.7.2 Run PHPStan analysis `[activity: lint-code]`
    - [x] T4.7.3 Verify PRD F2 acceptance criteria `[ref: product-requirements.md; lines: 125-133]` `[activity: business-acceptance]`

**Artifacts Created/Updated**:
- `userfrosting/src/BuyerKiosk/TaskEngine/Domain/Job/BaseJob.php` - Base job lifecycle + helpers
- `userfrosting/src/BuyerKiosk/TaskEngine/Domain/Job/JobTimeoutException.php` - Timeout exception class
- `userfrosting/src/BuyerKiosk/TaskEngine/Registry/JobRegistry.php` - Whitelisted job mapping and resolution
- `userfrosting/src/BuyerKiosk/TaskEngine/Infrastructure/Logging/ExecutionLogger.php` - Per-execution logging with buffering
- `userfrosting/src/BuyerKiosk/TaskEngine/Domain/Worker/WorkerProcess.php` - Worker loop + execution lifecycle + timeouts
- `userfrosting/src/BuyerKiosk/TaskEngine/Domain/Worker/WorkerManager.php` - Worker pool math + status + spawn commands
- `userfrosting/src/BuyerKiosk/TaskEngine/Infrastructure/Persistence/ExecutionLogRepository.php` - Added `getForExecution()` and `logBatch()`
- `userfrosting/src/BuyerKiosk/TaskEngine/Infrastructure/Persistence/JobDefinitionRepository.php` - Added `find()` alias
- `userfrosting/tests/Unit/TaskEngine/Domain/BaseJobTest.php` - Base job lifecycle tests (20 tests)
- `userfrosting/tests/Unit/TaskEngine/Domain/WorkerProcessTest.php` - Worker loop + execution lifecycle tests (21 tests)
- `userfrosting/tests/Unit/TaskEngine/Domain/WorkerManagerTest.php` - Worker manager behavior tests (15 tests)
- `userfrosting/tests/Unit/TaskEngine/Registry/JobRegistryTest.php` - Registry security and metadata tests (14 tests)
- `userfrosting/tests/Unit/TaskEngine/Infrastructure/ExecutionLoggerTest.php` - Execution logger behavior tests (13 tests)

---

### T5: Retry & Notification System ✅ COMPLETED

**Goal**: Implement automatic retry with exponential backoff and failure notifications.

**Completed**: 2025-12-18 | **Tests**: 25 passing (RetryScheduler + FailureNotifier) | **PHPStan**: 0 errors

- [x] T5.1 Prime Context
    - [x] T5.1.1 Read retry algorithm `[ref: solution-design.md; lines: 1059-1087]`
    - [x] T5.1.2 Read notification specification `[ref: solution-design.md; lines: 368-370]`
    - [x] T5.1.3 Read PRD retry requirements `[ref: product-requirements.md; lines: 166-173]`
    - [x] T5.1.4 Read PRD notification requirements `[ref: product-requirements.md; lines: 158-164]`

- [x] T5.2 Write Tests
    - [x] T5.2.1 Test retry delay calculation (exponential with jitter) `[activity: test-implementation]`
    - [x] T5.2.2 Test retry updates existing execution (attempt++, same idempotencyKey) and requeues `[activity: test-implementation]`
    - [x] T5.2.3 Test max retries exhausted marks permanently failed `[activity: test-implementation]`
    - [x] T5.2.4 Test FailureNotifier sends email on final failure `[activity: test-implementation]`
    - [x] T5.2.5 Test NotificationRateLimiter prevents floods (integrated into FailureNotifier) `[activity: test-implementation]`
    - [x] T5.2.6 Test notification email format includes required fields `[activity: test-implementation]`

- [x] T5.3 Implement Retry Logic
    - [x] T5.3.1 Create `RetryScheduler.php` service `[activity: domain-implementation]`
    - [x] T5.3.2 Implement exponential backoff calculation `[activity: domain-implementation]`
    - [x] T5.3.3 Implement jitter addition (0-10% of delay) `[activity: domain-implementation]`
    - [x] T5.3.4 Implement retry by ZADD to delayed queue, then update execution in-place `[activity: domain-implementation]`

- [x] T5.4 Implement Notification System
    - [x] T5.4.1 Create `FailureNotifier.php` `[ref: solution-design.md; lines: 368-370]` `[activity: notification-implementation]`
    - [x] T5.4.2 Rate limiting integrated into FailureNotifier (Redis-backed via `SET NX EX`, per job/store) `[activity: notification-implementation]`
    - [x] T5.4.3 Implement email template for failure notifications (HTML with error details, dashboard link) `[activity: notification-implementation]`
    - [x] T5.4.4 Create `MailerInterface.php` + `PHPMailerAdapter.php` for testable email sending `[activity: notification-implementation]`

- [x] T5.5 Validate
    - [x] T5.5.1 Run unit tests for retry and notification `[activity: run-tests]`
    - [x] T5.5.2 Run PHPStan analysis `[activity: lint-code]`
    - [x] T5.5.3 Verify PRD F6 acceptance criteria `[ref: product-requirements.md; lines: 158-164]` `[activity: business-acceptance]`
    - [x] T5.5.4 Verify PRD F7 acceptance criteria `[ref: product-requirements.md; lines: 166-173]` `[activity: business-acceptance]`

**Artifacts Created**:
- `userfrosting/src/BuyerKiosk/TaskEngine/Services/RetryScheduler.php` - Exponential backoff with jitter, retry scheduling
- `userfrosting/src/BuyerKiosk/TaskEngine/Services/FailureNotifier.php` - Email notifications with rate limiting
- `userfrosting/src/BuyerKiosk/TaskEngine/Services/MailerInterface.php` - Email sending abstraction
- `userfrosting/src/BuyerKiosk/TaskEngine/Services/PHPMailerAdapter.php` - PHPMailer implementation
- `userfrosting/src/BuyerKiosk/TaskEngine/Domain/Worker/WorkerProcess.php` - Integrates retry + notify hooks (optional setters)
- `userfrosting/tests/Unit/TaskEngine/Services/RetrySchedulerTest.php` - 13 tests for retry logic
- `userfrosting/tests/Unit/TaskEngine/Services/FailureNotifierTest.php` - 12 tests for notifications

---

### T6: CLI Commands ✅ COMPLETED

**Goal**: Implement CLI entry point for scheduler, worker, and manual dispatch.

**Completed**: 2025-12-18 | **Tests**: 17 passing | **PHPStan**: 0 errors

- [x] T6.1 Prime Context
    - [x] T6.1.1 Read CLI commands specification `[ref: solution-design.md; lines: 217-224]`
    - [x] T6.1.2 Read command class structure `[ref: solution-design.md; lines: 334-335]`
    - [x] T6.1.3 Review existing CLI patterns in codebase

- [x] T6.2 Write Tests
    - [x] T6.2.1 Test `scheduler:run` command invokes scheduler `[activity: test-implementation]`
    - [x] T6.2.2 Test `worker:start` command starts single worker `[activity: test-implementation]`
    - [x] T6.2.3 Test `worker:manager` command starts worker manager `[activity: test-implementation]`
    - [x] T6.2.4 Test `job:dispatch` command creates manual execution `[activity: test-implementation]`
    - [x] T6.2.5 Test `job:list` command outputs job definitions `[activity: test-implementation]`
    - [x] T6.2.6 Test `queue:status` command shows queue depths `[activity: test-implementation]`

- [x] T6.3 Implement CLI Entry Point
    - [x] T6.3.1 Create `userfrosting/bin/task` entry point script `[activity: cli-implementation]`
    - [x] T6.3.2 Implement command routing and argument parsing `[activity: cli-implementation]`

- [x] T6.4 Implement TaskCommand
    - [x] T6.4.1 Create `TaskCommand.php` `[ref: solution-design.md; lines: 334-335]` `[activity: cli-implementation]`
    - [x] T6.4.2 Implement `scheduler:run` subcommand `[activity: cli-implementation]`
    - [x] T6.4.3 Implement `worker:start` subcommand `[activity: cli-implementation]`
    - [x] T6.4.4 Implement `worker:manager` subcommand `[activity: cli-implementation]`
    - [x] T6.4.5 Implement `job:dispatch <job> [--store=<typeNum>]` subcommand `[activity: cli-implementation]`
    - [x] T6.4.6 Implement `job:list` subcommand `[activity: cli-implementation]`
    - [x] T6.4.7 Implement `queue:status` subcommand `[activity: cli-implementation]`

- [x] T6.5 Validate
    - [x] T6.5.1 Run unit tests for CLI commands `[activity: run-tests]`
    - [x] T6.5.2 Manual testing of CLI entry point `[activity: manual-testing]`
    - [x] T6.5.3 Run PHPStan analysis `[activity: lint-code]`
    - [x] T6.5.4 Verify PRD F8 acceptance criteria (manual dispatch) `[ref: product-requirements.md; lines: 178-182]` `[activity: business-acceptance]`

**Artifacts Created**:
- `userfrosting/bin/task` - CLI entry point script (executable)
- `userfrosting/src/BuyerKiosk/TaskEngine/Commands/TaskCommand.php` - Command handler with all subcommands
- `userfrosting/src/BuyerKiosk/TaskEngine/Commands/TaskCommandFactory.php` - Dependency injection factory
- `userfrosting/tests/Unit/TaskEngine/Commands/TaskCommandTest.php` - 17 tests for all commands

---

### T7: Admin Dashboard - Controllers & API ✅ COMPLETED

**Goal**: Implement admin dashboard controllers, API endpoints, and templates.

**Completed**: 2025-12-18 | **Tests**: 410 passing, 1592 assertions | **PHPStan**: 0 errors

- [x] T7.1 Prime Context
    - [x] T7.1.1 Read dashboard controller specification `[ref: solution-design.md; lines: 337-339]`
    - [x] T7.1.2 Read API endpoint specifications `[ref: solution-design.md; lines: 484-625]`
    - [x] T7.1.3 Read template structure `[ref: solution-design.md; lines: 388-397]`
    - [x] T7.1.4 Review existing admin dashboard patterns `[ref: userfrosting/src/BuyerKiosk/Core/Controllers/BaseController.php]`
    - [x] T7.1.5 Review existing route patterns `[ref: userfrosting/routes/admin/comeback-cash.php]`

- [x] T7.2 Write Tests `[parallel: true]` `[component: api]`
    - [x] T7.2.1 Test GET /api/:typeNum/tasks/stats returns metrics `[activity: test-implementation]`
    - [x] T7.2.2 Test GET /api/:typeNum/tasks/jobs returns job list `[activity: test-implementation]`
    - [x] T7.2.3 Test GET /api/:typeNum/tasks/jobs/:jobId returns job detail `[activity: test-implementation]`
    - [x] T7.2.4 Test PUT /api/:typeNum/tasks/jobs/:jobId updates job `[activity: test-implementation]`
    - [x] T7.2.5 Test POST /api/:typeNum/tasks/jobs/:jobId/dispatch creates execution `[activity: test-implementation]`
    - [x] T7.2.6 Test GET /api/:typeNum/tasks/executions returns execution list `[activity: test-implementation]`
    - [x] T7.2.7 Test GET /api/:typeNum/tasks/executions/:id returns detail with logs `[activity: test-implementation]`
    - [x] T7.2.8 Test POST /api/:typeNum/tasks/executions/:id/retry requeues job `[activity: test-implementation]`
    - [x] T7.2.9 Test GET /api/:typeNum/tasks/workers returns worker list `[activity: test-implementation]`

- [x] T7.3 Implement Page Controller `[parallel: true]` `[component: pages]`
    - [x] T7.3.1 Create `TaskDashboardController.php` extending BaseController `[activity: controller-implementation]`
    - [x] T7.3.2 Implement dashboard page action `[activity: controller-implementation]`
    - [x] T7.3.3 Implement jobs list page action `[activity: controller-implementation]`
    - [x] T7.3.4 Implement executions list page action `[activity: controller-implementation]`
    - [x] T7.3.5 Implement workers list page action `[activity: controller-implementation]`

- [x] T7.4 Implement API Controller `[parallel: true]` `[component: api]`
    - [x] T7.4.1 Create `TaskApiController.php` `[ref: solution-design.md; lines: 484-625]` `[activity: api-implementation]`
    - [x] T7.4.2 Implement GET /stats endpoint `[activity: api-implementation]`
    - [x] T7.4.3 Implement GET/PUT /jobs endpoints `[activity: api-implementation]`
    - [x] T7.4.4 Implement POST /jobs/:jobId/dispatch endpoint `[activity: api-implementation]`
    - [x] T7.4.5 Implement GET /executions endpoints `[activity: api-implementation]`
    - [x] T7.4.6 Implement POST /executions/:id/retry endpoint `[activity: api-implementation]`
    - [x] T7.4.7 Implement GET /workers endpoint `[activity: api-implementation]`

  Note: Abort execution endpoint is PRD F11 and deferred to T11.

- [x] T7.5 Implement Global Dashboard API `[component: global-api]`
    - [x] T7.5.1 Implement GET /api/tasks/stats (super-admin) `[activity: api-implementation]`
    - [x] T7.5.2 Implement GET /api/tasks/executions (super-admin) `[activity: api-implementation]`
    - [x] T7.5.3 Implement GET /api/tasks/workers (super-admin) `[activity: api-implementation]`

- [x] T7.6 Implement Routes
    - [x] T7.6.1 Create `userfrosting/routes/task-engine/pages.php` (store-scoped) `[activity: route-implementation]`
    - [x] T7.6.2 Create `userfrosting/routes/task-engine/global-pages.php` (super-admin) `[activity: route-implementation]`
    - [x] T7.6.3 Create `userfrosting/routes/task-engine/api.php` `[activity: route-implementation]`
    - [x] T7.6.4 Register routes in main route configuration `[activity: route-implementation]`

- [x] T7.7 Validate API
    - [x] T7.7.1 Run controller tests `[activity: run-tests]`
    - [x] T7.7.2 Run PHPStan analysis `[activity: lint-code]`
    - [x] T7.7.3 Verify PRD F5 functional acceptance criteria (security verified in T10/T12) `[ref: product-requirements.md; lines: 150-157]` `[activity: business-acceptance]`

**Artifacts Created**:
- `userfrosting/src/BuyerKiosk/TaskEngine/Controllers/TaskDashboardController.php` - Page controller (7 actions)
- `userfrosting/src/BuyerKiosk/TaskEngine/Controllers/TaskApiController.php` - API controller (12 endpoints)
- `userfrosting/routes/task-engine/pages.php` - Store-scoped page routes
- `userfrosting/routes/task-engine/global-pages.php` - Super-admin page routes
- `userfrosting/routes/task-engine/api.php` - All API routes
- `userfrosting/tests/Unit/TaskEngine/Controllers/TaskApiControllerTest.php` - 41 tests, 185 assertions

---

### T8: Admin Dashboard - Templates & UI ✅ COMPLETED

**Goal**: Implement Twig templates and CSS for admin dashboard.

**Completed**: 2025-12-18 | **Tests**: 384 passing (all existing tests) | **PHPStan**: 0 errors

- [x] T8.1 Prime Context
    - [x] T8.1.1 Read template structure specification `[ref: solution-design.md; lines: 388-397]`
    - [x] T8.1.2 Read dashboard user flow `[ref: product-requirements.md; lines: 267-280]`
    - [x] T8.1.3 Review existing admin template patterns `[ref: userfrosting/templates/themes/default/admin/comeback-cash/index.html]`
    - [x] T8.1.4 Review design token system `[ref: public_html/css/admin/tokens.css]`

- [x] T8.2 Implement Templates
    - [x] T8.2.1 Create `dashboard.html` main template `[activity: ui-implementation]`
    - [x] T8.2.2 Create `jobs.html` job definitions list `[activity: ui-implementation]`
    - [x] T8.2.3 Create `executions.html` execution history `[activity: ui-implementation]`
    - [x] T8.2.4 Create `workers.html` worker status `[activity: ui-implementation]`
    - [x] T8.2.5 Create `partials/stats-cards.html` summary metrics `[activity: ui-implementation]`
    - [x] T8.2.6 Create `partials/job-row.html` job list row `[activity: ui-implementation]`
    - [x] T8.2.7 Create `partials/execution-detail.html` execution detail modal `[activity: ui-implementation]`

- [x] T8.3 Implement CSS
    - [x] T8.3.1 Create `public_html/css/admin/modules/task-engine.css` `[activity: css-implementation]`
    - [x] T8.3.2 Build CSS with `php userfrosting/conductor build-css --minify` `[activity: css-implementation]`

- [x] T8.4 Implement JavaScript
    - [x] T8.4.1 Implement auto-refresh for dashboard stats (30 second interval) `[activity: js-implementation]`
    - [x] T8.4.2 Implement retry button handler `[activity: js-implementation]`
    - [x] T8.4.3 Implement Run Now button handler `[activity: js-implementation]`
    - [x] T8.4.4 Implement progress bar updates for running jobs `[activity: js-implementation]`

- [x] T8.5 Validate
    - [x] T8.5.1 Visual testing of dashboard in browser `[activity: manual-testing]`
    - [x] T8.5.2 Test responsive layout `[activity: manual-testing]`
    - [x] T8.5.3 Test error states (Redis unavailable, no workers) `[activity: manual-testing]`
    - [x] T8.5.4 Verify PRD dashboard business rules `[ref: product-requirements.md; lines: 283-293]` `[activity: business-acceptance]`

**Artifacts Created**:
- `userfrosting/templates/themes/default/admin/task-engine/dashboard.html` - Main dashboard template (20KB)
- `userfrosting/templates/themes/default/admin/task-engine/jobs.html` - Job definitions list (21KB)
- `userfrosting/templates/themes/default/admin/task-engine/executions.html` - Execution history (25KB)
- `userfrosting/templates/themes/default/admin/task-engine/workers.html` - Worker status (13KB)
- `userfrosting/templates/themes/default/admin/task-engine/partials/stats-cards.html` - Summary metrics (3KB)
- `userfrosting/templates/themes/default/admin/task-engine/partials/job-row.html` - Job row template (2KB)
- `userfrosting/templates/themes/default/admin/task-engine/partials/execution-detail.html` - Execution detail modal with logs (13KB)
- `public_html/css/admin/modules/task-engine.css` - Task Engine CSS module (11KB)

**Features Implemented**:
- Dashboard with stats cards (active workers, pending/running/completed/failed jobs)
- Queue depths display with status indicators
- Recent executions list with auto-refresh (30s)
- Jobs list with search, filtering by scope and status
- Executions list with pagination, filtering by status/job/store
- Workers list with health status and heartbeat monitoring
- Job detail modal with configuration display
- Execution detail modal with logs viewer
- Run Now button with confirmation
- Retry button for failed executions
- Progress bar display for running jobs
- Global dashboard support for super-admins
- Responsive design for mobile/tablet
- Error banners for Redis unavailability and no active workers

---

### T9: Concrete Job Implementations ✅ COMPLETED

**Goal**: Implement concrete job classes for existing background tasks.

**Completed**: 2025-12-18 | **Tests**: 399 passing, 1514 assertions | **PHPStan**: 0 errors

- [x] T9.1 Prime Context
    - [x] T9.1.1 Read job implementation examples `[ref: solution-design.md; lines: 829-894]`
    - [x] T9.1.2 Review EventPhaseProcessor `[ref: userfrosting/src/BuyerKiosk/EventManagement/Services/EventPhaseProcessor.php]`
    - [x] T9.1.3 Review existing SMS system `[ref: docs/systems/redis-worker-system.md]`
    - [x] T9.1.4 Review employee sync script `[ref: userfrosting/scripts/employee-sync.php]`

- [x] T9.2 Write Tests
    - [x] T9.2.1 Test EventPhaseJob processes store events `[activity: test-implementation]`
    - [x] T9.2.2 Test EventPhaseJob reports progress `[activity: test-implementation]`
    - [x] T9.2.3 Test SmsQueueJob processes SMS batch `[activity: test-implementation]`
    - [x] T9.2.4 Test EmployeeSyncJob syncs from WhenIWork `[activity: test-implementation]`

- [x] T9.3 Implement Jobs
    - [x] T9.3.1 Create `EventPhaseJob.php` `[ref: solution-design.md; lines: 829-894]` `[activity: job-implementation]`
    - [x] T9.3.2 Create `SmsQueueJob.php` (wrapper for existing SMS logic) `[activity: job-implementation]`
    - [x] T9.3.3 Create `EmployeeSyncJob.php` (wrapper for existing sync logic) `[activity: job-implementation]`
    - [x] T9.3.4 Create `QuickBooksSyncJob.php` `[activity: job-implementation]`
    - [x] T9.3.5 Create `FiveStarsSyncJob.php` `[activity: job-implementation]`
    - [x] T9.3.6 Create `AggregateStatsJob.php` `[activity: job-implementation]`

- [x] T9.4 Register Jobs
    - [x] T9.4.1 Add job class mappings to JobRegistry `[activity: job-implementation]`
    - [x] T9.4.2 Create database seed for initial job definitions `[activity: database-implementation]`

- [x] T9.5 Validate
    - [x] T9.5.1 Run unit tests for each job `[activity: run-tests]`
    - [x] T9.5.2 Run integration tests with mocked external APIs `[activity: run-tests]`
    - [x] T9.5.3 Run PHPStan analysis `[activity: lint-code]`

**Artifacts Created**:
- `userfrosting/src/BuyerKiosk/TaskEngine/Jobs/EventPhaseJob.php` - Per-store event phase processor (120s timeout)
- `userfrosting/src/BuyerKiosk/TaskEngine/Jobs/SmsQueueJob.php` - Global SMS queue processor (300s timeout)
- `userfrosting/src/BuyerKiosk/TaskEngine/Jobs/EmployeeSyncJob.php` - Per-store employee sync from WhenIWork/Homebase (180s timeout)
- `userfrosting/src/BuyerKiosk/TaskEngine/Jobs/QuickBooksSyncJob.php` - Per-store QuickBooks sync (300s timeout)
- `userfrosting/src/BuyerKiosk/TaskEngine/Jobs/FiveStarsSyncJob.php` - Per-store FiveStars loyalty sync (180s timeout)
- `userfrosting/src/BuyerKiosk/TaskEngine/Jobs/AggregateStatsJob.php` - Global statistics aggregation (600s timeout, low queue)
- `userfrosting/migrations/input/20251218_001_task_engine_job_definitions.json` - Database seed for all 6 job definitions
- `userfrosting/tests/Unit/TaskEngine/Jobs/ConcreteJobsTest.php` - 15 tests, 49 assertions

**Features Implemented**:
- 4 per-store jobs: EventPhaseJob, EmployeeSyncJob, QuickBooksSyncJob, FiveStarsSyncJob
- 2 global jobs: SmsQueueJob, AggregateStatsJob
- All jobs extend BaseJob with proper configuration (name, displayName, queue, scope, timeout)
- Jobs skip processing when integration not enabled (graceful handling)
- Progress reporting throughout job execution
- Proper error handling with failed() callback
- Jobs registered in TaskCommandFactory.registerJobs()

---

### T10: Permission & Security ✅ COMPLETED

**Goal**: Implement permission integration and security controls.

**Completed**: 2025-12-18 | **Tests**: 422 passing, 1600 assertions | **PHPStan**: 0 errors

**Implementation Notes**:
- Created `TaskApiSecurityTest.php` with comprehensive security tests (35 test cases)
- Added `checkCsrf()` method to `TaskApiController` for CSRF protection on mutations
- CSRF validation on: `updateJob()`, `dispatchJob()`, `retryExecution()`
- Permission checks (`uri_task_engine`, `uri_task_engine_global`) already in place from T7
- Store group filtering already in place from T7
- JobRegistry whitelist already validated (cannot resolve unregistered jobs)
- Updated PHPStan baseline for NoCSRF static calls

- [x] T10.1 Prime Context
    - [x] T10.1.1 Read security requirements `[ref: solution-design.md; lines: 1181-1186]`
    - [x] T10.1.2 Review existing permission system
    - [x] T10.1.3 Review CSRF protection patterns

- [x] T10.2 Write Tests
    - [x] T10.2.1 Test uri_task_engine permission check on dashboard `[activity: test-implementation]`
    - [x] T10.2.2 Test uri_task_engine_global permission for global dashboard `[activity: test-implementation]`
    - [x] T10.2.3 Test store group authorization filters executions `[activity: test-implementation]`
    - [x] T10.2.4 Test CSRF token validation on mutations `[activity: test-implementation]`
    - [x] T10.2.5 Test JobRegistry whitelist prevents arbitrary class execution `[activity: test-implementation]`

- [x] T10.3 Verify Permissions
    - [x] T10.3.1 Verify `uri_task_engine` and `uri_task_engine_global` permissions exist (from T1 migrations) `[activity: database-implementation]`
    - [x] T10.3.2 Assign permissions to appropriate user groups `[activity: database-implementation]`

- [x] T10.4 Implement Security Controls
    - [x] T10.4.1 Add permission checks to all dashboard routes `[activity: security-implementation]`
    - [x] T10.4.2 Add store group filtering to execution queries `[activity: security-implementation]`
    - [x] T10.4.3 Add CSRF protection to all mutation endpoints `[activity: security-implementation]`
    - [x] T10.4.4 Verify JobRegistry only instantiates registered jobs `[activity: security-implementation]`

- [x] T10.5 Validate
    - [x] T10.5.1 Run security-focused tests `[activity: run-tests]`
    - [x] T10.5.2 Manual security audit of API endpoints `[activity: security-review]`
    - [x] T10.5.3 Verify unauthorized access returns 403 `[activity: manual-testing]`

---

### T11: Should Have Features ✅ COMPLETED

**Goal**: Implement Should Have features (F8-F14) after core system is stable.

- [x] T11.1 Manual Job Dispatch (F8) `[parallel: true]` `[component: manual-dispatch]`
    - [x] T11.1.1 Dashboard "Run Now" button (already in T8) `[activity: ui-implementation]`
    - [x] T11.1.2 CLI command (already in T6) `[activity: cli-implementation]`
    - [x] T11.1.3 Test manual trigger type recorded `[activity: test-implementation]`

- [x] T11.2 Job Execution Logs (F9) `[parallel: true]` `[component: execution-logs]`
    - [x] T11.2.1 Enhance ExecutionLogger with log level support (debug/info/warning/error) `[activity: logging-implementation]`
    - [x] T11.2.2 Implement log retention (7 days) - deleteOlderThan() in ExecutionLogRepository `[activity: logging-implementation]`
    - [x] T11.2.3 Display logs in execution detail view `[activity: ui-implementation]`

- [x] T11.3 Worker Health Monitoring (F10) `[parallel: true]` `[component: worker-health]`
    - [x] T11.3.1 Dashboard worker status display (already in T8) `[activity: ui-implementation]`
    - [x] T11.3.2 Stale worker highlighting (heartbeat > 60s) - isHealthy() check `[activity: ui-implementation]`
    - [x] T11.3.3 Jobs processed/failed counts per worker `[activity: ui-implementation]`

- [x] T11.4 Abort Running Tasks (F11) `[parallel: true]` `[component: abort]`
    - [x] T11.4.1 Write tests for abort functionality - JobAbortedExceptionTest, JobContextAbortTest `[activity: test-implementation]`
    - [x] T11.4.2 Implement abort API endpoint - TaskApiController::cancelExecution() `[activity: api-implementation]`
    - [x] T11.4.3 Add Redis abort signal mechanism `[activity: infrastructure-implementation]`
    - [x] T11.4.4 Implement CLI `task job:cancel <execution_id>` command `[activity: cli-implementation]`
    - [x] T11.4.5 Worker polls for abort signal via Redis `[activity: domain-implementation]`
    - [x] T11.4.6 Worker gracefully handles JobAbortedException and marks cancelled `[activity: domain-implementation]`

- [x] T11.5 Progress Support (F12) `[parallel: true]` `[component: progress]`
    - [x] T11.5.1 Progress storage in execution record (already in schema) `[activity: domain-implementation]`
    - [x] T11.5.2 Progress update via callback for real-time `[activity: infrastructure-implementation]`
    - [x] T11.5.3 Progress bar display in dashboard (already in T8) `[activity: ui-implementation]`

- [x] T11.6 Job Lifecycle Hooks (F13) `[parallel: true]` `[component: hooks]`
    - [x] T11.6.1 beforeHandle() method (already in BaseJob) `[activity: domain-implementation]`
    - [x] T11.6.2 afterHandle() method (already in BaseJob) `[activity: domain-implementation]`
    - [x] T11.6.3 failed() method (already in BaseJob) `[activity: domain-implementation]`
    - [x] T11.6.4 Test hooks execute in correct order `[activity: test-implementation]`

- [x] T11.7 Orphan Job Detection (F14) `[parallel: true]` `[component: orphan-detection]`
    - [x] T11.7.1 Orphan detection algorithm (already in T3.5.5) - requeueStaleReservations() `[activity: domain-implementation]`
    - [x] T11.7.2 Alert when orphan count exceeds threshold - logged with warning level `[activity: notification-implementation]`
    - [x] T11.7.3 Test orphan detection and requeuing `[activity: test-implementation]`

- [x] T11.8 Validate Should Have Features
    - [x] T11.8.1 Run all tests for Should Have features - 437 tests, 1624 assertions `[activity: run-tests]`
    - [x] T11.8.2 Verify PRD F8-F14 acceptance criteria `[activity: business-acceptance]`

**New Files Created:**
- `src/BuyerKiosk/TaskEngine/Domain/Job/JobAbortedException.php`
- `tests/Unit/TaskEngine/Domain/JobAbortedExceptionTest.php`
- `tests/Unit/TaskEngine/Domain/JobContextAbortTest.php`

**Modified Files:**
- `TaskApiController.php` - Added cancelExecution() endpoint
- `TaskCommand.php` - Added job:cancel CLI command
- `WorkerProcess.php` - Added abort callback and JobAbortedException handling
- `JobContext.php` - Added shouldAbort() and checkAbort()
- `BaseJob.php` - Added shouldAbort() and checkAbort() helpers
- `routes/task-engine/api.php` - Added POST cancel route

---

### T12: Integration & End-to-End Validation ✅ COMPLETED

**Goal**: Comprehensive system validation and deployment readiness.

**Completed**: 2025-12-18 | **Tests**: 462 passing, 1746 assertions | **PRD**: F1-F14 verified

- [x] T12.1 Integration Tests
    - [x] T12.1.1 Test scheduler → dispatcher → queue → worker → execution flow `[activity: integration-testing]`
    - [x] T12.1.2 Test per-store job creates N executions for N stores `[activity: integration-testing]`
    - [x] T12.1.3 Test retry flow with real delays `[activity: integration-testing]`
    - [x] T12.1.4 Test orphan detection with simulated worker crash `[activity: integration-testing]`
    - [x] T12.1.5 Test concurrent workers processing from same queue `[activity: integration-testing]`

- [x] T12.2 End-to-End Tests
    - [x] T12.2.1 E2E: Admin views dashboard, sees stats `[activity: e2e-testing]`
    - [x] T12.2.2 E2E: Admin manually dispatches job, sees execution `[activity: e2e-testing]`
    - [x] T12.2.3 E2E: Job fails, admin retries from dashboard `[activity: e2e-testing]`
    - [x] T12.2.4 E2E: Job fails after max retries, email sent `[activity: e2e-testing]`
    - [x] T12.2.5 E2E: Admin aborts running job `[activity: e2e-testing]`

- [x] T12.3 Performance Tests
    - [x] T12.3.1 Test scheduler completes cycle in < 5 seconds `[ref: solution-design.md; lines: 1291-1295]` `[activity: performance-testing]`
    - [x] T12.3.2 Test worker picks up job in < 100ms `[activity: performance-testing]`
    - [x] T12.3.3 Test dashboard API responds in < 500ms `[activity: performance-testing]`
    - [x] T12.3.4 Test 10+ concurrent workers without contention `[activity: performance-testing]`

- [x] T12.4 Security Validation
    - [x] T12.4.1 Test unauthorized dashboard access blocked `[activity: security-testing]`
    - [x] T12.4.2 Test CSRF protection on mutations `[activity: security-testing]`
    - [x] T12.4.3 Test store isolation (user only sees their stores) `[activity: security-testing]`
    - [x] T12.4.4 Test JobRegistry rejects unregistered job names `[activity: security-testing]`

- [x] T12.5 Acceptance Criteria Verification
    - [x] T12.5.1 PRD F1: Unified Job Scheduler `[ref: product-requirements.md; lines: 116-123]` `[activity: business-acceptance]`
    - [x] T12.5.2 PRD F2: Worker Pool Management `[ref: product-requirements.md; lines: 125-133]` `[activity: business-acceptance]`
    - [x] T12.5.3 PRD F3: Database-Driven Job Definitions `[ref: product-requirements.md; lines: 135-140]` `[activity: business-acceptance]`
    - [x] T12.5.4 PRD F4: Job Execution History `[ref: product-requirements.md; lines: 142-148]` `[activity: business-acceptance]`
    - [x] T12.5.5 PRD F5: Admin Dashboard `[ref: product-requirements.md; lines: 150-157]` `[activity: business-acceptance]`
    - [x] T12.5.6 PRD F6: Failure Notifications `[ref: product-requirements.md; lines: 158-164]` `[activity: business-acceptance]`
    - [x] T12.5.7 PRD F7: Automatic Retry with Backoff `[ref: product-requirements.md; lines: 166-173]` `[activity: business-acceptance]`

- [x] T12.6 Documentation & Deployment
    - [x] T12.6.1 Create job pattern documentation `[activity: documentation]`
    - [x] T12.6.2 Create CLI usage documentation `[activity: documentation]`
    - [x] T12.6.3 Create deployment checklist `[activity: documentation]`
    - [x] T12.6.4 Verify cron entry documented `[activity: documentation]`
    - [x] T12.6.5 Verify Supervisor/systemd config documented `[activity: documentation]`

- [x] T12.7 Final Validation
    - [x] T12.7.1 All unit tests passing `[activity: run-tests]`
    - [x] T12.7.2 All integration tests passing `[activity: run-tests]`
    - [x] T12.7.3 PHPStan analysis clean `[activity: lint-code]`
    - [x] T12.7.4 Test coverage meets standards `[activity: run-tests]`
    - [x] T12.7.5 Build and deployment verification `[activity: deployment-testing]`
    - [x] T12.7.6 All PRD requirements implemented `[activity: business-acceptance]`
    - [x] T12.7.7 Implementation follows SDD design `[activity: specification-compliance]`

---

## Phase Dependencies

```
T1 (Foundation)
    ↓
T2 (Queue Infrastructure)
    ↓
T3 (Scheduler) ←→ T4 (Worker System) [can partially parallel after T2]
    ↓               ↓
T5 (Retry & Notifications)
    ↓
T6 (CLI Commands)
    ↓
T7 (Dashboard API) ←→ T8 (Dashboard UI) [parallel]
    ↓
T9 (Concrete Jobs)
    ↓
T10 (Permissions & Security)
    ↓
T11 (Should Have Features) [components can run in parallel]
    ↓
T12 (Integration & E2E Validation)
```

---

## Risk Mitigation

| Risk | Mitigation Strategy |
|------|---------------------|
| PCNTL unavailable | Verify extension in Phase T4 before implementing signal handling |
| Redis memory growth | Implement queue depth monitoring in T2, alerting in T12 |
| Worker memory leaks | Implement worker restart after N jobs in T4.6 |
| Dashboard performance | Implement pagination early in T7, test in T12.3 |
| Legacy job migration | Keep existing systems running until T9 validation complete |

---

## Success Criteria

- [x] Phases T1-T11 completed with passing validation
- [ ] Phase T12 (Integration & E2E) completed
- [ ] 99.9% job execution success rate (excluding business errors)
- [ ] Scheduler cycle < 5 seconds
- [ ] Job pickup latency < 100ms
- [ ] Dashboard API < 500ms
- [x] All PRD Must Have features (F1-F7) implemented
- [x] All PRD Should Have features (F8-F14) implemented
- [ ] Security validation passed
- [ ] Documentation complete

## Implementation Status

| Phase | Status | Tests | Notes |
|-------|--------|-------|-------|
| T1 Foundation | ✅ Complete | Passing | Schema, migrations, base infrastructure |
| T2 Queue Infrastructure | ✅ Complete | Passing | Redis adapter, queue interface |
| T3 Scheduler | ✅ Complete | Passing | Cron parsing, schedule evaluation |
| T4 Worker System | ✅ Complete | Passing | Worker process, manager, health |
| T5 Retry & Notifications | ✅ Complete | Passing | Backoff, failure notifier |
| T6 CLI Commands | ✅ Complete | Passing | task command with subcommands |
| T7 Dashboard API | ✅ Complete | Passing | TaskApiController, routes |
| T8 Dashboard UI | ✅ Complete | Passing | Templates, JS, modals |
| T9 Concrete Jobs | ✅ Complete | Passing | 6 concrete jobs implemented |
| T10 Permissions | ✅ Complete | Passing | CSRF, authorization, security |
| T11 Should Have | ✅ Complete | 437 tests | F8-F14 all implemented |
| T12 Integration | 🔄 Pending | - | Final validation phase |
