feat(apps): review durable approvals on mobile#104913
Merged
Merged
Conversation
Squash-rebased #103912 segment onto the deep-links tip on current main. Native approval surfaces: iOS approval presentation with gateway-switch lease preservation and resolution fencing, watchOS inbox + approval actions with shipped-shape payload codec, Android approval notices with publication-tokened dismissal. Native i18n inventory regenerated. (cherry picked from commit 428a76670ffeede54248b7bd7aa4438e2589851b) (cherry picked from commit 80225d5707c3645eeea5435f266131037b50ede6) (cherry picked from commit 2a23b714dc30d773a294aa45adc617e46b80732e) (cherry picked from commit 9ff1153827769e2cbab7c11c153f0f8634662c28) (cherry picked from commit 5b25723525bd562e5f97478af492f7b46ad30fd1) (cherry picked from commit 8c80e8467b5fe89aad0d4c74a0573f1600ed3af9) (cherry picked from commit ad4037bc9846bf6f082b41c129ee68aa344576c3) (cherry picked from commit fdf767dd662cff3c8a5a6d571f38f153410651ca) (cherry picked from commit 00c120376ffd992ea68ce29254a9bc0a25ed1740) (cherry picked from commit f36a952) (cherry picked from commit e2c25cbe2baacab44d21871d8cb6734704f065ac) (cherry picked from commit 7c4fda519080486d341a9f4df36d63f9e24b1235) (cherry picked from commit 1b3d4eda3dc5988012124597f9454ae21fb187a1) (cherry picked from commit 2a60619) (cherry picked from commit 6f0c386) (cherry picked from commit 784a585) (cherry picked from commit cbf294e)
Contributor
Author
|
Land-ready proof for exact head
Known proof gaps: the paired physical iPhone/Watch recipe was not run. Crabbox artifact publishing was attempted but this host has neither a configured artifact broker nor S3 credentials, so the screenshot was visually inspected locally and was not committed or uploaded. |
Contributor
Author
|
Merged via squash.
|
fakoli
added a commit
to fakoli/openclaw
that referenced
this pull request
Jul 12, 2026
- void the now-async submitToolResult calls in the anvil-voice test - oxfmt scripts/sync-fakoli-fork-main.mjs - sync control-ui i18n raw-copy baseline + locale meta (upstream openclaw#104768 left Interrupted strings out of the baseline; path-filtered upstream CI never ran the check) - drop unused WatchInboxStore.shouldShowExecApprovalReviewStatus (upstream openclaw#104913, flagged by the iOS periphery scan)
steipete
added a commit
that referenced
this pull request
Jul 12, 2026
- android: capture createdAtMs on the pending exec-approval write at registration; canonical readback after a refresh that already replaced the visible rows was dropping the approval instead of surfacing the still-pending reconciliation message (#104913 merged without this) - android: generous CI timeout ceilings in GatewayExecApprovalRuntimeTest - agents: hermetic model-discovery test via the plugins/provider-runtime boundary (lazy plugin-runtime resolution hangs vitest workers since #104770) - cli: usage-cost settle-budget test asserts the budget bound on every call instead of pinning the poll count (fast hosts fit a second poll in 50ms) - protocol coverage: allowlist session.approval for ios/android (native review rides exec.approval push/nudge delivery) - docs map, native i18n inventory, plugin-sdk api baseline regenerated
steipete
added a commit
that referenced
this pull request
Jul 12, 2026
- android: capture createdAtMs on the pending exec-approval write at registration; canonical readback after a refresh that already replaced the visible rows was dropping the approval instead of surfacing the still-pending reconciliation message (#104913 merged without this) - android: generous CI timeout ceilings in GatewayExecApprovalRuntimeTest - agents: hermetic model-discovery test via the plugins/provider-runtime boundary (lazy plugin-runtime resolution hangs vitest workers since #104770) - cli: usage-cost settle-budget test asserts the budget bound on every call instead of pinning the poll count (fast hosts fit a second poll in 50ms) - protocol coverage: allowlist session.approval for ios/android (native review rides exec.approval push/nudge delivery) - docs map, native i18n inventory, plugin-sdk api baseline regenerated
steipete
added a commit
that referenced
this pull request
Jul 12, 2026
- android: capture createdAtMs on the pending exec-approval write at registration; canonical readback after a refresh that already replaced the visible rows was dropping the approval instead of surfacing the still-pending reconciliation message (#104913 merged without this) - android: generous CI timeout ceilings in GatewayExecApprovalRuntimeTest - agents: hermetic model-discovery test via the plugins/provider-runtime boundary (lazy plugin-runtime resolution hangs vitest workers since #104770) - cli: usage-cost settle-budget test asserts the budget bound on every call instead of pinning the poll count (fast hosts fit a second poll in 50ms) - protocol coverage: allowlist session.approval for ios/android (native review rides exec.approval push/nudge delivery) - docs map, native i18n inventory, plugin-sdk api baseline regenerated
github-actions Bot
pushed a commit
to Desicool/openclaw
that referenced
this pull request
Jul 12, 2026
* feat(apps): Android, iPhone, and Watch approval clients Squash-rebased openclaw#103912 segment onto the deep-links tip on current main. Native approval surfaces: iOS approval presentation with gateway-switch lease preservation and resolution fencing, watchOS inbox + approval actions with shipped-shape payload codec, Android approval notices with publication-tokened dismissal. Native i18n inventory regenerated. (cherry picked from commit 428a76670ffeede54248b7bd7aa4438e2589851b) (cherry picked from commit 80225d5707c3645eeea5435f266131037b50ede6) (cherry picked from commit 2a23b714dc30d773a294aa45adc617e46b80732e) (cherry picked from commit 9ff1153827769e2cbab7c11c153f0f8634662c28) (cherry picked from commit 5b25723525bd562e5f97478af492f7b46ad30fd1) (cherry picked from commit 8c80e8467b5fe89aad0d4c74a0573f1600ed3af9) (cherry picked from commit ad4037bc9846bf6f082b41c129ee68aa344576c3) (cherry picked from commit fdf767dd662cff3c8a5a6d571f38f153410651ca) (cherry picked from commit 00c120376ffd992ea68ce29254a9bc0a25ed1740) (cherry picked from commit f36a952) (cherry picked from commit e2c25cbe2baacab44d21871d8cb6734704f065ac) (cherry picked from commit 7c4fda519080486d341a9f4df36d63f9e24b1235) (cherry picked from commit 1b3d4eda3dc5988012124597f9454ae21fb187a1) (cherry picked from commit 2a60619) (cherry picked from commit 6f0c386) (cherry picked from commit 784a585) (cherry picked from commit cbf294e) * fix(apps): harden approval reconciliation and watch states
steipete
added a commit
that referenced
this pull request
Jul 12, 2026
- android: capture createdAtMs on the pending exec-approval write at registration; canonical readback after a refresh that already replaced the visible rows was dropping the approval instead of surfacing the still-pending reconciliation message (#104913 merged without this) - android: generous CI timeout ceilings in GatewayExecApprovalRuntimeTest - agents: hermetic model-discovery test via the plugins/provider-runtime boundary (lazy plugin-runtime resolution hangs vitest workers since #104770) - cli: usage-cost settle-budget test asserts the budget bound on every call instead of pinning the poll count (fast hosts fit a second poll in 50ms) - protocol coverage: allowlist session.approval for ios/android (native review rides exec.approval push/nudge delivery) - docs map, native i18n inventory, plugin-sdk api baseline regenerated
steipete
added a commit
that referenced
this pull request
Jul 12, 2026
- android: capture createdAtMs on the pending exec-approval write at registration; canonical readback after a refresh that already replaced the visible rows was dropping the approval instead of surfacing the still-pending reconciliation message (#104913 merged without this) - android: generous CI timeout ceilings in GatewayExecApprovalRuntimeTest - agents: hermetic model-discovery test via the plugins/provider-runtime boundary (lazy plugin-runtime resolution hangs vitest workers since #104770) - cli: usage-cost settle-budget test asserts the budget bound on every call instead of pinning the poll count (fast hosts fit a second poll in 50ms) - protocol coverage: allowlist session.approval for ios/android (native review rides exec.approval push/nudge delivery) - docs map, native i18n inventory, plugin-sdk api baseline regenerated
steipete
added a commit
that referenced
this pull request
Jul 12, 2026
- android: capture createdAtMs on the pending exec-approval write at registration; canonical readback after a refresh that already replaced the visible rows was dropping the approval instead of surfacing the still-pending reconciliation message (#104913 merged without this) - android: generous CI timeout ceilings in GatewayExecApprovalRuntimeTest - agents: hermetic model-discovery test via the plugins/provider-runtime boundary (lazy plugin-runtime resolution hangs vitest workers since #104770) - cli: usage-cost settle-budget test asserts the budget bound on every call instead of pinning the poll count (fast hosts fit a second poll in 50ms) - protocol coverage: allowlist session.approval for ios/android (native review rides exec.approval push/nudge delivery) - docs map, native i18n inventory, plugin-sdk api baseline regenerated
steipete
added a commit
that referenced
this pull request
Jul 12, 2026
- android: capture createdAtMs on the pending exec-approval write at registration; canonical readback after a refresh that already replaced the visible rows was dropping the approval instead of surfacing the still-pending reconciliation message (#104913 merged without this) - android: generous CI timeout ceilings in GatewayExecApprovalRuntimeTest - agents: hermetic model-discovery test via the plugins/provider-runtime boundary (lazy plugin-runtime resolution hangs vitest workers since #104770) - cli: usage-cost settle-budget test asserts the budget bound on every call instead of pinning the poll count (fast hosts fit a second poll in 50ms) - protocol coverage: allowlist session.approval for ios/android (native review rides exec.approval push/nudge delivery) - docs map, native i18n inventory, plugin-sdk api baseline regenerated
steipete
added a commit
that referenced
this pull request
Jul 12, 2026
- android: capture createdAtMs on the pending exec-approval write at registration; canonical readback after a refresh that already replaced the visible rows was dropping the approval instead of surfacing the still-pending reconciliation message (#104913 merged without this) - android: generous CI timeout ceilings in GatewayExecApprovalRuntimeTest - agents: hermetic model-discovery test via the plugins/provider-runtime boundary (lazy plugin-runtime resolution hangs vitest workers since #104770) - cli: usage-cost settle-budget test asserts the budget bound on every call instead of pinning the poll count (fast hosts fit a second poll in 50ms) - protocol coverage: allowlist session.approval for ios/android (native review rides exec.approval push/nudge delivery) - docs map, native i18n inventory, plugin-sdk api baseline regenerated
steipete
added a commit
that referenced
this pull request
Jul 12, 2026
… gates (#104837) * feat(gateway): propagate approvals to ancestor sessions with replay Squash-rebased #103921 segment onto the native-clients tip on current main. Session-scoped approval events publish sanitized pending/terminal transitions to opted-in session audiences, with authoritative pending replay on stream subscribe and durable-expiry reconciliation through the owning manager. SessionApprovalEvent/Replay wire types export from the approvals owner module; Swift models regenerated. (cherry picked from commit 2d1dcf9747044710111d0c730fc46ba6013a165c) (cherry picked from commit ccf88efd56b513d07599ffcee997bf0cddaf9adc) (cherry picked from commit 8eb33f59f00ec9ee4625259b76bd7ae60d2cd480) (cherry picked from commit c297cbc93c8401e9c79c20f242245a194f5dd236) (cherry picked from commit 93d68f28601ff37d863da4db009504993a22533a) (cherry picked from commit d285ccd8b2f212bb57e814107e7709c896e96b7d) (cherry picked from commit 5c536982231402b1b58d1683794ea9948b32d077) (cherry picked from commit 1646e5b6dc4dd20de54e10f110a5909be18d7d50) (cherry picked from commit 35cf1b705b247fb282f4d56ffe74bd2fb238221f) (cherry picked from commit 4f8ef36) (cherry picked from commit 74fbdcc99d5fff062d67760a51dba4ee9e84479b) (cherry picked from commit 222b285502681d2be14b1819798e9ee5555f431e) (cherry picked from commit b9e744951f676b600e7c5322bfd04b0e99797c07) (cherry picked from commit 9e904ef) (cherry picked from commit 678f238) (cherry picked from commit 72842e5) (cherry picked from commit be74c25) (cherry picked from commit 93ba8c4) (cherry picked from commit 8f23761) * feat(gateway): fail-closed plugin and tool approval gates Squash-rebased #103932 segment onto the ancestor-propagation tip on current main. Plugin node.invoke approvals claim a one-shot allow-once decision before handing execution authority to the policy, so observation or retry cannot replay a consumed approval; sibling tool gates bind approval ids to their originating reviewer identity. (cherry picked from commit 122df0d75281f572c012b6484ed5daf085d1d577) (cherry picked from commit f23d8ac240a8dcf2a42c4daaae962263975a0ae8) (cherry picked from commit 8632fb6436a224dac7a9a9ef0216884530de2c24) (cherry picked from commit d9fe2dd5c53665e5732f5f3da5ed1907a686ade8) (cherry picked from commit bb139f2c8aa36ddad70413e1ef79ff491a6f2ecd) (cherry picked from commit 9b3e056b68ea515c7d4baef269289b6670570480) (cherry picked from commit b11e66b59a7af1f3b08712de06864aed64d349e4) (cherry picked from commit a12916ee592d03dfa35e86a2aaede4476a5d4e5d) (cherry picked from commit d699de840fc8346892b9ae244fe3c3e8c4413032) (cherry picked from commit 9b7e5a9) (cherry picked from commit 4b507593f1b2f10b4496984c84a2803b853e5c5e) (cherry picked from commit 56408a186733c4eeb5aa76bd5907cde7b0cd3d5b) (cherry picked from commit a4051d6d8353d39d6fa0b5d69c36e06c3cd3e796) (cherry picked from commit 7682980) (cherry picked from commit a8b493f) (cherry picked from commit aceb990) (cherry picked from commit a29b0e7) (cherry picked from commit 2e3be08) (cherry picked from commit c9ae3d7) * fix: main-gate repairs for the durable-approvals stack - android: capture createdAtMs on the pending exec-approval write at registration; canonical readback after a refresh that already replaced the visible rows was dropping the approval instead of surfacing the still-pending reconciliation message (#104913 merged without this) - android: generous CI timeout ceilings in GatewayExecApprovalRuntimeTest - agents: hermetic model-discovery test via the plugins/provider-runtime boundary (lazy plugin-runtime resolution hangs vitest workers since #104770) - cli: usage-cost settle-budget test asserts the budget bound on every call instead of pinning the poll count (fast hosts fit a second poll in 50ms) - protocol coverage: allowlist session.approval for ios/android (native review rides exec.approval push/nudge delivery) - docs map, native i18n inventory, plugin-sdk api baseline regenerated
github-actions Bot
pushed a commit
to Desicool/openclaw
that referenced
this pull request
Jul 13, 2026
… gates (openclaw#104837) * feat(gateway): propagate approvals to ancestor sessions with replay Squash-rebased openclaw#103921 segment onto the native-clients tip on current main. Session-scoped approval events publish sanitized pending/terminal transitions to opted-in session audiences, with authoritative pending replay on stream subscribe and durable-expiry reconciliation through the owning manager. SessionApprovalEvent/Replay wire types export from the approvals owner module; Swift models regenerated. (cherry picked from commit 2d1dcf9747044710111d0c730fc46ba6013a165c) (cherry picked from commit ccf88efd56b513d07599ffcee997bf0cddaf9adc) (cherry picked from commit 8eb33f59f00ec9ee4625259b76bd7ae60d2cd480) (cherry picked from commit c297cbc93c8401e9c79c20f242245a194f5dd236) (cherry picked from commit 93d68f28601ff37d863da4db009504993a22533a) (cherry picked from commit d285ccd8b2f212bb57e814107e7709c896e96b7d) (cherry picked from commit 5c536982231402b1b58d1683794ea9948b32d077) (cherry picked from commit 1646e5b6dc4dd20de54e10f110a5909be18d7d50) (cherry picked from commit 35cf1b705b247fb282f4d56ffe74bd2fb238221f) (cherry picked from commit 4f8ef36) (cherry picked from commit 74fbdcc99d5fff062d67760a51dba4ee9e84479b) (cherry picked from commit 222b285502681d2be14b1819798e9ee5555f431e) (cherry picked from commit b9e744951f676b600e7c5322bfd04b0e99797c07) (cherry picked from commit 9e904ef) (cherry picked from commit 678f238) (cherry picked from commit 72842e5) (cherry picked from commit be74c25) (cherry picked from commit 93ba8c4) (cherry picked from commit 8f23761) * feat(gateway): fail-closed plugin and tool approval gates Squash-rebased openclaw#103932 segment onto the ancestor-propagation tip on current main. Plugin node.invoke approvals claim a one-shot allow-once decision before handing execution authority to the policy, so observation or retry cannot replay a consumed approval; sibling tool gates bind approval ids to their originating reviewer identity. (cherry picked from commit 122df0d75281f572c012b6484ed5daf085d1d577) (cherry picked from commit f23d8ac240a8dcf2a42c4daaae962263975a0ae8) (cherry picked from commit 8632fb6436a224dac7a9a9ef0216884530de2c24) (cherry picked from commit d9fe2dd5c53665e5732f5f3da5ed1907a686ade8) (cherry picked from commit bb139f2c8aa36ddad70413e1ef79ff491a6f2ecd) (cherry picked from commit 9b3e056b68ea515c7d4baef269289b6670570480) (cherry picked from commit b11e66b59a7af1f3b08712de06864aed64d349e4) (cherry picked from commit a12916ee592d03dfa35e86a2aaede4476a5d4e5d) (cherry picked from commit d699de840fc8346892b9ae244fe3c3e8c4413032) (cherry picked from commit 9b7e5a9) (cherry picked from commit 4b507593f1b2f10b4496984c84a2803b853e5c5e) (cherry picked from commit 56408a186733c4eeb5aa76bd5907cde7b0cd3d5b) (cherry picked from commit a4051d6d8353d39d6fa0b5d69c36e06c3cd3e796) (cherry picked from commit 7682980) (cherry picked from commit a8b493f) (cherry picked from commit aceb990) (cherry picked from commit a29b0e7) (cherry picked from commit 2e3be08) (cherry picked from commit c9ae3d7) * fix: main-gate repairs for the durable-approvals stack - android: capture createdAtMs on the pending exec-approval write at registration; canonical readback after a refresh that already replaced the visible rows was dropping the approval instead of surfacing the still-pending reconciliation message (openclaw#104913 merged without this) - android: generous CI timeout ceilings in GatewayExecApprovalRuntimeTest - agents: hermetic model-discovery test via the plugins/provider-runtime boundary (lazy plugin-runtime resolution hangs vitest workers since openclaw#104770) - cli: usage-cost settle-budget test asserts the budget bound on every call instead of pinning the poll count (fast hosts fit a second poll in 50ms) - protocol coverage: allowlist session.approval for ios/android (native review rides exec.approval push/nudge delivery) - docs map, native i18n inventory, plugin-sdk api baseline regenerated
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related: #103505
Carries #103912 to
mainafter GitHub recorded that stacked PR as merged into its prerequisite branch.What Problem This Solves
Operators using Android, iPhone, or Apple Watch cannot reliably review the same Gateway approval shown in the Control UI or a chat channel. Lost acknowledgements can leave a native card looking actionable or resolved without canonical proof, and switching Gateways can misroute stale approval state.
Why This Change Was Made
The official mobile clients now read and resolve the durable Gateway approval record. Android and iPhone use the kind-aware unified RPCs, Watch relays reviewer-safe exec prompts through its paired iPhone, and every client treats Gateway terminal state as authoritative. A bounded legacy exec-method fallback supports shipped Gateway v4 peers.
The clients preserve approval and Gateway IDs as opaque exact identifiers, bind credentials and cached prompts to the selected Gateway, and freeze ambiguous writes until canonical readback. Review also fixed a same-endpoint Android method-catalog race and made Watch show explicit loading or unavailable states instead of falsely reporting a pending approval as clear.
User Impact
Authorized operators can review pending exec approvals from Android, iPhone, or Apple Watch. The first answer from any authorized surface wins, every native surface displays the recorded result, and a lost response or reconnect cannot silently fabricate approval success or reopen execution rights.
Evidence
tbx_01kxa2qa51wqsm9njcjdzsk0qd(silver-prawn-aefb): the exact Android method-catalog race passes in Play and ThirdParty; full Play and ThirdParty unit suites plus app/benchmark ktlint pass.test/scripts/native-app-i18n.test.tspasses 7/7.73b5ca0b7c1853e02fa5e8a9a8d5ed4cf5884eeeaae4f678a971c7af428c4cff; the local artifact publisher was unavailable, so no proof asset is committed.The paired physical iPhone/Watch interaction remains a manual release recipe; this PR does not claim that device run.