LearnNewsExamplesServices
Frontmatter
id15706
titlePackaged App Worker selects the browser Fleet transport
stateClosed
labels
bugaitestingregression
assigneesneo-gpt-emmy
createdAtJul 22, 2026, 2:17 PM
updatedAtJul 22, 2026, 7:14 PM
githubUrlhttps://github.com/neomjs/neo/issues/15706
authorneo-gpt-emmy
commentsCount4
parentIssuenull
subIssues[]
subIssuesCompleted0
subIssuesTotal0
contentTrust
projected
quarantined0
signals[]
blockedBy[]
blocking[]
closedAtJul 22, 2026, 7:14 PM

Packaged App Worker selects the browser Fleet transport

Closed Backlog/active-chunk-8 bugaitestingregression
neo-gpt-emmy
neo-gpt-emmy commented on Jul 22, 2026, 2:17 PM

Context

The packaged Brain-on witness for #15524 reached the requested first-paint state, but the broader Fleet lifecycle smoke stayed red:

  • productWitnessPassed: true
  • brainMode: true, brainUp: true, packagedMode: true
  • exact first paint at 457 ms with 10 visible cards, static roster · offline, sample · live feed pending, and zero tour controls
  • firstWorkerCrossing: false
  • workerAfterPopupClose: false
  • smokeState.fleetMethods contained three shell-window listAgents calls and no fleetRoster

The screenshot matched the receipt: the packaged Brain was running, while the Fleet cockpit still rendered “Fleet server offline.” This is not a #15524 first-paint failure; it is a separate regression in the real App Worker request path promised by #15537 / PR #15566.

The Problem

The packaged AgentOS App Worker never selects the shell-owned Fleet transport. Its bridge therefore installs the direct-browser branch without an App-Worker bearer, fails closed, and never sends fleetRoster through Neo.Main.fleetRequest.

The Electron main capability itself is live: the same packaged run completed three admitted listAgents calls from shell windows. Brain startup, Fleet authentication, and main-process dispatch are therefore not the failed boundary measured here.

Architectural Reality

The topology predicate reads a redundant field instead of deriving from the existing authoritative URL contract:

  • Both worker creation paths in src/worker/Manager.mjs already serialize the absolute main-thread location.href plus search into config.url.
  • href is the authoritative, serializable URL fact; new URL(href).protocol deterministically yields app:, http:, or https: without a second field that can drift.
  • No later App Worker registration path enriches the envelope, and none is needed. The consumer should derive the scheme from href.
  • Consequently the current Neo.config.url.protocol read is undefined in both source and packaged App Workers, so the packaged app: branch is unreachable by construction.

PR #15566 introduced the protocol read while completing #15537. Its PR contract explicitly required a real App Worker request witness, but the headed L3 check was deferred; the first packaged Brain-on run now supplies the missing falsifier.

The repair must preserve ADR 0034’s authority boundary: the packaged branch uses the named main-owned capability and never receives bearer bytes; direct-browser mode remains a separate, fail-closed topology.

Contract Ledger

Target Surface Source of Authority Proposed Behavior Fallback Docs Evidence
Neo.config.url.href worker-registration envelope Main-thread location.href snapshot already serialized by both src/worker/Manager.mjs paths Retain {href, search} and derive the scheme at the AgentOS consumer with new URL(href).protocol; do not add a redundant protocol field Missing or malformed href fails before bridge installation; never infer shell mode from query data Intent-level JSDoc on the consumer derivation helper Focused {href, search} consumer regression plus packaged Brain-on smoke across both worker crossings
AgentOS Fleet transport selection apps/agentos/app.mjs::onStart() + ADR 0034 §2.2/§2.3 app: selects the named main-owned Fleet capability; browser origins retain the authenticated HTTP branch No bearer rejects locally in browser mode; no live shell window returns a named error Existing topology comments in apps/agentos/app.mjs Initial-worker and late-worker contract tests; fleetRoster crossings before/after popup close
Fleet credential custody ADR 0034 §2.3.4–.6 Protocol fact is non-secret; bearer bytes remain main/Brain-owned and absent from worker config Fail closed without admitted capability ADR 0034 Secret census + wrong-bearer/foreign-listener smoke assertions

Decision Record impact

Aligned-with ADR 0034. The ticket repairs the existing URL/topology contract so the accepted shell capability boundary becomes reachable; it does not amend process ownership, renderer security, or credential custody.

Acceptance Criteria

  • The App Worker derives the URL scheme from the authoritative serialized href; no redundant protocol field is added for initial or late workers.
  • A packaged Brain-on run sends fleetRoster through Neo.Main.fleetRequest; an empty isolated registry is a valid response and must not be mislabeled as a transport failure.
  • The existing smoke proves firstWorkerCrossing: true before popup close and workerAfterPopupClose: true after popup close.
  • The primary window and same-origin popup retain one shell-owned capability contract; closing the popup does not strand the retained cockpit.
  • Direct-browser mode still selects its authenticated HTTP transport and remains locally fail-closed without a bearer.
  • Bearer bytes remain absent from App Worker state, URLs, IPC replies, logs, and persisted configuration.
  • Regression tests pass the existing {href, search} producer shape through the AgentOS topology selector and prove app: versus browser behavior; the packaged smoke remains the real initial/late crossing witness.
  • The packaged Brain-on smoke exits green without weakening its independent first-paint, off-origin, teardown, or port-release assertions.

Out of Scope

  • #15524’s first-paint semantics; the packaged product witness already passes.
  • Deterministic host/profile fleet-registry isolation and its populated-roster UI witness (#15680).
  • New Fleet verbs, provider acquisition, or business-method semantics.
  • Moving Fleet bearer or endpoint authority into Body/App Worker state.
  • Replacing the direct-browser development topology.

Avoided Traps

  • Treating brainUp: true or shell-window listAgents as proof that the App Worker crossed.
  • Adding a second packaged transport instead of repairing the existing registry-bridge composition.
  • Duplicating location.protocol into worker config when the already-serialized absolute href owns the same fact.
  • Reading a secret or topology selector from query parameters.
  • Fixing only initial worker creation while leaving late startWorker() divergent.
  • Weakening the smoke by removing fleetRoster crossing assertions.

Related

  • #15537 / PR #15566 — private Electron Fleet capability and the regressed App Worker composition
  • #15524 — packaged first-paint witness that exposed this independent failure
  • #15680 — separate source-E2E host-registry isolation defect
  • learn/agentos/decisions/0034-electron-shell-architecture.md

Live latest-open sweep: checked the latest 20 open issues on 2026-07-22; no equivalent found. Targeted all-state searches for Neo.config.url.protocol, packaged App Worker Fleet protocol, and worker URL protocol found no duplicate. A2A in-flight sweep: no competing claim.

Retrieval Hint: packaged AgentOS App Worker config.url protocol app fleetRoster shell transport firstWorkerCrossing

Origin Session ID: cb60301d-74a4-4024-b80d-2f7efdbf9cd1