D28 — Stage 2 Deploy + Live Smoke — Dispatch Package (DRAFT)
D28 — Stage 2 Deploy + Live Smoke — Dispatch Package (DRAFT)
Date: 2026-05-10 Status: DRAFT — chờ User ký approval phrase + GPT review wording Audience: Agent claude-go (sau khi User issue approval phrase verbatim) Predecessor: Stage 1 PREFLIGHT rev3 PASS clean (TS=1778397192) Critical: Pack này LẦN ĐẦU thực sự deploy production
⚠️ Cảnh báo cho User trước khi ký
Issue 2 dòng dispatch dưới đây sẽ kích hoạt:
- Build production image mới (
nuxt-ssr-local:d2db418). - Tag backup image cũ (
nuxt-ssr-local:pre-d28-rollback-1778397192). - Modify
/opt/incomex/docker/docker-compose.yml(đổi 1 lineimage:). - Restart
incomex-nuxtcontainer — ~30s downtime. - Brief 502 errors trong window restart.
- Nginx có thể serve stale cache vài phút sau restart.
- Live smoke 19-21 routes qua nginx public host.
KHÔNG kích hoạt:
- Directus / PostgreSQL service.
tbl_event_outboxpublication (vẫndraft).- P3D notification display (vẫn
paused). - Auto rollback (rollback chỉ chạy nếu User issue rollback phrase RIÊNG sau khi Stage 2 fail).
Cách User dispatch
User phải copy-paste VERBATIM cả 2 dòng dưới:
RUN_STAGE=2_DEPLOY_AND_SMOKE
APPROVE D28 DEPLOY: I authorize deploying commits d2db418 + 0947613 as image nuxt-ssr-local:d2db418 to production with brief service interruption, using rollback image nuxt-ssr-local:pre-d28-rollback-1778397192 and compose backup /opt/incomex/docker/docker-compose.yml.pre-d28-1778397192.
User KHÔNG được:
- Paraphrase (e.g., gõ "I approve" hoặc "yes" thay vì full phrase).
- Edit values (TS phải exact
1778397192; image tag phải exactnuxt-ssr-local:d2db418). - Skip
RUN_STAGEflag. - Issue partial phrase (thiếu commits, thiếu rollback image, thiếu compose backup path).
- Reformat (e.g., wrap, line break giữa phrase, viết hoa khác).
Nếu approval phrase không exact → Agent SẼ STOP với APPROVAL_PHRASE_OR_BINDING_MISMATCH, không deploy.
Tham chiếu KB
Prompt rev5 (GPT-approved):
knowledge/dev/laws/dieu28-trien-khai/prompts/d28-deploy-and-live-smoke-prompt-review.md
Stage 1 baseline (rev3, PASS clean):
knowledge/dev/laws/dieu28-trien-khai/reports/d28-deploy-and-live-smoke-stage1-preflight-report.md
Stage 2 report sẽ tạo:
knowledge/dev/laws/dieu28-trien-khai/reports/d28-deploy-and-live-smoke-stage2-execution-report.md
CHECKPOINT đầu prompt cho Agent
Trước khi mutation đầu tiên, Agent PHẢI:
- Đọc Stage 1 report rev3 từ KB (path trên).
- Verify Stage 1 rev5-clean (Phase 1A step 4 mới rev5):
Mismatch any → STOPservice_name_rule_applied=trueundeclared_substitution_used=falsedrift_detected=falseSTAGE1_NOT_REV5_CLEAN. - Verify approval phrase 3 fields exact match với Stage 1 report:
Mismatch any → STOPNEW_TAG = nuxt-ssr-local:d2db418BACKUP_TAG = nuxt-ssr-local:pre-d28-rollback-1778397192COMPOSE_BACKUP_PATH = /opt/incomex/docker/docker-compose.yml.pre-d28-1778397192APPROVAL_PHRASE_OR_BINDING_MISMATCH. - Load STAGE1_ variables* từ report (4 biến — không recompute):
STAGE1_NEW_IMAGE_TAG=nuxt-ssr-local:d2db418STAGE1_BACKUP_IMAGE_TAG=nuxt-ssr-local:pre-d28-rollback-1778397192STAGE1_COMPOSE_BACKUP_PATH=/opt/incomex/docker/docker-compose.yml.pre-d28-1778397192STAGE1_CURRENT_PRODUCTION_IMAGE=nuxt-ssr-local:s174 - Drift re-check (Phase 1B): git status clean, HEAD commits, current image, compose line, build verify report.
Drift → STOP
PREFLIGHT_DRIFT_AFTER_STAGE1, no mutation.
Chỉ sau khi 5 bước trên PASS, Agent mới được phép mutation đầu tiên ở Phase 1C.
Mục tiêu (theo prompt rev5)
Thực hiện đúng và đủ:
- Phase 1A → 1H (deploy execution)
- Phase 2A → 2F (live smoke, EXCLUDE event_outbox)
- Phase 3A → 3C (decision + Stage 2 report)
Tổng routes smoke: max 21, min 19 (workflow tab smoke SKIPPED do workflow_sample_status=NONE trong Stage 1).
Hard boundaries Stage 2 — phải attest TRUE trong Stage 2 report
Cấm tuyệt đối (12 mục tóm tắt + reference toàn bộ 26 NO_* trong rev5):
NO_DIRECTUS_MUTATION=true
NO_PG_MUTATION=true
NO_TABLE_REGISTRY_MUTATION=true
NO_PUBLISH_EVENT_OUTBOX=true
NO_SMOKE_EVENT_OUTBOX_ROUTE=true
NO_AUTO_ROLLBACK=true
NO_TOUCH_DIRECTUS_SERVICE=true
NO_TOUCH_POSTGRES_SERVICE=true
NO_FIX_TBL_MODULES_LIST=true
NO_ADD_ENTITY_TYPE_COLUMN=true
NO_UNDECLARED_SUBSTITUTION=true (rev5)
NO_STAGE2_RECOMPUTE_BACKUP_TIMESTAMP=true (rev4)
# Plus full rev3/rev4/rev5 boundary set (xem rev5 prompt section "Hard boundaries").
Naming reminder (rev4 + rev5)
TS = 1778397192 (captured Stage 1, FIXED — Stage 2 NEVER recompute)
TS_LOG = sinh mới mỗi log file Stage 2 (1D, 1E diff, 1F, 1H, 2E)
— independent từ TS, KHÔNG dùng cho image tag/path
nuxt = Compose service name (dùng cho mọi `docker compose <verb>`)
incomex-nuxt = Docker container_name (chỉ ở reference text, KHÔNG dùng trong `docker compose <verb>`)
Image lifecycle:
STAGE1_CURRENT_PRODUCTION_IMAGE = nuxt-ssr-local:s174 (cũ, sẽ giữ làm fallback)
STAGE1_BACKUP_IMAGE_TAG = nuxt-ssr-local:pre-d28-rollback-1778397192 (sẽ tạo Phase 1C)
STAGE1_NEW_IMAGE_TAG = nuxt-ssr-local:d2db418 (sẽ build Phase 1D, deploy Phase 1E-1F)
Log safety branching reminder (rev3 + rev4)
6 nguồn cần scan TRƯỚC inspection:
1. Build log (1D) → /tmp/d28-deploy-build-$TS_LOG.log
2. Compose up log (1F) → /tmp/d28-deploy-up-$TS_LOG.log
3. Container log (1H) → /tmp/d28-container-logs-$TS_LOG.log
4. Compose diff (1E, rev4) → /tmp/d28-compose-diff-$TS_LOG.txt
5. Relations response (2E) → /tmp/d28-relations-$TS_LOG.txt
6. Workflow sample (0K) → SKIPPED (default flag false)
3 nhánh sau secret-scan:
SCAN=PASS→ tail/summary printable.SCAN=FAIL_FILENAME_FALSE_POSITIVE(e.g. forgot-password.*.mjs) → counts/classification only, NO content.SCAN=FAIL_SECRET_LEAK_SUSPECTED→ STOP, NO content, alert User.
CẤM print tail khi SCAN=FAIL bất kể classification.
Failure handling tóm lược (chi tiết trong rev5 prompt)
| Phase | Symptom | Action |
|---|---|---|
| 1A | approval phrase mismatch | STOP APPROVAL_PHRASE_OR_BINDING_MISMATCH, no mutation |
| 1A | Stage 1 not rev5-clean | STOP STAGE1_NOT_REV5_CLEAN, no mutation |
| 1B | drift detected | STOP PREFLIGHT_DRIFT_AFTER_STAGE1, no mutation |
| 1C | backup tag fail | STOP, no mutation |
| 1D | build fail BEFORE restart | STOP, cleanup new image (docker image rm $STAGE1_NEW_IMAGE_TAG), no further |
| 1D | build log SCAN=FAIL_LEAK | STOP, cleanup new image, NO log content print |
| 1E | compose patch ambiguous (diff line ≠ 2) | restore backup, STOP |
| 1E | compose diff SCAN=FAIL_LEAK | restore backup, STOP, NO diff print |
| 1F | restart fail | STOP, recommend rollback (User decides) |
| 1F | up log SCAN=FAIL_LEAK | STOP, recommend rollback, NO log print |
| 1G | not ready 60s | STOP, recommend rollback |
| 1H | container log SCAN=FAIL_LEAK | Alert User as CRITICAL, NO log print |
| 2 | smoke 1-2 FAIL | Document, ask User, no auto rollback |
| 2 | smoke 3+ FAIL | Strong rollback recommend |
| 2E | relations HTTP FAIL | CRITICAL rollback recommend |
| 2E | relations SCAN=FAIL_LEAK | CRITICAL alert, NO body grep, possible API data leak |
CẤM auto-rollback. CẤM silent retry. CẤM workaround.
Rollback (Emergency only — KHÔNG kèm dispatch ban đầu)
Nếu Stage 2 fail và User decide rollback, User issue phrase RIÊNG (sau Stage 2 báo fail):
APPROVE D28 ROLLBACK: I authorize restoring compose backup /opt/incomex/docker/docker-compose.yml.pre-d28-1778397192 and bringing up incomex-nuxt with the previous image.
Khi nhận phrase này, Agent sẽ:
# 1. Restore compose backup
ssh contabo "cp /opt/incomex/docker/docker-compose.yml.pre-d28-1778397192 /opt/incomex/docker/docker-compose.yml"
# 2. Restart with previous image (rev5 — service name "nuxt")
ssh contabo "cd /opt/incomex/docker && docker compose up -d nuxt"
# 3. Wait + smoke 1-2 routes verify rollback (with same log safety pattern)
Method = restore compose backup file (KHÔNG dùng sed reverse — restore file là cleaner full state).
Tự kiểm tra Agent trước khi nộp Stage 2 report
| # | Câu hỏi | Phải đạt |
|---|---|---|
| 1 | Approval phrase 3 fields exact match Stage 1 report? | yes |
| 2 | Stage 1 rev5-clean verified (service_name_rule_applied, undeclared_substitution_used=false, drift_detected=false)? |
yes |
| 3 | STAGE1_* variables loaded từ report, KHÔNG recompute TS? | yes |
| 4 | Service name = nuxt ở MỌI docker compose <verb>? |
yes |
| 5 | Container name incomex-nuxt chỉ ở reference, KHÔNG trong docker compose <verb>? |
yes |
| 6 | Log safety branching áp dụng đủ 5 nguồn Stage 2 (build/up/container/diff/relations)? | yes |
| 7 | Compose diff scan TRƯỚC inspection (rev4)? | yes |
| 8 | Compose diff line count = 2 (1 line < + 1 line >, đều nuxt-ssr-local)? |
yes |
| 9 | Relations body scan TRƯỚC body grep (rev4)? | yes |
| 10 | Image lifecycle (old/backup/new + cleanup-on-abort) đầy đủ trong report? | yes |
| 11 | Compose lifecycle (modified/backup_path/diff_*) đầy đủ? | yes |
| 12 | Smoke results (registry 13 + non-reg 3 + special 2-4 + api + relations) đầy đủ? | yes |
| 13 | Hard boundary attestation TRUE cho 26+ NO_* flags? | yes |
| 14 | phase_status quyết định đúng theo decision matrix? |
yes |
| 15 | next_required_pack đúng? |
yes |
| 16 | Report uploaded KB đúng path? | yes |
Decision matrix sau Stage 2
| phase_status | next_required_pack |
|---|---|
| PASS | P3D4C2U_RESUME_NOTIFICATION_DISPLAY_PROMPT_REVIEW (P3D notification resume) |
| PARTIAL | D28_DEPLOY_PARTIAL_FIX_PACK |
| FAIL with rollback approved | D28_GENERATED_MAP_FIX |
| FAIL without rollback | D28_PROD_HOTFIX (emergency) |
| FAIL_LEAK (compose diff hoặc relations) | D28_LEAK_INVESTIGATION_PACK (offline review, no further deploy) |
Trạng thái khi soạn dispatch package này
stage1_rev3_outcome=PASS_CLEAN_OUTCOME_A
stage1_baseline_for_stage2=eligible (GPT-confirmed 2026-05-10)
approval_phrase_constructed=true
approval_phrase_signed_by_user=false
agent_dispatch_allowed=false_until_user_signs_approval_phrase
dispatch_package_status=DRAFT_AWAITING_USER_APPROVAL_AND_GPT_REVIEW
prompt_current_rev=5
build_verify_status=PASS
generated_map_commits=0947613,d2db418
tbl_event_outbox.status=draft
notification_display=paused
p3d_resume_allowed=false
Hard boundaries phiên soạn dispatch này (chưa dispatch)
Không dispatch Agent.
Không deploy.
Không restart containers.
Không smoke routes.
Không build production image.
Không create backup image tag.
Không modify docker-compose.yml.
Không publish tbl_event_outbox.
Không mutate Directus / PG / table_registry.
Không resume P3D.
D28 Stage 2 Deploy + Live Smoke Dispatch Package | Draft awaiting User approval + GPT review | rev5 prompt + Stage 1 rev3 baseline (TS=1778397192) | 2026-05-10