Conversation
File-based third-party bar widgets receive this facade instead of createScopedPluginShell. Without _serviceLookup, serviceFor() is always null and own-service panels silently no-op. Co-authored-by: Steve Curry <thescurry@users.noreply.github.com>
Automated AI review: request changesThis review was produced by an AI coding agent using runtime A/B tests in two isolated Omarchy sessions, not just static code analysis. The intended fix works, but this PR introduces a cross-plugin service-access regression. File-based QML widgets can now access their own service. However, a third-party replacement bar can also obtain and mutate another enabled plugin's service. The parent commit blocks that access. Tested parent ReproductionFrom a replacement-bar plugin's scoped shell facade: const entry = shell.pluginShellForBarEntry("probe", "test.registered")
const service = entry.serviceFor("test.registered")
if (service) service.increment()
EvidenceParent: cross-plugin access blocked PR: service exposed and mutated Read the probe at the top of each screenshot; terminal history below it is not the assertion result. Runtime assertions reproduced the regression twice, including after lifecycle checks and a shell restart. The existing targeted auth-boundary suite passes on both revisions and misses this path. Requested changePreserve the replacement-bar service boundary while enabling file-based widgets to access their own service. One approach is to keep replacement-bar entry facades service-less and grant own-service lookup through a trusted built-in-bar path. Add a runtime regression test using an actual replacement-bar plugin. This is a documented facade-boundary regression, not a demonstrated OS sandbox escape. Plugins already run unsandboxed. The null lock-service lookup is not evidence of authentication-service isolation because lock was disabled in the test configuration. Environment: Hyprland 0.56.2 with Quickshell, tested 2026-09-16. Matching inherited configurations, not clean-install defaults. |


Summary
Fixes #11949: installed third-party bar widgets got a
PluginShellApifrompluginShellForBarEntry()with no_serviceLookup, sobar.shell.serviceFor(id)always returnednulland panels that gate onif (svc)silently no-opped.Change
_serviceLookupinpluginShellForBarEntry()viashell.pluginServiceFor(target, requestedId)— same ownership-gated path ascreateScopedPluginShell().test/shell.d/plugin-auth-boundary-test.sh.Clone-id lookup PRs (#10429 / #10416 / #7587) are a different bug and were not touched.
Test plan
bash test/shell.d/plugin-auth-boundary-test.shc3efab8