Commit Graph
5 Commits
Author SHA1 Message Date
DottaandPaperclip 7e6d512597 fix(onboarding): make chief-of-staff hiring reliable (#13317)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The first agent helps the board define work and hire other agents.
> - That agent can have the general role while its instructions require
hiring skills.
> - Missing skills and blocked schema discovery make valid requests
fail.
> - Repeated confirmation and invalid waiting guidance can turn these
failures into extra runs.
> - This PR supplies the required skills, opens read-only schema
discovery, and corrects the guidance.
> - The agent can complete an authorized hire while company approval and
duplicate checks still apply.

## Linked Issues or Issue Description

Refs #13068 — the first-task onboarding flow that this change repairs.
Refs #12029 — related drift between the sandbox allowlist and bundled
hiring guidance. This PR adds schema access; it does not replace the
earlier hiring-route fix.

**What happened?**

A general-role onboarding chief received hiring instructions without the
core hiring skills. Sandbox requests to the documented OpenAPI endpoint
failed. The agent then guessed question and hire payloads. The persona
required new confirmation after validation errors and described waiting
states that agents cannot set.

**Expected behavior**

A direct request authorizes the requested hire. The chief asks only for
material missing details, uses valid API payloads, and completes the
task. Formal company approval gates still apply. A saved human-input
card gives the task a valid waiting state.

**Steps to reproduce**

1. Create an onboarding chief with role `general` through the board.
2. Ask it to hire a friendly robot with a supplied name and
responsibilities.
3. Check its assigned skills, schema requests, question cards, hire
requests, and final task state.

**Paperclip version or commit**

Reproduced on the first-task onboarding implementation after #13068. The
live local verification used this branch at `112f44610`.

**Deployment mode**

The original failure used a hosted sandbox with legacy Codex ACP. Live
verification used an isolated local instance and real `codex_local`
execution. Queue and HTTP/2 transport access is covered by automated
tests.

## What Changed

- Give board-created onboarding chiefs the existing core skills
regardless of role. Preserve explicit skill version pins, including
aliases. Keep ordinary general-agent defaults and authorization checks.
- Allow exactly `GET /api/openapi.json` through both sandbox bridge
transports.
- Publish validator-tested question, free-text, hire, and waiting
examples. Regenerate the runner API reference and capability inventory.
- Clarify direct authorization, material ambiguity, and correction of
confirmed pre-creation validation failures. Preserve uncertain-outcome
reconciliation, duplicate protection, and company approval gates.
- Align disposition instructions with agent permissions and the saved
human-input waiting path.

## Verification

- After rebasing onto current `master`: 69 targeted server tests, 110
queue/HTTP2 bridge tests, and 4 capability inventory tests passed. These
cover core skill defaults, version pins, actor restrictions, schema
access, published examples, hire validation, idempotency, and approval
gates. Waiting recovery tests and live question flows also passed before
the rebase.
- `pnpm -r typecheck` and `pnpm build` passed again after the rebase.
Frozen dependency installation and both generated capability checks
passed.
- Ran the full `pnpm test:run` suite. The initial run had 14 failed
server files due to local database resource limits, a missing built test
fixture, and socket failures. All 14 files passed after fixture repair
and isolated retries. UI, CLI, workspace packages, database tests, and
all 145 serialized server files passed.
- Real one-request hiring replay: one hire, one successful run, task
done in 2m16s. No repeated approval or recovery escalation.
- Real two-turn browser conversation: start with an unspecified hire,
then supply a name and friendly robot responsibilities. One
clarification card, one hire, two successful runs, task done in 3m27s of
execution. No failed writes, confirmation cards, or recovery actions.
- Assigned the hired robot a welcome-message task through the browser.
It produced a warm message under 100 words and finished in one
successful 66-second run, with no questions or recovery actions.
- The two-turn flow still asked an optional preferences question and
gave a technical final reply. These are remaining presentation limits.
- Greptile: 5/5 on `b71f83ba2`, with zero unresolved review threads.
Fixed its generator finding and passed 1,655 published-example/runtime
API tests plus server typecheck. All latest-head CI checks are green (32
passed; 2 unrelated Storybook checks skipped). The signoff-policy
browser test initially timed out while waiting for an approver run. Its
shard passed on one rerun without code changes. [CI
run](https://github.com/paperclipai/paperclip/actions/runs/34698211049).

## Risks

- Onboarding chiefs receive more default skills. Ordinary general agents
retain existing defaults, and explicit versions take precedence.
- Prompt guidance can affect model behavior. The live replays are
examples, not a guarantee that every model follows the guidance.
- Retry guidance applies only when validation confirms that nothing was
created. Uncertain outcomes still require checking existing agents.
- No database migration or new public endpoint. Existing company
boundaries, approval gates, and bounded recovery remain in force.

## Model Used

OpenAI Codex, model `gpt-6-astra`, with reasoning, tool use, code
editing, and live browser verification. The exact context-window size is
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-09-12 12:59:42 -05:00
Nicky LeachandPaperclip 6019e2bd6e feat(adapter-utils): carry binary bodies and attachment routes over the HTTP/2 sandbox bridge (#12923)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Paperclip runs agents in local and remote sandboxes through adapter
utilities
> - The HTTP/2 sandbox bridge decoded every body as UTF-8 text and
rejected non-JSON content
> - This stopped agents from uploading or downloading issue attachments
through that bridge
> - This pull request carries raw bytes, permits the two attachment
routes, and enforces a shared body limit
> - The benefit is correct attachment transfer with a process-wide
memory guard

## Linked Issues or Issue Description

**What existing behavior does this improve?**

The HTTP/2 sandbox bridge forwards request bodies between an agent
sandbox and the Paperclip host. It now supports binary bodies and the
issue attachment routes.

**Current behavior**

The bridge decodes each body as UTF-8 text. It returns HTTP 415 for
content types outside the JSON route list. An agent cannot upload or
download an issue attachment through this transport.

**Proposed behavior**

The bridge carries raw bytes through the forward path. It permits the
attachment upload and content routes. The queue transport and file
gateway keep their existing route behavior. A shared 10 MiB body limit
and process-wide byte reservation protect memory use.

**Reason and benefit**

Attachment clients need byte-preserving transfer. The shared limit keeps
the gateway and host aligned. The reservation prevents concurrent
streams from exceeding the accepted process memory ceiling.

**Breaking changes**

The HTTP/2 bridge accepts two attachment routes and permits binary
content. The queue transport and file gateway keep their previous route
lists and HTTP 415 behavior. No schema or external endpoint changes.

## What Changed

- Carry request and response bodies as raw bytes through the HTTP/2
bridge.
- Permit attachment upload and attachment content routes on the HTTP/2
bridge only.
- Raise the resolved per-body limit to 10 MiB and share it between the
gateway and host.
- Reserve body bytes before allocation and release each stream
reservation on every terminal path.
- Document the body limit, process ceiling, and reservation behavior.

## Verification

- Run `pnpm exec vitest run
packages/adapter-utils/src/http2-bridge-server.test.ts
packages/adapter-utils/src/execution-target-sandbox.test.ts
packages/adapter-utils/src/sandbox-callback-bridge.test.ts`; 226 tests
pass.
- Run `pnpm --filter @paperclipai/adapter-utils typecheck`; it passes.
- Run the direct server TypeScript check with `tsc --noEmit` in
`server/`; it passes with zero errors.
- Verify multipart upload and binary download round trips over HTTP/2
without corruption.
- Verify the queue transport and file gateway return HTTP 415 for the
same routes.
- Verify the host rejects bodies over the resolved limit.
- Verify a denied reservation returns HTTP 503 and allocates no copy.
- Verify stream cleanup releases reservations after completion, error,
abort, timeout, and close.

## Risks

The bridge now accepts larger bodies and binary content. The
process-wide reservation limits total live body bytes to 1 GiB. Route
behavior changes only for the HTTP/2 bridge. The security review found
no blocking issue for this commit range.

## Model Used

OpenAI Codex, GPT-5. The runtime used tool calls and code execution. The
runtime did not expose the context window size. No model-generated code
changes were made for this pull request.

## 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-09-08 14:18:12 -07:00
Nicky LeachandPaperclip 64b7dce0ad refactor(adapter-utils): replace the process-wide byte ledger with route-local byte bounds (#12465)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The adapter layer carries sandbox requests to host processes.
> - The HTTP/2 bridge used one process-wide byte ledger for all routes.
> - One busy route could exhaust that shared budget and move another
route to file transport.
> - This pull request gives each host retention site a fixed byte bound
and limits concurrent HTTP/2 streams.
> - The benefit is local protection: one route cannot consume the byte
budget of another route.

## Linked Issues or Issue Description

**What happened?**

The HTTP/2 bridge used one aggregate byte ledger for retained bytes
across all routes. A busy route could exhaust the shared budget and
force an unrelated route to use file transport.

**Expected behavior**

Each route should protect its own retained bytes. A reset on one HTTP/2
stream should cancel only that stream's host forward.

**Steps to reproduce**

1. Start the HTTP/2 bridge with multiple sandbox routes.
2. Send enough retained data through one route to reach the aggregate
byte limit.
3. Send a request through a sibling route.
4. Observe that the sibling route can fall back to file transport
because the first route used the shared ledger.

**Paperclip version or commit**

`47639e227e78e3c5e0dd1a3c0e2d792fe86895a3`

**Deployment mode**

Built from source with the adapter-utils and server test suites.

## What Changed

- Bound each host retention site with a fixed local byte limit.
- Limited concurrent live HTTP/2 streams with one built-in stream limit.
- Bound each host forward and response-body read to its own HTTP/2
stream lifetime.
- Removed the process-wide byte ledger, its environment override, its
metrics, and its file-transport fallbacks.
- Added tests for the stream limit, host body budget, and sibling-stream
cancellation.

## Verification

- Run `pnpm vitest run --project adapter-utils`.
- Confirm that 996 adapter-utils tests pass.
- Confirm that `test_live_forward_work_never_passes_the_stream_limit`
passes.
- Confirm that `test_the_host_body_budget_matches_the_stream_limit`
passes.
- Confirm that the sibling-stream cancellation test passes.
- Run `pnpm tsc --noEmit`.
- Confirm that all pull request checks pass.

## Risks

The bridge no longer uses a process-wide byte ledger. A local bound or
stream limit that is too low can reject or delay valid work. The tests
cover the new limits and stream cancellation behavior.

## Model Used

OpenAI GPT-5 Codex. Runtime model ID: GPT-5. The model used code
execution and repository tools. The runtime 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-08-28 14:36:18 -07:00
Nicky LeachandPaperclip 02a984068c refactor(adapter-utils): clean up the HTTP/2 bridge request-body bounds (#12166)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Agent adapters use the HTTP/2 bridge to carry requests and responses
> - The bridge has an idle bound and a total-lifetime ceiling for
request bodies
> - The old renewable lifetime bound re-armed with each DATA chunk and
could not act before the idle bound
> - The code also repeated the same bounds and rationale in several
places
> - This pull request removes the unreachable renewable bound, keeps the
one-shot ceiling, and simplifies the shared bounds object
> - The benefit is clearer protection logic with the same default
request-body behavior

## Linked Issues or Issue Description

**What existing behavior does this improve?**

The HTTP/2 bridge request-body reader uses several repeated bound
parameters and comments. One renewable lifetime bound cannot act before
the idle bound under the shipped defaults.

**Subsystem affected**

`packages/adapter-utils/` — HTTP/2 bridge adapter utilities.

**Current behavior**

The idle bound and renewable lifetime bound both re-arm after each DATA
chunk. The renewable bound therefore does not act on its own. The
total-lifetime ceiling also shares timer setup with the renewable bound.

**Proposed behavior**

Remove the renewable lifetime bound. Keep the total-lifetime ceiling as
an independent one-shot timer. Pass one bounds object to the bridge call
sites and keep tests for the idle bound and total-lifetime ceiling.

**Reason and benefit**

The change removes unreachable logic and repeated rationale. It keeps
the independent total-lifetime protection and makes the bound behavior
easier to review.

**Breaking changes**

The change removes two public constant and option names that
repository-wide search found unused outside this implementation. The
shipped default behavior does not change.

## What Changed

- Remove the renewable request-body lifetime bound and its public names.
- Keep the total-lifetime ceiling as a one-shot timer that starts when
the body read starts.
- Replace repeated bound parameters with one `Http2BridgeBodyBounds`
object.
- De-duplicate bound rationale comments.
- Add shared test helpers and update tests for the idle bound and
total-lifetime ceiling.

## Verification

- Run `npx tsc --noEmit -p packages/adapter-utils`.
- Run `npx vitest run
packages/adapter-utils/src/http2-bridge-server.test.ts`.
- Wait for the pull request CI checks.
- Request the Greptile review and confirm a 5/5 verdict with no open
findings.

## Risks

The main risk is an incorrect timer lifetime after the renewable timer
removal. The one-shot ceiling remains independent, and the updated tests
cover its expiry and cleanup paths. The change does not alter the
shipped default bounds.

## Model Used

OpenAI Codex based on GPT-5. Exact runtime model version is GPT-5. The
work used tool calls and code execution for repository inspection and
GitHub operations.

## 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-08-25 08:09:52 -07:00
Nicky LeachandPaperclip 445547c989 feat(duplex): run the Daytona sandbox callback bridge over Node HTTP/2 (#12120)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - Sandbox providers carry agent work through controlled execution
channels
> - The Daytona callback bridge uses a bespoke line-framed protocol over
its duplex channel
> - The bespoke protocol adds framing work and does not use the Node
transport that already supports multiplexed streams
> - This pull request carries raw bytes across the channel, adds a Node
HTTP/2 bridge, and selects it for Daytona
> - The benefit is one authenticated, multiplexed callback session with
queue_v1 as the bounded fallback

## Linked Issues or Issue Description

**Subsystem affected**

The packages/plugins Daytona provider and the shared duplex execution
path.

**Problem or motivation**

The Daytona callback bridge uses a bespoke line-framed protocol over the
provider duplex channel. This adds protocol work and limits stream
handling.

**Proposed solution**

Carry raw bytes through the cross-layer channel. Add an authenticated
Node HTTP/2 host server and sandbox client gateway. Select http2_v1 for
Daytona and retain queue_v1 as the fallback.

**Alternatives considered**

Keep the current duplex_v1 protocol. This keeps the bespoke framing path
and does not provide one HTTP/2 session for callback streams.

**Roadmap alignment**

ROADMAP.md lists Daytona under cloud and sandbox agents. This change
improves the shipped Daytona provider path.

**Additional context**

The branch adds no dependency. Node 24 provides the http2 module. The
host token check and canonical path parser remain the single dispatch
path.

## What Changed

- Carry raw Uint8Array chunks through the adapter, plugin, worker,
runtime, and Daytona layers.
- Encode bytes as base64 only across the JSON-RPC hop, because JSON has
no binary type.
- Add the bounded host HTTP/2 server and the in-sandbox HTTP/2 client
gateway.
- Authenticate every stream with the per-run bridge token before route
work.
- Parse the path once and reuse the canonical result for route and
forwarding work.
- Select http2_v1 for Daytona and fall back once to queue_v1 when the
client preface is absent.
- Add transport, session, stream, and fallback telemetry.
- Mark HTTP/2 as the preferred transport and queue_v1 as the
soft-deprecated fallback.

## Verification

- `npx vitest run packages/adapter-utils/src` — 990 passed and 4
skipped.
- `npx vitest run
server/src/__tests__/plugin-worker-manager-duplex.test.ts` — 32 passed.
- `npx vitest run --config
packages/plugins/sandbox-providers/daytona/vitest.config.ts` — 220
passed and 6 skipped.
- `npx tsc --noEmit` in `packages/adapter-utils`, `packages/shared`,
`packages/plugins/sdk`, and `server` — clean.
- No `package.json` or `pnpm-lock.yaml` file changed.
- The live Daytona test skips when `DAYTONA_API_KEY` is absent.
- The root `npx tsc --noEmit` command has a pre-existing missing
`packages/adapters/droid-local` reference on this branch and on
`master`.

## Risks

- The transport change affects several duplex layers and could expose
byte-boundary errors.
- A missing HTTP/2 client preface falls back once to queue_v1 and
records `preface_missing`.
- The host token check and canonical path parser must remain on the
shared dispatch path.
- The live Daytona test needs `DAYTONA_API_KEY` and does not run in this
agent sandbox.

## Model Used

OpenAI GPT-5, tool-enabled coding agent with repository inspection,
GitHub CLI, and shell 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 (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-08-25 07:35:39 -07:00