Skip to content

Production-polish: failure-boundary hardening, API hygiene, CDP-filter CI, docs#10

Merged
wenkaifan0720 merged 5 commits into
mainfrom
dig/production-polish
Jun 24, 2026
Merged

Production-polish: failure-boundary hardening, API hygiene, CDP-filter CI, docs#10
wenkaifan0720 merged 5 commits into
mainfrom
dig/production-polish

Conversation

@wenkaifan0720

Copy link
Copy Markdown
Collaborator

Summary

Production-grade polish for flutter_cef as a standalone (git-consumed) package, driven by an 8-dimension readiness audit. Verdict: well-engineered; the gap was failure-boundary hardening + enforcement + publishability polish — addressed here. (Publishing to pub.dev is deliberately out of scope per the maintainer; the package stays git-consumed, so the path-dep model is unchanged.)

Correctness / failure boundary

  • processGone now fails pending eval/cookie futures (was: hang forever on a host crash — the likeliest failure).
  • dispose() is idempotent (no throw on double-dispose).
  • enableAgentControl tolerates a partial native reply (null, not a TypeError).
  • CdpRelay.writeAll retries on EINTR (the last pipe writer still treating a signal as a dead socket).
  • JS-dialog handler errors are surfaced via FlutterError.reportError instead of swallowed.

Security

  • Corrected the enableAgentControl dartdoc — the token is required (matches the 401 gate), not optional.
  • Found + fixed a real pre-existing bug: the CDP per-tile isolation filter suite had a stale setAutoAttach assertion that was failing — but CI never ran the suite. Fixed the assertion (the relay correctly intercepts a browser-level setAutoAttach to prevent cross-tile control leak) and wired run_filter_tests.sh into CI.

API hygiene

  • Added removeJavaScriptChannel (Dart-only: stops delivery; the page-side shim is process-global on a shared profile, so tearing it down would hit siblings).
  • Marked sendPointer/sendKey @internal (raw wire encodings driven by CefWebView).
  • Documented external-controller ownership on CefWebView.controller.

Packaging / CI

  • macOS podspec version skew 0.1.30.2.0 + a 0.2.0 CHANGELOG entry.
  • Trimmed root + platform-interface descriptions under pub's 180-char limit.
  • CI now analyzes the sub-packages and runs the CDP-filter security suite.
  • Replaced the self-crashing example RunnerTests stub with a real dispatch test.

Tests

New: processGone-fails-pending, dispose-twice, enableAgentControl-nullable, removeJavaScriptChannel, processGone-reason, paintStalled — 58 controller tests total.

Docs

  • README: a symptom-keyed Troubleshooting section, the cmake+ninja build prerequisite, and the previously-untoured public API (removeJavaScriptChannel, onProcessGone, onPaintStalled, setVisible, enableCdp/cdpPort).
  • New CONTRIBUTING.md: federated layout, building cef_host, and the exact local check sequence CI runs.

Verification

flutter analyze clean (package + sub-packages + example); 58 Dart tests pass; CDP filter suite ALL PASS; the shared-host channel integration probe passes against a real cef_host.

Deferred to a follow-up PR — deeper consolidation

A coherent refactor wave best reviewed on its own: a shared Swift CefWire codec + CefOp enum, named wire constants in cef_input, a CefMethods/CefEvents source of truth, and native main.mm tidy-ups. These touch the IPC opcode space across the Swift + native layers and want a build-verified pass. Tracked from the audit backlog.

🤖 Generated with Claude Code

wenkaifan0720 and others added 5 commits June 24, 2026 15:23
…rol security doc

- processGone now fails pending eval/cookie futures before notifying the consumer
  (a host crash is the likeliest failure; in-flight round-trips otherwise hang forever).
- dispose() is idempotent (a second call returns early) — an externally-owned
  controller disposed twice no longer throws via the ValueNotifier asserts.
- enableAgentControl tolerates a partial native reply (returns null, not a TypeError);
  its dartdoc now states the token is REQUIRED (matches CdpRelay's 401 gate), replacing
  the stale "token is not the gate" claim.
- _handleJsDialog reports a throwing app handler via FlutterError.reportError (still
  fails closed) instead of swallowing it.
- Document external-controller ownership on CefWebView.controller (you dispose what you
  pass — the single most likely resource leak).

Adds tests for processGone-fails-pending, dispose-twice, and the nullable reply.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ter suite in CI

The CDP per-tile isolation filter suite had a stale assertion: it expected a
browser-level Target.setAutoAttach(flatten) to be FORWARDED, but the relay correctly
INTERCEPTS it (self-attaches + synthesizes attachedToTarget, H2) to prevent cross-tile
control leak. The failure went unnoticed because CI never ran the suite. Fix the
assertion to match the (correct) interception behavior, and wire run_filter_tests.sh
into CI so the security keystone is gated on every PR; also analyze the sub-packages.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…e the example test

- macos podspec 0.1.3 -> 0.2.0 to match its pubspec, with a 0.2.0 CHANGELOG entry
  (profiles, multi-view shared host, agent-control CDP relay, reliability).
- Trim the root + platform-interface pubspec descriptions under pub.dev's 180-char limit.
- Replace the example RunnerTests stub (it tested a non-existent verb and force-cast the
  result, crashing if ever run) with a real unknown-verb dispatch test.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… CdpRelay EINTR

- Add removeJavaScriptChannel (stops delivery; the process-global page-side shim is
  intentionally left intact since tearing it down would also remove it from sibling
  views on a shared profile).
- Mark sendPointer/sendKey @internal — they are raw wire encodings driven by
  CefWebView, not supported public API (adds the `meta` dep).
- CdpRelay.writeAll now retries on EINTR — the last pipe writer still treating a
  signal as a dead socket (matches CefProfileHost + the C++ host side).

Tests: removeJavaScriptChannel stops delivery; processGone reason default/passthrough;
paintStalled callback.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- CONTRIBUTING.md: federated layout, building cef_host (cmake+ninja), and the
  exact local check sequence CI runs (analyze x4, flutter test, the CDP-filter
  security suite, the real-host integration probes).
- README: a symptom-keyed Troubleshooting section (blank texture, hardware-access
  SIGABRT, ephemeral-profile downgrade, 'locked', paint-stall, CDP 401) and the
  cmake+ninja build prerequisite.
- README API tour: document the previously-untoured public members —
  removeJavaScriptChannel, onProcessGone, onPaintStalled, setVisible,
  enableCdp/cdpPort (with the agent-control contrast).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@wenkaifan0720 wenkaifan0720 merged commit 0d6fedb into main Jun 24, 2026
1 check passed
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