Skip to content

fix: persist queued iOS watch replies#100031

Closed
NianJiuZst wants to merge 0 commit into
openclaw:mainfrom
NianJiuZst:codex/fix-ios-watch-reply-persistence
Closed

fix: persist queued iOS watch replies#100031
NianJiuZst wants to merge 0 commit into
openclaw:mainfrom
NianJiuZst:codex/fix-ios-watch-reply-persistence

Conversation

@NianJiuZst

@NianJiuZst NianJiuZst commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

What Problem This Solves

iOS accepted Apple Watch quick replies into memory and could lose them if the app was suspended or terminated before delivery. Replies also lacked a durable source-gateway binding, so reconnects and gateway switches could route stale actions incorrectly.

Why This Change Was Made

Watch chat messages and quick replies now share one durable, gateway-scoped outbox. Every accepted message is persisted before network delivery, uses its stable command/reply ID as the chat.send idempotency key, retries bounded transient failures, and is removed only after acknowledged success or a permanent invalid request.

The notification payload carries its source gateway through watchOS and mirrored iOS actions. Persisted prompt-to-gateway routes support released Watch builds that omit the new field; unresolved legacy prompts are dropped instead of guessed. Bounded delivered-message tombstones persist across iPhone restarts so delayed WatchConnectivity fallbacks stay deduplicated.

User Impact

Watch replies survive offline periods, process restarts, and transient gateway failures without creating duplicate agent turns. Replies cannot cross to a newly selected gateway, while older Watch app versions remain compatible for prompts created by the updated iPhone app.

Evidence

  • xcrun swiftc -parse across all changed iOS and watchOS Swift files
  • swiftformat --lint --config config/swiftformat across changed app sources
  • Fresh Codex autoreview: no accepted/actionable findings
  • Sanitized AWS Crabbox exact-head run run_3afe370a8d62: pnpm native:i18n:check and pnpm check:changed passed
  • GitHub iOS/macOS build and Swift checks run against exact head b18c5af174717e965ce0ee13d9ce6f90ec81a55c

@clawsweeper

clawsweeper Bot commented Jul 4, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed July 5, 2026, 11:44 AM ET / 15:44 UTC.

Summary
The branch replaces in-memory iOS Watch quick-reply handling with a persisted gateway-scoped Watch message outbox, source-gateway routing metadata, retry/dedupe behavior, Watch payload plumbing, tests, generated native strings, and release-note/rebase artifacts.

Reproducibility: yes. from source inspection. Current main accepts Watch quick replies into process-local arrays in WatchReplyCoordinator, so queued replies and dedupe state can be lost if the iOS process is suspended or terminated before delivery; I did not run a physical Apple Watch reproduction.

Review metrics: 3 noteworthy metrics.

  • Persistent Watch storage surfaces: 1 existing queue key reused, 1 metadata key added. The outbox changes restart and upgrade behavior, so old queued Watch chat rows and new reply tombstones/routes need proof before merge.
  • Live mergeability: 1 conflicting PR head. The final merged code is not represented by prior proof until conflicts are resolved and exact-head validation reruns.
  • Current-main preservation: 1 QA-lab serialization fix absent from head. Conflict resolution must keep the latest channel-driver isolated worker serialization so QA smoke checks do not regain the known concurrency flake.

Stored data model
Persistent data-model change detected: migration/backfill/repair: CHANGELOG.md, migration/backfill/repair: apps/.i18n/native/ar.json, migration/backfill/repair: apps/.i18n/native/de.json, migration/backfill/repair: apps/.i18n/native/es.json, migration/backfill/repair: apps/.i18n/native/fa.json, migration/backfill/repair: apps/.i18n/native/fr.json, and 22 more. Confirm migration or upgrade compatibility proof before merge.

Merge readiness
Overall: 🦪 silver shellfish
Proof: 🦪 silver shellfish
Patch quality: 🦪 silver shellfish
Result: blocked until real behavior proof is added.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • Resolve the current-main conflicts while preserving the QA-lab channel-driver isolated worker serialization.
  • [P1] Add redacted Apple Watch or WatchConnectivity logs, terminal output, recording, or linked artifact showing queued reply persistence and gateway-scoped delivery.
  • Remove the normal-PR CHANGELOG.md edit and keep release-note context in the PR body or squash message.

Proof guidance:

  • [P1] Needs real behavior proof before merge: The PR body and maintainer comment provide parse, lint, CI, and Testbox output, but no real Apple Watch or WatchConnectivity after-fix run; redacted device logs, terminal output, screenshots/video, a linked artifact, or a reproducible live transcript should show the fixed queued-reply path before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.

Mantis proof suggestion
A real iOS Watch or WatchConnectivity visual/diagnostic run would materially prove the user-visible delivery behavior that CI cannot show. A maintainer can ask Mantis to capture proof by posting this exact PR comment:

@openclaw-mantis visual task: verify iOS Apple Watch quick replies survive reconnect/restart and do not duplicate or switch gateways, with private details redacted.

Risk before merge

  • [P1] The live PR is CONFLICTING/DIRTY, so prior exact-head proof does not represent the final merge result until conflicts are resolved and validation reruns.
  • [P1] No real Apple Watch or WatchConnectivity after-fix run is present; current proof is parse, lint, CI, and Testbox output only.
  • [P1] The change owns durable Watch outbox metadata, delivered tombstones, retry behavior, and source-gateway binding, so a bad merge resolution can lose, duplicate, or misroute Watch-originated agent turns.
  • [P1] The current head lacks the current-main QA-lab channel-driver isolated worker serialization fix, so rebase conflict resolution must preserve that automation stability work.

Maintainer options:

  1. Rebase and prove exact-head Watch delivery (recommended)
    Resolve the conflicts, preserve current-main QA serialization, remove release-owned changelog churn, rerun exact-head gates, and add real Watch or WatchConnectivity proof before merge.
  2. Accept proof gap deliberately
    A maintainer can explicitly override the real-device proof gap if source review and regression tests are sufficient for this hardware-limited path.
  3. Pause for the broader offline outbox
    If the broader iOS offline outbox stack is the intended canonical path, keep this PR paused or supersede it after that stack proves the Watch overlap.

Next step before merge

  • [P1] Manual maintainer handling is needed for conflict resolution, proof sufficiency or override, and rebase preservation of current-main QA automation; this is not a safe autonomous repair lane while device proof is missing.

Maintainer decision needed

  • Question: Should this PR wait for real Apple Watch or diagnostic WatchConnectivity proof after conflict resolution, or may maintainers explicitly override that proof gap?
  • Rationale: The changed path is user-visible Watch delivery plus durable message/session state, while the available evidence is source/CI/Testbox proof and the discussion says no physical Watch round-trip was available.
  • Likely owner: steipete — steipete adopted the branch, posted the land-ready review, and has the clearest recent ownership of the affected iOS/watch paths.
  • Options:
    • Require real Watch proof (recommended): Resolve conflicts, rerun exact-head checks, and require redacted Apple Watch or WatchConnectivity proof showing a queued quick reply surviving reconnect or restart before merge.
    • Maintainer proof override: A maintainer may explicitly accept the missing physical Watch proof after reviewing the source, regression tests, and conflict resolution.
    • Fold into broader outbox stack: Pause this PR if maintainers prefer to carry the Watch reply portion through the broader offline outbox stack.

Security
Cleared: No concrete credential, sandbox, dependency, or supply-chain regression was found in the reviewed diff; the gateway-binding and durable-message changes remain merge-risk sensitive and need proof.

Review findings

  • [P2] Preserve the QA isolated-worker serialization — extensions/qa-lab/src/suite-launch.runtime.ts:463-466
  • [P3] Remove the release-owned changelog entry — CHANGELOG.md:30
Review details

Best possible solution:

Resolve the current-main conflicts while preserving the QA-lab serialization fix, drop the normal-PR CHANGELOG.md edit, keep the gateway-scoped Watch outbox shape, rerun exact-head iOS/watch validation, and add real Watch/WatchConnectivity proof or an explicit maintainer proof override.

Do we have a high-confidence way to reproduce the issue?

Yes, from source inspection. Current main accepts Watch quick replies into process-local arrays in WatchReplyCoordinator, so queued replies and dedupe state can be lost if the iOS process is suspended or terminated before delivery; I did not run a physical Apple Watch reproduction.

Is this the best way to solve the issue?

Mostly yes for the Watch code shape: using one gateway-scoped durable outbox is the right boundary for this bug. It is not the best merge artifact until current-main conflicts, QA serialization preservation, release-owned changelog churn, and real Watch proof or maintainer override are resolved.

Full review comments:

  • [P2] Preserve the QA isolated-worker serialization — extensions/qa-lab/src/suite-launch.runtime.ts:463-466
    Late finding: this was visible on the previous review of the same head. The PR head drops current main's channelDriverFlowRequiresExclusiveWorkers limit and its regression test from commit a308e3b83429, so channel-driver isolated flow workers can run concurrently again under explicit channel-driver selection; rebase/conflict-resolve without removing that current-main QA fix.
    Confidence: 0.9
    Late finding: first raised on code an earlier review cycle already covered.
  • [P3] Remove the release-owned changelog entry — CHANGELOG.md:30
    This PR still adds an iOS Watch replies release note to CHANGELOG.md, but OpenClaw release generation owns that file for normal PRs. Keep the release-note context in the PR body or squash message and drop this changelog line.
    Confidence: 0.88

Overall correctness: patch is incorrect
Overall confidence: 0.86

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against a308e3b83429.

Label changes

Label justifications:

  • P2: This is a normal-priority mobile Watch message-loss fix with limited platform scope, not an emergency without real-device proof.
  • merge-risk: 🚨 message-delivery: The diff changes how Watch quick replies and Watch chat sends are queued, retried, deduped, forwarded, or discarded.
  • merge-risk: 🚨 session-state: The diff adds persisted Watch outbox metadata, prompt routes, and tombstones that affect restart and reconnect session behavior.
  • merge-risk: 🚨 security-boundary: The diff changes source-gateway binding for Watch replies so stale actions cannot cross to another selected gateway.
  • rating: 🦪 silver shellfish: Overall readiness is 🦪 silver shellfish; proof is 🦪 silver shellfish and patch quality is 🦪 silver shellfish.
  • status: 📣 needs proof: The PR needs real behavior proof before ClawSweeper can clear the contributor ask. Needs real behavior proof before merge: The PR body and maintainer comment provide parse, lint, CI, and Testbox output, but no real Apple Watch or WatchConnectivity after-fix run; redacted device logs, terminal output, screenshots/video, a linked artifact, or a reproducible live transcript should show the fixed queued-reply path before merge. After adding proof, update the PR body; ClawSweeper should re-review automatically. If it does not, the PR author or someone with repository write access can comment @clawsweeper re-review.
Evidence reviewed

What I checked:

  • Repository policy read: Root AGENTS.md plus scoped iOS, UI, scripts, and CODEOWNERS guidance were read; iOS persistence, generated output, release-owned changelog, and full-path PR review rules affected this verdict. (AGENTS.md:1, a308e3b83429)
  • Live PR state: GitHub reports the current head f312a74 as CONFLICTING with status: needs proof plus session-state, message-delivery, and security-boundary merge-risk labels still present. (f312a74022d2)
  • Current main source behavior: Current main keeps accepted Watch quick replies in an in-memory queuedReplies array and drains it only while the iOS process remains alive, so accepted replies can be lost across suspension or termination. (apps/ios/Sources/Model/WatchReplyCoordinator.swift:12, a308e3b83429)
  • PR persistence implementation: The PR replaces the separate reply/chat coordinators with WatchMessageOutbox, keeps the shipped watch.chat.command.queue.v1 key, adds metadata, and persists before returning forward or queue decisions. (apps/ios/Sources/Model/WatchReplyCoordinator.swift:13, f312a74022d2)
  • Source-gateway binding: The PR records prompt-to-gateway routes before Watch notification delivery and passes gatewayStableID through iOS/watch payloads so returned replies can be resolved instead of guessed. (apps/ios/Sources/Model/NodeAppModel.swift:1925, f312a74022d2)
  • Regression coverage: The PR adds tests for queued Watch replies, persisted restore, delivered tombstones, prompt routes, stale gateway drops, and idempotent duplicate handling. (apps/ios/Tests/NodeAppModelInvokeTests.swift:1977, f312a74022d2)

Likely related people:

  • steipete: GitHub shows steipete assigned and posting the land-ready review, while git blame/log history points to Peter Steinberger for the current WatchReplyCoordinator extraction, recent Apple Watch voice-turn work, and most commits in these iOS/watch files. (role: recent iOS/watch contributor and PR adopter; confidence: high; commits: 4a2629ebe36c, 245092dc3ae1, f399a818ef68; files: apps/ios/Sources/Model/WatchReplyCoordinator.swift, apps/ios/Sources/Model/NodeAppModel.swift, apps/ios/Tests/NodeAppModelInvokeTests.swift)
  • Mariano: Git history shows Mariano authored the original Apple Watch companion MVP and the mirrored notification quick-reply bridge that this PR now hardens. (role: introduced adjacent Watch messaging foundations; confidence: medium; commits: 57083e4220e3, f52476f18c37, 738b011624c7; files: apps/ios/Sources/Services/WatchMessagingPayloadCodec.swift, apps/ios/Sources/OpenClawApp.swift, apps/ios/WatchApp/Sources/WatchConnectivityReceiver.swift)
  • Vincent Koc: Current main commit a308e3b adds the QA-lab channel-driver isolated worker serialization that the PR head currently lacks, making Vincent Koc the best routing candidate for that rebase-sensitive surface. (role: current-main QA serialization owner; confidence: high; commits: a308e3b83429, e085fa1a3ffd; files: extensions/qa-lab/src/suite-launch.runtime.ts, extensions/qa-lab/src/suite-launch.runtime.test.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.
Review history (9 earlier review cycles; latest 8 shown)
  • reviewed 2026-07-05T11:30:24.078Z sha ade4304 :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-05T12:16:07.463Z sha 26b20d5 :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-05T13:18:05.619Z sha 4c9bd59 :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-05T14:01:45.452Z sha fff0522 :: needs real behavior proof before merge. :: [P1] Rebase without dropping local CLI shared-auth handling | [P2] Keep the pytest constraint as one dependency string
  • reviewed 2026-07-05T14:16:09.323Z sha a49b2fa :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-05T14:43:21.537Z sha 0e5d5ab :: needs real behavior proof before merge. :: none
  • reviewed 2026-07-05T15:29:54.442Z sha 1364510 :: needs real behavior proof before merge. :: [P3] Remove the release-owned changelog entry
  • reviewed 2026-07-05T15:36:59.668Z sha f312a74 :: needs real behavior proof before merge. :: [P3] Remove the release-owned changelog entry

@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. P2 Normal backlog priority with limited blast radius. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. labels Jul 4, 2026
@steipete steipete self-assigned this Jul 5, 2026
@steipete
steipete force-pushed the codex/fix-ios-watch-reply-persistence branch from bd81646 to 3252557 Compare July 5, 2026 11:05
@steipete
steipete force-pushed the codex/fix-ios-watch-reply-persistence branch 2 times, most recently from ade4304 to f978db8 Compare July 5, 2026 11:34
@steipete

steipete commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Land-ready review complete for f312a74022d21406295a869b16ec0795f9d352ee.

What changed:

  • Replaced the PR's separate quick-reply queue with the existing durable, gateway-scoped Watch message outbox.
  • Persist before delivery; use chat.send idempotency keys; retain bounded retries, delivery tombstones, and prompt-to-gateway routes across restarts.
  • Carry source gateway IDs through WatchConnectivity and mirrored iOS actions; reject unresolved or stale routes.
  • Preserve released Watch compatibility through recorded prompt routes and preserve the shipped watch.chat.command.queue.v1 data shape.

Proof:

  • xcrun swiftc -parse on all changed iOS/watchOS Swift files
  • swiftformat --lint --config config/swiftformat on changed app sources
  • node --import tsx scripts/native-app-i18n.ts check
  • Repeated Codex autoreview after accepted fixes: no accepted/actionable findings
  • Sanitized AWS Crabbox run run_3afe370a8d62 on lease cbx_c1f40dafdf1a: pnpm native:i18n:check and pnpm check:changed passed
  • Full exact-head GitHub release-gate run 28745844521: all 110 jobs passed, including ios-build, macos-swift, macos-node, Node 22/24, packaging, and platform lanes
  • Repo-native OPENCLAW_TESTBOX=1 scripts/pr prepare-run 100031: passed exact-head hosted gates; review artifacts validate READY FOR /prepare-pr with zero findings

Known gap: no physical Apple Watch round-trip was available. The separate iOS Periphery workflow reports the pre-existing unused TerminalHubScreen.webContentIdentity(config:) overload present on latest origin/main; it is unrelated to the Watch diff.

@openclaw-barnacle openclaw-barnacle Bot added scripts Repository scripts docker Docker and sandbox tooling labels Jul 5, 2026
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. and removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 5, 2026
@steipete
steipete requested a review from a team as a code owner July 5, 2026 12:42
@openclaw-barnacle openclaw-barnacle Bot added docs Improvements or additions to documentation channel: discord Channel integration: discord channel: imessage Channel integration: imessage channel: matrix Channel integration: matrix labels Jul 5, 2026
@clawsweeper clawsweeper Bot added the merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. label Jul 5, 2026
@clawsweeper clawsweeper Bot removed rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. labels Jul 5, 2026
@clawsweeper clawsweeper Bot added rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask. merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. labels Jul 5, 2026
@steipete steipete closed this Jul 5, 2026
@steipete
steipete force-pushed the codex/fix-ios-watch-reply-persistence branch from f312a74 to 286d0b9 Compare July 5, 2026 15:55
@steipete

steipete commented Jul 5, 2026

Copy link
Copy Markdown
Contributor

Thanks @NianJiuZst — the durable Watch reply work has landed through replacement PR #100372 as 70f2bef6b4cf04792f5f15fc12a9fafafa5771cc.

GitHub auto-closed this PR when its contributor branch briefly matched main during maintainer ancestry repair, and maintainer edit permission disappeared before the clean verified replacement commit could be written back. The replacement preserves your Co-authored-by credit, adds the pre-upgrade prompt regression fix found by final autoreview, and passed exact-head CI 28746617125, Workflow Sanity, iOS Periphery, and the repo-native prepare/merge guards.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling app: ios App: ios app: macos App: macos app: web-ui App: web-ui channel: discord Channel integration: discord channel: imessage Channel integration: imessage channel: matrix Channel integration: matrix channel: mattermost Channel integration: mattermost channel: qqbot channel: telegram Channel integration: telegram channel: voice-call Channel integration: voice-call channel: whatsapp-web Channel integration: whatsapp-web cli CLI command changes commands Command implementations docker Docker and sandbox tooling docs Improvements or additions to documentation extensions: clawrouter Extension: clawrouter extensions: codex extensions: copilot extensions: device-pair extensions: google extensions: policy extensions: qa-lab gateway Gateway runtime merge-risk: 🚨 message-delivery 🚨 May drop, duplicate, misroute, suppress, or wrongly target messages. merge-risk: 🚨 security-boundary 🚨 May affect sandboxing, authorization, credentials, or sensitive data. merge-risk: 🚨 session-state 🚨 May lose, corrupt, stale, or mis-associate session, agent, or context state. P2 Normal backlog priority with limited blast radius. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. scripts Repository scripts size: XS status: 📣 needs proof The PR needs real behavior proof before ClawSweeper can clear the contributor ask.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants