From f4d6730c97a7035a17b3eadcf3a6cb74bf12bb9d Mon Sep 17 00:00:00 2001 From: Sam & Claude Date: Sat, 20 Jun 2026 22:39:34 +0200 Subject: [PATCH] chore(jails): CI guard for agent-jail package drift vs clawdie-iso Closes the gap left after #70/PR #81: the agent-jail package set is hand-synced across two repos (this bootstrap's PKGS= and clawdie-iso pkg-list-jails.txt "# agent-jail" section) with nothing catching future drift. - check-agent-jail-pkgs.sh: pure POSIX sh; extracts PKGS= here, fetches the clawdie-iso list over HTTP (ISO_PKG_LIST_URL overridable), diffs the two sets, reports the delta, exits non-zero on mismatch. - ci.yml: new `agent-jail-pkgs` job runs it on every push/PR. Same shape as the CARGO_CRATES drift check. Verified: green in sync (5 pkgs); negative test flags missing packages and exits 1; ci.yml valid YAML. Single-sided (fires on colibri CI); the clawdie-iso list is fetched from main. Co-Authored-By: Claude Opus 4.8 --- .forgejo/workflows/ci.yml | 8 ++++ packaging/freebsd/check-agent-jail-pkgs.sh | 49 ++++++++++++++++++++++ 2 files changed, 57 insertions(+) create mode 100755 packaging/freebsd/check-agent-jail-pkgs.sh diff --git a/.forgejo/workflows/ci.yml b/.forgejo/workflows/ci.yml index 3109287..e85a009 100644 --- a/.forgejo/workflows/ci.yml +++ b/.forgejo/workflows/ci.yml @@ -47,3 +47,11 @@ jobs: - uses: actions/checkout@v4 - name: FreeBSD port CARGO_CRATES in sync with Cargo.lock run: ./packaging/freebsd/port/check-cargo-crates.sh + + agent-jail-pkgs: + runs-on: ubuntu-latest + container: python:3.12 + steps: + - uses: actions/checkout@v4 + - name: agent-jail package set in sync with clawdie-iso + run: sh packaging/freebsd/check-agent-jail-pkgs.sh diff --git a/packaging/freebsd/check-agent-jail-pkgs.sh b/packaging/freebsd/check-agent-jail-pkgs.sh new file mode 100755 index 0000000..53bc777 --- /dev/null +++ b/packaging/freebsd/check-agent-jail-pkgs.sh @@ -0,0 +1,49 @@ +#!/bin/sh +# Run as: sh check-agent-jail-pkgs.sh (or ./check-agent-jail-pkgs.sh) +# +# Cross-repo drift guard for the agent-jail package set. It must match between: +# - this repo's agent-jail-bootstrap.sh (the PKGS= line, the runtime truth) +# - clawdie-iso's pkg-list-jails.txt (the "# agent-jail" section) +# Run after changing either set (and in CI). Override the fetched list with +# ISO_PKG_LIST_URL to compare against a different ref. +# +# Exit: 0 = in sync, 1 = drift (prints the delta), 2 = fetch / IO error. + +set -u + +HERE=$(cd "$(dirname "$0")" && pwd) +BOOTSTRAP="${HERE}/agent-jail-bootstrap.sh" +ISO_PKG_LIST_URL="${ISO_PKG_LIST_URL:-https://code.smilepowered.org/clawdie/clawdie-iso/raw/branch/main/packages/pkg-list-jails.txt}" + +[ -f "$BOOTSTRAP" ] || { echo "ERROR: bootstrap not found: $BOOTSTRAP" >&2; exit 2; } +command -v curl >/dev/null 2>&1 || { echo "ERROR: curl required" >&2; exit 2; } + +_tmp=$(mktemp -d) +trap 'rm -rf "$_tmp"' EXIT + +# Bootstrap set: the PKGS="..." assignment, one package per line, sorted/unique. +grep -E '^PKGS=' "$BOOTSTRAP" | head -1 | sed -E 's/^PKGS=//; s/"//g' \ + | tr ' ' '\n' | sed '/^$/d' | sort -u > "$_tmp/bootstrap" +[ -s "$_tmp/bootstrap" ] || { echo "ERROR: no PKGS= line in $BOOTSTRAP" >&2; exit 2; } + +# clawdie-iso set: the "# agent-jail" section of pkg-list-jails.txt, up to the +# next blank line or next "#" header, sorted/unique. +if ! curl -fsS "$ISO_PKG_LIST_URL" > "$_tmp/jl" 2>"$_tmp/err"; then + echo "ERROR: failed to fetch ${ISO_PKG_LIST_URL}" >&2; cat "$_tmp/err" >&2; exit 2 +fi +awk '/^# agent-jail/{f=1;next} f&&/^#/{exit} f&&/^[[:space:]]*$/{exit} f{print}' "$_tmp/jl" \ + | sed 's/[[:space:]]//g' | sed '/^$/d' | sort -u > "$_tmp/iso" +[ -s "$_tmp/iso" ] || { echo "ERROR: no '# agent-jail' section in fetched pkg-list-jails.txt" >&2; exit 2; } + +missing=$(comm -23 "$_tmp/bootstrap" "$_tmp/iso") # in bootstrap, absent from the iso list +extra=$(comm -13 "$_tmp/bootstrap" "$_tmp/iso") # in the iso list, absent from the bootstrap + +if [ -z "$missing" ] && [ -z "$extra" ]; then + echo "OK: agent-jail package set in sync ($(wc -l < "$_tmp/bootstrap" | tr -d ' ') packages)." + exit 0 +fi + +[ -n "$missing" ] && { echo "In bootstrap PKGS, absent from clawdie-iso pkg-list-jails.txt # agent-jail:"; echo "$missing" | sed 's/^/ + /'; } +[ -n "$extra" ] && { echo "In clawdie-iso # agent-jail, absent from bootstrap PKGS:"; echo "$extra" | sed 's/^/ - /'; } +echo "Fix: align agent-jail-bootstrap.sh PKGS= with the clawdie-iso pkg-list-jails.txt # agent-jail section." +exit 1 -- 2.45.3