docs(agent): guardrail — never mkDefault a list/attrset option that merges
Some checks failed
Check / eval-and-lint (push) Failing after 7m7s
Some checks failed
Check / eval-and-lint (push) Failing after 7m7s
The "mkDefault everywhere user might override" rule is what caused the home.packages bug. Clarify: mkDefault is for scalars; on list/attrset options that other modules contribute to, a mkDefault def is dropped entirely (filterOverrides) rather than merged. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -77,7 +77,7 @@ These are inherited from the established Nomarchy conventions. Violating them is
|
||||
1. **Declarative-first.** No imperative state in `core/`. Mutable state goes in `~/.config/nomarchy/state.json` or in NixOS / home-manager options.
|
||||
2. **Downstream-flake friendly.** Every behavior toggle is a `nomarchy.*` option documented in `docs/OPTIONS.md`. Adding a feature without a corresponding option is a bug.
|
||||
3. **Opt-in by default.** New features default off (or default to existing behavior). The installer can flip defaults *for the user being installed*, but the option must read sensibly when set by hand.
|
||||
4. **`lib.mkDefault` everywhere user might override.** If a downstream `system.nix` would reasonably want to change something Nomarchy sets, set it with `lib.mkDefault`. If it must not be overridden, use `lib.mkForce` and explain why in a comment.
|
||||
4. **`lib.mkDefault` on *scalars* the user might override — never on lists/attrsets that merge.** If a downstream `system.nix` would reasonably want to change a scalar Nomarchy sets (a string, bool, int), set it with `lib.mkDefault`. If it must not be overridden, use `lib.mkForce` and explain why. **But do not wrap a list or attrset option (`home.packages`, `environment.systemPackages`, `boot.kernelParams`, …) in `lib.mkDefault`** when other modules also contribute to it: the module system's `filterOverrides` keeps only the highest-priority definitions, so a `mkDefault` list is *silently discarded the moment any module sets that option at normal priority* — it doesn't merge, it vanishes. This dropped the entire curated `home.packages` (firefox, mako, hyprlock, …) and broke notifications + the lock screen distro-wide (`1117dcf`, `f34f59c`). A plain list/attrset is the correct default — it merges, and downstream can still add to it (to *remove* a default, downstream uses `mkForce`/filtering, which is rare).
|
||||
5. **Reuse before invent.** ~155 `nomarchy-*` scripts already exist across `core/system/scripts/`, `features/scripts/utils/`, `themes/engine/scripts/`. Grep before writing a new one.
|
||||
6. **No comments that narrate.** Don't write comments explaining *what* the code does. Only write a comment when the *why* is non-obvious — a hidden constraint, a subtle invariant, a workaround.
|
||||
7. **No backwards-compat shims.** If you remove a thing, remove it everywhere. No re-exports, no `// removed` markers.
|
||||
|
||||
Reference in New Issue
Block a user