@@ -0,0 +1,65 @@
1+# Content addressed derivations
2+## Introduction
3+
4+Floating content addressed derivations (from now *CA derivations*) is an experimental feature which substantially change how the hashes in the store paths are calculated.
5+Indeed, normally derivations are input addressed i.e. the outputs store paths depends only on the derivation inputs, instead with CA derivations they depend on the content of the outputs.
6+
7+This has two main advantages:
8+
9+- The so-called "early cutoff", namely the ability of Nix to stop a build if the build outputs would be something already built.
10+For example suppose you add a comment in an Haskell source, at this point Nix will rebuild the component depending on this source but since the output will be the same (adding a comment is an "output-invariant" change for `ghc`) every other component that depends on that will not be rebuilt.
11+- Users of the same Nix store does not need to trust each other when using substituters.
12+
13+You can find more information in the [ca-derivations page on the wiki](https://nixos.wiki/wiki/Ca-derivations) (and in the other resources linked there).
14+
15+## Usage
16+### Enable CA derivations in your system
17+First of all your Nix installation must support the `ca-derivations` experimental feature, this can done by adding the following in your `nix.conf`:
18+
19+```
20+experimental-features = ca-derivations
21+```
22+
23+Or if you use NixOS:
24+```
25+nix.extraOptions = ''
26+ experimental-features = ca-derivations
27+'';
28+```
29+
30+## Enable CA derivations in your project
31+At this point you can pass a new module to `project'` that tells `haskell.nix` to build every component in the project as CA derivation.
32+
33+```
34+haskell-nix.project' {
35+ # ...
36+
37+ modules = [{
38+ contentAddressed = true;
39+ # packages.project-name.components.exes.executable.contentAddressed = true;
40+ }];
41+};
42+```
43+
44+Optionally you can also specify which components you don't want to be content addressed.
45+
46+## Known problems
47+### Limitation of the current CA derivations implementation
48+
49+As explained in the [RFC 62](https://github.com/tweag/rfcs/blob/cas-rfc/rfcs/0062-content-addressed-paths.md)
50+
51+> The current implementation has a naive approach that just forbids fetching a path if the local system has a different realisation for the same drv output. This approach is simple and correct, but it's possible that it might not be good-enough in practice as it can result in a totally useless binary cache in some pathological cases.
52+
53+For example, suppose that your machine builds a derivation `A` producing an output `A.out` in your store and that after that a CI machine builds the same derivation `A` but producing a different output `A.out'` and populating a cache with this output.
54+At this point, if you need to build a derivation `B` that depends on `A`, since you already have the realisation `A.out` in your local store and you can't get `B.out` from the cache and you will end up building `B` even if one of its realisation is in the cache.
55+
56+This means that, in some cases, enabling CA derivations would lead to more rebuilds than not having it.
57+
58+### Hydra
59+Hydra currently doesn't support CA derivations, efforts are being made in this direction.
60+
61+
62+### GHC is not deterministic
63+Currently `ghc` is determinstic only disabling the parallel building i.e. passing `-j1`. [Here](https://gitlab.haskell.org/ghc/ghc/-/issues/12935) the upstream issue.
64+
65+Having a deterministic `ghc` would be a dream since it will automatically fix all the pathological cases about substituters discussed above and would allow `haskell.nix` to parallel build even when using CA derivations.