[HN Gopher] Is NixOS truly reproducible?
___________________________________________________________________
Is NixOS truly reproducible?
Author : pabs3
Score : 236 points
Date : 2025-02-09 09:56 UTC (4 days ago)
(HTM) web link (luj.fr)
(TXT) w3m dump (luj.fr)
| opan wrote:
| Although I'm aware many distros care somewhat about reproducible
| builds these days, I tend to associate it primarily with Guix
| System, I never really considered it a feature of NixOS, having
| used both (though spent much more time on Guix System now).
|
| For the record, even in the land of Guix I semi-regularly see
| reports on the bug-guix mailing list that some package isn't
| reproducible. It seems to get treated as a bug and fixed then.
| With that in mind, and personally considering Guix kind of the
| flagship of these efforts, it doesn't surprise me if anyone else
| doesn't have perfectly reproducible builds yet either. Especially
| Nix with the huge number of things in nixpkgs. It's probably
| easier for stuff to fall through the cracks with that many
| packages to manage.
| jchw wrote:
| I think this debate comes down to exactly what "reproducible"
| means. Nix doesn't give bit-exact reproducibility, but it does
| give reproducible _environments_ , by ensuring that the inputs
| are always bit-exact. It is closer to being fully reproducible
| than most other build systems (including Bazel) -- but because it
| can only reasonably ensure that the inputs are exact, it's still
| necessary for the build processes themselves to be fully
| deterministic to get end-to-end bit-exactness.
|
| Nix on its own doesn't fully resolve supply chain concerns about
| binaries, but it can provide answers to a myriad of other
| problems. I think most people like Nix reproducibility, and it is
| marketed as such, for the sake of development: life is much
| easier when you know _for sure_ you have the exact same version
| of each dependency, in the exact same configuration. A build on
| one machine may not be bit-exact to a build on another machine,
| but it will be exactly the same source code all the way down.
|
| The quest to get every build process to be deterministic is
| definitely a bigger problem and it will never be solved for all
| of Nixpkgs. NixOS does have a reproducibility project[1], and
| some non-trivial amount of NixOS actually _is_ _properly_
| reproducible, but the observation that Nixpkgs is too vast is
| definitely spot-on, especially because in most cases the real
| issues lie upstream. (and carrying patches for reproducibility is
| possible, but it adds _even more_ maintainer burden.)
|
| [1]: https://reproducible.nixos.org/
| sa46 wrote:
| > It is closer to being fully reproducible than most other
| build systems (including Bazel).
|
| How so? Bazel produces the same results for the same inputs.
| jchw wrote:
| Bazel doesn't guarantee bit-exact outputs, but also Bazel
| doesn't guarantee pure builds. It does have a sandbox that
| prevents some impurities, but for example it doesn't prevent
| things from going out to the network, or even accessing files
| from anywhere in the filesystem, if you use absolute paths.
| (Although, on Linux at least, Bazel _does_ prevent you from
| _modifying_ files outside of the sandbox directory.)
|
| The Nix sandbox _does_ completely obscure the host filesystem
| and limit network access to processes that can produce a bit-
| exact output only.
|
| (Bazel also obviously uses the system compilers and headers.
| Nix does not.)
| dijit wrote:
| Uh, Either my understanding of Bazel is wrong, or
| everything you wrote is wrong.
|
| Bazel absolutely prevents network access and filesystem
| access (reads) from builds. (only permitting _explicit_
| network includes from the WORKSPACE file, and access to
| files explicitly depended on in the BUILD files).
|
| Maybe you _can_ write some "rules_" for languages that
| violate this, but it is designed purposely to be hermetic
| and bit-perfect reproducible.
|
| EDIT:
|
| From the FAQ[0]:
|
| > Will Bazel make my builds reproducible automatically?
|
| > For Java and C++ binaries, yes, assuming you do not
| change the toolchain.
|
| The issues with Docker's style of "reproducible" (meaning..
| consistent environment; are also outlined in the same
| FAQ[1]
|
| > Doesn't Docker solve the reproducibility problems?
|
| > Docker does not address reproducibility with regard to
| changes in the source code. Running Make with an
| imperfectly written Makefile inside a Docker container can
| still yield unpredictable results.
|
| [0]: https://bazel.build/about/faq#will_bazel_make_my_build
| s_repr...
|
| [1]: https://bazel.build/about/faq#doesn't_docker_solve_the
| _repro...
| valcron1000 wrote:
| I'm not familiar with Bazel at all so this might be
| obvious, but does Bazel check that the files listed in
| the BUILD file are the "right ones" (ex. through a
| checksum), and if so, is this always enforced (that is,
| this behavior cannot be disabled)?
| dijit wrote:
| The contents of files are basically hashed, if the
| contents don't change of the file listed for a target
| then no change will happen, even if you modify metadata
| of the file (like last modified time by `touch` or so
| on.)
|
| Bazel is really sophisticated and I'd be lying if I said
| I understood it well, but I have spent time looking at
| it.
| keithwinstein wrote:
| I think you're both right in a sense. Bazel doesn't (in
| general) prevent filesystem access, e.g. to library
| headers in /usr/include. If those headers change (maybe
| because a Debian package got upgraded or whatever), Bazel
| won't know it has to invalidate the build cache. I think
| the FAQ is still technically correct because upgrading
| the Debian package for a random library dependency counts
| as "chang[ing] the toolchain" in this context. But I
| don't think you'd call it hermetic by default.
|
| Check out the previous discussion at
| https://news.ycombinator.com/item?id=23184843 and below:
|
| > Under the hood there's a default auto-configured
| toolchain that finds whatever is installed locally in the
| system. Since it has no way of knowing what files an
| arbitrary "cc" might depend on, you lose hermeticity by
| using it.
| amarshall wrote:
| AFAIK Bazel does not use the sandbox by default. Last
| time I experimented with it, the sandbox had some
| problematic holes, but I don't remember exactly what, and
| it's been a few years.
|
| The very doc you link hints at that, while also giving
| many caveats where the build will become non-
| reproducible. So it boils down to "yes, but only if you
| configure it correctly and do things right".
| jchw wrote:
| Yeah, I think you are right: by default, there is no OS-
| level sandboxing going on. According to documentation,
| the default spawn strategy is `local`[1], whereas it
| would need to be `sandboxed` for sandboxing to take
| effect.
|
| Meanwhile, if you want to forcibly block network access
| for a specific action, you can pass `block-network` as an
| execution requirement[2]. You can also explicitly block
| network access with flags, using
| --nosandbox_default_allow_network[3]. Interestingly
| though, an action can also `require-network` to bypass
| this, and I don't think there's any way to account for
| that.
|
| Maybe more importantly, Bazel lacks the concept of a
| fixed-output action, so when an impure action needs
| `require-network` the potentially-impure results could
| impact downstream dependents of actions.
|
| I was still ultimately incorrect to say that Bazel's
| sandbox _can 't_ sandbox the network. The actual reality
| is that it _can_. If you _do_ enable the sandbox, while
| it 's not exactly pervasive through the entire ecosystem,
| it does look like a fair number of projects at least set
| the `block-network` tag--about 700 as of writing this[4].
| I think the broader point I was making (that Nix adheres
| to a stronger standard of "hermetic" than Bazel) is
| ultimately true, but I did miss on a bit of nuance
| initially.
|
| [1]: https://bazel.build/docs/user-manual#spawn-strategy
|
| [2]: https://bazel.build/reference/be/common-
| definitions#common.t...
|
| [3]: https://bazel.build/reference/command-line-
| reference#flag--s...
|
| [4]: https://github.com/search?q=language%3Abzl+%22block-
| network%...
| jchw wrote:
| I believe your understanding of Bazel is wrong. I don't
| see any documentation that suggests the Bazel sandbox
| prevents the toolchain from accessing the network.
|
| https://bazel.build/docs/sandboxing
|
| (Actually, it can: that documentation suggests it's
| optionally supported, at least on the Linux sandbox. That
| said, it's optional. There's definitely actions that use
| the network on purpose and can't participate in this.)
|
| This may seem pointless, because in many situations this
| would only matter in somewhat convoluted cases. In C++
| the toolchain probably won't connect to the network. This
| isn't the case for e.g. Rust, where proc macros _can_
| access the network. (In practical terms, I believe the
| sqlx crate does this, connecting to a local Postgres
| instance to do type inference.) Likewise, you could do an
| absolute file inclusion, but that would be very much on
| purpose and not an accident. So it 's reasonable to say
| that you get a level of reproducibility when you use
| Bazel for C++ builds...
|
| Kind of. It's not bit-for-bit because it uses the system
| toolchain, which is just an arbitrary choice. On Darwin
| it's even _more_ annoying: with XCode installed via Mac
| App Store, the XCode version can change transparently
| under Bazel in the background, entirely breaking the
| hermeticity, and require you to purge the Bazel cache
| (because the dependency graph will be wrong and break the
| build. Usually.)
|
| Nix is different. The toolchain is built by Nix and
| undergoes the same sandboxed build process with
| sandboxing and cryptographically verified inputs. Bazel
| does not do that.
| paulddraper wrote:
| It does.
|
| There are mechanisms for opting out/breaking that, just
| as with Nix or any other system.
|
| > macOS
|
| What does nix do on these systems?
| jchw wrote:
| Opt-out would be one thing, but it's actually _opt-in_
| for network isolation, and a project can disable all
| sandboxing with just a .bazelrc. Nix does have ways to
| opt-out of sandboxing, but you can 't do it inside a Nix
| expression: if you ran Nix with sandbox = true, anything
| being able to escape or bypass the sandbox restrictions
| would be a security vulnerability and assigned a CVE.
| Disabling the sandbox can only be done by a trusted user,
| and it's entirely out-of-band from the builder. For
| Bazel, the sandbox is mostly just there to prevent
| accidental impurities, but it's not water tight by any
| means.
|
| Ultimately, I still think that Nix provides a greater
| degree of isolation and reproducibility than Bazel
| overall, and especially out of the box, but I was
| definitely incorrect when I said that Bazel's sandbox
| doesn't/can't block the network. I did dive a little
| deeper into the nuances in another comment.[1]
|
| > What does nix do on these systems?
|
| On macOS, Nix is not exactly as solid as it is on Linux.
| It uses sandbox-exec for sandboxing, which achieves most
| of what the Nix sandbox does on Linux, except it
| disallows _all_ networking rather than just isolated
| networking. (Some derivations need local network access,
| so you can opt-in to having local network access per-
| derivation. This still doesn 't give Internet access,
| though: internet access still requires a fixed-output
| derivation.) There's definitely some room for improvement
| there but it will be hard to do too much better since xnu
| doesn't have anything similar to network namespaces
| afaik.
|
| As for the toolchain, I'm not sure how the Nix bootstrap
| works on macOS. It seems like a lot of effort went in to
| making it work and it can function without XCode
| installed. (Can't find a source for this, but I was using
| it on a Mac Mini that I'm pretty sure didn't have XCode
| installed. So it clearly has its own hermetic toolchain
| setup just like Linux.)
|
| [1]: https://news.ycombinator.com/item?id=43032285
| paulddraper wrote:
| > it's actually opt-in for network isolation
|
| Bazel enables sandboxing by default, including network
| isolation. [1] [2]
|
| The exception would be in environments that don't support
| it (Windows, unprivileged Docker container, etc.)
|
| [1] https://bazel.build/docs/user-manual#spawn-strategy
|
| [2] https://stackoverflow.com/a/63635141
| jchw wrote:
| My assertion that network isolation is opt-in is based on
| the fact that the --sandbox_default_allow_network
| defaults to true[1]. That suggests actions will have
| networking unless they are dispatched with `block-
| network`[2].
|
| (It's hard to figure out exactly what's going on based on
| the documentation and some crawling around, but I
| wouldn't be surprised if specifically tests defaulted to
| blocking the network.)
|
| [1]: https://bazel.build/reference/command-line-
| reference#flag--s...
|
| [2]: https://bazel.build/reference/be/common-
| definitions#common.t...
| dietr1ch wrote:
| I remember that a system nagged about non-reproducible
| outputs, Blaze (not Bazel, but the internal thing)
| allowed looking into the outside-world through bad
| Starlark rules and compile time tricks could get you
| questioning why there's so much evil in the world.
|
| Maybe Bazel forbid these things right away and Googlers
| actually talking about Blaze will be inadvertently lying
| thinking they are similar enough.
| gf000 wrote:
| I think talking about sandboxes is missing a point a bit.
|
| It's an important constituent, but only complete OS-
| emulation with deterministic scheduling could (at a huge
| overhead) actually result in bit-by-bit reproducible
| artifacts _with arbitrary build steps_.
|
| There are an endless source of impurities/randomness and
| most compilers haven't historically cared much about this.
| jchw wrote:
| The point I'm making is that neither Bazel nor Nix do
| that. However, sandboxing is still relevant, because if
| you still have impurities leaking from outside the
| closure of the build, you have bigger fish to fry than
| non-deterministic builds.
|
| That all said, in practice, many of the cases where
| Nixpkgs builds are not deterministic are actually fairly
| trivial. Despite not being a specific goal necessarily,
| compilers are more deterministic than not, and in
| practice the sources of non-determinism are fewer than
| you'd think. Case in point, I'm pretty sure the vast
| majority of Nixpkgs packages that are bit-for-bit
| reproducible just kind of are by accident, because
| nothing in the build is actually non-deterministic. Many
| of the cases of non-deterministic builds are fairly
| trivial, such as things just linking in different orders
| depending on scheduling.
|
| Running everything under a deterministic VM would
| probably be too slow and/or cumbersome, so I think Nix is
| the best it's going to get.
| gf000 wrote:
| Sandboxing is relevant, but nix does that by default, so
| no difference here.
|
| Nonetheless, I agree that Nix does the optimum here,
| full-on emulation would be prohibitively expensive.
| jchw wrote:
| You know, though, it would probably be possible to
| develop a pretty fast "deterministic" execution
| environment if you just limit execution to a single
| thread, still not resorting to full emulation. You'd
| still have to deal with differences between CPUs, but it
| would probably not be nearly as big of an issue. And it
| would slow down builds, but on the other hand, you can do
| a lot of them in parallel. This could be pretty
| interesting if you combined it with trying to integrate
| build system output directly into the Nix DAG, because
| then you could get back some of the intra-build
| parallelism, too. Wouldn't be applicable for Nixpkgs
| since it would require ugly IFD hacks, but might be
| interesting for a development setup.
|
| Perhaps it's an area worth researching.
| lmm wrote:
| > There are an endless source of impurities/randomness
| and most compilers haven't historically cared much about
| this.
|
| The point is that Nix will catch a lot more of them than
| Bazel does, since Nix manages the toolchain used to
| build, whereas Bazel just runs the host system cc.
| taurknaut wrote:
| > It's an important constituent, but only complete OS-
| emulation with deterministic scheduling could (at a huge
| overhead)
|
| This does actually exist; check out antithesis's product.
| I'm not sure how much is public information but their
| main service is a deterministic (...I'm not sure to what
| extent this is true, but that was the claim I heard)
| many-core vm on which otherwise difficult testing
| scenarios can be reproduced (clusters, databases, video
| games, maybe even kernels?) to observe bugs that only
| arise in extremely difficult to reproduce circumstances.
|
| It does seem like overkill just to get a marginally more
| reproducible build system, though.
| paulddraper wrote:
| > Bazel also obviously uses the system compilers and
| headers. Nix does not.
|
| Bazel allows hermetic toolchains, and uses it for most
| languages: Java, Python, Go, Rust, Node.js, etc. You can do
| the same for C++, but Bazel doesn't provide that out-of-
| the-box. [1]
|
| Bazel sandboxing can restrict system access on Linux with
| --experimental_use_hermetic_linux_sandbox and
| --sandbox_add_mount_pair. [2]
|
| Every "reproducible builds" discussion requires an
| understand of what is permitted to vary. E.g. Neither Nix
| nor Bazel attempts to make build products the same for x86
| host environments vs ARM host environments. Bazel is less
| aggressive than Nix in that it does not (by default)
| attempt to make build products the same for different host
| C++ compilers.
|
| [1] https://github.com/bazelbuild/bazel/discussions/18332
|
| [2] https://bazel.build/reference/command-line-
| reference#flag--e...
| gf000 wrote:
| No, most compilers are not themselves reproducible, even
| within very restrictive sandboxes (e.g. they may do some work
| concurrently and collect the results based on when it
| completes, then build on top of that. If they don't add a
| timing-insensitive sorting step, the resulting binary will
| (assuming no bugs) be functionally equivalent, but may not be
| bit-by-by equal), and a build tool can only do so much.
| matrss wrote:
| > The quest to get every build process to be deterministic
| [...] will never be solved for all of Nixpkgs.
|
| Not least because of unfree and/or binary-blob packages that
| can't be reproducible because they don't even build anything.
| As much as Guix' strict FOSS and build-from-source policy can
| be an annoyance, it is a necessary precondition to achieve full
| reproducibility from source, i.e. the full-source bootstrap.
| jchw wrote:
| Nixpkgs provides license[1] and source provenance[2]
| information. For legal reasons, Nix also defaults to not
| evaluating unfree packages. Not packaging them at all,
| though, doesn't seem useful from any technical standpoint; I
| think that is purely ideological.
|
| In any case, it's all a bit imperfect anyway, since it's from
| the perspective of the package manager, which can't be
| absolutely sure there's no blobs. Anyone who follows Linux-
| libre releases can see how hard it really is to find all of
| those needles in the haystack. (And yeah, it would be
| fantastic if we could have machines with zero unfree code and
| no blobs, but the majority of computers sold today can't
| meaningfully operate like that.)
|
| I actually believe there's plenty of value in the builds
| still being reproducible even when blobs are present: you can
| still verify that the supply chain is not compromised outside
| of the blobs. For practical reasons, most users will need to
| stick to limiting the amount of blobs rather than fully
| eliminating them.
|
| [1]: https://nixos.org/manual/nixpkgs/stable/#sec-meta-
| license
|
| [2]: https://nixos.org/manual/nixpkgs/stable/#sec-meta-
| sourceProv...
| 0x69420 wrote:
| you can slap a hash on a binary distribution and it becomes
| "reproducible" in the same trivial sense as any source
| tarball. after that, the reproducibility of whatever "build
| process" takes place to extract archives and shuffle assets
| around is no more or less fraught than any other package
| (probably less considering how much compilers have
| historically had to be brought to heel, especially before
| reproducibility was fashionable enough for it to enter much
| into compiler authors' consideration!!)
| colordrops wrote:
| I'm curious, why couldn't packages that are fully reproduceable
| be marked with metadata, and in your config you set a flag to
| only allow reproduceable packages? Similar to the nonfree tag.
|
| Then you'd have a 100% reproduceable OS if you have the flag
| set (assuming that required base packages are reproduceable)
| jchw wrote:
| You could definitely do that, I think the main thing stopping
| anyone is simply lack of demand for that specific feature.
| That, and also it might be hard to keep track of what things
| are properly reproducible; you can kind of only ever prove
| for sure that a package is _not_ reproducible. It could be
| non-deterministic but only produce differences on different
| CPUs or an infinitesimally small percentage of times.
| Actually being able to assure determinism would be pretty
| amazing although I don 't know how that could be achieved.
| colordrops wrote:
| I assume it would be somewhat of a judgement call. I mean
| that is the case with nonfree packages as well - licenses
| and whatnot have to be evaluated. I assume that there are
| no cases of non-trivially large software packages in the
| wild that have been formally proven to be reproducible, but
| I could be wrong.
| k__ wrote:
| What are the common issues besides timestamps?
| colejohnson66 wrote:
| Compiler executing internal work concurrently and merging at
| the end. Thread scheduling changes will cause a different
| output ordering.
| 0x457 wrote:
| IIRC any package that uses Java isn't reproducible because system
| time and fixing it to epoch permamently causes issues in some
| application builds.
|
| * there're maven and gradle plugins to make builds reproducible.
| yjftsjthsd-h wrote:
| Can you force it to some time other than 0? Ex. I've seen some
| packages force timestamps to the git commit timestamp, which is
| nice but still fixed.
| Cyph0n wrote:
| This is an approach you can use when building Docker images
| in Nix flakes: https://github.com/aksiksi/ncdmv/blob/aa108a1c
| 1e2c14a13dfbc0...
| layer8 wrote:
| Can you elaborate on the root causes?
| arjvik wrote:
| What issues? I'm not aware of any Java build process that
| checks timestamps.
| paulddraper wrote:
| JARs are archives, and archives have timestamps.
|
| You can remove those with some extra work.
| gf000 wrote:
| Just add a post-process step that sets the output
| artifacts' timestamps (including its content)?
|
| Wouldn't that work?
| paulddraper wrote:
| Yes, just add that.
| throitallaway wrote:
| IME Erlang was like this ~8 years ago (the last time I touched
| it) but things may have changed since then.
| arccy wrote:
| The standard usually isn't 0s since epoch:
|
| https://bugs.openjdk.org/browse/JDK-8264449
| https://reproducible-builds.org/docs/source-date-epoch/
| vlovich123 wrote:
| > Our most important finding is that the reproducibility rate in
| nixpkgs has increased steadily from 69% in 2017 to about 91% in
| April 2023. The high reproducibility rate in our most recent
| revision is quite impressive, given both the size of the package
| set and the absence of systematic monitoring in nixpkgs. We knew
| that it was possible to achieve very good reproducibility rate in
| smaller package sets like Debian, but this shows that achieving
| very high bitwise reproducibility is possible at scale, something
| that was believed impossible by practitioners4
|
| I think people in this thread are focusing on the wrong thing.
| Sure, not all packages are reproducible, but the project is
| systematically increasing the percentage of projects that are
| reproducible while ALSO adding new projects and demonstrating
| conclusively that what was considered infeasible is actually
| readily achievable.
|
| > The interesting aspect of these causes is that they show that
| even if nixpkgs already achieves great reproducibility rates,
| there still exists some low hanging fruits towards improving
| reproducibility that could be tackled by the Nix community and
| the whole FOSS ecosystem.
|
| This work is helpful I think for the community to tackle the
| sources of unreproducible builds to push the percentage up even
| further. I think it also highlights the need for automation to
| validate that there aren't systematic regressions or regressions
| in particularly popular packages (doing individual regressions
| for all packages is a futile effort unless a lot of people
| volunteer to be part of a distributed check effort).
| sublimefire wrote:
| Some interesting related stats from Debian also show good
| reproducibility progress
|
| https://tests.reproducible-builds.org/debian/reproducible.ht...
| mikepurvis wrote:
| What's even crazier is that Nix builds _are this reproducible
| for free_. Like, joe random developer can:
| nix build nixpkgs#vim nix build nixpkgs#vim --rebuild
|
| The first invocation will substitute binaries, and the second
| will rebuild those locally and validate the bit for bit
| reproducibility of the results.
|
| In Debian there is significant ceremony and special
| tools/wrappers required to set up the reproducible environment,
| so no one would bother to use it unless they were specifically
| working on the https://wiki.debian.org/ReproducibleBuilds
| initiative.
| IHLayman wrote:
| How this article discusses reproducibility in NixOS and declines
| to even mention the intensional model or efforts to implement it
| are surprising to me, since it appears they have done a lot of
| research into the matter.
|
| If you don't know, the intensional model is an alternative way to
| structure the NixOS store so that components are content-
| addressable (store hash is based on the targets) as opposed to
| being addressed based on the build instructions and dependencies.
| IIUC, the entire purpose of the intensional model is to make Nix
| stores shareable so that you could just depend on Cachix and such
| without the worry of a supply-chain attack. This approach was an
| entire chapter in the Nix thesis paper (chapter 6) and has been
| worked on recently (see https://github.com/NixOS/rfcs/pull/62 and
| https://github.com/NixOS/rfcs/pull/17 for current progress).
| mikepurvis wrote:
| You still need to trust _something_ though. It 's just that
| instead of trusting the signing of the binaries themselves, you
| trust the metadata that maps input hashes (computed locally) to
| content hashes (unknown until a build occurs).
|
| The real win with content addressing in Nix is being able to
| proactively dedupe the store and also cut off rebuild cascades,
| like if you have dependency chain A -> B -> C, and A changes,
| but you can demonstrate that the result of B is identical, then
| there's no longer a need to also rebuild C. With input
| addressing, you have to rebuild everything downtree of A when
| it changes, no exceptions.
| mschwaig wrote:
| I think it would have been a good thing to mention, but
| difficult to do well in more than a quick reference or sidenote
| and could easily turn into a extensive detour. I'm saying this
| as someone who's working on exactly that topic. There is a
| little bit of overlap between the kind of quantitative work
| that they do and this design aspect: the extensional model
| leaves the identity of direct dependencies not entirely
| certain. In practice that means we don't know if they built
| direct dependencies from source or substituted them from
| cache.nixos.org, but this exact concern also applies to
| cache.nixos.org itself.
|
| The intensional store makes the store shareable without also
| sharing trust relationships ('kind of trustless' in that
| sense), but only because it moves trust relationships out of
| the store, not because it gets rid of them. You still need to
| trust signatures which map an hash of inputs to a hash of the
| output, just like in the extensional model. You can however get
| really powerful properties for supply chain security from the
| intensional store model (and a few extra things). You can read
| about that in this recent paper of mine:
| https://dl.acm.org/doi/10.1145/3689944.3696169. I'm still
| working on this stuff and trying to find ways to get that work
| funded (see https://groundry.org/).
| SilentM68 wrote:
| In my case, I define, "reproducible," to mean, "immutable." After
| a few days of testing, I broke NixOS. Simple test was swapping
| different Desktop Environments, eventually broke Nix, thus I'm
| not at the point where I'd agree with Nix being truly
| reproducible, at least not in that context :(
| tmnvdb wrote:
| Those things are not the same though. Reproducible just means
| it will break again if you configure your system in the same
| way.
| bsimpson wrote:
| One problem is that the applications themselves are impure.
|
| Just running KDE litters a bunch of dotfiles into your user
| folder, even for settings you didn't adjust. This is true for
| many applications.
|
| If you had an empty home folder and passively tried a handful
| of desktops, you'd no longer have an empty home folder.
| Hopefully your environment is resilient to clutter being leaked
| into your home folder, but if your filesystem isn't truly
| immutable, rolling back to a particular Nix config might not
| get you the exact state your system was in when you first built
| that.
|
| There's a project that wipes all local changes when you restart
| your machine, with the goal of making Nix systems more
| reproducible. I think it's called Impermanence.
| alfiedotwtf wrote:
| I do all my stuff in temporary docker containers, and when
| I'm done, the container gets blown away.
|
| If the point of Nix is to keep a filesystem immutable as long
| as every app sticks to certain rules, is it actually the
| right till for the job?
|
| Sorry... I actually don't know much about Nix given I've been
| using VMs and now containers for over a decade, so just
| trying to understand the problem that nix actually solves
| alfiedotwtf wrote:
| Just chatgpt'd it. I see... what I'm thinking about more
| was NixOS. Ok, I think I see how it could work, but I'd
| apps aren't really isolated, then couldn't a system still
| get to a broken if it spills out?
|
| At the moment I'm using Ansible for the host and Docker for
| guests, but I see NixOS as combining these two lasers so
| everything just runs on the host? Is that fair to say how
| NixOS works? If so and I have it wrong, maybe I should
| check it out and I've been sleeping on Nix all this time
| alfiedotwtf wrote:
| Hmm.. nix-shell and "nix develop" do look interesting!
|
| Edit: ok I HAVE been sleeping on NixOS! I couldn't
| understand how isolation worked with /etc files, but it
| turns out /etc is not modified but you do it all through
| modifying the nix config and rebuild the system which
| generates /etc! Ok, super interesting
| c0balt wrote:
| A "normal" NixOS system will only give you a full
| sandboxed isolation for apps at build time and not a
| runtime. nixpkgs (the thing packaging the stuff for
| NixOS) provides packages for apps similar to Debian
| afterwards and not flatpak in terms of runtime isolation
| (if I understand your use case).
|
| My recommendation would be to test it out and look at how
| it does things. Maybe checkout the live installer with a
| gui to get a feel for a desktop system.
| tombert wrote:
| I do something similar with Nix Flakes for a lot of my
| applications. I get my stuff working in a Flake, then I
| execute it with `nix run`; this is an ephemeral thing; once
| I kill the app then it's unlinked and can be garbage
| collected eventually.
|
| It can still write to folders, so it's not completely
| silo'd off like a full-on Docker container, but I still
| really like it.
| jf wrote:
| Aside from this being a great article with lots of interesting
| details, it's also a rare example of a headline that does NOT
| follow "Betteridge's law of headlines"
| Ericson2314 wrote:
| I got scared and then I was unexpected releaved!
|
| (-- A Nix maintainer)
| advisedwang wrote:
| Is anyone actually implementing the concept of checking hashes
| with trusted builders? This is all wasted effort if that isn't
| needed.
|
| I've seen it pointed out (by mjg59, perhaps?) that if you have a
| trusted builder, why don't you just use their build? That seems
| to be the actual model in practice.
|
| Reproducibility seems only to be useful if you have a pool of
| mostly trustworthy builders and somehow want to build a consensus
| out of that. Which I suppose is useful for a distributed
| community but does seem like a stretch for the amount of work
| going in to reproducible builds.
| c0balt wrote:
| > is anyone actually implementing [..]
|
| Not for NixOS as far as I can tell. You only have this for
| source derivations where a hash is (usually in a PR) submitted
| and must be reproducable in CI. This specific example however
| has the problem that linkrot can be hard to detect unless you
| regularly check upstream sources.
| mschwaig wrote:
| You also couldn't feasibly do that for derivations that
| actually build packages, instead of fixed output derivations
| only, because if you the update the package set to include a
| newer version of the compiler, which would often produce a
| different output, in addition to having to rebuild
| everything, you would have to update all of the affected
| hashes.
|
| What you should be able to do in the future with a system
| like nix plus a few changes is use nix as a common underlying
| mechanism for precisely describing build steps, and then use
| whatever policy you like to determine who you trust.
|
| One policy can be about having an attestation for every build
| step, another one can be about two different builders being
| in agreement about the output of a specific build step.
|
| That way you can construct a policy that expresses
| reproducibility, and reproducibility strengthens any other
| verification mechanism you have, because it makes it so that
| you can aggregate evidence from different sources. and then
| have different build hosts
| arccy wrote:
| The superior distro Arch Linux does it:
| https://reproducible.archlinux.org/
|
| maintainers build the packages, other people check:
| https://wiki.archlinux.org/title/Rebuilderd#Package_rebuilde...
| __MatrixMan__ wrote:
| > if you have a trusted builder, why don't you just use their
| build
|
| Pardon my tinfoil hat, but doing this would make them a high-
| value target. If I like them enough to trust their builds, I
| probably also like them enough to avoid focusing the attentions
| of the bad guys on them.
|
| Better would be to have a lot of trusted builders all comparing
| hashes... like, every NixOS user you know (and also the ones
| they know) so that there's nobody in particular to target.
| Timber-6539 wrote:
| That's no different from how NixOS does it. You are still
| comparing hashes from the first build done by the
| distribution. A more pure approach would be to use the source
| code files (simple sha256sum will suffice) as the first
| independent variable in the chain of trust.
| __MatrixMan__ wrote:
| I'm not sure what you mean. It's your machine that
| calculates the hashes when it encounters the code.
|
| If you bulld the directed graph made by the symlinks in the
| nix store, and walk it backwards, a sha256 of the source
| files is what you'll find, both in the form of a nix store
| path and possibly in a derivation that relies on a remote
| resource but provides a hash of that resource so we can
| know it's unchanged when downloaded later.
|
| The missing piece is that they're not gossipped between
| users. So if I find some code in a dark alley somewhere and
| it has a nix flake to make building it easy, I've got no
| way to take the hashes and determine who else has
| experience with the same code and can help me decide if
| it's trustworthy.
| mschwaig wrote:
| There are also some other gaps left to close to implement
| this vision, mentioned in this post an my reply to it:
|
| https://news.ycombinator.com/item?id=43030046
| __MatrixMan__ wrote:
| I've opened a tab to your paper and I'll be reading it,
| thanks for the link
| Timber-6539 wrote:
| If your builder is compromised, it can be co-opted to
| sign and verify the "source code" files with any values.
| The risk of placing this trust in the builder or the nix
| store is an easy one to avoid. Getting the authencity of
| the code from the source code independently ought to be
| the correct way of verifying reproducible builds.
| __MatrixMan__ wrote:
| You mean like, as a signature made by the code's author?
|
| Hmm that feels a bit too much like a root of trust, those
| make me uncomfortable. I'm more interested in tooling for
| gathering metadata re: the trustworthiness of some code
| without the author's participation. If the author wants
| to be involved, all the better.
| whazor wrote:
| There is also an additional benefit to reproducible builds,
| where getting the same output every time could help avoiding
| certain regressions. For instance, if GitHub actions performs
| extensive testing on a particular executable. Then you want to
| be able to get the exact same executable in the future, not one
| that is slightly different.
| mschwaig wrote:
| Yes. Reproducibility also makes it possible to aggregate
| information about the links in dependency trees and
| distribute trust on that basis.
|
| That stuff is useful to humans, but it is also really useful
| for cold hard automated logical reasoning about dependency
| trees.
| sublimefire wrote:
| > is useful for a distributed community but does seem like a
| stretch for the amount of work going in to reproducible builds
|
| Good point but even in the case of a larger monolithic systems
| you want to be sure it is possible to forensically analyze your
| source, to audit it. Once you can trust that one hash relates
| to this specific thing you can sign it, etc. This can then be
| "sold" with some added value of trust down the stream. Tracking
| of hashes also becomes easier once they are reproducible
| because they mean much more than just a "version".
| jonhohle wrote:
| I work on a matching decomp project that has tooling to recompile
| C into binaries matching a 28 year old game.
|
| In the final binaries created by compiled with gcc 2.6.3 and
| assembled with a custom assembler there appear to be unused,
| uninitialized data that is whatever was in RAM when whoever
| compiled the game created the release build.
|
| Since the goal is a matching (reproducible) binary, we have tools
| to restore that random data at specific offsets. Fortunately our
| targets are fixed
| fngjdflmdflg wrote:
| What even causes this to happen? ie. what dev tool would add
| random data from RAM to a binary? Is this likely a bug or is
| there some reason for it like needing to reach a specific file
| size somewhere?
| dezgeg wrote:
| By accidentally writing out uninitialized memory contents to
| the file with the game still working. It's even worse in DOS
| era where there is no memory protection so uninitialized
| memory can contain data used by other processes, so for
| example parts of source code can get leaked that way. There's
| a big list of those in
| https://tcrf.net/Category:Games_with_uncompiled_source_code
| jonhohle wrote:
| Yeah, this was originally all DOS and Windows 3.1 utilities
| for writing programs that would run on MIPS. The data is
| small enough that it isn't relevant, just not reproducible
| through standard build tools because it was never meant to
| be bitwise reproducible.
| aidenn0 wrote:
| Simply calling write() on a C struct can do that, if there is
| any padding in the struct. Then, of course, there are bugs.
| tuananh wrote:
| please do write more about it.
| jonhohle wrote:
| We use a tool named dirt-patcher[0], which was written for
| the project. It lets you write arbitrary bytes at specified
| offsets[1].
|
| As far as we know at this time, they're just uninitialized
| bytes that would have been padding for alignment or other
| reasons anyway. Maybe if we move to an official build tool
| chain we'll find they are deterministic, but for now, we
| believe they are garbage that happened to make it into the
| final binary.
|
| 0 - https://github.com/Xeeynamo/sotn-
| decomp/blob/master/tools/di...
|
| 1 - https://github.com/Xeeynamo/sotn-
| decomp/blob/master/config/d...
| CamouflagedKiwi wrote:
| > Our most important finding is that the reproducibility rate in
| nixpkgs has increased steadily from 69% in 2017 to about 91% in
| April 2023. The high reproducibility rate in our most recent
| revision is quite impressive, given both the size of the package
| set and the absence of systematic monitoring in nixpkgs.
|
| That's one way to read the statistic. Another way you could read
| the graph is that they still have about the same number (~5k) of
| non-reproducible builds, which has been pretty constant over the
| time period. Adding a bunch of easily reproducible additional
| builds maybe doesn't make me believe it's solving the original
| issues.
|
| > We knew that it was possible to achieve very good
| reproducibility rate in smaller package sets like Debian, but
| this shows that achieving very high bitwise reproducibility is
| possible at scale, something that was believed impossible by
| practitioners.
|
| Maybe I miss some nuance here, but why is Debian written off as
| being so much smaller scale? The top end of the graph here
| suggests a bit over 70k packages, Debian apparently also
| currently has 74k packages available
| (https://www.debian.org/doc/manuals/debian-
| reference/ch02.en....); I guess there's maybe a bit of time lag
| here but I'm not sure that is enough to claim Debian is somehow
| not "at scale".
| dartos wrote:
| Are they mostly the same 5k packages as 2017?
|
| That seems to be the crux of it.
| vlovich123 wrote:
| According to https://tests.reproducible-
| builds.org/debian/reproducible.ht... (which is what the article
| links to btw) there are ~37k packages tracked for reproducible
| builds which is ~2.7x smaller than Nix's 100k packages.
| gf000 wrote:
| This is not really a Nix-issue to begin with.
|
| It's a bit like asking what percentage of Nix-packaged programs
| have Hungarian translation -- if Nix packages some more stuff
| the rate might decrease, but it's not Nix's task to add that to
| the programs that lack it.
|
| Nix does everything in its power to provide a sandboxed
| environment in which builds can happen. Given the way hardware
| works, there are still sources of non-determinism that are
| impossible to prevent, most importantly timing. Most programs
| depend on it, even compilers, and extra care should be taken
| _by them_ to change that. The only way to prevent it would be
| to go full-on CPU and OS emulation, but that would be
| prohibitively expensive.
| genewitch wrote:
| > The only way to prevent it would be to go full-on CPU and
| OS emulation, but that would be prohibitively expensive.
|
| How so?
|
| For ref I used a Gentoo distcc chroot inside a devuan VM to
| bootstrap gentoo on a 2009 netbook. It worked fine. I did
| this around Halloween.
| gf000 wrote:
| A compiler invoked twice on the same source file is not
| mandated to produce the same _binary_ , but it _should_
| produce a binary with the same _functionality_.
|
| There are infinite number of binaries that do the same
| thing (e.g. just padding random zeros in certain places
| wouldn't cause a functional problem).
|
| Nix is very good at doing functionally reproducible builds,
| that's its whole thing. But there are build steps which are
| simply not deterministic, and they might produce correct,
| but not always the same outputs.
| orbital-decay wrote:
| OS scheduling is non-deterministic, and there are quite a
| few things that are sensitive to the order of operations
| (simplest example: floating point addition). Is you want to
| _guarantee_ determinism, not just provide it on a best
| effort basis for things that are willing to cooperate, the
| only way do that is to put everything into a fully
| deterministic emulator, which is terribly slow.
| genewitch wrote:
| is SCHED_FIFO or SCHED_RR or the newer incarnations
| viable? Is it possible to make QEMU deterministic? a
| quick glance at the realtime schedulers state source code
| needs to take that into consideration.
|
| I know it seems like i don't know what i am talking
| about, often, on here. The reason is i don't live on HN
| so i type a comment and rarely remember the words i want
| to use before the edit/delete window closes.
|
| The idea that i can't control when things occur during a
| compilation seems suspect. Is there a certain "code size"
| or other bellwether where this non-determinism starts to
| crop up? I ask because i get the feeling if i start
| compiling trivial stuff it will all be bit-perfect and if
| i say so i'll get lambasted for "well obviously trivial
| stuff can be reproducible," so i am heading that off at
| the pass, first.
| wg0 wrote:
| Let me guess... No?
| rssoconnor wrote:
| I'll repeat my comment from last time this came up.[0]
|
| I could be wrong (and I probably am) but I feel like the term
| "reproducible build" has shifted/solidified since 2006 when
| Dolstra's thesis was first written (which itself doesn't really
| use that term all that much). As evidence the first wikipedia
| page on "Reproducible builds" seems to have appeared in 2016, a
| decade after Dolstra's thesis, and even that stub from 2016
| appears to prefer to use the term "Deterministic compilation".
|
| Anyhow, when the Nix project originally spoke about "reproducible
| builds", what I understood was meant by that term was "being able
| to repeat the same build steps with the same inputs". Because of
| the lack of determinstic compilation, this doesn't always yield
| bit-by-bit identical outputs, but are simply presumed to be
| "functionally identical". There is, of course, no reason to
| believe that they will necessarily be functionally identical, but
| it is what developers take for granted every day, and if
| otherwise would be considered a bug somewhere in the package.
|
| With Nix, when some software "doesn't work for me, but works for
| you", we can indeed recursively compare the nix derivation files
| locating and eliminating potential differences, a debugging
| process I have used on occasion.
|
| I agree that "reproducible builds" now means something different,
| but that isn't exactly the fault of Nix advocates. I guess a new
| term for "being able to repeat the same build steps with the same
| inputs" is needed.
|
| [0]https://news.ycombinator.com/item?id=41953155
| steve-chavez wrote:
| I think you want to link to
| https://news.ycombinator.com/item?id=41956044.
| naasking wrote:
| > There is, of course, no reason to believe that they will
| necessarily be functionally identical, but it is what
| developers take for granted every day, and if otherwise would
| be considered a bug somewhere in the package.
|
| Yes, the only possible differences result from either a
| compiler bug or a program bug that depends on undefined
| behaviour, in which case "anything can happen" as they say. As
| others have noted, parallel compilation depends on non-
| deterministic thread-scheduling, so this non-determinism can't
| be solved unless you restrict all compilation to be single-
| threaded. It's still not the only possible source of non-
| determinism though.
| tracnar wrote:
| > I agree that "reproducible builds" now means something
| different, but that isn't exactly the fault of Nix advocates. I
| guess a new term for "being able to repeat the same build steps
| with the same inputs" is needed.
|
| I've usually seen "repeatable builds" used for that.
| mhh__ wrote:
| I guess this is a tangent, but Nix to me feels like the right
| idea with the wrong abstraction. I can't explain / it would take
| a serious bit of genius to come up with an alternative worth
| switching to.
|
| Has anyone done any better?
| Ericson2314 wrote:
| You can use the low level stuff without the language to forge
| your own journey.
|
| https://github.com/NixOS/nix/blob/master/doc/manual/source/s...
|
| I am working on the docs for this as we speak.
| zanecodes wrote:
| I agree, I feel like Nix is kind of a hack to work around the
| fact that many build systems (especially for C and C++) aren't
| pure by default, so it tries to wrap them in a sandboxed
| environment that eliminates as many opportunities for impurity
| as it reasonably can.
|
| It's not solving the underlying problem: that build systems are
| often impure and sometimes nondeterministic. It also tries to
| solve a bunch of adjacent problems, like providing a common
| interface for building many different types of package,
| providing a common configuration language for builds as well as
| system services and user applications in the case of NixOS and
| home-manager, and providing end-user CLI tools to manage the
| packages built with it. It's trying to be a build wrapper, a
| package manager, a package repository, a configuration
| language, and more.
| gf000 wrote:
| > It's not solving the underlying problem: that build systems
| are often impure and sometimes nondeterministic
|
| It's not Nix's job, imo. Those compilers should be fixed.
|
| And all the other "features" come for free from Nix's
| fundamental abstractions, I don't feel it would overstep its
| boundaries anywhere.
| throwawayqqq11 wrote:
| Purity becomes a hard goal when ever you hit the real world
| at build or runtime. By definition, you have to bridge 2
| domains.
|
| Imagine constant time compute and constant memory constrains,
| required in cryptography, being applied to the nix ecosystem.
|
| Yes, this is an artifical example but it shows that purity is
| harder to define and come by, then some people think. Maybe
| someday these constraints actually do apply to nix goal of
| reproducibility.
|
| With ever changing hardware that purity is a moving target so
| nix imo will always be an approach to purity and bundling so
| much tooling is to be expected. Still, you can legitimately
| call it a hack :)
| genewitch wrote:
| I have never checked if my c compilers are deterministic, but
| Gentoo has tinderbox, and since everything that has an emake or
| whatever has a sha hash; this means if I use the exact same sha
| hashed source as the tinderbox binary, I should get a bitwise
| equal binary output myself. I of course imply _all_ of the
| toolchain is using sha hash verified source output.
|
| In Gentoo
|
| `emerge -e <package name>` will do it, add binpkgs if you know
| what you're doing (I do, and I do).
| tuananh wrote:
| so looks like reproducibility rate of nixos is not that high,
| roughly similar with debian?
|
| https://wiki.debian.org/ReproducibleBuilds
| dpc_01234 wrote:
| At this point almost all major package managers try to not
| introduce any non-reproducibility, so it comes down to package
| itself building deterministically. Nix just have an
| architectural sandboxing and isolation that enforces is maybe a
| bit better. But the moment e.g. ArchLinux devs fix determinism
| and upstream it in certain package, it will become
| deterministic in NixOS and others, and vice versa, so there is
| not going to be a lot of differences between distros at this
| point. Everyone agrees that deterministic builds are a good
| thing.
| GeezNuts wrote:
| Certainly not all packages are reproducible, but the project is
| systematically increasing the percentage of projects that are
| reproducible while ALSO adding new projects and demonstrating
| conclusively that what was considered infeasible is actually very
| readily achievable.
| rednafi wrote:
| Is it somewhat reproducible? Yes.
|
| But what did it cost? Usability.
| __MatrixMan__ wrote:
| > there exist no reproducibility monitoring at the scale of the
| Nix package set (nixpkgs)
|
| I think it would be fairly easy to do this monitoring with a bit
| of community participation. At least I'd enable telemetry
| -\\_(tsu)_/-.
|
| By default the pkz57 in /nix/store/pkz57...-nushell-0.97.1 is a
| hash of the build inputs for that package. If you hash the
| contents of that dir, you get an identifier for the build output.
|
| If we then make a big list of such pairs as built by different
| people on different machines at different times, and capture the
| frequency of each pair we'll either see this:
| /nix/store/pkz5..., sha256:0drrxa..., 121 users
|
| or we'll see this: /nix/store/pkz5...,
| sha256:0drrxa..., 100 users /nix/store/pkz5...,
| sha256:gvpbk5..., 20 users /nix/store/pkz5...,
| sha256:1fwwfe..., 1 user
|
| The former being an indicator that the build is reproducible, and
| the latter giving hints about why not (supposing these users are
| willing to share a bit more about the circumstances of that
| build). I'd call it a "build chromatograph". I expect that
| knowing whether you're one of the 100 or the odd-man-out could be
| relevant for certain scenarios.
| gf000 wrote:
| I'm not sure the "distribution" would be all that helpful.
|
| A single compiler that does some parallel work and collect the
| results of that work in a list in order of completion (and
| similar) are probably the most common cause of non-determinism.
|
| Given that, your chromatograph would be mostly "determined" by
| the source code's peculiarities, instead of the offending
| compiler itself. (E.g. I have n classes a compiler would
| process in parallel, so given a single point of timing non-
| determinism n! different combinations could possibly exist
| (assuming they all cause a different outputs). The only
| information I could conclude from such a distribution is that
| there is a common sequence of completing tasks).
|
| But your idea is cool, and simply reporting back non-matching
| local builds would be helpful (I believe the binary property of
| whether a different output could be built is the only relevant
| fact) -- also, if we were to mark a package as non-
| reproducible, we could recursively mark everything else that
| has it as a (transitive) input.
| ninetyninenine wrote:
| >As part of my PhD, and under the supervision of Theo Zimmermann
| and Stefano Zacchiroli, I have empirically studied bitwise build
| reproducibility in nixpkgs over a time period of 6 years.
|
| Why spend only 6 years on the most interesting topic of all
| mankind? I spent 10 years analyzing this.
| lrvick wrote:
| I would note that stagex is 100% reproducible, and full source
| bootstrapped.
|
| Every artifact is reproduced and signed by multiple maintainers
| on independently controlled hardware and this has been the case
| since our first release around this time last year.
|
| https://codeberg.org/stagex/stagex
| est31 wrote:
| Note that NixOS's "build" step often actually doesn't do any
| compilation. Often it's just downloading a binary from github
| releases and runs NixOS's specific binary tools on it to make it
| look for libraries in the right places.
|
| So if that process is reproducible, it's a different statement
| from a Debian package being reproducible, which requires build
| inputs in the preferred form of modification (source code).
| IngoBlechschmid wrote:
| You are right, but I would not agree with this appearing
| "often". I get the impression that the nixpkgs community tries
| quite hard to truly compile from source even quite complex
| projects like Firefox and LibreOffice.
| max-privatevoid wrote:
| Completely false. Building from the actual source code is
| strongly preferred and usually easier than patching a binary
| that wasn't built for such an environment.
| pmarreck wrote:
| It's massively closer than any other solution in this regard
| (nods to other Nix-inspired distros like Guix, Lix, etc.)
|
| Honestly, I believe every software developer owes it to
| themselves to read the original Nix paper. It's quite digestible
| and lays out a lot of what it brings to the table. I came away
| from it wondering why it took so long to realize it... which is a
| property I've found true of every new important discovery.
|
| https://edolstra.github.io/pubs/nspfssd-lisa2004-final.pdf
|
| If you want, you can even ask an LLM to sum up its main points
| for you. Or to sell it to you. =)
|
| https://chatgpt.com/share/67ae1a08-7354-8004-8200-e956cb6b59...
|
| I would like to say one thing about using Docker to "solve" this
| problem though: Once you think of builds in terms of functions,
| you realize that a Docker image is basically just the cached
| artifacts of a build that "just so happened" to work correctly.
| Consider a function that only occasionally produces a correct
| value: A Docker image is one of those values.
| tlavoie wrote:
| Thanks for the paper, will check it out! (Still skeptical that
| we should encourage LLM summarization though, suspect people
| would gain more and actually learn things from reading papers.)
| beebaween wrote:
| I've genuinely never really understood the appeal of Nix. I even
| attempted to use this to build and "maintain" the machines we
| used at an offsite factory and even then with just a basic
| electron app, a python installation and very basic mac configs
| Nix proved to be a complete nightmare.
___________________________________________________________________
(page generated 2025-02-13 23:02 UTC)