KB-6B84 rev 3

E-R3 Execution Prompt v0.3

12 min read Revision 3
dieu38p9e-r3executionddl

E-R3 Execution — CREATE FUNCTION fn_tac_log_checker_issue (v0.3)

Gate: GPT SUPERVISION PASS (2026-04-27). Scope-locked. Input: E-R3 dry-run v0.2 (GPT PASS) + GPT review v0.1→v0.2 (7 patches) + GPT review v0.2→v0.3 (4 patches).

Mục tiêu

Tạo wrapper function fn_tac_log_checker_issue trong schema public, database directus. Verify function đúng signature + owner + security attributes. Upload action log. STOP.

Ràng buộc tuyệt đối

  1. Chỉ được CREATE OR REPLACE FUNCTIONALTER FUNCTION ... OWNER TO cho đúng public.fn_tac_log_checker_issue. Không DDL/ALTER/DROP object nào khác, trừ rollback DROP đúng function target nếu post-create verify fail.
  2. KHÔNG ghi system_issues. KHÔNG test INSERT/UPDATE/DELETE.
  3. KHÔNG sửa fn_log_issue. KHÔNG ALTER bất kỳ table nào.
  4. KHÔNG chạy E4/E5/E7/P9.
  5. Nếu BẤT KỲ pre-check nào FAIL → STOP + report. Không tự sửa.
  6. Nếu CREATE thành công nhưng bước sau FAIL → chạy rollback (Step R) rồi STOP + report.
  7. Không tự remediate ngoài prompt này.

Step 0: Load environment

source /opt/incomex/.env
DB_USER="${PG_USER_DIRECTUS:-workflow_admin}"
echo "DB_USER=$DB_USER"

Mọi lệnh psql bên dưới dùng -U "$DB_USER". KHÔNG hardcode user name.

Step 1: Pre-check target function KHÔNG tồn tại

docker exec postgres psql -U "$DB_USER" -d directus -t -A -c "
SELECT proname, pg_get_function_arguments(oid)
FROM pg_proc
WHERE proname = 'fn_tac_log_checker_issue'"

Nếu có BẤT KỲ row nào → STOP: "target function already exists, cannot CREATE OR REPLACE safely". Report output. Không CREATE.

Nếu 0 rows → PASS, tiếp tục.

Step 2: Pre-check fn_log_issue exact signature

docker exec postgres psql -U "$DB_USER" -d directus -t -A -c "
SELECT pg_get_function_arguments(p.oid)
FROM pg_proc p JOIN pg_namespace n ON p.pronamespace = n.oid
WHERE p.proname = 'fn_log_issue' AND n.nspname = 'public'"

Expect: 1 row với đúng 10 params. Wrapper gọi fn_log_issue với 10 arguments theo thứ tự: (source, severity, title, description, entity_type, entity_code, issue_type, evidence, resolution, status)

Ghi output chính xác. Nếu:

  • 0 rows → STOP: "fn_log_issue không tồn tại"
  • Số params ≠ 10 → STOP: "fn_log_issue signature mismatch"
  • Tên/type param không tương thích → STOP + ghi chi tiết mismatch

Step 3: Pre-check system_issues columns + type contract

docker exec postgres psql -U "$DB_USER" -d directus -t -A -c "
SELECT column_name, data_type, udt_name
FROM information_schema.columns
WHERE table_schema = 'public' AND table_name = 'system_issues'
  AND column_name IN ('id','severity','status','coalesce_key','last_seen_at','occurrence_count','title','evidence_snapshot')
ORDER BY column_name"

Expect: đủ 8 rows. Ghi output đầy đủ.

Type contract — tất cả phải tương thích:

Column Compatible types
id integer, bigint, serial, bigserial
severity text, varchar, character varying
status text, varchar, character varying
coalesce_key text, varchar, character varying
title text, varchar, character varying
last_seen_at timestamp, timestamptz, timestamp with time zone, timestamp without time zone
occurrence_count integer, bigint, smallint, numeric
evidence_snapshot json HOẶC jsonb

Nếu:

  • Thiếu bất kỳ cột nào → STOP: "system_issues thiếu cột [tên]"
  • Bất kỳ type nào nằm ngoài danh sách compatible → STOP: "[column] type [actual] không tương thích"
  • GHI NHẬN chính xác type của evidence_snapshot (json hay jsonb) → dùng ở Step 5

Step 4: Pre-check owner role

docker exec postgres psql -U "$DB_USER" -d directus -t -A -c "
SELECT 1 FROM pg_roles WHERE rolname = 'workflow_admin'"

Expect: 1 row. Nếu 0 rows → STOP: "role workflow_admin không tồn tại".

Step 5: Materialize final SQL

Dựa trên Step 3 kết quả evidence_snapshot type:

Nếu jsonb: dòng assignment trong UPDATE phải là:

evidence_snapshot = COALESCE(p_details, evidence_snapshot)

Nếu json: dòng assignment phải là:

evidence_snapshot = COALESCE(p_details::json, evidence_snapshot)

Nếu type khác cả hai → STOP (đã bị chặn ở Step 3).

Agent PHẢI:

  1. Tạo biến hoặc ghi log dòng assignment đã chọn:
    echo "evidence_snapshot assignment: COALESCE(p_details[::json], evidence_snapshot)"
    
  2. Tạo final SQL string hoàn chỉnh với dòng assignment đúng.
  3. Log final SQL ra stdout hoặc file TRƯỚC KHI execute.

Step 6: CREATE FUNCTION

Chạy final SQL đã materialize ở Step 5. Template DDL (thay __EVIDENCE_ASSIGNMENT__ bằng dòng đúng):

docker exec postgres psql -U "$DB_USER" -d directus <<'EOSQL'
CREATE OR REPLACE FUNCTION fn_tac_log_checker_issue(
    p_checker_id       TEXT,
    p_severity         TEXT,
    p_entity_code      TEXT,
    p_summary          TEXT,
    p_issue_signature  TEXT DEFAULT NULL,
    p_details          JSONB DEFAULT NULL
) RETURNS INTEGER
LANGUAGE plpgsql
SECURITY DEFINER
SET search_path = public, pg_catalog
AS $$
DECLARE
    v_mapped_sev    TEXT;
    v_sev_rank      INTEGER;
    v_existing_id   INTEGER;
    v_existing_rank INTEGER;
    v_dedup_key     TEXT;
    v_new_id        INTEGER;
BEGIN
    -- 1. Map P6 severity
    v_mapped_sev := CASE upper(btrim(p_severity))
        WHEN 'BLOCK' THEN 'critical'
        WHEN 'ERROR' THEN 'critical'
        WHEN 'WARN'  THEN 'warning'
        WHEN 'INFO'  THEN 'info'
        ELSE NULL
    END;
    IF v_mapped_sev IS NULL THEN
        RAISE EXCEPTION 'fn_tac_log_checker_issue: invalid severity %',
            p_severity;
    END IF;
    v_sev_rank := CASE v_mapped_sev
        WHEN 'critical' THEN 3 WHEN 'warning' THEN 2 ELSE 1 END;

    -- 2. Compute dedup key (normalize inputs)
    v_dedup_key := md5(
        lower(btrim(p_checker_id)) || '|' ||
        btrim(COALESCE(p_entity_code, '')) || '|' ||
        btrim(COALESCE(p_issue_signature, ''))
    );

    -- 3. Check existing open issue
    SELECT id,
           CASE severity
               WHEN 'critical' THEN 3 WHEN 'warning' THEN 2 ELSE 1
           END
    INTO v_existing_id, v_existing_rank
    FROM system_issues
    WHERE coalesce_key = v_dedup_key AND status = 'open'
    LIMIT 1;

    -- 4a. Existing → UPDATE (escalate + refresh)
    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_sev_rank > v_existing_rank THEN v_mapped_sev
                ELSE severity
            END,
            title = p_summary,
            __EVIDENCE_ASSIGNMENT__
        WHERE id = v_existing_id;
        RETURN v_existing_id;
    END IF;

    -- 4b. New → INSERT via fn_log_issue + backfill coalesce_key
    v_new_id := fn_log_issue(
        btrim(p_checker_id),
        v_mapped_sev,
        p_summary,
        NULL,
        'tac_logical_unit',
        btrim(p_entity_code),
        btrim(p_checker_id),
        p_details,
        NULL,
        'open'
    );
    UPDATE system_issues SET coalesce_key = v_dedup_key WHERE id = v_new_id;
    RETURN v_new_id;
END;
$$;

ALTER FUNCTION fn_tac_log_checker_issue(TEXT,TEXT,TEXT,TEXT,TEXT,JSONB)
    OWNER TO workflow_admin;
EOSQL

Agent thay __EVIDENCE_ASSIGNMENT__ bằng dòng đã chọn ở Step 5 TRƯỚC KHI chạy.

Ghi output. Expect: CREATE FUNCTION + ALTER FUNCTION. Nếu ERROR → chạy Step R rồi STOP + report.

Step 7: Verify function — signature + owner + security

docker exec postgres psql -U "$DB_USER" -d directus -t -A -c "
SELECT
    p.proname,
    pg_get_function_arguments(p.oid) AS args,
    p.proowner::regrole AS owner,
    p.prosecdef AS security_definer,
    p.proconfig AS config
FROM pg_proc p JOIN pg_namespace n ON p.pronamespace = n.oid
WHERE p.proname = 'fn_tac_log_checker_issue' AND n.nspname = 'public'"

Expect:

  • proname = fn_tac_log_checker_issue
  • args = 6 params đúng tên + type
  • owner = workflow_admin
  • security_definer = t (true)
  • config chứa search_path=public, pg_catalog

Ghi output đầy đủ. Nếu BẤT KỲ mục nào sai → chạy Step R rồi STOP + report chi tiết.

Step R: Rollback (khi bất kỳ bước nào sau CREATE fail)

docker exec postgres psql -U "$DB_USER" -d directus -c "
DROP FUNCTION IF EXISTS fn_tac_log_checker_issue(TEXT,TEXT,TEXT,TEXT,TEXT,JSONB);"

Verify đã DROP:

docker exec postgres psql -U "$DB_USER" -d directus -t -A -c "
SELECT 1 FROM pg_proc WHERE proname = 'fn_tac_log_checker_issue'"

Expect: 0 rows.

Báo cáo

Tạo file reports/p9-e-r3-execution-log-2026-04-27.md với format:

# E-R3 Execution Log — 2026-04-27

> Agent: [tên agent]
> Gate: GPT SUPERVISION PASS
> Prompt: E-R3 Execution v0.3

## Environment
- DB_USER: [giá trị từ .env]
- Database: directus
- Schema: public

## Pre-checks

| # | Check | Output | Status |
|---|-------|--------|--------|
| 1 | Target function NOT exists | [output] | PASS/FAIL |
| 2 | fn_log_issue signature (10 params) | [output] | PASS/FAIL |
| 3 | system_issues 8 columns + types | [output] | PASS/FAIL |
| 3b | evidence_snapshot type | [json/jsonb] | [ghi nhận] |
| 3c | occurrence_count type | [integer/bigint/...] | [ghi nhận] |
| 4 | workflow_admin role exists | [output] | PASS/FAIL |

## SQL Materialization
- evidence_snapshot type detected: [json/jsonb]
- Assignment line chosen: [exact line]
- Final SQL logged: [yes/no]

## Execution

| # | Step | Output | Status |
|---|------|--------|--------|
| 6 | CREATE FUNCTION | [output] | PASS/FAIL |
| 6b | ALTER OWNER | [output] | PASS/FAIL |
| 7a | Verify 6 params | [output] | PASS/FAIL |
| 7b | Verify owner = workflow_admin | [output] | PASS/FAIL |
| 7c | Verify SECURITY DEFINER = true | [output] | PASS/FAIL |
| 7d | Verify search_path = public, pg_catalog | [output] | PASS/FAIL |

## DDL Applied
[Ghi chính xác final SQL đã chạy, bao gồm dòng evidence_snapshot đã chọn]

## Kết luận
- **Verdict:** PASS / FAIL
- **Rollback:** Không cần / Đã chạy (lý do)
- **DDL adjustment:** json/jsonb (chi tiết)

Upload report lên KB: knowledge/dev/laws/dieu38-trien-khai/reports/p9-e-r3-execution-log-2026-04-27.md

SAU KHI XONG: STOP. Không chạy thêm gì. Chờ GPT/User review.


Patch log

v0.1 → v0.2 (GPT review #1: 7 patches)

# Issue Fix
1 Hardcode -U directus source .env + $DB_USER
2 fn_log_issue chỉ check tồn tại ✅ Check exact 10 params
3 Thiếu pre-check system_issues columns ✅ Verify 8 cột + types
4 evidence_snapshot type mismatch ✅ Conditional cast json/jsonb
5 Hardcode owner chưa verify role ✅ Pre-check role exists
6 Thiếu verify SECURITY DEFINER + search_path ✅ Full pg_proc verify
7 Rollback chỉ Step 3 fail ✅ Rollback cho bất kỳ post-CREATE fail

v0.2 → v0.3 (GPT review #2: 4 patches)

# Issue Fix
1 CREATE OR REPLACE overwrite function cũ ✅ Step 1: STOP nếu target đã tồn tại
2 Ràng buộc thiếu ALTER OWNER ✅ Wording bao gồm CREATE + ALTER OWNER
3 Type assert chỉ evidence_snapshot ✅ Step 3: full type contract 8 cột
4 Agent sửa tay heredoc dễ quên ✅ Step 5: materialize final SQL + log trước execute

E-R3 Execution Prompt v0.3 | S183 | 2026-04-27 | Opus 4.6 GPT review #1 PASS (7) + GPT review #2 PASS (4) → v0.3