diff --git a/rfcs/0169-feature-parameter-names.md b/rfcs/0169-feature-parameter-names.md
new file mode 100644
index 000000000..4a81e2191
--- /dev/null
+++ b/rfcs/0169-feature-parameter-names.md
@@ -0,0 +1,595 @@
+---
+feature: feature_parameter_names
+start-date: 2024-01-10
+author: Dmitry Bogatov
+co-authors: (find a buddy later to help out with the RFC)
+shepherd-team: (names, to be nominated and accepted by RFC steering committee)
+shepherd-leader: (name to be appointed by RFC steering committee)
+related-issues: (will contain links to implementation PRs)
+---
+
+# Summary
+[summary]: #summary
+
+Nixpkgs has mechanisms to exports compile-time options of the upstream build
+system through the named parameters of derivation function, but the names of
+these parameters are inconsistent from package to package and from feature to
+feature.
+
+# Motivation
+[motivation]: #motivation
+
+Developer interface for building environment with specific features enabled and
+disabled is more complicated and and involves more "you just have to know it"
+compared to already existing systems.
+
+1. Writing generic code is complicated. Even if list of packages all have
+   optional dependency on package `foo`, duck-typing like
+
+```
+map (p: p.override { with_foo = false; }) packages
+```
+
+won't work because of lack of uniformity, leading to ugly code downstream.
+
+2. If user wants to globally disable support for optional feature or build
+   dependency as much as possible, he needs to set multiple feature parameters,
+   and he still can miss some. E.g, it is not obvious whether the following
+   list is enough to cover everything X11-related:
+
+```
+withX
+withX11
+x11Support
+enableX
+```
+
+3. There is no clear separation between feature parameters and other arguments
+   to the package. With naming mandated by this RFC, distinction is clear to
+   cater to automatic queries.
+
+4. Side effect of the proposdd migration plan is compiling of almost
+   exahustive list of known feature parameters.
+
+
+# Detailed design
+[design]: #detailed-design
+
+When upstream build system has options to enable or disable a optional features
+or configure some compile-time parameter, like path to default mailbox or
+initial size of hash map, derivation function (for short, package) MAY expose
+compile-time options via feature parameters that match
+`^(with|conf|enable)_[a-z_0-9]$` regular expression. For short, we will refer
+to them as `with`-parameter, `conf`-parameter and `enable`-parameter correspondingly,
+collectively as `feature parameters`.
+
+Note that this RFC does not establish any requirements whether package should or
+should not have any feature parameters, this decision is left at descretion of
+the package maintainer(s). This RFC only concerns itself with the naming of the
+feature flags. Further text will use wording "corresponding feature parameter"
+with implicit caveat "provided that package maintainer decided to export
+underlying build system configuration option".
+
+Feature parameters MUST only be used according to the rules outlined in this
+RFC. They MUST NOT be used for any other purpose.
+
+Boolean feature parameter MUST be either `with`-parameter or `enable`-parameter.
+Non-boolean (e.g. string or integer) feature parameter MUST be an `conf`-parameter.
+
+Feature parameter that incurs additional runtime dependency MUST be a `with`-parameter.
+
+Example
+
+```
+{ lib, stdenv, mpfr, with_mpfr ? true }:
+
+stdenv.mkDerivation {
+  # ... snip ...
+  configureFlags = lib.optionals with_mpfr ["--with-mpfr"];
+  buildInputs = lib.optionals with_mpfr [ mpfr ];
+  # ... snip ...
+}
+```
+
+Example
+
+If upstream uses `--enable-translations` to denote support for NLS,
+corresponding feature parameter SHOULD be `enable_nls`, since it is much more
+common term for enabling programs to produce output in non-English languages.
+
+Rationale
+
+This distinction between `with` and `enable` feature parameters is based on Autotools naming conventions.
+
+[Autoconf ENABLE](https://www.gnu.org/software/autoconf/manual/autoconf-2.66/html_node/Package-Options.html)
+[Autoconf WITH](https://www.gnu.org/savannah-checkouts/gnu/autoconf/manual/autoconf-2.72/html_node/External-Software.html)
+
+Example
+
+```
+{ lib
+, stdenv
+, openssl
+# At maintainer(s) discretion some coherent configuration is chosen.
+, with_openssl ? true
+, wolfssl
+, with_wolfssl ? false
+, enable_ssl ? with_openssl || with_wolfssl
+}:
+
+# Assertions are optional and might be infeasible when package has huge amount
+# of feature flags, but in general improve user experience.
+assert enable_ssl -> with_openssl || with_wolfssl;
+
+stdenv.mkDerivation {
+  # ... snip ...
+  configureFlags = lib.optionals enable_ssl ["--enable-ssl"];
+  buildInputs = lib.optionals with_wolfssl [ wolfssl ]
+             ++ lib.optionals with_openssl [ openssl ];
+  # ,,, snip ...
+}
+
+```
+
+Example
+
+```
+{ lib
+, stdenv
+, openssl
+, with_openssl ? true
+, enable_ssl ? with_openssl
+}:
+
+assert enable_ssl -> with_openssl;
+
+stdenv.mkDerivation {
+  # ... snip ...
+  configureFlags = lib.optionals enable_ssl ["--enable-ssl"];
+  buildInputs = lib.optionals with_openssl [ openssl ];
+  # ,,, snip ...
+
+  passthru.features = {
+    inherit with_openssl enable_ssl;
+  };
+}
+```
+
+Example
+
+```
+systemd => with_systemd
+libgif  => with_gif
+curl    => with_curl
+alsa    => with_alsa
+
+# When people say "Xorg" support, they usually mean linking "X11"
+# library which is one of the ways to talk X protocol to X server. "xcb"
+# being another one.
+xorg    => with_x11
+xcb     => with_xcb
+Qt5     => with_qt5
+
+# If upstream feature name contains multiple words (e.g --enable-frame-pointers)
+# then feature parameters SHOULD be snake_cased after upstream.
+--enable-frame-pointers => enable_frame_pointers
+
+# If optional dependency package name has multiple words in it, feature
+# name SHOULD follow the package attribute, but with dashes replaced
+# with underscores.
+pulseaudio => with_pulseaudio
+dump-init => with_dump_init
+
+
+```
+
+Example
+
+```
+{ lib
+, stdenv
+, curl
+, with_curl ? true
+, enable_ftp ? true
+, enable_http ? true
+}:
+
+# Assertions are fully optional.
+assert enable_ftp -> with_curl;
+assert enable_http -> with_curl;
+
+stdenv.mkDerivation {
+   # ... snip ...
+
+   configureFlags = lib.optionals enable_http ["--enable-http"]
+                 ++ lib.optionals enable_ftp ["--enable-ftp"];
+   buildInputs = lib.optionals withCurl [ curl ];
+
+   # ... snip ...
+
+   passthru.features = {
+      inherit with_curl enable_ftp enable_http;
+   };
+
+   # ... snip ...
+}
+```
+Folded changelog
+
+1. Changed wording to not imply that every upstream build system knob SHOULD be
+   exported via feature parameters. (Thx: 7c6f434c)
+
+2. Relaxed wording on the name of feature parameters to avoid painting ourselves
+   into ugly and non-intuitive names. (Thx: 7c6f434c)
+
+3. Fix typo in regex to be consistent that feature flag name can't have small
+   letter after `with|conf|enable` prefix. (Ths: don.dfh)
+
+4. Explicitly mention that static code analysis has support for overrides based
+   on human judgement call. (Thx: 7c6f434c)
+
+5. Clarify solution scenarios when build inputs and feature flags don't match
+   one-to-one. (Thx: Atemu, 7c6f434c)
+
+6. Refine the deprecation plan to make sure the warning includes the sunset
+   timestamp. (Thx: pbsds)
+
+7. Add rules about non-boolean feature parameters. (Thx: Atemu, pbsds)
+
+8. Set expectations for building and maintaining multiple configurations. (Thx: pbsds)
+
+9. Removed non-boolean parameters from "Future Work" section.
+
+10. Relaxed requirements for assertions about conflicting flags (Thx: Atemu)
+
+11. Add guideline so `pythonPackages.pillow` does not get `withPython` feature name. (Thx: 7c6f434c)
+
+12. Mention that vendored dependenices are still `with`. (Thx: 7c6f434c)
+
+13. Elaborate on camel case convention. (Thx: 7c6f434c)
+
+14. Explicitly mention that what feature parameters to introduce is left at discretion of the maintainer (Ths: Atemu)
+
+15. Add clause about passthrough `features` set.
+
+16. Switch to `snake_case` since it looks more consistent and less ugly than alternatives.
+
+17. Mention meta-parameters in the "Future Work" section.
+
+18. Elaborate on benefits if Nix were to allow introducing of default values.
+
+19. Downgrade "MUST be clear" to "SHOULD be clear". This way we won't need another RFC
+    for some corner case.
+
+20. Mention other ways to do (or not to do) the migration.
+
+21. Fix incorrect link to the autoconf manual.
+
+22. Avoid word "usually" in the summary. Many (most?) packages has no upstream feature flags.
+
+23. Remove side note about other independent implementations of X protocol.
+
+24. Change the migration plan to do renaming on the `makeOverrideable` level.
+
+25. Add link to the nix variable name code style. (Thx: @h7x4)
+
+26. Drop motivation part about mechanical translation of upstream parameter names. (Thx: infinisil)
+
+27. Drop mention of grace period, since it is not necessary with new migration plan.
+
+28. Document the `foo ? null` pattern and its drawbacks (Thx: Atemu)
+
+