Commit Graph
3 Commits
Author SHA1 Message Date
DottaandPaperclip 59a70dc9e2 fix(workspaces): expire reproducible Git files and restore exact commits (#16457)
## Thinking Path

> - Paperclip manages AI agents and their task workspaces.
> - Isolated Git worktrees and private repository copies remain on the
host after tasks finish.
> - These files can fill the disk even when every commit is available
upstream.
> - Cleanup must retain unique files, local Git state, live work, and
recovery data.
> - This pull request records and verifies an exact-commit restoration
recipe before expiration.
> - Normal reopening restores that commit even after upstream advances.
> - The benefit is lower host disk use while finished tasks remain
available for later work.

## Linked Issues or Issue Description

Refs #10285 and #2022. Follows #16433 for skill-cache expiration.
Related #11936 provides separate host-local cleanup tooling; this change
extends the existing company-scoped lifecycle worker and normal
workspace reopening. ROADMAP.md does not specify a competing
implementation.

## What Changed

- Add opt-in expiration for verified Paperclip-owned Git worktrees after
their whole task tree has been done or cancelled for 24 hours.
- Preserve active and scheduled runs, previews, pending reopening,
unresolved recovery, dirty files, unknown ignored files, and unsupported
or unique Git state.
- Verify an authenticated fetch in a fresh object store. Save repository
identity, exact commit, branch, and ownership before any deletion.
- Rename eligible files into recorded managed trash. Resume interrupted
cleanup under source and lifecycle locks.
- Expire private base clones only after consumer, file, reference,
reflog, and object checks pass. Preserve shared project base clones.
- Rebuild missing bases and worktrees through normal reopening at the
recorded commit. Return an explicit retryable error when repository
access fails.
- Add independent workspace/base switches, dry-run reports,
reclaimed-byte counts, and operational documentation. No table, public
API, UI, or recovery-retention change.

## Verification

- Real local bare remote plus Postgres: create at A, advance upstream to
B, expire the worktree and private base, reopen at A, then make and
retain a subsequent commit.
- Final lifecycle suite: all 20 tests passed in 46.41 seconds at
`d72947a2e45be5d0c912debb03c46b15863b4798`. Review fixes cover
second-cycle expiration, newer-branch recovery, normal preparation after
restoration, branch adoption, and Git administration path controls.
Eleven existing branch reconciliation controls also passed. Covers
unique files and Git state, live descendants, scheduled runs, recovery,
previews, unauthorized access, upstream failure, concurrent reopening,
interrupted deletion, shared bases, and nested private worktrees.
- Final guard regressions: 3 affected tests passed. Existing
workspace/runtime/preparation/source controls: 328 tests passed in
238.69 seconds.
- Full repository typecheck and build passed locally. The full local
test attempt did not pass: initial native-session cases hit macOS
Postgres shared-memory exhaustion, source changes invalidated two
discovery cases, and the checkout disappeared near the end. The
final-code retry of the remaining skill and unrelated controls passed
all 103 tests. All checks passed on this exact head, including
typecheck, general and serialized tests, Runner checks, build, canary
dry-run, browser E2E, and security scans. Greptile reviewed the head at
5/5 with all findings resolved.
- Fixed a blocking CI policy false positive for
`docker-compose-secrets.test.mjs`. The test still rejects GitHub secret
expressions, including dot, bracket, and multiline forms. Its full
15-test suite passes.
- Map validation and `git diff --check` passed.
- Staging dry-run inspection, measured reclamation, and ordinary product
acceptance remain pending. No live acceptance is claimed.

## Risks

- Git restoration depends on continued upstream availability and
credentials. Cleanup skips unverified commits; restoration never
substitutes the default branch.
- File deletion requires multiple conservative proofs. Unknown or
unsupported state is retained and can limit reclamation.
- Source and lifecycle locks serialize preparation, reopening, and
expiration. Remote verification has a deadline but can delay work on the
same source.
- Start with both expiration switches disabled. When enabled, dry-run
remains the default. Rollback disables further deletion while retaining
restoration support.

## Model Used

OpenAI GPT-6 through Codex, with reasoning, repository inspection, tool
use, and code execution. The exact backend 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 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 (focused tests; full local
limitation 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-15 13:09:59 -05:00
DottaandPaperclip 25b16e65fc fix(observability): detail workspace and connector preparation (#16454)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The server prepares a repository, sandbox workspace, and connector
access before an agent can reply.
> - Existing traces measure large preparation phases but leave important
work inside those phases unclear.
> - Repository source materialization and Browser Use discovery can do
more work than their callers suggest.
> - New detail must preserve access checks, run ownership, and the
existing work order.
> - This pull request adds fixed OpenTelemetry spans inside those
operations.
> - Operators can use one deployed trace to select the next performance
fix.

## Linked Issues or Issue Description

Refs: #16419, #16425, #16428.

**What existing behavior does this improve?**

Startup traces for server workspace preparation, native sandbox
synchronization, and connector assignment resolution.

**Current behavior**

Workspace and connector aggregate spans can take many seconds. The trace
does not separate private source cloning, seed reuse, archive work,
progress persistence, or each connector resolver. Browser Use resource
selection builds the full authorized tool catalog. The configuration and
native backend can each resolve connector assignments.

**Proposed behavior**

Show the awaited work as fixed child spans. Separate discovery queue
wait from catalog construction. Preserve the initiating run context when
another run releases a scheduler slot. Add no new lifecycle event writes
for workspace detail callbacks.

**Reason and benefit**

Operators need evidence about the hosted critical path before another
performance change. These spans distinguish filesystem work, provider
transfer, authorization, transaction entry, locks, and reporting
overhead.

**Breaking changes**

None. Authorization, query order, transaction ownership,
synchronization, existing progress events, and task results retain their
contracts. The change adds opt-in Observability spans under the existing
OTLP endpoint gate.

## What Changed

- Trace private source directory setup, Git credentials, clone,
requested ref, source identity, and checkout publication.
- Trace sandbox source capture, seed cache/replay, shallow clone and
archive, overlay copy/archive, verification, upload, warm stamps, and
descriptor persistence.
- Separate existing awaited progress reporting from useful workspace
work. Keep new detail callbacks trace-only.
- Trace each connector resolver and Browser Use catalog/grant work.
Split discovery queueing, descriptor sources, and policy evaluation.
- Trace Slack authority, credential reads, catalog synchronization,
transaction entry/settlement, and advisory locks.
- Update the real filesystem staging trace expectations and the
Honeycomb investigation guide.
- Add a real scheduler regression for a queued job released by another
run. Assert run ownership, parent spans, and exactly one completed queue
span.

## Verification

- Passed: server and adapter-utils TypeScript checks (`pnpm --filter
@paperclipai/server exec tsc --noEmit` and `pnpm --filter
@paperclipai/adapter-utils exec tsc --noEmit`).
- Passed: 252 checks across 9 focused files. These cover real filesystem
staging, native workspace synchronization, trace ownership, endpoint
gating, and workspace preparation.
- Passed after review: 26 trace-context, tracing-failure, and
discovery-scheduler checks across 3 files (these overlap the first run).
The new queued-discovery regression fails when context binding is
removed and passes after restoration. An initial submillisecond
timestamp assertion was replaced with explicit span-completion order to
avoid SDK clock precision assumptions.
- Passed on implementation commit
`0e68968a4bd61001893d833f281f12bb110edbe1`: `pnpm -r typecheck` and
`pnpm build`. The later commit updates only an engine test expectation.
- The first CI workspace lane found an old engine trace-tree
expectation. It expected the earlier span set. The updated assertion now
checks the new detail spans, their parents, and single completion. Its
targeted executor check passes.
- The full test suite, build, release registry, and end-to-end gates
pass in CI on final head `40e37d89ef679109d60a96bb5731a0616efeaa43`: 55
passing checks and 2 optional Storybook skips. The full suite was not
duplicated locally after the focused run.
- Greptile reviewed the final head at 5/5. No unresolved review threads
remain.
- After deployment, filter Honeycomb by the hashed run ID and verify
`service.version`. Inspect `heartbeat.prepare.workspace`,
`runtime_selection.workspace_sync`, and the connector assignment
parents. The guide in `doc/observability.md` explains each new family
and the nested intervals.
- No hosted run has used this new instrumentation yet. Local checks
cannot establish hosted latency improvement.

## Risks

- Tracing adds spans when an operator configures an OTLP endpoint.
Detail remains capped at 16 spans per phase per execution attempt.
- Parent and child durations overlap. The documentation explains how to
avoid counting them twice.
- A discovery job can start in another run's scheduler continuation. The
bound callback preserves the initiating async context.
- New spans export fixed names and the existing hashed run ID. They add
no paths, repository URLs, connector resource IDs, credentials, tool
schemas, or exception text.

## Model Used

OpenAI Codex, GPT-6 family, with reasoning, tool use, 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 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-15 12:21:32 -05:00
Devin FoleyandPaperclip c7f4b74111 fix: isolate fresh task sources from restricted project workspaces (#16095)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Each task must have an isolated workspace that its agent can read.
> - Older project checkouts can contain worktrees for restricted tasks.
> - The source access check correctly rejects these shared checkouts.
> - A fresh task then fails even when its agent can clone the project
remote.
> - This pull request gives fresh default tasks a separate clone of the
same remote.
> - The task can start while the restricted task files remain protected.

## Linked Issues or Issue Description

**What happened?**

Fresh tasks fail with `Task workspace access is no longer available`
when their default project checkout contains a restricted task worktree.
The caller has access to the new task and its remote repository. The
shared local Git source is unsafe to copy.

**Expected behavior**

Use a separate clone of the same authorized remote for a fresh default
task. Keep source access checks and responsible-user Git credentials in
force.

**Steps to reproduce**

1. Put a restricted task worktree inside a project checkout.
2. Assign a new default task to an agent that cannot read the restricted
task.
3. Start the new task. The current source check fails before workspace
creation.
4. With this fix, the task uses a separate remote source. The restricted
files are absent. Later runs reuse the same owned source.

Related work: Refs #15749, Refs #15528. This change keeps their source
retention and workspace ownership checks.

## What Changed

- Add a remote source path scoped to the company and task.
- Clone through the run’s Git connection after the shared source fails
its access check.
- Reject reused workspaces, explicit selections, pinned branches, local
sources, credential-bearing URLs, and symlink paths.
- Check source access again before publishing the workspace.
- Resolve later runs from the verified recorded source. Ignore leftover
clones that the saved workspace does not own.
- Record provenance for new implicit Git defaults. Read the current task
binding before fallback. Preserve explicit, inherited and ambiguous
legacy checkout choices.
- Keep the effective task strategy during startup validation of matching
implicit defaults. Preserve the existing explicit-selection write check.
- Add regression coverage and document the fallback.

## Verification

- Merged master `c8efdbfba43` and resolved both rounds of catalog/index
conflicts. All upstream suites, classifications, source references and
story IDs are preserved. Both fix branches combine cleanly in either
merge order, with no catalog fingerprint drift.
- Passed locally: 313 focused source-isolation, preparation,
task-creation, binding and trust tests before the final startup fix. The
final fix passes all 100 source-trust, task-binding and
environment-selection tests. Earlier workspace-resolution and
persisted-source suites also passed.
- Real-Git regressions cover all three review findings. Reconstruction
ignores an unrecorded clone and preserves unpublished commits/files.
Explicit and parent-inherited checkout IDs without typed selections
retain their denial and branch tips without cloning or acquiring an
environment. A protected-project heartbeat completes and resumes using
the task’s Git strategy with read access. Explicit selection still
requires writes, and a mismatched default is rejected.
- Passed: the complete Storybook catalog check with no drift errors,
feature and agent map structure checks, and all 17 catalog/index script
tests. The generated index counts match the merged catalog. The current
upstream verification-route inventory remains unchanged. The catalog
contains all 262 authored suites and 2,481 story IDs.
- Passed: full workspace typecheck and build after the final guard
changes, on latest head `79d2adadcb6d3d7a04b9943a91bdb8b0b6abea6d`.
- Latest head `79d2adadcb6d3d7a04b9943a91bdb8b0b6abea6d`: complete CI
passed (54 successful checks, two intentional skips), including the full
general/serialized suites and all eight browser shards. Fresh Greptile
Apex review is 5/5 on this same commit, with no unresolved findings or
recommendations. The full local test command was attempted earlier
without a complete aggregate result; the complete suite result is from
CI.
- Manual check: configure a shared project checkout with a restricted
task worktree. Admit a fresh default task using the authorized remote.
Confirm separate Git storage and no restricted local branch or file.
Reuse, close and reopen the task workspace. Confirm that explicit,
literal branch and low-trust selections retain the denied source.

## Risks

- A clean remote clone excludes unpublished local work. The fallback
applies only to fresh default tasks and rejects existing workspace or
branch selections.
- A private remote can fail to clone when the responsible user lacks Git
credentials. The run then reports the failure; access checks are not
bypassed.
- Older untyped checkout bindings cannot prove default provenance. They
keep the source denial instead of silently dropping unpublished work.
- New implicit Git defaults use the existing workspace-intent contract.
The source directory uses existing instance storage. No schema migration
is required.

## Model Used

OpenAI GPT-6, model ID `gpt-6`, through Codex. Used reasoning,
repository inspection, code editing, terminal tools, and test execution.
The API session does not expose an exact 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-13 12:31:40 -07:00