Files
agent-runtime-framework/harnesses/contexts/agent-repo/v1/init.sh
Paul O'Reilly 3087ad7de1 fix(agent-repo): full-history clone for reference + upstream-ref fetch
Probe 7 (2026-05-08) finally surfaced the actual push error:

  ! [remote rejected] HEAD -> task-9dc266b5 (shallow update not allowed)

Cause: REFERENCE_BRANCHES handler clones with --depth 1, AR-14a then
fetches upstream-ref --depth 1. The agent's task branch is a single
commit on top of a single shallow commit — no ancestry visible. Gitea
rejects shallow pushes server-side.

Fix:
- Reference clone drops --depth 1 (full history)
- AR-14a fetch upstream-ref drops --depth 1 (full fetch from local-path)
- Cost: a few extra MB per task on tmpfs/PVC. Acceptable.

This unblocks AR-14a's upstream-seeding for the dogfood pipeline. The
agent's branch now has the full upstream history visible to gitea.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-08 17:09:53 +12:00

144 lines
6.2 KiB
Bash

#!/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}')
# 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. The cost is a few extra MB on a tmpfs/PVC; acceptable.
result = subprocess.run(
['git', 'clone', '--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"
# 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 ==="