Skip to content

fix(mobile): an expired Live Activity no longer leaves a second card - #15254

Merged
juliusmarminge merged 1 commit into
mainfrom
t3code/live-activity-duplicate-cards
Oct 3, 2026
Merged

juliusmarminge merged 1 commit into
mainfrom
t3code/live-activity-duplicate-cards

Conversation

@juliusmarminge

@juliusmarminge juliusmarminge commented Oct 3, 2026 •

Copy link
Copy Markdown
Member

iOS ends a Live Activity 8 hours after it starts but keeps the ended card on the Lock Screen for up to 4 more hours. expo-widgets' getInstances() only returns active and stale cards (expo/expo#48489), so our app thought no card was showing and started a fresh one. That left two cards stacked: a frozen "Agent status out of date" card and the live one.

The fix extends our existing expo-widgets@58.0.11 patch: LiveActivityFactory.start() now dismisses this factory's ended activities (end(nil, dismissalPolicy: .immediate)) before requesting a new one. Every way the app starts a card (sending from the phone, foreground priming, showcase) goes through start(), so this one change covers all of them. The relay and the widget layout are unchanged, and Android doesn't use this code.

Verification

iOS 27 simulator, T3 Code Dev built from this patch. I started card A and ended it with default dismissal, which leaves it ended but still on screen with getInstances() returning 0, like a card after the 8-hour limit. Then I started card B.

Before: card A has ended but is still on the Lock Screen After: card B started, card A is gone
Before: ended card A still on the Lock Screen After: only card B on the Lock Screen

In the liveactivitiesd log, card A sat ended ("zombie") for about 45 seconds, then was ended by our app and removed ("discarded") at the same moment card B started. I didn't wait for a real 8-hour expiry.

Shipping: this needs a store build, and OTAs won't know

Expo's fingerprint doesn't include our root patches/ directory. It only hashes apps/mobile/patches plus each package's package.json. This change leaves the production fingerprint unchanged (509325fd…, the same as iOS 2.0.0 build 104), so:

  • The Mobile Fingerprint Check won't add the 📱 Native Change label.
  • The production workflow will publish this merge's JS as an OTA to 2.0.0 binaries that don't contain the fix. The JS still works on them, so nothing breaks.
  • Users get the fix only from the next production store build. Under the current workflow that only happens after a version bump (or a manual dispatch).

Fixing fingerprint coverage of root patches is a separate change.

🤖 Generated with Claude Code, Claude Opus 5.5 in T3 Code


Devin Review

iOS ends every Live Activity 8 hours after it starts but keeps the ended
card on the Lock Screen for up to 4 more hours. expo-widgets'
getInstances() hides ended cards, so the app thought none was showing and
started a new one, leaving a frozen "Agent status out of date" card next
to the live one.

LiveActivityFactory.start() now dismisses this factory's ended activities
before requesting a new one.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot added vouch:trusted PR author is trusted by repo permissions or the VOUCHED list. size:M 30-99 changed lines (additions + deletions). labels Oct 3, 2026
@juliusmarminge juliusmarminge added the macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews label Oct 3, 2026
@macroscopeapp

macroscopeapp Bot commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Approved at 910c9b8

Macroscope's review found this PR approvable — This is a focused iOS Live Activity bug fix that dismisses matching ended cards before starting a replacement, while the lockfile change only activates the updated dependency patch. The change is small, isolated, and has no product-default, schema, security, or deployment-infrastructure impact.

You can add or adjust custom eligibility rules. Learn more.

@github-actions

github-actions Bot commented Oct 3, 2026

Copy link
Copy Markdown
Contributor

Thread transfer impact

✅ Thread transfer remains within every enforced ceiling.

Provider Metric Main baseline This PR Impact PR ceiling
Codex Total thread wire 4.9 KiB 4.9 KiB 0 B (0.0%) 6.8 KiB ✅
Codex Thread snapshot wire 3.7 KiB 3.7 KiB 0 B (0.0%) 4.9 KiB ✅
Codex Live turn WebSocket wire 1.1 KiB 1.1 KiB 0 B (0.0%) 2.0 KiB ✅
Codex Live turn WebSocket decoded 20.4 KiB 20.4 KiB 0 B (0.0%) 29.3 KiB ✅
Codex Live turn messages 1 1 0 (0.0%) 8 ✅
Claude Total thread wire 4.9 KiB 4.9 KiB −41 B (−0.8%) 6.8 KiB ✅
Claude Thread snapshot wire 3.7 KiB 3.7 KiB 0 B (0.0%) 4.9 KiB ✅
Claude Live turn WebSocket wire 1.2 KiB 1.2 KiB −41 B (−3.4%) 2.0 KiB ✅
Claude Live turn WebSocket decoded 20.8 KiB 20.7 KiB −41 B (−0.2%) 29.3 KiB ✅
Claude Live turn messages 2 1 −1 (−50.0%) 8 ✅

Baseline: 65731f9 · PR result: 910c9b8 · Source CI: success

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: 106.1 KiB
  • Claude decoded thread snapshot: 106.4 KiB

Updated in place by a trusted workflow. PR artifacts are strictly validated and never executed.

@coderabbitai

coderabbitai Bot commented Oct 3, 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: pingdotgg/t3code/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Team
  • Run ID: 33faa98f-f698-4385-9841-8d0818a7e5f2
📥 Commits

Reviewing files that changed from the base of the PR and between 65731f9 and 910c9b8.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (1)
  • patches/expo-widgets@58.0.11.patch

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 6 remain after this review.


📝 Walkthrough

Walkthrough

The patch updates Live Activity environment properties and view construction, adds cleanup of matching ended activities before a new activity starts, and changes the layout-registry script’s direct-execution check to compare resolved paths.

Changes

Live Activity Updates

Layer / File(s) Summary
Live Activity environment and view rendering
patches/expo-widgets@58.0.11.patch
LiveActivityEnvironment adds optional widgetRenderingMode and isLiquidGlassAvailable properties. Live Activity views resolve nodes using their own rendering environments.
Dismiss matching ended activities
patches/expo-widgets@58.0.11.patch
Before requesting a named activity, LiveActivityFactory schedules immediate dismissal of matching activities in the .ended state.

Layout Registry Execution Check

Layer / File(s) Summary
Resolve paths for direct-execution check
patches/expo-widgets@58.0.11.patch
The layout-registry script compares resolved real paths in its direct-execution check.

Priority: ➖ Normal

Estimated code review effort: 2 (Simple) | ~15 minutes

Change: Bug fix

Merge Risk: 🔵 Low · up to 910c9

Starting a replacement may briefly show two cards, but the old card should be removed. This is a bounded risk rather than a merge blocker.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description explains the problem, the change, and focused verification. It does not include the required Scope and approval section or state that the focused fix qualifies without prior approval. Add a Scope and approval section. Link the triaged issue or maintainer approval, or explain why this is a small, focused fix of an obvious bug that does not need prior approval.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the primary change: preventing an ended Live Activity from remaining alongside a newly started card.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check. Docstring coverage is scoped to functions touched by this diff. Analyzed 0 functions across 0…
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.
  • Fix all pre-merge checks with AI
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Commit to this branch
  • Create a new PR
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

@juliusmarminge
juliusmarminge merged commit 77823bd into main Oct 3, 2026
32 of 33 checks passed
@juliusmarminge
juliusmarminge deleted the t3code/live-activity-duplicate-cards branch October 3, 2026 17:24
github-actions Bot added a commit to omarcresp/t3code-flake that referenced this pull request Oct 3, 2026
## What's Changed
* fix(mobile): iOS threads no longer jump to the top by @znoraka in pingdotgg/t3code#14808
* fix(web): reduce the gap above the draft composer by @Bil0000 in pingdotgg/t3code#15196
* fix(mobile): a dev server left running no longer shows the waiting bolt by @jakeleventhal in pingdotgg/t3code#15194
* fix(server): a Claude command you stop shows as interrupted by @SunkenInTime in pingdotgg/t3code#14896
* fix(server): editors appear once a slow discovery scan finishes by @bfowler in pingdotgg/t3code#13917
* fix(server): Claude threads no longer stay stuck in plan mode Claude entered itself by @juliusmarminge in pingdotgg/t3code#15224
* fix(mobile): show complete subagent details by @jakeleventhal in pingdotgg/t3code#15189
* fix(mobile): an expired Live Activity no longer leaves a second card by @juliusmarminge in pingdotgg/t3code#15254
* test(web): remove redundant thread sort fallback tests by @t3-code[bot] in pingdotgg/t3code#15095
* fix(web): thinking row after a failed tool expands the run's tool calls by @maria-rcks in pingdotgg/t3code#15056
* perf(web): DOM changes no longer restyle the whole page by @flamboh in pingdotgg/t3code#15265
* perf(usage): cut warm usage scans from seconds to milliseconds on large histories by @t3dotgg in pingdotgg/t3code#15149
* perf(web): virtualize command palette results by @flamboh in pingdotgg/t3code#15266
* chore(lint): flag :has() variants that restyle the whole page by @flamboh in pingdotgg/t3code#15274
* fix(web): workspace card docks beside chat when the window is narrow by @t3dotgg in pingdotgg/t3code#14992
* feat(web): render mermaid code blocks as diagrams by @maria-rcks in pingdotgg/t3code#15067

## New Contributors
* @znoraka made their first contribution in pingdotgg/t3code#14808

**Full Changelog**: pingdotgg/t3code@v0.0.46-nightly.20261003.2632...v0.0.46-nightly.20261003.2638

Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.46-nightly.20261003.2638
github-actions Bot added a commit to davidvanderklay/t3code-flake that referenced this pull request Oct 3, 2026
## What's Changed
* fix(mobile): iOS threads no longer jump to the top by @znoraka in pingdotgg/t3code#14808
* fix(web): reduce the gap above the draft composer by @Bil0000 in pingdotgg/t3code#15196
* fix(mobile): a dev server left running no longer shows the waiting bolt by @jakeleventhal in pingdotgg/t3code#15194
* fix(server): a Claude command you stop shows as interrupted by @SunkenInTime in pingdotgg/t3code#14896
* fix(server): editors appear once a slow discovery scan finishes by @bfowler in pingdotgg/t3code#13917
* fix(server): Claude threads no longer stay stuck in plan mode Claude entered itself by @juliusmarminge in pingdotgg/t3code#15224
* fix(mobile): show complete subagent details by @jakeleventhal in pingdotgg/t3code#15189
* fix(mobile): an expired Live Activity no longer leaves a second card by @juliusmarminge in pingdotgg/t3code#15254
* test(web): remove redundant thread sort fallback tests by @t3-code[bot] in pingdotgg/t3code#15095
* fix(web): thinking row after a failed tool expands the run's tool calls by @maria-rcks in pingdotgg/t3code#15056
* perf(web): DOM changes no longer restyle the whole page by @flamboh in pingdotgg/t3code#15265
* perf(usage): cut warm usage scans from seconds to milliseconds on large histories by @t3dotgg in pingdotgg/t3code#15149
* perf(web): virtualize command palette results by @flamboh in pingdotgg/t3code#15266
* chore(lint): flag :has() variants that restyle the whole page by @flamboh in pingdotgg/t3code#15274
* fix(web): workspace card docks beside chat when the window is narrow by @t3dotgg in pingdotgg/t3code#14992
* feat(web): render mermaid code blocks as diagrams by @maria-rcks in pingdotgg/t3code#15067

## New Contributors
* @znoraka made their first contribution in pingdotgg/t3code#14808

**Full Changelog**: pingdotgg/t3code@v0.0.46-nightly.20261003.2632...v0.0.46-nightly.20261003.2638

Upstream release: https://github.com/pingdotgg/t3code/releases/tag/v0.0.46-nightly.20261003.2638
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews size:M 30-99 changed lines (additions + deletions). vouch:trusted PR author is trusted by repo permissions or the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant