Skip to content

Redeploy main after a merge when prod has not converged on it #3848

Open

Description

@devantler

🤖 Generated by the Agentic Engineer

Part of #2838. It follows #3846, whose resolver merged in #3847.

Evidence

Audience and impact

This serves the platform operator. It closes the last path by which prod can silently disagree with main after a merge.

Smallest useful change

After a merge lands on main, run the resolver against the digest :latest names:

  • CONVERGED: do nothing.
  • BEHIND or DIVERGED: run the normal production deploy of main, through the same composite and the shared prod-deploy lock.
  • UNKNOWN: do not deploy; fail visibly, so a broken check is never mistaken for a converged prod.

Because this job reaches production, it inherits every gate the existing deploy paths carry: the publication gate, the authorization and signing contracts, and the per-workflow coverage guards. It lands behind an opt-in switch, defaulting off, and is activated separately.

Acceptance criteria

  • On a merge where prod already matches main, the job reads CONVERGED and does not deploy (proven on a real merge).
  • A BEHIND or DIVERGED verdict triggers exactly one deploy of main, and a second evaluation afterwards reads CONVERGED.
  • UNKNOWN never deploys and fails the job with the resolver's reason.
  • The job holds the shared prod-deploy lock and cannot run concurrently with a merge-group deploy or heal.
  • Tell whether prod has converged on main from the published artifact's signed provenance #3846's live CONVERGED acceptance point is recorded from this job's first real run.

Size

M: one workflow job plus contract-test updates, behind an opt-in switch.

Blocker: the next time production is behind main after a merge | outcome | last-verified 2026-10-17: not yet; the two bot-dispatched CD runs that succeeded since 2026-10-07 (10-12, 10-14) came from restore-stranded-prod.yaml, and the observer before the 10-12 one read DIVERGED and skipped its redeploy step. When the observer reads BEHIND, confirm it redeployed main and production converged, then close

Activity

  1. added theissue type on Sep 15, 2026
  2. moved this to 📥 Backlog in 🌊 Project Boardon Sep 15, 2026
  3. devantler commented on Sep 16, 2026

    @devantler
    ContributorAuthor

    🤖 Generated by the Agentic Engineer

    First slice merged: #3864 (5e3049c9). After every push to main, a read-only job reports the resolver's verdict. CONVERGED becomes a notice. BEHIND and DIVERGED become warnings, because a queued merge group can briefly show DIVERGED. UNKNOWN fails the job. The job never deploys. Before resolving, it fetches every commit the provenance names, so an artifact left by a merge-group heal does not read as UNKNOWN. Its first live run read CONVERGED (run 35150608562).

    Acceptance criterion State
    Prod already matches main → reads CONVERGED, no deploy (real merge) Met on the #3864 merge; this slice never deploys
    BEHIND/DIVERGED triggers exactly one deploy of main, then CONVERGED Open: the deploy slice
    UNKNOWN never deploys and fails with the resolver's reason Met for the report; still to keep in the deploy slice
    Holds the shared prod-deploy lock Open: the deploy slice
    #3846's live CONVERGED point recorded Met

    Next slice: a deploy of main on BEHIND/DIVERGED under prod-deploy, behind a switch that defaults to off. It reaches production, so it carries the deploy lane's usual gates.

  4. devantler commented on Sep 17, 2026

    @devantler
    ContributorAuthor

    🤖 Generated by the Agentic Engineer

    Status 2026-09-17: the deploy slice merged as #3870 (for #3869)

    Acceptance criterion State
    Prod already matches main → reads CONVERGED, no deploy (real merge) Met. On the #3870 merge itself, run 35212406549 read CONVERGED for 1dff6239, skipped the redeploy step, and dispatched no CD run.
    BEHIND triggers exactly one deploy of main, then CONVERGED Built, not yet observed live. The observer dispatches CD on main only on BEHIND, skips when an unfinished CD run already targets main's tip, and waits for its dispatched run to be listed before releasing the lock. Proven by the script's tests. A real BEHIND needs the #2838 interleaving, so this stays open until one happens.
    DIVERGED Deliberately not redeployed. A queued merge group that deployed before merging also reads DIVERGED, so redeploying on it would undo a deploy that is about to land (decision recorded on #3869). It stays a warning.
    UNKNOWN never deploys and fails with the resolver's reason Met (unchanged from #3864).
    Holds the shared prod-deploy lock Met: the observer job takes prod-deploy with queue: max.
    #3846's live CONVERGED point recorded Met.

    Remaining: record the first live BEHIND → one CD run → CONVERGED sequence. Nothing else is left to build here.

  5. devantler commented on Sep 19, 2026

    @devantler
    ContributorAuthor

    🤖 Generated by the Agentic Engineer

    Status 2026-09-19: still waiting on a live BEHIND. Nothing is left to build.

    Across the last 100 validate-main.yaml runs, 32 reached the 🧭 Observe Production Convergence job, and every one of them recorded CONVERGED in its annotations. None recorded BEHIND, DIVERGED or UNKNOWN. The only failed run in that window (35100863274, 2026-09-16) predates the observer.

    So the one open criterion (a real BEHIND, then one CD run, then CONVERGED) is waiting for the #2838 interleaving to actually happen. There is no code change to make until it does. Any later run can re-check with the check-run annotations on that job.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    Fields

    Priority

    None yet

    Effort

    None yet

    Projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions