# Deferred Derivation Resolution — Approaches Tried ## Problem A non-CA derivation depends on a CA derivation. At evaluation time, Nix can't compute the output path because the CA output is unknown. The .drv file stores `path=""` for each output — this is a **deferred** derivation. The deferred derivation's env contains `downstream_placeholder(drv, out)` strings that must be replaced with actual CA output paths before building. ## Approaches ### 1. Delegate to CADerivationHandler (DIDN'T WORK) `DerivationHandler` saw `output.path == ""` and dispatched to `CADerivationHandler`. But CADerivationHandler assumes CA semantics (content-addressed hash), and the daemon doesn't know the output path either → `$out` empty → `sh: can't create : nonexistent directory`. ### 2. Send empty paths, let daemon resolve (DIDN'T WORK) Sent `BuildDerivationRequest` with empty output paths in the `BasicDerivation`, relying on the daemon to resolve placeholders using registered realisations. The Nix daemon **does not** resolve deferred derivations during `BuildDerivation` — it just uses the output paths from the `BasicDerivation`. Empty path → `$out=""` → builder fails. ### 3. Pre-compute hash via _resolve_deferred_outputs (HASH MISMATCH) Used `_resolve_deferred_outputs` from the old `derivation_resolution` module. This calls `_hash_derivation_modulo()` which calls `_unparse_basic_derivation()` — produces an ATerm WITHOUT `input_drvs` (since `BasicDerivation` has no such field). But the daemon reads the `.drv` file which HAS `input_drvs`. The daemon's `hashDerivationModulo` replaces `input_drvs` with modulo values before hashing, while `_unparse_basic_derivation` just omits them entirely. These produce different hashes → `OUTPUT_REJECTED`. ### 4. Hash via Derivation.serialize() (HASH MISMATCH — different direction) Took the parsed `Derivation`, rewrote env/args with resolved paths, called `Derivation.serialize()` which includes `input_drvs` as raw store path references. Hashed the full ATerm. But the daemon's `hashDerivationModulo` replaces `input_drvs` with modulo hash values BEFORE hashing — not raw store paths. Different hash → wrong output path. ### 5. Clear input_drvs, serialize Derivation (CURRENT — SHOULD WORK) Same as approach 3 but uses the actual `Derivation.serialize()` (not `_unparse_basic_derivation`) after clearing `input_drvis` and `dynamic_input_drvs`. Should produce the same ATerm format as the daemon produces AFTER its modulo-replacement step, since: - Daemon replaces each `input_drv` entry with a fixed-size modulo hash placeholder - These placeholders are not part of the ATerm format — they collapse to the same empty `[]` as clearing them outright - Only input_srcs (which are real store paths) remain - Output paths, env, args match the resolved derivation