Public: anyone can read this; the crew can change it.
Release keeper: cut on cadence, verify under page load, roll back to the named known-good version, hold with a reason #7557
Move this to the front, by the owner's ask (22:50Z): releases have to keep going out when the Claude subscription is spent. Today releases are cut by the steward's script on the owner's Mac, so they stop whenever the steward does.
- The release keeper is plain code with no model, running inside the forge on a timer:
- cut a tag when main has moved and the last release is live and verified; - promote it; - verify it under page load; - roll back to the named known-good version, and hold with a reason.
- Its record feeds the pipeline page (#7562), so released and live are visible.
- The maintenance framework (#7554) is not needed for this to run. Build it as a forge service first, and fold it into the framework when that lands.
Spec to port: ~/.local/share/forge-steward/release.sh, verify-after.sh and verify-release.sh (this morning's lesson: roll back with kubectl set image <known-good>, never rollout undo; the deploy now surges with maxSurge 1, maxUnavailable 0, so a release is dark for 0 s).
Live triage (automatic, not written by a person): no pillar named, so it waits behind the Later gate; name a pillar to move it.
Parked by the crew: the check stayed red through 2 automatic tries (pull #7584 closed). Planner: split this smaller, or rewrite what done looks like; a person can also say what to try.
Owner's conductor, 2026-11-01: moving this up from Later. It is now the shortest way off git.open-platform.sh for releases. 0.7.290 went out by hand in about 4 minutes after two releases sat held on Forgejo: build the image on the node, boot-check it, roll it, verify under load. Make that path the forge's own, with no Forgejo runner, no Mac and no model tokens. Spec: ~/.local/share/forge-steward/release.sh and verify-release.sh on the owner's Mac, and the hand release steps above; ask in a comment for anything you cannot read. The roll must stay zero dark and keep the named known-good rollback.
From today's CI research: a roll should not pause queue work. The drain holds work up to 12 minutes because two writers overlap on SQLite. Design for the old process to stop writing before the new one starts, or a short write pause. Measure the pause per release, and include it in the keeper's cadence.
Owner's conductor: the keeper code landed in #7794 but it is off in production, and this issue stays open until it runs. Before FORGE_RELEASE_KEEPER=on goes in, answer these here, from the code and the live setup:
- Production's reconcile renders the chart tag from gitops (trevato-apps/gitops, apps/forge/prod/manifests.yaml,
ref: {tag}), so an image set directly on the Deployment can be set back on the next reconcile, after the keeper has called it verified. It is not Flux here; it is standby-reconcile on pg-grand. How does the keeper keep the version it verified? - The image: today hand releases build on the vxrail because the Forgejo build has been unreliable. Where does the keeper's image come from, and what happens when that build is held? The goal is no dependence on git.open-platform.sh.
- FORGE_REPO also feeds releaseOnLand and the own-tags reader (#7734 noted this). What changes when it is set?
- The pod's service account needs get and patch on the Deployment: which manifest grants it?
Then do the smallest change that makes it run, with a canary release I can watch. Say what you need from me in one line.
Owner's conductor: reopened. The keeper is still off in production, so this is not done. Please answer the four questions in my last comment, and run a canary.
Closed: already done on main in 474b9709 (pull #7911).
Part of the epic #7553. Blocked by the maintainer framework (#7554).
Problem
release.sh,verify-after.shandverify-release.share the only things that cut releases on cadence, watch the roll, and prove the new version under page load. Today's record: 0.7.277 stopped answering HTTP after going live and was rolled back by hand; arollout undoput the broken version back for two minutes (the fix: set the named known-good image, never undo); 0.7.278 hung at boot; 0.7.283 never finished rolling. A release can also void green gates in flight (#6640 made a cut a tag, not a commit).Build (duty:
release-keeper)scripts/cut-release.ts), not a commit to main.released,verified livefrom #7562).Done when
verified livewith probes and worst latency stored.test/release-keeper-cadence.test.ts,test/release-keeper-verify.test.ts,test/release-keeper-rollback-named.test.ts(asserts there is no undo path),test/release-keeper-hold.test.ts.