8. A bad manifest is shown, not applied
A mistake in an app's settings file (ratcloud.conf) leaves the old settings running and says what was wrong.
ratcloud.conf is checked before anything is applied. A bad one refuses the push, in the pusher's terminal and in RC_FACTS/manifest.json; the site keeps running.
This is the code serving the zoo right now: read from disk for this request, from commit
77ff74344d (staging). The zoo's own self-check fetches this
page and compares it byte for byte with the file it runs.
exhibits/08-bad-manifest.php sha256 521428ea5169 · raw
1<?php 2// Exhibit 8. A push whose ratcloud.conf is wrong is refused whole: the old code and settings keep 3// running and the error lands in the app's RC_FACTS/manifest.json. The sample app `zoo-broken` has a 4// deliberate typo pushed to it. The zoo reads only its own facts, so zoo-broken publishes its own 5// manifest fact at /manifest.json, from its last good version, and the zoo fetches that over HTTPS. 6// (The dashboard will show the same error to zoo-broken's creator.) 7return [ 8 "n" => 8, "wing" => "Deploy", 9 "title" => "A bad manifest is shown, not applied", 10 "promise" => "A mistake in an app's settings file (ratcloud.conf) leaves the old settings running and says what was wrong.", 11 "block" => "ratcloud.conf is checked before anything is applied. A bad one refuses the push, in the pusher's terminal and in RC_FACTS/manifest.json; the site keeps running.", 12 "show" => function (?array $me): string { 13 $s = stored(8)["data"] ?? null; 14 $url = rc_app_url("zoo-broken"); 15 if (!$s) return '<p>The sample app <a href="' . h($url) . '/">zoo-broken</a> has not been checked yet.</p>'; 16 return '<p>The sample app <a href="' . h($url) . '/">' . h(parse_url($url, PHP_URL_HOST)) . '</a> is up, and its last push was refused:</p>' 17 . '<pre class="log">' . h($s["error"] ?? "") . "</pre>" 18 . '<p class="muted">Refused ' . ago(strtotime($s["at"] ?? "now")) . ", commit " . h(substr($s["commit"] ?? "", 0, 7)) . ". It still serves its last good version.</p>"; 19 }, 20 "check" => function (): array { 21 $url = rc_app_url("zoo-broken"); 22 [$code] = (new Browser())->get("$url/"); 23 if ($code !== 200) return [false, "the sample app is down ($code): a bad manifest must not take it down"]; 24 [$code, , $m] = (new Browser())->get("$url/manifest.json"); 25 if ($code !== 200 || !is_array($m)) return [false, "the sample app's manifest fact did not load ($code)"]; 26 if (($m["ok"] ?? null) !== false) return [false, "the sample app's typo was accepted, or is gone: no error to show"]; 27 if (trim((string)($m["error"] ?? "")) === "") return [false, "the push was refused but no error was recorded"]; 28 return [true, "zoo-broken is up on its last good version; its typo was refused with: " . $m["error"], $m]; 29 }, 30];