Commit Graph
171 Commits
Author SHA1 Message Date
DottaandPaperclip f01d17e4fa test(hermes): verify API receipt authority through native execution
Require wrong-biller token totals to remain incomplete, and cover complete and interrupted Anthropic/OpenAI receipts during normal and shutdown delivery.

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-09 10:29:27 -05:00
DottaandPaperclip e025ff2286 fix(hermes): settle direct API usage with complete wire receipts
Export image-owned qualification assets from cloud builds and cover Claude/OpenAI image, question and billing journeys.

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-09 10:13:33 -05:00
DottaandPaperclip f628d54bc8 fix(hermes): project native completion and tool activity
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-09 01:57:28 -05:00
DottaandPaperclip b7ea45ae9c Preserve cancelled native questions and their Stop evidence
Use the canonical question converter for durable fallbacks. Retire pending native input only on its confirmed cancelled turn. Pass cancelled status to shared account and billing checks and retain the original browser acknowledgement before polling.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-08 12:28:13 -05:00
DottaandPaperclip e3be06f25e fix(hermes): retain usage after input-yield shutdown
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-08 12:28:12 -05:00
DottaandPaperclip 842925d08c fix(hermes): settle closed retry work with unknown usage
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-08 12:28:12 -05:00
DottaandPaperclip e5afbd7107 fix(hermes): retain per-turn reported OpenRouter billing
Capture pinned SDK wire attempts, carry closed versioned receipts through ACPX and PRP, and bind reported subtotals to native turn accounting. Keep incomplete attempts unpriced and require settled cost plus budget health in the live OpenRouter oracle.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-08 12:28:12 -05:00
DottaandPaperclip 19ab7e06df fix(hermes): pin v7 permission policy in the independent server launch
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-08 12:07:09 -05:00
DottaandPaperclip a2643eb538 fix(runner): preserve Dot v6 while versioning Hermes input as v7
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-08 12:07:09 -05:00
DottaandPaperclip 9e07748e91 feat(runner): add native Hermes ACP qualification candidate
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-08 12:07:09 -05:00
DottaandPaperclip 75abb6a774 fix(runner): accept native Rust question cancellation envelopes
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-08 12:05:53 -05:00
DottaandPaperclip d9e17db5ed fix(runner): settle stopped native questions without stranded recovery
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-08 11:43:10 -05:00
DottaandPaperclip 424d9fced8 test(routines): retain the current master authority inventory
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-08 02:35:21 -05:00
DottaandPaperclip c7afea8dab fix(routines): reject lock contention before receipt mutations
Keep owned-routine lock acquisition nonblocking after run authority locks. A scheduled firing can finish, and the same mutation may retry without a saved partial receipt. The real concurrency regression is added; local PostgreSQL bootstrap failed before assertions, so its execution still requires CI. Server typecheck passes.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-08 02:28:27 -05:00
Dotta 79e5d38139 fix(routines): remap annotations and verify atomic schedule edits 2026-10-08 02:27:42 -05:00
DottaandPaperclip 49fdc5899e feat(runner): bind routine management to the live service
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-08 02:27:42 -05:00
DottaandPaperclip dd777f4b73 feat(dot): complete onboarding and expand governed Runner capabilities (#15414)
## Thinking Path

> - Paperclip manages AI agents, their work, and their permissions.
> - Paperclip Runner supplies the same admitted tool authority to each
provider.
> - The Dot provider in #15402 needs reliable onboarding and useful
agent capabilities.
> - An idle Dot could not start work, assign a human, read skills, or
produce a workspace artifact.
> - Pairing also relied on a second configuration save before ordinary
admission could work.
> - This pull request adds governed idle admission and shared Runner
tools, and completes pairing atomically.
> - Operators can test Dot with fresh data while keeping normal company,
approval, budget, and run ownership checks.

## Linked Issues or Issue Description

**Subsystem affected**

Paperclip Runner, dedicated Dot MCP access, OAuth onboarding,
experimental settings, and empty worktree startup. This PR builds on
merged provider PR #15402. It reuses the merged MCP gateway from #14846
and assistant connection work from #14933 and #15380.

**Problem or motivation**

An idle Dot could see assignments but could not act on a conversation
request until someone created a task first. Its Runner catalog could not
assign tasks to humans or read pinned skills and workspace files.
First-time OAuth discovery and pairing also needed browser fixes, and a
completed pairing did not persist its binding reference on the agent.

**Proposed solution**

Keep Dot within the existing Runner. Admit a visible agent-authored
intake task for idle requests. Add people, human assignment, cross-task,
skill, and optional sandbox workspace tools through shared authority.
Relay assigned app calls through the configured MCP gateway. Add lease
renewal and follow-up references. Save pairing and its configuration
revision atomically. Show prerequisites and provide a complete copy
prompt.

**Roadmap alignment**

This extends the experimental provider in #15402. It uses the existing
governed gateway, task model, skills, artifact path, and native Runner.
It adds no separate execution subsystem.

## What Changed

- Add a standalone OpenAI Dot agent choice with an independent
experimental opt-in. It works with the general Runner option off.
Require Assistant connections (MCP), authenticated sign-in, and public
HTTPS for pairing.
- Use Dot’s own option for company package import. Allow an unpaired Dot
configuration to save after external billing acknowledgement; task
admission still requires pairing. Prepare the shared dev binary for
Dot-only opt-in.
- Label saved Dot agents as OpenAI Dot. Use prerequisite-check copy in
setup and runtime configuration.
- Route Dot creation directly to pairing after explicit external billing
acknowledgement. Hide local CLI, model, and harness setup for Dot.
Preserve the shared Runner implementation and canonical API type. Other
Runner providers still require their general opt-in.
- Add an empty worktree option with fresh signing keys and no production
data copy.
- Fix public-client OAuth negotiation, discovery compatibility, and
optional separate browser authorization origin.
- Add one-use pairing consent preview, clear copied setup instructions,
and atomic binding persistence and cleanup.
- Add idle request admission with stable request IDs and normal
scheduling, permissions, budgets, and task ownership.
- Add identity and people discovery, human task assignment and
reassignment, and authorized cross-task comments and documents.
- Read assigned skill files from pinned manifests. Relay assigned app
calls through the merged gateway without exposing credentials.
- Add an off-by-default workspace bridge. Constrain paths and writes.
Run commands in a deny-by-default OS sandbox with no network or injected
credentials. Reserve mutations before effects and never blindly repeat
uncertain work.
- Add rolling lease renewal, task pagination, bounded operation limits,
and deduplicated follow-up references without comment bodies in
webhooks.
- Add an off-by-default attachment reading setting. Restrict reads to
files on the current assigned task. Verify size and hash, cache bounded
verified copies per run, paginate text or binary bytes, and recheck live
authority before returning.
- Keep file grants operator-owned. Reject agent self-grants across
configuration routes. Preserve attachment consent in create/import
forms. Close generic API file bypasses while retaining current-run
response snapshots and permitted uploads.
- Keep provider limits explicit. Do not inherit a Dot binding,
attachment permission, or workspace permission when hiring another
agent.
- Include the required Markdown format in cross-task document writes and
validate the API title limit. Verify real creation and revision
persistence.
- Restrict command execution to Linux bubblewrap with descendant
containment. macOS retains workspace file tools and artifact publishing,
while refusing command calls. Explain the platform limit in setup.
- Exclude Paperclip instance state from workspace files, uploads,
artifact publication, and sandbox commands. Protect nested directories
and case variants. Fail closed when the directory protection scan
exceeds 4,096 directories.
- Add static UI compression for slow public tunnels. Document setup, the
complete tool inventory, and qualification limits.

## Verification

- Merge preparation on `00ca2c75b` integrates merged base #15402 and
master `fc6304dfe`. The ancestry commit preserves the reviewed follow-up
source tree. The subsequent security fix excludes instance state from
file tools, uploads, artifact publication, and sandbox commands. It
preserves private task authorization and task monitors. It regenerates
the combined tool catalog, seeded catalog digest, and protocol manifest.
Workspace typecheck, full build, and UI token gates pass. All sixteen
real Dot broker cases and 93 company import cases pass after the review
fixes and creator-attribution test correction. The exported
human-assignment catalog and Unicode page boundaries are also fixed. All
ten catalog tests and nine workspace/skill bridge tests pass. All 35
workspace bridge and authority tests passed after the instance-state
fix, including real macOS commands in that intermediate version. The
subsequent document and descendant-containment fixes pass 44 focused
tests across bridge, authority, and setup UI, with six Linux command
cases skipped on macOS. Real cross-task documents pass the route
validator and persist two revisions. macOS refuses command execution and
does not advertise the tool. Full workspace typecheck and build, changed
server/UI typechecks, and token gates pass again on the final commit.
Greptile rates final head 00ca2c75b 5/5 and its completed check
concludes success; all review threads are resolved. All 58 current-head
checks are complete: 54 passed and 4 intentionally skipped. This
includes full tests, typecheck, build, Runner, browser E2E, release
verification, and Canary Dry Run. The older full local root attempt
finished with 16,602 passes, 93 skips, and ten failures across two
suites: it began before source edits and retained earlier imported
implementations while loading later tests. Both suites pass a clean
final-head rerun (25 passed, six Linux-only command cases skipped on
macOS). This mixed-source full attempt is not a final-head full-suite
pass; use the fresh CI evidence below.
- Full workspace typecheck and build pass for the standalone Dot change
on head `392d54f80`. UI token gates are clean. The full workspace
typecheck passed before the final importer UI edit; the changed UI
typecheck, build, and token gates pass again on the final commit. The
server build passes for its unchanged final source.
- Standalone selection, creation, settings, harness visibility,
inventory, and runtime admission checks pass. OAuth onboarding and the
real Rust/PostgreSQL broker suite pass 27 cases with the general Runner
option disabled. Dot and MCP revocation still block pairing; other
Runner providers remain disabled. Create, hire, conversion, and
inherited-hire route regressions pass 68 cases. The runtime selection
suite passes 20 cases. The setup UI suite passes 50 cases. Company
import and dev binary checks pass 97 cases. Import UI checks pass 29
cases, including Dot-only selection, preservation of imported Dot
agents, generic Runner fallback, canonical configuration serialization,
and required billing acknowledgement. A read of the synthetic instance
reports the native binary required with Dot enabled, the general rollout
disabled, and no persisted native work.
- The latest attachment, operator-consent, generic API file-guard, and
bridge checks pass 80 tests. Cache and native lifecycle checks pass 550
tests; create/import builders pass 45 tests; attachment setup UI checks
pass 16 tests. The real Rust/PostgreSQL Dot broker suite passes 15
cases.
- Earlier authority, human assignment, pinned skill, confinement,
cancellation, inheritance, onboarding, replay, OpenAPI, and gateway
regressions pass their focused rechecks. Workspace writes reject
concurrent stale hashes.
- In the live empty test-drive, turn the general Runner option off and
leave Dot and MCP on. Add agent shows a separate OpenAI Dot choice.
Create rejects missing billing acknowledgement, saves the canonical Dot
configuration, and opens pairing. The existing paired Dot remains ready
and passes its prerequisite checks. No new plugin pairing was needed for
this UI change. The final browser import preview keeps a Dot source
agent as OpenAI Dot, falls back a generic Runner agent while its switch
is off, and offers Dot independently.
- Real Dot completed OAuth, signed MCP Events readiness, and an
event-only assigned document task in an empty synthetic instance.
Pairing saved its binding without a second configuration save.
- Real Dot verified human assignment, cross-task comments and documents,
pinned skill reading, sandbox commands, lease renewal, follow-up input,
and a downloaded artifact whose bytes and hash matched its receipt. An
idle conversation request created an intake, created a task for its
human owner, continued after a definite missing-file read error, and
finalized Done with exit code 0.
- After operator approval, real Dot read a synthetic assigned-task
attachment and wrote its file-only random proof into an agent-authored
document. Its first test required accepting review because the existing
document tool removed the final newline.
- On head `2626c8f9b`, real Dot read a 13,849-byte synthetic attachment
in two pages, used `expectedSha256` on page two, saved exactly its final
random marker, verified readback, and finalized Done with exit code 0. A
direct inbox check was required for this attachment qualification; it
does not claim event-only delivery.
- Previous head `392d54f80` passes all 55 checks (53 passed, two
intentionally skipped), including the full test, typecheck, build,
native Runner, browser, and release verification gates. Greptile rates
this head 5/5; all review threads are resolved.
- Head `2626c8f9b` passed all 56 checks: 54 passed and two intentionally
skipped. This includes full typecheck, build, native Runner, server
tests, serialized suites, browser E2E, and Canary Dry Run. The unchanged
Cursor managed-runtime test exceeded its five-second deadline on the
first attempt; its focused local suite passed all eight cases, and the
single CI rerun plus dependent verify gate passed.
- A prior full local serial test attempt reported 19 failures (16,141
passed, 88 skipped) and stopped before later wrapper groups. It began
before the final source edits. Every failed suite has a passing fresh
recheck; the macOS snapshot stress case passes alone in 227 seconds. The
previous head `000fb9261` passed all 56 CI checks. PRs leave
`pnpm-lock.yaml` unchanged; CI and the refresh bot own dependency
resolution.

## Risks

- Dot remains off by default. Its own opt-in does not enable other
Runner providers. It still requires the MCP option; disabling Dot blocks
new work while keeping existing recovery and saved bindings.
- Dot requires a stable public HTTPS origin. Its base provider in #15402
is merged. Temporary tunnels are useful for testing but are not
permanent deployments.
- Idle intake creates a visible agent-authored task. It does not
fabricate a human message or bypass ordinary admission.
- Workspace commands require Linux bubblewrap with a private PID
namespace; deployment qualification is still needed. macOS file tools
and artifact publishing remain available, but commands are disabled
because sandbox-exec does not contain detached descendants. There is no
unrestricted fallback. Command protection fails closed above 4,096
workspace directories. The historical macOS command walkthrough does not
qualify the current Linux implementation.
- Provider model choice, token usage, cost, native thread control, and
global external stopping remain unavailable. Known Paperclip budget
gates still apply.
- The workspace bridge and attachment reader are separate opt-in
settings. Reading assigned task files sends their contents to OpenAI.
Revocation prevents future reads but cannot withdraw bytes already sent.
Files are read on request; automatic inbound attachment staging remains
disabled.
- An existing event registration can retain earlier instructions that
prohibit extra tasks. Dot asked for permission before a second intake
after the final event-only bootstrap; that extra no-nudge continuation
is not live-qualified under that earlier registration. The later
attachment qualification submitted normally through the composer. The
revised onboarding prompt describes the new idle entry point, and its
protocol polling path is tested.
- OpenAI event delivery can be delayed; a webhook acknowledgement is not
proof that Dot has begun work.
- A running Dot can retain an old plugin catalog after tool refresh.
Refresh and actual tool exposure must be checked before using new
top-level actions.
- Hosted and remote controller modes are not qualified.

## Model Used

OpenAI Codex, based on GPT-6. The exact deployment ID and context window
size are not exposed in this session. Capabilities used: reasoning,
repository editing, code execution, test inspection, and browser
control.

## 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
Paperclip ticket id or instance-derived details
- [x] I have run tests locally and they pass (focused suites and all
fresh failure rechecks pass; the earlier full attempt is disclosed
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-07 19:44:17 -05:00
DottaandPaperclip fc6304dfe5 feat(runner): add experimental OpenAI Dot provider over MCP Events (#15402)
## Thinking Path

> - Paperclip manages AI agents, tasks, permissions, and execution
budgets.
> - Paperclip Runner gives each provider the same admitted task and tool
authority.
> - OpenAI Dot runs outside the local process tree and needs
asynchronous work delivery.
> - The merged MCP gateway supplies OAuth consent and signed event
delivery.
> - A personal assistant grant cannot safely stand in for an assigned
agent.
> - This pull request adds a separate Dot agent connection and a durable
Rust Runner bridge.
> - The operator can assign work to Dot and inspect its accepted work,
tool receipts, and result.

## Linked Issues or Issue Description

**Agent or provider**

OpenAI Dot, as an experimental provider of the existing Paperclip Runner
adapter.

**Why this adapter is useful**

An operator can assign normal Paperclip tasks to an existing Dot. Dot
can read its mailbox, request work on an assigned task, use admitted
task tools, and submit a result. Paperclip keeps company scope,
checkout, approvals, known budget limits, and activity attribution.

**How the agent is invoked**

A dedicated `/mcp/runner` OAuth resource pairs one Dot grant with one
agent. A signed MCP mailbox event wakes Dot. Dot explicitly accepts the
assignment. The Rust Runner owns the durable turn and operation
receipts. The first release supports self-hosted instances with a local
Runner controller.

**Additional context**

This extends the merged public MCP gateway from #14846 and the assistant
invitation and device-consent work from #14933. This also integrates the
merged assistant tool and configuration expansion in #15380. Dot retains
its dedicated agent resource and cannot receive personal configuration
permission. The public assistant connection remains a personal
connection.

## What Changed

- Add a durable Rust Dot provider and its TypeScript Runner driver.
- Add closed PRP v3 external-provider operations and native execution
input v6.
- Add company-scoped pairing, mailbox, assignment, and operation
records.
- Reuse merged browser/device consent, client metadata verification,
webhook admissions, refresh, secret rotation, and warm-standby gates.
- Keep Dot scopes, issuer, grants, event workers, and tool access
separate from personal assistant access.
- Add Dot configuration, pairing, readiness, and consent UI. Keep agent
grants out of the personal Connections entry.
- Regenerate the Dot-only migration after master. Preserve published
gateway migrations. Make the new migration safe to reapply.
- Document setup, recovery, accounting limits, evidence, and remaining
account qualification.
- Reverify reconnect callbacks and wake outstanding work with a fresh
mailbox reference; preserve the existing assignment and operation
receipts.
- Clean up Dot bindings and waiting runs on OAuth revoke and
refresh-token replay. Old grants cannot revoke replacement bindings.
- Restore the pairing reference when an unsaved agent form is reopened;
document board-only pairing routes in OpenAPI.
- Accept a clean Rust exit after the acknowledged shutdown receipt.
Unexpected exits still require recovery.
- Clear the cached binding after a successful revoke so a failed
connection refresh cannot restore it.
- Add production-component Storybook states and screenshots for pairing
and connection review. All preview account data is synthetic.
- Persist normalized completion, serialize Dot turns and durable work
admission, and poll subscription readiness.
- Serialize mailbox writes and cursor reads; retain paused fence
acknowledgement without task authority.
- Authorize admitted review runs without changing the worker assignee.
Include the fenced assignment ID in production stop notices.

## Verification

- This PR integrates master `4a8178e9c`. Dot migration
`0317_messy_famine.sql` follows the published history and is safe to
reapply. The merge preserves the reserved migration connection,
batch-commit handling, private task checks, task monitors, and native
accounting.
- Local workspace typecheck, full build, and UI token gates pass. The
server typecheck passes after the review fixes. Database and native
executor regressions pass.
- All twelve real Rust/PostgreSQL Dot integration tests and twelve Dot
driver tests pass. The tests cover native document writing and
finalization, durable replay, queue admission, mailbox ordering,
admitted reviews, stale authority, production stop references, and
paused acknowledgements.
- Current head `d0e7e0626` passes all 57 checks: 53 pass and four are
intentionally skipped. This includes full typecheck, build, tests, Rust
Runner verification, browser E2E, release verification, and Canary Dry
Run. Greptile rates this exact head 5/5. All review threads are
resolved.
- The full local root test run is slower than the sharded CI run and has
not completed. The full CI test gates pass on the current commit.
Focused local regressions pass.
- Real-account pairing and event delivery on this base commit remain
unqualified. Live account and setup proof are recorded in the follow-up
#15414.

The following screenshots use synthetic preview data. They show the
production pairing component and do not qualify a real account or the
full agent setup journey.

![Synthetic pairing
preview](https://github.com/paperclipai/paperclip/blob/codex/dot-events-prototype/doc/screenshots/openai-dot-runner/pairing.jpg?raw=true)

![Synthetic connected
preview](https://github.com/paperclipai/paperclip/blob/codex/dot-events-prototype/doc/screenshots/openai-dot-runner/connected.jpg?raw=true)

## Risks

- This base adapter uses `PAPERCLIP_ENABLE_OPENAI_DOT=1` plus Public MCP
and Paperclip Runner. The separate experimental-settings follow-up in
#15414 replaces this environment flag with saved operator settings.
- Dot does not expose provider token usage or cost. The operator must
acknowledge external billing. Known Paperclip budget gates still apply.
- Cancellation fences Paperclip authority. It does not confirm that Dot
stopped all external activity.
- Assigned skill files and third-party MCP bindings are unsupported and
reject admission. There is no mounted workspace, model selector, or
provider thread identifier.
- Hosted agent-broker and remote controller deployments are not
qualified.
- The new migration follows the merged master history. Existing
prototype databases still need the normal master migration history
before this Dot-only migration.

## Model Used

OpenAI Codex, based on GPT-6. The exact deployment ID and context window
size are not exposed in this session. Capabilities used: reasoning,
repository editing, code execution, and test inspection.

## 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 #123` 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 references)
- [x] My branch name describes the change 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-07 19:11:50 -05:00
DottaandPaperclip fd8c6b920a fix(native): resume connection tasks after approval decisions (#15471)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Native tasks can pause while a human decides whether to allow a
connection action.
> - The next turn needs both the saved decision and complete accounting
for the previous turn.
> - Cancellation could discard final usage, and complete direct Claude
API receipts could remain unpriced.
> - A stale blocked or review report could also request approval again
after the original card was declined.
> - This pull request retains shutdown accounting and rejects approval
waits bound to an already resolved action.
> - The benefit is reliable continuation with the existing budget and
approval controls.

## Linked Issues or Issue Description

Refs #15420. Related: #15312 addresses requester ownership during
dispatch. This change addresses receipt capture and final-response
validation.

## What Changed

- Retain usage events after native cancellation. Continue to reject late
provider messages and work.
- Drain same-turn accounting and terminal events for at most fifteen
seconds after a durable governed wait. Keep incomplete accounting
blocked.
- Estimate complete, unpriced, direct Anthropic API receipts for the
exact `claude-sonnet-5` model. Record the rate version and assumptions.
Use the one-hour cache-write rate when the receipt lacks cache TTL.
- Bind stale approval reports to exact interaction, action-request, or
invocation IDs in the same company, task, agent, and run. Cover blocked,
review, and response-wake reports. Keep independent reviews valid.
- Fence checkpoint and result writes after a controller detaches for
restart, including operations waiting for a database lock. Reject stale
successful returns before certifying accounting.
- Allow bounded subscription teardown only after retaining an actual
provider terminal.
- Journal the exact governed-wait trigger and disposition before
provider interruption. Recover that wait independently of a later saved
answer, replay retained accounting, and reject mismatched or unproven
terminal evidence.
- Give settling governed turns a bounded window before shutdown detaches
their controller.
- Keep fuzzy external app matches alongside installed capability matches
instead of forcing an unrelated provider question for a generic query.
- Return up to twenty exact active catalog tool names after an invalid
request, after eligibility checks; still reject the request without
granting access or creating an approval.
- Require retained provider terminal proof before settling a governed
wait, including when complete usage arrives before stream
closure/error/timeout. Retain harmless numbered cancellation events so
restart replay stays contiguous.
- Isolate accounting-test OpenCode config from the host plugin
directory.
- Add regression coverage and document the accounting, restart and
connection-search behavior.

## Verification

Current PR source: `0cf08efd75f8fb23f7989beda6dbda92587088bf`. The live
matrix below measured frozen `09a776bcb1f77422156f8be11e13f8c29f43e7f7`;
later review fixes are verified separately and do not relabel those
runs.

- Repository typecheck and build pass.
- Current runner runtime and cancellation suites: 191 tests pass. Six
new regressions cover stream end/error/timeout without provider-stop
proof and contiguous cancellation acknowledgement/request replay; all
six failed before the fix. The existing bounded cleanup case now
explicitly supplies terminal proof. All 31 adapter accounting tests pass
with isolated fixture config.
- New checkpoint-rebinding and approval-criterion suites: 65 tests pass;
runner HTTP integration: 29 tests pass. Unchanged executor/control-plane
suites: 640 tests pass; database-backed connection suites: 68 tests
pass.
- Current retained evidence verification covers 222 file hashes across
all fifteen original result artifacts. The three-case [published
report](https://d1p6rlowie26tp.cloudfront.net/runner-e2e/campaigns/gha-37651896525-1/index.html)
and all eight screenshot hashes verify. The [three-case recovery
report](https://d1p6rlowie26tp.cloudfront.net/runner-e2e/campaigns/gha-37662587356-1/index.html)
and all six screenshots also verify; the nine-result campaign did not
publish.
- Evaluation support: 1,805 Vitest tests pass, one skipped; 128 Node
tests pass. Eval typecheck and catalog discovery pass.
- Full local repository unit run was interrupted before the follow-up
edits after three tool-access failures and one runner HTTP failure.
Those failures pass in isolation; the 09a full run was interrupted after
one rapid Slack callback-ordering failure and seven skill-service
failures. All eight pass both isolated and with full-runner environment
settings, and all 74 skill-service tests pass together; the subsequent
full run reported two 15-second OpenCode accounting timeouts and was
stopped with exit 130 to apply review fixes. The timeouts reproduce
while copying this host’s 61 MB OpenCode config. All 31 tests pass after
isolating config inside each fixture without increasing timeouts or
changing assertions. A complete local full-suite pass is not claimed.
Repository-wide CI also passes on the final review-fix head in [run
37669185952](https://github.com/paperclipai/paperclip/actions/runs/37669185952).
Earlier database-skipped diagnostics and the older ENFILE run are
retained and are not full-suite passing evidence.
- Three-case live campaign
[37651896525](https://github.com/paperclipai/paperclip/actions/runs/37651896525)
passes all three original grades on frozen source 09a: 55/55 checks,
eight succeeded run records, complete accounting receipts, matching
checkpoint identities and no pending approvals. Campaign
[37653533353](https://github.com/paperclipai/paperclip/actions/runs/37653533353)
adds nine original passes (173/173 checks, eighteen succeeded records)
on the identical source. Its other three jobs failed before runner
assignment or any step while GitHub could not load the paid environment;
those original infrastructure failures are retained. Campaign
[37662587356](https://github.com/paperclipai/paperclip/actions/runs/37662587356)
completes only those unstarted cells: all three original grades pass
(57/57 checks, six succeeded run records). All fifteen exact cases now
pass on source 09a: eight FAIL → PASS, seven PASS → PASS, zero new
overall failures and zero pending pairs. Total current evidence: 285/285
checks and thirty-two succeeded run records, complete accounting
receipts, matching checkpoint identities, no pending approvals or retry
records. Earlier campaigns retain forty-seven additional run records and
two known same-run recovery attempts; actual provider-call counts and
invoices remain unknown. The nine-result campaign skipped publication
and its public URL returns 403; original artifacts remain retained.
Previous ba9 campaign
[37645656840](https://github.com/paperclipai/paperclip/actions/runs/37645656840)
completed 2 PASS / 1 FAIL: Claude restart/approval and Codex decline
pass, while OpenCode resumes but times out searching for exact tool
names and never creates the access card. That failure and incomplete
cancelled-run accounting remain preserved; the new catalog error
guidance targets this observed dead end. Campaign
[37642957312](https://github.com/paperclipai/paperclip/actions/runs/37642957312)
remains 0 PASS / 3 FAIL and exposed the now-corrected cross-run marker
leak and unknown-criterion approval gap. The original baseline remains 7
PASS / 8 FAIL, first repair 2 PASS / 3 FAIL, and second repair 0 PASS /
3 FAIL. All fifteen selected cases are qualified by their original
grades in this bounded trial. These live grades belong to 09a. Its
twelve governed-wait checkpoints retain matching same-turn terminal
fingerprints, but passing artifacts omit detailed event journals; the
later six adversarial regressions qualify the new terminal-proof and
replay guards separately. Final-head repository CI passes. [Fresh
Greptile
review](https://github.com/paperclipai/paperclip/pull/15471#issuecomment-6044369780)
is 5/5, confirms both findings are fixed, and reports no new actionable
issues. All review threads are resolved and the PR has no merge
conflicts.

## Risks

- Governed cancellation drains accounting for up to fifteen seconds.
Restart detachment gives a settling batch up to twenty seconds to
finish. An incomplete receipt or unproven provider terminal still
prevents successful qualification.
- Claude prices are estimates, not invoices. The estimate assumes
standard global API pricing and uses a conservative cache-write rate.
Unsupported models, billers, and billing modes remain unpriced.
- Approval identity matching must remain scoped to the current run and
the requested approval. It does not authorize execution of a declined
call.
- Original baseline and final candidate have different merged master
context. Exact-case outcomes are before/after observations, not isolated
causal attribution to this repair.
- No schema migration, fixture, oracle or grader change. Search-result
guidance now treats fuzzy external matches as suggestions. Existing app
authorization and provider-consent checks remain required.

## Model Used

- OpenAI GPT-6 through Codex, with code editing, terminal tools, and
test execution. The exact deployment identifier and context window 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
#` 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 (191 current runtime tests
and 31 accounting tests; interrupted full-suite history and CI coverage
are disclosed 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-07 14:43:07 -05:00
9fb955e9a2 fix(codex): gate models on the Codex CLI floor before the ChatGPT backend rejects them (#15399)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work
> - The Codex adapter and the native runner run Codex in local hosts and
in managed sandboxes, and the model catalog lists the models an operator
can select
> - The Codex backend accepts a new model with ChatGPT sign-in only from
a recent enough Codex CLI. An older CLI fails every turn with `The
'<model>' model is not supported when using Codex with a ChatGPT
account.`
> - After #14942 added `gpt-6.1-sol`, an operator selected it for an
agent in a managed Daytona sandbox. The sandbox image still shipped
Codex 0.156.0. The connection test and runs failed with that sentence,
which reads like an account problem
> - Paperclip only checked the Codex compatibility window (`>=0.149.0
<0.161.0`), so 0.156.0 passed and the failure surfaced from the backend
without a cause
> - This pull request records the verified Codex CLI floor for each
gated model, compares the installed `codex --version` with that floor in
the environment Test and in the remote runner, and names the backend
rejection when it still happens
> - The benefit is a precise, actionable message ("gpt-6.1-sol requires
Codex CLI 0.159.0 or newer; detected 0.156.0; promote a sandbox image
with Codex 0.160.0") instead of an opaque 400, and no doomed hello probe

## Linked Issues or Issue Description

Refs #14942

**Bug: selecting `gpt-6.1-sol` in a managed sandbox fails with a ChatGPT
account error.**

**Steps to reproduce**
1. Promote a sandbox image that ships Codex CLI 0.156.0.
2. Create a Codex agent with a ChatGPT sign-in connection, select
`gpt-6.1-sol`, and run the environment Test or a task in that sandbox.

**Expected behavior**
The Test or the run tells the operator that the Codex CLI in the sandbox
is older than the model needs.

**Actual behavior**
The Test reports `codex_hello_probe_failed` with
`{"type":"error","status":400,"error":{"type":"invalid_request_error","message":"The
'gpt-6.1-sol' model is not supported when using Codex with a ChatGPT
account."}}`. A run fails with "The selected model is not supported by
the current ChatGPT connection."

**Evidence**
- Codex 0.156.1 and older are rejected for `gpt-6.1-sol` with ChatGPT
sign-in: https://github.com/openai/codex/issues/49396
- Codex 0.159.0 and 0.159.2 are accepted:
https://github.com/openai/codex/issues/49464 and
https://github.com/decolua/9router/issues/4471 (same error, fixed by
raising the client version identity from 0.155.0 to 0.159.0)
- Codex 0.157.0 release notes: "Add GPT-6 Sol and Luna to the model
catalog": https://github.com/openai/codex/releases/tag/rust-v0.157.0
- GPT-6.1 Sol is included for Plus, Pro, Business, Enterprise, and Edu
with ChatGPT sign-in: https://learn.chatgpt.com/docs/models

## What Changed

- `packages/adapters/codex-local/src/index.ts`: add
`minimumCodexCliVersionForModel` (`gpt-6.1-sol` → 0.159.0, `gpt-6-sol`
and `gpt-6-luna` → 0.157.0, with the sources above),
`parseCodexCliVersionOutput`, `codexCliVersionAtLeast`, and
`CODEX_CHATGPT_MODEL_REJECTION_RE`. Models without a verified floor
return `null`, so nothing probes them. The agent configuration doc
describes the floors.
- `packages/adapters/codex-local/src/server/cli-version.ts` (new): run
`codex --version` where the run would execute it (local, SSH, or
sandbox), compare it with the model floor, and build the
`codex_cli_version_compatible` / `codex_cli_version_incompatible`
checks. Map the backend rejection sentence to
`codex_hello_probe_model_rejected` with the detected CLI version and a
hint that separates a stale CLI from a plan that does not include the
model.
- `packages/adapters/codex-local/src/server/test.ts` (CLI lane Test):
run the version check before the hello probe when the model has a floor.
Skip the hello probe when the CLI is too old
(`codex_hello_probe_skipped_cli_version`). When the probe still fails
with the backend sentence, report `codex_hello_probe_model_rejected`
instead of the generic `codex_hello_probe_failed`. The new codes do not
match the auth-failure patterns, so a managed connection is not
invalidated.
- `packages/adapters/codex-local/src/server/acp.ts` (ACP lane Test): for
remote targets, run the same version check against the shared `codex`
the ACP server spawns.
- `server/src/services/native-runtime/native-session-executor.ts`: after
the compatibility-window check, compare the remote Codex with the
configured model's floor and fail with
`runner_remote_provider_artifact_incompatible: <model> requires Codex
<floor> or newer with ChatGPT sign-in, received <version> from the
sandbox image; promote a sandbox image with Codex 0.160.0 or configure
PAPERCLIP_RUNNER_REMOTE_CODEX_NPM_SPEC=...`. When a preinstalled Codex
fails this check and an npm spec is configured, the existing fallback
installs the pinned release.
- Tests: adapter metadata, CLI-lane Test (too old, compatible, no floor,
backend rejection), ACP-lane Test (too old, compatible, no floor), and
the remote runner floor (nine version/model cases).
- `doc/adapter-model-audit-2026-10-02.md`: record the floors and the
reason.

No catalog entry, default model, saved agent configuration, pin,
lockfile, or image definition changes.

## Verification

Local (Node 25.9, pnpm 9.15.4 via corepack):

```sh
pnpm --filter @paperclipai/adapter-codex-local typecheck
pnpm --filter @paperclipai/adapter-codex-local exec vitest run            # 81 passed
pnpm --filter @paperclipai/server exec vitest run \
  src/services/native-runtime/native-session-executor.test.ts \
  src/services/native-runtime/codex-runtime-compatibility.test.ts -t Codex   # 84 passed
```

Also run locally: the full `native-session-executor.test.ts` file (533
passed) and the full Codex adapter suite (81 passed).

Follow-up commit `9fd4d3b25` (Greptile P2: the ACP-lane version probe
ignored the agent's configured env): the probe now receives the
adapter's string-valued `env` entries, the same ones
`buildCodexAcpConfig` hands to remote ACP runs, so a `PATH` override
selects the same `codex` for the Test as for the run. New test covers a
`PATH` + `CODEX_HOME` override and a dropped non-string entry. Re-run on
that head: `pnpm --filter @paperclipai/adapter-codex-local typecheck`
clean; full Codex adapter suite 503 passed (31 files).

Not run here: `pnpm -r typecheck` for `server` (the direct `tsc
--noEmit` was killed by the sandbox memory cap; the adapter package
typecheck passes and CI covers the server), `pnpm build`, browser
suites, and a live sandbox probe. No UI files changed, so token gates do
not apply.

Manual check for a reviewer: set an agent's Codex model to
`gpt-6.1-sol`, point its environment at a sandbox whose `codex
--version` prints `codex-cli 0.156.0`, and run the environment Test. The
result contains `codex_cli_version_incompatible` with `Detected Codex
CLI 0.156.0.` and no hello probe check. With Codex 0.160.0 the Test
contains `codex_cli_version_compatible` and runs the hello probe.

## Risks

- A floor is enforced for all authentication modes, because the runner
does not know the credential method at verification time. An OpenAI API
key on Codex 0.157.0 or 0.158.0 with `gpt-6.1-sol` is now rejected
before launch. Paperclip pins Codex 0.160.0 everywhere, so this only
affects installs that lag the pin, and the message names the fix.
- The 0.159.0 floor for `gpt-6.1-sol` is the oldest stable release
verified to work; 0.157.0 and 0.158.0 were not verified either way. If
OpenAI accepts an older client, the floor can be lowered in one table.
- The `codex --version` probe adds one short process run to the Test
only for models with a floor.
- Rollback: revert this pull request. No data or configuration migrates.

## Model Used

Claude Fable 5.1 (`claude-fable-5-1`), Anthropic, with extended
thinking, tool use, and web research, operating as a Paperclip agent
through Claude Code.

## 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
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Bender (Fable) <noreply@paperclip.ing>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-07 10:37:55 -07:00
DottaandPaperclip f669194298 fix(runner): propagate configured environment to future turns (#15451)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Native runners start provider processes and enforce a separate tool
environment policy.
> - The server resolves task environment bindings at each run boundary.
> - Fixed launch allowlists dropped custom variables after resolution.
> - Warm process reuse and a blanket fingerprint exclusion also hid
configuration changes.
> - This pull request carries a bounded, server-selected list of task
variable names through each process boundary.
> - The benefit is that later turns and tool commands receive configured
values while ambient host secrets stay excluded.

## Linked Issues or Issue Description

**What happened?**

A native Codex agent could not use configured task credentials. Adding
the variables in Settings did not fix the next turn. The provider
sanitizer, runner launch, Rust provider launch, and shell policy each
used fixed allowlists. Effective config fingerprints also excluded all
variables with the `PAPERCLIP_` prefix.

**Expected behavior**

Explicitly bound task variables must reach provider processes and tool
commands. Added, changed, and removed values must take effect at the
next run boundary. A running turn keeps its original configuration.

**Steps to reproduce**

1. Start a native Codex task without a custom environment binding.
2. Add a fake `PAPERCLIP_PAGE_BUCKET` value and a fake Pages credential
binding in Settings.
3. Continue the task and inspect the tool environment.
4. Before this fix, those values are absent even from a fresh runner
launch.

**Paperclip version or commit**

Reproduced at `b31558064`. The fix is rebased on current master.

**Deployment mode**

Self-hosted server with a native process runner.

Related changes: [the legacy Codex MCP environment
fix](https://github.com/paperclipai/paperclip/pull/13321) and [ambient
server-secret
exclusion](https://github.com/paperclipai/paperclip/pull/12870). These
affect different launch paths. This change preserves their credential
boundaries.

## What Changed

- Capture scoped task bindings after resolution, before managed provider
credential injection. Mint and validate the names-only projection at
native dispatch before host inheritance. Legacy adapters retain their
previous environment limits.
- Strip user-supplied projection markers from agent, environment,
project, and routine config.
- Carry selected values through the Codex, ACPX, OpenCode, runnerd, and
Rust subprocess launch boundaries.
- Add selected names to native and ACPX Codex shell include lists. Keep
selected values out of command arguments, including selected bootstrap
values.
- Reject malformed projections, reserved authority and loader names,
missing values, null bytes, and oversized input.
- Replace a retained native process when projected values change. Keep
unchanged processes reusable.
- Fingerprint custom namespaced variables while excluding known
generated runtime variables.
- Document next-run behavior and add regression coverage.

## Verification

- Red: the permanent reproduction failed at four launch/tool boundaries
and the namespaced fingerprint check. Two control checks passed.
- Green: the initial regression plus existing Codex environment and
shell tests passed (39 tests).
- Server config resolution, fingerprints, and native-session suites
passed (653 tests), including addition, rotation, removal, and unchanged
warm-session reuse.
- Rust regression tests passed. A real shell child received added and
rotated values, then lost them after removal. Unselected host variables
stayed absent.
- `pnpm -r typecheck` and `pnpm build` passed after rebase. The full
`pnpm test:run` was attempted but could not complete: fresh embedded
PostgreSQL databases fail during bootstrap on this macOS host. An
isolated suite and a disposable native `initdb` probe reproduced the
failure before test execution. `shmget` reports `No space left on
device` because the host has exhausted shared-memory IDs. This is not
disk exhaustion. The run was stopped after confirming the external setup
failure. CI results will be recorded separately.
- Runner boundary suites: 361 tests passed. Two process-launch errors
during concurrent binary staging passed on isolated rerun.
- Rust Codex provider and process supervisor integration suites: 97
passed, 2 intentionally ignored.
- ACPX shell and selected-bootstrap argv regressions: 3 failed before
the fix, then all 55 relevant tests passed.
- Review compatibility regression: 129-variable and large-value legacy
configurations failed before the correction and passed after moving
native-only validation to dispatch.
- Final review head `3f11e8d25`: repository typechecks and production
build passed. CI completed its implementation checks; one general-server
shard hit SQL `40P01` in `heartbeat-runtime-skills.test.ts` during its
`beforeEach` table truncate (1,199 tests passed in that shard). The
shard passed on its single rerun. All CI checks for this head are green.
Greptile reviewed this head at 5/5 with no new actionable findings; the
compatibility thread is resolved.
- No live provider credentials or model calls are required by these
tests.

## Risks

- Configured task credentials now reach the tools they were configured
for. The controller selects names only after existing scope and
secret-binding authorization.
- TypeScript and Rust validate the same bounded projection. Their
reserved-name rules must stay aligned.
- A changed projection replaces an idle provider process. Unchanged
values preserve reuse. Active turns retain their original environment.
- No database migration or API schema change.

> This fixes existing runner configuration behavior. It does not add a
new roadmap capability.

## Model Used

- OpenAI GPT-6 (Codex), with reasoning, local code execution, and
repository tools. The session does not expose a more specific API model
identifier or 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-07 10:16:49 -05:00
DottaandPaperclip 8cfedd7df8 fix(runner): restore task monitors and durable timed waits (#15446)
## Thinking Path

> - Paperclip manages AI agents and their task execution.
> - Agents need a durable way to return to work after a delayed check.
> - The issue monitor scheduler already provides a one-shot wake for an
assignee.
> - Native runners reject generic execution-policy writes and had no
bound monitor tool.
> - Scheduling alone is insufficient because native completion also
needs to accept a timed wait.
> - This pull request adds an authorized monitor tool and connects it to
completion and the existing scheduler.
> - An agent can now schedule its next check, end the run, and resume on
the same task.

## Linked Issues or Issue Description

**What happened?**

A native runner could not set its own task monitor. `call_api` correctly
rejected execution-policy writes, while `schedule_wake` had no
production binding. `paperclip_finish` also rejected monitor waits.

**Expected behavior**

A standard native run can set a one-shot monitor on its current task or
another accessible task assigned to the same agent. After a confirmed
schedule on the current task, it can yield. The scheduler later delivers
`issue_monitor_due`.

**Steps to reproduce**

1. Start a standard native task.
2. Ask the agent to check the task again later and end its current run.
3. Inspect available tools and try the generic issue execution-policy
update.
4. Observe the missing native tool and the lifecycle-write denial.

Related PRs: #14680 concerns monitor notes in the shared wake prompt.
#11919 changes attempt-limit scope. This PR adds native scheduling and
completion authority and retains the existing cumulative attempt bounds.
It does not depend on either PR.

## What Changed

- Add provider-neutral `set_task_monitor` with a default current-task
target, future timestamp, required notes, existing bounds, and explicit
clearing.
- Check company, task visibility, ownership, runtime permissions, work
mode, and active-run authority. Preserve review-only restrictions.
Reject the reserved server-owned quota-recovery name before saving or
accepting a native wait.
- Commit the monitor, audit event, and retry receipt together. Retry
receipts survive a successor run without re-arming cleared or consumed
timers.
- Permit `paperclip_finish` to yield to a persisted monitor. Recheck
ownership and the schedule when committing final disposition. Release
execution without an immediate continuation.
- Preserve due monitors during native execution. Fence wake admission
and consumption against replacement, clearing, reassignment, and
completion. Preserve unrelated review policy.
- Expose scheduled and consumed monitor instructions in task context.
Update provider schemas, Rust validation, generated contracts, and
execution documentation.
- Add an opt-in live Codex smoke script with isolated data and explicit
run/session/runner/process evidence.

## Verification

- Repository `pnpm -r typecheck` and `pnpm build` passed after rebase.
Server typecheck passed again after review fixes. All CI test shards
pass on `3def77b1b`, including runner TypeScript/Rust, server,
serialized server, workspace, and browser tests. All CI gates are green,
including the canary dry run. Greptile is 5/5 on the same commit with
zero unresolved threads.
- The local monolithic `pnpm test:run`, started before the rebase, was
interrupted after current-head CI test coverage passed. It is not
counted as a standalone full-suite pass; the focused local regression
suites passed.
- Targeted server tests cover scheduling, replacement, clearing, policy
preservation, cumulative bounds, cross-run retries, permissions,
provider-neutral discovery, review restrictions, completion authority,
and scheduler/finalizer races.
- Runner contract/catalog/semantic tests and Rust terminal-tool tests
cover the new operation and monitor completion.
- Live Codex test passed twice (latest live run on `e0bcd63e6`) in a
temporary database and workspace, with a 300,000 ms warm window. First
run `67bd7709-c089-4d4a-9d2b-0d6b618a34b0` yielded at
`2026-10-07T13:15:03.274Z`. Second run
`97c323f9-595a-4cc5-a007-db5a2fbb937c` started at `13:15:30.952Z`,
received `issue_monitor_due`, and completed the same task. Exactly one
monitor wake was recorded.
- Both live runs used native session
`7b1dd753-1c9b-4e7a-b22f-a125dbc3748c`, runner
`e90d9a1b-3502-4ee3-b15e-edc024c555d4`, provider session
`01a11680-6d01-70c0-9a55-db7246ed66c3`, and PID `64218` with the same
process start time. This proves warm reuse for that local Codex test,
not only successful scheduling.
- Reproduce the paid live test with `node --import
./server/node_modules/tsx/dist/loader.mjs
server/scripts/smoke-native-task-monitor.ts --run`, with the installed
Codex binary on `PATH` and a valid local login.

## Risks

- The scheduler now defers monitor dispatch while the task has an active
native run. A stuck run still depends on the existing recovery
lifecycle.
- Idempotency uses the existing run ledger; no table or migration is
added.
- Other providers share the tested tool and completion contracts. Only
Codex received a live model test.
- Existing `call_api` lifecycle restrictions remain enforced. Monitor
waits do not bypass task blockers, reviews, or approvals.

## Model Used

OpenAI Codex, GPT-6 family, with tool use, code execution, and
TypeScript/Rust editing. The session does not expose the exact deployed
model ID or 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-07 08:41:24 -05:00
DottaandPaperclip 3a726e676f feat: enforce private task permissions across execution and data (#10633)
Enforce private task and project access across direct reads, search, execution, files, plugins, live delivery, and sharing mutations. Preserve downward-only sharing, current responsible-user authorization, and audited emergency access. Bind historical draft assets with migration 0314.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-07 07:06:40 -05:00
DottaandPaperclip b67db12d90 feat: add durable storage for private tasks (#14717)
Add private task and project ownership, downward access grants, and immutable run/workspace provenance. Apply migration 0313 with bounded batch commits and concurrent indexes. Keep the enforcement and sharing changes in their dependent PRs.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-07 06:53:20 -05:00
DottaandPaperclip d0db8820db fix(connections): repair native baseline and approval continuations (#15420)
## Thinking Path

> - Paperclip manages AI agents and the tools they may use.
> - Connection setup separates provider preference from permission to
use a tool.
> - The first native connection baseline could not exercise its intended
decisions.
> - The browser used mutable task titles, and the provider fixture
already granted access.
> - Native provider-choice instructions also disagreed with the
preferred question format. Schema rejection gave no field guidance.
> - This pull request repairs those test preconditions and native
guidance, then fixes restart/approval defects exposed by the corrected
baseline. It also restores missing OpenCode tool-error evidence.
> - The benefit is an inspectable baseline before any further
instruction reduction.

## Linked Issues or Issue Description

Refs #15407.

The original 15-cell baseline remains 0 PASS / 15 FAIL. Ten cells
stopped on stale titles, two Codex cells had schema denials, two
OpenCode cells used already-granted tools, and one Claude cell returned
no native result. No intended user decisions were submitted. The exact
invalid Codex field and underlying Claude failure cause remain unknown.

[Original
campaign](https://github.com/paperclipai/paperclip/actions/runs/37562577199)
· [Original
report](https://d1p6rlowie26tp.cloudfront.net/runner-e2e/campaigns/gha-37562577199-1/index.html)

## What Changed

- Match the browser's task route and visible identifier instead of a
title the agent can change.
- Start native provider-choice fixtures with no agent tool access.
Verify the public effective-access records.
- In the positive case, select Arcade, then grant its exact HubSpot tool
through the real access card. Require both saved decisions and exactly
one observed call.
- Return a canonical `providerQuestionSet` for native input and retain
the equivalent legacy `providerQuestion`.
- Keep invalid input rejected. Return bounded schema locations and
required field names without submitted values.
- Preserve Claude's exact session/content identity while allowing
authenticated registered instruction-copy paths to rotate on a new run.
- Reject duplicate approval reports for an existing exact tool-action
card before they create another human review.
- Wait for a recorded service-approval continuation within the existing
deadline; retain missing or failed continuation grades.
- Forward OpenCode tool activity through the runner facade, preserving
bounded errors and execution-part identity without inventing host-call
joins or exposing arguments.
- Preserve original grades, costs, scope limits and diagnoses in the
dated repair report.

## Verification

- Eval typecheck passes. Support suite: 1,801 PASS, one intentional
skip; Node checks: 128 PASS.
- Connection/schema tests: 51 PASS. Real-server public fixture setup:
one PASS with zero providers.
- Browser support regression: five PASS, including renamed and wrong
tasks.
- Focused Rust safe-feedback test: one PASS.
- Repository typecheck and build pass before the latest master replay.
Post-replay connection/shared/real-server fixture checks: 52 PASS; eval
typecheck passes. The browser review fix additionally passes all five
browser checks and seven suite checks.
- The full local repository run was interrupted incomplete after about
45 minutes, with five integration failures retained. All five pass in a
separate targeted invocation (1,250 unrelated tests skipped). No full
local-suite pass or root cause for the initial local failures is
claimed.
- Corrected frozen source `162cc90fdabe7f505b88ae095044531b82784c92`:
**10 PASS / 5 FAIL** across the [passing Codex
canary](https://github.com/paperclipai/paperclip/actions/runs/37575158761)
and [remaining 14
cells](https://github.com/paperclipai/paperclip/actions/runs/37576261807).
The canary passes all 17 checks. Claude's two provider-choice
continuations fail on restart, Claude service approval exposes an early
evaluator rejection, Codex service approval creates a duplicate
approval, and OpenCode provider-second times out after both decisions
with no HubSpot call. No original result is regraded.
- Final ledgers count 31 actual runs: 27 succeeded, two failed, two
cancelled during cleanup. All 15 cleanup/budget checks pass. The late
Claude continuation is absent from its earlier workflow snapshot; it
remains in the result/API/final ledger. Original evidence retains 279
hashes. Recorded LLM subtotal $0.04553787 is incomplete billing, not
actual total cost; local runtime is unmetered.
- New repair regressions reproduce the Claude attach failure, duplicate
approval acceptance and dropped OpenCode tool events before their
respective fixes. Nine Rust attachment checks, 127 ACPX host/adapter
tests, 33 completion/control-plane checks, nine eval deadline tests, 59
OpenCode proxy/driver tests, one Rust tool-error/redaction check, and
TypeScript/Rust composer parity pass. Eval typecheck, repository
typecheck and build pass. Existing support coverage is 1,802 PASS plus
128 Node PASS, one intentional support skip; two additional deadline
tests also pass.
- New-source full CI/review and live canaries are pending. The next
bounded selection is Claude provider-decline, Codex service-approve and
one OpenCode provider-second diagnostic with repaired event evidence. No
broader campaign or instruction-reduction qualification is claimed.
- Initial corrected campaign
[37574251834](https://github.com/paperclipai/paperclip/actions/runs/37574251834)
was cancelled during shared build after review found the breadcrumb
whitespace assumption. Its matrix job has zero steps and no provider
execution. The real adjacent-span browser regression now reproduces the
old failure and passes after the fix.

## Risks

- The corrected baseline remains 10/15. The new restart/approval fixes
require live qualification; OpenCode evidence forwarding does not itself
establish or fix its prior behavioral failure.
- The positive provider case now expects three runs, including separate
access approval. Its new results are distinct from the original invalid
fixture.
- The old Claude missing-result cause and rejected Codex field are
unknown. These repairs do not retroactively explain or erase either
failure.
- Path rotation must preserve prompt, custom instruction, skill/content
identity and protected provider settings; regression checks reject stale
or changed content. No connection authorization, JSON schema, budget,
cleanup, or final-result requirement is relaxed. Historical Everyday
prompts and gateway setup remain unchanged.

## Model Used

OpenAI Codex, GPT-6. The exact deployment variant and context window are
not exposed in this session. Used repository inspection, code editing,
test execution and retained-evidence analysis.

## 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
- [ ] 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
- [ ] All Paperclip CI gates are green
- [ ] 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-07 06:18:51 -05:00
Devin FoleyandPaperclip 799e4d556f fix: make accounting durable and synchronize cost reporting (#14997)
Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-06 22:26:48 -07:00
DottaandPaperclip a6306ba606 feat(runner): consolidate Cursor production integration (#15075)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The native Runner keeps provider sessions under company authority,
approvals, budgets and durable recovery.
> - Cursor work was spread across candidate branches. The published
branch lacked later plan, permission and cleanup fixes.
> - Production also needs public installation and matching runtime
assets for local and Daytona execution.
> - This pull request consolidates Cursor onto current mainline recovery
behavior and completes that installation path.
> - The installed v11 release passed focused local and Daytona
qualification after the generic mode and lifecycle cleanup. The later
model-selection correction and current mainline merge produce v14
artifacts that need matching release qualification.
> - Cursor admission is enabled in source; publish only an artifact
combination with matching qualification. Native AskQuestion and complete
per-run dollar accounting remain excluded.

## Linked Issues or Issue Description

Refs: #14435, #14631, #14669, #14699, #14724.

This completes the Cursor implementation by @cryppadotta from combined
source `22c78242a4e0c2369fecf0c2dc4e7600fbad6706`. It preserves newer
mainline recovery, completion and warm-directory behavior. Pi and
Copilot remain gated.

## What Changed

- Generate named Rust and TypeScript ACPX release profiles from one
manifest. Share runtime pins with packaging and server verification.
Preserve vendor runtime versions; bind the updated ACPX patch to Cursor
profile v14 and reject stale generated declarations at build/typecheck.
- Remove ACPX model allowlists, including the former Codex and Pi
restrictions and the duplicate developer test-drive gate. Send any
explicit model ID unchanged to its provider and verify the effective
selection before prompting. The bundled ACPX package forwards unlisted
IDs, rejects mismatched acknowledgements, and restores the exact
selection after session load. It does not expand Cursor model aliases.
Provider rejection, mismatch, or missing model controls fails without a
fallback. Model examples live in evaluation fixtures, outside runtime
declarations.

- Add pinned Cursor execution, contained instructions, exact model
verification and Agent/Plan/Ask modes.
- Carry an opaque generic `mode` identifier in shared native execution,
sidecar, Rust and recovery contracts. The provider adapter owns
supported modes, defaults, native translation and acknowledgement.
- Keep native RPC recognition, accepted-plan interpretation and
permission evidence behind provider adapters. Shared settlement and
recovery verify normalized facts and their committed evidence.
- Replace the Cursor-only warm-attachment branch with a runner-owned
capability. Only Cursor opts into it. Move profile compatibility and
optional usage parsing into provider metadata and adapters.
- Write generic plan-wait receipts. Read exact historical Cursor
receipts through a separate compatibility decoder. Reject mixed formats
and preserve existing authority checks.
- Carry native plans, semantic questions, todos, child activity,
permission identities and partial usage diagnostics through the Runner.
- Preserve durable response delivery, cancellation, warm ownership and
process retirement.
- Finish accepted planning runs successfully. Keep their tasks open for
explicit direction. Acceptance does not start implementation.
- Ship `paperclipai runtime setup cursor` and its provisioner through
the public package. npm installation does not download Cursor. Setup
uses the OS account's closure-keyed cache so system-wide npm packages
can remain read-only. Run it as the Paperclip service account.
- Include Cursor in normal provider packs and Daytona images for macOS
ARM64/x64 and Linux x64.
- Reject stale release packs by source revision and current ACPX/Cursor
pins before assembly writes files. Verify current Cursor
version/profile/closure again at runtime.
- Ship all three daemon targets and the expected Linux image-pack
identity. A macOS controller uses its packaged Linux daemon for Daytona.
Image mismatches fail before provider launch.
- Use the vendored Runner boundary for installed readiness probes.
Verify the actual installed Cursor probe.
- Verify compiled public Daytona plugins and their release versions in
installed smokes.
- Record exact artifacts, the acceptance matrix, retained failures,
supported capabilities and rollback behavior in the [readiness
report](https://github.com/paperclipai/paperclip/blob/codex/cursor-production-readiness/doc/plans/2026-10-03-cursor-production-readiness.md).

## Verification

- Current head `f7ec5cc1f0e30c62a829c016ff2013a2a9d79037` merges
mainline `faa8e452c73bae5e044dd6379179a00106abb131`. It keeps Cursor
plan and cancellation guards alongside mainline historical-question
filtering. The evaluation catalog includes both Cursor and expanded
adapter accounting cases (683 total). Recursive typecheck, full build,
696 lifecycle/recovery tests, 45 fixture tests and fixture typecheck
passed. Current-head CI passed: 56 successful checks, one neutral and
four skipped. [Complete
CI](https://github.com/paperclipai/paperclip/actions/runs/37557996535).
The fresh Base Greptile review is 5/5 on this exact head, with 304 files
reviewed, zero new comments and zero unresolved threads. The user
authorized overriding the CODEOWNER review gate after checks passed; no
failing checks are overridden. Prior results below retain their own head
identities.
- Corrective head `3d2b168366258036f6b6a6fccb382c49138cc601` fixes the
post-merge Apex finding. Automatic-review and new-evidence
reconciliation preserve pending child results and recheck delivery under
the status lock before completing. Account repair now excludes unrelated
secret consumers and requires the failed agent's identity. Regression
coverage includes the commit race, delivery statuses,
current-run/current-intent exclusions, repeated reconciliation, both
database reconciliation paths, and credential consumer boundaries. All
184 affected tests, server typecheck and server build passed.
Current-head Base Greptile review is 5/5, with 304 files reviewed, zero
new comments and zero unresolved threads. Current-head CI passed: 56
successful checks, one neutral and four skipped. [Complete
CI](https://github.com/paperclipai/paperclip/actions/runs/37535994724).
This Base review is distinct from the earlier Apex review.
- Merge head `5957c257a` reconciles mainline `b508a05c4`. It preserves
both accepted-plan waits and pending-child-completion checks, current
provider selectors, task-creation response identities, and mainline ACPX
missing-file handling. The combined patch is bound to Cursor profile
v14; historical records keep their original identities.
- Merge head `5957c257a` passed recursive typecheck, full build, 43
installed ACPX/package contracts, 107 provider UI and plan/recovery
tests, 593 database-backed lifecycle tests, 49 profile/native contract
tests, 45 Product E2E fixture tests, fixture typecheck, token gates,
three provider-free browser task-creation cases, and Runner
conformance/replay checks. Its complete CI passed (55 successful checks,
one neutral and four skipped), while Apex returned 2/5 with a
child-delivery finding addressed below.
- The local full-suite attempt again failed the unchanged Git streaming
test (360-second timeout) and was stopped. The concurrent local Rust
attempt failed four unchanged Codex process/deadline tests; all four
passed serially without code changes in 7.29 seconds after removing the
competing test load. These failed commands are retained and are not
reported as full-suite passes; the fresh Linux CI runs are tracked
separately.
- The previous head `907bdb2a2778c7ffeb4a662a91460c9d1ddfc9c5` earned
Apex 5/5 with zero comments after fixing all three findings: per-user
install cache, stale release-pack rejection, and public Linux smoke
account/home handling. Its real built installer passed from read-only
public packages on macOS ARM64 and Linux x64. All 137 release-registry
checks and 64 ACPX package contracts passed. That review does not cover
this mainline reconciliation.
- Prior `beadd3654` passed the full CI matrix; its one unchanged chat
test failure and successful single retry remain in the [CI
history](https://github.com/paperclipai/paperclip/actions/runs/37521449327).
Historical results below remain attributed to their original builds.

- Fixture follow-up `dd59d7e82b103a88b7cbd7d2c38b612c0fbbff7a` removes
provider-specific model choices from generic offline ACPX tests. The
fake sidecar preserves the model and session identity selected at open
through suspension. Affected verification passed: 106 Rust tests and 73
TypeScript tests. This commit changes test code only; the
production-code checks below retain their recorded identities. Its CI
and Greptile review later passed; those results belong to that
historical head.
- Model-selection cleanup `9a070808b48960a41fdfd369ae0636b95af82459`:
252 focused Runner tests passed (six platform skips), covering all six
ACPX agents, native model acknowledgement, rejected selections,
installation integrity and recovery identity. The merged branch passed
recursive typecheck, full build, token gates, server admission (19
tests), and the Product E2E catalog (45 tests). The acceptance catalog
passed all four tests. The full Rust suite passed: 643 tests, 2 ignored.
It verifies sidecar acknowledgement of unlisted models and rejection of
model mismatches. The final commits only update Rust tests; production
sources match the verified build at
`65ec3279ac50185e3cda109b5cfd9b4f56105de0`. No new paid provider calls
were made.
- The merge preserves both Cursor and the new mainline public-MCP
fixture cases. Auto-merge remains disabled; the latest follow-up status
is recorded above. The local `pnpm test:run` attempt hit the unchanged
Git streaming test's 300-second timeout and was interrupted before
merging mainline. The broad Runner attempt found obsolete single-model
assertions plus three macOS fixture-path failures caused by a
`/private/tmp` override. The assertions are corrected; affected
TypeScript checks passed with the standard macOS temporary directory,
and the complete Rust suite passed. Neither interrupted command is a
full-suite pass.
- Earlier declaration-cleanup head `6f4a5e9e2` passed recursive
typecheck, build, Rust and focused tests. Its CI later exposed a test
expecting duplicated Grok digest literals. The current source fixes that
assertion to compare launcher bytes with the shared manifest. Historical
successes and failed attempts are retained; no new live provider
qualification is claimed.
- Previous head `e75fde6098b0ddd8cec765bfb6ecaeecb88a26a6` passed
complete CI (56 successful checks, one neutral, four skipped) and
Greptile 5/5. [Historical complete
CI](https://github.com/paperclipai/paperclip/actions/runs/37489112305).
Those results are not claimed for the cleanup head.
- Frozen live application: `d7b696f9b8f79095233e9e3d56d23e6a6018dd48`.
Public package version: `0.0.0-cursor-verify.3d0c9b7761c6`. The
declaration cleanup preserves release pins and does not relabel that
tested artifact as a build of the new source. Mainline through
`e34abee670` was reconciled while preserving accepted-plan waits,
provider-capacity handling, and both Cursor and public-MCP fixtures.
- Clean normal installation, explicit Cursor setup and daemon resolution
passed on macOS ARM64, macOS x64 under Rosetta, and Linux x64. npm
lifecycle hooks ran without silently downloading Cursor.
- Historical v11 live matrix: **18/18 passed with cleanup** (nine local,
nine Daytona) after the generic mode and lifecycle cleanup. The campaign
has 23 attempts; all five failures and their diagnoses remain recorded.
Exact case identities, hashes and limits are in the readiness report.
All provider calls are real, use the explicit Luna model and
company-bound credentials, and run without qualification or
runtime-asset overrides.
- The immutable Daytona image is
`ghcr.io/paperclipai/paperclip-daytona-runner@sha256:d6259b6bba094702c13fc2283bd85550849c1c53145b656fb2746778f9fa1747`.
The public Daytona plugin is installed independently and its version is
checked.
- Recursive typecheck, full build, token gates and Runner
contract/conformance/replay checks passed on the frozen application. Its
complete Linux CI suite passed. The duplicate local full-suite command
was incomplete after timing failures; affected repeats passed, but that
command is not reported as a clean pass.
- Qualification fixtures passed typecheck, 1,675 Vitest tests (one
skip), 128 Node checks, three provider-free browser tests, and 150
focused lifecycle tests after the final diagnostic correction. The
affected legacy Cursor command file also passed all five tests after
removing its shorter 10-second override; it now inherits the suite’s
standard 15-second timeout. Greptile is 5/5 on `e75fde609` with no
unresolved review threads. CI results above are recorded separately from
historical build results.

## Risks

- Cursor v14 includes the updated ACPX dependency patch and release
identity. The v11 live matrix and image below remain historical
evidence. They do not certify new v14 package/image artifacts.

- ACPX accepts models beyond the qualification fixtures. Availability
and entitlement depend on the provider. Successful configuration is not
a claim of live qualification for every model.
- Shared mode is an opaque identifier. Provider adapters own its
meaning. Incompatible historical sessions remain fenced; exact committed
plan waits and task history remain inspectable.
- Native AskQuestion is excluded. Paperclip semantic questions are
supported. Authoritative per-run dollar accounting is unavailable;
partial counters remain diagnostics and unknown cost is not zero.
- Image input, detailed native diffs, deeper child transcripts and
native plan-file export remain follow-ups.
- macOS x64 has clean-install and daemon-startup proof under Rosetta,
not a separate live campaign on Intel hardware.
- Release only the tested package/image combination. Merging this PR
does not publish npm packages or deploy that image. Later builds need
their own release verification. Rollback disables new Cursor admission
while preserving records and recovery inspection.
- A model can fail an exact instruction: one cancelled-plan attempt
returned the wrong summary marker despite correct cancellation. The
unchanged repeat passed; both results remain in the report.

> ROADMAP.md was checked. This completes existing native Runner/Cursor
work; it does not add an independent core feature proposal.

## Model Used

OpenAI Codex, GPT-6. The exact serving variant and context window are
not exposed in this session. The agent used reasoning, repository
inspection, code execution, protocol tests and browser-backed Product
E2E tools. Cursor acceptance uses the explicit
`gpt-5.6-luna[context=272k,reasoning=medium,fast=false]` model. That is
the evaluated provider model.

## 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 — affected suites passed;
full CI and the retained local failed attempts are recorded separately
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 — 56 successful checks, one
neutral and four skipped on `f7ec5cc1f0e30c62a829c016ff2013a2a9d79037`
- [x] Greptile is 5/5 with no open P2s, recommendations, or follow-ups —
fresh Base review passed on `f7ec5cc1f0e30c62a829c016ff2013a2a9d79037`;
zero new comments and no unresolved threads. The earlier Apex finding
remains fixed.
- [x] I will address all Greptile and reviewer comments before
requesting merge

---------

Co-authored-by: Paperclip <noreply@paperclip.ing>
2026-10-06 20:48:15 -05:00
DottaandPaperclip faa8e452c7 fix(tasks): stop repeated reminders for historical questions (#15392)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Task questions remain saved so a person can answer them later.
> - The composer moves an old question into history after a newer human
message.
> - Native completion still treated every pending question as a required
response.
> - This caused agents to demand an old answer after the person moved
work forward.
> - This pull request shares the historical-question rule across context
and task execution.
> - Agents can finish verified work while the original question remains
answerable.

## Linked Issues or Issue Description

Refs #15229, Refs #14613, Refs #13130.

**What happened?**

An agent repeatedly asked a person to answer a question that had moved
into feed history. Completion feedback explicitly told the agent to
request a response. The saved pending row also blocked task completion.

**Expected behavior**

A question before newer human direction remains answerable in the feed.
Its pending state alone must not require another reminder or stop
completed work. A new input blocker, an approval, or a configured review
stage must keep its gate.

**Steps to reproduce**

1. Let a task agent create an ordinary question.
2. Dismiss the question and send a newer task message.
3. Let the agent finish the requested work and submit its completion
report.
4. Observe a demand to answer the old question and a retained completion
gate.

## What Changed

- Add one company-scoped predicate for historical questions. Only later
human comments count. Exclude agent attribution, run attribution, system
notices, and untrusted source data.
- Apply the predicate to completion feedback, native waits,
finalization, commit validation, retry validation, blocked routing, and
successful-run handoff.
- Include question classification and guidance in heartbeat context and
both native task-context tools. Add the guidance to fresh and resumed
task prompts.
- Replace automatic reminders for current ordinary questions with
instructions to assess the real blocker, continue independent work, and
withdraw obsolete questions through the existing API.
- Preserve historical question rows during completion while cancelling
their live native source runs through the existing post-commit and
recovery paths. Let an authorized human answer them after completion
without reopening work or creating a response wake. Preserve
cancellation, current-input, approval, permission, credential,
connection, and review gates. Add no dismissal storage or migration.
- Document the rule in the execution contract and agent skill. Refresh
generated capability source anchors. Add database-backed status,
context, attribution, and governance regression tests.

## Verification

- `pnpm build` passed. The server rebuild also passed after the
lifecycle fix. Generated capability contract and inventory checks passed
after the agent documentation update.
- `pnpm -r typecheck` passed. Final `pnpm --filter @paperclipai/server
exec tsc --noEmit` also passed after the last test additions.
- Lifecycle and interaction regressions passed: 224 tests in 3 suites.
Context and prompt tests also passed. Final historical-question cases
passed (33 tests), native cancellation/recovery cases passed (6 tests),
and the existing interaction/confirmation suites passed (72 tests). The
full local `pnpm test:run` was attempted and stopped after more than two
hours with unrelated fixture/hook timeout failures; it did not pass. All
52 successful GitHub checks are green on the latest commit, including
the complete test matrix; no checks are pending or failing. Greptile is
5/5 and both review threads are resolved.
- Regression cases cover the old-question/new-human-message sequence,
final task status, answering after completion with no wake, live-run
cancellation and crash recovery, current input blockers, both
task-context tools, API context, timestamp precision, attribution
boundaries, and protected gates.

## Risks

- A later human task message makes an earlier ordinary question
historical even if its input is still missing. The agent must identify
the current blocker and ask only for information that still prevents
work.
- Browser dismissal remains a local preference. Dismissal without a
later human message is not recorded by this change.
- No schema change or data migration. Completion retains ordinary
historical questions; cancellation still expires them. A completed task
accepts historical answers only from an authorized human and creates no
response-delivery outbox row. Governed requests retain their gates.

## Model Used

OpenAI Codex, GPT-6, with repository editing, code execution, and
browser diagnostics. The exact deployment 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-06 20:33:13 -05:00
DottaandPaperclip b508a05c43 feat: add internal agent complaints and suggestions (#15367)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agents use legacy skills or native runner tools to work on tasks.
> - Those agents can encounter friction that does not belong in the task
thread.
> - A complaint should preserve the raw reaction. A suggestion should
describe an improvement.
> - This pull request adds attributed local storage and both submission
paths.
> - Agents can submit feedback once and continue their primary work.

## Linked Issues or Issue Description

**Subsystem affected**

Server, database, shared contracts, runtime skills, and native runner
tools.

**Problem or motivation**

Agents have no default internal channel for incidental complaints and
suggestions. Sending this feedback through task comments adds noise and
can alter task workflows.

**Proposed solution**

Store free-form feedback in the current instance database. Derive agent,
run, company, and task attribution from active authority. Provide
default legacy skills and provider-neutral native actions. Keep the
instructions close to Warp's MIT-licensed originals.

**Alternatives considered**

Task comments and external Slack delivery add unwanted side effects.
Mandatory suggestion fields and short editorial limits would discard
useful feedback. This release has no listing API, UI, read tool,
automatic triage, or external forwarding.

**Roadmap alignment**

This is a maintainer-requested addition to the existing runtime skills
and runner tool paths. It does not duplicate a listed roadmap milestone.
Searches for complaint tooling, suggestion-box, and agent commentary
found no overlapping public PR or issue.

## What Changed

- Add the company-scoped `agent_commentary` table, shared validation,
and idempotent migration `0310`.
- Add one transactional service and the agent-only POST route. Validate
active authority before writes or replay. Redact known credentials.
Commit a content-free audit with each new record.
- Add `submit_complaint` and `submit_suggestion` to standard, ask, and
planning modes. Keep review, revocation, and completion restrictions.
Store replay identity on the commentary row.
- Mount `complain` and `suggestion-box` by default for legacy agents.
Bundle a dependency-free Node.js stdin helper in the operational skill
and allow its POST through the sandbox bridge.
- Preserve Warp's complaint voice and suggestion guidance, with
attribution and local transport adaptations. Keep source attribution and
MIT notices in each skill's LICENSE, outside runtime instructions.
- Document custom-runtime HTTP use and database inspection. Add
real-database tests and a repeatable live Codex smoke for local and
Daytona execution.
- Pin the lagging-source migration fixture before the identity-repair
migration so later migrations preserve its regression coverage.

## Verification

- Personally ran real Codex submissions in all four environments on
2026-10-06. Local runs passed at 20:35 UTC. Daytona native passed at
20:31 UTC; Daytona legacy passed at 20:33 UTC. Each stored exactly two
rows with company, agent, run, and task attribution, wrote the
continuation marker, exited zero, created no task comments, and left
task status unchanged. Each recorded two content-free activity entries.
- Daytona used production provider hooks, real remote execution and file
transfer, the legacy queue callback bridge, and native private WebSocket
ingress. The current Linux runner was built from `abf47b595`, staged,
and verified against controller contracts. Both sandboxes were confirmed
deleted. This is a focused feedback transport smoke; it does not claim
full Runner E2E catalog or browser qualification.
- The immutable base image and Linux binary digest are recorded in [the
verification
documentation](https://github.com/paperclipai/paperclip/blob/codex/agent-commentary/doc/agent-commentary.md#verification).
The smoke script can save content-free JSON evidence. No credentials or
feedback bodies are in these reports.

| Environment | Runner | Complaint row | Suggestion row |
| --- | --- | --- | --- |
| local | legacy Codex | `59413a00-1de2-4bb1-bcc6-9c4b54c64aa6` |
`3db2364d-3e15-4f47-846f-875d3902999d` |
| local | native Codex | `5da22b5f-41df-4de5-8ba0-d9345ab01267` |
`2d5abe17-dd41-403c-a5ee-4729f2d58921` |
| daytona | legacy Codex | `27c9d0aa-8477-409f-9da0-e8ffa48dee50` |
`209681c9-d1e9-4ce1-999e-48fa07692389` |
| daytona | native Codex | `6eb001bb-4bcf-43f7-8717-f662f53dc7c3` |
`77c383d8-a997-49e5-a33e-25c70e15c0b2` |

- Run the local check with `node cli/node_modules/tsx/dist/cli.mjs
server/scripts/verify-agent-commentary-live.ts`. The documentation gives
the Daytona invocation. Both use disposable instance databases and
normal Codex provider usage.
- Repository `pnpm -r typecheck` and `pnpm build` passed after the test
extension. The build includes runner generation, contracts, and replay
checks. The smoke scripts also passed a separate TypeScript check. The
lagging-source migration regression passed. All equivalent current-head
Vitest CI shards passed. The local monolithic `pnpm test:run` invocation
was stopped after CI supplied that coverage; it did not complete
locally.
- Focused tests cover company isolation, spoofing, revoked credentials,
stale ownership, post-finish rejection, concurrent replay, conflicting
keys, atomic rollback, and deletion through existing services. Boundary
tests cover empty text, Unicode, text beyond 8,000 characters, and the
524,288-character ceiling without truncation. Mounting tests cover
Codex, Claude, and sandbox staging. Helper tests cover standalone Node
execution, stdin, invalid UTF-8, redirects, HTTP failure, and its
deadline. Privacy and bridge tests cover successful and rejected
requests.
- Instructions were compared with Warp's originals. MIT notices and
source credits live only in LICENSE files. Native tools preserve
truthful disclosure when asked, without routine announcements.
- [Full
CI](https://github.com/paperclipai/paperclip/actions/runs/37508559190)
and Greptile 5/5 passed on the earlier feature commit `5209c3501`. The
later head found the migration-fixture assumption fixed in this update.
On `8a4965164`, all 55 check contexts passed after one browser shard
rerun. Its initial reviewer signoff failure also passed an isolated
local browser run (1 test). Greptile scored that head 5/5 and identified
one smoke cleanup gap. `6ecbafb0b` fixes failed-acquisition cleanup with
four passing tests and a passing smoke-script typecheck. Fresh CI is
pending for this final test-only fix. No commentary production code
changed during verification.

## Risks

- Feedback is internally attributed. It is not anonymous. Existing
redaction removes known credentials, but agents must still omit
sensitive content. Normal provider transcripts can include their
submitted arguments.
- Default skill availability changes for existing legacy agents. Runtime
policy filtering still applies. The helper uses the existing Node.js
runtime with no extra dependencies; custom runtimes can call the HTTP
endpoint.
- Feedback is removed with its run, agent, or company. Task deletion
clears only the issue pointer. Normal database backups include the
table.
- The migration is additive and has no backfill. Writes serialize on the
active run for replay consistency. No server suggestion quota is
imposed.

## Model Used

OpenAI `gpt-6-astra` through Codex, with `xhigh` reasoning effort and a
reported 258,400-token context window. Capabilities used: repository
inspection, code execution, and live runtime verification. No subagents
were used.

## 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
- [ ] All Paperclip CI gates are green
- [ ] 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-06 16:14:06 -05:00
DottaandPaperclip fe9d865250 fix(native): wake parents after revised child completions (#15372)
## Thinking Path

> - Paperclip manages agents and the tasks they perform.
> - A parent needs a new notification when a child finishes requested
revisions.
> - Native completion currently identifies that wake by the parent and
child only.
> - An already consumed notification can suppress the child's next
completion.
> - This PR binds ordinary child notifications to the committed status
decision.
> - A replay keeps the same identity, while a new completion can wake
the parent.
> - Live evaluation then exposed new child results being swallowed by an
active parent.
> - The repair preserves that input for a fresh turn and prevents
premature Done from discarding it.

## Linked Issues or Issue Description

Refs: #15218. The procedure experiments remain unshipped. This fixes
native completion wake identity and durable delivery to a busy parent.

Related open work: #10559 and #4507 address legacy wake deduplication,
#11179 addresses delivery during an active parent run, and #13044
addresses watchdog signals. This PR changes native committed-decision
keys and their delivery to an active parent, while preserving exact
watchdog behavior.

**What happened?**

A native child completed, its parent consumed the notification, and
feedback reopened the child. The second completion found the old
completed wake and created no new notification.

**Expected behavior**

Each new ordinary child completion can notify the parent. Replaying the
same committed completion must not add a notification. If the parent is
already running, the new result must remain available for a fresh turn;
an unread result must survive a parent Done claim.

**Steps to reproduce**

Complete a native child, consume its parent wake, reopen and complete
that same child, then inspect the parent wakes. The regression fails on
unchanged master because only one wake exists after two completions.

**Paperclip version or commit**

Baseline: `0fe47882cfcb12082035113c59ca96091c46ebfc`.

**Deployment mode**

Native runner with the standard server and PostgreSQL control plane.

## What Changed

- Include the durable status-decision ID in ordinary child completion
wake keys.
- Defer new ordinary native child completions behind an active parent,
carrying the committed decision identity and revised summary.
- Keep a parent in progress while that result is still queued, claimed
or deferred; recheck before the status commit. Use the existing
continuation without reviving cancelled tasks.
- Lock the parent before ordinary child status writes, making the
notification/Done ordering explicit without upgrading an implicit
foreign-key lock.
- Cover exact sequential delivery, dispatcher replay, and
queued/claimed/deferred versus consumed/current-run completion
identities in database tests.
- Apply it when the child is also a dependency and when it is only a
child.
- Preserve the stable key for exact `task_watchdog` origins to avoid
repeated watchdog loops.
- Extend real database conformance coverage for both relationships,
ordinary and near-match origins, watchdogs, revised summaries, and
replay.
- Reconcile the working checklist with the merged guidance PRs and
record the bounded next step.
- Reuse the current composer helper for Everyday task creation: capture
the returned task ID, preserve the exact prompt and chosen
assignee/project, and cover the setup with paused-agent browser tests.
The same setup correction is present in both comparison variants.

## Verification

**Ready for review and merge at
`e2fc0c8e3ddb84dd9bc045704c3d1ecb23ee3447`: both original live cases
pass, zero new failures against the frozen baseline, all checks green,
CLEAN/MERGEABLE and out of draft. Not merged.**

| Profile | Original baseline | Initial candidate | Fixed candidate |
| --- | --- | --- | --- |
| native Codex / `gpt-5.6-sol` | PASS | FAIL | PASS |
| ACPX Claude / `claude-sonnet-5` | FAIL | PASS | PASS |

One new pass, one unchanged pass, zero new failures and no pending pairs
against the original baseline. The earlier failed candidate is
preserved; it was fixed and measured at a new source, not regraded or
rerolled unchanged.

### Current source and live evidence

- [Completed campaign
37523025407](https://github.com/paperclipai/paperclip/actions/runs/37523025407)
and [public report with original
screenshots](https://d1p6rlowie26tp.cloudfront.net/runner-e2e/campaigns/gha-37523025407-1/index.html).
Report and screenshots return HTTP 200; screenshot bytes match original
retained evidence.
- Measured candidate `e2fc0c8e3ddb84dd9bc045704c3d1ecb23ee3447`; reused
frozen baseline `7d700f43e93e89e4c196f8799b0aa3cef41d20da`. Trusted
workflow `88ff98b83d15eaa6640ee1848df4f0ad9bc82af3` is distinct from
measured sources; workflow blob
`0600886144d3e22ea2e4a38329a79177882f3948`. Prompts, fixture, oracle,
model/profile and input controls are unchanged. Both variants include
the same composer setup repair.
- Both original candidate grades PASS: all 31 checks per cell, parent
and child Done, independently tested revised ZIPs, successful cleanup.
Exactly one first attempt per profile on this source: 10 actual runs, no
retries. Reusing nine baseline runs gives 19 matched runs; the baseline
was not rerun.
- Claude directly exercised the repair: its revised child completed
while the parent was active, the parent's Done claim became InProgress
with `native_child_completion_pending`, and a fresh parent turn then
completed with the revised artifact.
- Both persisted final provider comments refer to the same attachment
whose parent-registration hash matches the revised ZIP tested by the
original oracle; native final evidence also references that attachment.
Codex provides a clickable download link. Claude describes the new
`--max-length` behavior but uses a backticked attachment ID, without a
clickable URL in the final prose. The artifact is registered on the
parent and independently downloaded/tested; prose-link usability remains
a presentation limit outside the original oracle. Artifact identity and
observed execution do not prove cognitive review.
- 68 focused scheduling/conformance/arbiter tests pass. Four regressions
fail against the original production files while four controls pass. The
database scheduler test proves one sequential continuation with the
revised summary and replay deduplication. It uses a mock adapter and is
separate from the live proof.
- Full local `pnpm -r typecheck` and `pnpm build` pass. [Exact-head full
CI
37522126627](https://github.com/paperclipai/paperclip/actions/runs/37522126627):
51 successful checks, two intentional skips, separate Snyk success.
Fresh exact-head Greptile
[5/5](https://github.com/paperclipai/paperclip/pull/15372#issuecomment-6022179172),
no new actionable findings; all review threads resolved.
- Ready-transition Contributor trust and Superagent Security Scan both
pass. The security scan completed at 2026-10-06T20:26:53Z with zero
annotations. Final total: 53 successful check runs, two intentional
skips and separate Snyk success; aggregate SUCCESS, source unchanged,
zero unresolved threads.
- The explicit parent lock precedes child writes. Its controlled
PostgreSQL ordering also passes on previous production through an
implicit foreign-key lock; this is hardening, not a reproduced
additional live failure. The four original failing regressions remain
the before/after proof of the active-parent repair.

### Preserved failures and accounting

- Initial candidate `a2ae2324ce7692e704fc43e99904b076d6246fee`: Codex
PASS → FAIL, Claude FAIL → PASS. Equal totals concealed a new failure
and did not qualify that source. Its Codex parent ended Blocked after
the revised child result coalesced into the active parent; there was no
retained later parent execution and the independent ZIP oracle was never
reached. A later server backstop log did not prove recovery.
- In the initial Claude cells, both parent finals referenced an earlier
parent ZIP while the oracle tested the revised child's ZIP. The original
candidate PASS did not establish latest-artifact delivery. Earlier
parent ZIP bytes are absent, so different hashes alone do not prove
missing functionality. Those original grades and content findings are
unchanged.
- Original baseline
[report](https://d1p6rlowie26tp.cloudfront.net/runner-e2e/campaigns/gha-37509893406-1/index.html);
original candidate Claude
[artifact](https://github.com/paperclipai/paperclip/actions/runs/37509916344/artifacts/11434353106);
failed candidate Codex
[campaign](https://github.com/paperclipai/paperclip/actions/runs/37513070706).
The original cohort contains 17 actual runs, no retries, successful
cleanup.
- Campaign 37509916344 was cancelled after its Codex job waited over 16
minutes without a runner or steps. Completed Claude evidence was
preserved; only the missing Codex first trial was dispatched in
37513070706. The trusted workflow revision differs but workflow bytes
are identical. The cancelled campaign has no published HTML. Earlier
campaigns 37506546098 / 37506550087 retain four composer setup failures,
zero agent runs; the identical fixture-only repair restored setup
without changing the prompt or outcome oracle.
- Intermediate `3c1cf6830ce9db4123b834ffb99c594c383a8986` [campaign
37518652522](https://github.com/paperclipai/paperclip/actions/runs/37518652522)
was cancelled after a concurrency review finding. Both paid-cell steps
started and both tasks were created. Only invocation policies survived;
no grade, run inventory or cleanup receipt. Provider activity and
charges are unknown: two incomplete attempts, not passes or
zero-provider setup failures.
- Cumulative accounting: **27 known actual runs** (17 original + 10
fixed-candidate), plus unknown activity in those two cancelled
intermediate attempts. The 19-run matched comparison reuses nine
baseline runs and is not additional execution. Reported LLM amounts are
zero with original billing `complete=true`; actual charges are unknown
and local/hosted runtime is unmetered. No free-run, speed or cost claim.
- Original and new results pass the canonical result validator. Retained
source, input, result/API/story/final-ledger/usage run identities and
artifact hashes were audited. Each downloaded package omits the
pre-upload-declared `playwright-output/.last-run.json`; primary result,
API, final ledger, story, screenshots and reached ZIP oracles are
retained. No full-package completeness claim.
- The initial redundant local full test invocation was stopped after
2,492.5 seconds once that head's CI passed; completed groups recorded
23,045 passes and 87 skips. That local invocation remains incomplete.
Current full CI is the repository-wide test evidence.

## Risks

A revised completion can schedule another sequential parent run and its
normal budget use. A parent Done claim remains non-terminal while a
newer native child result awaits delivery. Company scope, governance,
workspace-finalization, terminal cancellation and exact watchdog
behavior remain enforced. This changes native completion authority and
scheduling, so the durable identity, replay and concurrent-commit
controls matter.

The two live trials qualify the observed revised-child handoff, not
broad task quality or causal/general equivalence. Claude's final prose
still gives an attachment ID without a clickable URL, although the
registered revised artifact passes the original download oracle.
Completion before any new child result exists, removal of unfinished
dependencies and broader instruction reduction remain separate
questions. There is no schema or prompt change.

## Model Used

OpenAI Codex, GPT-6 family, with repository inspection, shell execution
and code editing. The exact serving model ID, reasoning setting and
context window 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-06 16:11:43 -05:00
DottaandPaperclip a590ab769d Give managed agents persistent cryptographic identities (#15352)
Give agents persistent Ed25519 identities encrypted with the existing instance master key. Create keys transactionally for new agents and lazily before supported managed runs, expose public identities in the API and agent UI, and protect private material during runtime delivery and output persistence.

Preserve identities in recovery backups while giving imported and development-cloned agents fresh keys.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-06 13:57:03 -05:00
DottaandPaperclip 9f7057e122 feat(connections): configure custom model providers across agent harnesses (#14970)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agents use a harness, a model, and a credential to run tasks.
> - Connections already store credentials and control who can use them.
> - Custom providers also need an endpoint and a supported API format.
> - A per-agent endpoint would duplicate credentials and access rules.
> - This pull request stores routing on the connection and projects it
into the harness.
> - Isolated credentials and protocol checks keep the selected
connection authoritative.

## Linked Issues or Issue Description

Refs #37, #13083, #14104, #14565, #12692.

#14016 is a reference only. This PR has its own schema, vault
persistence, routing validation, runtime projection, and tests. None of
the five commits in #14016 is an ancestor of this branch. We do not
depend on or plan to merge it. #14967 addresses task-pinned account
pools. #14422 addresses another provider integration.

This is the first of two linked PRs. Merge this connection change before
#15341, which refines agent setup and adds the qualification harness.
The split keeps each review below 100 changed files. Provider catalog
entries have usable setup forms in this PR. Local browser subscription
sign-in is included.

## What Changed

- Store non-secret routing metadata on AI connections. Vault provider
API keys, including Bedrock bearer API keys. Reject general AWS access
keys.
- Enforce company, owner, human audience, agent access, connection
status, and protocol checks before resolving credentials. Keep reconnect
destinations immutable and retain connection identity during key
rotation.
- Project OpenRouter and compatible custom endpoints into Codex, Claude,
OpenCode, and local Hermes. Carry these settings through both legacy and
native runner transports. Clear conflicting host credentials and redact
keys from diagnostics.
- Preserve older OpenRouter accounts and native personal defaults. Add
Google API-key accounts and migration `0306` for the two
provider-default constraints.
- Run local Claude and Codex subscription sign-in behind the existing
browser sign-in card. Use private attempt homes and owner-bound
completion instead of a copied terminal command.
- Seed isolated Gemini authentication and preserve OpenCode workspace
permissions. Keep the selected connection authoritative. The independent
Gemini and Grok workflow fixes are in #15341.
- Keep native OpenCode custom gateway keys in a runner-owned
selected-model proxy; the harness config contains only a session-scoped
capability. Honor runtime outgoing proxy and certificate settings.
Preserve streamed responses and revoke the proxy on close or startup
failure.
- Allow ordinary members to connect native personal accounts before an
agent exists.
- Repair routed accounts from task cards using the saved provider
destination, protocol, model aliases, and connection identity.
- Add provider catalog definitions, model discovery, pinned logos, and
complete native and routed setup forms. Allow a personal routed
connection before a new agent exists. Keep endpoint authentication keys
out of Hermes terminal children.
- Recover cancelled or restarted browser sign-in with a clear restart
action. Support no-auth endpoints without a vault credential. Add
isolation and recovery regressions and runtime documentation.

## Verification

- Updated with `origin/master` at `22a3ea341`. Migration `0306` follows
the new master migration and passes migration and snapshot checks.
- The integrated connection regressions passed 152 tests and 50 native
OpenCode driver tests, including key-free child-shell configuration
reads, authenticated/no-auth forwarding, streaming, model/path
restrictions, cancellation, outgoing proxy routing, and NO_PROXY bypass.
Provider setup has 14 passing tests. The pinned real OpenCode 1.18.34
executable also completed a turn through the proxy against a local
synthetic provider; the reusable key was absent from its config. A
second real-executable smoke passed with an HTTPS CONNECT proxy and
runtime-specific synthetic certificate trust. Certificate-file and
certificate-directory regressions pass.
- Task-card repair passed 48 tests, including OpenRouter, Bedrock, and
custom gateway reconnect cases. UI typecheck and token gates passed.
- The prior core regression set passed 133 tests across new-agent setup,
provider forms, browser sign-in, routing projection, and connection
authorization. Token gates and UI typecheck passed.
- Full workspace typecheck and production build passed again after the
latest integration and credential-proxy fix. The merged deterministic
runner E2E suite passed 1,400 Vitest tests and 128 Node tests.
- Full workspace typecheck passed on the prior linked combined
implementation. Production build, Storybook build, 1,316 browser-harness
Vitest tests, and 128 Node tests passed. Head `9d964c8d9` includes the
latest master integration and regenerated migration. This exact head
passed 54 remote checks with four expected skips and Greptile 5/5; no
review threads remain open. An unchanged server fixture had a random
six-character issue-prefix collision on its first attempt. All 245 tests
passed locally and the single CI retry passed.
- A provider-free terminal check used the cited supported Hermes source
and dummy keys. Gateway and OpenRouter terminal children could not read
the selected key.
- The broad local Vitest attempt passed 15,442 tests but was not green.
It had an embedded-Postgres startup failure, an HTTP logger timeout, an
origin socket error, and a browser cancellation wait timeout. The
cancellation wait was corrected. The relevant connection tests and the
full origin test file passed separately. Latest-head CI must pass before
merge.
- Prior credential-backed acceptance exercised task creation, tool use,
artifact delivery, completion, and context-dependent follow-up. Claude
legacy and native runners passed Bedrock with `us-east-1` and
`us.anthropic.claude-sonnet-4-6`.
- Historical local qualification retained 43 passing API/gateway cells
out of 46. Those attempts span earlier builds. They do not qualify this
exact commit or staging. All subscription combinations and staging
remain unqualified.
- Verify native subscription and API-key setup. Connect a regular
provider catalog row. Verify an incompatible harness and a changed
reconnect URL are rejected. Use #15341 for the complete browser
campaign.

## Risks

- Migration `0306` changes two check constraints. It preserves rows and
is safe to reapply. It takes normal constraint-change locks.
- Credential projection touches several harnesses. CLI upgrades can
change provider configuration and session behavior.
- The native OpenCode proxy adds a loopback hop, pins requests to the
selected model, limits request bodies to 16 MiB, rejects redirects, and
expires at session close. It prevents reusable keys in the child
configuration; it is not an OS isolation boundary against a process
debugger running as the same user.
- Custom endpoints must be reachable from the agent environment. Saving
a connection does not prove connectivity. Bedrock keys require rotation
before expiry.
- Gemini CLI 0.58.0 has an upstream ACP new-file error conversion
defect. Provider overloads and an unresolved follow-up timeout also
affect live Gemini qualification. We have not patched the installed CLI
or marked those cases as passing.
- OpenClaw Gateway, Hermes Gateway, Claude Managed, AWS AgentCore,
Process, HTTP, and legacy ACPX local are excluded. Vertex, ambient AWS
identity, arbitrary auth headers, and custom routing for other harnesses
are excluded.
- These PRs do not establish production or staging qualification for
every provider and login method.

## Model Used

OpenAI GPT-6 through Codex, with reasoning, repository tools, code
execution, and browser testing. The exact deployment model ID and
context window size were 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-06 13:29:03 -05:00
DottaandPaperclip f2715e02bb fix(native): surface model capacity errors and retry automatically (#15347)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Native runs preserve provider events and results, then decide task
state.
> - Codex can fail a turn because the selected model is temporarily at
capacity.
> - Paperclip displayed a generic native-session failure and left the
task in recovery.
> - A known capacity failure needs a clear message and a durable delayed
retry.
> - This pull request uses committed terminal evidence, the
status-effect ledger, and existing dispatch gates.
> - The task can continue automatically without an unbounded retry loop
or a model switch.

## Linked Issues or Issue Description

Related: #13993 adds launcher capacity deferrals before provider
startup. This change handles a committed native Codex `serverOverloaded`
terminal after provider work has started.

**What happened?**
A native Codex turn ended with `codexErrorInfo: serverOverloaded` and
“Selected model is at capacity. Please try a different model.” Paperclip
saved the result, showed a generic failure, and required recovery
instead of waiting and retrying.

**Expected behavior**
Show the capacity error directly. Schedule bounded retries after a short
delay. Preserve saved work and honor current execution gates.

**Steps to reproduce**
1. Run a native Codex task.
2. Commit a `turn.failed` event with `serverOverloaded`, then accept a
failed result for the same turn.
3. Inspect the task error and its recovery state. The regression test
reproduces this without a paid provider call.

**Paperclip version or commit**
Reproduced against master `16b7db35ffa0f9a95913c8cbdeea3d595435691f`.

## What Changed

- Classify capacity failures from committed runner events and the pinned
execution identity. Preserve accepted results and display the specific
capacity error.
- Atomically persist one scheduled successor with the status decision.
Retry after one minute, then two minutes. Share the existing failure
budget and stop after two automatic retries.
- Reuse dispatch gates for ownership, task holds, dependencies, budget,
and locks. Wait for predecessor execution, finalization, and cleanup
before claiming a retry.
- Preserve pending reviewer authority and suppress retries after
reassignment or a successor claim.
- Consume the failed run's resume receipt and delivered wake input.
Rebuild ordinary continuation from the failed run so explicitly resumed
tasks can retry without borrowing one-run authorization.
- Label scheduled retries “Model at capacity.” Add a Storybook example
and avoid duplicate punctuation in the existing retry card.
- Add regression coverage and document the runtime contract.

## Verification

- Targeted recovery and UI suites: 125 tests passed. Additional final
cleanup and lock regressions passed.
- Latest-head continuation and authorization regressions: 57 tests
passed, including all four capacity integration tests against an
isolated PostgreSQL database.
- Rechecked all four capacity integration tests with the full runner's
isolated `PAPERCLIP_HOME`, config, temporary directory, and serial fork
settings: passed.
- `pnpm -r typecheck`: passed. Final server typecheck passed.
- `pnpm build`: passed.
- `pnpm check:token-gates`: passed.
- Browser: checked the real Storybook card. It shows the capacity
message, automatic retry time, and existing Retry now action.
- `pnpm test:run`: attempted and restarted after an interruption. The
resumed run started before the final review correction and was stopped
after recorded workspace/native test failures and the five-minute Git
streaming timeout already documented on master. Exit 130; no complete
local full-suite pass is claimed. Current-head isolated capacity tests
and the complete CI suite pass.
- A combined local recovery-suite attempt also hit PostgreSQL
initialization failures at this macOS host's global shared-memory limit
(32 slots). The focused recovery suites passed separately; final-head
capacity tests also pass with the full runner's isolated environment
settings.
- Latest-head GitHub checks: all 56 checks green, including general and
serialized test shards, browser E2E, typecheck, build, Runner
verification, and canary dry run. No merge conflicts.
- Greptile: 5/5 on `813a470b8c18c05aeb7e31e63e573c3a3a2f5cac`, with zero
unresolved findings after fixing the resumed-task continuation issue.

## Risks

- Capacity retries can repeat a task turn after partial work. They start
a fresh provider session with task history and wait for predecessor
cleanup. They do not resume the failed turn.
- Retries retain the configured model unless an operator changes
configuration. Persistent overload consumes the existing failure budget
and then needs an explicit retry or model change.
- Only run-bound native Codex `serverOverloaded` failures qualify.
Usage-limit exhaustion, model/account incompatibility, unbound text, and
unknown provider failures retain their current recovery behavior.
- No schema migration is required.

## Model Used

- OpenAI GPT-6 through Codex. The exact model ID and context-window size
are not exposed to this session. Used reasoning, repository tools, code
execution, and browser verification. No subagents.

## 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
- [ ] 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-06 10:59:18 -05:00
1477d1ecea test: remove the no-op sequential describe modifier (#15286)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Paperclip runs the server and runner test suites with Vitest.
> - Vitest 5 removes the deprecated `describe.sequential` property, so
the pending Vitest 5 upgrade fails the type-check and test jobs.
> - `describe.sequential` only changes behaviour inside a
`describe.concurrent` suite, or when `sequence.concurrent` is on.
> - This repository has neither, so the modifier changed nothing at run
time.
> - The benefit is that the Vitest 5 upgrade can land, and the test
files lose a modifier that did no work.

## Linked Issues or Issue Description

Refs: #12969

## What Changed

- Replace every `describe.sequential` use with a plain `describe` call.
- Drop the `{ concurrent: false }` suite option from the two runner test
files.
- Add a comment to `server/vitest.config.ts` that records why these
suites must run one test at a time.
- Leave the package manifests and the lockfile unchanged.

## Why the modifier did nothing

The Vitest documentation states that `describe.sequential` is useful to
run tests in sequence inside a `describe.concurrent` suite, or with the
`--sequence.concurrent` option. `sequence.concurrent` defaults to
`false`.

This repository satisfies neither condition:

- No test file uses `describe.concurrent`, `it.concurrent`, or
`test.concurrent`.
- `server/vitest.config.ts` sets `sequence.concurrent: false`, with
`maxWorkers: 1`, `maxConcurrency: 1`, and `isolate: true`.
- `packages/paperclip-runner/vitest.config.ts` sets no `sequence` block,
so the `false` default applies.

`packages/db` and `cli` already run the same embedded-Postgres suites
with a plain `describe`, and those jobs are green. The server package
was the only outlier.

The modifier did carry one real piece of knowledge: these suites need
their tests to run one at a time. The new comment in
`server/vitest.config.ts` records that reason next to the setting that
enforces it.

## Verification

- `git grep` for `describe.sequential` returns nothing outside
`node_modules`.
- The author ran the changed server test files under the installed
Vitest 4, and the results match the results without this change.
- Two very large embedded-Postgres test files exceeded the author's
local memory limit, so the CI test jobs cover those two.
- The two changed runner test files have pre-existing local failures
caused by a missing Rust toolchain and a missing global `pnpm` binary.
The failures are identical with and without this change.
- The author type-checked the changed files and found no new error.
- CI must pass the typecheck, build, server test, and runner verify
jobs.

## Risks

- Low risk. Suite execution stays serial, because the Vitest config
enforces it.
- The change adds no dependency and changes no package manifest or
lockfile.
- A future change that turns `sequence.concurrent` on would break these
suites. The new config comment warns against it.

## Model Used

- Claude Sonnet 5 — code edits and local verification.
- OpenAI Codex, GPT-5 — the earlier revision of this branch.

## Test plan

- [x] Every CI check reaches a terminal green state. A pending or queued
check is not a pass.
- [x] The `Typecheck + Release Registry` job passes. This change must
not introduce a type error.
- [x] The `Build` job passes.
- [x] The server test jobs and the runner verify jobs pass.
- [x] Greptile re-reviews this commit set and posts a passing verdict.
The dependabot waiver does not apply to this pull request.
- [x] `mergeable` reads `MERGEABLE` as a terminal value.

## 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 linked the related public issue with `Refs: #12969`
- [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 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: Priya Raman <priya.raman@paperclip.ing>

---------

Co-authored-by: Priya Raman <priya.raman@paperclip.ing>
Co-authored-by: Paperclip <noreply@paperclip.ing>
Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
Co-authored-by: nickyleach <331803+nickyleach@users.noreply.github.com>
2026-10-06 07:19:15 -07:00
DottaandPaperclip 63f3aa2dbf fix(runner): continue restart-interrupted Codex turns (#15297)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Native runs retain their provider conversation across server
restarts.
> - A dead runner can restore a Codex conversation after its active turn
is lost.
> - The old recovery path synthesized a failed task result from that
interruption.
> - The task then required operator action even though its conversation
and workspace were available.
> - This pull request preserves the interruption cause and uses the
admitted restart attempt for one continuation in the same conversation.
> - The agent can reconcile unfinished actions and complete the current
request without resending the original task.

## Linked Issues or Issue Description

Related: #12845 added native restart recovery. #15042 covers admission
during shutdown. #14796 covers legacy shutdown recovery. This change
covers a lost native Codex turn after successful conversation
restoration.

**What happened?**

After a server restart killed the local runner, Paperclip restored the
saved Codex thread. Runnerd found that the old turn was no longer
active. It synthesized a failed terminal and a needs-review result from
the last progress message. The transport also discarded the terminal
error when it reconstructed thread history. The task failed instead of
continuing.

**Expected behavior**

After proving that the old process stopped and admitting a bounded
recovery attempt, resume the current request in the same conversation.
Preserve the workspace. Inspect unfinished actions before proceeding.
Keep real provider failures, accepted results, intentional stops,
unknown unreconciled effects, and exhausted attempts subject to their
existing rules.

**Steps to reproduce**

1. Start a local native Codex run and leave its turn active.
2. Kill the isolated runner and provider processes, as can happen during
a server restart.
3. Restore the same provider thread with no active turn.
4. Observe the synthetic task failure. The new real-process regression
reproduces this boundary with a scripted provider.

## What Changed

- Record an explicit recoverable process-loss cause without inventing a
task result.
- Preserve terminal errors and prior turns in reconstructed provider
history. Recover the authoritative saved result when adopting an
accepted continuation.
- Send one continuation in the same conversation for an admitted
dead-runner recovery. Require reconciliation of unfinished commands and
external actions.
- Persist the interrupted terminal before submission and retain the
existing recovery marker across another controller loss.
- Keep provider attempt limits, terminal failures, and intentional
cancellation behavior.
- Add red/green regressions, real process-kill coverage, restart
checkpoint coverage, and retry-budget coverage. Document the behavior
and run-log evidence.

## Verification

- Red: the new native runtime regression rejected with
`NativeProviderTerminalFailure` on the original code; the Rust restore
regression found a missing recovery cause.
- Red/green: if restoring the conversation fails and replacement is
allowed, the replacement receives the full task and fresh-session
handoff. Both prepared and legacy execution inputs are covered.
- Red: a second controller crash after the provider accepted the
continuation caused an extra `turn/start`. The regression now proves
there are exactly two submissions total: the original and its
continuation.
- Green: focused runtime, backend, driver recovery, and real-process
restart suites (207 tests). After the final history/result changes,
driver recovery and real-process restart suites passed again (36 tests).
- Green: complete Codex transport suite (186 tests), server restart
classification/database integration suites (34 tests), and Rust Codex
provider suite (92 passed, 2 ignored).
- Full `pnpm -r typecheck` and `pnpm build` passed on `60141e649`. The
subsequent replacement-prompt guard passed the Runner TypeScript check
and the complete runtime plus process-restart suites (148 tests).
- Local full-suite attempt: `pnpm test:run` reported two failures in the
untouched chat integration suite. Both passed individually, and the
complete chat suite passed on rerun (1,063 tests). After all remote test
shards passed, the duplicate serial local run was stopped with SIGINT;
it is not claimed as a full local-suite pass.
- Latest-head CI (`b1297dcd4`): 55 successful checks and 4 intentionally
skipped checks, including all test shards, typecheck, build, native
Runner verification, end-to-end tests, and canary dry run. [CI
run](https://github.com/paperclipai/paperclip/actions/runs/37405346303).
- Greptile: 5/5 on the latest head, with no unresolved review threads.
The PR is mergeable.
- The process tests use the real runner binary and a scripted Codex
provider. They do not call a live model service.

## Risks

- This changes local Codex recovery after process loss. A continuation
can execute more work in the retained conversation. Its prompt requires
state inspection before repeating an uncertain action; the system does
not replay tool calls.
- Recovery shares the existing three-attempt budget and one-shot
continuation marker. Real failures and older unmarked failed checkpoints
are not reopened.
- No database migration or API change is required.

## Model Used

- OpenAI Codex, based on GPT-6. The exact model ID and context-window
size are not exposed in this session.
- Capabilities: reasoning, source inspection, tool use, code editing,
code execution, and test analysis.

## 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-06 07:49:47 -05:00
Devin FoleyandPaperclip 1d5a439e2b Diagnose native model rejections and preserve repairable reviews (#15304)
## Thinking Path

> - Paperclip manages agent execution and recovery.
> - A native provider can return a failed turn with an accepted result.
> - This path replaced a structured model rejection with a generic
failure.
> - Finalization could also queue the same failed request for recovery.
> - This change retains a bounded model and authentication diagnosis.
> - Workers wait for a configuration fix; reviews retain their
assignment.

## Linked Issues or Issue Description

**Describe the bug**

A native Codex turn can report HTTP 400 because the selected model is
not supported by its ChatGPT connection. When the turn also returns a
failed semantic result, the run shows `Native session failed` and
`adapter_failed`. The native failed-result finalizer can create a retry
intent before the adapter error is saved.

**To Reproduce**

Use a native Codex session that returns a structured
`invalid_request_error` model/ChatGPT rejection and an accepted failed
result. The regression tests reproduce this with a stub provider and a
real isolated PostgreSQL database. No provider account or live request
is needed.

**Expected behavior**

Show an actionable error and stop automatic retries of the rejected
request. Block the current worker for a configuration fix. Preserve a
pending review so its reviewer can explicitly retry after repair and
resolve the original assignment. A stale run must not block a new task
owner or override a completed review.

**Version and deployment mode**

The affected source path is present at `858094ba81`. This change applies
to native Codex execution in local and remote environments.

Related work: #13853 covers CLI protocol compatibility, #14942 refreshes
runtime/model pins, and #12767 proposes legacy adapter model validation.
This change concerns accepted native failed results and does not replace
those changes.

## What Changed

- Recognize only a bounded structured HTTP 400 provider error for the
exact selected model and failed turn.
- Save a fixed actionable error and four fixed diagnostic fields.
Exclude raw provider text and model names from the new diagnostic.
- Re-derive finalization evidence from the pinned execution and
committed runner event, including its canonical hash and identity
bindings.
- Block only the current worker. For a current pending reviewer,
preserve the original review decision and status version, release
execution, and create no automatic recovery action. Recheck execution
ownership under the issue lock. Preserve superseded and completed
reviews.
- Keep unknown failures, accepted results, cleanup, and ownership fences
intact. Advance the status policy version to `phase6-v8`.
- Route this exact failure code through the existing configuration
recovery path. Permit an authenticated Board retry of this native
failure only for its saved, still-pending review; discard caller review
markers and revalidate at dispatch.

## Verification

- Node 24: `pnpm -r typecheck` and `pnpm build` passed.
- Independent focused validation: 222 tests passed across the new
observer and PostgreSQL integration suites, status arbiter, diagnostic
redaction, recovery classification, wake policy, and wake use cases.
- The integration tests use actual result persistence, finalization, and
the wake dispatcher. They cover zero retry dispatch for an authorized
rejection, repeated reconciliation, pending/superseded/resolved reviews,
reassignment, and a same-agent successor at an unchanged status version.
- Final-commit verification: full typecheck and build passed;
independent route/integration/arbiter/review validation passed 136 tests
with no remaining source findings. This includes authenticated retry
refusals, actual heartbeat retry admission, atomic queued-review claim,
and acceptance of the original review.
- The local aggregate test run was stopped to avoid duplicating the
canonical Linux CI aggregate on this development host. Its partial log
showed no failures; no full local-suite pass is claimed. The full hosted
Linux CI aggregate passed on the final commit.
- No live provider calls, runtime changes, or schema changes were made.

## Risks

The classifier is intentionally narrow. A changed provider response
format remains an unknown failure. No global model restriction is
introduced. The worker blocker requires current task authority and does
not replace newer assignments or completed review decisions. A pending
review remains in review and requires an explicit retry after
configuration repair; it is not rebound to a new status decision.

The retry decision is durable. There remains a small existing gap
between status/effect commit and diagnostic metadata persistence; a
crash there can leave a generic diagnostic while preserving the blocked
decision. No schema migration is required.

## Model Used

OpenAI Codex, GPT-6, with reasoning, tool use, and code execution. The
exact serving model suffix 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
#123` / `Refs #123` 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 references)
- [x] My branch name describes the change and contains no internal
ticket id or instance-derived details
- [x] I have run focused 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-05 20:57:33 -07:00
Devin FoleyandPaperclip e99854249c fix(workspaces): restore rebased sandbox history against its starting snapshot (#15268)
## Thinking Path

> - Paperclip manages agents and preserves their work across runs.
> - Sandbox execution restores Git history and files to the host
workspace.
> - An agent can rebase or amend its branch before it finishes.
> - Restore currently treats the original and rewritten tips as
concurrent work.
> - That merge can conflict even when the host has not changed.
> - This change uses the starting Git snapshot to accept rewritten
history safely.

## Linked Issues or Issue Description

**What happened?**

A successful sandbox turn can end with `workspace_restore_failed` after
the agent rebases and pushes its branch. The restore step merges the
original host tip with the rewritten sandbox tip. This can recreate
conflicts that the agent already resolved.

**Expected behavior**

Accept the rewritten history when the host still has the recorded
starting branch and commit. Preserve concurrent host work through the
existing merge and recovery paths.

**Steps to reproduce**

1. Start a sandbox from a feature branch.
2. Rebase that branch onto an upstream commit that changes the same
file. Resolve the conflict in the sandbox.
3. Restore the sandbox while the host remains on the original commit.
4. The old implementation attempts a conflicting Git merge and fails the
run after the agent finishes.

**Paperclip version or commit**

Reproduced on `cab4263dc9` with a real Git rebase fixture.

**Deployment mode**

Self-hosted server with sandbox execution.

Related work: #15005 records restore failure stages. #11638 preserves
unrelated imported history with a graft. #10601 handles bundle
prerequisites. Those changes do not distinguish a rebase from a
concurrent host edit.

## What Changed

- Pass the run's starting Git branch and commit into sandbox history
integration.
- Adopt a related rewritten tip when the host still matches that
snapshot. Keep the expected-old-value ref update and bounded retry.
- Verify the branch attachment inside a prepared Git transaction while
Git holds its ref locks. Abort if a checkout changed the branch.
- Check host and sandbox Git identity before warm reuse, including
nested repositories. Restage when their tips or branches differ.
- Reject host branch changes and unrelated imports after a concurrent
host commit.
- Retain the existing unrelated-history graft for an unchanged host and
the conservative behavior for callers without a snapshot.
- Export a full bundle for an intentional reset to an ancestor so
restore receives the actual sandbox tip.
- Add real Git and sandbox restore regressions. Document the restore
contract.

## Verification

- Eight Git sync, sandbox restore, and native workspace suites pass: 255
tests.
- The new checkout-race and warm-reuse regressions failed before the
fixes. Real Git hooks verify that prepared transactions prevent a
concurrent HEAD change.
- `pnpm -r typecheck` passed after rebasing onto `984f092ddf` and
applying the Apex findings.
- `pnpm build` passed on `f5132603d6`.
- The earlier `pnpm test:run` attempt reported three
`company-skills-service.test.ts` failures on macOS (`EACCES` renaming a
read-only staging directory). The same failures reproduced on unchanged
master. The broader run was stopped after confirming that baseline
failure; it was not a full-suite pass. Those source and test files are
unchanged in the current base.
- [Apex
review](https://github.com/paperclipai/paperclip/pull/15268#issuecomment-6002549219):
5/5 on `f5132603d6`, requested with `@greptileai apex review`. All three
historical findings are addressed and all review threads are resolved.
- All CI gates passed on `f5132603d6` (53 successful checks, two
skipped). The signoff-policy browser fixture initially timed out waiting
for a local process-agent run; its one retry passed without code
changes. [CI
run](https://github.com/paperclipai/paperclip/actions/runs/37387511152)

## Risks

- A recorded starting snapshot now authorizes replacement of related
rewritten history. A stale or changed host tip retains the
concurrent-history path. Ref writes still compare the expected old
commit.
- Branch changes and unrelated rewrites after host advancement require
recovery instead of replacing host work.
- An intentional reset to an ancestor uses a full bundle. Large
histories can increase transfer time in that case.
- The existing directory merge rules remain in force. The fix does not
resolve an earlier failed restore or replay its external actions.

## Model Used

OpenAI GPT-6 via Codex, with reasoning, repository analysis, code
editing, and local test execution. The exact deployment model ID and
context window were 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 — 255 affected tests; the
broader-suite baseline failure is 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-05 16:43:15 -07:00
DottaandPaperclip 4857799a88 feat(connections): deliver saved instructions to authorized agent turns (#15216)
Persist optional connection instructions and deliver authorized snapshots to agent execution prompts. Keep provider templates with each app definition, preserve edits and opt-outs, and replace sessions when guidance or access changes.

Use shared production settings across setup and Permissions, with source visibility in agent Instructions. Add the initial memory-provider defaults and managed Honcho workspace configuration. Include migration 0298 and regression coverage for generic providers, runtime delivery, authorization, and catalog regeneration.

Co-Authored-By: Paperclip <noreply@paperclip.ing>
2026-10-05 18:16:00 -05:00
6c36c07a4f feat(adapters): add GPT-6.1 Sol and refresh shared coding harness pins (#14942)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agents run through coding-agent adapters and the native runner. Both
use the same installed provider CLIs, model catalogs, and reasoning
controls.
> - OpenAI released GPT-6.1 Sol (`gpt-6.1-sol`) in Codex. Anthropic
released Claude Sonnet 5.5. The static Codex, Bedrock, and OpenCode
catalogs do not list these IDs.
> - The shared provider pack pins Codex 0.156.0 and OpenCode 1.18.32.
The evaluation image pins older Grok, Gemini, Kimi, Cursor, and GitHub
CLI releases. Codex 0.156.0 has no bundled metadata for GPT-6.1 Sol.
> - A model entry without a current harness, or a harness pin without
its runner integrity checks, fails at run time.
> - This pull request adds the verified model IDs and moves the harness
pins, executable digests, controller checks, and image pins together.
> - The benefit is that operators can select the current models, and the
native and local adapters share one current CLI installation.

## Linked Issues or Issue Description

Refs #13829 and #13838 (the September 22, 2026 model and harness
refresh). Related pull requests: #14993 (merged October 5, 2026,
superseding #14816) added the direct Claude Sonnet 5.5 entry and
refreshed the Claude runtime to Agent SDK 0.3.286 / Claude Code 2.1.286.
This pull request does not change the Claude runtime or the direct
Claude model list; it keeps the #14993 pins and adds only the Bedrock
Sonnet 5.5 ID. After #14993 merged, this branch was rebased onto
`master` (October 5, 2026). The six overlapping pin regions
(`docker/daytona-runner/Dockerfile`, `docker/daytona-runner/README.md`,
`package.json`, `pnpm-workspace.yaml`,
`packages/adapters/claude-local/src/index.test.ts`,
`packages/paperclip-runner/src/backends/native-backend-factory.test.ts`)
were resolved by keeping this pull request's Codex 0.160.0 and OpenCode
1.18.34 pins next to #14993's Claude 0.3.286 / 2.1.286 pins, taking the
union of the Sonnet 5.5 model IDs in the Claude test, and merging both
README paragraphs. The Sonnet 5.5 effort and CLI-gate lines in the
Claude adapter were identical in both pull requests and merged without a
diff. #14917 and #14918 reordered the Claude and Codex model lists
earlier; the new entries sit where those ordering rules put them.

Sources checked on 2026-10-02:

- [OpenAI Codex models](https://learn.chatgpt.com/docs/models): GPT-6.1
Sol uses `gpt-6.1-sol`, supports reasoning efforts from Light to Ultra,
and has Standard and Fast modes at launch. The page also records that
`gpt-5.4` and `gpt-5.4-mini` retired from Codex with ChatGPT sign-in on
August 31, 2026, and that `gpt-5.5` retires on October 14, 2026. Neither
retirement applies to the OpenAI API.
- [Codex CLI releases](https://github.com/openai/codex/releases) 0.157.0
through 0.160.0. The bundled model metadata in the 0.160.0 Linux binary
contains `gpt-6.1-sol`.
- [Claude Sonnet
5.5](https://platform.claude.com/docs/en/models/sonnet-5-5/overview):
Bedrock ID `anthropic.claude-sonnet-5-5`, released September 28, 2026.
- [OpenCode releases](https://github.com/anomalyco/opencode/releases)
1.18.33 and 1.18.34 (fixes only). The OpenCode model registry lists both
added provider-qualified IDs.
- npm `latest` tags for `@xai-official/grok` 1.0.46,
`@google/gemini-cli` 0.62.0, and `@moonshot-ai/kimi-code` 2.1.1.
[xAI](https://docs.x.ai/docs/models),
[Google](https://ai.google.dev/gemini-api/docs/models), and
[Kimi](https://www.kimi.com/code/docs/en/kimi-code/models.html) list no
newer coding models.
- Cursor CLI 2026.10.01-e373342 is the version the official installer
resolves. The pinned digest is the SHA-256 of the versioned Linux x64
archive.
- [GitHub CLI 2.102.0](https://github.com/cli/cli/releases/tag/v2.102.0)
(security fixes). The pinned digest matches the release `checksums.txt`.

## What Changed

- Codex adapter: add `gpt-6.1-sol` to the model list, the Fast mode
list, and the Ultra effort set. It is the first entry: #14918 orders the
list newest version first, and its description notes the ChatGPT app
lists GPT-6.1 Sol first. Update the adapter documentation text.
- Claude adapter: add `us.anthropic.claude-sonnet-5-5` (Bedrock Sonnet
5.5) to the Bedrock catalog in the newest-Sonnet slot after Opus 5.5;
`us.anthropic.claude-sonnet-5` moves into the older-Sonnet group,
matching what `sortClaudeModels` from #14917 produces at runtime. Any
Sonnet 5.5 ID (direct or Bedrock-qualified) now gets the documented
`xhigh` and `max` efforts and requires Claude Code 2.1.284 or later on
the CLI lane (the Claude Code changelog entry for 2.1.284 adds
`claude-sonnet-5-5`). These two lines are identical to the ones #14993
merged, so the branch carries no diff for them.
- OpenCode adapter: add `openai/gpt-6.1-sol` and
`anthropic/claude-sonnet-5-5` to the static fallback catalog.
- Codex runtime pin 0.156.0 → 0.160.0 in the root and workspace
overrides, the runner package, the Codex ACP package patch, the
qualified ACPX profiles, the Linux x64 executable digest, the Rust
provider backend and its tests, the provider-pack manifest pins, the
remote controller pins, the sandbox npm install spec, and the opt-in
qualification scripts.
- Remote Codex compatibility window: upper bound 0.157.0 → 0.161.0. The
minimum stays at 0.149.0.
- OpenCode runtime pin 1.18.32 → 1.18.34 in the runner package, the
materialization script, the server and Rust qualified versions, the eval
and live-session labels, fixtures, and the configuration label.
- Evaluation image (`docker/daytona-runner/Dockerfile`): Grok CLI
1.0.46, Gemini CLI 0.62.0, Kimi Code 2.1.1, Cursor CLI
2026.10.01-e373342 with its digest, GitHub CLI 2.102.0 with its digest,
Codex and OpenCode version probes, and the refreshed lockfile digest.
The Claude Code 2.1.286 probe comes from #14993 and is unchanged here.
- `pnpm-lock.yaml` is not part of this pull request. The repository's
pull request gate rejects lockfile edits, and the refresh bot
regenerates the lockfile on master (the same flow #13838 used). The
Dockerfile `PAPERCLIP_RUNNER_LOCK_SHA256` default is the digest of the
lockfile that `pnpm install --resolution-only --ignore-scripts
--no-frozen-lockfile` (the refresh workflow's command) produces for the
combined pins on the rebased branch (`e1856797…`); that lockfile differs
from master only in the `@openai/codex` 0.160.0 platform packages, the
`@anthropic-ai/claude-agent-sdk` 0.3.286 override that #14993 introduced
(the open refresh-bot pull request #14872 carries that part),
`opencode-ai` 1.18.34 with its Linux x64 baseline, and the `codex-acp`
patch hash.
- Documentation: runner README, runner compatibility doc, environment
variable example, and a new `doc/adapter-model-audit-2026-10-02.md` with
sources and deferred items.
- Tests: Codex adapter catalog, server adapter models, Codex
compatibility window, native session executor pins, runner package
contract, OpenCode materialization, and UI effort options.

Unchanged on purpose: Claude Agent SDK 0.3.286 / Claude Code 2.1.286
(already on `master` from #14993), ACP bridges (`acpx` 0.13.1,
`claude-agent-acp` 0.73.0, `codex-acp` 1.6.2; newer upstream releases
need a separate qualification), the native Grok runtime 1.0.13, Pi
0.84.2 / 0.87.1 (the Pi 1.0 runner stack covers it), and Hermes 0.19.0
(current). `gpt-5.4` and `gpt-5.4-mini` stay in the picker because the
OpenAI API still serves them.

## Verification

Run on Linux x64 with Node 25.9.0 and pnpm 9.15.4 after `pnpm install
--no-frozen-lockfile` (the refreshed lockfile stays local; see above).
The results below were re-run on the rebased head (October 5, 2026) for
the suites the conflict resolution touches; the other rows are from the
original run and are covered by CI on every push:

- Rebased head: `packages/adapters/codex-local` 482 passed;
`packages/adapters/claude-local` 340 passed, 4 failed (`execute.remote`,
`test.probe`, `execute.acp-fallback`, `acp` spawn/env-hardening cases
that fail identically on unchanged `master` in this host environment);
`server` adapter-models + codex-runtime-compatibility +
native-session-executor + adapter-registry 607 passed, 1 failed (the
same adapter-registry override-pause case as before, also failing on
`master` here); `packages/paperclip-runner` native-backend-factory +
qualified-profiles 36 passed; `ui` codex-reasoning-effort +
config-fields + model-utils 19 passed. Rust, full typecheck, build, and
the Docker image are left to CI as before.

- `vitest run` in `packages/adapters/codex-local`: 13 passed. `vitest
run` in `packages/adapters/claude-local` (whole package, including the
new Sonnet 5.5 gate and effort tests): see the latest CI run and the
comment below. `vitest run` in `packages/adapters/opencode-local`: 48
passed, 1 failed (`runtime-config.test.ts` reads the host
`PAPERCLIP_OPENCODE_PROVIDERS` variable; it fails the same way on the
unchanged base).
- `vitest run src/__tests__/adapter-models.test.ts
src/services/native-runtime/codex-runtime-compatibility.test.ts
src/__tests__/adapter-registry.test.ts` in `server`: 84 passed, 1 failed
(`adapter-registry.test.ts` override pause test; it fails the same way
on the unchanged base).
- `vitest run` in `ui` for `codex-reasoning-effort`,
`agent-setup-fields`, `config-fields`, and `ComposerRunSettingsPicker`:
25 passed.
- `node --test test/acpx-codex-package-contract.test.mjs
scripts/materialize-opencode-binary.test.mjs
scripts/runner-protocol-eval-campaign.test.mjs` in
`packages/paperclip-runner`: 23 passed. The package contract test
verifies the installed Codex ACP executable digest and the 0.160.0 patch
pin.
- `vitest run src/drivers/acpx src/backends src/drivers/opencode
src/live/live-session.test.ts` in `packages/paperclip-runner`: 626
passed, 5 failed, 1 skipped. The 5 failures
(`installation-integrity.test.ts` `/proc/self/fd` module loading and one
OpenCode answer-selection test) also fail on the unchanged base under
Node 25; Linux CI runs Node 24.
- `pnpm run test:opencode:qualification` in `packages/paperclip-runner`
against the installed OpenCode 1.18.34 executable: passed.
- `codex --version` from the installed pack prints `codex-cli 0.160.0`.
The Linux x64 executable digest `12eb3e81…652aad` was computed from the
`@openai/codex@0.160.0-linux-x64` archive after checking its registry
`dist.integrity`.
- `pnpm check:token-gates`: all gates clean.
- `pnpm run typecheck:typescript` in `packages/paperclip-runner`:
passed. Package typechecks ran one at a time; see the comment below for
the server and UI results.

Not run here, and needed from CI:

- Rust tests and `pnpm -r typecheck` / `pnpm build` for the server (no
`cargo` in this environment; the server typecheck prepares the runner
vendor build).
- The Docker evaluation image build and the real-binary Codex startup
and session-resume probes (no Docker; the probes need the compiled
`paperclip-runnerd`). The trusted CI runner workflow covers them.
- Authenticated inference with any new model. This change is metadata
and startup validation only.

## Risks

- Codex 0.160.0 changes the bundled model catalog and app-server
behaviour (authoritative provider catalogs, incremental running-turn
tracking). The patched `codex-acp` 1.6.2 bridge is unchanged and
declares `^0.148.0`; it worked with 0.156.0 under the same override. If
CI probes show a protocol change, the pin can return to 0.156.0 by
reverting this pull request.
- The compatibility window upper bound moves to `<0.161.0`. Remote
images with Codex 0.157 to 0.160 become accepted. Older images stay
accepted down to 0.149.0.
- Until the refresh bot lands the regenerated lockfile on master, the
Dockerfile lockfile digest default does not match the committed
lockfile. The trusted CI workflow computes the digest from its own
resolution at build time, so this affects only a local build that passes
no digest.
- Existing saved model selections and effort settings are not changed.
Agents on `gpt-5.4` or `gpt-5.5` with ChatGPT sign-in need a model
change before the OpenAI retirement dates; that is documented, not
enforced.
- Rollout order: deploy the controller and runner from this change
before promoting a sandbox image that carries these pins. Older
controllers reject the new provider-pack pins.

## Model Used

- Claude Fable 5.1 (Anthropic, model ID `claude-fable-5-1`), 1M context
window, adaptive thinking, tool use. The model ran as a Paperclip agent
through the Claude Code harness, performed the web research, edited the
code, and ran the tests listed above.

## 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
- [ ] All Paperclip CI gates are green
- [ ] Greptile is 5/5 with no open P2s, recommendations, or follow-ups
- [x] I will address all Greptile and reviewer comments before
requesting merge

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Bender (Fable) <noreply@paperclip.ing>
Co-authored-by: devinfoley <139239+devinfoley@users.noreply.github.com>
Co-authored-by: Claude Fable 5.1 <noreply@anthropic.com>
2026-10-05 13:59:08 -07:00
DottaandPaperclip b43073d11f feat(connections): sync and group accounts managed by aggregators (#15254)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Connections give agents governed access to external tools.
> - Aggregator gateways can expose accounts that users already connected
upstream.
> - The Apps catalog did not show those accounts or their current
provider status.
> - Separate cards and setup tasks also made account ownership unclear.
> - This pull request discovers upstream accounts and groups them under
one app card.
> - Users can find connected apps while each provider keeps control of
its accounts.

## Linked Issues or Issue Description

**Subsystem affected**

Connections across the database, shared contracts, server, and board UI.

**Problem or motivation**

Users cannot see which apps are connected through a saved aggregator
gateway. Native and upstream accounts need one app card. Discovery must
preserve company, user, gateway, and credential boundaries.

**Proposed solution**

Sync account metadata from Composio, Arcade, and supported Executor
gateways. Keep upstream account management in each provider. Use source
chips and search to browse the catalog. Preserve native setup and the
gateway's existing access policy.

**Alternatives considered**

Creating a local executable connection for each upstream account would
duplicate authorization state. Using an agent task for routine Composio
setup would add an unnecessary step. The board now calls the saved
gateway directly for that setup.

**Roadmap alignment**

This extends the shipped Connected Apps and MCP Tool Gateway features in
ROADMAP.md. The duplicate search found no open PR for managed account
discovery.

Related work: Refs #13755, Refs #13941, Refs #14725, Refs #13855. Open
PR #12906 covers adjacent toolkit routing work.

## What Changed

- Add provider-neutral discovery, sync, and refresh APIs. Preserve the
Composio API paths.
- Cache observations by company, saved gateway, viewing user, and
credential version. Retain stale observations after failed or incomplete
scans.
- Add optional Arcade account sync credentials in the vault. Discover
Executor accounts through its supported inventory interface.
- Group native and upstream accounts in one app card. Imported account
menus open their provider. Gateway menus own refresh and sync setup.
- Add Paperclip, Composio, Arcade, Installed, and All chips. Show 50
catalog entries per page. Keep connected accounts above discovery. Keep
explicit provider searches scoped.
- Simplify Composio app setup and refresh its connected app list on the
gateway Permissions page.
- Add a compact agent access card and task creation defaults for
connection setup. Preserve explicit blocks and approval policies.
- Add two replay-safe migrations, service and UI tests, Storybook
journeys, and acceptance stories.

## Verification

- Passed the repository typecheck, full build, token gates, and
migration ordering check.
- Passed the focused provider adapter, connection interaction, and
catalog tests after rebasing onto master.
- Passed all nine database sync and migration replay tests using a
disposable database on the test-drive PostgreSQL cluster. Removed that
database after the run.
- Verified Arcade cursor pagination against its official Go SDK and
passed all eight adapter tests, including short and incomplete pages.
- Passed all 45 interaction tests after making the exact requested tools
and their Allowed/Ask first permissions visible before granting access.
Verified the compact card in Storybook.
- Passed the complete UI suite on the final code: 683 files and 7,432
tests, including the corrected Composio destination assertions. Passed
130 focused tests for the UUID, management-link, and health-status
corrections.
- Passed 22 Composio setup/sync tests, 23 connection-intent service
tests, and the connection migration test in separate disposable
databases. Database startup alone was substituted; the suites exercised
their real SQL and services.
- Passed all 10 OpenAPI route checks and the full-stack
connection-intent browser test, including scoped consent, agent
continuation, and task completion.
- The local full runner encountered embedded PostgreSQL startup failures
on this loaded macOS host. The earlier in-flight run also held the
pre-fix Arcade transform; a fresh run of the final provider suite
passes. The final-head CI is queued during GitHub’s active Actions
incident: https://www.githubstatus.com/. The previous run also lost
several runners simultaneously; its real catalog assertion failures are
fixed and the fresh complete UI suite passes.
- Tested the real test-drive server in the embedded browser with a live
Composio gateway. Detected Airtable and Circleback. Verified refresh
progress, account rows, source chips, search scope, and 50-entry
pagination.
- Arcade and Executor coverage uses provider fixtures. Live credentials
were unavailable.
- Storybook builds successfully and includes grouped native/provider
accounts, stale and unavailable discovery, optional Arcade setup, and
mobile states. The acceptance document records the simulated and live
coverage separately.

- Greptile reviewed final commit
`217b024c27b5933e773ce9419c4e92b1032042c6` at 5/5. All six review
threads are resolved, security scans pass, and the PR has no merge
conflicts. The outstanding remote checks are `ci / Select trusted
runner` and `review`, queued by GitHub. They need to complete before
merge.

## Risks

- Provider response changes can break inventory discovery. Failed scans
retain observations and show stale status.
- Composio scans only the supported catalog and can take time. Large
inventories run in the background with progress and a bounded lease.
- Arcade requires a project API key and user ID when the gateway cannot
supply them. This key is used only for discovery.
- Executor discovery depends on the server's exposed inventory tools.
Unsupported servers report unavailable discovery.
- Cached account rows do not grant access or create executable
connections. Gateway policies still govern tool use. Account deletion
and per-app authorization remain upstream.
- The migrations add tables and one nullable column. Replay preserves
existing rows and company-scoped foreign keys.

## Model Used

OpenAI Codex, based on GPT-6. The session does not expose a more
specific serving model ID or context limit. Used reasoning, repository
tools, code execution, and browser verification.

## 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
- [ ] 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
- [ ] 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-05 14:57:04 -05:00
DottaandPaperclip a65ca09508 fix(runner): settle accepted results after shutdown failures (#15217)
## Thinking Path

> - Paperclip manages AI agents and the tasks they perform.
> - The native runner saves tool results and completion reports before
it releases a session.
> - Large project discovery responses can exceed the durable command
limit.
> - A shutdown failure can leave a saved answer waiting for workspace
repair.
> - Recovery reused the old assessment for a different status decision,
which violated a database constraint.
> - This pull request bounds discovery responses and lets recovery
commit the saved result after workspace repair.
> - The benefit is a task that reaches its correct final status without
another provider turn.

## Linked Issues or Issue Description

**What happened?**

A native run can save its final answer, fail during shutdown, and leave
the task In Progress after workspace repair succeeds. Reconciliation
tries to reuse the failed-workspace assessment for a new decision. The
one-decision-per-assessment constraint rejects the write. Replaying the
old decision can also retain a fresh coordinator lease. Separately,
retained session cleanup only recognizes the old `adapter_failed` label.

The project-list tool returns full project records, including large
descriptions and workspace configuration. A large response exceeds the
runner's durable command limit. The settlement diagnostic previously
recorded only a failure flag.

**Expected behavior**

Project discovery stays within the command limit. Recovery finishes the
saved result after workspace repair, releases its lease, and preserves
the original error for inspection. It does not repeat provider work or
relax session ownership checks.

**Steps to reproduce**

1. Return large project records from `list_projects` and observe an
oversized semantic result.
2. Persist an accepted native completion result, then record a shutdown
failure.
3. Finalize with a failed workspace, repeat that attempt, then record
successful workspace repair.
4. Reconcile the run. Before this fix, the issue stays In Progress.

**Paperclip version or commit**

Reproduced on `a386a599983519eb1d399f8b770bfccdb2a74762`.

**Deployment mode**

Self-hosted server with Paperclip Runner.

Related transport work: #12208 drains queued events; #12241 resumes
interrupted semantic calls. This change addresses bounded project
discovery and accepted-result finalization.

## What Changed

- Read bounded project summary projections from the database and return
at most 50 authorized summaries with a continuation cursor and explicit
description truncation. Agent and run trust boundaries narrow the
database candidates; project-specific policies still receive full
authorization. Only visible projects determine continuations. The
default project-list API remains unchanged.
- Record bounded, content-free settlement failure causes for command
limits, storage errors, and rejected dispatch.
- Include workspace state in assessment identity. Preserve the initial
assessment for interrupted finalization, and commit replacement
assessment and decision references together.
- Release the coordinator lease when an existing decision is replayed,
without repeating its effects.
- Clear stale errors when recovery succeeds and retain them in
`recoveredExecutionFailure`.
- Accept both current and legacy close-failure labels in the existing
exact-state cleanup path.
- Add regression tests and update the tool contracts and recovery
documentation.

## Verification

- Red: the new project paging, settlement diagnostic, current cleanup
label, and repaired-workspace regressions failed on the original
implementation.
- Green: protocol/catalog/tool checks (117 tests), the full project-tool
and finalizer suites (47 tests), cleanup ownership cases (70 tests), and
cleanup sweep cases (4 tests) pass. Database-backed pagination covers
large descriptions/configuration, complete enumeration, uppercase
cursors, agent/run restrictions, project-policy scope contributions, and
identical results/cursors when hidden projects are added.
- The initial CI failures in interrupted Board waits, contended endpoint
proof, and semantic schema validation were reproduced and fixed; all
affected cases pass locally.
- `pnpm -r typecheck` — passed.
- `pnpm build` — passed.
- `pnpm test:run` — started before the review corrections; it spanned
several source revisions and was stopped after reporting old-behavior
and timing failures. It is not claimed green. Fresh project and recovery
suites pass; the recovery suite also passes all 25 cases with the broad
runner’s isolated home/config. The Slack timing case passed in
isolation. Latest-head CI is the authoritative complete test matrix.
- Existing authorization suite — 66 tests passed.
- Latest-head CI on `8e5763d915aa6f375bdab6601996899ea01496fc` — 55
checks passed, 4 intentionally skipped, no pending or failing checks.
- Greptile — 5/5, zero unresolved threads on the same commit.
- `git diff --check` — passed.

## Risks

- `list_projects` now returns summaries. Callers must follow
`nextCursor` and use the authorized project API for full records.
Candidate narrowing is only an optimization: project policy and
responsible-user authorization remain authoritative.
- Assessment identity changes for workspace finalization. Existing
evidence remains intact; no migration is needed.
- Cleanup still requires matching identities, settled tool evidence, and
verified process ownership. Unknown tool outcomes remain blocked from
session reuse.

## Model Used

OpenAI Codex, based on GPT-6, with reasoning, code execution, and GitHub
tools. The exact serving model ID and context window 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-05 10:31:11 -05:00
DottaandPaperclip a386a59998 Reduce repeated native completion guidance and preserve final replies (#15151)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Native agents receive task constraints and completion tools from
Paperclip.
> - Completion tools already define the procedure for reporting a
result.
> - Repeated procedure text adds instructions to each full task turn.
> - The final reply must still explain a blocker and link a saved
document.
> - This pull request removes repeated procedure text and keeps these
visible outcome requirements explicit.
> - A document receipt supplies the exact link, and stricter evals check
the persisted reply and browser navigation.

## Linked Issues or Issue Description

Refs: #14961. Related: #14948 and #15007.

**What happened?**

Native task envelopes repeat completion procedure text. A reduced
envelope needs explicit final-reply requirements. The `write_document`
receipt also lacks a canonical document link.

**Expected behavior**

Keep the completion tools as the source of procedure details. Require
one accepted completion result before the final reply. A blocked reply
must explain the reason, owner and unblock action. A document reply must
contain a working link to the saved document.

**Steps to reproduce**

1. Run the native assigned-skill document case and native blocker case.
2. Inspect the run-attributed provider final and its persisted comment.
3. Check the blocker explanation or open the final reply's document
link.

## What Changed

- Remove repeated completion procedure text from the native task
constraints and backend instructions.
- Keep explicit blocker and document-link requirements in full task
turns.
- Return a company/task-scoped `documentHref` from `write_document`.
Preserve the link in the idempotent mutation receipt.
- Repeat canonical links for this run's current saved revisions in
accepted completion feedback. Give blocked providers final-response
guidance for the cause, owner and unblock action.
- Keep internal document/comment anchors when Markdown issue links load
cached issue details.
- Add a manual six-cell comparison suite with strict source, build,
default-instruction and budget admission.
- Capture eighteen shared runnerd RPC projections and six direct
OpenCode HTTP projections across start, resume and continuation phases,
using scripted local transports and no provider execution.
- Apply v3 checks only to the manual instruction comparison; preserve v2
checks for the existing native completion suite. Check the actual
persisted blocker reason and exact saved-document link. Click the
rendered document link and check the original content marker in the
classic document card or the new document tab.
- Forward exact OpenCode finishing calls through the controller. Wait
for acceptance, keep accepted feedback and concrete rejection text, and
reject malformed responses. Preserve ordinary dynamic-tool response
handling.
- Settle the completion decision and tool response before mapping a
racing idle/error/abort event or handling explicit close/interruption.
Reject a concurrent finishing call before controller admission.
- Add a provider-free regression through real runnerd, the OpenCode
proxy and a fake provider. Reject the first completion, accept the
corrected report in the same turn, and propose one result.
- Keep all original verdicts unchanged. Treat replay under new checks as
separate diagnostics.

## Verification

- `pnpm -r typecheck` and `pnpm build` pass locally.
- Native document-authority tests pass, including company/run
authorization and idempotent replay.
- Native runtime-context, backend and measurement tests pass.
- Final-answer calibration, protocol scoring, source-admission and
catalog tests pass. Wrong reasons, absent links and wrong link targets
fail.
- `pnpm test:e2e:runner:typecheck` passes. Discovery lists exactly six
single-attempt local cells with the declared models.
- Exported `prepareNativeInstructionPreflight` then
`verifyNativeInstructionPreflight` pass on this clean committed source.
They build locally and make zero provider calls.
- Corrective live confirmation is incomplete. Source 3a7349d passed both
Claude and both Codex cases. OpenCode saved the correct document but
omitted its final link; its blocker case was canceled before paid
execution. Preserve this failure. The e171282 confirmation was stopped
during build after fresh review found a completion-settlement race; it
executed zero providers. Source c3e0cb303 fixes that race. Two affected
OpenCode cases await fresh review and one bounded confirmation; earlier
results remain attributed to their original source.
- OpenCode proxy parsing, driver, factory and input tests: 81 pass
across retained focused runs, including six settlement races.
Evaluator/scoring/admission checks: 122 pass. The real proxy regression
passes. Fresh local prepare then verify passes with 18 shared and 6
direct scripted captures, fresh SDK/Rust builds and zero providers.
- The full local suite recorded two failures: a webhook timeout and a
Git-scan load count mismatch. Both files pass in isolation with
unchanged assertions/time budgets; preserve the original failure log.
Fresh c3e0cb303 CI and review are pending. This PR remains draft.

## Risks

- Final-answer wording can vary by provider. The checks cover the
declared release-access blocker and saved document fixture, not general
answer quality.
- A single trial does not establish general equivalence, cause, speed,
cost or live resume behavior.
- `documentHref` is an additive receipt field. It points to the current
saved document, not an immutable historical revision. Replaying an older
receipt does not fabricate a new link.
- The correction adds four production paths for document receipts,
accepted completion feedback and UI navigation, plus four OpenCode
controller/proxy paths, beyond the original three instruction paths.
Completion rejection must remain repairable; the production-boundary
regression covers it.
- Preserve the frozen comparison context for live measurement. A
merge-tree check against current master is clean. Do not relabel earlier
live results as results from a later source tree.

## Model Used

- OpenAI Codex, GPT-6 family. The exact serving model ID and context
window are unavailable in this session. Capabilities used: reasoning,
code editing, shell execution, test authoring and evidence review.

## 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
- [ ] 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
- [ ] All Paperclip CI gates are green
- [ ] 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-05 08:10:14 -05:00
DottaandPaperclip eb049aebf2 feat(skills): let agents update company skills safely (#15049)
## Thinking Path

> - Paperclip is an open source control plane for AI-agent companies.
> - Company skills give agents reusable work instructions.
> - Skill Studio can edit skill files and save version history.
> - Agents can create a skill, but they do not have a first-class update
tool.
> - An agent update needs a version check and safe retry behavior to
prevent lost edits.
> - This pull request adds `update_skill` through the existing company
skill file API.
> - The change keeps company policy, version history, and audit records
in one path.

## Linked Issues or Issue Description

**Subsystem affected**

Cross-cutting: the server API, shared validation, and runner tool
catalog.

**Problem or motivation**

An agent can create a company skill but cannot update its `SKILL.md`
through a first-class tool. An unguarded retry can also create duplicate
versions or overwrite a newer edit.

**Proposed solution**

Add `update_skill` with a required current version ID and a retry key.
Route it through the existing skill file API. Reject stale versions and
changed-input retries. Save the version and audit event together.

**Alternatives considered**

A separate write endpoint would duplicate the Skill Studio mutation path
and policy checks. This PR reuses that path instead.

**Roadmap alignment**

This work extends Skills Manager and Skill Studio, which are listed in
`ROADMAP.md`.

**Additional context**

The tool accepts a complete `SKILL.md`, not a partial patch. Callers
must read the current version before they edit it.

## What Changed

- Add optional version and retry fields to the existing skill file
update contract.
- Add a guarded API update with a stable retry receipt and attributed
audit event.
- Add `update_skill` to native and semantic runner tool catalogs, with
mode and policy gates.
- Add unit, integration, protocol, and semantic-tool regression
coverage.
- Document agent use and extend the OpenAPI request contract.

## Verification

- Focused tests and direct server and runner TypeScript checks passed
before this PR.
- `git diff --check` passed after the rebase onto `master`.
- CI passed on the latest PR head, including the full test matrix,
typecheck, and build. Local full typecheck and build stopped because
`cargo` is not installed. The local full test run ended without a
verdict.
- No dedicated end-to-end eval scenario was added or run. The protocol
coverage and semantic-tool test cover the new action deterministically.
- Reviewers can read a skill version, call `update_skill`, repeat the
same key, then try a stale version and a changed-input key. Only the
first edit must create a new version.

## Risks

- File writes and database transactions must stay in sync when a write
fails. The integration tests cover failed writes and retry behavior, but
CI must verify them on the PR head.
- Existing Skill Studio callers do not send the new optional
coordination fields. Their request shape remains valid.

## Model Used

- OpenAI Codex CLI assisted with this change. The runner did not expose
the exact model ID or context window. The agent used code execution and
repository 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; exact model ID and context window were not exposed)
- [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 suite
is pending CI)
- [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 (53 pass, 4 skip on the latest
head)
- [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-03 12:37:55 -05:00
DottaandPaperclip dd868ed125 fix(runner): share native completion tool guidance (#14961)
## Thinking Path

> - Paperclip manages AI agents and their work.
> - Native Runner agents report completion through finish and block
tools.
> - The providers receive different descriptions for those tools.
> - Completion guidance belongs with the tools that enforce the result.
> - This pull request shares the descriptions and refreshes retained
catalogs.
> - A separate native suite checks completion and blocking on production
defaults.
> - Legacy agents retain their separate skill and API paths.

## Linked Issues or Issue Description

Refs: #14920, #14948, #14985.

**Current behavior**

Native Codex and MCP bridges describe finish and block differently.
Retained provider sessions can keep old descriptions.

**Proposed behavior**

Native providers receive the same finish and block descriptions. The
descriptions cover report selection, validation feedback, returned
outcomes, approval gates and final-answer timing. Retained native
sessions refresh from v13 to v14.

**Reason and benefit**

Put the completion procedure next to its native tool. Preserve stock
base instructions, schemas, permissions and terminal semantics. This PR
now stands alone on master. It contains no reduced manual, shared prompt
or operational-skill changes from #14948.

## What Changed

- Add canonical native finish and block descriptions. Use them in direct
Codex and both native MCP bridges.
- Advance the native tool contract to v14. Cover old-v13 refresh without
replacing task identity or prior history.
- Check authenticated tool catalogs, provider start/resume frames and
serialized daemon catalogs.
- Add an independent, explicit-only native completion suite. Preserve
the original assigned-skill durable-document journey. Pair it with a
concrete whole-task blocker across Codex, ACPX Claude and OpenCode.
- Verify the actual public production default bundle and budgets before
execution. Require independent durable disposition, native
result/terminal receipts and observable provider-final ordering.
- Correct the blocker browser oracle to accept the requested
explanation. Keep exact owner/action/scope checks. Calibrate positive,
missing and contradictory replies.
- Preserve only actual `tool_call` terminal names (`paperclip_finish` /
`paperclip_block`) in the native compatibility run-log projection.
Require the same named call ID through its finishing result; retain all
other redaction boundaries.
- Admit verified hosted shallow checkout/build hydration and bind the
selected runnerd to exact source/archive/binary provenance. Hosted cells
truthfully reuse the existing trusted build; local admission executes
Rust calibration. Forward only public source/run identifiers through
both launcher preflight subprocess paths.
- Enforce single attempts in the launcher for opted-in fixtures. Keep
ordinary retry policy unchanged. Run exact-source, credential-free
admission before credential loading.

## Verification

- Frozen candidate: `d6e59e4712a3158ab4cd7d58deff1389b4578c21`, based on
master `59c07ede72dc08b8aba149a01cc11e0b7a204621`; historical
descriptions: `e74ed61a69fbdd8b3a8f15dd6456bc3140246e33`. Exactly the
five original native production files and six unit tests differ. Both
carry identical corrected fixtures, strict named finishing-call grader,
closed compatibility carrier and admission. Defaults,
profiles/models/auth/permissions and manifest bytes match.
- Actual launcher `prepareNativeCompletionPreflight` →
`verifyNativeCompletionPreflight` admission passes on both exact refs
with zero providers: candidate 132 / historical 127 selected TypeScript
assertions, 128 Node calibrations and one Rust normalization calibration
each; E2E typecheck, manifest checks, selected binary provenance and
six-cell discovery pass. Each has 257 explicitly skipped unrelated
assertions, not coverage. The credential-free environment calibration
exercises both real prepare/verify subprocess options with public hosted
identifiers and rejects credential/ambient overrides. Complete actual
launcher prepare→verify also passes on both frozen refs with explicitly
synthetic hosted metadata/verified archives, separately labeled as
calibration rather than a trusted GitHub run. Exact framed provenance
parsing and mock source identity are calibrated without relaxing the
real verifier.
- [Complete matched qualification
report](https://github.com/paperclipai/paperclip/blob/532066620b88e8731a5211fbe1cbc48ce8c7dd1a/doc/plans/2026-10-02-native-completion-master-qualification.md),
[immutable
manifest](https://github.com/paperclipai/paperclip/blob/532066620b88e8731a5211fbe1cbc48ce8c7dd1a/doc/plans/2026-10-02-native-completion-calibrated-manifest.json)
and [closed retained
audit/hashes](https://github.com/paperclipai/paperclip/blob/532066620b88e8731a5211fbe1cbc48ce8c7dd1a/doc/plans/2026-10-02-native-completion-calibrated-results/comparison.json)
are inspectable. All six candidate cells pass; historical descriptions
pass five. Paired outcomes: **zero new failures, one new pass (Codex
blocker), five unchanged passes, zero pending pairs**. [Candidate
campaign](https://github.com/paperclipai/paperclip/actions/runs/37098728980)
and [historical
campaign](https://github.com/paperclipai/paperclip/actions/runs/37098815696)
each execute six original attempt-1 native runs, with no campaign retry
and successful cleanup. Their trusted workflow revision is
`215586d127e97c9301d86e769a39a15c13298ca2`, separate from measured
source. [Candidate public
HTML](https://d1p6rlowie26tp.cloudfront.net/runner-e2e/campaigns/gha-37098728980-1/index.html)
and [historical public
HTML](https://d1p6rlowie26tp.cloudfront.net/runner-e2e/campaigns/gha-37098815696-1/index.html)
retain declared screenshots.
- Independent candidate evidence agrees with all original grades: 51
strict native checks, 12 served-default/budget checks and 21 original
skill/document checks pass. The historical Codex blocker saves the
correct whole-task blocker but omits the required marker from its actual
provider final and identical saved reply. This is not semantic-summary
fallback. Its original browser/matcher failure stays retained; the
additional native snapshot/grade and workspace before/after digest were
never written and are not fabricated by the separate API/PRP audit.
Historical Codex completion has one failed finish followed by success
within the same native run; the public receipt records no failure
reason. All twelve runs and their usage remain counted. Reported
model-cost subtotals are $0.00421482 historical/$0.00437391 candidate;
Codex/Claude zero entries have unknown billing type, actual invoices are
unverified and hosted execution cost is unmetered. One matched trial
supports no extra failure within these six cases, not broad statistical
or coding-quality equivalence.
- Initial hosted `e18c2cf9` / `459455ac` and subsequent `0a9c5a7` /
`00a761b` cohorts each stopped before providers in all twelve cells. The
latter failed a mocked-receipt unit test under ambient hosted metadata;
all source/build proofs passed. [All twelve later setup
receipts](https://github.com/paperclipai/paperclip/blob/402ee94c52273ad58de355ae9a7d562dd22f8101/doc/plans/2026-10-02-native-completion-qualified-hosted-setup.json)
are retained. [Exact failed setup
receipts](https://github.com/paperclipai/paperclip/blob/27653eb1a8f8ce839776d760f4563f672e5a706c/doc/plans/2026-10-02-native-completion-master-hosted-setup.json)
and the original manifest remain intact. Local sandbox-denied loopback
and stale anchor-expectation attempts are retained separately; unchanged
appropriate assertions were corrected/admitted before paid dispatch. Old
anonymous OpenCode streams are not assigned inferred tool names or
retroactively passed.
- Full provider-free E2E support previously passed 927 tests in 67
files. Exact-head d6 normal CI run `37098409915`, attempt 1 passes full
repository typecheck/build/tests, Runner Rust/static checks, all browser
shards/aggregate and canary: 52 check-runs pass, four intentional skips,
Snyk passes. Fresh Greptile check `111132956342` is 5/5 with zero
unresolved threads. Source-specific deterministic tests do not
substitute for the bounded live comparison.
- Earlier native source `9138f570c341c251a5727c32d6615ce238bc8e03` is
archived. Its [complete reduced-manual-context
report](https://github.com/paperclipai/paperclip/blob/9138f570c341c251a5727c32d6615ce238bc8e03/doc/plans/2026-10-02-native-completion-live-comparison.md)
remains intact, including original failures, grader limits and
provider-free replay. It is not current-master-context qualification.

## Risks

Changed tool text can change model behavior. The completed six-pair
qualification shows no extra failing outcomes in this bounded trial;
other tasks and repeated-run variance remain unmeasured. Observable
final ordering does not prove provider feedback consumption. Public
evidence can fail closed if a provider does not expose the required
result sequence. This slice does not remove native fixed prompts or
measure general coding quality. No database, schema, permission or
legacy completion changes occur.

## Model Used

OpenAI Codex, GPT-6 family, with code inspection, execution and tool
use. The exact deployment ID and context-window size are not exposed in
this session. They are unavailable rather than inferred from the model
menu.

## 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-03 06:20:38 -05:00
DottaandPaperclip cc67d4e1d8 fix: preserve steering and recover stopped task conversations (#15015)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - A task conversation must let a user guide a running agent and resume
stopped work.
> - The active run owns its input protocol, even when the user changes
the next model or effort.
> - Queue delivery waits for a provider receipt, which must be able to
persist during the request.
> - A stopped startup also needs a clear user action that passes normal
task admission.
> - This pull request fixes steering delivery, makes queue actions
immediate, and restores explicit continuation.
> - The benefit is a responsive conversation that can recover without
losing saved input.

## Linked Issues or Issue Description

**What happened?**

A queued message could change from Steer to Interrupt while a native run
prepared. A steer request could wait on its own database lock and fail
to deliver. A stopped startup could then leave the conversation without
a working Retry or message continuation. Interrupt also waited for the
server and showed a toast.

**Expected behavior**

The active run keeps its input protocol. Steer delivers input to that
run. Steer and Interrupt clear the submitted queue rows and show the
input in the conversation immediately. Failed delivery restores the
latest queue with an inline error. An eligible stopped run offers Retry,
and authenticated user input can start a fresh turn through normal task
admission.

**Steps to reproduce**

1. Start a task with a native Paperclip Runner.
2. Change the selected model or effort while that run prepares.
3. Queue a message and press Steer.
4. Observe the provider receipt and queue state during the request.
5. Stop a startup before its provider process begins, then try Retry or
send a new message.
6. Repeat queued delivery with a legacy runner and press Interrupt.

**Paperclip version or commit**

Reproduced on the parent of this branch, `59c07ede7`.

**Deployment mode**

Authenticated private deployment. The fixes also cover local task
conversations.

Related work: Refs #12834, Refs #13354, Refs #13275. The open refactor
in #13160 moves the same queue route; it does not fix the receipt lock
or stopped-run continuation addressed here.

## What Changed

- Select queue behavior from the active run's immutable dispatch and
runtime resolution.
- Leave the run row unlocked during provider acknowledgement, then lock
and read it before merging the receipt.
- Retain queued input if the target run stops during that wait. Keep
inline delivery errors visible after empty queue updates.
- Permit exact Retry and authenticated continuation after verified
native startup cancellation. Preserve pause, approval, budget,
ownership, and process-stop gates.
- Carry undelivered native queue input into a fresh turn once the old
execution is confirmed stopped.
- Show Steer and Interrupt input in the conversation and clear submitted
composer rows immediately. Restore the latest queue inline on failure.
Remove delivery toasts.
- Keep optimistic delivery stable across stale polls, empty queues, and
paginated history. Preserve classic Interrupt error handling.
- Document recovery and optimistic delivery behavior. Add regression
tests across server, shared queue projection, and UI boundaries.

## Verification

- Red-green regression tests reproduced the queue protocol, receipt
lock, stopped-startup continuation, and optimistic delivery failures.
- The focused server route, continuation, queue, and runner boundary
suites passed during implementation.
- The queue-route suite passes with 78 tests. The three complete
conversation UI suites pass with 347 tests.
- UI typecheck, production build, and `pnpm check:token-gates` pass.
- Workspace `pnpm -r typecheck` and `pnpm build` pass. The local
monolithic `pnpm test:run` is still running; remote CI verifies the
complete suite on the latest commit.
- All CI gates pass on `bd9031ad56abfcde13d13a13488c1b9217c2fd3a`,
including the full test shards, runner verification, browser E2E,
typecheck, release registry, and canary dry run.
- Greptile reports 5/5 for that commit. Both review threads are
resolved.

## Risks

This changes queue display and explicit continuation admission. The UI
must restore rejected delivery without losing other-session edits. The
server must preserve concurrent provider result updates and must not
resume a process whose stop is uncertain. Focused tests cover these
boundaries. This change has no database migration.

## Model Used

OpenAI Codex, an agent based on GPT-6. The exact runtime model ID and
context window are not exposed in this session. Used reasoning,
repository tools, code execution, and browser inspection.

## 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-02 22:07:14 -05:00
DottaandPaperclip 2ec82c5774 fix(runner): preserve task context when tool connections change (#14963)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agents use tools through company-scoped connections and provider
sessions.
> - Resolving a tool connection currently forces a fresh session even
when the provider can load new tools into the existing conversation.
> - A fresh provider conversation can receive too little history to
continue the task.
> - This pull request adds explicit tool-refresh capabilities and uses
them in both runner paths.
> - Fresh attempts receive bounded task history with source IDs and
retrieval instructions.
> - The benefit is that agents can continue the same task after a
connection changes.

## Linked Issues or Issue Description

**What happened?**

A resolved tool connection forced a fresh provider conversation. The new
conversation could lose the original goal and prior answers. Claude also
rejected resume when only the MCP server set changed.

**Expected behavior**

Resume the provider conversation when its harness can refresh tools.
When a fresh session is required, supply enough bounded history to
continue the task. Preserve company, agent, task, workspace, model,
instruction, and skill checks.

**Steps to reproduce**

1. Start a conversation and agree on a task and its constraints.
2. Request and connect a tool needed for the task.
3. Continue the conversation after the connection resolves.
4. Check that the agent remembers the task and can use the new tool.

**Paperclip version or commit**

The bug was reproduced on master at `c46e41e81`. This branch is rebased
on current master.

**Deployment mode**

Self-hosted server. Both legacy adapters and the native runner are
affected.

Related public work: Refs #13282 for task-backed conversations. Refs
#13057 for the broader session-compaction proposal. Refs #14659 for
another report about local CLI session continuity. This change fixes
tool-connection continuation. Provider authentication repairs keep their
existing recovery behavior.

## What Changed

- Expose tool-refresh support in native harness descriptors and legacy
adapter metadata.
- Request tool refresh after connection resolution. Keep provider
authentication repair as a fresh-session wake.
- Reload current tools and credentials while retaining supported Claude,
Codex, Grok, and other provider conversations.
- Allow MCP-only changes during qualified native recovery. Keep all
other compatibility checks.
- Refresh managed-provider and ACPX tool bindings when attaching a new
run.
- Add a fresh-session handoff for both runner paths. Bound database
reads, excerpts, and the final packet to 24,000 bytes.
- Include the original request, recent messages, decisions, plans, prior
answers, and source IDs. Mark omitted content. Apply reset boundaries,
wake cutoffs, quarantine, and secret redaction.
- Add regression tests and document the capabilities and handoff
behavior.

## Verification

- `pnpm -r typecheck` and `pnpm build` passed. Rust formatting passed.
- Final review fixes passed 314 server tests, 333 adapter utility tests,
139 native-session runtime tests, and 12 managed-provider Rust tests.
They verify historical quarantine, raised budgets across attachment, no
history reads on successful resume, and handoff delivery on fresh retry.
- Broader branch verification also passed 1,401 adapter utility tests,
1,047 runner TypeScript tests, 43 Grok adapter tests, and 311 Rust core
tests.
- Live Claude CLI and Grok ACP probes preserved the provider session ID,
recalled a prior task constraint, and called a newly added read-only MCP
tool.
- GitHub CI passed on `b21486d18084a7aa4cafbe8e012f7cad6585d9cc`: 55
successful checks and 4 skipped checks. This includes all test shards,
all eight browser shards, runner checks, and the Grok clean public npm
install canary. [CI
run](https://github.com/paperclipai/paperclip/actions/runs/37057514976).
- A full local test attempt encountered a separate Git snapshot timeout.
All affected local suites passed after the final edits, and the full CI
test gates passed.
- Review the capability matrix in `packages/paperclip-runner/README.md`.
Repeat the four reproduction steps with a supported provider and with an
unsupported harness.

## Risks

- Provider tool refresh can fail. Existing recovery falls back to a
fresh conversation where policy permits it.
- A new transport can replace an old process while preserving the
provider conversation. Tests cover current credentials and unchanged
identity.
- Long history can omit older context. Explicit markers and source IDs
let the agent retrieve needed context within task scope.
- Unknown and unqualified harnesses use the fresh-session path. No
database migration is required.

## Model Used

OpenAI Codex, GPT-6, with reasoning, tool use, code execution, and live
provider testing. The exact model ID and context-window size are not
exposed in this session. Claude and Grok also ran as test subjects.

## 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-02 15:11:44 -05:00
DottaandPaperclip d034ba7491 fix(interactions): derive question storage from canonical forms (#14946)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Agents request human input through durable issue interactions.
> - A question form has a canonical presentation and a compatibility
storage format.
> - The creation API required agents to write both formats.
> - Tool guidance told agents to split text and choice questions across
those formats.
> - This pull request accepts one complete canonical form and derives
storage fields on the server.
> - The benefit is a complete question card with stable answer and retry
behavior.

## Linked Issues or Issue Description

Related work: Refs #13630 and #14430. PR #13630 addresses the display of
historical partial forms. This change fixes creation and keeps the check
that rejects conflicting new forms.

**What happened?**

A question save supplied three compatibility questions and one canonical
text question. The API correctly rejected the incomplete canonical form.
The Runner's tool description encouraged this split. Sending only a
complete canonical form also failed because the API required
compatibility questions.

**Expected behavior**

An agent sends one complete `payload.questionSet` with every text and
choice question. Paperclip derives `payload.questions` for storage and
answer compatibility. Existing legacy requests remain valid. Explicitly
conflicting dual forms remain invalid.

**Steps to reproduce**

1. Call `paperclip_request_human_input` with `interactionKind:
"questions"`.
2. Send `payload: { version: 1, questionSet: ... }` with a required text
question and a required choice question.
3. The old API rejects the missing compatibility questions. With this
change, it stores both questions and preserves the canonical form.
4. Retry with the same idempotency key. Confirm that only one
interaction exists.
5. Submit both answers. Confirm that the normal resolver and
continuation rules apply.

**Paperclip version or commit**

The branch is based on `cf8ad63c8`. The problem affects the native
Runner and the interaction creation API.

**Deployment mode**

Server deployment with the native Paperclip Runner. Integration tests
use the real interaction service and an embedded test database.

## What Changed

- Add one shared canonical-to-storage projection. Reuse it for native
harness question requests.
- Accept canonical-only question creation at the shared validator and
server boundary.
- Export the input type and update the plugin SDK and its RPC contract.
- Advertise a typed, complete question form in the live and scenario
tool schemas.
- Enforce canonical text and custom-answer constraints before ordinary
or native resolution. Preserve harmless display whitespace.
- Run regex matching in isolated workers with a deadline and resource
limits. Both answer paths await the result before persistence. Saved
native delivery uses the validated answer without taking another worker
slot.
- Update agent guidance and generated Runner contracts.
- Test mixed forms, option-ID collisions, retries, answers, legacy
requests, and conflicting forms.

## Verification

- Interaction service, HTTP route, native bridge, and Runner authority
suites: 221 tests passed after correcting an obsolete tool-description
assertion.
- Shared validator, plugin SDK, CLI, and UI compatibility suites: 67
tests passed.
- Runner core tool-contract suite: 20 tests passed. AJV validates live
and scenario schemas.
- Final review regressions: 172 shared, service, native bridge, and
authority tests passed. These cover text length, pattern, numeric
limits, whitespace, custom option IDs, and historical pending cards.
- Runner session suites: 67 tests passed. Published example tests: 4
tests passed.
- Server typecheck and the shared/server builds passed after the
compatibility fixes.
- Final delivery verification: 35 response-delivery tests passed. The
native delivery regression proves saved answers do not enter pattern
workers; server typecheck and build passed.
- Pattern security and answer-flow verification: 205 tests passed after
repairing the child fixture loader. These cover pathological matching,
event-loop responsiveness, worker concurrency, slot cleanup, HTTP
routes, native delivery, and the full helper in a child process.
- `pnpm -r typecheck` passed on the bounded-worker revision.
- `pnpm build` passed on the bounded-worker revision.
- All 55 GitHub checks passed on `fe457af`; four optional jobs were
skipped. An unchanged Cursor adapter test timed out once in CI, passed
locally, and passed on one failed-job rerun.
- Reviewers can send the canonical-only mixed form above and verify that
the saved interaction contains both canonical and compatibility
questions.

## Risks

- The creation API accepts a new input shape. Stored rows and answer
contracts keep the existing shape.
- The shared projection must preserve synthetic free-text option IDs.
Collision and native round-trip tests cover this behavior.
- Historical partial rows remain readable. New conflicting dual forms,
including written-answer mismatches, remain rejected.
- Existing pending cards retain the written-answer paths offered by
their stored options. Canonical text constraints still apply.
- Ordinary answers now enforce declared canonical constraints before
persistence. Invalid answers leave the card pending.
- Regex validation has a one-second deadline and a four-worker capacity
limit. A complex pattern or capacity error leaves the card pending with
a validation error.
- No database migration or change to company authorization is required.

## Model Used

- OpenAI GPT-6 through Codex. The session exposes the GPT-6 model
family; its exact runtime model identifier and context window size are
not exposed. Used reasoning, tool use, and 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 (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-02 14:21:11 -05:00
DottaandPaperclip 9786f6df56 fix(runner): preserve credential content in document saves (#14937)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - The Runner sends authorized tool calls to the control plane.
> - Agents use these calls to save plans and instruction files.
> - The Runner used diagnostic secret detection to reject execution
arguments.
> - Ordinary credential-related prose could reject a document save
before persistence.
> - This pull request forwards the original arguments and leaves
credential policy to the provider harness.
> - The benefit is reliable saves with useful diagnostic records.

## Linked Issues or Issue Description

Related foundation: Refs #12415 and #14430. No duplicate save-policy fix
was found.

**What happened?**

A `write_document` call failed before the server saved its plan. The
Runner reported `semantic tool input contains credential material;
refusing to execute altered arguments`. The detector also masked
ordinary phrases such as `secret manager` and `credential handling` in
diagnostics. Both TypeScript dispatchers had equivalent execution gates.
One dispatcher also rewrote structured approval and question payloads
before execution.

**Expected behavior**

Paperclip forwards authorized arguments unchanged. The provider harness
decides credential-content policy. Log and audit redaction does not
reject or rewrite save input.

**Steps to reproduce**

1. Send an authorized `write_document` call with a plan that discusses
credential handling.
2. Include an intentional credential value in the body to exercise
harness-owned policy.
3. The old Runner rejects the call. With this change, the document
service stores the exact body.
4. Diagnostic records still mask explicit credential values. Qualified
credential fields, short bearer values, opaque diagnostic pairs, and
valid encoded JSON token headers have regression coverage.

**Paperclip version or commit**

Reproduced at `c46e41e81c03cd3c8b64cf993615b604d7fe8c62`. The branch is
based on current `master`.

**Deployment mode**

Server deployment with the native Paperclip Runner. Local regression
tests use the real document service and an embedded test database.

## What Changed

- Remove credential-content vetoes from Rust admission and both
TypeScript semantic dispatchers.
- Preserve original structured approval and question arguments during
execution.
- Keep transport bounds, schema checks, authorization, idempotency, and
audit masking.
- Require explicit credential syntax or recognized formats for
diagnostic masking. Preserve ordinary prose, metadata, and dotted
identifiers.
- Test exact document persistence, replay, nested argument identities,
and masked audit copies.
- Remove obsolete retry guidance and document harness-owned credential
policy.

## Verification

- `cargo test --manifest-path
packages/paperclip-runner/runner/Cargo.toml --locked -p
paperclip-runner-core --lib --test acpx_event_payload --test
acpx_provider_state --test acpx_provider_turns`: 355 tests passed.
- Focused server and adapter tests: 189 tests passed after rebase. These
include the real document save and the complete tool-gateway suite.
- Semantic dispatcher and conformance tests: 34 tests passed.
- Diagnostic redaction and MCP tests: 46 tests passed, including all six
review examples.
- `pnpm -r typecheck` and `pnpm build` passed on the repaired branch.
- The broad local root suite was interrupted after database fixture
setup failures. The focused database suites passed. CI runs the complete
configured test lanes.

## Risks

- Authorized tool arguments can intentionally contain credentials. The
harness must enforce its content policy.
- Diagnostic detection is narrower. Explicit assignments, credential
fields, and recognized credential formats remain masked.
- The change does not add a database migration or change company
authorization.

## Model Used

- OpenAI GPT-6 through Codex. The session exposes the GPT-6 model
family; its exact runtime model identifier and context window size are
not exposed. Used reasoning, tool use, and 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 (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-02 14:19:41 -05:00
DottaandPaperclip 4039d4f06b fix(auth): allow scoped low-trust work and owner-chat instruction edits (#14870)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Low-trust agents must work within their assigned scope.
> - Task creation currently rejects these agents before checking
assignment permission or scope.
> - Persistent instruction saves also reject direct requests from
authorized chat owners.
> - This PR checks the requested action and its recorded authority
instead of denying all such work.
> - Agents can organize permitted work and follow their owner's
instruction-edit requests while outside work stays restricted.

## Linked Issues or Issue Description

**What happened?**

Low-trust agents cannot create self-assigned tasks or subtasks, even
within their allowed scope. An authorized user also cannot ask an agent
in their own Agent Chat to update its managed `AGENTS.md`. Agent-folder
collection can hide the permission rejection behind a generic save
failure.

**Expected behavior**

Allow task creation when assignment permissions and project or root-task
scope permit it. Allow instruction self-edits during authenticated
owner-chat execution, subject to the user's current edit permission.
Outside tasks, subtasks, connector messages, and peer agents do not
inherit that instruction authority. Explain the actual denial when a
save fails.

**Steps to reproduce**

1. Configure an active agent with `low_trust_review` and a project or
root-task boundary.
2. Ask it to create an in-scope task assigned to itself, or a subtask of
its own task.
3. As a user with permission to configure that agent, ask it in your
Agent Chat to update its managed `AGENTS.md`.
4. Observe blanket permission denials rather than action-specific
checks.

**Paperclip version or commit**

Rebased onto master at `8ec4b84e1`. This is a core authorization change,
independent of adapter choice.

**Deployment mode**

Authenticated server. Regression coverage uses the server services, HTTP
routes, native tool authority, and embedded PostgreSQL.

Related work: #14775 adds human-directed task execution. #13599 concerns
instruction-path configuration; this PR leaves that configuration
restricted. #11988 proposes separate active-review instruction
protection. #10693 reports unclear authorization denials on a different
API surface.

## What Changed

- Apply task-assignment checks to both HTTP creation routes and native
task creation, including unassigned work. Preserve low-trust policy and
source attribution on the created task and its initial plan.
- Allow self-assigned decomposition within the permitted project or
root-task tree. Resolve workspace-derived project scope before
authorization, and reauthorize existing tasks before duplicate detection
returns them. Keep cross-project and peer-assignment checks.
- Derive instruction self-edit authority from the accepted run identity
and authenticated owner-message wake. Recheck current permissions at
save time. Bind retries to the same request and chat session.
- Reject inherited instruction authority from outside tasks, subtasks,
plugins, connectors, stale sessions, cancelled runs, and peer edits.
- Surface permission errors in instruction and agent-folder save
receipts. Tell chat agents to explain the rejected action and the
specific restriction.
- Update the low-trust policy and implementation documentation.

## Verification

- All 297 tests in 11 focused server suites pass after the rebase. These
cover owner-chat saves, private copies, warm agent directories, reset
and retry boundaries, permission revocation, task creation routes, and
native tool authority.
- After review fixes, all 126 tests in the four affected
authorization/chat suites pass. Workspace scope regressions and 146
existing creation/ownership/workspace-route tests also pass.
- The final duplicate-task and CI fixes pass all 39 tests across
chat-project tools, duplicate creation, environment-selection guards,
and assignee-invokability routes. The duplicate-task test reproduced an
unauthorized response before the fix and verifies denial plus permitted
reuse afterward.
- `pnpm --filter @paperclipai/server typecheck` passes after rebasing;
`pnpm --filter @paperclipai/server exec tsc --noEmit` also passes after
the review fixes.
- `git diff --check origin/master...HEAD` passes.
- Final head `7e73270b86748792649e4ae6fbc6879f73b42b73`: all 54 checks
passed, with two expected skips and no pending or failed checks. This
includes builds, typechecking, the full test matrix, end-to-end tests,
runner verification, the canary dry run, and security scans.
- Greptile is 5/5 on that exact head, with no unresolved review threads.
This change has not been deployed to staging.

## Risks

This changes authorization behavior. The instruction exception must not
become an inherited task permission. The check uses server-owned
execution records, requires the agent's own chat and instructions, and
keeps normal protected-change and responsible-user checks. Saves fail
closed when current provenance or permission is missing. Owner chat
grants a turn-scoped capability; the server does not classify the
message intent or require approval of the exact new file bytes. Prompt
injection within an authorized owner-chat turn remains a model-level
risk. This is the requested owner-chat trust boundary, without a new
per-edit confirmation flow. No database migration or broad trust-preset
change is required.

## Model Used

OpenAI Codex, based on GPT-6, with reasoning, code editing, shell tools,
and test execution. The exact runtime 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-01 15:42:40 -05:00
DottaandPaperclip 018993140f feat: let agents name prompt-only tasks (#14761)
## Thinking Path

> - Paperclip is the open source app people use to manage AI agents for
work.
> - Users create tasks with a title and a description.
> - A required title adds work when the prompt already explains the
request.
> - An agent can name the task once it reads that request.
> - This pull request accepts prompt-only tasks and starts them with a
short prompt slice.
> - A scoped title tool lets the assigned agent replace that slice early
without changing execution state.
> - A live browser eval checks the real agent call, saved title, audit
entry, and preservation of user titles.

## Linked Issues or Issue Description

**Subsystem affected**

Cross-cutting: task creation, shared contracts, database, server, runner
tools, and board UI.

**Problem or motivation**

Users must currently write a title before they can submit a detailed
task prompt. The agent has enough context to write a useful title
itself.

**Proposed solution**

Make the title optional when a description is present. Save the first
120 characters of the normalized prompt as a provisional title. Ask the
assigned agent to call `set_task_title` early. Use an atomic
provisional-title guard to preserve titles supplied or edited by users.
Keep explicit titles supported.

Related: #14543 and #14556 concern empty-title submission. This change
intentionally enables that submission when a prompt is present, instead
of requiring a title.

## What Changed

- Add the `titleNeedsGeneration` field with an idempotent migration.
Keep existing titles unchanged.
- Add `PUT /api/issues/:id/title` and the native and legacy
`set_task_title` tool. Enforce company access, active-run ownership,
shared, bounded retry receipts across native/HTTP calls, and
transactional audit logging. Refresh external-object links after commit,
with the same feature gate and plugin detectors as ordinary title edits.
- Add early naming guidance in Standard, Ask, and Plan task context.
Preserve the description, status, and assignment.
- Allow prompt-only root and child task creation, plus draft restoration
in the New Task dialog. Keep user titles supported.
- Add an opt-in Product E2E suite for prompt-only Standard and Ask
tasks, plus an explicit-title control. It checks actual provider calls
within the first five tools, persisted state, audit attribution, and the
reloaded UI.
- Preserve a closed vocabulary of API key maintenance phrases in
declared prose while rejecting opaque credential suffixes. Add one
bounded naming retry after wording is rejected, without treating the
rejected call as a saved title.
- Repair the native cleanup receipt check exposed during full
verification: accept matching input digests, retain legacy input checks,
and reject conflicting receipts.

## Verification

- Live Product E2E on `f43478473800e3a46b85c5ee79677efdb15108e7`: **3/3
passed** with native Codex `gpt-5.4-mini`, first attempts only,
automatic retries disabled. Standard and Ask each saved “Rotate expired
API key” on their first tool call, with matching persisted state and a
single same-run audit entry. The explicit-title control retained its
user title with zero title writes. All three verified the reloaded
browser UI.
- Campaign: `local-2026-09-30T21-30-11-021Z`. Earlier failed campaigns
are retained separately; they exposed credential-prose handling and
prompted the naming recovery fix. No failed result was regraded or
deleted.
- Reproduce with `pnpm test:e2e:runner -- --id
task-titles.runner-codex-mini.local.prompt-title-standard --id
task-titles.runner-codex-mini.local.prompt-title-ask --id
task-titles.runner-codex-mini.local.preserve-explicit-title
--max-automatic-retries 0` and an authorized provider key.
- Full `pnpm -r typecheck` and `pnpm build` passed on the latest commit.
The runner build used the configured external eval source tree.
- Product E2E unit suite: **61 files, 818 tests passed**; E2E typecheck
and UI token gates passed.
- Title API/native regressions cover prompt-only and explicit child
creation, user edits, ownership/company isolation, external reference
refresh, cross-surface retry replay, and the 64-key limit without
receipt eviction. All passed. Prompt-context coverage: **44 tests
passed**.
- Rust credential regressions: **35 tests passed**, including benign
maintenance qualifiers and opaque credential rejection in every declared
prose field. Catalog/report reconciliation: **28 tests passed**. Native
recovery: **560 tests passed**.
- Broad local `pnpm test:run`: **14,555 tests passed** in the general
server group; two suites failed to initialize embedded PostgreSQL and
the existing 40,000-file Git streaming stress test exceeded its
300-second macOS timeout. All three suites then passed in isolation (**5
tests passed**) without code or timeout changes. The original full local
command exited nonzero and is not being represented as a clean full run.
- Latest-head GitHub checks are green: **53 passed, 4 skipped, zero
failed or pending**, including all test shards and the canary packaging
dry run. Greptile reviewed the same commit at **5/5**, with zero
unresolved review threads.

## Risks

- The additive database field must reach the server and UI together. The
migration uses `IF NOT EXISTS` and defaults existing tasks to a final
title.
- Title generation depends on the assigned agent running. Tasks without
a run keep their provisional title.
- Live qualification covers the native Codex path in Standard and Ask
modes. API/legacy and Plan behavior have deterministic coverage.
- The credential-prose exception validates the entire suffix against a
closed maintenance vocabulary. Unknown suffixes, assignments, quoted
values, credential prefixes, and diagnostics retain strict checks.

## Model Used

OpenAI Codex, based on GPT-6, with reasoning, tool use, and code
execution. The exact deployment ID and context window are not exposed in
this session. The live eval uses the native Codex `gpt-5.4-mini`
profile.

## 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-30 16:48:24 -05:00