Repository navigation
Import against the server this run resolved, and relinquish on any exit - #765
Conversation
The context handed to the browser import lane is the snapshot taken before Step 1, and setup is exempt from the entry gate that refuses an unconfigured command — so on a first run nothing between the two catches an empty URL.
Environment.Exit runs no finally and disposes nothing, so a leg that ends that way never sends the notice it armed and the browser waits out the flow's whole lifetime. ProcessExit is the one hook Environment.Exit raises.
PR Summary by QodoFix first-run import routing and exit relinquish
AI Description
Diagram
High-Level Assessment
Files changed (6)
|
Code Review by Qodo
1.
|
A step number drifts if the flow is reordered; what the context is missing is a server, and the point it is missing one at is process start.
AI-2482, AI-2483 — no GitHub issue; both were found in-house and filed in Linear only.
What & why
kcap setup's browser leg imports nothing on a first run, and then ends the process without telling the browser, which holds its step until the flow's twelve-hour lifetime expires.The lane is handed
profiles, the context resolved before Step 1, andImportCommandreads its base URL from whatever context it gets. On a first run that names no server, andsetupis one of the commands exempt from the entry gate that refuses an unconfigured command — so nothing between the two catches it. It now gets a context carrying the URL this run resolved, which is what the flow client one call earlier already used.The empty URL then reaches
EnsureAbsolute, which underFailFastwrites a hint and callsEnvironment.Exit(2). That runs nofinallyand disposes nothing, so the relinquish notice the leg armed is never sent.Environment.Exitdoes raiseAppDomain.ProcessExit, and this file already leans on that to flush telemetry, so the notice now goes out from there too — covering everyEnvironment.Exitin the CLI, not just this one.Where to look
The notice is claimed once, so a leg that settled normally sends nothing on the way out and a process with none armed is a no-op. It goes ahead of the telemetry flush because both spend the runtime's single exit budget and only one of them is holding a page open.
Making the exit itself catchable is the wider change, tracked separately as AI-2486; it needs an audit of every broad
catchon a request path and is deliberately not here.Verification
Reproduced the exit in the devcontainer with a schemeless
KCAP_URL, matching the reported run on all three counts:Both guards were confirmed to fail without their fix:
SetupImportLaneConstructionGuardTestsSetupCommand.cs:1502 hands the lane a context that need not name a serverFirstRunExitNoticeGuardTestsExpected to contain "FirstRunInterruptRelinquish.RunBeforeExit"Capacitor.Cli.Tests.Unit3984 andCapacitor.Cli.Core.Tests.Unit2953, 0 failed.dotnet publish -c Releaseclean of IL2026/IL3050.