The validator pattern-matches *TOKEN* as credential-shaped and rejected both contexts, failing every task on the new harnesses. The env var name is fixed by Claude Code, so deliver the thinking budget via the settings.json env map in init.sh instead (jq-merge preserves apiKeyHelper from the minimax/oauth layer). Claude-Session: https://claude.ai/code/session_019tJk7P8tZzJ24PvtgoGhLN
155 lines
6.8 KiB
Bash
Executable File
155 lines
6.8 KiB
Bash
Executable File
#!/bin/bash
|
|
# Agent repo init script — clones reference repos and working repo
|
|
# AR-12 through AR-15, AR-32
|
|
set -euo pipefail
|
|
|
|
echo "=== agent-repo/v1 init.sh ==="
|
|
|
|
# Ensure workspace directories exist
|
|
mkdir -p /workspace/reference
|
|
mkdir -p /workspace/project
|
|
mkdir -p /workspace/.agent-output
|
|
|
|
# Clone reference branches (AR-12, AR-13)
|
|
if [ -n "${REFERENCE_BRANCHES:-}" ] && [ "${REFERENCE_BRANCHES:-}" != "[]" ]; then
|
|
echo "Cloning reference branches..."
|
|
echo "$REFERENCE_BRANCHES" | python3 -u -c "
|
|
import json, sys, subprocess, os
|
|
refs = json.load(sys.stdin)
|
|
print(f'reference_branches loop: {len(refs)} entries')
|
|
for ref in refs:
|
|
name = ref.get('name', '')
|
|
repo_url = ref.get('repo_url', '')
|
|
branch = ref.get('branch', 'main')
|
|
dest = f'/workspace/reference/{name}'
|
|
print(f'Cloning {repo_url} ({branch}) -> {dest}')
|
|
# Full clone (no --depth) so AR-14a-seeded agent branches have visible
|
|
# ancestry when pushed back to the agent-repo. Gitea rejects shallow
|
|
# pushes with shallow-update-not-allowed. Real incident: 2026-05-08
|
|
# probe 7.
|
|
result = subprocess.run(
|
|
['git', 'clone', '--branch', branch,
|
|
'-c', 'core.symlinks=false', repo_url, dest],
|
|
capture_output=True, text=True
|
|
)
|
|
print(f'clone returncode={result.returncode}')
|
|
if result.stdout:
|
|
print(f'clone stdout (last 1KB): {result.stdout[-1000:]}')
|
|
if result.stderr:
|
|
print(f'clone stderr (last 1KB): {result.stderr[-1000:]}')
|
|
if result.returncode != 0:
|
|
print(f'ERROR: Failed to clone {repo_url}', file=sys.stderr)
|
|
sys.exit(1)
|
|
# Strip any symlinks (security: prevent /proc/1/environ exfiltration)
|
|
subprocess.run(['find', dest, '-type', 'l', '-exec', 'rm', '{}', ';'])
|
|
# Make reference read-only
|
|
chmod_r = subprocess.run(['chmod', '-R', 'a-w', dest], capture_output=True, text=True)
|
|
if chmod_r.returncode != 0:
|
|
print(f'WARNING: chmod returned {chmod_r.returncode}: {chmod_r.stderr[:300]}')
|
|
if not os.path.isdir(os.path.join(dest, '.git')):
|
|
print(f'ERROR: clone exit 0 but {dest}/.git missing', file=sys.stderr)
|
|
sys.exit(1)
|
|
print(f'Cloned {name} successfully')
|
|
"
|
|
fi
|
|
|
|
# Clone agent repo working branch (AR-14).
|
|
#
|
|
# AR-14a (2026-05-08): seed fresh task branches from /workspace/reference/main/
|
|
# rather than the agent-repo fork's main, so a stale fork (e.g. periodic
|
|
# "Fork cleanup" PRs that reset main) doesn't poison every fresh task with
|
|
# old project state. Existing AGENT_BRANCH cherry-picks remain unchanged
|
|
# (continuing prior work). Pre-existing operator workaround in
|
|
# memory/gotchas-airouter.md item 27.
|
|
if [ -n "${AGENT_REPO_URL:-}" ] && [ -n "${AGENT_BRANCH:-}" ]; then
|
|
echo "Cloning agent working repo: $AGENT_REPO_URL (branch: $AGENT_BRANCH)"
|
|
if git clone --depth 1 --branch "$AGENT_BRANCH" "$AGENT_REPO_URL" /workspace/project 2>/dev/null; then
|
|
echo "Cloned existing branch $AGENT_BRANCH (continuing prior work)"
|
|
else
|
|
echo "Branch $AGENT_BRANCH does not exist — seeding fresh branch from upstream reference"
|
|
# Full clone (not --depth 1) so we get a working remote for finalize.sh push.
|
|
if git clone "$AGENT_REPO_URL" /workspace/project; then
|
|
cd /workspace/project
|
|
REF_REPO=/workspace/reference/main
|
|
if [ -d "$REF_REPO/.git" ]; then
|
|
# Seed working tree from the upstream reference clone — AR-14a.
|
|
# Reference is read-only (chmod a-w), but git can still read it
|
|
# as a local-path remote for fetch + reset.
|
|
#
|
|
# Use a temporary remote name so we don't collide with 'origin'.
|
|
git remote add upstream-ref "$REF_REPO"
|
|
# Full fetch (no --depth) — the agent's branch will be pushed
|
|
# back to the agent-repo, and gitea rejects shallow pushes
|
|
# with "shallow update not allowed". Even though the
|
|
# reference clone itself may be shallow, fetch as much as
|
|
# the source has so the agent's HEAD has visible ancestry.
|
|
# Real incident: 2026-05-08 probe 7 (shallow update reject).
|
|
git fetch upstream-ref 2>&1 | head -3 || {
|
|
echo "WARNING: failed to fetch from upstream reference; falling back to fork main" >&2
|
|
git remote remove upstream-ref 2>/dev/null
|
|
git checkout -b "$AGENT_BRANCH"
|
|
}
|
|
if git rev-parse upstream-ref/HEAD >/dev/null 2>&1; then
|
|
UPSTREAM_REF="upstream-ref/HEAD"
|
|
elif git rev-parse upstream-ref/main >/dev/null 2>&1; then
|
|
UPSTREAM_REF="upstream-ref/main"
|
|
else
|
|
UPSTREAM_REF=""
|
|
fi
|
|
if [ -n "$UPSTREAM_REF" ]; then
|
|
git checkout -b "$AGENT_BRANCH" "$UPSTREAM_REF"
|
|
git remote remove upstream-ref
|
|
echo "Seeded $AGENT_BRANCH from $REF_REPO ($(git log --oneline -1)) — AR-14a"
|
|
else
|
|
git remote remove upstream-ref 2>/dev/null
|
|
git checkout -b "$AGENT_BRANCH"
|
|
echo "WARNING: upstream-ref had no resolvable HEAD; using fork main (may be stale)" >&2
|
|
fi
|
|
else
|
|
# No reference clone available — fall back to fork main.
|
|
git checkout -b "$AGENT_BRANCH"
|
|
echo "WARNING: $REF_REPO/.git not found; using fork main (may be stale)" >&2
|
|
fi
|
|
else
|
|
echo "ERROR: Failed to clone agent repo $AGENT_REPO_URL" >&2
|
|
exit 1
|
|
fi
|
|
fi
|
|
fi
|
|
|
|
# Clean up results/ from any previous run (AR-15)
|
|
if [ -d /workspace/project/results ]; then
|
|
rm -rf /workspace/project/results
|
|
fi
|
|
mkdir -p /workspace/project/results
|
|
|
|
# Populate .gitignore (AR-32)
|
|
GITIGNORE=/workspace/project/.gitignore
|
|
cat >> "$GITIGNORE" << 'GITIGNORE_EOF'
|
|
# Agent-repo auto-generated gitignore entries
|
|
*.key
|
|
*.pem
|
|
*.p12
|
|
*.pfx
|
|
.env
|
|
*.env
|
|
*.secret
|
|
GITIGNORE_EOF
|
|
|
|
# Handle retry: clone previous attempt branch as read-only reference (AR-16)
|
|
if [ -n "${AGENT_PREVIOUS_BRANCH:-}" ] && [ "${AGENT_RETRY_COUNT:-0}" -gt 0 ]; then
|
|
echo "Cloning previous attempt branch: $AGENT_PREVIOUS_BRANCH"
|
|
git clone --depth 1 --branch "$AGENT_PREVIOUS_BRANCH" \
|
|
-c core.symlinks=false \
|
|
"$AGENT_REPO_URL" /workspace/reference/previous-attempt 2>/dev/null || \
|
|
echo "Warning: Could not clone previous attempt branch (non-fatal)"
|
|
if [ -d /workspace/reference/previous-attempt ]; then
|
|
find /workspace/reference/previous-attempt -type l -exec rm {} \;
|
|
chmod -R a-w /workspace/reference/previous-attempt
|
|
fi
|
|
fi
|
|
|
|
export AGENT_WORKING_DIR="/workspace/project"
|
|
echo "AGENT_WORKING_DIR=$AGENT_WORKING_DIR"
|
|
echo "=== agent-repo/v1 init.sh complete ==="
|