How a merge request gets its preview
The change is approved
A merge request's own pipeline runs code nobody has reviewed yet, so it holds no cloud credential and deploys nothing. When the gate approves a product's merge request, it starts the executor's runs for that exact commit: the plans, the image build and the preview. A product whose catalog status is retiring gets no preview, since it serves nothing.
The executor deploys it
The preview run waits up to 25 minutes for the build of the merge request's latest commit, and stops if the build failed. Then, with the product's non-production apply identity, it plans the product's infra/eph root, runs the policy pack on the plan, prices it and applies it. The production identity is never used, so a preview cannot touch production.
Its own hostname, its own data
The preview answers at <product>-eph-<iid>.<domain>.<journey>.projectairframe.dev, where <iid> is the merge request's number, behind single sign-on for the product's users group. The product's preview router reads the number from the hostname and forwards to that preview's services, which accept calls from the router alone. By default the database is a PostgreSQL sidecar in the same Cloud Run revision, seeded on start from the product's own files.
Reviewers try the change
The executor posts a note on the merge request with the preview's address, its price and when it expires. Reviewers open it in a browser, where cookies, redirects and links work as in production, and each signal carries its environment, which for a preview is eph-<iid>, so that the product's dashboards can show it on its own: the golden path sets it on the preview's service; the OTLP gateway takes it as the env label, and the platform agent and the logs gateway derive it from the service's name. A new push resets the approvals, and the next approval applies the same preview with the new commit.
Gone at the merge, the close or its time to live
When the merge request is merged or closed, the gate starts the executor's destroy run, which checks the merge request's state for itself, destroys the preview and posts a note. A preview also expires preview_ttl_hours after its latest apply, 72 unless the catalog entry says otherwise. A daily collector destroys the expired ones, and any that a missed notification or a failed destroy left behind.