GPT Review — 23-P3C2 Prompt rev1 + Notification Roadmap Directive
GPT Review — 23-P3C2 Prompt rev1 + Notification Roadmap Directive
Date: 2026-05-07
Reviewer: GPT-5.5 Thinking / Incomex Hội đồng AI
Reviewed:knowledge/dev/laws/dieu44-trien-khai/prompts/23-p3c2-iu-apply-edit-functions-prompt.mdrev1
New User requirement: PG-native notification/inbox logs for new comments and updates, separate lightweight logs, future Hermes/reviewer automation.
Verdict
P3C2 rev1 is directionally correct but NOT ready to dispatch. Rev2 required.
Opus correctly framed P3C2 as the dangerous write path and kept the objective narrow: fn_iu_apply_edit_draft + fn_iu_edit. However, rev1 has several concrete blockers that must be fixed before execution.
Separately, the new notification/log requirement is accepted as an important roadmap item. It should be recorded now, but not implemented inside P3C2, because P3C2 hard boundaries prohibit new DDL/triggers.
New requirement accepted: PG-native notification/outbox logs
The User requirement is valid and strategically important:
- Reviewers/agents should not search manually to discover what changed.
- The system should maintain lightweight lists of recent updates and comments.
- Comment events and update/apply events should be separated.
- These logs are not the same as general activity logs; they are operational work queues/inboxes for downstream processing.
- This is the beginning of automated reviewer agents such as Hermes.
Recommended future design direction
Create a future pack after P3C2 PASS, likely P3D — IU Notification Outbox / Reviewer Inbox.
PG-native, simple model:
-
iu_comment_event_log/iu_comment_inbox_log- append-only, lightweight
- populated by trigger after
unit_edit_comment INSERT - captures: comment_id, draft_id, unit_id, canonical_address, author_ref, comment_kind, created_at, maybe short preview/hash
-
iu_update_event_log/iu_update_inbox_log- append-only, lightweight
- populated by trigger after official update/apply event, likely
unit_version INSERTorunit_edit_drafttransition toapplied - captures: unit_id, canonical_address, version_id, version_seq, actor, applied_draft_id, created_at/applied_at
-
Keep this separate from general activity log.
-
Keep payload minimal. Large body/comment content should stay in canonical tables; event log stores references and short preview only.
-
Index for reviewer/Hermes flows:
- newest first (
created_at DESC/event_at DESC) - status/pending if later needed
- actor/unit filters
- newest first (
-
Later combine with per-actor watermark model:
- reviewer sees events newer than their last-view watermark;
- latest 3–5 viewers derived from review-state table.
Why not in P3C2
P3C2 must not add tables/triggers. It should only create apply/wrapper functions. Adding notification logs now would expand scope and risk delaying the official edit path.
But P3C2 prompt/report should explicitly record:
- notification outbox is not implemented yet;
- after P3C2 PASS, P3D should design the comment/update event logs;
- no production reviewer automation/Hermes should depend on notifications until P3D exists.
Accepted P3C2 direction
fn_iu_apply_edit_draftis the only Pack 23 function allowed to write IU/UV.fn_iu_editis a wrapper and should delegate official writes to apply.- Gateway marker
fn_iu_apply_edit_draftis used in apply. - Invariant verification is required after official writes.
stale_baseis enough for Phase 1; no rebase/merge complexity now.- Actor-card and per-actor watermark remain deferred hooks.
Required rev2 fixes
P1 — CRITICAL: content_anchor_ref must follow Pack 22 invariant, not draft hash
Rev1 sets:
content_anchor_ref = v_hash
But prior IU invariant says content_anchor_ref = version_anchor_ref::text. The old schema inspection explicitly captured that L2 requires content_anchor_ref = version_anchor_ref::text.
Patch:
content_anchor_ref = v_new_uv_id::text
Do not use content hash as the IU content anchor unless Pack 22 invariant has been changed and re-verified, which it has not.
P2 — JSON capture/parsing in tests is unsafe
Rev1 uses:
T1_JSON=$("${PSQL[@]}" <<EOSQL
SELECT public.fn_iu_apply_edit_draft(...);
EOSQL
)
T1_S=$("${PSQL[@]}" -t -A -c "SELECT ('$T1_JSON'::jsonb)->>'status';")
Plain psql output includes headers/formatting unless -t -A is used, and JSON may include quotes/newlines. This can break.
Patch tests to return status/key fields directly from SQL:
T1_P=$("${PSQL[@]}" -t -A <<EOSQL
WITH r AS (SELECT public.fn_iu_apply_edit_draft('$DRAFT_A_ID'::uuid,'agent:p3c2-test','P3C2 test apply') AS j)
SELECT j->>'status', j->>'version_id', j->>'version_seq', j FROM r;
EOSQL
)
Parse fields from T1_P. Do not echo captured JSON back into SQL.
Apply same fix to T10 and other JSON tests.
P3 — Avoid psql -c with :'var', but also avoid raw interpolation where possible
Rev1 notes the P3C1 caveat but still uses many raw shell interpolations. For UUIDs that are runtime-validated, shell interpolation is acceptable if carefully quoted. For address/body text, prefer heredoc and SQL literals generated inside SQL.
At minimum:
- validate draft IDs with UUID regex before use;
- validate
TEST_ADDR_Ais not empty and contains no single quote before raw interpolation; - avoid embedding arbitrary body text from shell.
P4 — Preflight Gate 5 must discover exact fn_iu_verify_invariants signature
Rev1 assumes:
public.fn_iu_verify_invariants(uuid)
This is likely correct but must be verified with to_regprocedure. If exact signature differs, STOP.
Also capture the signature in the report.
P5 — Unique constraint check must verify exact (unit_id, version_seq)
Rev1 accepts any unique constraint on unit_version, which can false-pass.
Patch using pg_index + pg_attribute exact attname array:
... i.indisunique
AND attname_array = ARRAY['unit_id','version_seq']
Expected exactly 1.
P6 — Lifecycle count uses fragile grep -c pattern
Rev1 uses:
UV_LC_COUNT=$(echo "$UV_LIFECYCLE" | grep -c . 2>/dev/null || echo "0")
This can produce 0\n0. Use SQL count directly:
SELECT count(DISTINCT lifecycle_status) FROM unit_version;
Also capture the single value separately.
P7 — Applying DRAFT_A marks DRAFT_B stale; then T10 on same address may depend on current state
This is acceptable, but rev2 should report state transitions explicitly:
- before apply: A=open, B=open;
- after apply A: A=applied, B=stale_base;
- after wrapper T10: a new draft is created and applied.
This helps distinguish expected stale behavior from accidental draft closure.
P8 — fn_iu_apply_edit_draft should update IU title and updated_at in one UPDATE if possible
Rev1 performs two IU UPDATEs:
- anchor/update metadata;
- title JSON update if draft title is not null.
This is not fatal, but it fires update triggers twice and creates unnecessary churn.
Patch to one UPDATE information_unit SET ... identity_profile = CASE ... END statement.
P9 — Stale-base path mutates draft before returning; test it explicitly
Rev1 tests already-applied draft, but not stale-base due to head changed before apply. Add or adjust a test:
- create a draft from current head;
- move head via another apply/wrapper;
- then apply old draft;
- expected
stale_base, no new UV, draft status becomesstale_base.
If this is too much for rev2, at minimum test that DRAFT_B is stale after applying A and cannot be applied.
P10 — fn_iu_edit wrapper must not auto-apply if policy is not exactly auto_apply
Rev1 treats all non-auto policies as require_review. Good. Add exact status field:
draft_created_review_required
and include policy in response. Add a test only if easily possible; otherwise report this as untested because current policy is auto_apply.
P11 — Source check should prove P3C1 function sources unchanged by hash
Rev1 only verifies P3C1 functions still exist. Since P3C2 should not alter P3C1, capture md5(prosrc) before and after for the 4 P3C1 functions.
Expected unchanged.
P12 — Security grantee checks should avoid raw role interpolation
Rev1 uses:
has_function_privilege('$R','public.$SIG','EXECUTE')
Use safer pattern via heredoc or validated role names. Since grantees are discovered from regrole::text, this is low risk, but rev2 should follow the safer P3C1 pattern if possible.
P13 — Cleanup behavior must acknowledge official writes are retained on test fail
If tests fail after successful apply, functions may be dropped but official version rows/comments remain. Do not imply full cleanup.
Report fields should include:
cleanup_on_test_fail=drop_p3c2_functions_onlyofficial_test_rows_retained_on_fail=truepilot_rows_retained=true
If this is unacceptable, redesign tests to run against dedicated pilot IU and retain it intentionally. Do not attempt destructive cleanup.
P14 — Add notification roadmap note to P3C2 prompt/report
Add a short section:
Notification / Hermes Outbox Hook (deferred)
Include:
- comments and official updates should later feed separate lightweight PG-native logs;
- comment log and update log must be separate;
- logs are operational work queues, not general activity logs;
- P3C2 does not implement them;
- next recommended pack after P3C2 PASS: P3D notification outbox design.
P15 — Report should include invariant JSON output from apply
Rev1 returns invariants in JSON, but tests/report should capture and display it. Required for confidence.
P16 — fn_iu_edit source should be allowed to mention fn_iu_apply_edit_draft but not direct write SQL
T15 currently checks wrapper for gateway marker / INSERT UV / UPDATE IU. Good. Expand to include DELETE and INSERT INTO information_unit / UPDATE unit_version as in P3C1.
P17 — Final readiness should be p3d_readiness=READY only if notification/outbox is acknowledged as deferred
This avoids confusion: P3C2 PASS means edit workflow usable, but production reviewer automation still needs P3D notification outbox.
In report:
p3d_readiness=READY_FOR_NOTIFICATION_OUTBOX_DESIGN
or keep p3d_readiness=READY and add:
next_required_pack=P3D_NOTIFICATION_OUTBOX_BEFORE_HERMES
GPT recommendation: keep p3d_readiness=READY, add next_required_pack=P3D_NOTIFICATION_OUTBOX_BEFORE_HERMES.
Directive to Opus
Patch P3C2 prompt to rev2 with P1–P17.
Path:
knowledge/dev/laws/dieu44-trien-khai/prompts/23-p3c2-iu-apply-edit-functions-prompt.md
Additionally create or update a roadmap note:
knowledge/dev/laws/dieu44-trien-khai/design/23-p3d-notification-outbox-roadmap-note.md
Roadmap note should capture:
- separate comment event log;
- separate update/apply event log;
- PG triggers are acceptable later;
- logs are lightweight references/queues, not full body stores;
- not the same as general activity log;
- future Hermes/reviewer agent consumes these logs;
- combine later with per-actor watermark review state.
Do not dispatch after patch. Return for GPT/User review.
Hard boundaries remain for P3C2 rev2 prompt
- No dispatch.
- No table DDL.
- No trigger/gateway changes.
- No vector mutation.
- No cleanup.
- No notification log implementation in P3C2.
- No Pack 2C.
Summary
P3C2 is the right next step, but rev1 has one critical invariant bug (content_anchor_ref must be new UV id text, not content hash) and fragile JSON parsing in tests. The new notification requirement is accepted but should become a P3D roadmap/design item, not be squeezed into P3C2 execution.