#!/usr/bin/env bash # Hermetic structural check for the explicit dogfood Compose overlay. set -euo pipefail repo_root=$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd) tmp=$(mktemp -d) trap 'rm -rf "$tmp"' EXIT mkdir -p "$tmp/worktree" "$tmp/common.git" "$tmp/seat/secrets" base_config_json=$( cd "$repo_root" BETTER_AUTH_SECRET=test-only-not-a-credential \ docker compose --profile stack config --format json ) BASE_CONFIG_JSON="$base_config_json" python3 <<'PY' import json import os config = json.loads(os.environ["BASE_CONFIG_JSON"]) gateway = config["services"]["gateway"] env = gateway["environment"] for key in ( "MOSAIC_AGENT_NAME", "MOSAIC_GIT_IDENTITY", "MOSAIC_BRAIN_HOME", "AGENT_FILE_SANDBOX_DIR", "AGENT_USER_TOOLS", "AGENT_SHELL_ENABLED", "AGENT_DELIVERY_ENABLED", "MOSAIC_GIT_TOOLS_DIR", "MOSAIC_INTEGRATION_TRUNK", ): assert key not in env, f"base compose unexpectedly sets dogfood variable {key}" targets = {mount["target"] for mount in gateway["volumes"]} assert "/workspace/stack" not in targets assert not any(target.startswith("/opt/mosaic/brain/") for target in targets) PY config_json=$( cd "$repo_root" BETTER_AUTH_SECRET=test-only-not-a-credential \ MOSAIC_DOGFOOD_WORKTREE="$tmp/worktree" \ MOSAIC_DOGFOOD_COMMON_GIT_DIR="$tmp/common.git" \ MOSAIC_DOGFOOD_SEAT_HOME="$tmp/seat" \ docker compose \ -f docker-compose.yml \ -f docker-compose.dogfood.yml \ --profile stack \ config --format json ) CONFIG_JSON="$config_json" EXPECT_WORKTREE="$tmp/worktree" EXPECT_COMMON_GIT="$tmp/common.git" EXPECT_SEAT="$tmp/seat" python3 <<'PY' import json import os config = json.loads(os.environ["CONFIG_JSON"]) gateway = config["services"]["gateway"] assert gateway.get("init") is True, "gateway must run below an init process for R4 lineage" env = gateway["environment"] expected_env = { "MOSAIC_AGENT_NAME": "stack-dogfood", "MOSAIC_GIT_IDENTITY": "stack-dogfood", "MOSAIC_BRAIN_HOME": "/opt/mosaic/brain", "AGENT_FILE_SANDBOX_DIR": "/workspace/stack", "AGENT_SHELL_ENABLED": "false", "AGENT_DELIVERY_ENABLED": "true", "MOSAIC_GIT_TOOLS_DIR": "/opt/mosaic/tools/git", "MOSAIC_INTEGRATION_TRUNK": "next", } for key, value in expected_env.items(): assert env.get(key) == value, f"{key}: expected {value!r}, got {env.get(key)!r}" allowed = set(env["AGENT_USER_TOOLS"].split(",")) assert allowed == { "fs_read_file", "fs_write_file", "fs_list_directory", "fs_edit_file", "git_status", "git_log", "git_diff", "git_publish_branch", "git_open_pull_request", }, f"unexpected dogfood tool set: {sorted(allowed)}" assert "shell_exec" not in allowed mounts = {mount["target"]: mount for mount in gateway["volumes"]} worktree = mounts["/workspace/stack"] assert worktree["type"] == "bind" assert worktree["source"] == os.environ["EXPECT_WORKTREE"] assert not worktree.get("read_only", False), "dogfood worktree must be writable" common_git = mounts[os.environ["EXPECT_COMMON_GIT"]] assert common_git["type"] == "bind" assert common_git["source"] == os.environ["EXPECT_COMMON_GIT"] assert not common_git.get("read_only", False), "common Git directory must accept branch updates" seat = mounts["/opt/mosaic/brain/fleet/agents/stack-dogfood"] assert seat["type"] == "bind" assert seat["source"] == os.environ["EXPECT_SEAT"] assert seat.get("read_only") is True, "seat credential slot must be read-only" other_seat_mounts = [ target for target in mounts if target.startswith("/opt/mosaic/brain/fleet/agents/") and target != "/opt/mosaic/brain/fleet/agents/stack-dogfood" ] assert other_seat_mounts == [], f"other seat mounts leaked: {other_seat_mounts}" PY # Each required path must fail closed rather than falling back to the current checkout. expect_missing_path() { local missing=$1 output rc set +e case "$missing" in MOSAIC_DOGFOOD_WORKTREE) output=$( cd "$repo_root" env -u MOSAIC_DOGFOOD_WORKTREE \ BETTER_AUTH_SECRET=test-only-not-a-credential \ MOSAIC_DOGFOOD_COMMON_GIT_DIR="$tmp/common.git" \ MOSAIC_DOGFOOD_SEAT_HOME="$tmp/seat" \ docker compose -f docker-compose.yml -f docker-compose.dogfood.yml \ --profile stack config 2>&1 ) rc=$? ;; MOSAIC_DOGFOOD_COMMON_GIT_DIR) output=$( cd "$repo_root" env -u MOSAIC_DOGFOOD_COMMON_GIT_DIR \ BETTER_AUTH_SECRET=test-only-not-a-credential \ MOSAIC_DOGFOOD_WORKTREE="$tmp/worktree" \ MOSAIC_DOGFOOD_SEAT_HOME="$tmp/seat" \ docker compose -f docker-compose.yml -f docker-compose.dogfood.yml \ --profile stack config 2>&1 ) rc=$? ;; MOSAIC_DOGFOOD_SEAT_HOME) output=$( cd "$repo_root" env -u MOSAIC_DOGFOOD_SEAT_HOME \ BETTER_AUTH_SECRET=test-only-not-a-credential \ MOSAIC_DOGFOOD_WORKTREE="$tmp/worktree" \ MOSAIC_DOGFOOD_COMMON_GIT_DIR="$tmp/common.git" \ docker compose -f docker-compose.yml -f docker-compose.dogfood.yml \ --profile stack config 2>&1 ) rc=$? ;; *) echo "FAIL: test requested unknown path variable $missing" >&2 exit 1 ;; esac set -e if [[ $rc -eq 0 ]]; then echo "FAIL: dogfood compose accepted missing $missing" >&2 exit 1 fi if [[ "$output" != *"$missing"* ]]; then echo "FAIL: missing-path failure did not name $missing" >&2 exit 1 fi } expect_missing_path MOSAIC_DOGFOOD_WORKTREE expect_missing_path MOSAIC_DOGFOOD_COMMON_GIT_DIR expect_missing_path MOSAIC_DOGFOOD_SEAT_HOME printf 'dogfood compose verification passed\n'