15 KiB
// File: specs/200-fullstacks/235-ai-runtime-policy-refactor/tasks.md // Change Log: // - 2026-06-11: Initial task list for AI Runtime Policy Refactor
Tasks: AI Runtime Policy Refactor
Input: Design documents from specs/200-fullstacks/235-ai-runtime-policy-refactor/
Prerequisites: plan.md ✅, spec.md ✅, research.md ✅, data-model.md ✅, contracts/ ✅
Format: [ID] [P?] [Story] Description
- [P]: Can run in parallel (different files, no dependencies)
- [Story]: US1=Contract&Naming, US2=OCR Residency, US3=Retrieval Fallback, US4=Queue Policy, US5=Verification
Phase 1: Setup (Shared Infrastructure)
Purpose: สร้าง foundational types และ interfaces ก่อน workstream ทุกอัน
- T001 สร้าง interface file
backend/src/modules/ai/interfaces/execution-policy.interface.ts(ExecutionProfile type, RuntimePolicy interface, VramHeadroom interface) - T002 สร้าง interface file
backend/src/modules/ai/interfaces/ocr-residency.interface.ts(OcrResidencyDecision interface) - T003 [P] สร้าง
backend/src/modules/ai/services/vram-monitor.service.ts— query Ollama/api/psเพื่อคำนวณ VRAM headroom - T004 [P] สร้าง
specs/04-Infrastructure-OPS/04-00-docker-compose/Desk-5439/ocr-sidecar/services/vram_monitor.py— Python VRAM headroom query via Ollama/api/ps
Phase 2: Foundational (Blocking Prerequisites)
Purpose: Policy infrastructure ที่ทุก workstream ต้องพึ่งพา — MUST complete ก่อนทุก user story
⚠️ CRITICAL: No user story work can begin until this phase is complete
- T005 สร้าง
backend/src/modules/ai/services/ai-policy.service.ts— ExecutionProfile → RuntimePolicy mapping, canonical model name mapping, data-affecting job override logic - T006 สร้าง
backend/src/modules/ai/guards/execution-profile.guard.ts— CASL check:large-contextเฉพาะ admin role - T007 [P] แก้
backend/src/modules/ai/dto/create-ai-job.dto.ts— เอาmodel.keyและ parameter override fields ออก, เพิ่มexecutionProfile?: ExecutionProfileพร้อม class-validator - T008 สร้าง
specs/04-Infrastructure-OPS/04-00-docker-compose/Desk-5439/ocr-sidecar/services/residency_policy.py— OCR keep_alive calculation function - T009 แก้
backend/src/modules/ai/ai.module.ts— registerAiPolicyService,VramMonitorService,ExecutionProfileGuard
Checkpoint: Foundation ready — policy services, guard, and updated DTO available
Phase 3: User Story 1 — Policy Contract & Canonical Naming (P1) 🎯 MVP
Goal: API reject model.key/parameter overrides; ทุก layer แสดง canonical names; data-affecting jobs ถูก override
Independent Test: ยิง POST ด้วย model.key → ต้องได้ 400; ยิงด้วย executionProfile: "balanced" → ต้องได้ 201 + modelUsed: "np-dms-ai"
Implementation for User Story 1
- T010 [US1] แก้
backend/src/modules/ai/ai.service.ts— injectAiPolicyService, validateexecutionProfile, apply backend override สำหรับmigrate-documentและauto-fill-document, setmodelUsedcanonical name ใน audit log - T011 [P] [US1] แก้
backend/src/modules/ai/dto/ai-job-response.dto.ts— เพิ่มmodelUsed: 'np-dms-ai' | 'np-dms-ocr'field, เพิ่มexecutionProfilefield (effective profile หลัง override) - T012 [P] [US1] แก้
backend/src/modules/ai/ai.controller.ts— ใช้ExecutionProfileGuardบน create-job endpoint, validate forbidden fields ใน pipe - T013 [P] [US1] แก้
frontend/types/ai.ts— เอาmodelfield ออก, เพิ่มexecutionProfile?: ExecutionProfile, เพิ่มmodelUsed?: string - T014 [US1] แก้
frontend/lib/services/admin-ai.service.ts— update request/response types ให้สอดคล้องกับ DTO ใหม่ - T015 [P] [US1] แก้
frontend/components/admin/ai/OcrSandboxPromptManager.tsx— แสดงnp-dms-ai/np-dms-ocrแทนชื่อ runtime ใน result cards และ model info - T016 [US1] แก้
frontend/app/(admin)/admin/ai/page.tsx— แสดง canonical names ใน System Health panel และ model status cards
Checkpoint: US1 fully functional — policy contract enforced, canonical naming in all layers
Phase 4: User Story 2 — Adaptive OCR Residency (P2)
Goal: OcrService คำนวณ keep_alive dynamic ตาม VRAM headroom + active profile; sidecar รับค่าและใช้
Independent Test: ดู log จาก OCR job ใน high-pressure scenario → keep_alive=0; ใน headroom-sufficient scenario → keep_alive>0
Implementation for User Story 2
- T017 [US2] แก้
backend/src/modules/ai/services/ocr.service.ts— injectVramMonitorServiceและAiPolicyService, เพิ่มcalculateOcrResidency()method, ส่งkeep_aliveที่คำนวณได้ไปใน OCR sidecar request, logOcrResidencyDecision - T018 [P] [US2] แก้
specs/04-Infrastructure-OPS/04-00-docker-compose/Desk-5439/ocr-sidecar/app.py— รับkeep_aliveparameter จาก request body แทน hardcodekeep_alive=0, ส่งkeep_aliveค่านั้นไปใน Ollama/v1/chat/completionscall - T019 [P] [US2] เพิ่ม env variables ใน docker-compose ของ Desk-5439 OCR sidecar —
VRAM_HEADROOM_THRESHOLD_MB,OCR_RESIDENCY_WINDOW_SECONDS,GPU_TOTAL_VRAM_MB - T020 [US2] เพิ่ม unit tests
backend/src/modules/ai/tests/ocr-residency.spec.ts— scenarios: large-context-active, high-pressure, headroom-sufficient, query-failed fallback
Checkpoint: US2 functional — OCR keep_alive computed dynamically per policy
Phase 5: User Story 3 — Retrieval Acceleration with CPU Fallback (P3)
Goal: /embed และ /rerank บน sidecar ตรวจ VRAM headroom; fallback CPU ถ้าไม่พอ; log fallback decision
Independent Test: จำลอง GPU pressure → ยิง /embed → ต้องได้ผลลัพธ์ (ไม่ fail) + log device: "cpu"
Implementation for User Story 3
- T021 [P] [US3] แก้
specs/04-Infrastructure-OPS/04-00-docker-compose/Desk-5439/ocr-sidecar/app.py— เพิ่ม VRAM headroom check ในPOST /embedendpoint; ถ้าผ่าน threshold ใช้ GPU, ถ้าไม่ผ่านหรือ query ล้มเหลว ใช้ CPU; logdeviceและreason - T022 [P] [US3] แก้
specs/04-Infrastructure-OPS/04-00-docker-compose/Desk-5439/ocr-sidecar/app.py— เพิ่ม VRAM headroom check ในPOST /rerankendpoint; CPU fallback logic เหมือน/embed; เพิ่ม timeout guard (504 response ถ้า CPU timeout) - T023 [US3] แก้
backend/src/modules/ai/processors/ai-batch.processor.ts— รอง handle กรณีที่/embedหรือ/rerankตอบdevice: "cpu"ใน response; logretrievalDeviceลง ai_audit_logs metadata - T024 [P] [US3] สร้าง
specs/04-Infrastructure-OPS/04-00-docker-compose/Desk-5439/ocr-sidecar/tests/test_retrieval_fallback.py— pytest tests สำหรับ CPU fallback behavior ของ/embedและ/rerank
Checkpoint: US3 functional — retrieval never hard-fails due to GPU pressure
Phase 6: User Story 4 — Queue Policy & Selective Realtime Concurrency (P4)
Goal: ai-realtime concurrency = 2 สำหรับ lightweight jobs; rag-query route ไป ai-batch; pause/resume ยังทำงาน
Independent Test: ส่ง 2 intent-classify jobs พร้อมกัน → ทั้งสองรันพร้อมกัน; ส่ง rag-query → ไปอยู่ใน ai-batch
Implementation for User Story 4
- T025 [US4] แก้
backend/src/config/bullmq.config.ts— เพิ่มREALTIME_CONCURRENCYenv variable (default: 2); ปรับai-realtimeworker concurrency ให้ configurable - T026 [US4] แก้
backend/src/modules/ai/processors/ai-realtime.processor.ts— เพิ่ม job type classification:LIGHTWEIGHT_REALTIME_JOBS = ['intent-classify', 'tool-suggest']; generation-heavy jobs ถูก redirect ไปai-batchถ้าเข้ามาผิด queue; เพิ่ม log สำหรับ classification decision - T027 [P] [US4] ตรวจสอบ
backend/src/modules/ai/ai.service.ts— ยืนยันว่าrag-queryถูก dispatch ไปai-batchเสมอ (ไม่ใช่ai-realtime); เพิ่ม explicit assertion ใน dispatch logic - T028 [P] [US4] เพิ่ม unit tests
backend/src/modules/ai/tests/queue-policy.spec.ts— ทดสอบ job classification, rag-query routing, lightweight job concurrency
Checkpoint: US4 functional — selective concurrency active, rag-query always in ai-batch
Phase 7: User Story 5 — Verification & Cutover Gate (P5)
Goal: Test suite ครอบ 4 แกน cutover gate ทั้งหมด; manual validation checklist พร้อม; Admin Console / OCR Sandbox แสดงถูกต้อง
Independent Test: pnpm test -- --testPathPattern="ai-policy|ocr-residency|execution-profile|queue-policy" ทุก test ผ่าน 100%
Implementation for User Story 5
- T029 [US5] สร้าง
backend/src/modules/ai/tests/ai-policy.service.spec.ts— unit tests ครอบ: profile mapping ทุก 4 values, canonical name mapping, data-affecting override,large-contextguard validation - T030 [P] [US5] สร้าง
backend/src/modules/ai/tests/execution-profile.guard.spec.ts— unit tests: admin passes, non-admin blocked, missing token blocked - T031 [P] [US5] สร้าง
backend/src/modules/ai/tests/vram-monitor.service.spec.ts— unit tests: successful query, Ollama timeout fallback, empty models response - T032 [US5] ทดสอบ manual validation ตาม
quickstart.md— รัน curl commands ทั้ง Gate 1–4, ตรวจ Admin Console labels, ตรวจ OCR Sandbox behavior; บันทึกผลใน checklist - T033 [P] [US5] อัปเดต env template ไฟล์
specs/04-Infrastructure-OPS/04-00-docker-compose/Desk-5439/.env.template— เพิ่มVRAM_HEADROOM_THRESHOLD_MB,OCR_RESIDENCY_WINDOW_SECONDS,GPU_TOTAL_VRAM_MB,REALTIME_CONCURRENCY - T034 [P] [US5] อัปเดต
backend/.env.example— เพิ่มAI_VRAM_HEADROOM_THRESHOLD_MB,AI_REALTIME_CONCURRENCY
Checkpoint: All 5 user stories complete — big bang cutover gate ready for validation
Phase 8: Polish & Cross-Cutting Concerns
- T039 [US1] แก้
backend/src/modules/ai/processors/ai-batch.processor.ts— เปลี่ยนocrUsedlabel value จาก"Typhoon OCR"/"PaddleOCR"เป็น"np-dms-ocr"ใน Redis completed result (ครอบคลุม FR-A07: canonical names ทุก layer รวมถึง OCR Sandbox badge) - T035 [P] ตรวจสอบ i18n keys ที่ต้องเพิ่มใน
frontend/public/locales/สำหรับ error messages ใหม่ (400 model.key, 403 large-context, 504 CPU timeout) - T036 อัปเดต CONTEXT.md และ AGENTS.md — เพิ่ม
np-dms-ai/np-dms-ocrเป็น canonical identity ใน System readiness summary; แก้ references เดิมที่ยังใช้ชื่อ runtime - T037 [P] ตรวจสอบ ADR-034 references ทั้งหมดใน codebase ด้วย search — ไฟล์ไหนยังใช้
typhoon2.5-np-dms:latestหรือtyphoon-np-dms-ocr:latestใน user-facing surfaces (ไม่ใช่ Modelfile/ops internals) - T038 รัน
pnpm lintและpnpm type-checkสำหรับ backend และ frontend — แก้ทุก error ก่อน cutover
Dependencies & Execution Order
Phase Dependencies
- Setup (Phase 1): ไม่มี dependency — เริ่มได้ทันที
- Foundational (Phase 2): ต้องรอ Phase 1 (T001, T002) — BLOCKS ทุก user story
- US1 (Phase 3): ต้องรอ Phase 2 complete — สำคัญสุด, ทำก่อน
- US2 (Phase 4): ต้องรอ Phase 2 complete — ขึ้นกับ
VramMonitorServiceจาก T003 - US3 (Phase 5): ต้องรอ Phase 2 complete — ขึ้นกับ
vram_monitor.pyจาก T004 - US4 (Phase 6): ต้องรอ Phase 2 complete — independent จาก US1/US2/US3
- US5 (Phase 7): ต้องรอ US1+US2+US3+US4 complete (ทดสอบทุกแกน)
- Polish (Phase 8): ต้องรอ US5 ผ่าน cutover gate
User Story Dependencies
- US1 (P1): ต้อง complete ก่อน — contract เป็น foundation ของ canonical naming ทุกชั้น
- US2 (P2): ขึ้นกับ
VramMonitorService(T003, Phase 1) เท่านั้น — parallel กับ US1 ได้ - US3 (P3): ขึ้นกับ
vram_monitor.py(T004, Phase 1) เท่านั้น — parallel กับ US1/US2 ได้ - US4 (P4): Independent จาก US1/US2/US3 — parallel ได้หลัง Phase 2
- US5 (P5): ต้องรอทุก US ก่อนหน้า
Parallel Opportunities
- T001 + T002: parallel (different files)
- T003 + T004: parallel (different stacks)
- T005, T006, T007: T005 ทำก่อน (T006, T007 ขึ้นกับ types จาก T005)
- US1 + US2 + US3 + US4: parallel หลัง Phase 2 complete (ถ้ามีทีม)
- T029, T030, T031, T033, T034: parallel (different test files / env files)
Implementation Strategy
MVP First (US1 Only)
- Phase 1: Setup (T001–T004)
- Phase 2: Foundational (T005–T009)
- Phase 3: US1 (T010–T016)
- STOP & VALIDATE: ยิง curl ตาม Gate 1 และ Gate 2 ใน quickstart.md
- Deploy/validate canonical naming ใน Admin Console
Incremental Delivery
- Phase 1+2 → Foundation
- US1 → Policy contract + canonical naming (MVP)
- US2 → Adaptive OCR residency
- US3 → Retrieval CPU fallback
- US4 → Queue policy
- US5 → Full cutover gate verification
Total Task Count
- Total: 39 tasks
- US1: 7 tasks (T010–T016)
- US2: 4 tasks (T017–T020)
- US3: 4 tasks (T021–T024)
- US4: 4 tasks (T025–T028)
- US5: 6 tasks (T029–T034)
- Setup: 4 tasks (T001–T004)
- Foundational: 5 tasks (T005–T009)
- Polish: 4 tasks (T035–T038)