S17 Phase 6: virtual and remote repository CRUD

Summary

CRUD for remote and virtual repositories on the management API, per ADR-009: the non-hosted polymorphic settings (remote upstream URL, auth, cache TTLs; virtual upstream associations), upstream management routes, and connection test. Phase 1 shipped the shared repository CRUD with hosted-only rows; this phase lifts the non-hosted rejection.

Gated on

  • S13 Virtual and remote foundation and the format slices: S14-S16 (remote), S30-S32 (virtual).

This phase patches the S17 spec and follows the repo gate: spec MR, plan MR, implementation. Part of &22341.

Workstream status (2026-08-25)

The graph is a ledger of work in progress and work to be done: a step's node leaves the graph when its merge request merges, and the Merge request status table below keeps the full step-to-MR record, merged rows included. Reading the colors, green nodes have an open merge request and link to it, amber nodes are being implemented but their merge requests have not opened yet, grey nodes are planned, red nodes are blocking follow-ups, and blue nodes are slices outside this issue's ownership whose schema migrations gate the virtual steps. Edges are the plan's dependency graph among the remaining nodes, plus the four slice edges, so every edge shown is an unsatisfied dependency. Blocking follow-ups join the map when they are filed and carry no plan edges, so the step each one holds is named in the external gates below. A follow-up leaves the map when the step it held merges, and joins the follow-up list until it closes.

Dependency graph

graph TD
    S36["Step 36: Virtual create and delete: Maven"]
    S37["Step 37: Virtual create and delete: npm"]
    S38["Step 38: Virtual create and delete: container"]
    S39["Step 39: Maven virtual upstream store and the delete-side guard"]
    S40["Step 40: Upstream association routes: Maven"]
    S41["Step 41: Upstream associations: npm"]
    S42["Step 42: Upstream associations: container"]
    EXTS30["S30 Maven virtual slice (#289)"]
    EXTS31["S31 npm virtual slice (#290)"]
    EXTS32["S32 container virtual slice (#291)"]
    S36 --> S40
    S37 --> S41
    S38 --> S42
    S39 --> S40
    S40 --> S41
    S40 --> S42
    EXTS30 --> S36
    EXTS30 --> S39
    EXTS31 --> S37
    EXTS32 --> S38
    click EXTS30 "https://gitlab.com/gitlab-org/ops/artifact-registry/-/issues/289"
    click EXTS31 "https://gitlab.com/gitlab-org/ops/artifact-registry/-/issues/290"
    click EXTS32 "https://gitlab.com/gitlab-org/ops/artifact-registry/-/issues/291"
    classDef stOpen fill:#c8e6c9,stroke:#2e7d32,color:#1b5e20
    classDef stInBuild fill:#ffecb3,stroke:#ff8f00,color:#ff6f00
    classDef stPlanned fill:#f5f5f5,stroke:#9e9e9e,color:#424242
    classDef stBlocking fill:#ffcdd2,stroke:#c62828,color:#b71c1c
    classDef stExternal fill:#d6e4ff,stroke:#3f51b5,color:#1a237e
    class S36,S37,S38,S39,S40,S41,S42 stPlanned
    class EXTS30,EXTS31,EXTS32 stExternal

Beyond the four slice edges the diagram carries, the plan names these external gates per step:

Non-blocking follow-ups filed against this phase carry no graph membership: Remote repository destructive delete (202 tombs... (#697) • Unassigned, Unify the container remote downloaded-at setter... (#698) • Unassigned, Container remote token cache is not evicted on ... (#706) • Unassigned, Visibility changes on hosted and virtual reposi... (#707) • Unassigned, AC #83's create-time coverage is fetch-only: up... (#715) • Hayley Swimelar • 19.4, Container remote read-store comments still desc... (#733) • Unassigned, Repository path segment reaches FindByName unsc... (#734 - closed) • Unassigned, Sweep: remote read stores carry identifiers in ... (#735) • Unassigned, delete_all contract defines completion by accep... (#738) • Hayley Swimelar • 19.4, DeleteIfUnreferenced takes no FOR UPDATE on blo... (#742) • Unassigned, ADR-012 deleted-event row reads as covering evi... (#743) • Unassigned, logAndWriteInternalError swallows context cance... (#744) • Unassigned, wire_oci_remote and wire_npm_remote build store... (#754 - closed) • Dzmitry (Dima) Meshcharakou, and Deploy-ordering gate for the remote bulk passes (#755) • Hayley Swimelar • 19.4.

Steps 1 through 35 are on main at f60ca64e3, and no step merge request is open. The seven that remain, steps 36 through 42, all hold on the virtual schema gate, directly or through the create step each one follows.

Merge request status

Step Reviewer Status Merge request
1 vespian_gl Merged feat(managementapi): declare connection test an... (!1568 - merged) • Hayley Swimelar • 19.3
2 jdrpereira Merged chore(datastore): add remote cache keyset and d... (!1581 - merged) • Hayley Swimelar • 19.3
3 radbatnag Merged chore(audit): add the management audit seam wit... (!1571 - merged) • Hayley Swimelar • 19.3
4 vespian_gl Merged chore(datastore): add the maven remote create a... (!1579 - merged) • Hayley Swimelar • 19.3
5 vespian_gl Merged chore(datastore): add the maven remote row-lock... (!1585 - merged) • Hayley Swimelar • 19.4
6 vespian_gl Merged chore(datastore): add container remote reposito... (!1578 - merged) • Hayley Swimelar • 19.3
7 radbatnag Merged chore(datastore): add container remote reposito... (!1586 - merged) • Hayley Swimelar • 19.3
8 vespian_gl Merged feat(managementapi): serialize remote settings ... (!1572 - merged) • Hayley Swimelar • 19.3
9 vespian_gl Merged chore(datastore): dispatch the repository delet... (!1576 - merged) • Hayley Swimelar • 19.3
10 vespian_gl Merged feat(datastore): dispatch the repository create... (!1618 - merged) • Hayley Swimelar • 19.4
11 vespian_gl Merged chore(managementapi): add remote settings decod... (!1575 - merged) • Hayley Swimelar • 19.3
12 vespian_gl Merged into !1572 (merged) feat(managementapi): serialize remote settings ... (!1625 - merged) • Hayley Swimelar • 19.4
13 mkhalifa3 Merged chore(managementapi): artifact-read kind-dispat... (!1582 - merged) • Hayley Swimelar • 19.4
14 vespian_gl Merged chore(datastore): add container remote image an... (!1629 - merged) • Hayley Swimelar • 19.4
15 mkhalifa3 Merged feat(managementapi): serve the maven remote pac... (!1749 - merged) • Hayley Swimelar • 19.4
16 vespian_gl Merged feat(managementapi): serve the maven remote fil... (!1794 - merged) • Hayley Swimelar • 19.4
17 mkhalifa3 Merged feat(managementapi): serve the npm remote packa... (!1750 - merged) • Hayley Swimelar • 19.4
18 arpitgogia Merged feat(managementapi): serve the npm remote file ... (!1799 - merged) • Hayley Swimelar • 19.4
19 vespian_gl Merged feat(managementapi): serve container remote ima... (!1747 - merged) • Hayley Swimelar • 19.4
20 arpitgogia Merged feat(managementapi): serve the container remote... (!1748 - merged) • Hayley Swimelar • 19.4
21 vespian_gl Merged chore(remote): add per-format health probe targ... (!1570 - merged) • Hayley Swimelar • 19.3
22 vespian_gl Merged feat(managementapi): serve the upstream connect... (!1632 - merged) • Hayley Swimelar • 19.4
23 radbatnag Merged feat(managementapi): serve the remote settings ... (!1732 - merged) • Hayley Swimelar • 19.4
24 suleimiahmed Merged into !1618 (merged) feat(managementapi): serve the remote repositor... (!1642 - merged) • Hayley Swimelar • 19.4
25 mkhalifa3 Merged chore(datastore): add maven remote eviction com... (!1574 - merged) • Hayley Swimelar • 19.4
26 vespian_gl Merged chore(datastore): compose the id-keyed npm remo... (!1573 - merged) • Hayley Swimelar • 19.3
27 mkhalifa3 Merged chore(datastore): add the container remote evic... (!1589 - merged) • Hayley Swimelar • 19.4
28 vespian_gl Merged feat(managementapi): serve the maven remote pac... (!1726 - merged) • Hayley Swimelar • 19.4
29 vespian_gl Merged feat(managementapi): evict on the npm remote de... (!1761 - merged) • Hayley Swimelar • 19.4
30 vespian_gl Merged feat(managementapi): serve container remote evi... (!1790 - merged) • Hayley Swimelar • 19.4
31 vespian_gl Merged feat(managementapi): maven remote bulk pass (S1... (!1756 - merged) • Hayley Swimelar • 19.4
32 vespian_gl Merged feat(managementapi): run npm bulk delete as a r... (!1759 - merged) • Hayley Swimelar • 19.4
33 radbatnag Merged feat(managementapi): container remote bulk pass... (!1805 - merged) • Hayley Swimelar • 19.4
34 jdrpereira Merged feat(managementapi): serve the url change on th... (!1841 - merged) • Hayley Swimelar • 19.4
35 mkhalifa3 Merged into !1748 (merged) feat(managementapi): serve the container remote... (!1900 - merged) • Hayley Swimelar • 19.4
Follow-up suleimiahmed Merged docs(plans): record the open phase 6 step MRs i... (!1580 - merged) • Hayley Swimelar • 19.3
Follow-up jdrpereira Merged docs(plans): record the second batch of phase 6... (!1619 - merged) • Hayley Swimelar • 19.4
Follow-up jdrpereira Merged docs(plans): record the third batch of phase 6 ... (!1668 - merged) • Hayley Swimelar • 19.4
Follow-up dmeshcharakou Merged docs(plans): record the batch-4 step MRs in the... (!1733 - merged) • Hayley Swimelar • 19.4
Follow-up 10io Merged docs(plans): record the batch-5 step MRs in the... (!1752 - merged) • Hayley Swimelar • 19.4
Follow-up 10io Merged docs(plans): record the batch-6 step MRs in the... (!1791 - merged) • Hayley Swimelar • 19.4
Follow-up 10io Merged docs(specs): state remote manifest size as the ... (!1796 - merged) • Hayley Swimelar • 19.4
Follow-up vespian_gl Merged docs(plans): record the step 33 and 34 MRs in t... (!1846 - merged) • Hayley Swimelar • 19.4
Follow-up unassigned Merged docs(plans): record the step 35 merge request (!1902 - merged) • Hayley Swimelar • 19.4
Edited by Hayley Swimelar