What happens
bb plugin reload <id> on a path-installed plugin rebuilds its dist/ using the host's own build. A plugin that ships a repository build script cannot make reload use it, so any behaviour that lives in that script is absent from the artifact the running plugin actually serves.
Our case: our build script excludes a docs/ directory from the staged tree, because the CSS scanner would otherwise emit utility classes derived from documentation prose. The host build has no such exclusion, so every reload reintroduces those rules into the shipped bundle. Isolated observation on 0.38.0:
| step |
dist/ dirty |
leaked classes |
| restore committed dist |
0 |
0 |
| wait 20s, no reload |
0 |
0 |
bb plugin reload <id> |
3 |
4 |
The waiting step is there to show nothing drifts on its own — the rebuild is caused by the reload.
The rebuilt dist/*.meta.json is also stamped with the local host toolchain rather than whatever produced the committed artifact, so the deployed checkout and its own commit diverge immediately and permanently after any reload.
Why we could not work around it
We looked for a hook before building a detector. On 0.38.0 the reload path reaches the internal loadOne / buildPluginApp directly, and neither the plugin manifest nor the reload CLI exposes a way to nominate a repository build command. If one exists and we missed it, that is the answer and we would rather be told.
What we shipped instead is a post-reload check that compares the deployed working tree against its own committed dist and fails loudly. It works, but it detects after the fact — it cannot stop the rebuild, and it cannot prevent the temporary divergence in between.
Why this is more than cosmetic for us
It quietly breaks the relationship between a commit and what is running. Three things we believed were protected were not:
- a fix in our build script protects the committed artifact and CI, not the running plugin
- a repository-side freshness gate protects the repository, not the deployment
- "deployed HEAD equals main" is not the same as "the running artifact equals the committed artifact"
We checked the third for an entire session and treated it as the second. The leak itself is bundle bloat with no data or security impact; the provenance break is the part that matters.
What would fix it
Any of:
- A manifest field naming a build command that
reload invokes for path plugins.
- A
--no-build (or equivalent) flag so reload loads the committed artifact as-is and leaves building to the plugin's own tooling.
- Documenting that reload always rebuilds with the host build, so plugin authors do not assume their build script governs the deployed artifact.
Option 2 is the smallest and would have solved our case completely — we already build correctly; we only need reload not to overwrite it.
What happens
bb plugin reload <id>on a path-installed plugin rebuilds itsdist/using the host's own build. A plugin that ships a repository build script cannot make reload use it, so any behaviour that lives in that script is absent from the artifact the running plugin actually serves.Our case: our build script excludes a
docs/directory from the staged tree, because the CSS scanner would otherwise emit utility classes derived from documentation prose. The host build has no such exclusion, so every reload reintroduces those rules into the shipped bundle. Isolated observation on 0.38.0:dist/dirtybb plugin reload <id>The waiting step is there to show nothing drifts on its own — the rebuild is caused by the reload.
The rebuilt
dist/*.meta.jsonis also stamped with the local host toolchain rather than whatever produced the committed artifact, so the deployed checkout and its own commit diverge immediately and permanently after any reload.Why we could not work around it
We looked for a hook before building a detector. On 0.38.0 the reload path reaches the internal
loadOne/buildPluginAppdirectly, and neither the plugin manifest nor thereloadCLI exposes a way to nominate a repository build command. If one exists and we missed it, that is the answer and we would rather be told.What we shipped instead is a post-reload check that compares the deployed working tree against its own committed
distand fails loudly. It works, but it detects after the fact — it cannot stop the rebuild, and it cannot prevent the temporary divergence in between.Why this is more than cosmetic for us
It quietly breaks the relationship between a commit and what is running. Three things we believed were protected were not:
We checked the third for an entire session and treated it as the second. The leak itself is bundle bloat with no data or security impact; the provenance break is the part that matters.
What would fix it
Any of:
reloadinvokes for path plugins.--no-build(or equivalent) flag so reload loads the committed artifact as-is and leaves building to the plugin's own tooling.Option 2 is the smallest and would have solved our case completely — we already build correctly; we only need reload not to overwrite it.