Files
PaperClipAI/server/src
DottaandPaperclip 4d5265fe7e Preserve fully covered historical workspace sources (#19872)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Workspace migration must preserve local files while retaining
unfinished recovery obligations.
> - A shared Git source needs proof for its companion workspaces before
import can publish.
> - Recovery backfill can add a historical-source marker to an exhausted
prepared-export hold.
> - The hold owner rejected that marker even when every recorded
allocation already belonged to its proven prepared source.
> - This pull request accepts only that fully validated form through the
existing source owners and publication fences.
> - Unrelated work can continue while import saves the local files and
keeps the remote recovery hold intact.

## Linked Issues or Issue Description

Refs #19830. No separate public issue was found. A search for the marker
found no open duplicate PR.

**What happened?**

A companion workspace with an exhausted prepared-export hold blocked the
whole shared Git cohort after canonical recovery backfill added its
historical-source marker. The prepared and historical source readers
both accepted the same allocation.

**Expected behavior**

Local file preservation can proceed when all historical references are
already covered by the proven prepared source. The recovery hold and
remote obligations remain unchanged. Unknown or uncovered sources stay
blocked.

**Steps to reproduce**

1. Create a shared Git repository with a selected leaf and a companion
workspace.
2. Give the companion a settled failed export, accepted result,
exhausted recovery and blocked task.
3. Run canonical historical recovery backfill for its retained
allocation.
4. Import the selected leaf through the normal online migration owner.

**Paperclip version or commit**

Reproduced on `4185e308659abf0887930e20049ca6e7cbfc0e81`.

**Deployment mode**

A source installation with legacy local Git workspaces and object
storage.

## What Changed

- Validate the exact historical marker schema, run and unique lease
references against the already proven prepared source and declared
allocations.
- Reuse the canonical historical-source inspector and compare the same
provider allocation and remote working directory.
- Reject unknown fields, malformed markers and foreign, duplicate or
uncovered references.
- Keep the full marker in the existing hold fingerprint and retain the
existing source, task, lifecycle, finalizer and publication checks.
- Add real PostgreSQL/Git tests through shared-cohort inspection and the
encrypted import/restore owners.

## Verification

- The unchanged owner failed the actual selected-leaf importer
regression with `online_workspace_source_scope_unproven`. The canonical
prepared/historical reader controls passed before that refusal.
- Production head `3e678e10fa` passed 41 focused PostgreSQL/Git cases
across three files in 18.93 seconds after rebasing onto the new
finalizer schema migration. This includes 14 new cases; 80 unrelated
cases were filtered out. The final test-only review update passed both
additional multi-allocation controls plus the original selected-leaf
cold restore (3/3, 11.29 seconds); TypeScript passed again.
- The positive uses the actual historical backfill producer. It
cold-restores an encrypted selected-leaf snapshot with the original Git
tree unavailable and keeps the peer's task, finalizer, result,
allocation and recovery action unchanged.
- The tests retain an unrelated active object-backed run, prove the peer
finalizer lock is held, refuse bad bindings and reject late marker
changes without discarding the uploaded snapshot.
- Server TypeScript, module-boundary checks and `git diff --check`
passed. The canonical PostgreSQL wrapper exited and cleaned up.
- Final-head CI passed: 56 successful checks and four intentional skips,
with no failures or pending jobs
([run](https://github.com/paperclipai/paperclip/actions/runs/42397090541)).
Greptile reviewed `0cbf0a0255` at 5/5 with no open findings; GitHub
reports CLEAN/MERGEABLE.

## Risks

- The allowance applies only to the existing exhausted prepared-export
hold. Other recovery forms and unknown or uncovered references remain
blockers.
- A marked hold adds database reads proportional to its already declared
allocations during maintenance inspection. It adds no provider calls,
payload download or recurring background work.
- Import saves the current local files. It does not claim that unsaved
remote files were recovered, that a provider stopped or that execution
may resume. Existing holds and warnings remain authoritative.
- Local tests use the real encryption and restore owners with a local
object backend. Hosted backfill and normal-delivery qualification remain
separate.

## Model Used

OpenAI Codex, based on GPT-6, with reasoning, repository tools and code
execution. The exact serving snapshot and context-window limit are not
exposed in this session.

## 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
#` 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-07 11:53:00 -06:00
..
…
…
…
…
…
…