Skip to content

perf: bound file IO concurrency - #1948

Merged
kevincodex1 merged 3 commits into
Twigpine:mainfrom
GautamBytes:perf/bounded-fs-concurrency
Jul 14, 2026
Merged

kevincodex1 merged 3 commits into
Twigpine:mainfrom
GautamBytes:perf/bounded-fs-concurrency

Conversation

@GautamBytes

@GautamBytes GautamBytes commented Jul 12, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Impact

  • user-facing impact: less IO pressure in large repos or large team-memory dirs; no intended behavior change.
  • developer/maintainer impact: focused helper + tests for concurrency and abort behavior.

Summary by CodeRabbit

  • New Features
    • Added abort-aware bounded async utilities to limit concurrent async work and fail fast on cancellation.
    • Introduced bounded, dependency-injected attachment and team-memory sync processing.
  • Bug Fixes
    • Prevented unsafe path traversal during team memory synchronization.
    • Ensured secret-containing items are excluded deterministically, including after secret filtering.
    • Improved cancellation behavior so aborted operations stop cleanly and propagate aborts consistently.
  • Performance
    • Reduced load spikes by enforcing concurrency caps for filesystem-heavy attachment and sync tasks.
  • Tests
    • Added concurrency, determinism, and performance “contract” tests for attachments, team memory sync, and bounded async helpers.

Copilot AI review requested due to automatic review settings July 12, 2026 14:38

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@coderabbitai

coderabbitai Bot commented Jul 12, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Changes

Bounded file I/O

Layer / File(s) Summary
Concurrency and abort primitives
src/utils/boundedAsync.ts, src/utils/boundedAsync.test.ts
Adds ordered bounded mapping and abort-aware promise racing, with tests covering concurrency, ordering, validation, cancellation, and rejection behavior.
Abort-aware attachment processing
src/utils/attachments.ts, src/utils/attachments.performance.test.ts
Applies bounded concurrency and abort propagation to attachment producers, at-mentioned files, and changed-file processing with dependency-injected filesystem operations.
Bounded team memory synchronization
src/services/teamMemorySync/index.ts, src/services/teamMemorySync/index.test.ts
Adds dependency-injected, bounded local reads and remote writes while retaining secret filtering, deterministic truncation, size limits, and path validation tests.

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

Suggested reviewers: kevincodex1, jatmn

🚥 Pre-merge checks | ✅ 6 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (6 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: bounding file I/O concurrency.
Description check ✅ Passed The description matches the template's key sections and clearly states the summary and impact.
Linked Issues check ✅ Passed The changes implement bounded concurrency and tests for the four requested file-IO paths while preserving the listed behaviors.
Out of Scope Changes check ✅ Passed The diff stays focused on bounded file I/O, shared async helpers, and tests, with no obvious unrelated changes.
Risk Surface Disclosed ✅ Passed It only changes bounded file-I/O in attachments/team-memory; none of the listed risk surfaces are touched, so no blocker disclosure was needed.
No Hidden Policy Change ✅ Passed Only bounded-concurrency/abort plumbing changed; permission checks, OAuth gating, secret scanning, and telemetry fields remain intact.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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.

@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/utils/attachments.ts`:
- Around line 1068-1075: Update the attachment helper maybe so it checks the
optional AbortSignal with throwIfAborted() before evaluating or invoking the
producer f, then passes the signal to raceAbort as before. Preserve existing
result and timeout handling, and add or update tests verifying a pre-aborted
signal rejects without invoking f.

In `@src/utils/boundedAsync.ts`:
- Around line 66-80: Update the worker loop in boundedAsync so the first mapper
rejection records shared failure state before rethrowing, and make workers stop
claiming queued items once that state is set. Preserve abort handling and
successful scheduling behavior, then add focused regression coverage proving
queued mapper work does not start after the first rejection.
🪄 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: ASSERTIVE

Plan: Pro

Run ID: ce310d81-9c06-4b08-a3c2-6be1668345d3

📥 Commits

Reviewing files that changed from the base of the PR and between 2448ea9 and 49f85ac.

📒 Files selected for processing (6)
  • src/services/teamMemorySync/index.test.ts
  • src/services/teamMemorySync/index.ts
  • src/utils/attachments.performance.test.ts
  • src/utils/attachments.ts
  • src/utils/boundedAsync.test.ts
  • src/utils/boundedAsync.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

TypeScript code in this repository must use strict mode and ESM imports.

Files:

  • src/services/teamMemorySync/index.test.ts
  • src/utils/boundedAsync.ts
  • src/utils/attachments.performance.test.ts
  • src/utils/boundedAsync.test.ts
  • src/services/teamMemorySync/index.ts
  • src/utils/attachments.ts
**

⚙️ CodeRabbit configuration file

**: # AGENTS.md - AI Agent Coding Guide

This guide is for AI coding agents working in the OpenClaude repository. Read it before changing code, and also follow CONTRIBUTING.md for contributor policy, PR expectations, review follow-up, and project scope.

Project Snapshot

OpenClaude is a coding-agent CLI for cloud and local model providers. It supports OpenAI-compatible APIs, Anthropic, Gemini, DeepSeek, Ollama, MCP, local backends, slash commands, tools, agents, and a React/Ink terminal UI.

The installed CLI runs on Node.js >=22.0.0. Bun is used for source builds, scripts, dependency management, and tests.

Work Style

  • Keep changes focused on one problem.
  • Prefer existing patterns in the file or nearby module.
  • Avoid unrelated formatting, renames, dependency changes, or broad rewrites.
  • Add or update tests when behavior changes.
  • Update docs when setup, commands, provider behavior, or user-facing behavior changes.
  • For new features, larger refactors, dependencies, or runtime changes, follow the issue-first guidance in CONTRIBUTING.md.

Stack And Conventions

  • TypeScript with strict mode and ESM imports.
  • React + Ink for terminal UI.
  • Bun lockfile and Bun scripts for development workflows.
  • Node runtime for the built CLI.

Common libraries and patterns:

  • chalk for terminal color.
  • commander for CLI argument parsing.
  • execa for child processes.
  • Existing service, provider, settings, permission, and UI patterns over new abstractions.

Repository Map

  • src/commands/ - slash and CLI command implementations.
  • src/components/ - React/Ink UI components.
  • src/services/ - API, MCP, OAuth, wiki, voice, and other service integrations.
  • src/tools/ - tool implementations.
  • src/utils/ - shared utilities.
  • src/integrations/ - provider and model integration metadata.
  • src/entrypoints/ - CLI, MCP, SDK, and generated public types.
  • src/tasks/ - local, remote, workflow, and monitor tas...

Files:

  • src/services/teamMemorySync/index.test.ts
  • src/utils/boundedAsync.ts
  • src/utils/attachments.performance.test.ts
  • src/utils/boundedAsync.test.ts
  • src/services/teamMemorySync/index.ts
  • src/utils/attachments.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.

Files:

  • src/services/teamMemorySync/index.test.ts
  • src/utils/boundedAsync.ts
  • src/utils/attachments.performance.test.ts
  • src/utils/boundedAsync.test.ts
  • src/services/teamMemorySync/index.ts
  • src/utils/attachments.ts
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}

⚙️ CodeRabbit configuration file

{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.

Files:

  • src/services/teamMemorySync/index.test.ts
  • src/utils/attachments.performance.test.ts
  • src/utils/boundedAsync.test.ts
🔇 Additional comments (6)
src/utils/boundedAsync.ts (1)

1-65: LGTM!

Also applies to: 81-85

src/utils/boundedAsync.test.ts (1)

1-138: LGTM!

src/utils/attachments.ts (1)

122-122: LGTM!

Also applies to: 768-769, 1103-1107, 1995-2136, 2291-2375, 3243-3246

src/utils/attachments.performance.test.ts (1)

1-90: LGTM!

src/services/teamMemorySync/index.ts (1)

29-126: LGTM!

Also applies to: 606-755, 772-846, 1349-1354

src/services/teamMemorySync/index.test.ts (1)

1-174: LGTM!

Comment thread src/utils/attachments.ts
Comment thread src/utils/boundedAsync.ts
Copilot AI review requested due to automatic review settings July 12, 2026 14:51

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 12, 2026

@jatmn jatmn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Findings

F1 — Major: 1s abort timeout now enforced on attachment producers (real behavior change)

  • Evidence (base): getAttachments already did const timeoutId = setTimeout(ac => ac.abort(), 1000, abortController)
    (now ~attachments.ts:795). In the base commit 2448ea9… the old maybe(label, f) took no signal
    (base line 1043) and processAtMentionedFiles/getChangedFiles used bare Promise.all with no
    throwIfAborted. So the 1s timer was effectively inert for those producers.
  • Evidence (this PR): maybeTimedAttachment (attachments.ts:804) calls
    maybe(label, f, context.abortController.signal) → maybe (:1068) now does
    signal?.throwIfAborted() (:1075) then await raceAbort(f(), signal, …); and
    processAtMentionedFilesWithDependencies (:2073, :2087) + getChangedFiles (:2312, :2329)
    call toolUseContext.abortController.signal.throwIfAborted() per item. So the 1s timeout is now live
    for: at_mentioned_files, mcp_resources, skill_discovery, changed_files, nested_memory,
    dynamic_skill, skill_listing.
  • Effect: under slow FS / large diffs / large repos any of these exceeding 1s now hard-resolves to
    [] (the per-producer maybe swallows the abort and returns [], and the abort is not logged —
    attachments.ts:1104 guards logging with if (!isAbortError(e))). User-visible content (the entire
    changed-files attachment, or all @-mentioned files) can be silently dropped where it was previously
    always delivered.
  • Note: maybeAttachment (no signal, :800) is correctly used for non-IO/CPU-bound producers, so
    only the timing-sensitive IO producers are affected.
  • Recommendation: decide intent. If intended, document it, add a log/telemetry line when an
    attachment is dropped by the timeout, and consider exempting local-fs producers or returning partial
    results; if not intended, raise/remove the 1s ceiling for these producers. Either way, fix the PR
    description.

F2 — Major: Missing focused regression coverage for the changed attachment paths

  • getChangedFiles was converted to mapWithConcurrency + per-item throwIfAborted
    (attachments.ts:2290-2372) but has no tests (the new attachments.performance.test.ts only
    exercises processAtMentionedFiles and maybe).
  • mapWithConcurrency abort mid-flight (abort fires while mappers run) is never tested end-to-end;
    only pre-abort and the standalone raceAbort path are covered.
  • processAtMentionedFilesWithDependencies is only exercised via the perf test with a never-aborted
    controller, so its throwIfAborted (:2073, :2087) and if (isAbortError(err)) throw err
    (:2130) wiring is unverified.
  • Per AGENTS.md ("Add or update tests when behavior changes") and the test-path review rubric ("Block
    when risky runtime changes lack focused regression coverage"), these gaps should be closed. The
    helper and team-memory already have good coverage.

F3 — Low: Abort-reason typing robustness hole in throwIfAborted call sites

  • raceAbort/maybe route the raceAbort rejection through abortReason, but the per-item
    throwIfAborted() calls (attachments.ts:2073, 2087, 2312, 2329) and the worker loop
    (boundedAsync.ts:72) rethrow signal.reason verbatim.
  • isAbortError (src/utils/errors.ts:28) is true only for AbortError/APIUserAbortError/an Error
    whose .name === 'AbortError'. A non-Error or non-AbortError reason (e.g.
    controller.abort('cancelled') or controller.abort(new TypeError())) is therefore not recognized.
  • Consequence: in processAtMentionedFilesWithDependencies (catch :2129-2130) and getChangedFiles
    (catch ~:2359) the guard if (isAbortError(err)) throw err would NOT rethrow such a reason; it
    falls through to return null, so the worker's failed flag stays false and remaining files keep
    being processed — cancellation is silently ignored.
    maybe (:1104) would also mis-log a
    cancellation as a real error.
  • In practice the PR's own wiring (setTimeout(ac => ac.abort(), 1000, abortController)) yields a
    DOMException with name === 'AbortError', so the common path is correct — this is a narrow
    robustness gap, not a current bug. Recommend routing every throwIfAborted() through abortReason
    (or an isAbortError-safe wrapper) and adding a test with a non-Error reason.

F4 — Low: Concurrent abort can mask a genuine mapper error

  • In raceAbort (boundedAsync.ts:24-45), if the abort event fires and rejects before the inner
    promise rejects, the genuine mapper error is swallowed and surfaces as an abort. Generally acceptable
    (abort precedence), but consider giving inner rejection precedence when both occur in the same tick.

Nits / Minor

  • processAtMentionedFiles returns results.filter(Boolean) (:2137) while getChangedFiles uses the
    safer results.filter(result => result != null) (:2366). Attachment objects are always truthy so
    no bug, but align for consistency.
  • Perf-contract waitFor predicates assert exact activeReads === CONCURRENCY
    (teamMemorySync/index.test.ts:77, attachments.performance.test.ts:596, boundedAsync.test.ts);
    airtight today (gated mappers) but >= is more robust to refactors.
  • boundedAsync.test.ts registers a global process.on('unhandledRejection') (~:134); low risk under
    Bun per-file isolation + finally cleanup, but prefer a scoped captured-rejection assertion.
  • Team-memory logs: oversized-file log now uses relPath instead of entry.name (more informative) and
    the secret-skip log changed em-dash — to hyphen -. Cosmetic only.

Copilot AI review requested due to automatic review settings July 13, 2026 06:27

Copilot AI 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.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/utils/attachments.ts (1)

804-817: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Thread the abort signal into maybeAttachment. maybe() only enforces the 1s timeout when a signal is passed; maybeAttachment currently calls maybe(label, f) without abortController.signal, so a slow attachment producer can stall getAttachments().

🤖 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/utils/attachments.ts` around lines 804 - 817, Update the maybeAttachment
helper to pass abortController.signal into maybe(label, f), ensuring attachment
producers are subject to the existing timeout and cancellation behavior while
preserving the current attachment collection flow.

Source: Path instructions

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

Outside diff comments:
In `@src/utils/attachments.ts`:
- Around line 804-817: Update the maybeAttachment helper to pass
abortController.signal into maybe(label, f), ensuring attachment producers are
subject to the existing timeout and cancellation behavior while preserving the
current attachment collection flow.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 543f139f-ffcc-4219-9d74-5daddb427cc9

📥 Commits

Reviewing files that changed from the base of the PR and between bf882ee and a3afbc8.

📒 Files selected for processing (5)
  • src/services/teamMemorySync/index.test.ts
  • src/utils/attachments.performance.test.ts
  • src/utils/attachments.ts
  • src/utils/boundedAsync.test.ts
  • src/utils/boundedAsync.ts
📜 Review details
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

TypeScript code in this repository must use strict mode and ESM imports.

Files:

  • src/services/teamMemorySync/index.test.ts
  • src/utils/attachments.performance.test.ts
  • src/utils/boundedAsync.ts
  • src/utils/boundedAsync.test.ts
  • src/utils/attachments.ts
**

⚙️ CodeRabbit configuration file

**: # AGENTS.md - AI Agent Coding Guide

This guide is for AI coding agents working in the OpenClaude repository. Read it before changing code, and also follow CONTRIBUTING.md for contributor policy, PR expectations, review follow-up, and project scope.

Project Snapshot

OpenClaude is a coding-agent CLI for cloud and local model providers. It supports OpenAI-compatible APIs, Anthropic, Gemini, DeepSeek, Ollama, MCP, local backends, slash commands, tools, agents, and a React/Ink terminal UI.

The installed CLI runs on Node.js >=22.0.0. Bun is used for source builds, scripts, dependency management, and tests.

Work Style

  • Keep changes focused on one problem.
  • Prefer existing patterns in the file or nearby module.
  • Avoid unrelated formatting, renames, dependency changes, or broad rewrites.
  • Add or update tests when behavior changes.
  • Update docs when setup, commands, provider behavior, or user-facing behavior changes.
  • For new features, larger refactors, dependencies, or runtime changes, follow the issue-first guidance in CONTRIBUTING.md.

Stack And Conventions

  • TypeScript with strict mode and ESM imports.
  • React + Ink for terminal UI.
  • Bun lockfile and Bun scripts for development workflows.
  • Node runtime for the built CLI.

Common libraries and patterns:

  • chalk for terminal color.
  • commander for CLI argument parsing.
  • execa for child processes.
  • Existing service, provider, settings, permission, and UI patterns over new abstractions.

Repository Map

  • src/commands/ - slash and CLI command implementations.
  • src/components/ - React/Ink UI components.
  • src/services/ - API, MCP, OAuth, wiki, voice, and other service integrations.
  • src/tools/ - tool implementations.
  • src/utils/ - shared utilities.
  • src/integrations/ - provider and model integration metadata.
  • src/entrypoints/ - CLI, MCP, SDK, and generated public types.
  • src/tasks/ - local, remote, workflow, and monitor tas...

Files:

  • src/services/teamMemorySync/index.test.ts
  • src/utils/attachments.performance.test.ts
  • src/utils/boundedAsync.ts
  • src/utils/boundedAsync.test.ts
  • src/utils/attachments.ts
**/*

⚙️ CodeRabbit configuration file

**/*: Apply the OpenClaude maintainer review rubric from AGENTS.md. Review the current diff, not stale discussion context. Separate real blockers from suggestions. Do not request changes for vague style churn. Treat approval as merge-ready from CodeRabbit's side, pending required human review and GitHub Checks. If checks are failing or unavailable, say so clearly instead of implying the PR is fully ready.

Files:

  • src/services/teamMemorySync/index.test.ts
  • src/utils/attachments.performance.test.ts
  • src/utils/boundedAsync.ts
  • src/utils/boundedAsync.test.ts
  • src/utils/attachments.ts
{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}

⚙️ CodeRabbit configuration file

{src/**/*.test.ts,src/**/*.test.tsx,tests/**,scripts/**/*.test.ts,vscode-extension/**/*.test.js}: Review tests for meaningful coverage of the changed behavior, isolation of global/env/config state, async cleanup, fake timers, provider profile leaks, and Windows-compatible assumptions. Block when risky runtime changes lack focused regression coverage or tests assert implementation details while missing the user-visible behavior.

Files:

  • src/services/teamMemorySync/index.test.ts
  • src/utils/attachments.performance.test.ts
  • src/utils/boundedAsync.test.ts
🔇 Additional comments (7)
src/utils/boundedAsync.ts (2)

14-21: LGTM!

Also applies to: 70-70, 81-81


59-103: LGTM!

Confirmed the previously-flagged scheduling bug (queued items starting after a mapper rejection) is fixed via the failed flag — workers stop claiming new indices once set.

src/utils/boundedAsync.test.ts (1)

84-128: LGTM!

Good coverage: non-Error abort reason normalization, and mid-flight abort correctly stopping queued (not yet started) work.

src/utils/attachments.ts (2)

1068-1112: LGTM!

maybe()'s own abort handling (check-then-race, abort errors excluded from logError/logAntError) is correctly implemented. Its correctness is undermined only by callers not forwarding signal (see comment on the maybeAttachment wrapper).


1996-2134: LGTM!

Dependency-injected AtMentionedFileDeps/ChangedFileDeps plus mapWithConcurrency(..., ATTACHMENT_FILE_IO_CONCURRENCY, ...) integration preserves ordering, per-file error containment (returns null rather than propagating), and permission/path checks. Test exposure via __test is appropriately scoped.

Also applies to: 2281-2403, 3268-3272

src/utils/attachments.performance.test.ts (1)

61-220: LGTM!

Bounded-concurrency assertions (>= polling instead of brittle ===) and the "run in-flight work to completion on abort" contract are well covered.

src/services/teamMemorySync/index.test.ts (1)

40-174: LGTM!

Deterministic truncation test after secret filtering is a good regression guard for the ordering guarantee mapWithConcurrency relies on, and the path-traversal skip test matches the stated preservation requirement.

@GautamBytes
GautamBytes requested a review from jatmn July 13, 2026 06:44

@jatmn jatmn left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

@kevincodex1
kevincodex1 merged commit c11c88b into Twigpine:main Jul 14, 2026
5 checks passed
@GautamBytes
GautamBytes deleted the perf/bounded-fs-concurrency branch July 14, 2026 08:22
hotmanxp pushed a commit to hotmanxp/openclaude that referenced this pull request Jul 15, 2026
* perf: bound file IO concurrency

* fix: honor abort and failure gates in bounded IO

* fix: preserve attachment timeout behavior

---------

Co-authored-by: Gautam Manchandani <gautammanch@Gautams-MacBook-Air.local>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Bound file IO concurrency for attachments and team memory sync

4 participants