Repository navigation
Complete host-driven native close veto lifecycle #87
Description
Activity
First implementation commit:
378dd29don consolidated draft PR #76, with the Cocoa host in SceneTech/AppScene029da1fb/ draft PR SceneTech/AppScene#65.Implemented: bounded HTTP(S) handoff, top-level focus/close requests, scripted beforeunload close veto,
location.reload(), Promise-based Element/Document fullscreen entry/exit with state andfullscreenchange, nativedocument.hasFocus()plus focus/blur propagation, existing visibility state/events, navigation cancellation, explicit completion failures, and an oversized JSON request discard contract.Repository CI is running. This stays open for native-initiated fullscreen synchronization, close-button veto qualification, typed request structs, transition/queue performance metrics, Windows/Linux packaged host qualification, and the combined Code OSS interaction gate.
Implemented at
da6ee30492294b94541ea5137d741916e53e4a2fin draft PR #76. Hosted macOS/Ubuntu/Windows, NativeAOT, native Linux, all three packaged RIDs, installed consumers, cross-RID evidence, and release-package verification pass. Contracts cover bounded focus/close/reload/fullscreen/external-URL requests, close veto, visibility/focus propagation, queue overflow, navigation cancellation, and stale completions.Reopening for the unchecked native close-button contract. Stack #186 completed the JavaScript-to-host path, but the reverse OS-to-browser lifecycle path is still absent.
Exact gap:
window.close()dispatches cancelablebeforeunloadin WebScene before it emitsWEBSCENE_HOST_REQUEST_WINDOW_CLOSE_V1; AppScene then closes the Cocoa window. This path is veto-aware.- A user or automation closing the native
NSWindowenters AppScenewindowWillClose/begin_closedirectly. No WebScene ABI lets AppScene ask the active top-level realm to dispatchbeforeunload/pagehideand return the allow/veto decision before teardown. - Packaged normal-close exit 0 therefore proves safe teardown, but it does not prove Code OSS
BrowserLifecycleServiceshutdown notification, storage flush, orwindow.confirmBeforeCloseveto on an OS close.
Recommended focused stack order:
- WebScene: add a versioned host-driven top-level close-request ABI with an explicit allow/veto/error result; dispatch cancelable
beforeunloadin the active realm, run the microtask checkpoint, and dispatch the noncancelable terminal lifecycle event only after an allow decision. Cover stale/no-realm/error behavior and repeated requests. Because the browser workbench rejects async vetoes, the current consumer needs a bounded synchronous decision rather than an unbounded callback. - AppScene: consume the optional ABI from
windowShouldClose, returnNOon veto, and distinguish an already-approved JavaScriptwindow.close()host request so it does not dispatchbeforeunloadtwice. Preserve an explicit compatibility policy when the symbol is absent. - Packaged Code OSS: verify native close veto with
window.confirmBeforeClose, allowed close with lifecycle/storage evidence, repeated normal close, and teardown. Keep external-link/fullscreen/reload package checks alongside this gate.
The existing typed desktop ABI and pending-host teardown from merged Stack #186 remain the prerequisite. SceneTech/AppScene#67 stays open for layer 2 and combined acceptance; AppScene #100 independently fixed composite visibility state.
- changed the title
[-]Add typed native window lifecycle and fullscreen host contracts[/-][+]Complete host-driven native close veto lifecycle[/+]on Sep 16, 2026 The generic host-driven close contract is now merged in #202 (
c83432769ab41ff14c26aa901b2e713503e76ab1).Evidence:
webscene_engine_request_window_close_v1returns explicit error/allow/veto decisions and runs on the owning V8 worker while the host waits synchronously through a bounded queue/wait.- The active top-level realm receives cancelable
beforeunload; its microtask checkpoint drains before the result. Veto suppresses terminal lifecycle. Allow dispatches one noncancelablepagehidewithpersisted=false; repeated approved requests coalesce until navigation. - The focused lifecycle/error/repeat regression passes. Its 10,000-decision gate completed in about 0.061s locally, and the exact PR head passed
portable-v8-contract. - The first consumer is merged in SceneTech/AppScene#102 (
9d627ea3aeb2444bf5a467370c7eff2950453ca5): CocoawindowShouldClosehonors veto/error and bypasses exactly one decision for an already approved JavaScriptwindow.close()request.
The remaining acceptance is the packaged Code OSS close-veto/storage/lifecycle qualification tracked by SceneTech/AppScene#67. Leaving this issue open until that cross-repository acceptance is recorded.
Closed by the merged typed host/window lifecycle contracts and exact packaged acceptance.
Source coverage is complete through PRs #202/#206 and the terminal lifecycle fixes #215 (
547395f2) and #217 (13c93852). Focused portable runners passed. Inspector Release gates completed 10,000 native decisions in 0.057832 seconds and 10,000 script closes in 0.00124571 seconds with stable V8 heap.Against final WebScene
24db1a2f/ AppScened7cbbaf9, three packaged Code OSS cycles each passed external-link handoff, fullscreen enter/exit, top-level reload, native close veto, and JavaScript-approved close. Every cycle observedbeforeunloadcounts 0→1→2 and exactly one terminalpagehide; recursive/capacity behavior remained bounded and repeated teardown left no processes. This satisfies the browser API, host denial/veto, ordering, capacity, reload, and packaged desktop round-trip scope. Consolidation PR #76 stays draft/open/unmerged.
AppScene coordination epic: SceneTech/AppScene#66
Problem
Unchanged browser applications use standard window/document APIs for close, focus, fullscreen, visibility, and external navigation. WebScene already translates HTTP(S) anchors and
window.openinto bounded host requests, but the Runtime contract has no typed close/focus/fullscreen completion path and visibility changes from the native window are incomplete. Code OSS's browserIHostServicecalls these APIs directly.Proposed contract
window.opencontinues system-browser handoff until that capability is implemented.Acceptance criteria
window.close/focus,Element.requestFullscreen,Document.exitFullscreen, fullscreen state/events, focus/blur,document.hidden,visibilityState, and reload.This is a standard browser/runtime boundary. Platform window operations remain AppScene's responsibility.