KB-4C10

GPT Review — P3D4C2U Option D Prompt rev1

7 min read Revision 1
gpt-reviewp3d4c2uoption-drev2-requiredfield-allowlistdirectus-table

GPT Review — 23-P3D4C2U Option D Prompt rev1

Date: 2026-05-08
Reviewer: GPT-5.5 Thinking / Incomex Hội đồng AI
Reviewed: knowledge/dev/laws/dieu44-trien-khai/prompts/23-p3d4c2u-option-d-base-table-field-allowlist-implementation-prompt.md rev1

Verdict

REV2 REQUIRED — do not dispatch rev1.

Rev1 correctly pivots away from the blocked PG view path. Option D is the right direction: expose the event_outbox base table with a real PK, protect it with Directus field allowlist + Table Module field config, and do not create view/materialized view/worker/cron/Nuxt code.

However rev1 still needs several production-safety patches before dispatch.

Accepted parts

  • Correctly abandons the PG view path for this pack.
  • Correctly uses base table event_outbox, which has a real primary key.
  • Correctly requires a Directus permission field allowlist.
  • Correctly requires Table Module / table_registry field config allowlist.
  • Correctly adds a critical gate for DirectusTable fetch behavior.
  • Correctly forbids Nuxt code, bespoke UI, mark-read/write, view/materialized view, worker/cron, new role, IU changes.

Required rev2 patches

P1 — Field-leak smoke must run under the intended Directus read role, not admin

Rev1 smoke examples do not specify which token/role is used. If Agent tests with an admin token, unsafe fields may be readable even though the intended public/user role is protected, or the reverse may be hidden by admin behavior.

Patch Step 4:

  • identify the intended Directus app role/policy from system_issues convention;
  • perform read and unsafe-field tests using that role/policy/token, not admin;
  • admin token may be used only for setup/introspection, not for exposure-safety proof;
  • report smoke_token_role=<role/policy>.

P2 — DirectusTable fetch path must be proven from code or live request, not inferred

Rev1 asks to determine fetch path, good. Make it stricter:

  • prove DirectusTable uses the table_registry field list as Directus fields= selector;
  • if proven by code, cite file/function path in report;
  • if proven by live network/log trace, report request URL/query fields;
  • if it uses admin/server token, Table Module field selector becomes mandatory protection;
  • if it fetches all fields or fetch path is unknown, STOP with NEEDS_TABLE_MODULE_FIELD_FILTER.

P3 — table_registry schema must still be inventory-driven, not assume fields_config

Rev1 says copy shape from system_issues, but Step 3 still says:

fields_config = [14 metadata fields with labels]

Patch:

  • inspect actual table_registry columns/types;
  • inspect actual tbl_system_issues row shape;
  • use the actual config column name, whether fields, fields_config, or another convention;
  • write via the convention channel found in inventory;
  • do not hardcode fields_config unless confirmed live.

P4 — Existing permission on event_outbox must be conflict-aware across all roles/policies

Rev1 checks existing read permission, but must handle multiple roles/policies:

  • list all Directus permissions for event_outbox;
  • if any existing read permission exposes unsafe fields to public/user/table-module role, STOP;
  • if admin-only permission exists, ignore for user exposure but record it;
  • create/update only the intended read role/policy;
  • assert no create/update/delete for intended role.

P5 — Existing table_registry row conflict must be checked by table_id and collection

Patch Step 3:

  • search both table_id='tbl_event_outbox' and collection='event_outbox';
  • if either exists and compatible, reuse;
  • if either exists and incompatible, STOP TABLE_REGISTRY_CONFLICT_STOP;
  • do not create duplicate rows.

P6 — Route smoke is referenced but not defined

Step 5 references route smoke, but Step 0 does not define how route smoke is performed.

Patch:

  • keep system_issues route smoke from previous prompt: /knowledge/registries/system_issue;
  • define event route smoke: /knowledge/registries/event_outbox only after draft row exists;
  • if tooling cannot verify route, keep registry status draft and report READONLY_EXPOSURE_DRAFT_PENDING_ROUTE_SMOKE;
  • do not publish on API-only proof.

P7 — Approved field list must match live schema exactly

Rev1 uses event_severity, which matches the latest report, good. Patch to require:

  • inspect live columns;
  • include only approved fields that actually exist;
  • if a required metadata field is absent, report it and continue only if non-critical;
  • never include safe_payload, payload, correlation_id, causation_id.

P8 — GET /items/event_outbox?fields=safe_payload smoke should define expected behavior precisely

Patch S3:

  • using intended read role, request safe_payload explicitly;
  • acceptable result: 403, 400/field forbidden, or response omits the field;
  • unacceptable: safe_payload value returned;
  • repeat for correlation_id or test all unsafe fields if feasible.

P9 — Rollback must track whether permission/registry/field metadata pre-existed

Rev1 says scoped rollback. Add fields:

permission_created_by_pack=true|false
permission_updated_by_pack=true|false
registry_row_created_by_pack=true|false
registry_row_updated_by_pack=true|false
field_metadata_changed_by_pack=<list>

If a compatible pre-existing permission/row was reused, do not delete it on rollback.

P10 — Next pack must be conditional

Rev1 always says:

next_required_pack=P3D4C3U_USER_VIEW_SMOKE_AND_MARK_READ_DECISION

Patch to conditional:

  • if published: P3D4C3U_USER_VIEW_SMOKE_AND_MARK_READ_DECISION;
  • if draft pending route smoke: P3D4C2U_MANUAL_ROUTE_SMOKE;
  • if Table Module fetch path unsafe: TABLE_MODULE_FIELD_FILTER_EXTENSION_PROMPT_REVIEW;
  • if field leak: FIELD_PERMISSION_REPAIR_PROMPT_REVIEW.

Directive to Opus

Patch the prompt to rev2 at:

knowledge/dev/laws/dieu44-trien-khai/prompts/23-p3d4c2u-option-d-base-table-field-allowlist-implementation-prompt.md

Patch narrowly. Keep Option D. Do not reopen the view/materialized-view/custom-extension options. Do not dispatch after patch; return for GPT/User review.

Hard boundaries unchanged

  • No PG view.
  • No materialized view.
  • No worker/cron/refresh.
  • No new table/write path.
  • No custom Directus extension.
  • No Nuxt code.
  • No bespoke notification UI.
  • No Directus click-config.
  • No Directus write/mark-read.
  • No unsafe field exposure.
  • No IU runtime change.
  • No event core mutation except Directus permission/field metadata/table_registry exposure.
  • No Điều 43 machinery change.

Summary

Option D is correct, but rev1 still needs stronger role-specific smoke testing and proof that Table Module uses field selection. The safety of exposing the base table depends entirely on those two allowlist layers working as intended.

Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/reviews/gpt-review-23-p3d4c2u-option-d-prompt-rev1-2026-05-08.md