Files
PaperClipAI/server/src/services
Nicky LeachandPaperclip 6d59f5ef7e fix: allow workspace changes after settled native bootstrap failures (#18166)
## Thinking Path

> - Paperclip manages work assigned to AI agents.
> - Workspace admission must wait for file persistence and execution
cleanup.
> - A native startup error can record a failed workspace finalization
before provider work starts.
> - The controller and environment can settle while that diagnostic
remains.
> - The workspace guard then blocks every later binding change.
> - This pull request recognizes settled bootstrap failures with no
output obligation.
> - Real output, process ownership, and cleanup obligations continue to
block changes.

## Linked Issues or Issue Description

Related: #14234 handles recovery-hold regeneration for legacy failures.
This change addresses the separate native workspace-finalization guard.

**What happened?**

A workspace change stayed blocked after two native startup failures.
Both runs had explicit bootstrap receipts with `providerWorkStarted:
false`. Their controllers were terminal and unowned. Their leases had
completed cleanup. No provider events or workspace copyback descriptors
existed. Each run still had a failed `workspace_finalize` diagnostic.
Later successful turns did not remove that historical record, so
selecting a task directory failed during setup on every retry.

**Expected behavior**

A confirmed startup failure with no provider work must not create a
permanent file-persistence barrier. A real workspace export or cleanup
obligation must remain fenced.

**Steps to reproduce**

1. Fail native session startup before provider work, leaving a failed
finalization diagnostic.
2. Settle the failed controller and its environment cleanup.
3. Schedule a different task workspace.
4. Start the next admission. Before this fix, it fails with “Previous
task run still owns workspace recovery.”

**Paperclip version or commit**

Reproduced against the workspace guard on master at `27be85904`.

**Deployment mode**

Hosted application with external PostgreSQL and a plugin-managed agent
computer.

## What Changed

- Exempt a failed finalization diagnostic only for finished native
bootstrap failures with an explicit no-work receipt and an unowned
terminal coordinator without a result.
- Keep provider events, process identities, restore failures, sync
descriptors, copyback owners, unfinished operations, and unsettled
environment cleanup as blockers.
- Reuse the existing batched provider-evidence reader.
- Test both pending workspace selection and legacy binding updates. Keep
the original failed operation unchanged.
- Document the admission invariant.

## Verification

- The new reproduction failed on both workspace-change paths before the
fix.
- `pnpm exec vitest run
server/src/__tests__/task-workspace-binding.test.ts`: 92 tests passed
after the fix.
- A first isolated test attempt needed the existing plugin SDK build
prerequisites. Tests ran after `pnpm --filter @paperclipai/plugin-sdk
ensure-build-deps`.
- `pnpm -r typecheck` and `pnpm build` pass with pnpm 9.15.4 and Rust
1.97.1. The initial typecheck attempt lacked Cargo on PATH; it was
corrected to use the installed toolchain. The unsharded local `pnpm
test:run` did not finish during the validation window and was stopped
after all PR CI test shards passed. It did not provide a completed local
full-suite verdict.
- Remote recovery used an audited, scoped transaction to append no-op
reconciliation records for the two verified bootstrap failures. Original
failures and workspace data were retained. The normal UI Retry then
applied the pending selection and reached native provider execution.
- Greptile reviewed commit `807d22be9e530e272d53def365a0cdd37bd142ea`:
5/5, with no review threads. All PR CI checks passed. GitHub reports no
merge conflicts.

## Risks

The main risk is misclassifying an unfinished workspace as a
startup-only diagnostic. The exemption requires positive no-work
evidence and rejects conflicting provider or output state. Existing
ownership and cleanup gates run first. Provider evidence adds one
batched database read only when eligible failed bootstrap diagnostics
exist. There is no new background work, migration, dependency, or
provider replay. Reverting this change restores the former guard.

## Model Used

OpenAI Codex, GPT-6 family, with reasoning, code execution, and browser
tools. This session does not expose a more specific model build ID or
context-window size.

## 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-10-29 08:34:52 -07:00
..
…
…
…