KB-122C

22-P3 — IU Native Create Adapter Scope / Design Note

11 min read Revision 1
pack-22p3designadapterscopefn-iu-create

22-P3 — IU Native Create Adapter Scope / Design Note

Date: 2026-05-06 Author: Opus (Claude) Controlling: GPT P3 directive (gpt-review-22-p2-execution-pass-and-p3-directive-2026-05-06.md) Status: DESIGN — chờ GPT/User review. Không implement, không mutate runtime.


1. P2 Closure Summary

Item Status
fn_iu_create Created, VOLATILE, SECDEF, owner=directus
fn_iu_create_plan Created, STABLE, SECDEF, owner=directus
P2 pilot pilot.p2.20260506-045033.e0ae7ec5 — retained
3-layer verify all_pass=true (i1–i5)
Idempotent exists_complete confirmed
Permissions directus EXECUTE only, PUBLIC revoked
p3_readiness READY
Hard boundaries All honored

P2 delivered: a PG-native complete-or-nothing writer function with full invariant verification before returning created. Birth via existing trigger, not raw insert.


2. Integration Surfaces Inventory

Ai có thể gọi fn_iu_create, và qua đường nào?

2.1 Hiện có (existing callers)

Surface Cách gọi Trạng thái
Agent (Claude Code CLI) docker exec psqlSELECT fn_iu_create(...) Sẵn sàng ngay — Agent đã chạy P2 pilot qua path này
VPS bash scripts Tương tự docker exec psql Sẵn sàng ngay
PG client trực tiếp psql/pgAdmin/DBeaver với role directus Sẵn sàng ngay

2.2 Tiềm năng (chưa build)

Surface Mô tả Cần gì
DOT tool wrapper Shell script gọi fn_iu_create, chuẩn DOT conventions Tạo script + DOT registration
Directus Flow Automation flow gọi PG function qua Run Script hoặc custom operation Tạo flow + test
Directus custom endpoint REST API endpoint expose fn_iu_create Extension code + deploy
Nuxt API route /api/iu/create gọi PG qua server-side Nuxt code + deploy
Batch/import pipeline Script đọc source → gọi fn_iu_create cho mỗi unit Tạo pipeline script

2.3 Existing non-canonical paths (direct INSERT)

Path Mô tả Rủi ro
TAC pipeline (P10A/P10B) Tạo 86+ IUs qua direct INSERT trong SQL blocks Bypass fn_iu_create invariants
Manual psql INSERT Dev/admin insert trực tiếp vào information_unit Bypass birth trigger nếu thiếu required fields
Directus Admin UI Create row qua Directus Data Studio Birth trigger fires nhưng không qua fn_iu_create validation
Future migrations Schema migration scripts có thể INSERT trực tiếp Cần policy

Opus note: TAC pipeline (P10A/P10B) hiện là nguồn tạo IU chính (86 units). Pipeline này INSERT trực tiếp, không qua fn_iu_create. Đây là integration surface quan trọng nhất cần xét — chuyển TAC sang fn_iu_create hay để song song?


3. Canonical Caller Policy

Nguyên tắc

  • fn_iu_create là canonical write path cho IU mới. Mọi IU tạo mới nên đi qua đường này.
  • Direct INSERT information_unit là non-canonical. Chỉ chấp nhận cho: migration, import legacy, schema drift fix — tất cả phải có kiểm soát và audit trail.
  • Non-canonical path phải được monitor như bypass risk. Có thể dùng PG trigger hoặc audit log để phát hiện INSERT không qua fn_iu_create.
  • Incomplete existing states (exists_missing_birth, exists_missing_version, exists_anchor_invalid, exists_duplicate_version, exists_unknown_state) là health/remediation, không phải success. Adapter KHÔNG được coi là create success.

Câu hỏi mở cho GPT/User

  • TAC pipeline (P10A/P10B) hiện INSERT trực tiếp. Có chuyển sang fn_iu_create không? Hay giữ song song với lý do TAC có logic riêng (multi-document validation, content hash, section parsing)?
  • Directus Admin UI create row: có cần block/warn hay chấp nhận vì birth trigger vẫn fire?

4. Adapter Options — Đánh giá

Option A: SQL-only contract (status quo)

Callers gọi SELECT fn_iu_create(...) trực tiếp qua psql.

Tiêu chí Đánh giá
Hardcode risk Thấp — function signature là contract
Permission risk Thấp — chỉ directus role
Simplicity ★★★★★ — không thêm gì
Auditability Trung bình — PG log có nhưng không structured
AI authoring Tốt — Agent gọi psql trực tiếp
Diagnostics/rollback Tốt — function trả JSON chi tiết, EXCEPTION = auto rollback

Opus opinion: Đây là lựa chọn đúng cho hiện tại. Agent đã chứng minh path này hoạt động (P2 pilot). Không thêm layer khi chưa cần.

Option B: Thin CLI/DOT wrapper

Shell script dot-iu-create.sh nhận arguments, gọi fn_iu_create, format output.

Tiêu chí Đánh giá
Hardcode risk Thấp nếu wrapper chỉ forward params
Permission risk Thấp — vẫn qua directus role
Simplicity ★★★☆☆ — thêm 1 file, DOT registration, conventions
Auditability Tốt — DOT tools có structured logging
AI authoring Tốt — Agent gọi shell script thay vì raw psql
Diagnostics/rollback Tốt — wrapper có thể format error output

Opus opinion: Có giá trị khi cần standardize interface cho nhiều agents hoặc cron jobs. Nhưng hiện tại chỉ có 1 agent gọi → overhead chưa justify. Defer.

Option C: Directus Flow/API endpoint

Directus Flow hoặc custom endpoint expose fn_iu_create qua REST.

Tiêu chí Đánh giá
Hardcode risk Trung bình — endpoint code có thể drift khỏi function signature
Permission risk Cao — phải quản lý Directus permissions + API tokens
Simplicity ★★☆☆☆ — cần extension code, deploy, test
Auditability Tốt — HTTP logs + Directus activity
AI authoring Trung bình — Agent gọi HTTP thay vì psql, overhead
Diagnostics/rollback Trung bình — thêm 1 layer error translation

Opus opinion: Có giá trị khi cần UI-facing create hoặc external API. Nhưng hiện tại chưa có use case — IU tạo bởi AI agents, không bởi UI users. Defer.

Option D: Wrapper + endpoint (B + C)

Cả DOT wrapper và Directus endpoint.

Opus opinion: Quá sớm. Hai adapter cho 1 function khi chưa rõ ai cần cái gì. Violates "Assembly First" — thêm layer khi chưa cần.

Option E: Defer adapter, dùng SQL-only contract

Giống Option A nhưng với ý thức rằng đây là quyết định tạm thời: dùng SQL-only cho đến khi có use case rõ ràng cần adapter.

Opus opinion: Đây là khuyến nghị của tôi. Lý do:

  1. Assembly First (Q0 = "PG đã giải quyết chưa?") — PG đã giải quyết. fn_iu_create callable trực tiếp. Không cần thêm layer.
  2. Agent đã chứng minh SQL path hoạt động — P2 pilot tạo thành công qua docker exec psql.
  3. Adapter sẽ rõ hơn sau P10D — khi render layer (Nuxt Laws Page) sẵn sàng, sẽ biết chính xác cần REST endpoint hay không.
  4. DOT wrapper có thể thêm sau bất cứ lúc nào — fn_iu_create signature là contract ổn định, wrapper không cần biết internal logic.

5. Permission Model

Hiện tại

  • directus role có EXECUTE trên cả 2 functions.
  • PUBLIC revoked.
  • fn_iu_create chạy SECURITY DEFINER (owner=directus) → caller chỉ cần EXECUTE, không cần table-level permissions.

Đánh giá

Hiện tại đủ. Lý do:

  • Agent (Claude Code) chạy psql với user directus → có EXECUTE.
  • Directus CMS chạy với user directus → có EXECUTE (nếu cần Flow/endpoint sau).
  • Không có user khác cần gọi fn_iu_create.

Câu hỏi mở

  • Có cần role riêng (ví dụ iu_writer) không? → Opus opinion: chưa cần. Khi có nhiều roles khác nhau cần gọi fn_iu_create với permissions khác nhau, tạo role mới. Hiện tại directus là role duy nhất.
  • Nếu sau này có API endpoint, API user cần EXECUTE → lúc đó GRANT thêm cho API role.

6. DOT Registration Question

Câu hỏi: fn_iu_create có cần thành DOT tool?

Opus opinion: Chưa.

Lý do:

  1. DOT tools là shell scripts wrapping operations. fn_iu_create là PG function, gọi được bằng 1 dòng SQL. Wrapping nó trong shell script chỉ thêm layer.
  2. DOT registration có giá trị cho discoverability và governance. Nhưng fn_iu_create đã visible qua pg_procinformation_schema.routine_privileges. Không bị "vô hình" (§0-AY).
  3. Governance metadata (ai tạo, khi nào, version, tests) đã có trong P2 report + KB documents. Không cần duplicate vào DOT registry.
  4. Health check cho fn_iu_create nên là PG-native (query fn_iu_create_preflight + fn_iu_verify_invariants), không phải DOT shell script.

Khuyến nghị: Nếu sau này cần DOT wrapper (Option B), lúc đó register DOT tool luôn. Không register trước khi có tool.


7. Authoring Workflow After P2

Opus note: Section này ghi nhận tầm nhìn từ GPT. Không phải P3 implementation scope.

GPT đã đề xuất mô hình 2 tầng: AI soạn theo IU từ đầu + render layer.

Opus đánh giá (nhất quán với phản biện trước):

  • Tầm nhìn đúng, nhưng phụ thuộc P10D render layer (chưa build) và fn_iu_create production (vừa xong P2).
  • Hiện tại: dual-form authoring = document trên KB (soạn/review) + IU map khi enacted. Đây là thực tế đang dùng và hiệu quả cho giai đoạn iterate nhanh.
  • Sau P10D: chuyển sang IU-first authoring cho nội dung mới. Legacy/import vẫn document → pipeline cắt.
  • Không enacted thành quy trình trong P3. Ghi nhận, xét lại sau P10D.

Khuyến nghị: Option E (SQL-only contract) + P3-P0 inventory

Bước 1 — P3-P0: Read-only integration inventory (đã hoàn thành phần lớn trong section 2 của document này)

  • Liệt kê tất cả surfaces hiện có và tiềm năng ✅
  • Xác nhận non-canonical paths ✅
  • Đánh giá adapter options ✅

Bước 2 — Quyết định (cần GPT/User)

  • Chọn Option E (defer adapter) hoặc Option B (thin DOT wrapper)
  • Xác nhận TAC pipeline policy: chuyển sang fn_iu_create hay song song
  • Xác nhận non-canonical monitoring approach

Bước 3 — Nếu chọn Option E (Opus khuyến nghị)

  • P3 thực chất là design-only phase. Không có execution prompt.
  • Output = policy document: canonical caller policy enacted.
  • Có thể close P3 ngay sau khi policy được GPT/User duyệt.
  • Chuyển focus sang P10D hoặc Pack tiếp theo.

Bước 4 — Nếu chọn Option B (DOT wrapper)

  • Cần P3 execution prompt: tạo shell script + DOT registration + tests.
  • Scope hẹp: 1 script, 1 registration, smoke test.

Opus strong opinion

Tôi khuyến nghị Option E + close P3 nhanh. Lý do chính:

fn_iu_create đã production-ready. Agent đã chứng minh gọi được. Thêm adapter bây giờ là giải pháp tìm vấn đề (solution looking for a problem). Khi vấn đề thật xuất hiện (nhiều callers, cần REST, cần batch), adapter sẽ tự rõ hình dạng.

Thời gian nên dành cho P10D render layer hoặc TAC pipeline tiếp theo — đó mới là nơi fn_iu_create sẽ được gọi thật trong production.


9. Boundaries — P3 Design Phase

  • ❌ Không function changes, không DDL
  • ❌ Không tạo IU rows, không default seed
  • ❌ Không DOT registration
  • ❌ Không adapter implementation
  • ❌ Không cleanup pilot
  • ❌ Không Pack 2C
  • ❌ Không mutate runtime

22-P3 Design Note | 2026-05-06 | Opus recommendation: Option E (SQL-only) + close P3 as policy-only. Chờ GPT/User review.