# Test-Specialist Agent — Persistent Memory > **Persistent diary cross-session.** Auto-injected first 200 lines / 25KB at spawn. > Update BEFORE every stop. Tiered Memory v1: L1 HOT soft-cap ~30KB · L2 `archive/` on-demand · L3 RAG `search_memory` just-in-time. Keep entry ≤ 1.5K chars (gotcha #53). > **NEW agent S39 (2026-05-29)** — dedicated test layer (tách khỏi implementer Case 3). --- ## 🎯 Role baseline WRITE specialist độc quyền `tests/**`. xUnit + FluentAssertions 7.2 + EF SQLite TestApplicationDbContext + IdentityFixture. Tools: Read, Edit, Write, Bash, Grep, Glob + 5 RAG. Skills: `contract-workflow` + `permission-matrix`. ## 🚫 Split boundary - ✅ MINE: `tests/SolutionErp.{Domain,Infrastructure}.Tests/**` - ❌ NOT: production code `src/Backend/**` + `fe-*/**` → test reveal bug → REPORT em main, KHÔNG fix - ❌ NOT: decide WHAT to test (test plan) → em main + reviewer chốt priority ## 📊 Baseline 130 PASS (58 Domain + 72 Infra) Run: `dotnet test SolutionErp.slnx --nologo --verbosity minimal` ## ⏱️ Timing rules (docs/rules.md §7) - Feature mới = test-after (UAT ổn → viết, Phase 9 skip per `feedback_uat_skip_verify`) - Bug fix = test-before BẮT BUỘC (reproduce → fix) - Critical algo = test-before merge (codegen/guard/financial/security) - Skip: DTO mapping, CRUD master, FE snapshot ## 📋 Patterns proven (apply confidently) ### Pattern 10 Reflection authz regression (~50 LOC) Catch class-level `[Authorize(Policy=...)]` regression: `typeof(Ctrl).GetCustomAttribute().Policy.Should().Be(...)`. KHÔNG WebApplicationFactory heavy. Cho gotcha #44 silent 403. ### Pattern 11 Test infra helper cookie-cutter `SeedWorkflowAsync` (1 Step DepartmentId=null skip FK + 2 Levels) + `SeedApproversAsync` (N user fix.CreateUserAsync). Reusable PE/Contract/Proposal workflow test. ### Pattern 12 InternalsVisibleTo Expose internal helper via `` csproj. ### Spec drift detection BEFORE write (S34 lesson) Test theo CODE (single source truth), document mismatch header comment + report. Vd soft-delete UNIQUE: code chặn opt-out → test theo code, flag drift. ### gotcha #48 SQLite tie-break `OrderByDescending(CreatedAt).First()` pick wrong khi 2+ Add() cùng CreatedAt frozen-clock → discriminator filter `.Where(Summary.Contains("Chuyển phase"))` BEFORE OrderBy. ## 🎯 Coverage gap backlog (priority — Reviewer flagged S36) 1. **CRITICAL:** HrmConfig 16 endpoint (S35) — Holiday composite UNIQUE (Year,Date) Update 0 test 2. **MAJOR:** EmployeeSatellite 15 endpoint (S34) — cascade + FK invariant 0 test 3. **MAJOR:** gotcha #44 regression MISS EmployeesController + HrmConfigsController 4. Phase 10.3 Proposal ApproveV2 (S37) + Workflow Apps skeleton (S38) — test-after khi UAT confirm ## 📅 Recent activity (last 10 FIFO) - **2026-05-29 (S39 agent split setup):** NEW dedicated agent. Seeded test patterns (10 reflection authz + 11 infra helper + 12 InternalsVisibleTo + #48 SQLite tie-break + spec drift S34). Inherited coverage gap backlog 4 priority items từ S36 Reviewer audit (130 PASS baseline). First spawn pending em main S39+ test bundle task (recommend Gap 1 Holiday composite UNIQUE first). - **2026-05-29 (S40 baseline audit smoke):** CONFIRMED 130 PASS (Domain 58 + Infra 72), 0 fail/skip, ~15s. Runner count authoritative; raw `[Fact]/[Theory]` attr = 48+70 (Theory→InlineData expand). Infra spread 15 files. Gap re-verified vs prod: EmployeesController+HrmConfigsController EXIST, authz regression chỉ ApprovalWorkflowsV2Controller (gotcha #44 gap real). Proposal = Domain entity + EF config only, CHƯA có ApproveV2Async service (S37 skeleton, defer đúng). Agent load OK. AUDIT-only, no write. --- ## ⚠️ Anti-patterns (DO NOT) 1. ❌ Touch production code → REPORT bug · 2. ❌ Skip MEMORY · 3. ❌ Test không chạy (dotnet test must PASS) · 4. ❌ `git add -A` · 5. ❌ Push remote · 6. ❌ Assertion trivial ## 🔄 Curate trigger Size > 25KB → archive. Commit scope (em main commits): `Tests`.