Skip to content

fix: audit wave 2 — stale element refs, reparent unification, snapshot fallback, remote GC, auto-install default - #313

Merged
arzafran merged 6 commits into
mainfrom
fix/audit-wave-2
Aug 20, 2026
Merged

fix: audit wave 2 — stale element refs, reparent unification, snapshot fallback, remote GC, auto-install default#313
arzafran merged 6 commits into
mainfrom
fix/audit-wave-2

Conversation

@arzafran

Copy link
Copy Markdown
Member

What this does

Second and final wave of the 2026-08-20 audit remediation, per the decisions taken today: agents driving the browser can no longer act on the wrong element after a navigation, the two WebKit reparent code paths are one, a corrupt session snapshot no longer silently loses the whole restore, remote hosts stop accumulating old daemon binaries, and updates now install silently by default so fixes actually reach users.

Summary (finding IDs from docs/audits/codebase-audit-2026-08-20.md)

  • M6a/M8 — element refs carry a navigation generation (stale_element on post-navigation use — verified live against a running build); v2 handle maps pruned at refresh, ref numbers never reissued (tested).
  • M5 — both reparent paths share WebKitSubviewTransfer (net −150 lines); smoke-verified by dragging a live browser pane across splits. Residual verification: docked-inspector churn scenarios listed in the source doc comment.
  • L4 — startup falls back to the 5 newest session-history archives when the primary snapshot fails decode/version, with diagnostics logging (3 behavioral tests).
  • M12 — remote finalize script prunes old programad-remote/<version> dirs, keep current + mtime-newest other; anchored rm, non-fatal, tested against a synthetic $HOME.
  • M4 — restore-time insecure-HTTP bypass documented as by-design + dilog on bypassed blocked hosts (decision: keep, no prompt storm at launch).
  • Update defaultSUAutomaticallyUpdate true via plist + registered default + one-time v3 migration clearing the v2-era stored false; later user choice wins (tested).

Test Plan

  • Unit + socket-integration CI green
  • Live-verified pre-merge: stale-ref error and reparent-under-split-churn on a tagged build (done, see PR description)
  • Manual after ship: docked Web Inspector through split churn and workspace round-trips (M5 scenarios 1–5 in WebKitSubviewTransfer.swift's doc comment)
  • Manual after ship: next update installs without a pill click

Audit 2026-08-20 M6a/M8 (decided: prune + stale errors). Element refs now
carry a per-surface navigation generation, bumped from the navigation
delegate's didCommit; resolving a ref captured on a previous page returns
stale_element instead of silently re-matching the selector on the new page —
verified live: navigate then click a pre-navigation ref errors. The v2 handle
maps are swept at refresh time for dead UUIDs under the existing lock; the
ordinal counter is untouched so a ref is never reissued for a different
object (invariant covered by a new test).
…t paths

Audit 2026-08-20 M5 (and 2026-08-19 N9). The portal and local-host reparent
copies had diverged: only the local-host copy had the slot-local fast path
from efc759e (DevTools-after-workspace-switch fix). Both call sites now
share WebKitSubviewTransfer, which applies the per-view fast path wherever
endpoints qualify and window-relative conversion otherwise; the portal path's
old top-level same-container guard was verified dead at both call sites and
dropped. Smoke-verified: a live browser pane dragged across splits keeps a
rendering, snapshot-responsive webview. Net -150 lines.
Audit 2026-08-20 M4 (decided: keep + document). Session/profile restore
reloading plaintext http tabs without the prompt is a deliberate trade
(N prompts at launch is hostile); the bypass function now says so, and
restore-class bypasses of blocked hosts log to the release diagnostics
channel.
Audit 2026-08-20 L4. A corrupt or schema-bumped primary snapshot silently
dropped the whole restore while intact archives sat in session-history/.
Startup now tries the 5 newest history entries (same-version, >=1 window)
before giving up, and logs the outcome to the release diagnostics channel —
a version-mismatch drop after an update previously looked identical to data
loss. Strict load() semantics unchanged for its other callers; covered by
three behavioral tests.
Audit 2026-08-20 M12 (decided: keep current + previous). The finalize script
now prunes old version directories after a new binary lands — anchored rm,
symlinks skipped, failures never fail the connect, retention by mtime since
lexical sort misorders CI-run patch numbers. Covered by a test that runs the
generated script against a synthetic HOME and asserts real filesystem
outcomes.
Decided 2026-08-20 (audit follow-up): the single-lane fix-forward release
model only works if fixes reach users, and a crash-looping user never clicks
the pill. Plist and registered defaults flip to true, and a one-time v3
migration clears the concrete false the v2 migration wrote into every
existing install — a post-migration Settings choice wins permanently. The v2
block no longer writes the key at all. Covered by a migration test.
@arzafran
arzafran merged commit 04c96d9 into main Aug 20, 2026
8 checks passed
@arzafran
arzafran deleted the fix/audit-wave-2 branch August 20, 2026 13:58
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.

1 participant