Files
stack/scripts/verify-dogfood-compose.sh
T
marcieandorch-01 736b0affc1
ci/woodpecker/push/publish Pipeline was successful
compose: add wrapper-first dogfood workspace (#1488)
Co-authored-by: marcie <[email protected]>
2026-08-30 22:29:30 +00:00

177 lines
5.6 KiB
Bash
Executable File

#!/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'