`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.