ci: split release vs dev registry image/cache paths
## Context
`build-image` pushes both the image (`$CI_REGISTRY_IMAGE:$CI_COMMIT_SHORT_SHA`) and the build cache (`$CI_REGISTRY_IMAGE/cache`) to the **same** registry paths for MR and default-branch pipelines.
Those paths carry `maintainer` container protection rules, so the Developer-role Renovate bot's MR pipelines get `403 Forbidden` pushing cache/image, while Owner-triggered runs succeed.
Rather than grant the bot push access to the protected release paths (or relax those rules), split ephemeral CI artifacts onto their own namespace so MR pipelines never touch release paths.
## Design
Split registry paths by default-branch vs not:
| scope | image | cache |
|---|---|---|
| default branch (release) | `mson/mr-reporter` | `mson/mr-reporter/cache` |
| non-default (dev) | `mson/mr-reporter/dev/$CI_COMMIT_REF_SLUG` | `mson/mr-reporter/dev/$CI_COMMIT_REF_SLUG/cache` |
- Keep `maintainer` protection on the release paths; only default-branch pipelines write them.
- `dev/*` paths carry no `maintainer` rule, so a Developer (the bot) can push there.
- Cache flow stays one-directional: `CACHE_FROM` = release `/cache` (read-only base; protection gates push/delete, not pull) plus the branch's own `dev/$CI_COMMIT_REF_SLUG/cache`; `CACHE_TO` = only the branch's `dev/$CI_COMMIT_REF_SLUG/cache`. Per-branch keying drops cross-feature-branch sharing for isolation (no branch can poison another's cache): the warm base comes from main, the incremental reuse from the branch's own prior runs.
- `MR_REPORTER_IMAGE` points downstream jobs at the dev image path on non-default pipelines.
Net property: nothing an MR does can affect a default-branch pipeline's cache or release image until it merges. The change has to pass the MR gate first.
## Tasks
- [ ] Parameterize image/cache paths by default-branch vs not in `.gitlab/ci/build.yml`.
- [ ] Confirm existing protection rule patterns are exact-match so `dev/*` is unprotected; if not, add an explicit Developer-push rule scoped to `dev/*`.
- [ ] Add a registry cleanup/expiration policy for `dev/*` (ephemeral images and per-branch caches accumulate).
- [ ] Verify a fresh bot MR pipeline pushes to `dev/*` and goes green end-to-end.
*Generated with Claude Code*
issue