Automattic / Automattic/studio
PHP recovery listener can conflict with Studio's offline lifecycle state
- Dominant language
- TypeScript
- Stars
- 517
- Forks
- 95
- Avg merge
- 1d 22h
- Merged PRs (30d)
- 162
Description
## Problem
When WordPress database bootstrap fails, Studio can launch a PHP recovery listener on the site's public port while continuing to report the site as offline. The lifecycle commands then disagree:
- `studio status`: offline
- the public port: owned by a PHP process
- `studio stop`: server is not running
- `studio start`: fails because startup/recovery state is not reconciled
The operator is pushed toward inspecting and terminating raw PIDs even though Studio owns both the normal server and recovery server.
## Reproduction
1. Configure a local site whose WordPress database bootstrap fails.
2. Run `studio start` and observe startup failure/recovery behavior.
3. Run `studio status`; observe offline.
4. Inspect the configured public port; observe a PHP recovery listener.
5. Run `studio stop`; observe that Studio says the server is not running and does not reconcile the listener.
6. Retry start and observe confusing port/lifecycle failure.
## Expected contract
Normal and recovery servers share one authoritative lifecycle record. Status identifies recovery mode, stop terminates it, and start reconciles or replaces it without raw PID intervention.
## Acceptance criteria
- `studio status` reports a typed `recovery` state when the recovery listener owns the public port.
- `studio stop` stops both normal and recovery listeners owned by the site.
- `studio start` detects and safely reconciles a retained recovery listener before binding.
- Output identifies the underlying WordPress bootstrap failure separately from port ownership.
- Tests cover failed DB bootstrap, recovery listener, stop, and successful subsequent restart.
## AI assistance
OpenAI GPT-5.6-sol via OpenCode reproduced the lifecycle contradiction, correlated Studio logs with port ownership, searched existing trackers, and drafted this report. Chris Huber directed and owns the issue.
Contributor guide
Research direction
Start with the documented failed WordPress database-bootstrap reproduction and compare `studio status`, `studio stop`, and `studio start` while a recovery listener owns the public port. Done means recovery is reported as a typed state, stop handles both listener types, start reconciles retained recovery state, and tests cover failure, stop, and restart.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- php, typescript
- Domain
- backend, cli, desktop
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 48/100