Commit Graph
9691 Commits
Author SHA1 Message Date
Brennan Benson 0440dab920 fix(orchestration): offer the worker brief to the one launch carry rule
Round-1 review fixes. The worker brief no longer forces its own sensitive
launch file past the host checks. Worker start offers the brief as an ordinary
startup prompt with main's paste (`once-agent-runs`): it rides the agent's
launch line where the line carries it exactly, and is otherwise pasted once the
agent is ready, as main pasted it, so a host that cannot take a launch file no
longer fails the start. With no sensitive file, the agent's hook reports the
brief itself, which status readers compact to its task as on main.

- Created worktrees are agent-first again, as on main: the startup terminal
  keeps the handle the brief names, setup and default tabs follow it, and a
  wait-for-setup sequence still holds the agent until setup succeeds.
- The brief names the CLI command the spawn's own WSL decision will give the
  terminal.
- A launch the shell reports finished, with no agent in front, fails and tears
  down the start. Where hooks are off or never reach the pane, the launch is
  judged by main's evidence: a title turn-start edge, or the agent holding its
  terminal.
2026-10-02 16:24:17 -07:00
Brennan Benson 2bd886311c fix(orchestration): start workers with their brief on the launch command line
A worker whose agent reads a launch file gets its dispatch brief in that file on
its launch command line instead of a paste once the agent looks ready. The start
counts only when the agent's own hook reports a turn that carried the prompt
after the spawn; a startup dialog that holds the agent is reported as blocked,
and the receipt steers to worker-stop. Agents that cannot carry a launch file
keep the paste.

The brief names the coordinator by its Orca session address, as the pasted
preamble does, and carries no dispatch capability, which Orca no longer mints.
2026-10-02 16:24:15 -07:00
Brennan Benson 0a43c0a28f test(launch-prompt): keep the cmd launch-file path case to what the piped harness can carry
The Windows CI harness pipes the typed line into cmd, which decodes it in its
startup code page whatever chcp says, so accents and CJK in the home folder
arrived garbled while cmd split the line into the right two arguments. The
case keeps the apostrophe, the space and the % pair, which are what cmd's
quoting has to survive; a non-ASCII path in a real cmd pane is not measured.
2026-10-02 16:03:08 -07:00
Brennan Benson f29abc5536 fix(launch-prompt): final review: paste where nothing can confirm, one foreground read, Windows CI
On a Windows host nothing proves the agent is in front, so a prompt an AI
button, a note or Fix checks carried on the line could never be
confirmed: for an agent with no hook the action never ran and a notice
said "couldn't confirm" on a launch that worked. The rule now gives a
caller whose paste main used that paste wherever the host cannot prove
the agent (final review P1-1), and a new tab's unconfirmed result,
which nothing waits on, is silent, as main reported nothing.

The receipt read the terminal twice, by foreground group and by a cached
process name. #24257's judgeTerminalForeground now tells the launched
agent named on its command line ('launched-agent') from any other
process that is not a shell ('other'); its paste guard counts both as
the agent, as before, and the receipt asks only it: delivered on either
once the agent looks ready, exited only after 'launched-agent' then the
shell. Reads back off from 250 ms to 2 s (about 18 per 30 s wait) and
run once more at the ready signal.

unstageableLine now comes from the rule's on-line outcome for every
caller whose paste main used, so the work-item route sends it too. A
draft is judged by the one measured Windows verdict. Command Code's
seeded status row no longer reads as its turn.

Windows CI (package (windows), red since d8cfcf397a): the cmd launch-file
line has two arguments, Claude's folder grant and the whole pointer, not
one; and a non-ASCII prompt piped into cmd is decoded in its startup code
page, so the rule leaves non-ASCII on cmd to main's delivery and the
piped harness no longer claims to measure it.

Also: stale comments from the old paste rule, the race and folder-mode
wording, and an unreachable half of a refusal message.
2026-10-02 15:52:51 -07:00
Brennan Benson ae59440a6a fix(launch-prompt): report an exited agent only on proof it ran
The receipt for a prompt on the new agent tab's launch line read what
held the terminal once, after the agent looked ready, and called a shell
in front an agent that exited at startup. A slow shell startup draws its
prompt, which looks ready, before it runs the launch line, so QA saw
"The agent exited at startup" 3 of 3 times while the agent ran with its
prompt.

The receipt now reads from the spawn on, every 250 ms. Exited needs
proof the agent ran: the agent itself named in front (not any process
that is not the shell, which a startup file's `sleep` also is), then the
shell back or the PTY gone. A shell in front before that is a line not
yet run, so the reads go on until the agent is in front (delivered) or
30 s after the ready signal (unconfirmed). A PTY that ends before the
agent was seen is unconfirmed, not exited.
2026-10-02 13:08:25 -07:00
Brennan Benson b622714d4f fix(launch-prompt): refuse an unstageable line for callers whose prompt main pasted
d260805adf types an agent line as is when the host's staging folder is
unusable, which is main's delivery where main typed the line. AI buttons,
notes and Fix checks are planned on the desktop, which cannot see that
folder, and main pasted their prompts: a long one typed raw could leave
the shell waiting with the prompt lost and no notice.

Those launches now carry one optional spawn field, unstageableLine
('type' | 'refuse'), from the renderer through main's pty spawn to the
terminal daemon, which is the one place that reads it. With 'refuse', a
line the host could not stage (this machine's temp folder unusable, or a
WSL distro with no folder) is refused as launch_file_unavailable, so the
desktop shows the Copy prompt notice once and closes the empty tab.
Absent means 'type', which is also what a daemon that predates the field
does; no protocol bump.
2026-10-02 12:54:53 -07:00
Brennan Benson d260805adf fix(launch-prompt): type main's line when the staging folder is unusable; one notice, no empty tab
ca1c4046ed planned such a host for main's delivery, but the spawn then
refused the line it chose: a WSL spawn with no distro folder refused any
line too long to type, and the daemon refused any agent line whose staging
write failed. On a Windows host nothing proves the agent is in front, so
agent.launch and worker start keep main's typed line, and every one of
them was refused (stack QA 2a, a 5-line prompt worse than main).

The spawn now reads the same folder answer the plan read. With no WSL
folder, or this machine's temp folder unwritable, the host types the line
as is, which is main's delivery. Only a write that fails in a folder that
looked usable (the WSL probe found it, or the temp folder passed its
check) is refused. Main's planners probe the WSL folder before planning a
prompt too long to type, so the first launch into a broken folder plans
like later ones.

A refused new agent tab showed its notice twice (the empty pane's recovery
spawned it again) under a red error panel, in a tab left open. The notice
now shows once per tab, without the error panel, and a tab left with no
live terminal closes, as main's desktop route closes a refused tab.
2026-10-02 12:31:41 -07:00
Brennan Benson ca1c4046ed fix(launch-prompt): plan a host that cannot write its staging folder for main's delivery
d8cfcf397a refused an agent launch the daemon could not stage, which also
refused worker briefs (and AI-button prompts) that main pasted. The staged
script and the launch file share one folder per host, so "can write it" now
folds into takesLaunchFile, derived before planning in main: this machine's
temp folder (checked when planned, a refused write remembered for 30 s) or the
WSL distro's folder (the probe's failure, and a refused write, are remembered
for the same TTL). A host that cannot write it is planned for main's delivery
up front: the paste where main pasted, the line within the typed budget where
main typed it. Only a write that fails after the plan said yes is refused.
2026-10-02 10:19:42 -07:00
Brennan Benson d8cfcf397a fix(launch-prompt): plan a WSL pane for its own shell; refuse a launch that cannot be staged
Stack QA on 193eeaddff:
- A WSL workspace added by its \\wsl.localhost path was planned as a Windows
  launch, so the Windows shell setting decided its line: under cmd, Claude's
  pointer was cmd-quoted and bash ran the backticked path, losing the prompt;
  the carry also changed with the setting. A WSL path now plans as the distro
  (POSIX quoting, WSL staging up to 100,000 bytes), and a pane whose Windows
  shell is wsl.exe is a host fact (windowsPaneShell) the rule reads.
- A Tab or bare carriage return was measured exact on both PowerShells and is
  no longer counted as damage there; cmd and Git Bash still damage it, and an
  unmeasured control byte does what main does on that path.
- The WSL folder probe kept a success forever. A refused spawn now forgets it,
  and the daemon refuses an agent launch whose line it could not stage
  (launch_file_unavailable) instead of typing it in full.
2026-10-02 09:38:20 -07:00
Brennan Benson 04417b6725 Merge #23962 head e2a732e546 (#24257 4523a4b3c4: pane-scoped foreground read) into the argv-carry step 2026-10-02 07:58:56 -07:00
Brennan Benson e2a732e546 Merge #24257 head 4523a4b3c4 (cheap pane-scoped foreground read) 2026-10-02 07:55:33 -07:00
Brennan Benson 4523a4b3c4 perf(agent-launch): read a local pane's foreground from its own terminal, not the whole process table
The foreground read that gates every launch paste ran the daemon's
inspectProcess capture and then a fresh scan, each a whole-machine ps; the
fresh one also waits for any capture already running before it starts its own.
Measured here at load 5: 1.2 s a read (M4Air QA: 3.4-5.0 s, and worker starts
17.6-32 s against main's 9-12 s at load 25-84).

On a local macOS or Linux host, take the pane's root pid from the provider's
session inventory and run one ps limited to that pane's terminal. Its
foreground process group decides: the launched agent or any non-shell member
is the agent (a wrapper that did not exec its agent leads the group), a group
of shells alone is the shell. Same pane, same verdict: 2.7 ms a read. SSH hosts
keep the relay's observation and name.
2026-10-02 07:54:35 -07:00
Brennan Benson c4b2cbfc46 fix(launch-prompt): title a launch file's session by its prompt; say when the agent exited
Stack QA 1.2: with a launch file, the tab label and the sidebar agent row showed
"The full task is in the file ..." while the status prompt held the real text.
They read the provider session title, taken from the transcript's first
message (the pointer, cut to 96 characters). Title requests now carry their
pane, and the host that spawned it maps the title through
launchPromptShownForPane, which also recognises a pointer cut short. The pane
stays on this host: it is not sent to an SSH relay.

Stack QA 1.3: "The agent started, but your prompt wasn't sent" also showed when
the agent crashed at startup with the prompt on its command line. The receipt
now reports 'agent-exited' when the PTY exits or the shell is back in front,
and that outcome gets its own notice with Copy prompt, in every catalog.
2026-10-02 07:53:23 -07:00
Brennan Benson e92f38d722 fix(launch-prompt): the PowerShell a pane is spawned as is a host fact
c729128c3a typed a PowerShell prompt holding `"` or a trailing `\` on the line
because it treated 5.1 and 7 as indistinguishable, so 5.1 broke it as main
does. But this Orca chooses the executable it spawns: the requested shell, the
PowerShell implementation setting, then whether pwsh.exe is installed.

LaunchHost gains windowsPowerShell, derived by spawnedWindowsPowerShell from
those same inputs (main reads its pwsh probe cache, the renderer main's probe
over the existing IPC). On powershell.exe those prompts are measured damaged
and get a launch file (or main's paste on an AI button); on pwsh.exe they ride
the line, which carried them exactly. The PowerShell stays unknown, and main's
delivery decides, for an SSH or paired host and before the pwsh probe answers.
2026-10-02 06:21:57 -07:00
Brennan Benson 636e3068e8 Merge #23962 head 2126ceeae6 (#24257 f02309f8c6, test-only) into the argv-carry step 2026-10-02 06:16:34 -07:00
Brennan Benson 2126ceeae6 Merge #24257 head f02309f8c6 (crash-guard live test: platform-neutral zsh lookup, refused-write assertion) 2026-10-02 06:14:55 -07:00
Brennan Benson f02309f8c6 test(agent-launch): keep the crash-guard live test out of the Windows lane's gate scan
The Windows-lane registration scan read the const assigned from a platform
check as a Windows-only gate, though the suite runs everywhere but Windows;
find zsh in a function instead, as the real-zsh typed-line test does.

Under load the fresh foreground scan can fail to answer, which lets the
shell's prompt settle readiness (2 of 4 paired runs). The guard still refuses
that write, so assert the refused write, the property that must always hold.
2026-10-02 06:14:03 -07:00
Brennan Benson c729128c3a fix(launch-prompt): judge a Windows line per shell from measured damage
Stack QA on Windows found Claude/Codex given a launch-file pointer where main's
typed line delivered the exact text: Git Bash multi-line and 8,191-character
lines, PowerShell 5-line, 20 KB and 8,191-character lines, %NAME% pairs, and on
pwsh 7 `"` and a trailing `\`. The rule treated every Windows shell like cmd.

windowsLaunchLineVerdict now judges the typed line per shell from the measured
rows: cmd (8,191-character cap, no line break), PowerShell (CreateProcess's cap;
multi-line within the typed budget; 9 KB measured damaged), Git Bash (9,089
characters measured whole, 20,551 never started). A spelled-out .cmd/.bat shim
adds its cmd hop's damage. Its verdict is exact (ride the line), damaged (main's
paste on that path, else a launch file) or uncertain (what main does on that
path: its paste, or the line it typed), so a launch file appears only where
main's line was measured to fail. PowerShell `"` and a trailing `\` are
uncertain, because 5.1 breaks them and 7 does not.
2026-10-02 06:06:03 -07:00
Brennan Benson 6bdfb960da refactor(launch-file): drop the unused sensitive flag
The worker brief was its only producer, and #24081 now routes the brief through
the carry rule as ordinary text, so every launch file was minted with
sensitive: false. The flag, its wire field, its parse check and the skip in the
pane prompt cache are removed; nothing that crossed the wire was released.
2026-10-02 04:41:18 -07:00
Brennan Benson 5c5f3f62b0 test(staging): read the stub agent's argv only once it is whole
The 100,000-byte case failed in zsh, dash and fish under load with a truncated
argv: the harness read the capture 100 ms after the redirect created it, before
printf finished. The stub now renames the capture into place once written.
2026-10-02 04:35:33 -07:00
Brennan Benson 9be1739f80 fix(launch-prompt): "takes a launch file" is a host fact; such hosts fall back, never refuse
An SSH Windows host's relay may run its panes in WSL (its OpenSSH default shell,
which this client cannot see), where it writes no launch file, so a multi-line
Claude/Codex prompt there was refused where main started the agent.
describeLaunchHost now derives takesLaunchFile (false for a paired Orca and an
SSH Windows host), and the one rule gives such a host the line or the caller's
paste instead of a file.

A spawn routed to a daemon older than launch files only attaches to a session
that daemon still runs, so it is sent with neither the launch file nor its
command instead of being refused.
2026-10-02 04:26:28 -07:00
Brennan Benson f4bebe01e0 Merge #23962 head 22c4f3eeba (#24257 29e38f61cb: group proof judged by when its capture began) into the argv-carry step 2026-10-02 04:06:23 -07:00
Brennan Benson 22c4f3eeba Merge #24257 head 29e38f61cb (group proof counts any capture begun after the read) 2026-10-02 04:05:07 -07:00
Brennan Benson 29e38f61cb fix(agent-launch): judge the foreground-group proof by when its capture began, not how long ps took
The age the host stamps on a process-group observation runs from the start
of its whole-machine ps, so on a loaded Mac a capture begun after the read
was asked for still read as older than 1 s and the proof was dropped. Count
an observation whose capture began after the read was asked for, less the
window a shared capture is reused across.
2026-10-02 04:04:12 -07:00
Brennan Benson d74371f1db Merge #23962 head b865c7d07e (plain Orca agent line typed as is in tcsh and nu) into the argv-carry step 2026-10-02 04:03:20 -07:00
Brennan Benson b865c7d07e fix(launch): type a plain Orca agent line as is in tcsh and nu
In tcsh and nu, every Orca-built agent line ran through `/bin/sh '<script>'`,
so the agent was a child of sh in sh's process group. When the prompt was
pasted after the agent was ready, the paste guard read sh in front and, on a
loaded Mac, reported the prompt not delivered (4/4 live runs in tcsh).

Now only a line that needs it goes through `/bin/sh`: one over 512 bytes, with
a control byte, or with a character those shells would not read literally
(`!`, backslash, `"`, `$`, backtick). A plain line such as
`claude '--dangerously-skip-permissions'` is typed as on main, so the agent is
the shell's own job.
2026-10-02 04:01:46 -07:00
Brennan Benson 6fe25271b8 fix(launch-prompt): one carry order on every platform; the line holds 100,000 bytes
A 20 KB Fix-checks prompt on macOS became a launch-file pointer, so the agent's
history showed "The full task is in the file ..." where main pasted the user's
text. The 16,384-character ceiling predated staging: a staged line now reaches
the agent's argv byte-exact at 100,000 UTF-8 bytes in bash, zsh, dash, sh, ksh,
tcsh and fish (measured in real shells), under Linux's 131,072-byte cap on one
argument.

The order is now the same everywhere: the line when it carries the exact text;
otherwise the paste main uses on that path ('once-agent-runs' for desktop
submit-after-ready prompts); the launch file only where neither exists.
2026-10-02 03:36:50 -07:00
Brennan Benson f8288f8a0f Merge #23962 head ef629543bd (#24257 3054018722: agent proven in front behind a wrapper) into the argv-carry step 2026-10-02 03:18:52 -07:00
Brennan Benson ef629543bd Merge #24257 head 3054018722 (agent proven in front from the foreground-group observation) 2026-10-02 03:17:56 -07:00
Brennan Benson 3054018722 fix(agent-launch): find a launched agent behind a wrapper that leads its process group
A tcsh or nu launch line runs the agent from /bin/sh '<script>', and a
wrapper script that does not exec its agent does the same: the wrapper leads
the terminal's foreground process group and the agent is a member of it. The
fresh foreground read names the group's leader, sh, so a prompted launch was
refused or pasted late (M4Air tcsh: 2 of 4 not delivered, 2 pasted ~9 s late).

Before that read, take the host's process-group observation as positive proof
when it names the launched agent among the foreground group's members and is
younger than a ready signal's quiet window. It never proves a shell.
2026-10-02 03:17:09 -07:00
Brennan Benson 0599ae2f56 fix(launch-prompt): on Windows, paste what the line can't carry where main pasted it
Main pastes an AI button's or notes send's prompt once the agent runs, so the
agent's history, /resume, the chat view and AI Vault show the user's text. A
launch file replaced nearly every such prompt on Windows with a pointer.

The caller's paste is now one of 'never', 'when-host-proves-agent' (#24257's
guarded paste) or 'once-agent-runs' (main's desktop paste for submit-after-ready
prompts). On Windows a prompt the line cannot carry exactly goes to an
'once-agent-runs' paste first; a launch file is left for the lines main would
have typed damaged or too long. Temporary, until the agent's own argv carries
multi-line text past cmd without a shim re-parsing it.
2026-10-02 03:08:42 -07:00
Brennan Benson ea4699eaea docs(launch-file): the sweep, not an age gate, is removeLaunchFile's fallback 2026-10-02 02:56:36 -07:00
Brennan Benson 7c0269be54 test(launch-prompt): build the phone line-carry runtime from the default store, without a cast 2026-10-02 02:52:48 -07:00
Brennan Benson a29e42f629 Merge #23962 head 57e77107b3 (#24257 long-poll launch, origin/main 66799f7e8f) into the argv-carry step 2026-10-02 02:50:48 -07:00
Brennan Benson ea0c65d041 fix(launch-prompt): one host-derived carry rule, receipts proven like the crash guard
- The carried prompt's receipt is delivered only on the agent's hook turn or a fresh
  foreground read that finds the launched agent in front; readiness alone never counts
  and bracketed paste turned off revokes it. An unknown read is reported as unconfirmed.
- Host facts (paired, proves the agent in front) come from describeLaunchHost; a caller
  that cannot paste keeps the prompt on the line as main did instead of refusing.
- Windows keeps any exact line up to cmd's 8,191 cap on the line; only damaged or
  multi-line prompts ride a launch file.
- A launch-file refusal is a "failed without effects" code for agent.launch, and the
  desktop closes the tab it opened for it.
- Launch-file folders carry their owner's pid; the sweep never removes a live owner's.
- The terminal-handle wait keeps waiting while that tab's spawn is still in flight.
2026-10-02 02:50:06 -07:00
Brennan Benson 57e77107b3 Merge #24257 head c9b4dc0578 (prompted agent.launch is a long poll) 2026-10-02 02:44:39 -07:00
Brennan Benson c9b4dc0578 refactor(agent-launch): narrow the launch params by 'in' instead of a cast 2026-10-02 02:44:11 -07:00
Brennan Benson 9e5108af50 fix(agent-launch): keep the local socket alive while a prompted launch waits for its agent
A launch with a prompt now waits up to 60 s for the terminal agent to be
ready before it writes the prompt, and reports not-delivered when the agent
never is. The local runtime socket closes a connection idle for 30 s unless
the request is a long poll, so a launch whose agent exited at startup lost its
reply and the caller saw 'runtime closed the connection' instead of
not-delivered. Classify a prompted agent.launch and agent.launchReplay as a
long poll, as orchestration.workerStart already is for the same wait.
2026-10-02 02:42:58 -07:00
Brennan Benson 188536439b Merge #24257 head bc7ed259a4 (origin/main 66799f7e8f) 2026-10-02 02:38:45 -07:00
Brennan Benson bc7ed259a4 Merge remote-tracking branch 'origin/main' into brennanb2025/agent-launch-host-prompt-delivery 2026-10-02 02:37:07 -07:00
Neil 66799f7e8f Keep paired browser terminal insertion in the host's requested position (#24676)
* test: align source-control fixtures with current store contracts

* Bound E2E package setup and retain cancelled-job traces

* Remove empty passing sentinels from opt-in socket tests

* Make SSH typing pressure fixture readiness and replies observable

* Advertise browser support for anchored terminal placement
2026-10-02 02:34:40 -07:00
Brennan Benson 4635a6406f docs(daemon): mark the pre-v41 launch-file refusal temporary, with why and when it ends 2026-10-02 01:50:33 -07:00
b49abdb1f4 fix: recover renderer launch failures in the running app (#24250)
* fix(recovery): back off a launch-failed renderer instead of tripping the crash breaker

A renderer that the OS refused to spawn (macOS exit 1003 = LAUNCH_RESULT_FAILURE; field
cause: per-user process limit, posix_spawn EAGAIN) burned the 3-reload crash-loop budget
in ~750ms and raised a "graphics driver" prompt, while the condition lasted minutes.

- launch-failed retries in place on a 250ms..60s backoff (~2 min), outside the breaker;
  a loaded document resets it. Other crash reasons keep the breaker.
- Each launch failure records renderer_launch_failed_probe {spawnError} from a cheap
  spawn probe, so bundles name EAGAIN/EACCES/ENOENT directly.
- The exhausted prompt says the process limit was hit (probe EAGAIN), drops the
  graphics-driver wording, keeps Try Again as default, and offers no Restart:
  app.relaunch also needs a free process slot and silently fails without one.

* fix(recovery): skip the launch probe on Windows and probe the prompt once

- Re-check quitting after the prompt's probe; don't re-probe on Copy Commands.
- recordRendererLaunchFailureProbe never rejects (breadcrumb write guarded).
- Windows: no spawn probe; a child per failed launch is the per-operation burst EDR scores.

* test: cover quitting and duplicate renderer launch failures

* test: use typed access in PTY delay regression fixture

* fix: scope extended launch retries to POSIX hosts

* test: cover launch probe behavior on native Windows

---------

Co-authored-by: m4air <m4air@m4airs-Air.localdomain>
Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-02 01:50:08 -07:00
Brennan Benson 7c221ad525 Merge #23962 head 74fa3f8e52 (#24257 crash guard) into the argv-carry step
A host that cannot prove the launched agent holds its terminal (a Windows
host, a local WSL pane on one, SSH to Windows) refuses a paste, so the one
carry rule keeps such a prompt on the line, as main typed it; Claude and
Codex still take a launch file for a long or shell-damaged prompt.
launchHostProvesAgentInFront moves to its own module, since the typed-line
shell naming beside it is gone with #24257's typed-line check.
2026-10-02 01:34:10 -07:00
Brennan Benson d3fdcac605 fix(agent-launch): make where a launch prompt rides explicit, and delivery mean the agent got it
Round-1 review of the rebuilt step 3.

- One outcome, switched on by every caller. planLaunchPrompt answers none,
  on-line, launch-file or paste-after-ready; only the carried outcomes hold
  the plan to launch, so no caller can read "a plan exists" as "carried".
  buildAgentStartupPlan now builds only a prompt-less launch. The new agent
  tab and work items had dropped a prompt an agent could not take in a file
  (any agent but Claude and Codex) and reported it delivered; they now paste
  it. The composer paths, background sessions, agent.launch, agentSession.create
  and phone quick commands switch on the same outcome.
- One rule for hosts that type the line raw. A Windows host or a paired Orca
  keeps a line to #24257's 512-byte typed budget; anything longer, multi-line
  or damaged by the shell rides a launch file for Claude and Codex and is
  pasted for others. A paired host is one predicate (launchHostIsPaired).
- Delivered means the agent got it. A prompt the new tab's line carried
  resolves its delivery when the agent's own hook reports a turn or the
  agent shows its composer, and false when the PTY never spawns (a refused
  launch file) or exits first, so callers that resolve review threads or
  mark notes delivered wait for that, not for the tab.
- Daemon protocol v41 writes launch files. A spawn routed to an older daemon
  is refused with the launch-file reason instead of typing a pointer to a
  file nobody wrote.
- A refused launch file or WSL staged line reaches agent.launch as its reason
  instead of a 10 s handle timeout, and hands the prompt back with Copy prompt
  for a staged line too.
- A WSL distro is probed only when the spawn needs its directory, and a
  failed probe is remembered for 30 s.
- Every hook status row shows the prompt a launch file carries instead of its
  pointer sentence.
2026-10-02 01:30:25 -07:00
Brennan Benson 74fa3f8e52 Merge #24257 head 2603d2cda1 (crash guard: paste only when the launched agent is proven in front) 2026-10-02 01:30:05 -07:00
Brennan Benson 2603d2cda1 test(agent-launch): cover the Windows QA stub, a grok override that exits at once 2026-10-02 01:28:09 -07:00
Brennan Benson d96b1e75f2 fix(agent-launch): paste a launch prompt only when the launched agent is proven in front
A launch pasted its prompt unless a shell was proven in the terminal's
foreground, so any read that could not prove one let the prompt through. After
an agent exited at startup, its shell turned bracketed paste on at the next
prompt, readiness fired on it, and the prompt was typed into the shell:

- macOS: a pane runs its shell under login, so the process-group fence's root
  was never the shell's group and never proved it; the cached foreground name
  could also still name the exited process.
- Windows Git Bash and WSL: the shell-alone-in-its-job check never answers.

Now one fresh read of the terminal's foreground decides: agent, shell or
unknown. Only 'agent' lets a write through (paste, Enter, second Enter, reused
panes too); 'shell' still drops a ready signal. A Windows host never proves the
agent, so there the launch line carries the prompt at any size, as on main.
2026-10-02 01:26:36 -07:00
f20836c296 fix(recovery): prompt instead of reloading into a repeat Windows OOM when commit is exhausted (#23886)
* fix(recovery): ask instead of reloading into a repeat Windows OOM with exhausted commit

When another program exhausts Windows commit (RAM + page file), the renderer
OOMs, Orca auto-reloads 250 ms later, and the new renderer OOMs again within
seconds (launch 13084: 3.5 s after the reload; launch 22912: 34 s). The crash-loop
breaker (3 in 60 s) never opens for this cadence, so the user is never told the
machine is out of memory.

Keep the first automatic reload, but when a win32 reason=oom death follows
another OOM within 5 minutes and the pre-gone host sample shows under 512 MB of
available commit, escalate to the existing recovery prompt with a new
'low-commit' cause that names the MB left and suggests closing apps or growing
the page file. Records renderer_recovery_low_commit_prompt. No-op on
macOS/Linux and when commit is healthy.

* fix(recovery): gate low-commit prompt on post-OOM readings and recovered deaths only

- Reject pre-gone samples taken at or before the previous OOM; they miss the commit that corpse released.
- Record an OOM for the repeat window only once recovery actually runs, so skipped teardown OOMs cannot suppress the next first reload.
- Skip the install-ACL diagnosis on the low-commit prompt, whose text would not explain Copy Commands.

* fix(recovery): read commit at gone time when no sampler tick followed the previous OOM

The 10 s pre-gone sampler lands between ~3.5 s repeat OOMs only ~35% of the time, so the gate usually fell back to a silent reload. A gone-time read can only over-report free commit (the corpse already released its pages), so it can miss a prompt but never raise a false one.

* fix: reject invalid low-commit readings and clarify recovery advice

---------

Co-authored-by: m4air <m4air@m4airs-Air.localdomain>
Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-02 01:20:03 -07:00
76c79f473a fix(linux): move Chromium shared memory off a tiny /dev/shm (#23751)
* fix(linux): move Chromium shared memory off a tiny /dev/shm

Containers such as GitHub Codespaces mount a 64 MB /dev/shm by default.
When it fills, Chromium aborts the renderer (IMMEDIATE_CRASH, SIGILL/SIGTRAP)
on every reload, trapping Orca in a renderer crash loop. On Linux, stat
/dev/shm before app ready and append --disable-dev-shm-usage when it is under
512 MB or unreadable (ORCA_DEV_SHM=off|force overrides). Records a
dev_shm_policy crash breadcrumb so future container crashes are diagnosable.

* docs(linux): correct dev-shm hasSwitch rationale

---------

Co-authored-by: m4air <m4air@m4airs-Air.localdomain>
Co-authored-by: m4air <m4air@Mac.localdomain>
2026-10-02 01:13:27 -07:00