fix(infra): scope pm2 stop/delete to the staging ecosystem, never all (#912) - #1006
Conversation
|
Claude finished @frankbria's task in 4m 35s —— View job Bug-hunting review of PR #1006 (pm2 scoping) — ✅ no defects foundGLM review: no defects found. No inline comments — nothing survived a concrete failure-scenario check. Verified against the checked-out branch (not the diff alone):
Scoping is correct. No working-directory bug. systemd unit parses correctly. No remaining operational No new failure mode. The ecosystem file must already parse for the apps to be running, so the new parse-dependency on Scope note: style, architecture, naming, and coverage belong to the separate general review and are intentionally not covered here. |
|
Claude finished @frankbria's task in 3m 50s —— View job Bug-hunting review of PR #1006 (pm2 scoping) — synchronize ✅Precision defect review (logic, security, data-loss, runtime contract). Style/architecture/naming/coverage are covered by the separate general review.
No defects found. Full verdict posted as a separate summary comment — scoping is correct (staging ecosystem defines only the two staging app names; production untouched), path resolution is sound across all three scripts and the systemd unit (the synchronize commit's absolute |
Bug-hunting review of PR #1006 (pm2 scoping) — synchronize — ✅ no defects foundGLM review: no defects found. No inline comments — nothing survived a concrete failure-scenario check. Reviewed the current branch state (both commits:
Scoping is correct. No working-directory bug (verified incl. the new absolute paths). All three scripts compute systemd unit parses and scopes correctly. No remaining operational No new failure mode. Every Scope note: style, architecture, naming, and coverage belong to the separate general review and are intentionally not covered here. |
Phase 11 — demo verification (hard gate)Every acceptance criterion mapped to outcome evidence, against a real pm2 6.0.13 daemon. 3. A staging restart leaves production pm2 processes onlineRan the exact command the scripts now run, from a different cwd, with an unrelated tenant app alongside the stand-in production process: And the old behaviour, for contrast: Edge case checked: apps started by name rather than from the ecosystem file are still matched — pm2 resolves the file to its declared app names, so 1. Every stop/delete names the staging processes8 shell call sites + 3 systemd 2. The issue's grep returns no operational linesHardening found while demoingTwo scripts used a bare relative
Docs sync (Phase 12b)No live runbook mentions |
Cross-family review — codex (Phase 10-pre)
Reviewer chain note, for the record: opencode is the documented primary and produced no output on two attempts (~15 min each, killed at timeout) — the same backend failure seen earlier today. codex is the sanctioned fallback; its first attempt also hit the timeout, and a second run with a tighter prompt returned the review above. Recording this because "the reviewer approved" and "the reviewer never ran" look identical from a green PR, and only one of those is a real gate. Independent passes on this PR: codex (APPROVE) + GLM bot (no defects found), both against the checked-out branch rather than the diff alone. |
Closes #912.
Problem
Four independent staging paths ran
pm2 stop allfollowed bypm2 delete all, then restarted onlyecosystem.staging.config.js.Staging and production deploy to the same host — both
deploy.ymljobs ssh tosecrets.HOSTand drive pm2 — so an unattended staging health-check remediation stopped and deleted the production backend and frontend, plus any unrelated app on the shared VPS, and never restarted them. A silent production outage lasting until the next production deploy.Fix
Every stop/delete now targets
ecosystem.staging.config.js. pm2 accepts an ecosystem file directly —stop <id|name|namespace|all|json...>— so there is no name list to duplicate and drift across three scripts and a systemd unit:scripts/health-check.shpm2 stop all/pm2 delete all— the unattended path that caused the outagescripts/start-staging.shpm2 stop all/pm2 delete allscripts/deploy-staging.shsystemd/codeframe-staging.serviceExecStop×2 andExecReloadThe help text those scripts print also told operators to run
pm2 stop all/pm2 restart all/pm2 delete all. That teaches the same footgun by proxy, so it now shows the scoped commands.deploy.ymlwas already fixed in #1002 (delete by name, notall), so this covers the shell/systemd half the issue names.Verified against a real pm2 daemon
pm2 6.0.13, three apps, a stand-in production process:
That is acceptance criterion 3 ("a staging restart leaves production pm2 processes online") demonstrated both ways.
Tests
tests/test_pm2_scoping_912.py, beside the existingtest_deploy_config.pydeploy guards — 4 tests:pm2 stop|delete|restart allinscripts/orsystemd/. Comment lines are excluded, so fix(deploy): unblock the Deploy workflow (known-hosts, Tailscale routing, pm2 env) #1002's deliberateNOT \pm2 delete all`` warnings do not trip it.all" cannot be satisfied by removing the stop entirely.Mutation-checked: restoring
pm2 stop allinhealth-check.shfails the scan.Deliberately not changed
grepalso findspm2 stop allinclaudedocs/sprint4-*.mdandlegacydocs/STAGING_SERVER.md. Those are historical sprint records and explicitly legacy documentation, not live runbooks — editing them rewrites a record rather than fixing a path. The issue scopes the criterion toscripts/andsystemd/. Flagging it here so it reads as a decision rather than an oversight.