Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC 0127] Nixpkgs "problem" infrastructure #127

Merged
merged 25 commits into from
Jul 12, 2023
Merged
Changes from 17 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
60cb23d
[RFC 0127] Nixpkgs issues and warnings (#127)
piegamesde Jun 11, 2022
ee72999
Add URLs as structured information
piegamesde Jun 15, 2022
c109c31
Update rfcs/0127-issues-warnings.md
piegamesde Sep 12, 2022
ff2e2d4
Update rfcs/0127-issues-warnings.md
piegamesde Sep 12, 2022
f83067a
Update rfcs/0127-issues-warnings.md
piegamesde Sep 13, 2022
2daf978
Update rfcs/0127-issues-warnings.md
piegamesde Sep 13, 2022
2b63424
Update rfcs/0127-issues-warnings.md
piegamesde Sep 13, 2022
e5c0e13
Update rfcs/0127-issues-warnings.md
piegamesde Sep 13, 2022
3212d31
RFC 127 update shepherds
piegamesde Sep 13, 2022
ecdbe2c
RFC 127 rework
piegamesde Sep 13, 2022
c907adb
Point out that the previous warnings system was not documented
piegamesde Sep 13, 2022
d232a2d
Rework ignore mechanism
piegamesde Sep 17, 2022
ff6e33d
Update rfcs/0127-issues-warnings.md
piegamesde Oct 14, 2022
6ffce6d
Update rfcs/0127-issues-warnings.md
piegamesde Oct 14, 2022
24a8985
Remove "resolved" attribute again
piegamesde Oct 15, 2022
1b1424e
Incorporate review feedback
piegamesde Oct 15, 2022
1e6725e
Rewrite (again)
piegamesde Dec 12, 2022
81564e6
Rename throw->error, trace->warn
piegamesde Jan 21, 2023
c5c64ec
Make meta.problems an attrset
piegamesde Jan 31, 2023
2a78241
Rewrite *again*, most change is in the configuration options
piegamesde Apr 28, 2023
4f311de
Review update (WIP)
piegamesde May 15, 2023
b253df1
Review update
piegamesde May 30, 2023
7939f49
Update shepherds list
piegamesde Jun 1, 2023
33ec9a6
Meeting update
piegamesde Jun 19, 2023
83319ec
Typos
piegamesde Jun 19, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
283 changes: 283 additions & 0 deletions rfcs/0127-issues-warnings.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,283 @@
---
feature: issues-warnings
start-date: 2022-06-11
author: piegames
co-authors: —
shepherd-team: @lheckemann, @mweinelt, @fgaz
piegamesde marked this conversation as resolved.
Show resolved Hide resolved
shepherd-leader: @mweinelt
related-issues: https://github.com/NixOS/nixpkgs/pull/177272
---

# RFC: Nixpkgs "problem" infrastructure

## Summary
[summary]: #summary

Inspired by the various derivation checks like for broken and insecure packages, a new system called "problems" is introduced. It is planned to eventually replace the previously mentioned systems where possible, as well as the current – undocumented – "warnings" (which currently only prints a trace message for unmaintained packages). A `config.problemHandler` option is added to the nixpkgs configuration, with centralized and granular control over how to handle problems that arise: "throw" (fail evaluation), "trace" (print a warning message) or "ignore" (do nothing).

Additionally, `meta.problems` is added to derivations, which can be used to manually declare that a package has a certain problem. This will then be used to inform users about packages that are in need of maintenance, for example security vulnerabilities or deprecated dependencies.

Using the newly introduced features, we may create a process for removing packages from nixpkgs that is easier to maintain and friendlier to users than just replacing packages with `throw`.

## Motivation
[motivation]: #motivation

Nixpkgs has the problem that it is often treated as "append-only", i.e. packages only get added but not removed. There are a lot of packages that are broken for a long time, have end-of-life dependencies with known security vulnerabilities or that are otherwise unmaintained.

Let's take the end of life of Python 2 as an example. (This applies to other ecosystems as well, and will come up again and again in the future.) It has sparked a few bulk package removal actions by dedicated persons, but those are pretty work intensive and prone to burn out maintainers. A goal of this RFC is to provide a way to notify all users of a package about the outstanding issues. This will hopefully draw more attention to abandoned packages, and spread the work load. It can also help soften the removal of packages by providing a period for users to migrate away at their own pace.
piegamesde marked this conversation as resolved.
Show resolved Hide resolved

For some use cases, like for packages without maintainers, we do not want to break evaluation of a package and simply warn the user instead. We want the users to configure all these according to their needs and through a single standardized interface.

## Detailed design
[design]: #detailed-design

### Package problems

A new attribute is added to the `meta` section of a package: `problems`. If present, it is a list of attrsets which each have at least the following fields:

- `kind`: Required. If present, the resulting warning will be printed as `kind: message`.
- `message`: Required. A string message describing the issue with the package. The value should:
- Start with the "This package", "The application" or equivalent, or simply with the package name.
- Be capitalized (unless it starts with the package name).
- Use a period at the end.
- `name`: Required if there are multiple values of the same `kind`. Give the issue a custom name for more easy filtering
piegamesde marked this conversation as resolved.
Show resolved Hide resolved
- `date`: Required. An ISO 8601 `yyyy-mm-dd`-formatted date from when the issue was added.
- `urls`: Optional, list of strings. Can be used to link issues, pull requests and other related items.
piegamesde marked this conversation as resolved.
Show resolved Hide resolved

Other attributes are allowed. Some message kinds may specify additional required attributes.
piegamesde marked this conversation as resolved.
Show resolved Hide resolved

Example values:

```nix
meta.problems = [
{
name = "python2-eol";
kind = "deprecated";
message = "This package depends on Python 2, which has reached end of life.";
date = "1970-01-01";
urls = [ "https://github.com/NixOS/nixpkgs/issues/148779" ];
}
{
kind = "removal";
message = "The application has been abandoned upstream, use libfoo instead";
piegamesde marked this conversation as resolved.
Show resolved Hide resolved
date = "1970-01-01";
}
];
```

### Problem kinds
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this section should introduce the different handler values and show the default one for each problem kind.


At the moment, the following values for the `kind` field of a warning are known:

- `removal`: The package is scheduled for removal some time in the future.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd argue that scheduled removals should not cause an error like this RFC is seemingly proposing. Or why should they?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Think of it as removing a package by adding a removal problem, and then users get some grace period where the package is still available for some time.

- `deprecated`: The package has been abandoned upstream or has end of life dependencies.
piegamesde marked this conversation as resolved.
Show resolved Hide resolved
Copy link
Member

@infinisil infinisil May 15, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think packages that have EOL dependencies should be marked as deprecated, they can still be maintained while having EOL dependencies.

Suggested change
- `deprecated`: The package has been abandoned upstream or has end of life dependencies.
- `deprecated`: The package is deprecated or abandoned upstream.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The general concept here is correct, although I agree that the name may be misleading. The representative use case for "deprecated" is the Python 2 EOL: some packages can be fixed by upgrading to Python 3 or otherwise removing the Python 2 dependency, others are probably hopeless and doomed.

they can still be maintained while having EOL dependencies.

IMO it's the other way around: packages with EOL dependencies are in need of maintenance

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, EOL packages receive security fixes or maintenance only via paid subscriptions usually.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(But I'm open to an EOL explicit flag.)

Copy link

@bew bew Jun 19, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hello, came to read the rfc after fcp was announced, this is the only thing that bugged me while reading..

It seems there was no conclusion to this comment.

The distinction can be hard to grasp, but I think deprecated and eol/obsolete are clearly different and should be handled differently.

Mozilla's JS docs uses deprecated/obsolete here:

deprecated: still available but planned for removal
obsolete: no longer usable

To me (french, not english-native), obsolete also means that something else took its place. eol would be stronger and wouldn't mean that.

Random guy on english stackexchange says:

Deprecated is more or less a "marker", saying that it should not be used, something else that has the same effect has been created, and it is soon to be deleted. It may still work as expected, but it will vanish soon.
Obsolete means that it no longer works as expected, or doesn't do anything at all.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bew, I don't see how this distinction is relevant in this context. The idea behind "deprecation" is, that some package has a problem related to software for which upstream dropped support, and thus needs fixing or removal. Whether or not it currently works is not relevant to me, since this is from a maintainer perspective and not a user perspective.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I wanted also a distinction, I feel like it's not that important from a maintainer perspective, and I agree with @bew ; though, if, in practice, we found ourselves wanting more, we can always discuss this after extensive experience with that RFC in production.

Copy link

@bew bew Jun 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok for the distinction between deprecated/obsolete/eol.

I'm now also thinking about the wording vs semantic difference between removal and deprecated.

Something that is marked for removal should not be used anymore, this actually looks like the definition of deprecated 🤔

Might be confusing, maybe we can rename:

  • removal to deprecated (or don't use rhe word deprecated at all?)
  • deprecated to obsolete/eol

What do you think? @piegamesde @RaitoBezarius

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm fine with changing names as long as we keep the originally intended semantics. I'd prefer to keep "removal" because it's for things "that are about to be removed" so I find it quite fitting. "removal" is a least resort measure, and "deprecated" would be too weak of a word for it.

I'd be fine with renaming "deprecated" to "obsolete" or "eol". Personally I don't mind "deprecated" and don't think the alternatives are a big improvement, but they're fine so if people prefer it we can do that.

- `maintainerless`: `meta.maintainers` is empty
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This feels a bit weird, because the user could declare problems with this kind, but this should never be done, it's entirely automated. Should users maybe not be allowed to declare this problem kind? And should the name maintainerless be reserved so there's nobody trying to declare their own maintainerless problem with a different kind? Because if not, what should happen when there's already a problem with that name defined but then meta.maintainers becomes empty? Should problems maybe not be declared automatically at all to make sure there's no name inconsistencies?

I feel like this needs a bit more thought.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point. How about specifying that some kinds are not allowed for manual declaration in meta.problems? I'd nominate maintainerless, broken and unsupported (the latter two are not currently in use either way, they are just reserved for future work)

- `insecure`: The package has some security vulnerabilities
- `broken`: The package is marked as broken
piegamesde marked this conversation as resolved.
Show resolved Hide resolved
piegamesde marked this conversation as resolved.
Show resolved Hide resolved
- `unsupported`: The package is not expected to build on this platform
piegamesde marked this conversation as resolved.
Show resolved Hide resolved

Not all values make sense for declaration in `meta.problems`: Some may be automatically generated from other `meta` attributes (for example `maintainerless`). New kinds may be added in the future. Furthermore, some kinds are expected to be present only up to once per derivation: for example, we have no use for having multiple `maintainerless` problems, and therefore also no need to give them a name in order to distinguish them.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would anything be generated from sourceProvenance = lib.sourceTypes.binaryNativeCode;? I'm of the opinion that not having the option to turn off substitution and build from source makes a package unsecure, but then some only consider that to be an inconvenience (because it's not patchable), so maybe a separate category? And you'd probably want to not flag bootstrapping seeds with a problem that can never be resolved.

Or maybe I should be saving these questions until after the proposal is accepted.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, to which extent the source provenance thing can be integrated into this RFC is an open question, and while we can already discuss it now I wouldn't commit on any of that in the RFC itself (apart from maybe mentioning it as potential future work).

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm of the opinion that not having the option to turn off substitution and build from source makes a package unsecure,

Me too, so I set allowNonSource = false; in nixpkgs.nix. Is there something you want that isn't achieved by that?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, I was just wondering if that had been considered.


### Nixpkgs configuration

The following new config option is added to nixpkgs: `config.problemHandler`. The (currently undocumented) option `config.showDerivationWarnings` will be removed.

Handler values can be either `"throw"`, `"trace"` or `"ignore"`. Future values may be added in the future. The key is of the form `packageName.problemKind` or `packageName.problemName`, where `"*"` is allowed on either level as a wildcard.
piegamesde marked this conversation as resolved.
Show resolved Hide resolved

```nix
problemHandler = {
"*" = {
"*" = "throw";
alias = "trace";
maintainerless = "ignore";
};
myPackage.foo = "ignore";
};
```

If multiple rules match a given problem of a package, the most specific handler will be called:

1. `pkgName.problemName`
2. `pkgName.problemKind`
3. `pkgName."*"`
4. `"*".problemName`
5. `"*".problemKind`
6. `"*"."*"`
piegamesde marked this conversation as resolved.
Show resolved Hide resolved

So for example the value of `myPackage.*` would override the one in `*.maintainerless` if both matched, as it is more specific.

The default value in nixpkgs might be something like:

```nix
problemHandler."*" = {
"*" = "trace";
removal = "throw";
deprecated = "throw";
maintainerless = "ignore";
};
```

It may also be expanded by values from other configuration options as part of a migration scheme from the other mechanisms.

## Examples and Interactions
[examples-and-interactions]: #examples-and-interactions

### Propagation across transitive dependencies

When a package has a problem that `throw`s, all packages that depend on it will fail to evaluate until that problem is ignored or resolved. Most of the time, this is sufficient.

When the problem requires actions on dependents however, it does not sufficiently inform about all packages that need action. Multiple packages may be annotated with the same problem, in that case it should be given a name and the name should be the same across all instances. Other values like the message or the URL list do not need to be the same and may be adapted sensibly.

For the example of Python 2 deprecation, all problems would have `name = "python2-eol"` and then a user may set `config."*".python2-eol = "ignore";` to ignore them.

### Backwards compatbility, Backporting and stable releases

New problems generally should not be added to stable branches if possible, and also not be backported to them, since it may break evaluation. The same rule applies to other changes to a pacakge's `meta` which may generate a problem and thus lead to evaluation failure too. Scenarios where evaluation failure is a desired goal, for example with unfixable security issues, are obviously exempt from this.
piegamesde marked this conversation as resolved.
Show resolved Hide resolved

### Removal of packages

The plan is to eventually remove packages with long outstanding problems. The details will be part of future work, but at the very least a package must have a problem whose kind defaults to "throw" for at least one full release cycle (so that stable users have sufficient time to be warned and intervene).

If a package needs to be removed for some other reason, the problem kind `removal` should be used instead:
piegamesde marked this conversation as resolved.
Show resolved Hide resolved

```nix
meta.problems = [{
kind = "removal";
message = "We don't want this in nixpkgs anymore";
date = "1970-01-01";
}];
```

## Drawbacks
[drawbacks]: #drawbacks

- Too much warnigns may cause Alarm fatigue
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I was deciding between gentoo and nixpkgs, this was the major strike against gentoo. The OS sends you email. And you sort of have to read it, because all the other users do.

That, plus wanting less Python in my life rather than more, is what tipped the balance.

Let's not go that way.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, nixpkgs errs on the other side of the spectrum. It is difficult for you to get notified about changes you care about, especially on the unstable channel. This RFC has started because people wanted to do some backwards-incompatible changes but did not have a good way to properly inform all stakeholders.

piegamesde marked this conversation as resolved.
Show resolved Hide resolved
- One idea I had is to be more verbose on the unstable channels, and then tune down the noise after branch-off.
- New lints to packages should be introduced gradually, by making them "silent" by default on start and only going to "warn" after most problems in nixpkgs itself are resolved.
- People have voiced strong negative opinions about the prospect of removing packages from nixpkgs at all, especially when they still *technically* work.
- We do not want to encourage the use of unmaintained software likely to contain security vulnerabilities, and we do not have the bandwidth to maintain packages deprecated by upstream. Nothing is lost though, because we have complete binary cache coverage of old nixpkgs versions, providing a comparatively easy way to pin old very package versions.
piegamesde marked this conversation as resolved.
Show resolved Hide resolved
Copy link

@ghost ghost Jan 21, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do not want to encourage the use of unmaintained software

This "unmaintained" boogeyman is a problem endemic to poorly-scoped software. Cough cough browsers cough.

dnscache, tinydns, and runit have been "unmaintained" for over a decade and work better than most of their competitors. The same is true of unfs3, but its alternatives (i.e. in-kernel nfs) can't be run in an unprivileged sandbox, which turns the whole unmainained==insecure on its head.

Is this RFC going to affect their presence in nixpkgs?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is not the kind of "unmaintained" the sentence is referring to. Yes, eventually people may start to enforce maintainers != [] using the features provided by this RFC if they want to, but this will be a new and separate discussion for sure.

This sentence is about all a) packages that are effectively unmaintained, i.e. they require some work to keep going but there is nobody and b) packages that are unmaintained or abandoned by upstream with no hope of fixing.

And no, "unmaintained" does not imply it's insecure by any means. Personally, I'd like to get to a point where we treat "end of life" as kind-of insecure. And this is not only about security, but also about workload: I do not want us to patch things on software if it is end of life, instead we should have a graceful way of removing it from nixpkgs.

- This change is a general improvement in the ecosystem even if we do not end up using it to remove any packages.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
- "in-band" maintenance of this data means that users have to upgrade their nixpkgs to become aware of new issues.
- The proposed approach has significantly less overhead than designing and maintaining a separate database along with tools to combine its data with nixpkgs. We are open to an alternative approach in the future, but do not want to incur such high maintenance costs at this time.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add as sub-point: out of band warnings would be impure if they stopped evaluation like they currently do.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I imagine such a tool not blocking evaluation at all, but providing the metadata, comparing it to local policy, annotating the drvs produced with said metadata, and (when used interactively) providing a "continue anyway" knob if anything happens that's not already permitted by local policy.

I don't count that as an impurity, since I don't want it to be able to modify the evaluation results at all -- only observe evaluation and decide what to do afterwards (which also allows getting all the warnings at once, and displaying all those that local policy considers as "blocking" at once).

## Alternatives
piegamesde marked this conversation as resolved.
Show resolved Hide resolved
[alternatives]: #alternatives

This project has gone through multiple iterations, and grown quite in scope during that. Therefore this section doubles a chronology of previous attempts of implementing it.

Alternative to the current solution, we could just continue to add new systems to `check-meta.nix` when specific use cases arise. The downside is that they are mostly similar yet not 100% consistent, resulting in both code duplication and user confusion.

The original proposal only wanted to deal with eval-breaking problems, and grew in scope since. Removing warnings from the equation makes the implementation simpler, however we would then miss out on things like tracing aliases. Maybe we should have a distinct mechanism for evaluation warnings.

The following sections discuss alternative ways of implementing the current feature proposal.

### Naming

A lot of names have been considered so far for this feature, currently "problems" is the "least bad" proposal.

- Problem: Extremely generic "kind of fits all use cases but not that well" word
- Issue: Colliding with GitHub issues
- Warning: People might expect that it would never break evaluation
- Error: This is too harsh of a word for things that are minor issues, like unmaintained packages
- Advisory: Too focused on security issues

Consider that the name should work as well as possible for all of the following cases, even if there are no current plans to replace all of these with our new feature: "removal", "deprecated", "maintainerless", "insecure", "broken", "unsupported", "unfree".

### Problem declaration

*n.b.: the terminology of the feature has multiple times since the earlier proposals were made*

An alternative design would be to have issues as a separate list (not part of the package). ~~Instead of allowing individual packages, one could ignore individual warnings (they'd need an identifying number for that). The advantage of doing this is that one could have one issue and apply it for a lot of packages (e.g. "Python 2 is deprecated"). The main drawback there is that it is more complex.~~ The advantages of that approach have been integrated while keeping the downsides small: Warnings are ignored with a per-kind granularity, but one may give some of them a name to allow finer control where necessary.

A few other sketches about how the declaration syntax might look like in different scenarios:

```nix
{
# As proposed in the RFC
meta.issues = [{
kind = "deprecated";
name = "python2-eol";
message = "deprecation: Python 2 is EOL. #12345";
# (Other fields omitted for brevity)
}];

# Issues are defined elsewhere in some nixpkgs-global table, only get referenced in packages
meta.issues = [ "1234-python-deprecation" ];

# Attempt to unify both approaches to allow both ad-hoc and cross-package declaration
meta.issues = {
"1234-python-deprecation" = {
message = "deprecation: Python 2 is deprecated #12345";
};
};

# Proposal by @matthiasbeyer
meta.issues = [
{ transitive = pkgs.python2.issues }
];
}
```

Some more design options that were considered:

```nix
meta.problems = {
"deprecated/python2-eol" = {
message = "This package depends on Python 2, which has reached end of life.";
date = "1970-01-01";
urls = [ "https://github.com/NixOS/nixpkgs/issues/148779" ];
};
removal = {
message = "The application has been abandoned upstream, use libfoo instead";
date = "1970-01-01";
};
};

meta.problems = {
"deprecated" = [{
name = "python2-eol";
message = "This package depends on Python 2, which has reached end of life.";
date = "1970-01-01";
urls = [ "https://github.com/NixOS/nixpkgs/issues/148779" ];
}];
removal = {
message = "The application has been abandoned upstream, use libfoo instead";
date = "1970-01-01";
};
};
```

These have the advantage of enforcing the presence of a name if there are multiple problems of the same kind, at the cost of some additional nesting in those cases.

### Problem resolution

On the nixpkgs configuration side, the first iteration used a generic "predicate" system for ignoring packages, similar to `allowUnfreePredicate` and `allowInsecurePredicate`. This turned out to be both too flexible and not convenient enough to use, so this was complemented with a list of packages to ignore and "smart" default values generation.

A second approach used a list type: `list of ("packageName.warningKind" or "packageName.*" or "*.warningKind" or "*.*")`. This was a binary choice (compared to the ternary value today), with an additional boolean `traceIgnoredWarnings` option. One downside is that it does not allow granular control over warnings, only evaluation failures. A bigger issue is that due to how the merge rules on lists work, it would have been difficult to provide good default values for the nixpkgs confinguration while keeping backwards compatibility.

## Unresolved questions
[unresolved]: #unresolved-questions

- ~~From above: "Ignoring a package without issues (i.e. they have all been resolved) results in a warning at evaluation time". How could this be implemented, and efficiently?~~
- ~~More generally, how do we tell users that their ignored warning can be removed, so that they won't accidentally miss future warnings?~~
- ~~Issues have a `resolved` attribute that may be used for that purpose.~~
- Properly implementing this turned out to be non-trivial, so this feature was cut for the sake of simplicity as it was not of high importance anyways.
- The ignore mechanism has been refined so that there is less risk of missing future warnings.
- ~~Should issues be a list or an attrset?~~·
- We are using a list ~~for now, there is always the possibility to also allow attrsets in the future.~~
- Currently, many of the relevant nixpkgs configuration options can also be set impurely via environment variables. The `config.problemHandler` option does however not easily map to some environment variable.
- When merging existing features into the problems system, existing environment variable will keep working in the future.
- Maybe using less environment variables is all for the better?
- We may always add specific environment variables for specific use cases where needed without having to expose the full expression power of `config.problemHandler`.

## Future work
[future]: #future-work

- The actual process of removing packages is only sketched out here to show how the new infrastructure may improve the situation. It is intentionally left as vague as possible, and details should be figured out in a follow-up discussion.
- The problems system is designed in a way that it supersedes a lot of our "insecure"/"unfree"/"unsupported" packages infrastructure. There is a lot of code duplication between them. In theory, we could migrate some of these to make use of problems. At the very least, we hope that problems are general enough so that no new similar features will have to be added in the future anymore.
- Migrating the existing systems may end up being tricky due to backwards compatibility issues.
- Inspired by the automation of aliases, we could build tooling for this as well. This is deemed out of scope of this RFC because only real world usage will tell which actions will be worthwhile automating, but it should definitely be considered in the future.
- There will likely be need for tooling that lists problems on all nixpkgs packages, filtered by kind or sorted chronologically.
- Automatically removing packages based on time will likely require providing more information whether it is safe to do so or not.
- > If the advisories were a list, and we also added them for modules, maybe we could auto-generate most release notes, and move release notes closer to the code they change. [[source]](https://discourse.nixos.org/t/pre-rfc-package-advisories/19509/4)
- Issues can certainly be automatically integrated into the release notes somehow. However, this alone would not allow us to move most of our release notes into the packages, because for many release entries breaking eval would be overkill.
- There has been discussion about introducing "tracing aliases", aliases that don't `throw` by default. Such an implementation may make use of the problem infrastructure.