mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-13 07:12:00 +01:00
## Thinking Path > - Paperclip is the open source app people use to manage AI agents for work > - A hosted Paperclip server can run volume-free: its durable state is in the database and object storage, and its local disk is replaced with every deployment > - At startup, a volume-free server runs a readiness gate that refuses to start when it finds data that still needs migration off a volume > - One of those findings is a harness backup that never reached durable storage. A volume-free server that stops in the middle of a run always leaves some > - The gate then refuses every later start, the process exits, and the host restarts it into the same refusal. The workspace stays down until a person repairs it > - This pull request lets a server start over such backups when its filesystem carries the volume-free owner marker > - The benefit is that a volume-free server recovers from an interrupted run by itself ## Linked Issues or Issue Description Refs #20952 (the same crash loop for Runner controller files; this is the next check in the same gate). **What happened?** A hosted volume-free workspace stopped while runs were in progress. Every later start logged `Paperclip server failed to start` with `Volume-free server data is not eligible: native_harness_backups_require_migration`, and exited. The host restarted the container and the server exited again. The workspace did not serve any request for more than two hours. **Expected behavior** A volume-free server starts after an interrupted run. Restart recovery handles the runs whose local harness backup was lost with the old container. **Steps to reproduce** 1. Run a volume-free server (`PAPERCLIP_EPHEMERAL_SERVER=true`) with native Runner tasks in progress. 2. Stop the server process before the harness backup of an active session reaches durable storage. 3. Start the server again. It refuses to start with `native_harness_backups_require_migration`. **Paperclip version or commit** `87fe4d979355232570428deba480b47e1812a26c` (contains #20952). ## What Changed - `assertEphemeralServerData`: when the only reason is `native_harness_backups_require_migration` and the filesystem carries the volume-free owner marker (`volumeFreeControllerStateOwned`), the gate removes that blocker, logs a warning, and lets the server start. - A filesystem without the marker is refused as before. All other blockers are unchanged. - `readEphemeralServerDataEligibility` is unchanged, so the migration and enrollment callers still see the blocker. - Added `ephemeral-server-startup-run-state.test.ts`. ## Verification - Red: with the change to `ephemeral-server-contract.ts` reverted, `starts a volume-free server over harness backups a volume-free server left unsaved` fails (1 failed, 2 passed). - Green: `npx vitest run src/__tests__/ephemeral-server-startup-run-state.test.ts src/__tests__/ephemeral-server-data.test.ts` in `server/`: 2 files, 8 tests passed. - Not run locally: the full suite. CI supplies that coverage. - Not verified: a live volume-free start. The hosted workspace that showed the failure will receive this change through the normal release. ## Risks - A server on a marked volume-free filesystem now starts with unsaved harness backups. Those backups were on a disk that no longer exists, so the refusal protected nothing. The affected runs depend on restart recovery. - The marker is the only evidence that there is no volume. A filesystem that still is a volume and does not carry the marker keeps the refusal. - The gate does not repair or delete the stale lease stamps. The warning repeats at each start until restart recovery settles those runs. ## Model Used Claude Fable 5.2 (`claude-fable-5-2`), through Claude Code with tool use and code execution. ## 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 - [ ] 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 Fable 5.2 <noreply@anthropic.com>