mirror of
https://github.com/msitarzewski/agency-agents.git
synced 2026-10-01 13:55:54 +03:00
fix(convert): refuse symlinked tool output directories
This commit is contained in:
@@ -28,6 +28,9 @@ jobs:
|
||||
- name: Reject colliding agent slugs before conversion
|
||||
run: bash scripts/test-convert-slug-collisions.sh
|
||||
|
||||
- name: Refuse symlinked conversion output directories
|
||||
run: bash scripts/test-convert-symlink-output.sh
|
||||
|
||||
- name: Validate converted outputs (round-trip, strict parse, counts, drift)
|
||||
# Drift is advisory on pull requests (agent PRs always move their own manifest line;
|
||||
# maintainers regenerate at landing) and enforced on pushes to main.
|
||||
|
||||
+5
-2
@@ -692,6 +692,9 @@ clean_tool_output() {
|
||||
# caller can never steer this rm -rf outside $OUT_DIR via "../" or "/".
|
||||
[[ "$1" =~ ^[a-z0-9-]+$ ]] || { echo "ERROR: clean_tool_output: refusing non-slug tool name '$1'" >&2; return 1; }
|
||||
local dir="$OUT_DIR/$1"
|
||||
# The converter writes into this directory after cleaning it. Following a
|
||||
# symlink here could overwrite an unrelated directory's existing agent files.
|
||||
[[ ! -L "$dir" ]] || { error "refusing symlinked output directory: $dir"; return 1; }
|
||||
[[ -d "$dir" ]] || return 0
|
||||
find "$dir" -mindepth 1 -maxdepth 1 ! -name 'README.md' -exec rm -rf {} +
|
||||
}
|
||||
@@ -730,12 +733,12 @@ run_conversions() {
|
||||
local count=0
|
||||
|
||||
if [[ "$tool" == "hermes" ]]; then
|
||||
clean_tool_output "$tool"
|
||||
clean_tool_output "$tool" || return 1
|
||||
python3 "$SCRIPT_DIR/build-hermes-plugin.py" --repo-root "$REPO_ROOT" --out "$OUT_DIR/hermes"
|
||||
return
|
||||
fi
|
||||
|
||||
clean_tool_output "$tool"
|
||||
clean_tool_output "$tool" || return 1
|
||||
|
||||
for dir in "${AGENT_DIRS[@]}"; do
|
||||
local dirpath="$REPO_ROOT/$dir"
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
#!/usr/bin/env bash
|
||||
# Conversion must not follow a tool-output symlink into unrelated files.
|
||||
set -euo pipefail
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
scratch="$(mktemp -d)"
|
||||
trap 'rm -rf "$scratch"' EXIT
|
||||
|
||||
mkdir -p "$scratch/repo/scripts" "$scratch/repo/engineering" \
|
||||
"$scratch/output" "$scratch/private/agents"
|
||||
cp "$SCRIPT_DIR/convert.sh" "$SCRIPT_DIR/lib.sh" "$scratch/repo/scripts/"
|
||||
cat > "$scratch/repo/engineering/example.md" <<'EOF'
|
||||
---
|
||||
name: Example Agent
|
||||
description: Example
|
||||
color: blue
|
||||
---
|
||||
# Example Agent
|
||||
EOF
|
||||
|
||||
printf 'private content\n' > "$scratch/private/agents/example-agent.md"
|
||||
ln -s "$scratch/private" "$scratch/output/gemini-cli"
|
||||
if bash "$scratch/repo/scripts/convert.sh" --tool gemini-cli --out "$scratch/output" > "$scratch/log" 2>&1; then
|
||||
echo 'FAIL: converter accepted a symlinked output directory' >&2
|
||||
exit 1
|
||||
fi
|
||||
grep -q 'refusing symlinked output' "$scratch/log"
|
||||
[[ "$(cat "$scratch/private/agents/example-agent.md")" == 'private content' ]]
|
||||
echo 'PASS: symlinked output refused before unrelated content changed'
|
||||
Reference in New Issue
Block a user