PoC|Fabbi · NEXA metrics 2026-06-13

Bộ chỉ số đánh giá hiệu quả áp dụng NEXA

Tài liệu giải thích cơ chế chấm điểm hiệu quả NEXA. Rê chuột vào keyword gạch-chân-chấm để xem định nghĩa (glossary hover).

Bộ chỉ số đánh giá hiệu quả áp dụng NEXA - Tài liệu giải thích

Người nhận: Thiên (POC Leader OPT) · Người soạn: facon (điều phối SDLC + AI adoption) · Ngày: 2026-06-13 Mục đích: giải thích đầy đủ, dễ hiểu cơ chế chấm điểm hiệu quả NEXA để trình bày lại với khách hàng (OPT). Nguyên tắc nền: mọi con số đều truy được nguồn; số chưa đo ghi rõ "chưa đo"; không bịa số.


⭐ Take-away (quan điểm chốt)

Tài liệu này là khung đo lường + nền chất lượng hiện tại, không phải báo cáo kết quả cuối. Quan điểm của chúng tôi:

  1. Đo hiệu quả AI phải theo công đoạn, không gộp một số. AI tham gia 4 nhóm công đoạn (đọc-tóm tắt source cũ · sinh tài liệu thiết kế · sinh code · sinh test); mỗi công đoạn mạnh-yếu khác nhau. Gộp 1 con số "AI đúng X%" là vừa thiếu công bằng vừa không actionable - nên đo riêng rồi mới gộp có trọng số.
  1. Số nào đo được thì đưa số thật, số nào chưa đo được thì nói thẳng - không bịa số ngược. Đây là quan điểm cốt lõi: thà "chưa đo" trung thực còn hơn một con số đẹp không bảo vệ được. 2/6 tiêu chí khách quan tâm đã có số thật (test-pass 100%, logic-coverage 87.7%); phần còn lại đang đo bằng cơ chế khách quan, có số là báo.
  1. Phân biệt rạch ròi "truy nguồn (tracing)" với "phủ logic (coverage)". Tracing→legacy 100% (mỗi class mới truy được về gốc VB cũ) là *điều kiện cần*, KHÔNG phải bằng chứng "đã cover 100% logic legacy". Coverage legacy thật phải lấy tổng logic legacy làm mẫu số (cần FARE detect đủ), chưa đo xong thì không tuyên bố 100%. Chúng tôi từ chối dùng con số dễ (tracing) thay con số khó (coverage).
  1. Chất lượng "phần đã làm" đã chứng minh được bằng bằng chứng cứng; UI còn lỗi đang sửa - báo cả hai. Cấu trúc DDD 4/4 gate PASS, parity cũ/mới 5/5 (scope hẹp, đang mở rộng), test-pass 100%. UI đo live lộ vài lỗi (leak/data-diff) - đang sửa, không giấu, không tô "100%".
  1. Công cụ đo cũng phải được kiểm định, không tin mù. Một số "lỗi" hoá ra là false-positive của chính engine đo (matcher CM30020, SpotBugs Spring-DI) - đã phát hiện + sửa engine + negative-test. Số chỉ đáng tin khi thước đo đáng tin.

Một câu cho khách: "Chúng tôi đánh giá hiệu quả AI trên bằng chứng kiểm chứng được, không trên nhận định chủ quan: các hạng mục đã hoàn thành đều đạt ngưỡng chất lượng đề ra, còn những chỉ số định lượng chưa đủ dữ liệu sẽ được công bố theo từng mốc M1-M4 - mỗi con số đều gắn phương pháp đo và nguồn truy xuất."

💡 Thuật ngữ khó có chú giải hover: trong bản HTML, các keyword khó (C1-C9, @LegacyOrigin, code-FPA, parity, audit-breadth, JaCoCo, SpotBugs, DDD/P1, golden-master...) được gạch chân chấm - rê chuột (hover) để xem định nghĩa + cách đo, trích từ "Danh mục chỉ số đầy đủ" (Phần 3) và bảng Thuật ngữ cuối tài liệu.

Bảng cầm tay: 4 màn × 5 trục (cheat-sheet trình khách)

MànTracing→legacy (C3UI live (C2)Cấu trúc DDD (C5)Parity cũ/mới (C6)Render live
CM06010✅ 100%⚠️ 81% (đa phần data-diff + leak)✅ PASS 0 P1✅ 受付状態 GREEN🟢 200
CM71060✅ 100%✅ 100%✅ PASS 0 P1✅ Region GREEN🟢 200
CM05110✅ 100%✅ 100%✅ PASS 0 P1✅ 工事連絡 GREEN🟢 200
CM30020✅ 100%⚠️ 83.3% (leak FIXME)✅ PASS 0 P1🟡 chưa có🟢 200

Đọc bảng: tracing→legacy + cấu trúc DDD + parity-mapping = xanh đều; UI live = chỗ yếu (2 màn render lỗi do data-diff/leak). 2 defect chặn boot app đã FIX. Owner + ngày cho từng ô cần CDXO điền (Phần 5).

¹ C3 = tracing (mỗi class mới truy được về gốc legacy), KHÔNG phải coverage (không phải "đã cover X% logic legacy"). Coverage legacy thật = Q1 §D (cần FARE detect 100% logic legacy). Đừng đọc C3 100% thành "phủ 100% legacy".

⭐⭐ 6 tiêu chí chất lượng (品質の基準) - trả lời chi tiết

Đây là 6 tiêu chí chất lượng - khách yêu cầu Fabbi đề xuất (Thiên đã trình khách). Khách chỉ cần: chỉ số nào · đo thế nào · hiện tại bao nhiêu · mục tiêu bao nhiêu. Bảng dưới trả lời thẳng (đo trên code 04-coding e1f3654, 2026-06-14). Số chưa đo ghi rõ "chưa đo" - không bịa, không phỏng đoán thành số.

Mục tiêu (cột Mục tiêu) = ngưỡng Fabbi ĐỀ XUẤT theo yêu cầu khách (khách asks Fabbi đề xuất tiêu chí 品質基準), chưa phải ngưỡng khách áp đặt - cần khách DUYỆT để thành ngưỡng nghiệm thu chính thức. Vì vậy 3 ô "chưa đo" (Q3/Q5 + Q4-Sonar) = rủi ro trượt nếu không lấp trước nghiệm thu - phải có mốc ngày.

#Tiêu chí kháchĐo thế nào (công cụ)Hiện tạiMục tiêu (Fabbi đề xuất)Đạt?
Q1Tỷ lệ ánh xạ logic cũ→mới (ロジックマッピング率)Mẫu số ĐÚNG = tổng logic legacy (FARE detect); @LegacyOrigin chỉ là tracing-helper, KHÔNG phải coverageproxy claim-matcher 85-94% (mẫu số = claim UI-presence, chưa = 100% logic legacy); số Q1 thật chưa đo (FARE full legacy-logic extraction chưa chạy - xem Chi tiết Q1 §D)≥ 70%🟡 proxy đạt, số thật chưa đo đúng cách
Q2Độ chính xác logic code mới sinh (ロジック正確度)new-old parity test (output Java == VB cũ) + code-FPA diffparity 5/5 PASS nhưng chỉ trên 3 logic tất định (chưa đại diện toàn bộ); A3 code-FPA toàn diện chưa đo≥ 80%🟡 Tín hiệu tốt (scope hẹp), chưa kết luận
Q3Tỷ lệ giảm công sức/thời gian (工数削減率)effort-log (giờ AI+người ÷ giờ thủ công baseline)🔧 cơ chế đã lập (.nexa/kb/scope-tracker/effort-log.csv + công thức B1/B4); 0 dòng dữ liệu → cần ghi vài tuần mới có số≥ 40%⏳ Chưa có dữ liệu (cơ chế sẵn)
Q4Sonar kiểm tĩnh (Sonar静的チェック)SonarQube quality-gate🟡 Sonar đã wire config (plugin + sonar-project.properties + jacoco.xml; cần SonarQube server + token để chạy sonar:sonar). Proxy hiện có 4/4 PASS: Spotless ✅ · Checkstyle ✅ · DDD-audit ✅ · SpotBugs ✅ 0 bug (16 bug CM71060: phần exposure-dữ-liệu thật fix bằng List.copyOf/null-check; phần false-positive Spring-DI singleton + cleanup-rethrow suppress có chú thích trong excludeFilter; BUILD SUCCESS)Pass🟡 Proxy 4/4 xanh; chờ server để chạy Sonar tổng hợp
Q5Coverage unit-test logic (単体テストカバレッジ)JaCoCo line coveragelogic (domain+application) = 87.7% (domain 88.9% / app 87.1%); tổng cả app = 59.9% (thấp do infra/IO/presentation plumbing ít unit-test)≥ 80%ĐẠT trên tầng logic (tiêu chí khách = "ロジックの単体テストカバレッジ" = coverage LOGIC)
Q6Tỷ lệ Pass test case (テストケースPass率)mvn test PASS/total100% (246/246) - sau khi khôi phục app-config.yaml (380-key từ legacy Commufa.config), 5 test AppConfig trước đỏ nay xanh hết100%ĐẠT

Tóm tắt thẳng cho khách (cập nhật sau vòng fix): 6 tiêu chí (ngưỡng Fabbi đề xuất, chờ khách duyệt) → 2 đạt rõ số thật (Q5 logic-coverage 87.7%, Q6 test-pass 100%) · 1 proxy đạt nhưng mẫu số chưa đúng (Q1: claim-matcher 85-94%, cần FARE detect 100% logic legacy mới ra số thật) · 1 gần đạt chờ server (Q4: SpotBugs 0, Sonar wired) · 1 tín-hiệu scope hẹp (Q2 parity 5/5) · 1 chưa có dữ liệu (Q3 effort-log). Việc còn lại: (1) ghi effort-log vài tuần → Q3; (2) cấp SonarQube server+token → chạy Q4 tổng hợp; (3) git-tag ai-gen/tuned + mở rộng parity → Q2 toàn diện. 5/6 tiêu chí đã có số thật / proxy xanh; chỉ Q3 cần thời gian tích luỹ.

🔬 Chi tiết Q1 - "ロジックマッピング率": @LegacyOrigin là gì, vì sao KHÔNG dùng làm mẫu số, và cách đo ĐÚNG

A. @LegacyOrigin - sample code thật (đây là TRACING helper, KHÔNG phải coverage metric)

Annotation Java đánh dấu mỗi class/function nghiệp vụ mới trỏ về gốc legacy (file/dòng VB + stored-proc). Retention = CLASS (giữ trong bytecode). Ví dụ thật trong repo:

// 04-coding/src/main/java/com/company/opt/optweb/cm06movirus/application/Cm06010UnlockResult.java:10
@LegacyOrigin(module = "CM06MoVirus", screen = "CM06010", source = "FrmCM06010.vb:L62")
public record Cm06010UnlockResult(String errorMessage) {

// 04-coding/src/main/java/com/company/opt/optweb/cm70maintenance/infrastructure/procedure/Cm71060ProcedureGateway.java:28
@LegacyOrigin(
    module = "CM70Maintenance",
    screen = "CM71060",
    source = "FrmCM71060.vb:L936",
    procedure = "CM71060_INS1,CM71060_INS2,CM71060_UPD")
public class Cm71060ProcedureGateway implements Cm71060ProcedurePort {

Định nghĩa annotation: 04-coding/src/main/java/com/company/opt/optweb/shared/annotation/LegacyOrigin.java. Enforce: ArchUnit LegacyOriginMappingTest + 04-coding/coding-rules/legacy-map-check.py (đối chiếu .nexa/legacy-map.yaml).

Đính chính phạm vi (quan trọng): KHÔNG phải "MỌI class". PoC này không có chức năng mới → quy tắc đúng = mọi class/function NGHIỆP VỤ phải có @LegacyOrigin; class hạ tầng/framework (config, adapter Spring thuần) khác biệt do khác framework, không bắt buộc. Vì vậy @LegacyOrigin = công cụ TRACING ("mảnh code mới này từ đâu ra"), KHÔNG phải thước đo coverage ("legacy đã cover bao nhiêu %").

B. Vì sao @LegacyOrigin (và "mapping 100%") KHÔNG đo được coverage - mẫu số sai

"100% class mới có @LegacyOrigin" = mẫu số là CODE MỚI, không phải LOGIC LEGACY. Hai phản ví dụ phơi bày lỗi:

Tình huốngChỉ số @LegacyOrigin/annotation báoThực tế coverage legacy
Legacy 100 logic · new chỉ làm 20 logic · cả 20 đều có annotation20/20 = 100% ✅ (ảo)20/100 = 20%
Legacy 100 logic · new 200 logic · đã cover đủ 100 legacy100/200 = 50% (sai hướng)100/100 = 100%

→ Annotation-based / new-denominator không bao giờ trả lời đúng "legacy đã được cover bao nhiêu". Mẫu số ĐÚNG phải là TỔNG logic legacy (đếm độc lập), tử số là logic legacy đã được cover.

C. screen-audit claim-coverage (85-94%) hiện có = proxy MỘT PHẦN, chưa phải số thật

Engine screen-audit-check.py đếm legacy_auditable (claim = control/table/message/rule presence) và aligned. Mẫu số ĐÃ là legacy (aligned/legacy_auditable, đúng hướng) - tốt hơn annotation. NHƯNG:

Mànclaim đếm đượcalignedcoverage% (proxy)
CM06010292896.6%
CM05110716895.8%
CM71060938793.5%
CM3002018376 raw → 90.6 corrected42.5% raw ⚠️ matcher-lỗi

Report/list: findings[] trong plans/reports/screen-audit-CM*.json. Kết luận trung thực: 85-94% = "% claim-matcher-bóc-được đã cover", KHÔNG phải "% toàn bộ logic legacy đã cover". Chưa được phép báo là Q1 thật.

D. Cách đo Q1 ĐÚNG (đề xuất - cần build, đây mới là số defensible)

Đo coverage legacy thật cần 4 bước, mẫu số = 100% logic legacy detect độc lập:

  1. Detect 100% legacy logic bằng FARE (thuật toán + semantic, không phụ thuộc người gắn tay): bóc toàn bộ đơn vị logic nghiệp vụ từ legacy VB + stored-proc → danh mục L = {l1..lN} (mỗi unit = 1 nhánh quyết định / rule / IO-transaction / proc). Đây là mẫu số thật N.
  2. Phân loại cách cover từng lᵢ: (a) cover bằng library/helper Java (vd validation, format chuẩn) · (b) cover bằng function/class mới (có @LegacyOrigin trỏ về lᵢ) · (c) chưa cover. Ví dụ: 100 legacy → 10 cover bằng library, 90 cover bằng function/class.
  3. Build map chi tiết legacy_unit → new_artifact (dùng @LegacyOrigin làm liên kết tracing + FARE semantic match để xác nhận đúng logic, không chỉ đúng tên).
  4. Coverage = |legacy unit đã cover (a+b)| / |N| + kiểm parity (Q2/C6) trên từng unit để chắc "cover" = "đúng hành vi", không chỉ "có code".

→ Chỉ khi bước 1 detect đủ N và bước 4 xác nhận đủ cover + đúng hành vi thì mới được nói 100% thật. Hiện trạng: chưa có N (FARE chưa chạy full legacy-logic extraction cho 4 màn) → Q1 thật CHƯA đo được; 85-94% chỉ là proxy claim-matcher. Đây là việc cần build (FARE semantic + bảng map) trước khi báo Q1 là con số nghiệm thu.

Bắc cầu với 4 nhóm A/B/C/D bên dưới: Q1↔C3+C4 · Q2↔C6+A3 · Q3↔B1 · Q4↔C5(DDD)+SpotBugs · Q5↔(coverage, nhóm C mới) · Q6↔(test-pass, nhóm C mới). 4 nhóm là khung nội bộ đầy đủ; 6 tiêu chí là tập con khách quan tâm nhất - bảng này map 1-1 để khách không phải đọc cả 4 nhóm.


Phần 0 - Tài liệu này trả lời câu hỏi gì

Khách hàng OPT hỏi đúng 2 câu (Goal 1 và Goal 2):

  1. AI tham gia vào công đoạn nào, và giảm được bao nhiêu % công sức/thời gian?
  2. Dùng AI vấp phải vấn đề gì, và kế hoạch cải thiện ra sao?

Bối cảnh niềm tin của khách hàng (nguồn: báo cáo họp khách của Thiên):

Tài liệu này định nghĩa cơ chế đo để trả lời 2 câu trên bằng con số đo được, có cách đo rõ ràng, tái lập được, thay vì nói cảm tính.

Khung đo, chưa phải kết quả: ở thời điểm này nhóm C (chất lượng) đã có số thật; nhóm A (độ chính xác %) và B (tiết kiệm %) đang trong quá trình đo. Đừng kỳ vọng con số % cuối cùng ngay hôm nay - kỳ vọng đúng là "cơ chế đo đã chặt chẽ, số sẽ đổ đầy theo mốc M1-M4".


Phần 1 - Vì sao thiết kế bộ chỉ số như thế này (logic nền)

1.1 Vì sao không dùng 1 con số "AI đúng X%"

"Độ chính xác của AI" khác nhau hẳn theo công đoạn:

Gộp tất cả vào 1 con số vừa không công bằng (kéo công đoạn yếu lên nhờ công đoạn mạnh), vừa không hành động được (không biết phải cải thiện chỗ nào). Nên ta đo theo từng công đoạn trước (Nhóm A), rồi mới gộp có trọng số thành 1 headline KPI để nói chuyện với lãnh đạo khách hàng.

1.2 Thước đo trung tâm: First-Pass Acceptance (FPA)

FPA = "% sản phẩm AI sinh ra được giữ lại sau khi người review".

Chọn FPA vì nó đúng ngôn ngữ khách đang dùng ("AI gen đúng cỡ 40%, còn lại người sửa"), và đo được khách quan bằng diff/so khớp - không phải tự chấm cảm tính. FPA cao = người sửa ít = AI đóng góp thực nhiều.

1.3 Bốn nhóm chỉ số (khung nội bộ) và cầu nối tới 6 tiêu chí khách

4 nhóm là khung đo nội bộ ĐẦY ĐỦ; 6 tiêu chí khách (bảng ⭐⭐ ở trên) là tập con khách quan tâm nhất. Cột cuối map sang tiêu chí khách để khách không phải đọc cả khung.

NhómTênTrả lời choMap tới tiêu chí khách
AĐộ chính xác AI theo công đoạn"AI đúng bao nhiêu %"Q2 (logic正確度)
BGiảm công sức / thời gian / chi phíGoal 1 (% tiết kiệm + quy tiền)Q3 (工数削減)
CChất lượng đầu ra đáng tinChứng minh "đúng" không phải "rác"Q1 (mapping率) · Q4 (Sonar) · Q5 (coverage) · Q6 (test Pass)
DVấn đề & cải thiệnGoal 2 (issue + giải pháp + kế hoạch)(xuyên suốt)

Cách đọc cho khách: muốn biết "AI làm đúng tới đâu" xem Q1+Q2; "tiết kiệm bao nhiêu" xem Q3; "chất lượng có tin được không" xem Q4+Q5+Q6. Mỗi tiêu chí đều có: cách đo + số hiện tại + mục tiêu (bảng ⭐⭐).

1.4 Thang chuẩn tham chiếu

Mượn từ benchmark nội bộ MSR-002 (đã dùng thật ở dự án trước; tài liệu gốc QUALITY_MANAGEMENT_GUIDE / AIDP_Enhanced_Review_Process không nằm trong repo PoC này - là tham chiếu second-hand, không phải chuẩn ngành ngoài):

Min ≥ 60% · Target ≥ 70% · Good ≥ 80% · Excellent ≥ 90%

Đây là lý do các ngưỡng target trong nhóm A bám quanh 60-70%.


Phần 2 - Headline KPI (con số nói với lãnh đạo khách hàng)

Chỉ sốĐịnh nghĩaBaseline (khách tin)Mục tiêu POCStretch (khách chưa tin)Hiện tại
AI-FPA tổng hợpTrung bình có trọng số FPA của 3 công đoạn sản xuất chính (Docs A2, Code A3, Test A4); trọng số theo khối lượng artifact40%≥ 60%≥ 70%chưa tính được (xem dưới)

Công thức (diễn giải bằng lời cho slide khách): AI-FPA tổng = trung bình có trọng số của 3 tỷ lệ FPA (tài liệu, code, test); công đoạn nào khối lượng lớn thì cân nặng hơn.

Dạng ký hiệu (để phụ lục/nội bộ, đừng đưa lên slide khách):

AI-FPA = Σ (FPAᵢ × Wᵢ)   với i ∈ {A2 Docs, A3 Code, A4 Test};  Σ Wᵢ = 1
Wᵢ = tỷ trọng khối lượng của công đoạn i

Lưu ý tái lập (quan trọng): headline hiện chưa tính được vì 2 lý do, không chỉ vì thiếu dữ liệu:

  1. Thiếu dữ liệu: A2/A3/A4 đều chưa có số (xem nhóm A).
  2. Trọng số Wᵢ chưa chốt cơ sở: tính theo "số artifact" và theo "effort-share" cho ra 2 kết quả khác nhau (4 màn code vs hàng trăm mục tài liệu sẽ làm lệch hẳn). Nên kể cả khi có FPA, headline vẫn chưa tái lập được cho tới khi anh Dzũng (CTO) chốt cơ sở trọng số. Đây là việc phải chốt trước khi báo headline.

Guard chống ảo số (bắt buộc - nên kể với khách như một điểm cộng tin cậy): Headline chỉ được công bố khi A3 (Code FPA) ≥ mức min 50%.

Cách báo cáo: luôn kèm bảng per-công-đoạn, không bao giờ nói trần 1 con số (tránh bị hỏi vặn "60% của cái gì").


Phần 3 - Danh mục chỉ số đầy đủ (định nghĩa, công thức, cách đo, hiện tại)

Ký hiệu trạng thái: ✅ đã đo (có evidence) · ⏳ chưa đo (cơ chế sẵn sàng) · ⛔ blocked (thiếu dữ liệu đầu vào).

Bảng thuật ngữ nhanh (gloss cho người không chuyên):

Nhóm A - Độ chính xác AI theo công đoạn

IDChỉ sốĐơn vịCông thứcNguồn dữ liệuTần suất đoMinTargetHiện tại
A1KB extraction accuracy (SCAN)%đúng / sample (sample ≥ 50 claim, thiếu-ngữ-cảnh = 0.5)Sample FARE KB đối chiếu tay với legacy source (HITL)Sau mỗi lần nexa scan đáng kể8090⏳ chưa đo
A2Docs gen FPA (BD/DD)%min(Completeness%, Accuracy%) của bản v0 (AI) so với bản final (sau review) - phương pháp so khớp MSR-002, lấy min để bảo thủ. Đơn vị đếm = mục (item) trong section, chốt với CTOEngine so khớp item; giữ bản v0 tại {artifact}/.v0/Mỗi tài liệu được APPROVED6070⏳ chưa đo
A3Code gen FPA%1 − (LoC người đổi semantic / LoC AI sinh)git diff --numstat ai-gen/<CM>..tuned/<CM> trên path screenMỗi screen xong tuning5060⏳ chưa có số (chưa bật giao thức git tag)
A4Test-case gen FPA%case dùng được không sửa / tổng case; phân bố ISTQB là cờ PASS/FAIL riêng, không cộng vào scalarQA review từng caseSau mỗi batch sinh test6070⏳ skill sẵn, chưa chạy

A3 là chỉ số quan trọng nhất vì đây đúng chỗ khách nghi ngờ (40%). Điều kiện đo: từ giờ phải tag commit ai-gen/<CM> (ngay sau khi AI sinh, trước khi người sửa) và tuned/<CM> (sau review duyệt). Màn đã làm trước khi có tag không truy hồi ngược được -> ghi pending, không ước lượng ngược.

Trung thực về tính khách quan của A3: git diff đếm *mọi* dòng đổi, không tự tách được "đổi logic" với "đổi hình thức". Phần "chỉ tính dòng đổi semantic" hiện vẫn cần người gắn cờ trong PR -> chưa hoàn toàn tự động. Vì vậy A3 chỉ thực sự tái lập được khi: (a) chốt định nghĩa "semantic" với CTO, và (b) cơ giới hoá bằng script (vd chạy formatter chuẩn hoá trước rồi mới diff). Cho tới lúc đó, đừng quảng cáo A3 là "hoàn toàn khách quan" - nói đúng: "đo bằng diff, có quy tắc loại trừ hình thức do reviewer áp dụng nhất quán". (Có thể báo song song một số phụ "churn-FPA thô" = đếm mọi dòng, hoàn toàn tự động, để khách thấy biên độ.)

Nhóm B - Giảm công sức / thời gian / chi phí (Goal 1)

IDChỉ sốĐơn vịCông thứcNguồn dữ liệuTần suất đoTargetHiện tại
B1Effort reduction theo phase%1 − Σ(giờ AI + giờ người) / Σ(giờ baseline thủ công) per phaseeffort-log.csv (append-only) + baseline ước lượng do KMD/chuẩn JP-SI cung cấpGhi hằng ngày, tổng hợp mỗi milestone≥ 40 overall, ≥ 50 BD/DD⛔ chưa có effort-log -> chưa có mẫu số
B2Review time per docgiờgiờ làm việc trôi qua để review 1 tài liệu (AI pre-review 2 lớp)timestamp mở/đóng review trên Backlog ticketMỗi vòng review16h -> ≤ 4h⏳ chưa đo
B3Throughputscreen / person-weekscreen hoàn tất / person-weekscope-tracker ledger + effort-logMỗi milestonereport-only (PoC 4 màn quá nhỏ để chốt target cứng)⏳ đo để report
B4Chi phí tiết kiệm (quy tiền)tiền (¥)hours_saved = B1% × baseline_hours_per_screen; cost_saved = hours_saved × hourly_rate; ngoại suy dự án thật: cost_saved_per_screen × 256 mànB1 + đơn giá GIỜ công (hourly_rate) chốt với CTO; baseline định nghĩa per-screen trước khi ×256Mỗi milestone + ước lượng dự án thật(mục tiêu kinh doanh, chốt với CTO)⛔ [Estimation] - chưa tính được vì B1 blocked + hourly_rate chưa chốt

Cảnh báo trung thực: B1 hiện không trả lời được vì chưa ghi effort-log. Đây là việc số 1 phải làm ngay: phát template log cho team. Không có mẫu số thì cuối POC chỉ nói được cảm tính - đúng cái khách không muốn nghe.

B4 - câu mà CEO/CFO hỏi đầu tiên: "tiết kiệm bao nhiêu *tiền*?". Hiện chưa có con số ¥ vì phụ thuộc B1 (chưa có) và đơn giá ngày công (chưa chốt). Công thức đã sẵn; khi B1 có số + CTO chốt hourly_rate -> ra ngay con số ¥ tiết kiệm per-screen cho 4 màn PoC và ngoại suy cho 256 màn dự án thật. Không đưa con số ¥ nào ra trước khi có 2 đầu vào này - đưa sớm = bịa. (Lưu ý đơn vị: dùng đơn giá GIỜ; nếu baseline tính bằng ngày-công thì quy về giờ trước khi nhân, tránh sai chiều đơn vị.)

Nhóm C - Chất lượng đầu ra đáng tin (chống "60% rác")

IDChỉ sốĐơn vịCông thứcNguồn dữ liệu (engine)Tần suấtTargetHiện tại
C1Quality-gate pass%gate G1-G11 PASS trước khi qua phasenexa gate run logMỗi chuyển phase100⏳ đang vận hành (chưa chốt số tổng hợp)
C2UI element coverage vs prototype%item PASS / item audit (mức màn: đủ thành phần, không thiếu/thừa)prototype-ui-audit.py (app LIVE :8080)Mỗi milestone≥ 95🟡 đo lại LIVE (e1f3654, sau khôi phục config): 2/4 PASS - CM71060 100% · CM05110 100% (PASS) · CM06010 81% · CM30020 83.3% (FAIL: leak FIXME/spList_ + prototype-data-diff). Số cũ "100% (4/4)" là json STALE - xem ghi chú
C3Legacy mapping integrity%screen pass ArchUnit @LegacyOrigin / tổng./mvnw test -Dtest=LegacyOriginMappingTest (surefire)Mỗi build100100% (4/4 màn)
C4Screen audit-breadth (logic)%coverage_pct engine = % claim-type trích/check được (audit rộng tới đâu), denominator = "extractable claim types, NOT full behavior surface". KHÔNG phải "% claim có mặt trong docs mới"screen-audit-check.py field coverage_pctMỗi screen audit≥ 90✅ đo lại 4/4 màn (e1f3654): CM06010 96.6% · CM71060 93.5% · CM05110 95.8% · CM30020 90.6% (xem caveat CM30020 dưới)
C5Code structure (DDD)số findingsố finding P1 mở tại thời điểm bàn giaocode-audit-check.pyMỗi milestone0 P1 open0 gateable P1, 4/4 màn gate PASS (e1f3654). CM05110 2 P1 cũ đã fix; 2 P1 CM71060 (S13/S14) xác định là false-positive của engine (adapter hexagonal ở thư mục riêng + shared cross-cutting port), đã tinh chỉnh engine + neg-test chứng minh vẫn bắt lỗi thật, code không đổi
C6新旧比較 UT (parity cũ/mới)%test so sánh (output VB == output Java, cùng input) PASS / tổngcomparison UT suite (./mvnw test -Dtest=*ComparisonTest)Mỗi milestone≥ 95🟡 5/5 PASS (100%) trên enum/mapping nghiệp vụ tất định, 3 màn (Region CM71060 + 受付状態 CM06010 + 工事連絡 CM05110; golden từ legacy source verbatim). Caveat: chưa phủ SQL/proc/validation parity - mở rộng dần
C7Unit-test coverage (Q5 khách)%line coverage = covered/(covered+missed)JaCoCo (jacoco-maven-plugin đã thêm → target/site/jacoco/jacoco.csv)Mỗi milestone≥ 80logic-ring 87.7% (domain 88.9% / app 87.1%); ⚠️ tổng-app 59.9% (infra/IO/presentation plumbing mỏng test - cần integration test). 117 class, đo thật e1f3654
C8Test-case Pass rate (Q6 khách)%(run − fail − err) / run./mvnw test surefireMỗi milestone100100% (246/246; sau khôi phục app-config.yaml 380-key, 5 test AppConfig đỏ trước nay xanh)
C9SpotBugs / static-bug (proxy Q4 Sonar)countsố bug spotbugs:check (threshold Low)./mvnw spotbugs:checkMỗi build00 bug (16 bug CM71060 → 0: fix thật mutable-data-exposure bằng List.copyOf + 1 null-check; suppress false-positive Spring-DI constructor-injection + cleanup-rethrow có chú thích lý do trong excludeFilter - không phải nới bừa). Spotless ✅ Checkstyle ✅ DDD ✅. Sonar đã wire config (cần server để chạy)

C2 - đo lại LIVE lật ngược số stale (quan trọng, trung thực): số cũ "100% (4/4 PASS)" lấy từ json đã commit = STALE. Khởi động app thật (Docker+Oracle FREEPDB1+Flyway) rồi chạy prototype-ui-audit.py ra 0/4 PASS. Phân loại:

C6 quan trọng đặc biệt với migration: cả dự án là *chuyển màn cũ (VB.NET) sang mới (Java) giữ nguyên hành vi*. Vì vậy "output mới == output cũ với cùng input" (C6, gọi là new-old parity / defect-escape proxy) là bằng chứng nghiệm thu cốt lõi, nên kể ngang hàng headline. Harness chạy + 5/5 PASS (100%) trên 3 màn (RegionComparisonTest CM71060 + ReceptionStatusComparisonTest CM06010 + ContactStatusComparisonTest CM05110; golden lấy verbatim từ legacy source basCM06_Common.vb:L60-66, FrmCM05110.vb:L583, FrmCM71060.vb:L821; engine GoldenMasterSupport định nghĩa ≡ qua normalizer). Lệnh suite: ./mvnw test -Dtest='*ComparisonTest'. Caveat trung thực: 5/5 mới phủ enum/mapping nghiệp vụ TẤT ĐỊNH; chưa phủ SQL body / stored-proc / validation parity. Việc còn lại = mở rộng sang các loại đó rồi tính C6 = ΣPASS/Σtotal. Đây là số nghiệm thu khách chờ nhất.

C5 - hiện trạng đo lại trên code mới e1f3654 (4/4 màn đã audit, tất cả gate PASS): CM06010/CM71060/CM05110/CM30020 đều 0 gateable P1. Diễn biến: (a) CM05110 2 P1 cũ (S12/S15 persistence leak) đã FIX về 0; (b) CM71060 từng báo 2 P1 (S13 "port thiếu infra-impl", S14 "controller chạm persistence") - điều tra ground-truth cho thấy là false-positive của audit engine: S13 chỉ quét ring infrastructure/persistence nên không thấy adapter hexagonal đặt ở excel/,file/,procedure/ (cả 4 port ĐỀU có adapter implements); S14 cờ field AppErrorLogPort (port cross-cutting import từ shared., whitelist đúng ý nhưng regex soi nhầm dòng). Đã tinh chỉnh engine cho chính xác (S13 quét mọi ring infra; S14 whitelist port import từ shared.) + negative-test chứng minh engine vẫn FAIL khi có leak thật / thiếu impl thật; code ứng dụng KHÔNG đổi (git clean). Cùng class với artifact 57.1% CM30020: lỗi đo, không phải lỗi code.

Lưu ý số CM30020 - xử lý dứt điểm [NỘI BỘ - chuẩn bị trước, không đọc nguyên văn cho khách]: cùng màn CM30020 có nhiều con số vì đo các thứ khác nhau. Quan trọng (đã verify từ file nguồn LIVE 2026-06-14): file plans/reports/screen-audit-cm30020/screen-audit-CM30020.json hiện chứa ĐỒNG THỜI coverage_pct: 90.6fidelity_pct: 57.1 - tức 57.1 KHÔNG phải "số cũ đã sửa", nó là fidelity logic HIỆN HÀNH của cùng lần chạy sinh ra 90.6. Nếu CTO/khách chạy lại tool hôm nay sẽ thấy cả 2 cạnh nhau.

Con sốĐo cái gìTrạng thái
90.6%audit-breadth: % claim-type engine trích/check được (denominator = "extractable claim types, NOT full behavior surface")LIVE; KHÔNG phải "% có mặt trong doc mới"
42.5% (76/179)presence thô đúng định nghĩa C4: aligned/auditableLIVE; con số "có mặt trong doc mới" thật theo công thức
57.1%fidelity logic hiện hành, bị ~102-105 FAIL "missing-from-new-doc" kéo xuốngLIVE; phần lớn FAIL là artifact matcher (chỉ đọc phạm vi BD, claim thật nằm trong DD shell)
98.6% (70/71)visual-fidelity bề mặt UI, capture 1 viewport (coverage 70%)LIVE; metric riêng, đừng trộn với logic

Kịch bản đính chính ĐÚNG (không nói "đã sửa, 57.1 biến mất" - file sống phản bác ngay): với khách kể bằng lời business: *"Công cụ đếm logic hiện đang đếm sót vì chỉ đối chiếu một phần tài liệu (BD) trong khi nội dung thật nằm ở tài liệu chi tiết (DD) - nên báo nhiều mục 'thiếu' không có thật. Chúng tôi đang sửa công cụ đếm; TRƯỚC khi sửa xong, KHÔNG trích cả 90.6% lẫn 57.1% như con số chất lượng cuối."* Quy tắc trình bày: với màn này, chưa trích số logic nào làm chất lượng cuối cho tới khi matcher được fix + chạy lại. Số dùng được hiện tại cho CM30020 = visual 98.6% (kèm caveat coverage 70%); C2 live = 83.3% element-coverage (có leak FIXME phải fix, không phải 100%). [SoT: cm30020-split-screen-audit-artifact]

Nhóm D - Vấn đề & cải thiện (Goal 2)

IDChỉ sốĐơn vịCông thứcNguồn dữ liệuTần suấtTargetHiện tại
D1Issue register đầy đủ%issue AI có root-cause + solution ghi nhận / tổng issueBacklog ticket (field bắt buộc)Liên tục100⏳ vận hành theo Backlog rules
D2First-time approval rate%artifact duyệt ngay vòng review đầu / tổngreview log (Backlog)Mỗi milestone40% -> ≥ 70%⏳ chưa đo (chỉ báo dẫn hướng, đổ đầy M1-M4)
D3Tuning iterationssố vòngtrung bình số vòng review tới khi duyệtreview log (Backlog)Mỗi milestone≤ 3 vòng⏳ chưa đo
D4Improvement plan coverage%issue được nhóm thành bài học + kế hoạch cho dự án thật / tổngbáo cáo cuối POCCuối POC100⏳ chưa tới kỳ

Nhóm D (mức độ chấp nhận/áp dụng AI) hiện toàn bộ là chỉ số dẫn hướng (leading indicator), sẽ đổ đầy theo M1-M4. Với PoC, đây là trạng thái bình thường - nói rõ với khách thay vì để trống gây hiểu lầm.


Phần 3b - Đo tương đương Legacy ↔ New một cách khoa học (nền của C3/C4/C6)

DORA/SPACE đo tốc độ + năng suất, KHÔNG đo "bản mới có làm đúng như bản cũ không". Đo tương đương legacy↔new là họ chuẩn riêng từ kỹ thuật kiểm thử/refactoring. C3/C4/C6 chính là họ này. Đây là phần product-driven, countable, verifiable.

Nguyên lý: "mapping legacy↔new" = 3 trục VUÔNG GÓC, không phải 1 số

Gộp 3 trục thành 1 số = lỗi đã cắn ta ở CM30020. Tách rõ:

TrụcCâu hỏiĐơn vị đếmCông thứcQuan hệ tương đương ≡Metric dự án
1. Mapping completeness (tĩnh)"có bỏ sót mảnh nào của hệ cũ?"anchor legacy (màn/control/field/SQL/rule)mapped / tổng anchor legacytồn tại link truy vết (@LegacyOrigin)C3 (155 marker, 100% file màn)
2. Behavioral equivalence (động)"new chạy ra kết quả y old?"case = (input, output-old chụp lại)parity = {x: New(x)≡Old(x)} / tổng xπ (output cần so) + ≡ (khớp/chuẩn-hoá/dung-sai ε) định nghĩa trướcC6 (harness GREEN 1 case, đang mở rộng)
3. Behavioral coverage"test parity chạm bao nhiêu % hành vi?"use case / transaction / nhánhexercised / tổng phần tử hành vi(đo bằng coverage trên legacy lúc capture)chưa có - cần thêm

Chuẩn ngành đặt tên cho Trục 2 (cái C6 đang gọi)

ChuẩnNguồn≡ định nghĩa quaHợp dùng cho
Characterization testFeathers 2004giá trị old đã chụp (golden)lưới an toàn per-màn khi spec cũ mất
Differential testingMcKeeman 1998old==new (không cần biết "đúng")fuzz/traffic, divergence→0 - mạnh nhất cho migration
Golden Master / ApprovalFalconormalizer + comparatoroutput lớn (màn/report cũ↔mới)
Parallel Run + ReconciliationFowler (legacy displacement)comparator nghiệp vụ, traffic thậtbằng chứng mạnh nhất - roadmap Phase 2
ISO/IEC 25010 Functional SuitabilityISOkhớp trong dung sai εkhung số hiệu quốc tế: Completeness% + Correctness%
Bidirectional TraceabilityCMMI REQMtồn tại ánh xạ 2 chiềuC3 đã có forward; thêm backward bắt code thừa

Cách báo cáo đúng (không 1 số trần)

"Mapping completeness = a% · Parity rate = b% trên Behavior coverage = c%, khớp tuyệt đối modulo timestamp/auto-ID."

Điểm phải nói thẳng với khách: với UI migration (VB WinForms → Java web), KHÔNG có "giống hệt từng byte/pixel" - mọi chuẩn nghiêm túc định nghĩa ≡ qua normalizer/dung-sai = "tương đương hành vi nghiệp vụ", không phải equality thô. ≡ phải reflexive + symmetric + transitive.

Cụ thể cho dự án (VB.NET Shift-JIS → Java)

Không chạy 2 hệ chung tiến trình → dùng golden-master đã chụp: mỗi màn định nghĩa input vector (EP/BVA trên field) → chụp output legacy làm golden (từ DB fixture cũ / capture tay / spec làm oracle) → viết *ComparisonTest assert New(x)==golden(x). Đó chính là suite C6. ≡ theo loại output: tập dòng DB (set-equal bỏ auto-ID/timestamp), message validate (khớp catalog legacy), giá trị tính (tuyệt đối hoặc ε). Đây là chỉ số migration-correctness quan trọng nhất đang thiếu - ưu tiên dựng sớm.


Phần 4 - Hiện trạng tổng hợp (ý nghĩa con số hiện tại) + câu trả lời phòng thủ

Cái đã đo được và đáng tin (nhóm C - chất lượng):

Cái chưa đo được và lý do (nhóm A, B, D - trung thực với khách):

Câu trả lời sẵn-để-đọc cho 2 câu khách chắc chắn hỏi

Q: "Sao nhiều chỉ số 'chưa đo' thế? NEXA không chạy được à?"

"Đo được hết, nhưng chúng tôi từ chối điền số ngược/cảm tính. Mỗi con số phải sinh từ log/diff/engine để khách kiểm chứng lại được. Biển 'chưa đo' là kỷ luật trung thực: số nào chưa đủ điều kiện đo thì nói thẳng chưa, không tô vẽ. Cơ chế đo đã dựng xong, số đổ đầy theo mốc M1-M4."

Q: "Chất lượng với độ chính xác khác nhau thế nào - đo cái gì?" (câu chí mạng)

Phân biệt rõ 2 thứ khác nhau:

Hai cái độc lập: AI có thể tự làm đúng 60% (FPA), 40% còn lại người chỉnh, và *sau chỉnh* thì đạt chuẩn chất lượng. Không mâu thuẫn. Lưu ý: chúng tôi KHÔNG tô chất lượng 100% trần - ví dụ UI đo live lộ vài lỗi đang fix, báo sòng phẳng.

Analogy thợ may (kể cho khách): "Vải nào đã may xong và kiểm thì đường kim mũi chỉ đạt chuẩn - đó là *chất lượng* (nhóm C; mapping legacy đã đạt, UI đang soi nốt vài lỗi). Còn 'máy tự may được bao nhiêu % cái áo trước khi thợ chỉnh tay' - đó là *FPA* (nhóm A). Cái thứ hai chúng tôi đang đếm bằng thước, chưa đếm xong nên không nói bừa." (Có analogy này, nhãn 'chưa đo' biến từ điểm yếu thành bằng chứng trung thực.)

Q: "100% chỉ trên 4 màn, có dám ngoại suy ra 256 màn không?"

"100% là trên scope PoC 4 màn - tín hiệu sớm tốt, không ngoại suy thành cam kết cho 256 màn. PoC để chứng minh cơ chế chạy đúng; con số quy mô lớn cần Phase 2."

Q: "2 lỗi P1 chưa fix mà vẫn báo chất lượng cao?"

"2 P1 đó nằm ở 1 màn đã audit cấu trúc; gate đang để FAIL đúng theo thiết kế (không cho qua khi còn P1). Đã có kế hoạch fix trước bàn giao - đây là bằng chứng quy trình chất lượng *hoạt động*, không phải lỗi bị bỏ qua."

Câu chuyện Goal 2 - kể bằng lời (đây là câu khách DỄ hài lòng nhất, đừng để trống dưới dạng bảng D⏳)

Khách hỏi Goal 2 = "dùng AI vấp gì, định sửa sao". Đừng trả lời bằng bảng chỉ số D1-D4 "chưa đo" - kể 5 vấn đề THỰC đã gặp + cách xử lý:

#Vấn đề thực đã gặp (PoC)Cách xử lý / bài học cho dự án thật
1Sinh code UI còn yếu, lệch nhiều (Thiên báo định tính)Tuning prompt/context + mở rộng golden sample; đo bằng A3 để biết tiến bộ. Đây là KPI trọng tâm tuning.
2Công cụ đo logic (matcher) đếm sót - báo 57.1% fidelity sai vì chỉ đọc phạm vi BD trong khi nội dung ở DDĐang fix matcher đọc cả DD; bài học: engine đo phải kiểm định trước khi tin số.
3Lỗi cấu trúc + độ chính xác công cụ đo - CM05110 từng 2 P1 (đã fix), CM71060 báo 2 P1 hoá ra false-positive engineCM05110 fix sạch (2→0); CM71060 điều tra ground-truth = lỗi đo (engine quét thiếu ring infra + whitelist soi nhầm dòng), đã sửa engine + neg-test chứng minh vẫn bắt lỗi thật, code không đổi. Bài học: engine đo phải kiểm định trước khi tin số (giống vụ 57.1%).
4Chưa có effort-log -> chưa đo được %tiết kiệmPhát template log ngay; bài học: phải đo từ ngày đầu, không dồn cuối.
5FarPoint Grid (thư viện thương mại) không có bản Java 1:1Thay bằng HTML table / quyết định license ở Phase 2; bài học: rà thư viện thương mại sớm.
6HEAD e1f3654 không tự boot được (phát hiện khi khởi động đo C2): Flyway 2 file trùng version V0023; file test Cm06010MovirusControllerTest.java byte non-UTF8ĐÃ FIX + verified: renumber cm05110 seed V0023→V0026 (giữ cm71060 V0023 vì V0024/25 phụ thuộc); khôi phục file test từ blob sạch f190ecf (UTF-8, JP nguyên) -> ./mvnw test-compile BUILD SUCCESS. Bài học: cần CI smoke-boot + .gitattributes UTF-8 chặn pull đỏ.
7Leak token máy + placeholder trong UI (đo C2 live): spList_ @cm06010, FIXME @cm30020, FIXME @customer lọt vào màn renderQuét bỏ FIXME/token máy trước bàn giao; bài học: cần gate chặn placeholder trong output UI.
82 màn 500 do thiếu local app-config (CM71060/CM05110): registry app.config[*] IO-dir gitignored, mất sau pullKhôi phục/cung cấp app-config registry cho môi trường đo; bài học: config registry phải có cơ chế seed local, không để mất sau clone.

Thông điệp Goal 2: "AI không hoàn hảo - chúng tôi ghi lại sòng phẳng chỗ vấp và cách xử lý, để khi sang dự án thật biết trước rủi ro." Đây là giá trị PoC khách thực sự muốn (PR cho End User về 'giới hạn AI và đối sách'), trả lời được NGAY không cần chờ đo.


Phần 5 - Baseline vs Target + lộ trình cải thiện

NhómBaseline (điểm xuất phát)Target POCCơ chế đạt target
Headline AI-FPA40% (khách tin)≥ 60%Tuning prompt/context + golden sample; đo bằng FPA per công đoạn
A3 Code FPA(chưa có, khách nghi 40%)≥ 60%Tag git -> đo diff -> tuning UI gen (chỗ yếu nhất)
A2 Docs FPA-≥ 70%Review 2 lớp + checklist quan điểm
B1 Effort100% công thủ cônggiảm ≥ 40% overall, ≥ 50% BD/DDeffort-log + baseline thủ công chốt với CTO
B2 Review time16h (2 ngày/doc, anchor MSR-002)≤ 4hAI pre-review 2 lớp
C6 Parity cũ/mới-≥ 95%comparison UT, bật M3/M4
C (chất lượng)-giữ ≥ 95-100%engine audit mỗi milestone
D2 First-time approval40%≥ 70%tuning theo issue tích lũy

Lộ trình theo milestone scope-tracker: M1 (BD xong) · M2 (DD xong) · M3 (CODE xong) · M4 (TEST xong) + 1 snapshot cuối POC. Đo sớm, đo thường, không dồn cuối.

Việc phải bật ngay để có số (cam kết mốc - điền owner/ngày trước khi trình khách)

#ViệcMở khoá chỉ sốOwnerMốc
1Phát template effort-log.csv + bắt đầu ghiB1, B3, B4(điền)tuần này
2Bật giao thức git tag ai-gen/tunedA3 (số khách quan tâm nhất)(điền)từ màn kế tiếp
3Lưu bản v0 (AI) của mỗi docA2(điền)từ doc kế tiếp
4Chốt với CTO: trọng số Wᵢ, baseline B1, day_rate B4, định nghĩa semantic A3headline + B4 + A3CDXO+CTOtrước buổi trình khách

Lưu ý quan trọng trước khi trình khách: các số gắn [Estimation] (trọng số headline, baseline B1, day_rate B4, target B1) chưa qua anh Dzũng (CTO). Phải có buổi freeze với CTO trước, nếu không là đang trình số chưa được CTO duyệt.


Phần 6 - Cơ chế chấm điểm tái lập được (defensible trước lãnh đạo)

Đây là phần thuyết phục CTO/CEO: cùng input -> cùng score, ai chạy lại cũng ra số đó.

  1. Số sinh từ engine/diff/log, không chấm tay. Mỗi chỉ số nhóm C có 1 lệnh cố định (bảng dưới); nhóm A có công thức diff/so khớp cố định. (Ngoại lệ trung thực: A3 còn 1 bước "loại trừ hình thức" do người gắn cờ -> đang cơ giới hoá, xem ghi chú A3.)
  2. Một file số liệu duy nhất: .nexa/kb/scope-tracker/kpi-targets.json. Engine kpi_snapshot.py ghi current + state; người viết không sửa tay số trong bảng báo cáo.
  3. Lịch sử bất biến: mỗi snapshot append 1 dòng vào kpi-history.jsonl (có timestamp) -> truy được số tại mọi thời điểm.
  4. Evidence file đính kèm: mỗi số nhóm C trỏ tới file output gốc (json/surefire).

Lệnh tái lập nhóm C:

IDLệnhOutput
C1nexa gate rungate log
C2prototype-ui-audit.py04-coding/report/prototype-ui-audit.json
C3cd 04-coding && ./mvnw test -Dtest=LegacyOriginMappingTestsurefire report
C4python3 04-coding/coding-rules/screen-audit-check.py <CM>screen-audit report
C5python3 04-coding/coding-rules/code-audit-check.py <ctx>code-audit.json
C6./mvnw test -Dtest=*ComparisonTestsurefire report

Pipeline snapshot mỗi milestone:

1. Chạy 6 lệnh nhóm C
2. Cập nhật effort-log.csv (đã ghi hằng ngày)
3. Tag git ai-gen/tuned cho screen mới xong
4. python3 .claude/skills/nexa-audit-target/scripts/kpi_snapshot.py --snapshot
   -> ghi current vào kpi-targets.json + append kpi-history.jsonl
   -> sinh kpi-report-{stamp}.md từ template
5. DDM (localhost:6392) đọc kpi-targets.json -> trực quan

Đề nghị kiểm định độc lập (gỡ nghi ngờ sau sự cố matcher 57.1%)

Vì engine từng báo sai 57.1% (lỗi đọc thiếu phạm vi), khách có quyền nghi cả các số PASS khác. Đối sách: mời khách (hoặc bên thứ 3) tự chạy lại 1 lệnh nhóm C trên 1 màn và đối chiếu tay. Khớp -> tin cả bộ engine. Đây là điều kiện để chuyển niềm tin từ "vendor nói" sang "khách tự kiểm". Nên chủ động đề nghị, không chờ khách đòi.

Phần 7b - Lộ trình chỉ số Phase 2 (để qua review hãng SI lớn)

Bộ chỉ số hiện mạnh ở AI-accuracy + chất lượng artifact (khớp mục tiêu khách), nhưng một review cấp NTT Data/Accenture sẽ đòi thêm các chỉ số chuẩn ngành dưới đây. PoC tài liệu/4-màn chưa tới kỳ đo, nhưng phải có roadmap (SI không chấp nhận "không có kế hoạch"):

NhómChỉ số bổ sung (đề xuất)Khung nguồnKhi đo
ROI/tài chínhROI% = (lợi ích − chi phí AI)/chi phí AI; Payback (tháng); TCO chi phí AI (token/license/HITL)thực hành business-case SIkhi có B1+B4
Chất lượng giao hàngDefect-escape rate (lỗi lọt sau gate); Defect density (/screen); Test coverage % (line/branch)QA ngành + DORAM3/M4 (code)
Tốc độ giao hàngDORA: Lead Time, Change Failure Rate, Deployment Frequency; Cycle time/artifactDORA/SPACEPhase 2 (CI/CD)
Con người/áp dụngAdoption/Utilization rate (% công đoạn thực dùng AI - khác FPA); Developer satisfaction (survey)SPACEđịnh kỳ
Kỹ thuật bổ trợSecurity/SAST density; Maintainability/tech-debt; Requirements traceability %OWASP/ISO/CMMIPhase 2

Lưu ý: DORA/SPACE là khung delivery+productivity, KHÔNG phải khung AI-accuracy - "thiếu DORA" ở PoC này không phải lỗi thiết kế, mà là phần bổ sung Phase 2. Mọi target phải freeze với CTO như các [Estimation] hiện có. [SoT: Inference + DORA/SPACE official frameworks - xem cmux-workers/researcher.md]


Phần 7c - Provenance: phân biệt NEXA gen-mass / NEXA-skill gen+fix / manual

Câu hỏi: trong source, phần nào AI sinh hàng loạt, phần nào dùng skill gen+fix, phần nào người gõ tay. Đo trên 04-coding HEAD e1f3654.

Giới hạn gốc (phải nói thẳng)

Provenance KHÔNG được ghi lúc commit: 0 git tag ai-gen/tuned, 0 header @generated trong source. Tác giả commit chỉ là proxy yếu (dev người có thể chạy AI rồi commit dưới tên mình - commit 4098c47 "re-generate BE logic" là ví dụ). Vì vậy tỷ lệ % từng lớp KHÔNG đo được hồi tố - chỉ ước lượng forensic gắn [Estimation] + confidence. Không bịa "X% do AI sinh".

Forensic best-effort (bằng chứng cứng + confidence)

LớpTín hiệu đếm được (verified)Confidence (lớp tồn tại)Confidence (% chính xác)
L1 NEXA gen-masscommit 9e08a17: 74 file / 5153 dòng / cả 4 màn sinh trong 1 commit (không thể gõ tay)HIGHLOW
L2 NEXA-skill gen+fix155 file @LegacyOrigin (100% file màn), ArchUnit pass, các commit nexa-audit/screen-audit/scope-trackerMED-HIGHMEDIUM
L3 manual204/212 java file last-touch bởi dev người, PR per-màn có issue-ref tinh chỉnh logic/UIHIGHLOW

3 lớp chồng lên nhau trên cùng file (gen-mass khai sinh → skill graft marker → human fix logic) → chia theo *giai đoạn lịch sử của file*, không theo file rời.

Câu defensible duy nhất trước CTO: "Khung 4 màn do NEXA sinh hàng loạt 1 lần (bằng chứng commit 9e08a17: 74 file/5153 dòng), traceability NEXA phủ 100% file (155 @LegacyOrigin), phần tinh chỉnh logic do dev người làm tiếp. Tỷ lệ % từng lớp KHÔNG đo hồi tố được vì provenance chưa ghi lúc commit - bật cơ chế đếm từ màn kế tiếp."

Cách đo COUNTABLE từ giờ (biến forensic-đoán thành đo-được, feed thẳng A3)

  1. Git tag 3 mốc per màn: ai-gen/<CM> (ngay sau NEXA sinh, trước khi người động) → skill-gen/<CM> (sau chạy NEXA-skill) → tuned/<CM> (sau dev review xong). Lớp = git diff --numstat giữa các tag. A3 Code-FPA = 1 − semantic-LoC(ai-gen..tuned)/LoC(ai-gen).
  2. Commit trailer bắt buộc: Provenance: nexa-gen | skill-gen=<skill> | manual | mixed + Provenance-Tool: + Screen:. Đếm: git log --format='%(trailers:key=Provenance,valueonly)' | sort | uniq -c.
  3. Header file máy-sinh: // @nexa-generated tool=vibecode v=3.2 screen=CM06010 + @provenance-layer L1 (sửa thành L3 khi người overwrite). Grep đếm file-level.

Màn đã code trước e1f3654 = pending, không hồi tố thành số chắc (đúng kỷ luật A3). Chi tiết: cmux-workers/provenance-analysis.md.


Phần 7 - Phụ lục: nguồn dữ liệu, giả định, khoảng còn thiếu

7.1 Nguồn dữ liệu gốc

7.2 Giả định (cần CTO chốt, hiện gắn [Estimation])

  1. Trọng số Wᵢ của headline AI-FPA (theo số artifact hay effort-share) - và headline chưa tái lập được tới khi chốt.
  2. Baseline thủ công cho B1 (ước lượng KMD hay chuẩn productivity JP-SI - phải chốt nguồn).
  3. Đơn giá GIỜ công (hourly_rate) cho B4 + baseline per-screen - chưa có thì không ra được con số ¥.
  4. Ngưỡng B1 target (50% BD/DD, 40% overall đang là ước lượng).
  5. Định nghĩa "người sửa semantic" trong A3 + cơ giới hoá script.
  6. Tần suất snapshot KPI (đề xuất: mỗi milestone M1-M4).
  7. A1 target 90% đặt cao vì trích xuất AST deterministic - cần sample thực xác nhận. C6 target 95% là ước lượng.

7.3 Khoảng dữ liệu còn thiếu (phải hành động ngay)


*Số mục tiêu đều có anchor trong bảng hoặc gắn [Estimation] chờ chốt với CTO; mục chưa đo ghi rõ "chưa đo" - không bịa. Bản machine-readable: .nexa/kb/scope-tracker/kpi-targets.json.*


Thuật ngữ (Glossary)

Bảng định nghĩa các keyword khó (so với mức Junior). Trong bản HTML, keyword được gạch-chân-chấm; hover ra định nghĩa này. Trích từ Phần 3 (Danh mục chỉ số đầy đủ).

Thuật ngữĐịnh nghĩa ngắn (hover)
C1Quality-gate pass: % gate G1-G11 PASS trước khi qua phase. Nguồn: nexa gate run log.
C2UI element coverage vs prototype: item PASS / item audit (đủ thành phần, không thiếu/thừa). Đo bằng prototype-ui-audit.py (app live :8080).
C3Legacy mapping integrity = TRACING: % màn pass ArchUnit @LegacyOrigin. Mỗi class nghiệp vụ mới truy được về gốc legacy. 100% = truy được hết, KHÔNG phải "cover 100% logic legacy" (mẫu số là code mới, không phải logic legacy - xem Q1 §B).
C4Screen audit-breadth (logic): coverage_pct = % claim-type trích/check được (audit rộng tới đâu), KHÔNG phải % có mặt trong doc mới. Đo bằng screen-audit-check.py.
C5Code structure (DDD): số finding P1 mở lúc bàn giao (đặt logic đúng tầng). Đo bằng code-audit-check.py. Hiện 0 P1, 4/4 gate PASS.
C6新旧比較 UT (parity cũ/mới): % test (output Java == output VB cũ, cùng input) PASS. Đo bằng *ComparisonTest golden-master. Hiện 5/5.
C7Unit-test coverage: line coverage = covered/(covered+missed). Đo bằng JaCoCo. Hiện logic-ring 87.7%.
C8Test-case Pass rate: (run−fail−err)/run. Đo bằng mvn test surefire. Hiện 246/246 = 100%.
C9SpotBugs count: số bug spotbugs:check (threshold Low). Hiện 0 (proxy cho Sonar bug-detection).
@LegacyOriginAnnotation Java trên mỗi class/function NGHIỆP VỤ mới: ghi module/screen/source(Frm.vb:Lxxx)/procedure gốc legacy. Là TRACING helper (truy nguồn), enforced bằng ArchUnit + legacy-map-check.py. KHÔNG phải coverage metric - không lấy làm mẫu số đo % logic legacy đã cover.
ArchUnitThư viện test kiểm tra quy tắc kiến trúc bằng code (vd "mọi class màn phải có @LegacyOrigin", "controller không chạm persistence"). Chạy như unit-test.
FPA (First-Pass Acceptance)% sản phẩm AI sinh ra được giữ lại sau khi người review (người sửa ít = AI đóng góp nhiều). Thước đo trung tâm nhóm A.
code-FPA (A3)FPA riêng cho code: 1 − (LoC người đổi semantic / LoC AI sinh), đo bằng git diff ai-gen/<CM>..tuned/<CM>. Hiện chưa đo (chưa bật git-tag).
parity (new-old)Tương đương hành vi: cùng input → output Java == output VB cũ. Bằng chứng nghiệm thu cốt lõi của migration.
golden-masterCách đo parity: chụp output bản cũ làm "chuẩn vàng" (golden file) → so bản mới với nó. Engine GoldenMasterSupport.
claim / legacy_auditable"Claim" = 1 đơn vị logic kiểm được trích từ legacy (control/table/message/business-rule). legacy_auditable = tổng số claim của 1 màn.
audit-breadthĐộ rộng audit (% claim-type engine trích/check được), khác với "presence" (% claim có mặt trong doc mới). C4 = breadth, không phải presence.
DDDDomain-Driven Design: đặt code đúng tầng (logic nghiệp vụ ở domain, không lẫn vào controller/repository).
P0/P1/P2/P3Mức ưu tiên lỗi: P0 nặng nhất > P1 > P2 > P3. P1 = phải fix trước bàn giao, chưa phải "sập hệ thống".
JaCoCoCông cụ đo code coverage cho Java (line/branch). Sinh target/site/jacoco/jacoco.csv.
SpotBugsCông cụ phân tích tĩnh bắt bug Java (null-deref, mutable-exposure...). Proxy cho phần bug-detection của Sonar.
Sonar / SonarQubeNền tảng phân tích tĩnh tổng hợp (bug + code-smell + coverage + security + quality-gate). Cần server + token để chạy.
EI_EXPOSE / mutable-exposureBug pattern: trả/lưu trực tiếp collection mutable nội bộ (rò rỉ tham chiếu). Fix bằng List.copyOf (defensive copy).
golden / matcher artifact"Matcher artifact" = con số sai do CÔNG CỤ ĐO lỗi (vd CM30020 42.5% do matcher chỉ đọc BD), KHÔNG phải chất lượng thật.
HITLHuman-in-the-loop: có người kiểm tra tay (vd audit KB sample).
A3 / B1 / Q1-Q6A3=code-FPA, B1=effort-reduction (nhóm nội bộ). Q1-Q6 = 6 tiêu chí khách (品質基準). Map: Q1↔C3+C4, Q2↔C6+A3, Q3↔B1, Q4↔C5+SpotBugs/Sonar, Q5↔C7, Q6↔C8.