Gate A — Production DDL Execution Prompt Design v0.5 FINAL
Gate A — Production DDL Execution Prompt Design v0.5 FINAL
Status: DRAFT v0.5 FINAL — patched per GPT R5 conditional PASS Phiên: S186 | Ngày: 2026-04-28 Scope: Gate A ONLY — Production DDL (14 tables + 6 fn + 6 trg → public) KHÔNG bao gồm: Gate B (collections), Gate C (seed), G8B, G11, P9 Executor: Agent (Claude Code) via SSH
contabo— TẤT CẢ lệnh chạy trên VPS, KHÔNG phải local Mac Effort: medium-high Authorize chain: Opus v0.1 → GPT R1 → v0.2 → GPT R2 → v0.3 → GPT R3 → v0.4 → GPT R4 → v0.5 → GPT R5 → User GO Revision: v0.1 (S185) → v0.2 (R1, 5p) → v0.3 (R2, 6p) → v0.4 (R3, 6p) → v0.5 (R4, 3p + R5, 3p)
⚠️ PROMPT NÀY CHƯA ĐƯỢC AUTHORIZE
Chưa ai được chạy. Cần GPT PASS + User GO trước khi dispatch.
⚠️ MỌI LỆNH CHẠY TRÊN VPS (GPT R3#6)
Tất cả path /opt/incomex/data/tac/gate-a/ và lệnh docker exec chạy trên VPS qua ssh contabo. Agent KHÔNG chạy trên local Mac. Nếu agent phát hiện mình đang ở Mac → STOP, SSH vào VPS trước.
0. Mục tiêu
Tạo 14 tac_* tables + 6 functions + 6 triggers trong public schema trên production PostgreSQL. Bước đầu tiên đưa TAC schema từ dry-run (PASS G6 Run 4) sang production.
PASS criteria: Tất cả post-checks Q1–Q8 PASS. Directus healthy (hoặc DB-accessible nếu HTTP auth-protected). Production không bị ảnh hưởng ngoài tac_* objects mới.
FAIL criteria: psql exit ≠ 0, hoặc bất kỳ Q1–Q8 FAIL, hoặc Directus/DB unhealthy → rollback theo đúng path (§3.3 hoặc §5).
Evidence base: G6 Run 4 action log (reports/p9-g6-execution-log-run4-2026-04-28.md) — 22/22 PASS, bundle DDL-only 566 dòng, seed riêng 8 files.
1. Pre-execution: Canonical DDL Persist + Sanitize
Step 1.1 — Copy bundle từ /tmp ra persistent path
ssh contabo
mkdir -p /opt/incomex/data/tac/gate-a/
cp /tmp/g6_run4_20260428_041121/ddl/g6_execution_bundle.sql \
/opt/incomex/data/tac/gate-a/g6_execution_bundle_dryrun.sql
sha256sum /opt/incomex/data/tac/gate-a/g6_execution_bundle_dryrun.sql
Expected SHA: c23987f29911e92d43d9ab6cb5e4fe77d64547785d98588859dfcc6f02997cad
Nếu SHA không khớp → STOP, report. /tmp có thể đã bị clear.
Step 1.2 — Controlled transform (KHÔNG blind sed)
Thứ tự: xóa scaffold TRƯỚC, thay tokens SAU.
cd /opt/incomex/data/tac/gate-a/
# Bước 1: Copy working file
cp g6_execution_bundle_dryrun.sql production_ddl_candidate.sql
# Bước 2: Xóa CREATE SCHEMA line (whitespace-tolerant — GPT R4#2)
sed -i '/^[[:space:]]*CREATE[[:space:]]\+SCHEMA.*p9_g6_dryrun/d' production_ddl_candidate.sql
# Bước 3: Xóa COMMENT ON SCHEMA line (whitespace-tolerant — GPT R4#2)
sed -i '/^[[:space:]]*COMMENT[[:space:]]\+ON[[:space:]]\+SCHEMA[[:space:]]\+p9_g6_dryrun/d' production_ddl_candidate.sql
# Bước 4: Thay exact tokens
sed -i 's/p9_g6_dryrun\./public\./g' production_ddl_candidate.sql
sed -i 's/search_path=p9_g6_dryrun, pg_catalog/search_path=public, pg_catalog/g' production_ddl_candidate.sql
sed -i 's/SET search_path TO p9_g6_dryrun, pg_catalog/SET search_path TO public, pg_catalog/g' production_ddl_candidate.sql
Step 1.3 — Verify transform (5 checks)
# V-T1: Không còn p9_g6_dryrun
grep -c 'p9_g6_dryrun' production_ddl_candidate.sql # Expected: 0
# V-T2: Không có CREATE SCHEMA public
grep -c 'CREATE SCHEMA public' production_ddl_candidate.sql # Expected: 0
# V-T3: Có public. references
grep -c 'public\.' production_ddl_candidate.sql # Expected: > 0
# V-T4: Không có DROP SCHEMA
grep -c 'DROP SCHEMA' production_ddl_candidate.sql # Expected: 0
# V-T5: BEGIN/COMMIT nguyên vẹn
grep -c '^BEGIN' production_ddl_candidate.sql # Expected: 1
grep -c '^COMMIT' production_ddl_candidate.sql # Expected: 1
Bất kỳ FAIL → STOP, report.
Step 1.4 — DML Denylist + Classification (GPT R1#1 + R2#1 + R3#4)
Expected: 0 DML matches cho candidate này. G6 evidence confirms bundle = DDL-only, 6 trigger functions chỉ RAISE/gán NEW.*, không chứa INSERT INTO.
Scan (whitespace-tolerant regex — GPT R4#1, shell-safe — GPT R5#2):
grep -nE 'INSERT[[:space:]]+INTO' production_ddl_candidate.sql || true
grep -nE '^[[:space:]]*COPY[[:space:]]' production_ddl_candidate.sql || true
grep -nE '^[[:space:]]*UPDATE[[:space:]]' production_ddl_candidate.sql || true
grep -nE '^[[:space:]]*DELETE[[:space:]]' production_ddl_candidate.sql || true
grep -nE '^[[:space:]]*TRUNCATE[[:space:]]' production_ddl_candidate.sql || true
Decision tree:
- 0 matches tổng cộng → PASS. Ghi "DML denylist: 0 matches, clean."
- Bất kỳ match > 0 → Agent PHẢI:
- In line number + full context (±3 dòng)
- Classify: top-level / function-body / comment / DDL-clause
- Top-level DML → STOP. Gate A FAIL.
- Function-body hoặc comment DML → STOP. Unexpected cho candidate này. Escalate GPT/User review. Agent KHÔNG tự approve.
Step 1.5 — Compute production SHA
sha256sum /opt/incomex/data/tac/gate-a/production_ddl_candidate.sql
Ghi SHA mới vào action log. Production SHA ≠ dry-run SHA (do retarget + scaffold removal).
⚠️ Tạo production_ddl_candidate.sql chỉ là bước chuẩn bị. Gate A PASS chỉ được tuyên bố SAU KHI execution COMMIT thành công VÀ Q1–Q8 post-checks ALL PASS. (GPT R5#3)
2. Pre-checks
| # | Check | Command | Expected |
|---|---|---|---|
| P1 | No tac_* tables | docker exec postgres psql -U directus -d directus -t -c "SELECT count(*) FROM pg_tables WHERE schemaname='public' AND tablename LIKE 'tac_%'" |
0 |
| P2 | fn_tac_* whitelist only | docker exec postgres psql -U directus -d directus -t -c "SELECT array_agg(proname ORDER BY proname) FROM pg_proc JOIN pg_namespace n ON pronamespace=n.oid WHERE nspname='public' AND proname LIKE 'fn_tac_%'" |
{fn_tac_log_checker_issue} |
| P3 | No trg_tac_* triggers | docker exec postgres psql -U directus -d directus -t -c "SELECT count(*) FROM pg_trigger t JOIN pg_class c ON t.tgrelid=c.oid JOIN pg_namespace n ON c.relnamespace=n.oid WHERE n.nspname='public' AND t.tgname LIKE 'trg_tac_%'" |
0 |
| P4 | Backup valid (PF-07 v0.5) | age ≤30h, size ≥1MB, gzip valid, PG dump header | PASS |
| P5 | Directus healthy | §2.1 | OK / DB-accessible |
| P6 | Candidate SHA | sha256sum ...production_ddl_candidate.sql |
Matches §1.5 |
| P7 | Trigger guard healthy | §2.2 (3 sub-checks) | ALL PASS |
Bất kỳ FAIL → STOP.
§2.1 P5 — Directus Health (token-safe, wording chính xác — GPT R3#5)
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \
https://vps.incomexsaigoncorp.vn/api/server/health)
if [ "$HTTP_CODE" = "200" ]; then
echo "P5 PASS: Directus HTTP healthy"
elif [ "$HTTP_CODE" = "401" ] || [ "$HTTP_CODE" = "403" ]; then
# HTTP auth-protected — fallback: verify DB metadata accessible
DB_CHECK=$(docker exec postgres psql -U directus -d directus -t -c \
"SELECT count(*) FROM directus_collections LIMIT 1" 2>&1)
if echo "$DB_CHECK" | grep -qE '^[[:space:]]*[0-9]+'; then
echo "P5 PASS: HTTP health auth-protected, DB metadata accessible"
echo "⚠️ LOG: HTTP health endpoint unverified (auth-protected). DB connectivity confirmed. Acceptable for Gate A."
else
echo "P5 FAIL: HTTP auth-protected AND DB metadata inaccessible"
# STOP
fi
elif [ "${HTTP_CODE:0:1}" = "5" ]; then
echo "P5 FAIL: HTTP $HTTP_CODE — Directus server error"
# STOP
else
echo "P5 FAIL: HTTP $HTTP_CODE — unexpected"
# STOP
fi
§2.2 P7 — Trigger Guard Deep Check (GPT R2#3 + R3#3)
Run #3 từng chết vì trigger guard search_path sai. Chỉ đếm event trigger = chưa đủ.
-- P7a: Event triggers exist + enabled
SELECT evtname, evtenabled
FROM pg_event_trigger
WHERE evtname LIKE 'evt_trigger_guard%';
-- Expected: 2 rows, evtenabled = 'O'
-- P7b: Guard function references QUALIFIED alert table
SELECT prosrc LIKE '%public.trigger_guard_alerts%' AS refs_qualified_table
FROM pg_proc WHERE proname = 'fn_evt_trigger_guard';
-- Expected: true (MUST be public.trigger_guard_alerts, not unqualified)
-- P7c: Guard function search_path = pg_catalog, public
SELECT proconfig
FROM pg_proc WHERE proname = 'fn_evt_trigger_guard';
-- Expected: contains 'search_path=pg_catalog, public'
-- MUST NOT contain p9_g6_dryrun (Run #3 lỗi này)
P7a/P7b/P7c bất kỳ FAIL → STOP. Repair trigger guard trước.
3. Execution
3.1 Chạy production DDL (GPT R3#1: pipefail)
set -o pipefail
docker exec -i postgres psql -U directus -d directus -v ON_ERROR_STOP=1 -X \
< /opt/incomex/data/tac/gate-a/production_ddl_candidate.sql \
2>&1 | tee /opt/incomex/data/tac/gate-a/execution-output.txt
PSQL_EXIT=${PIPESTATUS[0]}
if [ "$PSQL_EXIT" -ne 0 ]; then
echo "EXECUTION ERROR: psql exit code $PSQL_EXIT"
# → Go to §3.3 Error Path A
fi
Lưu ý:
- Single transaction (BEGIN/COMMIT trong file)
ON_ERROR_STOP=1— fail fast- Trigger guard emit WARNING cho 6 CREATE TRIGGER — expected, non-blocking
set -o pipefail+PIPESTATUS[0]đảm bảo không che exit code qua tee
3.2 Expected output (informational — KHÔNG phải source of truth)
Psql emit CREATE TABLE/INDEX/FUNCTION/TRIGGER/COMMIT. Post-check SQL counts (§4) là source of truth.
3.3 Error handling — 2 paths (GPT R3#2)
Path A — Execution ERROR (psql exit ≠ 0)
Transaction BEGIN/COMMIT + ON_ERROR_STOP → PG thường auto-rollback.
Bước 1 — Check auto-rollback:
T_COUNT=$(docker exec postgres psql -U directus -d directus -t -c \
"SELECT count(*) FROM pg_tables WHERE schemaname='public' AND tablename LIKE 'tac_%'" | tr -d ' ')
F_LIST=$(docker exec postgres psql -U directus -d directus -t -c \
"SELECT array_agg(proname ORDER BY proname) FROM pg_proc JOIN pg_namespace n ON pronamespace=n.oid WHERE nspname='public' AND proname LIKE 'fn_tac_%'" | tr -d ' ')
TRG_COUNT=$(docker exec postgres psql -U directus -d directus -t -c \
"SELECT count(*) FROM pg_trigger t JOIN pg_class c ON t.tgrelid=c.oid JOIN pg_namespace n ON c.relnamespace=n.oid WHERE n.nspname='public' AND t.tgname LIKE 'trg_tac_%'" | tr -d ' ')
Bước 2 — Đánh giá:
- tables=0 AND fn=chỉ
{fn_tac_log_checker_issue}AND triggers=0 → Auto-rollback sạch. Log "auto-rollback clean." KHÔNG chạy manual rollback. → Report GATE A FAIL. - Partial objects remain → Chạy manual rollback (§5). → Report GATE A FAIL + rollback evidence.
Path B — COMMIT thành công nhưng Q1–Q8 FAIL (GPT R3#2)
Transaction đã COMMIT → objects tồn tại trong production. Phải manual rollback.
→ Chạy pre-rollback catalog verification (§5.0) → manual rollback (§5.1) → rollback verification (§5.2). → Report GATE A FAIL + rollback evidence.
4. Post-checks
| # | Check | Command | Expected |
|---|---|---|---|
| Q1 | tac_* tables | Same as P1 | 14 |
| Q2 | FK constraints | docker exec postgres psql -U directus -d directus -t -c "SELECT count(*) FROM information_schema.table_constraints WHERE constraint_type='FOREIGN KEY' AND table_schema='public' AND table_name LIKE 'tac_%'" |
17 |
| Q3 | fn_tac_* total | Same as P2 | 7: {fn_tac_birth_gate_lu, fn_tac_birth_gate_uv, fn_tac_enacted_immut, fn_tac_log_checker_issue, fn_tac_pm_consistency, fn_tac_pm_enacted_lock, fn_tac_uv_compute_derived} |
| Q4 | trg_tac_* triggers | Same as P3 | 6 |
| Q5 | Indexes on tac_* | docker exec postgres psql -U directus -d directus -t -c "SELECT count(*) FROM pg_indexes WHERE schemaname='public' AND tablename LIKE 'tac_%'" |
41 |
| Q6 | Directus healthy | Same as P5 (§2.1) | OK / DB-accessible |
| Q7 | 6 NEW fn SECURITY DEFINER | docker exec postgres psql -U directus -d directus -t -c "SELECT proname, prosecdef FROM pg_proc JOIN pg_namespace n ON pronamespace=n.oid WHERE nspname='public' AND proname LIKE 'fn_tac_%' AND proname != 'fn_tac_log_checker_issue'" |
All 6 = t |
| Q8 | 6 NEW fn search_path locked | docker exec postgres psql -U directus -d directus -t -c "SELECT proname, proconfig FROM pg_proc JOIN pg_namespace n ON pronamespace=n.oid WHERE nspname='public' AND proname LIKE 'fn_tac_%' AND proname != 'fn_tac_log_checker_issue'" |
All search_path=public, pg_catalog |
ALL Q1–Q8 PASS → GATE A PASS. Any FAIL → §3.3 Path B (manual rollback).
5. Rollback
Khi nào chạy:
- §3.3 Path A: chỉ nếu partial objects remain sau execution error
- §3.3 Path B: sau COMMIT nhưng post-check fail
Step 5.0 — Pre-rollback catalog verification
-- Verify trigger names
SELECT tgname FROM pg_trigger t
JOIN pg_class c ON t.tgrelid = c.oid
JOIN pg_namespace n ON c.relnamespace = n.oid
WHERE n.nspname = 'public' AND t.tgname LIKE 'trg_tac_%'
ORDER BY tgname;
-- Expected: trg_tac_birth_gate_lu, trg_tac_birth_gate_uv,
-- trg_tac_enacted_immut, trg_tac_pm_consistency,
-- trg_tac_pm_enacted_lock, trg_tac_uv_compute_derived
-- Verify function signatures (no-arg trigger functions)
SELECT proname, pg_get_function_identity_arguments(oid) AS args
FROM pg_proc JOIN pg_namespace n ON pronamespace = n.oid
WHERE nspname = 'public'
AND proname LIKE 'fn_tac_%'
AND proname != 'fn_tac_log_checker_issue'
ORDER BY proname;
-- Expected: all args = '' (empty)
Names/signatures không khớp → STOP, report discrepancy.
Step 5.1 — Rollback SQL
-- Triggers first
DROP TRIGGER IF EXISTS trg_tac_birth_gate_lu ON public.tac_logical_unit;
DROP TRIGGER IF EXISTS trg_tac_birth_gate_uv ON public.tac_unit_version;
DROP TRIGGER IF EXISTS trg_tac_enacted_immut ON public.tac_publication;
DROP TRIGGER IF EXISTS trg_tac_pm_consistency ON public.tac_publication_member;
DROP TRIGGER IF EXISTS trg_tac_pm_enacted_lock ON public.tac_publication_member;
DROP TRIGGER IF EXISTS trg_tac_uv_compute_derived ON public.tac_unit_version;
-- 6 NEW functions only (created by this Gate A run)
DROP FUNCTION IF EXISTS public.fn_tac_birth_gate_lu();
DROP FUNCTION IF EXISTS public.fn_tac_birth_gate_uv();
DROP FUNCTION IF EXISTS public.fn_tac_enacted_immut();
DROP FUNCTION IF EXISTS public.fn_tac_pm_consistency();
DROP FUNCTION IF EXISTS public.fn_tac_pm_enacted_lock();
DROP FUNCTION IF EXISTS public.fn_tac_uv_compute_derived();
-- Tables reverse FK order
DROP TABLE IF EXISTS public.tac_change_set_member CASCADE;
DROP TABLE IF EXISTS public.tac_publication_member CASCADE;
DROP TABLE IF EXISTS public.tac_change_set CASCADE;
DROP TABLE IF EXISTS public.tac_publication CASCADE;
DROP TABLE IF EXISTS public.tac_unit_version CASCADE;
DROP TABLE IF EXISTS public.tac_logical_unit CASCADE;
DROP TABLE IF EXISTS public.tac_birth_gate_config CASCADE;
DROP TABLE IF EXISTS public.tac_publication_type_vocab CASCADE;
DROP TABLE IF EXISTS public.tac_section_type_vocab CASCADE;
DROP TABLE IF EXISTS public.tac_cs_lifecycle_vocab CASCADE;
DROP TABLE IF EXISTS public.tac_pub_lifecycle_vocab CASCADE;
DROP TABLE IF EXISTS public.tac_review_state_vocab CASCADE;
DROP TABLE IF EXISTS public.tac_uv_lifecycle_vocab CASCADE;
DROP TABLE IF EXISTS public.tac_lu_lifecycle_vocab CASCADE;
⚠️ TUYỆT ĐỐI KHÔNG DROP public.fn_tac_log_checker_issue — pre-existing E-R3.
Step 5.2 — Rollback verification
# P1 → 0 tables, P2 → whitelist only, P3 → 0 triggers, P5 → healthy
6. Hard Exclusions
| # | Cấm |
|---|---|
| HE-1 | Không top-level DML (INSERT/UPDATE/DELETE/COPY/TRUNCATE) |
| HE-2 | Không seed (Gate C scope) |
| HE-3 | Không Directus collection registration (Gate B scope) |
| HE-4 | Không role/policy/permission (G8B scope) |
| HE-5 | Không token provisioning |
| HE-6 | Không cron setup |
| HE-7 | Không modify fn_tac_log_checker_issue (pre-existing E-R3) |
| HE-8 | Không modify existing objects ngoài tac_* |
| HE-9 | Không DROP pre-existing objects. Rollback chỉ DROP objects tạo bởi Gate A run hiện tại. Tuyệt đối không DROP fn_tac_log_checker_issue. |
| HE-10 | Không chạy file nào khác ngoài production_ddl_candidate.sql |
| HE-11 | Không chạy lệnh trên local Mac — tất cả qua SSH VPS contabo |
7. Directus API Access Safety
- Token retrieval runtime-only, masked
- Không print token/Auth header/env secret
- Directus unhealthy (§2.1 both paths fail) → STOP
- Không hỏi User paste secrets
8. Action Log
Path: knowledge/dev/laws/dieu38-trien-khai/reports/p9-gate-a-production-ddl-execution-log-YYYY-MM-DD.md
No-overwrite policy (GPT R4#3): Nếu path đã tồn tại, tạo suffix -run2, -run3, hoặc timestamp. KHÔNG overwrite log cũ.
Nội dung bắt buộc:
- Timestamp start/end
- Candidate path:
/opt/incomex/data/tac/gate-a/production_ddl_candidate.sql - Dry-run bundle SHA (§1.1)
- Production DDL candidate SHA (§1.5)
- Transform summary: 5 sed steps, 5 verify results
- DML classification: total matches, per-line context + classification (hoặc "0 matches, clean")
- Pre-checks P1–P7 (incl. P5 health method + P7 3 sub-checks)
- psql exit code + full output
- Post-checks Q1–Q8
- Trigger guard warnings (expected count)
- Error handling path taken (none / Path A auto-clean / Path A manual / Path B manual)
- PASS/FAIL verdict
- Rollback evidence (nếu có)
9. Output Format
Gate A Production DDL Execution Results:
Context:
VPS: contabo (vmi3080463)
Candidate: /opt/incomex/data/tac/gate-a/production_ddl_candidate.sql
Pre-execution:
Bundle SHA (dry-run): [hash] (verified/MISSING)
Transform: 5 steps → V-T1–V-T5 [ALL PASS / FAIL detail]
DML denylist: [0 matches clean / N matches → classification]
Production SHA: [hash]
Pre-checks: P1–P7 [ALL PASS / FAIL detail]
P5: [HTTP 200 / auth-protected+DB-accessible / FAIL]
P7: [P7a enabled / P7b public.trigger_guard_alerts / P7c search_path]
Execution:
psql exit: [0 / non-zero]
Output: /opt/incomex/data/tac/gate-a/execution-output.txt
Error handling: [none / Path A auto-clean / Path A manual rollback / Path B manual rollback]
Post-checks: Q1–Q8 [ALL PASS / FAIL detail]
Verdict: GATE A PASS / GATE A FAIL
10. Sau Gate A PASS
STOP. Không tự chuyển sang Gate B/C. Báo cáo → GPT review → User authorize Gate B riêng.
Appendix A — Patch Log
| Rev | GPT | Patches | Key |
|---|---|---|---|
| v0.1→v0.2 | R1 | 5 | DML denylist, controlled transform, catalog verify, output≠truth, fn signature |
| v0.2→v0.3 | R2 | 6 | DML classify, Directus token-safe, trigger guard deep, auto-rollback, HE-9, action log |
| v0.3→v0.4 | R3 | 6 | pipefail, 2 rollback paths, P7b qualified, DML expected=0 escalate, health wording, VPS explicit |
| v0.4→v0.5 | R4+R5 | 3+3 | DML grep whitespace-tolerant, scaffold sed robust regex, action log no-overwrite, heading fix, grep ` |
v0.3→v0.4 detail:
| # | GPT R3 | Patch |
|---|---|---|
| 1 | tee masks exit code | §3.1: set -o pipefail + PIPESTATUS[0] |
| 2 | Tách rollback paths | §3.3: Path A (execution error) vs Path B (COMMIT + Q-fail) |
| 3 | P7b qualified reference | §2.2 P7b: public.trigger_guard_alerts not unqualified |
| 4 | DML expected=0, unexpected→STOP | §1.4: any match = escalate, agent không tự approve |
| 5 | Health wording | §2.1: HTTP 200 / auth+DB-accessible / 5xx STOP |
| 6 | VPS context | Header + HE-11 mới |
v0.4→v0.5 detail:
| # | GPT R4 | Patch |
|---|---|---|
| 1 | DML grep miss indented lines | §1.4: [[:space:]]* prefix + [[:space:]] suffix, INSERT[[:space:]]+INTO unanchored |
| 2 | Scaffold sed miss IF NOT EXISTS / indent | §1.2: whitespace-tolerant regex cho CREATE SCHEMA + COMMENT ON SCHEMA |
| 3 | Action log overwrite risk | §8: no-overwrite policy, suffix -run2 hoặc timestamp |
v0.5 GPT R5 final patches:
| # | GPT R5 | Patch |
|---|---|---|
| 1 | Heading still said v0.4 | Title → v0.5 FINAL |
| 2 | grep no-match exit 1 aborts strict shell | §1.4: ` |
| 3 | Candidate generation ≠ Gate A PASS | §1.5: clarification block added |
Gate A Production DDL Execution Prompt Design v0.5 FINAL | S186 | 2026-04-28 GPT R5 CONDITIONAL PASS — all final edits applied Chờ User GO → Agent execute KHÔNG authorize. KHÔNG Gate B/C/G8B/G11/P9.