GPT Review — 23-P3A Gateway Allow-list Prompt rev2
GPT Review — 23-P3A Gateway Allow-list Prompt rev2
Date: 2026-05-06
Reviewer: GPT-5.5 Thinking / Incomex Hội đồng AI
Reviewed:knowledge/dev/laws/dieu44-trien-khai/prompts/23-p3a-iu-gateway-allow-list-patch-prompt.mdrev2
Verdict
Rev2 is much better but still NOT ready to dispatch. Rev3 required.
Opus correctly applied the 12 fixes from the previous review. The prompt is close, but a few runtime issues remain that could cause failure, false PASS, or broken reporting.
Accepted improvements in rev2
pg_get_functiondef()backup is now used for restore.- Allow-list parsing syntax is fixed.
SAVEPOINTinsideDOblocks was removed.- Future marker
fn_iu_apply_edit_draftis tested in a rollback transaction. fn_iu_createis tested with a real pilot, not dry-run.- Function lookup is schema-qualified.
- dot_config uniqueness is checked.
- Error message guidance is tested.
- Metadata and privileges are captured.
- dot_config rollback is deterministic.
- Pilot address/counts are reported.
Required rev3 fixes
P1 — Fix variable typo: PSQL_NOSTOP vs PSQL_NONSTOP
The prompt defines:
PSQL_NOSTOP="docker exec -i $CONTAINER psql -U $USER -d $DB"
But tests use:
$PSQL_NONSTOP
This will fail at runtime.
Patch to one consistent name. Prefer:
PSQL_NOSTOP=(docker exec -i "$CONTAINER" psql -U "$USER" -d "$DB")
PSQL=(docker exec -i "$CONTAINER" psql -U "$USER" -d "$DB" -v ON_ERROR_STOP=1)
and call arrays as:
"${PSQL[@]}"
"${PSQL_NOSTOP[@]}"
If not converting to arrays, at minimum rename all PSQL_NONSTOP to PSQL_NOSTOP.
P2 — Verify fn_iu_create signature dynamically before Test 3
Rev2 calls:
fn_iu_create(address, title, body, actor)
But previous Pack 22 prompts used a wider signature, and exact runtime signature must not be assumed.
Patch Test 3 to discover signature first:
SELECT oid::regprocedure::text AS sig,
pg_get_function_arguments(oid) AS args
FROM pg_proc p
JOIN pg_namespace n ON n.oid=p.pronamespace
WHERE n.nspname='public' AND p.proname='fn_iu_create';
Then call the exact supported signature. If the prompt cannot safely branch by signature, use the signature reported by P3-P2/23-P2 runtime evidence and include it explicitly.
Do not assume the 4-arg form.
P3 — Fix Test 3 JSON parsing / status extraction
Current Test 3 contains a fragile nested shell/psql parse:
T3_STATUS=$(echo "$T3_RESULT" | $PSQL_NOSTOP -t -A -c "SELECT (\$\$${T3_RESULT}\$\$::jsonb)->>'status';")
This is unsafe and may break on quotes/newlines. Instead, have SQL return the status directly:
WITH r AS (
SELECT public.fn_iu_create(...) AS j
)
SELECT j->>'status' AS status,
j AS full_result
FROM r;
Or run two SQL columns with field separator and parse safely.
P4 — Initialize all verdict variables
The final report references variables that may never be set:
PATCH_STATUSTEST_FAILT3_STATUST4T6T7SOURCE_HASH_AFTERT2PILOT_ADDR
Initialize at top:
PREFLIGHT_STATUS=""
PATCH_STATUS="NOT_RUN"
TEST_FAIL=""
PHASE_STATUS=""
P3B_READINESS="BLOCKED"
ROLLBACK_STATUS="N/A"
SOURCE_HASH_AFTER=""
T2=""
T3_STATUS="NOT_RUN"
T4="NOT_RUN"
T5="NOT_RUN"
T6="NOT_RUN"
T7="NOT_RUN"
PILOT_ADDR=""
When each test runs, set a machine-readable variable, not only echo text.
P5 — Preflight fail should exit patch/test path cleanly
Rev2 says “jump to §5” in comments, but a shell script will not jump. Although later sections are conditionally guarded, final variables can still be inconsistent.
Add a clear control flow:
if [ "$PREFLIGHT_STATUS" != "PASS" ]; then
PATCH_STATUS="NOT_RUN"
TEST_FAIL="NOT_RUN"
PHASE_STATUS="FAIL"
P3B_READINESS="BLOCKED"
# write report and exit 0 after upload/report generation
fi
Do not rely on comments.
P6 — Test 4/7 direct IU inserts may leave aborted transactions or uncommitted behavior unclear
Use separate psql calls with no explicit transaction for direct-block tests, because gateway exception aborts only that statement/session and no row is inserted.
For marker-accepted tests that may insert, use explicit BEGIN ... ROLLBACK and set +e capture.
This is mostly present, but make the distinction explicit to avoid later “cleanup” attempts.
P7 — Test 5 should not treat FK-first as full gateway proof
It is acceptable as “direct UV write did not succeed,” but it does not prove the UV gateway trigger still blocks direct UV writes.
Rev3 should report it honestly:
T5_DIRECT_UV_WRITE_PREVENTED=PASST5_GATEWAY_PROVEN=PASS/NOT_PROVEN_FK_FIRST
Do not label FK-first as equivalent to gateway block. It is safe for this phase but should not overclaim.
P8 — Add direct UV UPDATE test on an existing pilot UV
P3A patches a guard for INSERT OR UPDATE on UV. Test 5 only tries INSERT and may be blocked by FK first.
Add a rollback transaction test:
- Select an existing UV id from a pilot IU.
- Begin transaction.
- Attempt direct
UPDATE unit_version SET body = body || 'x' WHERE id = <uv_id>without marker. - Expect
IU Gateway blocked. - Rollback.
This proves UV UPDATE guard still works.
P9 — Test 6 marker acceptance should avoid birth/business-gate false interpretation if possible
The marker-accepted IU INSERT may fail on birth/business gates. That is acceptable, but the test should classify:
IU Gateway blocked→ FAIL;- non-gateway error → PASS_GATEWAY_ACCEPTED_BUT_OTHER_ERROR;
- insert success → PASS_GATEWAY_ACCEPTED_INSERT_ROLLED_BACK.
Rev2 mostly does this. Make the report variable explicit:
T6="PASS_GATEWAY_ACCEPTED_BUT_OTHER_ERROR"
or equivalent.
P10 — Grants comparison should not treat intentional REVOKE PUBLIC as unexpected ACL change
The patch re-applies:
REVOKE ALL ... FROM PUBLIC
If PUBLIC was previously present, ACL may change in a stricter direction. That is acceptable. Rev3 should compare “not broadened,” not exact equality.
Add a clear rule:
- fail if PUBLIC gains EXECUTE;
- fail if intended role loses required execute only if it had it before and is expected to keep it;
- otherwise ACL change to stricter is OK.
P11 — dot_config uniqueness check should verify uniqueness on key, not any unique constraint
Rev2 fallback checks any UNIQUE/PK constraint on dot_config, which could be unrelated to key.
Use catalog join with attributes. Example:
SELECT count(*)
FROM pg_index i
JOIN pg_class t ON t.oid=i.indrelid
JOIN pg_namespace n ON n.oid=t.relnamespace
WHERE n.nspname='public'
AND t.relname='dot_config'
AND i.indisunique
AND (
SELECT array_agg(a.attname ORDER BY a.attnum)
FROM unnest(i.indkey) k(attnum)
JOIN pg_attribute a ON a.attrelid=t.oid AND a.attnum=k.attnum
) = ARRAY['key'];
Expected exactly 1.
P12 — Report upload instruction should be executable
The prompt ends with “UPLOAD REPORT NOW” but does not specify the Agent Data create/update command. Add explicit instruction:
- create/update KB doc at
knowledge/dev/laws/dieu44-trien-khai/reports/23-p3a-iu-gateway-allow-list-patch-report.md; - include full log content or a summarized report plus log path;
- upload even on preflight failure.
Directive to Opus
Patch P3A prompt to rev3 with P1–P12.
Path:
knowledge/dev/laws/dieu44-trien-khai/prompts/23-p3a-iu-gateway-allow-list-patch-prompt.md
Do not dispatch after patch. Return for GPT/User review.
Hard boundaries remain
- No P3B schema DDL.
- No edit draft/comment tables.
- No edit functions.
- No vector mutation.
- No cleanup.
- No Pack 2C.
Summary
Rev2 fixes the big SQL hazards from rev1, but still has runtime issues: a variable typo, likely wrong fn_iu_create signature assumption, fragile JSON parsing, incomplete verdict variables, and UV gateway coverage that may overclaim when FK fires first. Rev3 should correct these before dispatch.