KB-2E92

GPT Review — D28 Deploy Live Smoke Prompt rev1

10 min read Revision 1
gpt-reviewdieu28deploylive-smokerev2-requiredproduction

GPT Review — D28 Deploy + Live Smoke Prompt rev1

Date: 2026-05-10
Reviewer: GPT-5.5 Thinking / Incomex Hội đồng AI
Reviewed: knowledge/dev/laws/dieu28-trien-khai/prompts/d28-deploy-and-live-smoke-prompt-review.md rev1

Verdict

REV2 REQUIRED — do not dispatch rev1.

Rev1 has the right overall direction: two-stage deploy approval, explicit user-facing impact warning, no event_outbox publish, and no P3D resume inside this D28 deployment pack.

However, because this is the first prompt that may actually deploy to production, it needs stricter separation between preflight and mutation, stronger tag/rollback handling, and safer smoke/log rules.

Accepted parts

  • Two-stage model is correct:
    • Stage 1 = preflight only;
    • Stage 2 = deploy + smoke only after explicit approval.
  • Approval phrase is explicit and useful.
  • User-facing impact is disclosed.
  • event_outbox route smoke is deferred.
  • tbl_event_outbox remains draft.
  • No Directus/PG/table_registry mutation.
  • No P3D resume in this pack.
  • Smoke target set is broadly correct.
  • Failure matrix is useful.

Required rev2 patches

P1 — Phase 0 must be truly no-impact: move image backup out of Phase 0

Rev1 Phase 0I runs:

docker tag nuxt-ssr-local:s174 nuxt-ssr-local:pre-d28-rollback

This is a mutation. It violates the Stage 1 definition:

Stage 1: Phase 0 only (preflight, no impact)

Patch:

  • Phase 0 may only plan backup image tag creation.
  • Actual docker tag backup must move to Phase 1 after approval phrase is verified.
  • Stage 1 report should say:
backup_image_tag_planned=nuxt-ssr-local:pre-d28-rollback
backup_image_tag_created=false

P2 — Approval phrase must include exact new image tag and rollback image tag

Rev1 says Agent proposes tag in Phase 0, but Stage 2 approval phrase only mentions commits. It should also bind the deployment to the exact image tag.

Patch Stage 1 report to output:

proposed_new_image_tag=<exact>
proposed_backup_image_tag=<exact>

Stage 2 approval phrase should include them, e.g.:

APPROVE D28 DEPLOY: I authorize deploying commits d2db418 + 0947613 as image <new_image_tag> to production with brief service interruption, using rollback image <backup_image_tag>.

Agent must verify exact phrase or exact structured approval fields. Do not let Stage 2 deploy with a different tag than Stage 1 proposed.

P3 — New tag convention must be decided in prompt, not left open

Rev1 says s175 or commit hash or timestamp, and “Agent propose, không tự quyết.” That is fine for Stage 1, but Stage 2 needs a fixed value.

GPT recommendation:

new_image_tag=nuxt-ssr-local:d2db418

Reason: commit hash is traceable and avoids guessing what s174 means.

If User wants s175, Stage 1 report can expose the choice, but prompt rev2 should set the default to commit hash and require User approval if using another convention.

P4 — Compose image patch must not hardcode s174

Rev1 uses:

sed -i 's|nuxt-ssr-local:s174|nuxt-ssr-local:<new_tag>|g'

Patch:

  • Capture current production image from Phase 0D.
  • Patch only the exact Nuxt service image line, not every occurrence in compose.
  • Verify exactly one line changed.
  • If multiple or zero matches, STOP COMPOSE_IMAGE_PATCH_AMBIGUOUS.

P5 — Build/deploy logs need the same temp-log + scan-before-print rule

Rev1 build redirects to temp log and scans, but it does not define safe-tail printing/cleanup consistently. Rev1 container restart uses:

docker compose up -d incomex-nuxt 2>&1 | tail -10

This can print unscanned log output.

Patch all deploy/build/container-log commands:

  • redirect output to temp log;
  • chmod 600;
  • boolean secret scan first;
  • only print safe redacted tail if scan PASS;
  • cleanup temp logs;
  • never print matching lines.

This applies to:

  • production image build;
  • compose up/recreate;
  • container logs;
  • any curl response body stored for relation endpoint.

P6 — Do not use Directus admin token for workflow sample unless necessary; avoid printing response body

Rev1 fetches sample workflow id using:

curl -s -H 'Authorization: Bearer $DIRECTUS_ADMIN_TOKEN' '${DIRECTUS_PUBLIC_URL}/items/workflows?limit=1&fields=id' | head -c 200

This risks printing response bodies and uses admin token for a smoke helper.

Patch options:

  • Prefer using an existing public/UI route sample known from table_registry or skip workflow tab smoke if sample id cannot be discovered safely.
  • If Directus API is used, store response to temp file, scan/redact, extract only id, and print only WORKFLOW_SAMPLE_ID_FOUND=true|false plus redacted id if non-sensitive.
  • Do not print Directus URL or response body.

If sample id cannot be found safely, report:

workflow_tab_smoke=SKIPPED_NO_SAMPLE_ID

P7 — Use production host/base URL discovery instead of assuming http://localhost

Rev1 uses http://localhost/... for smoke. This may be correct on VPS, but the prompt should require verification.

Patch Phase 0 to discover smoke base:

smoke_base_url=http://localhost|http://127.0.0.1|https://<public-host>|BLOCKED

Do not print sensitive URL if it contains credentials. Public host is acceptable if already public.

If localhost is not routed through nginx/Nuxt correctly, smoke may be false-negative.

P8 — Route count inconsistency: be explicit that event_outbox is excluded

Header says “Smoke 21 routes” and Phase 2 says “Total smoke 20 (13+3+4+1 - 1 deferred)” but arithmetic is confusing.

Patch:

planned_smoke_targets=21_without_event_outbox? or 20?

Use clear counts:

  • 13 registry routes excluding event_outbox;
  • 3 non-registry pages;
  • up to 4 special routes, with workflow tabs optional;
  • 1 API endpoint.

Total max = 21 if both workflow tab routes are smoked. event_outbox is not counted in this pack.

P9 — HTTP smoke should verify more than status for key routes, but not overdo it

For ordinary routes, HTTP 200/3xx may be enough. For critical endpoint /api/discovery/relations, verify body shape without printing body.

Patch:

  • For UI routes: status 200 is acceptable.
  • For /api/discovery/relations: status 200 + body contains expected key, e.g. system_issue, without printing body.
  • Store response temp file and cleanup.

P10 — Rollback policy must distinguish “recommend” vs “execute after explicit rollback approval”

Rev1 says no auto-rollback, but also includes rollback commands. Patch:

  • Deploy pack may recommend rollback.
  • Agent must not execute rollback unless a separate explicit rollback approval phrase is present.
  • Add rollback approval phrase, e.g.:
APPROVE D28 ROLLBACK: I authorize restoring <old_image_tag> and redeploying previous Nuxt image.

If not present, report rollback_recommended=true, rollback_executed=false.

P11 — Compose file mutation must be tracked and recoverable

Rev1 edits /opt/incomex/docker/docker-compose.yml. That is a real file mutation.

Patch:

  • backup compose before edit;
  • verify backup checksum;
  • after deploy, report compose diff;
  • if deploy succeeds, keep new image reference and report it;
  • if rollback is approved, restore previous image reference or backup.

Report fields:

compose_file_modified=true|false
compose_backup_path=/opt/incomex/docker/docker-compose.yml.pre-d28
compose_image_line_before=<redacted/plain image tag>
compose_image_line_after=<new tag>

P12 — This prompt should be split operationally into Stage 1 and Stage 2 dispatch instructions

Rev1 contains both stages in one prompt. That is acceptable, but dispatch instruction must be clear:

  • First dispatch should say RUN_STAGE=1_PREFLIGHT_ONLY.
  • Agent must stop after Stage 1 report.
  • Second dispatch should say RUN_STAGE=2_DEPLOY_AND_SMOKE and include exact approval phrase.

Add this to the top of the prompt.

P13 — Stage 1 should not require User approval to run, Stage 2 does

Rev1 says pack not dispatch if User has not explicit approve both phases. But Stage 1 is preflight/no-impact and should be allowed without deploy approval.

Patch:

Stage 1 preflight may run after GPT/User approves this prompt.
Stage 2 deploy/smoke requires additional explicit deploy approval after Stage 1 report.

P14 — Future Phase 1C naming

After Stage 2 PASS, next pack should be:

P3D4C2U_RESUME_NOTIFICATION_DISPLAY_PROMPT_REVIEW

or if keeping D28 prefix:

D28_PHASE_1C_PUBLISH_EVENT_OUTBOX_PROMPT_REVIEW

But because the next work returns to notification/P3D, GPT prefers:

P3D4C2U_RESUME_NOTIFICATION_DISPLAY_PROMPT_REVIEW

P15 — Add report fields for Stage 1 and Stage 2 hard attestations

Stage 1 report must attest:

stage=1_prefight_only
deploy_executed=false
smoke_executed=false
image_tag_created=false
compose_modified=false
container_restarted=false

Stage 2 report must attest:

approval_phrase_verified=true
image_tag_created=true|false
compose_modified=true|false
container_restarted=true|false
smoke_executed=true|false
no_directus_mutation=true
no_pg_mutation=true
no_publish_event_outbox=true

Directive to Opus

Patch prompt rev2 at:

knowledge/dev/laws/dieu28-trien-khai/prompts/d28-deploy-and-live-smoke-prompt-review.md

Keep two-stage design. Patch narrowly. Do not dispatch after patch; return for GPT/User review.

Summary

Rev1 is a strong draft but not safe enough for first production deploy. Rev2 must make Stage 1 purely no-impact, bind Stage 2 to exact image tag approval, harden log/URL/body handling, clarify route counts, and add explicit rollback approval mechanics.

Back to Knowledge Hub knowledge/dev/laws/dieu44-trien-khai/reviews/gpt-review-d28-deploy-live-smoke-prompt-rev1-2026-05-10.md