Release plan
Omniyat Collection · release engineering · 31 Oct 2026

Release independence, speed and previews

Release each repository on its own, ship migrations ahead of code, switch Workers blue/green, and see every release by its tag. Previews join as a second track. Decisions Q1 to Q39 are settled. The page also maps the repositories, the code, the infrastructure and the security controls as they stand on 31 Oct 2026.

⏸
Plan only. No PR in this plan gets merged, and each step starts only when confirmed.

TL;DR

Release one repository at a time

oc release staging --only salesforce or --only collections runs alone. A cascade with pin PRs still exists, and --serial orders it. There is one lock per Worker.

Migrations before code

A migrations-only API release cuts its own api-v tag and runs only the migration part of the graph. Expand migrations ship first; contract migrations carry a marker and ship later.

Blue/green Workers

The engine uploads a version, holds it at 0%, checks its health through the override header, then moves it to 100%. Rollback is a version switch. A failed node retries once first.

Releases visible by tag

service.version, the Sentry release and the Cloudflare version tag become api-v… or connector-v…. Today they are a UUID and a SHA.

Previews: second track

One preview per developer handle, a mock connector by default, the shared development database, and telemetry in evidence. api-pr retires once previews are on develop and proven.

Order

Step 0 lands the environment foundation (cloud 552 + 554). The seven release steps then run beside the environment steps. Production is parked.

6 min
API release
today ~11 min
4 min
Salesforce alone
not possible today
3 min
Migrations only
not possible today
5 min?
Preview, code-only push
proposed, not decided

Repositories

Eight repositories supply the app, its backend and its release tools. Select a box to trace what it takes and gives; hover an arrow for detail, or toggle link kinds below.

Repository suppliers and consumers Arrows flow from supplier to consumer. Select a repository with a click or Enter to show its details. Dashed boxes are external services.

Scroll the map sideways to see every box.

Pin order: framework → engine → evidence → ops → connector → api

One pin pull request per repository per cycle. Evidence and artefacts are consumed by URL, without a version pin.

Code architecture

Each repository as a stack of layers: imports flow downwards, and dashed rows sit beside the stack. Click a box to see what it uses and what uses it, or press ▶ Trace to walk one path through the code.

—
—
—
—
selectedusesused bydashed row: beside the stack

Infrastructure

Trace a request, a Salesforce change or a release through the platform. Switch environment while it plays; hover or focus a box for its role and bindings.

Staging · live
01 / 05
Resident request · iOS app
Current step Visited Unavailable or replaced here Connection used by a flow

Security: defence in depth

Nine layers, from the edge in to the audit trail, with every control checked against the repositories on 31 Oct 2026. Follow an attack to see which layers stop it, filter by status or environment, and click any control for its detail.

Follow an attack

—
Pick an attack
Each step lights the layer that meets the attacker and says whether it stops, limits or misses the attack.

    Every control, layer by layer

    Release data flow

    It plays every release type in turn once it is on screen. Pick one, or use the controls, to take over. Each repository's lane can release on its own; the numbered dashed links are where lanes meet. Hover any box for its detail.

    —
    Choose a release
    The diagram shows all four lanes. Pick a release above to trace its path.
    1Cascade only: the engine tag opens pin PRs in salesforce and collections. 2Schema first: API code that needs a migration ships in a later release. 3The live API declares the connector minors it accepts.

    Blue/green Worker cutover

    It plays every outcome in turn once it is on screen. Pick one, or use the controls, to take over. This applies to Workers with no pending Durable Object migration or Container change. The connector Worker stays on wrangler deploy because it runs a Container; Containers keep the rolling rollout plus a health check after 10%.

      Migrations: expand, then contract

      An illustrative column rename across three releases. Click a release on the timeline. Then turn on the toggle to see what the gate does with a destructive migration in a migrations-only release.

      Schema · residents

      Live code

      Gate

        Refused. The destructive-statement check fails because vN-1 still reads phone. A contract migration ships only in a normal API release, and only after the check shows the live release no longer uses the column (Q21).

        Roadmap

        Click a step to see what it delivers, its PRs and its decisions. Steps it depends on and steps it unblocks light up.

        selecteddepends onunblocks
        0
        Environment foundation: cloud 552 + 554environment as data and the preview and production kinds; staging stays byte-identical

        Release track

        Environments track

        Budgets

        Time from command to live. The top bar is today's API release, split into its serial stages. The other bars are the agreed budgets; the dashed bar is still a proposal. Hover a bar for details.

        trusted CI bundle release run budget
        PathTodayBudgetWhere the time goes
        API release~11 min6 minThe stages run in series: trusted CI 1–4 min (slowest recent run 9m21s), the bundle ~2.5 min, the release run ~4.7 min (graph 158 s, apply 106 s). Building the bundle alongside CI, reusing green runs and switching versions instead of deploying removes most of it.
        Salesforce alonenot possible4 minToday it rides the full cascade.
        Migrations onlynot possible3 minRuns only the migration part of the graph, from the sealed bundle.
        Preview, code-only push—5 min?Proposed, not decided. Mock connector, shared database, warm.

        Decisions

        All 39 answers from the grilling rounds on 31 Oct 2026.

        Current state

        The facts behind the plan, as of 31 Oct 2026.

        Preview and environment PR set

        Already merged: collections 1896 (the X-Worker-Version header that cloud 559's health check reads) and 1893. The cloud PRs form one stack, 552 → 554 → 555 → 557 → 559. Step 3 restacks 559 directly onto 554.

        Release lines
        LineRepositoryTag or target
        frameworkframeworkv, golang/v
        enginecloudcloud-cli-v
        evidencecloudevidence-v
        opssalesforceops-v
        connectorsalesforceconnector-v image; nothing goes live until an API release binds it
        apicollectionsapi-v

        Releases run in dependency waves (cloud/oc.yml). UPSTREAM=0 releases only the API. There is no --only and no serial mode.

        Where checks run, and why
        WhereEngineConsumer tree
        Consumer's own PR CIpinnedthat PR
        Cloud consumers jobbuilt from the cloud PRdevelop or main head
        Pin PRnew releasehead plus the pin commit

        These checks look like duplicates, but each pairs a different engine with a different tree. The cloud consumers job stays because tags are immutable, so a break found after the tag costs a whole extra release. Since cloud 688 it takes 60 s for collections and 9 s for salesforce; the Workers job, at 340 s, is the critical path.

        The API release today
        • Graph order: api.store → api.image → api.migrate-worker → api.migration → api.connector-worker and api.worker → api.health. The applied ledger skips migrations that already ran. Shadow mode applies nothing. Schema never rolls back.
        • Each Worker deploys in place with wrangler deploy. When health fails, wrangler rollback runs per Worker, capped at 1 min per undo. No node is retried.
        • The connector Container rolls out in steps [10,100] with full_auto. The release waits up to 15 min, polling every 10 s, and holds when the image is unchanged. Nothing holds or waits for the migrate Container.
        • Wrangler 4.149.0 limits: Durable Object migrations need wrangler deploy; Container config changes apply only on deploy; a percentage split needs identical Durable Object exports.
        Telemetry identity today
        • service.version is the Cloudflare version UUID (packages/observability/src/runtime/observability-composition.ts).
        • The Sentry release is the commit SHA.
        • RELEASE_VERSION is stamped at prepare and shown only by /health (apps/api/src/core/runtime/release-identity.ts).
        • Evidence accepts only deployment.environment.name = staging (edge/obsx backend-envelope-dto.ts), so it would refuse preview telemetry.

        Open questions and risks

        Written so they make sense without access to the code host. Questions need a decision; risks are ranked by how likely each is to slow or break a release.

        Open questions

        Risks