The above paths have the format of "/Programs/<PackageName>/<VersionNumber>/<TraditionalDirectory>/<FileName>". GoboLinux presumably scans every package directory and adds symbolic links to "/System/Index/<TraditionalDirectory>/<FileName>", like the following example (respectively):
The primary file locations make it easy to handle one package at a time, cleanly adding and removing entire packages. The indexed view makes it easy to find files (binaries, libraries, includes, man pages, etc.) by name without worrying about what packages they belong to.
Generally speaking, tagging can be half-simulated using hierarchies and (hard/soft) links. But a tag-based system would be cleaner and not prioritize one retrieval method over another. Here is an illustration of how I might rephrase GoboLinux's package storage and retrieval system in terms of tags:
Blob("... binary data of bash executable ..."), with hash = 9e19e455.
Blob("... binary data of ping executable ..."), with hash = 28224f5b.
Blob("... binary data of libpng.so library ..."), with hash = 6243c115.
Blob("... binary data of stdio.h C code ..."), with hash = d0335126.
Tag(packageName="Bash", version="4.4", target=9e19e455).
Tag(packageName="Netkit-Base", Version="0.17", target=28224f5b).
Tag(packageName="LibPNG", version="1.2.5", target=6243c115).
Tag(packageName="Glibc", version="2.24", target=d0335126).
Tag(traditionalDirectory="bin", fileName="bash", target=9e19e455).
Tag(traditionalDirectory="bin", fileName="ping", target=28224f5b).
Tag(traditionalDirectory="lib", fileName="libpng.so.3", target=6243c115).
Tag(traditionalDirectory="include", fileName="stdio.h", target=d0335126).
Everything remains in a hierarchical structure (or a few, if you consider the symlinks).
The notion of tags does away with a hierarchy.