Files
Priya RamanandPaperclip e26b917971 fix(sandbox): enforce the duplex readiness cap on every pre-READY path and tolerate PTY noise
Enforce the O(1) readiness-buffer cap on every pre-READY path. Before this
change the gate checked the cap only on the no-newline branch. An over-cap blank
prefix followed by a valid nonce-bound READY frame in one chunk reached READY
acceptance without a cap check. The gate now rejects when the cursor passes the
cap after it skips a line, and before it decodes a completed candidate line. The
cap check has priority over READY acceptance on every path. A cap breach settles
protocol contamination and falls back to the file bridge with bounded cleanup.

Make the readiness gate tolerant of pre-READY noise. A PTY channel echoes the
launch wrapper line before it sets raw mode, so the first line is often not the
READY frame. The gate now skips each pre-READY line that does not decode as a
READY frame, then accepts the first line that decodes as a READY frame with the
matching nonce. A READY frame with a wrong nonce still fails the handshake. The
skipped bytes stay in the capped buffer, so the cap and the timeout still bound
the wait, and the newline scan stays linear in the bytes received.

Fix the gateway launch command. A POSIX shell rejects an environment-assignment
prefix on exec, so exec NAME=value command exits 127 and the gateway never
starts. Use exec env NAME=value command, which keeps the exec-replaces-shell
property and passes the assigned environment.

Add fallback_reason to the channel-open span on the fallback path only.
fallback_reason is an existing closed dimension key, so no new key reaches a sink.

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-08-20 20:24:36 +00: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.