Before you submit
What happened?
Two related host defects prevent pipeline plugins from reliably reaching existing-project runs:
POST /api/plugins/:id/apply correctly returns a pure snapshot with snapshotId: "", but the web send path forwards only that empty ID. /api/runs receives neither pluginId nor pluginInputs, so the selected plugin is omitted or an older project pin is reused.
- A restricted plugin with
od.pipeline.stages requires pipeline:*, but the trust endpoint rejects that exact capability. If the grant is otherwise persisted, applyPlugin() recomputes defaults instead of using capabilitiesGranted, so the grant is ignored and revoked trusted capabilities can reappear.
Steps to reproduce
- Install a plugin with
od.pipeline.stages and attach it from an existing project's composer.
- Send a message and inspect
POST /api/runs; the request has no plugin identity or inputs because pure apply returned an empty snapshot ID.
- Install the same plugin from a URL/GitHub source so it is restricted.
- Run
od plugin trust <id> --capabilities pipeline:*; the daemon returns invalid-capability.
- Persist the grant directly and apply again; the snapshot still uses recomputed trust defaults rather than the stored grants.
Expected behavior
When pure apply has no snapshot ID, the existing-project run should send pluginId and pluginInputs so the daemon can persist and pin the snapshot. pipeline:* should be a valid persistent grant, and apply should honor stored grants while retaining the prompt:inject floor.
Open Design version
0.16.1, reproduced on main at f52fda29a
Platform
Linux
Logs (optional)
POST /api/plugins/<id>/trust -> 400 invalid-capability: pipeline:*
POST /api/runs -> 409 capabilities-required after the grant is stored
Screenshots (optional)
Not applicable.
Additional context
Reproduced with a real custom publishing plugin and isolated daemon data. Relevant paths are ProjectView.tsx -> providers/daemon.ts -> /api/runs, plus plugins/trust.ts and plugins/apply.ts. Focused regression tests and an imported-project fake-agent run confirm the expected behavior.
Note: I did use opencode and GPT 5.6 Sol to do this investigation and a PR with fixes for the issues I ran into testing a custom plugin.
Before you submit
od --version.What happened?
Two related host defects prevent pipeline plugins from reliably reaching existing-project runs:
POST /api/plugins/:id/applycorrectly returns a pure snapshot withsnapshotId: "", but the web send path forwards only that empty ID./api/runsreceives neitherpluginIdnorpluginInputs, so the selected plugin is omitted or an older project pin is reused.od.pipeline.stagesrequirespipeline:*, but the trust endpoint rejects that exact capability. If the grant is otherwise persisted,applyPlugin()recomputes defaults instead of usingcapabilitiesGranted, so the grant is ignored and revoked trusted capabilities can reappear.Steps to reproduce
od.pipeline.stagesand attach it from an existing project's composer.POST /api/runs; the request has no plugin identity or inputs because pure apply returned an empty snapshot ID.od plugin trust <id> --capabilities pipeline:*; the daemon returnsinvalid-capability.Expected behavior
When pure apply has no snapshot ID, the existing-project run should send
pluginIdandpluginInputsso the daemon can persist and pin the snapshot.pipeline:*should be a valid persistent grant, and apply should honor stored grants while retaining theprompt:injectfloor.Open Design version
0.16.1, reproduced on
mainatf52fda29aPlatform
Linux
Logs (optional)
Screenshots (optional)
Not applicable.
Additional context
Reproduced with a real custom publishing plugin and isolated daemon data. Relevant paths are
ProjectView.tsx->providers/daemon.ts->/api/runs, plusplugins/trust.tsandplugins/apply.ts. Focused regression tests and an imported-project fake-agent run confirm the expected behavior.Note: I did use opencode and GPT 5.6 Sol to do this investigation and a PR with fixes for the issues I ran into testing a custom plugin.