Chat On Steroids 2.0.0
Windows installers for both architectures are attached below. Download the one that matches your
PC, then reload the browser extension — the app and the extension are versioned together and
the app refuses a mismatched copy.
Chat-On-Steroids-Setup-x64.exe— Intel/AMDChat-On-Steroids-Setup-arm64.exe— Arm (Snapdragon, Surface Pro X)Chat-On-Steroids-Extension.zip— the extension on its own, for loading unpackedSHA256SUMS.txt— checksums for all three
This is the first published release to carry the goal loop. It supersedes 1.9.9, which was tagged
in the repository but never published.
Why 2.0
Not because of what is on screen. Three modules that production no longer reached were deleted
outright, exec_command began refusing shell text it used to run against the wrong filesystem
dialect, and two process launchers stopped handing connector credentials to their children.
Anything built against the removed internals, or against the old pass-through behaviour, will
notice. The user-facing surface is the same one 1.9.9 described.
The goal loop
A second model reads each finished ChatGPT answer and writes your next message for you, until it
decides the thing you asked for is done — at which point it writes nothing at all. Off by default,
and it needs an OpenRouter API key, which is the one credential in this app a model can cause to
be spent.
The trust boundary is where the work splits. The page owns the one judgement only a browser can
make — that the turn is really over — using the same four-signal barrier a compaction brief waits
on: the stop control gone, the answer no longer growing, the tool rail still, and the app
reporting no local call open, held for eight seconds. A reply that fires early types "what about
the tests" into a chat that is still writing them, and the model then answers it as if it were a
correction. Everything after the barrier is the app's: the context, the key, the request, and one
draft per generation.
What leaves this machine is only your messages and ChatGPT's final answers — not tool calls, not
their results, not the interim commentary a turn produces while it works. A recorded session holds
file contents and command output, and none of that is anybody's next chat message.
The compaction button on the composer is a gear now, opening a small settings sheet in ChatGPT's
own type and hairline: a switch each for automatic compaction and the goal loop, and Compact &
resume now as its single action. The panel above the composer says what the loop is doing, and a
failure shows its code rather than going quiet.
What was fixed
The full write-up is in docs/bughunt-follow-up-2026-08-24.md. Credible leads that were reviewed
but not reproducible enough to fix are tracked privately rather than published — see SECURITY.md.
- A patch that moved a file onto itself deleted it.
apply_patchwrites the destination then
removes the source, sosource.txtand./source.txtwrote the new contents and immediately
unlinked them. Move verification now compares resolved identities and refuses before anything is
mutated. - A glob starting with
*searched a virtual root instead of your workspace. With no literal
prefix before the first wildcard,*.tsand**/*.tsquietly asked a different question — and
answered it successfully, which is the worse half. - A malformed Goal stream record could be typed into the composer as a finished reply. A
truncated sentence was promoted to a message at EOF. A malformed record is now a protocol
failure: the stream is cancelled and no draft is exposed. - Compact & Resume, automatic compaction and Goal startup used the capped UI list as an
ownership index, so a valid older conversation came backsession_not_recorded. All three now
use the durable catalog. - Editing a Chat setting could be undone by a background status push. Home controls had a
focused-dirty guard; the Chat sheet did not, so a half-typed threshold or worker count could be
wiped mid-edit. - Virtual app paths inside shell text ran against the wrong filesystem dialect. PowerShell
reads/workspace/fileas a drive-root path, not this app's approved virtual root.exec_command
now refuses that and names the two fallbacks that work. - A broken desktop helper could keep input authority while its replacement started, because
its post-start error path skipped the retirement barrier that every other failure waits on. - "Extension folder opened" was shown when it had not. Electron reports
shell.openPath
failure as a resolved error string, and the handler discarded it. - Renderer redirects are vetoed as well as navigations;
swarm:clearAgentvalidates its id at the
IPC boundary;readcharges the base64 it actually emits against its output budget; Fiber no
longer skips assistant turns without adata-turn-id, nor swallows a message on a second id
collision; and recovery hints stopped suggesting fixes for causes the command did not contain.
Security
Tunnel children inherited ambient connector credentials. The OpenAI tunnel client spread raw
process.env and cloudflared inherited the environment implicitly, so starting the app from a
credential-bearing terminal passed unrelated provider secrets into both children. Both launch
paths now use the shared environment scrubber, and the OpenAI path adds back only its own
control-plane key, the local MCP URL and its discovery headers.
Build
Built and smoke-tested on native Windows x64 and ARM64 runners, with the full typecheck-and-test
gate — 49 suites, 1,411 tests — green on both. noUnusedLocals and noUnusedParameters are now
permanently on; they are what surfaced most of the dead code this release removes.
Beta despite the version number. Behaviour may still change between releases.