fix(ios): delegated task threads open with literal percent IDs#23547
Problem
In the SwiftUI app, tapping a completed delegated task in the Agents sheet fails with thread_not_found. Delegated thread IDs contain literal percent escapes; the Swift client escapes the path a second time, so the host looks up a different ID.
Change
Build environment request URLs with an explicitly percent-encoded path helper. Keep the plain-path helper for discovery, pairing, and route probes. Add a regression assertion on the outgoing bounded snapshot URL for a delegated thread ID containing %3A.
Scope and approval
Fixes #17643
Triaged bug via the automated issue flow. Targets t3code/rebuild-mobile-app-swift, which owns the native SwiftUI client.
Verification
- Real main server at
8d3b061121, isolated synthetic thread projection: the single-encoded bounded request returned HTTP 200 with the original thread ID; the double-encoded request returned HTTP 404thread_not_found. Runtime transcript. - Added
V2OrchestrationClientTests.testThreadReadEncodesLiteralPercentInThreadIDOncein the existing transport test file. Swift tests were not executed: Linux has no Swift compiler or Xcode. No claim of an observed red or green XCTest result. git diff --checkpassed. Two independent reviews (gpt-6.1-sol and claude-opus-5-5) returned MERGE with no confirmed code findings.- No UI rendering code changes. Fixture matrix and evidence index explicitly list the unverified Swift/native rows. Native before/after captures, recordings, visual diffs, and “what else changed” are unavailable; the host transcript does not substitute for them.
| Evidence | Before | After | Diff0 | DiffT |
|---|---|---|---|---|
| Native SwiftUI interaction and static rows | Not captured (4619c0bca6) | Not captured (f8dadbc5f6) | Unavailable | Unavailable |
cannot-verify ios-swift: native build, focused XCTest execution, and opening the delegated child on an Apple runtime remain for Mac verification.
Models: gpt-6.1-sol and claude-opus-5-5. Harnesses: Codex and Claude Agent via T3 Code.
Fixes pingdotgg/t3code#17643
Checks
Failing4
- CheckGitHubFailed
- Failed
- Release SmokeGitHubFailed
- Test Server 3GitHubFailed
Added 2 commits
Approvability
Verdict: Approved at f8dadbc
Macroscope's review found this PR approvable — This is a narrowly scoped iOS URL-encoding fix that preserves percent-encoded delegated-task thread IDs and adds a focused regression test. Existing static API routes and query behavior remain unchanged.
No code changes detected at 58eb305. Prior analysis still applies.
You can add or adjust custom eligibility rules. Learn more.
Thread transfer impact
✅ Thread transfer remains within every enforced ceiling.
ℹ️ No successful
mainbaseline artifact is available yet. This run establishes the initial measurement.
| Provider | Metric | Main baseline | This PR | Impact | PR ceiling | |
|---|---|---|---|---|---|---|
| Codex | Total thread wire | — | 5.0 KiB | — | 6.8 KiB | ✅ |
| Codex | Thread snapshot wire | — | 3.8 KiB | — | 4.9 KiB | ✅ |
| Codex | Live turn WebSocket wire | — | 1.2 KiB | — | 2.0 KiB | ✅ |
| Codex | Live turn WebSocket decoded | — | 20.9 KiB | — | 29.3 KiB | ✅ |
| Codex | Live turn messages | — | 2 | — | 8 | ✅ |
| Claude | Total thread wire | — | 5.0 KiB | — | 6.8 KiB | ✅ |
| Claude | Thread snapshot wire | — | 3.8 KiB | — | 4.9 KiB | ✅ |
| Claude | Live turn WebSocket wire | — | 1.2 KiB | — | 2.0 KiB | ✅ |
| Claude | Live turn WebSocket decoded | — | 21.2 KiB | — | 29.3 KiB | ✅ |
| Claude | Live turn messages | — | 2 | — | 8 | ✅ |
Baseline: unavailable · PR result: 58eb305 · Source CI: failure
Scenario and decoded snapshot size
10 historical turns, 5 command tools per turn, 878.9 KiB retained MCP result per historical turn, and a 1.05 MiB retained result in the measured turn.
- Codex decoded thread snapshot: 108.5 KiB
- Claude decoded thread snapshot: 108.8 KiB
Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.
Added 1 commit
- Merge remote-tracking branch 'origin/t3code/rebuild-mobile-app-swift' into fix/issue-1764358eb305
The automated pipeline stopped on this pull request and will not merge it:
these checks fail on 58eb305768, also when run again: Release Smoke, Contract fixtures and native tests, and the rework changed nothing:
No change pushed. The item's premise does not hold for this PR: #23547 targets t3code/rebuild-mobile-app-swift, not main, and that branch is 3,670 commits behind origin/main, so merging main would put the whole divergence into a 23-line fix's diff. Both failing checks come from the base branch, not the fix (which touches only apps/swift-ios/Core/HTTP.swift and DualOrchestrationClientTests.swift). Contract fixtures and native tests: the iOS build fails in apps/swift-ios/Features/Chat/FeatureThreadToolsToolbar.swift (no member 'visibilityPriority', 'toolbarMinimizationBehavior' on the runner's Xcode). That file is identical to base tip f021c92cc9, the job lives in swift-ios.yml which exists only on the Swift branch, and main has no apps/swift-ios, so main cannot have fixed it. Release Smoke: vp install --lockfile-only fails with ERR_PNPM_UNUSED_PATCH for node-pty@1.2.0-beta.15 and @expo/fingerprint@0.21.5 in the base branch's patchedDependencies. Both need fixing on t3code/rebuild-mobile-app-swift (newer Xcode on CI or availability guards; remove the unused patches). The fix's native test remains unverified until the base compiles.
It stays open for a person to finish or close.