openclaw/docs
Peter Steinberger 1c08d96d8b
feat(android): durable offline chat with attachments and history-proof retirement (#104089)
* feat(android): durable offline chat with attachments and history-proof retirement

Every chat send is journaled to the per-gateway Room outbox before any
network attempt, so process death always has one durable recovery owner.
Rows survive gateway ACKs as 'accepted' and retire only once the turn is
proven in canonical chat.history by idempotency key; ambiguous outcomes
(lost ACK, kill mid-send, gateway restart before the transcript write)
park as delivery-unconfirmed for explicit retry, per the fail-closed
model #103273 landed. An unproven accepted head briefly holds only its
own session's queue, and retrying a parked head re-orders still-queued
successors behind it. Offline sends now accept picked images and voice
notes; attachment bytes persist as chunked BLOBs (512 KB chunks, 8 MB
per message, 48 MB per gateway) admitted and retired atomically with
their row. Pre-hello 'main' rows pin to the canonical session at first
dispatch so later default-agent changes cannot retarget captured input;
slash commands are connection-gated by a persisted epoch (legacy queued
command rows migrate to a never-matching sentinel) and never auto-replay
across reconnects. The Room store moves to schema v4 on top of v3's
data-parking migration, adding the epoch column and attachment tables
while preserving queued rows. The queued->sending claim is an atomic
compare-and-set shared by the direct dispatch and the flush loop, the
direct path waits for the startup recovery sweep before claiming, and
failed reconnect attempts republish outbox rows so queued sends stay
visible on offline cold starts.

Proof: 1151 Android unit tests and :app:ktlintCheck green (new
migration, storage, and controller coverage for admission, restarts,
claims, pinning, gating, ordering, and byte round-trips); a live
emulator scenario on the pre-integration build queued text+image
offline, survived force-stop plus a device reboot, resent exactly once
on reconnect (single <rowId>:user turn in the gateway transcript), and
drained the outbox after canonical-history confirmation.

Closes #104087.

* fix(android): rearm outbox recovery when direct-send state persistence fails

* fix(android): keep direct dispatch alive across caller cancellation

The direct send's network phase now runs in the controller scope, so a
cancelled UI scope (leaving the chat screen mid-send) can no longer
strand a claimed row in 'sending' with no user action available; the
dispatch completes and settles the row exactly once. Direct-path state
persistence failures also re-arm the startup recovery sweep, mirroring
the flush path's fail-closed handling.

* fix(android): hand claim-persistence failures to the flush lane

A direct-send claim that fails to persist no longer reads as a lost race:
the admitted row is handed to the flush lane so a healthy connection still
delivers it, and the flush path's fail-closed handling owns any repeated
storage failure instead of the UI reporting success with no active owner.

* fix(android): enforce connection gating and fail-closed parking on every send path

The direct dispatch now rechecks a slash command's connection epoch after
its durable claim, so a reconnect between admission and dispatch parks the
command instead of replaying it on the new connection. Parking a stale
gated row only counts once the write persists; a storage failure drops
health, re-arms recovery, and halts the flush pass instead of spinning or
dispatching the stale row.

* fix(android): recognize gateway-acknowledged run ids in outbox ownership checks

A chat.send ACK can return a run id that differs from the row's
idempotency key (the direct path transfers local run ownership to it).
Ownership, in-flight, backlog, and timeout-park checks now consider both
ids, so reconciliation can no longer park — and Retry can no longer
duplicate — a turn that is still running on the gateway.

* fix(android): close remaining ack-ownership and persistence-failure gaps in the outbox

Flushed sends acked under a divergent run id now transfer local run
ownership like the direct path, so live runs cannot time out and surface
spurious errors for delivered turns. A session pin that cannot persist
stops the dispatch while the row is still safely queued. Reconcile and
timeout parking only report changes their writes actually persisted,
failing closed on storage errors.

* docs(android): record why acknowledged run ids stay in-memory
2026-07-10 22:12:25 -07:00
..
.generated chore(release): set version to 2026.7.2 2026-07-11 04:00:49 +01:00
.i18n fix(i18n): add Meta docs glossary terms (#103923) 2026-07-10 21:10:05 +01:00
announcements docs: rewrite published docs grounded in current source (#100142) 2026-07-05 00:32:47 -04:00
assets docs(readme): trim banner whitespace for a more compact hero 2026-07-09 14:53:52 -07:00
automation fix(session-memory): honor configured slug model (#97007) 2026-07-10 22:08:12 -07:00
channels fix(channels): honor configured read target policies (#99905) 2026-07-10 22:29:37 -05:00
clawhub docs: rewrite published docs grounded in current source (#100142) 2026-07-05 00:32:47 -04:00
cli fix(channels): honor configured read target policies (#99905) 2026-07-10 22:29:37 -05:00
concepts feat(ui): worktrees page owners and creation, structured snapshot failures, preserved-checkout cleanup (#103526) 2026-07-10 19:16:36 +01:00
debug docs: rewrite published docs grounded in current source (#100142) 2026-07-05 00:32:47 -04:00
diagnostics docs: rewrite published docs grounded in current source (#100142) 2026-07-05 00:32:47 -04:00
gateway fix(gateway): preserve local access for specific binds (#98479) 2026-07-10 19:18:47 -07:00
help fix(gateway): preserve local access for specific binds (#98479) 2026-07-10 19:18:47 -07:00
images
install fix(installer): default to Node 22.22.2 (#104073) 2026-07-10 19:28:49 -07:00
maturity chore(repo): remove stale repository artifacts (#103152) 2026-07-10 05:28:12 +05:30
nodes docs(node): clarify headless identity and pairing state (#103964) 2026-07-10 22:55:45 +01:00
plan chore(repo): remove stale repository artifacts (#103152) 2026-07-10 05:28:12 +05:30
platforms feat(android): durable offline chat with attachments and history-proof retirement (#104089) 2026-07-10 22:12:25 -07:00
plugins fix(channels): honor configured read target policies (#99905) 2026-07-10 22:29:37 -05:00
providers fix(providers): align Meta Model API contract (#103680) 2026-07-10 05:24:14 -07:00
refactor refactor(pairing): move device pairing store to shared SQLite state DB (#103160) 2026-07-10 01:46:56 +01:00
reference improve(release): reuse exact-SHA validation evidence (#104162) 2026-07-11 12:48:27 +08:00
releases docs: publish release notes for v2026.6.11 (#98319) 2026-06-30 19:42:12 -06:00
security docs: rewrite published docs grounded in current source (#100142) 2026-07-05 00:32:47 -04:00
snippets/plugin-publish docs: restore source-backed contract details (#100182) 2026-07-05 01:26:25 -04:00
specs feat: show Codex sessions across Gateway and paired nodes (#102586) 2026-07-09 03:42:03 -07:00
start fix(onboarding): make fresh AI setup reliable and transparent (#103962) 2026-07-10 23:44:53 +01:00
tools fix(channels): honor configured read target policies (#99905) 2026-07-10 22:29:37 -05:00
web feat(ui): gateway browser panel with annotate-to-prompt and element inspect in the web Control UI (#104012) 2026-07-10 19:54:47 -07:00
agent-runtime-architecture.md docs: rewrite published docs grounded in current source (#100142) 2026-07-05 00:32:47 -04:00
AGENTS.md docs: rewrite published docs grounded in current source (#100142) 2026-07-05 00:32:47 -04:00
auth-credential-semantics.md docs: rewrite published docs grounded in current source (#100142) 2026-07-05 00:32:47 -04:00
brave-search.md
ci.md improve(release): reuse exact-SHA validation evidence (#104162) 2026-07-11 12:48:27 +08:00
CLAUDE.md
date-time.md docs: rewrite published docs grounded in current source (#100142) 2026-07-05 00:32:47 -04:00
docs.json docs(gateway): document restart and crash recovery behavior (#103985) 2026-07-11 00:44:16 +01:00
docs_map.md fix(docs): expose top-level docs hubs on mobile (#100908) 2026-07-10 20:30:35 -07:00
index.md fix(docs): expose top-level docs hubs on mobile (#100908) 2026-07-10 20:30:35 -07:00
logging.md docs: rewrite published docs grounded in current source (#100142) 2026-07-05 00:32:47 -04:00
nav-tabs-underline.js
network.md docs: rewrite published docs grounded in current source (#100142) 2026-07-05 00:32:47 -04:00
openclaw-agent-runtime.md docs: rewrite published docs grounded in current source (#100142) 2026-07-05 00:32:47 -04:00
perplexity.md
prose.md docs: rewrite published docs grounded in current source (#100142) 2026-07-05 00:32:47 -04:00
style.css docs: clarify maturity scorecard scoring (#96594) 2026-06-24 17:32:08 -07:00
tts.md
vps.md docs: rewrite published docs grounded in current source (#100142) 2026-07-05 00:32:47 -04:00
whatsapp-openclaw.jpg