Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions apps/desktop-cef/src/worldscript_handler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <unordered_map>

#include "include/cef_app.h"
#include "include/cef_browser.h"
#include "include/cef_task.h"
#include "include/wrapper/cef_helpers.h"

Expand Down Expand Up @@ -61,6 +62,11 @@ void WorldScriptHandler::OnAfterCreated(CefRefPtr<CefBrowser> browser) {
printf("[worldscript_host] rust_core ping = %d\n", worldscript_rust_ping());
fflush(stdout);

// QNBS-v3: CefClient::GetAccessibilityHandler doesn't exist (PR #391's real finding) — that method is on CefRenderHandler instead, which is OSR-only ("when window rendering is disabled", include/cef_render_handler.h) and doesn't apply to this Views-based windowed host. SetAccessibilityState's own doc comment (include/cef_browser.h) confirms windowed browsers need only this one call: "all platform accessibility objects will be created and managed by Chromium's internal implementation" — no CefAccessibilityHandler required.
Comment thread
qnbs marked this conversation as resolved.
browser->GetHost()->SetAccessibilityState(STATE_ENABLED);
Comment thread
qnbs marked this conversation as resolved.
printf("[worldscript_host] accessibility_state_requested = true\n");
fflush(stdout);

CefPostDelayedTask(TID_UI, new PollShutdownTask(this), kShutdownPollIntervalMs);
}

Expand Down
4 changes: 2 additions & 2 deletions docs/architecture/native-readiness.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,12 @@ Wave 2's first deliverable — the CEF binding/C++ decision — is now backed by
| CEF renders reliably on Linux dev systems | DEBT — partial | cef-runtime, Wave 2 (in progress) | Two data points now (dev-machine spike + CI-run PR #388 on GitHub Actions `ubuntu-latest`), the second of which renders the **real production bundle** (not `about:blank`) with a verified exact title, not just a blank page. Still one GPU config per machine, no sandbox, mainly X11/Xvfb (Wayland now also smoke-proven, see the dedicated row below). Exit condition (unchanged from roadmap §2's Wave 2 exit criteria): broader Linux/GPU/display-server matrix coverage (Appendix A.3) before this can flip to PASS. |
| Wayland display-server smoke | **PASS** — single-runner smoke only | cef-runtime, Wave 2 | PR #393: `worldscript_host` (the exact binary already proven under X11) also renders the real production bundle under a headless Weston Wayland compositor (`--ozone-platform=wayland`), same FFI-boundary + exact-title checks as the X11 harness, CI-run and non-blocking (roadmap §44.2). Grounded in real evidence before attempting: Chromium's own upstream GN default compiles Wayland Ozone support into every standard Linux build, and CEF's `tools/gn_args.py` has no override disabling it. Does **not** satisfy roadmap §44.2/§44.5's real-hardware/compositor matrix (NVIDIA/AMD/Intel × KDE/GNOME) — one virtual CI runner, one compositor implementation (Weston headless), no real GPU. |
| CEF lifecycle assumptions documented | **PASS** | cef-runtime | `docs/cef/knowledge/subprocess-and-shutdown.md`'s core Wave 2 claim (SIGTERM → graceful `TryCloseBrowser`/`OnBeforeClose`/`CefQuitMessageLoop`/`CefShutdown`, repeated clean start/close cycles) now has a real linked chain: test (`scripts/cef/run-launch-cycle-proof.mjs`) → CI job (`🧪 CEF Learning Harness`) → doc, exactly what §61.1.4 requires. Save-coordinator/window-state persistence remain explicitly Wave 5+ scope (not a Wave 2 gap); Windows/macOS and a real packaged layout remain open, tracked in the doc's own "Outline" section. |
| Early Accessibility Gate | Not yet attempted (real blocker found) | cef-runtime, Wave 2 | PR #391 attempted `CefAccessibilityHandler` — does not compile against CEF 151.3.18 (`CefClient::GetAccessibilityHandler()` doesn't exist in this version). Reverted rather than left half-working, after a fallback attempt (enable-only, no observability) regressed the previously-reliable FFI/rendering proofs. Real CEF-151 API research needed before the next attempt — see `docs/cef/knowledge/cef-architecture-primer.md`. |
| Early Accessibility Gate | **PASS** — state enablement only, tree observability open | cef-runtime, Wave 2 | PR #391 found the real root cause: `GetAccessibilityHandler()` is declared on `CefRenderHandler` (OSR-only, "when window rendering is disabled"), not `CefClient` — never reachable from this windowed host regardless of what was inherited. PR #397: `CefBrowserHost::SetAccessibilityState(STATE_ENABLED)` alone is windowed-mode-correct per its own doc comment; CI-proven in every one of 3 repeated cycles with zero regression to the FFI/rendering/crash-reporting/Wayland proofs. Does **not** yet prove the platform accessibility tree is observable — that needs OS-level AT-SPI introspection on Linux, separate unattempted follow-up — see `docs/cef/knowledge/cef-architecture-primer.md`. |
| Sandbox posture | Not yet attempted | desktop-security, Wave 2/3 (roadmap §12) | Every run so far used `no_sandbox=true`; zero evidence either way on this row. |
| Crash reporting / renderer-crash resilience | **PASS** — crash-reporting half only | cef-runtime | PR #392: `crash_reporter.cfg` + `CefCrashReportingEnabled()` verified true, `chrome://crash` deliberately crashes the renderer, `CefRequestHandler::OnRenderProcessTerminated` fires (`TS_PROCESS_CRASHED`), the browser process/message loop survive, and a real Crashpad `.dmp` file — the harness's actual assertion, alongside Crashpad's own `.meta`/`settings.dat` housekeeping files (observed, not independently asserted) — is produced under an overridden `BREAKPAD_DUMP_LOCATION`; all CI-run, not a doc claim. Symbolization (decoding the dump into a stack trace via `dump_syms`/`minidump_stackwalk`) needs a full Chromium source checkout and was not attempted — see `docs/cef/knowledge/cef-architecture-primer.md`. |
| CEF SDK fetch/verify + version diagnostics automated | **PASS** | cef-runtime | `🧪 CEF Learning Harness` CI job (`.github/workflows/cef-learning-harness.yml`) fetches the pinned CEF SDK, verifies its checksum, and parses real version macros out of the extracted `include/cef_version.h` — a genuine CI-run check, not a doc claim. |
| Linux dependency inventory — clean-machine data point | DEBT — partial | cef-runtime | Same CI job runs the package-presence check against a stock `ubuntu-latest` runner before any `apt-get`, adding a real second data point beyond the spike's one already-configured dev machine. PR #395 added the specific check this row previously flagged as missing: `scripts/cef/check-linux-runtime-linkage.mjs` runs `ldd` against the real, already-built `worldscript_host` and `libcef.so` — both fully resolved on the runner, zero unresolved dependencies. Still narrow: one distro/runner image only, no packaged-installer dependency declaration. |
| CEF host build + repeated launch/close cycle proof, in CI | **PASS** | cef-runtime | PR #388: `apps/desktop-cef/`'s `worldscript_host` (real, repo-committed C++/Rust source, not spike code) builds against the fetched CEF SDK and runs 3 independently-verified clean start/close cycles under Xvfb in CI — the roadmap's literal "isolated learning harness" / "safe repeated startup/shutdown" deliverables (§3142), not just the fetch/diagnostics increment. |
| Rust FFI boundary proven inside the real host | **PASS** | cef-runtime, rust-core | `worldscript_rust_ping()` (rust-core, linked via Corrosion) is called from `OnAfterCreated` on every cycle and its exact sentinel value observed in CI output — stronger than the ADR-0020 spike's decoupled isolation test, since this proves the boundary works inside the actual multi-process CEF host, not a standalone C++ program. |

**Overall for this snapshot**: 7 PASS (crash reporting explicitly PASS for its reporting half only, not symbolization; Wayland explicitly PASS for a single-runner smoke only, not the real-hardware/compositor matrix), 2 explicit DEBT-in-progress rows (each with a concrete exit condition, not open-ended), 2 not-yet-attempted rows correctly left blank rather than assumed. No row is marked PASS without the evidence cited above.
**Overall for this snapshot**: 8 PASS (crash reporting explicitly PASS for its reporting half only, not symbolization; Wayland explicitly PASS for a single-runner smoke only, not the real-hardware/compositor matrix; Early Accessibility Gate explicitly PASS for state enablement only, not tree observability), 2 explicit DEBT-in-progress rows (each with a concrete exit condition, not open-ended), 1 not-yet-attempted row (Sandbox posture) correctly left blank rather than assumed. No row is marked PASS without the evidence cited above.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
12 changes: 6 additions & 6 deletions docs/cef/CEF-RUST-COMPETENCY-MATRIX.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# CEF/Rust Competency Matrix

**Companion to:** [`ROADMAP-CEF-DESKTOP-MIGRATION.md`](ROADMAP-CEF-DESKTOP-MIGRATION.md) §4.11, §61.1, Appendix A.1 · [ADR-0019](../adr/0019-cef-desktop-runtime-strategy.md)
**Established:** Wave 0, 2026-08-18. **Baseline was: nothing done yet.** Updated in place, 2026-08-18/19 (Wave 2, ADR-0020 spike + PR #386/#387/#388/#391/#392/#393), per this doc's own "Update discipline" below — items flip to `true` only with a linked evidence commit, in the same commit as the flip. This file exists so future waves have a live, gradeable target instead of re-deriving the checklist from the roadmap prose each time.
**Established:** Wave 0, 2026-08-18. **Baseline was: nothing done yet.** Updated in place, 2026-08-18/19 (Wave 2, ADR-0020 spike + PR #386/#387/#388/#391/#392/#393/#397), per this doc's own "Update discipline" below — items flip to `true` only with a linked evidence commit, in the same commit as the flip. This file exists so future waves have a live, gradeable target instead of re-deriving the checklist from the roadmap prose each time.

This is an engineering gate (roadmap §4.11.6), not a training checklist. `WS-CEF-IPC` (Wave 4) and any production storage capability exposing privileged native operations may not proceed until the relevant items below are `true` with linked evidence.

Expand All @@ -14,7 +14,7 @@ cef_competency:
repeated_shutdown_ci: true # scripts/cef/run-launch-cycle-proof.mjs, cef-learning-harness CI job (PR #388)
renderer_crash_ci: true # chrome://crash + OnRenderProcessTerminated + browser-process survival, cef-learning-harness CI job (PR #392)
sandbox_smoke: false
accessibility_smoke: false
accessibility_smoke: false # state ENABLEMENT is proven (PR #397, SetAccessibilityState, 3/3 CI cycles) — this field is specifically about the platform accessibility tree being observable, which needs OS-level AT-SPI introspection and was not attempted
crash_symbolization_smoke: false # crash REPORTING is proven (PR #392) — this field is specifically about decoding a dump (dump_syms/minidump_stackwalk), which needs a full Chromium source checkout and was not attempted
```

Expand All @@ -27,7 +27,7 @@ CI validation of this block ("fail CI when a required item for the active progra
| CEF architecture (process model, browser/frame/client ownership, message loop, shutdown ordering, subprocess packaging, sandbox expectations) | Partial | Process model, message loop, and shutdown ordering all have real working code + CI proof (`apps/desktop-cef/`, PR #388), now written up in `docs/cef/knowledge/cef-architecture-primer.md` (PR #390, no longer a skeleton). Subprocess *resource layout* (unpackaged CEF build output — `COPY_FILES`) is confirmed, but real shipped/installer packaging is separate, unproven, later scope. Sandbox expectations still have zero evidence. |
| CEF threading & lifetime rules (UI-thread callbacks, IO thread, ref-counted objects, callback lifetime, async cancellation, shutdown races) | Partial | `CEF_REQUIRE_UI_THREAD()` used throughout; `IMPLEMENT_REFCOUNTING`/`CefRefPtr` applied correctly; a real callback-lifetime lesson learned and fixed (`base::Unretained` vs. a plain `CefTask` — see `apps/desktop-cef/src/worldscript_handler.cpp`), now written up in `docs/cef/knowledge/threading-and-lifetimes.md` (PR #390, no longer a skeleton). IO thread, render-process-side code, and async-cancellation patterns remain untouched. |
| Rust binding layer (crate/version, unsafe/FFI boundary, wrapper ownership, API coverage gaps, upgrade procedure) | Partial | `apps/desktop-cef/rust-core/` (`worldscript_rust_core`, Corrosion-linked) — FFI boundary proven inside the real CEF host in CI (PR #388), not just an isolated test. No upgrade procedure written yet (`docs/cef/knowledge/binding-upgrade-playbook.md` still skeleton); API coverage is currently one trivial function, not representative of real surface area. |
| Cross-platform native host (Linux loader/resource layout, Windows process/installer/sandbox, macOS bundle/signing, window lifecycle, high-DPI, IME/a11y) | Partial (Linux only) | Linux loader/resource layout confirmed via a real filesystem listing in CI (`docs/cef/knowledge/linux-runtime-notes.md`); a real cwd-relative-path startup bug found and fixed. Zero Windows/macOS evidence. Window lifecycle proven for open/close only — high-DPI and IME/a11y untouched. |
| Cross-platform native host (Linux loader/resource layout, Windows process/installer/sandbox, macOS bundle/signing, window lifecycle, high-DPI, IME/a11y) | Partial (Linux only) | Linux loader/resource layout confirmed via a real filesystem listing in CI (`docs/cef/knowledge/linux-runtime-notes.md`); a real cwd-relative-path startup bug found and fixed. Zero Windows/macOS evidence. Window lifecycle proven for open/close only. Accessibility: state enablement proven (PR #397), tree observability (AT-SPI) and IME both still untouched. High-DPI untouched. |
| Operational CEF (crash reporting, symbol handling, version-update automation, sandbox verification, packaging deps, runtime diagnostics) | Partial | Packaging deps: `scripts/cef/check-linux-runtime-deps.mjs` (dpkg package presence) + `scripts/cef/check-linux-runtime-linkage.mjs` (PR #395 — real `ldd` against the CI-built runtime artifacts `worldscript_host` and `libcef.so`, both fully resolved on the CI runner), both CI-run. Runtime diagnostics: `scripts/cef/print-cef-version-diagnostics.mjs` + verbose CEF logging (`--enable-logging=stderr --v=1`) added mid-debugging this wave. Crash reporting: proven in CI (PR #392) — `crash_reporter.cfg` + `CefCrashReportingEnabled()` + a deliberately induced renderer crash (`chrome://crash`) produced a real Crashpad `.dmp` file (the harness's actual assertion) under an overridden `BREAKPAD_DUMP_LOCATION`, alongside Crashpad's own `.meta`/`settings.dat` housekeeping files (observed, not independently asserted); the browser process survived. Symbol handling (decoding a dump into a stack trace) needs `dump_syms`/`minidump_stackwalk` built from a full Chromium source checkout — out of reach of this project's minimal-CEF-SDK CI setup, not attempted. Version-update automation and sandbox verification remain not started. |

## Appendix A.1 checklist (live)
Expand All @@ -42,7 +42,7 @@ CI validation of this block ("fail CI when a required item for the active progra
[x] Unpackaged CEF resource layout proven — PR #388, real filesystem listing in CI (real shipped/installer packaging remains separate, unproven, later scope)
[x] Repeated startup/shutdown harness green — PR #388, 3/3 cycles, cef-learning-harness CI job
[x] Renderer crash observation green — PR #392, chrome://crash + OnRenderProcessTerminated (TS_PROCESS_CRASHED), browser process survived, cef-learning-harness CI job
[ ] Accessibility smoke green (attempted, real blocker — see cef-architecture-primer.md's "Accessibility API" section)
[ ] Accessibility smoke green (state enablement proven, PR #397, 3/3 CI cycles, zero regression; tree observability — AT-SPI introspection — still open, see cef-architecture-primer.md's "Accessibility API" section)
[ ] Crash-reporting/symbolization smoke green (crash-reporting half proven — PR #392, real Crashpad dump produced in CI; symbolization/decoding the dump not attempted, needs a full Chromium source checkout — see cef-architecture-primer.md)
[ ] Linux dependency inventory complete (inventoried + ldd-verified against the real CI-built runtime artifacts (worldscript_host, libcef.so), PR #395 — still one distro/runner image, no packaged-installer declaration; see native-readiness.md)
[x] X11/Wayland initial smoke complete — PR #393: X11 proven since PR #388 (Xvfb); Wayland now also proven (headless Weston compositor, --ozone-platform=wayland, same FFI+title checks, cef-learning-harness CI job). Real-hardware/compositor matrix (roadmap §44.2/§44.5 — NVIDIA/AMD/Intel × KDE/GNOME, real graphics hardware) remains unproven; this is one virtual-CI runner only.
Expand All @@ -62,7 +62,7 @@ CI validation of this block ("fail CI when a required item for the active progra
[x] renderer termination observed and handled — PR #392, chrome://crash deliberately crashes the renderer, OnRenderProcessTerminated fires, browser process/message loop survive, cef-learning-harness CI job
[ ] sandbox development plan validated
[ ] Linux runtime dependencies inventoried (inventoried + ldd-verified against the real CI-built runtime artifacts (worldscript_host, libcef.so), PR #395 — still one distro/runner image, no packaged-installer declaration; see native-readiness.md)
[ ] at least one accessibility smoke test performed (attempted, real blocker — see cef-architecture-primer.md's "Accessibility API" section)
[ ] at least one accessibility smoke test performed (state enablement proven, PR #397, 3/3 CI cycles, zero regression; tree observability — AT-SPI introspection — still open, see cef-architecture-primer.md's "Accessibility API" section)
[x] at least one crash-reporting/symbolization path proven — PR #392: crash-reporting path proven end-to-end (real Crashpad dump produced in CI); full symbolization (decoding the dump) is a separate, unattempted step needing a full Chromium source checkout
[ ] upgrade playbook exists
```
Expand All @@ -76,7 +76,7 @@ Superseding the original "Wave 0 does not claim" list, now that some of those it
- The CEF integration approach **has** been selected (Option B, ADR-0020) — this is no longer an open item.
- A learning harness **does** exist and runs in CI (`cef-learning-harness`, PR #388) — this is no longer an open item.
- Still true: no external-expertise engagement has been triggered — none of the escalation criteria (roadmap §4.11.5) have occurred.
- Still true, and still the most important caveat: this is Linux-only (X11 proven since PR #388, Wayland smoke also proven PR #393 — but one virtual CI runner, no real GPU/hardware matrix), `no_sandbox=true` throughout, no dump symbolization (crash *reporting* is proven), no working accessibility mechanism (a real CEF-151 API blocker was found and documented, not silently skipped), and no upgrade-playbook prose exists yet (`docs/cef/knowledge/binding-upgrade-playbook.md` remains a skeleton — architecture, threading, and binding-cookbook docs are no longer skeletons, PR #390). The competency gate above is explicitly **not** satisfied.
- Still true, and still the most important caveat: this is Linux-only (X11 proven since PR #388, Wayland smoke also proven PR #393 — but one virtual CI runner, no real GPU/hardware matrix), `no_sandbox=true` throughout, no dump symbolization (crash *reporting* is proven), no accessibility-tree observability (state *enablement* is proven, PR #397 — its own real root cause was found rather than staying blocked, but the tree itself is still unverified), and no upgrade-playbook prose exists yet (`docs/cef/knowledge/binding-upgrade-playbook.md` remains a skeleton — architecture, threading, and binding-cookbook docs are no longer skeletons, PR #390). The competency gate above is explicitly **not** satisfied.
- This matrix will continue to be updated in place as each item is genuinely satisfied, with a link to the proving test/CI job/doc (roadmap §61.1.4 evidence-link pattern) — not marked done on intention alone.

## Update discipline
Expand Down
Loading
Loading