The original implementation tried to integrate `--set` with the prompt /
result-template / schema-strict-partition system: pre-seeding answers,
filtering questions, evaluating function defaults, tracking override
keys for partition exemption, mirroring carry-forward in two collection
helpers, threading state through Config + ui.js + collection helpers +
manifest writer. ~900 lines spawned across 4 review rounds, with bugs
the bots kept finding because every change touched a different layer.
The simpler model: `--set` is a post-install patch. The installer runs
its normal flow untouched, then `applySetOverrides` upserts each value
into `_bmad/config.toml` (team scope) or `_bmad/config.user.toml` (user
scope) AND into `_bmad/<module>/config.yaml` so declared keys carry
forward via the existingValue path on the next install.
What gets ripped out
- All `setOverrides` plumbing through OfficialModules (constructor
field, applyOverridesAfterSeeding, _trackUnknownKeysAsOverrides,
declaredResultKeys, override classification + pre-write +
question-filter + two-pass function-defaults + carry-forward in
collectModuleConfig, _trackUnknownKeysAsOverrides calls in
collectModuleConfigQuick, headless-branch additions in
Installer.build). official-modules.js reset to its pre-#1663 baseline
(commit 48a7ec8b).
- `setOverrideKeys` field on Config, threading from ui.js, partition
exemption parameter on `manifest-generator.writeCentralConfig`.
- The "ignored under quick-update" warning in install.js — `--set` is
now a uniform post-install patch, so it works the same way for
quick-update as for a regular install.
What stays
- `tools/installer/set-overrides.js` parser with the prototype-pollution
guard, prefixed by the new `applySetOverrides` / `upsertTomlKey` /
`tomlString` / `tomlHasKey` helpers.
- `tools/installer/list-options.js` — small standalone discovery
helper, untouched.
- The `--set` and `--list-options` CLI flag registration in
`commands/install.js`.
- ui.js `collectModuleConfigs` retains the early-feedback warning for
overrides targeting modules not in the install set (and now also
filters them out of `setOverrides` before threading).
Routing rules (post-install patch)
- If `_bmad/config.user.toml` already has `[section] key`, update it
there (so user-scope keys like `core.user_name` and
`bmm.user_skill_level` keep their proper file).
- Otherwise update `_bmad/config.toml` (team scope, default).
- A module without `_bmad/<module>/config.yaml` (i.e. not installed)
is skipped silently — no orphan `[modules.notamodule]` sections.
Tradeoffs documented in `docs/how-to/install-bmad.md`
- Values are written verbatim — no `result:` template rendering. Pass
`--set bmm.project_knowledge='{project-root}/research'` if you want
the rendered form.
- Carry-forward is automatic for declared schema keys (per-module yaml
→ existingValue → prompt default → accepted under --yes). For keys
outside any module's schema, the value lands in `config.toml` for
the current install but won't be re-emitted on the next install.
Re-pass `--set` if you need it sticky.
- No "key not in schema" validation — whatever you assert is written.
Tests: Suite 44 rewritten. 355 passing (was 351). Coverage now focused
on what matters: parser + pollution guard, tomlString escaping,
upsertTomlKey across insert/replace/missing-section/empty-file/
preserved-newline cases, applySetOverrides happy path + uninstalled-
module skip + missing-user-toml-creation + empty-input no-op,
discoverOfficialModuleYamls / formatOptionsList sanity.
E2E smoke verified across all 6 scenarios:
1. fresh install with mixed declared + undeclared --set → correct files
2. quick-update no --set → declared keys persist via per-module yaml
3. quick-update WITH --set → applies (used to be warned + dropped)
4. --set for unselected module → warned, no orphan section
5. prototype pollution → exit 1
6. --list-options bmm exit 0, --list-options nope exit 1
Net: -158 lines vs HEAD. The complex integration was load-bearing for
edge cases nobody actually needed; the simple post-install patch
covers the real use case (script a config value from CI) without the
schema gymnastics.