P9 E1–E3 Read-only Design Pack v0.2
E1–E3 Read-only Design Pack v0.2
Phase: P9 Entry Gate, E1–E3 Trạng thái: DRAFT v0.2 — Patched 3 điểm GPT. Chờ GPT final + User. Ngày: 2026-04-27 | Phiên: S182
E1 — fn_log_issue / system_issues (COMPLETED)
Result: PASS — adapter feasible without ALTER.
Full report: knowledge/draft/p9-e1-fn-log-issue-verify-2026-04-27.md
Key: fn_log_issue = plain INSERT, no dedup, severity chỉ critical/warning/info, không ghi coalesce_key.
R3 — Checker Adapter Design (dựa trên E1)
R3.1 Wrapper contract
fn_tac_log_checker_issue(
p_checker_id TEXT, -- P6 checker ID, e.g. 'DOT-LU-01'
p_severity TEXT, -- P6 vocabulary: BLOCK/ERROR/WARN/INFO
p_entity_code TEXT, -- canonical_address
p_summary TEXT, -- finding summary
p_details JSONB DEFAULT NULL
) RETURNS INTEGER
R3.2 Field mapping contract (full chain)
| P6/P8 field | Wrapper param | fn_log_issue param | system_issues column | Dedup key? |
|---|---|---|---|---|
| checker_id | p_checker_id | p_source | source | ✅ YES |
| severity | p_severity | p_severity (mapped) | severity | ❌ |
| category | p_checker_id | p_issue_type | issue_type | ❌ |
| entity_code | p_entity_code | p_entity_code | entity_code | ✅ YES |
| summary | p_summary | p_title | title | ❌ |
| details | p_details | p_evidence | evidence_snapshot | ❌ |
| issue_signature | (computed) | — | coalesce_key (backfill) | ✅ YES (= dedup key itself) |
R3.3 Dedup contract (cụ thể)
Dedup key definition:
coalesce_key = md5(p_checker_id || '|' || p_entity_code)
Rationale: Cùng checker + cùng entity = cùng violation. Severity/summary có thể thay đổi giữa runs nhưng violation identity không đổi.
Dedup logic trong wrapper:
-- Step 1: Compute dedup key
v_dedup_key := md5(p_checker_id || '|' || p_entity_code);
-- Step 2: Check existing open issue with same key
SELECT id, severity INTO v_existing_id, v_existing_severity
FROM system_issues
WHERE coalesce_key = v_dedup_key AND status = 'open'
LIMIT 1;
-- Step 3a: Existing → UPDATE (escalate severity + refresh timestamp)
IF v_existing_id IS NOT NULL THEN
UPDATE system_issues SET
last_seen_at = NOW(),
occurrence_count = COALESCE(occurrence_count, 1) + 1,
severity = CASE
WHEN v_mapped_severity_rank > v_existing_severity_rank
THEN v_mapped_severity
ELSE severity
END,
title = p_summary, -- refresh summary
evidence_snapshot = p_details -- refresh evidence
WHERE id = v_existing_id;
RETURN v_existing_id;
END IF;
-- Step 3b: New → INSERT via fn_log_issue + backfill coalesce_key
v_new_id := fn_log_issue(
p_checker_id, -- source
v_mapped_severity, -- severity (mapped)
p_summary, -- title
NULL, -- description
'tac_logical_unit', -- entity_type (or derive from checker)
p_entity_code, -- entity_code
p_checker_id, -- issue_type = checker_id
p_details, -- evidence
NULL, -- run_id
'open' -- status
);
-- Backfill coalesce_key (fn_log_issue doesn't write it)
UPDATE system_issues SET coalesce_key = v_dedup_key WHERE id = v_new_id;
RETURN v_new_id;
R3.4 Severity mapping
| P6 vocabulary | Wrapper maps to | fn_log_issue accepts |
|---|---|---|
| BLOCK | critical | ✅ |
| ERROR | critical | ✅ |
| WARN | warning | ✅ |
| INFO | info | ✅ |
Severity rank for escalation: critical=3, warning=2, info=1.
R3.5 Dedup guarantees
| Guarantee | Mechanism |
|---|---|
| Same checker + same entity = 1 open issue | coalesce_key = md5(checker|entity) + SELECT before INSERT |
| Severity only escalates, never downgrades | CASE rank comparison |
| occurrence_count tracks frequency | INCREMENT on existing |
| latest finding reflected | UPDATE title + evidence on existing |
| resolved issues don't block new detection | WHERE status = 'open' filter |
R3.6 Execution note
Wrapper = DDL (CREATE FUNCTION). Thuộc E-R3 execution — cần prompt riêng + GPT/User approval. Không tạo trong E1–E3 pack.
E2 — Đ24 Facet Reconciliation Design
2.1 Candidate proposal (NOT default)
FAC-07/08/09 là candidate theo pattern hiện có. APR có quyền approve/modify/reject.
| Alias | Candidate code | Candidate name | Status |
|---|---|---|---|
| doc | FAC-07 | Thuộc tài liệu nào? | Candidate — chờ APR |
| topic | FAC-08 | Chủ đề nội dung? | Candidate — chờ APR |
| layer | FAC-09 | Tầng kiến trúc? | Candidate — chờ APR |
No APR = no facet creation. APR có thể:
- Approve FAC-07/08/09 as proposed
- Modify code/name (e.g. FAC-07→FAC-DOC nếu Council quyết)
- Reject (nếu dùng facet hiện có tốt hơn)
2.2 Governed flow
DOT-TAC-LABEL-FACET-VERIFY
→ detect missing → system_issues (via fn_tac_log_checker_issue)
→ create APR request_type='create_taxonomy_facet'
proposed_action: INSERT taxonomy_facets (code='FAC-07', ...)
→ User/Council approve/modify/reject
→ If approved → DOT-TAC-LABEL-SYNC via Directus API POST
→ Re-verify
2.3 Label values
| Facet | Values pilot | Notes |
|---|---|---|
| FAC-07 (doc) | D38-HOWTO, D38-C1A, D38-P5 | 3 values |
| FAC-08 (topic) | guide, segmentation, schema | 3 values |
| FAC-09 (layer) | design | 1 value |
Values registration: verify taxonomy_labels table exists trước execution.
2.4 P8 amendment
P8 §5: "doc/topic/layer = alias. Production dùng facet_id FK → taxonomy_facets. Facet codes = APR outcome."
E3 — D38 Entity Code Format Contract
3.1 Scope: LOCAL contract only
D38-domain contract cho TAC canonical_address. KHÔNG phải global Đ24 standard. Đ24 global format = separate OD nếu sau này cần.
Ghi cứng: contract này KHÔNG lan thành chuẩn toàn hệ thống. Mỗi domain tự chốt entity_code convention.
3.2 Contract
D38 Text as Code entity_code convention:
- entity_code = tac_logical_unit.canonical_address (verbatim)
- LOCAL D38-domain contract, NOT global Đ24 standard
- Regex: ^D38-[A-Z0-9]+-((ROOT)|(S[0-9]+(-P[0-9]+(-[0-9]+)*)?))$
- Covers:
D38-HOWTO-ROOT (root)
D38-HOWTO-S1 (section)
D38-C1A-S4-P1 (paragraph)
D38-C1A-S4-P1-1 (deep nesting, future)
- Character set: uppercase alphanumeric + hyphen
- Length: 10–30
- UNIQUE: tac_logical_unit.canonical_address constraint
- Prefix: D38-
3.3 Validation
DOT-TAC-LABEL-FORMAT-VERIFY: query all canonical_address, match regex. Any miss = FAIL.
76 pilot units: all match D38-{DOC}-(ROOT|S{n}|S{n}-P{n}). Regex covers.
Summary
| Step | Status | Next |
|---|---|---|
| E1 fn_log_issue | ✅ PASS verified | — |
| R3 adapter design | ✅ DESIGN v0.2 (dedup contract) | E-R3 execution (approval) |
| E2 Đ24 facets | ✅ DESIGN v0.2 (candidate, not default) | E4 APR (approval) |
| E3 entity_code | ✅ DESIGN v0.2 (local D38 only) | P8 amendment |
All design-only. No DDL/DML. No production mutation.
Execution roadmap (chờ review)
| Phase | Scope | Mutate? |
|---|---|---|
| E-R3 | Create fn_tac_log_checker_issue wrapper | ✅ DDL |
| E-E3 | Amend P8 §5 (entity_code + alias) | ❌ doc |
| E4 | APR request FAC-07/08/09 | ✅ APR |
| E5 | If approved → create facets | ✅ taxonomy |
| E6 | Re-run Tier 1 A1–A3 | ❌ read-only |
| E7 | dot-dot-register v2 D1–D3 dry-run | ❌ |
| E8 | dot-dot-register v2 D4 register | ✅ dot_tools |
Mỗi mutate step = prompt riêng + GPT review.
Patch log v0.1 → v0.2
| # | GPT điểm | Sửa |
|---|---|---|
| 1 | R3 dedup key contract | ✅ coalesce_key = md5(checker_id|entity_code). Full dedup logic: SELECT existing → UPDATE or INSERT+backfill. Severity escalation. occurrence_count. |
| 2 | E2 facets = candidate not default | ✅ FAC-07/08/09 = candidate. APR can approve/modify/reject. No APR = no creation. |
| 3 | E3 entity_code = local D38 only | ✅ Ghi cứng: local contract, KHÔNG lan thành global Đ24 standard. |
E1–E3 Design Pack v0.2 | S182 | 2026-04-27 | Opus 4.6 GPT: v0.1 PASS CĐK (3) → v0.2 patched Chờ GPT final + User