Skip to content

feat: add sandbox creation failure tolerance - #1325

Merged
waynesun09 merged 3 commits into
mainfrom
failure-tolerance
May 21, 2026
Merged

feat: add sandbox creation failure tolerance#1325
waynesun09 merged 3 commits into
mainfrom
failure-tolerance

Conversation

@waynesun09

@waynesun09 waynesun09 commented May 21, 2026

Copy link
Copy Markdown
Member

Summary

  • Pre-pull sandbox image in action.yml before fullsend run — moves image pull time out of the sandbox ready timeout window
  • Add CreateWithRetry with exponential backoff (3 attempts, 5-15s delay) and cleanup between attempts — a single transient failure no longer kills the run
  • Increase default readyTimeout from 60s to 120s — gives cold image pulls more headroom
  • Add sandbox_timeout_seconds harness config field — per-agent tuning without env vars
  • Add FULLSEND_SANDBOX_READY_TIMEOUT env var override — operator tuning without code changes

Fixes #1298

Test plan

  • effectiveReadyTimeout unit tests: default, override, env var, precedence, invalid/negative env, capped at max
  • CreateWithRetry error path tests (openshell not in PATH, zero/negative maxAttempts)
  • SandboxTimeoutSeconds harness validation tests: negative rejected, >600 rejected, zero/positive/600 accepted
  • SandboxTimeoutSeconds YAML load round-trip test
  • make go-test passes
  • make go-vet passes
  • make lint passes
  • Re-run agentshed/seshi PR Review arxiv.org/abs/2602.20021 for security threat model insights #51 failed job to verify fix in CI

Sandbox creation can fail due to transient infrastructure issues like
slow image pulls exceeding the ready timeout. Add multi-layer failure
tolerance to prevent single transient failures from killing agent runs.

- Pre-pull sandbox image in action.yml before fullsend run
- Add CreateWithRetry with exponential backoff (3 attempts, 5-15s)
- Increase default readyTimeout from 60s to 120s
- Add sandbox_timeout_seconds harness config field
- Add FULLSEND_SANDBOX_READY_TIMEOUT env var override

Signed-off-by: Wayne Sun <gsun@redhat.com>
@github-actions

github-actions Bot commented May 21, 2026

Copy link
Copy Markdown

Site preview

Preview: https://fd4047ae-site.fullsend-ai.workers.dev

Commit: 2a36937bc38b68240621631316e0458934026c74

@fullsend-ai-review

fullsend-ai-review Bot commented May 21, 2026

Copy link
Copy Markdown

Review

Findings

Low

  • [docs-staleness] docs/ADRs/0024-harness-definitions.md — The harness YAML schema reference does not document the new sandbox_timeout_seconds field or the FULLSEND_SANDBOX_READY_TIMEOUT environment variable. The existing timeout_minutes entry (line 402) would benefit from a sibling entry explaining the sandbox-specific timeout and its relationship to the overall harness timeout.
    Remediation: Add sandbox_timeout_seconds to the schema reference in ADR 0024 with a note explaining the precedence chain (harness config > env var > 120s default) and the valid range (30–600).
Previous run

Review

Findings

Low

  • [correctness] internal/sandbox/sandbox.go:162 — The backward-compatible Create() wrapper now silently retries 3 times via CreateWithRetry, changing observable behavior (longer wall-clock time on failure, sandbox deletion side effects between attempts) for any future caller who expects single-attempt semantics. The only current caller (run.go) was already migrated to CreateWithRetry, so this has no immediate impact.
    Remediation: Update the Create() godoc to explicitly note that it retries up to DefaultMaxCreateAttempts times with exponential backoff.

Info

  • [correctness] internal/harness/harness.go:252sandbox_timeout_seconds validation accepts values as low as 1, which would be too short for any practical sandbox creation. Consider adding a minimum (e.g., 30s) to prevent misconfiguration, or document that very low values will almost certainly cause retries and eventual failure.
Previous run (2)

Review

Findings

Low

  • [documentation-currency] docs/ADRs/0024-harness-definitions.md — ADR 0024 documents the harness YAML schema but does not include the new sandbox_timeout_seconds field. The customizing-agents guide (docs/guides/user/customizing-agents.md) shows timeout_minutes customization examples but does not mention sandbox_timeout_seconds. The new FULLSEND_SANDBOX_READY_TIMEOUT env var is also undocumented. Consider adding these to the harness schema reference and operator guide so users can discover the tuning knobs.
    Remediation: Add sandbox_timeout_seconds to the harness schema in ADR 0024 (after timeout_minutes) and document FULLSEND_SANDBOX_READY_TIMEOUT in the operator/user guide.

  • [style] internal/harness/harness.go:206 — The new SandboxTimeoutSeconds field introduces column-aligned struct tags, which changes whitespace on the existing TimeoutMinutes and Security lines. The rest of the struct does not use column alignment. This is cosmetic but creates unnecessary diff noise.
    Remediation: Use single-space separation between field type and tag, consistent with the rest of the struct.

Comment thread internal/harness/harness.go Outdated
RunnerEnv map[string]string `yaml:"runner_env,omitempty"`
TimeoutMinutes int `yaml:"timeout_minutes,omitempty"`
Security *SecurityConfig `yaml:"security,omitempty"`
TimeoutMinutes int `yaml:"timeout_minutes,omitempty"`

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[low] style

The new SandboxTimeoutSeconds field introduces column-aligned struct tags, changing whitespace on existing TimeoutMinutes and Security lines. The rest of the struct uses single-space separation.

Suggested fix: Use single-space separation between field type and tag, consistent with the rest of the struct.

@fullsend-ai-review fullsend-ai-review Bot added the ready-for-merge All reviewers approved — ready to merge label May 21, 2026
- Guard maxAttempts < 1 in CreateWithRetry (returns error instead of nil)
- Cap effectiveReadyTimeout at 600s to prevent extreme values
- Add upper bound (600) on sandbox_timeout_seconds harness validation
- Use exec.CommandContext for readiness poll to respect timeout context
- Add timeout 300s and -- separator to podman pull in action.yml
- Wrap final error with attempt count for better diagnostics
- Include error reason in retry stderr message
- Log Delete failures between retries instead of silencing
- Use exported DefaultMaxCreateAttempts constant in run.go
- Replace magic 10s context buffer with named readyCtxBuffer constant
- Remove unused createTimeout constant
- Cap backoff shift at 30 to prevent overflow

Signed-off-by: Wayne Sun <gsun@redhat.com>
// env var > package default.
func effectiveReadyTimeout(override time.Duration) time.Duration {
t := readyTimeout
if override > 0 {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[low] correctness

The backward-compatible Create() wrapper now silently retries 3 times via CreateWithRetry, changing observable behavior (longer wall-clock time on failure, sandbox deletion side effects between attempts) for any future caller who expects single-attempt semantics.

Suggested fix: Update the Create() godoc to explicitly note that it retries up to DefaultMaxCreateAttempts times with exponential backoff.

Comment thread internal/harness/harness.go Outdated
if h.TimeoutMinutes < 0 {
return fmt.Errorf("timeout_minutes must be non-negative, got %d", h.TimeoutMinutes)
}
if h.SandboxTimeoutSeconds < 0 || h.SandboxTimeoutSeconds > 600 {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[info] correctness

sandbox_timeout_seconds validation accepts values as low as 1, which would be too short for any practical sandbox creation. Consider adding a minimum (e.g., 30s) or documenting that very low values will cause retries and eventual failure.

@fullsend-ai-review fullsend-ai-review Bot added ready-for-merge All reviewers approved — ready to merge and removed ready-for-merge All reviewers approved — ready to merge labels May 21, 2026
- Enforce minimum sandbox_timeout_seconds of 30 (values 1-29 are too
  short for any practical sandbox creation)
- Fix struct tag alignment to use consistent single-space separation
- Update Create() godoc to document retry and cleanup behavior

Signed-off-by: Wayne Sun <gsun@redhat.com>
@fullsend-ai-review fullsend-ai-review Bot added ready-for-merge All reviewers approved — ready to merge and removed ready-for-merge All reviewers approved — ready to merge labels May 21, 2026
@waynesun09
waynesun09 added this pull request to the merge queue May 21, 2026
Merged via the queue into main with commit 0403621 May 21, 2026
9 of 10 checks passed
@waynesun09
waynesun09 deleted the failure-tolerance branch May 21, 2026 19:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready-for-merge All reviewers approved — ready to merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Review agent sandbox timeout: container not ready after 60s

1 participant