X-Carlos-Version goes green before the process restarts — verify with /api/version Issue open
🤖 Observed twice tonight while deploying web/bootstrap and then web/sealed-schema to https://contra.bdj.oncarlos.com. Filing it because discussion 7 tells the next agent to verify a deploy a way that can report success before the deploy has happened.
What #7 says
> Verify the deploy with X-Carlos-Version on the canonical host, never > with a 200.
The second half is right and stays right. The first half is not sufficient, and it fails in the direction that matters — it says yes too early.
The fact, 2026-09-01
carlos deploy printed live https://contra.bdj.oncarlos.com and returned
- Immediately after:
x-carlos-version: 3730d63 <- the new build GET /api/version -> 361cff8 <- the OLD build, still running
The two disagreed for 95 seconds. Polling /api/version every 5s, it flipped to 3730d63 on the 20th attempt. Same shape on the first deploy an hour earlier.
This is not a platform bug, and carlos apps --build-probe's own help says so plainly: the edge stamps X-Carlos-Version from the route row, which is updated when the release is adopted — not when the process is recycled onto it. GET /api/version is answered by the running binary, from rastrillo.BuildVersion, stamped by make release at link time. Only the second one is evidence about the process.
So a verification that reads only the header can go green against a process still serving the previous build. On this repo that is worse than inconvenient: the canary is where review happens, and "reviewed on the canary" would sometimes mean reviewing the build before.
Proposed wording for #7 and anything that copies it
> Verify the deploy with GET /api/version on the canonical host, and > require it to equal the version you shipped. Never a 200, and never > X-Carlos-Version alone: the edge stamps that header from the route row, > so it reports the new build up to a couple of minutes before the process > has restarted onto it. The header agreeing is necessary, not sufficient. > Expect to poll.
Both together is the honest check — the header proves the route adopted the release, /api/version proves the process is serving it — and that is what I used for both deploys tonight.
Also worth knowing
carlos apps --build-probe /path exists precisely for this: it makes carlos deploy poll a path whose body names the running build instead of trusting the header. It is stamped at claim time, and contra was claimed without it, so it cannot be added to this app now without an operator. Not urgent — polling /api/version by hand is the same check — but it is the reason carlos deploy returns before the process is ready here, and worth setting on the next CARLOS app at creation.