/ios-qa and /ios-design-review first-run is broken at v1.45.0.0 (still on v1.46.0.0) — 7 reproducible bugs
- Dominant language
- TypeScript
- Stars
- 133k
- Forks
- 19.9k
- Avg merge
- 18h 46m
- Merged PRs (30d)
- 26
Description
# `/ios-qa` + `/ios-design-review` first-run is broken in v1.45.0.0 (still broken on v1.46.0.0)
**Update 2026-05-26 (post-v1.46.0.0):** Reproduced on v1.46.0.0. `ios-qa/SKILL.md` was modified by the catalog-trim work (frontmatter shrink, routing prose moved to `## When to invoke` body section), but the three broken Swift files were untouched: `ios-qa/scripts/gen-accessors-tool/Package.swift`, `ios-qa/templates/Package.swift.template`, and `ios-qa/templates/StateAccessor.swift.template`. All 7 issues below are reproducible on v1.46.0.0 with identical error output. Verified via:
```
cd ~/.claude/skills/gstack
git diff cf50443b..22f8c7f4 --stat ios-qa/scripts/gen-accessors-tool/Package.swift ios-qa/templates/Package.swift.template ios-qa/templates/StateAccessor.swift.template
# (no output — files unchanged across v1.45.0.0 → v1.46.0.0)
```
---
**gstack version:** 1.45.0.0 (originally hit) and 1.46.0.0 (re-verified)
**macOS / Xcode:** Xcode 26.5 / Swift 6.3.2
**Skill files affected:** `ios-qa/SKILL.md`, `ios-qa/scripts/gen-accessors-tool/Package.swift`, `ios-qa/templates/Package.swift.template`, `ios-qa/templates/StateAccessor.swift.template`
**Reporter context:** Solo dev, real iPhone 17 Pro Max connected via USB CoreDevice, fresh first-run after `/gstack-upgrade` (1.39.2.0 → 1.45.0.0).
## Summary
Attempted `/ios-design-review` cold-start. Hit 7 distinct issues in ~30 minutes before stopping. Several are blocking, several are misleading docs that cause wasted time. Net effect: the iOS QA family ships in a state where a first-time user cannot run it end-to-end without patching gstack itself.
## Bugs
### 1. SKILL.md describes an SPM dependency install; reality is template codegen
`ios-qa/SKILL.md` Phase 2 step 1 says:
> Add the `DebugBridge` SPM dependency to the app's `Package.swift`.
But there is no `DebugBridge` package published anywhere — no GitHub URL, no remote git ref. The actual install model is to render 8 `.template` files from `ios-qa/templates/` into the user's iOS repo as a LOCAL Swift package. The docs lead users to look for a remote dep that doesn't exist.
**Fix:** Replace "Add the SPM dependency" language with "Codegen the DebugBridge local Swift package into your iOS source tree from the shipped templates."
### 2. `gstack-ios-qa-daemon` has no `--help` flag — appears to hang
`~/.claude/skills/gstack/bin/gstack-ios-qa-daemon --help` starts the server (prints `READY: port=9099 pid=`) and runs indefinitely. Common first-thing-a-user-tries fails to exit, looks like the daemon is broken.
**Repro:**
```bash
~/.claude/skills/gstack/bin/gstack-ios-qa-daemon --help
# Hangs. Single-instance lock at ~/.gstack/ios-qa-daemon.pid is created.
```
**Fix:** Add `--help`/`-h` handling that prints usage and exits 0. Bonus: show the loopback port and the auth headers needed.
### 3. `gen-accessors-tool/Package.swift` declares testTarget without shipping the directory
`ios-qa/scripts/gen-accessors-tool/Package.swift:34-38`:
```swift
.testTarget(
name: "GenAccessorsTests",
dependencies: ["GenAccessors"],
path: "Tests/GenAccessorsTests"
),
```
The `Tests/GenAccessorsTests` directory does not exist in the shipped skill. SwiftPM rejects the manifest at parse time:
```
error: 'gen-accessors-tool': invalid custom path 'Tests/GenAccessorsTests' for target 'GenAccessorsTests'
```
This breaks the entire `/ios-qa` and `/ios-design-review` setup, since accessor codegen runs before everything else. `swift build --target GenAccessors` does not bypass the error — SwiftPM validates ALL target paths before building any.
**Fix:** Either ship a `Tests/GenAccessorsTests/` directory with a stub test, or remove the testTarget declaration from the shipped `Package.swift`.
### 4. `gen-accessors` emits `import DebugBridge` — that module does not exist
For projects with 0 `@Snapshotable`-marked fields (the default for any app that hasn't been instrumented yet), `gen-accessors` writes:
```swift
// AUTO-GENERATED — DO NOT EDIT. Regenerate with /ios-sync.
#if DEBUG
import Foundation
import DebugBridge
#endif
```
But `Package.swift.template` declares three products: `DebugBridgeCore`, `DebugBridgeUI`, `DebugBridgeTouch`. There is no umbrella `DebugBridge` module. The generated file fails to compile.
**Fix:** Either (a) add an umbrella `DebugBridge` library product that re-exports Core, or (b) change `gen-accessors` to emit `import DebugBridgeCore` (since StateServer lives in Core).
### 5. `Package.swift.template` has `swift-tools-version` on the wrong line
`ios-qa/templates/Package.swift.template` line 21:
```swift
// AUTO-GENERATED from gstack/ios-qa/templates/Package.swift.template
//
// Drop-in SPM package definition for the DebugBridge stack. ...
// ... (20-line comment header) ...
// swift-tools-version:5.9 ← line 21, not line 1
import PackageDescription
```
SwiftPM requires `// swift-tools-version:X.Y` as the literal first line of `Package.swift`. The shipped template fails:
```
error: 'debugbridge': the manifest is backward-incompatible with Swift < 6.0
because the tools-version was specified in a subsequent line of the
manifest, not the first line.
```
**Fix:** Move `// swift-tools-version:5.9` to line 1 of `Package.swift.template`. The comment header can follow.
### 6. `Package.swift.template` has the same testTarget-without-directory bug as #3
Same pattern as gen-accessors:
```swift
.testTarget(
name: "DebugBridgeCoreTests",
dependencies: ["DebugBridgeCore"],
path: "Tests/DebugBridgeCoreTests"
)
```
The codegen flow creates `Sources/DebugBridgeCore` etc., but the template doesn't tell users to ALSO create `Tests/DebugBridgeCoreTests/`. SwiftPM rejects with:
```
error: 'debugbridge': invalid custom path 'Tests/DebugBridgeCoreTests' for target 'DebugBridgeCoreTests'
```
**Fix:** Either ship a stub `Tests/DebugBridgeCoreTests/` test file in the codegen pipeline, or remove the testTarget from `Package.swift.template`.
### 7. `apps/web/.gitignore`-style guidance missing for the codegen output
Lower-priority observation: the SKILL.md doesn't mention that the codegen'd `DebugBridge/` directory in the user's repo (with ~10 new files) should be committed, gitignored, or otherwise discussed. For solo dev this is small; for teams it's confusing — should everyone codegen, or should one person commit and the rest pull?
**Fix:** Add a brief paragraph on how to handle the codegen output in source control, especially the `Sources/DebugBridgeCore/StateAccessor.swift` file that's user-source-dependent.
## What worked
For the record:
- `gstack-ios-qa-daemon` itself starts cleanly and responds to `/healthz` ✓
- The iOS Simulator (and `xcrun simctl io booted screenshot`) is a perfectly viable alternative for design-review-style work that only needs screenshots
- `xcrun devicectl list devices` correctly detected the paired iPhone 17 Pro Max
- The skill detection of `@Observable` classes worked (found three in Opzaco's source)
## Suggested fix priority
P0 (blocking first-run for everyone): #3, #5, #6
P1 (blocking once you get past P0): #4
P2 (docs / UX): #1, #2, #7
## Repro environment
- macOS (Xcode 26.5, Swift 6.3.2)
- pnpm 10.7.0
- Skill: gstack v1.45.0.0 (upgraded from v1.39.2.0)
- Project: solo dev, SwiftUI iOS app under XcodeGen (`project.yml`), three `@Observable` classes, no `@Snapshotable` fields, paired physical iPhone 17 Pro Max via USB CoreDevice, iOS Simulator iPhone 17 Pro also booted.
## Local patches applied during repro (NOT recommended as a real fix)
For documentation only — these were dead-end workarounds that hit additional bugs each time:
1. Copied `gen-accessors-tool` to `/tmp` and patched out the testTarget — let the tool build, but then it emitted broken `import DebugBridge` for 0-accessor case.
2. Codegen'd `apps/ios/DebugBridge/` from templates — Package.swift was unusable due to bugs #5 and #6 above.
Both directories should be considered scratch work, not real fixes.
Contributor guide
Assessment
This issue has not been assessed yet.