Files
PaperClipAI/packages/adapter-utils
Nicky LeachandPaperclip 5cffd5c72e feat(sandbox): declare and collect the advisory read-write intent (#10521)
## Thinking Path

> - Paperclip is the control plane for AI agent companies
> - Sandbox providers move files between the host and the sandbox
> - The runtime needs advisory data for which sync paths are writable
> - The host already knows that intent when it prepares the sync map
> - Daytona can record that intent for later use
> - This pull request adds the advisory access field and collects
writable paths
> - The benefit is that later runtime work can use the data without
changing current flow

## Linked Issues or Issue Description

No public GitHub issue exists for this change. The description below
follows the feature-request template fields.

### Problem or motivation
An agent runs inside an ephemeral sandbox. Some sandbox paths keep agent
changes; other paths do not. Today the runtime has no declared signal
for which sync destinations the agent may change and keep. A later
feedback wrapper needs this signal to give the agent real-time feedback
when a write lands on a non-persistent path.

### Proposed solution
Add an optional advisory `access: "rw" | "ro"` field to the sync
file-mapping types. The host sets `rw` for the workspace, git-history,
and asset destinations, and `ro` for referenced-project trees. An absent
value defaults to `ro`. The Daytona provider collects the `rw` target
directories into a per-lease writable set for later use. This change
adds the metadata and the collection only. No execution path reads the
writable set yet, so runtime behavior does not change.

### Alternatives considered
Derive a static writable set in provider code. This alternative is
weaker: the layer that authors each sync destination already knows the
intent, so a per-operation declaration is more accurate and does not
hard-code a path list.

### Roadmap alignment
This is the first step toward an advisory sandbox feedback wrapper. The
wrapper is best-effort and adds no security. The ephemeral sandbox stays
the only boundary.

### Additional context
The field is advisory metadata. It does not change the file transfer and
adds no security.

## What Changed

- Added an optional `access` field to the sync file mapping types.
- Set the workspace, git history, and asset destinations to writable.
- Set referenced project destinations to read only.
- Added a writable set store in the Daytona provider.
- Recorded the parent directory of each writable sync mapping during
sync in.

## Verification

- The handoff reports these checks before push.
- `pnpm --filter @paperclipai/adapter-utils exec vitest run
sandbox-managed-runtime.test.ts`
- `pnpm --filter @paperclipai/plugin-sdk exec tsc --noEmit`
- `vitest run src/plugin.test.ts` in the Daytona package
- `tsc --noEmit` in the Daytona package

## Risks

- Low risk.
- The new field is advisory.
- The writable set store is best effort and in memory.
- A cold store falls back to the workspace baseline.

## Model Used

OpenAI Codex, GPT-5, tool use, 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 linked existing issues or described the issue in the
PR
- [x] I have not referenced internal or instance-local Paperclip issues
or links (only public GitHub `#NNN` / `github.com/paperclipai/paperclip`
URLs)
- [x] My branch name describes the change and contains no internal
Paperclip ticket id or instance-derived details
- [ ] I have run tests locally and they pass
- [ ] I have added or updated tests where applicable
- [ ] I have updated relevant documentation to reflect my changes
- [ ] I have considered and documented any risks above
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [ ] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-07-30 21:20:13 -07:00
..
2026-03-12 13:09:22 -05:00

@paperclipai/adapter-utils

Shared utilities for Paperclip adapters: process spawning, environment injection, sandbox/SSH transport, workspace sync, and the round-trip helpers that move code between the local execution-workspace cwd and wherever the agent actually runs.

For the adapter-author guide see docs/adapters/creating-an-adapter.md and the in-repo notes at packages/adapters/AUTHORING.md.

No-remote-git contract

The local execution-workspace cwd is the only persistence boundary across runs. No adapter may depend on a git remote for cross-run state.

Adapters that run the agent on a different host should use the SSH round-trip helpers in src/ssh.ts:

  • prepareWorkspaceForSshExecution({ spec, localDir, remoteDir }) — bundles the local cwd (tracked files, dirty edits, untracked additions, and the git history needed to reconstruct it) to remoteDir before the run starts. Runs with no git remote configured.
  • restoreWorkspaceFromSshExecution({ spec, localDir, remoteDir, ... }) — syncs the remote cwd back into localDir after the run, including any new commits the agent created. Also runs with no git remote configured.

prepareRemoteManagedRuntime in src/remote-managed-runtime.ts wraps both calls for adapters that want a per-run remote workspace and an automatic restoreWorkspace() finally hook.

The invariant is pinned by the no-remote-git contract case in src/ssh-fixture.test.ts, which asserts that a remote-only commit propagates to the local worktree through the prepare → restore round-trip with no git remote configured at any point. Do not regress that test.