Skip to content

refactor(network): standardize HTTP operations on async reqwest (#496) - #548

Merged
yacosta738 merged 3 commits into
mainfrom
refactor/496-async-http
Aug 11, 2026
Merged

yacosta738 merged 3 commits into
mainfrom
refactor/496-async-http

Conversation

@yacosta738

Copy link
Copy Markdown
Contributor

Description

Standardizes all HTTP operations on async reqwest, eliminating reqwest::blocking from the codebase. This removes blocking HTTP from the Tokio runtime, improving scheduler efficiency and aligning with the existing bridge pattern in install.rs.

Fixes #496

Changes

  • src/update_check.rs: fetch_latest_version() converted to async with new UpdateCheckError enum carrying useful context (timeout duration, URL, HTTP status). Background spawn now uses tokio::spawn instead of std::thread.
  • src/skills/provider.rs: resolve_via_search() now uses async reqwest::Client via the bridge pattern (Handle::try_current() + Runtime::new() fallback), mirroring install.rs:244-253.
  • tests/test_catalog_integrity.rs: Converted to #[tokio::test] with async client.
  • Cargo.toml: Removed blocking feature from reqwest.

Acceptance Criteria

  • No blocking HTTP runs inside the Tokio runtime
  • Timeouts and HTTP errors carry useful context (URL, duration, status)
  • Tests cover success, timeout, and invalid response cases
  • Any operation that must stay synchronous is documented (cache file I/O noted)

Type of change

  • Refactor (non-breaking change)

How Has This Been Tested?

  • cargo test --all-features — 575 lib tests + 185 integration tests pass
  • cargo clippy --all-targets --all-features -- -D warnings — clean
  • cargo fmt --all -- --check — clean
  • SDD verify: PASS (16/16 correctness items)
  • SDD QA: PASS (14/14 capability tests)

Test Configuration:

  • OS: macOS
  • Rust version: 1.89
  • Test command: cargo test --all-features

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation (openspec specs updated)
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules

Convert reqwest::blocking to async reqwest across the network layer:
- update_check.rs: async fetch_latest_version with UpdateCheckError carrying timeout/connection/status context; spawn via tokio instead of std thread
- skills/provider.rs: resolve_via_search via bridge pattern (Handle::try_current + Runtime::new fallback), mirroring install.rs
- test_catalog_integrity.rs: #[tokio::test] with async client
- Cargo.toml: remove blocking feature from reqwest

Closes #496
@coderabbitai

coderabbitai Bot commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@yacosta738, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 9 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 9318edef-84b7-4c69-89a5-50fe7369b663

📥 Commits

Reviewing files that changed from the base of the PR and between 5019498 and 4acc40b.

📒 Files selected for processing (2)
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/proposal.md
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/tasks.md
📝 Walkthrough

Summary by CodeRabbit

  • New Features

    • Improved asynchronous network requests for update checks, skill searches, and catalog validation.
    • Added clearer diagnostics for timeouts, connection failures, invalid responses, and HTTP errors.
    • Update checks now run in the background without delaying normal CLI startup.
  • Bug Fixes

    • Improved catalog integrity checks and retry reliability.
    • Update-check failures remain non-disruptive to CLI use.
  • Tests

    • Added coverage for asynchronous requests, timeouts, invalid JSON, and HTTP errors.
  • Documentation

    • Added specifications, implementation plans, verification reports, and QA records.

Walkthrough

The refactor replaces blocking Reqwest calls with asynchronous clients. It adds Tokio runtime bridging, structured update-check errors, asynchronous retries and tests, removes the blocking feature, and records the specifications and verification results.

Changes

Async HTTP refactor

Layer / File(s) Summary
Async HTTP contracts and execution plan
openspec/changes/archive/.../{design,exploration,proposal}.md, openspec/specs/{version-check,skill-recommendations,dependency-management,e2e-testing}/spec.md
Defines async Reqwest usage, Tokio bridging, structured errors, synchronous boundaries, test scenarios, and rollout requirements.
Provider search runtime bridge
src/skills/provider.rs, openspec/specs/skill-recommendations/spec.md
Uses async skills.sh requests with timeout handling, runtime reuse or fallback, contextual errors, and failure tests.
Asynchronous update checks
src/update_check.rs
Adds UpdateCheckError, async crates.io requests, Tokio execution, documented synchronous cache I/O, and failure-case tests.
Async catalog checks and dependency cleanup
Cargo.toml, tests/test_catalog_integrity.rs, openspec/specs/{dependency-management,e2e-testing}/spec.md
Removes Reqwest’s blocking feature and converts catalog requests and retry delays to async operations.
Specification and verification records
openspec/changes/archive/.../{archive-report,qa-report,verify-report,state.yaml,tasks.md}, .atl/skill-registry.md
Records implementation scope, QA scenarios, verification results, archived state, completed work items, and project metadata.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant CLI
  participant TokioRuntime
  participant ReqwestClient
  participant HTTPServer
  CLI->>TokioRuntime: start async operation
  TokioRuntime->>ReqwestClient: send timed request
  ReqwestClient->>HTTPServer: HTTP request
  HTTPServer-->>ReqwestClient: response or failure
  ReqwestClient-->>TokioRuntime: parsed result or contextual error
  TokioRuntime-->>CLI: continue synchronously or log failure
Loading

Poem

A rabbit hops through async streams,
While Tokio guards the request dreams.
No blocking gates remain in sight,
Errors wear their names just right.
Tests retry, timeout, and cheer—
The HTTP path is bright and clear!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main change: standardizing HTTP operations on asynchronous reqwest.
Description check ✅ Passed The description directly explains the async HTTP refactor, dependency changes, tests, and acceptance criteria.
Linked Issues check ✅ Passed The changes address issue #496 by removing blocking reqwest usage, adding contextual errors, converting tests, and documenting synchronous I/O.
Out of Scope Changes check ✅ Passed The code and specification changes support the async HTTP refactor and its documented requirements; no unrelated changes are evident.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch refactor/496-async-http

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@codecov

codecov Bot commented Aug 11, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 81.48148% with 60 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/skills/provider.rs 74.30% 37 Missing ⚠️
src/update_check.rs 87.22% 23 Missing ⚠️

📢 Thoughts on this report? Let us know!

@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: 16

🤖 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
`@openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/archive-report.md`:
- Around line 32-38: Add blank lines before and after the affected Markdown
headings in
openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/archive-report.md
(lines 32-38); add blank lines after ## Identity, ## Sources of Truth, and ##
Target and Environment in
openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/qa-report.md
(lines 3-18); and add a blank line after ### Implementation Order in
openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/tasks.md
(lines 19-20) to satisfy MD022.
- Around line 27-35: Correct the archived update-check documentation to match
the implementation: in the version-check change summary and
specs/version-check/spec.md, describe the detached background thread using
std::thread::Builder, a created tokio runtime, and block_on. Remove claims that
it uses tokio::spawn or implicit naming, while preserving the other async HTTP
changes.

In `@openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/design.md`:
- Line 89: Resolve the Markdown-lint findings across the documentation: in
openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/design.md:89,
specify a language on the data-flow fenced block; in exploration.md:1, make the
opening heading top-level; and in proposal.md:9, add the required spacing after
the heading marker.
- Around line 39-63: Align all version-check specifications with the dedicated
Tokio Runtime created inside the detached thread by update_check::spawn, using
Runtime::block_on rather than tokio::spawn, and document runtime ownership, task
lifetime, cancellation, and shutdown behavior. Update
openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/design.md:39-63,
exploration.md:174-180, proposal.md:25-31, specs/version-check/spec.md:50-72,
and openspec/specs/version-check/spec.md:61-83; remove contradictory spawn-model
requirements and state that spawning occurs after Cli::parse as implemented by
main.rs.
- Around line 65-85: Complete structured HTTP error handling around
UpdateCheckError, fetch_latest_version, and resolve_via_search_http: map
redirect errors before generic connection errors, include the request URL in
ParseError, and call error_for_status() before JSON parsing. In
openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/design.md
lines 65-85 and 120-142, document URL, duration, reason, and status fields plus
redirect and parse scenarios. Apply the corresponding documentation updates in
openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/specs/version-check/spec.md
lines 5-13 and openspec/specs/version-check/spec.md lines 156-193.

In
`@openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/exploration.md`:
- Around line 91-97: Update the Tokio dependency feature list to include time,
preserving the existing rt-multi-thread, macros, and fs features so tests such
as test_catalog_integrity.rs can use tokio::time::sleep.

In
`@openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/proposal.md`:
- Around line 96-104: Update the Success Criteria command for the E2E test to
explicitly set RUN_E2E=1 when invoking cargo test, ensuring the gated catalog
integrity test executes rather than being skipped.

In
`@openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/qa-report.md`:
- Line 47: Update the QA-7 row in the QA report so its evidence describes the
resolve_via_search_http error context without unescaped pipe characters, either
by rewording the closure reference or escaping both pipes; preserve the table’s
five-cell structure.

In
`@openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/state.yaml`:
- Around line 19-33: Update state.yaml to reflect the completed archived change:
add Cargo.toml to scope, and rewrite the summary and Affected entries for
update_check.rs, skills/provider.rs, test_catalog_integrity.rs, and Cargo.toml
in past/completed tense, removing descriptions of the old blocking
implementation and pending “must be removed” work.

In `@openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/tasks.md`:
- Around line 24-35: Update task 1.1 so its listed UpdateCheckError variants and
payloads match the final contract documented in verify-report.md, including
Connection with url and reason, HttpStatus with url and status, and Timeout with
url and duration_secs; alternatively, explicitly document the intentional
deviation if the implementation deliberately retains the current reqwest-based
variants.

In
`@openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/verify-report.md`:
- Around line 103-112: Remove the stale State.yaml current_phase finding from
the correctness table and Issues section in the verification report, updating
both to reflect current_phase: archive with sdd-verify and sdd-archive
completed.
- Around line 41-46: Update the success scenario in the verification report to
reference a test that exercises fetch_latest_version_async and asserts the
expected version from a successful response, rather than
test_fetch_latest_version_timeout. Add that success-path test if none exists,
and keep the timeout test cited only for the timeout scenario.
- Around line 62-70: The e2e-testing table in the verification report
incorrectly marks unexecuted scenarios as passing. Update the five scenario
statuses to untested or conditional unless live execution was performed, and
only mark them PASS when accompanied by output from the test_catalog_integrity
command with RUN_E2E=1.

In `@src/skills/provider.rs`:
- Around line 294-309: Remove the active-runtime Handle::block_on path from
SkillsShProvider::resolve: add separate async and synchronous resolution entry
points, have async callers await the async path, and let the synchronous path
create a temporary runtime only when no runtime is active. Add a #[tokio::test]
covering public resolution, and update src/skills/provider.rs:294-309,
openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/specs/skill-recommendations/spec.md:7-10,
and openspec/specs/skill-recommendations/spec.md:905-910 to remove the
handle.block_on requirement and document both paths.
- Around line 323-330: Update the skills.sh request flow in the visible
SearchResponse fetch to call error_for_status() on the response before JSON
parsing, preserving contextual error handling for failed requests. Add a test
covering 4xx or 5xx responses and verify the resulting error reflects the HTTP
failure rather than a JSON parsing or not-found error.

In `@src/update_check.rs`:
- Around line 146-149: Update the response parsing in the update-check request
around the `response.json().await` call to map errors where `e.is_timeout()` is
true to `UpdateCheckError::Timeout`, while retaining `ParseError` for other
failures. Add a test that sends response headers, stalls the body, and verifies
the configured client timeout produces `UpdateCheckError::Timeout`.
🪄 Autofix

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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ab8e046e-a1c1-4020-a553-64ed4749c3f6

📥 Commits

Reviewing files that changed from the base of the PR and between 50463af and beb6dd0.

⛔ Files ignored due to path filters (1)
  • Cargo.lock is excluded by !**/*.lock
📒 Files selected for processing (20)
  • Cargo.toml
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/archive-report.md
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/design.md
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/exploration.md
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/proposal.md
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/qa-report.md
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/specs/dependency-management/spec.md
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/specs/e2e-testing/spec.md
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/specs/skill-recommendations/spec.md
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/specs/version-check/spec.md
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/state.yaml
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/tasks.md
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/verify-report.md
  • openspec/specs/dependency-management/spec.md
  • openspec/specs/e2e-testing/spec.md
  • openspec/specs/skill-recommendations/spec.md
  • openspec/specs/version-check/spec.md
  • src/skills/provider.rs
  • src/update_check.rs
  • tests/test_catalog_integrity.rs

Comment on lines +32 to +38
### version-check — Changes Applied
- `crates.io API Query`: MODIFIED — async client replaces blocking, HTTP errors carry diagnostic context
- `Detached Background Thread`: MODIFIED — Tokio spawn replaces std::thread, implicit naming
- `Synchronous Path Documentation`: ADDED (new requirement) — cache I/O documented with `// Note: sync path`

### skill-recommendations — Changes Applied
- `Provider Skill Resolution Uses Async HTTP`: ADDED — resolve_via_search uses async reqwest with bridge pattern, all HTTP errors carry context

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.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add blank lines around the affected Markdown headings.

markdownlint reports MD022 in all three files.

  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/archive-report.md#L32-L38: add blank lines before and after the affected headings.
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/qa-report.md#L3-L18: add blank lines after ## Identity, ## Sources of Truth, and ## Target and Environment.
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/tasks.md#L19-L20: add a blank line after ### Implementation Order.
🧰 Tools
🪛 markdownlint-cli2 (0.23.2)

[warning] 32-32: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)


[warning] 37-37: Headings should be surrounded by blank lines
Expected: 1; Actual: 0; Below

(MD022, blanks-around-headings)

📍 Affects 3 files
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/archive-report.md#L32-L38 (this comment)
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/qa-report.md#L3-L18
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/tasks.md#L19-L20
🤖 Prompt for 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.

In
`@openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/archive-report.md`
around lines 32 - 38, Add blank lines before and after the affected Markdown
headings in
openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/archive-report.md
(lines 32-38); add blank lines after ## Identity, ## Sources of Truth, and ##
Target and Environment in
openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/qa-report.md
(lines 3-18); and add a blank line after ### Implementation Order in
openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/tasks.md
(lines 19-20) to satisfy MD022.

Source: Linters/SAST tools

Comment thread openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/design.md Outdated
Comment thread openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/design.md Outdated
Comment on lines +62 to +70
### e2e-testing (5 scenarios)

| Scenario | Covered By | Status |
|----------|-----------|--------|
| All curated entries reachable — async client | `test_catalog_integrity.rs` uses `#[tokio::test]` + `reqwest::Client` | ✅ PASS |
| Retry on transient failure with async client | `send_request().await` + `tokio::time::sleep` retry logic | ✅ PASS |
| Timeout on slow endpoint with context | `client.builder().timeout(Duration::from_secs(15))` + failures list with context | ✅ PASS |
| Non-200 HTTP response carries status context | failure message includes `r.status()` | ✅ PASS |
| Network error carries diagnostic context | failure message includes `e` (error Debug impl) | ✅ PASS |

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.

🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- candidate files ---'
fd -i 'qa-report.md|verify-report.md|state.yaml|test_catalog_integrity.rs' . || true

printf '%s\n' '--- relevant report references ---'
rg -n -C 5 'e2e-testing|catalog integrity|RUN_E2E|untested|not selected|PASS|current_phase|archive|propose' \
  openspec/changes/archive/2026-08-11-issue-496-async-http-refactor \
  --glob 'qa-report.md' --glob 'verify-report.md' --glob 'state.yaml' || true

printf '%s\n' '--- test implementation and invocation references ---'
rg -n -C 5 'test_catalog_integrity|RUN_E2E|reqwest::Client|send_request|tokio::time::sleep|timeout|GITHUB_TOKEN' \
  . --glob '*.rs' --glob '*.md' --glob '*.yaml' --glob '*.yml' || true

Repository: dallay/agentsync

Length of output: 50375


🏁 Script executed:

#!/bin/bash
set -eu

for f in \
  openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/qa-report.md \
  openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/verify-report.md \
  openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/state.yaml
do
  if [ -f "$f" ]; then
    printf '\n--- %s ---\n' "$f"
    cat -n "$f"
  fi
done

printf '\n--- test files ---\n'
fd -i 'test_catalog_integrity.rs' . -x sh -c 'echo "--- $1"; cat -n "$1"' sh {}

Repository: dallay/agentsync

Length of output: 24851


🏁 Script executed:

#!/bin/bash
set -eu
find openspec/changes/archive/2026-08-11-issue-496-async-http-refactor -maxdepth 1 -type f -print
printf '\n--- qa report ---\n'
sed -n '1,220p' openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/qa-report.md
printf '\n--- verify report ---\n'
sed -n '1,140p' openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/verify-report.md

Repository: dallay/agentsync

Length of output: 17422


🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- E2E execution evidence and commands ---'
rg -n -C 3 \
  'RUN_E2E|test_catalog_integrity|catalog_dallay_skill_urls_are_reachable|--ignored|running [0-9]+ tests|test result' \
  openspec/changes/archive/2026-08-11-issue-496-async-http-refactor \
  README.md \
  tests/test_catalog_integrity.rs

printf '%s\n' '--- source-derived test attributes ---'
python3 - <<'PY'
from pathlib import Path
p = Path("tests/test_catalog_integrity.rs")
lines = p.read_text().splitlines()
for i, line in enumerate(lines, 1):
    if "#[test]" in line or "#[tokio::test]" in line or "#[ignore]" in line or "RUN_E2E" in line:
        print(f"{i}: {line}")
PY

Repository: dallay/agentsync

Length of output: 39586


Do not mark unexecuted E2E scenarios as PASS.

qa-report.md marks live catalog-integrity execution as not selected and untested. verify-report.md provides no E2E execution output and marks all five scenarios PASS based on source references. If the test was not run, mark these scenarios untested or conditional. Otherwise, include output from RUN_E2E=1 GITHUB_TOKEN=... cargo test --test test_catalog_integrity -- --nocapture.

🤖 Prompt for 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.

In
`@openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/verify-report.md`
around lines 62 - 70, The e2e-testing table in the verification report
incorrectly marks unexecuted scenarios as passing. Update the five scenario
statuses to untested or conditional unless live execution was performed, and
only mark them PASS when accompanied by output from the test_catalog_integrity
command with RUN_E2E=1.

Comment thread src/skills/provider.rs
Comment on lines +294 to +309
match tokio::runtime::Handle::try_current() {
Ok(handle) => handle.block_on(resolve_via_search_http(
&url,
std::time::Duration::from_secs(10),
id,
)),
Err(_) => {
let rt = tokio::runtime::Runtime::new()
.map_err(|e| anyhow::anyhow!("failed to create runtime: {}", e))?;
rt.block_on(resolve_via_search_http(
&url,
std::time::Duration::from_secs(10),
id,
))
}
}

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.

🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- provider.rs relevant symbols and call sites ---'
rg -n -C 8 'resolve_via_search|Handle::try_current|block_on|resolve' src/skills/provider.rs

printf '%s\n' '--- related provider-resolution call sites ---'
rg -n -C 5 'resolve_via_search|resolve_provider|provider.*resolve|skill.*provider' src tests openspec 2>/dev/null | head -n 500

printf '%s\n' '--- specification sections ---'
sed -n '1,30p' openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/specs/skill-recommendations/spec.md
sed -n '895,920p' openspec/specs/skill-recommendations/spec.md

Repository: dallay/agentsync

Length of output: 46779


🌐 Web query:

Tokio Handle::block_on panics called within asynchronous execution context documentation current behavior

💡 Result:

Calling Tokio's Handle::block_on from within an asynchronous execution context causes the thread to panic [1][2][3]. This behavior is explicitly documented as a safety mechanism to prevent blocking an executor thread, which could lead to deadlocks or runtime instability [4]. According to the official documentation, the panic occurs if the method is called from within an asynchronous context, such as inside another Runtime::block_on, Handle::block_on, or from a function annotated with #[tokio::main] [1][2][5]. The runtime enforces this to ensure that asynchronous tasks do not block the worker threads responsible for driving other asynchronous operations [4]. If you need to execute blocking code or block the current thread to wait for a future within an asynchronous context, the recommended alternative is to use tokio::task::block_in_place [6][7]. This function informs the executor that the current task is about to block, allowing the executor to potentially hand off remaining tasks to other worker threads while the current thread is occupied [7]. Once inside a block_in_place closure, it is safe to use Handle::block_on to re-enter the asynchronous context if necessary [7]. Top results: [1], [2], [7], [4], [3]

Citations:


🏁 Script executed:

#!/bin/bash
set -eu

printf '%s\n' '--- Cargo Tokio configuration ---'
rg -n -C 3 'tokio|reqwest' Cargo.toml Cargo.lock

printf '%s\n' '--- full SkillsShProvider implementation and public provider API ---'
sed -n '230,410p' src/skills/provider.rs

printf '%s\n' '--- provider tests around all resolution paths ---'
sed -n '1,260p' tests/unit/provider.rs
sed -n '410,520p' src/skills/provider.rs

printf '%s\n' '--- async contexts calling synchronous recommendation/install APIs ---'
rg -n -C 8 '#\[tokio::test\]|async fn|install_selected_with|install_all|provider\.resolve\(' src tests -g '*.rs' | head -n 700

printf '%s\n' '--- archived and active specification references ---'
rg -n -C 4 'bridge pattern|handle\.block_on|try_current|Provider Skill Resolution Uses Async HTTP|resolve_via_search' openspec

Repository: dallay/agentsync

Length of output: 50373


Remove the active-runtime Handle::block_on() path.

SkillsShProvider::resolve() is synchronous, but its search path calls Handle::block_on() when Handle::try_current() succeeds. Tokio panics when Handle::block_on() runs inside an asynchronous execution context. Split resolution into async and synchronous entry points. Async callers must await the async path. The synchronous path may create and use a temporary runtime only when no runtime is active. Add a #[tokio::test] for the public resolution path, and update both specifications to remove the handle.block_on() requirement and define the async and synchronous paths.

📍 Affects 3 files
  • src/skills/provider.rs#L294-L309 (this comment)
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/specs/skill-recommendations/spec.md#L7-L10
  • openspec/specs/skill-recommendations/spec.md#L905-L910
🤖 Prompt for 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.

In `@src/skills/provider.rs` around lines 294 - 309, Remove the active-runtime
Handle::block_on path from SkillsShProvider::resolve: add separate async and
synchronous resolution entry points, have async callers await the async path,
and let the synchronous path create a temporary runtime only when no runtime is
active. Add a #[tokio::test] covering public resolution, and update
src/skills/provider.rs:294-309,
openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/specs/skill-recommendations/spec.md:7-10,
and openspec/specs/skill-recommendations/spec.md:905-910 to remove the
handle.block_on requirement and document both paths.

Comment thread src/skills/provider.rs
Comment thread src/update_check.rs Outdated

@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

♻️ Duplicate comments (1)
openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/tasks.md (1)

30-33: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Correct the HttpStatus test contract.

Line 32 uses the obsolete tuple-style variant. The recorded contract on line 26 and the implementation use UpdateCheckError::HttpStatus { url, status }.

Proposed fix
-- [x] 2.3 RED: Add test — `test_fetch_latest_version_404` returns HTTP 404, expects `UpdateCheckError::HttpStatus(404)`
+- [x] 2.3 RED: Add test — `test_fetch_latest_version_404` returns HTTP 404, expects `UpdateCheckError::HttpStatus { status: 404, .. }`
🤖 Prompt for 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.

In `@openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/tasks.md`
around lines 30 - 33, Update the `test_fetch_latest_version_404` expectation to
use the struct-style `UpdateCheckError::HttpStatus { url, status }` variant,
matching the contract and implementation. Preserve the existing 404 status
assertion and provide the expected request URL in the pattern.
🤖 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 @.atl/skill-registry.md:
- Around line 31-32: Update the registry entries for HTTP, Tokio, and relevant
code paths to reflect the async implementation: remove stale reqwest::blocking
references, add Tokio’s time feature, and document the runtime bridges used by
the async flows.

In
`@openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/proposal.md`:
- Around line 57-59: Update the `Cargo.toml` section in the proposal by adding a
blank line immediately after the `#### 4. Cargo.toml` heading and another blank
line before the TOML code fence.

---

Duplicate comments:
In `@openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/tasks.md`:
- Around line 30-33: Update the `test_fetch_latest_version_404` expectation to
use the struct-style `UpdateCheckError::HttpStatus { url, status }` variant,
matching the contract and implementation. Preserve the existing 404 status
assertion and provide the expected request URL in the pattern.
🪄 Autofix

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: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 11795914-ea1a-48c7-b0ee-079e331c27bf

📥 Commits

Reviewing files that changed from the base of the PR and between beb6dd0 and 5019498.

📒 Files selected for processing (16)
  • .atl/skill-registry.md
  • Cargo.toml
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/archive-report.md
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/design.md
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/exploration.md
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/proposal.md
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/qa-report.md
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/specs/dependency-management/spec.md
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/specs/version-check/spec.md
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/state.yaml
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/tasks.md
  • openspec/changes/archive/2026-08-11-issue-496-async-http-refactor/verify-report.md
  • openspec/specs/dependency-management/spec.md
  • openspec/specs/version-check/spec.md
  • src/skills/provider.rs
  • src/update_check.rs

Comment thread .atl/skill-registry.md
Comment on lines +31 to +32
| HTTP | reqwest 0.13 (blocking feature present) |
| Async runtime | Tokio (rt-multi-thread, macros, fs) |

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.

🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

rg -n 'reqwest\s*=|tokio\s*=' Cargo.toml
rg -n 'reqwest::blocking|reqwest::Client|tokio::time::sleep|Handle::try_current|Runtime::new' src tests
rg -n 'blocking feature present|reqwest::blocking|Tokio \(' .atl/skill-registry.md

Repository: dallay/agentsync

Length of output: 1675


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '--- registry ---'
cat -n .atl/skill-registry.md | sed -n '24,60p'

printf '%s\n' '--- update_check ---'
cat -n src/update_check.rs | sed -n '90,135p;190,225p'

printf '%s\n' '--- provider ---'
cat -n src/skills/provider.rs | sed -n '275,335p'

printf '%s\n' '--- catalog test ---'
cat -n tests/test_catalog_integrity.rs | sed -n '1,95p'

printf '%s\n' '--- all relevant dependency/API references ---'
rg -n 'reqwest::blocking|reqwest::Client|tokio::time::sleep|Handle::try_current|Runtime::new|blocking feature present|Tokio \(' Cargo.toml src tests .atl/skill-registry.md

Repository: dallay/agentsync

Length of output: 12930


Update the registry to match the async implementation.

Change the HTTP, Tokio, and relevant code-path entries to remove stale reqwest::blocking references, document the Tokio time feature, and describe the runtime bridges.

🤖 Prompt for 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.

In @.atl/skill-registry.md around lines 31 - 32, Update the registry entries for
HTTP, Tokio, and relevant code paths to reflect the async implementation: remove
stale reqwest::blocking references, add Tokio’s time feature, and document the
runtime bridges used by the async flows.

@sonarqubecloud

Copy link
Copy Markdown

@yacosta738
yacosta738 merged commit 1839fe0 into main Aug 11, 2026
28 of 29 checks passed
@yacosta738
yacosta738 deleted the refactor/496-async-http branch August 11, 2026 20:32
@dallay-bot dallay-bot Bot mentioned this pull request Aug 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

refactor(network): standardize HTTP operations on async reqwest

1 participant