Sửa rẻ - LẬP sổ khái niệm UI
Sửa rẻ - LẬP sổ khái niệm UI
0. Mục tiêu
Quy trình này dùng cho lần đầu lập sổ khái niệm của một UI.
Mục tiêu:
- Đưa khái niệm của UI vào bảng nháp
sua_re_ui_khai_niem_nhap. - So với sổ chung nháp
sua_re_khai_niem_nhap. - Khái niệm cũ thì nối về concept đã có.
- Khái niệm mới thì Owner duyệt rồi mới đưa vào sổ chung.
- Không tạo DOT mới trong G1.
1. Phạm vi G1
G1 chọn PA3:
Agent đọc seed/scan → render SQL template → manifest duyệt → dot-pg-atomic-apply → PG nháp → SELECT/VIEW report
Không làm trong G1:
- DOT mới.
- Directus collection.
- Nuxt UI.
- Promote sang bảng chính thức.
- Vector/report chính thức.
dot-collection-create.dot-report-publish.
2. Quy tắc khóa dữ liệu
2.1. slot_key
slot_key là danh tính bền của một vị trí/đầu mối khái niệm trên UI.
Công thức:
slot_key = ui_id + '::' + location_anchor
Trong đó location_anchor ưu tiên:
config_key:<path> tốt nhất
code_marker:<class> chấp nhận
text_marker:<string> dễ vỡ, chỉ dùng tạm
Cấm đưa các thành phần sau vào slot_key:
raw_labelscan_id- chỉ số mảng như
items[3]
2.2. item_key
item_key là danh tính của một bản ghi slot trong một lần scan.
Công thức:
item_key = slot_key || '::' || scan_id
2.3. raw_label và purpose
raw_label và purpose chỉ là thuộc tính của slot.
Chúng không phải khóa.
Lý do: nếu đưa nhãn vào khóa, sửa nhãn sẽ biến thành xóa bản ghi cũ + thêm bản ghi mới, phá mục tiêu sửa-rẻ.
3. Ghi chú riêng cho pilot master-list
Pilot đầu tiên dùng:
master-list-quy-trinh-v1
Trong pilot này, không bóc lại UI từ đầu nếu đã có seed hợp lệ.
Input seed đã có:
concept-ledger.js: 13 concept.ui-contracts.js: 30 usage.- Kỳ vọng: 27 matched, 2 candidate, 1 review.
Agent phải đọc seed, sinh slot_key, rồi render SQL import.
Không được bóc lại UI thô rồi tạo bộ concept khác, vì sẽ không tái tạo được baseline 27/2/1.
4. Quy trình vận hành
A0. Nhận diện nguồn UI trước khi lập sổ
Trước A1, Agent phải xác định nguồn khái niệm thật của UI nằm ở đâu. Không mặc định bóc DOM, không mặc định tìm một biến cụ thể như MASTER_CONFIG, không mặc định dùng seed.
Thứ tự nhận diện nguồn ưu tiên:
1. structured config inline trong HTML/script;
2. structured config file rời: JSON/YAML/JS module/config object;
3. UI contract/schema/metadata;
4. JS render/computed marker/code marker;
5. DOM/static HTML có marker ổn định: data-*, id, class, role;
6. text_marker chỉ là fallback yếu.
Agent phải ghi rõ:
- primary source đã chọn;
- secondary source nếu có;
- nguồn nào không đọc được;
- cách nhận ra nguồn đó để tái dùng cho UI khác.
Mục tiêu là đọc được UI bất kỳ có cấu trúc, không phải chỉ một UI pilot.
A0a. Bảng SOURCE RECOGNITION RULE R1–R5 (luật chung, tái dùng)
Bảng dưới chuẩn hóa danh sách ưu tiên ở A0 thành luật nhận diện nguồn tái dùng cho mọi UI; dừng ở lớp bền nhất tìm được. Đây là nguồn sự thật gốc của luật nhận diện nguồn (SR-SUA trỏ về đây, không chép lại).
| # | Dấu hiệu nhận ra | Kết luận nguồn | Anchor phát sinh |
|---|---|---|---|
| R1 | Object JS nhúng trong <script>/HTML chứa luồng/field/bước/task/link/status (vd MASTER_CONFIG, PAGE_CONFIG, FLOW_DEF) |
primary structured source | config_key:<path> (strong) |
| R2 | File rời JSON/YAML/JS-module/schema/contract | primary structured source | config_key: / contract_key: (strong) |
| R3 | Không có structured source nhưng JS render sinh nhãn/tổng hợp/marker/computed field | secondary source (bổ sung, không thay primary) | code_marker:<class/fn/key ổn định> (strong) |
| R4 | Không structured, nhưng DOM có data-* / id / class ổn định |
DOM/data marker | data_key: / dom_marker: (medium) |
| R5 | Chỉ còn text hiển thị | text-only fallback | text_marker:<text> (weak) |
Luật phân vai đi kèm:
- (a) Một UI có thể có nhiều nguồn cùng lúc — chọn 1 primary, các nguồn còn lại là secondary/non-source.
- (b) JS chỉ điều hướng/theme/chrome dùng chung ⇒ non-source, không sinh slot khái niệm.
- (c) Nếu một lớp JS đọc được thì phải đọc để không bị trần PARTIAL; nếu không đọc được thì scan phần còn lại, verdict trần PARTIAL, ghi rõ nhóm chưa kiểm.
Hệ quả luật (c): JS-render là secondary source bắt buộc đọc khi UI có code_marker/computed field không nằm trong structured config (vd qv-grp, qv-tot, tổng phút cộng dồn). Chỉ scan config sẽ thiếu các slot code_marker + toàn bộ header render.
(Nguồn: scan thật master-list — báo cáo sr-scan-test-master-list-actual-ui-2026-07-07.md §3.1; áp qua SR-LAP-PATCH-1, 2026-07-08.)
A0b. Một scanner, hai chế độ dùng
Cùng một cách scan UI thật được dùng cho cả lập sổ lần đầu và sửa-rẻ về sau.
SR-LAP: UI scan → PG chưa có slot → new_slot / candidate / review.
SR-SUA: UI scan → PG đã có current slot → unchanged / changed / missing / new_slot.
Không có hai cách đọc UI khác nhau. Lần đầu hay lần sau chỉ khác ở bước đối chiếu PG.
A0c. Scan khái niệm, không scan dữ liệu
Nếu nguồn có mảng/list, anchor phải gộp mảng bằng [].
Ví dụ đúng:
config_key:PAGE.items[].steps[].tasks[].minutes
Ví dụ sai:
config_key:PAGE.items[0].steps[2].tasks[4].minutes
Một thuộc tính xuất hiện ở 1.000 dòng dữ liệu vẫn là 1 slot khái niệm nếu cùng path tổng quát. Sổ này đếm loại thuộc tính/khái niệm UI, không đếm bản ghi dữ liệu.
Luật độ hạt object-leaf (bổ sung từ scan thật master-list): ngoài gộp mảng [] theo chiều dữ liệu, còn gộp các leaf scalar chỉ-cùng-nhau-xuất-hiện trên bề mặt thành 1 slot. Ví dụ maker.t + maker.n luôn đi liền ⇒ 1 slot maker; links.mot + links.moit + links.mout ⇒ 1 slot links. Chỉ tách leaf khi leaf tự nổi độc lập trên bề mặt (người dùng thấy/sửa riêng từng leaf). Phân biệt: [] gộp theo chiều dữ liệu; object-leaf gộp theo chiều đồng-xuất-hiện.
A0d. Hai lớp scan: UI concept và luồng nghiệp vụ
Một UI có thể chỉ là thiết kế giao diện đơn thuần, hoặc có thể chứa cả luồng nghiệp vụ như các UI “4 bà mẹ”. Vì vậy Agent phải phân biệt 2 lớp:
- UI concept layer: field, button, column, status, filter, link, computed display, marker hiển thị. Lớp này ghi vào quy trình sổ khái niệm hiện tại và có thể nạp vào 2 bảng
sua_re_*sau khi Owner duyệt. - Business-flow layer: quy trình, bước, vai trò, trạng thái, điều kiện chuyển bước, đầu vào/đầu ra nghiệp vụ. Lớp này phải scan nếu UI có nguồn cấu trúc rõ, nhưng không nhét lẫn vào 2 bảng sổ khái niệm UI khi chưa có schema riêng.
Trong SR-LAP hiện tại, business-flow layer được lưu trước dưới dạng artifact/report, ví dụ:
/opt/incomex/docs/mcp-writes/sua-re/flow-scan/<ui_id>/<scan_id>.jsonl
Artifact flow tối thiểu nên có:
ui_id, scan_id, flow_key, step_key, actor/role, action, input, output, condition, source_anchor, evidence, note
Khi cần đưa business-flow vào PG để làm hợp đồng thông tin, phải thiết kế bảng riêng hoặc phase riêng; không ép vào sua_re_ui_khai_niem_nhap.
A0e. Scoping page-frame: config khung trang không auto thành khái niệm
Structured config thường chứa cả khung trang (page-frame) lẫn khái niệm domain. Config khung trang — ví dụ title, mother, noun, itemBase, sub, principle, createUrl, createLabel — là page_config, không tự động thành khái niệm quy trình.
Các slot page_config phải đánh needs_review và không auto-import vào sổ khái niệm; để Owner quyết có nâng thành khái niệm hay không. Lý do: khung trang là chrome cấu hình, không phải khái niệm nghiệp vụ của UI; nhét vào sổ sẽ làm phồng số khái niệm bằng dữ kiện không phải domain.
A0f. Concept vs usage: một khái niệm, nhiều điểm bề mặt
Đây là điểm khung chung dễ hiểu sai nhất. Luật anchor priority (config_key > code_marker > text_marker, ở §2.1) áp cho chất lượng anchor của MỘT điểm bề mặt, không phải để bóp bỏ các điểm bề mặt khác.
Một khái niệm có thể hiện ở nhiều nơi cùng lúc: structured config + header cột render + code_marker. Thiết kế 2 bảng tách rõ vai:
sua_re_khai_niem_nhap= concept (1 dòng/khái niệm).sua_re_ui_khai_niem_nhap= usage/location (nhiều dòng/điểm bề mặt).
Vậy 1 concept → nhiều usage row (mỗi điểm bề mặt 1 usage), tất cả dedup về cùng 1 concept_id. Không được vì "đã có config_key bền hơn" mà xóa usage-row của header cột hay code_marker cùng khái niệm. Mỗi điểm bề mặt là một usage thật; anchor priority chỉ chọn anchor tốt nhất cho từng usage đó.
| Bước | Nhiệm vụ | Khi nào bắt đầu / ai ra lệnh / trigger | Ai làm | Yêu cầu sản phẩm hoàn thành | Ghi/lưu ở đâu | Lưu ý |
|---|---|---|---|---|---|---|
| A1 | Chỉ định UI lập sổ | Owner yêu cầu lập sổ cho một UI | Owner | ui_id, ui_file, phạm vi scan |
Prompt hoặc KB task | G1 pilot là master-list-quy-trinh-v1 |
| A2 | Lấy input seed/scan | Sau A1 | Agent | seed hoặc scan artifact đã đọc được | file seed / file scan | Pilot dùng concept-ledger.js + ui-contracts.js, không bóc lại từ đầu |
| A3 | Sinh slot_key và item_key |
Sau A2 | Agent | mỗi usage có slot_key, item_key, anchor_quality |
scan artifact nội bộ / report | slot_key không chứa nhãn, scan_id, index |
| A4 | Render SQL tạo/nạp | Sau A3 | Agent | SQL create/import đã render | /opt/incomex/dot/sql/sua-re/*.sql |
SQL chưa ghi PG nếu chưa qua manifest |
| A5 | Kiểm SQL trước khi duyệt manifest | Có SQL | Agent trình summary; Owner/Fable/GPT soi nếu cần | Summary: file nào, bảng nào, số dòng, thao tác gì | KB/prompt report | Không để Agent tự duyệt mù SQL của chính nó |
| A6 | Cập nhật manifest | SQL đã được chấp nhận | Claude Code/Owner theo lệnh | dòng sha256<TAB>relpath |
/opt/incomex/dot/sql/approved-sql-manifest.tsv |
Manifest là cổng duyệt ghi PG |
| A7 | Apply SQL | Manifest hợp lệ | dot-pg-atomic-apply |
dữ liệu được ghi atomic | PG public.directus |
Không psql tay |
| A8 | Resolve concept khi import | Trong SQL import/apply | SQL qua dot-pg-atomic-apply |
dòng matched được gán concept_id; dòng chưa chắc để null/pending |
sua_re_ui_khai_niem_nhap |
Match có phần ghi: concept_id được resolve ngay khi import; SELECT/VIEW chỉ report |
| A9 | Xuất review report | Sau import/match | Agent chạy SELECT/VIEW read-only | report chỉ gồm review/candidate/delta | KB report | Không bắt Owner xem matched |
| A10 | Owner duyệt pending | Có review report | Owner | quyết định map_existing, create_new, keep_pending |
phản hồi Owner / phiếu decision | AI không tự quyết ca mơ hồ |
| A11 | Apply decision | Owner đã duyệt | Agent render SQL decision + dot-pg-atomic-apply |
usage được nối concept; nếu mới thì insert concept | 2 bảng PG nháp | Một transaction |
| A12 | Báo cáo hoàn tất | Sau A11 | Agent | số concept, usage, matched, review, candidate, new | KB report | Là bằng chứng kết thúc lượt lập sổ |
5. Cơ chế match trong lượt lập sổ
Match không chỉ là SELECT read-only.
Khi import, SQL được phép resolve khớp rõ:
exact concept_key / alias rõ → gán concept_id
không rõ → concept_id null, đưa review/candidate
SELECT/VIEW dùng để:
- kiểm số lượng matched/review/candidate;
- xuất report Owner;
- không ghi dữ liệu.
Không fuzzy auto-match.
6. Hạ tầng/công cụ phục vụ quy trình này
| Hạ tầng/công cụ | Trạng thái | Vai trò |
|---|---|---|
dot-pg-atomic-apply |
đã có | cổng ghi PG duy nhất |
/opt/incomex/dot/sql/ |
đã có | nơi đặt SQL allowlist |
approved-sql-manifest.tsv |
đã có | duyệt SQL bằng sha256 |
sua_re_khai_niem_nhap |
cần tạo | sổ khái niệm chung nháp |
sua_re_ui_khai_niem_nhap |
cần tạo | usage/slot từng UI |
SQL create-core.sql |
cần làm | tạo 2 bảng |
| SQL import seed/full | cần làm | nạp concept + usage |
| SQL decision | cần làm | apply quyết định Owner |
| SELECT/VIEW delta | cần làm | report review/candidate/delta |
7. Tiêu chí PASS của quy trình lập sổ
Với pilot master-list-quy-trinh-v1, PASS khi:
- 2 bảng PG nháp được tạo bằng dot-pg-atomic-apply.
- Concept seed được nạp đúng.
- Usage seed được nạp đúng.
- 30 usage có slot_key hợp lệ.
- Không slot_key nào chứa raw_label, scan_id, hoặc index.
- Tái tạo được baseline 27 matched / 2 candidate / 1 review.
- Review report chỉ hiện dòng cần Owner quyết.
- Không dùng DOT mới.
- Không dùng Directus/Nuxt/vector/promote.
8. Cái không giải quyết trong quy trình này
- Không sửa UI.
- Không xử lý delta sửa-rẻ.
- Không promote sang bảng chính thức.
- Không tạo DOT mới.
- Không chuẩn hóa toàn bộ MO*.
Phần sửa-rẻ sau khi sổ đã lập nằm ở quy trình riêng: sua-re-sua-so-khai-niem-ui.md.