3-stage Workflow run-id evidence: investigate wf_be952f3c-97f / implement wf_a58e0d15-beb / audit wf_9520d8cd-4fe. PART 1 (L2 recovery): 4 over-cap sub (cicd-monitor/investigator-codebase/reviewer/implementer-backend) curated L1->L2 byte-exact + archive/_INDEX.md (substring sha-keyed pointers, no line-hints) + <period>.gist.md (4-field distill, distill-gen:1, verbatim frozen). All 4 MEMORY.md now < 25KB auto-inject cap (closes P1 curate-debt). ~240KB archive no longer RAG-dark. 0-byte-loss git+sha verified (Stage C audit + em-main self-gate on 2 reviewer StructuredOutput no-returns). Read-side gap fixed (MEMORY.md L5 header -> _INDEX). + memory-budget.json (seed-by-measure) + scripts/measure-agent-memory.ps1 + .ragignore guard. PART 2/3 (process mandate): every adap = 2 separate workflows (implement + review) + report with run-id; short-but-needs-confirm still requires review. Codified in .claude/commands/adap-apply.md + agents/README.md (Upgrade S70) + session-start.md (§2.1.2 budget-audit, pending-restart). adap-report + email-back to AI_INFRA (body-hash 7c07b716e775). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
11 KiB
distill-gen: 1
Gist — 2026-06 archive (S41-S55) · 4-field distillation
distill-gen: 1 — already-distilled; do NOT re-compress. Each block = VIỆC · KẾT-LUẬN(+Mig/file:line) · BÀI-HỌC · BẤT-NGỜ, ending
→ substring:"…"grep-UNIQUE in2026-06.md(14 bullets moved byte-exact from MEMORY.md L87-L104, S? Harness-9 curate). Pointer-style = substring (Ctrl-F), Mig-name / phrase keyed. value tag: cao/vừa/thấp. The final subsection distills L1-HOT markers (S56/S57bis/S65) that REMAIN in MEMORY.md (not moved) — included here only so the coverage checklist resolves in one place; their verbatim lives in MEMORY.md, pointer notes say so.
P11-A WorkflowApps wave (S41-S42) — schema + app + seed
[cao] Mig 41 schema — 4 WorkflowApps ApproveV2 + LevelOpinions (S41 P11-A W1). VIỆC: cookie-cutter mirror Proposal Mig 38 — 5 entity (4 {Leave,Ot,Travel,Vehicle}RequestLevelOpinion + shared WorkflowAppCodeSequence Prefix-PK) + 5 EF config (auto-discover ApplyConfigurationsFromAssembly) + 4 parent nav + enum TravelRequest=9 + 2 DbSet. KẾT-LUẬN: Mig 41 WireWorkflowAppsApprovalV2; diff CLEAN 5 CreateTable+4 AddColumn; FK Cascade parent + Restrict Level + UNIQUE composite; both DB. BÀI-HỌC: Pattern 12-bis 13× cumulative. BẤT-NGỜ: none (spec deterministic 100%). → substring:"S41 P11-A Wave 1 SCHEMA — wire ApproveV2+LevelOpinions"
[cao] App-layer ApproveV2 CQRS (S42 Wave 2a LeaveOt stub + 2b Travel/Vehicle). VIỆC: per-module DetailDto+LevelOpinionDto+GetById(JOIN Step/Level)+UpdateDraft+Submit+Approve(UPSERT+advance)+Reject+Return; shared internal CodeGen Serializable-tx. KẾT-LUẬN: TravelVehicleApprovalFeatures ~830 LOC; codes {prefix}/{seq:D3} (D3 NO year segment per spec) vs Leave/Ot {prefix}/{year}/{seq:D3}. BÀI-HỌC: WorkflowAppCodeGen Serializable-tx Prefix-keyed; WorkflowAppStatus enum DIFFERS ProposalStatus int values (DaGuiDuyet=2 not 1, TraLai=3) → mirror by SEMANTIC enum member NOT literal; Owner=RequesterUserId (not DrafterUserId); Submit verify wf.ApplicableType else Conflict. BẤT-NGỜ: 2a content absorbed (stub→git) into Pattern 4 + this 2b entry. → substring:"S42 P11-A Wave 2b APP — wire ApproveV2 CQRS Travel+Vehicle"
[cao] Seed 4 sample workflow V2 (S42 P11-A) — gotcha #51. VIỆC: DbInitializer mirror SeedSampleProposalWorkflowV2Async EXACT ×4 (Leave/Ot/Travel/Vehicle), each idempotent AnyAsync(ApplicableType) guard → 1 Workflow+1 Step+1 Level, codes QT-NP/OT/CT/XE-V2-001. KẾT-LUẬN: wired 4 calls; build 0 err 0 warn. BÀI-HỌC (marker #4): gotcha #51 — infra seed NOT gated by DemoSeed:Disabled (by-design reaches prod, like SeedDemoMasterData/Catalogs). BẤT-NGỜ: Bash tool runs bash NOT PowerShell despite env hint → use cd && cmd | grep. → substring:"S42 P11-A SEED — 4 sample ApprovalWorkflow V2"
P11-B/C HRM business + catalogs (S43, S51)
[cao] LeaveBalance deduct exactly-once (S43 P11-B W1) — Mig 42. VIỆC: entity LeaveBalance:AuditableEntity (UserId/LeaveTypeId/Year + Entitled/Used/Adjustment decimal(5,2)); FK LeaveType Restrict + UNIQUE composite (UserId,LeaveTypeId,Year); deduction hook in ApproveLeaveRequestHandler terminal DaDuyet branch ONLY. KẾT-LUẬN: Mig 42 AddLeaveBalances; RemainingDays = Entitled+Adjustment−Used COMPUTED (not stored); GetMy/GetUser lazy-merge in-memory (no EF LEFT JOIN). BÀI-HỌC (marker #12): deduct exactly-once GUARANTEED by early guard Status != DaGuiDuyet throw; HRM admin convention [Authorize(Roles="Admin")] not menu policy. BẤT-NGỜ: OtRequest/Travel/Vehicle untouched — only Leave has balance. → substring:"S43 P11-B Wave 1 — LeaveBalance business logic"
[cao] Vehicle+Driver catalogs (S51 P11-C W1) — Mig 44, gotcha #57. VIỆC: 2 entity + 2 EF config (mirror filtered HolidayConfiguration NOT buggy bare LeaveType) + 2 DbSet + HrmConfigFeatures Region5/6 + Controller 8 endpoint (GET public, write Admin) + MenuKeys + DbInitializer seed. KẾT-LUẬN: Mig 44 AddVehicleAndDriverCatalogs; diff CLEAN 2 CreateTable+2 filtered IX. BÀI-HỌC (markers #57,#13,#14): Code UNIQUE .HasFilter("[IsDeleted]=0"); admin perm AUTO via MenuKeys.All (SeedAdminPermissions + Program.cs:78 both iterate); HRM no HasQueryFilter→.Where(!IsDeleted) manual. BẤT-NGỜ: RAG/Qdrant DOWN → all Read/Grep on-disk. → substring:"S51 P11-C HMW W1 — Vehicle+Driver catalogs HrmConfigs"
P11-D/E/F WorkflowApps wave2 (S52)
[cao] ItTicket round-robin + SLA (S52 P11-D W2) — Mig 46. VIỆC: entity +SlaDueAt/SlaWarnedSent/SlaBreached; CreateItTicketHandler SlaWindow static map (Urgent4/High8/Medium24/Low72h) shared w/ ItTicketSlaJob; round-robin least-loaded assign (itDept=Departments.Code=="IT"); new ItTicketSlaJob:BackgroundService (breach+warn only, NO auto-transition). KẾT-LUẬN: Mig 46 AddSlaFieldsToItTicket 3 AddColumn no-table; AssignItTicketCommand PUT /{id}/assign [Authorize(Roles=Admin)]. BÀI-HỌC: SeedItDepartmentStaffAsync MUST run AFTER SeedDemoUsersAsync (that method reconciles 2 users to PRO/CCM each boot → override to IT after, end-state deterministic). BẤT-NGỜ: agent killed session-limit before MEMORY → proxy by em main. → substring:"S52 P11-D Wave2 BE — ItTicket round-robin + SLA"
[cao] Attendance report + IT codegen (S52 P11-E+F) — NO mig. VIỆC: P11-F MaTicket gen at Create (kanban no-workflow) IT/2026/001; P11-E AttendanceReportFeatures + IAttendanceReportExcelExporter (ClosedXML mirror ContractExcelExporter). KẾT-LUẬN: 2 endpoint [Authorize(Roles=Admin)] GET /api/attendances/report + /report/excel. BÀI-HỌC: DayOfWeek+holidaySet NOT EF-translate → .ToListAsync() then group/classify IN-MEMORY C#; Holiday.Date = DateOnly NOT DateTime (spec wrote HashSet wrong) → HashSet; day-type prio holiday→weekend→weekday; OtWeighted=Σ(level×coef). BẤT-NGỜ: spec type-error caught (DateOnly). → substring:"S52 P11-E+F Wave1 BE migration-FREE"
Master + cross-stack (S53, S54, S55)
[cao] Filter 3 Master unique indexes (S53 gotcha #57 EXT) — Mig 47 + Mig 46 catch-up. VIỆC: test-before RED→GREEN; edit 3 config Code unique +.HasFilter("[IsDeleted] = 0") (Department/Project/Supplier); Supplier ONLY Code filtered, Type index left untouched. KẾT-LUẬN: Mig 47 FilterMasterCatalogUniqueIndexesByIsDeleted; Mig 46 local catch-up closed LocalDB gap; 203 GREEN. BÀI-HỌC (markers #2,#57): gotcha #57 — soft-delete UNIQUE must filter [IsDeleted]=0; copied filter string BYTE-FOR-BYTE from HolidayConfiguration:18 + LeaveTypeConfiguration:19 (spaces around =, not guessed) → snapshot+SQL consistent w/ 13 existing filtered idx. BẤT-NGỜ: Master HAS global HasQueryFilter (unlike HRM) → app-check passes but bare DB index counts soft-deleted → 500; filter aligns. → substring:"S53 gotcha #57 EXT BE — filter 3 Master Code unique indexes"
[cao] ItTicket reassign capability + fail-closed authz (S54 cross-stack) — NO mig. VIỆC: new GetAssignableItStaffQuery capability endpoint + AssignItTicketHandler authz Admin-OR-dept-IT→ForbiddenException, assignee-must-be-IT→ConflictException; controller /assign lowered Roles=Admin→[Authorize]. KẾT-LUẬN: 2 patterns saved (controller-lower-authorize-handler-finegrained + scoped-capability-endpoint-anti-silent-403); reviewer chain-verified role-string "Admin" real (AppRoles→SeedRoles→JWT→cu.Roles). BÀI-HỌC (marker #11): fail-closed authz — Forbidden BEFORE NotFound (avoid existence-oracle); ICurrentUser lacks DepartmentId → query db.Users. BẤT-NGỜ: em main reconciled 2 patterns from stray src/Backend/.claude (cwd-relative Write mishap). → substring:"S54 ItTicket reassign cross-stack — IT-staff self-service"
[vừa] Menu leaf AttendanceReport (S54 Task D) — NO mig. VIỆC: 3 insert — MenuKeys const Off_AttendanceReport + All[] + DbInitializer menu tuple (Order 8, parent Off). KẾT-LUẬN: admin perm auto via MenuKeys.All 2-point (SeedAdminPermissions :1916 + Program.cs:78). BÀI-HỌC: idempotent seed upsert (existing prod gets leaf on restart, existing rows only Order-reconciled). BẤT-NGỜ: none. → substring:"S54 Task D BE — promote AttendanceReport to sidebar menu leaf"
[cao] Real master-data import (S55) — Mig 48 + ungated seed. VIỆC: Project +4 prop (Year int?, Investor/Location/Package, maxlen 250/500/300); SeedRealMasterDataAsync 3 tuple-loop per-code idempotent, wired UNGATED after SeedCatalogsAsync. KẾT-LUẬN: Mig 48 AddProjectMasterFields 4 AddColumn no-table; seeds 62 Project+71 WorkItem+3 Supplier; runtime Dev proof landed. BÀI-HỌC: real-data import reaches prod by-design (DemoSeed:Disabled NOT gate); FLOCK01 collision demo↔real → per-code skip (demo wins). BẤT-NGỜ: WorkItem divider row "THIẾT BỊ" dropped; agent return truncated #53 → proxy by em main. → substring:"S55 master-data import (Mig 48 AddProjectMasterFields"
[stub→git d2f52ba] older absorbed (S35/S40 trim)
[thấp] S35 BE-CRUD-4-catalog + S29 Contract-V2-mirror. KEY absorbed into L1 Pattern 12-bis foundation (catalog-mega + HRM .Where(!IsDeleted) manual + Validator MaxLength=EF). → substring:"Archived S35 G-H2 BE-CRUD-4-catalog + S29 Plan-B-Chunk-C Contract-V2-mirror"
[thấp] S40 curate — FE/test + older BE → git d2f52ba. S35 FE inline forms 5 satellite + S34 test +10 (130 PASS) + S33 EmployeesListPage + S32 wrap/startup. → substring:"Archived FE/test + older BE entries → archive/2026-05-q4.md + git d2f52ba (S40 curate)"
L1-HOT markers (still in MEMORY.md — NOT moved; distilled here for coverage completeness)
These live VERBATIM in MEMORY.md (kept hot). Pointers below target MEMORY.md, not 2026-06.md.
- [cao] S56 GOLIVE-HARDEN — ExecuteUpdate atomic + fail-closed (markers #10,#11). LeaveBalance lost-update →
ExecuteUpdateAsyncserver-side row-lock inside tx (em-main post-review bumped toIsolationLevel.Serializable); AssignItTicket existence-oracle → Forbidden guard BEFORE NotFound (fail-closed). STALE-TRACKED caveat: ExecuteUpdate bypasses tracker → don't re-addbal.UsedDays +=(double-count). → substring(MEMORY.md):"S56 GOLIVE-HARDEN 3 BE fix" - [cao] S57bis/S65 loose-Guid FK guard (marker #13). loose-Guid FK (WorkItemId S57bis, Department.ParentId S65) = NO physical FK; guard
AnyAsync(x.Id==id && x.IsActive)→Conflict (mirror S43); UpdateDraft null-safeif (request.WorkItemId is not null)to avoid null-ing bug-class S42. → substring(MEMORY.md):"FK-guard loose-Guid" - [vừa] L1 Pattern foundation markers (#3,#5,#9b). gotcha #17 = EF migration 3-file rule (Pattern 2, BẮT BUỘC commit
.cs+.Designer.cs+snapshot); gotcha #65 =dotnet build SolutionErp.slnxincludes 2 test projects; Mig 29/30/31 per-NV admin opt-in (Pattern 7, proven 4×). → substring(MEMORY.md):"EF migration 3-file rule (gotcha #17"