/**
 * Variant-scoped outgoing artifacts.
 *
 * <p>This package models the external artifact contract of a project in terms of variant-local slots.
 * A variant represents one outgoing contract, while a slot represents one artifact set inside that
 * contract.
 *
 * <p>The model intentionally separates cheap identity objects from stateful build objects:
 *
 * <ul>
 * <li>{@link org.implab.gradle.variants.artifacts.ArtifactSlot} identifies a published slot inside a
 * variant;</li>
 * <li>{@link org.implab.gradle.variants.artifacts.ArtifactAssembly} is the lazily materialized body of
 * that slot.</li>
 * </ul>
 *
 * <p>Each slot is expected to materialize to exactly one published artifact: either one file or one
 * directory. Internal build topology such as roles may participate in slot assembly rules, but does not
 * belong to external artifact identity.
 *
 * <p>Typical usage:
 *
 * <pre>{@code
 * variantArtifacts {
 *     variant("browser") {
 *         primarySlot("runtime") {
 *             fromRole("main") { output("js") }
 *         }
 *         slot("sources") {
 *             fromLayer("main") { output("sources") }
 *         }
 *     }
 * }
 * }</pre>
 *
 * <p>After finalization, slot identities can be observed through
 * {@link org.implab.gradle.variants.artifacts.VariantArtifactsContext#getSlots()}, while slot bodies are
 * obtained on demand through
 * {@link org.implab.gradle.variants.artifacts.VariantArtifactsContext#getAssemblies()}.
 */
package org.implab.gradle.variants.artifacts;
