damocles-daemon/scripts/deploy.sh

80 lines
3.3 KiB
Bash
Executable file

#!/usr/bin/env bash
# Build, deploy, and fix permissions on the damocles-lab state tree.
# Run from the damocles-daemon repo root (or anywhere - resolves paths absolutely).
set -euo pipefail
REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
TARGET=/persist/damocles-lab
STATE="$TARGET/state"
echo "==> checking for running daemon in lab"
if RUNNING=$(~/lab.sh "pgrep -af damocles-daemon" 2>/dev/null); then
echo "ERROR: daemon is running in lab - won't overwrite live binary." >&2
echo "$RUNNING" >&2
echo "Stop it first: ~/lab.sh \"pkill damocles-daemon\"" >&2
exit 1
fi
echo "==> building"
cd "$REPO"
nix develop --command cargo build --bin damocles-daemon --bin damocles-mcp 2>&1 | tail -3
echo "==> deploying binaries to $TARGET"
for bin in damocles-daemon damocles-mcp; do
cp "$REPO/target/debug/$bin" "$TARGET/$bin.new"
chown muede:users "$TARGET/$bin.new"
mv "$TARGET/$bin.new" "$TARGET/$bin"
done
ls -la "$TARGET/damocles-daemon" "$TARGET/damocles-mcp"
echo "==> fixing state tree ownership (muede:users)"
# Anything touched by full-Damocles from the (root-running) damocles container
# ends up root-owned and unwritable by the daemon. Bulk-fix every time we deploy.
chown -R muede:users "$STATE"
# SYSTEM.md ships from the repo and is the harness contract. Replacing on
# every deploy guarantees it matches the binary's actual capabilities (no
# stale references to tools that aren't enabled). Locked root:root 644 so
# the daemon (running as muede) can read but not edit it.
echo "==> shipping SYSTEM.md from repo"
install -m 644 -o root -g root "$REPO/prompts/SYSTEM.md" "$STATE/identity/SYSTEM.md"
echo "==> shipping project settings.json from repo"
mkdir -p "$STATE/identity/.claude"
install -m 644 -o root -g root "$REPO/prompts/shard_project_settings.json" "$STATE/identity/.claude/settings.json"
# Append pending CHANGELOG entries (new tool announcements etc.) to the live
# CHANGELOG.md and then clear the pending file. This guarantees the shard
# only sees announcements AFTER the binary supporting them is deployed.
PENDING="$REPO/prompts/pending_changelog.md"
LIVE="$STATE/CHANGELOG.md"
# Extract everything after the closing --> of the header comment, trim
# whitespace. If there's anything left, we have actual entries to append.
PENDING_BODY=$(awk '/^-->$/{p=1; next} p' "$PENDING" | sed -e 's/^[[:space:]]*$//' | grep -v '^$' || true)
if [ -n "$PENDING_BODY" ]; then
echo "==> appending pending CHANGELOG entries"
{
echo
awk '/^-->$/{p=1; next} p' "$PENDING"
} >> "$LIVE"
chown muede:users "$LIVE"
# reset the pending file to just the header comment
cat > "$PENDING" <<'EOF'
<!--
Pending CHANGELOG entries. Edit this file to queue announcements to the shard
about new capabilities/behavior shipped in the next deploy. The deploy script
appends this content to /persist/damocles-lab/state/CHANGELOG.md and clears
this file. That way CHANGELOG entries can never reference tools that aren't
actually in the deployed binary yet.
Format: same as live CHANGELOG entries - heading + body, ending with a
"Capability addition:" line for the shard to lift into notes.md.
-->
EOF
fi
echo " state tree fixed"
echo "==> done. restart daemon to pick up new binary:"
echo " ~/lab.sh \"cd /workspace && RUST_LOG=info ./damocles-daemon\""