Fuenf Befunde aus der abschliessenden Review, in einer Runde behoben:
- EnvFileEditor::backup() liess PHPs copy() die Umask entscheiden statt den
Modus der Quelle zu uebernehmen — .env stand mit deploy/install.sh auf 0600,
jede Sicherung landete trotzdem weltlesbar bei 0644, mit APP_KEY,
DB_PASSWORD, VPN_CONFIG_KEY und STRIPE_SECRET darin. Reproduziert (per
kurzzeitigem git stash des Fixes: 420 statt 384) und jetzt durch einen
expliziten chmod nach dem Kopieren sowie einen neuen Test verhindert.
- HostSeparationTest pruefte "jede Route hat einen Hostnamen" nur scheinbar
allgemein — deploy/install.sh schreibt ADMIN_HOST_EXCLUSIVE=false als
Vorgabe, und im nicht-exklusiven Fallback registriert routes/web.php jede
/admin/*-Route absichtlich ohne Domain. Der Test setzte zwar
ADMIN_HOST_EXCLUSIVE=true, sagte aber nirgends, dass genau das die
Voraussetzung der Pruefung ist. hostSeparationTable() gibt AdminArea::
isExclusive() jetzt als Out-Parameter zurueck, gelesen waehrend die zweite
Anwendung noch gebootet ist, und der Test besteht darauf.
- clupilot:bind-hosts existierte, aber nichts sagte einem Operator, dass es
ihn braucht. deploy/update.sh druckt jetzt einen eigenen Hinweis, wenn
APP_HOST in .env leer ist — mit der vollen docker-compose-Zeile statt der
internen in_app-Abkuerzung, weil der Operator sie in seiner eigenen Shell
eintippt.
- ask STATUS_DOMAIN und ask FILES_DOMAIN versprachen "blank to keep it auf
jedem Host", fuellten Enter aber ueber den dritten ask()-Parameter mit dem
Default. Fuer FILES_DOMAIN war das kein Schoenheitsfehler: der Default
verschiebt /bootstrap.tar.gz vom Portal weg, bevor DNS fuer den neuen Namen
existiert. Beide Defaults entfernt.
- ask WWW_DOMAIN erklaerte nicht, dass SITE_HOST mehrere kommagetrennte Namen
traegt (der erste kanonisch, der Rest leitet dauerhaft um) — ein Operator,
der die Apex-Domain zusaetzlich zu www. binden wollte, hatte keinen Weg,
das aus dem Prompt zu erfahren. Nur der Prompt-Text geaendert, kein neuer
Prompt, Default unveraendert.
Voller Testlauf: 2953 passed (Baseline 2952 + der neue Backup-Berechtigungs-
Test), 0 failed. routes/web.php, RestrictAdminHost, config/fortify.php und
PublicSiteGate unangetastet.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>