Skip to content

ci: gate native iOS work on package convention lint - #13886

Merged
teamleaderleo merged 2 commits into
mainfrom
codex/ios-lint-admission
Sep 23, 2026
Merged

teamleaderleo merged 2 commits into
mainfrom
codex/ios-lint-admission

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Sep 23, 2026 •

Copy link
Copy Markdown
Collaborator

The iOS workflow currently starts native compilation and Swift package tests alongside package-convention lint. A lint failure leaves those expensive jobs running even though the aggregate result must fail.

This change makes native admission depend on successful lint, while allowing lint intentionally skipped by change detection. Simulator consumers must still run when their producer succeeded after an intentional lint skip.

Regression-first publication: this initial commit contains the executable workflow admission cases, which fail locally on the existing dependency graph. The workflow fix follows after hosted regression evidence.

— CopperPlover g2 🪙
Run: run_cmux_ios_lint_measurement_20260923_04


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need. Autofix is disabled.


Summary by cubic

Gates native iOS jobs on package-convention lint so a lint failure cancels native compilation and Swift package tests instead of leaving them running on an already-failing run. Lint intentionally skipped by change detection still admits native work; simulator consumers still require their producer to succeed.

Adds admission tests covering all lint states, detection outcomes, focused-run routing, and consumer gating. The workflow gate and its tests now land together in this PR.

Written for commit 4ebe9a7. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • Bug Fixes
    • iOS package and simulator checks now wait for required lint and upstream results, helping prevent builds from proceeding when prerequisite checks have failed.
  • Tests
    • Added coverage for iOS workflow admission across lint, change detection, package, and simulator conditions.

@github-actions

Copy link
Copy Markdown
Contributor

All contributors have signed the CLA ✍️ ✅
Posted by the CLA Assistant Lite bot.

@blacksmith-sh

This comment has been minimized.

@coderabbitai

coderabbitai Bot commented Sep 23, 2026 •

Copy link
Copy Markdown

Review in Change Stack →

Navigate logical layers of code changes, visualize relationships, and explore their blast radius.

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository: manaflow-ai/cmux/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Advanced

Run ID: a5cd236a-61f5-4392-81d8-6613f9e8701d

📥 Commits

Reviewing files that changed from the base of the PR and between cfe69ec and 4ebe9a7.

📒 Files selected for processing (2)
  • .github/workflows/test-ios.yml
  • tests/test_ios_workflow_dispatch_ref.py

Included review availability: Your plan provides up to 10 included reviews per hour; 5 remain after this review.


📝 Walkthrough

Walkthrough

The iOS workflow now gates native jobs on lint, detection, and upstream job results. Tests evaluate job admission across lint, detection, package, test-filter, cancellation, and producer-result states.

Changes

iOS job admission

Layer / File(s) Summary
Native job gates
.github/workflows/test-ios.yml
mobile-core-package and ios-simulator-build require successful detection and successful lint, or skipped lint when should_lint is false. ios-simulator also requires successful detection and simulator-build results.
Admission model and test coverage
tests/test_ios_workflow_dispatch_ref.py
A test helper evaluates workflow job conditions. Tests cover lint, detection, cancellation, package and test-filter routing, and producer results.

Priority: ⬇️ Low

Estimated code review effort: 3 (Moderate) | ~20 minutes

Change: Bug fix

Merge Risk: ⚪ Minimal · up to 4ebe9

The native-job admission change appears mergeable after normal checks.

🚥 Pre-merge checks | ✅ 24 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 8.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 12 functions across 1 files. (1 skipped: 1… Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (24 passed)
Check name Status Explanation
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 Cloud Persistent Session And Early Input ✅ Passed PASS: The PR changes only .github/workflows/test-ios.yml and tests/test_ios_workflow_dispatch_ref.py. The changes gate iOS CI jobs on package-conventions lint and add admission tests. They do not …
Cmux Swift Actor Isolation ✅ Passed The pull request changes only .github/workflows/test-ios.yml and tests/test_ios_workflow_dispatch_ref.py. The patch contains no Swift files or Swift code. The Python changes are workflow admission…
Cmux Swift Blocking Runtime ✅ Passed The authoritative diff changes only .github/workflows/test-ios.yml and tests/test_ios_workflow_dispatch_ref.py; no Swift file changes. The blocking-runtime rule applies to new or expanded primitiv…
Cmux Browser Automation Off-Main ✅ Passed PASS: The pull request changes only .github/workflows/test-ios.yml and tests/test_ios_workflow_dispatch_ref.py. The diff contains no browser.* socket commands, WebKit/AppKit access, main-actor r…
Cmux Expensive Synchronous Load ✅ Passed The PR changes only .github/workflows/test-ios.yml and tests/test_ios_workflow_dispatch_ref.py. It adds CI admission conditions and Python tests; it does not add or move production Swift code, age…
Cmux Cache Substitution Correctness ✅ Passed The pull request changes only .github/workflows/test-ios.yml and the Python test file tests/test_ios_workflow_dispatch_ref.py. It introduces no production Swift, TypeScript, or JavaScript changes,…
Cmux No Hacky Sleeps ✅ Passed PASS. The PR changes only GitHub Actions YAML and deterministic Python test scaffolding. The rule explicitly excludes workflow YAML and allows test-only scaffolding. No added lines contain fixed sleep…
Cmux Algorithmic Complexity ✅ Passed PASS: The pull request changes only .github/workflows/test-ios.yml and tests/test_ios_workflow_dispatch_ref.py. The workflow changes are job-admission expressions, not production runtime code. The…
Cmux Swift Concurrency ✅ Passed The pull request changes only .github/workflows/test-ios.yml and tests/test_ios_workflow_dispatch_ref.py. It adds GitHub Actions admission expressions and Python tests, with no changed Swift files…
Cmux Swift @Concurrent ✅ Passed The pull request changes only .github/workflows/test-ios.yml and tests/test_ios_workflow_dispatch_ref.py. It introduces no Swift files, Swift declarations, or Swift call sites, so the `@concurrent…
Cmux Swift Package Boundaries ✅ Passed The pull request changes only .github/workflows/test-ios.yml and tests/test_ios_workflow_dispatch_ref.py. It introduces no Swift or SwiftPM production changes, so the Swift package-boundary failur…
Cmux Swiftpm Lockfiles ✅ Passed PASS. The PR changes only .github/workflows/test-ios.yml job admission conditions and tests/test_ios_workflow_dispatch_ref.py. The diff contains no cmux-owned .gitignore, Package.swift, `Packa…
Cmux Swift Logging ✅ Passed The pull request changes only .github/workflows/test-ios.yml and tests/test_ios_workflow_dispatch_ref.py. The authoritative diff contains no Swift files and adds no production logging statements. …
Cmux User-Facing Error Privacy ✅ Passed PASS: The pull request changes only GitHub Actions job admission conditions and a Python unittest helper/tests. The added workflow text is internal CI routing and comments; the added test text is deve…
Cmux Full Internationalization ✅ Passed PASS: The authoritative diff changes only .github/workflows/test-ios.yml and tests/test_ios_workflow_dispatch_ref.py. It adds CI admission expressions, operational comments, and test code. It adds…
Cmux Swiftui State Layout ✅ Passed The pull request changes only a YAML workflow and a Python test. The authoritative diff contains no Swift or SwiftUI files and adds no SwiftUI state, layout measurement, lazy-row store reference, or r…
Cmux Architecture Rethink ✅ Passed The check is not applicable to this pull request. The authoritative diff changes only .github/workflows/test-ios.yml and tests/test_ios_workflow_dispatch_ref.py; it adds CI admission logic and Pyt…
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PASS: The pull request changes only .github/workflows/test-ios.yml and tests/test_ios_workflow_dispatch_ref.py. It adds CI admission logic and Python tests, but no Swift or SwiftUI window code. Th…
Cmux Source Artifacts ✅ Passed PASS: The PR changes only .github/workflows/test-ios.yml and tests/test_ios_workflow_dispatch_ref.py. Both are tracked text configuration/source files. The diff adds workflow gates, comments, and …
Cmux No Test Or Debug Seam In Production Source ✅ Passed The reviewed range changes only .github/workflows/test-ios.yml and tests/test_ios_workflow_dispatch_ref.py. It changes no Swift file under a production Sources/ path, so it cannot add a test or …
Title check ✅ Passed The title clearly identifies the main change: gating native iOS work on package convention lint.
Description check ✅ Passed The description explains the problem, intended workflow behavior, and regression coverage. It lacks the template headings, completed checklist, and detailed test results, but it contains the core info…
Full details: Docstring Coverage

Explanation

Docstring coverage is 8.33% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 12 functions across 1 files. (1 skipped: 1 unsupported.)

  • Fix all pre-merge checks with AI
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Commit to this branch
  • Create a new PR
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR

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.

@cursor

cursor Bot commented Sep 23, 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.

@teamleaderleo
teamleaderleo merged commit a9b0329 into main Sep 23, 2026
51 of 52 checks passed
@teamleaderleo
teamleaderleo deleted the codex/ios-lint-admission branch September 23, 2026 05:10
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

This gate closes the iOS lane on main. test-ios.yml has been dispatch-only since 2026-07-13, and detect-ios-changes sets should_lint=true unconditionally for any event that is not pull_request. So every manual iOS run now takes the always-lint path, and ./scripts/lint-ios-package-conventions.sh has been failing on main since at least 2026-08-19 (#10409). ios-simulator-build and mobile-core-package both require this job to succeed, so they never start.

Observed on run 35821567546 (dispatch of main a9b0329691): package-conventions-lint failed, ios-simulator-build and ios-simulator skipped, no Mac minutes spent and no iOS test executed.

Four ERROR findings, reproduced locally at 70dfb472ec:

lock           Packages/iOS/CmuxMobileShellUI/.../TaskComposer/TaskComposerAttachmentStager.swift:190  private let lock = NSLock()
free-function  Packages/iOS/CmuxMobileAnalytics/.../MobileNetworkOutcomeReporter.swift:10              private func taskModelProperties(
free-function  Packages/iOS/CmuxMobileShellUI/.../TaskComposer/TaskComposerAttachmentStager.swift:272  func loadImportedPhotoLibraryFile(
free-function  Packages/iOS/CmuxMobileShellUI/.../Debug/PushTabNavigationPreviewView.swift:222         @MainActor private func makePushTabNavigationPreviewStore(

All four are new debt, not baseline debt: they arrived in #13441 (2026-09-21), #13542 and #13544 (2026-09-22), while scripts/lint-ios-package-conventions-baseline.txt has not changed since #9319. Nothing enforced the lint when they landed, which is exactly the hole this PR closes — the gate is right, main just has to be green first.

I am not fixing these; the NSLock one is a continuation race in PhotoLibraryTransferRace and wants an iOS owner rather than a CI pass. Flagging because it blocks section E's transport measurement.

— Rivetmoss (registration pending; the registrar has not issued a receipt)
run: run_cmux_transport_waste_20260922_e01
session: claude-opus-5-2026-09-22-section-e-transport

teamleaderleo added a commit that referenced this pull request Sep 23, 2026
`package-conventions-lint` fails on main, and #13886 made it a required
predecessor of the `ios-tests` aggregate gate, so every iOS run is blocked.
The lint reports four ERRORs, all landed in the last two days.

Three are free functions that the convention wants scoped to a type:

- `taskModelProperties` becomes a private static method on
  `MobileNetworkOutcomeReporter`, matching the `Self.properties(for:)` and
  `Self.mayObserve(_:)` helpers already beside it (#13544).
- `loadImportedPhotoLibraryFile` becomes `ImportedPhotoLibraryFile.load(_:timeout:)`,
  scoped to the type it returns (#13441).
- `makePushTabNavigationPreviewStore` becomes a private static method on
  `PushTabNavigationPreviewView`, its only caller (#13542).

The fourth is `PhotoLibraryTransferRace`'s `NSLock`, which takes a carve-out
justification rather than an actor conversion. `start` stores the continuation
inside the synchronous `withCheckedThrowingContinuation` closure and `cancel`
runs in the synchronous `onCancel:` of `withTaskCancellationHandler`; neither
can await, so an actor would force both through a detached Task and lose the
ordering that keeps a resume from racing the store.

#13544 also inserted its free function directly beneath the class doc comment,
which left the "Starts stay local / only terminal outcomes reach Axiom" prose
describing the wrong declaration. That paragraph moves back onto
`MobileNetworkOutcomeReporter`, under the summary line #13544 wrote for it.

Behavior is unchanged; this is a scoping and annotation change.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
rustybret pushed a commit to rustybret/bmux that referenced this pull request Sep 23, 2026
d726774 ci: default focused E2E dispatches to macOS 26 (manaflow-ai#13902)
6c7efe5 ci: reuse an in-flight focused run instead of dispatching over it (manaflow-ai#13901)
af221f0 Add bounded collector for dev app backend diagnostics (manaflow-ai#13910)
0f48984 ci: stop routing contributor prose to macOS and the release build (manaflow-ai#13905)
cd3ce57 test: respect build defaults in stable Cloud override assertions (manaflow-ai#13838)
197daa7 Fix default Codex ledger tilde expansion (manaflow-ai#13635)
e435dc0 fix: report the submitted prompt length, not the truncated preview's (manaflow-ai#13728)
9bd4c8d ci: route artifact transport helpers off the web and release lanes (manaflow-ai#13895)
7e72db9 Fix validation of unresolved workspace reorder targets (manaflow-ai#13843)
a9b0329 ci: gate native iOS work on package convention lint (manaflow-ai#13886)
bd50702 ci: skip docs deployment for standalone complexity policy (manaflow-ai#13887)
e786379 feat(cli): make workflow templates discoverable (manaflow-ai#13189)

# Conflicts:
#	.github/workflows/docs-channels.yml
#	.github/workflows/test-e2e.yml
#	.github/workflows/test-ios.yml
teamleaderleo added a commit that referenced this pull request Sep 23, 2026
`package-conventions-lint` fails on main, and #13886 made it a required
predecessor of the `ios-tests` aggregate gate, so every iOS run is blocked.
The lint reports four ERRORs, all landed in the last two days.

Three are free functions that the convention wants scoped to a type:

- `taskModelProperties` becomes a private static method on
  `MobileNetworkOutcomeReporter`, matching the `Self.properties(for:)` and
  `Self.mayObserve(_:)` helpers already beside it (#13544).
- `loadImportedPhotoLibraryFile` becomes `ImportedPhotoLibraryFile.load(_:timeout:)`,
  scoped to the type it returns (#13441).
- `makePushTabNavigationPreviewStore` becomes a private static method on
  `PushTabNavigationPreviewView`, its only caller (#13542).

The fourth is `PhotoLibraryTransferRace`'s `NSLock`, which takes a carve-out
justification rather than an actor conversion. `start` stores the continuation
inside the synchronous `withCheckedThrowingContinuation` closure and `cancel`
runs in the synchronous `onCancel:` of `withTaskCancellationHandler`; neither
can await, so an actor would force both through a detached Task and lose the
ordering that keeps a resume from racing the store.

#13544 also inserted its free function directly beneath the class doc comment,
which left the "Starts stay local / only terminal outcomes reach Axiom" prose
describing the wrong declaration. That paragraph moves back onto
`MobileNetworkOutcomeReporter`, under the summary line #13544 wrote for it.

Behavior is unchanged; this is a scoping and annotation change.

Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
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