ADR-008: uses composition is a flat union of independent trees, not a layered override¶
Status: accepted
Context¶
An overlay can uses other overlays, pulling in their files and packages.
Two composition models fit: a layered override (later entries take priority
over earlier ones' values, like the ancestor-directory config cascade in
Overlay::new — see ADR-002)
or a flat union (every used overlay applies to the same target, with no
declared priority between them).
Decision¶
Overlay::apply_inner applies every uses entry, recursively, to the same
target directory as the parent overlay — not a separate namespace. A
visited set skips an overlay already fully applied (safe for diamond
dependencies) and a stack set turns a real cycle into an error rather than
infinite recursion. Package installs compose the same way, as a pure
BTreeSet union (collect_packages), with their own visited set so a
diamond-shared overlay's packages aren't installed twice.
over lint's check_cycles treats graph validity (acyclic, every uses
target exists) as a static-analysis concern, separate from apply-time cycle
detection.
Consequences¶
Diamond dependencies (two overlays both usesing a common third one) work
correctly and cheaply — no double-application, no double-install. But there
is no way to declare that one used overlay's file should win over another's
identically-named file: the outcome depends on uses list order plus
whatever the user picks in the interactive conflict prompt. That is a
fragile, order-sensitive behavior for something that looks, from the
config, like a composition feature with defined priority.