v2 builder: expose `.doc` via sibling `cabal v2-haddock` slice
Under v1 every component's `.doc` was a sibling Setup haddock
derivation that shared the lib's UnitId. Under cabal v2-build
this no longer holds: `cabal v2-haddock` flips
`elabBuildHaddocks` (and the haddock-html / haddock-hscolour /
... family) on every unit's `ElaboratedConfiguredPackage`, which
all land in `pkgHashConfigInputs`. Calling `cabal v2-haddock`
against a plan that didn't already have `documentation: True`
forks every UnitId in the closure and triggers a from-source
rebuild.
Round-tripping `documentation: True` through plan.json's
`--ghc-option=-haddock` / `configure-args.nix` /
`ghc-options: -haddock` is NOT equivalent: the ghc-option keeps
haddock comments in `.hi` files but doesn't set the haddock-config
booleans, so the slice's `pkgHashConfigInputs` diverges from
plan-nix's and the dep closure's UnitIds fork (observed on
OneTuple in `tests.sublib-docs`: plan-nix `9a847723` vs slice
`f546bd36`).
Approach:
* `comp-v2-builder.nix` detects per-package `--ghc-option=-haddock`
in plan.json (the `documentation: True` signal cabal-install
surfaces) and emits `package <pkg>\n documentation: True\n`
in the slice's cabal.project for every documented package.
`-haddock` is filtered out of the per-pkg `ghc-options:` block
so cabal doesn't see it twice in `pkgHashGhcOptions`.
* Each library slice exposes `.doc`, a sibling derivation that
runs `cabal v2-haddock` against the already-built unit (no
closure rebuild). `.doc` throws with a migration hint when
documentation isn't in the project's plan-json — that's the
only shape where the UnitIds align.
* Doc slices propagate `(map d: d.doc)` for `docEnabled` deps
only, so cross-package hyperlinks resolve. Mixed projects
(some packages docs, others not) keep working because non-doc
deps come in as plain slices.
* `build-cabal-slice.nix` keeps cabal's native unit-dir layout
(`$out/store/<ghc>/<unit-id>/share/doc/html/`) so doc slices
`lndir` into `~/.cabal/store/` as drop-in replacements, and
cross-package hyperlinks (absolute
`file:///nix/store/<doc-slice>/store/<ghc>/<dep-uid>/...`)
resolve back into the slice's own tree. Non-target unit
haddocks are stripped from `$out` to keep each slice lean —
deps' html lives in the deps' own `.doc` slices.
`docs/dev/haddock.md` documents the v2 semantics, the
`documentation: True` requirement, and why there's no
`slice.haddockDir` (local plan-nix UnitIds use `<pkg>-<ver>-inplace`
form while the slice's cabal-store uses cabal's mangled hash form,
so there's no eval-time-stable html path — callers `find` it
under the doc slice).
Verified `tests.sublib-docs.run` builds Lib.html and Slib.html
under `slice.doc`, and OneTuple's UnitId in plan.json matches
plan-nix's recorded id.