KB-6156

G2-1A Time Concept Ledger Delta — READY_FOR_AUDIT

13 min read Revision 1
sua-reg2-1atime-concept-deltaready-for-auditsr-sualedger-onlylaws-newpa32026-07-07

G2-1A Time Concept Ledger Delta — READY_FOR_AUDIT

Ngày: 2026-07-07. Nhiệm vụ: G2-1A — render concept-delta đúng schema thật cho drift "3 giá trị thời gian" (phần tổng phút cộng dồn). Chỉ read-only PG + ghi artifact audit trong mcp-writes. 0 ghi PG, 0 copy vào /opt/incomex/dot/sql, 0 append manifest, 0 apply.

Gate: GO_OPEN_G2_LEDGER_TIME_CONCEPT_DELTA received — yes. Owner phát lệnh nguyên văn trong phiên khi được hỏi trực tiếp (đúng kỷ luật G1-2B: lượt nhận prompt chỉ chứa chuỗi gate trong phần mô tả đã HOLD 0 hành động trước, không tự suy GO).

1. Verdict

READY_FOR_AUDIT

2. Scope

Ledger-only. Schema-aware (information_schema là nguồn cuối cùng). No UI source patch, no rescan, no shadow edit. Không tạo field.tong_thoigian_nhaptay (defer).

3. G1 sealed baseline check

Đối chiếu g1-final-proof-2026-07-07.md + sealed baseline, SELECT read-only trước khi render — PASS toàn bộ:

  • concept = 13; usage total = 31; current = 30; current distinct slot_key = 30; non-current = 1 (chỉ id 11); 0 slot vi phạm 1-current.
  • current match_status = matched 27 / candidate 2 / review 1.
  • id 24/25/30 vẫn keep_pending, không dòng nào khác decided.
  • G1 target: id 11 history + id 31 current (field.so_phut, matched) đúng như sealed.
  • CHƯA có field.tong_phut_congdon; CHƯA có field.tong_thoigian_nhaptay (0 rows).

Re-check sau render: 13/31/30, 0 concept mới, 3 decided, id 13 vẫn current → PG không bị ghi trong suốt G2-1A.

4. Live schema of 2 tables

Đọc information_schema.columns (đủ data_type, is_nullable, column_default, is_generated, generation_expression, is_identity) — 17 + 23 = 40 cột.

public.sua_re_khai_niem_nhap (concept):

Cột Type Nullable Default Ghi chú
id bigint NO IDENTITY ALWAYS — không insert
concept_key text NO NOT NULL không default, unique
ten text NO NOT NULL không default
concept_kind text NO NOT NULL không default (không có trong danh sách dự kiến của đề — schema thật thắng)
mo_ta text NO NOT NULL không default — xác nhận nghi vấn của đề
ranh_gioi text YES cột boundary thật
aliases jsonb NO '[]'::jsonb
match_policy text NO 'auto'
status text NO 'draft' có default → muốn active phải set tường minh
note, first_seen_ui_id/raw_label/scan_id, first_seen_usage_id, contract_ref, promoted_at YES
date_created timestamptz NO now() không insert

KHÔNG có cột canonical_label, KHÔNG có boundary, KHÔNG có near_concepts ở bảng concept — SQL không dùng.

public.sua_re_ui_khai_niem_nhap (usage):

Cột Type Nullable Default Ghi chú
id bigint NO IDENTITY ALWAYS
item_key, slot_key, ui_id, scan_id, raw_label, purpose, location_anchor, dedupe_key text NO NOT NULL không default — INSERT phải điền đủ 8 cột này
ui_file, location text YES
scan_at timestamptz NO now() không insert
is_current boolean NO true
anchor_quality text NO 'strong'
concept_id, owner_concept_id bigint YES
near_concepts jsonb NO '[]'::jsonb
match_status text YES GENERATED ALWAYS: CASE concept_id NOT NULL→'matched'; dedupe_key LIKE 'review.%'→'review'; LIKE 'candidate.%'→'candidate'; ELSE 'pending' — không được INSERT/UPDATE
owner_decision, decision_note, decision_by, decision_at YES
date_created timestamptz NO now() không insert

field.so_phut (id=5, full row):

  • ten: Số phút thực hiện; concept_kind: field; status: active; match_policy: auto; aliases ["min","phút","thời gian thực hiện"]; note/first_seen_*/contract_ref/promoted_at NULL.
  • mo_ta: Thời lượng ước tính của MỘT task, đơn vị phút.ĐÃ hẹp đúng nghĩa từng task — KHÔNG sửa mo_ta (đúng kỳ vọng phản biện).
  • ranh_gioi: KHÔNG phải tổng phút của quy trình (giá trị TÍNH từ các task, không phải khái niệm riêng).cái sai chính nằm ở đây (đúng kỳ vọng phản biện): câu "không phải khái niệm riêng" chặn tổng phút cộng dồn thành concept riêng, trong khi usage id=13 (tổng phút) đang phải trỏ nhờ field.so_phut.

Filter: concept_key='field.so_phut' OR raw_label/purpose ILIKE %phút%/%thời lượng%/%tổng% OR location/anchor ILIKE %qv-tot% → 5 dòng:

id cur slot_key (rút gọn) scan_id raw_label dedupe_key concept status decision classification
7 …items[].n scan_0 Tên việc (task) task task matched KHÔNG phải giá trị thời gian (lọt filter do chữ "phút" trong purpose) — không đụng
11 …items[].min scan_0 Số phút của task field.so_phut field.so_phut matched task_duration_minutes (history G1-5) — giữ nguyên
12 …text_marker:Số phút scan_0 Cột Số phút (ma trận qv) field.so_phut field.so_phut matched task_duration_minutes (cột render phút mỗi task) — giữ field.so_phut
13 …code_marker:qv-tot scan_0 Tổng phút (dòng tổng) field.so_phut field.so_phut matched NULL computed_total_task_minutes — TARGET remap
31 …items[].min scan_g1_5_demo_001 Thời lượng task (phút) field.so_phut field.so_phut matched task_duration_minutes (slot hiện hành) — giữ field.so_phut
  • manual_total_process_duration: KHÔNG có usage nào → chỉ backlog, không tạo concept/usage trong G2-1A.
  • id=13 là dòng computed_total duy nhất → không HOLD_TARGET_NOT_UNIQUE.

7. Target id=13

Điều kiện target: id=13 ✓; is_current=true ✓; match_status=matched ✓; concept_key=field.so_phut ✓; owner_decision IS NULL ✓; raw_label "Tổng phút (dòng tổng)" + purpose "Tổng thời lượng cả quy trình — giá trị TÍNH từ các task." + location_anchor code_marker:qv-tot thể hiện tổng phút cộng dồn ✓; không phải task duration ✓; không phải 24/25/30 ✓.

Full pre-state (lưu để render guard):

  • item_key master-list-quy-trinh-v1::code_marker:qv-tot::scan_0; slot_key master-list-quy-trinh-v1::code_marker:qv-tot; ui_id master-list-quy-trinh-v1; ui_file master-list.js; scan_id scan_0; scan_at = date_created = 2026-07-07 08:18:04+00; is_current true; raw_label Tổng phút (dòng tổng); purpose Tổng thời lượng cả quy trình — giá trị TÍNH từ các task.; location master-list.js · qv-tot; location_anchor code_marker:qv-tot; anchor_quality strong; dedupe_key field.so_phut; concept_id 5; owner_concept_id NULL; near_concepts []; match_status matched; owner_decision/decision_note/decision_by/decision_at NULL.

Pre-check bổ sung: item_key mới …::scan_g2_1_time_concept_001 và scan_id mới chưa tồn tại (SELECT = 0 rows).

8. Proposed delta

  1. create field.tong_phut_congdon — kind field, ten "Tổng phút cộng dồn", mo_ta "Tổng thời lượng tính toán bằng cách cộng thời lượng các task trong một nhiệm vụ/quy trình, đơn vị phút.", ranh_gioi "Đây là giá trị tính toán ở cấp nhiệm vụ/quy trình; không phải thời lượng của từng task và không phải tổng thời gian quy trình nhập tay.", aliases 5 mục, status active tường minh, match_policy để default 'auto'.
  2. update ranh_gioi field.so_phut → "Thời lượng của MỘT task riêng lẻ, đơn vị phút. Không dùng cho tổng phút cộng dồn từ nhiều task, và không dùng cho tổng thời gian quy trình nhập tay." — guard nguyên văn mo_ta + ranh_gioi cũ; không sửa mo_ta.
  3. remap id=13 bằng SR-SUA — UPDATE id=13 current=false (10 guard) + INSERT dòng mới cùng slot_key, scan_id scan_g2_1_time_concept_001, dedupe_key đổi thành field.tong_phut_congdon (dedupe_key cũ là concept key), concept_id qua subquery, giữ nguyên raw_label/purpose/location/anchor/near_concepts, 4 cột decision NULL, không insert match_status/date_created/scan_at.
  4. defer field.tong_thoigian_nhaptay — chưa có usage; chỉ backlog, bài riêng.

9. Change-scope

  • Path: /opt/incomex/docs/mcp-writes/sua-re/change-scope/g2-1-time-concept-delta.jsonl
  • sha256: b7133a7d82296be3cd311a36b6f31dc14f0c9432081ae2086d63c14a378cb39f (4398 B, xác nhận local shasum + VPS sha256sum)
  • 4 object JSONL hợp lệ: 1 meta + 3 action đúng danh sách cho phép (create_concept, update_boundary, remap_usage). Không có patch_ui_source / rescan / create field.tong_thoigian_nhaptay / modify id 24/25/30.
  • JSONL mô tả quyết định, không phải nguồn apply tự động.
  • Thư mục sua-re/change-scope mới tạo (chown 10001:10001, chmod 2775 — pattern G1).

10. Golden SQL

  • Path: /opt/incomex/docs/mcp-writes/sua-re/golden/concept-delta-time-values-g2-1.golden.sql
  • sha256: 23ced9a4cc0e6eeffa8c73233d824584aed9a82849bb50d9d1278dcb5e0478c0 (6440 B, xác nhận 2 phía)
  • Đúng 4 statement write theo thứ tự: INSERT concept → UPDATE ranh_gioi → UPDATE usage 13 current=false → INSERT usage mới. Kỳ vọng output: INSERT 0 1 / UPDATE 1 / UPDATE 1 / INSERT 0 1.
  • Không BEGIN/COMMIT (gate psql -1 tự bọc). Không ON CONFLICT, không DDL, không DELETE, không ghi match_status (chỉ đọc trong WHERE guard), không nhắc id 24/25/30, không tạo concept type-3.
  • Fail-closed: unique concept_key chặn concept trùng; unique item_key + ux_sruk_slot_current chặn INSERT usage nếu statement (3) không hạ current cũ → transaction abort.
  • CHƯA copy vào /opt/incomex/dot/sql/sua-re/ (ls xác nhận chỉ 4 file G1), CHƯA append manifest (vẫn 8 dòng, 0 dòng g2), CHƯA apply (PG counts nguyên 13/31/30).

11. Self-check

# Mục Kết quả
1 Đã đọc information_schema 2 bảng (40 cột, đủ nullable/default/generated/identity) PASS
2 SQL không dùng cột không tồn tại (không canonical_label/boundary/near_concepts ở concept) PASS
3 SQL điền đủ NOT NULL không default (concept 4 cột; usage 8 cột) PASS
4 Concept insert có mo_ta (NOT NULL bắt buộc) PASS
5 status='active' tường minh (default 'draft'; so_phut active) PASS
6 Boundary update dùng đúng cột thật ranh_gioi PASS
7 Không sửa mo_ta (đã đúng nghĩa task; chỉ dùng trong WHERE guard) PASS
8 SR-SUA: UPDATE old current=false trước, INSERT new current=true sau PASS
9 item_key mới = slot_key ‖ '::' ‖ scan_g2_1_time_concept_001; pre-check 0 rows PASS
10 Không INSERT/UPDATE match_status PASS
11 Không copy SQL sang apply path PASS
12 Không append manifest (8 dòng nguyên) PASS
13 Không apply (0 dot-pg-atomic-apply; PG nguyên) PASS
14 Không đụng/nhắc id 24/25/30 trong SQL PASS
15 Không UI patch, không sửa shadow/preview PASS
16 Không tạo concept type-3 (tong_thoigian_nhaptay chỉ xuất hiện trong text ranh giới + backlog defer) PASS
17 G1 baseline còn nguyên (check trước render + re-check sau render) PASS

17/17 PASS.

12. Owner decisions needed before G2-1B

Owner cần chốt tường minh 4 điểm trước khi mở G2-1B (copy apply path + manifest + apply qua gate):

  1. Đồng ý tạo field.tong_phut_congdon (ten/mo_ta/ranh_gioi/aliases như mục 8.1)?
  2. Đồng ý text ranh_gioi mới của field.so_phut (mục 8.2)?
  3. Đồng ý remap usage id=13 bằng SR-SUA (id=13 thành history, dòng mới current trỏ concept mới)?
  4. Đồng ý defer field.tong_thoigian_nhaptay sang bài riêng?

13. Caveat

  • Shadow/preview files không phải UI source thật; G2-1A không đọc/không sửa chúng (dữ liệu lấy từ PG + KB).
  • Chưa có scan/re-scan pipeline — scan_id scan_g2_1_time_concept_001 là scan-id thủ công cho delta ledger, như khuôn G1-5.
  • G2-1A chỉ ledger — dòng tổng phút trên UI thật không đổi gì; đây là sửa sổ khái niệm.
  • Schema thật (information_schema) là nguồn cuối cùng — mọi cột trong SQL đã đối chiếu schema đọc 2026-07-07; nếu schema đổi trước G2-1B, phải re-check.
  • Guard UPDATE (statement 2/3) không tự abort khi UPDATE 0 (transaction vẫn commit các statement khác) — verifier G2-1B bắt buộc đối chiếu 4 dòng affected-count với kỳ vọng INSERT 0 1 / UPDATE 1 / UPDATE 1 / INSERT 0 1; INSERT (1)/(4) đã fail-closed bằng unique constraint + ux_sruk_slot_current.
  • Sau khi G2-1B apply thành công, sealed baseline G1 (concept 13/usage 31) sẽ lỗi thời theo thiết kế — phải tạo sealed baseline mới (đã ghi trong g1-final-proof mục 8).
Back to Knowledge Hub knowledge/dev/laws-new/kestra/sua-re/nhap-ui/g2-1a-time-concept-ledger-delta-ready-for-audit-2026-07-07.md