#!/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 -c " import json, sys, subprocess, os refs = json.load(sys.stdin) 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}') result = subprocess.run( ['git', 'clone', '--depth', '1', '--branch', branch, '-c', 'core.symlinks=false', repo_url, dest], capture_output=True, text=True ) if result.returncode != 0: print(f'ERROR: Failed to clone {repo_url}: {result.stderr}', 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 subprocess.run(['chmod', '-R', 'a-w', dest]) 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" git fetch upstream-ref --depth 1 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 ==="