GPT Review — 22-P3-P1 Policy + Canonical Marker Prompt rev3
GPT Review — 22-P3-P1 Policy + Canonical Marker Prompt rev3
Date: 2026-05-06
Reviewer: GPT-5.5 Thinking / Incomex Hội đồng AI
Reviewed:knowledge/dev/laws/dieu44-trien-khai/prompts/22-p3-p1-iu-gateway-policy-and-canonical-marker-prompt.mdrev3
Verdict
Do not dispatch rev3. Rev4 required.
Rev3 fixes the big idempotency blocker: CREATE OR REPLACE is now shell-branched and will not run in PATCHED_EXACT. That is the right direction.
However, a few last shell-safety/report-safety issues remain. These are small but real: under failure paths, the script can still abort before final verdict due to unset variables, and final verdict can pass without proving all 9 policy keys exist.
Required rev4 patches
P1 — Initialize KEY_COUNT and avoid unset-variable failure
Rev3 echoes:
echo "gateway_keys=$KEY_COUNT"
But KEY_COUNT is only set inside if [ $PSQL_EXIT -eq 0 ]; then .... If SQL fails, KEY_COUNT is unset and set -u can terminate the script before final report.
Patch:
KEY_COUNT="NOT_RUN"
at initialization.
P2 — Final verdict must require KEY_COUNT=9
Policy keys are half of P3-P1. Rev3 verifies key count post-commit but does not use it in final verdict.
Patch final condition:
if [ $PSQL_EXIT -eq 0 ] && [ $POST_EXIT -eq 0 ] && [ "$POST_STATUS" = "PASS" ] && [ "$LEAK_STATUS" = "PASS" ] && [ "$KEY_COUNT" = "9" ]; then
If KEY_COUNT is not 9, phase FAIL / P3P2 BLOCKED.
P3 — Normalize KEY_COUNT output
The key-count query can return noisy output or fail. Normalize it:
KEY_COUNT=$(echo "$KEY_COUNT" | tr -d '[:space:]')
if ! [[ "$KEY_COUNT" =~ ^[0-9]+$ ]]; then
KEY_COUNT="INVALID_OUTPUT"
fi
P4 — Patch state detection failure/empty result must STOP safely
Rev3 only blocks UNKNOWN_PATCH_STATE. If the detection query fails or returns empty, the script proceeds with an invalid branch.
Patch:
if [ "$PATCH_STATE" != "PATCHED_EXACT" ] && [ "$PATCH_STATE" != "UNPATCHED" ]; then
echo "STOP: invalid patch_state=$PATCH_STATE"
echo "phase_status=BLOCKED"
echo "=== UPLOAD REPORT NOW ==="
exit 0
fi
Keep explicit UNKNOWN_PATCH_STATE handling.
P5 — Validate pilot address before SQL
Rev3 embeds PILOT_ADDRESS into the generated SQL DO block. It is generated internally, but writer prompts should still validate before use.
Add strict regex:
if ! [[ "$PILOT_ADDRESS" =~ ^pilot\.p3\.p1\.[0-9]{8}-[0-9]{6}\.[0-9a-f]{8}$ ]]; then
echo "STOP: invalid pilot address: $PILOT_ADDRESS"
echo "phase_status=BLOCKED"
echo "=== UPLOAD REPORT NOW ==="
exit 0
fi
P6 — PUBLIC EXECUTE check should cover both fn_iu_create and fn_iu_create_plan
Rev3 checks only fn_iu_create. Since P3-P1 policy references both canonical and plan functions, check both:
WHERE routine_schema='public'
AND routine_name IN ('fn_iu_create','fn_iu_create_plan')
AND grantee='PUBLIC'
P7 — Directus effective execute should be machine-checked
Rev3 displays routine privileges, but final safety should assert directus can execute fn_iu_create after patch.
Add DO block before COMMIT:
DO $$
BEGIN
IF NOT has_function_privilege('directus', 'public.fn_iu_create(text,text,text,text,text,text,text,text,uuid)', 'EXECUTE') THEN
RAISE EXCEPTION 'directus lacks EXECUTE on fn_iu_create';
END IF;
END $$;
P8 — Trigger-count unchanged should be machine-checked, not display-only
Rev3 displays before/after trigger counts but does not assert they match. Since P3-P1 must not create trigger guard, add expected count variables inside SQL or a simple DO block:
- capture pre-counts into temp settings or temp variables in transaction;
- after pilot, compare counts;
- if changed, raise exception.
Keep it simple. Example with transaction-local temp table is acceptable:
CREATE TEMP TABLE p3p1_baseline(k text primary key, v int) ON COMMIT DROP;
INSERT INTO p3p1_baseline VALUES ('iu_triggers', ...), ('uv_triggers', ...);
...
DO $$
DECLARE v_iu int; v_uv int;
BEGIN
SELECT count(*) INTO v_iu FROM pg_trigger ... information_unit ...;
SELECT count(*) INTO v_uv FROM pg_trigger ... unit_version ...;
IF v_iu <> (SELECT v FROM p3p1_baseline WHERE k='iu_triggers') THEN RAISE EXCEPTION ...; END IF;
IF v_uv <> (SELECT v FROM p3p1_baseline WHERE k='uv_triggers') THEN RAISE EXCEPTION ...; END IF;
END $$;
P9 — Report should include function_replace branch even on early STOP
If early STOP occurs due invalid patch state or invalid pilot address, report should still include:
patch_statefunction_replace=NOT_RUNphase_status=BLOCKED- reason.
Directive to Opus
Patch P3-P1 prompt to rev4 with P1–P9.
The rev3 direction is acceptable; do not redesign. This is last-mile hardening only.
Do not dispatch after patch; return for GPT/User approval.
Hard boundaries remain
- no trigger guard creation;
- no GRANT/REVOKE;
- no Directus permission changes;
- no role separation;
- no detector implementation;
- no DOT registration;
- no adapter implementation;
- no cleanup pilots;
- no Pack 2C.
Summary
Rev3 solved the stale-body clobber issue. Rev4 should prevent failure-path shell aborts and ensure the final PASS proves all required outcomes: SQL success, post-commit invariant success, marker no-leak, exactly 9 policy keys, no PUBLIC execute, directus execute intact, and trigger counts unchanged.