Files
PaperClipAI/server
DottaandPaperclip 275b334fc5 fix(workspaces): skip redundant repository admission snapshots (#19444)
## Thinking Path

> - Paperclip manages AI agents and their execution state.
> - Remote workspace admission must preserve files before execution
starts.
> - Admission saved the entire workspace once per registered repository
on every run.
> - Existing snapshot receipts can prove that validated repositories are
already saved.
> - This change uses those receipts and saves new repositories once per
admission batch.
> - It also preserves fresh configuration metadata and reports actual
workspace reuse.

## Linked Issues or Issue Description

**What happened**
Remote follow-up runs uploaded an unchanged workspace for each
registered repository before starting the provider. Configuration
persistence also overwrote new evaluation metadata, and freshness logs
could claim replacement when the same workspace was reused.

**Expected behavior**
Validate existing repositories without uploads when a committed snapshot
covers their descriptors. Save acquired repositories before publishing
ready receipts. Retain current evaluation metadata and report the actual
workspace outcome.

**Steps to reproduce**
Use a remote workspace with two registered repositories. Prepare it,
then admit a follow-up run. Observe repository snapshot operations
despite unchanged repositories. The regression tests exercise this with
real Postgres, Git, and separate sandbox directories.

**Environment**
Server remote workspace admission at commit
c0214826b3. Related work: #19374 handles
interrupted clone staging; this change handles snapshot admission cost.

## What Changed

- Skip repository saves when the committed snapshot covers the validated
descriptor.
- Save all repositories in one admission snapshot before publishing
ready receipts.
- Retain descriptor coverage only when the new archive contains the
checkout. Drop deleted checkout coverage so admission can acquire it
again.
- Restore `needs_repair` status for failed batch saves and retry failed
uploads.
- Let fresh preparation metadata override stale reserved metadata while
preserving storage authority.
- Report actual reuse when freshness policy requested replacement.
- Add regression coverage and fix an existing routine user fixture
missing its membership role.

## Verification

- Red: original code fails unnecessary-snapshot, evaluation-metadata,
and reuse-message regressions.
- Green: 517 affected tests across six suites before the final coverage
correction. After that correction, all 102 remote workspace/concurrency
tests and 96 archive tests pass. Imported-repository, deleted-checkout,
and upload-retry cases pass.
- Additional red/green: deleted checkout coverage fails before the fix
and passes after it. All 96 archive tests pass, including manifest
digest and size bounds.
- `pnpm -r typecheck`, `pnpm build`, and `pnpm check:token-gates` pass
locally.
- All final-head CI verification jobs pass, including the aggregate `ci
/ verify` check. Greptile gives the final head 5/5.
- The monolithic local `pnpm test:run` passed all six chat shards and
continued through general server tests. It was stopped after final-head
CI passed; it did not complete locally. The targeted local regressions,
affected suites, typecheck, and build completed successfully.

## Risks

Snapshot receipts must refer to committed bytes. Legacy receipts require
one conservative save. Failed uploads must not publish repository
readiness. Replacement-class drift still retains the original
configuration for an explicitly reused workspace.

Existing directories with damaged or missing Git metadata still require
repair. Master and this PR both validate those directories without
cloning over them, preserving any surviving user files. Clearing a
snapshot descriptor would not change that path. Complete directory
deletion is different: this PR clears coverage so normal acquisition can
clone it again.

## Model Used

OpenAI gpt-6.1-sol through Codex. Used reasoning, repository inspection,
code editing, and local execution. The host does not expose the 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-11-06 07:08:59 -06:00
..