From dd1166e1ed1cab7747693fdbf9fcad98de6bf3ac Mon Sep 17 00:00:00 2001 From: dan-claude-bot Date: Sat, 18 Jul 2026 14:53:24 +0000 Subject: [PATCH] =?UTF-8?q?test(cli):=20template=20suite=20=E2=80=94=20eve?= =?UTF-8?q?ry=20templates/*/=20dir=20proven,=20dynamically=20(#68)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The old tmux check hardcoded blank/claude/codex/grok, so a new template could ship without CI ever reading it. The suite now discovers templates/*/ and, for each: drives the REAL load_template (extracted from bin/box, the same trick box_tier and install.sh's DEST block get) so box.env must parse against the actual allowlist with BOX_IMAGE + BOX_USER present; asserts user-data.yaml exists, declares #cloud-config, and is well-formed YAML (python3+pyyaml, skipped loudly where absent — CI has both); and keeps the #65 tmux contract. Fixtures prove the dies a green parse cannot: an unknown key (no template grows a network) and a missing required key. Staging-specific: both boot demands proven through the parser, docker + rig preinstalled, and a creds-free refusal grep — no tailscale/authkey/ssh in effective cloud-init lines; rig installs those inside the guest. Plus the cmd_new half, grepped the way the expose guard is: the REQUIRE_VM refusal orders after pick_mode, and boot.autostart is stamped only under the T_AUTOSTART guard. Co-Authored-By: Claude Fable 5 --- test/cli.sh | 105 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 100 insertions(+), 5 deletions(-) diff --git a/test/cli.sh b/test/cli.sh index 9c838df..e569549 100644 --- a/test/cli.sh +++ b/test/cli.sh @@ -130,15 +130,110 @@ check "install.sh: still no-ops on an existing install (#66)" 0 "" \ grep -qF 'already installed' "$ROOT/install.sh" # --------------------------------------------------------------------------- -# Templates — #65 tmux. `box tmux` runs `tmux new-session` INSIDE the box, so a -# template that never installs tmux fails with "tmux: command not found". Every -# template must carry it in its cloud-init package list. +# Templates — DYNAMIC over templates/*/ (#68): the loop discovers every +# template directory, so a new template cannot ship without passing these (the +# old hardcoded blank/claude/codex/grok list let exactly that happen). The +# box.env parse is proven against the REAL allowlist: load_template is +# extracted from bin/box and DRIVEN against each template — the same +# source-the-pure-function trick install.sh's DEST block and box_tier get +# below — so an unknown key, a missing BOX_IMAGE/BOX_USER, or a line that is +# not KEY="value" fails HERE, not at mint time on a host. # --------------------------------------------------------------------------- -for t in blank claude codex grok; do +TPLFN="$(mktemp)" +awk '/^load_template\(\) \{/,/^\}/' "$ROOT/bin/box" > "$TPLFN" +check "load_template: extracted from bin/box (guards the awk)" 0 "unknown key" cat "$TPLFN" +check "load_template: the extracted function is valid bash" 0 "" bash -n "$TPLFN" + +# tpl