fix(cloud-init): make Caddy runcmd POSIX-compatible#1582
Merged
Conversation
Contributor
Auto-committed by SAM on agent completion.
This reverts commit d203b0e.
|
raphaeltm
marked this pull request as ready for review
July 21, 2026 11:31
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
set: Illegal option -o pipefailby making the scalar Caddyruncmdblock POSIX-compatible (set -eu)./bin/shwith isolatedloggerandmkdirboundary stubs.mainnormally; no force-push was used.Validation
f4e759a2311df8bae0607ab94b522193be586f4bTDD evidence is retained in the active task: before the runtime fix, the two new interpreter-contract tests failed under Dash with status 2 and the exact
pipefailerror; after the one-line fix both role branches pass.Staging Verification (merge-blocking)
f4e759a2311df8bae0607ab94b522193be586f4bdeployed in run29727014256; deploy and 12/12 built-in smoke tests passed.01KNY6DC06C9QCYQM0389NAGNTwas confirmed.01KXZAN71M1XKPSXTG79QJXVF0was created through the Nodes UI via user→platform fallback and reached Hetzner running/healthy with a heartbeat.Illegal option -o pipefail,cc_scripts_userfailure, andFailed to run module scripts-userwere absent. VM-agent error entries were zero.ae17814d-dcec-4dec-bd7a-1a02c8161128rendered and persisted markerPR1582_CLAUDE_20260720090229, then returned idle.6cbba882-2291-457a-b5be-8d54c9848906rendered and persisted markerPR1582_CODEX_20260720090324, then returned idle.01KXZAN71M1XKPSXTG79QJXVF0was deleted and verified absent.01KXZFJGBDVSQA0H73QJ71CDS9passed from fresh prerequisites with no code/profile mutation or API-created chat sessions.01KXZGB1E2SYY1Z592EB82TBKCreached running/healthy/heartbeat on exact agent SHAf4e759a2311df8bae0607ab94b522193be586f4b;modules-finalandconfig-scripts_usersucceeded, actual cloud-init/VM-agent error records were zero, and all regression signatures were absent.4c337d61-1700-4f8b-b0cb-fe7743478294/ workspace01KXZGTFKRQXP9DTCFE70DCAENrendered and persistedSTAGING-VALIDATE-CLAUDE-20260720-UNIQUE-a7b3c9; Codex sessiond171ed63-1902-4c56-911f-88522978dd05/ workspace01KXZH36JCND69CVJRXNGT7Y8Yrendered and persistedSTAGING-VALIDATE-CODEX-20260720-UNIQUE-d8e2f1. Both conversation turns settled into the expected waiting-for-next-input state.01KXZGB1E2SYY1Z592EB82TBKCwas deleted and verified absent; the secondary account returned to zero nodes.Cloud-init also emitted recovered Hetzner metadata discovery probe messages inside normalized
level=infoentries. They are recorded rather than hidden; final cloud-init completion, the feature-specific failure signatures, normalized severity, node health, and agent logs are the merge gates.Two earlier validator tasks were invalidated and stopped after violating their account/UI constraints. Their exact nodes, two unintended profiles, and one empty API-created session were validated, cleaned, and verified terminal/absent; none of their evidence is counted as independent PASS evidence.
End-to-End Verification
generateCloudInit()renders the production template.runcmdentry./bin/shwith only external commands stubbed.Post-Mortem
The Caddy scalar command introduced in PR #1308 assumed Bash even though cloud-init executes scalar
runcmdentries through/bin/sh/Dash. Existing tests checked YAML structure and command ordering but never executed the rendered command. The process fix adds both executable interpreter-contract coverage and path-scoped guidance.Specialist Review Evidence
/bin/sh, both roles, and exact side effects coveredUI Compliance
N/A: no UI changes. Core browser journeys were nevertheless validated on exact-head staging before merge.
Agent Preflight (Required)
Classification
External References
N/A: no external API contract changed. Evidence comes from the exact Hetzner failure, the production template, current repository tests, and exact-head staging.
Codebase Impact Analysis
packages/cloud-init/src/template.ts,packages/cloud-init/tests/generate.test.ts,.claude/rules/06-vm-agent-patterns.md, and the active task record.Documentation & Specs
Updated the path-scoped agent rule and active task/post-mortem. No public API, environment variable, schema, or user-visible configuration changed.
Constitution & Risk Check
Principle XI checked.
/bin/sh, POSIXset -eu, and the existing Caddy paths are runtime contract invariants, not configurable business values. Fresh-node bootstrap risk is gated by exact-head staging, real platform-fallback provisioning, rendered Claude/Codex replies, and independent validation.