Repository navigation
fix(daemon): allowlist the active skill root for external_directory - #8178
AmyShang-alt merged 1 commit into
Conversation
… allowlist resolveChatExtraAllowedDirs built the allowlist from SKILLS_DIR only, so a skill installed under the daemon data dir or loaded from a bundled plugin folder resolved to a root outside it. withSkillRootPreamble still advertises that root as the absolute fallback path, so OpenCode asked for external_directory approval on files OD itself pointed the agent at, and a headless run reported the ask as a rejected tool call. Pass the turn's active skill dirs so the allowlist is keyed on the roots actually in play. Codex stays excluded: it treats allowlisted dirs as writable and skill roots are read-only resources.
|
Thanks @aron-intframe — the description clearly connects the permission prompt to the active skill root. The change is now in the review queue. |
|
Queued for QA validation — this change affects a live skill-execution path and needs a manual pass before merge. Nothing needed from you right now; we’ll update here once it is validated. |
PerishCode
left a comment
There was a problem hiding this comment.
@aron-intframe I verified that the daemon now carries every resolved active skill directory into the run-scoped external-directory allowlist while preserving the Codex exclusion, and that the regression coverage exercises both a user skill through the real chat route and the shipped plugin-local asset shape. The change stays within the existing prompt, staging, and runtime-config seams. Nicely focused fix, and the layered tests make the intended fallback behavior especially clear.
🔁 Powered by Looper · runner=reviewer · agent=codex · An autonomous AI dev team for your GitHub repos.|
Thanks for the approval. I re-ran both of your claims on a clean clone of the reviewed SHA ( Falsification, one half at a time. Deleting Restoring that and instead dropping the A correction to my own PR description. I described the new suite as "red before the fix: 0/4 manifest-declared assets allowed". Only one of its three cases is actually falsifiable against the change. The caveat I filed does not reproduce. I wrote that Where "every resolved active skill directory" has an edge, since QA is about to exercise this path: two other sites deliberately pass an empty list, Also not verified: a real |
QA Acceptance Record@aron-intframe QA passed for the verified scope at head
Environment record: the QA Electron/web/daemon namespace was stopped, its ports closed, and the disposable runtime data and copied credential removed. Durable evidence and the QA worktree/dependencies were retained. An earlier unsandboxed test invocation touched shared OpenCode log/database/lock state; additional skill-file changes were observed but cannot be attributed. Full restoration is unproven, and no unsafe rollback of concurrent user state was attempted. This remains a separately disclosed local environment incident, not a confirmed PR defect. Associated acceptance suggestion: perform the planned packaged-app smoke for bundled and user-installed skill resource reads. |
🎉 📡 You just leveled up to Giotto
🙌 Your contributions are sending a clear signal across the network: you care about making Open Design better. Keep transmitting. 💛 Thanks for helping Open Design move forward. Keep building in the open. 🚀 📊 Rank #206 among 800+ contributors |
|
Thanks for the record. I re-ran it against merged The test count matches exactly. Node 24.21 / pnpm 10.33.2, both touched suites:
"Two targeted regression cases" is the right count, and each half of the fix carries exactly one. Removing Restoring that and instead dropping the The third case in that suite is a fixture guard rather than regression cover, as I corrected earlier, so your count of two is the honest one. On the deferred packaged smoke, I can rule one failure mode out for you statically. The risk worth naming is that a bundled skill root is unreadable by the external
What I did not verify. There is no real OpenCode or Codex binary in this environment ( |

Fixes #8173
Why
resolveChatExtraAllowedDirsbuilds the run-scoped allowlist fromSKILLS_DIRonly, whilewithSkillRootPreamble()advertises the active skill's own root as the absolute fallback path. A plugin-localSKILL.mdloads from the bundled plugin folder, so the four filesweb-prototype/open-design.jsondeclares inod.context.assetssit outside it: OpenCode correctly sees an external directory, asks, and a headless run reports the ask as a rejected tool call.SKILL_ROOTSis[USER_SKILLS_DIR, SKILLS_DIR], so data-dir skills hit it too.Passing the turn's active skill dirs keys the allowlist on the roots in play. Codex still gets none, it treats allowlisted dirs as writable (#622).
What users will see
Bundled and user-installed skills read their own side files without a permission prompt. No new setting.
Surface area
Bug fix verification
tests/skill-root-external-directory.test.ts— red before the fix: 0/4 manifest-declared assets allowed; green after: 4/4.tests/chat-route.test.ts→ "allowlists the active skill root…" — real/api/chatturn, fakeopencodeon PATH, readsOPENCODE_CONFIG_CONTENT. Red whenactiveSkillDirsis dropped at the call site.Validation
pnpm guard, daemontypecheck, touched suites.chat-route.test.tsaborts mid-file in my sandbox on abetter-sqlite3teardown assertion, identical on unmodifiedmain: my locally built native module, not this change. The new case passes with-t.Not covered: the lost-prompt-on-restart half of #8173, and the
memory-llmBYOK id.