LearnNewsExamplesServices
Frontmatter
id15531
titleE8: Electron app lifecycle + tray — hide the cockpit, quit explicitly
stateClosed
labels
enhancementaiarchitecture
assigneesneo-gpt-emmy
createdAtJul 18, 2026, 9:56 PM
updatedAtJul 19, 2026, 6:26 AM
githubUrlhttps://github.com/neomjs/neo/issues/15531
authorneo-gpt-emmy
commentsCount1
parentIssue13377
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJul 19, 2026, 6:26 AM

E8: Electron app lifecycle + tray — hide the cockpit, quit explicitly

Closed Backlog/active-chunk-7 enhancementaiarchitecture
neo-gpt-emmy
neo-gpt-emmy commented on Jul 18, 2026, 9:56 PM

Context

ADR-0034 §2.1.5 and §5 reserve E8 under epic #13377: the organism outlives its windows, the cockpit hides instead of being destroyed, and Brain teardown happens only on explicit quit. #14793 remains the broader native-shell UX authority; this leaf is its shell-lifecycle implementation slice.

The former architecture/build blockers are gone (#13033 and #14786 are closed). Live source still carries the deliberate pre-E8 simplification: harness/main.mjs line 731 handles window-all-closed by calling app.quit(), and createHarnessWindow() returns the primary BrowserWindow without a durable cockpit-lifecycle owner. harness/README.md lines 174–175 names this exact gap.

Problem

Closing the cockpit currently destroys its last renderer and quits the shell. That violates ADR-0034 twice: the Brain does not outlive its windows, and the client-scoped SharedWorker heap (stores, undo state, live UI identity) is destroyed while a future tray would claim the institution is still running.

The repair must stay shell-owned. Electron materializes and frames windows; it does not become a second Neo window manager, agent controller, or health poller.

Contract

  • The primary cockpit BrowserWindow is retained by one shell lifecycle owner.
  • A user close request on that cockpit is intercepted and mapped to hide() while the app is running. The exact same renderer/SharedWorker client is shown again from the tray; no destroy/recreate shortcut.
  • window-all-closed no longer quits the app. Only an explicit Quit action (tray/app menu or an equivalent OS quit intent) permits cockpit destruction and Brain teardown.
  • The tray is the last-window handle. Its running | degraded | stopped state derives from the existing main-process Brain lifecycle owner and its events; no second polling loop or independently inferred health truth.
  • The minimum E8 menu exposes the current state, Open Cockpit, and Quit. Individual agent start/stop control remains on the existing Fleet control-plane surface; this leaf does not invent a shell actuator.
  • Smoke/error exits keep their bounded app.exit(...) safety semantics and continue to tear down only the Brain children this harness owns.

Contract Ledger

Target Surface Source of Authority Proposed Behavior Fallback / Edge Case Docs Evidence
Shell lifecycle owner (harness/) ADR-0034 §2.1.5; E8 row Retain the primary cockpit and the tray for the app lifetime If the cockpit failed to boot, Open Cockpit reports/retains degraded truth; it never creates a duplicate owner owner JSDoc + harness/README.md unit lifecycle matrix + headed shell witness
Cockpit close event ADR-0034 §2.1.5; #14793 refinement comment prevent default and hide() while not explicitly quitting repeated close/hide is idempotent; popup closes do not hide the cockpit same same-window/webContents identity before hide and after show
window-all-closed ADR-0034 §2.1.5 suppress Electron's default quit explicit quit remains reachable from tray/app menu same app remains ready with zero visible windows
Tray handle + state triad #14793 §3 consuming ADR-0034's one lifecycle owner event-derived `running degraded stopped`; Open Cockpit shows/focuses the retained window; Quit enters explicit teardown no icon/menu action may claim a healthier state than the owner
Explicit quit / Brain teardown ADR-0034 §2.1.1–.5; existing will-quit owner mark explicit quit, permit window destruction, settle teardownBrain() exactly once, then exit repeated quit intents coalesce; no orphan child tree existing teardown JSDoc + README unit exact-once control + harness smoke/quit receipt
Smoke/error nets existing smokeMode, unhandledRejection, timeout paths preserve bounded exit and explicit owned-child teardown E8 handlers cannot turn smoke completion into a resident tray process spec header existing smoke plus E8 regression control

Acceptance Criteria

  • Closing the cockpit hides it; the app and supervised Brain remain alive; Open Cockpit restores the same BrowserWindow/renderer generation and same SharedWorker-backed UI identity.
  • window-all-closed does not quit. Explicit Quit is the only normal path that destroys the cockpit and tears down the Brain; teardown is exact-once under repeated quit intents.
  • One tray handle ships with an event-derived running | degraded | stopped state plus Open Cockpit and Quit. No second health poller and no new individual-agent actuator are introduced.
  • Popup-window close remains ordinary popup close; only the retained cockpit receives hide-on-close semantics.
  • Smoke mode remains terminal and non-resident; existing UI+Brain smoke stays green.
  • Unit evidence covers close/hide/show, zero-window survival, repeated explicit quit, state projection, and smoke bypass. A headed Electron witness proves same renderer/SharedWorker identity across hide/show and clean Brain teardown on Quit.
  • harness/README.md retires the pre-E8 simplification note and documents the tray/lifecycle contract.

Rejected Shapes / Negative ROI

  • Destroy/recreate the cockpit: kills the shared client heap and makes restoration a serialization problem ADR-0034/0029 already reject.
  • Keep an invisible sacrificial window: hides the lifecycle defect behind a second renderer owner.
  • Poll health from the tray: creates split-brain truth beside the existing main-process lifecycle owner.
  • Pull dock placement, first-run setup/TTFP, or individual agent controls into E8: crosses the shell/product/control-plane authority boundaries isolated by #14793's intake.

Out of Scope

First-run/setup/TTFP UI · promoted-window topology restoration · individual agent lifecycle controls · auto-update/signing · custom titlebars · Electron-owned window choreography.

Related

Parent: #13377 · design consumer: #14793 · ADR source: learn/agentos/decisions/0034-electron-shell-architecture.md §2.1.5 / §5 E8 · roadmap: v13.2 downloadable harness.

Duplicate sweep (2026-07-18): #13377 sub-issues contain E1, ADR, and E6 only; all-state searches for tray app lifecycle, window-all-closed, hide not destroy cockpit, and explicit quit tray found no E8 implementation leaf.

Origin Session ID: 019f6981-3a8c-7530-a68b-50a2788698d0 Retrieval Hint: "E8 Electron tray hide cockpit explicit quit SharedWorker lifetime one lifecycle owner"

Authored by @neo-gpt-emmy (Emmy, GPT-5/Codex).