Skip to content

cmuxTests: stop grading the CLI spawn on a five-second stopwatch - #8867

Merged
austinywang merged 6 commits into
manaflow-ai:mainfrom
ejc3:fix/cli-spawn-timeout-not-a-speed-gate
Jul 28, 2026
Merged

austinywang merged 6 commits into
manaflow-ai:mainfrom
ejc3:fix/cli-spawn-timeout-not-a-speed-gate

Conversation

@ejc3

@ejc3 ejc3 commented Jul 24, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Replace seven five-second runProcess deadlines in the CLI sessions-list regression suite with one 20-second liveness deadline.
  • Name the deadline for its actual role: detecting a hung CLI process, not grading command speed.
  • Keep status, JSON decoding, and field assertions as the independent correctness checks.

The original failure occurred on a loaded builder after 6.0 seconds even though the command exited 0 and returned complete, correct JSON. The same commit passed on an idle builder, so the old deadline made host load part of the test verdict. Twenty seconds gives more than three times the observed loaded runtime while still detecting a genuine hang promptly.

This change intentionally stays within the seven calls sharing the same runner. Other five-second values in the repository have different meanings, including protocol waits, so a repository-wide process-runner consolidation should be a separate, semantics-aware refactor rather than a blanket replacement.

Testing

  • git diff --check
  • ./scripts/lint-pbxproj-test-wiring.sh — passed for 602 test files
  • Canonical branch autoreview — clean, including merge-conflict and cmux/Aziz policy gates
  • Verified cmuxTests/CMUXCLISessionsListTranscriptPidTests.swift is 499 lines and the PR does not touch either Swift budget TSV
  • Local Xcode builds/tests were not run per the maintainer instruction for this PR; the latest pushed HEAD is gated by PR checks

Demo Video

  • Not applicable: test-only change with no user-facing UI or runtime behavior.

Review Trigger (Copy/Paste as PR comment)

@codex review
@coderabbitai review
@greptile-apps review
@cubic-dev-ai review

Checklist

  • I tested the change locally with the allowed static/test-wiring checks
  • I added or updated tests for behavior changes (not applicable: this only changes an existing test's liveness deadline)
  • I updated docs/changelog if needed (not applicable: test-only)
  • I requested bot reviews after my latest code change
  • All code review bot comments are resolved
  • All human review comments are resolved

@ejc3
ejc3 marked this pull request as draft July 24, 2026 14:36
@ejc3

ejc3 commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

Marking this draft until I have compiled it. The change is twenty lines of test-only edit and a named constant, but ci.yml is dispatch-only so nothing here builds it, and I would rather verify than assert. Build check queued on my own machine; I will flip it to ready with the result.

@coderabbitai

coderabbitai Bot commented Jul 24, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

The CLI session list tests introduce a shared 60-second process spawn timeout and replace seven hardcoded five-second runProcess timeouts with it.

Changes

CLI test timeout standardization

Layer / File(s) Summary
Shared CLI process timeout
cmuxTests/CMUXCLISessionsListTranscriptPidTests.swift
Adds the private cliSpawnTimeout constant and uses it across seven CLI process invocations in session list tests.

Estimated code review effort: 1 (Trivial) | ~2 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 25
✅ Passed checks (25 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
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.
Cmux Swift Actor Isolation ✅ Passed Only a test file changed, adding a timeout constant and replacing seven timeout literals; no actor-isolation-sensitive declarations were introduced.
Cmux Swift Blocking Runtime ✅ Passed Only a test-only CLI timeout constant was widened; no semaphores, sleeps, sync waits, locks, or asyncAfter were introduced.
Cmux Browser Automation Off-Main ✅ Passed PR only changes cmux CLI test timeouts in cmuxTests; it does not touch browser automation routing or WebKit/AppKit worker policy files.
Cmux Expensive Synchronous Load ✅ Passed Only a test file changed, and the rule applies to non-test Swift; no expensive main-actor or interactive load was added.
Cmux Cache Substitution Correctness ✅ Passed Diff only replaces hardcoded test timeouts with a named constant; no cache/persistence/history/snapshot read substitution occurred.
Cmux No Hacky Sleeps ✅ Passed Change is only a Swift test timeout constant; the no-hacky-sleeps rule is out of scope and no sleep/timer/polling was introduced.
Cmux Algorithmic Complexity ✅ Passed Only a test file changed; it replaces hardcoded timeouts with a shared constant and adds no scalable collection scans or hot-path algorithm changes.
Cmux Swift Concurrency ✅ Passed Diff only raises XCTest runProcess timeouts via a shared constant; no DispatchQueue, Combine, Task, or completion-handler patterns were introduced.
Cmux Swift @Concurrent ✅ Passed Touched Swift tests are synchronous throws tests only; no async/@Concurrent changes or UI-isolation hops were introduced.
Cmux Swift Package Boundaries ✅ Passed The diff only touches a test file and changes a timeout constant; no app-target domain logic or package-boundary issue is introduced.
Cmux Swiftpm Lockfiles ✅ Passed Diff only changes a Swift test file; no .gitignore, Package.resolved, workflow, or Xcode package-reference files were touched.
Cmux Swift Logging ✅ Passed Test-only timeout changes; no added print/debugPrint/dump/NSLog, ad hoc logging, or sensitive data exposure in the diff.
Cmux User-Facing Error Privacy ✅ Passed Only a test file changed; the rule allows tests/docs/developer-only comments, so there’s no production user-facing privacy violation.
Cmux Full Internationalization ✅ Passed Only a test file changed, with a timeout constant and developer comments; no user-facing Swift, web, catalog, or locale data was introduced.
Cmux Swiftui State Layout ✅ Passed The PR only changes a Swift test file and timeout constant; it introduces no SwiftUI state, layout, or render-time mutation code covered by the rule.
Cmux Architecture Rethink ✅ Passed Test-only timeout constant replaces hardcoded 5s in seven CLI-spawn tests; no sleeps, observers, split ownership, or other architectural anti-patterns introduced.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PR only changes a test file and adds a timeout constant; it introduces no NSWindow/NSPanel/NSWindowController/WindowGroup code or cmux.* window identifiers.
Cmux Source Artifacts ✅ Passed Only a test source file changed; it updates a timeout constant and adds rationale, with no generated or scratch artifacts in the diff.
Cmux No Test Or Debug Seam In Production Source ✅ Passed Only a test file under cmuxTests changed; no production Sources/ Swift code or new debug/test seam was introduced.
Cmux No Ambient Global State ✅ Passed PASS: the change is test-only and adds a private file-scope constant; no new top-level func, mutable var, namespace type, or singleton was introduced.
Title check ✅ Passed The title clearly and concisely describes the main change: replacing the CLI spawn timeout in cmuxTests.
Description check ✅ Passed The description follows the template and covers summary, testing, demo, review trigger, and checklist, with only a minor not-applicable note.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@greptile-apps

greptile-apps Bot commented Jul 24, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a load-sensitive flaky test by replacing hardcoded 5-second timeouts with a named constant set to 60 seconds in cmuxTests/CMUXCLISessionsListTranscriptPidTests.swift. No production code, behavioral assertions, or test logic is changed.

  • Introduces private let cliSpawnTimeout: TimeInterval = 60 with a detailed doc-comment explaining why the budget is intentionally generous (hang detection only, not speed grading), and replaces 7 timeout: 5 call sites in the same file.
  • The PR description correctly identifies 490 remaining hardcoded timeout: 5 sites across 30 copy-pasted helpers in the broader test suite and defers those to a follow-up change.

Confidence Score: 5/5

Safe to merge — the change is isolated to test scaffolding and makes existing flakiness-prone assertions more reliable without altering any behavior.

The only file touched is a test file under cmuxTests/. The constant is immutable (private let), well-documented, and replaces magic numbers at exactly the call sites that caused the reported flake. No production code, no logic changes, no new assertions added or removed.

Files Needing Attention: No files require special attention.

Important Files Changed

Filename Overview
cmuxTests/CMUXCLISessionsListTranscriptPidTests.swift Replaces 7 hardcoded timeout: 5 values with a named private let cliSpawnTimeout: TimeInterval = 60 constant; purely a test-flakiness fix with no behavioral or production-code changes.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Test calls runProcess] --> B{cliSpawnTimeout = 60s}
    B --> C[cmux binary spawns and emits JSON]
    C --> D{timedOut?}
    D -- No --> E[#expect status == 0, JSON parse, field checks]
    D -- Yes/hang --> F[Test fails: output truncated, assertions cannot pass]
    E --> G[Test passes]
Loading

Reviews (3): Last reviewed commit: "cmuxTests: stop grading the CLI spawn on..." | Re-trigger Greptile

@ejc3

ejc3 commented Jul 24, 2026

Copy link
Copy Markdown
Contributor Author

Build check came back FAILED with 7 errors — and none of them are from this change. All seven are main's own, the ones #8857 fixes:

Sources/ControlSurfaceResumeTarget.swift:282,283,284  .auto / .prompt / .manual cannot be resolved without a contextual type
Sources/DockSplitStore+RestoredAgentLifecycle.swift:13  cannot find type 'PanelShellActivityState' in scope
Sources/DockSplitStore+SessionSnapshot.swift:44,44,332  generic parameter 'Key' / 'Value' / 'U' could not be inferred

cmuxTests/CMUXCLISessionsListTranscriptPidTests.swift does not appear. This branch cannot be compiled in isolation because its base cannot be compiled, which is the same wall every open PR is behind right now.

Re-running the check with this stacked on #8857, since that is the only way to build anything today. Staying draft until that comes back green, then I will flip it with the result.

@ejc3
ejc3 marked this pull request as ready for review July 25, 2026 04:46
@ejc3

ejc3 commented Jul 25, 2026

Copy link
Copy Markdown
Contributor Author

Verified stacked on #8857 (the only way to compile anything until it lands):

** TEST BUILD SUCCEEDED **   errors=0   sha=26de379b86

build-for-testing with wholemodule, both targets. The earlier 7-error failure was measured on plain main and every error belonged to the base, none to this change. Flipping to ready.

testSessionsListTreatsTranscriptBackedClaudeRecordAsRestorable failed on a loaded
builder with:

  Expectation failed: !(result.timedOut)
  ProcessRunResult(status: 0, stdout: "{ ...complete sessions JSON... }", timedOut: true)

The command had succeeded. It exited 0 and emitted the full, correct JSON the rest of the
test then parses; it just took 6.0s against a 5s budget while sixty other suites were
running on the same machine. The same commit passed on an idle box, so the suite's verdict
was decided by machine load.

These cases fork the real cmux binary and wait for it to emit JSON, so their wall-clock
cost is a property of the host, not of the behaviour under test. The timeout is there to
catch a hang, and the assertions that follow each call already grade correctness: status,
then a JSON parse, then the field checks. A process killed at the deadline cannot satisfy
those, because its output is truncated.

So the budget moves to a named constant set far above any healthy run, with the reasoning
next to it. Same seven call sites, no behavioural assertions changed.

Note the rest of cmuxTests carries 490 more `timeout: 5` call sites across 30 separately
copy-pasted runProcess helpers. That is the same trap thirty times over and wants one
shared helper, but it is a refactor of its own rather than a rider on this fix.
@ejc3
ejc3 force-pushed the fix/cli-spawn-timeout-not-a-speed-gate branch from 43d5c96 to ed9cde1 Compare July 25, 2026 04:55
@cursor

cursor Bot commented Jul 25, 2026

Copy link
Copy Markdown

Bugbot is paused — on-demand spend limit reached

Bugbot uses usage-based billing for this team and has hit its on-demand spend limit.

A team admin can raise the spend limit in the Cursor dashboard, or wait for the next billing cycle to continue.

@austinywang

austinywang commented Jul 27, 2026 •

Copy link
Copy Markdown
Contributor

Updated the PR description to the required template and clarified that the timeout is a process liveness deadline, while status/JSON/field assertions independently grade correctness. The later review pass tightened the current value to 20 seconds; see the follow-up below. Re-requested review after merging current main:

@codex review
@coderabbitai review
@greptile-apps review
@cubic-dev-ai review

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@cubic-dev-ai

cubic-dev-ai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Updated the PR description to the required template and clarified that the 60-second value is a process liveness deadline, while status/JSON/field assertions independently grade correctness. Re-requesting review on the latest HEAD after merging current main:

@codex review
@coderabbitai review
@greptile-apps review
...

@austinywang I can't start this review because your workspace has reached its free monthly review limit. cubic has reviewed 241,631 of the 240,000 allowed lines of code this month. Reviews resume on 1 August 2026 (in 5 days). Paid plans include much higher monthly review limits. Upgrade now to resume reviews.

To help optimise your usage, you can tune cubic to get the most out of your usage limits:

Learn more →

@coderabbitai

coderabbitai Bot commented Jul 27, 2026 •

Copy link
Copy Markdown

@austinywang: Re-reviewing the latest HEAD with the clarified liveness-versus-correctness test contract.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@austinywang

Copy link
Copy Markdown
Contributor

Addressed the structured-review timeout concern on the latest HEAD: the shared liveness deadline is now 20 seconds (over 3× the observed loaded runtime), so every same-path invocation gets load headroom without allowing a serialized hang to stall for minutes. The touched test file is also back below 500 lines.

@codex review
@coderabbitai review
@greptile-apps review
@cubic-dev-ai review

@cubic-dev-ai

cubic-dev-ai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Addressed the structured-review timeout concern on the latest HEAD: the shared liveness deadline is now 20 seconds (over 3× the observed loaded runtime), so every same-path invocation gets load headroom without allowing a serialized hang to stall for minutes. The touched test file is also back below 500 lines.

@codex review
@coderabbitai review
@greptile-apps review
...

@austinywang I can't start this review because your workspace has reached its free monthly review limit. cubic has reviewed 241,631 of the 240,000 allowed lines of code this month. Reviews resume on 1 August 2026 (in 5 days). Paid plans include much higher monthly review limits. Upgrade now to resume reviews.

To help optimise your usage, you can tune cubic to get the most out of your usage limits:

Learn more →

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026 •

Copy link
Copy Markdown

@austinywang: Re-reviewing the latest HEAD, including the 20-second shared liveness deadline and the test-file size adjustment.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create a Codex account and connect to github.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026 •

Copy link
Copy Markdown

@austinywang: Re-reviewing the latest HEAD with the clarified liveness-versus-correctness test contract and the updated timeout rationale.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@austinywang
austinywang merged commit fe57d57 into manaflow-ai:main Jul 28, 2026
5 checks passed
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.

2 participants