KB-2B49

GPT Review — D28 Deploy Live Smoke Prompt rev2

9 min read Revision 1
gpt-reviewdieu28deploylive-smokerev3-requiredproduction

GPT Review — D28 Deploy + Live Smoke Prompt rev2

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 rev2

Verdict

REV3 REQUIRED — do not dispatch rev2.

Rev2 fixes the largest issue from rev1: Stage 1 is now genuinely no-impact. It also adds exact-tag approval, dynamic image discovery, better rollback approval, and clearer route counts.

However, because Stage 2 will deploy production, several operational-safety issues still need patching before dispatch.

Accepted rev2 fixes

  • Stage 1 no longer creates backup image tag.
  • Stage 1 has clear RUN_STAGE=1_PREFLIGHT_ONLY behavior.
  • Stage 2 requires RUN_STAGE=2_DEPLOY_AND_SMOKE plus exact approval phrase.
  • Default image tag is traceable: nuxt-ssr-local:d2db418.
  • Compose image patch no longer hardcodes s174.
  • event_outbox smoke remains excluded.
  • Next pack after Stage 2 PASS returns to P3D resume.
  • Rollback has separate approval phrase.
  • Route count is clearer.

Required rev3 patches

P1 — Do not print safe-tail if secret scan fails before classification

Rev2 commands often do:

grep -qi ... $LOGFILE && echo SCAN=FAIL || echo SCAN=PASS
grep -v -i -E 'token|secret|bearer|password|authorization' $LOGFILE | tail -15

This prints a filtered tail even when scan failed. That is too loose for production deploy. If scan fails, Agent must classify without printing log content. Only after classification as FILENAME_FALSE_POSITIVE may it print safe redacted tail if still needed.

Patch all Stage 2 log handling:

IF SCAN=PASS → safe tail allowed.
IF SCAN=FAIL → do not print tail; inspect/classify privately; report only classification/counts.
IF classification=FILENAME_FALSE_POSITIVE → optional redacted safe tail may be printed, but not required.
IF classification=SECRET_LEAK_FAIL → STOP, no tail, no matching lines.

Apply to:

  • production image build log;
  • compose up log;
  • container logs;
  • workflow sample response;
  • relations endpoint response.

P2 — Backup image tag must not overwrite an existing rollback tag silently

Rev2 uses:

docker tag <current_production_image> nuxt-ssr-local:pre-d28-rollback

If pre-d28-rollback already exists from a prior run, this can overwrite or mask rollback state.

Patch Stage 1 preflight to inspect whether backup tag exists:

backup_tag_exists=true|false
backup_tag_points_to_current_image=true|false|UNKNOWN

Stage 2 policy:

  • If backup tag absent → create it.
  • If backup tag exists and points to current image → reuse or refresh with report.
  • If backup tag exists and differs from current image → STOP ROLLBACK_TAG_CONFLICT unless User explicitly approves overwrite.

Alternative: use unique backup tag:

nuxt-ssr-local:pre-d28-rollback-<timestamp>

GPT preference: use unique backup tag generated in Stage 1 report to avoid conflict.

P3 — Compose backup file must not overwrite previous backup silently

Rev2 uses fixed path:

/opt/incomex/docker/docker-compose.yml.pre-d28

Patch:

  • Stage 1 inspect if file exists.
  • Use unique backup path:
/opt/incomex/docker/docker-compose.yml.pre-d28-<timestamp>
  • Stage 2 approval phrase/report must include this exact backup path or Stage 2 must recompute using the same Stage 1 report values.
  • If using fixed path, STOP if existing file differs unless explicit overwrite approval. GPT preference: unique path.

P4 — Approval phrase should bind to Stage 1 report values, not hardcoded text only

Rev2 hardcodes approval phrase with nuxt-ssr-local:d2db418 and pre-d28-rollback. If Stage 1 proposes a unique backup tag/path, Stage 2 must verify against Stage 1 report.

Patch:

  • Stage 1 report outputs exact:
    • proposed_new_image_tag;
    • proposed_backup_image_tag;
    • compose_backup_path;
    • current_production_image.
  • Stage 2 reads Stage 1 report and verifies approval phrase matches these values.

P5 — Stage 1 workflow sample discovery should be optional and safer

Rev2 uses Directus admin token in Stage 1 to discover workflow sample id. This is read-only but not strictly necessary for deploy preflight.

Patch:

  • Make workflow sample discovery optional.
  • If Directus API call would require admin token or response body handling, Agent may skip and report:
workflow_sample_id=NONE
workflow_sample_discovery=SKIPPED_SAFETY
  • If performed, do not print ID unless ID is non-sensitive and only an opaque UUID/int; preferably report WORKFLOW_SAMPLE_ID_FOUND=true|false, not actual value.

P6 — Do not use head -50 web/Dockerfile if it could contain env values

Dockerfiles usually do not contain secrets, but to stay consistent, Stage 1 should avoid printing large file chunks. Patch:

  • Use grep for structural lines only:
grep -E '^(FROM|WORKDIR|COPY|RUN|CMD|ENTRYPOINT)' web/Dockerfile | head -30
  • Do not print ARG/ENV lines unless values are redacted.

P7 — docker logs should not be listed as read-only allowed without log-safety caveat

Stage 1 allowed read-only includes docker logs, but printing logs can leak secrets. Patch:

  • Either remove docker logs from Stage 1 allowed ops; or
  • state explicitly: docker logs may only be captured to temp file and secret-scanned before any output.

GPT recommends removing docker logs from Stage 1 unless needed.

P8 — Smoke base URL must not print public URL if not needed

Rev2 says smoke base can be https://public-host. Public host is generally okay, but to align with NO_PRINT_ENV_TOKEN_URL, report only chosen mode and redacted host if sourced from env:

smoke_base_url_mode=LOCALHOST|PORT_MAPPING|PUBLIC_HOST
smoke_base_url_redacted=<scheme>://<host-redacted>

Agent can use actual URL internally for curl but should avoid printing env-derived URL.

P9 — Curl command in relations smoke writes body but does not separate status correctly

Rev2 command:

curl -s -o $RESPFILE -w '%{http_code}' '<smoke_base_url>/api/discovery/relations'

This prints status to stdout, okay, but then it calls curl again for status. Patch to one call if possible:

STATUS=$(curl -s -o "$RESPFILE" -w '%{http_code}' ...)

Report status only, no body. Cleanup response temp file.

P10 — Compose patch should verify only one line changed via diff

Rev2 says verify grep line, but prompt should require:

diff -u docker-compose.yml.<backup> docker-compose.yml

Do not print full diff if it might contain secrets. For compose image line, print only redacted/filtered diff lines containing nuxt-ssr-local if safe.

Report:

compose_diff_only_nuxt_image_line=true|false
compose_patch_line_count=1

If not exactly one image line changed, restore backup and STOP.

P11 — Stage 2 should snapshot source/infra state before mutation

Before Stage 2 mutation, re-run critical preflight:

  • git status clean;
  • HEAD still includes commits;
  • current image still equals Stage 1 current image or user-approved current image;
  • compose line still matches Stage 1 report;
  • build verify PASS report still exists.

If drift occurred between Stage 1 and Stage 2, STOP PREFLIGHT_DRIFT_AFTER_STAGE1.

P12 — Build image tag cleanup policy

If build succeeds and deploy succeeds, keep new image. If build succeeds but deploy fails before restart, decide whether to remove new image. Patch report fields:

new_image_created=true|false
new_image_removed_on_abort=true|false|N/A
old_image_preserved=true
backup_image_created=true|false

P13 — Rollback wording: backup image tag vs compose restore

Rev2 rollback has both copy backup compose and sed to backup image; copying old compose may restore old image tag, not necessarily backup tag. Clarify two rollback methods:

  • Method A: restore compose backup to original tag, then compose up -d.
  • Method B: patch compose to backup image tag, then compose up -d.

Do not mix them in one command. GPT preference: restore compose backup to original tag, because it returns infra to exact pre-deploy compose state.

P14 — Stage 1 report path and Stage 2 report path are good; require Stage 2 to read Stage 1 report

Patch Stage 2 preflight to read:

knowledge/dev/laws/dieu28-trien-khai/reports/d28-deploy-and-live-smoke-stage1-preflight-report.md

and verify preflight_status=PASS, status=AWAITING_DEPLOY_APPROVAL.

Directive to Opus

Patch prompt rev3 at:

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

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

Summary

Rev2 is close, but rev3 must strengthen production-safety around backup-tag conflicts, compose backup uniqueness, Stage 2 drift checks, and no log output after secret-scan failure. After rev3 it may be close to Stage 1 dispatch approval.

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