Decision from Paul (2026-10-05): option 1, a console credential CI can hold, limited to canary and edge. Not option 2.
The reasoning:
- Direct-bucket mode stays, as the operator's tool. The signed pointers in the bucket are what boxes trust, and the console sits on top of them. Direct mode is for setting up a deployment before a console exists, deployments with no console, recovery when the console is down, and the platform's own releases.
- It should not be the normal CI path. A direct promote skips the console's audit line, pipeline rules, pending approvals and the serial bump. Every CI deploy that bypasses the console is one the console can't account for. On Carloku, customers never hold bucket credentials, so the console is the only way in for them, and their CI needs exactly what titogo is asking for.
- 2a (direct promote bumps the serial) is declined. Making the bypass faster makes it more attractive.
- 2b (poll every followed channel pointer) is declined. Today an idle box makes one serial check per 2-second tick. 2b multiplies that by every followed channel on every box, and avoiding that cost is why the serial exists.
- README.md:170 changes with the feature. It currently tells CI to use direct mode ("logging in is for a human at a laptop, never a box or a pipeline"). That was right when the console only had human logins. Once a scoped CI credential exists, the README will point CI at the console and describe direct mode as operator and break-glass only.
Next: a spec for the credential on a design- branch, linked here when it's up. Until it lands, titogo stays on direct mode with the scoped key and the 2-minute timer drop-in. That is slow but correct, and not a workaround.
What I verified on main (8d8e4bae): direct promote never calls release.BumpSerial, and svcrole.Publish reaches promote, rollback, ship, retention, version-target and trash (internal/console/authcli.go:482-549).