Reviewer: Astra (GPT-6-Astra via Codex). Whole-branch review of feat/k2-connectivity at fd67d33b36e52896e1ef0200b413b3d3eb7acb19, against fetched origin/main (e0c2f2a). Binding spec: rastrillo/native spec/offline-kit at 6049830, §3.2–3.4 and the K2 slice in §4.10. I read the aggregate merge-base diff and checked its content against current main: K1's squash is byte-for-byte identical to this branch's parent, so the main-to-head content delta is the nine-file K2 change.
VERDICT: CHANGES-REQUIRED
- P2 — a connectivity wake bypasses Retry-After.
native/apple/Sources/DocsKit/DocsModel.swift:352. A 429 withRetry-After: 30becomes a 30-second argument towait, but foreground/path/reachability wakes end that wait, reset backoff and immediately start another stream attempt. Scratch reproduction against the realDocsModel.listen,BackoffandNativeConnectivity: send the 429, foreground after 100 ms, inspect after another 600 ms; stream count is 2, expected 1. Keep a monotonic server-imposed retry deadline (capped at five minutes) separately from exponential backoff. A wake can reset exponential delay and reassess connectivity but must not erase the remaining server floor. Preserve the path-down/no-timer rule. Add a regression test with a wake inside Retry-After.
- P2 — connection setup and access refresh are counted as an open stream.
native/apple/Sources/DocsKit/DocsModel.swift:332and:350–351.openedis captured before the stream request, and elapsed time is read after the catch'srefreshAccess. A slow refusal, timeout or access-refresh request therefore resets backoff even when no stream ever opened. Scratch reproduction: three quick 503s, followed by a fourth 503 delayed 5.2 seconds; a fifth stream attempt occurs within 700 ms instead of retaining the expected 2–4-second delay. Capture a successful opening via the transport'sonOpen, measure until stream termination, and exclude connection setup and post-failure requests. Only an actually open stream lasting more than five seconds should get the stable-stream reset.
- P2 — merge main into this stacked branch before its squash merge. This is a demonstrated integration blocker, not a recommendation based only on ancestry.
git merge-tree --write-tree origin/main HEADreports six content conflicts:native/apple/Package.resolved,native/apple/Package.swift,native/apple/Sources/DocsKit/DocsModel.swift,native/ios/project.yml,native/macos/project.yml, andnative/smoke/document-window/Package.resolved.git diff --quiet e0c2f2a HEAD^succeeds for the entire tree, confirming the parent and K1 squash have identical content. Mergeorigin/maininto the branch, preserve the K2 content in these conflicts, verify the resulting main-to-branch diff contains only K2, then rerun the gate and request review of the corrected head. I did not perform a merge or move a checkout.
Validation: with $HOME/.cargo/bin first on PATH, native/scripts/check-native.sh exited 0. Rust tests, both directions of wire compatibility, rule-wire checks and all CRDT framework architecture builds passed; Swift ran 55 XCTest cases (3 existing fixture-dependent skips) plus 16 Swift Testing tests with no failures. Mutation check: replacing the backoff wait with a fixed two-second wait made testStreamBacksOffBetweenQuickFailures fail specifically with 1 attempt, expected at least 2. After restoring the source, both original StreamConnectivityTests passed again. The two failing probes above ran against the unmodified production loop; an additional probe confirmed closing a clean model while offline cancels the loop and foreground does not restart it.
Other checks: the immediate-EOF test exercises the actual listen implementation and does not spin without delay. The supplier/account-boundary tests also passed; the K1 supplier still prevents an old workspace borrowing another account's transport. ScriptedTransport drives the real code, but does not emit NativeHTTP outcome-observer notifications, so it is not end-to-end coverage of request-driven reachability. There are no server/migration changes in K2.
Spec departures: per-origin connectivity is accepted; deferring banner summary and durable-save wording until K3 is correct. App-catalog English copy is acceptable for K2, with the package catalog/twelve locales still required at K3. The English wording is approved. Re-pin to reviewed native main after native #7 lands, as already planned.
Review-only: no branch edits, commits, pushes or merges. Scratch mutations were restored; the scratch worktree and build outputs have been removed. Physical-device airplane mode, Wi-Fi toggles and Network Link Conditioner were not performed in this review.