The CLI resolves a config for specs generate --from-bridge and then never sends it. postGenerateFromSelection({ fileKey, nodeId }) carries only those two fields, so the plugin processes the node under whatever its own UI settings happen to be. The CLI's --config governs only where output is written.
Why it matters
Every render round-trip in the #208 verification loop silently compares a baseline generated under one config against a read performed under another. The differences that produces look exactly like render fidelity loss.
Concretely, from the #266 investigation: the plugin's Include invalid variants setting defaults to off. testWrap's baseline holds 47 variant entries (8 valid + 39 invalid); it read back as 8. The differ compares index-to-index, so {b:2} was compared against {a:2,b:2,c:2} and every subsequent row cascaded.
Turning that one toggle on took four fixtures from 231 differences to 1 — and that last one was a genuine defect that had been buried in the noise the whole time.
| Component |
Config mismatched |
Config matched |
| testChildren |
14 |
0 |
| testChildren2 |
17 |
0 |
| testWrap |
101 |
0 |
| testWrap2 |
99 |
1 (real) |
The harness does warn about the mismatch, but a warning next to a 101-row table reads as a footnote.
Where the config would flow
| Layer |
Change |
Size |
cli/src/bridge/client.ts |
add config?: ResolvedConfig to GenerateFromSelectionRequestBody |
~2 lines |
cli/src/commands/GenerateCommand.ts |
pass it — modelConfig is already loaded at line 277 |
~1 line |
cli/src/bridge/server.ts |
widen the /generate params, thread through sendGenerateFromSelection, add to the ws message |
~4 lines |
specs-plugin-2/src/UI/Managers/MessageManager.ts |
read m.config, pass into this.specs.process(...) |
~2 lines |
specs-plugin-2/src/SpecsController.ts |
the actual work — see scope decision |
— |
Pending decision — scope
SpecsController.process() reads this._settings at four points, not one:
buildPhaseConfiguration(this._settings) (line 119)
settingsToModelConfig(this._settings) (line 125)
FORMAT_OUTPUT, choosing YAML vs JSON (line 162)
new OutputController(this._settings) (line 170)
Two options:
- Narrow — override
settingsToModelConfig only. ~15 lines across all repos. Fixes the entire class of bug above, since include and processing are what shape the spec body. Leaves format.output still stamped from UI state, so that config-mismatch warning persists (benign — the harness writes YAML either way).
- Complete — make
process() take a ResolvedConfig and thread it through all four sites. Forces a decision about buildPhaseConfiguration and OutputController, which are Settings-shaped rather than ResolvedConfig-shaped. Roughly a day, with real regression risk in the plugin's normal interactive path.
Recommendation: narrow, escalating only if it proves insufficient.
Whichever is chosen, a per-request config must not persist into the plugin's stored UI settings — an automated round-trip should not silently reconfigure the user's plugin.
Note on config resolution
generate --from-bridge has no source spec to read a config from — it is creating one. The CLI's existing resolution (--config, else the workspace root) is already correct and already in hand; it simply is not sent. A two-step "config in the spec's source, falling back to the workspace root" applies to render, where a baseline spec exists and carries metadata.config.
Done when
- A
generate --from-bridge run reports metadata.config.include and metadata.config.processing matching the config the CLI resolved, regardless of the plugin's UI settings.
- A round-trip of testWrap with the plugin toggles deliberately set wrong still reports 0 fidelity differences.
- The plugin's stored settings are unchanged after such a run.
The CLI resolves a config for
specs generate --from-bridgeand then never sends it.postGenerateFromSelection({ fileKey, nodeId })carries only those two fields, so the plugin processes the node under whatever its own UI settings happen to be. The CLI's--configgoverns only where output is written.Why it matters
Every render round-trip in the #208 verification loop silently compares a baseline generated under one config against a read performed under another. The differences that produces look exactly like render fidelity loss.
Concretely, from the #266 investigation: the plugin's Include invalid variants setting defaults to off. testWrap's baseline holds 47 variant entries (8 valid + 39 invalid); it read back as 8. The differ compares index-to-index, so
{b:2}was compared against{a:2,b:2,c:2}and every subsequent row cascaded.Turning that one toggle on took four fixtures from 231 differences to 1 — and that last one was a genuine defect that had been buried in the noise the whole time.
The harness does warn about the mismatch, but a warning next to a 101-row table reads as a footnote.
Where the config would flow
cli/src/bridge/client.tsconfig?: ResolvedConfigtoGenerateFromSelectionRequestBodycli/src/commands/GenerateCommand.tsmodelConfigis already loaded at line 277cli/src/bridge/server.ts/generateparams, thread throughsendGenerateFromSelection, add to the ws messagespecs-plugin-2/src/UI/Managers/MessageManager.tsm.config, pass intothis.specs.process(...)specs-plugin-2/src/SpecsController.tsPending decision — scope
SpecsController.process()readsthis._settingsat four points, not one:buildPhaseConfiguration(this._settings)(line 119)settingsToModelConfig(this._settings)(line 125)FORMAT_OUTPUT, choosing YAML vs JSON (line 162)new OutputController(this._settings)(line 170)Two options:
settingsToModelConfigonly. ~15 lines across all repos. Fixes the entire class of bug above, sinceincludeandprocessingare what shape the spec body. Leavesformat.outputstill stamped from UI state, so that config-mismatch warning persists (benign — the harness writes YAML either way).process()take aResolvedConfigand thread it through all four sites. Forces a decision aboutbuildPhaseConfigurationandOutputController, which areSettings-shaped rather thanResolvedConfig-shaped. Roughly a day, with real regression risk in the plugin's normal interactive path.Recommendation: narrow, escalating only if it proves insufficient.
Whichever is chosen, a per-request config must not persist into the plugin's stored UI settings — an automated round-trip should not silently reconfigure the user's plugin.
Note on config resolution
generate --from-bridgehas no source spec to read a config from — it is creating one. The CLI's existing resolution (--config, else the workspace root) is already correct and already in hand; it simply is not sent. A two-step "config in the spec's source, falling back to the workspace root" applies torender, where a baseline spec exists and carriesmetadata.config.Done when
generate --from-bridgerun reportsmetadata.config.includeandmetadata.config.processingmatching the config the CLI resolved, regardless of the plugin's UI settings.