Symlinks in FSOs don't create closures

I have a directory that has a non-dangling symlink to an absolute path within the Nix store. Let’s say that the path is called P and the directory is D. I first run:

nix-store --add-fixed --recursive sha256 $D

The resulting stored path, let’s call it S, has an intact symlink to P within it. However, P is not in the closure of S; the following query only prints one path:

nix-store -q --tree $S

Concretely, I have the following FSOs checked into my Nix store:

$ readlink /nix/store/fnzvpr0i9pdy9fkls7rd9vq11c5kxwg4-Process/parent\*
/nix/store/vj1bv876kxyj6b4a5h69kfp1vqn6wvb5-V

$ nix-store -q --tree /nix/store/fnzvpr0i9pdy9fkls7rd9vq11c5kxwg4-Process
/nix/store/fnzvpr0i9pdy9fkls7rd9vq11c5kxwg4-Process

$ nix-store -q --referrers-closure /nix/store/fnzvpr0i9pdy9fkls7rd9vq11c5kxwg4-Process
/nix/store/fnzvpr0i9pdy9fkls7rd9vq11c5kxwg4-Process

I want to know if this behavior is (1) intended, (2) stable/reliable, (3) a known issue with a known workaround, and (4) something that could change in the future. I did read the thesis first to double-check whether it’s addressed there; the thesis suggests that this sort of symlink is legal but doesn’t say whether it creates closure around the referent FSO.

Context: I adopt Nix as a native package manager when designing programming languages. I’d like to know what happens when I invoke nix-store --add-fixed on compiler-generated artifacts without generating a derivation first. I found this behavior while playing around.

As far as I know, fixed-ca objects do not and cannot have dependencies, and this is intended behavior. It carries through to other similar locations, like how you cannot use builtins.toFile on a string with a context, and how FODs cannot retain any references to their build deps.

On an implementation level, consider how you would scan for these dependencies. In a derivation, you have a set of store paths to look for in your scan, which you get from the string context that went into the derivation. For a fixed blob like this, there’s no starting point.