Fibretrace Monet docs/Start here/Master Report (VI)

Báo cáo tổng hợp — 2026-08-19: đồng bộ Lovable, phân tích QC script, knowledge base business-logic

Bản tiếng Việt của .local/MASTER-REPORT.md. Hai bản sống song song và giữ nguyên cấu trúc phần để đối chiếu được với nhau; bản tiếng Anh là bản gốc. Thuật ngữ nghiệp vụ, tên file, đường dẫn, route, tên bảng/cột, tên hàm và mã task được giữ nguyên tiếng Anh có chủ đích.

Báo cáo do session điều phối (monet-master) viết, sau khi thu debrief trực tiếp từ hai session worker (qc-script-analysis, biz-logic-kb) và tự đọc lại độc lập từng deliverable trên đĩa. Chỗ nào lời session nói khác với file thì file thắng, và chỗ lệch đó được ghi lại bên dưới. Người chưa đọc bất kỳ tài liệu nền nào vẫn có thể đọc từ đầu đến cuối và nắm đủ.

Cập nhật 2026-08-20 (session monet-003): hai mục trong danh sách bên dưới đã được kiểm trực tiếp. T88 đã đóng — bug CHECK revoked là có thật, nay nằm ở Hạng 7 dưới dạng một phát hiện. Mục bảo mật được viết lại và nâng từ Hạng 7 lên Hạng 2: chỗ phơi nhiễm thật là RLS của Supabase bên Lovable đang mở cho anon đọc và ghi, khiến cổng public-token bị vô hiệu; nó được theo dõi bằng task mới T91 và đứng đầu danh sách câu hỏi T86. Các hạng ở phần 5 đã đánh số lại theo đó; bằng chứng đầy đủ nằm ở Q10/Q12 trong 06-open-questions.md của KB.

1. Hôm nay có gì, theo thứ tự

Ngày 2026-08-19 có ba khối việc hoàn thành, khối sau dựng trên khối trước.

Thứ nhất, buổi sáng (06:41 UTC), lần đồng bộ Lovable theo lịch chạy (flow-ft-lovable-sync, run wf_70fb9c32-51f, 44 agent, pull git-first sạch). Nó phân tích 781 commit Lovable (2,5 ngày autosave, từ 2026-08-16 đến 2026-08-19) đối chiếu với port cursor của monet, và cho ra một port plan 29 unit. Deliverable: .local/lovable/sync-20260819/port-plan.md, RUN-SUMMARY.md, cùng với cursor đã cập nhật trong .local/lovable/state.json và một entry mới trên đầu .local/lovable/CHANGELOG.md.

Thứ hai, buổi tối, một session chuyên trách phân tích tài liệu FibreTrace QC Test Script v1.0 mà Malcolm gửi cùng ngày (kịch bản test 50 case, 6 section cho toàn nền tảng). Deliverable: .local/qc-test-script/test-cases.md (bản rút gọn trung thành từng case), analysis.md (kiểm kê route, đối chiếu business rule, thứ tự dựng môi trường test, các lỗi nội tại của script, cách chia việc cho tester, 11 câu hỏi gửi Malcolm), kèm bản thô extracted.txt / fibretrace-qc-test-script.docx.

Thứ ba, khuya, một session thứ hai dựng lại toàn bộ business logic của FibreTrace từ số không. Mọi tài liệu có trước (các buổi walkthrough tháng 7, khoảng 195 memory record, backend spec, chính bản phân tích QC, các sync plan) đều bị coi là giả thiết cần kiểm lại đối chiếu với code — clone Lovable tại origin/main (ffab85ca), các Supabase migration, adapter của apps/dashboard, frontend-canvas, và apps/sat. Deliverable: knowledge base 15 file tại .local/business-logic/knowledge-base/ (tổng quan, domain model kèm ERD, các lifecycle kèm sơ đồ máy trạng thái SVG, glossary với 8 va chạm thuật ngữ, 45 rule và invariant, file riêng cho từng persona, ma trận trạng thái hiện thực, 20 câu hỏi treo đã xếp hạng) cùng một portal.html self-contained chạy offline. Mỗi claim đều mang nhãn độ tin cậy: 343 VERIFIED (có citation tới code/migration), 63 STATED (được khẳng định nhưng không có citation trong code), 11 INFERRED, 16 UNKNOWN.

Cả hai session worker đều trả lời trực tiếp yêu cầu debrief của session điều phối. Phần kiến thức không nằm trên đĩa của họ (phương pháp, những chỗ tự sửa giữa chừng, những gì họ không kiểm được) được gộp vào phần 7.

2. Kết quả đồng bộ Lovable và ý nghĩa với việc port

Cửa sổ 0df29e60 -> f0d02a28 cho ra 29 unit: 7 PORT, 14 REVIEW, 8 SKIP, 0 ALREADY_DONE (.local/lovable/sync-20260819/RUN-SUMMARY.md). Con số quan trọng nhất nằm ở phần resolve API: trong 12 spec có đụng dữ liệu, EXISTS = 0, GAP = 9, PARTIAL = 3. Nghĩa là lần này không có thứ gì đụng dữ liệu wire được vào backend thật. Toàn bộ giá trị port được của đợt này là visual/structural.

Port được ngay, theo thứ tự phụ thuộc (tất cả đã thành task, xem phần 6): trước hết là đợt rebrand design-system của button.tsx (thêm variant tertiary, pill trắng cho table, bo góc 8 lên 10px, thống nhất chiều cao CTA về h-9, variant action đổi từ xanh lá sang primary) — đây là thay đổi toàn cục, Button render trong khoảng 86 file. Kế đó là restyle pill của tabs.tsx cộng với một component dùng chung hoàn toàn mới table-pagination.tsx. Sau cùng là ba unit thuần UI: Partners chuyển ra khỏi Settings vào main nav (/partners, kèm redirect), polish trang SDU (Sliver Delivery Unit — phần cứng đặt trực tiếp trên dây chuyền tại nhà máy sợi), và chỉnh copy/chip của supply-chain (.local/lovable/sync-20260819/port-plan.md, unit 1-5).

Chín unit GAP đều dồn vào một chỗ: domain claim/PO/nomination (viết lại Ready-to-Claim, viết lại Nominations, thiết kế lại ClaimPosition, dashboard của owner, mô hình hết hạn reservation, v.v.). Port phần nhìn của chúng chỉ tạo thêm vỏ rỗng có toast chặn, chồng lên năm cái vỏ đã theo dõi từ tháng 6. Đây là một quyết định thu hẹp phạm vi có chủ đích, không phải mặc định (RUN-SUMMARY.md gap 2, nay là task T90). Mỗi unit GAP đều kèm sẵn một beSpecForGap để team backend nộp thẳng thành ticket.

Bản thân lần chạy sync để lộ một lỗi thật: port plan nói index.css không có diff, nhưng thực tế monet đang thiếu block hạ cấp typography .tier0-quiet và font weight Mona Sans 800. Đây là drift từ commit Lovable 90b49e35 (2026-06-27) — nó có TRƯỚC baseline của lần sync này, không xuất hiện trong bất kỳ cửa sổ commit tương lai nào, và cũng không có entry known_unported. Cơ chế duy nhất có thể phát hiện ra nó là completeness pass độc lập với cửa sổ, mà pass của lần chạy này lại chỉ so mỗi colour token. Nói cách khác, món này đã suýt mất vĩnh viễn trong im lặng (RUN-SUMMARY.md gap 1). Nay nó là task T80 (port lại, khoảng 7 dòng, không phụ thuộc BE) và T89 (siết completeness pass để loại drift kiểu này không lọt được nữa).

Trạng thái cursor sau lần chạy (.local/lovable/state.json): last_fetched_sha = f0d02a28, last_ported_sha = 2b52a608 (tự động tiến 67 commit trên một đoạn đầu đã kiểm chứng bằng bằng chứng; đã được kiểm lại độc lập trong RUN-SUMMARY), 10 entry known_unported. Đề xuất tiến thẳng cursor lên f0d02a28 chỉ nên chấp nhận SAU KHI unit 1-5 của port plan thực sự đã vào code.

3. Phân tích QC script và hệ quả cho vòng QC

QC Test Script v1.0 của Malcolm gồm 50 case trải trên 6 section (FT Admin, Program Owner, Producer, Manufacturer, Retailer, và nhóm cross-cutting) cộng phần sign-off, kèm 6 business rule được phát biểu và một checklist dựng môi trường test (.local/qc-test-script/test-cases.md).

Kết luận quan trọng nhất, không kèm điều kiện: kịch bản này nhắm vào bản Lovable MVP đang chạy. 30 trên 31 route của nó tồn tại ở Lovable origin/main. Trong khi đó monet chỉ có 7 route thực sự có dữ liệu được wire, 14 route là vỏ rỗng, và 10 route không tồn tại; ngoài ra mọi thao tác ghi đi qua adapter của monet đều throw MutationNotImplementedError (.local/qc-test-script/analysis.md, mục a-b). Hôm nay không một case nào trong 50 case chạy được end-to-end trên monet. Ai đem script này chạy lên monet sẽ đẻ ra một loạt bug report sai, lặp lại đúng những khoảng trống BE đã biết và đã ghi nhận. Vòng QC bắt buộc phải chạy trên app Lovable.

Ba case không test được kể cả trên Lovable ở HEAD. A-08 và R-13 test một module Insights không tồn tại ở đâu cả — không route, không module flag, không có ở Lovable, monet, hay canvas; riêng R-13 còn gọi đích danh Walmart, một company thuộc demo modal mà tester bị cấm đụng vào. Còn A-13 yêu cầu “add an override” tại /admin/overrides, nhưng trang đó là một báo cáo calibration chỉ đọc, không hề có form thêm (analysis.md, mục d-e).

Nút thắt thật sự là dựng môi trường test, không phải chuyển persona. 7 trong 11 loại object của checklist môi trường đều bị khóa sau quyền FT Admin (product category, programme, registration, reservation, licence, scanner, SDU). Cái tab “QC account-switcher” mà Malcolm đề nghị chỉ bỏ được ma sát đăng nhập giữa các persona — nó không gỡ được cái xương sống tạo object bị gate bởi admin, và chức năng admin Impersonate thì vốn đã có sẵn (analysis.md, mục d). Điều này làm đề nghị của anh ấy phải được đặt lại vấn đề, và nó là câu hỏi số 8 trong danh sách gửi trước buổi call thứ Năm.

Bản thân script cũng chứa những lỗi nội tại sẽ sinh ra kết quả fail giả:

  • Rule 1 bỏ sót loss multiplier mà app có áp vào phép tính CU (Claim Unit — 1 CU = 1 kg sợi thô đã đánh dấu; 1000 CU = 1 MT). Tester tự tính tay theo quantity x net weight x blend % (tỷ lệ pha sợi) sẽ lệch ở mọi chỗ multiplier khác 1, mà con số này lại được cố ý giấu khỏi họ.
  • A-01 trông đợi có field blend trên form programme, nhưng field đó không tồn tại — blend nằm ở product category.
  • A-04 trông đợi nhập được CU âm tại /admin/reservation-requests, nhưng hàng đợi đó chủ động từ chối giá trị âm; số âm chỉ tồn tại trên panel của programme.
  • Chỉ dẫn “chạy các section theo thứ tự” gãy ngay tại M-05: case này cần một Nomination (đề cử: brand chỉ định đơn hàng cho manufacturer) mà chỉ R-01 ở section sau mới tạo ra. Thứ tự chạy được là A, rồi R-01/R-02, rồi M, rồi phần còn lại của R, rồi O, rồi X (analysis.md, mục e).

Cách chia việc đề xuất cho tester rơi vào khoảng 4,5 tester-day cho một lượt chạy đầy đủ, chia cho ba tester cộng một người dự phòng, với điều kiện người giữ quyền FT Admin phải dựng môi trường trước (analysis.md, mục f, kèm 11 câu hỏi cho thứ Năm).

4. Knowledge base business-logic: nó là gì và tin được tới đâu

KB (.local/business-logic/knowledge-base/, hai cửa vào là README.mdportal.html) là một bản dựng lại từ số không, không phải bản biên soạn gom góp. Chín luồng research song song được tổng hợp lại, xung đột giải quyết theo thứ tự ưu tiên: code trước, rồi migration, rồi tài liệu mới nhất; thứ gì không giải quyết được thì bị đánh dấu là chưa rõ thay vì đoán bừa. Hồ sơ độ tin cậy của nó — 343 VERIFIED so với 63 STATED, 11 INFERRED, 16 UNKNOWN — có nghĩa là phần cơ chế lõi (sổ cái capacity, máy trạng thái PO, vòng đời claim, cơ chế che dữ liệu, cách suy ra persona, các guard ở tầng DB) đã được chứng minh bằng code tại Lovable ffab85ca; còn tầng chỉ-STATED thì phần lớn là ý định nghiệp vụ của Malcolm phát biểu trong các buổi walkthrough tháng 7.

Bộ persona: năm persona của QC mỗi cái có một file đầy đủ.

  • FT Admin (persona-01) — nắm toàn bộ xương sống cấp phát.
  • Program Owner (persona-02) — là một dữ kiện ở cấp company với hai cổng độc lập, kèm một mini-CMS cho credential/wording.
  • Tier 4 Fibre Producer (persona-03) — suy ra từ registration, và là bên làm tăng pool Activated của programme.
  • Tier 1 Manufacturer (persona-04) — suy ra từ hoạt động: có Nomination đến CHÍNH LÀ persona này; bên này sở hữu việc link và số lượng đề xuất.
  • Tier 0 Retailer/Brand (persona-05) — suy ra từ type cộng participation; sở hữu Nomination, việc confirm, và evidence.

persona-06 bổ sung bốn actor mà QC script bỏ sót: auditor (chỉ scan, bị buộc đăng xuất khỏi dashboard); persona “scanner” trung tính ở Tier 2/3 (actor thầm lặng nhưng chịu lực — scan của họ dựng nên chain of custody nhưng bản thân không bao giờ claim); public verifier (các trang /c/:token gate bằng token); và trục team-role. persona-00-map.md vẽ ra ai cấp phát cho ai và ai chặn ai.

Ma trận trạng thái hiện thực (05-implementation-state.md) là bản đối chiếu thực tế gọn trong một trang: business logic hiện chỉ demo được ở đúng một nơi, là bản Lovable MVP. Monet phủ thật phần vành đai vận hành (auth, company, team, partners, facilities, scanners, invoices, collections, quét SAT), nhưng toàn bộ phần lõi thương mại (programme, capacity, nomination, claim, evidence) render ra vỏ rỗng một cách có chủ đích. Còn backend thật thì bắt đầu từ đầu kia — từ phía tổng hợp (đọc funnel, tạo claim một bước) — và chưa bao giờ mô hình hóa cỗ máy propose/confirm xoay quanh PO mà cả UI lẫn QC script đều mặc định là có.

Các citation trỏ sang Lovable trong KB được kiểm tại đúng ffab85ca. App thay đổi hàng ngày, nên đường kiểm lại nhanh nhất là git -C .local/lovable-source show origin/main:<path> sau khi fetch mới — tuyệt đối không đọc working tree trên đĩa của clone, vì nó lệch khoảng 4.300 commit (xem phần 7).

5. Mâu thuẫn và câu hỏi treo trên cả ba khối, đã dedupe và xếp theo mức chặn

File 06-open-questions.md của KB đã gộp và xếp hạng sẵn 20 câu hỏi treo từ mọi nguồn; phần này là bản dedupe xuyên ba khối kèm người chịu trách nhiệm. Hạng 1 chặn nhiều nhất.

Hạng 1 — sự phân ly về mô hình claim (KB Q1, task T87). Lovable và QC script hiện thực một cỗ máy hai bên: manufacturer đề xuất dựa trên một PO (Purchase Order — đơn đặt hàng), retailer confirm hoặc reject, các trigger ở DB đo đếm mọi thứ. Backend thật đã deploy (2026-08-03) lại là một mô hình khác hẳn, một bước: POST /api/monet/v1/claims, với bước validate mà bản thân nó vẫn còn 404 trên DEV. Ba memory record độc lập đều mô tả hai thứ này là song song và chưa được hòa giải. Một phán quyết duy nhất này quyết định: BE phải build gì cho cả 9 unit GAP, monet có port UI propose/confirm ra thứ gì hơn cái vỏ hay không, section 4-5 của QC đang test sản phẩm hay test prototype, và số phận của đường claim trực tiếp không qua PO (KB Q13, cùng một cuộc trao đổi). Người quyết: Malcolm + team BE. Mọi thứ còn lại trong danh sách này đều nhỏ hơn nó.

Hạng 2 — Supabase của bản Lovable MVP đang mở cho ẩn danh ĐỌC và GHI (KB Q12, task T91). Đã kiểm ngày 2026-08-20. Route webhook không token chỉ là triệu chứng nhìn thấy được: ClaimWebhookPreview là trang client-side gọi thẳng Supabase, nên thứ quyết định phơi nhiễm là RLS chứ không phải route. Cả production_claims lẫn public_verification_tokens đều mang policy FOR ALL USING (true) WITH CHECK (true) không có mệnh đề TO, nên mặc định áp cho role public, tức bao gồm cả anon (SQL 20260421164336:40-44 và 20260611094428:79-80). Đây là lối viết chung của cả dự án chứ không phải một chỗ sẩy tay: 79 lần xuất hiện USING (true) trên 33 file migration. Hệ quả trước đây chưa được ghi nhận: public_verification_tokens đọc được ẩn danh, nên chỉ cần có claimId là lấy được các dòng token của claim đó và mở được Evidence Pack public kể cả khi enabled = false — cổng public-token bị VÔ HIỆU, không phải chỉ bị một route đi vòng qua. Và WITH CHECK (true) nghĩa là anon GHI được, không chỉ đọc. Phạm vi: đây là Supabase riêng của Lovable, không bao giờ là backend production của monet (monet đi tới Laravel qua apiAdapter.ts), nên không có gì trong repo này sửa được. Nhưng đó đúng là instance mà vòng QC sắp chĩa tester vào, và cũng là bản Malcolm đem đi demo. Người chịu trách nhiệm: phải báo Malcolm TRƯỚC khi QC khởi động, sau đó Lovable/BE xử lý. Mục này đứng trên câu hỏi QC-có-chạy-được-không vì nó là một sự thật về an toàn dữ liệu, không phải một quyết định phạm vi.

Hạng 3 — vòng QC có khởi động được không (QC analysis mục d/f; KB Q5, Q20; task T86). Ba câu hỏi con cho Malcolm: Insights có tồn tại hay bị bỏ (A-08/R-13, cộng mâu thuẫn Walmart); ai được cấp quyền FT Admin để dựng phần môi trường bị gate 7/11 (cái switcher không giải quyết chuyện này); và file CSV kết quả đi kèm chưa từng được gửi. Ba câu này quyết định kế hoạch cho thứ Năm.

Hạng 4 — hai vụ đổi tên thuật ngữ (KB Q2, Q3; va chạm glossary C1, C2). Nhãn CU (“Claim Unit” hay “credit units”): treo từ 2026-08-18, QC script dùng CẢ HAI và canon hóa cả cặp, còn đợt rà copy của chính Lovable ở HEAD vẫn chưa xong. Việc này chặn đợt sweep toàn nền tảng (port plan unit 9) và làm case QC X-02 không test được đúng như đang viết. Vụ PO đổi thành Nomination: cách hiển thị đã chốt qua X-02, nhưng có đổi tên ở tầng domain/bảng hay không thì chưa. Người quyết: Malcolm (đặt tên), BE (contract).

Hạng 5 — mô hình reservation trên backend thật (KB Q6, Q7). Hình thái cuối cùng bên Lovable (sổ cái ghi từng lần điều chỉnh, expires_at NOT NULL mặc định bằng ngày tạo cộng 18 tháng, phần giải phóng âm bị chặn trần ở mức đang reserved — migration 20260816203909/20260818202335) mới hơn mọi thứ đang nằm trong .local/backend-specs/. Backend thật thì không có khái niệm hết hạn, và cũng không có endpoint GET reservation ở mức từng dòng. BE phải chọn: hoặc trả expires_at theo từng dòng, hoặc gộp luôn việc loại trừ hàng hết hạn vào funnel ở phía server. Người quyết: team BE. Lưu ý: bản thân mô hình sổ cái nay đã là ý định sản phẩm đã chốt (xem phần 6).

Hạng 6 — các điểm script lệch code mà Malcolm phải phán từng cái (QC analysis mục e; KB Q4, Q8, Q14-Q18): chỗ nhập giá trị âm của A-04 (hàng đợi từ chối theo thiết kế); vị trí của loss multiplier trong phép tính của QC; form add-override không tồn tại của A-13; yêu cầu scanner bằng mailto của M-02; licence tính theo tiền hay theo số lượng (A-12/M-01 trông đợi đơn vị tiền tệ, còn mô hình chỉ đếm số lượng); mục nav SDU của P-01 (một company chỉ có SDU vẫn nhìn thấy Device Status — nav gate theo số lượng thiết bị, không theo registration); lỗi vượt hạn mức sản xuất phía client bị thiếu ở P-06; việc duyệt hàng loạt ở R-07 không có cơ chế rollback theo lô; và độ lệch nhãn tier trong wizard đăng ký. Tất cả đã gộp vào danh sách câu hỏi T86.

Hạng 7 — đã giải quyết trong đợt này, giờ là một phát hiện chứ không còn là câu hỏi (KB Q10, task T88, đã đóng). App ghi production_claims.status = "revoked" trong khi production_claims_status_check chỉ cho phép proposed/confirmed/rejected. Đã kiểm: constraint đó được tạo đúng một lần (SQL 20260618105531:20-24), là migration duy nhất trong 132 file chạm tới tên đó, không có DROP CONSTRAINT nào trên production_claims, và không migration nào từng nới CHECK đó để nhận revoked — trong khi SQL 20260811125616:1-4 lại cố ý thêm revoked_at/revoked_by_user_id/revoke_reason, và EvidencePackDetail.tsx:137-157 ghi đúng các cột đó. Vậy thao tác revoke claim của admin throw ngay ở DB, toast “Could not revoke this record” nổ, và banner Revoked ở trang public (PublicClaim.tsx:64,86) là code không bao giờ chạy tới — một half-migration: cột thì thêm rồi, constraint thì quên. Không mang tính hệ thống: chỗ revoke còn lại (OwnerCertificates.tsx:152) ghi vào program_certificates, bảng có CHECK được viết đúng ngay từ đầu là (status IN ('active','revoked')) (SQL 20260606025632:77-78), và chạy tốt. Đưa vào danh sách gửi Malcolm.

Hạng 8 — tồn dư sản phẩm lâu ngày: khả năng nhìn thấy chuỗi cung ứng của bên không phải partner (che hay bỏ hẳn, KB Q9, treo từ tháng 7); certificate 1:N và việc kế thừa xuống sub-tier (KB Q19); tier tính theo company hay theo facility (KB Q11); và cái “webhook” đến giờ vẫn chỉ là trang preview không có cú đẩy ra ngoài nào, trong khi copy ở Connections thì hứa ngược lại.

Những chỗ lời khai lệch file, phát hiện trong lúc hợp nhất: (1) RUN-SUMMARY.md của lần sync nói “đã phát ra 20 task draft tương thích nf-tasks”, nhưng .local/tasks/drafts/ không chứa file draft nào (chỉ có mấy cái từ tháng 6 đã tiêu thụ) — các draft đó chưa bao giờ đáp xuống đĩa; session điều phối đã tạo thẳng task thay thế (phần 6). (2) Đoạn nói về design-system trong port-plan.md khẳng định index.css không có diff; chính gap 1 trong RUN-SUMMARY.md sửa lại điều đó — phần text của plan sai, phần ghi chú gap đúng. (3) Session QC phân tích tại ffab85ca trong khi các con số API của port plan phủ cửa sổ kết thúc sớm hơn 2 commit tại f0d02a28 — không ảnh hưởng tới bất kỳ kết luận nào, ghi lại cho sạch phần citation.

6. Cái gì đã chốt, cái gì còn treo, và sổ task

Đã chốt trong hôm nay (hoặc do QC script là phát biểu sản phẩm mới nhất, hoặc do kiểm chứng bằng code):

  • Sổ cái reservation ghi theo từng lần điều chỉnh, bao gồm cả phần giải phóng âm, là quyết định sản phẩm — đóng lại câu hỏi treo số 3 trong memory về reservation.
  • Persona producer chỉ suy ra từ registration (usePersonaContext là bản canonical; mệnh đề SDU-OR cũ trong usePersona chính thức là code đã nghỉ hưu).
  • Thuật ngữ hiển thị là “Nominations”, “Verification Records”, “Scan History”, và “Claim” chứ không phải “Activate” — chỉ ở tầng hiển thị, tên bảng/domain vẫn còn treo.
  • Việc che dữ liệu được làm ở phía server trong Supabase của Lovable (masking view cộng REVOKE), giải quyết câu hỏi server-hay-client từ tháng 7 cho phạm vi MVP; còn backend thật làm gì thì vẫn treo.
  • reserved >= nominated >= claimed nay là một invariant hạng nhất ở mức STATED, trong đó code mới chỉ cưỡng chế cứng vế claimed.
  • Đích nhắm của QC script là bản Lovable MVP đang chạy, nên đem QC chạy trên monet là một lỗi sai phạm trù.

Thay đổi trên manifest task do session này thực hiện (đều qua bộ công cụ nf-tasks, manifest ở .local/tasks/ACTIVE.md): T74 (hiểu business logic của Lovable) đóng lại là done — KB chính là công việc đó, hoàn thành tới giới hạn mà code trả lời được, phần dư đã được đẩy ra ngoài (lý do ghi trong journal của task). Blocker của T45 được cập nhật để nêu đích danh phán quyết mô hình claim (T87) là cổng chặn quyết định BE build CÁI GÌ. Một journal note gắn vào T20, ghi lại rằng unit 7/12 của port plan thay thế một phần hướng dẫn của nó (viết lại usePartners trước; scanner_facility_assignments bị thay thế vĩnh viễn). Mười một task mới được tạo: T80 (port drift .tier0-quiet trong index.css có trước baseline — chính là món suýt mất trong im lặng), T81 (rebrand button.tsx), T82 (tabs cộng table-pagination dùng chung, phụ thuộc T81), T83 (Partners ra main nav), T84 (copy/chip của supply-chain, phụ thuộc T83), T85 (polish SDU), T86 (gộp danh sách câu hỏi của QC và KB thành một bản hỏi Malcolm đã xếp hạng, trước thứ Năm), T87 (phán quyết mô hình claim, làm tay, đang blocked chờ Malcolm và BE), T88 (kiểm code câu Q10 về CHECK revoked), T89 (siết completeness pass của sync), T90 (quyết định port vỏ ngay hay chờ BE cho 9 unit GAP, làm tay). Mỗi task đều có brief đầy đủ tại .local/tasks/tasks/T<NN>.md. Thay đổi ngày 2026-08-20: T88 đóng lại là done (câu trả lời ghi vào KB Q10 — constraint chưa bao giờ được nới, nên revoke claim của admin đang hỏng ở tầng DB); T91 được tạo cho vụ phơi nhiễm RLS (là task ĐI BÁO Malcolm, vì việc khắc phục không thuộc quyền monet); T86 được mở rộng để mang cả hai phát hiện, với RLS đứng đầu danh sách.

7. Xuất xứ và độ tin cậy (những gì worker session báo mà không nằm trong file)

Vết sẹo mà mọi session sau bắt buộc phải thừa hưởng: working tree trên đĩa của clone Lovable đang lệch khoảng 4.300 commit so với origin/main, vì protocol đồng bộ là fetch-only. Cả hai research agent của QC ban đầu đều báo cáo dựa trên cây cũ đó và kết luận rằng signup, reservation request, override, và claim-verification không tồn tại — đều SAI ở HEAD. Toàn bộ citation đã công bố sau đó được kiểm lại bằng git show / git grep đối chiếu với ref. Chỉ đọc clone qua đúng một đường: git -C .local/lovable-source show origin/main:<path>. Session QC đã lưu điều này thành một memory dạng reference lúc debrief.

Những gì KHÔNG kiểm được, theo chính lời khai của các session: Insights có đang được build bên trong Lovable ngay lúc này hay không (không có truy vấn list_edits nào cho phần việc chưa push của hôm nay — Malcolm nói hôm nay anh ấy fix bug, nên HEAD có thể dịch chuyển trước thứ Năm); hạn mức allocation của P-06 có guard phía server hay không (phía client thì không có); có thứ gì phía server kiểm mật khẩu đăng nhập demo hay không; các công thức funnel của chính server (lần dò DEV ngày 2026-08-03 dùng một tài khoản không có programme nào, nên chưa ai từng thấy response có dữ liệu của /claim-positions/{id}/fibre-programs/{id} — kể cả việc default_reservation_term_months có được trả về hay không); link 404 của /owner/programme-uptake có sống sót qua các đợt viết lại HIG hồi tháng 8 hay không; và quan sát hồi tháng 7 rằng “tile của Tier 4 hiện 0 thay vì 274 MT”. App Lovable đang chạy thì không với tới được ở chế độ headless (vướng auth-bridge), nên mọi thứ mang tiếng “live” đều là suy ra từ code tại ffab85ca.

Những chỗ session tự sửa giữa chừng (đã phản ánh vào file đã công bố): vụ cây cũ ở trên; A-04 được nâng từ “route ghi nhãn sai” lên “mâu thuẫn với phần hiện thực”; giá trị “closed” của po_status được sửa từ mức app-level thành một giá trị enum thật thêm vào DB (migration 20260814091422); câu hỏi treo tháng 7 “việc che dữ liệu nên làm ở server” được đặt lại thành một sự thật đã hiện thực và đã kiểm chứng; và một bug linkifier của md2html biến các citation dạng .md:line thành link http:// sống (vì .md là TLD của Moldova) đã bị bắt và sửa ở cả bộ dựng portal lẫn các bản render đứng riêng — nếu không, cái portal mang tiếng “offline” đã ship kèm 18 link đi ra ngoài.

Cố ý để lại chưa làm, nay đã có task hoặc thuộc về các đợt sau: khoảng 15 file memory cũ đã được đánh dấu cho một đợt dọn vệ sinh (đó là việc của một job flow-dream, không phải hiệu ứng phụ của việc này); bản giải thích luồng bằng tiếng Việt hồi tháng 7 chưa được đối chiếu lại với các phát hiện mới (giữ nguyên như một tài liệu có trước, đã trích dẫn); không ghi gì sang JIRA; và không session nào tự draft task (đúng theo thiết kế — việc hợp nhất này sở hữu manifest, xem phần 6).

8. Hành động tiếp theo đề xuất, kèm người chịu trách nhiệm

Trước hết, user (cùng Malcolm và BE): đặt phán quyết mô hình claim (T87) lên đầu mọi bản hỏi — nó gate 9 unit GAP, toàn bộ domain PO phía BE, đợt wiring của T45, và cả ý nghĩa của section 4-5 trong QC. Thứ hai, trước buổi call thứ Năm: duyệt và gửi danh sách câu hỏi hợp nhất mà T86 sẽ tạo ra (11 câu của session QC cộng các điểm lệch bổ sung từ KB, đã dedupe) — riêng câu trả lời về Insights và về quyền admin để dựng môi trường sẽ quyết định vòng QC có khởi động được hay không. Đặt vụ phơi nhiễm RLS (T91) lên đầu chính message đó: QC sắp chĩa tester vào đúng cái instance mà anon đọc và ghi được các bảng của nó, còn Malcolm thì đang demo nó cho phía business — anh ấy cần biết TRƯỚC khi một trong hai việc đó xảy ra, không phải sau. Thứ ba, và chỉ mình user quyết: chốt T90 (port phần nhìn của 9 unit GAP thành vỏ ngay bây giờ, hay chờ) — nên quyết SAU khi có phán quyết T87, vì restyle một UI propose/confirm rồi bị bỏ đi là kết cục tệ nhất.

Agent chạy được ngay, theo thứ tự: T80 (drift index.css — gỡ bỏ rủi ro mất trong im lặng), rồi T81 rồi T82 (rebrand design-system), rồi T83 rồi T84, và T85 (các bản port thuần UI). Sau khi những cái này vào code, chấp nhận việc tiến cursor bằng python3 .claude/skills/monet-dashboard-lovable/scripts/state.py set-ported f0d02a28... theo đúng RUN-SUMMARY. Song song: T89 (siết completeness pass trước khi lần sync kế tiếp chạy). T88 thì đã xong — câu trả lời nằm ở Hạng 7 phía trên và đã vào danh sách gửi Malcolm.

Team BE, ngay khi T87 có phán quyết: các block beSpecForGap trong .local/lovable/sync-20260819/port-plan.md unit 6-20 đã sẵn sàng nộp thành ticket; quyết định về hết hạn reservation (KB Q6/Q7) cộng với yêu cầu che dữ liệu ngay tại tầng API (session_code_masked) nên đi chung một đợt ticket.

Việc quan trọng nhất cần quyết tiếp theo: phán quyết mô hình claim (T87). Mọi luồng đang bị chặn khác — ticket BE, phạm vi port vỏ, section 4-5 của QC, T45 — đều được gỡ chặn hoặc được định lại phạm vi ngay khi nó có kết quả.