`instance` takes three new inputs so one project can include the component once per build lane. `job_name_prefix` renames that lane's four job keys (lint-containerfile, detect-changes, build, promote) and the three `needs:` edges between them; `containerfile` is hadolint's target and buildah's `-f`; `context` is buildah's trailing context argument, so a lane builds from its own subtree and anchors `build_change_paths` there. A second inclusion used to deep-merge silently onto the first's four job keys, later include winning, and every image built from the repo root. All three default to the previous behaviour: existing consumers get byte-for-byte identical merged jobs. `consumer-shape-test` runs two lanes: `instance` included twice, the second prefixed with its own containerfile and context, so child-pipeline creation reconciles eight job keys and two `needs:` chains. A child pipeline's source is `parent_pipeline`, matching neither build's nor promote's rules, so those two resolve structurally and never instantiate; their prefixed names and edges are graded by a real multi-lane consumer's pipeline, not here. `check-change-paths` reads every instance include, not only the first, diffs each against the Containerfile its own include names, and fails a repo whose includes share a prefix. Coverage now spans the Containerfile path and the context subtree as well as the COPY/ADD sources, so a lane that moves its Containerfile under `lanes/` while leaving the anchor at the template default reads DRIFT, not OK; a `containerfile` outside its own include's `context` is DRIFT too. An ancestor anchor reaches in, so one `lanes/**/*` covers every lane, and a single-mapping `include:` is checked, not skipped. Every command-level registry and network call retries. skopeo copy/inspect/delete and buildah push/pull against docker:// carry --retry-times/--retry-delay or --retry/--retry-delay (verified against skopeo v1.22.2, buildah v1.43.2). Every curl call gains --retry-connrefused and --connect-timeout 15 alongside its existing --retry flavor: the five binary downloads keep --retry-all-errors/--retry-max-time, API reads use --retry 3 --retry-delay 5 --max-time 120, release-create's release-metadata calls use --max-time 60. kickstart.yml and summary.yml's apt-get calls gain -o Acquire::Retries=3 on update and install. check-change-paths.py's fetch_url wraps urllib in a 3-attempt loop: a transport error (URLError, including a bare read timeout) retries after 5s; an HTTPError re-raises immediately as a verdict, not a flake. Job-level retry adds api_failure everywhere an outbound call is made, and script_failure only where a job's body is idempotent: a digest-compare guarded copy/promote, a read-only lint, a deterministic drift assertion. Four untimed jobs gain a timeout: seal 45m, image-verify 20m, installer-anaconda-iso and qcow2-bake 60m each, and the two long bakes gain `interruptible: true`, so a second push to the same branch cancels a running bake. `instance`'s build and promote gain 30m each; detect-changes stays untimed by design. base-build-scratch's `promote` no longer treats a failed `buildah pull` as a uniform no-op: only a captured stderr matching manifest-unknown/404 (no build at this sha) logs and exits 0, and every other pull failure, a registry flake included, exits 1 instead of silently skipping :latest/:stable promotion on a pipeline that stays green. installer-anaconda-iso and qcow2-bake's `--upload-file` calls raise `--max-time` from 900 to 1800 and add `--speed-limit 1024 --speed-time 120 --retry-max-time 3000`, so a transfer stalled below 1 KB/s for two minutes aborts and retries. `--max-time` bounds one attempt, `--retry-max-time` bounds how long the loop keeps starting them, and the loop closes at 3600s: the job's own 60m ceiling, not merely inside it. `consumers-aligned` and `release-check` accept a major-version range pin (`@10`) alongside an exact tag. `consumers-aligned` takes the literal after `@` verbatim instead of demanding a full `vX.Y.Z`, and compares it against the major of the catalog's newest release. `release-check` requires every catalog component pin in README.md to read `@<major-of-the-tag-being-checked>`; an exact `vX.Y.Z` pin, or a bare pin count of zero, fails. README.md's own pins move to `@10`: a range resolves at pipeline-parse time to the newest published release on that major, so a patch or minor reaches a consumer with no pin bump, leaving a major bump as the one fan-out step. `create-release` now carries `needs: [publish-images]`. Without the edge the two `release`-stage jobs ran in parallel, so a red `publish-images` did not stop the GitLab Release (and the Catalog release riding on it) being created. Survivable under an exact pin, but a range pin makes the Release itself the propagation event, so it must not register while the images it names are failing to publish. `seal`'s `buildah build` gains `--label catalog-ref=<catalog_ref>` on downstream runs, where the sealing recipe is cloned at the pinned `catalog_ref`. The label is conditional: a catalog self-test build uses the checked-out recipe and stamps none. Once a consumer cites `@10` instead of an exact tag, that label is the only place the resolved catalog release survives on a downstream image, readable with `skopeo inspect`. Minor bump: every new input keeps its previous default, and every other edit is additive (the label, the `needs:` edge) or a check accepting a second, already-valid pin shape.