Repository navigation
[Bug]: status and doctor ignore an identity-verified live proxy when ocx.pid is missing #618
Description
Client or integration
Codex CLI
Area
CLI
Summary
When the proxy is healthy and identity-verified through runtime-port.json plus /healthz, but ocx.pid is missing or stale, OpenCodex's own findLiveProxy() correctly finds the live process. However, ocx status --json reports proxy.running: false with pid: null, and ocx doctor reports that no proxy is running and recommends a restart.
I expected read-only diagnostics to use the same identity-verified liveness result as lifecycle and OAuth-health paths. A missing PID file should remain a separate warning; it should not turn a verified live proxy into a stopped one.
This matters because status --json is the machine-readable diagnostics contract, doctor suppresses live service memory/runtime information, and the restart hint is incorrect while the service is healthy.
Reproduction
This state was observed after normal Windows Task Scheduler service operation. No PID or runtime file was removed for this report.
Environment state:
~/.opencodex/ocx.pid: absent
runtime-port.json: {"pid":39196,"port":10100}
process 39196: alive, OpenCodex Bun CLI, start --port 10100
GET /healthz: service=opencodex, version=2.7.42, pid=39196, port=10100
-
Confirm the identity-verified liveness helpers find the proxy:
findLiveProxy() -> {"pid":39196,"port":10100} ocx health --json -> {"ok":true,"pid":39196,"port":10100} -
Run
ocx status --json. -
Observe that the same response says both
running:falseandhealth.ok:true:{ "proxy": { "running": false, "pid": null, "health": { "ok": true, "url": "http://127.0.0.1:10100/healthz", "message": "ok v2.7.42, uptime ..." } } } -
Run
ocx doctor. -
Observe:
no running ocx proxy process found no running ocx proxy found (no live pid/runtime record) The ocx proxy is not running ... Restart it ...
The OAuth-health section in that same doctor run did not claim the proxy was unavailable because that path already uses findLiveProxy(), so doctor is internally inconsistent.
A fallback-port orphan can be worse: status ignores the runtime target and may report both running:false and health.ok:false, along with the wrong health/dashboard URL.
Version
- Released package:
@bitkyc08/opencodex 2.7.42 - Also reproduced against current
dev:ca7b1049f6c198311ae260e8f1db019fcc759877
The relevant status, doctor, and liveness source is unchanged between the installed package and this dev revision.
Operating system
Microsoft Windows 11 Pro 25H2, x64 (build 26200.8894)
Provider and model
Not provider-specific.
Logs or error output
# ocx status --json
"proxy":{"running":false,"pid":null,"health":{"ok":true,"url":"http://127.0.0.1:10100/healthz","message":"ok v2.7.42, uptime ..."}}
# ocx doctor
no running ocx proxy process found
no running ocx proxy found (no live pid/runtime record)
The ocx proxy is not running ... Restart it ...Screenshots and supporting files
Current dev source:
src/server/proxy-liveness.ts:93-143:findLiveProxy()intentionally recovers from a missing/corrupt PID file using the runtime record, then verifies OpenCodex health identity and the expected PID.tests/proxy-liveness.test.ts:95-109: an existing regression explicitly expects an orphaned runtime record to be adopted.src/cli/status.ts:132-137,231-246: status callsreadPid(), only reads runtime state when that succeeds, and defines JSONrunningasBoolean(pid && health.ok).src/cli/doctor.ts:396-399,745-757,815-822: doctor independently treats a missing PID file as stopped, suppresses live runtime diagnostics, and emits the restart hint.src/oauth/health.ts:323-335: the OAuth doctor path already usesfindLiveProxy(), causing the internal contradiction.
Redacted configuration
{
"listenPort": 10100,
"serviceBackend": "scheduler",
"providerSpecific": false
}Checks
- I searched open and closed issues and pull requests for
runtime-port.json,ocx.pid,findLiveProxy, the emitted doctor messages, and orphan-proxy combinations. - I removed secrets, tokens, account details, request credentials, personal paths, usernames, and response contents.
Root cause
findLiveProxy() already implements the safe orphan-recovery contract: a runtime record is discovery-only and must pass OpenCodex /healthz identity and expected-PID checks before it is returned. Status and several doctor sections bypass that helper and require readPid() first, so they discard the verified orphan-recovery result.
Suggested safe direction
Use identity-checked findLiveProxy() for read-only status and doctor discovery, while preserving readPid() or equivalent strict ownership checks for destructive actions. Never trust runtime-port.json by itself.
Keep “PID file missing or stale” as a separate diagnostic rather than mapping it to running:false. Suggested regressions:
status --jsonreports a verified orphan proxy as running with its resolved PID and port.- Doctor uses its live process/runtime endpoint and does not emit the stopped/restart hint.
- A stale runtime record or foreign listener remains rejected.
- An identity-verified orphan on a fallback port supplies the correct health and dashboard URLs.
Activity
github-actions commentedon Jul 28, 2026
Automated translation bookkeeping — detected language: English.
fix(cli): status/doctor use identity-verified live proxy (#642)
fix(cli): status/doctor use identity-verified live proxy (lidge-jun#642)