What happened
The retro agent ran against PR #3048 but could not access the GitHub API from inside the sandbox. gh auth status reported the GH_TOKEN as invalid, and gh pr view 3048 returned HTTP 403.
The retro agent's entire workflow depends on runtime GitHub API access:
- Reading PR details (title, body, state, author, labels, changed files)
- Reading PR comments and reviews (to categorize agent vs human interactions)
- Tracing workflow runs via
gh run list and gh run view
- Downloading JSONL reasoning traces from workflow artifacts
- Searching for existing issues to avoid filing duplicates
With the token invalid, none of these were possible. The agent could only analyze the local codebase (harness configs, agent definitions, policies, scripts) — useful for meta-analysis but insufficient for retrospective analysis of a specific PR workflow.
The pre-retro.sh script (internal/scaffold/fullsend-repo/scripts/pre-retro.sh) runs on the host where GitHub API access is reliable, but it only validates the ORIGINATING_URL format. It pre-fetches zero data. This is by design per the retro agent design spec, which states: "The pre-script does not attempt to gather logs, traces, or workflow history. That is the agent's job."
What could go better
Confidence: High. The failure mode is clear and reproducible — when the sandbox GH_TOKEN is invalid or expired, the retro agent is completely blocked. The pattern for fixing this already exists in the codebase: pre-fetch-prior-review.sh pre-fetches review data on the host and passes it as a file to the sandbox.
Token expiry risk: GitHub App installation tokens expire after 1 hour. The mintAgentToken() function in run.go mints a fresh token right before sandbox creation, but between minting and the agent actually using the token, there is image pull time, OpenShell setup, sandbox bootstrap, and agent startup. If any of these steps are slow (e.g., cold image pull), the token's remaining lifetime shrinks. Combined with the 30-minute agent timeout, there is a realistic window for token expiry on long-running retro runs.
What I'm less certain about: Whether this specific failure was caused by token expiry, a minting error, or a transient infrastructure issue. I could not differentiate because the sandbox had no way to reach GitHub to get more diagnostic information. The proxy returned 403 for curl (correctly, per the L7 policy which only allows gh and node), and gh reported the token as invalid rather than providing a more specific error.
Impact: Every retro agent run that encounters this failure mode produces zero useful analysis. The 30-minute timeout is consumed, tokens are spent, and no proposals are generated. On automatic PR-close triggers, this means the feedback loop is silently broken.
Proposed change
Add a data pre-fetching step to pre-retro.sh (internal/scaffold/fullsend-repo/scripts/pre-retro.sh) that runs on the host before sandbox creation, and deliver the pre-fetched data into the sandbox via host_files in the harness config.
1. Extend pre-retro.sh to pre-fetch PR/issue context:
After the existing URL validation, add steps to fetch and write:
- PR details:
gh pr view <number> --repo <repo> --json title,body,state,author,labels,comments,reviews,changedFiles,commits,mergedAt,closedAt,baseRefName,headRefName
- Recent workflow runs:
gh run list --repo <repo> --workflow=fullsend.yaml --limit 20 --json databaseId,status,conclusion,event,createdAt,headBranch
- Dispatch repo workflow runs (triage, code, review, fix, retro):
gh run list --repo <org>/.fullsend --workflow=<stage>.yml --limit 10 --json databaseId,status,conclusion,createdAt
Write each result as a JSON file under a retro-context/ directory (e.g., retro-context/pr-details.json, retro-context/workflow-runs.json, retro-context/dispatch-runs.json).
Use the existing token available on the host (GH_TOKEN) which is reliable since the pre-script runs before the sandbox is created.
2. Add host_files entries in harness/retro.yaml:
host_files:
- src: retro-context/
dest: /sandbox/workspace/retro-context/
3. Update the retro agent definition and skill to check for pre-fetched data at /sandbox/workspace/retro-context/ before attempting live API calls. The agent should prefer pre-fetched data as the baseline and use live API calls only for follow-up exploration (e.g., downloading JSONL traces, searching for duplicate issues).
This follows the established pattern from pre-fetch-prior-review.sh and pre-fetch-prior-review-test.sh.
Validation criteria
- Resilience test: Run the retro agent with GH_TOKEN deliberately unset inside the sandbox (but valid on the host for pre-fetch). The agent should still produce a meaningful analysis of the PR using pre-fetched data. Success = non-empty
what_happened sections in proposals.
- Normal operation: Run the retro agent with valid GH_TOKEN in the sandbox. The agent should use pre-fetched data as baseline and augment with live API calls (e.g., for JSONL traces). Verify pre-fetched files exist in the sandbox at the expected path.
- Pre-script test: Add a test script (following the
pre-code-test.sh / pre-fetch-prior-review-test.sh pattern) that validates pre-retro.sh produces the expected output files with mock gh responses.
- Measure over 5 retro runs: Zero runs should produce empty analysis due to API access failures.
Generated by retro agent from #3048
What happened
The retro agent ran against PR #3048 but could not access the GitHub API from inside the sandbox.
gh auth statusreported the GH_TOKEN as invalid, andgh pr view 3048returned HTTP 403.The retro agent's entire workflow depends on runtime GitHub API access:
gh run listandgh run viewWith the token invalid, none of these were possible. The agent could only analyze the local codebase (harness configs, agent definitions, policies, scripts) — useful for meta-analysis but insufficient for retrospective analysis of a specific PR workflow.
The
pre-retro.shscript (internal/scaffold/fullsend-repo/scripts/pre-retro.sh) runs on the host where GitHub API access is reliable, but it only validates theORIGINATING_URLformat. It pre-fetches zero data. This is by design per the retro agent design spec, which states: "The pre-script does not attempt to gather logs, traces, or workflow history. That is the agent's job."What could go better
Confidence: High. The failure mode is clear and reproducible — when the sandbox GH_TOKEN is invalid or expired, the retro agent is completely blocked. The pattern for fixing this already exists in the codebase:
pre-fetch-prior-review.shpre-fetches review data on the host and passes it as a file to the sandbox.Token expiry risk: GitHub App installation tokens expire after 1 hour. The
mintAgentToken()function inrun.gomints a fresh token right before sandbox creation, but between minting and the agent actually using the token, there is image pull time, OpenShell setup, sandbox bootstrap, and agent startup. If any of these steps are slow (e.g., cold image pull), the token's remaining lifetime shrinks. Combined with the 30-minute agent timeout, there is a realistic window for token expiry on long-running retro runs.What I'm less certain about: Whether this specific failure was caused by token expiry, a minting error, or a transient infrastructure issue. I could not differentiate because the sandbox had no way to reach GitHub to get more diagnostic information. The proxy returned 403 for
curl(correctly, per the L7 policy which only allowsghandnode), andghreported the token as invalid rather than providing a more specific error.Impact: Every retro agent run that encounters this failure mode produces zero useful analysis. The 30-minute timeout is consumed, tokens are spent, and no proposals are generated. On automatic PR-close triggers, this means the feedback loop is silently broken.
Proposed change
Add a data pre-fetching step to
pre-retro.sh(internal/scaffold/fullsend-repo/scripts/pre-retro.sh) that runs on the host before sandbox creation, and deliver the pre-fetched data into the sandbox viahost_filesin the harness config.1. Extend
pre-retro.shto pre-fetch PR/issue context:After the existing URL validation, add steps to fetch and write:
gh pr view <number> --repo <repo> --json title,body,state,author,labels,comments,reviews,changedFiles,commits,mergedAt,closedAt,baseRefName,headRefNamegh run list --repo <repo> --workflow=fullsend.yaml --limit 20 --json databaseId,status,conclusion,event,createdAt,headBranchgh run list --repo <org>/.fullsend --workflow=<stage>.yml --limit 10 --json databaseId,status,conclusion,createdAtWrite each result as a JSON file under a
retro-context/directory (e.g.,retro-context/pr-details.json,retro-context/workflow-runs.json,retro-context/dispatch-runs.json).Use the existing token available on the host (
GH_TOKEN) which is reliable since the pre-script runs before the sandbox is created.2. Add
host_filesentries inharness/retro.yaml:3. Update the retro agent definition and skill to check for pre-fetched data at
/sandbox/workspace/retro-context/before attempting live API calls. The agent should prefer pre-fetched data as the baseline and use live API calls only for follow-up exploration (e.g., downloading JSONL traces, searching for duplicate issues).This follows the established pattern from
pre-fetch-prior-review.shandpre-fetch-prior-review-test.sh.Validation criteria
what_happenedsections in proposals.pre-code-test.sh/pre-fetch-prior-review-test.shpattern) that validates pre-retro.sh produces the expected output files with mockghresponses.Generated by retro agent from #3048