KB-6740 rev 6

Quy trình Quản lý Thực thể — v3.1 (+QT-003R)

9 min read Revision 6
birth-proceduresqt-001qt-002qt-003qt-003rqt-005qt-006v3.1

Quy trình Quản lý Thực thể — v3.1

v3.1 | 2026-05-04 | S193 | +QT-003R retroactive collection registration. Patch narrow từ 12d. v3.0 | 2026-03-22 | S160 | Thống nhất 1 hệ thống. +QT-006 khai tử. Đơn giản hóa QT-003/004. v2.0 | S160 | +QT-003,004,005 cho collections. v1.0 | S159 | QT-001 nhập khai sinh + QT-002 khai trước sinh sau. Luật: Điều 0-G (Khai sinh), Điều 26 (Đếm), Điều 29 v2.0 (Phân loại — 1 hệ thống). Mục tiêu: Thêm collection, loài, cá thể → hệ thống TỰ ĐẾM. Chỉ cần khai sinh.


QT-001: NHẬP KHAI SINH (Backfill — thực thể ĐÃ tồn tại)

Dọn quá khứ. Chạy 1 lần per collection. Xong → QT-002 vĩnh viễn. Áp dụng cho TẤT CẢ collections (governed + observed + excluded). Số lượng collections là dynamic — query collection_registry thay vì hardcode.

BƯỚC 1 — Kiểm tra: species_collection_map có? birth trigger có?
BƯỚC 2 — Đếm: nơi chứa (A) vs nơi sinh (B). Gap = A - B. Nếu 0 → XONG.
BƯỚC 3 — Nhập: dot-birth-backfill --collection=<collection>
BƯỚC 4 — Xác nhận: đếm lại. B' = A → KHỚP ✅. B' ≠ A → investigate.
BƯỚC 5 — Thanh tra: dot-inspect-pen (chỉ governed).

Runtime truth — QT-001 tooling (Pack 21, 2026-05-05). dot-birth-backfill (DOT-118) là backfill tool. Verify state hiện tại trước khi dispatch:

ls -la /opt/incomex/dot/bin/dot-birth-backfill
crontab -l 2>/dev/null | grep birth

Snapshot P2B-INV (2026-05-05): binary present, manual execution only, no cron found. Re-verify trước khi đưa quyết định.


QT-002: KHAI TRƯỚC SINH SAU (Birth-first — thực thể MỚI)

Vĩnh viễn. Mọi DOT tạo entity PHẢI implement. Áp dụng cho TẤT CẢ collections (governed + observed + excluded).

BƯỚC 1 — Kiểm tra loài: species_collection_map + entity_species hợp lệ?
BƯỚC 2 — Tạo khai sinh TRƯỚC: INSERT birth_registry
BƯỚC 3 — Tạo thực thể SAU: INSERT source. FAIL → ROLLBACK birth.
BƯỚC 4 — Xác nhận khớp: cả 2 tồn tại?
BƯỚC 5 — Thanh tra: inspect_pen (governed). Observed/excluded: chỉ verify birth.

Runtime truth — QT-002 enforcement (Pack 21, 2026-05-05). QT-002 là canonical birth process name. Runtime enforcement do PG triggers + gates đảm nhiệm, không có wrapper binary dedicated cho QT-002. Re-verify tool/trigger availability trước khi quyết định:

-- Birth-related triggers
SELECT tgname, tgrelid::regclass FROM pg_trigger
WHERE NOT tgisinternal AND tgname ~ '^(trg_birth_|birth_trigger_)';

-- Verify dot_tools schema first
SELECT column_name FROM information_schema.columns
WHERE table_name='dot_tools' ORDER BY ordinal_position;

-- Then query birth-related DOT tools (adjust column list nếu schema khác):
SELECT code, name, status, operation, file_path
FROM dot_tools
WHERE code ILIKE '%BIRTH%' OR name ILIKE '%birth%'
   OR operation ILIKE '%birth%' OR file_path ILIKE '%birth%'
ORDER BY code;
-- Note: nếu operation/file_path columns vắng mặt, re-check schema trước.

Snapshot P2B-INV (2026-05-05): no QT-002 wrapper binary. Enforcement = fn_birth_registry_auto (AFTER INSERT) + fn_birth_gate (BEFORE INSERT). Trigger counts là dynamic — query pg_trigger thay vì hardcode.


QT-003: KHAI BÁO COLLECTION MỚI

Collection mới PHẢI có species + birth trigger + mô tả TRƯỚC KHI dùng. v1.1 (2026-04-13): +Bước 0 cho collection Lark namespace. +Bước 5 lark_sync_jobs.

BƯỚC 0 — (CHỈ collection từ Lark) Chọn namespace prefix:
  □ larkpc_*     → Lark Phái cử  → species nhóm lark_phai_cu
  □ larkschool_* → Lark Trường học → species nhóm lark_school
  Tên không hợp lệ → reject ngay, không qua bước tiếp.

BƯỚC 1 — Xác định governance_role: governed / observed / excluded
  (Lark namespace mặc định governed, không cho phép excluded)

BƯỚC 2 — Chọn hoặc tạo species:
  □ Governed: tạo species riêng (SPE-xxx) nếu chưa có
  □ Observed/excluded: gom vào species nhóm (SPE-BLK, SPE-OSC...)
  □ Lark: gom vào lark_phai_cu / lark_school, hoặc tạo species con riêng

BƯỚC 3 — Đăng ký: dot-species-map + dot-collection-register (+ purpose bắt buộc)

BƯỚC 4 — Setup birth trigger: dot-birth-trigger-setup

BƯỚC 5 — (CHỈ collection từ Lark) Tạo entry trong PG table lark_sync_jobs:
  job_code, target_collection, lark_base_token, lark_table_id,
  field_whitelist (JSONB list field_id), schedule_cron, enabled

BƯỚC 6 — Verify: fn_registry_health() bắt collection mới + smoke test sync 1 record

QT-003R: KHAI BÁO COLLECTION ĐÃ LỠ TẠO NHƯNG CHƯA DÙNG (Retroactive)

v3.1 (2026-05-04). Biến thể QT-003 cho case: PG table đã tồn tại từ trước nhưng chưa được đăng ký governance và chưa có data rows. Đăng ký trước khi tạo row đầu tiên. Nếu table có >0 rows → STOP, chuyển QT-001 backfill. Thiết kế chi tiết: knowledge/dev/laws/dieu44-trien-khai/design/12d-iu0-pack2a-qt003r-process-addendum.md

BƯỚC 1 — Verify table tồn tại + 0 rows + chưa có collection_registry row.
  □ SELECT count(*) FROM <table> → phải = 0. Nếu >0 → STOP, reclassify QT-001.
  □ SELECT count(*) FROM collection_registry WHERE collection_name = '<table>' → phải = 0.

BƯỚC 2 — Resolve parameters:
  □ governance_role (observed cho pilot, governed cho production)
  □ source_kind (native / derived / registry / policy)
  □ storage_role (primary / junction / log / system)
  □ migration_state (pilot / stable / deprecated)
  □ description theo Đ3 §A.3

BƯỚC 3 — Register qua DOT tool:
  □ dot-collection-register <table> --cloud với parameters từ bước 2.
  □ Không raw SQL INSERT. Không admin fallback.

BƯỚC 4 — Verify:
  □ collection_registry: row tồn tại, parameters đúng.
  □ birth_registry: auto-created row cho COL-NNN.
  □ dot-collection-health: no finding cho table.

BƯỚC 5 — Trigger governance sync (nếu applicable):
  □ dot-schema-trigger-registry-ensure. Nếu tool fail → STOP, ghi TD.

BƯỚC 6 — Declare follow-up:
  □ Trước khi tạo data rows: chốt birth path (QT-002 hoặc domain-specific).
  □ Ghi blocking gate cho pack tiếp theo.

Tiền lệ: Pack 2A (IU-0) — information_unit/unit_version → COL-176/COL-177.


QT-005: THĂNG CẤP / HẠ CẤP COLLECTION

Chuyển governance_role khi business thay đổi.

THĂNG CẤP (observed/excluded → governed):
  BƯỚC 1 — Tạo species riêng (tách khỏi species gom)
  BƯỚC 2 — dot-species-map cập nhật
  BƯỚC 3 — Backfill QT-001
  BƯỚC 4 — UPDATE governance_role = 'governed'
  BƯỚC 5 — Verify fn_registry_health()

HẠ CẤP (governed → observed/excluded):
  BƯỚC 1 — Xác nhận không còn cần inspect chi tiết
  BƯỚC 2 — Gom vào species nhóm (SPE-xxx)
  BƯỚC 3 — UPDATE governance_role
  BƯỚC 4 — Birth records VẪN GIỮ (không xóa)

QT-006: KHAI TỬ (Entity DELETE — MỚI v3.0)

Khai sinh nhiều → khai tử cũng nhiều. Phải quản lý cả 2 chiều.

BƯỚC 1 — Entity bị DELETE trong source collection
BƯỚC 2 — PG trigger cập nhật birth_registry:
  □ SET died_at = now(), status = 'retired'
  □ HOẶC: DELETE birth record (nếu chọn strategy "clean")
BƯỚC 3 — fn_registry_health() phát hiện:
  □ Nơi chứa giảm, nơi sinh vẫn cao → PHANTOM nếu không cập nhật birth
  □ Strategy "clean": birth tự xóa → fn_health vẫn KHỚP
  □ Strategy "archive": birth giữ, filter WHERE died_at IS NULL khi đếm active

STRATEGY LỰA CHỌN (quyết định 1 lần, ghi vào Điều 0-G):
  A) CLEAN: DELETE birth khi entity DELETE → đơn giản, fn_health luôn khớp
  B) ARCHIVE: SET died_at, đếm WHERE died_at IS NULL → lịch sử đầy đủ, phức tạp hơn
  → Đề xuất: CLEAN cho excluded/observed, ARCHIVE cho governed. Hoặc: CLEAN tất cả cho đơn giản.
  → GHI TD: chốt strategy khai tử. Hiện tại chưa có death trigger.

TỔNG KẾT QUY TRÌNH

QT Tên Khi nào Áp dụng cho
QT-001 Nhập khai sinh (backfill) Entity đã tồn tại TẤT CẢ collections (count dynamic — query collection_registry)
QT-002 Khai trước sinh sau Entity mới TẤT CẢ collections vĩnh viễn
QT-003 Khai báo collection mới Collection mới tạo TẤT CẢ
QT-003R Khai báo collection retroactive PG table đã tạo, 0 rows, chưa registry Trước first data row
QT-005 Thăng cấp / hạ cấp Đổi governance_role Khi business thay đổi
QT-006 Khai tử Entity bị xóa TẤT CẢ

Mục tiêu cuối cùng: Thêm collection/loài/cá thể → hệ thống TỰ ĐẾM. Chỉ cần khai sinh (QT-002/003). fn_registry_health() tự cập nhật. Registries tự hiển thị. Operator chỉ GIÁM SÁT.


v3.1 | +QT-003R retroactive. QT-001→006 áp dụng TẤT CẢ collections.