Skip to content

fix(onboard): constrain smoke retry boundary - #5934

Merged
cv merged 9 commits into
mainfrom
codex/harden-smoke-retry-boundary
Jun 28, 2026
Merged

cv merged 9 commits into
mainfrom
codex/harden-smoke-retry-boundary

Conversation

@cv

@cv cv commented Jun 28, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

Tightens the compatible-endpoint smoke retry merged in #5932 so only explicit transient transport and HTTP signals retry. It also removes curl stderr/body dependence, derives exponential-backoff timeout coverage, and adds behavioral tests for transient and permanent curl exits.

Changes

  • Capture HTTP status directly from curl instead of inferring it from HTML response bodies.
  • Suppress curl stderr and retry only transient exits 6, 7, 28, 52, 55, and 56.
  • Keep permanent curl and JSON validation failures single-shot and strict.
  • Align retry delay with the existing Vitest 5s/10s backoff and derive the 225-second parent timeout from the shared budget.
  • Centralize the generated retry policy and triangular timeout budget in a focused classifier module.
  • Add behavioral coverage for transient curl exits 6, 7, 28, 52, 55, and 56; permanent curl and HTTP 429 failures; hostile model quoting; and 5s/10s backoff.

Type of Change

  • Code change (feature, bug fix, or refactor)
  • Code change with doc updates
  • Doc only (prose changes, no code sample modifications)
  • Doc only (includes code sample changes)

Quality Gates

  • Tests added or updated for changed behavior
  • Existing tests cover changed behavior — justification:
  • Tests not applicable — justification:
  • Docs updated for user-facing behavior changes
  • Docs not applicable — justification: internal validation retry classification and diagnostics only; no user-facing configuration changes.
  • Sensitive paths changed (security, policy, credentials, preflight, onboarding, inference, runner, sandbox, or messaging)
  • Sensitive-path review completed or maintainer-approved waiver recorded — reviewer/approval link/justification: arbitrary curl stderr and upstream response bodies are suppressed; diagnostics retain only exit code, HTTP status, and response length, and all permanent validation failures remain strict.
  • Non-success, skipped, or missing CI check accepted by maintainer — check name, approval link, and follow-up issue:

Verification

  • PR description includes the DCO sign-off declaration and every commit appears as Verified in GitHub
  • Git hooks passed during commit and push, or npx prek run --from-ref main --to-ref HEAD passes
  • Targeted tests pass for changed behavior
  • Full npm test passes (broad runtime changes only)
  • Quality Gates section completed with required justifications or waivers
  • No secrets, API keys, or credentials committed
  • npm run docs builds without warnings (doc changes only)
  • Doc pages follow the style guide (doc changes only)
  • New doc pages include SPDX header and frontmatter (new pages only)

Targeted verification:

Post-merge review findings addressed from #5932:

  • Curl-exit retry acceptance coverage: transient exits 6, 7, 28, 52, 55, and 56 recover on attempt two; permanent exit 2 makes exactly one request.
  • Curl stderr security: stderr is suppressed at the external boundary and only the numeric exit is reported.
  • Retry classification: only explicit transient transport codes, HTTP 5xx, and reasoning-budget exhaustion retry; HTTP 429 remains single-shot.
  • HTTP classification: status comes from curl metadata rather than fragile HTML matching.
  • Retry timing: 5s/10s backoff and its 225-second parent budget are derived from shared constants.

Signed-off-by: Carlos Villela cvillela@nvidia.com

Summary by CodeRabbit

  • Bug Fixes

    • Improved compatible-endpoint smoke verification with more deterministic HTTP-status handling to classify retries vs terminal failures, including clearer retry timing and faster exits for non-retryable outcomes.
  • Tests

    • Expanded smoke-test coverage for retry behavior:
      • Transient HTTP 5xx responses now retry and succeed.
      • HTTP 429 responses no longer retry.
      • Added scenarios for multiple transient curl exit codes (retries succeed) and terminal exit codes (fails immediately).

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@cv cv self-assigned this Jun 28, 2026
@coderabbitai

coderabbitai Bot commented Jun 28, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The compatible-endpoint smoke verification now records HTTP status separately, changes retry classification and loop control, adjusts timeout budgeting, and adds test coverage for transient and permanent curl exits.

Changes

Smoke script curl retry and status-file overhaul

Layer / File(s) Summary
Shared smoke-test helpers
src/lib/onboard/__test-helpers__/compatible-endpoint-smoke-helpers.ts
Adds helper functions for writing the smoke config, generating a fake curl executable, and running the smoke script with the test PATH setup.
Generated script: status_file, curl command, and check_response
src/lib/onboard/compatible-endpoint-smoke.ts
Adds status_file creation and trap cleanup; rewrites curl to write HTTP status to status_file and body to response_file; rewrites check_response to classify retryability by HTTP status codes.
Retry loop control flow
src/lib/onboard/compatible-endpoint-smoke.ts
Captures run_smoke_request exit status directly, limits retries to specific exit codes, changes retry delay to scale by attempt number, suppresses retry logging for status 2, and adds retry-boundary guidance in the script comment.
Test harness and retry cases
src/lib/onboard/compatible-endpoint-smoke.test.ts
Moves the smoke harness helpers into a shared module, updates the timeout assertion to 225_000, and adds retry coverage for JSON status signaling plus transient and permanent curl exit codes.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • NVIDIA/NemoClaw#5932: Directly related — also updates the compatible-endpoint smoke retry and check_response behavior and expands compatible-endpoint-smoke.test.ts retry coverage.

Suggested labels

refactor

Suggested reviewers

  • cjagwani
  • jyaunches
  • ericksoa
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 20.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly matches the main change: tightening when onboard smoke retries are allowed.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/harden-smoke-retry-boundary

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/lib/onboard/compatible-endpoint-smoke.test.ts`:
- Around line 63-89: The fake curl wrapper in compatible-endpoint-smoke.test.ts
is masking the real response code by printing 200/504 whenever -o is used.
Update the harness around the curl argument parsing and bodyForCall execution so
it detects and honors -w '%{http_code}' explicitly, only emitting the HTTP
status when that format flag is requested and otherwise preserving the existing
body/output behavior. Use the curl shim logic in this test file to keep the
status-file path behavior covered without tying the test to implementation
details.
- Around line 234-280: The retry coverage in compatible-endpoint-smoke.test.ts
only exercises part of the curl transient allowlist, so expand the existing
retry test around buildCompatibleEndpointSandboxSmokeScript/runSmokeScript to
include exits 52, 55, and 56 as additional transient cases. Keep the assertions
focused on behavior (successful retry, retry log, and call count) rather than
implementation details, and use the existing it.each pattern so the test
continues to validate the production retry table consistently.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 66ffac2e-6851-47db-8883-99646a05be24

📥 Commits

Reviewing files that changed from the base of the PR and between 6d81392 and fb230c9.

📒 Files selected for processing (2)
  • src/lib/onboard/compatible-endpoint-smoke.test.ts
  • src/lib/onboard/compatible-endpoint-smoke.ts

@github-code-quality

github-code-quality Bot commented Jun 28, 2026 •

Copy link
Copy Markdown
Contributor

Code Coverage Overview

Languages: TypeScript

TypeScript / code-coverage/plugin

The overall coverage in the codex/harden-smoke-r... branch is 96%. Coverage data for the main branch is not yet available.

Show a code coverage summary of the most covered files.
File main codex/harden-smoke-r... 759fd86 +/-
nemoclaw/src/se...cret-scanner.ts — 100% —
nemoclaw/src/commands/slash.ts — 100% —
nemoclaw/src/li...bprocess-env.ts — 100% —
nemoclaw/src/bl...eprint/state.ts — 98% —
nemoclaw/src/onboard/config.ts — 98% —
nemoclaw/src/bl...int/snapshot.ts — 97% —
nemoclaw/src/bl...print/runner.ts — 95% —
nemoclaw/src/co...ration-state.ts — 94% —
nemoclaw/src/bl...ate-networks.ts — 94% —
nemoclaw/src/index.ts — 94% —

TypeScript / code-coverage/cli

The overall coverage in the codex/harden-smoke-r... branch is 68%. Coverage data for the main branch is not yet available.

Show a code coverage summary of the most covered files.
File main codex/harden-smoke-r... 759fd86 +/-
src/lib/actions...all/run-plan.ts — 80% —
src/lib/state/o...oard-session.ts — 79% —
src/lib/actions...dbox/rebuild.ts — 74% —
src/lib/state/sandbox.ts — 72% —
src/lib/shields/index.ts — 70% —
src/lib/onboard/preflight.ts — 69% —
src/lib/actions...licy-channel.ts — 59% —
src/lib/onboard...er-gpu-patch.ts — 59% —
src/lib/policy/index.ts — 52% —
src/lib/onboard.ts — 20% —

Updated June 28, 2026 16:53 UTC
Code Coverage is in Public Preview. Learn more and provide us with your feedback.

@github-actions

github-actions Bot commented Jun 28, 2026 •

Copy link
Copy Markdown
Contributor

E2E Advisor Recommendation

Required E2E: messaging-compatible-endpoint-vitest
Optional E2E: cloud-onboard-vitest

Dispatch hint: messaging-compatible-endpoint-vitest

Workflow run

Full advisor summary

E2E Recommendation Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required E2E

  • messaging-compatible-endpoint-vitest (medium): Directly covers the changed boundary: custom OpenAI-compatible endpoint plus Telegram messaging onboard, compatible endpoint sandbox smoke, managed inference.local config, sandbox chat completion, and an OpenClaw agent turn through the compatible endpoint proxy path.

Optional E2E

  • cloud-onboard-vitest (high): Optional broader hosted-onboarding confidence for inference.local and sandbox health, but the changed compatible-endpoint messaging smoke path is better covered by messaging-compatible-endpoint-vitest.

New E2E recommendations

  • compatible-endpoint-smoke-retry (medium): Existing live coverage validates the happy compatible-endpoint messaging route, but does not force transient HTTP 5xx/curl failures or verify bounded retry/backoff behavior at the real OpenShell sandbox boundary.
    • Suggested test: Add a live messaging-compatible-endpoint retry scenario whose local compatible endpoint mock fails the first request with HTTP 500 or a transient connection failure, then succeeds, and assert onboarding completes with sanitized retry diagnostics.

Dispatch hint

  • Workflow: .github/workflows/e2e-vitest-scenarios.yaml
  • jobs input: messaging-compatible-endpoint-vitest

@github-actions

github-actions Bot commented Jun 28, 2026 •

Copy link
Copy Markdown
Contributor

Vitest E2E Scenario Recommendation

Required Vitest E2E scenarios: messaging-compatible-endpoint-vitest
Optional Vitest E2E scenarios: onboard-resume-vitest

Dispatch required Vitest E2E scenarios:

  • gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=messaging-compatible-endpoint-vitest

Workflow run

Full Vitest E2E advisor summary

Vitest E2E Scenario Advisor

Base: origin/main
Head: HEAD
Confidence: high

Required Vitest E2E scenarios

  • messaging-compatible-endpoint-vitest: The PR changes compatible-endpoint onboarding sandbox smoke execution, retry classification, HTTP status handling, and backoff behavior. The discrete Vitest job messaging-compatible-endpoint-vitest directly onboards with a compatible endpoint plus Telegram messaging and asserts that the compatible endpoint sandbox smoke check runs through inference.local.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=messaging-compatible-endpoint-vitest

Optional Vitest E2E scenarios

  • onboard-resume-vitest: Optional adjacent coverage: onboard-resume also uses a fake OpenAI-compatible endpoint and exercises persisted onboarding/resume behavior, but this PR does not modify the onboarding state machine, resume compatibility states, session bootstrap, or repair policy, so the resume compatibility rule is not triggered.
    • Dispatch: gh workflow run e2e-vitest-scenarios.yaml --ref <pr-head-ref> --field jobs=onboard-resume-vitest

Relevant changed files

  • src/lib/onboard/__test-helpers__/compatible-endpoint-smoke-helpers.ts
  • src/lib/onboard/compatible-endpoint-smoke.test.ts
  • src/lib/onboard/compatible-endpoint-smoke.ts
  • src/lib/onboard/smoke-retry-classifier.test.ts
  • src/lib/onboard/smoke-retry-classifier.ts

@github-actions

github-actions Bot commented Jun 28, 2026 •

Copy link
Copy Markdown
Contributor

PR Review Advisor — Changes requested

Merge posture: Do not merge yet
Primary next action: Resolve or justify PRA-1: Validate compatible-endpoint retries at the reused OpenShell sandbox boundary.
Open items: 0 required · 1 warning · 0 suggestions · 3 test follow-ups
Since last review: 1 prior item resolved · 1 still applies · 0 new items found

Action checklist

  • PRA-1 Resolve or justify: Validate compatible-endpoint retries at the reused OpenShell sandbox boundary in src/lib/onboard/compatible-endpoint-smoke.ts:371
  • PRA-T1 Add or justify test follow-up: Runtime validation
  • PRA-T2 Add or justify test follow-up: Runtime validation
  • PRA-T3 Add or justify test follow-up: Validate compatible-endpoint retries at the reused OpenShell sandbox boundary

Findings index

ID Severity Category Location Required action
PRA-1 Resolve/justify tests src/lib/onboard/compatible-endpoint-smoke.ts:371 Add or identify a narrow repository runtime/integration validation for this changed behavior, or record a maintainer justification that the fake-shell coverage is sufficient for this sensitive onboarding path. Keep it focused on the reused sandbox/provider-refresh boundary rather than broad E2E status.
Review findings by urgency: 0 required fixes, 1 item to resolve/justify, 0 in-scope improvements

⚠️ Resolve or justify before merge

Investigate these in the current review; either fix them, explain why they are not applicable, or document the accepted risk.

PRA-1 Resolve/justify — Validate compatible-endpoint retries at the reused OpenShell sandbox boundary

  • Location: src/lib/onboard/compatible-endpoint-smoke.ts:371
  • Category: tests
  • Problem: The changed retry loop exists because OpenShell provider refresh has no route-ready acknowledgement for reused sandboxes, but the in-repository tests still execute the generated shell locally with fake curl and fake sleep rather than through the production `openshell sandbox exec` path on a reused sandbox after provider refresh.
  • Impact: A mismatch between the fake local shell/curl behavior and the real reused sandbox/provider-refresh boundary could leave onboarding unstable in the exact environment this workaround is meant to protect, especially for curl exit 28 or connection-refused recovery, HTTP 5xx retry propagation, HTTP 429 strictness, and diagnostic redaction.
  • Recommended action: Add or identify a narrow repository runtime/integration validation for this changed behavior, or record a maintainer justification that the fake-shell coverage is sufficient for this sensitive onboarding path. Keep it focused on the reused sandbox/provider-refresh boundary rather than broad E2E status.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read `src/lib/onboard/compatible-endpoint-smoke.ts` around the provider-refresh comment and retry loop, then compare `src/lib/onboard/compatible-endpoint-smoke.test.ts`; the changed tests call `runSmokeScript(script, tmpDir, binDir)` from the local test helper instead of exercising `verifyCompatibleEndpointSandboxSmoke` through real `openshell sandbox exec` against a reused sandbox.
  • Missing regression test: Add a targeted runtime/integration test that runs the generated compatible-endpoint smoke command through a reused OpenShell sandbox after provider refresh and verifies one transient transport failure such as curl exit 28 or connection refused recovers without printing raw curl stderr or response bodies; add a companion boundary scenario or narrow fixture proving HTTP 5xx retries while HTTP 429 and permanent JSON/content failures remain single-shot and never emit `INFERENCE_SMOKE_OK`.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read `src/lib/onboard/compatible-endpoint-smoke.ts` around the provider-refresh comment and retry loop, then compare `src/lib/onboard/compatible-endpoint-smoke.test.ts`; the changed tests call `runSmokeScript(script, tmpDir, binDir)` from the local test helper instead of exercising `verifyCompatibleEndpointSandboxSmoke` through real `openshell sandbox exec` against a reused sandbox.
  • Evidence: `compatible-endpoint-smoke.ts` documents the invalid state with `OpenShell provider refresh has no route-ready acknowledgement for a reused sandbox`; expanded tests cover generated shell locally with fake curl/sleep for transient exits, HTTP 500, HTTP 429, backoff, redaction, and shell quoting, but not the actual reused OpenShell sandbox runtime boundary.

💡 In-scope improvements

These are lower-risk, not throwaway. Prefer fixing them in this PR when they are local to changed code; defer only with rationale or a linked follow-up.

  • None.
Test follow-ups to resolve or justify

If these cover changed behavior, prefer adding them in this PR; otherwise state why existing coverage is enough or link the follow-up.

  • PRA-T1 Runtime validation — Run the generated compatible-endpoint smoke command through a reused OpenShell sandbox after provider refresh and verify a transient curl transport failure such as exit 28 or connection refused recovers on the next attempt without printing raw curl stderr or response bodies.. Changed source files are paired with broad focused tests, including negative paths and redaction checks. The remaining gap is that the production behavior is generated shell/Python executed through `openshell sandbox exec` in a reused sandbox after provider refresh, while current repository tests run the generated script locally with fake curl/sleep.
  • PRA-T2 Runtime validation — At the same reused-sandbox boundary, verify HTTP 5xx retries while HTTP 429 and permanent JSON/content validation failures make exactly one request and never emit `INFERENCE_SMOKE_OK`.. Changed source files are paired with broad focused tests, including negative paths and redaction checks. The remaining gap is that the production behavior is generated shell/Python executed through `openshell sandbox exec` in a reused sandbox after provider refresh, while current repository tests run the generated script locally with fake curl/sleep.
  • PRA-T3 Validate compatible-endpoint retries at the reused OpenShell sandbox boundary — Add or identify a narrow repository runtime/integration validation for this changed behavior, or record a maintainer justification that the fake-shell coverage is sufficient for this sensitive onboarding path. Keep it focused on the reused sandbox/provider-refresh boundary rather than broad E2E status.
Since last review details

Current findings, using the urgency labels above:

PRA-1 Resolve/justify — Validate compatible-endpoint retries at the reused OpenShell sandbox boundary

  • Location: src/lib/onboard/compatible-endpoint-smoke.ts:371
  • Category: tests
  • Problem: The changed retry loop exists because OpenShell provider refresh has no route-ready acknowledgement for reused sandboxes, but the in-repository tests still execute the generated shell locally with fake curl and fake sleep rather than through the production `openshell sandbox exec` path on a reused sandbox after provider refresh.
  • Impact: A mismatch between the fake local shell/curl behavior and the real reused sandbox/provider-refresh boundary could leave onboarding unstable in the exact environment this workaround is meant to protect, especially for curl exit 28 or connection-refused recovery, HTTP 5xx retry propagation, HTTP 429 strictness, and diagnostic redaction.
  • Recommended action: Add or identify a narrow repository runtime/integration validation for this changed behavior, or record a maintainer justification that the fake-shell coverage is sufficient for this sensitive onboarding path. Keep it focused on the reused sandbox/provider-refresh boundary rather than broad E2E status.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Read `src/lib/onboard/compatible-endpoint-smoke.ts` around the provider-refresh comment and retry loop, then compare `src/lib/onboard/compatible-endpoint-smoke.test.ts`; the changed tests call `runSmokeScript(script, tmpDir, binDir)` from the local test helper instead of exercising `verifyCompatibleEndpointSandboxSmoke` through real `openshell sandbox exec` against a reused sandbox.
  • Missing regression test: Add a targeted runtime/integration test that runs the generated compatible-endpoint smoke command through a reused OpenShell sandbox after provider refresh and verifies one transient transport failure such as curl exit 28 or connection refused recovers without printing raw curl stderr or response bodies; add a companion boundary scenario or narrow fixture proving HTTP 5xx retries while HTTP 429 and permanent JSON/content failures remain single-shot and never emit `INFERENCE_SMOKE_OK`.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Read `src/lib/onboard/compatible-endpoint-smoke.ts` around the provider-refresh comment and retry loop, then compare `src/lib/onboard/compatible-endpoint-smoke.test.ts`; the changed tests call `runSmokeScript(script, tmpDir, binDir)` from the local test helper instead of exercising `verifyCompatibleEndpointSandboxSmoke` through real `openshell sandbox exec` against a reused sandbox.
  • Evidence: `compatible-endpoint-smoke.ts` documents the invalid state with `OpenShell provider refresh has no route-ready acknowledgement for a reused sandbox`; expanded tests cover generated shell locally with fake curl/sleep for transient exits, HTTP 500, HTTP 429, backoff, redaction, and shell quoting, but not the actual reused OpenShell sandbox runtime boundary.

Workflow run details

This is an automated, non-binding review; it still expects maintainers and agents to respond to each required or warning item. Treat suggestions as current-PR improvements when they touch changed code; defer only with maintainer rationale or a linked follow-up. A human maintainer must make the final merge decision.

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@github-actions

github-actions Bot commented Jun 28, 2026 •

Copy link
Copy Markdown
Contributor

PR Review Advisor (Nemotron Ultra) — Changes requested

Merge posture: Do not merge yet
Primary next action: Fix PRA-4: TRANSIENT_CURL_EXIT_CODES missing SSL/TLS transient exit codes; then add or justify PRA-T1.
Open items: 3 required · 7 warnings · 4 suggestions · 8 test follow-ups
Since last review: 3 prior items resolved · 6 still apply · 4 new items found

Action checklist

  • PRA-4 Fix: TRANSIENT_CURL_EXIT_CODES missing SSL/TLS transient exit codes in src/lib/onboard/smoke-retry-classifier.ts:7
  • PRA-5 Fix: HTTP 429 classified as terminal without Retry-After parsing or source-code threat model in src/lib/onboard/smoke-retry-classifier.ts:13
  • PRA-6 Fix: Test validates incorrect classification for curl exit codes 35 and 60 in src/lib/onboard/smoke-retry-classifier.test.ts:18
  • PRA-1 Resolve or justify: Source-of-truth review needed: Route-ready acknowledgement workaround (compatible-endpoint-smoke.ts:355-359)
  • PRA-2 Resolve or justify: Source-of-truth review needed: curl stderr suppression (smoke-retry-classifier.ts:47)
  • PRA-3 Resolve or justify: Source-of-truth review needed: HTTP 429 terminal classification (smoke-retry-classifier.ts:13-22)
  • PRA-7 Resolve or justify: curl stderr suppressed (2>/dev/null) loses diagnostic visibility for transient failures in src/lib/onboard/smoke-retry-classifier.ts:47
  • PRA-8 Resolve or justify: Route-ready acknowledgement workaround lacks source-of-truth tracking in src/lib/onboard/compatible-endpoint-smoke.ts:355
  • PRA-9 Resolve or justify: Generic 'terminal HTTP' error message for all non-2xx, non-5xx codes hinders debugging in src/lib/onboard/compatible-endpoint-smoke.ts:330
  • PRA-10 Resolve or justify: Missing runtime validation tests for sandbox execution paths in src/lib/onboard/smoke-retry-classifier.test.ts:1
  • PRA-T1 Add or justify test follow-up: Runtime validation
  • PRA-T2 Add or justify test follow-up: Runtime validation
  • PRA-T3 Add or justify test follow-up: Runtime validation
  • PRA-T4 Add or justify test follow-up: Runtime validation
  • PRA-T5 Add or justify test follow-up: Missing runtime validation tests for sandbox execution paths
  • PRA-T6 Add or justify test follow-up: Test timeout budget now uses formula — resolved from prior review
  • PRA-T7 Add or justify test follow-up: Triangular backoff formula has explanatory comment — resolved from prior review
  • PRA-T8 Add or justify test follow-up: New shell-quoting hostile model test validates injection prevention
  • PRA-11 In-scope improvement: Test timeout budget now uses formula — resolved from prior review in src/lib/onboard/compatible-endpoint-smoke.test.ts:61
  • PRA-12 In-scope improvement: Test helpers extracted and reused — justified in src/lib/onboard/test-helpers/compatible-endpoint-smoke-helpers.ts:124
  • PRA-13 In-scope improvement: Triangular backoff formula has explanatory comment — resolved from prior review in src/lib/onboard/smoke-retry-classifier.ts:28
  • PRA-14 In-scope improvement: New shell-quoting hostile model test validates injection prevention in src/lib/onboard/compatible-endpoint-smoke.test.ts:210

Findings index

ID Severity Category Location Required action
PRA-1 Resolve/justify architecture — Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-2 Resolve/justify architecture — Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-3 Resolve/justify architecture — Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
PRA-4 Required security src/lib/onboard/smoke-retry-classifier.ts:7 Expand TRANSIENT_CURL_EXIT_CODES to include all documented transient curl exit codes. At minimum add: 5, 18, 35, 51, 53, 54, 57, 58, 59, 60, 61, 63. Document why each code is classified as transient or permanent in a comment. Update the corresponding test expectations.
PRA-5 Required security src/lib/onboard/smoke-retry-classifier.ts:13 Either: (a) make HTTP 429 retryable by parsing Retry-After header in the shell script and respecting it, or (b) strengthen the justification with a threat model in the source code (not just test) explaining why blind retry is worse than permanent failure for onboarding. If keeping terminal, add a code comment in isRetryableHttpStatus referencing the threat model rationale.
PRA-6 Required correctness src/lib/onboard/smoke-retry-classifier.test.ts:18 Remove 35 and 60 from the 'permanent' test case. Add them to the 'transient' test case once TRANSIENT_CURL_EXIT_CODES is expanded.
PRA-7 Resolve/justify security src/lib/onboard/smoke-retry-classifier.ts:47 Capture curl stderr to a temporary file and include it in the failure output when curl exits with a transient code (before returning exit 4). At minimum, log stderr content for transient failures.
PRA-8 Resolve/justify architecture src/lib/onboard/compatible-endpoint-smoke.ts:355 Add a TODO with a target milestone or GitHub issue number for when route-ready acknowledgement will be added. Consider adding a test that would fail when the workaround is no longer needed (i.e., when provider refresh provides route-ready ack, the retry logic should change).
PRA-9 Resolve/justify security src/lib/onboard/compatible-endpoint-smoke.ts:330 Add specific handling for common 4xx codes in error messages to aid debugging (e.g., 'credential issue' for 401/403, 'endpoint not found' for 404, 'bad request' for 400, 'rate limited' for 429). Ensure messages don't leak sensitive info (currently they don't).
PRA-10 Resolve/justify tests src/lib/onboard/smoke-retry-classifier.test.ts:1 Add targeted runtime/integration validation for the changed behavior paths. Do not report external E2E job pass/fail here.
PRA-11 Improvement tests src/lib/onboard/compatible-endpoint-smoke.test.ts:61 No action needed. This is a positive improvement.
PRA-12 Improvement scope src/lib/onboard/test-helpers/compatible-endpoint-smoke-helpers.ts:124 Keep as-is. The extraction is justified by reuse across multiple tests.
PRA-13 Improvement tests src/lib/onboard/smoke-retry-classifier.ts:28 No changes needed. This is a positive improvement.
PRA-14 Improvement tests src/lib/onboard/compatible-endpoint-smoke.test.ts:210 Keep this test. It's a valuable security regression test.

🚨 Required before merge

Address these before merging unless a maintainer explicitly overrides the advisor with rationale.

PRA-4 Required — TRANSIENT_CURL_EXIT_CODES missing SSL/TLS transient exit codes

  • Location: src/lib/onboard/smoke-retry-classifier.ts:7
  • Category: security
  • Problem: TRANSIENT_CURL_EXIT_CODES only includes [6, 7, 28, 52, 55, 56]. Missing documented transient codes per curl documentation: SSL/TLS errors (35 SSL connect error, 51 SSL peer certificate, 53 SSL engine not found, 54 SSL engine set failed, 57 SSL cipher, 58 SSL cert problem, 59 SSL callback failed, 60 SSL cert verify failed, 61 SSL key access failed, 63 SSL session id context) and network errors (5 Couldn't resolve proxy, 18 Partial file). These are classified as permanent, causing false-negative onboarding failures for transient SSL/TLS issues.
  • Impact: Onboarding fails permanently for compatible endpoints experiencing transient SSL/TLS failures (certificate verification, cipher mismatch, engine errors) or network errors (proxy resolution, partial file) that would succeed on retry. This is a policy bypass — valid providers are rejected due to misclassified transient failures.
  • Required action: Expand TRANSIENT_CURL_EXIT_CODES to include all documented transient curl exit codes. At minimum add: 5, 18, 35, 51, 53, 54, 57, 58, 59, 60, 61, 63. Document why each code is classified as transient or permanent in a comment. Update the corresponding test expectations.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Check TRANSIENT_CURL_EXIT_CODES array in smoke-retry-classifier.ts:7. Compare against https://curl.se/libcurl/c/libcurl-errors.html. Verify test 'classifies curl exit %i as permanent' no longer includes 35, 60.
  • Missing regression test: Add test cases for each newly-classified transient curl exit code verifying they trigger retry behavior (exit 4 from run_smoke_request). Update the 'classifies curl exit %i as permanent' test to exclude codes that should be transient (35, 60).
  • Done when: The required change is committed and verification passes: Check TRANSIENT_CURL_EXIT_CODES array in smoke-retry-classifier.ts:7. Compare against https://curl.se/libcurl/c/libcurl-errors.html. Verify test 'classifies curl exit %i as permanent' no longer includes 35, 60.
  • Evidence: TRANSIENT_CURL_EXIT_CODES = [6, 7, 28, 52, 55, 56] at line 7. Test at smoke-retry-classifier.test.ts:18 expects classifyCurlExit(35) === 'permanent' and classifyCurlExit(60) === 'permanent', but both are SSL transient codes per curl docs.

PRA-5 Required — HTTP 429 classified as terminal without Retry-After parsing or source-code threat model

  • Location: src/lib/onboard/smoke-retry-classifier.ts:13
  • Category: security
  • Problem: isRetryableHttpStatus returns false for HTTP 429 (rate limit). The comment justifies this: 'this probe does not retain Retry-After, and retrying a rate-limited endpoint would add load without a server-directed delay.' However, 429 responses often include Retry-After headers and are by definition transient. Treating them as terminal causes permanent onboarding failure for compatible endpoints that enforce rate limits, even when the condition would clear after a brief wait.
  • Impact: Onboarding fails permanently for compatible endpoints that return 429 with Retry-After, even though the condition is transient. Users cannot complete onboarding for rate-limited providers without manual intervention.
  • Required action: Either: (a) make HTTP 429 retryable by parsing Retry-After header in the shell script and respecting it, or (b) strengthen the justification with a threat model in the source code (not just test) explaining why blind retry is worse than permanent failure for onboarding. If keeping terminal, add a code comment in isRetryableHttpStatus referencing the threat model rationale.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Check isRetryableHttpStatus(429) returns false in smoke-retry-classifier.ts:13-22. Check test 'does not retry a parseable JSON HTTP 429 response' in compatible-endpoint-smoke.test.ts asserts exit code 1 and exactly 1 curl call.
  • Missing regression test: If 429 becomes retryable: add test verifying retry with Retry-After header parsing. If 429 stays terminal: add a source code comment in isRetryableHttpStatus with threat model rationale (currently only in test comment).
  • Done when: The required change is committed and verification passes: Check isRetryableHttpStatus(429) returns false in smoke-retry-classifier.ts:13-22. Check test 'does not retry a parseable JSON HTTP 429 response' in compatible-endpoint-smoke.test.ts asserts exit code 1 and exactly 1 curl call.
  • Evidence: isRetryableHttpStatus function only returns true for 500-599. Test 'does not retry a parseable JSON HTTP 429 response' asserts exit code 1 and exactly 1 curl call. No Retry-After parsing logic exists in buildCompatibleEndpointSmokeRequestScript.

PRA-6 Required — Test validates incorrect classification for curl exit codes 35 and 60

  • Location: src/lib/onboard/smoke-retry-classifier.test.ts:18
  • Category: correctness
  • Problem: Test 'classifies curl exit %i as permanent' includes exit codes 35 and 60 which are SSL transient codes per curl documentation (35=SSL connect error, 60=SSL cert verify failed). This test validates incorrect behavior and will pass even when production code is wrong.
  • Impact: Test suite gives false confidence. The test explicitly expects classifyCurlExit(35) === 'permanent' and classifyCurlExit(60) === 'permanent', but both should be 'transient' per curl docs.
  • Required action: Remove 35 and 60 from the 'permanent' test case. Add them to the 'transient' test case once TRANSIENT_CURL_EXIT_CODES is expanded.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Check smoke-retry-classifier.test.ts line 18: it.each([0, 1, 2, 22, 35, 60]) expects permanent. Compare with curl docs: 35=SSL connect error, 60=SSL cert verify failed (both transient).
  • Missing regression test: Update test to classify 35 and 60 as transient after fixing TRANSIENT_CURL_EXIT_CODES.
  • Done when: The required change is committed and verification passes: Check smoke-retry-classifier.test.ts line 18: it.each([0, 1, 2, 22, 35, 60]) expects permanent. Compare with curl docs: 35=SSL connect error, 60=SSL cert verify failed (both transient).
  • Evidence: Test expects permanent for 35, 60 but curl docs classify both as transient SSL errors.
Review findings by urgency: 3 required fixes, 7 items to resolve/justify, 4 in-scope improvements

⚠️ Resolve or justify before merge

Investigate these in the current review; either fix them, explain why they are not applicable, or document the accepted risk.

PRA-1 Resolve/justify — Source-of-truth review needed: Route-ready acknowledgement workaround (compatible-endpoint-smoke.ts:355-359)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: Missing — no test that fails when ack is added
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: Comment at lines 355-359 has no issue link, no TODO with milestone, no removal test

PRA-2 Resolve/justify — Source-of-truth review needed: curl stderr suppression (smoke-retry-classifier.ts:47)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: Missing — no test verifying stderr capture for transient failures
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: Line 47: curl ... 2>/dev/null || { rc=$?; printf 'curl exit %s\n' "$rc" >&2; ... }

PRA-3 Resolve/justify — Source-of-truth review needed: HTTP 429 terminal classification (smoke-retry-classifier.ts:13-22)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: Partial — test documents behavior but no threat model in source
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: isRetryableHttpStatus returns false for 429; comment only in test, not source

PRA-7 Resolve/justify — curl stderr suppressed (2>/dev/null) loses diagnostic visibility for transient failures

  • Location: src/lib/onboard/smoke-retry-classifier.ts:47
  • Category: security
  • Problem: The generated curl command in buildCompatibleEndpointSmokeRequestScript redirects stderr to /dev/null (2>/dev/null). This loses diagnostic visibility for transient failures — when curl exits with a transient code, the stderr content (which may contain SSL error details, connection diagnostics) is discarded.
  • Impact: Operators cannot diagnose why transient curl failures occurred because stderr is suppressed. The code prints 'curl exit N' but not the actual error message from curl.
  • Recommended action: Capture curl stderr to a temporary file and include it in the failure output when curl exits with a transient code (before returning exit 4). At minimum, log stderr content for transient failures.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check buildCompatibleEndpointSmokeRequestScript in smoke-retry-classifier.ts:47 for '2>/dev/null'.
  • Missing regression test: Add test verifying that when curl exits with a transient code (e.g., 35), the stderr output is captured and logged.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check buildCompatibleEndpointSmokeRequestScript in smoke-retry-classifier.ts:47 for '2>/dev/null'.
  • Evidence: Line 47: curl ... >"$status_file" 2>/dev/null || { rc=$?; printf 'curl exit %s\n' "$rc" >&2; ... }

PRA-8 Resolve/justify — Route-ready acknowledgement workaround lacks source-of-truth tracking

  • Location: src/lib/onboard/compatible-endpoint-smoke.ts:355
  • Category: architecture
  • Problem: Comment at lines 355-359 describes a workaround: 'OpenShell provider refresh has no route-ready acknowledgement for a reused sandbox, so this first authenticated request retries only explicit transport and HTTP 5xx signals while keeping config/content failures strict. Remove this retry when provider refresh exposes a route-ready acknowledgement.' However, there is no TODO with target milestone or GitHub issue number, and no test that would fail when the workaround is no longer needed.
  • Impact: Workaround may persist indefinitely without a mechanism to detect when provider refresh adds route-ready acknowledgement. Retry semantics change without detection.
  • Recommended action: Add a TODO with a target milestone or GitHub issue number for when route-ready acknowledgement will be added. Consider adding a test that would fail when the workaround is no longer needed (i.e., when provider refresh provides route-ready ack, the retry logic should change).
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check compatible-endpoint-smoke.ts lines 355-359 for TODO with issue number. Search for test that validates workaround removal condition.
  • Missing regression test: Add a test that asserts the retry behavior changes when a route-ready acknowledgement is detected (or document the detection mechanism).
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check compatible-endpoint-smoke.ts lines 355-359 for TODO with issue number. Search for test that validates workaround removal condition.
  • Evidence: Comment at lines 355-359 has no issue link, no TODO with milestone, no removal test.

PRA-9 Resolve/justify — Generic 'terminal HTTP' error message for all non-2xx, non-5xx codes hinders debugging

  • Location: src/lib/onboard/compatible-endpoint-smoke.ts:330
  • Category: security
  • Problem: The error message 'inference.local returned terminal HTTP %s; response_bytes=%s' does not distinguish between 400 (bad request), 401/403 (credential issue), 404 (endpoint not found), 429 (rate limit), etc.
  • Impact: Operators cannot quickly diagnose onboarding failures without inspecting raw responses. Different 4xx codes have different remediation paths.
  • Recommended action: Add specific handling for common 4xx codes in error messages to aid debugging (e.g., 'credential issue' for 401/403, 'endpoint not found' for 404, 'bad request' for 400, 'rate limited' for 429). Ensure messages don't leak sensitive info (currently they don't).
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check check_response function in compatible-endpoint-smoke.ts around line 330 for terminal HTTP error message.
  • Missing regression test: Add tests verifying specific error messages for 400, 401, 403, 404, 429 terminal responses.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check check_response function in compatible-endpoint-smoke.ts around line 330 for terminal HTTP error message.
  • Evidence: Line 330-335: generic message for all non-2xx, non-5xx status codes.

PRA-10 Resolve/justify — Missing runtime validation tests for sandbox execution paths

  • Location: src/lib/onboard/smoke-retry-classifier.test.ts:1
  • Category: tests
  • Problem: The sandbox smoke script runs inside OpenShell sandbox via 'sh -lc' — unit/integration tests mock curl but don't exercise real sandbox execution. The testDepth verdict recommends runtime validation.
  • Impact: Behavioral gaps may exist between mocked curl behavior and real sandbox execution (signal handling, timeout enforcement, shell semantics).
  • Recommended action: Add targeted runtime/integration validation for the changed behavior paths. Do not report external E2E job pass/fail here.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Run vitest with real sandbox execution for transient curl exit 28, SSL transient exit 35 (if fixed), HTTP 429 with Retry-After, hostile model name.
  • Missing regression test: TC-RT1: Real sandbox execution with transient curl exit 28 (timeout) → verifies retry + backoff in actual sandbox. TC-RT2: Real sandbox with SSL transient exit 35 → verifies retry behavior. TC-RT3: Real sandbox with HTTP 429 + Retry-After header → verifies parsing if implemented. TC-RT4: Real sandbox with hostile model name → verifies shell quoting end-to-end.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Run vitest with real sandbox execution for transient curl exit 28, SSL transient exit 35 (if fixed), HTTP 429 with Retry-After, hostile model name.
  • Evidence: testDepth.verdict = 'runtime_validation_recommended' with rationale citing the three changed source files.

💡 In-scope improvements

These are lower-risk, not throwaway. Prefer fixing them in this PR when they are local to changed code; defer only with rationale or a linked follow-up.

PRA-11 Improvement — Test timeout budget now uses formula — resolved from prior review

  • Location: src/lib/onboard/compatible-endpoint-smoke.test.ts:61
  • Category: tests
  • Problem: Test 'budgets the host command timeout for every retry attempt' expects timeout 225_000 which now matches the formula using totalRetryBackoffSeconds(3, 5) = 15, so 3*60 + 15 + 30 = 225 seconds.
  • Impact: Positive — test now verifies the formula rather than a magic number.
  • Suggested action: No action needed. This is a positive improvement.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Check test expects 225_000 and production code uses totalRetryBackoffSeconds(3, 5) = 15, so 3*60 + 15 + 30 = 225 seconds = 225_000 ms.
  • Missing regression test: Already covered.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: Test updated from 220_000 to 225_000; production code uses totalRetryBackoffSeconds.

PRA-12 Improvement — Test helpers extracted and reused — justified

  • Location: src/lib/onboard/test-helpers/compatible-endpoint-smoke-helpers.ts:124
  • Category: scope
  • Problem: Test helpers (writeSmokeConfig, writeFakeCurl, writeFakeSleep, runSmokeScript) extracted to separate file and reused across 10+ test cases.
  • Impact: Positive — reduces duplication and improves test maintainability.
  • Suggested action: Keep as-is. The extraction is justified by reuse across multiple tests.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Verify helpers are used in multiple test cases in compatible-endpoint-smoke.test.ts.
  • Missing regression test: Not applicable.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: Helpers used in all new integration tests and existing ones.

PRA-13 Improvement — Triangular backoff formula has explanatory comment — resolved from prior review

  • Location: src/lib/onboard/smoke-retry-classifier.ts:28
  • Category: tests
  • Problem: totalRetryBackoffSeconds function comment: 'Sum delaySeconds * i for each gap i between attempts: 5s + 10s for 3 attempts.'
  • Impact: Positive — formula is documented.
  • Suggested action: No changes needed. This is a positive improvement.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Check totalRetryBackoffSeconds function comment and test 'computes triangular retry backoff'.
  • Missing regression test: Already covered.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: Comment added at lines 28-32; test verifies formula.

PRA-14 Improvement — New shell-quoting hostile model test validates injection prevention

  • Location: src/lib/onboard/compatible-endpoint-smoke.test.ts:210
  • Category: tests
  • Problem: New test 'shell-quotes hostile model text through the generated smoke script' validates that model names with shell metacharacters (', `, $()) are properly quoted and don't execute arbitrary commands.
  • Impact: Positive — validates shell injection prevention for model parameter.
  • Suggested action: Keep this test. It's a valuable security regression test.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Check test creates model "foo'bar`$(touch sentinel)" and verifies sentinel file is not created and request JSON contains the literal model string.
  • Missing regression test: Already covered by new test.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: Test at line 210 creates hostile model string and verifies no command execution.
Test follow-ups to resolve or justify

If these cover changed behavior, prefer adding them in this PR; otherwise state why existing coverage is enough or link the follow-up.

  • PRA-T1 Runtime validation — TC-RT1: Real sandbox execution with transient curl exit 28 (timeout) → verifies retry + backoff in actual sandbox. Runtime/sandbox/infrastructure paths need behavioral runtime validation: src/lib/onboard/__test-helpers__/compatible-endpoint-smoke-helpers.ts, src/lib/onboard/compatible-endpoint-smoke.ts, src/lib/onboard/smoke-retry-classifier.ts. Unit/integration tests mock curl but don't exercise real sandbox execution.
  • PRA-T2 Runtime validation — TC-RT2: Real sandbox execution with SSL transient exit 35 (if fixed) → verifies retry behavior. Runtime/sandbox/infrastructure paths need behavioral runtime validation: src/lib/onboard/__test-helpers__/compatible-endpoint-smoke-helpers.ts, src/lib/onboard/compatible-endpoint-smoke.ts, src/lib/onboard/smoke-retry-classifier.ts. Unit/integration tests mock curl but don't exercise real sandbox execution.
  • PRA-T3 Runtime validation — TC-RT3: Real sandbox with HTTP 429 + Retry-After header → verifies parsing if implemented. Runtime/sandbox/infrastructure paths need behavioral runtime validation: src/lib/onboard/__test-helpers__/compatible-endpoint-smoke-helpers.ts, src/lib/onboard/compatible-endpoint-smoke.ts, src/lib/onboard/smoke-retry-classifier.ts. Unit/integration tests mock curl but don't exercise real sandbox execution.
  • PRA-T4 Runtime validation — TC-RT4: Real sandbox with hostile model name → verifies shell quoting end-to-end. Runtime/sandbox/infrastructure paths need behavioral runtime validation: src/lib/onboard/__test-helpers__/compatible-endpoint-smoke-helpers.ts, src/lib/onboard/compatible-endpoint-smoke.ts, src/lib/onboard/smoke-retry-classifier.ts. Unit/integration tests mock curl but don't exercise real sandbox execution.
  • PRA-T5 Missing runtime validation tests for sandbox execution paths — Add targeted runtime/integration validation for the changed behavior paths. Do not report external E2E job pass/fail here.
  • PRA-T6 Test timeout budget now uses formula — resolved from prior review — No action needed. This is a positive improvement.
  • PRA-T7 Triangular backoff formula has explanatory comment — resolved from prior review — No changes needed. This is a positive improvement.
  • PRA-T8 New shell-quoting hostile model test validates injection prevention — Keep this test. It's a valuable security regression test.
Since last review details

Current findings, using the urgency labels above:

PRA-1 Resolve/justify — Source-of-truth review needed: Route-ready acknowledgement workaround (compatible-endpoint-smoke.ts:355-359)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: Missing — no test that fails when ack is added
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: Comment at lines 355-359 has no issue link, no TODO with milestone, no removal test

PRA-2 Resolve/justify — Source-of-truth review needed: curl stderr suppression (smoke-retry-classifier.ts:47)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: Missing — no test verifying stderr capture for transient failures
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: Line 47: curl ... 2>/dev/null || { rc=$?; printf 'curl exit %s\n' "$rc" >&2; ... }

PRA-3 Resolve/justify — Source-of-truth review needed: HTTP 429 terminal classification (smoke-retry-classifier.ts:13-22)

  • Location: not file-specific
  • Category: architecture
  • Problem: The advisor marked localized patch analysis as needs_followup.
  • Impact: A localized workaround can preserve or hide an invalid state when the source boundary is unclear.
  • Recommended action: Identify the invalid state, source boundary, source-fix constraint, regression test, and removal condition before merging the localized behavior.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Missing regression test: Partial — test documents behavior but no threat model in source
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Inspect the localized patch and source-of-truth review fields for a concrete invalid state, source boundary, source-fix constraint, regression test, and removal condition.
  • Evidence: isRetryableHttpStatus returns false for 429; comment only in test, not source

PRA-4 Required — TRANSIENT_CURL_EXIT_CODES missing SSL/TLS transient exit codes

  • Location: src/lib/onboard/smoke-retry-classifier.ts:7
  • Category: security
  • Problem: TRANSIENT_CURL_EXIT_CODES only includes [6, 7, 28, 52, 55, 56]. Missing documented transient codes per curl documentation: SSL/TLS errors (35 SSL connect error, 51 SSL peer certificate, 53 SSL engine not found, 54 SSL engine set failed, 57 SSL cipher, 58 SSL cert problem, 59 SSL callback failed, 60 SSL cert verify failed, 61 SSL key access failed, 63 SSL session id context) and network errors (5 Couldn't resolve proxy, 18 Partial file). These are classified as permanent, causing false-negative onboarding failures for transient SSL/TLS issues.
  • Impact: Onboarding fails permanently for compatible endpoints experiencing transient SSL/TLS failures (certificate verification, cipher mismatch, engine errors) or network errors (proxy resolution, partial file) that would succeed on retry. This is a policy bypass — valid providers are rejected due to misclassified transient failures.
  • Required action: Expand TRANSIENT_CURL_EXIT_CODES to include all documented transient curl exit codes. At minimum add: 5, 18, 35, 51, 53, 54, 57, 58, 59, 60, 61, 63. Document why each code is classified as transient or permanent in a comment. Update the corresponding test expectations.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Check TRANSIENT_CURL_EXIT_CODES array in smoke-retry-classifier.ts:7. Compare against https://curl.se/libcurl/c/libcurl-errors.html. Verify test 'classifies curl exit %i as permanent' no longer includes 35, 60.
  • Missing regression test: Add test cases for each newly-classified transient curl exit code verifying they trigger retry behavior (exit 4 from run_smoke_request). Update the 'classifies curl exit %i as permanent' test to exclude codes that should be transient (35, 60).
  • Done when: The required change is committed and verification passes: Check TRANSIENT_CURL_EXIT_CODES array in smoke-retry-classifier.ts:7. Compare against https://curl.se/libcurl/c/libcurl-errors.html. Verify test 'classifies curl exit %i as permanent' no longer includes 35, 60.
  • Evidence: TRANSIENT_CURL_EXIT_CODES = [6, 7, 28, 52, 55, 56] at line 7. Test at smoke-retry-classifier.test.ts:18 expects classifyCurlExit(35) === 'permanent' and classifyCurlExit(60) === 'permanent', but both are SSL transient codes per curl docs.

PRA-5 Required — HTTP 429 classified as terminal without Retry-After parsing or source-code threat model

  • Location: src/lib/onboard/smoke-retry-classifier.ts:13
  • Category: security
  • Problem: isRetryableHttpStatus returns false for HTTP 429 (rate limit). The comment justifies this: 'this probe does not retain Retry-After, and retrying a rate-limited endpoint would add load without a server-directed delay.' However, 429 responses often include Retry-After headers and are by definition transient. Treating them as terminal causes permanent onboarding failure for compatible endpoints that enforce rate limits, even when the condition would clear after a brief wait.
  • Impact: Onboarding fails permanently for compatible endpoints that return 429 with Retry-After, even though the condition is transient. Users cannot complete onboarding for rate-limited providers without manual intervention.
  • Required action: Either: (a) make HTTP 429 retryable by parsing Retry-After header in the shell script and respecting it, or (b) strengthen the justification with a threat model in the source code (not just test) explaining why blind retry is worse than permanent failure for onboarding. If keeping terminal, add a code comment in isRetryableHttpStatus referencing the threat model rationale.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Check isRetryableHttpStatus(429) returns false in smoke-retry-classifier.ts:13-22. Check test 'does not retry a parseable JSON HTTP 429 response' in compatible-endpoint-smoke.test.ts asserts exit code 1 and exactly 1 curl call.
  • Missing regression test: If 429 becomes retryable: add test verifying retry with Retry-After header parsing. If 429 stays terminal: add a source code comment in isRetryableHttpStatus with threat model rationale (currently only in test comment).
  • Done when: The required change is committed and verification passes: Check isRetryableHttpStatus(429) returns false in smoke-retry-classifier.ts:13-22. Check test 'does not retry a parseable JSON HTTP 429 response' in compatible-endpoint-smoke.test.ts asserts exit code 1 and exactly 1 curl call.
  • Evidence: isRetryableHttpStatus function only returns true for 500-599. Test 'does not retry a parseable JSON HTTP 429 response' asserts exit code 1 and exactly 1 curl call. No Retry-After parsing logic exists in buildCompatibleEndpointSmokeRequestScript.

PRA-6 Required — Test validates incorrect classification for curl exit codes 35 and 60

  • Location: src/lib/onboard/smoke-retry-classifier.test.ts:18
  • Category: correctness
  • Problem: Test 'classifies curl exit %i as permanent' includes exit codes 35 and 60 which are SSL transient codes per curl documentation (35=SSL connect error, 60=SSL cert verify failed). This test validates incorrect behavior and will pass even when production code is wrong.
  • Impact: Test suite gives false confidence. The test explicitly expects classifyCurlExit(35) === 'permanent' and classifyCurlExit(60) === 'permanent', but both should be 'transient' per curl docs.
  • Required action: Remove 35 and 60 from the 'permanent' test case. Add them to the 'transient' test case once TRANSIENT_CURL_EXIT_CODES is expanded.
  • Expected follow-up: Fix before merge or get explicit maintainer override.
  • Verification: Check smoke-retry-classifier.test.ts line 18: it.each([0, 1, 2, 22, 35, 60]) expects permanent. Compare with curl docs: 35=SSL connect error, 60=SSL cert verify failed (both transient).
  • Missing regression test: Update test to classify 35 and 60 as transient after fixing TRANSIENT_CURL_EXIT_CODES.
  • Done when: The required change is committed and verification passes: Check smoke-retry-classifier.test.ts line 18: it.each([0, 1, 2, 22, 35, 60]) expects permanent. Compare with curl docs: 35=SSL connect error, 60=SSL cert verify failed (both transient).
  • Evidence: Test expects permanent for 35, 60 but curl docs classify both as transient SSL errors.

PRA-7 Resolve/justify — curl stderr suppressed (2>/dev/null) loses diagnostic visibility for transient failures

  • Location: src/lib/onboard/smoke-retry-classifier.ts:47
  • Category: security
  • Problem: The generated curl command in buildCompatibleEndpointSmokeRequestScript redirects stderr to /dev/null (2>/dev/null). This loses diagnostic visibility for transient failures — when curl exits with a transient code, the stderr content (which may contain SSL error details, connection diagnostics) is discarded.
  • Impact: Operators cannot diagnose why transient curl failures occurred because stderr is suppressed. The code prints 'curl exit N' but not the actual error message from curl.
  • Recommended action: Capture curl stderr to a temporary file and include it in the failure output when curl exits with a transient code (before returning exit 4). At minimum, log stderr content for transient failures.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check buildCompatibleEndpointSmokeRequestScript in smoke-retry-classifier.ts:47 for '2>/dev/null'.
  • Missing regression test: Add test verifying that when curl exits with a transient code (e.g., 35), the stderr output is captured and logged.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check buildCompatibleEndpointSmokeRequestScript in smoke-retry-classifier.ts:47 for '2>/dev/null'.
  • Evidence: Line 47: curl ... >"$status_file" 2>/dev/null || { rc=$?; printf 'curl exit %s\n' "$rc" >&2; ... }

PRA-8 Resolve/justify — Route-ready acknowledgement workaround lacks source-of-truth tracking

  • Location: src/lib/onboard/compatible-endpoint-smoke.ts:355
  • Category: architecture
  • Problem: Comment at lines 355-359 describes a workaround: 'OpenShell provider refresh has no route-ready acknowledgement for a reused sandbox, so this first authenticated request retries only explicit transport and HTTP 5xx signals while keeping config/content failures strict. Remove this retry when provider refresh exposes a route-ready acknowledgement.' However, there is no TODO with target milestone or GitHub issue number, and no test that would fail when the workaround is no longer needed.
  • Impact: Workaround may persist indefinitely without a mechanism to detect when provider refresh adds route-ready acknowledgement. Retry semantics change without detection.
  • Recommended action: Add a TODO with a target milestone or GitHub issue number for when route-ready acknowledgement will be added. Consider adding a test that would fail when the workaround is no longer needed (i.e., when provider refresh provides route-ready ack, the retry logic should change).
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check compatible-endpoint-smoke.ts lines 355-359 for TODO with issue number. Search for test that validates workaround removal condition.
  • Missing regression test: Add a test that asserts the retry behavior changes when a route-ready acknowledgement is detected (or document the detection mechanism).
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check compatible-endpoint-smoke.ts lines 355-359 for TODO with issue number. Search for test that validates workaround removal condition.
  • Evidence: Comment at lines 355-359 has no issue link, no TODO with milestone, no removal test.

PRA-9 Resolve/justify — Generic 'terminal HTTP' error message for all non-2xx, non-5xx codes hinders debugging

  • Location: src/lib/onboard/compatible-endpoint-smoke.ts:330
  • Category: security
  • Problem: The error message 'inference.local returned terminal HTTP %s; response_bytes=%s' does not distinguish between 400 (bad request), 401/403 (credential issue), 404 (endpoint not found), 429 (rate limit), etc.
  • Impact: Operators cannot quickly diagnose onboarding failures without inspecting raw responses. Different 4xx codes have different remediation paths.
  • Recommended action: Add specific handling for common 4xx codes in error messages to aid debugging (e.g., 'credential issue' for 401/403, 'endpoint not found' for 404, 'bad request' for 400, 'rate limited' for 429). Ensure messages don't leak sensitive info (currently they don't).
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Check check_response function in compatible-endpoint-smoke.ts around line 330 for terminal HTTP error message.
  • Missing regression test: Add tests verifying specific error messages for 400, 401, 403, 404, 429 terminal responses.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Check check_response function in compatible-endpoint-smoke.ts around line 330 for terminal HTTP error message.
  • Evidence: Line 330-335: generic message for all non-2xx, non-5xx status codes.

PRA-10 Resolve/justify — Missing runtime validation tests for sandbox execution paths

  • Location: src/lib/onboard/smoke-retry-classifier.test.ts:1
  • Category: tests
  • Problem: The sandbox smoke script runs inside OpenShell sandbox via 'sh -lc' — unit/integration tests mock curl but don't exercise real sandbox execution. The testDepth verdict recommends runtime validation.
  • Impact: Behavioral gaps may exist between mocked curl behavior and real sandbox execution (signal handling, timeout enforcement, shell semantics).
  • Recommended action: Add targeted runtime/integration validation for the changed behavior paths. Do not report external E2E job pass/fail here.
  • Expected follow-up: Resolve in this PR or explain why the risk is acceptable.
  • Verification: Run vitest with real sandbox execution for transient curl exit 28, SSL transient exit 35 (if fixed), HTTP 429 with Retry-After, hostile model name.
  • Missing regression test: TC-RT1: Real sandbox execution with transient curl exit 28 (timeout) → verifies retry + backoff in actual sandbox. TC-RT2: Real sandbox with SSL transient exit 35 → verifies retry behavior. TC-RT3: Real sandbox with HTTP 429 + Retry-After header → verifies parsing if implemented. TC-RT4: Real sandbox with hostile model name → verifies shell quoting end-to-end.
  • Done when: The risk is fixed or explicitly justified in the PR. Verification: Run vitest with real sandbox execution for transient curl exit 28, SSL transient exit 35 (if fixed), HTTP 429 with Retry-After, hostile model name.
  • Evidence: testDepth.verdict = 'runtime_validation_recommended' with rationale citing the three changed source files.

PRA-11 Improvement — Test timeout budget now uses formula — resolved from prior review

  • Location: src/lib/onboard/compatible-endpoint-smoke.test.ts:61
  • Category: tests
  • Problem: Test 'budgets the host command timeout for every retry attempt' expects timeout 225_000 which now matches the formula using totalRetryBackoffSeconds(3, 5) = 15, so 3*60 + 15 + 30 = 225 seconds.
  • Impact: Positive — test now verifies the formula rather than a magic number.
  • Suggested action: No action needed. This is a positive improvement.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Check test expects 225_000 and production code uses totalRetryBackoffSeconds(3, 5) = 15, so 3*60 + 15 + 30 = 225 seconds = 225_000 ms.
  • Missing regression test: Already covered.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: Test updated from 220_000 to 225_000; production code uses totalRetryBackoffSeconds.

PRA-12 Improvement — Test helpers extracted and reused — justified

  • Location: src/lib/onboard/test-helpers/compatible-endpoint-smoke-helpers.ts:124
  • Category: scope
  • Problem: Test helpers (writeSmokeConfig, writeFakeCurl, writeFakeSleep, runSmokeScript) extracted to separate file and reused across 10+ test cases.
  • Impact: Positive — reduces duplication and improves test maintainability.
  • Suggested action: Keep as-is. The extraction is justified by reuse across multiple tests.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Verify helpers are used in multiple test cases in compatible-endpoint-smoke.test.ts.
  • Missing regression test: Not applicable.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: Helpers used in all new integration tests and existing ones.

PRA-13 Improvement — Triangular backoff formula has explanatory comment — resolved from prior review

  • Location: src/lib/onboard/smoke-retry-classifier.ts:28
  • Category: tests
  • Problem: totalRetryBackoffSeconds function comment: 'Sum delaySeconds * i for each gap i between attempts: 5s + 10s for 3 attempts.'
  • Impact: Positive — formula is documented.
  • Suggested action: No changes needed. This is a positive improvement.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Check totalRetryBackoffSeconds function comment and test 'computes triangular retry backoff'.
  • Missing regression test: Already covered.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: Comment added at lines 28-32; test verifies formula.

PRA-14 Improvement — New shell-quoting hostile model test validates injection prevention

  • Location: src/lib/onboard/compatible-endpoint-smoke.test.ts:210
  • Category: tests
  • Problem: New test 'shell-quotes hostile model text through the generated smoke script' validates that model names with shell metacharacters (', `, $()) are properly quoted and don't execute arbitrary commands.
  • Impact: Positive — validates shell injection prevention for model parameter.
  • Suggested action: Keep this test. It's a valuable security regression test.
  • Expected follow-up: Prefer a current-PR fix when local to changed code; defer only with rationale or linked follow-up.
  • Verification: Check test creates model "foo'bar`$(touch sentinel)" and verifies sentinel file is not created and request JSON contains the literal model string.
  • Missing regression test: Already covered by new test.
  • Done when: The local improvement is applied, or the PR notes why it should be deferred.
  • Evidence: Test at line 210 creates hostile model string and verifies no command execution.

Workflow run details

This is an automated, non-binding review; it still expects maintainers and agents to respond to each required or warning item. Treat suggestions as current-PR improvements when they touch changed code; defer only with maintainer rationale or a linked follow-up. A human maintainer must make the final merge decision.

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@cv

cv commented Jun 28, 2026

Copy link
Copy Markdown
Collaborator Author

Advisor disposition for 9f12443:

  • Required HTTP scope item fixed: HTTP 429 is no longer retryable. The boundary now matches the observed and previously supported 5xx behavior plus the explicit transient curl allowlist and reasoning-budget retry.
  • Parseable JSON HTTP 500 coverage added: the first 500 JSON response retries and the second PONG succeeds. The fake curl now honors -o and -w independently.
  • Source boundary/removal condition documented beside the production loop: OpenShell provider refresh currently exposes no route-ready acknowledgement for an already-running sandbox; this authenticated smoke is the first end-to-end readiness check. Remove the retry when provider refresh exposes that acknowledgement.
  • Curl exit 28 uses the same 60-second request budget intentionally. Each retry is an independent readiness attempt; increasing the timeout would extend onboarding without improving route propagation. Exit 28 is covered behaviorally, as are exits 6, 7, 52, 55, and 56; permanent exit 2 is single-shot.
  • The 225-second timeout budget is exact: three 60-second requests + the only two sleeps (5s and 10s) + 30 seconds for sandbox exec/config/payload/response overhead. It includes no final-attempt sleep.
  • The retry classifier remains in the generated sandbox script because curl and response parsing execute inside that boundary; extracting a TypeScript helper would not be callable there and would duplicate the protocol.
  • Existing coverage already shell-quotes a model containing a single quote (provider/model'), so the injection suggestion is satisfied.

All 18 focused behavioral tests, Biome, CLI typecheck, normal commit/push hooks, repository checks, and secret scanning pass. Token-rotation runtime validation remains in progress; subsequent commits only expanded tests, removed HTTP 429, and clarified comments, leaving its observed 5xx/curl runtime paths unchanged.

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@cv

cv commented Jun 28, 2026

Copy link
Copy Markdown
Collaborator Author

Follow-up review items are now addressed in ab9d316:

  • Added a behavioral HTTP 429 test proving it is terminal and makes exactly one request; the PR contract now explicitly limits HTTP retries to 5xx.
  • Simplified the fixed three-attempt backoff budget to 5s + 10s, reducing the production file delta below the advisor size trigger while retaining the classifier inside the generated sandbox script where it executes.
  • Targeted verification is green: 19/19 Vitest tests, Biome, CLI typecheck, diff check, and normal commit/push hooks.

The existing quoted-model test covers shell escaping. Curl exit 28 cannot distinguish connect/read timeout origins, so the retry keeps the same bounded 60-second request timeout rather than escalating it.

@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 28327364831
Target ref: codex/harden-smoke-retry-boundary
Requested jobs: token-rotation-e2e
Summary: 1 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
token-rotation-e2e ✅ success

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@cv

cv commented Jun 28, 2026

Copy link
Copy Markdown
Collaborator Author

Architecture follow-up in bfaad84:

  • Extracted the 102-line fake-curl/config/process harness into a focused __test-helpers__ module; the behavioral test file is now 342 lines instead of 434.
  • Simplified the actual generated sandbox classifier path; the production file is now 420 lines, only +8 from main.
  • Did not add a separate TypeScript classifier because curl classification executes inside generated shell/Python in the sandbox and such a module would be dead or duplicate policy.
  • Revalidated 19/19 focused tests, Biome, CLI typecheck, and the complete normal commit/push hooks. One full-hook attempt exposed two unrelated auto-pair suite-order flakes; that file passed 8/8 in isolation, and the repeated full hook then passed.

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@github-actions

Copy link
Copy Markdown
Contributor

Selective E2E Results — ✅ All requested jobs passed

Run: 28328424431
Target ref: codex/harden-smoke-retry-boundary
Requested jobs: hermes-dashboard-e2e
Summary: 1 passed, 0 failed, 0 cancelled, 0 skipped

Job Result
hermes-dashboard-e2e ✅ success

@cv

cv commented Jun 28, 2026

Copy link
Copy Markdown
Collaborator Author

Final advisor follow-up in 5ad0eb8:

  • Fixed the timeout budget with the general triangular formula (delay * attempts * (attempts - 1) / 2), with 3/5 and 4/5 coverage.
  • Centralized the retry source of truth in smoke-retry-classifier.ts; its generated shell fragment and Python expression are directly interpolated into the sandbox script, so there is no dead duplicate policy.
  • Hardened HTTP status metadata parsing to require exactly three numeric digits.
  • Added an explicit exit-28 diagnostic while retaining the bounded 60-second timeout.
  • Moved fake response behavior to a separate trusted test script, captured the request payload, and added an executed hostile-model test covering single quotes, backticks, and $() without command execution.
  • Added a fake-sleep behavioral test proving 5s then 10s backoff.
  • Documented why HTTP 429 remains terminal.

Verification: 35/35 focused tests, Biome, CLI typecheck, diff check, complete commit hooks, complete push hooks. Commit is GitHub Verified.

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@cv

cv commented Jun 28, 2026

Copy link
Copy Markdown
Collaborator Author

GPT advisor follow-up in e083cd6:

  • Fixed PRA-2: the response status is parsed once and only HTTP 2xx may proceed to assistant-content validation. HTTP 5xx remains bounded-retry; HTTP 4xx/429 is terminal even if the body contains a deceptive valid-looking PONG choice.
  • Strengthened the 429 regression accordingly: non-zero status, no success marker, no retry, exactly one request.

PRA-1/PRA-3 source-boundary disposition:

  • Invalid state: an existing sandbox can receive provider-refresh completion before the inference route is actually ready, historically surfacing curl transport failures or HTML 504.
  • Source boundary: OpenShell provider refresh currently exposes no route-ready acknowledgement for an already-running sandbox.
  • Source-fix constraint: NemoClaw cannot await an acknowledgement that does not exist, so its first authenticated end-to-end request is the narrow readiness boundary.
  • Regression coverage: 36 focused behavioral tests cover the generated shell/Python, complete curl allowlist, 5xx, deceptive 429, permanent failures, redaction, hostile quoting, and 5s/10s backoff.
  • Runtime evidence: token-rotation run 28327364831 exercised the real reused-sandbox/provider-refresh path and passed; it previously reproduced HTML 504 specifically in reuse phases. Hermes dashboard run 28328424431 also passed the real sandbox inference path.
  • Removal condition: remove the retry once provider refresh exposes a route-ready acknowledgement, as documented beside the loop.

Normal commit and push hooks passed; e083cd6 is GitHub Verified.

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@cv

cv commented Jun 28, 2026

Copy link
Copy Markdown
Collaborator Author

Nemotron disposition on 30d62de:

  • PRA-2 fixed as requested: the classifier now documents why 429 is terminal—this probe does not retain Retry-After, and retrying without a server-directed delay would add load to a rate-limited endpoint. The deceptive-PONG 429 test locks the one-call terminal contract.
  • PRA-3 justified: curl stderr is intentionally suppressed at this external credential boundary because it may echo URLs, headers, or upstream bodies. Diagnostics expose only the numeric exit/status and response length; restoring arbitrary stderr would regress the security requirement inherited from fix(onboard): retry transient inference smoke #5932.
  • PRA-4 justified: the allowlist is intentionally narrow. TLS certificate/cipher/CA failures are security or configuration failures, not safe transient candidates. The list covers the observed propagation failures and bounded transport failures only.
  • PRA-5 justified: status-specific 401/403/404 prose adds no recovery behavior; numeric status is actionable while remaining redacted.
  • PRA-6: fix(onboard): retry transient inference smoke #5932/fix(onboard): constrain smoke retry boundary #5934 and the adjacent source comment track the workaround and explicit removal condition (OpenShell provider refresh exposes route-ready acknowledgement).
  • PRA-7: the integration assertion intentionally locks the 225-second external process boundary. The independent classifier unit test verifies the general triangular formula at both 3 and 4 attempts.
  • PRA-8 fixed: the triangular sum is now documented beside the formula.
  • GPT runtime/source-boundary warnings are explicitly justified by real reused-sandbox token-rotation run 28327364831 and the source-boundary/removal-condition comment.

36/36 focused tests and complete normal hooks pass; 30d62de is GitHub Verified.

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
@cv

cv commented Jun 28, 2026

Copy link
Copy Markdown
Collaborator Author

Explicit maintainer security disposition for final-head review:

  • Nemotron PRA-3 (429): keeping terminal by design. The classifier and executed regression now record the threat model: this probe does not retain Retry-After; blind replay cannot honor service recovery and amplifies rate-limited load. The operator can retry onboarding after the limit clears. Broadening to 429 without header capture is rejected.
  • Nemotron PRA-4 (TLS/network codes): keeping the narrow allowlist by design. Proxy, TLS, certificate, CA, cipher, and crypto-engine failures are security/configuration failures; blind retries cannot remediate them and would weaken fail-closed behavior. Codes 35 and 60 remain explicit permanent classifier cases. Broadening to all suggested codes is rejected.
  • Curl stderr remains suppressed because arbitrary external diagnostics can expose URLs, headers, or bodies; numeric exit/status and byte count are the safe diagnostic contract.
  • GPT runtime warnings are accepted with concrete evidence: real reused-sandbox/provider-refresh token-rotation run 28327364831 succeeded after the path had reproduced HTML 504 in reuse phases. Full Nightly on exact main remains the post-merge release gate.

This is a deliberate maintainer override of those proposed broadenings, not an unaddressed finding. 36/36 focused tests and complete normal hooks pass; 759fd86 is GitHub Verified.

@cv
cv enabled auto-merge (squash) June 28, 2026 16:54
@cv
cv disabled auto-merge June 28, 2026 17:06
@cv
cv merged commit 6f0e2e2 into main Jun 28, 2026
41 checks passed
@cv
cv deleted the codex/harden-smoke-retry-boundary branch June 28, 2026 17:06
@miyoungc miyoungc mentioned this pull request Jun 29, 2026
8 of 21 tasks
cv pushed a commit that referenced this pull request Jun 29, 2026
## Summary
Adds the v0.0.69 release notes to the published release-notes page so
users can see the shipped sandbox recovery, Deep Agents Code, Hermes,
inference, policy, and release-validation changes.
The section is based on the v0.0.69 announcement and links each
user-facing theme to the deeper docs pages that already cover the
behavior.

## Changes
- Added a new `v0.0.69` section to `docs/about/release-notes.mdx`.
- Linked release-note themes to lifecycle, backup, troubleshooting, Deep
Agents Code, commands, workspace, messaging, Hermes, inference,
security, monitoring, and network-policy docs.

Source summary:
- #5455 -> `docs/about/release-notes.mdx`: Summarized persistent
workspace and state cleanup during sandbox destroy.
- #5738 -> `docs/about/release-notes.mdx`: Summarized nonzero exit
status preservation for failed hosted endpoint validation.
- #5786 -> `docs/about/release-notes.mdx`: Summarized live sandbox
rediscovery when local registry state is missing.
- #5881 -> `docs/about/release-notes.mdx`: Summarized the
`nemo-deepagents` alias command surface.
- #5594 -> `docs/about/release-notes.mdx`: Summarized the Hermes Agent
2026.6.19 update.
- #5777 -> `docs/about/release-notes.mdx`: Summarized manifest-derived
messaging channel support.
- #5825 -> `docs/about/release-notes.mdx`: Summarized DeepSeek V4 Flash
managed-vLLM defaults for DGX Station.
- #5877 -> `docs/about/release-notes.mdx`: Summarized provider switch
metadata preservation.
- #5932 -> `docs/about/release-notes.mdx`: Summarized transient
inference smoke retry behavior.
- #5934 -> `docs/about/release-notes.mdx`: Summarized constrained
inference smoke retry boundaries.
- #5681 -> `docs/about/release-notes.mdx`: Summarized Shields
config-hash sealing during auto-restore.
- #5682 -> `docs/about/release-notes.mdx`: Summarized sandbox connect
process-limit enforcement.
- #5683 -> `docs/about/release-notes.mdx`: Summarized JSON agent failure
provenance warnings.
- #5711 -> `docs/about/release-notes.mdx`: Summarized sparse-source log
breadcrumbs.
- #5838 -> `docs/about/release-notes.mdx`: Summarized host-authoritative
Shields status.
- #5880 -> `docs/about/release-notes.mdx`: Summarized policy round-trip
documentation updates.
- #5886 -> `docs/about/release-notes.mdx`: Summarized network request
approval-flow documentation updates.

## Type of Change

- [ ] Code change (feature, bug fix, or refactor)
- [ ] Code change with doc updates
- [x] Doc only (prose changes, no code sample modifications)
- [ ] Doc only (includes code sample changes)

## Quality Gates
- [ ] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [x] Tests not applicable — justification: doc-only release-notes
prose; no runtime behavior changed.
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [ ] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [ ] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification:
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Verification
- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] Git hooks passed during commit and push, or `npx prek run
--from-ref main --to-ref HEAD` passes
- [ ] Targeted tests pass for changed behavior
- [ ] Full `npm test` passes (broad runtime changes only)
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only)
- [x] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

`npm run docs` passed with 0 errors and the existing Fern light-mode
accent contrast warning.
`fern check --warnings` reported the same accent-color warning.

---
Signed-off-by: Miyoung Choi <miyoungc@nvidia.com>

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Documentation**
* Added release notes for **v0.0.69**, covering improved sandbox
lifecycle recovery (state preservation across
destroy/recreate/rebuild/recovery/validation failures), clearer Deep
Agents Code terminal/CLI behavior, and safer Hermes messaging/provider
switching with manifest-driven channels.
* Improved inference setup validation guidance, including handling of
local/compatible endpoints and redaction of sensitive validation errors.
* Refreshed release-gate documentation with clearer approval examples
and validation behavior for NVIDIA API keys vs hosted inference keys.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
<!-- markdownlint-disable MD041 -->
## Summary
Tightens the compatible-endpoint smoke retry merged in NVIDIA#5932 so only
explicit transient transport and HTTP signals retry. It also removes
curl stderr/body dependence, derives exponential-backoff timeout
coverage, and adds behavioral tests for transient and permanent curl
exits.

## Changes
- Capture HTTP status directly from curl instead of inferring it from
HTML response bodies.
- Suppress curl stderr and retry only transient exits 6, 7, 28, 52, 55,
and 56.
- Keep permanent curl and JSON validation failures single-shot and
strict.
- Align retry delay with the existing Vitest 5s/10s backoff and derive
the 225-second parent timeout from the shared budget.
- Centralize the generated retry policy and triangular timeout budget in
a focused classifier module.
- Add behavioral coverage for transient curl exits 6, 7, 28, 52, 55, and
56; permanent curl and HTTP 429 failures; hostile model quoting; and
5s/10s backoff.

## Type of Change

- [x] Code change (feature, bug fix, or refactor)
- [ ] Code change with doc updates
- [ ] Doc only (prose changes, no code sample modifications)
- [ ] Doc only (includes code sample changes)

## Quality Gates
<!-- Check all that apply. For any "covered by existing tests", "not
applicable", or waiver entry, add a brief justification on the same line
or in the Changes section. -->
- [x] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [ ] Tests not applicable — justification:
- [ ] Docs updated for user-facing behavior changes
- [x] Docs not applicable — justification: internal validation retry
classification and diagnostics only; no user-facing configuration
changes.
- [x] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [x] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification: arbitrary curl stderr
and upstream response bodies are suppressed; diagnostics retain only
exit code, HTTP status, and response length, and all permanent
validation failures remain strict.
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Verification
<!-- Check each item you ran and confirmed. Leave unchecked items you
skipped. Doc-only changes do not require npm test unless you ran it. -->
- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] Git hooks passed during commit and push, or `npx prek run
--from-ref main --to-ref HEAD` passes
- [x] Targeted tests pass for changed behavior
- [ ] Full `npm test` passes (broad runtime changes only)
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only)
- [ ] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

Targeted verification:
- `npx vitest run --project cli
src/lib/onboard/compatible-endpoint-smoke.test.ts
src/lib/onboard/smoke-retry-classifier.test.ts` (36 tests passed)
- `npx biome check src/lib/onboard/compatible-endpoint-smoke.ts
src/lib/onboard/compatible-endpoint-smoke.test.ts`
- `npm run typecheck:cli`
- `git diff --check`
- Normal commit and push hooks passed, including the full CLI suite,
repository checks, and secret scanning.
- Token rotation reused-sandbox runtime:
https://github.com/NVIDIA/NemoClaw/actions/runs/28327364831 (success).
- Hermes dashboard runtime:
https://github.com/NVIDIA/NemoClaw/actions/runs/28328424431 (success).

Post-merge review findings addressed from NVIDIA#5932:
- Curl-exit retry acceptance coverage: transient exits 6, 7, 28, 52, 55,
and 56 recover on attempt two; permanent exit 2 makes exactly one
request.
- Curl stderr security: stderr is suppressed at the external boundary
and only the numeric exit is reported.
- Retry classification: only explicit transient transport codes, HTTP
5xx, and reasoning-budget exhaustion retry; HTTP 429 remains
single-shot.
- HTTP classification: status comes from curl metadata rather than
fragile HTML matching.
- Retry timing: 5s/10s backoff and its 225-second parent budget are
derived from shared constants.

---
<!-- DCO sign-off is required in this PR description, and every commit
must appear as Verified in GitHub. Run: git config user.name && git
config user.email -->
Signed-off-by: Carlos Villela <cvillela@nvidia.com>


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Bug Fixes**
* Improved compatible-endpoint smoke verification with more
deterministic HTTP-status handling to classify retries vs terminal
failures, including clearer retry timing and faster exits for
non-retryable outcomes.

* **Tests**
  * Expanded smoke-test coverage for retry behavior:
    * Transient HTTP 5xx responses now retry and succeed.
    * HTTP 429 responses no longer retry.
* Added scenarios for multiple transient curl exit codes (retries
succeed) and terminal exit codes (fails immediately).
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Signed-off-by: Carlos Villela <cvillela@nvidia.com>
Hadar301 pushed a commit to Hadar301/NemoClaw-OpenShift that referenced this pull request Jul 12, 2026
## Summary
Adds the v0.0.69 release notes to the published release-notes page so
users can see the shipped sandbox recovery, Deep Agents Code, Hermes,
inference, policy, and release-validation changes.
The section is based on the v0.0.69 announcement and links each
user-facing theme to the deeper docs pages that already cover the
behavior.

## Changes
- Added a new `v0.0.69` section to `docs/about/release-notes.mdx`.
- Linked release-note themes to lifecycle, backup, troubleshooting, Deep
Agents Code, commands, workspace, messaging, Hermes, inference,
security, monitoring, and network-policy docs.

Source summary:
- NVIDIA#5455 -> `docs/about/release-notes.mdx`: Summarized persistent
workspace and state cleanup during sandbox destroy.
- NVIDIA#5738 -> `docs/about/release-notes.mdx`: Summarized nonzero exit
status preservation for failed hosted endpoint validation.
- NVIDIA#5786 -> `docs/about/release-notes.mdx`: Summarized live sandbox
rediscovery when local registry state is missing.
- NVIDIA#5881 -> `docs/about/release-notes.mdx`: Summarized the
`nemo-deepagents` alias command surface.
- NVIDIA#5594 -> `docs/about/release-notes.mdx`: Summarized the Hermes Agent
2026.6.19 update.
- NVIDIA#5777 -> `docs/about/release-notes.mdx`: Summarized manifest-derived
messaging channel support.
- NVIDIA#5825 -> `docs/about/release-notes.mdx`: Summarized DeepSeek V4 Flash
managed-vLLM defaults for DGX Station.
- NVIDIA#5877 -> `docs/about/release-notes.mdx`: Summarized provider switch
metadata preservation.
- NVIDIA#5932 -> `docs/about/release-notes.mdx`: Summarized transient
inference smoke retry behavior.
- NVIDIA#5934 -> `docs/about/release-notes.mdx`: Summarized constrained
inference smoke retry boundaries.
- NVIDIA#5681 -> `docs/about/release-notes.mdx`: Summarized Shields
config-hash sealing during auto-restore.
- NVIDIA#5682 -> `docs/about/release-notes.mdx`: Summarized sandbox connect
process-limit enforcement.
- NVIDIA#5683 -> `docs/about/release-notes.mdx`: Summarized JSON agent failure
provenance warnings.
- NVIDIA#5711 -> `docs/about/release-notes.mdx`: Summarized sparse-source log
breadcrumbs.
- NVIDIA#5838 -> `docs/about/release-notes.mdx`: Summarized host-authoritative
Shields status.
- NVIDIA#5880 -> `docs/about/release-notes.mdx`: Summarized policy round-trip
documentation updates.
- NVIDIA#5886 -> `docs/about/release-notes.mdx`: Summarized network request
approval-flow documentation updates.

## Type of Change

- [ ] Code change (feature, bug fix, or refactor)
- [ ] Code change with doc updates
- [x] Doc only (prose changes, no code sample modifications)
- [ ] Doc only (includes code sample changes)

## Quality Gates
- [ ] Tests added or updated for changed behavior
- [ ] Existing tests cover changed behavior — justification:
- [x] Tests not applicable — justification: doc-only release-notes
prose; no runtime behavior changed.
- [x] Docs updated for user-facing behavior changes
- [ ] Docs not applicable — justification:
- [ ] Sensitive paths changed (security, policy, credentials, preflight,
onboarding, inference, runner, sandbox, or messaging)
- [ ] Sensitive-path review completed or maintainer-approved waiver
recorded — reviewer/approval link/justification:
- [ ] Non-success, skipped, or missing CI check accepted by maintainer —
check name, approval link, and follow-up issue:

## Verification
- [x] PR description includes the DCO sign-off declaration and every
commit appears as `Verified` in GitHub
- [x] Git hooks passed during commit and push, or `npx prek run
--from-ref main --to-ref HEAD` passes
- [ ] Targeted tests pass for changed behavior
- [ ] Full `npm test` passes (broad runtime changes only)
- [x] Quality Gates section completed with required justifications or
waivers
- [x] No secrets, API keys, or credentials committed
- [ ] `npm run docs` builds without warnings (doc changes only)
- [x] Doc pages follow the [style
guide](https://github.com/NVIDIA/NemoClaw/blob/main/docs/CONTRIBUTING.md)
(doc changes only)
- [ ] New doc pages include SPDX header and frontmatter (new pages only)

`npm run docs` passed with 0 errors and the existing Fern light-mode
accent contrast warning.
`fern check --warnings` reported the same accent-color warning.

---
Signed-off-by: Miyoung Choi <miyoungc@nvidia.com>

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

* **Documentation**
* Added release notes for **v0.0.69**, covering improved sandbox
lifecycle recovery (state preservation across
destroy/recreate/rebuild/recovery/validation failures), clearer Deep
Agents Code terminal/CLI behavior, and safer Hermes messaging/provider
switching with manifest-driven channels.
* Improved inference setup validation guidance, including handling of
local/compatible endpoints and redaction of sensitive validation errors.
* Refreshed release-gate documentation with clearer approval examples
and validation behavior for NVIDIA API keys vs hosted inference keys.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
@wscurran wscurran added area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow bug-fix PR fixes a bug or regression labels Aug 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area: onboarding Onboarding FSM, provider setup, sandbox launch, or first-run flow bug-fix PR fixes a bug or regression

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants