Skip to content

feat(agent-launch): name the kept workspace when a new workspace's agent provably never started - #26060

Draft
brennanb2025 wants to merge 17 commits into
mainfrom
brennanb2025/agent-launch-create-intent-record
Draft

brennanb2025 wants to merge 17 commits into
mainfrom
brennanb2025/agent-launch-create-intent-record

Conversation

@brennanb2025

@brennanb2025 brennanb2025 commented Oct 7, 2026 •

Copy link
Copy Markdown
Contributor

ELI5

Starting an agent can create a workspace and then fail before asking for the agent. The launch response previously did not identify that workspace. A capable runtime caller can now receive its ID, so a future client can offer the workspace that was kept.

The phone is the only shipped caller of agent.launch today. No orca CLI command calls it, and the current phone does not enable the new response capability, so its visible behavior is unchanged in this PR.

What Changed

  • A live launch names its kept workspace and says the agent did not start only when no request for that launch's agent escaped. Startup terminals and window handoffs count too; an already-live pane or session never proves an agent did not start.
  • The failure and workspace ID settle together. The stored base error remains readable by older hosts; capable newer readers present the richer response.
  • Before local Git creation, the launch records the chosen path, branch and workspace creation instance. The workspace stores that same instance. An interrupted launch's replay can name only an instance-matched workspace and remains uncertain about its agent. It does not change the launch record or start another agent.

Why

Live control flow can prove a request was never sent. A restart cannot recover that proof from a missing note or an empty terminal list, and a path alone can belong to another creation. Keeping those facts separate avoids a false promise that no agent started and avoids offering another launch's workspace. Optional bookkeeping failure reduces recovery detail and does not stop the user's action.

The common pattern is to keep ownership with the execution host and bind recovery to identity. Intended difference: this step derives a workspace on demand rather than adding background recovery work; no new durable obligation is left behind. Temporary difference: interrupted launches remain uncertain until the host-owned first-prompt/resume step in launch plan v5. Desktop SSH and folder registration currently lack this local creation association and retain the plain uncertain replay answer.

Linked Issue

Step 3 of agent-launch plan v5. The separate folder-create target in #26083 is not covered here; whichever change lands second must extend this answer to that target.

Visual Proof

N/A

The current phone does not opt into this response, so no shipped UI changes in this PR. Final runtime QA is pending; screenshots and evidence belong in the final review comment.

Testing

Reviewed candidate: 25351ba93c4516144384a6d0f173312a96fb15d4, pushed normally to the existing branch. Source review is complete; final live Windows runtime QA and CI are running. The PR remains draft until those gates finish.

  • Real runtime QA on the pushed commit (in progress).
  • Automated coverage for startup-dispatch proof, creation identity, resolved workspace IDs, atomic settlement and caller capability handling.

The scoped Node typecheck, 274 tests in 11 named files (no skips), and all 22 repository checks passed on this commit. The compatibility tests exercised the actual prior-host store, replay reader and error mapper from main 80d45095d2f, including 14 cases. The broader 478 tests in 29 named files passed at 62143361d4e; the SSH startup-proof production code and tests are unchanged from that run.

Not verified live: SSH. A throwaway target was prepared on the available remote Mac, but its SSH port could not be reached from the test driver; the target was removed. Unit coverage includes runtime-remote-managed-worktree-create.test.ts and agent-launch-executor.test.ts. Native phone and paired-device capability negotiation have not been exercised live.

Review

Fresh full reviews covered launch proof, stored identity and wire compatibility, with an independent architecture challenge. The earlier false no-start claim, foreign-path recovery, two-write settlement and resolved-ID gaps are fixed. The rollback compatibility correction and saved-ID validation were verified by a fresh final reviewer; the source readiness scan found no new proven issue.

Agent skill upstream boundary

  • Not applicable; no upstream skill material is copied or translated.

Notes

This changes a capability-gated runtime answer, without automatic retry, recovery, new UI, dependencies or new Git commands. Folder workspaces, SSH execution authority and clients updating independently were reviewed. Native phone QA and other unexercised platform paths will be listed explicitly in the final comment.

Checklist

  • This PR is focused on kept-workspace answers.
  • Problem, user-facing scope, mechanism and alternatives explained.
  • No shipped UI change; runtime evidence pending.
  • Source review covered correctness, security and bounded recovery.
  • Cross-platform, SSH, folder and capability boundaries considered.
  • Final checks and QA green.

…vably never started

A create-worktree launch records the path it is about to add before
`git worktree add`, and the workspace it made before it asks for any agent.
When the launch can prove its agent never started (the failure came before an
agent was requested, or the terminal failed before its spawn request left), it
settles failed with `agent_launch_agent_not_started` and names the workspace,
to callers advertising `agent.launch.workspace-kept.v1` and the CLI. Every
other caller, and every unproven failure, keeps the uncertain answer.

A replay after a restart settles the same way only for a host that stopped
between the add and the second record; past it the launch stays uncertain.
# Conflicts:
#	src/main/agent-launch/agent-launch-executor.ts
#	src/main/runtime/rpc/methods/agent-launch.ts
It opens the real SQLite record store, so it belongs beside the other
agent-launch tests that do.
…tartup terminal asked for one

A create launched in terminal mode asks for its agent inside the create:
the startup terminal. That spawn never told the launch it had been
requested, and a failure there only became a warning. If its request
left and the reply was lost, the launch went on to build a second
terminal, and a failure before that second spawn's request answered
"workspace kept, agent not started" while the first agent might run.

The create now reports when it asks for its startup agent (the startup
spawn's request leaving this process, local, SSH and folder alike, or the
startup being handed to the window), and from then on the launch makes
no "not started" claim. A live reserved pane or a taken reserved session
on a create is likewise never "not started"; the test fixture now
refuses a live pane after its spawn request left, as the runtime does.
A create whose agent provably never started was recorded in two writes:
the kept workspace's id as a side note on the row, then the failed code.
If only one landed, the live answer and every replay disagreed.

The kept workspace now rides on the failed outcome itself
(keptWorktreeId), written in the same settle as the code, and a replay
reads it from there.
…stance, and never claim its agent

A replay of a create left unknown claimed "workspace kept, agent not
started" whenever some worktree sat at the path the launch had intended
and the row lacked a second note (createdWorktreeId). That note is
bookkeeping allowed to fail, so its absence was no proof that no agent
was asked for; and nothing reserves the path between the record and
`git worktree add`, so the worktree found there could be another
create's, with its own agent running.

The create now mints the worktree's metadata instance id before the add
and records it in createIntent (repo, path, branch, instance), the one
note on the row; createdWorktreeId and onWorktreeCreated are gone. A
replay of a row still unknown derives, and writes nothing: it finds the
worktree the way the create does (by path, else branch) and names it to
a caller that reads agent.launch.workspace-kept.v1 only when its
metadata carries that instance id, as agent_session_operation_unknown
with data.worktreeId set to the listed worktree's id. The agent stays
uncertain. Any other caller, a foreign or metadata-less worktree, or a
failed listing gets exactly the answer it got before.

errors.ts passes agent_session_operation_unknown through the path that
keeps data; without data it maps exactly as before.
…d method

A paired phone that reads agent.launch.workspace-kept.v1, the local
socket, and an older phone, each on agent.launchReplay, agent.launch with
an operation id and agent.launch without one, live and on a replay of the
same id, against the real ledger and mapped as the wire maps it.

The older-phone case in the prestart test went through the dispatcher,
which does not carry a paired device into the context, so that launch
failed on creator provenance before any create and its unknown answer
proved nothing; it is replaced by these.
No `orca` command calls agent.launch; only the phone does. A caller with
no declared client (the local runtime socket, the SSH CLI bridge) still
reads the answer, as for the unconfirmed prompt, but the comments no
longer claim the CLI reads it. The capability's note now also covers the
workspace named on a replay's uncertain answer.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant