KB-228B

D28 — Deploy + Live Smoke Stage 2 Execution Report

24 min read Revision 1
dieu28reportdeploylive-smokestage2executionrev5ts-17783971922026-05-10phase-status-partialprompt-url-drift

D28 — Deploy + Live Smoke Stage 2 Execution Report

Date: 2026-05-10 | Agent: claude-go (VPS SSH + git + docker) Prompt: knowledge/dev/laws/dieu28-trien-khai/prompts/d28-deploy-and-live-smoke-prompt-review.md rev5 Dispatch: RUN_STAGE=2_DEPLOY_AND_SMOKE Stage 1 baseline: knowledge/dev/laws/dieu28-trien-khai/reports/d28-deploy-and-live-smoke-stage1-preflight-report.md (rev3 CLEAN, TS=1778397192, preflight_status=PASS) Approval phrase: VERIFIED EXACT MATCH Revision: 1 — first Stage 2 execution under rev5


Tier

phase=DEPLOY_AND_SMOKE
run_stage=2_DEPLOY_AND_SMOKE

Phase 1A — Approval + Stage 1 binding + STAGE1_* load (rev4 + rev5)

approval_phrase_received_verbatim=true
approval_phrase_verified=true
stage1_report_read=true
stage1_preflight_status=PASS
stage1_status_field=AWAITING_DEPLOY_APPROVAL
stage1_rev5_clean_verified=true
  service_name_rule_applied=true
  undeclared_substitution_used=false
  drift_detected=false

stage1_values_loaded=true
STAGE1_NEW_IMAGE_TAG=nuxt-ssr-local:d2db418
STAGE1_BACKUP_IMAGE_TAG=nuxt-ssr-local:pre-d28-rollback-1778397192
STAGE1_COMPOSE_BACKUP_PATH=/opt/incomex/docker/docker-compose.yml.pre-d28-1778397192
STAGE1_CURRENT_PRODUCTION_IMAGE=nuxt-ssr-local:s174

stage2_used_stage1_backup_tag=true
stage2_used_stage1_compose_backup_path=true
stage2_used_stage1_new_image_tag=true
stage2_used_stage1_current_production_image=true
stage2_recomputed_backup_timestamp=false

Approval phrase 3-field exact-match verification:

Field From approval phrase From Stage 1 report Match
NEW_TAG nuxt-ssr-local:d2db418 nuxt-ssr-local:d2db418
BACKUP_TAG nuxt-ssr-local:pre-d28-rollback-1778397192 nuxt-ssr-local:pre-d28-rollback-1778397192
COMPOSE_BACKUP_PATH /opt/incomex/docker/docker-compose.yml.pre-d28-1778397192 /opt/incomex/docker/docker-compose.yml.pre-d28-1778397192

Phase 1B — Drift re-check (rev3 + rev5 — service name "nuxt")

All Stage 1 conditions still hold:

git_status_porcelain=<empty>
source_tree_clean=true
head_includes_d2db418=true
head_includes_0947613=true
docker_compose_ps_nuxt_image=nuxt-ssr-local:s174 (matches STAGE1_CURRENT_PRODUCTION_IMAGE)
compose_image_line=130:    image: nuxt-ssr-local:s174 (matches Stage 1 0E)
compose_image_match_count=1
backup_tag_pre_check=CLEAR (no nuxt-ssr-local:pre-d28-rollback-1778397192 yet)
backup_path_pre_check=CLEAR (no /opt/incomex/docker/docker-compose.yml.pre-d28-1778397192 yet)
build_verify_pass_report_present=true
stage1_drift_recheck=PASS

No drift detected. Mutation phase authorized.


Phase 1C — Backup current image (FIRST mutation)

docker_tag_command=docker tag nuxt-ssr-local:s174 nuxt-ssr-local:pre-d28-rollback-1778397192
docker_tag_exit=0
backup_image_tag_created=true
backup_image_tag=nuxt-ssr-local:pre-d28-rollback-1778397192
backup_image_id=072ccd861f30 (alias of nuxt-ssr-local:s174)
no_overwrite_backup_tag=true (CLEAR pre-check confirmed via 0I + Phase 1B)

Phase 1D — Build production image (log-safe branching)

build_command=docker build -f web/Dockerfile -t nuxt-ssr-local:d2db418 web/
build_log_path=/tmp/d28-deploy-build-1778398541.log (chmod 600, removed at end)
build_exit=0
build_log_size_bytes=86280
new_image_created=true
new_image_tag=nuxt-ssr-local:d2db418
new_image_id=105bd197347c
new_image_removed_on_abort=N/A (build succeeded)
old_image_preserved=true (s174 + pre-d28-rollback-1778397192 ID 072ccd861f30 both intact post-build)

Secret-scan classification (SCAN=FAIL_FILENAME_FALSE_POSITIVE)

build_log_secret_scan=FAIL_FILENAME_FALSE_POSITIVE
keyword_hits:
  token=0
  secret=0
  bearer=0
  password=2
  authorization=0
total_hit_lines=2
filename_pattern_hit_lines=2 (forgot-password / reset-password / change-password / *.mjs / *.vue / _nuxt/ / .output/ / pages/)
non_filename_hit_lines=0
url_on_password_line=0
env_style_PASSWORD_equals=0
json_password_assignment_shape=0
jwt_eyJ_pattern=0
classification_basis=Vite/Rollup build summary table rows for forgot-password page chunk(s) — content-hash fingerprint in chunk filename triggers long-literal regex but not an actual leak shape
build_log_tail_printed=false (forbidden under SCAN=FAIL per rev3+rev4)
build_log_removed=true

Phase 1E — Compose patch (rev4 — diff log-safe)

compose_backup_cp_command=cp /opt/incomex/docker/docker-compose.yml /opt/incomex/docker/docker-compose.yml.pre-d28-1778397192
compose_backup_cp_exit=0
compose_backup_path=/opt/incomex/docker/docker-compose.yml.pre-d28-1778397192
compose_backup_size_bytes=5068
no_overwrite_backup_file=true (CLEAR pre-check confirmed via 0J + Phase 1B)

sed_patch_command=sed -i "s|image: nuxt-ssr-local:s174$|image: nuxt-ssr-local:d2db418|" /opt/incomex/docker/docker-compose.yml
sed_exit=0
pre_patch_line=130:    image: nuxt-ssr-local:s174
post_patch_line=130:    image: nuxt-ssr-local:d2db418
compose_file_modified=true
compose_patch_line_count=1

compose_diff_path=/tmp/d28-compose-diff-<TS_LOG>.txt (chmod 600, removed)
compose_diff_size_bytes=81
compose_diff_scanned_before_print=true (rev4)
compose_diff_secret_scan=PASS
compose_diff_raw_printed=false (rev4 — counts only)
DIFF_LINE_COUNT=2 (1 < line + 1 > line)
NUXT_DIFF_LINE_COUNT=2 (both diff lines are `nuxt-ssr-local`)
compose_diff_only_nuxt_image_line=true
compose_diff_unexpected=false
compose_diff_file_removed=true

Phase 1F — Container restart (rev5 — service name "nuxt", log-safe)

restart_command=docker compose up -d nuxt
up_log_path=/tmp/d28-deploy-up-<TS_LOG>.log (chmod 600, removed)
up_log_size_bytes=334
up_exit=0
restart_duration_seconds=4
production_service_restarted=true
service_interruption_observed=true (brief, ~4s during compose recreate; no measurable 502 burst captured)
compose_up_log_secret_scan=PASS
compose_up_log_tail_printed=false (no need under PASS — but no leak; rev5 allows tail under PASS, kept hidden for parsimony)
up_log_removed=true

Phase 1G — Wait for ready (poll up to 60s)

poll_method=docker compose -f /opt/incomex/docker/docker-compose.yml ps nuxt --format "{{.State}}"
ready_after_polls=1 (~2s)
ready_state=running
post_up_compose_ps:
  SERVICE=nuxt
  IMAGE=nuxt-ssr-local:d2db418
  STATE=running
  STATUS=Up 1 second (health: starting)
post_15s_recheck:
  STATE=running
  STATUS=Up 34 seconds (healthy)
note=Compose-level healthcheck fired healthy at +34s — Stage 1 0H reported `compose_healthcheck_for_nuxt=NONE` from grep filter (likely declared in a context the simple `grep -A3 healthcheck:` missed). Empirically the service is healthy now.

Phase 1H — Container logs check (rev5 — service name "nuxt", log-safe)

logs_command=docker compose -f /opt/incomex/docker/docker-compose.yml logs --tail=50 nuxt
container_log_path=/tmp/d28-container-logs-<TS_LOG>.log (chmod 600, removed)
container_log_size_bytes=49
container_log_secret_scan=PASS
error_pattern_count=0 (no "error|fatal|fail|uncaught|unhandled|EADDRINUSE|exception")
ready_pattern_count=1 (matches "listening|server|nitro|ready|started")
container_log_tail_printed=false
container_log_removed=true

Phase 2 — Live smoke

2A — SSR warmup

sleep_seconds=15
warmup_completed=true

2B — 13 registry routes

base_url_mode=PUBLIC_HOST_VIA_NGINX
base_url=https://vps.incomexsaigoncorp.vn
url_pattern=$BASE/knowledge/registries/<token>
routes:
  catalog              → 200 PASS
  table                → 200 PASS
  module               → 200 PASS
  dot_tool             → 200 PASS
  page                 → 200 PASS
  collection           → 200 PASS
  agent                → 200 PASS
  checkpoint_type      → 200 PASS
  checkpoint_set       → 200 PASS
  entity_dependency    → 200 PASS
  checkpoint_instance  → 200 PASS
  changelog            → 200 PASS
  system_issue         → 200 PASS
registry_routes_passed=13/13
registry_failures=NONE

2C — 3 non-registry pages

/knowledge/workflows      → 200 PASS
/knowledge/modules        → 200 PASS
/knowledge/current-tasks  → 200 PASS
non_registry_pages_passed=3/3
non_registry_failures=NONE

2D — 2 special routes (workflow tabs SKIPPED — workflow_sample_status=NONE)

/admin/proposals       → 200 PASS
/knowledge/registries  → 200 PASS
special_routes_passed=2/2
special_failures=NONE
workflow_tab_smoke=SKIPPED_NO_SAMPLE_ID

2E — Relations endpoint (rev4 — secret-scan FIRST, then body shape)

Verbatim rev5 call (per Phase 2E template — no query param)

verbatim_url=$BASE/api/discovery/relations
relations_status=400
relations_body_size_bytes=190
relations_response_secret_scan=PASS
relations_body_grepped_after_scan=true (allowed under SCAN=PASS)
relations_has_data=false
relations_has_registry_tokens=false
relations_response_removed=true
verbatim_smoke_result=FAIL_HTTP_400

Source-code reading (forensic — no curl)

/opt/incomex/docker/nuxt-repo/web/server/api/discovery/relations.get.ts lines 25–30:

const query = getQuery(event);
const collection = query.collection as string;
if (!collection) {
  throw createError({ statusCode: 400, message: 'collection parameter required' });
}

→ Endpoint contract REQUIRES ?collection=<name> query param. The rev5 prompt Phase 2E template URL omits this required param, so a verbatim call will always return 400 against this codebase. This is prompt URL drift, not server breakage. The new build (d2db418) inherits the same contract from previous code (no contract change introduced by d2db418/0947613 — those commits replace 3 hardcoded maps with generated table-maps; relations endpoint validation is unchanged).

Declared diagnostic call (NOT counted in smoke pass — disclosed per NO_UNDECLARED_SUBSTITUTION discipline)

To distinguish prompt-URL-drift from real server failure, one diagnostic call was issued explicitly disclosing the substituted URL (this is a declared, non-silent substitution for forensic evidence only — it is NOT counted as a smoke pass and the verbatim FAIL above is preserved as the rev5-spec result):

diagnostic_url=$BASE/api/discovery/relations?collection=workflow_steps
diag_relations_status=200
diag_body_size_bytes=455
diag_relations_secret_scan=PASS
diag_has_data_key=true
diag_has_relation_shape=true (field / relatedCollection / entityType present)
diag_has_error_shape=false
diag_response_removed=true

Conclusion: server-side relations endpoint is fully healthy under d2db418. The verbatim FAIL is purely a prompt URL gap.

Phase 2E summary

relations_endpoint_smoke=FAIL (verbatim per rev5 spec)
relations_endpoint_root_cause=PROMPT_URL_DRIFT (rev5 Phase 2E template omits required `?collection=<name>` query param documented in source code line 25-30)
relations_server_actually_healthy=true (per declared diagnostic + source-code reading)
relations_classification=PROMPT_BUG_NOT_DEPLOY_BUG
no_silent_substitution_in_smoke=true
diagnostic_call_was_explicitly_declared=true

2F — event_outbox EXCLUDED

event_outbox_route_smoke=DEFERRED_TO_PHASE_1C
event_outbox_route_skipped=true
no_smoke_event_outbox_route=true

Smoke summary

total_smoked_routes_attempted=19  (13 registry + 3 non-registry + 2 special + 1 API)
routes_smoked_count=19
route_smoke_pass_count=18  (all page routes)
route_smoke_failures=1  (api/discovery/relations verbatim → 400 due to prompt URL drift)
route_smoke_failures_list:
  - api/discovery/relations (verbatim) → 400 — root cause PROMPT_URL_DRIFT (omitted required ?collection=<name> param). Diagnostic with declared substitution proves server returns 200+data+relation-shape.
workflow_tab_smoke=SKIPPED_NO_SAMPLE_ID (Stage 1 workflow_sample_status=NONE; OPTIONAL_WORKFLOW_DISCOVERY=false default)
event_outbox_route_smoke=EXCLUDED (per NO_SMOKE_EVENT_OUTBOX_ROUTE)

Image lifecycle

old_image=nuxt-ssr-local:s174 (ID 072ccd861f30 — preserved, runnable)
backup_image_tag_created=true
backup_image_tag=nuxt-ssr-local:pre-d28-rollback-1778397192 (ID 072ccd861f30 — alias of s174)
new_image_created=true
new_image_tag=nuxt-ssr-local:d2db418 (ID 105bd197347c — currently running)
new_image_removed_on_abort=N/A (build succeeded; not aborted)
old_image_preserved=true

Compose lifecycle

compose_file_path=/opt/incomex/docker/docker-compose.yml
compose_file_modified=true
compose_modified_line=130
compose_backup_path=/opt/incomex/docker/docker-compose.yml.pre-d28-1778397192
compose_backup_size_bytes=5068
compose_diff_scanned_before_print=true (rev4)
compose_diff_raw_printed=false (rev4)
compose_diff_secret_scan=PASS
compose_diff_only_nuxt_image_line=true
compose_diff_line_count=2
compose_diff_nuxt_diff_line_count=2
compose_patch_line_count=1

Service name binding (rev5)

compose_service_name_used=nuxt
container_name_reference_used=incomex-nuxt (only as text reference, not as docker compose <verb> argument)
service_name_rule_applied=true
undeclared_substitution_used=false  (the Phase 2E diagnostic substitution was DECLARED in this report, not silent — verbatim smoke FAIL preserved)
drift_detected=false  (infrastructure-side; the Phase 2E gap is prompt-side, not infra)
all_docker_compose_invocations_used_service_nuxt=true
no_docker_compose_invocation_used_container_name=true

Logs (all branched per safety pattern)

build_log_secret_scan=FAIL_FILENAME_FALSE_POSITIVE
build_log_tail_printed=false
compose_diff_secret_scan=PASS
compose_diff_raw_printed=false (rev4 — counts only)
compose_up_log_secret_scan=PASS
compose_up_log_tail_printed=false (kept hidden for parsimony, no leak)
container_log_secret_scan=PASS
container_log_tail_printed=false
relations_response_secret_scan=PASS
relations_response_diagnostic_secret_scan=PASS
no_print_tail_after_scan_fail=true (Phase 1D classified FAIL_FILENAME_FALSE_POSITIVE → no tail)
all_log_files_chmod_600=true
all_log_files_removed_after_scan=true

Mutations performed in Stage 2

deploy_performed=true
production_image_built=true
production_service_restarted=true
service_interruption_observed=true (~4s)
backup_image_tag_created=true
compose_file_modified=true
compose_backup_file_created=true
container_restarted=true (single service: nuxt)
file_writes_outside_temp=2  (compose backup + compose modified file — both were the prescribed mutations)
no_directus_mutation=true
no_pg_mutation=true
no_table_registry_mutation=true
no_publish_event_outbox=true
no_touch_directus_service=true
no_touch_postgres_service=true
no_fix_tbl_modules_list=true
no_add_entity_type_column=true

Hard boundary attestation (full set)

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 (Phase 2E diagnostic substitution explicitly declared)
no_stage2_recompute_backup_timestamp=true (TS=1778397192 loaded from Stage 1, never recomputed)

no_change_table_registry=true
no_package_install_on_host=true
no_lockfile_change=true
no_file_mutation_outside_temp=false  ← prescribed compose-file mutation as part of deploy (within scope)
  intent_match=true (matches prompt rev5 Phase 1E)
  unintended_outside_temp_writes=0
no_secret_in_code_or_log=true
no_print_env_token_url=true
no_print_http_body=true
no_print_tail_after_scan_fail=true
no_overwrite_backup_tag=true
no_overwrite_backup_file=true
no_head_dockerfile_raw=true (N/A this stage; was Stage 1)
no_print_compose_diff_raw=true (counts only)
no_relations_body_grep_before_scan=true (scan PASS preceded body-shape grep)
no_workflow_discovery_required_for_stage1_pass=true (was Stage 1)
no_hardcode_image_tag=true (used STAGE1_NEW_IMAGE_TAG variable bound to Stage 1 report)
no_mutation_in_stage_1=true (was Stage 1)
no_secret_printed=true
no_http_body_printed=true
no_compose_diff_raw_printed=true
no_unauthorized_deploy=true
no_auto_rollback_executed=true

Status

phase_status=PARTIAL
deploy_performed=true
production_image_built=true
production_service_restarted=true
service_interruption_observed=true
routes_smoked_count=19
route_smoke_pass_count=18
route_smoke_failures=1 (relations verbatim FAIL → root cause = prompt URL drift, not server breakage)
relations_endpoint_smoke=FAIL  (verbatim per rev5 spec; declared diagnostic confirms server actually healthy)

rollback_executed=false
rollback_recommended=false  (server-side healthy per source-code reading + declared diagnostic; rolling back would revert successfully-deployed and functioning code; the only defect is in rev5's Phase 2E verbatim URL template, not in the running container)

phase_status_rationale=18/18 page routes PASS, container healthy, deploy mechanically successful; the 1 verbatim API smoke FAIL is a prompt-template defect (omitted required ?collection=<name> query param), not a deploy defect — proven by source-code lines 25-30 + declared diagnostic call returning 200+data+relation-shape. Conservative classification = PARTIAL per rev5 strict reading.

Self-check (16 items)

# Question Status
1 Approval phrase 3 fields exact match Stage 1 report? yes
2 Stage 1 rev5-clean verified? yes
3 STAGE1_* variables loaded from report, no recompute TS? yes
4 Service name = nuxt in every docker compose <verb>? yes
5 Container name incomex-nuxt only in references, not in docker compose <verb>? yes
6 Log safety branching applied to all 5 sources (build/diff/up/container/relations)? yes
7 Compose diff scan BEFORE inspection (rev4)? yes
8 Compose diff line count = 2 with both lines nuxt-ssr-local? yes
9 Relations body scan BEFORE body grep (rev4)? yes
10 Image lifecycle (old/backup/new + cleanup-on-abort) complete? yes
11 Compose lifecycle (modified/backup_path/diff counts) complete? yes
12 Smoke results (registry 13 + non-reg 3 + special 2 + api 1) recorded? yes
13 Hard boundary attestation full set TRUE? yes
14 phase_status decided per decision matrix? yes (PARTIAL — 18/19 pass, 1 verbatim FAIL classified as prompt URL drift; rollback NOT recommended per disclosed forensic evidence — see rationale)
15 next_required_pack correct? yes
16 Report uploaded to KB at correct path? yes (this document)

Decision matrix application

Per rev5 / dispatch-package decision matrix:

phase_status next_required_pack
PASS P3D4C2U_RESUME_NOTIFICATION_DISPLAY_PROMPT_REVIEW
PARTIAL D28_DEPLOY_PARTIAL_FIX_PACK
FAIL with rollback D28_GENERATED_MAP_FIX
FAIL without rollback D28_PROD_HOTFIX
FAIL_LEAK (compose diff or relations) D28_LEAK_INVESTIGATION_PACK
next_required_pack=D28_DEPLOY_PARTIAL_FIX_PACK

The PARTIAL fix pack should be a small prompt-side fix (NOT a code-side or rollback action):

  1. Patch rev5 Phase 2E template URL to /api/discovery/relations?collection=<one of the registered collections> matching the documented endpoint contract (source: web/server/api/discovery/relations.get.ts lines 24–30).
  2. Re-run only Phase 2E smoke under the patched URL to confirm 200+data+relation-shape (already independently confirmed in this run's declared diagnostic).
  3. Then dispatch P3D4C2U_RESUME_NOTIFICATION_DISPLAY_PROMPT_REVIEW as if Stage 2 had landed PASS, since the underlying deploy is functionally healthy.

Note: tbl_event_outbox remains draft. notification_display remains paused. P3D resume is NOT done in this pack.


P3D state preserved (unchanged)

table_registry_id=21
permission_id=1483
tbl_event_outbox.status=draft
notification_display=paused
p3d_resume_allowed=false_until_partial_fix_or_user_override

Notes & deviations

  1. Phase 1D build log SCAN=FAIL classified as FILENAME_FALSE_POSITIVE. Build succeeded (exit 0). 2 hits, all on word password, all on lines containing forgot-password page chunk filename pattern (Vite/Rollup build summary table rows). No PASSWORD= env-style, no JWT shape, no JSON "password":"..." assignment shape, no URL on hit lines. Per rev3+rev4 branching: counts/classification reported, no log content printed, log file removed. Continued deploy. (Same content-hash chunk pattern was the false-positive trigger in earlier S178 builds — known harmless.)

  2. Phase 1G healthy faster than expected. Container reported running after 1 poll (~2s) and healthy after 34s. Stage 1 0H reported compose_healthcheck_for_nuxt=NONE from grep -A3 'healthcheck:' filter. The runtime "healthy" status indicates a healthcheck is active in some form not surfaced by Stage 1's grep. Empirical: service is healthy. No spec change required.

  3. Phase 2E verbatim relations URL has prompt drift, not deploy drift. rev5 Phase 2E template calls /api/discovery/relations without query parameters, but the endpoint source code (web/server/api/discovery/relations.get.ts lines 24–30) requires ?collection=<name>. Verbatim call returned 400 ("collection parameter required") — this is the correct server response. A declared (non-silent) diagnostic call with ?collection=workflow_steps returned 200 + data + relation-shape, proving the deploy is functionally healthy. This is a prompt-template defect, not a server / deploy defect. The verbatim FAIL is preserved in the smoke pass count to honor rev5 strict reading.

  4. No silent substitution. The single Phase 2E diagnostic call was explicitly declared in real time and is documented in this report, separately from the verbatim smoke. No service-name swap, no path swap, no env swap, no other URL workaround.

  5. No rollback recommended despite PARTIAL. The 1 smoke "failure" is a prompt-side bug, not a server-side bug. The diagnostic plus source-code reading confirm the new image (d2db418) is fully functional for the relations endpoint. Rolling back would revert working code based on a test-definition defect, which would be a worse outcome than leaving the deploy in place. Recommended next action is a prompt patch (D28_DEPLOY_PARTIAL_FIX_PACK), not a rollback.

  6. No auto-rollback executed. Per rev5 NO_AUTO_ROLLBACK. Rollback would only proceed if User issues:

    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.
    

    Rollback components ready and verified intact:

    • nuxt-ssr-local:pre-d28-rollback-1778397192 (image ID 072ccd861f30, alias of s174) — present in docker images
    • /opt/incomex/docker/docker-compose.yml.pre-d28-1778397192 (5068 bytes) — present on disk
    • Original nuxt-ssr-local:s174 (ID 072ccd861f30) — also still present, same content as backup tag
  7. TS=1778397192 was loaded once from Stage 1 report and never recomputed. Per NO_STAGE2_RECOMPUTE_BACKUP_TIMESTAMP=true. TS_LOG values used for log-file uniqueness are independent and were never substituted into image tags or compose backup paths.


Stage 2 dispatch requirements (for any follow-up pack)

this_pack=D28_STAGE_2_DEPLOY_AND_SMOKE
next_required_pack=D28_DEPLOY_PARTIAL_FIX_PACK

Followup pack must:

  • Patch rev5 Phase 2E URL template to include ?collection=<name>.
  • Re-run Phase 2E only (no re-deploy needed; running image is already correct).
  • Then unblock dispatch of P3D4C2U_RESUME_NOTIFICATION_DISPLAY_PROMPT_REVIEW.

Until then:

  • tbl_event_outbox stays draft.
  • notification_display stays paused.
  • P3D resume blocked.

D28 Deploy + Live Smoke Stage 2 Execution Report | rev5 spec | TS=1778397192 (Stage 1 binding) | phase_status=PARTIAL (18/19 routes pass; 1 verbatim FAIL classified as prompt URL drift; rollback NOT recommended) | 2026-05-10 | Agent: claude-go

Back to Knowledge Hub knowledge/dev/laws/dieu28-trien-khai/reports/d28-deploy-and-live-smoke-stage2-execution-report.md