Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
c9f0ec9
Update MapSelectionView.swift
dizzafizza Jul 14, 2026
07577f5
Create swift.yml
dizzafizza Jul 14, 2026
e380f63
Update build_ipa.yml
dizzafizza Jul 14, 2026
c3cda9f
Update build_ipa.yml
dizzafizza Jul 14, 2026
61f43e6
Update build_ipa.yml
dizzafizza Jul 14, 2026
7880604
Add speed profiles for route playback (walking/jogging/cycling/drivin…
Jul 14, 2026
69d7a1d
Fix build: return RouteSpeedContext, not [], in fetchRouteSpeedContext
Jul 14, 2026
f848bca
Add map style options to location simulator (satellite, hybrid, traff…
claude Jul 14, 2026
8ea835e
Show bus stops on the map in bus simulator mode
claude Jul 14, 2026
3e3fc5e
Catch bus stops mapped with the public_transport schema
claude Jul 14, 2026
984a94a
Speed up route preparation for long routes
claude Jul 14, 2026
656ec6d
Keep JIT/debug sessions alive when backgrounded and support cellular
claude Jul 14, 2026
84a5a5e
Add experimental "hold app alive in background" mode
claude Jul 14, 2026
abcc0cf
Fix build: convert packet.count to UInt for debug_proxy_send_raw
claude Jul 14, 2026
2ee7a0c
Fix cryptic error for pairing files missing required fields
claude Jul 14, 2026
2b56d47
Merge pull request #1 from dizzafizza/claude/error-investigation-n934o5
dizzafizza Jul 14, 2026
dad59fa
Revert "Fix cryptic error for pairing files missing required fields"
dizzafizza Jul 14, 2026
346bff6
Merge pull request #2 from dizzafizza/revert-1-claude/error-investiga…
dizzafizza Jul 14, 2026
7b1df35
Remove Swift Package CI workflow that can never pass
claude Jul 14, 2026
e11a606
Index long rural road segments instead of dropping them
claude Jul 14, 2026
b394334
Add fork code-review report
claude Jul 14, 2026
1e21c6a
Merge pull request #3 from dizzafizza/claude/fork-code-review-33fkom
dizzafizza Jul 14, 2026
5e8c4bd
Rename CODE_REVIEW_REPORT.md to CODE_REVIEW_REPORT_BY_FABLE_5.md
dizzafizza Jul 14, 2026
dcf7c6d
Load bus stops in chunks so long routes stop timing out
claude Jul 14, 2026
f81e666
Merge pull request #4 from dizzafizza/claude/fork-code-review-33fkom
dizzafizza Jul 14, 2026
a7792d0
Switch route data fetch from around() to bbox: fixes inconsistent bus…
claude Jul 15, 2026
15ca7d4
Merge pull request #5 from dizzafizza/claude/fork-code-review-33fkom
dizzafizza Jul 15, 2026
d2f09be
Honor "Hidden" points of interest for bus stops and declutter at low …
claude Jul 15, 2026
42951c6
Run the JIT script in hold-alive mode so attached apps get working JIT
claude Jul 15, 2026
5c3c37a
Merge pull request #6 from dizzafizza/claude/fork-code-review-33fkom
dizzafizza Jul 15, 2026
23e8052
Fix experimental keep-alive, wire it into "Other" tab, add Dynamic Is…
claude Jul 15, 2026
e4f0210
Remove widget extension, keep the keep-alive banner in-app only
claude Jul 15, 2026
12684b7
Merge pull request #7 from dizzafizza/claude/keep-alive-banner-fixes-…
dizzafizza Jul 15, 2026
67794a0
Fix keep-alive crash on non-JIT apps (e.g. Roblox)
claude Jul 15, 2026
b4c84c9
Merge pull request #8 from dizzafizza/claude/keep-alive-banner-fixes-…
dizzafizza Jul 15, 2026
04712e2
Keep held apps alive by actively servicing the debug connection
claude Jul 15, 2026
ffaf52a
Merge pull request #9 from dizzafizza/claude/keep-alive-banner-fixes-…
dizzafizza Jul 15, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion .github/workflows/build_ipa.yml
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ jobs:
- name: 2. Configure Xcode Environment
uses: maxim-lobanov/setup-xcode@v1
with:
xcode-version: '26.0.1'
xcode-version: '26.6.0'



- name: 3. Compile Project Archive
run: |
Expand All @@ -42,6 +44,7 @@ jobs:
SWIFT_OPTIMIZATION_LEVEL="-Onone" \
IPHONEOS_DEPLOYMENT_TARGET=17.4


- name: 4. Package .app into .ipa
run: |
cp -R build/StikDebug.xcarchive/Products/Applications/StikDebug.app .
Expand Down
151 changes: 151 additions & 0 deletions CODE_REVIEW_REPORT_BY_FABLE_5.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
# Fork Code-Review Report — StikDebug-PLUS

**Date:** 2026-07-14
**Branch reviewed:** `claude/fork-code-review-33fkom`
**Scope:** All fork-specific changes since divergence from upstream StikDebug (commit `c5b23e2`).

## Summary

The fork adds four feature areas on top of upstream StikDebug: a location-simulator
overhaul (speed profiles, bus stops, map styles, long-route performance), a
cellular/Wi-Fi network path monitor with tunnel auto-reconnect, background
keep-alive improvements for debug sessions, and an experimental "hold app alive
in background" mode. 15 files changed, ~1,400 lines added.

I reviewed the full diff against upstream, cross-checked every new FFI call
against `idevice.h`, traced the state machines in the changed managers, and
confirmed build status via GitHub Actions history. **Two genuine defects were
found and fixed; both are pushed to the review branch.** No crashes, compile
errors, or logic bugs remain in the reviewed code.

---

## Defects fixed

### 1. Always-failing CI workflow — `.github/workflows/swift.yml` (removed)

**Severity:** Medium (broken CI signal on every push/PR)

The workflow ran `swift build` / `swift test`, which require a `Package.swift`.
This repository is an Xcode app project with no Swift package, so the job failed
with `error: Could not find Package.swift` on **every run since it was added**,
marking each push and PR with a red ❌ check.

The existing **Build Debug IPA** workflow already compiles the project with
`xcodebuild` on the same `push`/`pull_request` triggers and passes green, so
build validation is fully covered without it.

- **Fix:** Deleted `swift.yml` (commit `7b1df35`).
- **Evidence:** GitHub Actions run `29341384965` (job `87113733956`) —
`Could not find Package.swift in this directory or any of its parent directories`.

### 2. Long rural road segments dropped from the speed index — `MapSelectionView.swift` (fixed)

**Severity:** Low (accuracy regression on long routes; no crash)

`RouteSpeedIndex` bucketed each OSM way segment into ~440 m grid cells, but
skipped any segment whose bounding box spanned more than **8 cells (~3.5 km)**:

```swift
guard maxX - minX <= 8, maxY - minY <= 8 else { continue }
```

Sparsely-noded rural highways can legitimately run tens of km between OSM
geometry nodes. Those segments were silently dropped from the index, so those
stretches lost their real speed limit and fell back to average-route pacing —
a behavior regression versus upstream, whose (slower) implementation scanned
every segment without this cap.

- **Fix:** Raised the guard to **128 cells (~57 km at the equator)** (commit
`e11a606`). This still catches genuinely broken data such as antimeridian
jumps (which span ~90,000 cells) while keeping realistic long segments
indexed. Per-segment registration stays bounded, and the `nearestWayThreshold`
(40 m) distance filter means indexing extra cells never produces false matches.

---

## Areas verified as correct (no change needed)

### Build / compilation
- **Build Debug IPA is green** on the fork tip (`346bff6`), confirming the app
compiles and that the `xcode-version: 26.6.0` pin resolves on the runner.
- `packet.count` is correctly converted to `UInt` for the `uintptr_t`
`debug_proxy_send_raw` parameter; `fetchRouteSpeedContext` returns a
`RouteSpeedContext` on all paths (both were prior build-fix commits and hold up).

### Experimental "hold app alive" / JIT keep-alive (`JITEnableContext`, `BackgroundAliveManager`, `DebugKeepAliveLease`)
- Every FFI call matches `idevice.h`: `process_control_launch_app` argument
order and `bool` flags, `process_control_disable_memory_limit`, and
`debug_proxy_send_raw(handle, ptr, uintptr_t)`.
- The hand-built RSP continue packet `$c#63` has the correct payload and
checksum (`0x63 % 256` → `63`), and is valid in no-ack mode.
- The hold sequence mirrors the proven `debugApp` path: drain acks →
`QStartNoAckMode` → disable ack mode → `vAttach` → continue → poll for
cancellation → interrupt (`0x03`) → detach (`D`).
- `HoldToken` is lock-guarded; `BackgroundAliveManager` balances start/stop and
its `stillCurrent` check prevents a late-finishing session from clobbering a
newer one. `DebugKeepAliveLease()` auto-activates in `init`, so the bare
construction in both `BackgroundAliveManager` and `HomeView` is correct.
- Background-task renewal re-checks `isActive` before re-arming, so an expiring
UIKit assertion no longer tears down long sessions.

### Background audio / location (`BackgroundAudioManager`, `BackgroundLocationManager`)
- The new `force:` (session) vs. unforced (user-toggle) activity counters are
balanced on every start/stop path and never go negative (`max(… - 1, 0)`).
- `refreshRunningState()` correctly honors forced holds regardless of the user's
keep-alive toggles, and `refreshFromSettings()` re-evaluates on toggle change.
- The non-zero silent-audio fill is inaudible (~-80 dBFS, DC-free) and guarded
by `!format.isInterleaved` with the correct channel/frame iteration; the
interleaved branch is an unreachable fallback on the standard mixer format.

### Network path monitor & tunnel reconnect (`NetworkPathMonitor`, `TunnelManager`)
- Path state is lock-guarded; change notifications are deduplicated by signature.
- Tunnel retry (3 attempts, 1s→2s backoff) correctly short-circuits on permanent
errors (invalid/expired/missing pairing `-9/-17`, bad target IP `-18`, parse
failures) instead of pointlessly retrying user-actionable failures.
- The reconnect observer is registered on the main queue, matching `start()`'s
main-thread expectation; the debounced work item cancels prior pending work.

### Location simulator — speed profiles, bus stops, map styles (`MapSelectionView`)
- The Overpass query moved from a bounding-box GET to a corridor `around` POST;
the body is percent-encoded with a form-safe character set and the client
timeout (30 s) exceeds the server timeout (25 s).
- `OverpassResponse.Element` decodes both way `geometry` and node `lat`/`lon`,
which `out tags geom;` emits for nodes — bus-stop parsing is sound.
- Bus-stop detection covers both the legacy `highway=bus_stop` and the modern
`public_transport=platform/stop_position` + `bus=yes` schemas.
- Route state (`routeBusStops`, `isImportedRoute`, `lastFallbackSpeed`,
`routeRequestID`) is reset consistently across import / clear / reset / refresh,
and every async prefetch guards on `routeRequestID` before applying results.
- Profile switching re-plans directions only when walking-vs-driving changes and
the route is searched (not imported); otherwise it rebuilds pacing in place.
- All SwiftUI/MapKit symbols are valid for the iOS 17.4 deployment target
(`MapStyle`, `PointOfInterestCategories`, `Marker`, `.mapStyle`).

---

## Minor observations (intentional trade-offs — not changed)

- **Bus ETA** in the route summary uses MapKit's automobile travel time and does
not add the per-stop dwell time, so a bus route's ETA is slightly optimistic.
- **Bus stop dwell** (12 s) is applied to the sample nearest the stop (≤25 m),
so playback pauses just before arriving rather than exactly at the stop.
- **`build_ipa.yml`** has two stray blank lines from an earlier edit; harmless
(YAML ignores them).
- **Bus-stop cell lookup** assumes non-polar latitudes (documented); above ~80°N
a 90 m search radius could exceed a longitude cell. Not reachable in practice.
- **`keepAppAlive`** blocks a global-queue thread for the hold duration and opens
multiple concurrent debug tunnels; acceptable for an explicitly experimental
feature, but worth revisiting if it graduates out of experimental.

---

## Commits on the review branch

| Commit | Change |
|--------|--------|
| `7b1df35` | Remove Swift Package CI workflow that can never pass |
| `e11a606` | Index long rural road segments instead of dropping them |

Both are pushed to `origin/claude/fork-code-review-33fkom`. The Build Debug IPA
workflow will validate compilation on the branch tip.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,8 @@ StikDebug enables **JIT** for sideloaded apps on iOS 17.4+ without needing a com

**Troubleshooting**
- "Connection dropped" or loopback errors → Check iOS version compatibility / beta warnings.
- Heartbeat errors → Ensure that the VPN is on and that you are connecected to Wi-Fi. It may be a pairing file issue.
- Heartbeat errors → Ensure that LocalDevVPN is on. Any network works (Wi-Fi **or** cellular); the tunnel rides the VPN, so cellular-only is supported. It may also be a pairing file issue.
- Session drops after switching to another app → Keep the background keep-alive enabled (Settings → Background Keep-Alive). While a JIT/debug session is active, StikDebug plays inaudible audio and holds a background assertion so the session survives being switched out of the app instead of timing out.
- Pairing file issues → Replace file with device unlocked & trusted.
- Still stuck? Join the [Discord](https://discord.gg/ZnNcrRT3M8) with logs/screenshots.

Expand Down
4 changes: 3 additions & 1 deletion StikDebug/App/AppBootstrapper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ enum AppBootstrapper {
registerDefaultSettings()
startConfiguredKeepAliveServices()
applyDocumentPickerCopyWorkaround()
NetworkPathMonitor.shared.start()
}

private static func registerDefaultSettings() {
Expand All @@ -23,7 +24,8 @@ enum AppBootstrapper {
UserDefaults.Keys.txmOverride: false,
UserDefaults.Keys.confirmExternalJITRequests: true,
"keepAliveAudio": true,
"keepAliveLocation": true
"keepAliveLocation": true,
"keepAppAliveBackground": false
])
}

Expand Down
Loading