Files
PaperClipAI/ui/src
Devin FoleyandPaperclip c3550cfb38 fix(daytona): send archive chunks in bounded windows (#19339)
## Thinking Path

> - Paperclip manages agents and saves their work when execution stops.
> - The Daytona plugin saves an archive through a terminal when disk
capacity prevents the normal archive or download copy.
> - That fallback sent one 40 KiB chunk and waited for its host write
acknowledgement.
> - Network delay then applied to every small chunk. A large archive
could exceed the recovery deadline even while bytes were moving safely.
> - This pull request sends a bounded window of chunks and still
acknowledges every completed host write.
> - The benefit is faster recovery over delayed connections, with
bounded memory and the existing size, space and completion checks.

## Linked Issues or Issue Description

Refs #19034, which added the capacity fallback.

**What happened?**

The archive fallback waits for one network round trip after each 40 KiB
chunk. A saved workspace archive can be much larger than that chunk.
Repeating a timed-out transfer does not remove this throughput limit.

**Expected behavior**

Allow a small amount of data to travel before waiting for
acknowledgements. Keep memory bounded, write bytes in order, and stop
after any write or protocol failure.

**Steps to reproduce**

1. Run the real Bash archive sender against a host that delays each
acknowledgement by 400 ms.
2. Transfer 1 MiB plus a partial final chunk with a four-second
deadline.
3. The original implementation times out. The bounded-window
implementation completes and preserves the exact source bytes.

**Paperclip version or commit**

The failing regression uses the original implementation from
`6a66c09f7f7`.

## What Changed

- Send at most sixteen 40 KiB chunks before collecting their
acknowledgements. Drain the final partial window before the completion
receipt.
- Serialize host writes and reject more than sixteen pending frames.
Stop queued writes on the first failure.
- Keep per-frame size checks, total archive limits, the 1 GiB host space
reserve, the transfer deadline and bounded teardown.
- Add a real Bash regression with delayed acknowledgements, plus
overflow and failed-write coverage. Update the plugin documentation.
- Update the agent-creator test fixture for the required directory
membership role introduced by #15183, which otherwise breaks merged CI
typechecking.

## Verification

- Failing first: the final real-Bash regression fails against the
original source with `Daytona archive stream timed out`. It passes with
the change. The empty-stream case passes too.
- Standalone Daytona package `pnpm test`: 578 passed, 8 skipped. The
skips are the existing opt-in live tests.
- Standalone package `pnpm typecheck` and `pnpm build`: passed.
- `pnpm test src/file-sync-capacity.live.test.ts` with a staging Daytona
key: 2 passed on isolated test sandboxes. This covers actual terminal
transport, stop/start, archive and file-copy capacity failures, exact
saved hashes, safe links, cleanup and a second export. The tests removed
their own sandboxes.
- The production dependency assumption is bounded: at most 640 KiB of
decoded payloads can wait for host writes. The parser also has a bounded
encoded buffer. No background work or idle timer is added.
- Initial hosted CI failed with TS2741 in
`ui/src/lib/agent-creator.test.ts` after #15183 made `membershipRole`
required. Rebased onto that change and added the nullable field to the
fixture. UI `pnpm typecheck`, all 4 existing creator-label tests, and
`pnpm check:token-gates` now pass locally. Hosted CI subsequently passed
on the updated head.
- `git diff --check` and a local secret and PII scan: passed.
- Full repository checks were not repeated locally for this standalone
plugin change. Hosted verification at
`bf6b3cb6a622a9523c72b86fdfe616555c8f3ef8`: all 53 check runs passed,
with the 2 opt-in Storybook checks skipped; both required gates (`ci /
verify`, `ci / e2e`) passed. Greptile is 5/5 at this exact head, with no
review threads or merge conflicts. The separate non-required
`security/snyk (cryppadotta)` status remains pending; it is not claimed
as passed.

## Risks

- A burst can queue up to sixteen chunks instead of one. The receiver
enforces this bound and acknowledges a chunk only after its ordered host
write.
- The timeout budget is unchanged. A connection that cannot finish
within that budget can still fail. This change does not retry a provider
turn or change file-recovery authority.
- Source confinement, archive validation, successful producer completion
and publication rules are unchanged. No schema migration.

## Model Used

- OpenAI `gpt-6.1-sol` with xhigh reasoning, in Codex through T3 Code.
Tool use included source edits, real Bash and filesystem tests, and
isolated Daytona tests. The runtime does not expose its context window.

## Checklist

- [x] I have included a thinking path that traces from project context
to this change
- [x] I have specified the model used (with version and capability
details)
- [x] I have checked ROADMAP.md and confirmed this PR does not duplicate
planned core work
- [x] I have searched GitHub for duplicate or related PRs and linked
them above
- [x] I have either (a) linked existing issues with `Fixes: #` / `Closes
#` / `Refs #` OR (b) described the issue in-PR following the relevant
issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change (e.g. `docs/...`, `fix/...`)
and contains no internal Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass
- [x] I have added or updated tests where applicable
- [x] I have updated relevant documentation to reflect my changes
- [x] I have considered and documented any risks above
- [x] All Paperclip CI gates are green
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-11-05 13:12:11 -08:00
..
…