Skip to content

fix: codex acp integration - #151

Merged
pedronauck merged 3 commits into
mainfrom
fix-codex
May 14, 2026
Merged

pedronauck merged 3 commits into
mainfrom
fix-codex

Conversation

@pedronauck

@pedronauck pedronauck commented May 14, 2026 •

Copy link
Copy Markdown
Member

Summary by CodeRabbit

  • New Features

    • Terminal process management for agent sessions: command execution, buffered output (with truncation), kill/release, and graceful shutdown handling
    • New provider watch state representing a “settled on current head” condition
  • Improvements

    • Run IDs now include timestamp plus cryptographic entropy, with retrying to avoid collisions and clearer allocation error handling
    • Codex/bootstrap launch arguments include managed runtime overrides for more predictable runtime behavior
    • Review-watch logic treats the settled state as ready to progress
  • Tests

    • Expanded test coverage for terminal lifecycle, run-manager run-id allocation/resumption, provider status gating, and diagnostic parsing

Review Change Stack

@pedronauck pedronauck self-assigned this May 14, 2026
@coderabbitai

coderabbitai Bot commented May 14, 2026 •

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 88cf256e-be54-4067-9f38-97485f6eb234

📥 Commits

Reviewing files that changed from the base of the PR and between 56b249b and d2eae01.

⛔ Files ignored due to path filters (1)
  • .compozy/tasks/codex-acp/reviews-002/issue_001.md is excluded by !**/*.md
📒 Files selected for processing (1)
  • internal/daemon/run_manager_test.go
🚧 Files skipped from review as they are similar to previous changes (1)
  • internal/daemon/run_manager_test.go

Walkthrough

This PR implements ACP terminal process management and client integration, refactors run ID generation to use entropy with RunManager allocation/retry wiring, centralizes Codex bootstrap runtime overrides, and introduces a "current_settled" watch state with CodeRabbit commit-status gating and daemon readiness updates.

Changes

ACP Terminal Process Management

Layer / File(s) Summary
Terminal process implementation
internal/core/agent/terminal.go
Introduces terminal subsystem: process state tracking, output buffering with UTF-8 truncation, process control, and session-scoped working-directory enforcement with allowed-root validation.
Client-side terminal integration
internal/core/agent/client.go
Integrates terminal lifecycle into ACP client: tracks active terminals via mutex, implements RPC handlers, closes terminals on shutdown, and diagnoses agent exit errors with terminal cleanup and stderr diagnostics.
Terminal tests and helpers
internal/core/agent/client_test.go
Tests terminal operations: agent-triggered requests, command execution with output/exit-code validation, working-directory enforcement, kill semantics, client Close cleanup, and deterministic helper-process entrypoints for stderr diagnostics.

Run ID Generation and Allocation with Entropy

Layer / File(s) Summary
Entropy-based run ID generation
internal/core/model/run_scope.go
Refactors BuildRunID to return (string, error) and generate IDs using entropy-backed random hex appended to timestamp and label; runLabel is made nil-safe.
Run ID generation tests
internal/core/model/run_scope_internal_test.go
Tests explicit run ID preservation, entropy-backed generation with differing entropy, mode-specific labels, and entropy reader error propagation.
Run manager ID allocation and retry
internal/daemon/run_manager.go
Wires BuildRunID into RunManager via RunManagerConfig.BuildRunID, distinguishes explicit vs implicit run IDs, and adds bounded-retry implicit allocation on ErrRunAlreadyExists.
Run manager allocation tests
internal/daemon/run_manager_test.go
Tests implicit run_id collision retry, explicit duplicate failure, parallel implicit allocation uniqueness, and resumption failure marking; adds persisted-run helper and deterministic buildRunID injection.
Consolidate run ID generation in exec
internal/core/run/exec/exec.go
Delegates exec persisted-run fallback run-id generation to model.BuildRunID and removes local helpers.

Review Watch Status with Settled State

Layer / File(s) Summary
Watch status provider definition
internal/core/provider/provider.go
Adds WatchStatusCurrentSettled constant ("current_settled") to the watch status enum.
CodeRabbit status classification refactoring
internal/core/provider/coderabbit/coderabbit.go
Refactors WatchStatus classification to separate the no-latest-review path, centralize commit-status gating via applyCodeRabbitStatusGate, set CurrentSettled on pending/no-commit cases, and simplify review-only staleness logic.
CodeRabbit status tests
internal/core/provider/coderabbit/coderabbit_test.go
Extends watch-status tests to accept commit-status slices, adds settled/pending cases, and adds a failing-status assertion when CodeRabbit reports failure without provider review.
Review watch settled state handling
internal/daemon/review_watch.go
Updates waitForCurrentReview to use reviewWatchStatusReady so both CurrentReviewed and CurrentSettled satisfy readiness; tests added for settled fetch and clean completion.

Codex Configuration Override Standardization

Layer / File(s) Summary
Codex config helper and override list
internal/core/agent/registry_specs.go
Introduces codexManagedRuntimeConfigOverrides and appendCodexConfigOverrides helper; refactors codexBootstrapArgs to consistently append managed Code Mode -c overrides and conditionally include full-access overrides.
Codex configuration tests
internal/core/agent/registry_test.go
Updates codex bootstrap tests to verify managed feature overrides (features.code_mode=false, features.code_mode_only=false) are present or omitted according to accessMode; replaces single-case test with table-driven coverage.

Minor Cleanup and Configuration

Layer / File(s) Summary
Prettier formatting exclusions
.prettierignore
Excludes CHANGELOG.md, RELEASE_BODY.md, and package.json from Prettier formatting.

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs:

  • compozy/compozy#133: Related to review-watch implementation and watch-state handling extended here with current_settled.
  • compozy/compozy#128: Overlaps in Codex bootstrap/config handling and ACP client compatibility changes.
🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 3.49% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'fix: codex acp integration' is vague and generic. It uses broad terminology ('integration') without specifying which aspects are being fixed or what the main changes address. Provide a more specific title that describes the primary fix, such as 'fix: add terminal lifecycle management to ACP client' or 'fix: implement terminal subsystem and run ID generation for codex ACP integration' to better reflect the substantial changes.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ 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 fix-codex

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

@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: 6

🤖 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 `@internal/core/agent/terminal.go`:
- Around line 332-337: newTerminalOutputBuffer currently treats a nil or
non-positive limit as "unlimited", which can let a single command exhaust RAM;
change newTerminalOutputBuffer to apply a server-side default cap when limit is
nil or <= 0 (e.g., a constant like defaultOutputByteLimit such as 10*1024*1024
bytes), so resolvedLimit is set to that default instead of 0; update/introduce
the default constant (name: defaultOutputByteLimit) and ensure
terminalOutputBuffer{limit: resolvedLimit} uses that capped value so
OutputByteLimit unset no longer means unlimited.
- Around line 123-129: The code currently calls c.removeTerminal(...) before
terminal.waitFor(ctx), which removes the terminal from c.terminals and can
orphan the subprocess on context deadline; instead, look up the terminal without
removing it (or fetch it from c.terminals directly), call terminal.kill(), wait
for it with terminal.waitFor(ctx), and only after waitFor returns (successful
cleanup or final error) call c.removeTerminal(...) to remove tracking; update
code paths that used removeTerminal(...) to use the non-destructive lookup
first, then call removeTerminal by name/ID after waitFor completes.

In `@internal/core/provider/coderabbit/coderabbit_test.go`:
- Around line 147-175: The test table entries use names that will be passed to
t.Run but do not follow the required "Should ..." pattern; update the name
fields for the affected cases in the test table in coderabbit_test.go (the
entries with headSHA "head-without-review", "head-new" with stale latest
provider review, and "head-new" with stale review + pending status) so each name
begins with "Should ..." (e.g., "Should mark current settled when CodeRabbit
completed current head without a provider review", "Should mark current settled
when CodeRabbit completed current head but latest provider review is stale",
"Should be pending when CodeRabbit is still processing current head with stale
latest review") to comply with the t.Run naming convention.
- Around line 203-218: Wrap the test body of
TestWatchStatusFailsWhenCodeRabbitStatusFailsWithoutProviderReview in a t.Run
subtest whose name starts with "Should" (e.g., t.Run("Should return coderabbit
status failure", func(t *testing.T) { ... })), move the assertions and the call
to New(...).WatchStatus(...) into that subtest, and call t.Parallel()
appropriately (either keep the existing top-level t.Parallel() or call
t.Parallel() inside the subtest) so the test follows the required
t.Run("Should...") pattern while preserving the existing logic and referenced
symbols (TestWatchStatusFailsWhenCodeRabbitStatusFailsWithoutProviderReview,
New, WithCommandRunner, testWatchStatusRunnerWithStatuses, WatchStatus).

In `@internal/daemon/review_watch_test.go`:
- Around line 117-190: Both subtests titled "Should fetch and fix unresolved
reviews when provider settled without a current review object" and "Should
declare clean after provider settled current head and no unresolved reviews
remain" are independent and should be marked parallel; add t.Parallel() as the
first line inside each subtest's anonymous func(t *testing.T) to enable
concurrent execution and follow the test guideline. Locate the two t.Run(...)
blocks in internal/daemon/review_watch_test.go and insert t.Parallel() at the
top of each subtest function body (the funcs passed to t.Run).

In `@internal/daemon/run_manager.go`:
- Around line 1164-1176: The resumeExistingExecRun success path currently
returns createdRun=false which loses the fact the persisted row was touched;
change the return to propagate the `ok` flag returned by `resumeExistingExecRun`
(i.e., return row, ok, nil) so callers like `openRunScopeForStart`/`startRun`
know the row was resumed and can run rollback/terminal-state mirroring; ensure
the code path that calls `resumeExistingExecRun` uses the `ok` boolean instead
of a hardcoded false when deciding cleanup or failure-marking.
🪄 Autofix (Beta)

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: CHILL

Plan: Pro

Run ID: 6286b4d3-18ef-4071-a2e2-cec777e7f96e

📥 Commits

Reviewing files that changed from the base of the PR and between 209603a and 4cd1f2b.

⛔ Files ignored due to path filters (1)
  • .codex/ledger/2026-05-13-MEMORY-reviews-fix-watch.md is excluded by !**/*.md
📒 Files selected for processing (16)
  • .prettierignore
  • internal/core/agent/client.go
  • internal/core/agent/client_test.go
  • internal/core/agent/registry_specs.go
  • internal/core/agent/registry_test.go
  • internal/core/agent/terminal.go
  • internal/core/model/run_scope.go
  • internal/core/model/run_scope_internal_test.go
  • internal/core/provider/coderabbit/coderabbit.go
  • internal/core/provider/coderabbit/coderabbit_test.go
  • internal/core/provider/provider.go
  • internal/core/run/exec/exec.go
  • internal/daemon/review_watch.go
  • internal/daemon/review_watch_test.go
  • internal/daemon/run_manager.go
  • internal/daemon/run_manager_test.go

Comment thread internal/core/agent/terminal.go Outdated
Comment thread internal/core/agent/terminal.go
Comment thread internal/core/provider/coderabbit/coderabbit_test.go
Comment thread internal/core/provider/coderabbit/coderabbit_test.go
Comment thread internal/daemon/review_watch_test.go
Comment thread internal/daemon/run_manager.go Outdated
coderabbitai[bot]
coderabbitai Bot previously approved these changes May 14, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes May 14, 2026

@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.

🧹 Nitpick comments (1)
internal/daemon/run_manager_test.go (1)

1127-1283: ⚡ Quick win

Wrap new exec-run scenarios in t.Run("Should...") subtests.

Line 1127, Line 1176, and Line 1209 add standalone test cases. Please wrap these scenarios in t.Run("Should ...") (or table-driven subtests) to match the test-case pattern required for this repo.

As per coding guidelines, **/*_test.go: MUST use t.Run("Should...") pattern for ALL test 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 `@internal/daemon/run_manager_test.go` around lines 1127 - 1283, Wrap each
standalone test scenario into a t.Run("Should ...") subtest: for
TestRunManagerStartExecRunRetriesImplicitRunIDCollision,
TestRunManagerStartExecRunExplicitDuplicateRunIDStillFails, and
TestRunManagerStartExecRunAllocatesDistinctImplicitRunIDsInParallel move the
current test body into a t.Run call (e.g. t.Run("Should retry implicit run-id
collision", func(t *testing.T) { ... })) so the existing setup, channels, env :=
newRunManagerTestEnv(...), assertions and cleanup remain inside the closure;
keep the top-level Test... function as a thin wrapper that calls t.Run so the
repo-wide t.Run("Should...") pattern is followed and test semantics are
unchanged.
🤖 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.

Nitpick comments:
In `@internal/daemon/run_manager_test.go`:
- Around line 1127-1283: Wrap each standalone test scenario into a t.Run("Should
...") subtest: for TestRunManagerStartExecRunRetriesImplicitRunIDCollision,
TestRunManagerStartExecRunExplicitDuplicateRunIDStillFails, and
TestRunManagerStartExecRunAllocatesDistinctImplicitRunIDsInParallel move the
current test body into a t.Run call (e.g. t.Run("Should retry implicit run-id
collision", func(t *testing.T) { ... })) so the existing setup, channels, env :=
newRunManagerTestEnv(...), assertions and cleanup remain inside the closure;
keep the top-level Test... function as a thin wrapper that calls t.Run so the
repo-wide t.Run("Should...") pattern is followed and test semantics are
unchanged.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: fab508d7-c491-4758-998e-0d1d075c6bb5

📥 Commits

Reviewing files that changed from the base of the PR and between 4cd1f2b and 56b249b.

⛔ Files ignored due to path filters (6)
  • .compozy/tasks/codex-acp/reviews-001/issue_001.md is excluded by !**/*.md
  • .compozy/tasks/codex-acp/reviews-001/issue_002.md is excluded by !**/*.md
  • .compozy/tasks/codex-acp/reviews-001/issue_003.md is excluded by !**/*.md
  • .compozy/tasks/codex-acp/reviews-001/issue_004.md is excluded by !**/*.md
  • .compozy/tasks/codex-acp/reviews-001/issue_005.md is excluded by !**/*.md
  • .compozy/tasks/codex-acp/reviews-001/issue_006.md is excluded by !**/*.md
📒 Files selected for processing (6)
  • internal/core/agent/client_test.go
  • internal/core/agent/terminal.go
  • internal/core/provider/coderabbit/coderabbit_test.go
  • internal/daemon/review_watch_test.go
  • internal/daemon/run_manager.go
  • internal/daemon/run_manager_test.go
🚧 Files skipped from review as they are similar to previous changes (5)
  • internal/daemon/review_watch_test.go
  • internal/daemon/run_manager.go
  • internal/core/provider/coderabbit/coderabbit_test.go
  • internal/core/agent/terminal.go
  • internal/core/agent/client_test.go

@pedronauck
pedronauck merged commit a87f821 into main May 14, 2026
7 checks passed
@pedronauck
pedronauck deleted the fix-codex branch May 14, 2026 01:43
@coderabbitai coderabbitai Bot mentioned this pull request Jun 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant