Skip to content

fix(android): preserve quiet Gateway turns and recover completion - #694

Merged
Codename-11 merged 9 commits into
devfrom
fix/android-idle-watchdog
Oct 15, 2026
Merged

Codename-11 merged 9 commits into
devfrom
fix/android-idle-watchdog

Conversation

@Codename-11

@Codename-11 Codename-11 commented Oct 8, 2026 •

Copy link
Copy Markdown
Owner

Summary

Android treated a quiet Gateway turn as failed and sent session.interrupt, including when another client submitted the turn. Quiet tools, provider waits, and compaction now keep their stream alive. Authoritative Gateway state recovers a missing completion frame and its saved answer without sending Stop.

Addresses #676 and preserves the passive-observation guarantees discussed in #365.

Changes

  • Remove idle interruption, local timeout failure, and obsolete per-kind and post-retarget deadlines.
  • Reuse read-only session.active_list checks during quiet periods. Fence settlement by turn, runtime/durable session, profile, socket, and progress generation.
  • Settle admitted unsolicited streams locally. Reconnect reads existing request snapshots; shutdown detaches without cancelling the producer. Pending asks retain their server-owned deadline, and explicit cancellation still works.
  • Distinguish authoritative settlement from ordinary reconnect completion. Missing-final recovery trusts bounded history without requiring partial text to match or the latest window to grow. Normal terminal delivery retains its persistence check.
  • Recover a lost start frame from an exact running activation after reconnect. Idle-only, foreign-session, and queued-successor snapshots cannot establish that proof. Fence activation by the current turn and socket.
  • Add transport and rendered regressions, update the contract documentation, and adapt source conformance to current upstream's extracted helper and additive request methods.

Verification

Candidate: 3ab59c12c496c44ae1669af4be87d402ce54216c, incorporating verified dev at ebebc3183bb62bb7feccfcad344ac9c3d75023f6. Prerequisite #715 restored the compatible native runtime and enforced the required-checks merge gate.

  • Final-head required CI: passed on 3ab59c12c496c44ae1669af4be87d402ce54216c, including both APK native compatibility checks, lint, unit tests, and upstream routes. The first unit-test job timed out without a reported failing assertion; the job retry and the same focused CI shard run locally both passed on the unchanged commit.
  • API 36 GatewayForegroundRecoveryInstrumentedTest: all nine tests passed on the exact final candidate 3ab59c12c, with zero failures, errors, or skips. The active-list scenario now waits for its received partial answer so the idle probe captures the current progress generation. The timeout and production settlement guards are unchanged.
  • python -m unittest discover -s scripts/tests -p check_gateway_scenario_conformance_test.py: 15 passed. The checker follows upstream's extracted session registry while retaining identity, status, and settlement checks; regressions verify missing fields/states still fail.
  • Seven manifests passed against clean vanilla upstream 73b9f2af7b87a619f42396710c332be04353aef2: quiet_turn_recovery, terminal_gap_activate, terminal_gap_session_info, terminal_gap_active_list, cross_client_observation, clarify_batch, and queued_stop_resume. These are source-conformance checks, not live provider execution.
  • Earlier focused local proof at 0e0e26e0d: 439 sideload and 206 Google Play unit tests passed, with no failures, errors, or skips. Subsequent changes are base integration, instrumentation synchronization, and source-checker maintenance; the Gateway runtime and focused unit sources are unchanged.
  • Earlier quiet-turn fixture instrumentation: 1 passed, with one submit, zero activations, and zero interrupts; the full saved answer appeared after a missing final frame. The fixture Python suite passed 38 tests. These sources are unchanged by the final follow-up.
  • Negative controls: both quiet-turn regressions failed on 749b6c02d with Gateway turn timed out; both lost-start regressions failed on 23248ea75 because authoritative completion was ignored.
  • All local Android runs used scripts/android-lane.ps1. No physical-device installation/certification or production deployment for this PR.

Screenshots

No layout change. Rendered stream and transcript behavior passed on the Standard Phone API 36 emulator.

Compatibility / risk

Client-only, with no new host routes or migrations. Unknown, absent, unsupported, or failed active-state reads remain unknown; they cannot invent completion. A host that provides no terminal or authoritative state still requires transport recovery or explicit Stop. Rollback is a revert.

Native request replay uses the existing read-only session.events.since surface. No interrupt-reason fields are added to the wire. The source checker still requires every existing request contract while allowing additional methods that Android can decline with JSON-RPC method-not-found.

Lineage / contributor credit

Checklist

  • Target branch is dev
  • Scope is focused and related issues/PRs are linked
  • Android lint and focused tests ran
  • Translation changes: N/A
  • Server/plugin changes: no production changes; fixture tests and conformance ran
  • Desktop changes: N/A
  • Docs/site changes: contract documentation updated; no site routes changed
  • Rendered behavior tested on API 36; physical-device proof remains separate
  • Commit messages follow Conventional Commits
  • CHANGELOG.md updated
  • Public writing hygiene checked
  • Source PRs linked and contributor authorship preserved

BrokeSkill and others added 5 commits October 7, 2026 21:23
Extend the preserved PR #675 commits with read-only quiet probes, exact unsolicited settlement, passive reconnect and shutdown, native ask replay, and missing-final history reconciliation. Cover owner and observer paths through real Gateway transport and rendered fixture tests. Update current-upstream conformance for extracted helpers and additive requests.

Adapt cancellation-only diagnostics from PR #668. Supersede PR #662's eventual interrupt lease; quiet tools use server-owned liveness instead.

Co-authored-by: ophirhan <ophirhan@users.noreply.github.com>
@ophirhan

Copy link
Copy Markdown
Contributor

Noting handoff from my open #668 (fix/watchdog-no-interrupt-on-retarget).

I agree with the lineage note here: the cancellation-only interrupt diagnostics were the durable piece; the local idle-timeout failure is correctly superseded by this PR’s quiet session.active_list / authoritative recovery path.

I’ve closed #668 as superseded by this consolidation (thanks for preserving co-authorship on the adapted commit). No further action needed from me on that branch unless something from #668’s Diagnostics Stop entry (chat_user_stop) is wanted as a tiny follow-up after this merges — happy to open that separately if useful.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants