Skip to content

fix(cli): check live proxy before journal recovery - #1269

Draft
Ingwannu wants to merge 1 commit into
devfrom
agent/fix-1230-start-journal-order
Draft

fix(cli): check live proxy before journal recovery#1269
Ingwannu wants to merge 1 commit into
devfrom
agent/fix-1230-start-journal-order

Conversation

@Ingwannu

@Ingwannu Ingwannu commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Summary

  • Check the PID-file owner and the live proxy before reconciling a stale Codex journal during ocx start.
  • Exit without mutating Codex integration state when another healthy OpenCodex proxy already owns the start lifecycle.
  • Keep stale-PID cleanup and journal recovery in place for genuine replacement starts.
  • Add an ordering regression that pins the ownership check ahead of journal recovery.

Closes #1230

Verification

  • taskset -c 0-1 bun test tests/cli-start-journal-order.test.ts tests/codex-journal.test.ts tests/proxy-liveness.test.ts tests/stale-state-purge.test.ts — 105 passed.
  • taskset -c 0-1 bun run typecheck — passed.
  • taskset -c 0-1 bun run privacy:scan — passed.
  • taskset -c 0-1 bun run test — 9,765 passed and 10 skipped; the local all-suite run also retained unrelated baseline/environment failures in the Codex shim token fixture, Live sideband close timing, and GUI dependency setup. The focused lifecycle suites above are green; exact-head CI remains authoritative.

Checklist

  • Scope stays focused and avoids unrelated cleanup.
  • Docs or release notes were updated when needed.
  • Security-sensitive changes were reviewed for secrets, auth, and unsafe defaults.

Summary by CodeRabbit

  • Bug Fixes

    • Improved startup handling when another healthy proxy is already running.
    • Prevented competing startup attempts from modifying the active proxy’s configuration.
    • Correctly removes stale process state before reconciling startup data.
  • Tests

    • Added coverage to verify the expected startup sequence and proxy detection behavior.

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

handleStart now checks for a healthy existing proxy before reconciling journal state. It removes stale PID state before reconciliation. A source-order test verifies the startup sequence.

Changes

Startup lifecycle

Layer / File(s) Summary
Check proxy ownership before journal reconciliation
src/cli/index.ts, tests/cli-start-journal-order.test.ts
handleStart checks PID liveness and exits for a healthy proxy before journal reconciliation. It removes stale PID state before reconciling. The test verifies the ordering through update prompting.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: lidge-jun, wibias

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR fixes ordering in handleStart, but handleEnsure still reconciles the journal before liveness checks and required behavioral coverage is missing. Apply the same ordering fix to handleEnsure and add behavioral tests for healthy-owner preservation and dead-owner journal recovery.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the main change: checking for a live proxy before journal recovery.
Out of Scope Changes check ✅ Passed The changed startup logic and regression test directly support issue #1230 and contain no unrelated code changes.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch agent/fix-1230-start-journal-order

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Deterministic PR hygiene checks passed.

@github-actions github-actions Bot added the bug Something isn't working label Aug 8, 2026
@lidge-jun

Copy link
Copy Markdown
Owner

Adopting this — the handleStart reordering is exactly right.

One gap: handleEnsure still has the same defect. On current dev it calls reconcileJournal() at src/cli/index.ts:441, before the liveness check at :447, so the autostart path keeps the destructive ordering your fix removes from handleStart. Issue #1230 would only be half closed.

Could you extend the fix to handleEnsure? If you would rather keep this PR scoped, say so and I will follow up separately — either way #1230 stays open until both are covered.

On the test: the indexOf ordering check is a reasonable minimum, but it stops meaning anything if someone extracts reconcileJournal() into a helper. A behavioural test with isolated OPENCODEX_HOME/CODEX_HOME, a dead journal PID and a separately started healthy proxy would survive that. The negative control matters most — dead PID with no listener must still reconcile — since without it the test cannot tell reordering from removal.

@github-actions

github-actions Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

⏳ DRAFT

  • UI screenshot required.

What to do

  • Add a screenshot of the UI change to the PR description.

This pull request was already a draft. Its draft status will be preserved after every issue above is resolved.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/cli/index.ts`:
- Around line 234-237: Move the ownership gate currently guarding
reconcileJournal near the startup path into a shared helper, including PID
existence, live-proxy detection, and stale-PID cleanup. Invoke this helper
before reconcileJournal in both the startup flow and handleEnsure, so a healthy
active proxy prevents journal merging while stale ownership is cleaned up first;
add an ensure regression case covering this behavior.

In `@tests/cli-start-journal-order.test.ts`:
- Around line 15-30: Replace the source-offset assertions in the journal
ownership ordering test with Bun behavioral regression tests that invoke the
actual CLI lifecycle. In the healthy-owner case, isolate OPENCODEX_HOME and
CODEX_HOME, seed a dead journal PID, run a healthy proxy, execute ocx start, and
verify managed Codex configuration, catalog, journal, profile, and history
remain unchanged; in the dead-owner/no-listener case, use the isolated state
without a proxy and verify reconciliation restores the expected state. Add
equivalent ocx ensure coverage when it uses the shared startup gate, using
existing test helpers and symbols rather than asserting source layout.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 28e246d3-22ea-4c78-8117-76a364e9b03c

📥 Commits

Reviewing files that changed from the base of the PR and between fdc47db and 8b7831e.

📒 Files selected for processing (2)
  • src/cli/index.ts
  • tests/cli-start-journal-order.test.ts

Comment thread src/cli/index.ts
Comment on lines +234 to +237
// A losing concurrent start must not restore the active proxy's Codex config.
// Establish that the PID-file owner is stale before reconciling a dead journal;
// a healthy owner exits above without changing integration state (#1230).
if (!currentExternalCodexModelProvider()) reconcileJournal();

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

ast-grep outline src/cli/index.ts --items all --type function
rg -n -C 30 'async function handleEnsure|reconcileJournal|findLiveProxy|readPid|removePid' src/cli/index.ts

Repository: lidge-jun/opencodex

Length of output: 41991


Apply the ownership gate to handleEnsure before merging.

src/cli/index.ts:444 calls reconcileJournal() before handleEnsure checks for a live proxy at line 450. When another healthy proxy already owns the lifecycle, ocx ensure can restore the stale journal and overwrite the active proxy's Codex configuration/profile. Apply the same PID existence/live-proxy/stale-PID cleanup sequence used in src/cli/index.ts:225-237, share it for both startup paths, and add an ensure regression case.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/cli/index.ts` around lines 234 - 237, Move the ownership gate currently
guarding reconcileJournal near the startup path into a shared helper, including
PID existence, live-proxy detection, and stale-PID cleanup. Invoke this helper
before reconcileJournal in both the startup flow and handleEnsure, so a healthy
active proxy prevents journal merging while stale ownership is cleaned up first;
add an ensure regression case covering this behavior.

Comment on lines +15 to +30
describe("handleStart journal ownership ordering (#1230)", () => {
test("a healthy PID-file proxy is detected before journal reconciliation", () => {
const handleStart = handleStartSource();
const readPid = handleStart.indexOf("const existingPid = readPid();");
const findLive = handleStart.indexOf("const live = await findLiveProxy();", readPid);
const healthyExit = handleStart.indexOf("process.exit(1);", findLive);
const removeStalePid = handleStart.indexOf("removePid(existingPid);", healthyExit);
const reconcile = handleStart.indexOf("reconcileJournal();", removeStalePid);
const updatePrompt = handleStart.indexOf("await maybeShowUpdatePrompt();", reconcile);

expect(readPid).toBeGreaterThanOrEqual(0);
expect(findLive).toBeGreaterThan(readPid);
expect(healthyExit).toBeGreaterThan(findLive);
expect(removeStalePid).toBeGreaterThan(healthyExit);
expect(reconcile).toBeGreaterThan(removeStalePid);
expect(updatePrompt).toBeGreaterThan(reconcile);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Replace the source-order assertion with behavioral coverage.

This test compares string offsets only. It never runs handleStart, writes a PID or journal, starts a healthy proxy, or verifies Codex state. A broken implementation can still satisfy Lines [18-30]. Moving reconcileJournal() into a helper also makes the test enforce source layout instead of behavior. The test cannot detect the handleEnsure gap.

Add two Bun regression tests:

  • For a healthy owner, use isolated OPENCODEX_HOME and CODEX_HOME, seed a dead journal PID, run a separate healthy proxy, invoke ocx start, and assert that managed Codex configuration, catalog, journal, profile, and history remain unchanged.
  • For a dead owner with no listener, use the same isolated state without a running proxy and assert that journal reconciliation restores the expected state.

Also cover ocx ensure if it uses the shared startup lifecycle gate.

As per path instructions, runtime behavior changes require focused regression coverage in tests/**. The PR objective also requires healthy-owner and dead-owner/no-listener cases.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/cli-start-journal-order.test.ts` around lines 15 - 30, Replace the
source-offset assertions in the journal ownership ordering test with Bun
behavioral regression tests that invoke the actual CLI lifecycle. In the
healthy-owner case, isolate OPENCODEX_HOME and CODEX_HOME, seed a dead journal
PID, run a healthy proxy, execute ocx start, and verify managed Codex
configuration, catalog, journal, profile, and history remain unchanged; in the
dead-owner/no-listener case, use the isolated state without a proxy and verify
reconciliation restores the expected state. Add equivalent ocx ensure coverage
when it uses the shared startup gate, using existing test helpers and symbols
rather than asserting source layout.

Source: Path instructions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants