Codex review — Kế hoạch nháp UI v0 / Sửa rẻ
Codex review — Kế hoạch nháp UI v0 / Sửa rẻ
Date: 2026-07-06
Agent: Codex
Scope: Review only. No DB write, no DDL, no Nuxt edit. Production checks were read-only SELECT/GET, except no mutation DOT was executed.
Verdict: HOLD
One-line reason: GĐ1 is feasible and worth doing, but the plan cannot run as written because seed JS files are not present/verified, the proposed PK shape is risky for existing table molds, and the required custom writable PG-table DOT/rollback is not already available.
0. 3 câu Tuyên ngôn
-
Vĩnh viễn?
Do not build a one-off UI counter. Keep the root fix in PG: a draft usage ledger with stable dedupe keys and a concept catalog, written only by DOT, queryable bycount(distinct dedupe_key). -
Nhầm được không?
Not yet if executed as written. Current gaps: no hard DB uniqueness for current scan, no verified seed source, no custom rollback DOT, and localSharedDirectusTableassumesid. Must add DOT verify/rollback and useidPK before execution. -
100% tự động?
Not yet. GĐ1 needs a DOT-B import path plus DOT-A verify path. Manualpsql, manual inserts, or manual Directus edits must remain forbidden.
1. Documents / luật / skill read
.claude/skills/incomex-rules.md: 36 mục / 8 bước read.search_knowledge("operating rules SSOT"): hitknowledge/dev/ssot/vps/vps-operating-rules.md, Version 1.0, Date 2026-02-28, Status Active.search_knowledge("hiến pháp v4.0 constitution"): active hit isknowledge/dev/laws/constitution.md, title says v4.6.3 BAN HÀNH, not v4.0.search_knowledge("law-01-foundation-principles DOT 100% Assembly First PG first metadata code Nuxt màn hình dual-trigger"): hitknowledge/dev/laws/law-07-assembly-first.md.search_knowledge("DOT Cấp A Cấp B paired DOT verify COUNT thật dual-trigger AP-12 AP-16"): hit DOT Usage Handbook and Điều 35 DOT Governance v5.2.search_knowledge("UI v0 plan pivot registry table module DirectusTable Registry 3-layer UI Nuxt dynamic metadata code"): hit Table Module SSOT v4.1, Registries-Pivot, related reports.- Full read:
knowledge/dev/laws-new/kestra/sua-re/nhap-ui/ke-hoach-nhap-ui-v0.mdfrom Agent Data, revision 2. - Full read:
knowledge/dev/ssot/table-module/index.md, revision 11. - Full read:
knowledge/dev/laws-new/pg-read-pg/old-delete/runbook-reports-mvp.md.
Important stale-input note: the user prompt mentions constitution v4.0, but KB active constitution hit is v4.6.3. Do not cite DFL v1.1 / constitution v3.9.
2. Field evidence
2.1 Plan exists in KB, not local checkout
Local:
sed: knowledge/dev/laws-new/kestra/sua-re/nhap-ui/ke-hoach-nhap-ui-v0.md: No such file or directory
find: knowledge/dev/laws-new/kestra/sua-re: No such file or directory
Agent Data:
document_id: knowledge/dev/laws-new/kestra/sua-re/nhap-ui/ke-hoach-nhap-ui-v0.md
title: Kế hoạch — Sửa rẻ / Nháp UI v0 (Rev 2...)
revision: 2
Risk: source sync gap. The plan is in KB, not in this local workspace.
2.2 Production PG is PG16 / DB directus
Read-only query:
db | schema | pg_version
directus | public | PostgreSQL 16.13 ... 64-bit
Proposed tables do not exist yet:
public | balo_thuc_the
public | collection_registry
public | directus_collections
public | directus_fields
public | entity_species
public | meta_catalog
public | species_collection_map
public | table_registry
No sua_re_khai_niem_nhap or sua_re_ui_khai_niem_nhap in that list.
2.3 Reports/table_registry reality
Production:
table_registry_total | 28
view_name_not_null | 2
view_sql_not_null | 2
collection_not_null | 28
Sample:
tbl_report_home | Reports Home | v_report_home | /reports | view_name=v_report_home | has_view_sql=t
tbl_report_pg | PG Census | v_report_pg | /reports/report-pg | view_name=v_report_pg | has_view_sql=t
tbl_loai | Loài | entity_species | /reports/report-loai | view_name NULL | has_view_sql=f
tbl_balo_table | Balo — Table | balo_thuc_the | /reports/report-balo-table | view_name NULL | has_view_sql=f
v_report_home and v_report_pg are BASE TABLE, not PG VIEW:
public | v_report_home | BASE TABLE
public | v_report_pg | BASE TABLE
Conclusion: Rev 2 is right that Directus/SharedDirectusTable reads collections. But it is too broad when saying reports do not use view_sql: two report snapshot rows still use view_sql/view_name metadata.
2.4 Report mold production pass
Public HTTP:
home_http=200 bytes=281753
pg_http=200 bytes=291525
loai_http=200 bytes=349674
/reports/report-balo-function
/reports/report-balo-table
/reports/report-balo-trigger
/reports/report-balo-view
/reports/report-loai
/reports/report-pg
dot-verify-loai-report read-only output:
PG_COUNT=42 API_COUNT=42 PK=id
CHECK 8.1-count PASS pg==api==42
ROW=Loài|entity_species|id|NULL|composition_level,display_name|true|true|50|NULL|/reports/report-loai
CHECK 8.2-fields PASS 5 data cols correct key/label/order (STT synthetic)
CHECK 8.5-home PASS Home keeps 5 old reports + Loài = 6
CHECK prod-detail PASS SSR shows headers (3/3) + species 'No-Vector Staging Zone'
DOT_VERIFIED: PASS
Conclusion: report/list/table mold is production-ready.
2.5 Species reality
Production:
catalog | SPE-CAT | Danh muc he thong | atom | governed | CAT | active
collection | SPE-COL | Collection | molecule | governed | COL | active
page | SPE-PGE | Trang UI | molecule | governed | PG | active
table_ui | SPE-TBL | Bang UI | molecule | governed | TBL | active
task | SPE-TSK | Nhiem vu | compound | governed | TSK | active
workflow | SPE-WKF | Quy trinh | compound | governed | WF | active
workflow_step | SPE-WFS | Buoc quy trinh | molecule | governed | ND | active
SPE-NVS | SPE-NVS | No-Vector Staging Zone | 1 | governed | IUS | active
Existing maps:
catalog -> meta_catalog
collection -> collection_registry
page -> ui_pages
table_ui -> table_registry
workflow -> workflows, workflow_categories
workflow_step -> workflow_steps, workflow_step_relations
Conclusion: do not create a new workflow/quy-trinh species. For GĐ1, defer species. For GĐ2, prefer catalog for the concept catalog; avoid workflow and avoid table_ui unless the table itself is a UI-table config.
2.6 species_collection_map idempotency is not structurally enforced
Production constraints show no unique index on (species_code, collection_name). Actual duplicate exists:
species_code | collection_name | n
pivot_result | pivot_results | 2
Conclusion: plan's "idempotent" rule must be DOT-enforced/readback-verified. Current DB does not make duplication impossible.
2.7 Seed JS not found
Local:
find . -type f \( -name 'concept-ledger.js' -o -name 'ui-contracts.js' -o -name 'verify-contracts.js' \) -print
Output: empty.
Agent Data search for concept-ledger.js ui-contracts.js verify-contracts.js 13 khái niệm 30 usage items did not return the seed files, only unrelated UI docs.
Conclusion: "13 concepts / 30 usage rows" is unverified. GĐ1 migration from JS is HOLD until seed content is supplied or reconstructed as an explicit JSON/CSV artifact.
2.8 DOT/khuôn inventory
Local repo has:
dot/bin/dot-collection-create
dot/bin/dot-collection-register
dot/bin/dot-schema-apply
dot/bin/dot-schema-snapshot
dot/bin/dot-schema-diff
dot/bin/dot-species-map
dot/bin/dot-species-register
dot/bin/dot-registries-verify
...
Production VPS additionally has:
dot-report-publish
dot-list-publish
dot-collection-track-readonly
dot-verify-loai-report
Relevant behavior:
dot-collection-create: creates a new table and Directus collection, then registry/meta/birth/species/permissions. It is B, paired withDOT-COL-HEALTH.dot-collection-track-readonly: tracks an existing PG base table into Directus read-only without touching the table.dot-list-publish: writes onlytable_registryconfig for an already tracked live collection.dot-report-publish: creates/refreshes^v_report_base-table snapshots fromview_sql; not suitable for arbitrary writable draft tables.dot-collection-health: A/self-healing and can write fixes/system_issues. Do not run in a read-only review session.dot-rollback: local version rolls back DOT flows only; not a generic DDL/table rollback.
3. Những điểm kế hoạch đúng
- PG-first is correct for the real problem:
count(distinct dedupe_key)is a DB job. - Separating "concept definition" from "UI usage occurrence" is the right model.
- Keeping v0 exact/alias/ILIKE and deferring pg_trgm/Qdrant is correct.
- GĐ1 and GĐ2 must be separated. PG count must work before reports/species/balo.
- Do not create a new "quy trình" species.
workflowalready exists. - Portal/report should reuse
table_registry+ SharedDirectusTable/list/report molds. purpose NOT NULL CHECK length(trim(purpose)) >= 15is a useful cheap guard, though not sufficient as semantic quality.dedupe_key NOT NULLis necessary for the count-after-dedupe metric.status='draft'and_nhapnaming are correct to avoid confusing draft with official metadata.- Hoãn pg_trgm/Qdrant/tab UI is correct.
4. Những điểm sai hoặc nguy cơ sai
-
GĐ1 cannot migrate 13/30 as written. The JS seed files are not present in local workspace or retrieved from KB search.
-
The proposed PK shape is risky. Local
web/composables/useDirectusTable.tsalways addsidand countsaggregate count id; it does not referenceprimary_key. Ifsua_re_khai_niem_nhapusesconcept_idas the only PK orsua_re_ui_khai_niem_nhapuses onlyitem_id, later list/report may break unless production code differs. Safer minimal shape: keepid bigserial primary key, and makeconcept_key/item_keyunique business keys. -
"Reports do not use view_sql" is partially false. Production has two
table_registryrows withview_sql/view_name:tbl_report_home,tbl_report_pg. Correct statement: live list reports can use direct collections withview_sql NULL; snapshot reports usedot-report-publishandview_sql. -
No existing generic DOT creates these exact custom writable draft tables while deferring Directus.
dot-collection-createwould create/register a Directus collection immediately.dot-schema-applyadds Directus fields but does not express the needed PG CHECKs/partial indexes/scan-current guard. A mission-specific DOT is required unless the plan accepts Directus registration in GĐ1. -
Rollback is underspecified. Existing
dot-rollbackis for Directus flows, not dropping tables/registry rows. A new DOT must include--rollbackallowlisted to the two table names or a documented rollback DOT. -
scan_id + is_currentis queryable but not hard enough by itself. Multiple current scan_ids for the same UI can still be inserted unless writes are exclusively via DOT transaction + verify, or a trigger/scan table enforces it. For v0, DOT transaction + post-write fail/rollback is acceptable if strictly enforced. -
species_collection_mapidempotency is not DB-enforced. Duplicatepivot_result/pivot_resultsalready exists. Any GĐ2 species map needs precheck + readback output; do not rely onON CONFLICT DO NOTHING. -
Local repo is stale vs production. Local lacks
dot-report-publish,dot-list-publish,dot-collection-track-readonly, and/reportspages. Production has them and routes pass. Any code/source change must first address this sync gap; do not "rebuild" these molds locally. -
loaicolumn name in concept table conflicts with Incomex terminology. In this system "loài" isentity_species. Useconcept_kindfor workflow/step/task/field/role/org to avoid misrouting agents. -
GĐ2 balo/species/table_registry is not required for the original Cowork count. Doing it before the PG count works would create governance surface without proving the core value.
5. Things already available and should be reused
- PostgreSQL 16.13 production DB
directus. - Directus system metadata:
directus_collections,directus_fields,directus_permissions, policies. - Existing registries:
collection_registry(168),meta_catalog(169),table_registry(28),entity_species(42),species_collection_map,balo_thuc_the. - Existing table/list/report molds:
SharedDirectusTable/ DirectusTable.- Production
/reportsgeneric route. dot-report-publishfor snapshot report tables.dot-list-publishfor live Directus lists under/reports.dot-collection-track-readonlyfor tracking existing PG tables without recreating them.
- Existing DOTs:
dot-schema-snapshot,dot-schema-diffdot-collection-create,dot-collection-register,dot-schema-applydot-species-map,dot-species-registerdot-registries-verify,dot-verify-loai-reportdot-collection-healthonly after approval because it self-heals/writes.
Do not create a new UI registry, page registry, field registry, species registry, or report renderer.
6. Proposed minimal schema after review
6.1 sua_re_khai_niem_nhap
Use an id PK for mold compatibility; use a stable business key separately.
id bigserial primary key,
concept_key text not null unique,
ten text not null,
concept_kind text not null check (concept_kind in ('workflow','workflow_step','task','field','role','org','other')),
mo_ta text not null check (length(trim(mo_ta)) >= 15),
ranh_gioi text,
aliases jsonb not null default '[]'::jsonb,
status text not null default 'draft' check (status in ('draft','active','retired')),
note text,
date_created timestamptz not null default now(),
date_updated timestamptz not null default now()
Change vs plan:
- Replace
concept_id varchar PKwithid+concept_key unique. - Replace
loaiwithconcept_kind. - Drop
match_policyfrom v0 unless a DOT actually uses it.
6.2 sua_re_ui_khai_niem_nhap
id bigserial primary key,
item_key text not null unique,
ui_id text not null,
ui_name text,
ui_file text,
scan_id text not null,
scan_at timestamptz not null default now(),
is_current boolean not null default true,
raw_label text not null,
purpose text not null check (length(trim(purpose)) >= 15),
location text,
dedupe_key text not null,
concept_id bigint references sua_re_khai_niem_nhap(id) on delete restrict,
match_status text not null default 'raw'
check (match_status in ('raw','matched','candidate','review','deferred')),
suggested_concept_id bigint references sua_re_khai_niem_nhap(id) on delete restrict,
owner_note text,
date_created timestamptz not null default now(),
date_updated timestamptz not null default now(),
check (match_status <> 'matched' or concept_id is not null)
Minimal indexes:
create index on sua_re_ui_khai_niem_nhap (ui_id, is_current, scan_id);
create index on sua_re_ui_khai_niem_nhap (ui_id, scan_id, dedupe_key);
create index on sua_re_ui_khai_niem_nhap (match_status) where is_current;
create index on sua_re_ui_khai_niem_nhap (concept_id) where concept_id is not null;
No scan table in v0 if DOT import guarantees:
- update old current rows for
ui_idtois_current=false; - insert new scan rows;
- verify no
ui_idhas more than one currentscan_id; - rollback if verification returns rows.
If that guard must be DB-impossible without trusting DOT, add a scan table. Otherwise defer scan table.
7. Proposed execution
GĐ1 — minimal and PG-first
Do only this:
- Recover/freeze seed payload:
- Either provide
concept-ledger.js+ui-contracts.js, or create a reviewed JSON/CSV seed artifact. - Record
PG is draft SSOT from YYYY-MM-DD HH:mm +07in the seed report/readme.
- Either provide
- Run
dot-schema-snapshotbefore any Directus-visible change if using Directus; for PG-only table, captureinformation_schemabefore snapshot in the mission DOT. - New DOT-B:
dot-sua-re-nhap-ui-v0-ensure- create the two tables, constraints, indexes, update timestamps;
- allowlisted rollback mode for exactly those two tables;
- no Directus collection/table_registry/species/balo in this step.
- New DOT-B:
dot-sua-re-nhap-ui-v0-import- import seed/scans idempotently by
item_key/concept_key; - update old
is_current=falsebefore inserting current scan rows; - no manual insert.
- import seed/scans idempotently by
- New DOT-A:
dot-sua-re-nhap-ui-v0-verify- row counts, distinct dedupe counts, unmatched/candidate counts;
- current-scan invariant query;
- expected seed count if seed is provided;
- paste real SELECT output.
Stop after PG count output. Do not surface in /reports yet.
GĐ2 — only after GĐ1 passes
Use existing molds; do not create new UI:
dot-collection-track-readonlyfor each existing PG table if it must be served by Directus read-only.dot-list-publishfor live/reports/report-...list pages.dot-report-publishonly for derived snapshot reports namedv_report_*, not for the draft source tables.dot-species-maponly after choosing the species. Recommended:- concept catalog table:
catalog; - usage ledger: defer, or use
catalogif it is published as a draft catalog/ledger; - avoid
workflow; avoidtable_uiunless it is actually a UI-table configuration.
- concept catalog table:
balo_thuc_the: add only after the table is stable enough to inventory; usekhoa_nhan_dien='table:public.<name>'.- Run
dot-verify-loai-reportas canary if touching/reports.
Hoãn tuyệt đối
- pg_trgm, Qdrant, fuzzy auto-match.
- Nuxt code changes.
- New species.
- New page/report mold.
- Scan table unless DOT guard proves insufficient.
- Balo/species/table_registry until PG count works.
8. DOT list
Reuse existing
dot-schema-snapshot/DOT_SCHEMA_SNAPSHOT: Directus schema snapshot when Directus-visible changes happen.dot-schema-diff/DOT_SCHEMA_DIFF: Directus schema diff.dot-collection-track-readonly(VPS): track existing PG table read-only in Directus.dot-list-publish(VPS): publish live collection list to/reports.dot-report-publish(VPS): publish/refresh snapshot report tables^v_report_.dot-verify-loai-report(VPS): read-only canary for species/report path.dot-species-map/DOT-145: species map after GĐ1.dot-collection-register/DOT-120: collection_registry registration if required.dot-registries-verify/DOT-102: registry verification.
Do not use for this GĐ1 as-is
dot-collection-create: creates Directus collection immediately and standard fields; not the custom PG-only draft table shape.dot-report-publish: only forv_report_*snapshots, not source draft tables.dot-collection-health: can self-heal/write; not read-only.dot-rollback: rollback flows only; not table rollback.
Minimal new DOTs
-
dot-sua-re-nhap-ui-v0-ensure— Cấp B
Create/ensure the two draft tables, constraints, indexes, timestamps, and allowlisted rollback. -
dot-sua-re-nhap-ui-v0-import— Cấp B
Import seed/scans idempotently and enforce current-scan flow. -
dot-sua-re-nhap-ui-v0-verify— Cấp A
Read-only verification paired to both DOT-Bs. Should be runnable manually and later by cron.
This is the minimum if GĐ1 remains PG-only and custom constrained. If Owner accepts Directus collection in GĐ1, reuse dot-collection-create + dot-schema-apply, but custom CHECK/current-scan guards still need a patch/DOT.
9. Owner questions
Only these need Owner:
- Provide/approve the seed source: actual
concept-ledger.js+ui-contracts.js, or approve a reconstructed JSON/CSV seed. Without this, the 13/30 counts are not evidence. - Confirm whether GĐ1 tables are PG-only draft tables, or Directus-visible collections from day one. Recommendation: PG-only in GĐ1.
- Confirm whether draft UI data must never be embedded/vectorized. If yes, use
SPE-NVS/staging governance when registering; if no, defer species until GĐ2.
Technical decisions not needing Owner:
- Use
idPK plus unique business keys. - Do not create a new species.
- Do not touch Nuxt in GĐ1.
- Do not use
workflowfor these draft tables.
10. Risk checklist before any DOT run
- Seed artifact exists and expected counts are written down.
-
dot-sua-re-nhap-ui-v0-ensure --dry-runprints the exact two table names only. - Rollback mode exists and is allowlisted to only those two table names.
- Verify DOT includes the current-scan invariant query:
SELECT ui_id, count(DISTINCT scan_id)FROM sua_re_ui_khai_niem_nhapWHERE is_currentGROUP BY ui_idHAVING count(DISTINCT scan_id) > 1; - Verify DOT prints
count(*),count(distinct dedupe_key), match-status counts, and sample rows. - No Directus collection/table_registry/species/balo writes in GĐ1.
- If moving to GĐ2, production-only DOTs (
dot-list-publish,dot-report-publish,dot-collection-track-readonly) are synchronized or explicitly run on VPS per runbook. - If species mapping is done, check for duplicate map first because DB lacks composite unique constraint.
- Paste real output, not only "PASS".
11. Step report 0→6
- Bước 0: Read skill, OR, constitution, DOT/Assembly/Table/Reports laws via Agent Data.
- Bước 1: Mission confirmed as review only; no DB mutation and no code/Nuxt change.
- Bước 2: Design review done. Condition-needed gap found: missing seed files and missing custom DOT pair.
- Bước 3: No production code written. Local report files only.
- Bước 4: No deploy/PR because this is review-only.
- Bước 5: Production verification used read-only SELECT/GET and
dot-verify-loai-report; output pasted above. - Bước 6: Report written at
knowledge/current-state/reports/ui-v0-plan-field-review-2026-07-06.md; KB upload target should also receive this content.
Final: HOLD execution as written. PASS_TO_GD1 only after seed source and the minimal DOT-A/B pair are in place.