Skip to content

Conversation

ibizaman
Copy link

@ibizaman ibizaman commented Aug 10, 2025

Rendered - Draft PR.

This PR introduces the contracts RFC. This follows the discussion on the pre-RFC discourse post.

@ibizaman ibizaman mentioned this pull request Aug 10, 2025
19 tasks
@ibizaman ibizaman changed the title [RFC 0XXX] Contracts [RFC 0189] Contracts Aug 10, 2025
@KiaraGrouwstra
Copy link

Thanks for filing. I would like to join here to shepherd this.

@ibizaman ibizaman force-pushed the contracts branch 2 times, most recently from 51033e6 to 198f98c Compare August 10, 2025 20:16
@nixos-discourse
Copy link

This pull request has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/pre-rfc-decouple-services-using-structured-typing/58257/42

They don't have access to the actual `input` and `output` values of an instantiated contract.

Experimenting on this has been done in the [module interfaces][] repo.
There, we set the `provider` option as a function which takes an argument

Choose a reason for hiding this comment

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

maybe for context we could link 'set the provider option' to the lines in question

[drawbacks]: #drawbacks

We are not aware of any because this solution is fully backwards compatible,
incremental and has a lot advantages. It also arose from a real practical need.
Copy link
Member

Choose a reason for hiding this comment

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

Standard question for any module-system-based increase in layers: what is the estimated evaluation-time resource impact?

Copy link
Author

@ibizaman ibizaman Aug 16, 2025

Choose a reason for hiding this comment

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

That’s a great question. Is there a standard set of benchmarking tooling? After some quick online search, I see some external repos and wiki guides but I was wondering how from scratch I should start from.

Copy link
Member

Choose a reason for hiding this comment

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

Good question; I don't actually know things beyond export NIX_SHOW_STATS=1. There are some scripts in ci/eval but I am not sure whether reusing parts of them is worth it (but maybe looking at what is done there could be useful)

Care should be taken to not abuse this pattern though. It should be reserved
for contracts where abstracting away a `consumer` and `provider` makes sense.
We didn't find a general rule for that but a good indication that the pattern gets abused
is if we only find one `consumer` and `provider` pair in the whole of nixpkgs.
Copy link
Member

Choose a reason for hiding this comment

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

This is confusing. Is this what you meant?

Suggested change
is if we only find one `consumer` and `provider` pair in the whole of nixpkgs.
is if we only find one `consumer` and one `provider` usage of a contract in Nixpkgs.

Copy link
Author

Choose a reason for hiding this comment

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

Yes indeed thats what I meant :)

We started by fiddling with nix code and the implementation came up naturally.

We are not aware of any alternatives to do this,
mostly because our attempts to tweak the code often led us often to infinite recursion or other module issues
Copy link
Member

Choose a reason for hiding this comment

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

The dual-linking approach strikes dangerously close to infinite recursion in my mind. What do you think?

Choose a reason for hiding this comment

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

in my understanding the reason the current implementation works is lazy evaluation

What we propose answers to all those issues
as well as allows a few things that's not possible currently:

- interfacing with dependencies and services outside of NixOS,
Copy link
Member

Choose a reason for hiding this comment

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

Is there an example for this? The contract system will also probably need integration with service managers for scheduling and bringing up dependencies.

Copy link
Author

@ibizaman ibizaman Aug 20, 2025

Choose a reason for hiding this comment

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

I can’t believe I forgot to add an example for this IMO important point. I’ll add that.

The intent here is to provide an escape hatch to the outside (of NixOS) world. Which means you’re free to do whatever you want. The use case I had in mind does imply “manual” scheduling. Let’s say you want to integrate a NixOS service with a database that exists already on another server which does not run NixOS. You would create a database provider which hardcodes the url and credentials to the other server. Then the consumer would be able to access it. Of course you must set up the other server beforehand correctly. And of course the other server could be a NixOS machine too.

I can see a separate contract for interacting with service management. This should be merged with the module interfaces initiative.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants