You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
execute_codenever registers a tool in the packaged desktop app. It's a hard, unconditional gate with no config override. The consequence isn't one broken feature — any plugin or skill whose capability routes through code execution is silently inert on our flagship distribution, including the Cowork archetype's entire document half.
This also means ADR 0092 D1 does not achieve its stated outcome: bundling the doc stack made cowork install on desktop, but its doc skills still can't run there.
The gate
plugins/execute_code/__init__.py:35-40
# Frozen desktop build: spawning a Python subprocess needs a standalone# interpreter the PyInstaller binary doesn't ship. Don't register the tool# there at all — it simply won't exist (matches the old core behavior).ifgetattr(sys, "frozen", False):
log.info("[execute_code] packaged desktop build — no standalone Python, tool not loaded")
return
Root mechanism — plugins/execute_code/engine.py:143-155: code runs via create_subprocess_exec(sys.executable, …), and in a PyInstaller build sys.executableis the frozen server binary, not an interpreter. The reasoning is sound; the consequence is what needs a platform answer.
"I don't have a code execution tool available in my current toolset — the docx skill requires execute_code to run python-docx and produce the .docx file."
Why this is bigger than docx
ADR 0092's own framing:
"The desktop app can't make a .docx" is a credibility gap for that positioning, not a plugin edge case.
and D1's stated effect:
cowork's hardrequires_pip is simply satisfied — cowork installs and works on desktop with zero manifest change.
D1 delivered the first half (deps satisfied → installs) but not the second (works). cowork's docx/xlsx/pptx/pdf skills all author documents throughexecute_code, so on desktop they still cannot produce a file. "The desktop app can't make a .docx" is still true after #2123.
Generalizing — the blast radius is the capability tier, not the feature:
ADR 0083 Cowork archetype — a first-party flagship whose headline document half is dead on the very distribution it targets ("own your stack", local-first).
ADR 0092 D1 (feat(desktop): bundle the document-generation stack (ADR 0092 D1) #2123) — goal unreachable as-is. (The bundled libs do still earn their keep: save_file_artifact's preview extractors run in-process, so D2/D3 previews work. D1 is not wasted — it's just insufficient for generation.)
Any future plugin that computes rather than calls an API hits the same wall on desktop.
Secondary: the limitation is invisible
The plugin reports as loaded, the gate logs at INFO, and the operator-facing copy in engine.py says "turn it off under Settings ▸ Tools ▸ Enable execute_code" — implying it could be on. So a desktop operator can enable an arbitrary-code-execution capability and receive zero signal that it does nothing. That cuts against ADR 0071's "present only the boundary we enforce": here we present a capability we structurally can't provide.
Possible directions (core's call)
In-process execution path for frozen builds — reuse the existing timeout / tools allowlist posture. Worth noting the plugin's own docstring already says subprocess isolation "is isolation, NOT a true sandbox" (the script reaches disk/network as the server user), so in-process may be less of a posture change than it first appears. Still a real security decision.
First-party in-process document tools — build .docx/.xlsx/.pptx directly with the now-bundled libs, no subprocess. Narrower and safer than general code execution, and it directly delivers ADR 0092's goal without granting arbitrary execution. Probably the cheapest path to "the desktop app can make a .docx."
Ship a standalone interpreter for execute_code to spawn (heaviest; likely previously rejected on bundle size).
At minimum — make it visible. Surface "unavailable on desktop" in the plugin list / Settings / archetype catalog, and don't let an operator enable a no-op capability silently. This is worth doing regardless of which of 1-3 is chosen.
How this surfaced
Building the careercoach plugin's render_format: docx path on top of #2123/#2126. Everything verified green — doc libs confirmed extracted and importable in the running v0.107.0 sidecar (docx, openpyxl, pptx, reportlab, PIL), save_file_artifact verified working end-to-end on a real .docx (blob stored, text preview extracted, versioned in place) — and it still can't generate a document on desktop, purely because of this gate. Happy to provide the repro or test against a fix.
Summary
execute_codenever registers a tool in the packaged desktop app. It's a hard, unconditional gate with no config override. The consequence isn't one broken feature — any plugin or skill whose capability routes through code execution is silently inert on our flagship distribution, including the Cowork archetype's entire document half.This also means ADR 0092 D1 does not achieve its stated outcome: bundling the doc stack made cowork install on desktop, but its doc skills still can't run there.
The gate
plugins/execute_code/__init__.py:35-40Root mechanism —
plugins/execute_code/engine.py:143-155: code runs viacreate_subprocess_exec(sys.executable, …), and in a PyInstaller buildsys.executableis the frozen server binary, not an interpreter. The reasoning is sound; the consequence is what needs a platform answer.Observed on a live v0.107.0 desktop install
The agent, asked to produce a
.docx:Why this is bigger than docx
ADR 0092's own framing:
and D1's stated effect:
D1 delivered the first half (deps satisfied → installs) but not the second (works). cowork's
docx/xlsx/pptx/pdfskills all author documents throughexecute_code, so on desktop they still cannot produce a file. "The desktop app can't make a .docx" is still true after #2123.Generalizing — the blast radius is the capability tier, not the feature:
save_file_artifact's preview extractors run in-process, so D2/D3 previews work. D1 is not wasted — it's just insufficient for generation.)Secondary: the limitation is invisible
The plugin reports as loaded, the gate logs at INFO, and the operator-facing copy in
engine.pysays "turn it off under Settings ▸ Tools ▸ Enable execute_code" — implying it could be on. So a desktop operator can enable an arbitrary-code-execution capability and receive zero signal that it does nothing. That cuts against ADR 0071's "present only the boundary we enforce": here we present a capability we structurally can't provide.Possible directions (core's call)
toolsallowlist posture. Worth noting the plugin's own docstring already says subprocess isolation "is isolation, NOT a true sandbox" (the script reaches disk/network as the server user), so in-process may be less of a posture change than it first appears. Still a real security decision..docx/.xlsx/.pptxdirectly with the now-bundled libs, no subprocess. Narrower and safer than general code execution, and it directly delivers ADR 0092's goal without granting arbitrary execution. Probably the cheapest path to "the desktop app can make a .docx."execute_codeto spawn (heaviest; likely previously rejected on bundle size).How this surfaced
Building the
careercoachplugin'srender_format: docxpath on top of #2123/#2126. Everything verified green — doc libs confirmed extracted and importable in the running v0.107.0 sidecar (docx,openpyxl,pptx,reportlab,PIL),save_file_artifactverified working end-to-end on a real.docx(blob stored, text preview extracted, versioned in place) — and it still can't generate a document on desktop, purely because of this gate. Happy to provide the repro or test against a fix.