mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-12 14:19:00 +01:00
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - The restart-chaos harness tests recovery on Daytona sandboxes > - The harness extracts the runner from the Daytona image with skopeo before a wave starts > - A skopeo blob read that timed out failed the whole run before any test started > - This pull request makes the image extraction retry cleanly and share one cache > - The benefit is that one network hiccup no longer costs a 20+ minute run ## Linked Issues or Issue Description Related: #19544 (Daytona chaos waves without Docker). No duplicate PR was found. **What happened?** The Daytona wave `w-20261108T082021` and the crash-point run `cp-20261108T101304` stopped before any test ran. skopeo reported `read: operation timed out` while it copied a blob. The retry then reported `not a containers image directory, don't want to overwrite`, because the destination already had partial files. The crash-point suite also used its own image cache, so it downloaded the image again on each run. **Expected behavior** A failed copy retries into an empty directory. Every wave and crash-point run reuses an image that another run already extracted. **Steps to reproduce** 1. Run `node scripts/crash-points.mjs --env daytona --daytona-image <image>` on a slow or unstable network. 2. Let skopeo time out on one blob read. 3. See the harness stop with exit 2 before any point runs. **Paperclip version or commit** `master` at `8475826d2d`. ## What Changed - With a shared cache, two runs can extract the same image at once. The final cache directory is created only by an atomic rename, and no run deletes a cache entry. A run that loses the rename adopts the valid entry. An invalid leftover stays in place, and the run publishes its extraction to a unique sibling directory. - `copyImageToDir` runs up to 3 `skopeo copy` attempts. Each attempt starts from an empty destination directory. - `defaultDaytonaImageCacheRoot()` is now the one cache for both the wave harness and the CLI: `tests/restart-chaos/results/daytona-images` by default, or `RESTART_CHAOS_IMAGE_CACHE` if set. Crash-point runs reuse an image that a wave already extracted. - README updated. - Three more tests: two runs against one cache through a barrier, a corrupt leftover, and two runs that both meet a corrupt leftover. - Unit tests use a fake skopeo that behaves like the real one: it refuses a non-empty destination and leaves partial blobs behind when it fails. ## Verification - `pnpm exec vitest run --config tests/restart-chaos/vitest.config.ts tests/restart-chaos/daytona-image.test.ts`: 17/17 passed. - `tsc -p tests/restart-chaos/tsconfig.json`: no errors in `tests/restart-chaos`. - Live run: the six Daytona crash points were rerun with this patch, reusing the cached image. ## Risks - Low. Test harness only; no product code changes. - A shared cache means all runs depend on one receipt per image digest. Receipts are already written atomically by renaming the staging dir, and each one is keyed by the immutable digest. ## Model Used - Anthropic Claude Opus 5.5 (`claude-opus-5-5`), via Claude Code with tool use. ## 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 - [ ] All Paperclip CI gates are green - [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups - [x] I will address all Greptile and reviewer comments before requesting merge 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>