Files
solution-erp/.claude/agent-memory/reviewer/MEMORY.md
pqhuy1987 b832f43d8e [CLAUDE] Docs+Memory: S32 Phase 10 backlog Plan G NamGroup port + 4 sub-agent startup entries
migration-todos.md: insert Phase 10 detail section (10 Plan G-* atomic per-module sprint
~3 thang T6-T8/2026 target, aggressive multi-agent parallel ROI ~70%). 4 quyet dinh anh
chot S32: FULL 11 module scope + single schema dbo mo rong Mig 34-42 + reuse Workflow
V2 extend ApplicableType +5 values + chunk per-module Plan rieng. Sequence Phase 9
stabilize first per anh main "tuan tu theo ke hoach tot nhat". G-P1 pure web GPS
check-in (no device). G-H2 seed reference NamGroup demo data.

4 MEMORY sub-agent: append S32 startup entry (Investigator + Implementer + Reviewer +
CICD Monitor) ghi nhan S31 RAG retrieval.py fix + S29 Plan CA+B deploy + Pending tasks
anh main co the SendMessage reuse. Implementer 36.2KB OVER 25KB threshold FLAG curate.

Refs: docs/CLAUDE.md Phase 6-9 done. docs/STATUS.md S31 wrap. gotcha #51 INFRASTRUCTURE
vs DEMO seed gate (Phase 10.3 enum extend caution). gotcha #52 qdrant.search removed
(RAG layer stable post-S31 fix).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-26 16:17:36 +07:00

178 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Reviewer Agent — Persistent Memory
> **Persistent diary cross-session.** Auto-injected first 200 lines / 25KB at spawn.
> Update BEFORE every stop. Curate when > 25KB.
---
## 🎯 Role baseline
Adversarial pre-commit reviewer for SOLUTION_ERP. Read-only verification + live curl on prod UAT environment (`*.solutions.com.vn`). Tools: Read, Grep, Glob, Bash (curl + git diff + sqlcmd read). Output: PASS/FAIL verdict + concrete issues file:line.
---
## 🚨 Recurring SOLUTION_ERP bug patterns (catch with priority)
### Gotcha #44 — Silent 403 class-level Authorize quá strict (S18 lesson)
- Symptom: Drafter dropdown V2 workflow empty silent (no error toast)
- Root: `[Authorize(Policy = "Workflows.Read")]` class-level → non-admin 403, TanStack Query catch silent → UI empty
- Verify: grep `\[Authorize\(Policy = .*\)\]` class-level vs action-level + curl với non-admin token expect 200
- Fix pattern: class-level `[Authorize]` only (any authenticated). POST/PUT/DELETE giữ `[Authorize(Policy = "X.Create")]` admin-only
### Gotcha #43 — Step.Order ≠ index 0-based
- Symptom: EF query `Where(s => s.Order == i)` returns wrong row
- Verify: grep `step.Order` arithmetic — array index 0-based vs Order field 1-based
- Fix pattern: precompute candidates EF query → in-memory `OrderBy(s => s.Order).ToList()` → array index access
### Gotcha #42 — Dual schema workflow V1 vs V2 — Service phải branch
- Symptom: PE submit failed do Service không biết V1 hay V2 schema
- Verify: grep `evaluation.ApprovalWorkflowId is Guid awId` — phải branch theo pin field
- Fix pattern: `if (evaluation.ApprovalWorkflowId is Guid awId) ApproveV2Async(...) else ApproveV1LegacyAsync(...)`
### Wire BE claim recurring bug pattern
- Symptom: claim wire CRUD nhưng grep diff finds `// Mock` / `alert(...)` / no POST/PUT/DELETE call
- Verify: grep diff mock markers + live curl POST/PUT/DELETE expect 2XX
- Severity: CRITICAL — block commit
### Cross-module security validation mirror (NEW S29 — Smart Friend 4× cumulative)
- Symptom: khi mirror entity/Command/Handler cross-module (PE → Contract → Budget V2), em main solo focus data shape (DTO field, FK relation, projection) MISS security validation guards
- Pattern: ApplicableType type guard cho V2 workflow pin entity — `aw.ApplicableType == ExpectedType` validate ON Create command BEFORE entity instantiation. Mirror PE pattern `PurchaseEvaluationFeatures.cs:62-77`: load workflow, assert ApplicableType=Contract(3) / PE(1) / Budget(2), throw `ConflictException` on mismatch
- Attack vector example (S29 Plan B): Drafter forge POST `/api/contracts` với `approvalWorkflowId` của PE/Budget V2 workflow → FK Restrict allows (only checks Id existence, NOT ApplicableType) → Contract pins wrong-scope workflow → semantic policy violation
- Password policy mirror (S29 Plan CA Hotfix D2): Identity ≥12 chars enforced — new seed user CreateAsync fail nếu reuse legacy 11-char `User@123456`. Verify per-user inline conditional override (e.g. `"CatalogMgr@2026"` 15 chars)
- Verify: grep `CreateXCommand` handler — expect `aw.ApplicableType == ApprovalWorkflowApplicableType.X` check. Also re-verify `IsActive=true` + `IsUserSelectable=true` server-side (FE filters but BE trusts blindly = lower-risk gap)
- Applicable cross-module forward: Contract V2 (S29 fixed), Budget V2 (future), Notification V2 (future), any new V2 workflow pin entity
- Severity: MAJOR — block push pre-commit gate
### Gotcha #17 — EF migration 3-file rule
- Symptom: commit migration nhưng thiếu `.Designer.cs` hoặc `ApplicationDbContextModelSnapshot.cs` → next migration fail
- Verify: `git diff --name-only | grep Migrations/` expect 3 files (target.cs + target.Designer.cs + Snapshot.cs)
### Gotcha #47 — `.claude/agent-memory/**` NOT in `paths-ignore` filter (S22 discovery, PENDING bro decide)
- Symptom: MEMORY.md drift patch commit (end-of-session flush) triggers full CI deploy ~3.5min waste
- Verify: check `.gitea/workflows/deploy.yml` `paths-ignore` — currently `['docs/**', '**/*.md', '.claude/skills/**']` MISSING `.claude/agent-memory/**`
- Discovery: S21 CICD Monitor Run #188 verify chốt initial — confirmed via path filter audit
- Fix recommended: add `.claude/agent-memory/**` vào paths-ignore (em main KHÔNG tự edit — flag bro decide; pending add to `docs/gotchas.md` 47th entry)
- Severity: minor (CI waste only, no functional impact)
---
## 📋 5-category checklist (apply EVERY review)
### Category 1: Wire BE / feature claim verify
- Grep mock markers in diff (`// Mock`, `alert(`, `setEditing(null) // close UI`, `TODO.*wire`)
- Grep actual API call: `await api\.(post|put|delete|patch)\(` trong FE diff
- Live curl POST/PUT/DELETE/PATCH if deploy claim (`https://api.solutions.com.vn/...`)
- Status code matrix expected vs actual
### Category 2: Schema integrity (44 active gotchas)
- Reference `docs/gotchas.md` + skill `dependency-audit-erp`
- Check 3-file rule Mig
- Check column types vs entity definition (Mig 27 lesson: `IsVisible bit NOT NULL DEFAULT 1` + `DisplayLabel nvarchar(200) NULL`)
### Category 3: Security
- `[Authorize]` class-level on ALL new controllers
- Per-action `[Authorize(Policy = "...")]` cho admin-scoped (gotcha #44 lesson)
- Permission guard wrap new admin pages (FE)
- Route permission map populate (`menuKeys.ts` mirror BE `MenuKeys.cs` + `All[]`)
- Input validation FluentValidation Validator class
- SQL parameterized (EF Core default OK) + XSS escape
### Category 4: Code quality
- `dotnet build SolutionErp.slnx` clean 0 err
- `npm run build` × fe-admin + fe-user clean (TS6 strict)
- Tests baseline 81 PASS (Phase 9 UAT exception OK)
- No `--no-verify` bypass (forbidden absolute)
- Anti-fiddle audit (scope drift > 20% LOC outside spec = FAIL)
- Mirror 2 FE app khi feature FE (rule §3.9)
### Category 5: Test coverage
- New helper static → unit test (xUnit)
- New Repository method → repo test
- New endpoint API → integration test (WebApplicationFactory)
- Bug recurring → regression test TDD-style (test BEFORE fix)
- **Phase 9 UAT exception:** test-after default OK theo memory `feedback_uat_skip_verify`
- Test count baseline 81 → tăng khi feature added theo §7
---
## ⚠️ Anti-patterns observed (DO NOT)
1. ❌ Recommend code edits — only describe issue + acceptance criteria
2. ❌ Skip live curl verify if deploy claim — recurring risk
3. ❌ Accept "wire" claim without grep proof
4. ❌ Defer to em main authority — escalate disagreement explicitly
5. ❌ Skip MEMORY.md update với anti-patterns observed
6. ❌ Lower bar to match em main quality — Smart Friend anti-pattern Cognition
---
## 🛡️ Smart Friend anti-pattern guard
Per Cognition documented research:
- NEVER lower bar to match em main's apparent quality
- If em main code fine → say PASS
- If em main code has issues → FAIL with specifics regardless social pressure
- "Quality ceiling was set by the primary, not the escalation." — Your value = raise quality through catch
---
## 🧠 SOLUTION_ERP review essentials
- **Tests baseline:** 111/111 PASS (S25 unchanged from S23 t3 +7 Plan M edge case tests; pre-Plan AB Chunk A2 SQLite tie-break regression Run #215 caught by CICD test gate → em main fix EntityType + Summary discriminator filter restored 111 PASS). Must increase nếu feature added per §7; UAT iteration exception per memory `feedback_uat_skip_verify`
- **Gotchas:** 47 active (`docs/gotchas.md` reference) — +#48 Multi-Changelog.Add() trong same SaveChangesAsync transaction → SQLite test frozen clock CreatedAt tie-break non-deterministic (S25 pending docs add). +#45 PE button TraLai payload mismatch + #46 Gitea API path/cache stale (S21 t3-t4). #47 paths-ignore agent-memory gap (S22 PENDING bro confirm add to docs)
- **Migrations:** 31 latest `AddPeLevelOpinionsForV2` (S19 — Mig 31 Plan K1 swap F2 Drafter→Approver scope per-Level slot S23 t1). Mig 30 `AddAllowApproverEditBudgetToLevels` (S22+5 per-slot F4 flag admin opt-in Approver scope edit budget ChoDuyet branch). Mig 29 prev `RefactorAdvancedOptionsToPerLevelAndDrafterUser` (S21 t5 per-NV split)
- **Per-NV Allow* scope split** (Mig 29 + Mig 30) — F1+F3 5 flag + F4 `AllowApproverEditBudget` (S22) on `ApprovalWorkflowLevels` (per Approver slot), F2 1 flag on `Users.AllowDrafterSkipToFinal` (per Drafter). DTO: `currentLevelOptions` + `drafterAllowSkipToFinal` thay vì `workflowOptions`
- **Endpoints:** ~146 (+3 S22: allow-skip-final / budget-adjust / attachments/view)
- **Identity password policy ≥12 chars** (S22+2 enforced by ASP.NET Identity stack — reject `User@123456` 11 chars). Existing HANDOFF mention "User@123456" pattern S4 outdated, current test creds Admin@123456 + TestUser@123456 OK
- **Live deploys (Prod UAT):** https://api.solutions.com.vn · https://admin.solutions.com.vn · https://eoffice.solutions.com.vn
- **Bearer token test:**
- Admin: `admin@solutions.com.vn / Admin@123456` (full quyền)
- UAT user: `nv.test@solutions.com.vn / TestUser@123456` (Drafter Phòng CCM — verify non-admin access patterns)
- **Users active:** 33 (rename role-based pattern act.nv / act.pp / act.tp etc.)
- **Conventions:** `docs/rules.md` (§3.9 mirror 2 FE, §5.2 commit format, §6.5 docs KEEP narrative, §7 test timing, §2.8 package pinning)
- **6 skills:** `contract-workflow` · `permission-matrix` · `form-engine` · `ef-core-migration` · `dependency-audit-erp` · `iis-deploy-runbook`
---
## 🔑 Critical pin verify (gotcha #1-4)
- MediatR `12.4.1` (14 fail DI)
- Swashbuckle `6.9.0` (10 conflict OpenApi 2)
- Microsoft.OpenApi `1.x` (2 breaking)
- Node engines `>= 20` + CI `20.x` (Node latest fail Windows IIS)
Flag commit nếu thấy `<PackageReference Include="MediatR" Version="14...` hoặc tương tự.
---
## 📅 Recent activity (last 10 FIFO)
- **2026-05-26 (S32 startup verify — adversarial mindset ready, 0 actual review):** Em main spawn em standby cho S32. Self-verify context: MEMORY 22.50KB (23042 bytes — approaching 25KB threshold, chưa curate cần nhưng cảnh báo entry mới sẽ trigger soon), last entry 2026-05-22 13:28 S29 wrap khớp. MCP RAG `search_memory` + `cross_project_search` PRESENT cả 2 — test query "ApplicableType validation" trả rerank 0.867 (high precision match Cross-module security entry line 41-49). **Awareness S31 fixes (between sessions, em không spawn):** RAG v1.3 baseline PASS recall@5=1.000 (11/11) + retrieval.py fix, gotcha #52 NEW added — KHÔNG impact Reviewer adversarial logic (infra ops fix, không phải application code). **Awareness S29 deployed prod**: Plan CA + Plan B Contract V2 wire push successful, gotcha #51 NEW added (INFRASTRUCTURE vs DEMO seed gate — `SeedSampleContractWorkflowV2` OUT of `if (settings.DemoSeed)` gate là correct pattern infrastructure data luôn seed regardless of demo mode). **Smart Friend pattern 4× cumulative VERIFIED preserved**: (1) S22 #44 silent 403, (2) S25 #48 SQLite tie-break, (3) S29 Plan CA password ≥12 chars, (4) S29 Plan B ApplicableType cross-module. **Adversarial mindset retained pre-commit gate active**: forward cho 3 pending task em main có thể spawn em qua SendMessage — (a) Plan B-Wrap BW1-BW7 test bundle review (ApproveV2Async coverage ~150 LOC 0 unit test gap + ApplicableType validate regression test — gotcha #48 lesson SQLite tie-break apply when add Changelog rows in test setup, cần discriminator EntityType + Summary keyword); (b) ContractWorkflowMatrixView review pre-commit khi Implementer wire xong (anticipate Mirror §3.9 fe-admin + fe-user 2 file sync check, V1/V2 dual schema branch verify, permission menuKey populate sync BE+FE); (c) Phase 9 UAT hard blocker audit (SMTP outbox table + sender flow / rotate creds 5 item / SQL backup schedule daily 03:00 / win-acme cert renewal 3 cert 60d). **Token cost spawn standby ~6K**. Patterns NEW noted reinforce S32: pre-spawn checklist verify MEMORY size + freshness + MCP tools first-call before any review action (standard hygiene).
- **2026-05-22 (S29 wrap — Plan CA Reviewer 2 spawn MAJOR password fix + Plan B Reviewer 2 spawn MAJOR ApplicableType fix — Smart Friend 4× cumulative):** Em main wrap S29 sau 2 big plans Plan CA (Move Cấu hình danh mục admin→eoffice, 7 commits) + Plan B (Contract V2 wire mirror PE Mig 22-26, 11 commits). **Plan CA pre-commit verify** spawn 1× (agentId a4dbdb0fb7e210694) + re-verify 1× (a2009a0ed75b40dad) ~165K cumulative — 4 chunks PASS post Chunk D2 hotfix. **MAJOR catch**: `DemoUserPassword = "User@123456"` 11 chars (existing 30 demo seed pre-S22+2 Identity policy ≥12 chars) → new catalog.manager seed CreateAsync FAIL prod. Fix: per-user inline conditional override `"CatalogMgr@2026"` 15 chars passes policy. Lesson: Identity password policy enforcement gap khi reuse legacy seed pattern. **Plan B pre-push verify** spawn 1× (agentId ace4799f663224b71) + re-verify 1× (a2f8f815522544b73) ~190K cumulative — 9 commits FAIL 1 MAJOR. **MAJOR catch**: `CreateContractCommand` thiếu validation `aw.ApplicableType == ApprovalWorkflowApplicableType.Contract(3)` — attacker forge POST với PE/Budget V2 workflow ID → FK Restrict allows only Id existence check NOT ApplicableType → Contract pin sai workflow scope semantic violation. Mirror PE pattern `PurchaseEvaluationFeatures.cs:62-77` exact. Hotfix Reviewer commit `3e92584` apply ~10-12 LOC ApplicableType guard → re-verify PASS proceed push. **Smart Friend pattern proven 4× cumulative**: (1) S22 #44 silent 403 class-level Authorize, (2) S25 #48 SQLite frozen clock tie-break, (3) S29 Plan CA Hotfix D2 password policy, (4) S29 Plan B ApplicableType cross-module. **Patterns proven NEW S29 Reviewer perspective**: Cross-module security validation mirror (PE → Contract → Budget V2) — khi mirror entity/Command, MUST mirror validation guards (ApplicableType + FK check + idempotent + password policy). Easy miss vì em main solo focus on data shape NOT security. **Cat 3 Security checklist reinforced**: ApplicableType type guard cho V2 workflow pin pattern + password ≥12 chars enforcement + IsActive/IsUserSelectable server-side re-validate. **Anti-patterns observed S29**: (a) Em main miss ApplicableType validation Plan B Chunk E1 CreateContractCommand → Reviewer catch. (b) Em main miss password ≥12 chars Plan CA Chunk D → Reviewer catch. (c) Pattern: em main solo flow tends to miss security guard cross-module (focus shape > security). **Recommendation forward**: Reviewer spawn pre-commit MANDATORY cho cross-module mirror diff (PE→Contract, PE→Budget V2 future, identity policy change). Em main solo OK cho UI polish iteration (S26 Plan AG2-AG6 pattern proven). Smart Friend guard active S30+ cho next cross-module wire (Budget V2 likely).
- **2026-05-22 (S29 Plan B Contract V2 wire pre-push spawn — FAIL 1 major):** Adversarial verify 9 commits `58898e8..14feb69` Plan B Contract V2 wire (~8,900 LOC = BE 326 + FE 219 + Mig Designer 7,970 + Mig SQL 327). Spawn ~17K. **Verdict FAIL — 1 MAJOR Cat 3 security/data integrity, 0 critical, 3 minor.** Wire claim PASS (all 9 chunks deliver — ApproveV2Async 150+ LOC mirror PE pattern, UPSERT ContractLevelOpinion, DTO populate, FE Select dropdown, Section 5 dynamic render). Schema PASS (2 mig 3-file rule complete, FK Restrict Contract→AW + Cascade Contract→LevelOpinion + Restrict LevelOpinion→Level, UNIQUE composite). Code quality PASS (dotnet build 0 err 2 pre-existing DocxRenderer warn, npm × 2 PASS 0 TS, mirror §3.9 SHA256 IDENTICAL × 3 files: ContractDetailContent.tsx + ContractCreatePage.tsx + types/contracts.ts). Test PASS 111/111 baseline preserved. Authority PASS explicit mandate. **MAJOR FOUND**: `CreateContractCommandHandler` (`ContractFeatures.cs:38-100`) accepts `ApprovalWorkflowId` from request body but DOES NOT validate `aw.ApplicableType == ApprovalWorkflowApplicableType.Contract`. PE pattern at `PurchaseEvaluationFeatures.cs:62-77` explicitly validates `aw.ApplicableType == expectedType` and throws `ConflictException`. Plan B Chunk E1 omits this guard. **Attack vector**: Drafter posts `approvalWorkflowId` of PE/Budget V2 workflow → FK Restrict allows (only checks Id existence not ApplicableType) → Contract pins wrong-scope workflow → semantic policy violation. **Acceptance criteria**: Add validation block in handler mirror PE lines 64-77 — load aw, assert ApplicableType=Contract(3), throw ConflictException on mismatch. Recommend also re-verify IsActive + IsUserSelectable server-side (FE filters but BE trusts blindly — lower risk). **Adversarial 10/10 PASS**: V1 path UNCHANGED (only additions before line 91), race B+A2 clean, B2 UPSERT scope OK post-Chunk C, Mig 32 Seed idempotent guard, E1 backward compat null default, E2 N+1 avoided via dict, E3 V1 hide Section 5 conditional, E3 adminProxy GUID comparison TS-correct, no menu visibility drift, test gate 111/111 confirmed. **Recommendation**: HOLD push. Add ~10-12 LOC ApplicableType validation guard in CreateContractCommandHandler.Handle before entity instantiation. Re-run build+test. Then PROCEED push 9 commits + 1 fix commit (10th). **Smart Friend guard active — caught major security gap via cross-reference PE pattern** (lesson Cognition: independent adversarial perspective raises quality vs em main solo). **Test gap noted defer**: ApproveV2Async ~150 LOC + UPSERT 0 unit test — gotcha #48 lesson recurring risk — recommend Plan B Wrap test-after bundle covering V2 happy path advance + OR-of-N + skipToFinal F2 + terminal gen mã + V1 regression.
- **2026-05-21 (S26 Plan AG pre-commit + 5 follow-up plans AG2-AG6 em main solo self-review):** Plan AG Chunk A+B+C pre-commit verify spawn 1× ~25K with 5-category checklist + 12 adversarial deep checks (A-L) PASS 0 critical/major/minor. Commit `0bf6c7e` 2 file +346/-116 LOC mirror IDENTICAL hash `21001E90...`. Wire claim verify: 3 chunk delivered (useMemo group nested + `<details>/<summary>` 2-level + localStorage Set persist). Schema 0 mig, 0 BE, 0 entity. Security: localStorage non-sensitive (projectId GUID + normalizedGoiThau text), XSS safe React auto-escape, no new [Authorize] needed (read-only view). Code quality: npm build × 2 PASS 0 TS err, anti-fiddle 0% drift, Mirror §3.9 byte-identical 21,521 bytes. Test coverage: Phase 9 UAT exception accept. Adversarial 12/12 PASS — edge case empty tenGoiThau/projectName/localStorage corrupt/Tailwind named groups/HTML details accessibility/degenerate cases/vi locale sort/filter-then-group order/bundle size delta. **Minor noted defer:** Selected PE inside collapsed tree không auto-expand path → recommend Plan AG2 useEffect watch selectedId. Recommendation: PASS proceed push. **Subsequent Plan AG2-AG6 em main solo self-review** (5 plan UI polish iteration UAT feedback bro Tra Sol — Panel 1 widen 400px, drop tầng gói thầu 1-level, drop single-PE flat consistent, add Drafter+Department BE+FE, 3-level Project>Năm>NCC>PE, compact card 3-row). Em main verify mỗi commit: SHA256 hash 2 file IDENTICAL + npm build × 2 app + dotnet test 111/111 PASS (Plan AG4 BE+FE cross-stack — dotnet build clean + 3 projection update LIST/INBOX/APPROVED). KHÔNG re-spawn Reviewer mỗi plan (mirror S24 Plan AA pattern: ROI thấp khi UI polish ~50-100 LOC per chunk + cost spawn ~25K × 5 = ~125K vô lý vs em main self-verify build pass + bro visual confirm). **Pattern reinforced**: Reviewer spawn 1 lần cho heavy cross-stack initial Chunk A+B+C (~370 LOC + 4 sub-agent collab), em main solo cho polish iteration. Cumulative S26 6 commits `0bf6c7e..d99069a` push remote: AG (`0bf6c7e`) + AG2 (`c5429c0`) + AG3 (`fbad4a9`) + AG4 (`2bf0118`) + AG5 (`083b601`) + AG6 (`d99069a`). 0 prod regression observed, test baseline 111 preserved. Smart Friend guard still active for next session feature spawn.
- **2026-05-19 (S25 wrap — Plan AB pre-commit verify + 6 follow-up plans em main solo self-review + 1 lesson catched by CICD):** Plan AB Chunk A pre-commit verify spawn 1× ~22K with 5-category checklist + 8 adversarial deep checks PASS 0 blocker (1 minor V1 legacy fallback acceptable). Recommended PROCEED push cdfd542. **MISSED gotcha #48**: Multi-Changelog.Add() trong same SaveChangesAsync transaction → SQLite test frozen clock CreatedAt tie-break non-deterministic → Plan M existing tests `.OrderByDescending(CreatedAt).FirstAsync()` picked wrong entry → CI Run #215 FAIL. **Lesson reinforced**: UAT mode `feedback_uat_skip_verify` skip `dotnet test` per chunk risk recurring khi BE refactor > 100 LOC + signature change. Em main resumed local `dotnet test` post Plan AB Chunk A2 fix — caught by CICD test gate (no prod impact). **Em main solo self-review** Plan AC-AF (5 plans em main solo, Reviewer KHÔNG re-spawn — em main verify build+test+npm × 2 app mỗi chunk + CICD post-deploy verify thay vai pre-commit). Cumulative S25: 0 prod regression, 6 commits PASS CICD. **Pattern caught: SQLite frozen clock multi-row tie-break** — tests querying audit table cần discriminator beyond timestamp (EntityType + Summary keyword). Cross-ref future Contract V2 test setup. **Smart Friend guard still active** for future spawn — Reviewer should ADD test filter discriminator check vào Category 5 checklist post-S25.
- **2026-05-19 (S25 Plan AB Chunk A pre-push verify, spawn):** Adversarial verify commit `cdfd542` fix Changelog visibility 2 bug PE — Budget Adjust không hiện history + Trả lại Người chỉ định không log. 3 files +146/-95 LOC. **Verdict: PASS proceed push, 1 minor V1 legacy fallback acceptable.** V2 ApplyReturnModeAsync refactor Drafter early return→if/else common path + new Changelog.Add EntityType=Workflow(5) Action=Update(2) PhaseAtChange=evaluation.Phase. FE HistoryTab filter extend 3 rule. Schema 0 mig. Adversarial 8 deep check PASS. Lesson narrative archived `archive/2026-05-q1.md`.
- **2026-05-22 (S28 wrap — Layer A governance Reviewer perspective + Cat 6 add):** Reviewer perspective về S28 trajectory (em main solo, KHÔNG actual review work): t1 RAG ROI verdict marginal short-term / transform long-term → t2 em main self-authorize cross-project rule "ghi RAG mọi tương tác" WITHOUT bro consent → t3 monitoring 5 metric đề xuất → t4 bro caught mistake scope-down về SOLUTION_ERP self-discipline → t5 Layer A governance broadcast active (3-Layer distributed, em apply 4-category default + skip list + tag schema mandatory + phase + BC/module enum). **Smart Friend Cat 1 "Wire claim verify" lesson S28**: em main t2 implicit interpret "chú ý X" (bro suggestion) AS "MANDATORY X" (em policy decision) → cross-project rule self-authorize. Pattern catch retroactive: scope creep từ project-local → cross-project KHÔNG bro consent là authority boundary violation. Cần check authority boundary mỗi khi em main đề xuất "rule cross-project" hoặc "mọi tương tác mandatory". **Tag schema mandatory forward S28+**: store lesson/gotcha chunk với `[lesson, phase-<N>, <bc>]` format (phase ∈ {phase-9, phase-9plus, phase-10}, BC enum ∈ {contract, pe, budget, workflow, identity, form, infra}). **Adversarial check NEW Cat 6 — Authority boundary check**: verify em main self-authorize vs bro centralized — distinguish "bro suggested option X" (advisory) vs "bro mandated X" (directive); flag any "MANDATORY ... cross-project" sourced từ em main self-decision. 5-category checklist baseline UNCHANGED (Wire BE + Schema + Security + Code quality + Test), Cat 6 add forward. **Rule cũ ABANDONED**: "RAG ghi mọi tương tác mandatory" S28 t2 over-reach — lesson learned authority boundary: implicit consent ("chú ý" / "có thể") KHÔNG = explicit mandate ("BẮT BUỘC" / "mandatory") — verify scope rõ TRƯỚC commit policy. Smart Friend guard active S28+ cho Plan B Contract V2 wire pre-commit spawn (mandatory heavy diff > 50 LOC cross-stack).
---
## 🔄 Curate trigger
- Memory size > 25KB → archive recent entries to `archive/<period>.md`
- Duplicate entries detected → merge
- Stale > 3 months → remove
**Last curate: 2026-05-26 S32 startup drop oldest entry** — dropped 2026-05-22 S27 retrospective entry (Qdrant 404 lesson — preserved redundantly trong S29 wrap "Self-review bias" reference + already in archive 2026-05-q1.md). Reason: S32 entry added → size cross 25KB threshold (25.23KB) → maintain 10-FIFO ceiling. KEEP: S32 startup (new), S29 wrap (2 MAJOR catches), S29 Plan B pre-push detail, S26 Plan AG, S25 wrap, S25 Plan AB pre-push, S28 governance. 5-category checklist (Cat 3 Security ApplicableType + password ≥12 chars reinforced S29) + Smart Friend guard 4× cumulative + Cross-module security validation mirror pattern (NEW S29 foundation) preserved. Next curate trigger: > 25KB OR Plan B Wrap test bundle complete OR Budget V2 wire start OR Phase 9 UAT hard blocker audit spawn.