Files
solution-erp/.claude/agent-memory/test-specialist/archive/activity-s51-s52.gist.md
pqhuy1987 e939fab50a [CLAUDE] Memory: sleep-compress L2 test-specialist — activity-s51-s52.gist.md additive
/sleep-recovery-memory-l2 all (S88). Phase 0 scan: 18/19 L2 verbatim SKIP
(14x 2026-05-qN.md already in aggregate 2026-05.gist.md gen:1, verified by
reading source-decl; 4x 2026-06.md double-distill guard gen 1-2; 5 subs
empty archive). 1 distilled: test-specialist activity-s51-s52.md (gen-0
orphan, no gist) -> activity-s51-s52.gist.md (distill-gen:1), 4 records ->
3 clusters (C-A merges the 2 gotcha#57 episodes).

reviewer Fidelity-gate FAIL v1 -> re-distill: C-A merge had mis-attributed
the whole fix to "Mig 45"; verbatim ties Mig 45 to HRM-only (LeaveTypes/
ShiftPatterns), Master (Dept/Project/Supplier) = Mig 47 per canonical
CLAUDE.md. Split per-episode -> PASS. coverage-diff 26/26, G-009 clean,
ratio 97% (signal-dense, report-not-target). last_sleep_at -> 2026-06-25.

+reviewer self-harvest: merge-distill false-specificity anti-pattern
(presence-gate blind to cross-episode shared-token mis-attribution).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-25 08:35:26 +07:00

5.2 KiB
Raw Blame History

distill-gen: 1

Gist — activity-s51-s52 (test-specialist · S51-S52) · 4-field distillation

distill-gen: 1 — already-distilled; do NOT re-compress (Phase 0.3 double-distill guard). Each block = VIỆC · KẾT-LUẬN(+file:line) · BÀI-HỌC · BẤT-NGỜ, ending → substring:"…" that grep-resolves UNIQUE in the verbatim file. Pointer-style = substring (Ctrl-F), file/phrase keyed. value tag: cao/vừa/thấp. source-verbatim: activity-s51-s52.md (4 records → 3 clusters; C-A MERGES the two gotcha#57 episodes S51-HRM + S52-Master). Distilled S88 (2026-06-25) via /sleep-recovery-memory-l2, harvest-curator Phase-1 propose + reviewer Fidelity-gate. ⚠️ Counts (185 / 191 / 200 PASS) are EPISODE-LOCAL FIFO-snapshots (S51-S52-era), NOT current state — canonical current → docs/STATUS.md.


C-A · gotcha #57 filtered-unique soft-delete (MERGED S51-HRM + S52-Master) [cao]

VIỆC: Test-before reproduce gotcha #57 across 2 episodes — S51 HRM (HrmConfigFilteredUniqueTests.cs, +4: 2 GREEN Vehicle/Driver Mig 44-already-filtered + 2 RED LeaveType/Shift) → S52 Master (MasterCatalogFilteredUniqueTests.cs, +3 ALL RED Dept/Project/Supplier). test-before.

KẾT-LUẬN: Bare .IsUnique() (Master configs Dept cfg:18 / Proj:19 / Supp:24) counts soft-deleted rows → SQLite Error 19 UNIQUE constraint failed on {Departments|Projects|Suppliers|LeaveTypes|ShiftPatterns}.Code. ROOT-CAUSE: app-check AnyAsync(Code==X) passes THROUGH HasQueryFilter (excludes soft-deleted → PASS) → Add+SaveChanges → DB UNIQUE counts the dead row → throw. Fix = .HasFilter("[IsDeleted]=0") (disk-true form [IsDeleted] = 0, with spaces) → flip GREEN — PER-EPISODE (do NOT cross-attribute): HRM LeaveTypes/ShiftPatterns in Mig 45 (S51); Master Departments/Projects/Suppliers in Mig 47 (S53, gotcha #57 EXT — per canonical CLAUDE.md; the verbatim Master record left the migration number bare). Handlers 1-dep Create{Dept|Project|Supplier}CommandHandler(db) / new CreateXxxHandler(db). Verdict: S52 3 RED (Failed 3/Passed 0); S51 2 RED INTENTIONAL + 2 GREEN. RED ≠ test bug → REPORTED em main fix migration.

BÀI-HỌC: all-count assertion MUST use IgnoreQueryFilters() (verified 3× on disk in Master test) — CORRECTED the HRM-ref's wrong Count(Code==X)-on-filtered-DbSet (returns 1 not 2 because DbSet already carries HasQueryFilter). Reusable pattern = active-count = plain DbSet · all-count = IgnoreQueryFilters(). Mirror = HrmConfigFilteredUniqueTests GROUP B / HolidayTests Case 7 (seed-soft-deleted-slot origin).

BẤT-NGỜ: AuditingInterceptor (prod soft-delete Deleted→Modified+IsDeleted=true) NOT wired in SqliteDbFixtureRemove+SaveChanges = HARD delete (can't test soft-delete via Remove) → must seed row IsDeleted=true manually to simulate the occupied Code-slot.

→ substring:"all-count PHẢI" (IgnoreQueryFilters nuance, S52-Master record) + substring:"AuditingInterceptor (prod soft-delete" (soft-delete-in-test surprise, S51-HRM record)

C-B · round-robin assign + SLA-due [vừa · S52]

VIỆC: +9 test ItTicketAssignSlaTests.cs (Infra 133→142, baseline 191→200); proxy by em main (agent killed session-limit before MEMORY step).

KẾT-LUẬN: Round-robin assigns lowest-load IsActive user in Dept Code="IT" (A=1-open ticket vs B=0 → assign B, load 0<1); tie A=B → ThenBy(Id); edge no-dept-IT / no-user-IT / user-outside-IT / IsActive=false → unassigned. SLA-due Urgent→+4h / High→+8h / Medium→+24h / Low→+72h, assert SlaDueAt == CreatedAt + SlaWindow[priority]. Regression P11-F: code-gen still ^IT/\d{4}/\d{3}$.

BÀI-HỌC: assign + per-priority SLA-window unit-testable via direct handler; window = flat lookup table.

BẤT-NGỜ: ItTicketSlaJob BackgroundService SKIP unit-test — breach-query inline, hard to test directly (REPORTED, not covered).

→ substring:"load 0<1"

C-C · codegen day-type + Serializable-SQLite-OK [vừa · S52]

VIỆC: +5 test (Infra 128→133, 191 PASS): ItTicketCodeGenTests (3) + AttendanceReportTests (2), P11-E/F test-after. Handler CreateItTicketHandler(db, cu, clock) 3-dep MediatR.

KẾT-LUẬN: Codegen ^IT/\d{4}/\d{3}$ sequential 001→002 per-prefix IT/{year} LastSeq++, 2027 reset 001. Day-type: holiday check runs BEFORE weekend/weekday → seed 2026-06-01 (thứ Hai) into holidaySet → asserts Holiday despite weekday (override day-of-week); Holiday.Date=DateOnlyBuildHoliday uses DateOnly.FromDateTime. OtWeighted = 2×1.5+3×2.0+1×3.0 = 12.0m. DepartmentId filter joins Users u.DepartmentId==deptId with DefaultIfEmpty (dept row optional).

BÀI-HỌC: holiday-precedence-over-day-of-week = core day-type rule. MSBuild-OOM on full parallel → -maxcpucount:1 -p:BuildInParallel=false (env resource, NOT test fail).

BẤT-NGỜ: Serializable-on-SQLite GOTCHA = NON-ISSUE (confirmed)BeginTransactionAsync(IsolationLevel.Serializable) in WorkflowAppCodeGen.GenerateMaDonTuAsync runs CLEAN on SQLite (provider maps isolation gracefully, no throw); format+seq+per-year hold without try/skip. Also proven by WorkflowAppApproveV2Tests (DT/LR path).

→ substring:"Serializable-on-SQLite GOTCHA = NON-ISSUE"