Repository navigation
Description
Before submitting
- I searched existing issues and did not find a duplicate.
- I included enough detail to reproduce or investigate the problem.
Area
apps/server (code lives in packages/provider-acp and packages/provider-grok)
Root cause
On Windows, if grok resolves to a .cmd shim, T3 starts the Grok ACP process with shell: true and detached: true. In that combination grok.exe does not inherit T3's stdio pipes. It ends up attached to its own new console, so:
initializenever reaches Grok, and the probe times out after 20 seconds.- The console is visible, which is the blank window.
The chain:
grokAcpRuntimeProcessOwnershipalways returnsownDetachedProcessGroup: true, including onwin32(packages/provider-grok/src/server/acpSupport.ts:83).AcpSessionRuntimeturns that intodetached: true(packages/provider-acp/src/server/AcpSessionRuntime.ts:1447).resolveSpawnCommandruns.cmdand.batfiles withshell: true, socmd.exeis the detached process andgrok.exeis its child.- Effect's
buildSpawnOptionssetswindowsHide: options.windowsHide ?? !detached, so detached also means not hidden.
The grok --version and model probes don't set detached, so they pass. That is why T3 reports "Grok CLI is installed but ACP initialize failed. Model options may be incomplete."
Both files above are from main at 333f7a6, so this looks unfixed there. I confirmed the same behavior in the 0.1.6 bundle.
Steps to reproduce
- On Windows, make
grokresolve to a.cmdshim that is ahead ofgrok.exeon PATH. For example,%USERPROFILE%\.local\bin\grok.cmd:@echo off "C:\path\to\.grok\bin\grok.exe" %*
- Leave the Grok provider
binaryPathasgrokand enable the provider. - Wait for a provider health check, which runs about every 5 minutes.
Expected behavior
The probe finishes hidden, initialize succeeds, and no window appears.
Actual behavior
- A blank Windows Terminal window opens, titled
"...\.grok\bin\grok.exe" agent stdio. - After 20 seconds T3 kills it. The window stays open showing
[process exited with code 1 (0x00000001)]. - The provider status changes to the
ACP initialize failedwarning. - This repeats on every health check.
- From reading the code, Grok sessions use the same
makeGrokAcpRuntimespawn path, so they should fail the same way. I did not test a Grok thread directly.
Impact
Major degradation or frequent failure
Version or commit
T3 Code 0.1.6 (desktop). Same code on main at 333f7a6.
Environment
Windows 11 Pro 10.0.26200, Grok CLI 1.0.70, Windows Terminal installed.
Logs or stack traces
Spawn matrix. Same initialize payload as T3 (including clientInfo and _meta), with a 22 second limit, run outside T3 under Node:
| Case | Target | detached |
windowsHide |
Result |
|---|---|---|---|---|
| A | grok.exe |
false | true | OK, 545 ms |
| B | grok.cmd (shell: true) |
false | true | OK, 630 ms |
| C | grok.exe |
true | true | OK, 657 ms |
| D | grok.cmd (shell: true) |
true | true | Timeout |
| E | grok.exe |
true | false | OK, 777 ms |
| F | grok.cmd (shell: true) |
true | false (T3 today) | Timeout |
Only shell: true plus detached: true fails. windowsHide makes no difference to the hang, so setting windowsHide: true alone would not fix it (case D).
Stdio proof. A throwaway .cmd shim runs a Node script that reports what kind of stdio it received:
not-detached: cmd exit=0 grandchild={"stdin":"Socket","stdout":"Socket","stderr":"Socket"} pipeReceivedOutput=true
detached: cmd exit=0 grandchild={"stdin":"ReadStream(TTY)","stdout":"WriteStream(TTY)","stderr":"WriteStream(TTY)"} pipeReceivedOutput=false
This takes Grok out of the picture: under a detached cmd.exe, the grandchild gets a console instead of the pipes.
T3 server trace:
checkGrokProviderStatus: "Grok ACP initialize probe failed or timed out." { errorTag: "Timeout" }
initialize span: ~20000 ms, exit Interrupted
~/.grok/logs/unified.jsonl. In failing runs Grok boots normally, then never handles initialize. Each one stops here, with no built auth_methods for ACP response line:
last line: "model catalog: auth refresh watcher started"
Cases D and F produced this same log signature, which ties the matrix to the failures inside T3.
Timing on my machine:
- Every ACP probe in the traces before a reboot at 11:42 PM succeeded in 1-4 seconds.
- All 4 ACP probes after the reboot failed.
- The T3 process tree now has
.local\binat PATH index 4 and.grok\binat index 27, sogrokresolves to the.cmd. - I can't prove what the PATH order was before the reboot, so why it flipped is unconfirmed. The bug itself doesn't depend on that, since it reproduces from the spawn options alone.
Suggested fix
Don't pass detached: true on Windows in AcpSessionRuntime, while keeping ownDetachedProcessGroup so process-tree cleanup still runs. Windows has no POSIX process groups to own, and cleanup there already appears to go by PID through the Windows tree terminator.
// packages/provider-acp/src/server/AcpSessionRuntime.ts
...(options.ownDetachedProcessGroup === undefined
? {}
: { detached: options.ownDetachedProcessGroup && hostPlatform !== "win32" }),This gives case B above, which passes. It also fixes the window, because windowsHide then defaults to true. I tested those spawn options, but not this patch in a T3 build.
Avoid setting ownDetachedProcessGroup: false for win32 in acpSupport.ts instead. terminateOwnedProcessGroupImpl returns early when it is not true, so that would skip tree cleanup.
A regression test could assert that a win32 ACP spawn with ownDetachedProcessGroup: true doesn't pass detached: true. apps/server/src/orchestration-v2/Adapters/AcpAdapterV2.test.ts already covers this option.
Workaround
Either of these should avoid it. Neither has been tested inside T3:
- Set the Grok provider
binaryPathto the full path ofgrok.exe. That skips the shell, which is case E above.checkGrokProviderStatuswill still run. - Disable the Grok provider.
checkGrokProviderStatusreturns before spawning anything when it's disabled.
Activity
ElliotDrel commentedon Nov 4, 2026
Note
🤖 gpt-6.1-sol responding on behalf of Elliot
Reviewed candidate: #30544
Recommended over #29098 : both make the same non-Windows detachment gate while retaining ownership; this candidate additionally asserts retained PID cleanup and reports an actual Windows Grok .cmd ACP handshake. No unresolved inline review threads found. Console-window disappearance was not visually checked, so that portion of the report remains a verification gap. Avoid merging both duplicate production changes.
Source/patch and GitHub review audit only in this pass; no new runtime verification. The candidate remains open and unmerged.