Commit Graph
7 Commits
Author SHA1 Message Date
Nicky LeachandPaperclip aab87ce707 Prove workspace delivery before inspecting cleanup candidates (#18493)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Completed tasks leave workspaces that need safe cleanup.
> - Providers without ancestry inspection currently need a recorded
merged PR before cleanup can start.
> - A squash merge changes commit identity, so direct ancestry cannot
prove that delivery.
> - This change proves delivery from the finalized HEAD and captured
destination before storage inspection.
> - Fresh storage checks and a second delivery check still protect
removal.
> - This reuses the existing worker and receipts. It adds no table or
timer.

## Linked Issues or Issue Description

Refs #18410. Related: #13400 addresses workspace identity during
inspection; this change adds destination-aware delivery discovery.

## What Changed

- Resolve direct ancestry or discover an associated merged GitHub PR
without a recorded work product. Require exact HEAD, destination
repository and branch, and a reachable integration commit.
- Use the latest settled finalization receipt as a candidate. Reject
missing, failed, pending, conflicting, or changed evidence.
- Inspect storage only after positive remote proof for providers that
disable ancestry inspection. Recheck HEAD, branch, source identity and
delivery before removal intent.
- Add an optional provider capability for a specific PR recovery hint
and an optional prepared destination receipt. Older providers keep their
existing protocol.
- Wake cleanup when finalization writes settle or gain a workspace
binding. Keep remote-only retries for concrete unresolved delivery. Park
missing or unsupported candidate identity.
- Reuse the source project's explicit GitHub consent for delivery checks
through the existing authorization service. Revalidate the bound
repository and consent before removal; missing or revoked consent
retains storage without switching identities. Public sources remain
anonymous.
- Update the contracts, documentation, access map, and targeted
regressions.

## Verification

- Initial-head GitHub CI passed at
`5acd4c818be6f1764f8319f42891f9956c357c26`, including full build and
typecheck. Standard Greptile is 5/5 with no open threads. The first Apex
review scored 3/5 and found startup latency from remote proof lookups
and removal retry identity changes across provider capability changes.
Both corrections are pushed in `9d1a38df3d`, with the qualified
destination-ref length fix. Red regressions reproduced each issue.
Latest targeted checks passed: cleanup/worker 26, provider integration
41, SDK contract 8. Head `9d1a38df3d` passed standard and Apex reviews
at 5/5 with no open threads, plus all CI including full build/typecheck.
Canary Dry Run initially failed on an npm 404 fetching
`rollup-4.67.3.tgz`; the exact tarball subsequently returned HTTP 200,
and one targeted retry passed without source changes. Aggregate
verification also passed. After #18403 merged, master introduced
conflicts in shared workspace cleanup and metadata handling. Resolved
them in `7700832536`, preserving remote snapshot cleanup and Git
delivery-proof cleanup. Targeted merge verification: 93 tests passed in
the first run (59 opt-in skips), then all 16 remote lifecycle tests
passed with explicit database opt-in; map checks passed. The isolated
database is stopped. The merge head received standard review 5/5. Its CI
found two failures in unchanged test cleanup paths: native runtime
temporary-directory ENOTEMPTY and agent-chat cancellation lock timeout.
Those failures remain recorded and require successful final-head
verification. The subsequent project-consent change has targeted
coverage: authorization36, resolver33 and cleanup19 tests passed,
including revoked consent, anonymous public access and source-binding
races. The positive consent test failed before the fix. Current head
`c772679e05` has green GitHub CI, including full build/typecheck and
both previously failing test jobs, plus standard Greptile 5/5 with no
open threads. Neither cleanup failure required changes to its test path.
Apex also completed at 5/5 on this exact head (check `124651548532`,
summary updated 2026-10-31 20:45 UTC), with no open review threads. The
PR remains draft. Earlier failures remain recorded above.

- Final focused run on the rebased branch: **182 tests passed across six
files**, covering the resolver, delivery cleanup, provider bridge,
finalization notifications, existing workspace service and SDK
contracts. The disposable test database was stopped afterward.
- Targeted resolver tests: 33 passed. These cover ancestry, discovered
squash PRs, wrong HEAD/base/repository, removed integration commits,
bounded responses, cancellation and credential isolation.
- Targeted cleanup integration tests: 17 passed. Provider bridge
integration: 36 passed. SDK contract tests: 7 passed. Finalization
notification tests: 9 passed.
- A negative control that removed the final delivery check failed the
race regression as expected. The check was restored.
- Read-only live GitHub probe: the new resolver discovered PR #18410
from HEAD `3f5ade4cd42b707040e9a82fdaed343e3d736a09`, without PR hints.
It proved integration commit `6484f96c28bfb11a793ce4be6cc5ac15643a5a02`
reachable from observed master
`5bc029bf6c1db6647e96acea323f3723fd1d3eba`. GitHub also advertised the
exact original HEAD at `refs/pull/18410/head`.
- `node scripts/check-maps.mjs` passed. Structural checks do not prove
deployment behavior.
- Local tests are targeted by user request. Full build, typecheck and
test suite run in GitHub CI. A standalone server typecheck could not
complete because local Runner build declarations were absent; no
changed-file diagnostics were reported.
- Initial local execution hit a stalled pnpm wrapper, sandbox socket
denial and stale generated SDK declarations. Direct installed binaries,
the authorized isolated test database and rebuilt SDK resolved those
setup failures. No deployment was performed.

## Risks

- Destructive cleanup still requires fresh storage safety and lifecycle
checks. Remote proof alone never authorizes removal. A persisted removal
intent preserves existing recovery semantics.
- Legacy workspaces without an unambiguous destination or completion
HEAD remain retained. This does not guess the original default branch.
- Private repositories use the explicit standing GitHub consent on the
bound source project, with current membership, grant, repository access
and trust checks. No separate company token is required when that
consent is valid. Missing or revoked consent and unavailable or
rate-limited access retain storage; the worker does not borrow a task or
agent identity.
- A known undelivered commit keeps the existing five-minute retry
because external GitHub changes have no guaranteed ingress to this lane.
This can keep cleanup scheduled. Missing evidence parks instead.
- Providers need the new recovery capability to clean a squash merge
whose original HEAD is reachable only through its PR ref. Providers
without it remain conservative.
- The resolver currently supports GitHub.com. Existing local and
other-provider ancestry paths stay in place.

## Model Used

OpenAI Codex, GPT-6 family, with reasoning, repository tools and
parallel code agents. The exact runtime model ID and context-window size
were not exposed to 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
#` / `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-02 07:59:17 -08:00
Nicky Leach 6484f96c28 fix(workspaces): inspect storage only when needed (#18410) 2026-10-31 11:43:18 -07:00
DottaandPaperclip b6b57079b9 fix: evaluate status cards on committed changes and deadlines (#18401)
Reviewed and verified at 21795e222a.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-31 11:41:59 -05:00
Nicky LeachandPaperclip a708a13336 Separate plugin workspace completion from maintenance inspection (#17329)
## Thinking Path

> - Paperclip manages AI agents and their work.
> - Storage plugins own remote task workspaces.
> - Run completion currently requests the same inspection used for
storage cleanup.
> - That inspection can fetch remote refs and scan files after the agent
has finished.
> - Completion needs retained workspace identity and durable writes, not
permission to delete files.
> - This change adds an optional completion operation and keeps
maintenance inspection separate.

## Linked Issues or Issue Description

**What happened?**

A successful plugin-backed run can fail during completion because the
storage provider performs a slow remote-recoverability inspection. Dirty
or unpublished output does not need a deletion-safety proof to remain
valid task output.

**Expected behavior**

Completion verifies the assigned workspace and confirms durable writes
through the provider. Cleanup still requires the existing full
inspection.

**Steps to reproduce**

Run a task with plugin-owned storage whose inspection fetches remote
refs. Let the agent finish, then observe completion waiting for the
maintenance inspection.

Related context: #16428 added finalization observability. The duplicate
search found no existing PR for this provider contract.

## What Changed

- Add optional `workspaceProvider.finalizationVersion: 1` and strict
`finalize` / `finalized` schemas.
- Pass original run and agent context through live completion and
recovered completion.
- Give the new operation a 30-second deadline and keep ownership checks
and lifecycle serialization.
- Retain the inspection fallback for providers without the capability.
Keep maintenance inspection and removal unchanged.

## Verification

- SDK build passed.
- Targeted SDK and completion unit tests: 7 passed.
- Added integration coverage for capability selection, legacy fallback,
maintenance separation, and failure propagation.
- Local integration setup timed out starting PostgreSQL; the integration
suite passed in GitHub CI.
- Full build/typecheck and broader tests passed in GitHub CI (55
successful checks, 2 skipped). Local checks remained targeted as
requested.
- Diff reviewed for secrets and operational identifiers.

## Risks

The capability is opt-in. Providers must not advertise it until their
completion implementation is available. An unavailable provider or
failed durability barrier remains retryable. No schema or stored-binding
migration is required.

Test-file size exception: the provider integration suite grows from 973
to 1,002 lines. The 29-line case follows the same prepared binding
through legacy completion, opted-in completion, and maintenance
inspection using the existing single-connection database fixture.
Keeping it there avoids a second embedded-Postgres lifecycle for one
transition test. The completion helper unit tests are in a separate
focused file.

## Model Used

OpenAI GPT-6 Codex, with reasoning and code/test tools.

## 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-23 09:07:35 -07:00
Nicky LeachandPaperclip 989ee668e0 Support provider-owned fresh retry workspaces (#17252)
## Thinking Path

> - Paperclip coordinates AI agents and retains their work across
failures.
> - A retry can require a new workspace while preserving the failed
attempt.
> - Core rejects this recovery strategy for provider-owned storage.
> - Providers should implement the required outcome using their own
storage design.
> - This pull request adds a semantic fresh-preparation contract and
delegates recovery preparation.
> - The benefit is that a supported provider can run a fresh retry
without losing prior work.

## Linked Issues or Issue Description

**What happened?**
A retry that selects `fresh_isolated_workspace` fails with
`fresh_workspace_storage_unsupported` for provider-owned storage.

**Expected behavior**
Core asks a capable provider to prepare new storage and attach verified
recovery files. The failed workspace remains intact.

**Steps to reproduce**
Run a task in a task-capable plugin environment. Let the task fail
without a verified workspace preservation receipt. Retry the task so
Core selects a fresh attempt.

**Paperclip version or commit**
6204239cf (rebased on current master).

**Deployment mode**
Self-hosted server with a plugin task environment and managed workspace
provider.

Search found no duplicate implementation. This branch includes the
default-provider changes from #17247 and preserves their source
selection behavior.

## What Changed

- Define an opt-in fresh-preparation contract with a stable attempt
identity and verified recovery file descriptors.
- Describe retained-storage and recovery-attachment guarantees without
requiring a Git storage layout.
- Reserve replacement task bindings with revision checks and keep the
failed workspace intact. Projectless and project-backed task
environments both replay their stable attempt reservation.
- Reconcile an interrupted preparation against its reserved workspace
and stable operation identity.
- Stage verified recovery archives at stable transfer paths. Delegate
attachment materialization to the provider.
- Preserve projectless attempt directory identities through later turns
and pin the intent into each execution lease.
- Protect fresh intent and projectless ownership from caller metadata
replacement or injection.

## Verification

- SDK workspace-provider tests: 4 passed.
- Targeted reservation and task-dispatch tests: 31 passed.
- Recovery transfer staging and lifecycle focus: 7 passed. The separate
cache-cleanup failure reconciliation case also passed.
- After rebasing on current master, 7 focused preparation and ownership
cases passed. These cover inherited provider defaults, fresh
preparation, stable projectless identity, and authorization denial.
- The focused metadata authority regression passed, including forged
intent, replacement, and null metadata patches.
- Three assembled interrupted task-reservation cases passed:
projectless, project with a saved source, and project with a newly
selected default source.
- Targeted tests use worktree SDK sources. No full local build or
typecheck ran.
- Local checks remain targeted as requested. Latest-head GitHub CI
passed: 54 successful checks, including typecheck, build, server suites,
Runner validation, and E2E shards; 2 unrelated Storybook checks were
skipped.
- Greptile reviewed commit 73595b0c61 at
5/5 with zero unresolved threads.
- Live VM E2E has not run.

## Risks

- Existing providers retain their existing behavior. Fresh attempts
require explicit version support.
- The companion provider implementation must materialize recovery
snapshots safely and preserve the old workspace.
- Fresh retries require the companion provider implementation. Providers
without the version marker fail closed.

## Model Used

- OpenAI GPT-6.1 (`gpt-6.1-sol`), reasoning and coding tools. The
runtime does not expose the context-window limit.

## 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-22 17:46:27 -07:00
Nicky LeachandPaperclip 6204239cfc Support installed default project workspace providers (#17247)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Storage plugins already own project storage and task checkout
preparation.
> - Core only selected these plugins through an explicit project policy.
> - Installation could therefore leave new and existing projects on
incompatible Core preparation.
> - This pull request adds one generic manifest declaration and one
shared effective-policy resolver.
> - Project configuration shows inheritance while durable workspace
bindings retain their owners.

## Linked Issues or Issue Description

**Subsystem affected**

Plugin contracts, project configuration, and execution workspace
preparation.

**Problem or motivation**

An installed storage provider cannot become the company default.
Projects without an explicit provider keep Core preparation, even when
their execution environment cannot use a Core Git checkout.

**Proposed solution**

A provider declares supported `workspaceProvider.defaultForProjects`
mode and strategy. Company-enabled installations supply inherited
defaults. Explicit plugin selections and explicit Core/local
(`storageProviderPluginId: null`) win. Conflicting defaults require an
operator choice. The declaration and implementation contain no
provider-specific identifiers.

**Alternatives considered**

Rewriting every project would lose the distinction between inheritance
and overrides. Selecting by worker health would silently change storage
on an outage.

**Roadmap alignment**

Extends the existing workspace and sandbox provider contracts. The
roadmap has no duplicate default-provider implementation. Related public
work includes #17243, which covers prepared execution directories rather
than provider selection.

## What Changed

- Add a validated generic default-provider declaration and document it
in the SDK.
- Resolve provider selection and Git defaults consistently in project
responses, source selection, heartbeat source resolution, reservation,
and preparation.
- Keep stored policy separate from effective configuration. Add the
normal project configuration selector for inheritance, explicit plugins,
and Core/local.
- Preserve existing local and plugin workspace ownership. Pin selection
through preparation and keep provider failures visible.
- Add database, API, manifest, heartbeat, and UI regressions. Update the
verification maps.

## Verification

- Targeted Vitest runs cover manifest validation, project defaults and
API access, explicit overrides, existing ownership, new/imported task
inheritance, heartbeat routing, source-free tasks, selection pinning
during setup, and UI configuration.
- Combined policy, provider integration, and heartbeat run: 58 tests
pass; 60 unrelated cases excluded. After the final shared-provider
fallback fix, all 47 policy tests pass, including shared and
operator-mode regressions.
- Server and UI TypeScript checks, SDK build, verification-map
validation, credential-pattern scan, added-comment scan, and `git diff
--check` pass.
- A downstream integration uses this Core resolver and preparation
service with a real storage hook and mocked remote infrastructure. A new
Git project reaches the hook without a stored provider ID.
- Standard Greptile and Apex both scored 5/5 on
5d42998466. All review threads are
resolved.
- Final GitHub CI is fully green on
5d42998466. Browser shard 3 initially hit
a PostgreSQL deadlock during cleanup cancellation, which left an
experiment flag enabled for a later test. A failed-job retry passed all
26 browser tests. The workflow completed successfully on attempt 2. Full
final verification was delegated to CI at the user's request.
- No live provider or hosted tenant run was performed.

## Risks

- Installing one default-claiming provider changes effective selection
for unconfigured projects. Existing explicit settings and workspace
ownership remain intact; incompatible explicit settings fail clearly.
- Each configuration/admission resolution reads installed plugin
metadata and the selected company's enablement. Project list reads share
one catalog query. Selection does not call workers or external
providers.
- Deploy the Core contract before any downstream manifest uses the
declaration. No migration or backfill is required. A downstream
immutable image pin must include this change before packaging its
declaration.
- No merge or deployment is authorized by this PR.

## Model Used

OpenAI GPT-6 through Codex, with reasoning, repository tools, and code
execution. The exact served model ID and context-window size 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 described the issue in-PR following the relevant issue
template
- [x] I have not referenced internal/instance-local Paperclip issues or
links
- [x] My branch name describes the change and contains no internal
ticket id
- [x] I have run targeted tests locally and they pass; full gates are
delegated to CI at the user's request
- [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 on
5d42998466ad42400564ba34f48124f40c53fbc5; the branch has no merge
conflicts
- [x] Standard Greptile is 5/5 on 5d4299846 after all fixes, with no
unresolved threads
- [x] Apex is 5/5 on 5d42998466, after
standard Greptile 5/5 on that same head
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-22 17:12:29 -07:00
Nicky LeachandPaperclip 8b4ab65b1c Add plugin-owned project storage and task workspaces (#17001)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Tasks can use isolated repository workspaces.
> - Core currently prepares those repositories on its own filesystem.
> - A storage provider may only expose repositories inside remote agent
computers.
> - Project storage and task workspace preparation must have one
provider owner.
> - This pull request adds that contract and keeps execution as a
separate plugin interface.
> - Core keeps authorization, durable task bindings, and lifecycle
fences.

## Linked Issues or Issue Description

**Subsystem affected**

Plugin SDK, project workspace policy, heartbeat preparation, execution
leases, and workspace lifecycle.

**Problem or motivation**

Core cannot prepare a task workspace when its repository storage is
unavailable on the Core host. An execution lease must not be required
just to prepare persistent storage.

**Proposed solution**

Let one plugin provide project resource lifecycle and workspace prepare,
inspect, restore, and remove behavior. Core reserves a task workspace
before it calls the plugin. The plugin returns an opaque durable
reference. The matching execution plugin receives that reference on its
task RPC.

**Alternatives considered**

Preparing repositories on Core would require a provider mount on Core.
Preparing them only during task launch would tie persistent workspace
lifecycle to execution leases and agent availability.

**Roadmap alignment**

This extends the remote provider model in ROADMAP.md. Related execution
work is in #16978. This PR does not replace that task bridge. Native
execution of managed storage requires the bridge; this change fails
closed when it is absent.

## What Changed

- Add one storage provider declaration with supported modes/strategies,
a capability, a validated RPC contract, and a test harness.
- Persist provider ownership, repository revision, and
execution-workspace identity before external effects. Reconcile retries
with a stable operation ID.
- Prepare provider storage before environment acquisition. Keep Core
filesystem preparation out of this path.
- Pin the durable reference to the matching execution plugin and
validate the lease binding before task dispatch.
- Route inspection, reopen, and removal through the existing lifecycle
process. Keep local data when remote recovery is uncertain.
- Keep the application database pool free during lifecycle locks.
Preserve pending workspace selections, validate source edits before
retirement, and retry unfinished closed storage cleanup.
- Protect provider metadata and live repository sources from caller
edits. Storage edits retire only closed records with confirmed removal;
retired records cannot reopen.

## Verification

- Current head `8214b3ca5`: all 25 provider lifecycle tests pass with
`maxConnections=1`. They cover preparation, inspection, reopening,
removal, a paused provider with responsive ordinary SQL and a competing
source edit, pending selection preservation, rejected source edits,
cleanup retry scheduling, and providers that cache operation results,
and committed cleanup notifications for storage intent and recovered
state.
- Final frozen-tree lifecycle run on `8214b3ca5`: all 318 tests passed
in 10 files, covering workspace services, reopen, compaction, task
binding, project sources, heartbeat preparation, display caching, and
source locks.
- Direct server `tsc --noEmit` passes. The SDK build and all 128 SDK
tests passed during initial verification; later SDK changes are
documentation only.
- Full CI on the previous head `ec5c7209a` passed all 55 applicable
checks; 2 conditional checks skipped. Standard Greptile reviewed current
head `342e6d9c3` at 5/5 with no unresolved threads. All 55 applicable CI
checks passed on `342e6d9c3`; 2 conditional checks skipped. The Slack
browser and CLI startup jobs passed on their single unchanged-head
rerun. Its Apex review returned 4/5 with one pending-restoration issue.
Commit `1b58943b1` reconciles that durable intent before cleanup,
advances the generation without reopening the Core row, and blocks
direct removal or retirement while intent remains unresolved. Standard
Greptile reviewed `1b58943b1` at 5/5 with no new findings. All 54
applicable CI checks passed on `1b58943b1`; 3 conditional checks
skipped. The chat job passed on its single unchanged-head rerun. Apex
then returned 4/5 for a missing cleanup wake after recovery. Commit
`8214b3ca5` atomically registers cleanup intent before storage intent
and recovery-result writes. Its provider test observes real committed
notification hints and the visible advanced generation. Standard
Greptile reviewed `8214b3ca5` at 5/5 with no new findings. All 55
applicable current-head CI checks passed on the first run; 2 conditional
checks skipped. Final Apex verification completed at 5/5 on this exact
head: 38 files reviewed, no new comments, and no unresolved threads. The
PR is ready for review and mergeable.
- The first Apex review found five issues after a standard 5/5:
application-pool starvation, stale pending selections, retirement during
rejected source edits, lost cleanup retries, and reused inspection
identities. Commits `6d72e7fd4` and `342e6d9c3` fix each with regression
coverage. Archive lock waits use dedicated connections, and source edits
fail promptly if the lifecycle is busy. Retirement compares normalized
values. The normalized-source regression initially failed with the
raw-value comparison; after moving the check after normalization, a
clean provider-suite rerun passed all 24 tests at that stage. Those
threads are resolved; the earlier Apex 0/5 is not a passing acceptance
result.
- Earlier local integration attempts could not bind localhost inside the
sandbox. The same suites passed with permission to start local
PostgreSQL.
- The earlier broad local `pnpm test:run` overlapped edits and reported
stale-revision and checkout-path/Git-fixture failures. It was not a
final-tree result. Full CI subsequently passed; the original local
failure remains part of verification history.
- Local repository-wide typecheck/build cannot complete because `cargo`
is unavailable. Direct server TypeScript checks and affected tests pass;
full Rust and build validation comes from CI.
- An earlier browser run on `ff918c5a8` failed in the unchanged
case-filter journey: expected “Done,” received “All statuses,” with an
announcement handler recorded during the assertion. The cause is not
confirmed. [The failed
job](https://github.com/paperclipai/paperclip/actions/runs/39500611857/job/118896954508)
remains verification history. The unchanged shard passed in the next
full CI run on `ec5c7209a`; no UI or fixture change was made.
- Current-head browser shard 2 failed waiting five seconds for the
mocked Slack setup Success heading. This PR changes neither that UI nor
its fixture. [The failed
job](https://github.com/paperclipai/paperclip/actions/runs/39506070513/job/118916021232)
remains verification evidence. The cause is not confirmed; the single
unchanged-shard rerun passed; no UI or fixture change was made, and the
original cause remains unconfirmed.
- The workspace test shard passed its 3,978 general tests, then its CLI
company-import/export fixture timed out after 30 seconds waiting for
startup health before creating any company or workspace. [The failed
job](https://github.com/paperclipai/paperclip/actions/runs/39506070513/job/118916021855)
remains verification history. The child reached external-PostgreSQL
startup without exiting or reporting an exception. Its cause is not
confirmed; the single unchanged-job rerun passed, including the CLI
fixture. No startup or fixture change was made, and the original cause
remains unconfirmed.
- The new cached-removal regression initially failed because its fake
worker advertised availability for unrelated fixture plugins, so another
workspace changed its fake checkout state. Worker availability now
matches the fixture plugin; the complete 25-test provider suite passes.
- On `1b58943b1`, the chat shard timed out polling for one conversation
after an authorized GitHub description edit. [The failed
job](https://github.com/paperclipai/paperclip/actions/runs/39510521657/job/118930193418)
remains evidence. The exact case passes locally against PostgreSQL (1
passed, 1,380 unrelated cases skipped), and this PR changes neither that
test nor its handler. The original cause is unconfirmed; the single
unchanged-job CI rerun passed without a code or fixture change. The
original cause remains unconfirmed.
- The diff was checked for credentials, private references, and
generated artifacts.

## Risks

This is an additive provider contract with no database migration.
Existing projects keep their local behavior unless their policy selects
a storage plugin. A selected provider must be ready and enabled. Unknown
or unsafe cleanup fails closed.

Managed native execution depends on #16978. Core refuses a host Runner
fallback. Providers must fence lifecycle generations, preserve ambiguous
retries, and report remote recovery honestly. Provider-specific live
storage and guest mount qualification remain separate from these Core
contract tests.

## Model Used

OpenAI Codex (GPT-6), with repository inspection, code execution, and
tests. The exact model variant was not exposed.

## 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 linked existing issues or described the issue in-PR
following the relevant issue template
- [x] I have not referenced internal/instance-local Paperclip issues or
links
- [x] My branch name describes the change and contains no internal
ticket id
- [x] I have run tests locally and they pass (affected suites; broad-run
limits are documented above)
- [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-20 16:35:33 -07:00