Skip to content

feat(retro): pre-fetch PR context in pre-retro.sh to survive sandbox API failures #3210

Description

@fullsend-ai-retro

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:

  1. Reading PR details (title, body, state, author, labels, changed files)
  2. Reading PR comments and reviews (to categorize agent vs human interactions)
  3. Tracing workflow runs via gh run list and gh run view
  4. Downloading JSONL reasoning traces from workflow artifacts
  5. 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

  1. 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.
  2. 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.
  3. 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.
  4. Measure over 5 retro runs: Zero runs should produce empty analysis due to API access failures.

Generated by retro agent from #3048

Metadata

Metadata

Assignees

No one assigned

    Labels

    duplicateThis issue or pull request already existsready-for-triageRetro-filed issue awaiting triage agent

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    Status
    Done

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions