Skip to content

fix(ios): unbreak the iOS build (pbxproj id collision) + gate it in CI#277

Merged
haowei2000 merged 3 commits into
developfrom
fix/ios-pbxproj-id-collision
Jul 20, 2026
Merged

fix(ios): unbreak the iOS build (pbxproj id collision) + gate it in CI#277
haowei2000 merged 3 commits into
developfrom
fix/ios-pbxproj-id-collision

Conversation

@haowei2000

Copy link
Copy Markdown
Collaborator

The bug

develop does not build for iOS. xcodebuild fails with:

AppModel.swift:36: error: cannot find 'ChatModelStore' in scope

...for a file that is on disk and has all four of its project.pbxproj entries.

ChatModelStore.swift and WorkbenchSheet.swift share the same object ids
(…0124 PBXFileReference, …0223 PBXBuildFile). They arrived from two parallel
branches — claude/channel-initial-load-perf and
claude/ios-workbench-plugin-feasibility — that each hand-picked "the next"
sequential id off the same base, and the merge kept both. Xcode dedupes by id,
WorkbenchSheet won, and ChatModelStore was dropped from Compile Sources. The only
clue was an easily-missed warning: Skipping duplicate build file.

This is currently included in #276 (develop → main).

The fix

Reassign ChatModelStore to unused ids (…0126 / …0225). Four lines.

Why CI missed it

Nothing in CI compiled iOS at allapps/ios/** was in no path filter and had
no job. The app stopped building and every gate stayed green.

  • ios-build (macos-14) — builds against a generic simulator destination with
    CODE_SIGNING_ALLOWED=NO, so a real compile gates every apps/ios change with no
    signing certs or provisioning profile needed in CI.
  • scripts/check-pbxproj.py — runs first in that job. Flags duplicate object
    ids, Swift files on disk missing from Compile Sources, and dangling references.
    xcodebuild catches the same class of bug, but minutes later and pointing at an
    unrelated file; this names both colliding files in a second.
  • gateway cargo fmt --check — the other Rust crates gate on fmt and CLAUDE.md
    tells contributors to run it, but gateway-check never did. 7 hunks of drift
    across 4 files, formatted here.

Verification

  • xcodebuild … buildBUILD SUCCEEDED, duplicate warning gone
  • Installed and ran on a real iPhone 17
  • The exact CI simulator command run locally → BUILD SUCCEEDED
  • Guard replayed against the pre-fix pbxproj → flags both ids, exits 1; against the fixed one → passes
  • cargo fmt --check and cargo check clean in server/

🤖 Generated with Claude Code

haowei2000 and others added 3 commits July 20, 2026 10:50
ChatModelStore.swift and WorkbenchSheet.swift shared the same PBXFileReference
(...0124) and PBXBuildFile (...0223) ids: they landed from two parallel branches
(claude/channel-initial-load-perf and claude/ios-workbench-plugin-feasibility)
that each hand-picked "the next" sequential id off the same base, and the merge
kept both.

Xcode dedupes by id, so ChatModelStore lost and was dropped from the compile
list — even though the file was on disk with all four pbxproj entries present.
The build failed at AppModel.swift:36 with `cannot find 'ChatModelStore' in
scope`, and the only clue was a "Skipping duplicate build file" warning.

Reassign ChatModelStore to unused ids (...0126 / ...0225). Verified: the
duplicate warning is gone, BUILD SUCCEEDED, and the app installs and runs on
device.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Nothing in CI compiled iOS, so the pbxproj id collision fixed in the previous
commit broke develop unnoticed — the app stopped building and every gate stayed
green. Three additions, all motivated by that miss:

- ios-build (macos-14): builds the app for a generic simulator destination with
  CODE_SIGNING_ALLOWED=NO, so a real compile gates every apps/ios change without
  signing certs or a provisioning profile in CI.
- scripts/check-pbxproj.py: runs first in that job. Catches duplicate object ids,
  Swift files on disk that are missing from Compile Sources, and references to
  files that no longer exist. xcodebuild would catch the same class of problem,
  but minutes later and pointing at whichever unrelated file used the dropped
  symbol; this names the two colliding files in a second. Verified against the
  broken pbxproj: it flags both ids and exits 1.
- gateway-check now runs `cargo fmt --check`. The other Rust crates already gate
  on fmt and CLAUDE.md tells contributors to run it, but the gateway had no such
  step, so drift accumulated (7 hunks across 4 files, formatted here).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The first run of the new job failed on the runner's default Xcode 15.4
(Swift 5.10): `unknown attribute 'retroactive'` in ShellComponents.swift, plus
"call to main actor-isolated initializer in a synchronous nonisolated context"
in AppShellView/AgentsView. Both are Swift 6 features the sources already rely
on — the code is fine, the CI toolchain was years behind what the project is
developed against (Xcode 26.6 locally).

Move to macos-15 and xcode-select the newest Xcode on the image rather than
pinning a version, which would only need bumping again at the next image
refresh. The chosen version is printed so the next toolchain drift is legible
in the log instead of surfacing as mystery syntax errors.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@haowei2000
haowei2000 merged commit 579f3db into develop Jul 20, 2026
14 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.

1 participant