test(recovery): publish fixtures under the owned workspace path (#18969)

## Thinking Path

> - Paperclip preserves agent workspace files before it retries stopped
work.
> - A saved workspace must use the directory owned by its workspace ID.
> - The recovery test helper saves files under a generic `remote`
directory.
> - New tests from #18908 restore that fixture into a new allocation.
> - The existing path validator rejects the fixture before the intended
checks.
> - This pull request gives the fixture the same published path as real
workspaces.
> - The tests can then verify native continuation and current repository
denials.

## Linked Issues or Issue Description

Refs #18908, which added the five native provider boundary cases.

**What happened?**

Five `workspace-recovery.test.ts` cases fail with
`remote_workspace_published_path_invalid`. The fixture saves real files
at `<allocation>/remote`. A cold restore requires
`<allocation>/.paperclip-workspaces/<workspaceId>` so it can preserve
the workspace-owned directory name.

**Expected behavior**

The fixture must satisfy the existing path contract. The complete case
must start one native continuation. The four catalog cases must reach
their repository access and warning checks.

**Steps to reproduce**

Run the selected five cases on master
`0eaabe5c0b37c99d827f78a1a8598e7b3534078a`. They fail before their
intended assertions. The same five failures reproduce on exact CI merge
`dd508ded616ae0dd6062ddb03572f8b08a79c10c` with
`chat-attachment-reuse.ts` restored to its pre-optimization `55d7df2bad`
bytes. The failure is independent of the prepared-query change in
#18966.

**Paperclip version or commit**

Master `0eaabe5c0b37c99d827f78a1a8598e7b3534078a`. The path validator
predates the new cases; commit `b5b0dbb03f` introduced it.

**Deployment mode**

Local source tests with real PostgreSQL, temporary filesystem archives
and a controlled native provider boundary.

## What Changed

- Move the helper's real files into
`.paperclip-workspaces/<workspaceId>` before recording the existing
target, lease and workspace bindings.
- Keep all production path validation and all native execution, archive
and current-access assertions.

## Verification

- RED: the five selected cases fail on current master without either
prepared-query patch.
- Causal RED: the five cases also fail on the exact CI merge with only
the chat production module restored to its pre-optimization bytes. All
five report the same invalid published path.
- GREEN: the same five cases pass with this fixture-only change. The
other 239 cases were skipped in this focused run.
- Command from `server/`: `pnpm exec vitest run
src/services/workspace-recovery.test.ts -t 'dispatches the recovered
failed-preparation Retry once through the native provider boundary'`.
- Node24.22.2 and real embedded PostgreSQL. The complete case reads
restored `saved.txt`, writes `continued.txt` and completes through the
real finalizer once. The controlled backend does not make a live
provider call.
- The first attempted baseline on the older `81b01bcc16` checkout
skipped all 188 cases because the selected tests did not exist there.
That attempt is not a baseline proof.
- Greptile reviewed current head
`4ca1487ddfafe868daeef5e1cf7a3b1c504e9b32` at 5/5, with no actionable
findings. Current-head CI is green: 51 successful checks, two
intentional skips and the successful Snyk status. [Workflow
41840916418](https://github.com/paperclipai/paperclip/actions/runs/41840916418)
completed successfully on attempt 3. No duplicate full local build was
run for this test-only change.
- Initial CI attempt: the unrelated task-reload browser case timed out
waiting five seconds for its heading after Reload page. Its assertion
snapshot shows Loading conversation; the later retained screenshot shows
the expected heading, saved comment and composer. The cause is unknown.
The later Cloud-auth task case in shard 3 had the same five-second
heading timeout: its assertion snapshot also shows Loading conversation,
and its later screenshot shows the expected heading and composer. Both
unchanged UI tests passed in the stacked #18966 run. Shard 7 passed its
one same-source retry: 20 passed, one skipped; the previously failing
task-reload case passed in 4.1 seconds. Its checkout remained
`da8190914f2d5b77c127f6a8b0cdd2250f009611`. Shard 3 passed its one
actual retry: 41/41 tests passed in 7.8 minutes; the previously failing
Cloud-auth case passed in 6.9 seconds. Its checkout also remained
`da8190914f2d5b77c127f6a8b0cdd2250f009611`. Passed jobs were preserved.
These successful retries establish recovery on unchanged source; they do
not establish the timeout causes. The original failure remains part of
the verification record.

## Risks

- Low risk. This changes only a test helper. The helper now relocates
its files before it records all existing bindings.
- Production path validation, workspace ownership and current repository
access remain enforced.
- The focused run covers five cases. Current-head CI must cover the rest
of the shared helper's callers before review is complete.

## Model Used

OpenAI `gpt-6.1-sol` through Codex. Context-window size is not exposed.
Used reasoning, tool calls, source editing, real PostgreSQL tests 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
- [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>
This commit is contained in:
DottaandPaperclip authored and GitHub committed 2026-11-04 08:28:39 -06:00
1 parent 396b7fc62a
commit 76e43852ac

Diff Content Not Available