Skip to content

Keep GUI auth relaunch inside Fleet lifecycle ownership #14988

Description

@neo-gpt

Context

PR #14977 makes Claude Desktop and Antigravity launchable as directly supervised Fleet children and adds the first reachable in-app authentication handoff. The exact-head re-review proved that the handoff now reaches the real post-startAgent() branch.

That review also falsified the fallback instruction: for an in-app family, buildLoginCommand() prints the raw app-bundle binary with --user-data-dir and labels it “relaunch if closed”.

The Problem

Executing that printed fallback starts a new app process outside FleetLifecycleService. It therefore bypasses the lifecycle owner's reserved child environment and process record:

  • NEO_FLEET_BRIDGE_TOKEN
  • NEO_AGENT_IDENTITY
  • the forced Neural Link tool projection
  • the optional credential injection
  • Fleet PID/state/stop ownership

The primary path is safe because the operator signs in inside the already Fleet-launched window. Only the “window was closed” recovery text is wrong, so this is intentionally a non-blocking follow-up rather than another #14977 review cycle.

Source of Authority

Expected Behavior

The in-app handoff says to authenticate inside the Fleet-launched window. If that window was closed, it routes the operator back through a Fleet-owned start path (for example, rerun the same onboardPeer ... --commit command or use the cockpit Start action) and never prints an executable raw-binary relaunch.

CLI-family marker/login behavior remains byte-stable.

Acceptance Criteria

  • deriveAuthHandoff() for claude-desktop and antigravity prints a non-executable in-window sign-in instruction.
  • The closed-window recovery instruction names a Fleet-owned restart path; it does not emit launchCommand or --user-data-dir.
  • Codex and Claude Code marker-mode login output is unchanged.
  • Unit coverage falsifies raw-binary fallback leakage for both in-app families.
  • JSDoc no longer describes buildLoginCommand() as valid for GUI relaunch, or the helper is narrowed to marker families.

Fix Sketch

Keep deriveAuthHandoff() mode-first. Split its in-app branch from buildLoginCommand(): return human instructions only, while the marker branch retains the current executable per-home login command. No launch contract, lifecycle service, or persisted schema changes are needed.

Contract Ledger

Target Surface Source of Authority Required Behavior Fallback Evidence
GUI auth handoff deriveAuthHandoff() sign in inside the already supervised window rerun Fleet-owned start path direct function tests
Child process ownership FleetLifecycleService.start() reserved env + PID/state remain Fleet-owned no raw app spawn negative output assertions
CLI login existing marker-mode contract unchanged existing unknown-state warning regression tests

Decision Record Impact

None — this restores the already-settled Fleet supervision boundary.

Relations

Parent: #13015 · discovered in re-review of PR #14977 · source ticket #14972 · cockpit successor #14987.

Live duplicate sweep: three focused GitHub searches plus the latest 15 open issues checked at 2026-07-10T20:00Z; no equivalent issue found.

Origin Session ID: 019f484c-662f-7f31-969a-cbde373efd4a

Retrieval Hint: Fleet GUI auth relaunch bypasses lifecycle reserved env raw app binary

Metadata

Metadata

Assignees

Labels

aibugSomething isn't workingdeveloper-experienceThis improves the ease and fun of developing apps with neo.

Type

No type

Fields

No fields configured for issues without a type.

Projects

Status
Done

Relationships

None yet

Development

No branches or pull requests

Issue actions