
Tested in an AI-assisted isolated Linux workspace. Not yet independently rerun on Romeo’s own host. Evidence and review policy.
01. Give the health check a contract
“The server returned 200” is a narrow claim. This lab makes the limitation visible: both releases serve health.txt successfully, but only one contains the expected healthy response. A deployment gate that checks status alone would accept the wrong release.
The expected response lives in config.json. Treat it as the exercise’s contract. A real application’s contract should reflect its critical operation and dependencies, not just a static text file.
02. Understand the release layout
releases/v1/health.txt # release-v1: healthy
releases/v2/health.txt # release-v2: not-ready
current -> releases/v1The source constructs these files in a temporary directory and serves the current path through a loopback-only HTTP server. It creates a separate candidate symlink and uses os.replace to replace the current symlink on the same filesystem.
This local pointer operation is not a complete deployment architecture. Existing requests, distributed instances, schema changes, and writes require additional coordination. Do not point this exercise at a production directory.
03. Reproduce the unhealthy release
Extract the lab bundle, inspect it, and run python3 run_lab.py --config config.json. The third experiment promotes v2, checks its response, rejects it, and restores v1.
Candidate health -> 200 | release-v2: not-ready
HTTP-only check would pass: True
Expected-content health check passes: False
After rollback -> 200 | release-v1: healthy
Current release: v1These are actual captured results from the isolated workspace run. The script asserts the unhealthy decision and the restored response. It does not measure production downtime or claim a recovery-time guarantee.
04. Keep the rollback boundary explicit
Switching a symlink back changes which files new lookups see. It does not undo a database migration, retract a sent email, cancel a payment, or recover lost writes. Before choosing rollback, verify that the previous code can still use the current data and configuration.
Some failures call for a forward fix or a tested data restore. Define the trigger, the responsible operator, and the user-facing verification before the change window. The recovery design note develops that planning exercise.
Lesson from the failure: check the operation you depend on. A health endpoint that cannot distinguish the bad release from the good one cannot protect the release gate.
05. Make the result useful to someone else
Record the environment, exact command, expected response, observed response, and final release. Keep both the failed candidate result and the recovery result. A single “PASS” screenshot without the setup is difficult to reproduce.
The free checklist includes a handoff template. Repeat the lab on your own disposable host and record differences before adapting the pattern to a real application. The published evidence here is workspace-tested; an independent host rerun is still welcome.
Sources & further reading
Found a mistake or a different result? Send a correction with the article title and the environment you tested.